System Preprocessors
u4.c
Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include "syspro.h"
00003 #include "sysprotransform.h"
00004 #include "string.h"
00005 
00006 /*
00007   Test for a single preprocessor, iterating over options;
00008   the preprocessor adds the option to the problem number
00009   This also features the use of a context object.
00010  */
00011 
00012 /* the problem solving function: just a simple copy */
00013 #undef __FUNCT__
00014 #define __FUNCT__ "solvebycopy"
00015 static PetscErrorCode solvebycopy
00016 (NumericalProblem problem,void *dum,NumericalSolution *rsol)
00017 {
00018   NumericalSolution sol; PetscErrorCode ierr;
00019   PetscFunctionBegin;
00020   ierr = PetscMalloc(sizeof(int),(int**)&sol); CHKERRQ(ierr);
00021   SysProTraceMessage("Solving problem %d\n",*(int*)problem);
00022   *(int*)sol = *(int*)problem;
00023   *rsol = sol;
00024   PetscFunctionReturn(0);
00025 }
00026 
00027 /* context functions */
00028 #undef __FUNCT__
00029 #define __FUNCT__ "makeintctx"
00030 static PetscErrorCode makeintctx(NumericalProblem problem,void**ctx)
00031 {
00032   int *ictx; PetscErrorCode ierr;
00033   PetscFunctionBegin;
00034   ierr = PetscMalloc(sizeof(int),&ictx); CHKERRQ(ierr);
00035   *(int**)ctx = ictx;
00036   PetscFunctionReturn(0);
00037 }
00038 
00039 #undef __FUNCT__
00040 #define __FUNCT__ "delintctx"
00041 static PetscErrorCode delintctx(void*ctx)
00042 {
00043   PetscErrorCode ierr;
00044   PetscFunctionBegin;
00045   ierr = PetscFree(ctx); CHKERRQ(ierr);
00046   PetscFunctionReturn(0);
00047 }
00048 
00049 /* deallocate a problem object */
00050 #undef __FUNCT__
00051 #define __FUNCT__ "delprob"
00052 static PetscErrorCode delprob(NumericalProblem p)
00053 {
00054   PetscErrorCode ierr;
00055   PetscFunctionBegin;
00056   ierr = PetscFree(p); CHKERRQ(ierr);
00057   PetscFunctionReturn(0);
00058 }
00059 
00060 /* allocate a solution object */
00061 #undef __FUNCT__
00062 #define __FUNCT__ "makesol"
00063 static PetscErrorCode makesol(NumericalProblem p,NumericalSolution *rs)
00064 {
00065   NumericalSolution s; PetscErrorCode ierr;
00066   PetscFunctionBegin;
00067   ierr = PetscMalloc(sizeof(int),(int**)&s); CHKERRQ(ierr);
00068   *rs = s;
00069   PetscFunctionReturn(0);
00070 }
00071 
00072 /* deallocate a solution object */
00073 #undef __FUNCT__
00074 #define __FUNCT__ "delsol"
00075 static PetscErrorCode delsol(NumericalSolution s)
00076 {
00077   PetscErrorCode ierr;
00078   PetscFunctionBegin;
00079   ierr = PetscFree(s); CHKERRQ(ierr);
00080   PetscFunctionReturn(0);
00081 }
00082 
00083 /* preprocessor handling: we only know the function "addto",
00084    which adds the option value to the problem value */
00085 #undef __FUNCT__
00086 #define __FUNCT__ "adder"
00087 static PetscErrorCode adder
00088 (const char *choice,int optionvalue,PetscBool overwrite,
00089  NumericalProblem oldproblem,NumericalProblem *rnew,
00090  void *ctx,void **lctx,PetscBool *success)
00091 {
00092   NumericalProblem newproblem; PetscErrorCode ierr;
00093   PetscFunctionBegin;
00094   if (strcmp(choice,"addto")) SETERRQ1(PETSC_COMM_SELF,1,"Unknown choice <%s>",choice);
00095 
00096   ierr = PetscMalloc(sizeof(int),(int**)&newproblem); CHKERRQ(ierr);
00097   *(int*)newproblem = *(int*)oldproblem+optionvalue;
00098   SysProTraceMessage("new problem: %d\n",*(int*)newproblem);
00099   *rnew = newproblem;
00100 
00101   *(int*)ctx = optionvalue;
00102  *success = PETSC_TRUE;
00103   PetscFunctionReturn(0);
00104 }
00105 
00106 /* the unpreprocess function subtracts one */
00107 #undef __FUNCT__
00108 #define __FUNCT__ "unadder"
00109 static PetscErrorCode unadder
00110 (const char *choice,PetscBool overwrite,void *ctx,void *lctx,
00111  NumericalProblem pproblem,NumericalProblem oproblem,
00112  NumericalSolution psol,NumericalSolution osol)
00113 {
00114   PetscFunctionBegin;
00115   if (strcmp(choice,"addto")) SETERRQ1(PETSC_COMM_SELF,1,"Unknown choice <%s>",choice);
00116   *(int*)osol = *(int*)psol-*(int*)ctx;
00117   PetscFunctionReturn(0);
00118 }
00119 
00120 /* we declare our one and only preprocessor */
00121 #undef __FUNCT__
00122 #define __FUNCT__ "declareadders"
00123 static PetscErrorCode declareadders()
00124 {
00125   SalsaTransformObject cur; PetscErrorCode ierr;
00126   PetscFunctionBegin;
00127   ierr = NewTransformObject("adder","addto",&cur); CHKERRQ(ierr);
00128   ierr = TransformObjectDefineOption(cur,"shift"); CHKERRQ(ierr);
00129   ierr = TransformObjectAddOption(cur,1); CHKERRQ(ierr);
00130   ierr = TransformObjectAddOption(cur,2); CHKERRQ(ierr);
00131   ierr = TransformObjectAddOption(cur,3); CHKERRQ(ierr);
00132   PetscFunctionReturn(0);
00133 }
00134 
00135 #undef __FUNCT__
00136 #define __FUNCT__ "main"
00137 int main(int argc,char **argv) {
00138   NumericalProblem problem; NumericalSolution solution;
00139   PetscErrorCode ierr;
00140   PetscInitialize(&argc,&argv,0,0);
00141   ierr = SysProInitialize(); CHKERRQ(ierr);
00142   ierr = SysProDeclareFunctions
00143     (NULL,NULL,NULL,solvebycopy,delprob,
00144      makesol,NULL,delsol,NULL,NULL,NULL); CHKERRQ(ierr);
00145   ierr = SysProDeclareTraceFunction(&SysProDefaultTrace); CHKERRQ(ierr);
00146 
00147   /* set up a simple problem */
00148   ierr = PetscMalloc(sizeof(int),(int**)&problem); CHKERRQ(ierr);
00149   *(int*)problem = 5;
00150 
00151   /* declare a preprocessor */
00152   ierr = DeclarePreprocessor
00153     ("adder",&declareadders,NULL,NULL,NULL,&makeintctx,&delintctx,
00154      &adder,&unadder); CHKERRQ(ierr);
00155   ierr = PetscOptionsSetValue("-syspro_exhaustive","true"); CHKERRQ(ierr);
00156   ierr = PreprocessorsOptionsHandling(); CHKERRQ(ierr);
00157 
00158   /* solve this problem */
00159   ierr = PreprocessedProblemSolving(problem,&solution); CHKERRQ(ierr);
00160 
00161   /* check for correctness */
00162   {
00163     int s = *(int*)solution;
00164     if (s!=5)
00165       SETERRQ1(PETSC_COMM_SELF,1,"Computed wrong solution %d",s);
00166   }
00167 
00168   ierr = PetscFree(problem); CHKERRQ(ierr);
00169   ierr = PetscFree(solution); CHKERRQ(ierr);
00170   ierr = SysProFinalize(); CHKERRQ(ierr);
00171   PetscFinalize();
00172   return 0;
00173 }