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 PetscErrorCode ierr; 62c4762a1bSJed Brown DM da; 63c4762a1bSJed Brown PetscReal dt; 64c4762a1bSJed Brown PetscBool mymonitor; 65c4762a1bSJed Brown UserCtx ctx; 66c4762a1bSJed Brown 67c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 68c4762a1bSJed Brown Initialize program 69c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 70c4762a1bSJed Brown ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; 71c4762a1bSJed Brown ctx.kappa = 1.0; 72*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetReal(NULL,NULL,"-kappa",&ctx.kappa,NULL)); 73c4762a1bSJed Brown ctx.degenerate = PETSC_FALSE; 74*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-degenerate",&ctx.degenerate,NULL)); 75c4762a1bSJed Brown ctx.cahnhillard = PETSC_FALSE; 76*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-cahn-hillard",&ctx.cahnhillard,NULL)); 77c4762a1bSJed Brown ctx.netforce = PETSC_FALSE; 78*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-netforce",&ctx.netforce,NULL)); 79c4762a1bSJed Brown ctx.energy = 1; 80*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-energy",&ctx.energy,NULL)); 81c4762a1bSJed Brown ctx.tol = 1.0e-8; 82*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetReal(NULL,NULL,"-tol",&ctx.tol,NULL)); 83c4762a1bSJed Brown ctx.theta = .001; 84c4762a1bSJed Brown ctx.theta_c = 1.0; 85*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetReal(NULL,NULL,"-theta",&ctx.theta,NULL)); 86*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetReal(NULL,NULL,"-theta_c",&ctx.theta_c,NULL)); 87c4762a1bSJed Brown ctx.truncation = 1; 88*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-truncation",&ctx.truncation,NULL)); 89*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsHasName(NULL,NULL,"-mymonitor",&mymonitor)); 90c4762a1bSJed Brown 91c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 92c4762a1bSJed Brown Create distributed array (DMDA) to manage parallel grid and vectors 93c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 94*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_PERIODIC, 10,1,2,NULL,&da)); 95*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetFromOptions(da)); 96*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetUp(da)); 97*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDASetFieldName(da,0,"Biharmonic heat equation: u")); 98*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAGetInfo(da,0,&Mx,0,0,0,0,0,0,0,0,0,0,0)); 99c4762a1bSJed Brown dt = 1.0/(10.*ctx.kappa*Mx*Mx*Mx*Mx); 100c4762a1bSJed Brown 101c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 102c4762a1bSJed Brown Extract global vectors from DMDA; then duplicate for remaining 103c4762a1bSJed Brown vectors that are the same types 104c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 105*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMCreateGlobalVector(da,&x)); 106*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(x,&r)); 107c4762a1bSJed Brown 108c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 109c4762a1bSJed Brown Create timestepping solver context 110c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 111*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSCreate(PETSC_COMM_WORLD,&ts)); 112*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetDM(ts,da)); 113*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetProblemType(ts,TS_NONLINEAR)); 114*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetRHSFunction(ts,NULL,FormFunction,&ctx)); 115*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetMatType(da,MATAIJ)); 116*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMCreateMatrix(da,&J)); 117*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetRHSJacobian(ts,J,J,FormJacobian,&ctx)); 118*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetMaxTime(ts,.02)); 119*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetExactFinalTime(ts,TS_EXACTFINALTIME_INTERPOLATE)); 120c4762a1bSJed Brown 121c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 122c4762a1bSJed Brown Create matrix data structure; set Jacobian evaluation routine 123c4762a1bSJed Brown 124c4762a1bSJed Brown Set Jacobian matrix data structure and default Jacobian evaluation 125c4762a1bSJed Brown routine. User can override with: 126c4762a1bSJed Brown -snes_mf : matrix-free Newton-Krylov method with no preconditioning 127c4762a1bSJed Brown (unless user explicitly sets preconditioner) 128c4762a1bSJed Brown -snes_mf_operator : form preconditioning matrix as set by the user, 129c4762a1bSJed Brown but use matrix-free approx for Jacobian-vector 130c4762a1bSJed Brown products within Newton-Krylov method 131c4762a1bSJed Brown 132c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 133c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 134c4762a1bSJed Brown Customize nonlinear solver 135c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 136*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetType(ts,TSCN)); 137c4762a1bSJed Brown 138c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 139c4762a1bSJed Brown Set initial conditions 140c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 141*5f80ce2aSJacob Faibussowitsch CHKERRQ(FormInitialSolution(da,x)); 142*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetTimeStep(ts,dt)); 143*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetSolution(ts,x)); 144c4762a1bSJed Brown 145c4762a1bSJed Brown if (mymonitor) { 146c4762a1bSJed Brown ctx.ports = NULL; 147*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSMonitorSet(ts,MyMonitor,&ctx,MyDestroy)); 148c4762a1bSJed Brown } 149c4762a1bSJed Brown 150c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 151c4762a1bSJed Brown Set runtime options 152c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 153*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetFromOptions(ts)); 154c4762a1bSJed Brown 155c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 156c4762a1bSJed Brown Solve nonlinear system 157c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 158*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSolve(ts,x)); 159*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetStepNumber(ts,&steps)); 160*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecView(x,PETSC_VIEWER_BINARY_WORLD)); 161c4762a1bSJed Brown 162c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 163c4762a1bSJed Brown Free work space. All PETSc objects should be destroyed when they 164c4762a1bSJed Brown are no longer needed. 165c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 166*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&J)); 167*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&x)); 168*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&r)); 169*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSDestroy(&ts)); 170*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDestroy(&da)); 171c4762a1bSJed Brown 172c4762a1bSJed Brown ierr = PetscFinalize(); 173c4762a1bSJed Brown return ierr; 174c4762a1bSJed Brown } 175c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 176c4762a1bSJed Brown /* 177c4762a1bSJed Brown FormFunction - Evaluates nonlinear function, F(x). 178c4762a1bSJed Brown 179c4762a1bSJed Brown Input Parameters: 180c4762a1bSJed Brown . ts - the TS context 181c4762a1bSJed Brown . X - input vector 182c4762a1bSJed Brown . ptr - optional user-defined context, as set by SNESSetFunction() 183c4762a1bSJed Brown 184c4762a1bSJed Brown Output Parameter: 185c4762a1bSJed Brown . F - function vector 186c4762a1bSJed Brown */ 187c4762a1bSJed Brown PetscErrorCode FormFunction(TS ts,PetscReal ftime,Vec X,Vec F,void *ptr) 188c4762a1bSJed Brown { 189c4762a1bSJed Brown DM da; 190c4762a1bSJed Brown PetscInt i,Mx,xs,xm; 191c4762a1bSJed Brown PetscReal hx,sx; 192c4762a1bSJed Brown PetscScalar *x,*f,c,r,l; 193c4762a1bSJed Brown Vec localX; 194c4762a1bSJed Brown UserCtx *ctx = (UserCtx*)ptr; 195c4762a1bSJed 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 */ 196c4762a1bSJed Brown 197c4762a1bSJed Brown PetscFunctionBegin; 198*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetDM(ts,&da)); 199*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLocalVector(da,&localX)); 200*5f80ce2aSJacob 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)); 201c4762a1bSJed Brown 202c4762a1bSJed Brown hx = 1.0/(PetscReal)Mx; sx = 1.0/(hx*hx); 203c4762a1bSJed Brown 204c4762a1bSJed Brown /* 205c4762a1bSJed Brown Scatter ghost points to local vector,using the 2-step process 206c4762a1bSJed Brown DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). 207c4762a1bSJed Brown By placing code between these two statements, computations can be 208c4762a1bSJed Brown done while messages are in transition. 209c4762a1bSJed Brown */ 210*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX)); 211*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX)); 212c4762a1bSJed Brown 213c4762a1bSJed Brown /* 214c4762a1bSJed Brown Get pointers to vector data 215c4762a1bSJed Brown */ 216*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecGetArrayRead(da,localX,&x)); 217*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecGetArray(da,F,&f)); 218c4762a1bSJed Brown 219c4762a1bSJed Brown /* 220c4762a1bSJed Brown Get local grid boundaries 221c4762a1bSJed Brown */ 222*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL)); 223c4762a1bSJed Brown 224c4762a1bSJed Brown /* 225c4762a1bSJed Brown Compute function over the locally owned part of the grid 226c4762a1bSJed Brown */ 227c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 228c4762a1bSJed Brown if (ctx->degenerate) { 229c4762a1bSJed Brown c = (1. - x[i]*x[i])*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 230c4762a1bSJed Brown r = (1. - x[i+1]*x[i+1])*(x[i] + x[i+2] - 2.0*x[i+1])*sx; 231c4762a1bSJed Brown l = (1. - x[i-1]*x[i-1])*(x[i-2] + x[i] - 2.0*x[i-1])*sx; 232c4762a1bSJed Brown } else { 233c4762a1bSJed Brown c = (x[i-1] + x[i+1] - 2.0*x[i])*sx; 234c4762a1bSJed Brown r = (x[i] + x[i+2] - 2.0*x[i+1])*sx; 235c4762a1bSJed Brown l = (x[i-2] + x[i] - 2.0*x[i-1])*sx; 236c4762a1bSJed Brown } 237c4762a1bSJed Brown f[i] = -ctx->kappa*(l + r - 2.0*c)*sx; 238c4762a1bSJed Brown if (ctx->cahnhillard) { 239c4762a1bSJed Brown switch (ctx->energy) { 240c4762a1bSJed Brown case 1: /* double well */ 241c4762a1bSJed 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; 242c4762a1bSJed Brown break; 243c4762a1bSJed Brown case 2: /* double obstacle */ 244c4762a1bSJed Brown f[i] += -(x[i-1] + x[i+1] - 2.0*x[i])*sx; 245c4762a1bSJed Brown break; 246c4762a1bSJed Brown case 3: /* logarithmic + double well */ 247c4762a1bSJed 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; 248c4762a1bSJed Brown if (ctx->truncation==2) { /* log function with approximated with a quadratic polynomial outside -1.0+2*tol, 1.0-2*tol */ 249c4762a1bSJed 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; 250c4762a1bSJed 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; 251c4762a1bSJed 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; 252c4762a1bSJed Brown } else { /* log function is approximated with a cubic polynomial outside -1.0+2*tol, 1.0-2*tol */ 253c4762a1bSJed Brown a = 2.0*theta*(1.0-2.0*tol)/(16.0*tol*tol*(1.0-tol)*(1.0-tol)); 254c4762a1bSJed Brown b = theta/(4.0*tol*(1.0-tol)) - a*(1.0-2.0*tol); 255c4762a1bSJed 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; 256c4762a1bSJed 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; 257c4762a1bSJed 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; 258c4762a1bSJed Brown } 259c4762a1bSJed Brown break; 260c4762a1bSJed Brown case 4: /* logarithmic + double obstacle */ 261c4762a1bSJed Brown f[i] += -theta_c*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 262c4762a1bSJed Brown if (ctx->truncation==2) { /* quadratic */ 263c4762a1bSJed 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; 264c4762a1bSJed 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; 265c4762a1bSJed 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; 266c4762a1bSJed Brown } else { /* cubic */ 267c4762a1bSJed Brown a = 2.0*theta*(1.0-2.0*tol)/(16.0*tol*tol*(1.0-tol)*(1.0-tol)); 268c4762a1bSJed Brown b = theta/(4.0*tol*(1.0-tol)) - a*(1.0-2.0*tol); 269c4762a1bSJed 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; 270c4762a1bSJed 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; 271c4762a1bSJed 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; 272c4762a1bSJed Brown } 273c4762a1bSJed Brown break; 274c4762a1bSJed Brown } 275c4762a1bSJed Brown } 276c4762a1bSJed Brown 277c4762a1bSJed Brown } 278c4762a1bSJed Brown 279c4762a1bSJed Brown /* 280c4762a1bSJed Brown Restore vectors 281c4762a1bSJed Brown */ 282*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecRestoreArrayRead(da,localX,&x)); 283*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecRestoreArray(da,F,&f)); 284*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreLocalVector(da,&localX)); 285c4762a1bSJed Brown PetscFunctionReturn(0); 286c4762a1bSJed Brown } 287c4762a1bSJed Brown 288c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 289c4762a1bSJed Brown /* 290c4762a1bSJed Brown FormJacobian - Evaluates nonlinear function's Jacobian 291c4762a1bSJed Brown 292c4762a1bSJed Brown */ 293c4762a1bSJed Brown PetscErrorCode FormJacobian(TS ts,PetscReal ftime,Vec X,Mat A,Mat B,void *ptr) 294c4762a1bSJed Brown { 295c4762a1bSJed Brown DM da; 296c4762a1bSJed Brown PetscInt i,Mx,xs,xm; 297c4762a1bSJed Brown MatStencil row,cols[5]; 298c4762a1bSJed Brown PetscReal hx,sx; 299c4762a1bSJed Brown PetscScalar *x,vals[5]; 300c4762a1bSJed Brown Vec localX; 301c4762a1bSJed Brown UserCtx *ctx = (UserCtx*)ptr; 302c4762a1bSJed Brown 303c4762a1bSJed Brown PetscFunctionBegin; 304*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetDM(ts,&da)); 305*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLocalVector(da,&localX)); 306*5f80ce2aSJacob 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)); 307c4762a1bSJed Brown 308c4762a1bSJed Brown hx = 1.0/(PetscReal)Mx; sx = 1.0/(hx*hx); 309c4762a1bSJed Brown 310c4762a1bSJed Brown /* 311c4762a1bSJed Brown Scatter ghost points to local vector,using the 2-step process 312c4762a1bSJed Brown DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). 313c4762a1bSJed Brown By placing code between these two statements, computations can be 314c4762a1bSJed Brown done while messages are in transition. 315c4762a1bSJed Brown */ 316*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX)); 317*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX)); 318c4762a1bSJed Brown 319c4762a1bSJed Brown /* 320c4762a1bSJed Brown Get pointers to vector data 321c4762a1bSJed Brown */ 322*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecGetArrayRead(da,localX,&x)); 323c4762a1bSJed Brown 324c4762a1bSJed Brown /* 325c4762a1bSJed Brown Get local grid boundaries 326c4762a1bSJed Brown */ 327*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL)); 328c4762a1bSJed Brown 329c4762a1bSJed Brown /* 330c4762a1bSJed Brown Compute function over the locally owned part of the grid 331c4762a1bSJed Brown */ 332c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 333c4762a1bSJed Brown row.i = i; 334c4762a1bSJed Brown if (ctx->degenerate) { 335c4762a1bSJed Brown /*PetscScalar c,r,l; 336c4762a1bSJed Brown c = (1. - x[i]*x[i])*(x[i-1] + x[i+1] - 2.0*x[i])*sx; 337c4762a1bSJed Brown r = (1. - x[i+1]*x[i+1])*(x[i] + x[i+2] - 2.0*x[i+1])*sx; 338c4762a1bSJed Brown l = (1. - x[i-1]*x[i-1])*(x[i-2] + x[i] - 2.0*x[i-1])*sx; */ 339c4762a1bSJed Brown } else { 340c4762a1bSJed Brown cols[0].i = i - 2; vals[0] = -ctx->kappa*sx*sx; 341c4762a1bSJed Brown cols[1].i = i - 1; vals[1] = 4.0*ctx->kappa*sx*sx; 342c4762a1bSJed Brown cols[2].i = i ; vals[2] = -6.0*ctx->kappa*sx*sx; 343c4762a1bSJed Brown cols[3].i = i + 1; vals[3] = 4.0*ctx->kappa*sx*sx; 344c4762a1bSJed Brown cols[4].i = i + 2; vals[4] = -ctx->kappa*sx*sx; 345c4762a1bSJed Brown } 346*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValuesStencil(B,1,&row,5,cols,vals,INSERT_VALUES)); 347c4762a1bSJed Brown 348c4762a1bSJed Brown if (ctx->cahnhillard) { 349c4762a1bSJed Brown switch (ctx->energy) { 350c4762a1bSJed Brown case 1: /* double well */ 351c4762a1bSJed 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; */ 352c4762a1bSJed Brown break; 353c4762a1bSJed Brown case 2: /* double obstacle */ 354c4762a1bSJed Brown /* f[i] += -(x[i-1] + x[i+1] - 2.0*x[i])*sx; */ 355c4762a1bSJed Brown break; 356c4762a1bSJed Brown case 3: /* logarithmic + double well */ 357c4762a1bSJed Brown break; 358c4762a1bSJed Brown case 4: /* logarithmic + double obstacle */ 359c4762a1bSJed Brown break; 360c4762a1bSJed Brown } 361c4762a1bSJed Brown } 362c4762a1bSJed Brown 363c4762a1bSJed Brown } 364c4762a1bSJed Brown 365c4762a1bSJed Brown /* 366c4762a1bSJed Brown Restore vectors 367c4762a1bSJed Brown */ 368*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecRestoreArrayRead(da,localX,&x)); 369*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreLocalVector(da,&localX)); 370*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 371*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 372c4762a1bSJed Brown if (A != B) { 373*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 374*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 375c4762a1bSJed Brown } 376c4762a1bSJed Brown PetscFunctionReturn(0); 377c4762a1bSJed Brown } 378c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 379c4762a1bSJed Brown PetscErrorCode FormInitialSolution(DM da,Vec U) 380c4762a1bSJed Brown { 381c4762a1bSJed Brown PetscInt i,xs,xm,Mx,N,scale; 382c4762a1bSJed Brown PetscScalar *u; 383c4762a1bSJed Brown PetscReal r,hx,x; 384c4762a1bSJed Brown const PetscScalar *f; 385c4762a1bSJed Brown Vec finesolution; 386c4762a1bSJed Brown PetscViewer viewer; 387c4762a1bSJed Brown 388c4762a1bSJed Brown PetscFunctionBegin; 389*5f80ce2aSJacob 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)); 390c4762a1bSJed Brown 391c4762a1bSJed Brown hx = 1.0/(PetscReal)Mx; 392c4762a1bSJed Brown 393c4762a1bSJed Brown /* 394c4762a1bSJed Brown Get pointers to vector data 395c4762a1bSJed Brown */ 396*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecGetArray(da,U,&u)); 397c4762a1bSJed Brown 398c4762a1bSJed Brown /* 399c4762a1bSJed Brown Get local grid boundaries 400c4762a1bSJed Brown */ 401*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL)); 402c4762a1bSJed Brown 403c4762a1bSJed Brown /* 404c4762a1bSJed Brown Seee heat.c for how to generate InitialSolution.heat 405c4762a1bSJed Brown */ 406*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerBinaryOpen(PETSC_COMM_WORLD,"InitialSolution.heat",FILE_MODE_READ,&viewer)); 407*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreate(PETSC_COMM_WORLD,&finesolution)); 408*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecLoad(finesolution,viewer)); 409*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerDestroy(&viewer)); 410*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetSize(finesolution,&N)); 411c4762a1bSJed Brown scale = N/Mx; 412*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(finesolution,&f)); 413c4762a1bSJed Brown 414c4762a1bSJed Brown /* 415c4762a1bSJed Brown Compute function over the locally owned part of the grid 416c4762a1bSJed Brown */ 417c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 418c4762a1bSJed Brown x = i*hx; 419c4762a1bSJed Brown r = PetscSqrtReal((x-.5)*(x-.5)); 420c4762a1bSJed Brown if (r < .125) u[i] = 1.0; 421c4762a1bSJed Brown else u[i] = -.5; 422c4762a1bSJed Brown 423c4762a1bSJed Brown /* With the initial condition above the method is first order in space */ 424c4762a1bSJed Brown /* this is a smooth initial condition so the method becomes second order in space */ 425c4762a1bSJed Brown /*u[i] = PetscSinScalar(2*PETSC_PI*x); */ 426c4762a1bSJed Brown u[i] = f[scale*i]; 427c4762a1bSJed Brown } 428*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(finesolution,&f)); 429*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&finesolution)); 430c4762a1bSJed Brown 431c4762a1bSJed Brown /* 432c4762a1bSJed Brown Restore vectors 433c4762a1bSJed Brown */ 434*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecRestoreArray(da,U,&u)); 435c4762a1bSJed Brown PetscFunctionReturn(0); 436c4762a1bSJed Brown } 437c4762a1bSJed Brown 438c4762a1bSJed Brown /* 439c4762a1bSJed Brown This routine is not parallel 440c4762a1bSJed Brown */ 441c4762a1bSJed Brown PetscErrorCode MyMonitor(TS ts,PetscInt step,PetscReal time,Vec U,void *ptr) 442c4762a1bSJed Brown { 443c4762a1bSJed Brown UserCtx *ctx = (UserCtx*)ptr; 444c4762a1bSJed Brown PetscDrawLG lg; 445c4762a1bSJed Brown PetscErrorCode ierr; 446c4762a1bSJed Brown PetscScalar *u,l,r,c; 447c4762a1bSJed Brown PetscInt Mx,i,xs,xm,cnt; 448c4762a1bSJed Brown PetscReal x,y,hx,pause,sx,len,max,xx[4],yy[4],xx_netforce,yy_netforce,yup,ydown,y2,len2; 449c4762a1bSJed Brown PetscDraw draw; 450c4762a1bSJed Brown Vec localU; 451c4762a1bSJed Brown DM da; 452c4762a1bSJed Brown int colors[] = {PETSC_DRAW_YELLOW,PETSC_DRAW_RED,PETSC_DRAW_BLUE,PETSC_DRAW_PLUM,PETSC_DRAW_BLACK}; 453c4762a1bSJed Brown /* 454c4762a1bSJed 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"}}; 455c4762a1bSJed Brown */ 456c4762a1bSJed Brown PetscDrawAxis axis; 457c4762a1bSJed Brown PetscDrawViewPorts *ports; 458c4762a1bSJed 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 */ 459c4762a1bSJed Brown PetscReal vbounds[] = {-1.1,1.1}; 460c4762a1bSJed Brown 461c4762a1bSJed Brown PetscFunctionBegin; 462*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerDrawSetBounds(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),1,vbounds)); 463*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerDrawResize(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),800,600)); 464*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetDM(ts,&da)); 465*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLocalVector(da,&localU)); 466c4762a1bSJed Brown ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, 467c4762a1bSJed Brown PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); 468*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL)); 469c4762a1bSJed Brown hx = 1.0/(PetscReal)Mx; sx = 1.0/(hx*hx); 470*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU)); 471*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU)); 472*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecGetArrayRead(da,localU,&u)); 473c4762a1bSJed Brown 474*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerDrawGetDrawLG(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),1,&lg)); 475*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGGetDraw(lg,&draw)); 476*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawCheckResizedWindow(draw)); 477c4762a1bSJed Brown if (!ctx->ports) { 478*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawViewPortsCreateRect(draw,1,3,&ctx->ports)); 479c4762a1bSJed Brown } 480c4762a1bSJed Brown ports = ctx->ports; 481*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGGetAxis(lg,&axis)); 482*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGReset(lg)); 483c4762a1bSJed Brown 484c4762a1bSJed Brown xx[0] = 0.0; xx[1] = 1.0; cnt = 2; 485*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetRealArray(NULL,NULL,"-zoom",xx,&cnt,NULL)); 486c4762a1bSJed Brown xs = xx[0]/hx; xm = (xx[1] - xx[0])/hx; 487c4762a1bSJed Brown 488c4762a1bSJed Brown /* 489c4762a1bSJed Brown Plot the energies 490c4762a1bSJed Brown */ 491*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetDimension(lg,1 + (ctx->cahnhillard ? 1 : 0) + (ctx->energy == 3))); 492*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetColors(lg,colors+1)); 493*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawViewPortsSet(ports,2)); 494c4762a1bSJed Brown x = hx*xs; 495c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 496c4762a1bSJed Brown xx[0] = xx[1] = xx[2] = x; 497c4762a1bSJed 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); 498c4762a1bSJed Brown else yy[0] = PetscRealPart(.25*ctx->kappa*(u[i-1] - u[i+1])*(u[i-1] - u[i+1])*sx); 499c4762a1bSJed Brown 500c4762a1bSJed Brown if (ctx->cahnhillard) { 501c4762a1bSJed Brown switch (ctx->energy) { 502c4762a1bSJed Brown case 1: /* double well */ 503c4762a1bSJed Brown yy[1] = .25*PetscRealPart((1. - u[i]*u[i])*(1. - u[i]*u[i])); 504c4762a1bSJed Brown break; 505c4762a1bSJed Brown case 2: /* double obstacle */ 506c4762a1bSJed Brown yy[1] = .5*PetscRealPart(1. - u[i]*u[i]); 507c4762a1bSJed Brown break; 508c4762a1bSJed Brown case 3: /* logarithm + double well */ 509c4762a1bSJed Brown yy[1] = .25*PetscRealPart((1. - u[i]*u[i])*(1. - u[i]*u[i])); 510c4762a1bSJed 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)); 511c4762a1bSJed 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)); 512c4762a1bSJed 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)); 513c4762a1bSJed Brown break; 514c4762a1bSJed Brown case 4: /* logarithm + double obstacle */ 515c4762a1bSJed Brown yy[1] = .5*theta_c*PetscRealPart(1.0-u[i]*u[i]); 516c4762a1bSJed 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)); 517c4762a1bSJed 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)); 518c4762a1bSJed 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)); 519c4762a1bSJed Brown break; 520c4762a1bSJed Brown default: 521c4762a1bSJed Brown SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"It will always be one of the values"); 522c4762a1bSJed Brown } 523c4762a1bSJed Brown } 524*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGAddPoint(lg,xx,yy)); 525c4762a1bSJed Brown x += hx; 526c4762a1bSJed Brown } 527*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawGetPause(draw,&pause)); 528*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawSetPause(draw,0.0)); 529*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawAxisSetLabels(axis,"Energy","","")); 530*5f80ce2aSJacob Faibussowitsch /* CHKERRQ(PetscDrawLGSetLegend(lg,legend[ctx->energy-1])); */ 531*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGDraw(lg)); 532c4762a1bSJed Brown 533c4762a1bSJed Brown /* 534c4762a1bSJed Brown Plot the forces 535c4762a1bSJed Brown */ 536*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetDimension(lg,0 + (ctx->cahnhillard ? 2 : 0) + (ctx->energy == 3))); 537*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetColors(lg,colors+1)); 538*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawViewPortsSet(ports,1)); 539*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGReset(lg)); 540c4762a1bSJed Brown x = xs*hx; 541c4762a1bSJed Brown max = 0.; 542c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 543c4762a1bSJed Brown xx[0] = xx[1] = xx[2] = xx[3] = x; 544c4762a1bSJed Brown xx_netforce = x; 545c4762a1bSJed Brown if (ctx->degenerate) { 546c4762a1bSJed Brown c = (1. - u[i]*u[i])*(u[i-1] + u[i+1] - 2.0*u[i])*sx; 547c4762a1bSJed Brown r = (1. - u[i+1]*u[i+1])*(u[i] + u[i+2] - 2.0*u[i+1])*sx; 548c4762a1bSJed Brown l = (1. - u[i-1]*u[i-1])*(u[i-2] + u[i] - 2.0*u[i-1])*sx; 549c4762a1bSJed Brown } else { 550c4762a1bSJed Brown c = (u[i-1] + u[i+1] - 2.0*u[i])*sx; 551c4762a1bSJed Brown r = (u[i] + u[i+2] - 2.0*u[i+1])*sx; 552c4762a1bSJed Brown l = (u[i-2] + u[i] - 2.0*u[i-1])*sx; 553c4762a1bSJed Brown } 554c4762a1bSJed Brown yy[0] = PetscRealPart(-ctx->kappa*(l + r - 2.0*c)*sx); 555c4762a1bSJed Brown yy_netforce = yy[0]; 556c4762a1bSJed Brown max = PetscMax(max,PetscAbs(yy[0])); 557c4762a1bSJed Brown if (ctx->cahnhillard) { 558c4762a1bSJed Brown switch (ctx->energy) { 559c4762a1bSJed Brown case 1: /* double well */ 560c4762a1bSJed 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); 561c4762a1bSJed Brown break; 562c4762a1bSJed Brown case 2: /* double obstacle */ 563c4762a1bSJed Brown yy[1] = -PetscRealPart(u[i-1] + u[i+1] - 2.0*u[i])*sx; 564c4762a1bSJed Brown break; 565c4762a1bSJed Brown case 3: /* logarithmic + double well */ 566c4762a1bSJed 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); 567c4762a1bSJed Brown if (ctx->truncation==2) { /* quadratic */ 568c4762a1bSJed 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; 569c4762a1bSJed 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; 570c4762a1bSJed 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); 571c4762a1bSJed Brown } else { /* cubic */ 572c4762a1bSJed Brown a = 2.0*theta*(1.0-2.0*tol)/(16.0*tol*tol*(1.0-tol)*(1.0-tol)); 573c4762a1bSJed Brown b = theta/(4.0*tol*(1.0-tol)) - a*(1.0-2.0*tol); 574c4762a1bSJed 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); 575c4762a1bSJed 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); 576c4762a1bSJed 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); 577c4762a1bSJed Brown } 578c4762a1bSJed Brown break; 579c4762a1bSJed Brown case 4: /* logarithmic + double obstacle */ 580c4762a1bSJed Brown yy[1] = theta_c*PetscRealPart(-(u[i-1] + u[i+1] - 2.0*u[i]))*sx; 581c4762a1bSJed Brown if (ctx->truncation==2) { 582c4762a1bSJed 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; 583c4762a1bSJed 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; 584c4762a1bSJed 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); 585c4762a1bSJed Brown } 586c4762a1bSJed Brown else { 587c4762a1bSJed Brown a = 2.0*theta*(1.0-2.0*tol)/(16.0*tol*tol*(1.0-tol)*(1.0-tol)); 588c4762a1bSJed Brown b = theta/(4.0*tol*(1.0-tol)) - a*(1.0-2.0*tol); 589c4762a1bSJed 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); 590c4762a1bSJed 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); 591c4762a1bSJed 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); 592c4762a1bSJed Brown } 593c4762a1bSJed Brown break; 594c4762a1bSJed Brown default: 595c4762a1bSJed Brown SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"It will always be one of the values"); 596c4762a1bSJed Brown } 597c4762a1bSJed Brown if (ctx->energy < 3) { 598c4762a1bSJed Brown max = PetscMax(max,PetscAbs(yy[1])); 599c4762a1bSJed Brown yy[2] = yy[0]+yy[1]; 600c4762a1bSJed Brown yy_netforce = yy[2]; 601c4762a1bSJed Brown } else { 602c4762a1bSJed Brown max = PetscMax(max,PetscAbs(yy[1]+yy[2])); 603c4762a1bSJed Brown yy[3] = yy[0]+yy[1]+yy[2]; 604c4762a1bSJed Brown yy_netforce = yy[3]; 605c4762a1bSJed Brown } 606c4762a1bSJed Brown } 607c4762a1bSJed Brown if (ctx->netforce) { 608*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGAddPoint(lg,&xx_netforce,&yy_netforce)); 609c4762a1bSJed Brown } else { 610*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGAddPoint(lg,xx,yy)); 611c4762a1bSJed Brown } 612c4762a1bSJed Brown x += hx; 613c4762a1bSJed Brown /*if (max > 7200150000.0) */ 614c4762a1bSJed Brown /* printf("max very big when i = %d\n",i); */ 615c4762a1bSJed Brown } 616*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawAxisSetLabels(axis,"Right hand side","","")); 617*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetLegend(lg,NULL)); 618*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGDraw(lg)); 619c4762a1bSJed Brown 620c4762a1bSJed Brown /* 621c4762a1bSJed Brown Plot the solution 622c4762a1bSJed Brown */ 623*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetDimension(lg,1)); 624*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawViewPortsSet(ports,0)); 625*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGReset(lg)); 626c4762a1bSJed Brown x = hx*xs; 627*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetLimits(lg,x,x+(xm-1)*hx,-1.1,1.1)); 628*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGSetColors(lg,colors)); 629c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 630c4762a1bSJed Brown xx[0] = x; 631c4762a1bSJed Brown yy[0] = PetscRealPart(u[i]); 632*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGAddPoint(lg,xx,yy)); 633c4762a1bSJed Brown x += hx; 634c4762a1bSJed Brown } 635*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawAxisSetLabels(axis,"Solution","","")); 636*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawLGDraw(lg)); 637c4762a1bSJed Brown 638c4762a1bSJed Brown /* 639c4762a1bSJed Brown Print the forces as arrows on the solution 640c4762a1bSJed Brown */ 641c4762a1bSJed Brown x = hx*xs; 642c4762a1bSJed Brown cnt = xm/60; 643c4762a1bSJed Brown cnt = (!cnt) ? 1 : cnt; 644c4762a1bSJed Brown 645c4762a1bSJed Brown for (i=xs; i<xs+xm; i += cnt) { 646c4762a1bSJed Brown y = yup = ydown = PetscRealPart(u[i]); 647c4762a1bSJed Brown c = (u[i-1] + u[i+1] - 2.0*u[i])*sx; 648c4762a1bSJed Brown r = (u[i] + u[i+2] - 2.0*u[i+1])*sx; 649c4762a1bSJed Brown l = (u[i-2] + u[i] - 2.0*u[i-1])*sx; 650c4762a1bSJed Brown len = -.5*PetscRealPart(ctx->kappa*(l + r - 2.0*c)*sx)/max; 651*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawArrow(draw,x,y,x,y+len,PETSC_DRAW_RED)); 652c4762a1bSJed Brown if (ctx->cahnhillard) { 653c4762a1bSJed Brown if (len < 0.) ydown += len; 654c4762a1bSJed Brown else yup += len; 655c4762a1bSJed Brown 656c4762a1bSJed Brown switch (ctx->energy) { 657c4762a1bSJed Brown case 1: /* double well */ 658c4762a1bSJed 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; 659c4762a1bSJed Brown break; 660c4762a1bSJed Brown case 2: /* double obstacle */ 661c4762a1bSJed Brown len = -.5*PetscRealPart(u[i-1] + u[i+1] - 2.0*u[i])*sx/max; 662c4762a1bSJed Brown break; 663c4762a1bSJed Brown case 3: /* logarithmic + double well */ 664c4762a1bSJed 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; 665c4762a1bSJed Brown if (len < 0.) ydown += len; 666c4762a1bSJed Brown else yup += len; 667c4762a1bSJed Brown 668c4762a1bSJed Brown if (ctx->truncation==2) { /* quadratic */ 669c4762a1bSJed 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; 670c4762a1bSJed 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; 671c4762a1bSJed 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); 672c4762a1bSJed Brown } else { /* cubic */ 673c4762a1bSJed Brown a = 2.0*theta*(1.0-2.0*tol)/(16.0*tol*tol*(1.0-tol)*(1.0-tol)); 674c4762a1bSJed Brown b = theta/(4.0*tol*(1.0-tol)) - a*(1.0-2.0*tol); 675c4762a1bSJed 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); 676c4762a1bSJed 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); 677c4762a1bSJed 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); 678c4762a1bSJed Brown } 679c4762a1bSJed Brown y2 = len < 0 ? ydown : yup; 680*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawArrow(draw,x,y2,x,y2+len2,PETSC_DRAW_PLUM)); 681c4762a1bSJed Brown break; 682c4762a1bSJed Brown case 4: /* logarithmic + double obstacle */ 683c4762a1bSJed Brown len = -.5*theta_c*PetscRealPart(-(u[i-1] + u[i+1] - 2.0*u[i])*sx/max); 684c4762a1bSJed Brown if (len < 0.) ydown += len; 685c4762a1bSJed Brown else yup += len; 686c4762a1bSJed Brown 687c4762a1bSJed Brown if (ctx->truncation==2) { /* quadratic */ 688c4762a1bSJed 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; 689c4762a1bSJed 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; 690c4762a1bSJed 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); 691c4762a1bSJed Brown } else { /* cubic */ 692c4762a1bSJed Brown a = 2.0*theta*(1.0-2.0*tol)/(16.0*tol*tol*(1.0-tol)*(1.0-tol)); 693c4762a1bSJed Brown b = theta/(4.0*tol*(1.0-tol)) - a*(1.0-2.0*tol); 694c4762a1bSJed 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; 695c4762a1bSJed 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; 696c4762a1bSJed 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; 697c4762a1bSJed Brown } 698c4762a1bSJed Brown y2 = len < 0 ? ydown : yup; 699*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawArrow(draw,x,y2,x,y2+len2,PETSC_DRAW_PLUM)); 700c4762a1bSJed Brown break; 701c4762a1bSJed Brown } 702*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawArrow(draw,x,y,x,y+len,PETSC_DRAW_BLUE)); 703c4762a1bSJed Brown } 704c4762a1bSJed Brown x += cnt*hx; 705c4762a1bSJed Brown } 706*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecRestoreArrayRead(da,localU,&x)); 707*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreLocalVector(da,&localU)); 708*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawStringSetSize(draw,.2,.2)); 709*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawFlush(draw)); 710*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawSetPause(draw,pause)); 711*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawPause(draw)); 712c4762a1bSJed Brown PetscFunctionReturn(0); 713c4762a1bSJed Brown } 714c4762a1bSJed Brown 715c4762a1bSJed Brown PetscErrorCode MyDestroy(void **ptr) 716c4762a1bSJed Brown { 717c4762a1bSJed Brown UserCtx *ctx = *(UserCtx**)ptr; 718c4762a1bSJed Brown 719c4762a1bSJed Brown PetscFunctionBegin; 720*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawViewPortsDestroy(ctx->ports)); 721c4762a1bSJed Brown PetscFunctionReturn(0); 722c4762a1bSJed Brown } 723c4762a1bSJed Brown 724c4762a1bSJed Brown /*TEST 725c4762a1bSJed Brown 726c4762a1bSJed Brown test: 727c4762a1bSJed Brown TODO: currently requires initial condition file generated by heat 728c4762a1bSJed Brown 729c4762a1bSJed Brown TEST*/ 730