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*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X,&x)); 38*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(Xdot,&xdot)); 39*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X,&x)); 44*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(Xdot,&xdot)); 45*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X,&x)); 57*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(MatSetValues(B,3,rowcol,3,rowcol,&J[0][0],INSERT_VALUES)); 62*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X,&x)); 63*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(Xdot,&xdot)); 64c4762a1bSJed Brown 65*9566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 66*9566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 67c4762a1bSJed Brown if (A != B) { 68*9566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 69*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(VecGetArray(X,&x)); 81c4762a1bSJed Brown x[0] = 1; 82c4762a1bSJed Brown x[1] = 0; 83c4762a1bSJed Brown x[2] = 0; 84*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X,&x)); 123*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(Xdot,&xdot)); 124*9566063dSJacob Faibussowitsch PetscCall(VecGetArray(F,&f)); 125c4762a1bSJed Brown f[0] = xdot[0] + l*(x[0] - PetscCosReal(t)); 126c4762a1bSJed Brown #if 0 127*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X,&x)); 130*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(Xdot,&xdot)); 131*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X,&x)); 144*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(Xdot,&xdot)); 145c4762a1bSJed Brown J[0][0] = a + l; 146*9566063dSJacob Faibussowitsch PetscCall(MatSetValues(B,1,rowcol,1,rowcol,&J[0][0],INSERT_VALUES)); 147*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X,&x)); 148*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(Xdot,&xdot)); 149c4762a1bSJed Brown 150*9566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 151*9566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 152c4762a1bSJed Brown if (A != B) { 153*9566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 154*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(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; 189*9566063dSJacob Faibussowitsch ierr = PetscOptionsBegin(p->comm,NULL,"CE options","");PetscCall(ierr); 190c4762a1bSJed Brown { 191*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-problem_ce_lambda","Parameter controlling stiffness: xdot + lambda*(x - cos(t))","",ce->lambda,&ce->lambda,NULL)); 192c4762a1bSJed Brown } 193*9566063dSJacob Faibussowitsch ierr = PetscOptionsEnd();PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X,&x)); 207*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(Xdot,&xdot)); 208*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X,&x)); 213*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(Xdot,&xdot)); 214*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X,&x)); 226*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(MatSetValues(B,3,rowcol,3,rowcol,&J[0][0],INSERT_VALUES)); 237*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X,&x)); 238*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(Xdot,&xdot)); 239c4762a1bSJed Brown 240*9566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 241*9566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 242c4762a1bSJed Brown if (A != B) { 243*9566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 244*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(VecGetArray(X,&x)); 256c4762a1bSJed Brown x[0] = 1; 257c4762a1bSJed Brown x[1] = 2; 258c4762a1bSJed Brown x[2] = 3; 259*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall((*mon->problem->solution)(t,mon->x,mon->problem->data)); 292*9566063dSJacob Faibussowitsch PetscCall(VecNorm(x,NORM_2,&nrm_x)); 293*9566063dSJacob Faibussowitsch PetscCall(VecNorm(mon->x,NORM_2,&nrm_exact)); 294*9566063dSJacob Faibussowitsch PetscCall(VecAYPX(mon->x,-1,x)); 295*9566063dSJacob Faibussowitsch PetscCall(VecNorm(mon->x,NORM_2,&nrm_diff)); 296*9566063dSJacob Faibussowitsch PetscCall(TSGetTimeStep(ts,&h)); 297c4762a1bSJed Brown if (step < 0) { 298*9566063dSJacob Faibussowitsch PetscCall(PetscPrintf(mon->comm,"Interpolated final solution ")); 299c4762a1bSJed Brown } 300*9566063dSJacob Faibussowitsch PetscCall(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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 323*9566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc,&argv,(char*)0,help)); 324*9566063dSJacob Faibussowitsch PetscCallMPI(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*9566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&plist,"rober",&RoberCreate)); 329*9566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&plist,"ce",&CECreate)); 330*9566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&plist,"orego",&OregoCreate)); 331*9566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(pname,"ce")); 332c4762a1bSJed Brown 333c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 334c4762a1bSJed Brown Set runtime options 335c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 336*9566063dSJacob Faibussowitsch ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Timestepping benchmark options","");PetscCall(ierr); 337c4762a1bSJed Brown { 338*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-problem_type","Name of problem to run","",plist,pname,pname,sizeof(pname),NULL)); 339c4762a1bSJed Brown use_monitor = PETSC_FALSE; 340*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-monitor_error","Display errors relative to exact solutions","",use_monitor,&use_monitor,NULL)); 341*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-monitor_result","Display result","",use_result,&use_result,NULL)); 342c4762a1bSJed Brown } 343*9566063dSJacob Faibussowitsch ierr = PetscOptionsEnd();PetscCall(ierr); 344c4762a1bSJed Brown 345c4762a1bSJed Brown /* Create the new problem */ 346*9566063dSJacob Faibussowitsch PetscCall(PetscNew(&problem)); 347c4762a1bSJed Brown problem->comm = MPI_COMM_WORLD; 348c4762a1bSJed Brown { 349c4762a1bSJed Brown PetscErrorCode (*pcreate)(Problem); 350c4762a1bSJed Brown 351*9566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(plist,pname,&pcreate)); 3523c633725SBarry Smith PetscCheck(pcreate,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"No problem '%s'",pname); 353*9566063dSJacob Faibussowitsch PetscCall((*pcreate)(problem)); 354c4762a1bSJed Brown } 355c4762a1bSJed Brown 356c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 357c4762a1bSJed Brown Create necessary matrix and vectors 358c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 359*9566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD,&A)); 360*9566063dSJacob Faibussowitsch PetscCall(MatSetSizes(A,problem->n,problem->n,PETSC_DETERMINE,PETSC_DETERMINE)); 361*9566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(A)); 362*9566063dSJacob Faibussowitsch PetscCall(MatSetUp(A)); 363c4762a1bSJed Brown 364*9566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A,&x,NULL)); 365*9566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x,&r)); 366c4762a1bSJed Brown 367c4762a1bSJed Brown mon.comm = PETSC_COMM_WORLD; 368c4762a1bSJed Brown mon.problem = problem; 369*9566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x,&mon.x)); 370c4762a1bSJed Brown 371c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 372c4762a1bSJed Brown Create timestepping solver context 373c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 374*9566063dSJacob Faibussowitsch PetscCall(TSCreate(PETSC_COMM_WORLD,&ts)); 375*9566063dSJacob Faibussowitsch PetscCall(TSSetProblemType(ts,TS_NONLINEAR)); 376*9566063dSJacob Faibussowitsch PetscCall(TSSetType(ts,TSROSW)); /* Rosenbrock-W */ 377*9566063dSJacob Faibussowitsch PetscCall(TSSetIFunction(ts,NULL,problem->function,problem->data)); 378*9566063dSJacob Faibussowitsch PetscCall(TSSetIJacobian(ts,A,A,problem->jacobian,problem->data)); 379*9566063dSJacob Faibussowitsch PetscCall(TSSetMaxTime(ts,problem->final_time)); 380*9566063dSJacob Faibussowitsch PetscCall(TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER)); 381*9566063dSJacob Faibussowitsch PetscCall(TSSetMaxStepRejections(ts,10)); 382*9566063dSJacob Faibussowitsch PetscCall(TSSetMaxSNESFailures(ts,-1)); /* unlimited */ 383c4762a1bSJed Brown if (use_monitor) { 384*9566063dSJacob Faibussowitsch PetscCall(TSMonitorSet(ts,&MonitorError,&mon,NULL)); 385c4762a1bSJed Brown } 386c4762a1bSJed Brown 387c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 388c4762a1bSJed Brown Set initial conditions 389c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 390*9566063dSJacob Faibussowitsch PetscCall((*problem->solution)(0,x,problem->data)); 391*9566063dSJacob Faibussowitsch PetscCall(TSSetTimeStep(ts,.001)); 392*9566063dSJacob Faibussowitsch PetscCall(TSSetSolution(ts,x)); 393c4762a1bSJed Brown 394c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 395c4762a1bSJed Brown Set runtime options 396c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 397*9566063dSJacob Faibussowitsch PetscCall(TSSetFromOptions(ts)); 398c4762a1bSJed Brown 399c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 400c4762a1bSJed Brown Solve nonlinear system 401c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 402*9566063dSJacob Faibussowitsch PetscCall(TSSolve(ts,x)); 403*9566063dSJacob Faibussowitsch PetscCall(TSGetSolveTime(ts,&ftime)); 404*9566063dSJacob Faibussowitsch PetscCall(TSGetStepNumber(ts,&steps)); 405*9566063dSJacob Faibussowitsch PetscCall(TSGetSNESFailures(ts,&snesfails)); 406*9566063dSJacob Faibussowitsch PetscCall(TSGetStepRejections(ts,&rejects)); 407*9566063dSJacob Faibussowitsch PetscCall(TSGetSNESIterations(ts,&nonlinits)); 408*9566063dSJacob Faibussowitsch PetscCall(TSGetKSPIterations(ts,&linits)); 4093d5a8a6aSBarry Smith if (use_result) { 410*9566063dSJacob Faibussowitsch PetscCall(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*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 418*9566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 419*9566063dSJacob Faibussowitsch PetscCall(VecDestroy(&r)); 420*9566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mon.x)); 421*9566063dSJacob Faibussowitsch PetscCall(TSDestroy(&ts)); 422c4762a1bSJed Brown if (problem->destroy) { 423*9566063dSJacob Faibussowitsch PetscCall((*problem->destroy)(problem)); 424c4762a1bSJed Brown } 425*9566063dSJacob Faibussowitsch PetscCall(PetscFree(problem)); 426*9566063dSJacob Faibussowitsch PetscCall(PetscFunctionListDestroy(&plist)); 427c4762a1bSJed Brown 428*9566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 429b122ec5aSJacob Faibussowitsch return 0; 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