1c4762a1bSJed Brown 2c4762a1bSJed Brown static char help[] = "Solves biharmonic equation in 1d.\n"; 3c4762a1bSJed Brown 4c4762a1bSJed Brown /* 5c4762a1bSJed Brown Solves the equation 6c4762a1bSJed Brown 7c4762a1bSJed Brown u_t = - kappa \Delta \Delta u 8c4762a1bSJed Brown Periodic boundary conditions 9c4762a1bSJed Brown 10c4762a1bSJed Brown Evolve the biharmonic heat equation: 11c4762a1bSJed Brown --------------- 12c4762a1bSJed Brown ./biharmonic -ts_monitor -snes_monitor -pc_type lu -draw_pause .1 -snes_converged_reason -draw_pause -2 -ts_type cn -da_refine 5 -mymonitor 13c4762a1bSJed Brown 14c4762a1bSJed Brown Evolve with the restriction that -1 <= u <= 1; i.e. as a variational inequality 15c4762a1bSJed Brown --------------- 16c4762a1bSJed Brown ./biharmonic -ts_monitor -snes_monitor -pc_type lu -draw_pause .1 -snes_converged_reason -draw_pause -2 -ts_type cn -da_refine 5 -mymonitor 17c4762a1bSJed Brown 18c4762a1bSJed Brown u_t = kappa \Delta \Delta u + 6.*u*(u_x)^2 + (3*u^2 - 12) \Delta u 19c4762a1bSJed Brown -1 <= u <= 1 20c4762a1bSJed Brown Periodic boundary conditions 21c4762a1bSJed Brown 22c4762a1bSJed Brown Evolve the Cahn-Hillard equations: double well Initial hump shrinks then grows 23c4762a1bSJed Brown --------------- 24c4762a1bSJed Brown ./biharmonic -ts_monitor -snes_monitor -pc_type lu -draw_pause .1 -snes_converged_reason -draw_pause -2 -ts_type cn -da_refine 6 -kappa .00001 -ts_dt 5.96046e-06 -cahn-hillard -ts_monitor_draw_solution --mymonitor 25c4762a1bSJed Brown 26c4762a1bSJed Brown Initial hump neither shrinks nor grows when degenerate (otherwise similar solution) 27c4762a1bSJed Brown 28c4762a1bSJed Brown ./biharmonic -ts_monitor -snes_monitor -pc_type lu -draw_pause .1 -snes_converged_reason -draw_pause -2 -ts_type cn -da_refine 6 -kappa .00001 -ts_dt 5.96046e-06 -cahn-hillard -degenerate -ts_monitor_draw_solution --mymonitor 29c4762a1bSJed Brown 30c4762a1bSJed Brown ./biharmonic -ts_monitor -snes_monitor -pc_type lu -draw_pause .1 -snes_converged_reason -draw_pause -2 -ts_type cn -da_refine 6 -kappa .00001 -ts_dt 5.96046e-06 -cahn-hillard -snes_vi_ignore_function_sign -ts_monitor_draw_solution --mymonitor 31c4762a1bSJed Brown 32c4762a1bSJed Brown Evolve the Cahn-Hillard equations: double obstacle 33c4762a1bSJed Brown --------------- 34c4762a1bSJed Brown ./biharmonic -ts_monitor -snes_monitor -pc_type lu -draw_pause .1 -snes_converged_reason -draw_pause -2 -ts_type cn -da_refine 5 -kappa .00001 -ts_dt 5.96046e-06 -cahn-hillard -energy 2 -snes_linesearch_monitor -ts_monitor_draw_solution --mymonitor 35c4762a1bSJed Brown 36c4762a1bSJed Brown Evolve the Cahn-Hillard equations: logarithmic + double well (never shrinks and then grows) 37c4762a1bSJed Brown --------------- 38c4762a1bSJed Brown ./biharmonic -ts_monitor -snes_monitor -pc_type lu --snes_converged_reason -draw_pause -2 -ts_type cn -da_refine 5 -kappa .0001 -ts_dt 5.96046e-06 -cahn-hillard -energy 3 -snes_linesearch_monitor -theta .00000001 -ts_monitor_draw_solution --ts_max_time 1. -mymonitor 39c4762a1bSJed Brown 40c4762a1bSJed Brown ./biharmonic -ts_monitor -snes_monitor -pc_type lu --snes_converged_reason -draw_pause -2 -ts_type cn -da_refine 5 -kappa .0001 -ts_dt 5.96046e-06 -cahn-hillard -energy 3 -snes_linesearch_monitor -theta .00000001 -ts_monitor_draw_solution --ts_max_time 1. -degenerate -mymonitor 41c4762a1bSJed Brown 42c4762a1bSJed Brown Evolve the Cahn-Hillard equations: logarithmic + double obstacle (never shrinks, never grows) 43c4762a1bSJed Brown --------------- 44c4762a1bSJed Brown ./biharmonic -ts_monitor -snes_monitor -pc_type lu --snes_converged_reason -draw_pause -2 -ts_type cn -da_refine 5 -kappa .00001 -ts_dt 5.96046e-06 -cahn-hillard -energy 4 -snes_linesearch_monitor -theta .00000001 -ts_monitor_draw_solution --mymonitor 45c4762a1bSJed Brown 46c4762a1bSJed Brown */ 47c4762a1bSJed Brown #include <petscdm.h> 48c4762a1bSJed Brown #include <petscdmda.h> 49c4762a1bSJed Brown #include <petscts.h> 50c4762a1bSJed Brown #include <petscdraw.h> 51c4762a1bSJed Brown 52c4762a1bSJed Brown extern PetscErrorCode FormFunction(TS,PetscReal,Vec,Vec,void*),FormInitialSolution(DM,Vec),MyMonitor(TS,PetscInt,PetscReal,Vec,void*),MyDestroy(void**),FormJacobian(TS,PetscReal,Vec,Mat,Mat,void*); 53c4762a1bSJed Brown typedef struct {PetscBool cahnhillard;PetscBool degenerate;PetscReal kappa;PetscInt energy;PetscReal tol;PetscReal theta,theta_c;PetscInt truncation;PetscBool netforce; PetscDrawViewPorts *ports;} UserCtx; 54c4762a1bSJed Brown 55c4762a1bSJed Brown int main(int argc,char **argv) 56c4762a1bSJed Brown { 57c4762a1bSJed Brown TS ts; /* nonlinear solver */ 58c4762a1bSJed Brown Vec x,r; /* solution, residual vectors */ 59c4762a1bSJed Brown Mat J; /* Jacobian matrix */ 60c4762a1bSJed Brown PetscInt steps,Mx; 61c4762a1bSJed Brown DM da; 62c4762a1bSJed Brown PetscReal dt; 63c4762a1bSJed Brown PetscBool mymonitor; 64c4762a1bSJed Brown UserCtx ctx; 65c4762a1bSJed Brown 66c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 67c4762a1bSJed Brown Initialize program 68c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 69*b122ec5aSJacob Faibussowitsch CHKERRQ(PetscInitialize(&argc,&argv,(char*)0,help)); 70c4762a1bSJed Brown ctx.kappa = 1.0; 715f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetReal(NULL,NULL,"-kappa",&ctx.kappa,NULL)); 72c4762a1bSJed Brown ctx.degenerate = PETSC_FALSE; 735f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-degenerate",&ctx.degenerate,NULL)); 74c4762a1bSJed Brown ctx.cahnhillard = PETSC_FALSE; 755f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-cahn-hillard",&ctx.cahnhillard,NULL)); 76c4762a1bSJed Brown ctx.netforce = PETSC_FALSE; 775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-netforce",&ctx.netforce,NULL)); 78c4762a1bSJed Brown ctx.energy = 1; 795f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-energy",&ctx.energy,NULL)); 80c4762a1bSJed Brown ctx.tol = 1.0e-8; 815f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetReal(NULL,NULL,"-tol",&ctx.tol,NULL)); 82c4762a1bSJed Brown ctx.theta = .001; 83c4762a1bSJed Brown ctx.theta_c = 1.0; 845f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetReal(NULL,NULL,"-theta",&ctx.theta,NULL)); 855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetReal(NULL,NULL,"-theta_c",&ctx.theta_c,NULL)); 86c4762a1bSJed Brown ctx.truncation = 1; 875f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-truncation",&ctx.truncation,NULL)); 885f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsHasName(NULL,NULL,"-mymonitor",&mymonitor)); 89c4762a1bSJed Brown 90c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 91c4762a1bSJed Brown Create distributed array (DMDA) to manage parallel grid and vectors 92c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 935f80ce2aSJacob Faibussowitsch CHKERRQ(DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_PERIODIC, 10,1,2,NULL,&da)); 945f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetFromOptions(da)); 955f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetUp(da)); 965f80ce2aSJacob Faibussowitsch CHKERRQ(DMDASetFieldName(da,0,"Biharmonic heat equation: u")); 975f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAGetInfo(da,0,&Mx,0,0,0,0,0,0,0,0,0,0,0)); 98c4762a1bSJed Brown dt = 1.0/(10.*ctx.kappa*Mx*Mx*Mx*Mx); 99c4762a1bSJed Brown 100c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 101c4762a1bSJed Brown Extract global vectors from DMDA; then duplicate for remaining 102c4762a1bSJed Brown vectors that are the same types 103c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1045f80ce2aSJacob Faibussowitsch CHKERRQ(DMCreateGlobalVector(da,&x)); 1055f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(x,&r)); 106c4762a1bSJed Brown 107c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 108c4762a1bSJed Brown Create timestepping solver context 109c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1105f80ce2aSJacob Faibussowitsch CHKERRQ(TSCreate(PETSC_COMM_WORLD,&ts)); 1115f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetDM(ts,da)); 1125f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetProblemType(ts,TS_NONLINEAR)); 1135f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetRHSFunction(ts,NULL,FormFunction,&ctx)); 1145f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetMatType(da,MATAIJ)); 1155f80ce2aSJacob Faibussowitsch CHKERRQ(DMCreateMatrix(da,&J)); 1165f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetRHSJacobian(ts,J,J,FormJacobian,&ctx)); 1175f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetMaxTime(ts,.02)); 1185f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetExactFinalTime(ts,TS_EXACTFINALTIME_INTERPOLATE)); 119c4762a1bSJed Brown 120c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 121c4762a1bSJed Brown Create matrix data structure; set Jacobian evaluation routine 122c4762a1bSJed Brown 123c4762a1bSJed Brown Set Jacobian matrix data structure and default Jacobian evaluation 124c4762a1bSJed Brown routine. User can override with: 125c4762a1bSJed Brown -snes_mf : matrix-free Newton-Krylov method with no preconditioning 126c4762a1bSJed Brown (unless user explicitly sets preconditioner) 127c4762a1bSJed Brown -snes_mf_operator : form preconditioning matrix as set by the user, 128c4762a1bSJed Brown but use matrix-free approx for Jacobian-vector 129c4762a1bSJed Brown products within Newton-Krylov method 130c4762a1bSJed Brown 131c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 132c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 133c4762a1bSJed Brown Customize nonlinear solver 134c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1355f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetType(ts,TSCN)); 136c4762a1bSJed Brown 137c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 138c4762a1bSJed Brown Set initial conditions 139c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1405f80ce2aSJacob Faibussowitsch CHKERRQ(FormInitialSolution(da,x)); 1415f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetTimeStep(ts,dt)); 1425f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetSolution(ts,x)); 143c4762a1bSJed Brown 144c4762a1bSJed Brown if (mymonitor) { 145c4762a1bSJed Brown ctx.ports = NULL; 1465f80ce2aSJacob Faibussowitsch CHKERRQ(TSMonitorSet(ts,MyMonitor,&ctx,MyDestroy)); 147c4762a1bSJed Brown } 148c4762a1bSJed Brown 149c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 150c4762a1bSJed Brown Set runtime options 151c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1525f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetFromOptions(ts)); 153c4762a1bSJed Brown 154c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 155c4762a1bSJed Brown Solve nonlinear system 156c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1575f80ce2aSJacob Faibussowitsch CHKERRQ(TSSolve(ts,x)); 1585f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetStepNumber(ts,&steps)); 1595f80ce2aSJacob Faibussowitsch CHKERRQ(VecView(x,PETSC_VIEWER_BINARY_WORLD)); 160c4762a1bSJed Brown 161c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 162c4762a1bSJed Brown Free work space. All PETSc objects should be destroyed when they 163c4762a1bSJed Brown are no longer needed. 164c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1655f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&J)); 1665f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&x)); 1675f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&r)); 1685f80ce2aSJacob Faibussowitsch CHKERRQ(TSDestroy(&ts)); 1695f80ce2aSJacob Faibussowitsch CHKERRQ(DMDestroy(&da)); 170c4762a1bSJed Brown 171*b122ec5aSJacob Faibussowitsch CHKERRQ(PetscFinalize()); 172*b122ec5aSJacob Faibussowitsch return 0; 173c4762a1bSJed Brown } 174c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 175c4762a1bSJed Brown /* 176c4762a1bSJed Brown FormFunction - Evaluates nonlinear function, F(x). 177c4762a1bSJed Brown 178c4762a1bSJed Brown Input Parameters: 179c4762a1bSJed Brown . ts - the TS context 180c4762a1bSJed Brown . X - input vector 181c4762a1bSJed Brown . ptr - optional user-defined context, as set by SNESSetFunction() 182c4762a1bSJed Brown 183c4762a1bSJed Brown Output Parameter: 184c4762a1bSJed Brown . F - function vector 185c4762a1bSJed Brown */ 186c4762a1bSJed Brown PetscErrorCode FormFunction(TS ts,PetscReal ftime,Vec X,Vec F,void *ptr) 187c4762a1bSJed Brown { 188c4762a1bSJed Brown DM da; 189c4762a1bSJed Brown PetscInt i,Mx,xs,xm; 190c4762a1bSJed Brown PetscReal hx,sx; 191c4762a1bSJed Brown PetscScalar *x,*f,c,r,l; 192c4762a1bSJed Brown Vec localX; 193c4762a1bSJed Brown UserCtx *ctx = (UserCtx*)ptr; 194c4762a1bSJed Brown PetscReal tol = ctx->tol, theta=ctx->theta,theta_c=ctx->theta_c,a,b; /* a and b are used in the cubic truncation of the log function */ 195c4762a1bSJed Brown 196c4762a1bSJed Brown PetscFunctionBegin; 1975f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetDM(ts,&da)); 1985f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLocalVector(da,&localX)); 1995f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE)); 200c4762a1bSJed Brown 201c4762a1bSJed Brown hx = 1.0/(PetscReal)Mx; sx = 1.0/(hx*hx); 202c4762a1bSJed Brown 203c4762a1bSJed Brown /* 204c4762a1bSJed Brown Scatter ghost points to local vector,using the 2-step process 205c4762a1bSJed Brown DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). 206c4762a1bSJed Brown By placing code between these two statements, computations can be 207c4762a1bSJed Brown done while messages are in transition. 208c4762a1bSJed Brown */ 2095f80ce2aSJacob Faibussowitsch CHKERRQ(DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX)); 2105f80ce2aSJacob Faibussowitsch CHKERRQ(DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX)); 211c4762a1bSJed Brown 212c4762a1bSJed Brown /* 213c4762a1bSJed Brown Get pointers to vector data 214c4762a1bSJed Brown */ 2155f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecGetArrayRead(da,localX,&x)); 2165f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecGetArray(da,F,&f)); 217c4762a1bSJed Brown 218c4762a1bSJed Brown /* 219c4762a1bSJed Brown Get local grid boundaries 220c4762a1bSJed Brown */ 2215f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL)); 222c4762a1bSJed Brown 223c4762a1bSJed Brown /* 224c4762a1bSJed Brown Compute function over the locally owned part of the grid 225c4762a1bSJed Brown */ 226c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 227c4762a1bSJed Brown if (ctx->degenerate) { 228c4762a1bSJed Brown c = (1. - x[i]*x[i])*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 229c4762a1bSJed Brown r = (1. - x[i+1]*x[i+1])*(x[i] + x[i+2] - 2.0*x[i+1])*sx; 230c4762a1bSJed Brown l = (1. - x[i-1]*x[i-1])*(x[i-2] + x[i] - 2.0*x[i-1])*sx; 231c4762a1bSJed Brown } else { 232c4762a1bSJed Brown c = (x[i-1] + x[i+1] - 2.0*x[i])*sx; 233c4762a1bSJed Brown r = (x[i] + x[i+2] - 2.0*x[i+1])*sx; 234c4762a1bSJed Brown l = (x[i-2] + x[i] - 2.0*x[i-1])*sx; 235c4762a1bSJed Brown } 236c4762a1bSJed Brown f[i] = -ctx->kappa*(l + r - 2.0*c)*sx; 237c4762a1bSJed Brown if (ctx->cahnhillard) { 238c4762a1bSJed Brown switch (ctx->energy) { 239c4762a1bSJed Brown case 1: /* double well */ 240c4762a1bSJed Brown f[i] += 6.*.25*x[i]*(x[i+1] - x[i-1])*(x[i+1] - x[i-1])*sx + (3.*x[i]*x[i] - 1.)*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 241c4762a1bSJed Brown break; 242c4762a1bSJed Brown case 2: /* double obstacle */ 243c4762a1bSJed Brown f[i] += -(x[i-1] + x[i+1] - 2.0*x[i])*sx; 244c4762a1bSJed Brown break; 245c4762a1bSJed Brown case 3: /* logarithmic + double well */ 246c4762a1bSJed Brown f[i] += 6.*.25*x[i]*(x[i+1] - x[i-1])*(x[i+1] - x[i-1])*sx + (3.*x[i]*x[i] - 1.)*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 247c4762a1bSJed Brown if (ctx->truncation==2) { /* log function with approximated with a quadratic polynomial outside -1.0+2*tol, 1.0-2*tol */ 248c4762a1bSJed Brown if (PetscRealPart(x[i]) < -1.0 + 2.0*tol) f[i] += (.25*theta/(tol-tol*tol))*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 249c4762a1bSJed Brown else if (PetscRealPart(x[i]) > 1.0 - 2.0*tol) f[i] += (.25*theta/(tol-tol*tol))*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 250c4762a1bSJed Brown else f[i] += 2.0*theta*x[i]/((1.0-x[i]*x[i])*(1.0-x[i]*x[i]))*.25*(x[i+1] - x[i-1])*(x[i+1] - x[i-1])*sx + (theta/(1.0-x[i]*x[i]))*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 251c4762a1bSJed Brown } else { /* log function is approximated with a cubic polynomial outside -1.0+2*tol, 1.0-2*tol */ 252c4762a1bSJed Brown a = 2.0*theta*(1.0-2.0*tol)/(16.0*tol*tol*(1.0-tol)*(1.0-tol)); 253c4762a1bSJed Brown b = theta/(4.0*tol*(1.0-tol)) - a*(1.0-2.0*tol); 254c4762a1bSJed Brown if (PetscRealPart(x[i]) < -1.0 + 2.0*tol) f[i] += -1.0*a*.25*(x[i+1] - x[i-1])*(x[i+1] - x[i-1])*sx + (-1.0*a*x[i] + b)*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 255c4762a1bSJed Brown else if (PetscRealPart(x[i]) > 1.0 - 2.0*tol) f[i] += 1.0*a*.25*(x[i+1] - x[i-1])*(x[i+1] - x[i-1])*sx + ( a*x[i] + b)*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 256c4762a1bSJed Brown else f[i] += 2.0*theta*x[i]/((1.0-x[i]*x[i])*(1.0-x[i]*x[i]))*.25*(x[i+1] - x[i-1])*(x[i+1] - x[i-1])*sx + (theta/(1.0-x[i]*x[i]))*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 257c4762a1bSJed Brown } 258c4762a1bSJed Brown break; 259c4762a1bSJed Brown case 4: /* logarithmic + double obstacle */ 260c4762a1bSJed Brown f[i] += -theta_c*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 261c4762a1bSJed Brown if (ctx->truncation==2) { /* quadratic */ 262c4762a1bSJed Brown if (PetscRealPart(x[i]) < -1.0 + 2.0*tol) f[i] += (.25*theta/(tol-tol*tol))*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 263c4762a1bSJed Brown else if (PetscRealPart(x[i]) > 1.0 - 2.0*tol) f[i] += (.25*theta/(tol-tol*tol))*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 264c4762a1bSJed Brown else f[i] += 2.0*theta*x[i]/((1.0-x[i]*x[i])*(1.0-x[i]*x[i]))*.25*(x[i+1] - x[i-1])*(x[i+1] - x[i-1])*sx + (theta/(1.0-x[i]*x[i]))*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 265c4762a1bSJed Brown } else { /* cubic */ 266c4762a1bSJed Brown a = 2.0*theta*(1.0-2.0*tol)/(16.0*tol*tol*(1.0-tol)*(1.0-tol)); 267c4762a1bSJed Brown b = theta/(4.0*tol*(1.0-tol)) - a*(1.0-2.0*tol); 268c4762a1bSJed Brown if (PetscRealPart(x[i]) < -1.0 + 2.0*tol) f[i] += -1.0*a*.25*(x[i+1] - x[i-1])*(x[i+1] - x[i-1])*sx + (-1.0*a*x[i] + b)*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 269c4762a1bSJed Brown else if (PetscRealPart(x[i]) > 1.0 - 2.0*tol) f[i] += 1.0*a*.25*(x[i+1] - x[i-1])*(x[i+1] - x[i-1])*sx + ( a*x[i] + b)*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 270c4762a1bSJed Brown else f[i] += 2.0*theta*x[i]/((1.0-x[i]*x[i])*(1.0-x[i]*x[i]))*.25*(x[i+1] - x[i-1])*(x[i+1] - x[i-1])*sx + (theta/(1.0-x[i]*x[i]))*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 271c4762a1bSJed Brown } 272c4762a1bSJed Brown break; 273c4762a1bSJed Brown } 274c4762a1bSJed Brown } 275c4762a1bSJed Brown 276c4762a1bSJed Brown } 277c4762a1bSJed Brown 278c4762a1bSJed Brown /* 279c4762a1bSJed Brown Restore vectors 280c4762a1bSJed Brown */ 2815f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecRestoreArrayRead(da,localX,&x)); 2825f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecRestoreArray(da,F,&f)); 2835f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreLocalVector(da,&localX)); 284c4762a1bSJed Brown PetscFunctionReturn(0); 285c4762a1bSJed Brown } 286c4762a1bSJed Brown 287c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 288c4762a1bSJed Brown /* 289c4762a1bSJed Brown FormJacobian - Evaluates nonlinear function's Jacobian 290c4762a1bSJed Brown 291c4762a1bSJed Brown */ 292c4762a1bSJed Brown PetscErrorCode FormJacobian(TS ts,PetscReal ftime,Vec X,Mat A,Mat B,void *ptr) 293c4762a1bSJed Brown { 294c4762a1bSJed Brown DM da; 295c4762a1bSJed Brown PetscInt i,Mx,xs,xm; 296c4762a1bSJed Brown MatStencil row,cols[5]; 297c4762a1bSJed Brown PetscReal hx,sx; 298c4762a1bSJed Brown PetscScalar *x,vals[5]; 299c4762a1bSJed Brown Vec localX; 300c4762a1bSJed Brown UserCtx *ctx = (UserCtx*)ptr; 301c4762a1bSJed Brown 302c4762a1bSJed Brown PetscFunctionBegin; 3035f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetDM(ts,&da)); 3045f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLocalVector(da,&localX)); 3055f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE)); 306c4762a1bSJed Brown 307c4762a1bSJed Brown hx = 1.0/(PetscReal)Mx; sx = 1.0/(hx*hx); 308c4762a1bSJed Brown 309c4762a1bSJed Brown /* 310c4762a1bSJed Brown Scatter ghost points to local vector,using the 2-step process 311c4762a1bSJed Brown DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). 312c4762a1bSJed Brown By placing code between these two statements, computations can be 313c4762a1bSJed Brown done while messages are in transition. 314c4762a1bSJed Brown */ 3155f80ce2aSJacob Faibussowitsch CHKERRQ(DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX)); 3165f80ce2aSJacob Faibussowitsch CHKERRQ(DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX)); 317c4762a1bSJed Brown 318c4762a1bSJed Brown /* 319c4762a1bSJed Brown Get pointers to vector data 320c4762a1bSJed Brown */ 3215f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecGetArrayRead(da,localX,&x)); 322c4762a1bSJed Brown 323c4762a1bSJed Brown /* 324c4762a1bSJed Brown Get local grid boundaries 325c4762a1bSJed Brown */ 3265f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL)); 327c4762a1bSJed Brown 328c4762a1bSJed Brown /* 329c4762a1bSJed Brown Compute function over the locally owned part of the grid 330c4762a1bSJed Brown */ 331c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 332c4762a1bSJed Brown row.i = i; 333c4762a1bSJed Brown if (ctx->degenerate) { 334c4762a1bSJed Brown /*PetscScalar c,r,l; 335c4762a1bSJed Brown c = (1. - x[i]*x[i])*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 336c4762a1bSJed Brown r = (1. - x[i+1]*x[i+1])*(x[i] + x[i+2] - 2.0*x[i+1])*sx; 337c4762a1bSJed Brown l = (1. - x[i-1]*x[i-1])*(x[i-2] + x[i] - 2.0*x[i-1])*sx; */ 338c4762a1bSJed Brown } else { 339c4762a1bSJed Brown cols[0].i = i - 2; vals[0] = -ctx->kappa*sx*sx; 340c4762a1bSJed Brown cols[1].i = i - 1; vals[1] = 4.0*ctx->kappa*sx*sx; 341c4762a1bSJed Brown cols[2].i = i ; vals[2] = -6.0*ctx->kappa*sx*sx; 342c4762a1bSJed Brown cols[3].i = i + 1; vals[3] = 4.0*ctx->kappa*sx*sx; 343c4762a1bSJed Brown cols[4].i = i + 2; vals[4] = -ctx->kappa*sx*sx; 344c4762a1bSJed Brown } 3455f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValuesStencil(B,1,&row,5,cols,vals,INSERT_VALUES)); 346c4762a1bSJed Brown 347c4762a1bSJed Brown if (ctx->cahnhillard) { 348c4762a1bSJed Brown switch (ctx->energy) { 349c4762a1bSJed Brown case 1: /* double well */ 350c4762a1bSJed Brown /* f[i] += 6.*.25*x[i]*(x[i+1] - x[i-1])*(x[i+1] - x[i-1])*sx + (3.*x[i]*x[i] - 1.)*(x[i-1] + x[i+1] - 2.0*x[i])*sx; */ 351c4762a1bSJed Brown break; 352c4762a1bSJed Brown case 2: /* double obstacle */ 353c4762a1bSJed Brown /* f[i] += -(x[i-1] + x[i+1] - 2.0*x[i])*sx; */ 354c4762a1bSJed Brown break; 355c4762a1bSJed Brown case 3: /* logarithmic + double well */ 356c4762a1bSJed Brown break; 357c4762a1bSJed Brown case 4: /* logarithmic + double obstacle */ 358c4762a1bSJed Brown break; 359c4762a1bSJed Brown } 360c4762a1bSJed Brown } 361c4762a1bSJed Brown 362c4762a1bSJed Brown } 363c4762a1bSJed Brown 364c4762a1bSJed Brown /* 365c4762a1bSJed Brown Restore vectors 366c4762a1bSJed Brown */ 3675f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecRestoreArrayRead(da,localX,&x)); 3685f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreLocalVector(da,&localX)); 3695f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 3705f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 371c4762a1bSJed Brown if (A != B) { 3725f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 3735f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 374c4762a1bSJed Brown } 375c4762a1bSJed Brown PetscFunctionReturn(0); 376c4762a1bSJed Brown } 377c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 378c4762a1bSJed Brown PetscErrorCode FormInitialSolution(DM da,Vec U) 379c4762a1bSJed Brown { 380c4762a1bSJed Brown PetscInt i,xs,xm,Mx,N,scale; 381c4762a1bSJed Brown PetscScalar *u; 382c4762a1bSJed Brown PetscReal r,hx,x; 383c4762a1bSJed Brown const PetscScalar *f; 384c4762a1bSJed Brown Vec finesolution; 385c4762a1bSJed Brown PetscViewer viewer; 386c4762a1bSJed Brown 387c4762a1bSJed Brown PetscFunctionBegin; 3885f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE)); 389c4762a1bSJed Brown 390c4762a1bSJed Brown hx = 1.0/(PetscReal)Mx; 391c4762a1bSJed Brown 392c4762a1bSJed Brown /* 393c4762a1bSJed Brown Get pointers to vector data 394c4762a1bSJed Brown */ 3955f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecGetArray(da,U,&u)); 396c4762a1bSJed Brown 397c4762a1bSJed Brown /* 398c4762a1bSJed Brown Get local grid boundaries 399c4762a1bSJed Brown */ 4005f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL)); 401c4762a1bSJed Brown 402c4762a1bSJed Brown /* 403c4762a1bSJed Brown Seee heat.c for how to generate InitialSolution.heat 404c4762a1bSJed Brown */ 4055f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerBinaryOpen(PETSC_COMM_WORLD,"InitialSolution.heat",FILE_MODE_READ,&viewer)); 4065f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreate(PETSC_COMM_WORLD,&finesolution)); 4075f80ce2aSJacob Faibussowitsch CHKERRQ(VecLoad(finesolution,viewer)); 4085f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerDestroy(&viewer)); 4095f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetSize(finesolution,&N)); 410c4762a1bSJed Brown scale = N/Mx; 4115f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(finesolution,&f)); 412c4762a1bSJed Brown 413c4762a1bSJed Brown /* 414c4762a1bSJed Brown Compute function over the locally owned part of the grid 415c4762a1bSJed Brown */ 416c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 417c4762a1bSJed Brown x = i*hx; 418c4762a1bSJed Brown r = PetscSqrtReal((x-.5)*(x-.5)); 419c4762a1bSJed Brown if (r < .125) u[i] = 1.0; 420c4762a1bSJed Brown else u[i] = -.5; 421c4762a1bSJed Brown 422c4762a1bSJed Brown /* With the initial condition above the method is first order in space */ 423c4762a1bSJed Brown /* this is a smooth initial condition so the method becomes second order in space */ 424c4762a1bSJed Brown /*u[i] = PetscSinScalar(2*PETSC_PI*x); */ 425c4762a1bSJed Brown u[i] = f[scale*i]; 426c4762a1bSJed Brown } 4275f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(finesolution,&f)); 4285f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&finesolution)); 429c4762a1bSJed Brown 430c4762a1bSJed Brown /* 431c4762a1bSJed Brown Restore vectors 432c4762a1bSJed Brown */ 4335f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecRestoreArray(da,U,&u)); 434c4762a1bSJed Brown PetscFunctionReturn(0); 435c4762a1bSJed Brown } 436c4762a1bSJed Brown 437c4762a1bSJed Brown /* 438c4762a1bSJed Brown This routine is not parallel 439c4762a1bSJed Brown */ 440c4762a1bSJed Brown PetscErrorCode MyMonitor(TS ts,PetscInt step,PetscReal time,Vec U,void *ptr) 441c4762a1bSJed Brown { 442c4762a1bSJed Brown UserCtx *ctx = (UserCtx*)ptr; 443c4762a1bSJed Brown PetscDrawLG lg; 444c4762a1bSJed Brown PetscScalar *u,l,r,c; 445c4762a1bSJed Brown PetscInt Mx,i,xs,xm,cnt; 446c4762a1bSJed Brown PetscReal x,y,hx,pause,sx,len,max,xx[4],yy[4],xx_netforce,yy_netforce,yup,ydown,y2,len2; 447c4762a1bSJed Brown PetscDraw draw; 448c4762a1bSJed Brown Vec localU; 449c4762a1bSJed Brown DM da; 450c4762a1bSJed Brown int colors[] = {PETSC_DRAW_YELLOW,PETSC_DRAW_RED,PETSC_DRAW_BLUE,PETSC_DRAW_PLUM,PETSC_DRAW_BLACK}; 451c4762a1bSJed Brown /* 452c4762a1bSJed Brown const char *const legend[3][3] = {{"-kappa (\\grad u,\\grad u)","(1 - u^2)^2"},{"-kappa (\\grad u,\\grad u)","(1 - u^2)"},{"-kappa (\\grad u,\\grad u)","logarithmic"}}; 453c4762a1bSJed Brown */ 454c4762a1bSJed Brown PetscDrawAxis axis; 455c4762a1bSJed Brown PetscDrawViewPorts *ports; 456c4762a1bSJed Brown PetscReal tol = ctx->tol, theta=ctx->theta,theta_c=ctx->theta_c,a,b; /* a and b are used in the cubic truncation of the log function */ 457c4762a1bSJed Brown PetscReal vbounds[] = {-1.1,1.1}; 458c4762a1bSJed Brown 459c4762a1bSJed Brown PetscFunctionBegin; 4605f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerDrawSetBounds(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),1,vbounds)); 4615f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerDrawResize(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),800,600)); 4625f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetDM(ts,&da)); 4635f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLocalVector(da,&localU)); 464*b122ec5aSJacob Faibussowitsch CHKERRQ(DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, 465*b122ec5aSJacob Faibussowitsch PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE)); 4665f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL)); 467c4762a1bSJed Brown hx = 1.0/(PetscReal)Mx; sx = 1.0/(hx*hx); 4685f80ce2aSJacob Faibussowitsch CHKERRQ(DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU)); 4695f80ce2aSJacob Faibussowitsch CHKERRQ(DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU)); 4705f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecGetArrayRead(da,localU,&u)); 471c4762a1bSJed Brown 4725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerDrawGetDrawLG(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),1,&lg)); 4735f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGGetDraw(lg,&draw)); 4745f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawCheckResizedWindow(draw)); 475c4762a1bSJed Brown if (!ctx->ports) { 4765f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawViewPortsCreateRect(draw,1,3,&ctx->ports)); 477c4762a1bSJed Brown } 478c4762a1bSJed Brown ports = ctx->ports; 4795f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGGetAxis(lg,&axis)); 4805f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGReset(lg)); 481c4762a1bSJed Brown 482c4762a1bSJed Brown xx[0] = 0.0; xx[1] = 1.0; cnt = 2; 4835f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetRealArray(NULL,NULL,"-zoom",xx,&cnt,NULL)); 484c4762a1bSJed Brown xs = xx[0]/hx; xm = (xx[1] - xx[0])/hx; 485c4762a1bSJed Brown 486c4762a1bSJed Brown /* 487c4762a1bSJed Brown Plot the energies 488c4762a1bSJed Brown */ 4895f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetDimension(lg,1 + (ctx->cahnhillard ? 1 : 0) + (ctx->energy == 3))); 4905f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetColors(lg,colors+1)); 4915f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawViewPortsSet(ports,2)); 492c4762a1bSJed Brown x = hx*xs; 493c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 494c4762a1bSJed Brown xx[0] = xx[1] = xx[2] = x; 495c4762a1bSJed Brown if (ctx->degenerate) yy[0] = PetscRealPart(.25*(1. - u[i]*u[i])*ctx->kappa*(u[i-1] - u[i+1])*(u[i-1] - u[i+1])*sx); 496c4762a1bSJed Brown else yy[0] = PetscRealPart(.25*ctx->kappa*(u[i-1] - u[i+1])*(u[i-1] - u[i+1])*sx); 497c4762a1bSJed Brown 498c4762a1bSJed Brown if (ctx->cahnhillard) { 499c4762a1bSJed Brown switch (ctx->energy) { 500c4762a1bSJed Brown case 1: /* double well */ 501c4762a1bSJed Brown yy[1] = .25*PetscRealPart((1. - u[i]*u[i])*(1. - u[i]*u[i])); 502c4762a1bSJed Brown break; 503c4762a1bSJed Brown case 2: /* double obstacle */ 504c4762a1bSJed Brown yy[1] = .5*PetscRealPart(1. - u[i]*u[i]); 505c4762a1bSJed Brown break; 506c4762a1bSJed Brown case 3: /* logarithm + double well */ 507c4762a1bSJed Brown yy[1] = .25*PetscRealPart((1. - u[i]*u[i])*(1. - u[i]*u[i])); 508c4762a1bSJed Brown if (PetscRealPart(u[i]) < -1.0 + 2.0*tol) yy[2] = .5*theta*(2.0*tol*PetscLogReal(tol) + PetscRealPart(1.0-u[i])*PetscLogReal(PetscRealPart(1.-u[i])/2.0)); 509c4762a1bSJed Brown else if (PetscRealPart(u[i]) > 1.0 - 2.0*tol) yy[2] = .5*theta*(PetscRealPart(1.0+u[i])*PetscLogReal(PetscRealPart(1.0+u[i])/2.0) + 2.0*tol*PetscLogReal(tol)); 510c4762a1bSJed Brown else yy[2] = .5*theta*(PetscRealPart(1.0+u[i])*PetscLogReal(PetscRealPart(1.0+u[i])/2.0) + PetscRealPart(1.0-u[i])*PetscLogReal(PetscRealPart(1.0-u[i])/2.0)); 511c4762a1bSJed Brown break; 512c4762a1bSJed Brown case 4: /* logarithm + double obstacle */ 513c4762a1bSJed Brown yy[1] = .5*theta_c*PetscRealPart(1.0-u[i]*u[i]); 514c4762a1bSJed Brown if (PetscRealPart(u[i]) < -1.0 + 2.0*tol) yy[2] = .5*theta*(2.0*tol*PetscLogReal(tol) + PetscRealPart(1.0-u[i])*PetscLogReal(PetscRealPart(1.-u[i])/2.0)); 515c4762a1bSJed Brown else if (PetscRealPart(u[i]) > 1.0 - 2.0*tol) yy[2] = .5*theta*(PetscRealPart(1.0+u[i])*PetscLogReal(PetscRealPart(1.0+u[i])/2.0) + 2.0*tol*PetscLogReal(tol)); 516c4762a1bSJed Brown else yy[2] = .5*theta*(PetscRealPart(1.0+u[i])*PetscLogReal(PetscRealPart(1.0+u[i])/2.0) + PetscRealPart(1.0-u[i])*PetscLogReal(PetscRealPart(1.0-u[i])/2.0)); 517c4762a1bSJed Brown break; 518c4762a1bSJed Brown default: 519c4762a1bSJed Brown SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"It will always be one of the values"); 520c4762a1bSJed Brown } 521c4762a1bSJed Brown } 5225f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGAddPoint(lg,xx,yy)); 523c4762a1bSJed Brown x += hx; 524c4762a1bSJed Brown } 5255f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawGetPause(draw,&pause)); 5265f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawSetPause(draw,0.0)); 5275f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawAxisSetLabels(axis,"Energy","","")); 5285f80ce2aSJacob Faibussowitsch /* CHKERRQ(PetscDrawLGSetLegend(lg,legend[ctx->energy-1])); */ 5295f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGDraw(lg)); 530c4762a1bSJed Brown 531c4762a1bSJed Brown /* 532c4762a1bSJed Brown Plot the forces 533c4762a1bSJed Brown */ 5345f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetDimension(lg,0 + (ctx->cahnhillard ? 2 : 0) + (ctx->energy == 3))); 5355f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetColors(lg,colors+1)); 5365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawViewPortsSet(ports,1)); 5375f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGReset(lg)); 538c4762a1bSJed Brown x = xs*hx; 539c4762a1bSJed Brown max = 0.; 540c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 541c4762a1bSJed Brown xx[0] = xx[1] = xx[2] = xx[3] = x; 542c4762a1bSJed Brown xx_netforce = x; 543c4762a1bSJed Brown if (ctx->degenerate) { 544c4762a1bSJed Brown c = (1. - u[i]*u[i])*(u[i-1] + u[i+1] - 2.0*u[i])*sx; 545c4762a1bSJed Brown r = (1. - u[i+1]*u[i+1])*(u[i] + u[i+2] - 2.0*u[i+1])*sx; 546c4762a1bSJed Brown l = (1. - u[i-1]*u[i-1])*(u[i-2] + u[i] - 2.0*u[i-1])*sx; 547c4762a1bSJed Brown } else { 548c4762a1bSJed Brown c = (u[i-1] + u[i+1] - 2.0*u[i])*sx; 549c4762a1bSJed Brown r = (u[i] + u[i+2] - 2.0*u[i+1])*sx; 550c4762a1bSJed Brown l = (u[i-2] + u[i] - 2.0*u[i-1])*sx; 551c4762a1bSJed Brown } 552c4762a1bSJed Brown yy[0] = PetscRealPart(-ctx->kappa*(l + r - 2.0*c)*sx); 553c4762a1bSJed Brown yy_netforce = yy[0]; 554c4762a1bSJed Brown max = PetscMax(max,PetscAbs(yy[0])); 555c4762a1bSJed Brown if (ctx->cahnhillard) { 556c4762a1bSJed Brown switch (ctx->energy) { 557c4762a1bSJed Brown case 1: /* double well */ 558c4762a1bSJed Brown yy[1] = PetscRealPart(6.*.25*u[i]*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (3.*u[i]*u[i] - 1.)*(u[i-1] + u[i+1] - 2.0*u[i])*sx); 559c4762a1bSJed Brown break; 560c4762a1bSJed Brown case 2: /* double obstacle */ 561c4762a1bSJed Brown yy[1] = -PetscRealPart(u[i-1] + u[i+1] - 2.0*u[i])*sx; 562c4762a1bSJed Brown break; 563c4762a1bSJed Brown case 3: /* logarithmic + double well */ 564c4762a1bSJed Brown yy[1] = PetscRealPart(6.*.25*u[i]*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (3.*u[i]*u[i] - 1.)*(u[i-1] + u[i+1] - 2.0*u[i])*sx); 565c4762a1bSJed Brown if (ctx->truncation==2) { /* quadratic */ 566c4762a1bSJed Brown if (PetscRealPart(u[i]) < -1.0 + 2.0*tol) yy[2] = (.25*theta/(tol-tol*tol))*PetscRealPart(u[i-1] + u[i+1] - 2.0*u[i])*sx; 567c4762a1bSJed Brown else if (PetscRealPart(u[i]) > 1.0 - 2.0*tol) yy[2] = (.25*theta/(tol-tol*tol))*PetscRealPart(u[i-1] + u[i+1] - 2.0*u[i])*sx; 568c4762a1bSJed Brown else yy[2] = PetscRealPart(2.0*theta*u[i]/((1.0-u[i]*u[i])*(1.0-u[i]*u[i]))*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (theta/(1.0-u[i]*u[i]))*(u[i-1] + u[i+1] - 2.0*u[i])*sx); 569c4762a1bSJed Brown } else { /* cubic */ 570c4762a1bSJed Brown a = 2.0*theta*(1.0-2.0*tol)/(16.0*tol*tol*(1.0-tol)*(1.0-tol)); 571c4762a1bSJed Brown b = theta/(4.0*tol*(1.0-tol)) - a*(1.0-2.0*tol); 572c4762a1bSJed Brown if (PetscRealPart(u[i]) < -1.0 + 2.0*tol) yy[2] = PetscRealPart(-1.0*a*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (-1.0*a*u[i] + b)*(u[i-1] + u[i+1] - 2.0*u[i])*sx); 573c4762a1bSJed Brown else if (PetscRealPart(u[i]) > 1.0 - 2.0*tol) yy[2] = PetscRealPart(1.0*a*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + ( a*u[i] + b)*(u[i-1] + u[i+1] - 2.0*u[i])*sx); 574c4762a1bSJed Brown else yy[2] = PetscRealPart(2.0*theta*u[i]/((1.0-u[i]*u[i])*(1.0-u[i]*u[i]))*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (theta/(1.0-u[i]*u[i]))*(u[i-1] + u[i+1] - 2.0*u[i])*sx); 575c4762a1bSJed Brown } 576c4762a1bSJed Brown break; 577c4762a1bSJed Brown case 4: /* logarithmic + double obstacle */ 578c4762a1bSJed Brown yy[1] = theta_c*PetscRealPart(-(u[i-1] + u[i+1] - 2.0*u[i]))*sx; 579c4762a1bSJed Brown if (ctx->truncation==2) { 580c4762a1bSJed Brown if (PetscRealPart(u[i]) < -1.0 + 2.0*tol) yy[2] = (.25*theta/(tol-tol*tol))*PetscRealPart(u[i-1] + u[i+1] - 2.0*u[i])*sx; 581c4762a1bSJed Brown else if (PetscRealPart(u[i]) > 1.0 - 2.0*tol) yy[2] = (.25*theta/(tol-tol*tol))*PetscRealPart(u[i-1] + u[i+1] - 2.0*u[i])*sx; 582c4762a1bSJed Brown else yy[2] = PetscRealPart(2.0*theta*u[i]/((1.0-u[i]*u[i])*(1.0-u[i]*u[i]))*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (theta/(1.0-u[i]*u[i]))*(u[i-1] + u[i+1] - 2.0*u[i])*sx); 583c4762a1bSJed Brown } 584c4762a1bSJed Brown else { 585c4762a1bSJed Brown a = 2.0*theta*(1.0-2.0*tol)/(16.0*tol*tol*(1.0-tol)*(1.0-tol)); 586c4762a1bSJed Brown b = theta/(4.0*tol*(1.0-tol)) - a*(1.0-2.0*tol); 587c4762a1bSJed Brown if (PetscRealPart(u[i]) < -1.0 + 2.0*tol) yy[2] = PetscRealPart(-1.0*a*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (-1.0*a*u[i] + b)*(u[i-1] + u[i+1] - 2.0*u[i])*sx); 588c4762a1bSJed Brown else if (PetscRealPart(u[i]) > 1.0 - 2.0*tol) yy[2] = PetscRealPart(1.0*a*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + ( a*u[i] + b)*(u[i-1] + u[i+1] - 2.0*u[i])*sx); 589c4762a1bSJed Brown else yy[2] = PetscRealPart(2.0*theta*u[i]/((1.0-u[i]*u[i])*(1.0-u[i]*u[i]))*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (theta/(1.0-u[i]*u[i]))*(u[i-1] + u[i+1] - 2.0*u[i])*sx); 590c4762a1bSJed Brown } 591c4762a1bSJed Brown break; 592c4762a1bSJed Brown default: 593c4762a1bSJed Brown SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"It will always be one of the values"); 594c4762a1bSJed Brown } 595c4762a1bSJed Brown if (ctx->energy < 3) { 596c4762a1bSJed Brown max = PetscMax(max,PetscAbs(yy[1])); 597c4762a1bSJed Brown yy[2] = yy[0]+yy[1]; 598c4762a1bSJed Brown yy_netforce = yy[2]; 599c4762a1bSJed Brown } else { 600c4762a1bSJed Brown max = PetscMax(max,PetscAbs(yy[1]+yy[2])); 601c4762a1bSJed Brown yy[3] = yy[0]+yy[1]+yy[2]; 602c4762a1bSJed Brown yy_netforce = yy[3]; 603c4762a1bSJed Brown } 604c4762a1bSJed Brown } 605c4762a1bSJed Brown if (ctx->netforce) { 6065f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGAddPoint(lg,&xx_netforce,&yy_netforce)); 607c4762a1bSJed Brown } else { 6085f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGAddPoint(lg,xx,yy)); 609c4762a1bSJed Brown } 610c4762a1bSJed Brown x += hx; 611c4762a1bSJed Brown /*if (max > 7200150000.0) */ 612c4762a1bSJed Brown /* printf("max very big when i = %d\n",i); */ 613c4762a1bSJed Brown } 6145f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawAxisSetLabels(axis,"Right hand side","","")); 6155f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetLegend(lg,NULL)); 6165f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGDraw(lg)); 617c4762a1bSJed Brown 618c4762a1bSJed Brown /* 619c4762a1bSJed Brown Plot the solution 620c4762a1bSJed Brown */ 6215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetDimension(lg,1)); 6225f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawViewPortsSet(ports,0)); 6235f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGReset(lg)); 624c4762a1bSJed Brown x = hx*xs; 6255f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetLimits(lg,x,x+(xm-1)*hx,-1.1,1.1)); 6265f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetColors(lg,colors)); 627c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 628c4762a1bSJed Brown xx[0] = x; 629c4762a1bSJed Brown yy[0] = PetscRealPart(u[i]); 6305f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGAddPoint(lg,xx,yy)); 631c4762a1bSJed Brown x += hx; 632c4762a1bSJed Brown } 6335f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawAxisSetLabels(axis,"Solution","","")); 6345f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGDraw(lg)); 635c4762a1bSJed Brown 636c4762a1bSJed Brown /* 637c4762a1bSJed Brown Print the forces as arrows on the solution 638c4762a1bSJed Brown */ 639c4762a1bSJed Brown x = hx*xs; 640c4762a1bSJed Brown cnt = xm/60; 641c4762a1bSJed Brown cnt = (!cnt) ? 1 : cnt; 642c4762a1bSJed Brown 643c4762a1bSJed Brown for (i=xs; i<xs+xm; i += cnt) { 644c4762a1bSJed Brown y = yup = ydown = PetscRealPart(u[i]); 645c4762a1bSJed Brown c = (u[i-1] + u[i+1] - 2.0*u[i])*sx; 646c4762a1bSJed Brown r = (u[i] + u[i+2] - 2.0*u[i+1])*sx; 647c4762a1bSJed Brown l = (u[i-2] + u[i] - 2.0*u[i-1])*sx; 648c4762a1bSJed Brown len = -.5*PetscRealPart(ctx->kappa*(l + r - 2.0*c)*sx)/max; 6495f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawArrow(draw,x,y,x,y+len,PETSC_DRAW_RED)); 650c4762a1bSJed Brown if (ctx->cahnhillard) { 651c4762a1bSJed Brown if (len < 0.) ydown += len; 652c4762a1bSJed Brown else yup += len; 653c4762a1bSJed Brown 654c4762a1bSJed Brown switch (ctx->energy) { 655c4762a1bSJed Brown case 1: /* double well */ 656c4762a1bSJed Brown len = .5*PetscRealPart(6.*.25*u[i]*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (3.*u[i]*u[i] - 1.)*(u[i-1] + u[i+1] - 2.0*u[i])*sx)/max; 657c4762a1bSJed Brown break; 658c4762a1bSJed Brown case 2: /* double obstacle */ 659c4762a1bSJed Brown len = -.5*PetscRealPart(u[i-1] + u[i+1] - 2.0*u[i])*sx/max; 660c4762a1bSJed Brown break; 661c4762a1bSJed Brown case 3: /* logarithmic + double well */ 662c4762a1bSJed Brown len = .5*PetscRealPart(6.*.25*u[i]*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (3.*u[i]*u[i] - 1.)*(u[i-1] + u[i+1] - 2.0*u[i])*sx)/max; 663c4762a1bSJed Brown if (len < 0.) ydown += len; 664c4762a1bSJed Brown else yup += len; 665c4762a1bSJed Brown 666c4762a1bSJed Brown if (ctx->truncation==2) { /* quadratic */ 667c4762a1bSJed Brown if (PetscRealPart(u[i]) < -1.0 + 2.0*tol) len2 = .5*(.25*theta/(tol-tol*tol))*PetscRealPart(u[i-1] + u[i+1] - 2.0*u[i])*sx/max; 668c4762a1bSJed Brown else if (PetscRealPart(u[i]) > 1.0 - 2.0*tol) len2 = .5*(.25*theta/(tol-tol*tol))*PetscRealPart(u[i-1] + u[i+1] - 2.0*u[i])*sx/max; 669c4762a1bSJed Brown else len2 = PetscRealPart(.5*(2.0*theta*u[i]/((1.0-u[i]*u[i])*(1.0-u[i]*u[i]))*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (theta/(1.0-u[i]*u[i]))*(u[i-1] + u[i+1] - 2.0*u[i])*sx)/max); 670c4762a1bSJed Brown } else { /* cubic */ 671c4762a1bSJed Brown a = 2.0*theta*(1.0-2.0*tol)/(16.0*tol*tol*(1.0-tol)*(1.0-tol)); 672c4762a1bSJed Brown b = theta/(4.0*tol*(1.0-tol)) - a*(1.0-2.0*tol); 673c4762a1bSJed Brown if (PetscRealPart(u[i]) < -1.0 + 2.0*tol) len2 = PetscRealPart(.5*(-1.0*a*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (-1.0*a*u[i] + b)*(u[i-1] + u[i+1] - 2.0*u[i])*sx)/max); 674c4762a1bSJed Brown else if (PetscRealPart(u[i]) > 1.0 - 2.0*tol) len2 = PetscRealPart(.5*(a*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + ( a*u[i] + b)*(u[i-1] + u[i+1] - 2.0*u[i])*sx)/max); 675c4762a1bSJed Brown else len2 = PetscRealPart(.5*(2.0*theta*u[i]/((1.0-u[i]*u[i])*(1.0-u[i]*u[i]))*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (theta/(1.0-u[i]*u[i]))*(u[i-1] + u[i+1] - 2.0*u[i])*sx)/max); 676c4762a1bSJed Brown } 677c4762a1bSJed Brown y2 = len < 0 ? ydown : yup; 6785f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawArrow(draw,x,y2,x,y2+len2,PETSC_DRAW_PLUM)); 679c4762a1bSJed Brown break; 680c4762a1bSJed Brown case 4: /* logarithmic + double obstacle */ 681c4762a1bSJed Brown len = -.5*theta_c*PetscRealPart(-(u[i-1] + u[i+1] - 2.0*u[i])*sx/max); 682c4762a1bSJed Brown if (len < 0.) ydown += len; 683c4762a1bSJed Brown else yup += len; 684c4762a1bSJed Brown 685c4762a1bSJed Brown if (ctx->truncation==2) { /* quadratic */ 686c4762a1bSJed Brown if (PetscRealPart(u[i]) < -1.0 + 2.0*tol) len2 = .5*(.25*theta/(tol-tol*tol))*PetscRealPart(u[i-1] + u[i+1] - 2.0*u[i])*sx/max; 687c4762a1bSJed Brown else if (PetscRealPart(u[i]) > 1.0 - 2.0*tol) len2 = .5*(.25*theta/(tol-tol*tol))*PetscRealPart(u[i-1] + u[i+1] - 2.0*u[i])*sx/max; 688c4762a1bSJed Brown else len2 = PetscRealPart(.5*(2.0*theta*u[i]/((1.0-u[i]*u[i])*(1.0-u[i]*u[i]))*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (theta/(1.0-u[i]*u[i]))*(u[i-1] + u[i+1] - 2.0*u[i])*sx)/max); 689c4762a1bSJed Brown } else { /* cubic */ 690c4762a1bSJed Brown a = 2.0*theta*(1.0-2.0*tol)/(16.0*tol*tol*(1.0-tol)*(1.0-tol)); 691c4762a1bSJed Brown b = theta/(4.0*tol*(1.0-tol)) - a*(1.0-2.0*tol); 692c4762a1bSJed Brown if (PetscRealPart(u[i]) < -1.0 + 2.0*tol) len2 = .5*PetscRealPart(-1.0*a*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (-1.0*a*u[i] + b)*(u[i-1] + u[i+1] - 2.0*u[i])*sx)/max; 693c4762a1bSJed Brown else if (PetscRealPart(u[i]) > 1.0 - 2.0*tol) len2 = .5*PetscRealPart(a*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + ( a*u[i] + b)*(u[i-1] + u[i+1] - 2.0*u[i])*sx)/max; 694c4762a1bSJed Brown else len2 = .5*PetscRealPart(2.0*theta*u[i]/((1.0-u[i]*u[i])*(1.0-u[i]*u[i]))*.25*(u[i+1] - u[i-1])*(u[i+1] - u[i-1])*sx + (theta/(1.0-u[i]*u[i]))*(u[i-1] + u[i+1] - 2.0*u[i])*sx)/max; 695c4762a1bSJed Brown } 696c4762a1bSJed Brown y2 = len < 0 ? ydown : yup; 6975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawArrow(draw,x,y2,x,y2+len2,PETSC_DRAW_PLUM)); 698c4762a1bSJed Brown break; 699c4762a1bSJed Brown } 7005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawArrow(draw,x,y,x,y+len,PETSC_DRAW_BLUE)); 701c4762a1bSJed Brown } 702c4762a1bSJed Brown x += cnt*hx; 703c4762a1bSJed Brown } 7045f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecRestoreArrayRead(da,localU,&x)); 7055f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreLocalVector(da,&localU)); 7065f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawStringSetSize(draw,.2,.2)); 7075f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawFlush(draw)); 7085f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawSetPause(draw,pause)); 7095f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawPause(draw)); 710c4762a1bSJed Brown PetscFunctionReturn(0); 711c4762a1bSJed Brown } 712c4762a1bSJed Brown 713c4762a1bSJed Brown PetscErrorCode MyDestroy(void **ptr) 714c4762a1bSJed Brown { 715c4762a1bSJed Brown UserCtx *ctx = *(UserCtx**)ptr; 716c4762a1bSJed Brown 717c4762a1bSJed Brown PetscFunctionBegin; 7185f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawViewPortsDestroy(ctx->ports)); 719c4762a1bSJed Brown PetscFunctionReturn(0); 720c4762a1bSJed Brown } 721c4762a1bSJed Brown 722c4762a1bSJed Brown /*TEST 723c4762a1bSJed Brown 724c4762a1bSJed Brown test: 725c4762a1bSJed Brown TODO: currently requires initial condition file generated by heat 726c4762a1bSJed Brown 727c4762a1bSJed Brown TEST*/ 728