1c4762a1bSJed Brown 2c4762a1bSJed Brown static char help[] = "Nonlinear DAE benchmark problems.\n"; 3c4762a1bSJed Brown 4c4762a1bSJed Brown /* 5c4762a1bSJed Brown Include "petscts.h" so that we can use TS solvers. Note that this 6c4762a1bSJed Brown file automatically includes: 7c4762a1bSJed Brown petscsys.h - base PETSc routines petscvec.h - vectors 8c4762a1bSJed Brown petscmat.h - matrices 9c4762a1bSJed Brown petscis.h - index sets petscksp.h - Krylov subspace methods 10c4762a1bSJed Brown petscviewer.h - viewers petscpc.h - preconditioners 11c4762a1bSJed Brown petscksp.h - linear solvers 12c4762a1bSJed Brown */ 13c4762a1bSJed Brown #include <petscts.h> 14c4762a1bSJed Brown 15c4762a1bSJed Brown typedef struct _Problem* Problem; 16c4762a1bSJed Brown struct _Problem { 17c4762a1bSJed Brown PetscErrorCode (*destroy)(Problem); 18c4762a1bSJed Brown TSIFunction function; 19c4762a1bSJed Brown TSIJacobian jacobian; 20c4762a1bSJed Brown PetscErrorCode (*solution)(PetscReal,Vec,void*); 21c4762a1bSJed Brown MPI_Comm comm; 22c4762a1bSJed Brown PetscReal final_time; 23c4762a1bSJed Brown PetscInt n; 24c4762a1bSJed Brown PetscBool hasexact; 25c4762a1bSJed Brown void *data; 26c4762a1bSJed Brown }; 27c4762a1bSJed Brown 28c4762a1bSJed Brown /* 29c4762a1bSJed Brown Stiff 3-variable system from chemical reactions, due to Robertson (1966), problem ROBER in Hairer&Wanner, ODE 2, 1996 30c4762a1bSJed Brown */ 31c4762a1bSJed Brown static PetscErrorCode RoberFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,void *ctx) 32c4762a1bSJed Brown { 33c4762a1bSJed Brown PetscScalar *f; 34c4762a1bSJed Brown const PetscScalar *x,*xdot; 35c4762a1bSJed Brown 36c4762a1bSJed Brown PetscFunctionBeginUser; 37*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(X,&x)); 38*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(Xdot,&xdot)); 39*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(F,&f)); 40c4762a1bSJed Brown f[0] = xdot[0] + 0.04*x[0] - 1e4*x[1]*x[2]; 41c4762a1bSJed Brown f[1] = xdot[1] - 0.04*x[0] + 1e4*x[1]*x[2] + 3e7*PetscSqr(x[1]); 42c4762a1bSJed Brown f[2] = xdot[2] - 3e7*PetscSqr(x[1]); 43*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(X,&x)); 44*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(Xdot,&xdot)); 45*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(F,&f)); 46c4762a1bSJed Brown PetscFunctionReturn(0); 47c4762a1bSJed Brown } 48c4762a1bSJed Brown 49c4762a1bSJed Brown static PetscErrorCode RoberJacobian(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal a,Mat A,Mat B,void *ctx) 50c4762a1bSJed Brown { 51c4762a1bSJed Brown PetscInt rowcol[] = {0,1,2}; 52c4762a1bSJed Brown PetscScalar J[3][3]; 53c4762a1bSJed Brown const PetscScalar *x,*xdot; 54c4762a1bSJed Brown 55c4762a1bSJed Brown PetscFunctionBeginUser; 56*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(X,&x)); 57*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(Xdot,&xdot)); 58c4762a1bSJed Brown J[0][0] = a + 0.04; J[0][1] = -1e4*x[2]; J[0][2] = -1e4*x[1]; 59c4762a1bSJed Brown J[1][0] = -0.04; J[1][1] = a + 1e4*x[2] + 3e7*2*x[1]; J[1][2] = 1e4*x[1]; 60c4762a1bSJed Brown J[2][0] = 0; J[2][1] = -3e7*2*x[1]; J[2][2] = a; 61*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(B,3,rowcol,3,rowcol,&J[0][0],INSERT_VALUES)); 62*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(X,&x)); 63*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(Xdot,&xdot)); 64c4762a1bSJed Brown 65*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 66*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 67c4762a1bSJed Brown if (A != B) { 68*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 69*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 70c4762a1bSJed Brown } 71c4762a1bSJed Brown PetscFunctionReturn(0); 72c4762a1bSJed Brown } 73c4762a1bSJed Brown 74c4762a1bSJed Brown static PetscErrorCode RoberSolution(PetscReal t,Vec X,void *ctx) 75c4762a1bSJed Brown { 76c4762a1bSJed Brown PetscScalar *x; 77c4762a1bSJed Brown 78c4762a1bSJed Brown PetscFunctionBeginUser; 793c633725SBarry Smith PetscCheck(t == 0,PETSC_COMM_WORLD,PETSC_ERR_SUP,"not implemented"); 80*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(X,&x)); 81c4762a1bSJed Brown x[0] = 1; 82c4762a1bSJed Brown x[1] = 0; 83c4762a1bSJed Brown x[2] = 0; 84*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(X,&x)); 85c4762a1bSJed Brown PetscFunctionReturn(0); 86c4762a1bSJed Brown } 87c4762a1bSJed Brown 88c4762a1bSJed Brown static PetscErrorCode RoberCreate(Problem p) 89c4762a1bSJed Brown { 90c4762a1bSJed Brown PetscFunctionBeginUser; 91c4762a1bSJed Brown p->destroy = 0; 92c4762a1bSJed Brown p->function = &RoberFunction; 93c4762a1bSJed Brown p->jacobian = &RoberJacobian; 94c4762a1bSJed Brown p->solution = &RoberSolution; 95c4762a1bSJed Brown p->final_time = 1e11; 96c4762a1bSJed Brown p->n = 3; 97c4762a1bSJed Brown PetscFunctionReturn(0); 98c4762a1bSJed Brown } 99c4762a1bSJed Brown 100c4762a1bSJed Brown /* 101c4762a1bSJed Brown Stiff scalar valued problem 102c4762a1bSJed Brown */ 103c4762a1bSJed Brown 104c4762a1bSJed Brown typedef struct { 105c4762a1bSJed Brown PetscReal lambda; 106c4762a1bSJed Brown } CECtx; 107c4762a1bSJed Brown 108c4762a1bSJed Brown static PetscErrorCode CEDestroy(Problem p) 109c4762a1bSJed Brown { 110c4762a1bSJed Brown PetscFunctionBeginUser; 111*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(p->data)); 112c4762a1bSJed Brown PetscFunctionReturn(0); 113c4762a1bSJed Brown } 114c4762a1bSJed Brown 115c4762a1bSJed Brown static PetscErrorCode CEFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,void *ctx) 116c4762a1bSJed Brown { 117c4762a1bSJed Brown PetscReal l = ((CECtx*)ctx)->lambda; 118c4762a1bSJed Brown PetscScalar *f; 119c4762a1bSJed Brown const PetscScalar *x,*xdot; 120c4762a1bSJed Brown 121c4762a1bSJed Brown PetscFunctionBeginUser; 122*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(X,&x)); 123*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(Xdot,&xdot)); 124*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(F,&f)); 125c4762a1bSJed Brown f[0] = xdot[0] + l*(x[0] - PetscCosReal(t)); 126c4762a1bSJed Brown #if 0 127*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_WORLD," f(t=%g,x=%g,xdot=%g) = %g\n",(double)t,(double)x[0],(double)xdot[0],(double)f[0])); 128c4762a1bSJed Brown #endif 129*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(X,&x)); 130*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(Xdot,&xdot)); 131*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(F,&f)); 132c4762a1bSJed Brown PetscFunctionReturn(0); 133c4762a1bSJed Brown } 134c4762a1bSJed Brown 135c4762a1bSJed Brown static PetscErrorCode CEJacobian(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal a,Mat A,Mat B,void *ctx) 136c4762a1bSJed Brown { 137c4762a1bSJed Brown PetscReal l = ((CECtx*)ctx)->lambda; 138c4762a1bSJed Brown PetscInt rowcol[] = {0}; 139c4762a1bSJed Brown PetscScalar J[1][1]; 140c4762a1bSJed Brown const PetscScalar *x,*xdot; 141c4762a1bSJed Brown 142c4762a1bSJed Brown PetscFunctionBeginUser; 143*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(X,&x)); 144*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(Xdot,&xdot)); 145c4762a1bSJed Brown J[0][0] = a + l; 146*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(B,1,rowcol,1,rowcol,&J[0][0],INSERT_VALUES)); 147*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(X,&x)); 148*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(Xdot,&xdot)); 149c4762a1bSJed Brown 150*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 151*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 152c4762a1bSJed Brown if (A != B) { 153*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 154*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 155c4762a1bSJed Brown } 156c4762a1bSJed Brown PetscFunctionReturn(0); 157c4762a1bSJed Brown } 158c4762a1bSJed Brown 159c4762a1bSJed Brown static PetscErrorCode CESolution(PetscReal t,Vec X,void *ctx) 160c4762a1bSJed Brown { 161c4762a1bSJed Brown PetscReal l = ((CECtx*)ctx)->lambda; 162c4762a1bSJed Brown PetscScalar *x; 163c4762a1bSJed Brown 164c4762a1bSJed Brown PetscFunctionBeginUser; 165*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(X,&x)); 166c4762a1bSJed Brown x[0] = l/(l*l+1)*(l*PetscCosReal(t)+PetscSinReal(t)) - l*l/(l*l+1)*PetscExpReal(-l*t); 167*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(X,&x)); 168c4762a1bSJed Brown PetscFunctionReturn(0); 169c4762a1bSJed Brown } 170c4762a1bSJed Brown 171c4762a1bSJed Brown static PetscErrorCode CECreate(Problem p) 172c4762a1bSJed Brown { 173c4762a1bSJed Brown PetscErrorCode ierr; 174c4762a1bSJed Brown CECtx *ce; 175c4762a1bSJed Brown 176c4762a1bSJed Brown PetscFunctionBeginUser; 177*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc(sizeof(CECtx),&ce)); 178c4762a1bSJed Brown p->data = (void*)ce; 179c4762a1bSJed Brown 180c4762a1bSJed Brown p->destroy = &CEDestroy; 181c4762a1bSJed Brown p->function = &CEFunction; 182c4762a1bSJed Brown p->jacobian = &CEJacobian; 183c4762a1bSJed Brown p->solution = &CESolution; 184c4762a1bSJed Brown p->final_time = 10; 185c4762a1bSJed Brown p->n = 1; 186c4762a1bSJed Brown p->hasexact = PETSC_TRUE; 187c4762a1bSJed Brown 188c4762a1bSJed Brown ce->lambda = 10; 189c4762a1bSJed Brown ierr = PetscOptionsBegin(p->comm,NULL,"CE options","");CHKERRQ(ierr); 190c4762a1bSJed Brown { 191*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsReal("-problem_ce_lambda","Parameter controlling stiffness: xdot + lambda*(x - cos(t))","",ce->lambda,&ce->lambda,NULL)); 192c4762a1bSJed Brown } 193c4762a1bSJed Brown ierr = PetscOptionsEnd();CHKERRQ(ierr); 194c4762a1bSJed Brown PetscFunctionReturn(0); 195c4762a1bSJed Brown } 196c4762a1bSJed Brown 197c4762a1bSJed Brown /* 1980e3d61c9SBarry Smith Stiff 3-variable oscillatory system from chemical reactions. problem OREGO in Hairer&Wanner 199c4762a1bSJed Brown */ 200c4762a1bSJed Brown static PetscErrorCode OregoFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,void *ctx) 201c4762a1bSJed Brown { 202c4762a1bSJed Brown PetscScalar *f; 203c4762a1bSJed Brown const PetscScalar *x,*xdot; 204c4762a1bSJed Brown 205c4762a1bSJed Brown PetscFunctionBeginUser; 206*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(X,&x)); 207*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(Xdot,&xdot)); 208*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(F,&f)); 209c4762a1bSJed Brown f[0] = xdot[0] - 77.27*(x[1] + x[0]*(1. - 8.375e-6*x[0] - x[1])); 210c4762a1bSJed Brown f[1] = xdot[1] - 1/77.27*(x[2] - (1. + x[0])*x[1]); 211c4762a1bSJed Brown f[2] = xdot[2] - 0.161*(x[0] - x[2]); 212*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(X,&x)); 213*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(Xdot,&xdot)); 214*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(F,&f)); 215c4762a1bSJed Brown PetscFunctionReturn(0); 216c4762a1bSJed Brown } 217c4762a1bSJed Brown 218c4762a1bSJed Brown static PetscErrorCode OregoJacobian(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal a,Mat A,Mat B,void *ctx) 219c4762a1bSJed Brown { 220c4762a1bSJed Brown PetscInt rowcol[] = {0,1,2}; 221c4762a1bSJed Brown PetscScalar J[3][3]; 222c4762a1bSJed Brown const PetscScalar *x,*xdot; 223c4762a1bSJed Brown 224c4762a1bSJed Brown PetscFunctionBeginUser; 225*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(X,&x)); 226*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(Xdot,&xdot)); 227c4762a1bSJed Brown J[0][0] = a - 77.27*((1. - 8.375e-6*x[0] - x[1]) - 8.375e-6*x[0]); 228c4762a1bSJed Brown J[0][1] = -77.27*(1. - x[0]); 229c4762a1bSJed Brown J[0][2] = 0; 230c4762a1bSJed Brown J[1][0] = 1./77.27*x[1]; 231c4762a1bSJed Brown J[1][1] = a + 1./77.27*(1. + x[0]); 232c4762a1bSJed Brown J[1][2] = -1./77.27; 233c4762a1bSJed Brown J[2][0] = -0.161; 234c4762a1bSJed Brown J[2][1] = 0; 235c4762a1bSJed Brown J[2][2] = a + 0.161; 236*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(B,3,rowcol,3,rowcol,&J[0][0],INSERT_VALUES)); 237*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(X,&x)); 238*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(Xdot,&xdot)); 239c4762a1bSJed Brown 240*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 241*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 242c4762a1bSJed Brown if (A != B) { 243*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 244*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 245c4762a1bSJed Brown } 246c4762a1bSJed Brown PetscFunctionReturn(0); 247c4762a1bSJed Brown } 248c4762a1bSJed Brown 249c4762a1bSJed Brown static PetscErrorCode OregoSolution(PetscReal t,Vec X,void *ctx) 250c4762a1bSJed Brown { 251c4762a1bSJed Brown PetscScalar *x; 252c4762a1bSJed Brown 253c4762a1bSJed Brown PetscFunctionBeginUser; 2543c633725SBarry Smith PetscCheck(t == 0,PETSC_COMM_WORLD,PETSC_ERR_SUP,"not implemented"); 255*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(X,&x)); 256c4762a1bSJed Brown x[0] = 1; 257c4762a1bSJed Brown x[1] = 2; 258c4762a1bSJed Brown x[2] = 3; 259*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(X,&x)); 260c4762a1bSJed Brown PetscFunctionReturn(0); 261c4762a1bSJed Brown } 262c4762a1bSJed Brown 263c4762a1bSJed Brown static PetscErrorCode OregoCreate(Problem p) 264c4762a1bSJed Brown { 265c4762a1bSJed Brown PetscFunctionBeginUser; 266c4762a1bSJed Brown p->destroy = 0; 267c4762a1bSJed Brown p->function = &OregoFunction; 268c4762a1bSJed Brown p->jacobian = &OregoJacobian; 269c4762a1bSJed Brown p->solution = &OregoSolution; 270c4762a1bSJed Brown p->final_time = 360; 271c4762a1bSJed Brown p->n = 3; 272c4762a1bSJed Brown PetscFunctionReturn(0); 273c4762a1bSJed Brown } 274c4762a1bSJed Brown 275c4762a1bSJed Brown /* 2760e3d61c9SBarry Smith User-defined monitor for comparing to exact solutions when possible 277c4762a1bSJed Brown */ 278c4762a1bSJed Brown typedef struct { 279c4762a1bSJed Brown MPI_Comm comm; 280c4762a1bSJed Brown Problem problem; 281c4762a1bSJed Brown Vec x; 282c4762a1bSJed Brown } MonitorCtx; 283c4762a1bSJed Brown 284c4762a1bSJed Brown static PetscErrorCode MonitorError(TS ts,PetscInt step,PetscReal t,Vec x,void *ctx) 285c4762a1bSJed Brown { 286c4762a1bSJed Brown MonitorCtx *mon = (MonitorCtx*)ctx; 287c4762a1bSJed Brown PetscReal h,nrm_x,nrm_exact,nrm_diff; 288c4762a1bSJed Brown 289c4762a1bSJed Brown PetscFunctionBeginUser; 290c4762a1bSJed Brown if (!mon->problem->solution) PetscFunctionReturn(0); 291*5f80ce2aSJacob Faibussowitsch CHKERRQ((*mon->problem->solution)(t,mon->x,mon->problem->data)); 292*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecNorm(x,NORM_2,&nrm_x)); 293*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecNorm(mon->x,NORM_2,&nrm_exact)); 294*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecAYPX(mon->x,-1,x)); 295*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecNorm(mon->x,NORM_2,&nrm_diff)); 296*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetTimeStep(ts,&h)); 297c4762a1bSJed Brown if (step < 0) { 298*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(mon->comm,"Interpolated final solution ")); 299c4762a1bSJed Brown } 300*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(mon->comm,"step %4D t=%12.8e h=% 8.2e |x|=%9.2e |x_e|=%9.2e |x-x_e|=%9.2e\n",step,(double)t,(double)h,(double)nrm_x,(double)nrm_exact,(double)nrm_diff)); 301c4762a1bSJed Brown PetscFunctionReturn(0); 302c4762a1bSJed Brown } 303c4762a1bSJed Brown 304c4762a1bSJed Brown int main(int argc,char **argv) 305c4762a1bSJed Brown { 306c4762a1bSJed Brown PetscFunctionList plist = NULL; 307c4762a1bSJed Brown char pname[256]; 308c4762a1bSJed Brown TS ts; /* nonlinear solver */ 309c4762a1bSJed Brown Vec x,r; /* solution, residual vectors */ 310c4762a1bSJed Brown Mat A; /* Jacobian matrix */ 311c4762a1bSJed Brown Problem problem; 3123d5a8a6aSBarry Smith PetscBool use_monitor = PETSC_FALSE; 3133d5a8a6aSBarry Smith PetscBool use_result = PETSC_FALSE; 314c4762a1bSJed Brown PetscInt steps,nonlinits,linits,snesfails,rejects; 315c4762a1bSJed Brown PetscReal ftime; 316c4762a1bSJed Brown MonitorCtx mon; 317c4762a1bSJed Brown PetscErrorCode ierr; 318c4762a1bSJed Brown PetscMPIInt size; 319c4762a1bSJed Brown 320c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 321c4762a1bSJed Brown Initialize program 322c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 323c4762a1bSJed Brown ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; 324*5f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Comm_size(PETSC_COMM_WORLD,&size)); 3253c633725SBarry Smith PetscCheck(size == 1,PETSC_COMM_WORLD,PETSC_ERR_WRONG_MPI_SIZE,"Only for sequential runs"); 326c4762a1bSJed Brown 327c4762a1bSJed Brown /* Register the available problems */ 328*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFunctionListAdd(&plist,"rober",&RoberCreate)); 329*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFunctionListAdd(&plist,"ce",&CECreate)); 330*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFunctionListAdd(&plist,"orego",&OregoCreate)); 331*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStrcpy(pname,"ce")); 332c4762a1bSJed Brown 333c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 334c4762a1bSJed Brown Set runtime options 335c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 336c4762a1bSJed Brown ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Timestepping benchmark options","");CHKERRQ(ierr); 337c4762a1bSJed Brown { 338*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsFList("-problem_type","Name of problem to run","",plist,pname,pname,sizeof(pname),NULL)); 339c4762a1bSJed Brown use_monitor = PETSC_FALSE; 340*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsBool("-monitor_error","Display errors relative to exact solutions","",use_monitor,&use_monitor,NULL)); 341*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsBool("-monitor_result","Display result","",use_result,&use_result,NULL)); 342c4762a1bSJed Brown } 343c4762a1bSJed Brown ierr = PetscOptionsEnd();CHKERRQ(ierr); 344c4762a1bSJed Brown 345c4762a1bSJed Brown /* Create the new problem */ 346*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNew(&problem)); 347c4762a1bSJed Brown problem->comm = MPI_COMM_WORLD; 348c4762a1bSJed Brown { 349c4762a1bSJed Brown PetscErrorCode (*pcreate)(Problem); 350c4762a1bSJed Brown 351*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFunctionListFind(plist,pname,&pcreate)); 3523c633725SBarry Smith PetscCheck(pcreate,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"No problem '%s'",pname); 353*5f80ce2aSJacob Faibussowitsch CHKERRQ((*pcreate)(problem)); 354c4762a1bSJed Brown } 355c4762a1bSJed Brown 356c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 357c4762a1bSJed Brown Create necessary matrix and vectors 358c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 359*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(PETSC_COMM_WORLD,&A)); 360*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(A,problem->n,problem->n,PETSC_DETERMINE,PETSC_DETERMINE)); 361*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetFromOptions(A)); 362*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetUp(A)); 363c4762a1bSJed Brown 364*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateVecs(A,&x,NULL)); 365*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(x,&r)); 366c4762a1bSJed Brown 367c4762a1bSJed Brown mon.comm = PETSC_COMM_WORLD; 368c4762a1bSJed Brown mon.problem = problem; 369*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(x,&mon.x)); 370c4762a1bSJed Brown 371c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 372c4762a1bSJed Brown Create timestepping solver context 373c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 374*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSCreate(PETSC_COMM_WORLD,&ts)); 375*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetProblemType(ts,TS_NONLINEAR)); 376*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetType(ts,TSROSW)); /* Rosenbrock-W */ 377*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetIFunction(ts,NULL,problem->function,problem->data)); 378*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetIJacobian(ts,A,A,problem->jacobian,problem->data)); 379*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetMaxTime(ts,problem->final_time)); 380*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER)); 381*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetMaxStepRejections(ts,10)); 382*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetMaxSNESFailures(ts,-1)); /* unlimited */ 383c4762a1bSJed Brown if (use_monitor) { 384*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSMonitorSet(ts,&MonitorError,&mon,NULL)); 385c4762a1bSJed Brown } 386c4762a1bSJed Brown 387c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 388c4762a1bSJed Brown Set initial conditions 389c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 390*5f80ce2aSJacob Faibussowitsch CHKERRQ((*problem->solution)(0,x,problem->data)); 391*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetTimeStep(ts,.001)); 392*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetSolution(ts,x)); 393c4762a1bSJed Brown 394c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 395c4762a1bSJed Brown Set runtime options 396c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 397*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetFromOptions(ts)); 398c4762a1bSJed Brown 399c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 400c4762a1bSJed Brown Solve nonlinear system 401c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 402*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSolve(ts,x)); 403*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetSolveTime(ts,&ftime)); 404*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetStepNumber(ts,&steps)); 405*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetSNESFailures(ts,&snesfails)); 406*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetStepRejections(ts,&rejects)); 407*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetSNESIterations(ts,&nonlinits)); 408*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetKSPIterations(ts,&linits)); 4093d5a8a6aSBarry Smith if (use_result) { 410*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"steps %D (%D rejected, %D SNES fails), ftime %g, nonlinits %D, linits %D\n",steps,rejects,snesfails,(double)ftime,nonlinits,linits)); 4113d5a8a6aSBarry Smith } 412c4762a1bSJed Brown 413c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 414c4762a1bSJed Brown Free work space. All PETSc objects should be destroyed when they 415c4762a1bSJed Brown are no longer needed. 416c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 417*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&A)); 418*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&x)); 419*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&r)); 420*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&mon.x)); 421*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSDestroy(&ts)); 422c4762a1bSJed Brown if (problem->destroy) { 423*5f80ce2aSJacob Faibussowitsch CHKERRQ((*problem->destroy)(problem)); 424c4762a1bSJed Brown } 425*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(problem)); 426*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFunctionListDestroy(&plist)); 427c4762a1bSJed Brown 428c4762a1bSJed Brown ierr = PetscFinalize(); 429c4762a1bSJed Brown return ierr; 430c4762a1bSJed Brown } 431c4762a1bSJed Brown 432c4762a1bSJed Brown /*TEST 433c4762a1bSJed Brown 434c4762a1bSJed Brown test: 435c4762a1bSJed Brown requires: !complex 4363d5a8a6aSBarry Smith args: -monitor_result -monitor_error -ts_atol 1e-2 -ts_rtol 1e-2 -ts_exact_final_time interpolate -ts_type arkimex 437c4762a1bSJed Brown 438c4762a1bSJed Brown test: 439c4762a1bSJed Brown suffix: 2 440c4762a1bSJed Brown requires: !single !complex 4413d5a8a6aSBarry Smith args: -monitor_result -ts_atol 1e-2 -ts_rtol 1e-2 -ts_max_time 15 -ts_type arkimex -ts_arkimex_type 2e -problem_type orego -ts_arkimex_initial_guess_extrapolate 0 -ts_adapt_time_step_increase_delay 4 442c4762a1bSJed Brown 443c4762a1bSJed Brown test: 444c4762a1bSJed Brown suffix: 3 445c4762a1bSJed Brown requires: !single !complex 4463d5a8a6aSBarry Smith args: -monitor_result -ts_atol 1e-2 -ts_rtol 1e-2 -ts_max_time 15 -ts_type arkimex -ts_arkimex_type 2e -problem_type orego -ts_arkimex_initial_guess_extrapolate 1 4473d5a8a6aSBarry Smith 4483d5a8a6aSBarry Smith test: 4493d5a8a6aSBarry Smith suffix: 4 4503d5a8a6aSBarry Smith 4513d5a8a6aSBarry Smith test: 4523d5a8a6aSBarry Smith suffix: 5 4533d5a8a6aSBarry Smith args: -snes_lag_jacobian 20 -snes_lag_jacobian_persists 454c4762a1bSJed Brown 455c4762a1bSJed Brown TEST*/ 456