173f4d377SMatthew Knepley /*$Id: posindep.c,v 1.60 2001/09/11 16:34:22 bsmith Exp $*/ 22d3f70b5SBarry Smith /* 3fb4a63b6SLois Curfman McInnes Code for Timestepping with implicit backwards Euler. 42d3f70b5SBarry Smith */ 5e090d566SSatish Balay #include "src/ts/tsimpl.h" /*I "petscts.h" I*/ 62d3f70b5SBarry Smith 72d3f70b5SBarry Smith typedef struct { 82d3f70b5SBarry Smith Vec update; /* work vector where new solution is formed */ 92d3f70b5SBarry Smith Vec func; /* work vector where F(t[i],u[i]) is stored */ 102d3f70b5SBarry Smith Vec rhs; /* work vector for RHS; vec_sol/dt */ 112d3f70b5SBarry Smith 122d3f70b5SBarry Smith /* information used for Pseudo-timestepping */ 132d3f70b5SBarry Smith 1487828ca2SBarry Smith int (*dt)(TS,PetscReal*,void*); /* compute next timestep, and related context */ 152d3f70b5SBarry Smith void *dtctx; 1687828ca2SBarry Smith int (*verify)(TS,Vec,void*,PetscReal*,int*); /* verify previous timestep and related context */ 177bf11e45SBarry Smith void *verifyctx; 182d3f70b5SBarry Smith 1987828ca2SBarry Smith PetscReal initial_fnorm,fnorm; /* original and current norm of F(u) */ 2087828ca2SBarry Smith PetscReal fnorm_previous; 2128aa8177SBarry Smith 2287828ca2SBarry Smith PetscReal dt_increment; /* scaling that dt is incremented each time-step */ 234bbc92c1SBarry Smith PetscTruth increment_dt_from_initial_dt; 247bf11e45SBarry Smith } TS_Pseudo; 252d3f70b5SBarry Smith 262d3f70b5SBarry Smith /* ------------------------------------------------------------------------------*/ 272d3f70b5SBarry Smith 284a2ae208SSatish Balay #undef __FUNCT__ 294a2ae208SSatish Balay #define __FUNCT__ "TSPseudoComputeTimeStep" 307bf11e45SBarry Smith /*@ 317bf11e45SBarry Smith TSPseudoComputeTimeStep - Computes the next timestep for a currently running 32564e8f4eSLois Curfman McInnes pseudo-timestepping process. 332d3f70b5SBarry Smith 3415091d37SBarry Smith Collective on TS 3515091d37SBarry Smith 367bf11e45SBarry Smith Input Parameter: 377bf11e45SBarry Smith . ts - timestep context 387bf11e45SBarry Smith 397bf11e45SBarry Smith Output Parameter: 40fb4a63b6SLois Curfman McInnes . dt - newly computed timestep 41fb4a63b6SLois Curfman McInnes 4215091d37SBarry Smith Level: advanced 43564e8f4eSLois Curfman McInnes 44564e8f4eSLois Curfman McInnes Notes: 45564e8f4eSLois Curfman McInnes The routine to be called here to compute the timestep should be 46564e8f4eSLois Curfman McInnes set by calling TSPseudoSetTimeStep(). 47564e8f4eSLois Curfman McInnes 48fb4a63b6SLois Curfman McInnes .keywords: timestep, pseudo, compute 49564e8f4eSLois Curfman McInnes 50564e8f4eSLois Curfman McInnes .seealso: TSPseudoDefaultTimeStep(), TSPseudoSetTimeStep() 517bf11e45SBarry Smith @*/ 5287828ca2SBarry Smith int TSPseudoComputeTimeStep(TS ts,PetscReal *dt) 537bf11e45SBarry Smith { 547bf11e45SBarry Smith TS_Pseudo *pseudo = (TS_Pseudo*)ts->data; 557bf11e45SBarry Smith int ierr; 567bf11e45SBarry Smith 573a40ed3dSBarry Smith PetscFunctionBegin; 58d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(TS_PseudoComputeTimeStep,ts,0,0,0);CHKERRQ(ierr); 597bf11e45SBarry Smith ierr = (*pseudo->dt)(ts,dt,pseudo->dtctx);CHKERRQ(ierr); 60d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(TS_PseudoComputeTimeStep,ts,0,0,0);CHKERRQ(ierr); 613a40ed3dSBarry Smith PetscFunctionReturn(0); 627bf11e45SBarry Smith } 637bf11e45SBarry Smith 647bf11e45SBarry Smith 657bf11e45SBarry Smith /* ------------------------------------------------------------------------------*/ 664a2ae208SSatish Balay #undef __FUNCT__ 674a2ae208SSatish Balay #define __FUNCT__ "TSPseudoDefaultVerifyTimeStep" 687bf11e45SBarry Smith /*@C 69639f9d9dSBarry Smith TSPseudoDefaultVerifyTimeStep - Default code to verify the quality of the last timestep. 707bf11e45SBarry Smith 7115091d37SBarry Smith Collective on TS 7215091d37SBarry Smith 737bf11e45SBarry Smith Input Parameters: 7415091d37SBarry Smith + ts - the timestep context 757bf11e45SBarry Smith . dtctx - unused timestep context 7615091d37SBarry Smith - update - latest solution vector 777bf11e45SBarry Smith 78564e8f4eSLois Curfman McInnes Output Parameters: 7915091d37SBarry Smith + newdt - the timestep to use for the next step 8015091d37SBarry Smith - flag - flag indicating whether the last time step was acceptable 817bf11e45SBarry Smith 8215091d37SBarry Smith Level: advanced 83fee21e36SBarry Smith 84564e8f4eSLois Curfman McInnes Note: 85564e8f4eSLois Curfman McInnes This routine always returns a flag of 1, indicating an acceptable 86564e8f4eSLois Curfman McInnes timestep. 87564e8f4eSLois Curfman McInnes 88564e8f4eSLois Curfman McInnes .keywords: timestep, pseudo, default, verify 89564e8f4eSLois Curfman McInnes 90564e8f4eSLois Curfman McInnes .seealso: TSPseudoSetVerifyTimeStep(), TSPseudoVerifyTimeStep() 917bf11e45SBarry Smith @*/ 9287828ca2SBarry Smith int TSPseudoDefaultVerifyTimeStep(TS ts,Vec update,void *dtctx,PetscReal *newdt,int *flag) 937bf11e45SBarry Smith { 943a40ed3dSBarry Smith PetscFunctionBegin; 957bf11e45SBarry Smith *flag = 1; 963a40ed3dSBarry Smith PetscFunctionReturn(0); 977bf11e45SBarry Smith } 987bf11e45SBarry Smith 997bf11e45SBarry Smith 1004a2ae208SSatish Balay #undef __FUNCT__ 1014a2ae208SSatish Balay #define __FUNCT__ "TSPseudoVerifyTimeStep" 1027bf11e45SBarry Smith /*@ 103564e8f4eSLois Curfman McInnes TSPseudoVerifyTimeStep - Verifies whether the last timestep was acceptable. 1047bf11e45SBarry Smith 10515091d37SBarry Smith Collective on TS 10615091d37SBarry Smith 107fb4a63b6SLois Curfman McInnes Input Parameters: 10815091d37SBarry Smith + ts - timestep context 10915091d37SBarry Smith - update - latest solution vector 1107bf11e45SBarry Smith 111fb4a63b6SLois Curfman McInnes Output Parameters: 11215091d37SBarry Smith + dt - newly computed timestep (if it had to shrink) 11315091d37SBarry Smith - flag - indicates if current timestep was ok 1147bf11e45SBarry Smith 11515091d37SBarry Smith Level: advanced 116fee21e36SBarry Smith 117564e8f4eSLois Curfman McInnes Notes: 118564e8f4eSLois Curfman McInnes The routine to be called here to compute the timestep should be 119564e8f4eSLois Curfman McInnes set by calling TSPseudoSetVerifyTimeStep(). 120564e8f4eSLois Curfman McInnes 121564e8f4eSLois Curfman McInnes .keywords: timestep, pseudo, verify 122564e8f4eSLois Curfman McInnes 123564e8f4eSLois Curfman McInnes .seealso: TSPseudoSetVerifyTimeStep(), TSPseudoDefaultVerifyTimeStep() 1247bf11e45SBarry Smith @*/ 12587828ca2SBarry Smith int TSPseudoVerifyTimeStep(TS ts,Vec update,PetscReal *dt,int *flag) 1267bf11e45SBarry Smith { 1277bf11e45SBarry Smith TS_Pseudo *pseudo = (TS_Pseudo*)ts->data; 1287bf11e45SBarry Smith int ierr; 1297bf11e45SBarry Smith 1303a40ed3dSBarry Smith PetscFunctionBegin; 1313a40ed3dSBarry Smith if (!pseudo->verify) {*flag = 1; PetscFunctionReturn(0);} 1327bf11e45SBarry Smith 1337bf11e45SBarry Smith ierr = (*pseudo->verify)(ts,update,pseudo->verifyctx,dt,flag);CHKERRQ(ierr); 1347bf11e45SBarry Smith 1353a40ed3dSBarry Smith PetscFunctionReturn(0); 1367bf11e45SBarry Smith } 1377bf11e45SBarry Smith 1387bf11e45SBarry Smith /* --------------------------------------------------------------------------------*/ 1397bf11e45SBarry Smith 1404a2ae208SSatish Balay #undef __FUNCT__ 1414a2ae208SSatish Balay #define __FUNCT__ "TSStep_Pseudo" 14287828ca2SBarry Smith static int TSStep_Pseudo(TS ts,int *steps,PetscReal *ptime) 1432d3f70b5SBarry Smith { 1442d3f70b5SBarry Smith Vec sol = ts->vec_sol; 145f2267985SLois Curfman McInnes int ierr,i,max_steps = ts->max_steps,its,ok,lits; 1467bf11e45SBarry Smith TS_Pseudo *pseudo = (TS_Pseudo*)ts->data; 14787828ca2SBarry Smith PetscReal current_time_step; 1482d3f70b5SBarry Smith 1493a40ed3dSBarry Smith PetscFunctionBegin; 1502d3f70b5SBarry Smith *steps = -ts->steps; 1512d3f70b5SBarry Smith 1527bf11e45SBarry Smith ierr = VecCopy(sol,pseudo->update);CHKERRQ(ierr); 1532d3f70b5SBarry Smith for (i=0; i<max_steps && ts->ptime < ts->max_time; i++) { 1547bf11e45SBarry Smith ierr = TSPseudoComputeTimeStep(ts,&ts->time_step);CHKERRQ(ierr); 155e6e5fe25SBarry Smith ierr = TSMonitor(ts,ts->steps,ts->ptime,sol);CHKERRQ(ierr); 1567bf11e45SBarry Smith current_time_step = ts->time_step; 157e6e5fe25SBarry Smith while (PETSC_TRUE) { 1587bf11e45SBarry Smith ts->ptime += current_time_step; 159c9780b6fSBarry Smith ierr = SNESSolve(ts->snes,pseudo->update);CHKERRQ(ierr); 160f2267985SLois Curfman McInnes ierr = SNESGetNumberLinearIterations(ts->snes,&lits);CHKERRQ(ierr); 161*9f954729SBarry Smith ierr = SNESGetIterationNumber(ts->snes,&its);CHKERRQ(ierr); 162c9780b6fSBarry Smith ts->nonlinear_its += its; ts->linear_its += lits; 1637bf11e45SBarry Smith ierr = TSPseudoVerifyTimeStep(ts,pseudo->update,&ts->time_step,&ok);CHKERRQ(ierr); 1647bf11e45SBarry Smith if (ok) break; 1657bf11e45SBarry Smith ts->ptime -= current_time_step; 1667bf11e45SBarry Smith current_time_step = ts->time_step; 1677bf11e45SBarry Smith } 1687bf11e45SBarry Smith ierr = VecCopy(pseudo->update,sol);CHKERRQ(ierr); 1692d3f70b5SBarry Smith ts->steps++; 1702d3f70b5SBarry Smith } 171e6e5fe25SBarry Smith ierr = TSComputeRHSFunction(ts,ts->ptime,ts->vec_sol,pseudo->func);CHKERRQ(ierr); 172e6e5fe25SBarry Smith ierr = VecNorm(pseudo->func,NORM_2,&pseudo->fnorm);CHKERRQ(ierr); 173e6e5fe25SBarry Smith ierr = TSMonitor(ts,ts->steps,ts->ptime,sol);CHKERRQ(ierr); 1742d3f70b5SBarry Smith 1752d3f70b5SBarry Smith *steps += ts->steps; 176142b95e3SSatish Balay *ptime = ts->ptime; 1773a40ed3dSBarry Smith PetscFunctionReturn(0); 1782d3f70b5SBarry Smith } 1792d3f70b5SBarry Smith 1802d3f70b5SBarry Smith /*------------------------------------------------------------*/ 1814a2ae208SSatish Balay #undef __FUNCT__ 1824a2ae208SSatish Balay #define __FUNCT__ "TSDestroy_Pseudo" 183e1311b90SBarry Smith static int TSDestroy_Pseudo(TS ts) 1842d3f70b5SBarry Smith { 1857bf11e45SBarry Smith TS_Pseudo *pseudo = (TS_Pseudo*)ts->data; 1862d3f70b5SBarry Smith int ierr; 1872d3f70b5SBarry Smith 1883a40ed3dSBarry Smith PetscFunctionBegin; 189e4ef1970SSatish Balay if (pseudo->update) {ierr = VecDestroy(pseudo->update);CHKERRQ(ierr);} 1907bf11e45SBarry Smith if (pseudo->func) {ierr = VecDestroy(pseudo->func);CHKERRQ(ierr);} 1917bf11e45SBarry Smith if (pseudo->rhs) {ierr = VecDestroy(pseudo->rhs);CHKERRQ(ierr);} 192606d414cSSatish Balay ierr = PetscFree(pseudo);CHKERRQ(ierr); 1933a40ed3dSBarry Smith PetscFunctionReturn(0); 1942d3f70b5SBarry Smith } 1952d3f70b5SBarry Smith 1962d3f70b5SBarry Smith 1972d3f70b5SBarry Smith /*------------------------------------------------------------*/ 1982d3f70b5SBarry Smith 1992d3f70b5SBarry Smith /* 2002d3f70b5SBarry Smith This defines the nonlinear equation that is to be solved with SNES 2012d3f70b5SBarry Smith 2022d3f70b5SBarry Smith (U^{n+1} - U^{n})/dt - F(U^{n+1}) 2032d3f70b5SBarry Smith */ 2044a2ae208SSatish Balay #undef __FUNCT__ 2054a2ae208SSatish Balay #define __FUNCT__ "TSPseudoFunction" 2067bf11e45SBarry Smith int TSPseudoFunction(SNES snes,Vec x,Vec y,void *ctx) 2072d3f70b5SBarry Smith { 2082d3f70b5SBarry Smith TS ts = (TS) ctx; 209ea709b57SSatish Balay PetscScalar mdt = 1.0/ts->time_step,*unp1,*un,*Funp1; 2102d3f70b5SBarry Smith int ierr,i,n; 2112d3f70b5SBarry Smith 2123a40ed3dSBarry Smith PetscFunctionBegin; 2132d3f70b5SBarry Smith /* apply user provided function */ 2142d3f70b5SBarry Smith ierr = TSComputeRHSFunction(ts,ts->ptime,x,y);CHKERRQ(ierr); 2157bf11e45SBarry Smith /* compute (u^{n+1) - u^{n})/dt - F(u^{n+1}) */ 2162d3f70b5SBarry Smith ierr = VecGetArray(ts->vec_sol,&un);CHKERRQ(ierr); 2172d3f70b5SBarry Smith ierr = VecGetArray(x,&unp1);CHKERRQ(ierr); 2182d3f70b5SBarry Smith ierr = VecGetArray(y,&Funp1);CHKERRQ(ierr); 2192d3f70b5SBarry Smith ierr = VecGetLocalSize(x,&n);CHKERRQ(ierr); 2202d3f70b5SBarry Smith for (i=0; i<n; i++) { 2212d3f70b5SBarry Smith Funp1[i] = mdt*(unp1[i] - un[i]) - Funp1[i]; 2222d3f70b5SBarry Smith } 223888f2ed8SSatish Balay ierr = VecRestoreArray(ts->vec_sol,&un);CHKERRQ(ierr); 224888f2ed8SSatish Balay ierr = VecRestoreArray(x,&unp1);CHKERRQ(ierr); 225888f2ed8SSatish Balay ierr = VecRestoreArray(y,&Funp1);CHKERRQ(ierr); 2262d3f70b5SBarry Smith 2273a40ed3dSBarry Smith PetscFunctionReturn(0); 2282d3f70b5SBarry Smith } 2292d3f70b5SBarry Smith 2302d3f70b5SBarry Smith /* 2312d3f70b5SBarry Smith This constructs the Jacobian needed for SNES 2322d3f70b5SBarry Smith 2332d3f70b5SBarry Smith J = I/dt - J_{F} where J_{F} is the given Jacobian of F. 2342d3f70b5SBarry Smith */ 2354a2ae208SSatish Balay #undef __FUNCT__ 2364a2ae208SSatish Balay #define __FUNCT__ "TSPseudoJacobian" 2377bf11e45SBarry Smith int TSPseudoJacobian(SNES snes,Vec x,Mat *AA,Mat *BB,MatStructure *str,void *ctx) 2382d3f70b5SBarry Smith { 2392d3f70b5SBarry Smith TS ts = (TS) ctx; 2402d3f70b5SBarry Smith int ierr; 241ea709b57SSatish Balay PetscScalar mone = -1.0,mdt = 1.0/ts->time_step; 2422d3f70b5SBarry Smith 2433a40ed3dSBarry Smith PetscFunctionBegin; 2442d3f70b5SBarry Smith /* construct users Jacobian */ 245a7a1495cSBarry Smith ierr = TSComputeRHSJacobian(ts,ts->ptime,x,AA,BB,str);CHKERRQ(ierr); 2462d3f70b5SBarry Smith 247614f654bSBarry Smith /* shift and scale Jacobian */ 2482d3f70b5SBarry Smith ierr = MatScale(&mone,*AA);CHKERRQ(ierr); 2492d3f70b5SBarry Smith ierr = MatShift(&mdt,*AA);CHKERRQ(ierr); 250614f654bSBarry Smith if (*BB != *AA && *str != SAME_PRECONDITIONER) { 2512d3f70b5SBarry Smith ierr = MatScale(&mone,*BB);CHKERRQ(ierr); 2522d3f70b5SBarry Smith ierr = MatShift(&mdt,*BB);CHKERRQ(ierr); 2532d3f70b5SBarry Smith } 2542d3f70b5SBarry Smith 2553a40ed3dSBarry Smith PetscFunctionReturn(0); 2562d3f70b5SBarry Smith } 2572d3f70b5SBarry Smith 2582d3f70b5SBarry Smith 2594a2ae208SSatish Balay #undef __FUNCT__ 2604a2ae208SSatish Balay #define __FUNCT__ "TSSetUp_Pseudo" 2617bf11e45SBarry Smith static int TSSetUp_Pseudo(TS ts) 2622d3f70b5SBarry Smith { 2637bf11e45SBarry Smith TS_Pseudo *pseudo = (TS_Pseudo*)ts->data; 264b1bcba4aSBarry Smith int ierr; 2652d3f70b5SBarry Smith 2663a40ed3dSBarry Smith PetscFunctionBegin; 267e6e5fe25SBarry Smith /* ierr = SNESSetFromOptions(ts->snes);CHKERRQ(ierr); */ 2687bf11e45SBarry Smith ierr = VecDuplicate(ts->vec_sol,&pseudo->update);CHKERRQ(ierr); 2697bf11e45SBarry Smith ierr = VecDuplicate(ts->vec_sol,&pseudo->func);CHKERRQ(ierr); 2707bf11e45SBarry Smith ierr = SNESSetFunction(ts->snes,pseudo->func,TSPseudoFunction,ts);CHKERRQ(ierr); 2717bf11e45SBarry Smith ierr = SNESSetJacobian(ts->snes,ts->A,ts->B,TSPseudoJacobian,ts);CHKERRQ(ierr); 2723a40ed3dSBarry Smith PetscFunctionReturn(0); 2732d3f70b5SBarry Smith } 2742d3f70b5SBarry Smith /*------------------------------------------------------------*/ 2752d3f70b5SBarry Smith 2764a2ae208SSatish Balay #undef __FUNCT__ 2774a2ae208SSatish Balay #define __FUNCT__ "TSPseudoDefaultMonitor" 27887828ca2SBarry Smith int TSPseudoDefaultMonitor(TS ts,int step,PetscReal ptime,Vec v,void *ctx) 2792d3f70b5SBarry Smith { 2807bf11e45SBarry Smith TS_Pseudo *pseudo = (TS_Pseudo*)ts->data; 281d132466eSBarry Smith int ierr; 2822d3f70b5SBarry Smith 2833a40ed3dSBarry Smith PetscFunctionBegin; 284142b95e3SSatish Balay ierr = (*PetscHelpPrintf)(ts->comm,"TS %d dt %g time %g fnorm %g\n",step,ts->time_step,ptime,pseudo->fnorm);CHKERRQ(ierr); 2853a40ed3dSBarry Smith PetscFunctionReturn(0); 2862d3f70b5SBarry Smith } 2872d3f70b5SBarry Smith 2884a2ae208SSatish Balay #undef __FUNCT__ 2894a2ae208SSatish Balay #define __FUNCT__ "TSSetFromOptions_Pseudo" 2907bf11e45SBarry Smith static int TSSetFromOptions_Pseudo(TS ts) 2912d3f70b5SBarry Smith { 2924bbc92c1SBarry Smith TS_Pseudo *pseudo = (TS_Pseudo*)ts->data; 293f1af5d2fSBarry Smith int ierr; 294f1af5d2fSBarry Smith PetscTruth flg; 2952d3f70b5SBarry Smith 2963a40ed3dSBarry Smith PetscFunctionBegin; 2972d3f70b5SBarry Smith 298b0a32e0cSBarry Smith ierr = PetscOptionsHead("Pseudo-timestepping options");CHKERRQ(ierr); 299b0a32e0cSBarry Smith ierr = PetscOptionsName("-ts_monitor","Monitor convergence","TSPseudoDefaultMonitor",&flg);CHKERRQ(ierr); 3002d3f70b5SBarry Smith if (flg) { 301329f5518SBarry Smith ierr = TSSetMonitor(ts,TSPseudoDefaultMonitor,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 30228aa8177SBarry Smith } 303b0a32e0cSBarry Smith ierr = PetscOptionsName("-ts_pseudo_increment_dt_from_initial_dt","Increase dt as a ratio from original dt","TSPseudoIncrementDtFromInitialDt",&flg);CHKERRQ(ierr); 304ca4b7087SBarry Smith if (flg) { 305ca4b7087SBarry Smith ierr = TSPseudoIncrementDtFromInitialDt(ts);CHKERRQ(ierr); 306ca4b7087SBarry Smith } 307419fbf4bSSatish Balay ierr = PetscOptionsReal("-ts_pseudo_increment","Ratio to increase dt","TSPseudoSetTimeStepIncrement",pseudo->dt_increment,&pseudo->dt_increment,0);CHKERRQ(ierr); 308b0a32e0cSBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 3092d3f70b5SBarry Smith 3103a40ed3dSBarry Smith PetscFunctionReturn(0); 3112d3f70b5SBarry Smith } 3122d3f70b5SBarry Smith 3134a2ae208SSatish Balay #undef __FUNCT__ 3144a2ae208SSatish Balay #define __FUNCT__ "TSView_Pseudo" 315b0a32e0cSBarry Smith static int TSView_Pseudo(TS ts,PetscViewer viewer) 3162d3f70b5SBarry Smith { 3173a40ed3dSBarry Smith PetscFunctionBegin; 3183a40ed3dSBarry Smith PetscFunctionReturn(0); 3192d3f70b5SBarry Smith } 3202d3f70b5SBarry Smith 32182bf6240SBarry Smith /* ----------------------------------------------------------------------------- */ 3224a2ae208SSatish Balay #undef __FUNCT__ 3234a2ae208SSatish Balay #define __FUNCT__ "TSPseudoSetVerifyTimeStep" 324ac226902SBarry Smith /*@C 32582bf6240SBarry Smith TSPseudoSetVerifyTimeStep - Sets a user-defined routine to verify the quality of the 32682bf6240SBarry Smith last timestep. 32782bf6240SBarry Smith 32815091d37SBarry Smith Collective on TS 32915091d37SBarry Smith 33082bf6240SBarry Smith Input Parameters: 33115091d37SBarry Smith + ts - timestep context 33282bf6240SBarry Smith . dt - user-defined function to verify timestep 33315091d37SBarry Smith - ctx - [optional] user-defined context for private data 33482bf6240SBarry Smith for the timestep verification routine (may be PETSC_NULL) 33582bf6240SBarry Smith 33615091d37SBarry Smith Level: advanced 337fee21e36SBarry Smith 33882bf6240SBarry Smith Calling sequence of func: 33987828ca2SBarry Smith . func (TS ts,Vec update,void *ctx,PetscReal *newdt,int *flag); 34082bf6240SBarry Smith 34182bf6240SBarry Smith . update - latest solution vector 34282bf6240SBarry Smith . ctx - [optional] timestep context 34382bf6240SBarry Smith . newdt - the timestep to use for the next step 34482bf6240SBarry Smith . flag - flag indicating whether the last time step was acceptable 34582bf6240SBarry Smith 34682bf6240SBarry Smith Notes: 34782bf6240SBarry Smith The routine set here will be called by TSPseudoVerifyTimeStep() 34882bf6240SBarry Smith during the timestepping process. 34982bf6240SBarry Smith 35082bf6240SBarry Smith .keywords: timestep, pseudo, set, verify 35182bf6240SBarry Smith 35282bf6240SBarry Smith .seealso: TSPseudoDefaultVerifyTimeStep(), TSPseudoVerifyTimeStep() 35382bf6240SBarry Smith @*/ 35487828ca2SBarry Smith int TSPseudoSetVerifyTimeStep(TS ts,int (*dt)(TS,Vec,void*,PetscReal*,int*),void* ctx) 35582bf6240SBarry Smith { 35687828ca2SBarry Smith int ierr,(*f)(TS,int (*)(TS,Vec,void*,PetscReal *,int *),void *); 35782bf6240SBarry Smith 35882bf6240SBarry Smith PetscFunctionBegin; 3594482741eSBarry Smith PetscValidHeaderSpecific(ts,TS_COOKIE,1); 36082bf6240SBarry Smith 361c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)ts,"TSPseudoSetVerifyTimeStep_C",(void (**)(void))&f);CHKERRQ(ierr); 36282bf6240SBarry Smith if (f) { 36382bf6240SBarry Smith ierr = (*f)(ts,dt,ctx);CHKERRQ(ierr); 36482bf6240SBarry Smith } 36582bf6240SBarry Smith PetscFunctionReturn(0); 36682bf6240SBarry Smith } 36782bf6240SBarry Smith 3684a2ae208SSatish Balay #undef __FUNCT__ 3694a2ae208SSatish Balay #define __FUNCT__ "TSPseudoSetTimeStepIncrement" 37082bf6240SBarry Smith /*@ 37182bf6240SBarry Smith TSPseudoSetTimeStepIncrement - Sets the scaling increment applied to 37282bf6240SBarry Smith dt when using the TSPseudoDefaultTimeStep() routine. 37382bf6240SBarry Smith 374fee21e36SBarry Smith Collective on TS 375fee21e36SBarry Smith 37615091d37SBarry Smith Input Parameters: 37715091d37SBarry Smith + ts - the timestep context 37815091d37SBarry Smith - inc - the scaling factor >= 1.0 37915091d37SBarry Smith 38082bf6240SBarry Smith Options Database Key: 38182bf6240SBarry Smith $ -ts_pseudo_increment <increment> 38282bf6240SBarry Smith 38315091d37SBarry Smith Level: advanced 38415091d37SBarry Smith 38582bf6240SBarry Smith .keywords: timestep, pseudo, set, increment 38682bf6240SBarry Smith 38782bf6240SBarry Smith .seealso: TSPseudoSetTimeStep(), TSPseudoDefaultTimeStep() 38882bf6240SBarry Smith @*/ 38987828ca2SBarry Smith int TSPseudoSetTimeStepIncrement(TS ts,PetscReal inc) 39082bf6240SBarry Smith { 39187828ca2SBarry Smith int ierr,(*f)(TS,PetscReal); 39282bf6240SBarry Smith 39382bf6240SBarry Smith PetscFunctionBegin; 3944482741eSBarry Smith PetscValidHeaderSpecific(ts,TS_COOKIE,1); 39582bf6240SBarry Smith 396c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)ts,"TSPseudoSetTimeStepIncrement_C",(void (**)(void))&f);CHKERRQ(ierr); 39782bf6240SBarry Smith if (f) { 39882bf6240SBarry Smith ierr = (*f)(ts,inc);CHKERRQ(ierr); 39982bf6240SBarry Smith } 40082bf6240SBarry Smith PetscFunctionReturn(0); 40182bf6240SBarry Smith } 40282bf6240SBarry Smith 4034a2ae208SSatish Balay #undef __FUNCT__ 4044a2ae208SSatish Balay #define __FUNCT__ "TSPseudoIncrementDtFromInitialDt" 40582bf6240SBarry Smith /*@ 40682bf6240SBarry Smith TSPseudoIncrementDtFromInitialDt - Indicates that a new timestep 40782bf6240SBarry Smith is computed via the formula 40882bf6240SBarry Smith $ dt = initial_dt*initial_fnorm/current_fnorm 40982bf6240SBarry Smith rather than the default update, 41082bf6240SBarry Smith $ dt = current_dt*previous_fnorm/current_fnorm. 41182bf6240SBarry Smith 41215091d37SBarry Smith Collective on TS 41315091d37SBarry Smith 41482bf6240SBarry Smith Input Parameter: 41582bf6240SBarry Smith . ts - the timestep context 41682bf6240SBarry Smith 41782bf6240SBarry Smith Options Database Key: 41882bf6240SBarry Smith $ -ts_pseudo_increment_dt_from_initial_dt 41982bf6240SBarry Smith 42015091d37SBarry Smith Level: advanced 42115091d37SBarry Smith 42282bf6240SBarry Smith .keywords: timestep, pseudo, set, increment 42382bf6240SBarry Smith 42482bf6240SBarry Smith .seealso: TSPseudoSetTimeStep(), TSPseudoDefaultTimeStep() 42582bf6240SBarry Smith @*/ 42682bf6240SBarry Smith int TSPseudoIncrementDtFromInitialDt(TS ts) 42782bf6240SBarry Smith { 42882bf6240SBarry Smith int ierr,(*f)(TS); 42982bf6240SBarry Smith 43082bf6240SBarry Smith PetscFunctionBegin; 4314482741eSBarry Smith PetscValidHeaderSpecific(ts,TS_COOKIE,1); 43282bf6240SBarry Smith 433c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)ts,"TSPseudoIncrementDtFromInitialDt_C",(void (**)(void))&f);CHKERRQ(ierr); 43482bf6240SBarry Smith if (f) { 43582bf6240SBarry Smith ierr = (*f)(ts);CHKERRQ(ierr); 43682bf6240SBarry Smith } 43782bf6240SBarry Smith PetscFunctionReturn(0); 43882bf6240SBarry Smith } 43982bf6240SBarry Smith 44082bf6240SBarry Smith 4414a2ae208SSatish Balay #undef __FUNCT__ 4424a2ae208SSatish Balay #define __FUNCT__ "TSPseudoSetTimeStep" 443ac226902SBarry Smith /*@C 44482bf6240SBarry Smith TSPseudoSetTimeStep - Sets the user-defined routine to be 44582bf6240SBarry Smith called at each pseudo-timestep to update the timestep. 44682bf6240SBarry Smith 44715091d37SBarry Smith Collective on TS 44815091d37SBarry Smith 44982bf6240SBarry Smith Input Parameters: 45015091d37SBarry Smith + ts - timestep context 45182bf6240SBarry Smith . dt - function to compute timestep 45215091d37SBarry Smith - ctx - [optional] user-defined context for private data 45382bf6240SBarry Smith required by the function (may be PETSC_NULL) 45482bf6240SBarry Smith 45515091d37SBarry Smith Level: intermediate 456fee21e36SBarry Smith 45782bf6240SBarry Smith Calling sequence of func: 45887828ca2SBarry Smith . func (TS ts,PetscReal *newdt,void *ctx); 45982bf6240SBarry Smith 46082bf6240SBarry Smith . newdt - the newly computed timestep 46182bf6240SBarry Smith . ctx - [optional] timestep context 46282bf6240SBarry Smith 46382bf6240SBarry Smith Notes: 46482bf6240SBarry Smith The routine set here will be called by TSPseudoComputeTimeStep() 46582bf6240SBarry Smith during the timestepping process. 46682bf6240SBarry Smith 46782bf6240SBarry Smith .keywords: timestep, pseudo, set 46882bf6240SBarry Smith 46982bf6240SBarry Smith .seealso: TSPseudoDefaultTimeStep(), TSPseudoComputeTimeStep() 47082bf6240SBarry Smith @*/ 47187828ca2SBarry Smith int TSPseudoSetTimeStep(TS ts,int (*dt)(TS,PetscReal*,void*),void* ctx) 47282bf6240SBarry Smith { 47387828ca2SBarry Smith int ierr,(*f)(TS,int (*)(TS,PetscReal *,void *),void *); 47482bf6240SBarry Smith 47582bf6240SBarry Smith PetscFunctionBegin; 4764482741eSBarry Smith PetscValidHeaderSpecific(ts,TS_COOKIE,1); 47782bf6240SBarry Smith 478c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)ts,"TSPseudoSetTimeStep_C",(void (**)(void))&f);CHKERRQ(ierr); 47982bf6240SBarry Smith if (f) { 48082bf6240SBarry Smith ierr = (*f)(ts,dt,ctx);CHKERRQ(ierr); 48182bf6240SBarry Smith } 48282bf6240SBarry Smith PetscFunctionReturn(0); 48382bf6240SBarry Smith } 48482bf6240SBarry Smith 48582bf6240SBarry Smith /* ----------------------------------------------------------------------------- */ 48682bf6240SBarry Smith 4878e019c35SBarry Smith typedef int (*FCN1)(TS,Vec,void*,PetscReal*,int*); /* force argument to next function to not be extern C*/ 488fb2e594dSBarry Smith EXTERN_C_BEGIN 4894a2ae208SSatish Balay #undef __FUNCT__ 4904a2ae208SSatish Balay #define __FUNCT__ "TSPseudoSetVerifyTimeStep_Pseudo" 4918e019c35SBarry Smith int TSPseudoSetVerifyTimeStep_Pseudo(TS ts,FCN1 dt,void* ctx) 49282bf6240SBarry Smith { 49382bf6240SBarry Smith TS_Pseudo *pseudo; 49482bf6240SBarry Smith 49582bf6240SBarry Smith PetscFunctionBegin; 49682bf6240SBarry Smith pseudo = (TS_Pseudo*)ts->data; 49782bf6240SBarry Smith pseudo->verify = dt; 49882bf6240SBarry Smith pseudo->verifyctx = ctx; 49982bf6240SBarry Smith PetscFunctionReturn(0); 50082bf6240SBarry Smith } 501fb2e594dSBarry Smith EXTERN_C_END 50282bf6240SBarry Smith 503fb2e594dSBarry Smith EXTERN_C_BEGIN 5044a2ae208SSatish Balay #undef __FUNCT__ 5054a2ae208SSatish Balay #define __FUNCT__ "TSPseudoSetTimeStepIncrement_Pseudo" 50687828ca2SBarry Smith int TSPseudoSetTimeStepIncrement_Pseudo(TS ts,PetscReal inc) 50782bf6240SBarry Smith { 5084bbc92c1SBarry Smith TS_Pseudo *pseudo = (TS_Pseudo*)ts->data; 50982bf6240SBarry Smith 51082bf6240SBarry Smith PetscFunctionBegin; 51182bf6240SBarry Smith pseudo->dt_increment = inc; 51282bf6240SBarry Smith PetscFunctionReturn(0); 51382bf6240SBarry Smith } 514fb2e594dSBarry Smith EXTERN_C_END 51582bf6240SBarry Smith 516fb2e594dSBarry Smith EXTERN_C_BEGIN 5174a2ae208SSatish Balay #undef __FUNCT__ 5184a2ae208SSatish Balay #define __FUNCT__ "TSPseudoIncrementDtFromInitialDt_Pseudo" 51982bf6240SBarry Smith int TSPseudoIncrementDtFromInitialDt_Pseudo(TS ts) 52082bf6240SBarry Smith { 5214bbc92c1SBarry Smith TS_Pseudo *pseudo = (TS_Pseudo*)ts->data; 52282bf6240SBarry Smith 52382bf6240SBarry Smith PetscFunctionBegin; 5244bbc92c1SBarry Smith pseudo->increment_dt_from_initial_dt = PETSC_TRUE; 52582bf6240SBarry Smith PetscFunctionReturn(0); 52682bf6240SBarry Smith } 527fb2e594dSBarry Smith EXTERN_C_END 52882bf6240SBarry Smith 5298e019c35SBarry Smith typedef int (*FCN2)(TS,PetscReal*,void*); /* force argument to next function to not be extern C*/ 530fb2e594dSBarry Smith EXTERN_C_BEGIN 5314a2ae208SSatish Balay #undef __FUNCT__ 5324a2ae208SSatish Balay #define __FUNCT__ "TSPseudoSetTimeStep_Pseudo" 5338e019c35SBarry Smith int TSPseudoSetTimeStep_Pseudo(TS ts,FCN2 dt,void* ctx) 53482bf6240SBarry Smith { 5354bbc92c1SBarry Smith TS_Pseudo *pseudo = (TS_Pseudo*)ts->data; 53682bf6240SBarry Smith 53782bf6240SBarry Smith PetscFunctionBegin; 53882bf6240SBarry Smith pseudo->dt = dt; 53982bf6240SBarry Smith pseudo->dtctx = ctx; 54082bf6240SBarry Smith PetscFunctionReturn(0); 54182bf6240SBarry Smith } 542fb2e594dSBarry Smith EXTERN_C_END 54382bf6240SBarry Smith 54482bf6240SBarry Smith /* ----------------------------------------------------------------------------- */ 54582bf6240SBarry Smith 546fb2e594dSBarry Smith EXTERN_C_BEGIN 5474a2ae208SSatish Balay #undef __FUNCT__ 5484a2ae208SSatish Balay #define __FUNCT__ "TSCreate_Pseudo" 5497bf11e45SBarry Smith int TSCreate_Pseudo(TS ts) 5502d3f70b5SBarry Smith { 5517bf11e45SBarry Smith TS_Pseudo *pseudo; 5522d3f70b5SBarry Smith int ierr; 5532d3f70b5SBarry Smith 5543a40ed3dSBarry Smith PetscFunctionBegin; 555000e7ae3SMatthew Knepley ts->ops->destroy = TSDestroy_Pseudo; 556000e7ae3SMatthew Knepley ts->ops->view = TSView_Pseudo; 5572d3f70b5SBarry Smith 5582d3f70b5SBarry Smith if (ts->problem_type == TS_LINEAR) { 55929bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_WRONG,"Only for nonlinear problems"); 5602d3f70b5SBarry Smith } 5612d3f70b5SBarry Smith if (!ts->A) { 56229bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must set Jacobian"); 5632d3f70b5SBarry Smith } 564273d9f13SBarry Smith 565000e7ae3SMatthew Knepley ts->ops->setup = TSSetUp_Pseudo; 566000e7ae3SMatthew Knepley ts->ops->step = TSStep_Pseudo; 567000e7ae3SMatthew Knepley ts->ops->setfromoptions = TSSetFromOptions_Pseudo; 5687bf11e45SBarry Smith 5697bf11e45SBarry Smith /* create the required nonlinear solver context */ 5704b27c08aSLois Curfman McInnes ierr = SNESCreate(ts->comm,&ts->snes);CHKERRQ(ierr); 5712d3f70b5SBarry Smith 572b0a32e0cSBarry Smith ierr = PetscNew(TS_Pseudo,&pseudo);CHKERRQ(ierr); 573b0a32e0cSBarry Smith PetscLogObjectMemory(ts,sizeof(TS_Pseudo)); 574eed86810SBarry Smith 575549d3d68SSatish Balay ierr = PetscMemzero(pseudo,sizeof(TS_Pseudo));CHKERRQ(ierr); 5767bf11e45SBarry Smith ts->data = (void*)pseudo; 5772d3f70b5SBarry Smith 57828aa8177SBarry Smith pseudo->dt_increment = 1.1; 5794bbc92c1SBarry Smith pseudo->increment_dt_from_initial_dt = PETSC_FALSE; 58028aa8177SBarry Smith pseudo->dt = TSPseudoDefaultTimeStep; 58182bf6240SBarry Smith 582f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSPseudoSetVerifyTimeStep_C", 583e1311b90SBarry Smith "TSPseudoSetVerifyTimeStep_Pseudo", 5840c97f09dSSatish Balay TSPseudoSetVerifyTimeStep_Pseudo);CHKERRQ(ierr); 585f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSPseudoSetTimeStepIncrement_C", 586e1311b90SBarry Smith "TSPseudoSetTimeStepIncrement_Pseudo", 5870c97f09dSSatish Balay TSPseudoSetTimeStepIncrement_Pseudo);CHKERRQ(ierr); 588f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSPseudoIncrementDtFromInitialDt_C", 589e1311b90SBarry Smith "TSPseudoIncrementDtFromInitialDt_Pseudo", 5900c97f09dSSatish Balay TSPseudoIncrementDtFromInitialDt_Pseudo);CHKERRQ(ierr); 5910c97f09dSSatish Balay ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSPseudoSetTimeStep_C", 5920c97f09dSSatish Balay "TSPseudoSetTimeStep_Pseudo", 5930c97f09dSSatish Balay TSPseudoSetTimeStep_Pseudo);CHKERRQ(ierr); 5943a40ed3dSBarry Smith PetscFunctionReturn(0); 5952d3f70b5SBarry Smith } 596fb2e594dSBarry Smith EXTERN_C_END 5972d3f70b5SBarry Smith 5984a2ae208SSatish Balay #undef __FUNCT__ 5994a2ae208SSatish Balay #define __FUNCT__ "TSPseudoDefaultTimeStep" 60082bf6240SBarry Smith /*@C 60182bf6240SBarry Smith TSPseudoDefaultTimeStep - Default code to compute pseudo-timestepping. 60282bf6240SBarry Smith Use with TSPseudoSetTimeStep(). 60328aa8177SBarry Smith 60415091d37SBarry Smith Collective on TS 60515091d37SBarry Smith 60628aa8177SBarry Smith Input Parameters: 60728aa8177SBarry Smith . ts - the timestep context 60882bf6240SBarry Smith . dtctx - unused timestep context 60928aa8177SBarry Smith 61082bf6240SBarry Smith Output Parameter: 61182bf6240SBarry Smith . newdt - the timestep to use for the next step 61228aa8177SBarry Smith 61315091d37SBarry Smith Level: advanced 61415091d37SBarry Smith 61582bf6240SBarry Smith .keywords: timestep, pseudo, default 616564e8f4eSLois Curfman McInnes 61782bf6240SBarry Smith .seealso: TSPseudoSetTimeStep(), TSPseudoComputeTimeStep() 61828aa8177SBarry Smith @*/ 61987828ca2SBarry Smith int TSPseudoDefaultTimeStep(TS ts,PetscReal* newdt,void* dtctx) 62028aa8177SBarry Smith { 62182bf6240SBarry Smith TS_Pseudo *pseudo = (TS_Pseudo*)ts->data; 62287828ca2SBarry Smith PetscReal inc = pseudo->dt_increment,fnorm_previous = pseudo->fnorm_previous; 62382bf6240SBarry Smith int ierr; 62428aa8177SBarry Smith 6253a40ed3dSBarry Smith PetscFunctionBegin; 62682bf6240SBarry Smith ierr = TSComputeRHSFunction(ts,ts->ptime,ts->vec_sol,pseudo->func);CHKERRQ(ierr); 62782bf6240SBarry Smith ierr = VecNorm(pseudo->func,NORM_2,&pseudo->fnorm);CHKERRQ(ierr); 62882bf6240SBarry Smith if (pseudo->initial_fnorm == 0.0) { 62982bf6240SBarry Smith /* first time through so compute initial function norm */ 63082bf6240SBarry Smith pseudo->initial_fnorm = pseudo->fnorm; 63182bf6240SBarry Smith fnorm_previous = pseudo->fnorm; 63282bf6240SBarry Smith } 63382bf6240SBarry Smith if (pseudo->fnorm == 0.0) { 63482bf6240SBarry Smith *newdt = 1.e12*inc*ts->time_step; 635004884caSBarry Smith } else if (pseudo->increment_dt_from_initial_dt) { 63682bf6240SBarry Smith *newdt = inc*ts->initial_time_step*pseudo->initial_fnorm/pseudo->fnorm; 63782bf6240SBarry Smith } else { 63882bf6240SBarry Smith *newdt = inc*ts->time_step*fnorm_previous/pseudo->fnorm; 63982bf6240SBarry Smith } 64082bf6240SBarry Smith pseudo->fnorm_previous = pseudo->fnorm; 6413a40ed3dSBarry Smith PetscFunctionReturn(0); 64228aa8177SBarry Smith } 6432d3f70b5SBarry Smith 644004884caSBarry Smith 645004884caSBarry Smith 646004884caSBarry Smith 647004884caSBarry Smith 648004884caSBarry Smith 649004884caSBarry Smith 650004884caSBarry Smith 651004884caSBarry Smith 652004884caSBarry Smith 653004884caSBarry Smith 654004884caSBarry Smith 655004884caSBarry Smith 656004884caSBarry Smith 657004884caSBarry Smith 658004884caSBarry Smith 659004884caSBarry Smith 660