1 #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 2 #include <petscdmshell.h> 3 #include <petscdmda.h> 4 #include <petscviewer.h> 5 #include <petscdraw.h> 6 7 /* Logging support */ 8 PetscClassId TS_CLASSID, DMTS_CLASSID; 9 PetscLogEvent TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval; 10 11 const char *const TSExactFinalTimeOptions[] = {"UNSPECIFIED","STEPOVER","INTERPOLATE","MATCHSTEP","TSExactFinalTimeOption","TS_EXACTFINALTIME_",0}; 12 13 /*@C 14 TSMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 15 16 Collective on TS 17 18 Input Parameters: 19 + ts - TS object you wish to monitor 20 . name - the monitor type one is seeking 21 . help - message indicating what monitoring is done 22 . manual - manual page for the monitor 23 . monitor - the monitor function 24 - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the TS or PetscViewer objects 25 26 Level: developer 27 28 .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 29 PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 30 PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 31 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 32 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 33 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 34 PetscOptionsFList(), PetscOptionsEList() 35 @*/ 36 PetscErrorCode TSMonitorSetFromOptions(TS ts,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(TS,PetscViewerAndFormat*)) 37 { 38 PetscErrorCode ierr; 39 PetscViewer viewer; 40 PetscViewerFormat format; 41 PetscBool flg; 42 43 PetscFunctionBegin; 44 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject)ts)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr); 45 if (flg) { 46 PetscViewerAndFormat *vf; 47 ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr); 48 ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr); 49 if (monitorsetup) { 50 ierr = (*monitorsetup)(ts,vf);CHKERRQ(ierr); 51 } 52 ierr = TSMonitorSet(ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr); 53 } 54 PetscFunctionReturn(0); 55 } 56 57 static PetscErrorCode TSAdaptSetDefaultType(TSAdapt adapt,TSAdaptType default_type) 58 { 59 PetscErrorCode ierr; 60 61 PetscFunctionBegin; 62 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 63 PetscValidCharPointer(default_type,2); 64 if (!((PetscObject)adapt)->type_name) { 65 ierr = TSAdaptSetType(adapt,default_type);CHKERRQ(ierr); 66 } 67 PetscFunctionReturn(0); 68 } 69 70 /*@ 71 TSSetFromOptions - Sets various TS parameters from user options. 72 73 Collective on TS 74 75 Input Parameter: 76 . ts - the TS context obtained from TSCreate() 77 78 Options Database Keys: 79 + -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSALPHA, TSGLLE, TSSSP, TSGLEE 80 . -ts_save_trajectory - checkpoint the solution at each time-step 81 . -ts_max_time <time> - maximum time to compute to 82 . -ts_max_steps <steps> - maximum number of time-steps to take 83 . -ts_init_time <time> - initial time to start computation 84 . -ts_final_time <time> - final time to compute to 85 . -ts_dt <dt> - initial time step 86 . -ts_exact_final_time <stepover,interpolate,matchstep> whether to stop at the exact given final time and how to compute the solution at that ti,e 87 . -ts_max_snes_failures <maxfailures> - Maximum number of nonlinear solve failures allowed 88 . -ts_max_reject <maxrejects> - Maximum number of step rejections before step fails 89 . -ts_error_if_step_fails <true,false> - Error if no step succeeds 90 . -ts_rtol <rtol> - relative tolerance for local truncation error 91 . -ts_atol <atol> Absolute tolerance for local truncation error 92 . -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - test the Jacobian at each iteration against finite difference with RHS function 93 . -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - test the Jacobian at each iteration against finite difference with RHS function 94 . -ts_adjoint_solve <yes,no> After solving the ODE/DAE solve the adjoint problem (requires -ts_save_trajectory) 95 . -ts_fd_color - Use finite differences with coloring to compute IJacobian 96 . -ts_monitor - print information at each timestep 97 . -ts_monitor_lg_solution - Monitor solution graphically 98 . -ts_monitor_lg_error - Monitor error graphically 99 . -ts_monitor_error - Monitors norm of error 100 . -ts_monitor_lg_timestep - Monitor timestep size graphically 101 . -ts_monitor_lg_timestep_log - Monitor log timestep size graphically 102 . -ts_monitor_lg_snes_iterations - Monitor number nonlinear iterations for each timestep graphically 103 . -ts_monitor_lg_ksp_iterations - Monitor number nonlinear iterations for each timestep graphically 104 . -ts_monitor_sp_eig - Monitor eigenvalues of linearized operator graphically 105 . -ts_monitor_draw_solution - Monitor solution graphically 106 . -ts_monitor_draw_solution_phase <xleft,yleft,xright,yright> - Monitor solution graphically with phase diagram, requires problem with exactly 2 degrees of freedom 107 . -ts_monitor_draw_error - Monitor error graphically, requires use to have provided TSSetSolutionFunction() 108 . -ts_monitor_solution [ascii binary draw][:filename][:viewerformat] - monitors the solution at each timestep 109 . -ts_monitor_solution_vtk <filename.vts,filename.vtu> - Save each time step to a binary file, use filename-%%03D.vts (filename-%%03D.vtu) 110 . -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time 111 112 Developer Note: We should unify all the -ts_monitor options in the way that -xxx_view has been unified 113 114 Level: beginner 115 116 .keywords: TS, timestep, set, options, database 117 118 .seealso: TSGetType() 119 @*/ 120 PetscErrorCode TSSetFromOptions(TS ts) 121 { 122 PetscBool opt,flg,tflg; 123 PetscErrorCode ierr; 124 char monfilename[PETSC_MAX_PATH_LEN]; 125 PetscReal time_step; 126 TSExactFinalTimeOption eftopt; 127 char dir[16]; 128 TSIFunction ifun; 129 const char *defaultType; 130 char typeName[256]; 131 132 PetscFunctionBegin; 133 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 134 135 ierr = TSRegisterAll();CHKERRQ(ierr); 136 ierr = TSGetIFunction(ts,NULL,&ifun,NULL);CHKERRQ(ierr); 137 138 ierr = PetscObjectOptionsBegin((PetscObject)ts);CHKERRQ(ierr); 139 if (((PetscObject)ts)->type_name) 140 defaultType = ((PetscObject)ts)->type_name; 141 else 142 defaultType = ifun ? TSBEULER : TSEULER; 143 ierr = PetscOptionsFList("-ts_type","TS method","TSSetType",TSList,defaultType,typeName,256,&opt);CHKERRQ(ierr); 144 if (opt) { 145 ierr = TSSetType(ts,typeName);CHKERRQ(ierr); 146 } else { 147 ierr = TSSetType(ts,defaultType);CHKERRQ(ierr); 148 } 149 150 /* Handle generic TS options */ 151 ierr = PetscOptionsReal("-ts_max_time","Maximum time to run to","TSSetMaxTime",ts->max_time,&ts->max_time,NULL);CHKERRQ(ierr); 152 ierr = PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetMaxSteps",ts->max_steps,&ts->max_steps,NULL);CHKERRQ(ierr); 153 ierr = PetscOptionsReal("-ts_init_time","Initial time","TSSetTime",ts->ptime,&ts->ptime,NULL);CHKERRQ(ierr); 154 ierr = PetscOptionsReal("-ts_final_time","Final time to run to","TSSetMaxTime",ts->max_time,&ts->max_time,NULL);CHKERRQ(ierr); 155 ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetTimeStep",ts->time_step,&time_step,&flg);CHKERRQ(ierr); 156 if (flg) {ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr);} 157 ierr = PetscOptionsEnum("-ts_exact_final_time","Option for handling of final time step","TSSetExactFinalTime",TSExactFinalTimeOptions,(PetscEnum)ts->exact_final_time,(PetscEnum*)&eftopt,&flg);CHKERRQ(ierr); 158 if (flg) {ierr = TSSetExactFinalTime(ts,eftopt);CHKERRQ(ierr);} 159 ierr = PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","TSSetMaxSNESFailures",ts->max_snes_failures,&ts->max_snes_failures,NULL);CHKERRQ(ierr); 160 ierr = PetscOptionsInt("-ts_max_reject","Maximum number of step rejections before step fails","TSSetMaxStepRejections",ts->max_reject,&ts->max_reject,NULL);CHKERRQ(ierr); 161 ierr = PetscOptionsBool("-ts_error_if_step_fails","Error if no step succeeds","TSSetErrorIfStepFails",ts->errorifstepfailed,&ts->errorifstepfailed,NULL);CHKERRQ(ierr); 162 ierr = PetscOptionsReal("-ts_rtol","Relative tolerance for local truncation error","TSSetTolerances",ts->rtol,&ts->rtol,NULL);CHKERRQ(ierr); 163 ierr = PetscOptionsReal("-ts_atol","Absolute tolerance for local truncation error","TSSetTolerances",ts->atol,&ts->atol,NULL);CHKERRQ(ierr); 164 165 ierr = PetscOptionsBool("-ts_rhs_jacobian_test_mult","Test the RHS Jacobian for consistency with RHS at each solve ","None",ts->testjacobian,&ts->testjacobian,NULL);CHKERRQ(ierr); 166 ierr = PetscOptionsBool("-ts_rhs_jacobian_test_mult_transpose","Test the RHS Jacobian transpose for consistency with RHS at each solve ","None",ts->testjacobiantranspose,&ts->testjacobiantranspose,NULL);CHKERRQ(ierr); 167 #if defined(PETSC_HAVE_SAWS) 168 { 169 PetscBool set; 170 flg = PETSC_FALSE; 171 ierr = PetscOptionsBool("-ts_saws_block","Block for SAWs memory snooper at end of TSSolve","PetscObjectSAWsBlock",((PetscObject)ts)->amspublishblock,&flg,&set);CHKERRQ(ierr); 172 if (set) { 173 ierr = PetscObjectSAWsSetBlock((PetscObject)ts,flg);CHKERRQ(ierr); 174 } 175 } 176 #endif 177 178 /* Monitor options */ 179 ierr = TSMonitorSetFromOptions(ts,"-ts_monitor","Monitor time and timestep size","TSMonitorDefault",TSMonitorDefault,NULL);CHKERRQ(ierr); 180 ierr = TSMonitorSetFromOptions(ts,"-ts_monitor_solution","View the solution at each timestep","TSMonitorSolution",TSMonitorSolution,NULL);CHKERRQ(ierr); 181 182 ierr = PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 183 if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ts,monfilename);CHKERRQ(ierr);} 184 185 ierr = PetscOptionsName("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",&opt);CHKERRQ(ierr); 186 if (opt) { 187 TSMonitorLGCtx ctx; 188 PetscInt howoften = 1; 189 190 ierr = PetscOptionsInt("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",howoften,&howoften,NULL);CHKERRQ(ierr); 191 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 192 ierr = TSMonitorSet(ts,TSMonitorLGSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 193 } 194 195 ierr = PetscOptionsName("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",&opt);CHKERRQ(ierr); 196 if (opt) { 197 TSMonitorLGCtx ctx; 198 PetscInt howoften = 1; 199 200 ierr = PetscOptionsInt("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",howoften,&howoften,NULL);CHKERRQ(ierr); 201 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 202 ierr = TSMonitorSet(ts,TSMonitorLGError,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 203 } 204 ierr = TSMonitorSetFromOptions(ts,"-ts_monitor_error","View the error at each timestep","TSMonitorError",TSMonitorError,NULL);CHKERRQ(ierr); 205 206 ierr = PetscOptionsName("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",&opt);CHKERRQ(ierr); 207 if (opt) { 208 TSMonitorLGCtx ctx; 209 PetscInt howoften = 1; 210 211 ierr = PetscOptionsInt("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,NULL);CHKERRQ(ierr); 212 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 213 ierr = TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 214 } 215 ierr = PetscOptionsName("-ts_monitor_lg_timestep_log","Monitor log timestep size graphically","TSMonitorLGTimeStep",&opt);CHKERRQ(ierr); 216 if (opt) { 217 TSMonitorLGCtx ctx; 218 PetscInt howoften = 1; 219 220 ierr = PetscOptionsInt("-ts_monitor_lg_timestep_log","Monitor log timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,NULL);CHKERRQ(ierr); 221 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 222 ierr = TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 223 ctx->semilogy = PETSC_TRUE; 224 } 225 226 ierr = PetscOptionsName("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",&opt);CHKERRQ(ierr); 227 if (opt) { 228 TSMonitorLGCtx ctx; 229 PetscInt howoften = 1; 230 231 ierr = PetscOptionsInt("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",howoften,&howoften,NULL);CHKERRQ(ierr); 232 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 233 ierr = TSMonitorSet(ts,TSMonitorLGSNESIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 234 } 235 ierr = PetscOptionsName("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",&opt);CHKERRQ(ierr); 236 if (opt) { 237 TSMonitorLGCtx ctx; 238 PetscInt howoften = 1; 239 240 ierr = PetscOptionsInt("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",howoften,&howoften,NULL);CHKERRQ(ierr); 241 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 242 ierr = TSMonitorSet(ts,TSMonitorLGKSPIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 243 } 244 ierr = PetscOptionsName("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",&opt);CHKERRQ(ierr); 245 if (opt) { 246 TSMonitorSPEigCtx ctx; 247 PetscInt howoften = 1; 248 249 ierr = PetscOptionsInt("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",howoften,&howoften,NULL);CHKERRQ(ierr); 250 ierr = TSMonitorSPEigCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 251 ierr = TSMonitorSet(ts,TSMonitorSPEig,ctx,(PetscErrorCode (*)(void**))TSMonitorSPEigCtxDestroy);CHKERRQ(ierr); 252 } 253 opt = PETSC_FALSE; 254 ierr = PetscOptionsName("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",&opt);CHKERRQ(ierr); 255 if (opt) { 256 TSMonitorDrawCtx ctx; 257 PetscInt howoften = 1; 258 259 ierr = PetscOptionsInt("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",howoften,&howoften,NULL);CHKERRQ(ierr); 260 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,"Computed Solution",PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 261 ierr = TSMonitorSet(ts,TSMonitorDrawSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 262 } 263 opt = PETSC_FALSE; 264 ierr = PetscOptionsName("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",&opt);CHKERRQ(ierr); 265 if (opt) { 266 TSMonitorDrawCtx ctx; 267 PetscReal bounds[4]; 268 PetscInt n = 4; 269 PetscDraw draw; 270 PetscDrawAxis axis; 271 272 ierr = PetscOptionsRealArray("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",bounds,&n,NULL);CHKERRQ(ierr); 273 if (n != 4) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Must provide bounding box of phase field"); 274 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,1,&ctx);CHKERRQ(ierr); 275 ierr = PetscViewerDrawGetDraw(ctx->viewer,0,&draw);CHKERRQ(ierr); 276 ierr = PetscViewerDrawGetDrawAxis(ctx->viewer,0,&axis);CHKERRQ(ierr); 277 ierr = PetscDrawAxisSetLimits(axis,bounds[0],bounds[2],bounds[1],bounds[3]);CHKERRQ(ierr); 278 ierr = PetscDrawAxisSetLabels(axis,"Phase Diagram","Variable 1","Variable 2");CHKERRQ(ierr); 279 ierr = TSMonitorSet(ts,TSMonitorDrawSolutionPhase,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 280 } 281 opt = PETSC_FALSE; 282 ierr = PetscOptionsName("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",&opt);CHKERRQ(ierr); 283 if (opt) { 284 TSMonitorDrawCtx ctx; 285 PetscInt howoften = 1; 286 287 ierr = PetscOptionsInt("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",howoften,&howoften,NULL);CHKERRQ(ierr); 288 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,"Error",PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 289 ierr = TSMonitorSet(ts,TSMonitorDrawError,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 290 } 291 opt = PETSC_FALSE; 292 ierr = PetscOptionsName("-ts_monitor_draw_solution_function","Monitor solution provided by TSMonitorSetSolutionFunction() graphically","TSMonitorDrawSolutionFunction",&opt);CHKERRQ(ierr); 293 if (opt) { 294 TSMonitorDrawCtx ctx; 295 PetscInt howoften = 1; 296 297 ierr = PetscOptionsInt("-ts_monitor_draw_solution_function","Monitor solution provided by TSMonitorSetSolutionFunction() graphically","TSMonitorDrawSolutionFunction",howoften,&howoften,NULL);CHKERRQ(ierr); 298 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,"Solution provided by user function",PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 299 ierr = TSMonitorSet(ts,TSMonitorDrawSolutionFunction,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 300 } 301 302 opt = PETSC_FALSE; 303 ierr = PetscOptionsString("-ts_monitor_solution_vtk","Save each time step to a binary file, use filename-%%03D.vts","TSMonitorSolutionVTK",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 304 if (flg) { 305 const char *ptr,*ptr2; 306 char *filetemplate; 307 if (!monfilename[0]) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 308 /* Do some cursory validation of the input. */ 309 ierr = PetscStrstr(monfilename,"%",(char**)&ptr);CHKERRQ(ierr); 310 if (!ptr) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 311 for (ptr++; ptr && *ptr; ptr++) { 312 ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr); 313 if (!ptr2 && (*ptr < '0' || '9' < *ptr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Invalid file template argument to -ts_monitor_solution_vtk, should look like filename-%%03D.vts"); 314 if (ptr2) break; 315 } 316 ierr = PetscStrallocpy(monfilename,&filetemplate);CHKERRQ(ierr); 317 ierr = TSMonitorSet(ts,TSMonitorSolutionVTK,filetemplate,(PetscErrorCode (*)(void**))TSMonitorSolutionVTKDestroy);CHKERRQ(ierr); 318 } 319 320 ierr = PetscOptionsString("-ts_monitor_dmda_ray","Display a ray of the solution","None","y=0",dir,16,&flg);CHKERRQ(ierr); 321 if (flg) { 322 TSMonitorDMDARayCtx *rayctx; 323 int ray = 0; 324 DMDADirection ddir; 325 DM da; 326 PetscMPIInt rank; 327 328 if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir); 329 if (dir[0] == 'x') ddir = DMDA_X; 330 else if (dir[0] == 'y') ddir = DMDA_Y; 331 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir); 332 sscanf(dir+2,"%d",&ray); 333 334 ierr = PetscInfo2(((PetscObject)ts),"Displaying DMDA ray %c = %D\n",dir[0],ray);CHKERRQ(ierr); 335 ierr = PetscNew(&rayctx);CHKERRQ(ierr); 336 ierr = TSGetDM(ts,&da);CHKERRQ(ierr); 337 ierr = DMDAGetRay(da,ddir,ray,&rayctx->ray,&rayctx->scatter);CHKERRQ(ierr); 338 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)ts),&rank);CHKERRQ(ierr); 339 if (!rank) { 340 ierr = PetscViewerDrawOpen(PETSC_COMM_SELF,0,0,0,0,600,300,&rayctx->viewer);CHKERRQ(ierr); 341 } 342 rayctx->lgctx = NULL; 343 ierr = TSMonitorSet(ts,TSMonitorDMDARay,rayctx,TSMonitorDMDARayDestroy);CHKERRQ(ierr); 344 } 345 ierr = PetscOptionsString("-ts_monitor_lg_dmda_ray","Display a ray of the solution","None","x=0",dir,16,&flg);CHKERRQ(ierr); 346 if (flg) { 347 TSMonitorDMDARayCtx *rayctx; 348 int ray = 0; 349 DMDADirection ddir; 350 DM da; 351 PetscInt howoften = 1; 352 353 if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Malformed ray %s", dir); 354 if (dir[0] == 'x') ddir = DMDA_X; 355 else if (dir[0] == 'y') ddir = DMDA_Y; 356 else SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Unknown ray direction %s", dir); 357 sscanf(dir+2, "%d", &ray); 358 359 ierr = PetscInfo2(((PetscObject) ts),"Displaying LG DMDA ray %c = %D\n", dir[0], ray);CHKERRQ(ierr); 360 ierr = PetscNew(&rayctx);CHKERRQ(ierr); 361 ierr = TSGetDM(ts, &da);CHKERRQ(ierr); 362 ierr = DMDAGetRay(da, ddir, ray, &rayctx->ray, &rayctx->scatter);CHKERRQ(ierr); 363 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&rayctx->lgctx);CHKERRQ(ierr); 364 ierr = TSMonitorSet(ts, TSMonitorLGDMDARay, rayctx, TSMonitorDMDARayDestroy);CHKERRQ(ierr); 365 } 366 367 ierr = PetscOptionsName("-ts_monitor_envelope","Monitor maximum and minimum value of each component of the solution","TSMonitorEnvelope",&opt);CHKERRQ(ierr); 368 if (opt) { 369 TSMonitorEnvelopeCtx ctx; 370 371 ierr = TSMonitorEnvelopeCtxCreate(ts,&ctx);CHKERRQ(ierr); 372 ierr = TSMonitorSet(ts,TSMonitorEnvelope,ctx,(PetscErrorCode (*)(void**))TSMonitorEnvelopeCtxDestroy);CHKERRQ(ierr); 373 } 374 375 flg = PETSC_FALSE; 376 ierr = PetscOptionsBool("-ts_fd_color", "Use finite differences with coloring to compute IJacobian", "TSComputeJacobianDefaultColor", flg, &flg, NULL);CHKERRQ(ierr); 377 if (flg) { 378 DM dm; 379 DMTS tdm; 380 381 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 382 ierr = DMGetDMTS(dm, &tdm);CHKERRQ(ierr); 383 tdm->ijacobianctx = NULL; 384 ierr = TSSetIJacobian(ts, NULL, NULL, TSComputeIJacobianDefaultColor, 0);CHKERRQ(ierr); 385 ierr = PetscInfo(ts, "Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr); 386 } 387 388 /* Handle specific TS options */ 389 if (ts->ops->setfromoptions) { 390 ierr = (*ts->ops->setfromoptions)(PetscOptionsObject,ts);CHKERRQ(ierr); 391 } 392 393 /* Handle TSAdapt options */ 394 ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr); 395 ierr = TSAdaptSetDefaultType(ts->adapt,ts->default_adapt_type);CHKERRQ(ierr); 396 ierr = TSAdaptSetFromOptions(PetscOptionsObject,ts->adapt);CHKERRQ(ierr); 397 398 /* TS trajectory must be set after TS, since it may use some TS options above */ 399 tflg = ts->trajectory ? PETSC_TRUE : PETSC_FALSE; 400 ierr = PetscOptionsBool("-ts_save_trajectory","Save the solution at each timestep","TSSetSaveTrajectory",tflg,&tflg,NULL);CHKERRQ(ierr); 401 if (tflg) { 402 ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); 403 } 404 405 ierr = TSAdjointSetFromOptions(PetscOptionsObject,ts);CHKERRQ(ierr); 406 407 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 408 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ts);CHKERRQ(ierr); 409 ierr = PetscOptionsEnd();CHKERRQ(ierr); 410 411 if (ts->trajectory) { 412 ierr = TSTrajectorySetFromOptions(ts->trajectory,ts);CHKERRQ(ierr); 413 } 414 415 ierr = TSGetSNES(ts,&ts->snes);CHKERRQ(ierr); 416 if (ts->problem_type == TS_LINEAR) {ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr);} 417 ierr = SNESSetFromOptions(ts->snes);CHKERRQ(ierr); 418 PetscFunctionReturn(0); 419 } 420 421 /*@ 422 TSGetTrajectory - Gets the trajectory from a TS if it exists 423 424 Collective on TS 425 426 Input Parameters: 427 . ts - the TS context obtained from TSCreate() 428 429 Output Parameters; 430 . tr - the TSTrajectory object, if it exists 431 432 Note: This routine should be called after all TS options have been set 433 434 Level: advanced 435 436 .seealso: TSGetTrajectory(), TSAdjointSolve(), TSTrajectory, TSTrajectoryCreate() 437 438 .keywords: TS, set, checkpoint, 439 @*/ 440 PetscErrorCode TSGetTrajectory(TS ts,TSTrajectory *tr) 441 { 442 PetscFunctionBegin; 443 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 444 *tr = ts->trajectory; 445 PetscFunctionReturn(0); 446 } 447 448 /*@ 449 TSSetSaveTrajectory - Causes the TS to save its solutions as it iterates forward in time in a TSTrajectory object 450 451 Collective on TS 452 453 Input Parameters: 454 . ts - the TS context obtained from TSCreate() 455 456 Options Database: 457 + -ts_save_trajectory - saves the trajectory to a file 458 - -ts_trajectory_type type 459 460 Note: This routine should be called after all TS options have been set 461 462 The TSTRAJECTORYVISUALIZATION files can be loaded into Python with $PETSC_DIR/lib/petsc/bin/PetscBinaryIOTrajectory.py and 463 MATLAB with $PETSC_DIR/share/petsc/matlab/PetscReadBinaryTrajectory.m 464 465 Level: intermediate 466 467 .seealso: TSGetTrajectory(), TSAdjointSolve(), TSTrajectoryType, TSSetTrajectoryType() 468 469 .keywords: TS, set, checkpoint, 470 @*/ 471 PetscErrorCode TSSetSaveTrajectory(TS ts) 472 { 473 PetscErrorCode ierr; 474 475 PetscFunctionBegin; 476 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 477 if (!ts->trajectory) { 478 ierr = TSTrajectoryCreate(PetscObjectComm((PetscObject)ts),&ts->trajectory);CHKERRQ(ierr); 479 } 480 PetscFunctionReturn(0); 481 } 482 483 /*@ 484 TSComputeRHSJacobian - Computes the Jacobian matrix that has been 485 set with TSSetRHSJacobian(). 486 487 Collective on TS and Vec 488 489 Input Parameters: 490 + ts - the TS context 491 . t - current timestep 492 - U - input vector 493 494 Output Parameters: 495 + A - Jacobian matrix 496 . B - optional preconditioning matrix 497 - flag - flag indicating matrix structure 498 499 Notes: 500 Most users should not need to explicitly call this routine, as it 501 is used internally within the nonlinear solvers. 502 503 See KSPSetOperators() for important information about setting the 504 flag parameter. 505 506 Level: developer 507 508 .keywords: SNES, compute, Jacobian, matrix 509 510 .seealso: TSSetRHSJacobian(), KSPSetOperators() 511 @*/ 512 PetscErrorCode TSComputeRHSJacobian(TS ts,PetscReal t,Vec U,Mat A,Mat B) 513 { 514 PetscErrorCode ierr; 515 PetscObjectState Ustate; 516 PetscObjectId Uid; 517 DM dm; 518 DMTS tsdm; 519 TSRHSJacobian rhsjacobianfunc; 520 void *ctx; 521 TSIJacobian ijacobianfunc; 522 TSRHSFunction rhsfunction; 523 524 PetscFunctionBegin; 525 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 526 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 527 PetscCheckSameComm(ts,1,U,3); 528 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 529 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 530 ierr = DMTSGetRHSJacobian(dm,&rhsjacobianfunc,&ctx);CHKERRQ(ierr); 531 ierr = DMTSGetIJacobian(dm,&ijacobianfunc,NULL);CHKERRQ(ierr); 532 ierr = DMTSGetRHSFunction(dm,&rhsfunction,&ctx);CHKERRQ(ierr); 533 ierr = PetscObjectStateGet((PetscObject)U,&Ustate);CHKERRQ(ierr); 534 ierr = PetscObjectGetId((PetscObject)U,&Uid);CHKERRQ(ierr); 535 if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.Xid == Uid && ts->rhsjacobian.Xstate == Ustate)) && (rhsfunction != TSComputeRHSFunctionLinear)) { 536 PetscFunctionReturn(0); 537 } 538 539 if (!rhsjacobianfunc && !ijacobianfunc) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 540 541 if (ts->rhsjacobian.reuse) { 542 ierr = MatShift(A,-ts->rhsjacobian.shift);CHKERRQ(ierr); 543 ierr = MatScale(A,1./ts->rhsjacobian.scale);CHKERRQ(ierr); 544 if (B && A != B) { 545 ierr = MatShift(B,-ts->rhsjacobian.shift);CHKERRQ(ierr); 546 ierr = MatScale(B,1./ts->rhsjacobian.scale);CHKERRQ(ierr); 547 } 548 ts->rhsjacobian.shift = 0; 549 ts->rhsjacobian.scale = 1.; 550 } 551 552 if (rhsjacobianfunc) { 553 PetscBool missing; 554 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 555 PetscStackPush("TS user Jacobian function"); 556 ierr = (*rhsjacobianfunc)(ts,t,U,A,B,ctx);CHKERRQ(ierr); 557 PetscStackPop; 558 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 559 if (A) { 560 ierr = MatMissingDiagonal(A,&missing,NULL);CHKERRQ(ierr); 561 if (missing) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Amat passed to TSSetRHSJacobian() must have all diagonal entries set, if they are zero you must still set them with a zero value"); 562 } 563 if (B && B != A) { 564 ierr = MatMissingDiagonal(B,&missing,NULL);CHKERRQ(ierr); 565 if (missing) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Bmat passed to TSSetRHSJacobian() must have all diagonal entries set, if they are zero you must still set them with a zero value"); 566 } 567 } else { 568 ierr = MatZeroEntries(A);CHKERRQ(ierr); 569 if (A != B) {ierr = MatZeroEntries(B);CHKERRQ(ierr);} 570 } 571 ts->rhsjacobian.time = t; 572 ierr = PetscObjectGetId((PetscObject)U,&ts->rhsjacobian.Xid);CHKERRQ(ierr); 573 ierr = PetscObjectStateGet((PetscObject)U,&ts->rhsjacobian.Xstate);CHKERRQ(ierr); 574 PetscFunctionReturn(0); 575 } 576 577 /*@ 578 TSComputeRHSFunction - Evaluates the right-hand-side function. 579 580 Collective on TS and Vec 581 582 Input Parameters: 583 + ts - the TS context 584 . t - current time 585 - U - state vector 586 587 Output Parameter: 588 . y - right hand side 589 590 Note: 591 Most users should not need to explicitly call this routine, as it 592 is used internally within the nonlinear solvers. 593 594 Level: developer 595 596 .keywords: TS, compute 597 598 .seealso: TSSetRHSFunction(), TSComputeIFunction() 599 @*/ 600 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec U,Vec y) 601 { 602 PetscErrorCode ierr; 603 TSRHSFunction rhsfunction; 604 TSIFunction ifunction; 605 void *ctx; 606 DM dm; 607 608 PetscFunctionBegin; 609 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 610 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 611 PetscValidHeaderSpecific(y,VEC_CLASSID,4); 612 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 613 ierr = DMTSGetRHSFunction(dm,&rhsfunction,&ctx);CHKERRQ(ierr); 614 ierr = DMTSGetIFunction(dm,&ifunction,NULL);CHKERRQ(ierr); 615 616 if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 617 618 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr); 619 if (rhsfunction) { 620 PetscStackPush("TS user right-hand-side function"); 621 ierr = (*rhsfunction)(ts,t,U,y,ctx);CHKERRQ(ierr); 622 PetscStackPop; 623 } else { 624 ierr = VecZeroEntries(y);CHKERRQ(ierr); 625 } 626 627 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr); 628 PetscFunctionReturn(0); 629 } 630 631 /*@ 632 TSComputeSolutionFunction - Evaluates the solution function. 633 634 Collective on TS and Vec 635 636 Input Parameters: 637 + ts - the TS context 638 - t - current time 639 640 Output Parameter: 641 . U - the solution 642 643 Note: 644 Most users should not need to explicitly call this routine, as it 645 is used internally within the nonlinear solvers. 646 647 Level: developer 648 649 .keywords: TS, compute 650 651 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction() 652 @*/ 653 PetscErrorCode TSComputeSolutionFunction(TS ts,PetscReal t,Vec U) 654 { 655 PetscErrorCode ierr; 656 TSSolutionFunction solutionfunction; 657 void *ctx; 658 DM dm; 659 660 PetscFunctionBegin; 661 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 662 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 663 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 664 ierr = DMTSGetSolutionFunction(dm,&solutionfunction,&ctx);CHKERRQ(ierr); 665 666 if (solutionfunction) { 667 PetscStackPush("TS user solution function"); 668 ierr = (*solutionfunction)(ts,t,U,ctx);CHKERRQ(ierr); 669 PetscStackPop; 670 } 671 PetscFunctionReturn(0); 672 } 673 /*@ 674 TSComputeForcingFunction - Evaluates the forcing function. 675 676 Collective on TS and Vec 677 678 Input Parameters: 679 + ts - the TS context 680 - t - current time 681 682 Output Parameter: 683 . U - the function value 684 685 Note: 686 Most users should not need to explicitly call this routine, as it 687 is used internally within the nonlinear solvers. 688 689 Level: developer 690 691 .keywords: TS, compute 692 693 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction() 694 @*/ 695 PetscErrorCode TSComputeForcingFunction(TS ts,PetscReal t,Vec U) 696 { 697 PetscErrorCode ierr, (*forcing)(TS,PetscReal,Vec,void*); 698 void *ctx; 699 DM dm; 700 701 PetscFunctionBegin; 702 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 703 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 704 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 705 ierr = DMTSGetForcingFunction(dm,&forcing,&ctx);CHKERRQ(ierr); 706 707 if (forcing) { 708 PetscStackPush("TS user forcing function"); 709 ierr = (*forcing)(ts,t,U,ctx);CHKERRQ(ierr); 710 PetscStackPop; 711 } 712 PetscFunctionReturn(0); 713 } 714 715 static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs) 716 { 717 Vec F; 718 PetscErrorCode ierr; 719 720 PetscFunctionBegin; 721 *Frhs = NULL; 722 ierr = TSGetIFunction(ts,&F,NULL,NULL);CHKERRQ(ierr); 723 if (!ts->Frhs) { 724 ierr = VecDuplicate(F,&ts->Frhs);CHKERRQ(ierr); 725 } 726 *Frhs = ts->Frhs; 727 PetscFunctionReturn(0); 728 } 729 730 static PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs) 731 { 732 Mat A,B; 733 PetscErrorCode ierr; 734 TSIJacobian ijacobian; 735 736 PetscFunctionBegin; 737 if (Arhs) *Arhs = NULL; 738 if (Brhs) *Brhs = NULL; 739 ierr = TSGetIJacobian(ts,&A,&B,&ijacobian,NULL);CHKERRQ(ierr); 740 if (Arhs) { 741 if (!ts->Arhs) { 742 if (ijacobian) { 743 ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);CHKERRQ(ierr); 744 } else { 745 ts->Arhs = A; 746 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 747 } 748 } else { 749 PetscBool flg; 750 ierr = SNESGetUseMatrixFree(ts->snes,NULL,&flg);CHKERRQ(ierr); 751 /* Handle case where user provided only RHSJacobian and used -snes_mf_operator */ 752 if (flg && !ijacobian && ts->Arhs == ts->Brhs){ 753 ierr = PetscObjectDereference((PetscObject)ts->Arhs);CHKERRQ(ierr); 754 ts->Arhs = A; 755 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 756 } 757 } 758 *Arhs = ts->Arhs; 759 } 760 if (Brhs) { 761 if (!ts->Brhs) { 762 if (A != B) { 763 if (ijacobian) { 764 ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);CHKERRQ(ierr); 765 } else { 766 ts->Brhs = B; 767 ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 768 } 769 } else { 770 ierr = PetscObjectReference((PetscObject)ts->Arhs);CHKERRQ(ierr); 771 ts->Brhs = ts->Arhs; 772 } 773 } 774 *Brhs = ts->Brhs; 775 } 776 PetscFunctionReturn(0); 777 } 778 779 /*@ 780 TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,U,Udot)=0 781 782 Collective on TS and Vec 783 784 Input Parameters: 785 + ts - the TS context 786 . t - current time 787 . U - state vector 788 . Udot - time derivative of state vector 789 - imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate 790 791 Output Parameter: 792 . Y - right hand side 793 794 Note: 795 Most users should not need to explicitly call this routine, as it 796 is used internally within the nonlinear solvers. 797 798 If the user did did not write their equations in implicit form, this 799 function recasts them in implicit form. 800 801 Level: developer 802 803 .keywords: TS, compute 804 805 .seealso: TSSetIFunction(), TSComputeRHSFunction() 806 @*/ 807 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec U,Vec Udot,Vec Y,PetscBool imex) 808 { 809 PetscErrorCode ierr; 810 TSIFunction ifunction; 811 TSRHSFunction rhsfunction; 812 void *ctx; 813 DM dm; 814 815 PetscFunctionBegin; 816 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 817 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 818 PetscValidHeaderSpecific(Udot,VEC_CLASSID,4); 819 PetscValidHeaderSpecific(Y,VEC_CLASSID,5); 820 821 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 822 ierr = DMTSGetIFunction(dm,&ifunction,&ctx);CHKERRQ(ierr); 823 ierr = DMTSGetRHSFunction(dm,&rhsfunction,NULL);CHKERRQ(ierr); 824 825 if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 826 827 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr); 828 if (ifunction) { 829 PetscStackPush("TS user implicit function"); 830 ierr = (*ifunction)(ts,t,U,Udot,Y,ctx);CHKERRQ(ierr); 831 PetscStackPop; 832 } 833 if (imex) { 834 if (!ifunction) { 835 ierr = VecCopy(Udot,Y);CHKERRQ(ierr); 836 } 837 } else if (rhsfunction) { 838 if (ifunction) { 839 Vec Frhs; 840 ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr); 841 ierr = TSComputeRHSFunction(ts,t,U,Frhs);CHKERRQ(ierr); 842 ierr = VecAXPY(Y,-1,Frhs);CHKERRQ(ierr); 843 } else { 844 ierr = TSComputeRHSFunction(ts,t,U,Y);CHKERRQ(ierr); 845 ierr = VecAYPX(Y,-1,Udot);CHKERRQ(ierr); 846 } 847 } 848 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr); 849 PetscFunctionReturn(0); 850 } 851 852 /*@ 853 TSComputeIJacobian - Evaluates the Jacobian of the DAE 854 855 Collective on TS and Vec 856 857 Input 858 Input Parameters: 859 + ts - the TS context 860 . t - current timestep 861 . U - state vector 862 . Udot - time derivative of state vector 863 . shift - shift to apply, see note below 864 - imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate 865 866 Output Parameters: 867 + A - Jacobian matrix 868 - B - matrix from which the preconditioner is constructed; often the same as A 869 870 Notes: 871 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 872 873 dF/dU + shift*dF/dUdot 874 875 Most users should not need to explicitly call this routine, as it 876 is used internally within the nonlinear solvers. 877 878 Level: developer 879 880 .keywords: TS, compute, Jacobian, matrix 881 882 .seealso: TSSetIJacobian() 883 @*/ 884 PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,PetscBool imex) 885 { 886 PetscErrorCode ierr; 887 TSIJacobian ijacobian; 888 TSRHSJacobian rhsjacobian; 889 DM dm; 890 void *ctx; 891 892 PetscFunctionBegin; 893 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 894 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 895 PetscValidHeaderSpecific(Udot,VEC_CLASSID,4); 896 PetscValidPointer(A,6); 897 PetscValidHeaderSpecific(A,MAT_CLASSID,6); 898 PetscValidPointer(B,7); 899 PetscValidHeaderSpecific(B,MAT_CLASSID,7); 900 901 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 902 ierr = DMTSGetIJacobian(dm,&ijacobian,&ctx);CHKERRQ(ierr); 903 ierr = DMTSGetRHSJacobian(dm,&rhsjacobian,NULL);CHKERRQ(ierr); 904 905 if (!rhsjacobian && !ijacobian) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 906 907 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 908 if (ijacobian) { 909 PetscBool missing; 910 PetscStackPush("TS user implicit Jacobian"); 911 ierr = (*ijacobian)(ts,t,U,Udot,shift,A,B,ctx);CHKERRQ(ierr); 912 PetscStackPop; 913 ierr = MatMissingDiagonal(A,&missing,NULL);CHKERRQ(ierr); 914 if (missing) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Amat passed to TSSetIJacobian() must have all diagonal entries set, if they are zero you must still set them with a zero value"); 915 if (B != A) { 916 ierr = MatMissingDiagonal(B,&missing,NULL);CHKERRQ(ierr); 917 if (missing) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Bmat passed to TSSetIJacobian() must have all diagonal entries set, if they are zero you must still set them with a zero value"); 918 } 919 } 920 if (imex) { 921 if (!ijacobian) { /* system was written as Udot = G(t,U) */ 922 PetscBool assembled; 923 ierr = MatZeroEntries(A);CHKERRQ(ierr); 924 ierr = MatAssembled(A,&assembled);CHKERRQ(ierr); 925 if (!assembled) { 926 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 927 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 928 } 929 ierr = MatShift(A,shift);CHKERRQ(ierr); 930 if (A != B) { 931 ierr = MatZeroEntries(B);CHKERRQ(ierr); 932 ierr = MatAssembled(B,&assembled);CHKERRQ(ierr); 933 if (!assembled) { 934 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 935 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 936 } 937 ierr = MatShift(B,shift);CHKERRQ(ierr); 938 } 939 } 940 } else { 941 Mat Arhs = NULL,Brhs = NULL; 942 if (rhsjacobian) { 943 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 944 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 945 } 946 if (Arhs == A) { /* No IJacobian, so we only have the RHS matrix */ 947 PetscBool flg; 948 ts->rhsjacobian.scale = -1; 949 ts->rhsjacobian.shift = shift; 950 ierr = SNESGetUseMatrixFree(ts->snes,NULL,&flg);CHKERRQ(ierr); 951 /* since -snes_mf_operator uses the full SNES function it does not need to be shifted or scaled here */ 952 if (!flg) { 953 ierr = MatScale(A,-1);CHKERRQ(ierr); 954 ierr = MatShift(A,shift);CHKERRQ(ierr); 955 } 956 if (A != B) { 957 ierr = MatScale(B,-1);CHKERRQ(ierr); 958 ierr = MatShift(B,shift);CHKERRQ(ierr); 959 } 960 } else if (Arhs) { /* Both IJacobian and RHSJacobian */ 961 MatStructure axpy = DIFFERENT_NONZERO_PATTERN; 962 if (!ijacobian) { /* No IJacobian provided, but we have a separate RHS matrix */ 963 ierr = MatZeroEntries(A);CHKERRQ(ierr); 964 ierr = MatShift(A,shift);CHKERRQ(ierr); 965 if (A != B) { 966 ierr = MatZeroEntries(B);CHKERRQ(ierr); 967 ierr = MatShift(B,shift);CHKERRQ(ierr); 968 } 969 } 970 ierr = MatAXPY(A,-1,Arhs,axpy);CHKERRQ(ierr); 971 if (A != B) { 972 ierr = MatAXPY(B,-1,Brhs,axpy);CHKERRQ(ierr); 973 } 974 } 975 } 976 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 977 PetscFunctionReturn(0); 978 } 979 980 /*@C 981 TSSetRHSFunction - Sets the routine for evaluating the function, 982 where U_t = G(t,u). 983 984 Logically Collective on TS 985 986 Input Parameters: 987 + ts - the TS context obtained from TSCreate() 988 . r - vector to put the computed right hand side (or NULL to have it created) 989 . f - routine for evaluating the right-hand-side function 990 - ctx - [optional] user-defined context for private data for the 991 function evaluation routine (may be NULL) 992 993 Calling sequence of func: 994 $ func (TS ts,PetscReal t,Vec u,Vec F,void *ctx); 995 996 + t - current timestep 997 . u - input vector 998 . F - function vector 999 - ctx - [optional] user-defined function context 1000 1001 Level: beginner 1002 1003 Notes: You must call this function or TSSetIFunction() to define your ODE. You cannot use this function when solving a DAE. 1004 1005 .keywords: TS, timestep, set, right-hand-side, function 1006 1007 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSSetIFunction() 1008 @*/ 1009 PetscErrorCode TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx) 1010 { 1011 PetscErrorCode ierr; 1012 SNES snes; 1013 Vec ralloc = NULL; 1014 DM dm; 1015 1016 PetscFunctionBegin; 1017 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1018 if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1019 1020 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1021 ierr = DMTSSetRHSFunction(dm,f,ctx);CHKERRQ(ierr); 1022 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1023 if (!r && !ts->dm && ts->vec_sol) { 1024 ierr = VecDuplicate(ts->vec_sol,&ralloc);CHKERRQ(ierr); 1025 r = ralloc; 1026 } 1027 ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr); 1028 ierr = VecDestroy(&ralloc);CHKERRQ(ierr); 1029 PetscFunctionReturn(0); 1030 } 1031 1032 /*@C 1033 TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE 1034 1035 Logically Collective on TS 1036 1037 Input Parameters: 1038 + ts - the TS context obtained from TSCreate() 1039 . f - routine for evaluating the solution 1040 - ctx - [optional] user-defined context for private data for the 1041 function evaluation routine (may be NULL) 1042 1043 Calling sequence of func: 1044 $ func (TS ts,PetscReal t,Vec u,void *ctx); 1045 1046 + t - current timestep 1047 . u - output vector 1048 - ctx - [optional] user-defined function context 1049 1050 Options Database: 1051 + -ts_monitor_lg_error - create a graphical monitor of error history, requires user to have provided TSSetSolutionFunction() 1052 - -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 1053 1054 Notes: 1055 This routine is used for testing accuracy of time integration schemes when you already know the solution. 1056 If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to 1057 create closed-form solutions with non-physical forcing terms. 1058 1059 For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history. 1060 1061 Level: beginner 1062 1063 .keywords: TS, timestep, set, right-hand-side, function 1064 1065 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetForcingFunction(), TSSetSolution(), TSGetSolution(), TSMonitorLGError(), TSMonitorDrawError() 1066 @*/ 1067 PetscErrorCode TSSetSolutionFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx) 1068 { 1069 PetscErrorCode ierr; 1070 DM dm; 1071 1072 PetscFunctionBegin; 1073 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1074 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1075 ierr = DMTSSetSolutionFunction(dm,f,ctx);CHKERRQ(ierr); 1076 PetscFunctionReturn(0); 1077 } 1078 1079 /*@C 1080 TSSetForcingFunction - Provide a function that computes a forcing term for a ODE or PDE 1081 1082 Logically Collective on TS 1083 1084 Input Parameters: 1085 + ts - the TS context obtained from TSCreate() 1086 . func - routine for evaluating the forcing function 1087 - ctx - [optional] user-defined context for private data for the 1088 function evaluation routine (may be NULL) 1089 1090 Calling sequence of func: 1091 $ func (TS ts,PetscReal t,Vec f,void *ctx); 1092 1093 + t - current timestep 1094 . f - output vector 1095 - ctx - [optional] user-defined function context 1096 1097 Notes: 1098 This routine is useful for testing accuracy of time integration schemes when using the Method of Manufactured Solutions to 1099 create closed-form solutions with a non-physical forcing term. It allows you to use the Method of Manufactored Solution without directly editing the 1100 definition of the problem you are solving and hence possibly introducing bugs. 1101 1102 This replaces the ODE F(u,u_t,t) = 0 the TS is solving with F(u,u_t,t) - func(t) = 0 1103 1104 This forcing function does not depend on the solution to the equations, it can only depend on spatial location, time, and possibly parameters, the 1105 parameters can be passed in the ctx variable. 1106 1107 For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history. 1108 1109 Level: beginner 1110 1111 .keywords: TS, timestep, set, right-hand-side, function 1112 1113 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetSolutionFunction() 1114 @*/ 1115 PetscErrorCode TSSetForcingFunction(TS ts,TSForcingFunction func,void *ctx) 1116 { 1117 PetscErrorCode ierr; 1118 DM dm; 1119 1120 PetscFunctionBegin; 1121 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1122 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1123 ierr = DMTSSetForcingFunction(dm,func,ctx);CHKERRQ(ierr); 1124 PetscFunctionReturn(0); 1125 } 1126 1127 /*@C 1128 TSSetRHSJacobian - Sets the function to compute the Jacobian of G, 1129 where U_t = G(U,t), as well as the location to store the matrix. 1130 1131 Logically Collective on TS 1132 1133 Input Parameters: 1134 + ts - the TS context obtained from TSCreate() 1135 . Amat - (approximate) Jacobian matrix 1136 . Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat) 1137 . f - the Jacobian evaluation routine 1138 - ctx - [optional] user-defined context for private data for the 1139 Jacobian evaluation routine (may be NULL) 1140 1141 Calling sequence of f: 1142 $ func (TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx); 1143 1144 + t - current timestep 1145 . u - input vector 1146 . Amat - (approximate) Jacobian matrix 1147 . Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat) 1148 - ctx - [optional] user-defined context for matrix evaluation routine 1149 1150 Notes: 1151 You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value 1152 1153 The TS solver may modify the nonzero structure and the entries of the matrices Amat and Pmat between the calls to f() 1154 You should not assume the values are the same in the next call to f() as you set them in the previous call. 1155 1156 Level: beginner 1157 1158 .keywords: TS, timestep, set, right-hand-side, Jacobian 1159 1160 .seealso: SNESComputeJacobianDefaultColor(), TSSetRHSFunction(), TSRHSJacobianSetReuse(), TSSetIJacobian() 1161 1162 @*/ 1163 PetscErrorCode TSSetRHSJacobian(TS ts,Mat Amat,Mat Pmat,TSRHSJacobian f,void *ctx) 1164 { 1165 PetscErrorCode ierr; 1166 SNES snes; 1167 DM dm; 1168 TSIJacobian ijacobian; 1169 1170 PetscFunctionBegin; 1171 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1172 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 1173 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 1174 if (Amat) PetscCheckSameComm(ts,1,Amat,2); 1175 if (Pmat) PetscCheckSameComm(ts,1,Pmat,3); 1176 1177 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1178 ierr = DMTSSetRHSJacobian(dm,f,ctx);CHKERRQ(ierr); 1179 if (f == TSComputeRHSJacobianConstant) { 1180 /* Handle this case automatically for the user; otherwise user should call themselves. */ 1181 ierr = TSRHSJacobianSetReuse(ts,PETSC_TRUE);CHKERRQ(ierr); 1182 } 1183 ierr = DMTSGetIJacobian(dm,&ijacobian,NULL);CHKERRQ(ierr); 1184 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1185 if (!ijacobian) { 1186 ierr = SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1187 } 1188 if (Amat) { 1189 ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 1190 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 1191 ts->Arhs = Amat; 1192 } 1193 if (Pmat) { 1194 ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr); 1195 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 1196 ts->Brhs = Pmat; 1197 } 1198 PetscFunctionReturn(0); 1199 } 1200 1201 /*@C 1202 TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved. 1203 1204 Logically Collective on TS 1205 1206 Input Parameters: 1207 + ts - the TS context obtained from TSCreate() 1208 . r - vector to hold the residual (or NULL to have it created internally) 1209 . f - the function evaluation routine 1210 - ctx - user-defined context for private data for the function evaluation routine (may be NULL) 1211 1212 Calling sequence of f: 1213 $ f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx); 1214 1215 + t - time at step/stage being solved 1216 . u - state vector 1217 . u_t - time derivative of state vector 1218 . F - function vector 1219 - ctx - [optional] user-defined context for matrix evaluation routine 1220 1221 Important: 1222 The user MUST call either this routine or TSSetRHSFunction() to define the ODE. When solving DAEs you must use this function. 1223 1224 Level: beginner 1225 1226 .keywords: TS, timestep, set, DAE, Jacobian 1227 1228 .seealso: TSSetRHSJacobian(), TSSetRHSFunction(), TSSetIJacobian() 1229 @*/ 1230 PetscErrorCode TSSetIFunction(TS ts,Vec r,TSIFunction f,void *ctx) 1231 { 1232 PetscErrorCode ierr; 1233 SNES snes; 1234 Vec ralloc = NULL; 1235 DM dm; 1236 1237 PetscFunctionBegin; 1238 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1239 if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1240 1241 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1242 ierr = DMTSSetIFunction(dm,f,ctx);CHKERRQ(ierr); 1243 1244 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1245 if (!r && !ts->dm && ts->vec_sol) { 1246 ierr = VecDuplicate(ts->vec_sol,&ralloc);CHKERRQ(ierr); 1247 r = ralloc; 1248 } 1249 ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr); 1250 ierr = VecDestroy(&ralloc);CHKERRQ(ierr); 1251 PetscFunctionReturn(0); 1252 } 1253 1254 /*@C 1255 TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it. 1256 1257 Not Collective 1258 1259 Input Parameter: 1260 . ts - the TS context 1261 1262 Output Parameter: 1263 + r - vector to hold residual (or NULL) 1264 . func - the function to compute residual (or NULL) 1265 - ctx - the function context (or NULL) 1266 1267 Level: advanced 1268 1269 .keywords: TS, nonlinear, get, function 1270 1271 .seealso: TSSetIFunction(), SNESGetFunction() 1272 @*/ 1273 PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx) 1274 { 1275 PetscErrorCode ierr; 1276 SNES snes; 1277 DM dm; 1278 1279 PetscFunctionBegin; 1280 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1281 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1282 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1283 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1284 ierr = DMTSGetIFunction(dm,func,ctx);CHKERRQ(ierr); 1285 PetscFunctionReturn(0); 1286 } 1287 1288 /*@C 1289 TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it. 1290 1291 Not Collective 1292 1293 Input Parameter: 1294 . ts - the TS context 1295 1296 Output Parameter: 1297 + r - vector to hold computed right hand side (or NULL) 1298 . func - the function to compute right hand side (or NULL) 1299 - ctx - the function context (or NULL) 1300 1301 Level: advanced 1302 1303 .keywords: TS, nonlinear, get, function 1304 1305 .seealso: TSSetRHSFunction(), SNESGetFunction() 1306 @*/ 1307 PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx) 1308 { 1309 PetscErrorCode ierr; 1310 SNES snes; 1311 DM dm; 1312 1313 PetscFunctionBegin; 1314 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1315 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1316 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1317 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1318 ierr = DMTSGetRHSFunction(dm,func,ctx);CHKERRQ(ierr); 1319 PetscFunctionReturn(0); 1320 } 1321 1322 /*@C 1323 TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function 1324 provided with TSSetIFunction(). 1325 1326 Logically Collective on TS 1327 1328 Input Parameters: 1329 + ts - the TS context obtained from TSCreate() 1330 . Amat - (approximate) Jacobian matrix 1331 . Pmat - matrix used to compute preconditioner (usually the same as Amat) 1332 . f - the Jacobian evaluation routine 1333 - ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL) 1334 1335 Calling sequence of f: 1336 $ f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx); 1337 1338 + t - time at step/stage being solved 1339 . U - state vector 1340 . U_t - time derivative of state vector 1341 . a - shift 1342 . Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t 1343 . Pmat - matrix used for constructing preconditioner, usually the same as Amat 1344 - ctx - [optional] user-defined context for matrix evaluation routine 1345 1346 Notes: 1347 The matrices Amat and Pmat are exactly the matrices that are used by SNES for the nonlinear solve. 1348 1349 If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 1350 space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 1351 1352 The matrix dF/dU + a*dF/dU_t you provide turns out to be 1353 the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved. 1354 The time integrator internally approximates U_t by W+a*U where the positive "shift" 1355 a and vector W depend on the integration method, step size, and past states. For example with 1356 the backward Euler method a = 1/dt and W = -a*U(previous timestep) so 1357 W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt 1358 1359 You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value 1360 1361 The TS solver may modify the nonzero structure and the entries of the matrices Amat and Pmat between the calls to f() 1362 You should not assume the values are the same in the next call to f() as you set them in the previous call. 1363 1364 Level: beginner 1365 1366 .keywords: TS, timestep, DAE, Jacobian 1367 1368 .seealso: TSSetIFunction(), TSSetRHSJacobian(), SNESComputeJacobianDefaultColor(), SNESComputeJacobianDefault(), TSSetRHSFunction() 1369 1370 @*/ 1371 PetscErrorCode TSSetIJacobian(TS ts,Mat Amat,Mat Pmat,TSIJacobian f,void *ctx) 1372 { 1373 PetscErrorCode ierr; 1374 SNES snes; 1375 DM dm; 1376 1377 PetscFunctionBegin; 1378 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1379 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 1380 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 1381 if (Amat) PetscCheckSameComm(ts,1,Amat,2); 1382 if (Pmat) PetscCheckSameComm(ts,1,Pmat,3); 1383 1384 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1385 ierr = DMTSSetIJacobian(dm,f,ctx);CHKERRQ(ierr); 1386 1387 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1388 ierr = SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1389 PetscFunctionReturn(0); 1390 } 1391 1392 /*@ 1393 TSRHSJacobianSetReuse - restore RHS Jacobian before re-evaluating. Without this flag, TS will change the sign and 1394 shift the RHS Jacobian for a finite-time-step implicit solve, in which case the user function will need to recompute 1395 the entire Jacobian. The reuse flag must be set if the evaluation function will assume that the matrix entries have 1396 not been changed by the TS. 1397 1398 Logically Collective 1399 1400 Input Arguments: 1401 + ts - TS context obtained from TSCreate() 1402 - reuse - PETSC_TRUE if the RHS Jacobian 1403 1404 Level: intermediate 1405 1406 .seealso: TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 1407 @*/ 1408 PetscErrorCode TSRHSJacobianSetReuse(TS ts,PetscBool reuse) 1409 { 1410 PetscFunctionBegin; 1411 ts->rhsjacobian.reuse = reuse; 1412 PetscFunctionReturn(0); 1413 } 1414 1415 /*@C 1416 TSSetI2Function - Set the function to compute F(t,U,U_t,U_tt) where F = 0 is the DAE to be solved. 1417 1418 Logically Collective on TS 1419 1420 Input Parameters: 1421 + ts - the TS context obtained from TSCreate() 1422 . F - vector to hold the residual (or NULL to have it created internally) 1423 . fun - the function evaluation routine 1424 - ctx - user-defined context for private data for the function evaluation routine (may be NULL) 1425 1426 Calling sequence of fun: 1427 $ fun(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,Vec F,ctx); 1428 1429 + t - time at step/stage being solved 1430 . U - state vector 1431 . U_t - time derivative of state vector 1432 . U_tt - second time derivative of state vector 1433 . F - function vector 1434 - ctx - [optional] user-defined context for matrix evaluation routine (may be NULL) 1435 1436 Level: beginner 1437 1438 .keywords: TS, timestep, set, ODE, DAE, Function 1439 1440 .seealso: TSSetI2Jacobian() 1441 @*/ 1442 PetscErrorCode TSSetI2Function(TS ts,Vec F,TSI2Function fun,void *ctx) 1443 { 1444 DM dm; 1445 PetscErrorCode ierr; 1446 1447 PetscFunctionBegin; 1448 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1449 if (F) PetscValidHeaderSpecific(F,VEC_CLASSID,2); 1450 ierr = TSSetIFunction(ts,F,NULL,NULL);CHKERRQ(ierr); 1451 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1452 ierr = DMTSSetI2Function(dm,fun,ctx);CHKERRQ(ierr); 1453 PetscFunctionReturn(0); 1454 } 1455 1456 /*@C 1457 TSGetI2Function - Returns the vector where the implicit residual is stored and the function/contex to compute it. 1458 1459 Not Collective 1460 1461 Input Parameter: 1462 . ts - the TS context 1463 1464 Output Parameter: 1465 + r - vector to hold residual (or NULL) 1466 . fun - the function to compute residual (or NULL) 1467 - ctx - the function context (or NULL) 1468 1469 Level: advanced 1470 1471 .keywords: TS, nonlinear, get, function 1472 1473 .seealso: TSSetI2Function(), SNESGetFunction() 1474 @*/ 1475 PetscErrorCode TSGetI2Function(TS ts,Vec *r,TSI2Function *fun,void **ctx) 1476 { 1477 PetscErrorCode ierr; 1478 SNES snes; 1479 DM dm; 1480 1481 PetscFunctionBegin; 1482 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1483 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1484 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1485 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1486 ierr = DMTSGetI2Function(dm,fun,ctx);CHKERRQ(ierr); 1487 PetscFunctionReturn(0); 1488 } 1489 1490 /*@C 1491 TSSetI2Jacobian - Set the function to compute the matrix dF/dU + v*dF/dU_t + a*dF/dU_tt 1492 where F(t,U,U_t,U_tt) is the function you provided with TSSetI2Function(). 1493 1494 Logically Collective on TS 1495 1496 Input Parameters: 1497 + ts - the TS context obtained from TSCreate() 1498 . J - Jacobian matrix 1499 . P - preconditioning matrix for J (may be same as J) 1500 . jac - the Jacobian evaluation routine 1501 - ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL) 1502 1503 Calling sequence of jac: 1504 $ jac(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,PetscReal v,PetscReal a,Mat J,Mat P,void *ctx); 1505 1506 + t - time at step/stage being solved 1507 . U - state vector 1508 . U_t - time derivative of state vector 1509 . U_tt - second time derivative of state vector 1510 . v - shift for U_t 1511 . a - shift for U_tt 1512 . J - Jacobian of G(U) = F(t,U,W+v*U,W'+a*U), equivalent to dF/dU + v*dF/dU_t + a*dF/dU_tt 1513 . P - preconditioning matrix for J, may be same as J 1514 - ctx - [optional] user-defined context for matrix evaluation routine 1515 1516 Notes: 1517 The matrices J and P are exactly the matrices that are used by SNES for the nonlinear solve. 1518 1519 The matrix dF/dU + v*dF/dU_t + a*dF/dU_tt you provide turns out to be 1520 the Jacobian of G(U) = F(t,U,W+v*U,W'+a*U) where F(t,U,U_t,U_tt) = 0 is the DAE to be solved. 1521 The time integrator internally approximates U_t by W+v*U and U_tt by W'+a*U where the positive "shift" 1522 parameters 'v' and 'a' and vectors W, W' depend on the integration method, step size, and past states. 1523 1524 Level: beginner 1525 1526 .keywords: TS, timestep, set, ODE, DAE, Jacobian 1527 1528 .seealso: TSSetI2Function() 1529 @*/ 1530 PetscErrorCode TSSetI2Jacobian(TS ts,Mat J,Mat P,TSI2Jacobian jac,void *ctx) 1531 { 1532 DM dm; 1533 PetscErrorCode ierr; 1534 1535 PetscFunctionBegin; 1536 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1537 if (J) PetscValidHeaderSpecific(J,MAT_CLASSID,2); 1538 if (P) PetscValidHeaderSpecific(P,MAT_CLASSID,3); 1539 ierr = TSSetIJacobian(ts,J,P,NULL,NULL);CHKERRQ(ierr); 1540 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1541 ierr = DMTSSetI2Jacobian(dm,jac,ctx);CHKERRQ(ierr); 1542 PetscFunctionReturn(0); 1543 } 1544 1545 /*@C 1546 TSGetI2Jacobian - Returns the implicit Jacobian at the present timestep. 1547 1548 Not Collective, but parallel objects are returned if TS is parallel 1549 1550 Input Parameter: 1551 . ts - The TS context obtained from TSCreate() 1552 1553 Output Parameters: 1554 + J - The (approximate) Jacobian of F(t,U,U_t,U_tt) 1555 . P - The matrix from which the preconditioner is constructed, often the same as J 1556 . jac - The function to compute the Jacobian matrices 1557 - ctx - User-defined context for Jacobian evaluation routine 1558 1559 Notes: You can pass in NULL for any return argument you do not need. 1560 1561 Level: advanced 1562 1563 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 1564 1565 .keywords: TS, timestep, get, matrix, Jacobian 1566 @*/ 1567 PetscErrorCode TSGetI2Jacobian(TS ts,Mat *J,Mat *P,TSI2Jacobian *jac,void **ctx) 1568 { 1569 PetscErrorCode ierr; 1570 SNES snes; 1571 DM dm; 1572 1573 PetscFunctionBegin; 1574 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1575 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 1576 ierr = SNESGetJacobian(snes,J,P,NULL,NULL);CHKERRQ(ierr); 1577 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1578 ierr = DMTSGetI2Jacobian(dm,jac,ctx);CHKERRQ(ierr); 1579 PetscFunctionReturn(0); 1580 } 1581 1582 /*@ 1583 TSComputeI2Function - Evaluates the DAE residual written in implicit form F(t,U,U_t,U_tt) = 0 1584 1585 Collective on TS and Vec 1586 1587 Input Parameters: 1588 + ts - the TS context 1589 . t - current time 1590 . U - state vector 1591 . V - time derivative of state vector (U_t) 1592 - A - second time derivative of state vector (U_tt) 1593 1594 Output Parameter: 1595 . F - the residual vector 1596 1597 Note: 1598 Most users should not need to explicitly call this routine, as it 1599 is used internally within the nonlinear solvers. 1600 1601 Level: developer 1602 1603 .keywords: TS, compute, function, vector 1604 1605 .seealso: TSSetI2Function() 1606 @*/ 1607 PetscErrorCode TSComputeI2Function(TS ts,PetscReal t,Vec U,Vec V,Vec A,Vec F) 1608 { 1609 DM dm; 1610 TSI2Function I2Function; 1611 void *ctx; 1612 TSRHSFunction rhsfunction; 1613 PetscErrorCode ierr; 1614 1615 PetscFunctionBegin; 1616 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1617 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 1618 PetscValidHeaderSpecific(V,VEC_CLASSID,4); 1619 PetscValidHeaderSpecific(A,VEC_CLASSID,5); 1620 PetscValidHeaderSpecific(F,VEC_CLASSID,6); 1621 1622 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1623 ierr = DMTSGetI2Function(dm,&I2Function,&ctx);CHKERRQ(ierr); 1624 ierr = DMTSGetRHSFunction(dm,&rhsfunction,NULL);CHKERRQ(ierr); 1625 1626 if (!I2Function) { 1627 ierr = TSComputeIFunction(ts,t,U,A,F,PETSC_FALSE);CHKERRQ(ierr); 1628 PetscFunctionReturn(0); 1629 } 1630 1631 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,V,F);CHKERRQ(ierr); 1632 1633 PetscStackPush("TS user implicit function"); 1634 ierr = I2Function(ts,t,U,V,A,F,ctx);CHKERRQ(ierr); 1635 PetscStackPop; 1636 1637 if (rhsfunction) { 1638 Vec Frhs; 1639 ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr); 1640 ierr = TSComputeRHSFunction(ts,t,U,Frhs);CHKERRQ(ierr); 1641 ierr = VecAXPY(F,-1,Frhs);CHKERRQ(ierr); 1642 } 1643 1644 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,V,F);CHKERRQ(ierr); 1645 PetscFunctionReturn(0); 1646 } 1647 1648 /*@ 1649 TSComputeI2Jacobian - Evaluates the Jacobian of the DAE 1650 1651 Collective on TS and Vec 1652 1653 Input Parameters: 1654 + ts - the TS context 1655 . t - current timestep 1656 . U - state vector 1657 . V - time derivative of state vector 1658 . A - second time derivative of state vector 1659 . shiftV - shift to apply, see note below 1660 - shiftA - shift to apply, see note below 1661 1662 Output Parameters: 1663 + J - Jacobian matrix 1664 - P - optional preconditioning matrix 1665 1666 Notes: 1667 If F(t,U,V,A)=0 is the DAE, the required Jacobian is 1668 1669 dF/dU + shiftV*dF/dV + shiftA*dF/dA 1670 1671 Most users should not need to explicitly call this routine, as it 1672 is used internally within the nonlinear solvers. 1673 1674 Level: developer 1675 1676 .keywords: TS, compute, Jacobian, matrix 1677 1678 .seealso: TSSetI2Jacobian() 1679 @*/ 1680 PetscErrorCode TSComputeI2Jacobian(TS ts,PetscReal t,Vec U,Vec V,Vec A,PetscReal shiftV,PetscReal shiftA,Mat J,Mat P) 1681 { 1682 DM dm; 1683 TSI2Jacobian I2Jacobian; 1684 void *ctx; 1685 TSRHSJacobian rhsjacobian; 1686 PetscErrorCode ierr; 1687 1688 PetscFunctionBegin; 1689 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1690 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 1691 PetscValidHeaderSpecific(V,VEC_CLASSID,4); 1692 PetscValidHeaderSpecific(A,VEC_CLASSID,5); 1693 PetscValidHeaderSpecific(J,MAT_CLASSID,8); 1694 PetscValidHeaderSpecific(P,MAT_CLASSID,9); 1695 1696 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1697 ierr = DMTSGetI2Jacobian(dm,&I2Jacobian,&ctx);CHKERRQ(ierr); 1698 ierr = DMTSGetRHSJacobian(dm,&rhsjacobian,NULL);CHKERRQ(ierr); 1699 1700 if (!I2Jacobian) { 1701 ierr = TSComputeIJacobian(ts,t,U,A,shiftA,J,P,PETSC_FALSE);CHKERRQ(ierr); 1702 PetscFunctionReturn(0); 1703 } 1704 1705 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,J,P);CHKERRQ(ierr); 1706 1707 PetscStackPush("TS user implicit Jacobian"); 1708 ierr = I2Jacobian(ts,t,U,V,A,shiftV,shiftA,J,P,ctx);CHKERRQ(ierr); 1709 PetscStackPop; 1710 1711 if (rhsjacobian) { 1712 Mat Jrhs,Prhs; MatStructure axpy = DIFFERENT_NONZERO_PATTERN; 1713 ierr = TSGetRHSMats_Private(ts,&Jrhs,&Prhs);CHKERRQ(ierr); 1714 ierr = TSComputeRHSJacobian(ts,t,U,Jrhs,Prhs);CHKERRQ(ierr); 1715 ierr = MatAXPY(J,-1,Jrhs,axpy);CHKERRQ(ierr); 1716 if (P != J) {ierr = MatAXPY(P,-1,Prhs,axpy);CHKERRQ(ierr);} 1717 } 1718 1719 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,J,P);CHKERRQ(ierr); 1720 PetscFunctionReturn(0); 1721 } 1722 1723 /*@ 1724 TS2SetSolution - Sets the initial solution and time derivative vectors 1725 for use by the TS routines handling second order equations. 1726 1727 Logically Collective on TS and Vec 1728 1729 Input Parameters: 1730 + ts - the TS context obtained from TSCreate() 1731 . u - the solution vector 1732 - v - the time derivative vector 1733 1734 Level: beginner 1735 1736 .keywords: TS, timestep, set, solution, initial conditions 1737 @*/ 1738 PetscErrorCode TS2SetSolution(TS ts,Vec u,Vec v) 1739 { 1740 PetscErrorCode ierr; 1741 1742 PetscFunctionBegin; 1743 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1744 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 1745 PetscValidHeaderSpecific(v,VEC_CLASSID,3); 1746 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 1747 ierr = PetscObjectReference((PetscObject)v);CHKERRQ(ierr); 1748 ierr = VecDestroy(&ts->vec_dot);CHKERRQ(ierr); 1749 ts->vec_dot = v; 1750 PetscFunctionReturn(0); 1751 } 1752 1753 /*@ 1754 TS2GetSolution - Returns the solution and time derivative at the present timestep 1755 for second order equations. It is valid to call this routine inside the function 1756 that you are evaluating in order to move to the new timestep. This vector not 1757 changed until the solution at the next timestep has been calculated. 1758 1759 Not Collective, but Vec returned is parallel if TS is parallel 1760 1761 Input Parameter: 1762 . ts - the TS context obtained from TSCreate() 1763 1764 Output Parameter: 1765 + u - the vector containing the solution 1766 - v - the vector containing the time derivative 1767 1768 Level: intermediate 1769 1770 .seealso: TS2SetSolution(), TSGetTimeStep(), TSGetTime() 1771 1772 .keywords: TS, timestep, get, solution 1773 @*/ 1774 PetscErrorCode TS2GetSolution(TS ts,Vec *u,Vec *v) 1775 { 1776 PetscFunctionBegin; 1777 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1778 if (u) PetscValidPointer(u,2); 1779 if (v) PetscValidPointer(v,3); 1780 if (u) *u = ts->vec_sol; 1781 if (v) *v = ts->vec_dot; 1782 PetscFunctionReturn(0); 1783 } 1784 1785 /*@C 1786 TSLoad - Loads a KSP that has been stored in binary with KSPView(). 1787 1788 Collective on PetscViewer 1789 1790 Input Parameters: 1791 + newdm - the newly loaded TS, this needs to have been created with TSCreate() or 1792 some related function before a call to TSLoad(). 1793 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() 1794 1795 Level: intermediate 1796 1797 Notes: 1798 The type is determined by the data in the file, any type set into the TS before this call is ignored. 1799 1800 Notes for advanced users: 1801 Most users should not need to know the details of the binary storage 1802 format, since TSLoad() and TSView() completely hide these details. 1803 But for anyone who's interested, the standard binary matrix storage 1804 format is 1805 .vb 1806 has not yet been determined 1807 .ve 1808 1809 .seealso: PetscViewerBinaryOpen(), TSView(), MatLoad(), VecLoad() 1810 @*/ 1811 PetscErrorCode TSLoad(TS ts, PetscViewer viewer) 1812 { 1813 PetscErrorCode ierr; 1814 PetscBool isbinary; 1815 PetscInt classid; 1816 char type[256]; 1817 DMTS sdm; 1818 DM dm; 1819 1820 PetscFunctionBegin; 1821 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1822 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1823 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1824 if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 1825 1826 ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr); 1827 if (classid != TS_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Not TS next in file"); 1828 ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr); 1829 ierr = TSSetType(ts, type);CHKERRQ(ierr); 1830 if (ts->ops->load) { 1831 ierr = (*ts->ops->load)(ts,viewer);CHKERRQ(ierr); 1832 } 1833 ierr = DMCreate(PetscObjectComm((PetscObject)ts),&dm);CHKERRQ(ierr); 1834 ierr = DMLoad(dm,viewer);CHKERRQ(ierr); 1835 ierr = TSSetDM(ts,dm);CHKERRQ(ierr); 1836 ierr = DMCreateGlobalVector(ts->dm,&ts->vec_sol);CHKERRQ(ierr); 1837 ierr = VecLoad(ts->vec_sol,viewer);CHKERRQ(ierr); 1838 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1839 ierr = DMTSLoad(sdm,viewer);CHKERRQ(ierr); 1840 PetscFunctionReturn(0); 1841 } 1842 1843 #include <petscdraw.h> 1844 #if defined(PETSC_HAVE_SAWS) 1845 #include <petscviewersaws.h> 1846 #endif 1847 /*@C 1848 TSView - Prints the TS data structure. 1849 1850 Collective on TS 1851 1852 Input Parameters: 1853 + ts - the TS context obtained from TSCreate() 1854 - viewer - visualization context 1855 1856 Options Database Key: 1857 . -ts_view - calls TSView() at end of TSStep() 1858 1859 Notes: 1860 The available visualization contexts include 1861 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 1862 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 1863 output where only the first processor opens 1864 the file. All other processors send their 1865 data to the first processor to print. 1866 1867 The user can open an alternative visualization context with 1868 PetscViewerASCIIOpen() - output to a specified file. 1869 1870 Level: beginner 1871 1872 .keywords: TS, timestep, view 1873 1874 .seealso: PetscViewerASCIIOpen() 1875 @*/ 1876 PetscErrorCode TSView(TS ts,PetscViewer viewer) 1877 { 1878 PetscErrorCode ierr; 1879 TSType type; 1880 PetscBool iascii,isstring,isundials,isbinary,isdraw; 1881 DMTS sdm; 1882 #if defined(PETSC_HAVE_SAWS) 1883 PetscBool issaws; 1884 #endif 1885 1886 PetscFunctionBegin; 1887 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1888 if (!viewer) { 1889 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts),&viewer);CHKERRQ(ierr); 1890 } 1891 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1892 PetscCheckSameComm(ts,1,viewer,2); 1893 1894 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1895 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 1896 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1897 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 1898 #if defined(PETSC_HAVE_SAWS) 1899 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 1900 #endif 1901 if (iascii) { 1902 PetscInt tabs; 1903 ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr); 1904 ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)ts)->tablevel);CHKERRQ(ierr); 1905 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer);CHKERRQ(ierr); 1906 if (ts->ops->view) { 1907 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1908 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1909 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1910 } 1911 if (ts->max_steps < PETSC_MAX_INT) { 1912 ierr = PetscViewerASCIIPrintf(viewer," maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr); 1913 } 1914 if (ts->max_time < PETSC_MAX_REAL) { 1915 ierr = PetscViewerASCIIPrintf(viewer," maximum time=%g\n",(double)ts->max_time);CHKERRQ(ierr); 1916 } 1917 if (ts->usessnes) { 1918 PetscBool lin; 1919 if (ts->problem_type == TS_NONLINEAR) { 1920 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solver iterations=%D\n",ts->snes_its);CHKERRQ(ierr); 1921 } 1922 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",ts->ksp_its);CHKERRQ(ierr); 1923 ierr = PetscObjectTypeCompare((PetscObject)ts->snes,SNESKSPONLY,&lin);CHKERRQ(ierr); 1924 ierr = PetscViewerASCIIPrintf(viewer," total number of %slinear solve failures=%D\n",lin ? "" : "non",ts->num_snes_failures);CHKERRQ(ierr); 1925 } 1926 ierr = PetscViewerASCIIPrintf(viewer," total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr); 1927 if (ts->vrtol) { 1928 ierr = PetscViewerASCIIPrintf(viewer," using vector of relative error tolerances, ");CHKERRQ(ierr); 1929 } else { 1930 ierr = PetscViewerASCIIPrintf(viewer," using relative error tolerance of %g, ",(double)ts->rtol);CHKERRQ(ierr); 1931 } 1932 if (ts->vatol) { 1933 ierr = PetscViewerASCIIPrintf(viewer," using vector of absolute error tolerances\n");CHKERRQ(ierr); 1934 } else { 1935 ierr = PetscViewerASCIIPrintf(viewer," using absolute error tolerance of %g\n",(double)ts->atol);CHKERRQ(ierr); 1936 } 1937 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1938 ierr = TSAdaptView(ts->adapt,viewer);CHKERRQ(ierr); 1939 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1940 if (ts->snes && ts->usessnes) { 1941 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1942 ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr); 1943 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1944 } 1945 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1946 ierr = DMTSView(sdm,viewer);CHKERRQ(ierr); 1947 ierr = PetscViewerASCIISetTab(viewer, tabs);CHKERRQ(ierr); 1948 } else if (isstring) { 1949 ierr = TSGetType(ts,&type);CHKERRQ(ierr); 1950 ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr); 1951 } else if (isbinary) { 1952 PetscInt classid = TS_FILE_CLASSID; 1953 MPI_Comm comm; 1954 PetscMPIInt rank; 1955 char type[256]; 1956 1957 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 1958 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 1959 if (!rank) { 1960 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 1961 ierr = PetscStrncpy(type,((PetscObject)ts)->type_name,256);CHKERRQ(ierr); 1962 ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 1963 } 1964 if (ts->ops->view) { 1965 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1966 } 1967 if (ts->adapt) {ierr = TSAdaptView(ts->adapt,viewer);CHKERRQ(ierr);} 1968 ierr = DMView(ts->dm,viewer);CHKERRQ(ierr); 1969 ierr = VecView(ts->vec_sol,viewer);CHKERRQ(ierr); 1970 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1971 ierr = DMTSView(sdm,viewer);CHKERRQ(ierr); 1972 } else if (isdraw) { 1973 PetscDraw draw; 1974 char str[36]; 1975 PetscReal x,y,bottom,h; 1976 1977 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1978 ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr); 1979 ierr = PetscStrcpy(str,"TS: ");CHKERRQ(ierr); 1980 ierr = PetscStrcat(str,((PetscObject)ts)->type_name);CHKERRQ(ierr); 1981 ierr = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLACK,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr); 1982 bottom = y - h; 1983 ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr); 1984 if (ts->ops->view) { 1985 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1986 } 1987 if (ts->adapt) {ierr = TSAdaptView(ts->adapt,viewer);CHKERRQ(ierr);} 1988 if (ts->snes) {ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);} 1989 ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr); 1990 #if defined(PETSC_HAVE_SAWS) 1991 } else if (issaws) { 1992 PetscMPIInt rank; 1993 const char *name; 1994 1995 ierr = PetscObjectGetName((PetscObject)ts,&name);CHKERRQ(ierr); 1996 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1997 if (!((PetscObject)ts)->amsmem && !rank) { 1998 char dir[1024]; 1999 2000 ierr = PetscObjectViewSAWs((PetscObject)ts,viewer);CHKERRQ(ierr); 2001 ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time_step",name);CHKERRQ(ierr); 2002 PetscStackCallSAWs(SAWs_Register,(dir,&ts->steps,1,SAWs_READ,SAWs_INT)); 2003 ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time",name);CHKERRQ(ierr); 2004 PetscStackCallSAWs(SAWs_Register,(dir,&ts->ptime,1,SAWs_READ,SAWs_DOUBLE)); 2005 } 2006 if (ts->ops->view) { 2007 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 2008 } 2009 #endif 2010 } 2011 2012 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2013 ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr); 2014 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2015 PetscFunctionReturn(0); 2016 } 2017 2018 /*@ 2019 TSSetApplicationContext - Sets an optional user-defined context for 2020 the timesteppers. 2021 2022 Logically Collective on TS 2023 2024 Input Parameters: 2025 + ts - the TS context obtained from TSCreate() 2026 - usrP - optional user context 2027 2028 Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this 2029 function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 2030 2031 Level: intermediate 2032 2033 .keywords: TS, timestep, set, application, context 2034 2035 .seealso: TSGetApplicationContext() 2036 @*/ 2037 PetscErrorCode TSSetApplicationContext(TS ts,void *usrP) 2038 { 2039 PetscFunctionBegin; 2040 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2041 ts->user = usrP; 2042 PetscFunctionReturn(0); 2043 } 2044 2045 /*@ 2046 TSGetApplicationContext - Gets the user-defined context for the 2047 timestepper. 2048 2049 Not Collective 2050 2051 Input Parameter: 2052 . ts - the TS context obtained from TSCreate() 2053 2054 Output Parameter: 2055 . usrP - user context 2056 2057 Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this 2058 function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 2059 2060 Level: intermediate 2061 2062 .keywords: TS, timestep, get, application, context 2063 2064 .seealso: TSSetApplicationContext() 2065 @*/ 2066 PetscErrorCode TSGetApplicationContext(TS ts,void *usrP) 2067 { 2068 PetscFunctionBegin; 2069 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2070 *(void**)usrP = ts->user; 2071 PetscFunctionReturn(0); 2072 } 2073 2074 /*@ 2075 TSGetStepNumber - Gets the number of steps completed. 2076 2077 Not Collective 2078 2079 Input Parameter: 2080 . ts - the TS context obtained from TSCreate() 2081 2082 Output Parameter: 2083 . steps - number of steps completed so far 2084 2085 Level: intermediate 2086 2087 .keywords: TS, timestep, get, iteration, number 2088 .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSSetPostStep() 2089 @*/ 2090 PetscErrorCode TSGetStepNumber(TS ts,PetscInt *steps) 2091 { 2092 PetscFunctionBegin; 2093 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2094 PetscValidIntPointer(steps,2); 2095 *steps = ts->steps; 2096 PetscFunctionReturn(0); 2097 } 2098 2099 /*@ 2100 TSSetStepNumber - Sets the number of steps completed. 2101 2102 Logically Collective on TS 2103 2104 Input Parameters: 2105 + ts - the TS context 2106 - steps - number of steps completed so far 2107 2108 Notes: 2109 For most uses of the TS solvers the user need not explicitly call 2110 TSSetStepNumber(), as the step counter is appropriately updated in 2111 TSSolve()/TSStep()/TSRollBack(). Power users may call this routine to 2112 reinitialize timestepping by setting the step counter to zero (and time 2113 to the initial time) to solve a similar problem with different initial 2114 conditions or parameters. Other possible use case is to continue 2115 timestepping from a previously interrupted run in such a way that TS 2116 monitors will be called with a initial nonzero step counter. 2117 2118 Level: advanced 2119 2120 .keywords: TS, timestep, set, iteration, number 2121 .seealso: TSGetStepNumber(), TSSetTime(), TSSetTimeStep(), TSSetSolution() 2122 @*/ 2123 PetscErrorCode TSSetStepNumber(TS ts,PetscInt steps) 2124 { 2125 PetscFunctionBegin; 2126 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2127 PetscValidLogicalCollectiveInt(ts,steps,2); 2128 if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Step number must be non-negative"); 2129 ts->steps = steps; 2130 PetscFunctionReturn(0); 2131 } 2132 2133 /*@ 2134 TSSetTimeStep - Allows one to reset the timestep at any time, 2135 useful for simple pseudo-timestepping codes. 2136 2137 Logically Collective on TS 2138 2139 Input Parameters: 2140 + ts - the TS context obtained from TSCreate() 2141 - time_step - the size of the timestep 2142 2143 Level: intermediate 2144 2145 .seealso: TSGetTimeStep(), TSSetTime() 2146 2147 .keywords: TS, set, timestep 2148 @*/ 2149 PetscErrorCode TSSetTimeStep(TS ts,PetscReal time_step) 2150 { 2151 PetscFunctionBegin; 2152 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2153 PetscValidLogicalCollectiveReal(ts,time_step,2); 2154 ts->time_step = time_step; 2155 PetscFunctionReturn(0); 2156 } 2157 2158 /*@ 2159 TSSetExactFinalTime - Determines whether to adapt the final time step to 2160 match the exact final time, interpolate solution to the exact final time, 2161 or just return at the final time TS computed. 2162 2163 Logically Collective on TS 2164 2165 Input Parameter: 2166 + ts - the time-step context 2167 - eftopt - exact final time option 2168 2169 $ TS_EXACTFINALTIME_STEPOVER - Don't do anything if final time is exceeded 2170 $ TS_EXACTFINALTIME_INTERPOLATE - Interpolate back to final time 2171 $ TS_EXACTFINALTIME_MATCHSTEP - Adapt final time step to match the final time 2172 2173 Options Database: 2174 . -ts_exact_final_time <stepover,interpolate,matchstep> - select the final step at runtime 2175 2176 Warning: If you use the option TS_EXACTFINALTIME_STEPOVER the solution may be at a very different time 2177 then the final time you selected. 2178 2179 Level: beginner 2180 2181 .seealso: TSExactFinalTimeOption, TSGetExactFinalTime() 2182 @*/ 2183 PetscErrorCode TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt) 2184 { 2185 PetscFunctionBegin; 2186 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2187 PetscValidLogicalCollectiveEnum(ts,eftopt,2); 2188 ts->exact_final_time = eftopt; 2189 PetscFunctionReturn(0); 2190 } 2191 2192 /*@ 2193 TSGetExactFinalTime - Gets the exact final time option. 2194 2195 Not Collective 2196 2197 Input Parameter: 2198 . ts - the TS context 2199 2200 Output Parameter: 2201 . eftopt - exact final time option 2202 2203 Level: beginner 2204 2205 .seealso: TSExactFinalTimeOption, TSSetExactFinalTime() 2206 @*/ 2207 PetscErrorCode TSGetExactFinalTime(TS ts,TSExactFinalTimeOption *eftopt) 2208 { 2209 PetscFunctionBegin; 2210 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2211 PetscValidPointer(eftopt,2); 2212 *eftopt = ts->exact_final_time; 2213 PetscFunctionReturn(0); 2214 } 2215 2216 /*@ 2217 TSGetTimeStep - Gets the current timestep size. 2218 2219 Not Collective 2220 2221 Input Parameter: 2222 . ts - the TS context obtained from TSCreate() 2223 2224 Output Parameter: 2225 . dt - the current timestep size 2226 2227 Level: intermediate 2228 2229 .seealso: TSSetTimeStep(), TSGetTime() 2230 2231 .keywords: TS, get, timestep 2232 @*/ 2233 PetscErrorCode TSGetTimeStep(TS ts,PetscReal *dt) 2234 { 2235 PetscFunctionBegin; 2236 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2237 PetscValidRealPointer(dt,2); 2238 *dt = ts->time_step; 2239 PetscFunctionReturn(0); 2240 } 2241 2242 /*@ 2243 TSGetSolution - Returns the solution at the present timestep. It 2244 is valid to call this routine inside the function that you are evaluating 2245 in order to move to the new timestep. This vector not changed until 2246 the solution at the next timestep has been calculated. 2247 2248 Not Collective, but Vec returned is parallel if TS is parallel 2249 2250 Input Parameter: 2251 . ts - the TS context obtained from TSCreate() 2252 2253 Output Parameter: 2254 . v - the vector containing the solution 2255 2256 Note: If you used TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP); this does not return the solution at the requested 2257 final time. It returns the solution at the next timestep. 2258 2259 Level: intermediate 2260 2261 .seealso: TSGetTimeStep(), TSGetTime(), TSGetSolveTime(), TSGetSolutionComponents(), TSSetSolutionFunction() 2262 2263 .keywords: TS, timestep, get, solution 2264 @*/ 2265 PetscErrorCode TSGetSolution(TS ts,Vec *v) 2266 { 2267 PetscFunctionBegin; 2268 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2269 PetscValidPointer(v,2); 2270 *v = ts->vec_sol; 2271 PetscFunctionReturn(0); 2272 } 2273 2274 /*@ 2275 TSGetSolutionComponents - Returns any solution components at the present 2276 timestep, if available for the time integration method being used. 2277 Solution components are quantities that share the same size and 2278 structure as the solution vector. 2279 2280 Not Collective, but Vec returned is parallel if TS is parallel 2281 2282 Parameters : 2283 . ts - the TS context obtained from TSCreate() (input parameter). 2284 . n - If v is PETSC_NULL, then the number of solution components is 2285 returned through n, else the n-th solution component is 2286 returned in v. 2287 . v - the vector containing the n-th solution component 2288 (may be PETSC_NULL to use this function to find out 2289 the number of solutions components). 2290 2291 Level: advanced 2292 2293 .seealso: TSGetSolution() 2294 2295 .keywords: TS, timestep, get, solution 2296 @*/ 2297 PetscErrorCode TSGetSolutionComponents(TS ts,PetscInt *n,Vec *v) 2298 { 2299 PetscErrorCode ierr; 2300 2301 PetscFunctionBegin; 2302 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2303 if (!ts->ops->getsolutioncomponents) *n = 0; 2304 else { 2305 ierr = (*ts->ops->getsolutioncomponents)(ts,n,v);CHKERRQ(ierr); 2306 } 2307 PetscFunctionReturn(0); 2308 } 2309 2310 /*@ 2311 TSGetAuxSolution - Returns an auxiliary solution at the present 2312 timestep, if available for the time integration method being used. 2313 2314 Not Collective, but Vec returned is parallel if TS is parallel 2315 2316 Parameters : 2317 . ts - the TS context obtained from TSCreate() (input parameter). 2318 . v - the vector containing the auxiliary solution 2319 2320 Level: intermediate 2321 2322 .seealso: TSGetSolution() 2323 2324 .keywords: TS, timestep, get, solution 2325 @*/ 2326 PetscErrorCode TSGetAuxSolution(TS ts,Vec *v) 2327 { 2328 PetscErrorCode ierr; 2329 2330 PetscFunctionBegin; 2331 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2332 if (ts->ops->getauxsolution) { 2333 ierr = (*ts->ops->getauxsolution)(ts,v);CHKERRQ(ierr); 2334 } else { 2335 ierr = VecZeroEntries(*v); CHKERRQ(ierr); 2336 } 2337 PetscFunctionReturn(0); 2338 } 2339 2340 /*@ 2341 TSGetTimeError - Returns the estimated error vector, if the chosen 2342 TSType has an error estimation functionality. 2343 2344 Not Collective, but Vec returned is parallel if TS is parallel 2345 2346 Note: MUST call after TSSetUp() 2347 2348 Parameters : 2349 . ts - the TS context obtained from TSCreate() (input parameter). 2350 . n - current estimate (n=0) or previous one (n=-1) 2351 . v - the vector containing the error (same size as the solution). 2352 2353 Level: intermediate 2354 2355 .seealso: TSGetSolution(), TSSetTimeError() 2356 2357 .keywords: TS, timestep, get, error 2358 @*/ 2359 PetscErrorCode TSGetTimeError(TS ts,PetscInt n,Vec *v) 2360 { 2361 PetscErrorCode ierr; 2362 2363 PetscFunctionBegin; 2364 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2365 if (ts->ops->gettimeerror) { 2366 ierr = (*ts->ops->gettimeerror)(ts,n,v);CHKERRQ(ierr); 2367 } else { 2368 ierr = VecZeroEntries(*v);CHKERRQ(ierr); 2369 } 2370 PetscFunctionReturn(0); 2371 } 2372 2373 /*@ 2374 TSSetTimeError - Sets the estimated error vector, if the chosen 2375 TSType has an error estimation functionality. This can be used 2376 to restart such a time integrator with a given error vector. 2377 2378 Not Collective, but Vec returned is parallel if TS is parallel 2379 2380 Parameters : 2381 . ts - the TS context obtained from TSCreate() (input parameter). 2382 . v - the vector containing the error (same size as the solution). 2383 2384 Level: intermediate 2385 2386 .seealso: TSSetSolution(), TSGetTimeError) 2387 2388 .keywords: TS, timestep, get, error 2389 @*/ 2390 PetscErrorCode TSSetTimeError(TS ts,Vec v) 2391 { 2392 PetscErrorCode ierr; 2393 2394 PetscFunctionBegin; 2395 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2396 if (!ts->setupcalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetUp() first"); 2397 if (ts->ops->settimeerror) { 2398 ierr = (*ts->ops->settimeerror)(ts,v);CHKERRQ(ierr); 2399 } 2400 PetscFunctionReturn(0); 2401 } 2402 2403 /* ----- Routines to initialize and destroy a timestepper ---- */ 2404 /*@ 2405 TSSetProblemType - Sets the type of problem to be solved. 2406 2407 Not collective 2408 2409 Input Parameters: 2410 + ts - The TS 2411 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 2412 .vb 2413 U_t - A U = 0 (linear) 2414 U_t - A(t) U = 0 (linear) 2415 F(t,U,U_t) = 0 (nonlinear) 2416 .ve 2417 2418 Level: beginner 2419 2420 .keywords: TS, problem type 2421 .seealso: TSSetUp(), TSProblemType, TS 2422 @*/ 2423 PetscErrorCode TSSetProblemType(TS ts, TSProblemType type) 2424 { 2425 PetscErrorCode ierr; 2426 2427 PetscFunctionBegin; 2428 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2429 ts->problem_type = type; 2430 if (type == TS_LINEAR) { 2431 SNES snes; 2432 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2433 ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr); 2434 } 2435 PetscFunctionReturn(0); 2436 } 2437 2438 /*@C 2439 TSGetProblemType - Gets the type of problem to be solved. 2440 2441 Not collective 2442 2443 Input Parameter: 2444 . ts - The TS 2445 2446 Output Parameter: 2447 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 2448 .vb 2449 M U_t = A U 2450 M(t) U_t = A(t) U 2451 F(t,U,U_t) 2452 .ve 2453 2454 Level: beginner 2455 2456 .keywords: TS, problem type 2457 .seealso: TSSetUp(), TSProblemType, TS 2458 @*/ 2459 PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type) 2460 { 2461 PetscFunctionBegin; 2462 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2463 PetscValidIntPointer(type,2); 2464 *type = ts->problem_type; 2465 PetscFunctionReturn(0); 2466 } 2467 2468 /*@ 2469 TSSetUp - Sets up the internal data structures for the later use 2470 of a timestepper. 2471 2472 Collective on TS 2473 2474 Input Parameter: 2475 . ts - the TS context obtained from TSCreate() 2476 2477 Notes: 2478 For basic use of the TS solvers the user need not explicitly call 2479 TSSetUp(), since these actions will automatically occur during 2480 the call to TSStep() or TSSolve(). However, if one wishes to control this 2481 phase separately, TSSetUp() should be called after TSCreate() 2482 and optional routines of the form TSSetXXX(), but before TSStep() and TSSolve(). 2483 2484 Level: advanced 2485 2486 .keywords: TS, timestep, setup 2487 2488 .seealso: TSCreate(), TSStep(), TSDestroy(), TSSolve() 2489 @*/ 2490 PetscErrorCode TSSetUp(TS ts) 2491 { 2492 PetscErrorCode ierr; 2493 DM dm; 2494 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 2495 PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 2496 TSIFunction ifun; 2497 TSIJacobian ijac; 2498 TSI2Jacobian i2jac; 2499 TSRHSJacobian rhsjac; 2500 PetscBool isnone; 2501 2502 PetscFunctionBegin; 2503 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2504 if (ts->setupcalled) PetscFunctionReturn(0); 2505 2506 if (!((PetscObject)ts)->type_name) { 2507 ierr = TSGetIFunction(ts,NULL,&ifun,NULL);CHKERRQ(ierr); 2508 ierr = TSSetType(ts,ifun ? TSBEULER : TSEULER);CHKERRQ(ierr); 2509 } 2510 2511 if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first"); 2512 2513 if (ts->rhsjacobian.reuse) { 2514 Mat Amat,Pmat; 2515 SNES snes; 2516 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2517 ierr = SNESGetJacobian(snes,&Amat,&Pmat,NULL,NULL);CHKERRQ(ierr); 2518 /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would 2519 * have displaced the RHS matrix */ 2520 if (Amat == ts->Arhs) { 2521 /* we need to copy the values of the matrix because for the constant Jacobian case the user will never set the numerical values in this new location */ 2522 ierr = MatDuplicate(ts->Arhs,MAT_COPY_VALUES,&Amat);CHKERRQ(ierr); 2523 ierr = SNESSetJacobian(snes,Amat,NULL,NULL,NULL);CHKERRQ(ierr); 2524 ierr = MatDestroy(&Amat);CHKERRQ(ierr); 2525 } 2526 if (Pmat == ts->Brhs) { 2527 ierr = MatDuplicate(ts->Brhs,MAT_COPY_VALUES,&Pmat);CHKERRQ(ierr); 2528 ierr = SNESSetJacobian(snes,NULL,Pmat,NULL,NULL);CHKERRQ(ierr); 2529 ierr = MatDestroy(&Pmat);CHKERRQ(ierr); 2530 } 2531 } 2532 2533 ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr); 2534 ierr = TSAdaptSetDefaultType(ts->adapt,ts->default_adapt_type);CHKERRQ(ierr); 2535 2536 if (ts->ops->setup) { 2537 ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr); 2538 } 2539 2540 /* Attempt to check/preset a default value for the exact final time option */ 2541 ierr = PetscObjectTypeCompare((PetscObject)ts->adapt,TSADAPTNONE,&isnone);CHKERRQ(ierr); 2542 if (!isnone && ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) 2543 ts->exact_final_time = TS_EXACTFINALTIME_MATCHSTEP; 2544 2545 /* In the case where we've set a DMTSFunction or what have you, we need the default SNESFunction 2546 to be set right but can't do it elsewhere due to the overreliance on ctx=ts. 2547 */ 2548 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2549 ierr = DMSNESGetFunction(dm,&func,NULL);CHKERRQ(ierr); 2550 if (!func) { 2551 ierr = DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr); 2552 } 2553 /* If the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it. 2554 Otherwise, the SNES will use coloring internally to form the Jacobian. 2555 */ 2556 ierr = DMSNESGetJacobian(dm,&jac,NULL);CHKERRQ(ierr); 2557 ierr = DMTSGetIJacobian(dm,&ijac,NULL);CHKERRQ(ierr); 2558 ierr = DMTSGetI2Jacobian(dm,&i2jac,NULL);CHKERRQ(ierr); 2559 ierr = DMTSGetRHSJacobian(dm,&rhsjac,NULL);CHKERRQ(ierr); 2560 if (!jac && (ijac || i2jac || rhsjac)) { 2561 ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr); 2562 } 2563 2564 /* if time integration scheme has a starting method, call it */ 2565 if (ts->ops->startingmethod) { 2566 ierr = (*ts->ops->startingmethod)(ts);CHKERRQ(ierr); 2567 } 2568 2569 ts->setupcalled = PETSC_TRUE; 2570 PetscFunctionReturn(0); 2571 } 2572 2573 /*@ 2574 TSReset - Resets a TS context and removes any allocated Vecs and Mats. 2575 2576 Collective on TS 2577 2578 Input Parameter: 2579 . ts - the TS context obtained from TSCreate() 2580 2581 Level: beginner 2582 2583 .keywords: TS, timestep, reset 2584 2585 .seealso: TSCreate(), TSSetup(), TSDestroy() 2586 @*/ 2587 PetscErrorCode TSReset(TS ts) 2588 { 2589 PetscErrorCode ierr; 2590 2591 PetscFunctionBegin; 2592 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2593 2594 if (ts->ops->reset) { 2595 ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr); 2596 } 2597 if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);} 2598 if (ts->adapt) {ierr = TSAdaptReset(ts->adapt);CHKERRQ(ierr);} 2599 2600 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 2601 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 2602 ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr); 2603 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 2604 ierr = VecDestroy(&ts->vec_dot);CHKERRQ(ierr); 2605 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 2606 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 2607 ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr); 2608 2609 ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr); 2610 ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr); 2611 2612 ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 2613 ierr = VecDestroy(&ts->vec_costintegral);CHKERRQ(ierr); 2614 ierr = VecDestroy(&ts->vec_costintegrand);CHKERRQ(ierr); 2615 ierr = MatDestroy(&ts->mat_sensip);CHKERRQ(ierr); 2616 2617 ts->setupcalled = PETSC_FALSE; 2618 PetscFunctionReturn(0); 2619 } 2620 2621 /*@ 2622 TSDestroy - Destroys the timestepper context that was created 2623 with TSCreate(). 2624 2625 Collective on TS 2626 2627 Input Parameter: 2628 . ts - the TS context obtained from TSCreate() 2629 2630 Level: beginner 2631 2632 .keywords: TS, timestepper, destroy 2633 2634 .seealso: TSCreate(), TSSetUp(), TSSolve() 2635 @*/ 2636 PetscErrorCode TSDestroy(TS *ts) 2637 { 2638 PetscErrorCode ierr; 2639 2640 PetscFunctionBegin; 2641 if (!*ts) PetscFunctionReturn(0); 2642 PetscValidHeaderSpecific((*ts),TS_CLASSID,1); 2643 if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);} 2644 2645 ierr = TSReset((*ts));CHKERRQ(ierr); 2646 2647 /* if memory was published with SAWs then destroy it */ 2648 ierr = PetscObjectSAWsViewOff((PetscObject)*ts);CHKERRQ(ierr); 2649 if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);} 2650 2651 ierr = TSTrajectoryDestroy(&(*ts)->trajectory);CHKERRQ(ierr); 2652 2653 ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr); 2654 ierr = TSEventDestroy(&(*ts)->event);CHKERRQ(ierr); 2655 2656 ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr); 2657 ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr); 2658 ierr = TSMonitorCancel((*ts));CHKERRQ(ierr); 2659 ierr = TSAdjointMonitorCancel((*ts));CHKERRQ(ierr); 2660 2661 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 2662 PetscFunctionReturn(0); 2663 } 2664 2665 /*@ 2666 TSGetSNES - Returns the SNES (nonlinear solver) associated with 2667 a TS (timestepper) context. Valid only for nonlinear problems. 2668 2669 Not Collective, but SNES is parallel if TS is parallel 2670 2671 Input Parameter: 2672 . ts - the TS context obtained from TSCreate() 2673 2674 Output Parameter: 2675 . snes - the nonlinear solver context 2676 2677 Notes: 2678 The user can then directly manipulate the SNES context to set various 2679 options, etc. Likewise, the user can then extract and manipulate the 2680 KSP, KSP, and PC contexts as well. 2681 2682 TSGetSNES() does not work for integrators that do not use SNES; in 2683 this case TSGetSNES() returns NULL in snes. 2684 2685 Level: beginner 2686 2687 .keywords: timestep, get, SNES 2688 @*/ 2689 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 2690 { 2691 PetscErrorCode ierr; 2692 2693 PetscFunctionBegin; 2694 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2695 PetscValidPointer(snes,2); 2696 if (!ts->snes) { 2697 ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr); 2698 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2699 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);CHKERRQ(ierr); 2700 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 2701 if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 2702 if (ts->problem_type == TS_LINEAR) { 2703 ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); 2704 } 2705 } 2706 *snes = ts->snes; 2707 PetscFunctionReturn(0); 2708 } 2709 2710 /*@ 2711 TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context 2712 2713 Collective 2714 2715 Input Parameter: 2716 + ts - the TS context obtained from TSCreate() 2717 - snes - the nonlinear solver context 2718 2719 Notes: 2720 Most users should have the TS created by calling TSGetSNES() 2721 2722 Level: developer 2723 2724 .keywords: timestep, set, SNES 2725 @*/ 2726 PetscErrorCode TSSetSNES(TS ts,SNES snes) 2727 { 2728 PetscErrorCode ierr; 2729 PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*); 2730 2731 PetscFunctionBegin; 2732 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2733 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 2734 ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr); 2735 ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr); 2736 2737 ts->snes = snes; 2738 2739 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2740 ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr); 2741 if (func == SNESTSFormJacobian) { 2742 ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr); 2743 } 2744 PetscFunctionReturn(0); 2745 } 2746 2747 /*@ 2748 TSGetKSP - Returns the KSP (linear solver) associated with 2749 a TS (timestepper) context. 2750 2751 Not Collective, but KSP is parallel if TS is parallel 2752 2753 Input Parameter: 2754 . ts - the TS context obtained from TSCreate() 2755 2756 Output Parameter: 2757 . ksp - the nonlinear solver context 2758 2759 Notes: 2760 The user can then directly manipulate the KSP context to set various 2761 options, etc. Likewise, the user can then extract and manipulate the 2762 KSP and PC contexts as well. 2763 2764 TSGetKSP() does not work for integrators that do not use KSP; 2765 in this case TSGetKSP() returns NULL in ksp. 2766 2767 Level: beginner 2768 2769 .keywords: timestep, get, KSP 2770 @*/ 2771 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 2772 { 2773 PetscErrorCode ierr; 2774 SNES snes; 2775 2776 PetscFunctionBegin; 2777 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2778 PetscValidPointer(ksp,2); 2779 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 2780 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 2781 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2782 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 2783 PetscFunctionReturn(0); 2784 } 2785 2786 /* ----------- Routines to set solver parameters ---------- */ 2787 2788 /*@ 2789 TSSetMaxSteps - Sets the maximum number of steps to use. 2790 2791 Logically Collective on TS 2792 2793 Input Parameters: 2794 + ts - the TS context obtained from TSCreate() 2795 - maxsteps - maximum number of steps to use 2796 2797 Options Database Keys: 2798 . -ts_max_steps <maxsteps> - Sets maxsteps 2799 2800 Notes: 2801 The default maximum number of steps is 5000 2802 2803 Level: intermediate 2804 2805 .keywords: TS, timestep, set, maximum, steps 2806 2807 .seealso: TSGetMaxSteps(), TSSetMaxTime(), TSSetExactFinalTime() 2808 @*/ 2809 PetscErrorCode TSSetMaxSteps(TS ts,PetscInt maxsteps) 2810 { 2811 PetscFunctionBegin; 2812 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2813 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 2814 if (maxsteps < 0 ) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of steps must be non-negative"); 2815 ts->max_steps = maxsteps; 2816 PetscFunctionReturn(0); 2817 } 2818 2819 /*@ 2820 TSGetMaxSteps - Gets the maximum number of steps to use. 2821 2822 Not Collective 2823 2824 Input Parameters: 2825 . ts - the TS context obtained from TSCreate() 2826 2827 Output Parameter: 2828 . maxsteps - maximum number of steps to use 2829 2830 Level: advanced 2831 2832 .keywords: TS, timestep, get, maximum, steps 2833 2834 .seealso: TSSetMaxSteps(), TSGetMaxTime(), TSSetMaxTime() 2835 @*/ 2836 PetscErrorCode TSGetMaxSteps(TS ts,PetscInt *maxsteps) 2837 { 2838 PetscFunctionBegin; 2839 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2840 PetscValidIntPointer(maxsteps,2); 2841 *maxsteps = ts->max_steps; 2842 PetscFunctionReturn(0); 2843 } 2844 2845 /*@ 2846 TSSetMaxTime - Sets the maximum (or final) time for timestepping. 2847 2848 Logically Collective on TS 2849 2850 Input Parameters: 2851 + ts - the TS context obtained from TSCreate() 2852 - maxtime - final time to step to 2853 2854 Options Database Keys: 2855 . -ts_max_time <maxtime> - Sets maxtime 2856 2857 Notes: 2858 The default maximum time is 5.0 2859 2860 Level: intermediate 2861 2862 .keywords: TS, timestep, set, maximum, time 2863 2864 .seealso: TSGetMaxTime(), TSSetMaxSteps(), TSSetExactFinalTime() 2865 @*/ 2866 PetscErrorCode TSSetMaxTime(TS ts,PetscReal maxtime) 2867 { 2868 PetscFunctionBegin; 2869 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2870 PetscValidLogicalCollectiveReal(ts,maxtime,2); 2871 ts->max_time = maxtime; 2872 PetscFunctionReturn(0); 2873 } 2874 2875 /*@ 2876 TSGetMaxTime - Gets the maximum (or final) time for timestepping. 2877 2878 Not Collective 2879 2880 Input Parameters: 2881 . ts - the TS context obtained from TSCreate() 2882 2883 Output Parameter: 2884 . maxtime - final time to step to 2885 2886 Level: advanced 2887 2888 .keywords: TS, timestep, get, maximum, time 2889 2890 .seealso: TSSetMaxTime(), TSGetMaxSteps(), TSSetMaxSteps() 2891 @*/ 2892 PetscErrorCode TSGetMaxTime(TS ts,PetscReal *maxtime) 2893 { 2894 PetscFunctionBegin; 2895 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2896 PetscValidRealPointer(maxtime,2); 2897 *maxtime = ts->max_time; 2898 PetscFunctionReturn(0); 2899 } 2900 2901 /*@ 2902 TSSetInitialTimeStep - Deprecated, use TSSetTime() and TSSetTimeStep(). 2903 2904 Level: deprecated 2905 2906 @*/ 2907 PetscErrorCode TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step) 2908 { 2909 PetscErrorCode ierr; 2910 PetscFunctionBegin; 2911 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2912 ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr); 2913 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 2914 PetscFunctionReturn(0); 2915 } 2916 2917 /*@ 2918 TSGetDuration - Deprecated, use TSGetMaxSteps() and TSGetMaxTime(). 2919 2920 Level: deprecated 2921 2922 @*/ 2923 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 2924 { 2925 PetscFunctionBegin; 2926 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2927 if (maxsteps) { 2928 PetscValidIntPointer(maxsteps,2); 2929 *maxsteps = ts->max_steps; 2930 } 2931 if (maxtime) { 2932 PetscValidScalarPointer(maxtime,3); 2933 *maxtime = ts->max_time; 2934 } 2935 PetscFunctionReturn(0); 2936 } 2937 2938 /*@ 2939 TSSetDuration - Deprecated, use TSSetMaxSteps() and TSSetMaxTime(). 2940 2941 Level: deprecated 2942 2943 @*/ 2944 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 2945 { 2946 PetscFunctionBegin; 2947 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2948 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 2949 PetscValidLogicalCollectiveReal(ts,maxtime,2); 2950 if (maxsteps >= 0) ts->max_steps = maxsteps; 2951 if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime; 2952 PetscFunctionReturn(0); 2953 } 2954 2955 /*@ 2956 TSGetTimeStepNumber - Deprecated, use TSGetStepNumber(). 2957 2958 Level: deprecated 2959 2960 @*/ 2961 PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt *steps) { return TSGetStepNumber(ts,steps); } 2962 2963 /*@ 2964 TSGetTotalSteps - Deprecated, use TSGetStepNumber(). 2965 2966 Level: deprecated 2967 2968 @*/ 2969 PetscErrorCode TSGetTotalSteps(TS ts,PetscInt *steps) { return TSGetStepNumber(ts,steps); } 2970 2971 /*@ 2972 TSSetSolution - Sets the initial solution vector 2973 for use by the TS routines. 2974 2975 Logically Collective on TS and Vec 2976 2977 Input Parameters: 2978 + ts - the TS context obtained from TSCreate() 2979 - u - the solution vector 2980 2981 Level: beginner 2982 2983 .keywords: TS, timestep, set, solution, initial values 2984 2985 .seealso: TSSetSolutionFunction(), TSGetSolution(), TSCreate() 2986 @*/ 2987 PetscErrorCode TSSetSolution(TS ts,Vec u) 2988 { 2989 PetscErrorCode ierr; 2990 DM dm; 2991 2992 PetscFunctionBegin; 2993 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2994 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 2995 ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr); 2996 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 2997 ts->vec_sol = u; 2998 2999 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 3000 ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr); 3001 PetscFunctionReturn(0); 3002 } 3003 3004 /*@C 3005 TSSetPreStep - Sets the general-purpose function 3006 called once at the beginning of each time step. 3007 3008 Logically Collective on TS 3009 3010 Input Parameters: 3011 + ts - The TS context obtained from TSCreate() 3012 - func - The function 3013 3014 Calling sequence of func: 3015 . func (TS ts); 3016 3017 Level: intermediate 3018 3019 .keywords: TS, timestep 3020 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep(), TSRestartStep() 3021 @*/ 3022 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 3023 { 3024 PetscFunctionBegin; 3025 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3026 ts->prestep = func; 3027 PetscFunctionReturn(0); 3028 } 3029 3030 /*@ 3031 TSPreStep - Runs the user-defined pre-step function. 3032 3033 Collective on TS 3034 3035 Input Parameters: 3036 . ts - The TS context obtained from TSCreate() 3037 3038 Notes: 3039 TSPreStep() is typically used within time stepping implementations, 3040 so most users would not generally call this routine themselves. 3041 3042 Level: developer 3043 3044 .keywords: TS, timestep 3045 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep() 3046 @*/ 3047 PetscErrorCode TSPreStep(TS ts) 3048 { 3049 PetscErrorCode ierr; 3050 3051 PetscFunctionBegin; 3052 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3053 if (ts->prestep) { 3054 Vec U; 3055 PetscObjectState sprev,spost; 3056 3057 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3058 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3059 PetscStackCallStandard((*ts->prestep),(ts)); 3060 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3061 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3062 } 3063 PetscFunctionReturn(0); 3064 } 3065 3066 /*@C 3067 TSSetPreStage - Sets the general-purpose function 3068 called once at the beginning of each stage. 3069 3070 Logically Collective on TS 3071 3072 Input Parameters: 3073 + ts - The TS context obtained from TSCreate() 3074 - func - The function 3075 3076 Calling sequence of func: 3077 . PetscErrorCode func(TS ts, PetscReal stagetime); 3078 3079 Level: intermediate 3080 3081 Note: 3082 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3083 The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being 3084 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3085 3086 .keywords: TS, timestep 3087 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3088 @*/ 3089 PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal)) 3090 { 3091 PetscFunctionBegin; 3092 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3093 ts->prestage = func; 3094 PetscFunctionReturn(0); 3095 } 3096 3097 /*@C 3098 TSSetPostStage - Sets the general-purpose function 3099 called once at the end of each stage. 3100 3101 Logically Collective on TS 3102 3103 Input Parameters: 3104 + ts - The TS context obtained from TSCreate() 3105 - func - The function 3106 3107 Calling sequence of func: 3108 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y); 3109 3110 Level: intermediate 3111 3112 Note: 3113 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3114 The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being 3115 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3116 3117 .keywords: TS, timestep 3118 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3119 @*/ 3120 PetscErrorCode TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*)) 3121 { 3122 PetscFunctionBegin; 3123 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3124 ts->poststage = func; 3125 PetscFunctionReturn(0); 3126 } 3127 3128 /*@C 3129 TSSetPostEvaluate - Sets the general-purpose function 3130 called once at the end of each step evaluation. 3131 3132 Logically Collective on TS 3133 3134 Input Parameters: 3135 + ts - The TS context obtained from TSCreate() 3136 - func - The function 3137 3138 Calling sequence of func: 3139 . PetscErrorCode func(TS ts); 3140 3141 Level: intermediate 3142 3143 Note: 3144 Semantically, TSSetPostEvaluate() differs from TSSetPostStep() since the function it sets is called before event-handling 3145 thus guaranteeing the same solution (computed by the time-stepper) will be passed to it. On the other hand, TSPostStep() 3146 may be passed a different solution, possibly changed by the event handler. TSPostEvaluate() is called after the next step 3147 solution is evaluated allowing to modify it, if need be. The solution can be obtained with TSGetSolution(), the time step 3148 with TSGetTimeStep(), and the time at the start of the step is available via TSGetTime() 3149 3150 .keywords: TS, timestep 3151 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3152 @*/ 3153 PetscErrorCode TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS)) 3154 { 3155 PetscFunctionBegin; 3156 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3157 ts->postevaluate = func; 3158 PetscFunctionReturn(0); 3159 } 3160 3161 /*@ 3162 TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage() 3163 3164 Collective on TS 3165 3166 Input Parameters: 3167 . ts - The TS context obtained from TSCreate() 3168 stagetime - The absolute time of the current stage 3169 3170 Notes: 3171 TSPreStage() is typically used within time stepping implementations, 3172 most users would not generally call this routine themselves. 3173 3174 Level: developer 3175 3176 .keywords: TS, timestep 3177 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3178 @*/ 3179 PetscErrorCode TSPreStage(TS ts, PetscReal stagetime) 3180 { 3181 PetscErrorCode ierr; 3182 3183 PetscFunctionBegin; 3184 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3185 if (ts->prestage) { 3186 PetscStackCallStandard((*ts->prestage),(ts,stagetime)); 3187 } 3188 PetscFunctionReturn(0); 3189 } 3190 3191 /*@ 3192 TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage() 3193 3194 Collective on TS 3195 3196 Input Parameters: 3197 . ts - The TS context obtained from TSCreate() 3198 stagetime - The absolute time of the current stage 3199 stageindex - Stage number 3200 Y - Array of vectors (of size = total number 3201 of stages) with the stage solutions 3202 3203 Notes: 3204 TSPostStage() is typically used within time stepping implementations, 3205 most users would not generally call this routine themselves. 3206 3207 Level: developer 3208 3209 .keywords: TS, timestep 3210 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3211 @*/ 3212 PetscErrorCode TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y) 3213 { 3214 PetscErrorCode ierr; 3215 3216 PetscFunctionBegin; 3217 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3218 if (ts->poststage) { 3219 PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y)); 3220 } 3221 PetscFunctionReturn(0); 3222 } 3223 3224 /*@ 3225 TSPostEvaluate - Runs the user-defined post-evaluate function set using TSSetPostEvaluate() 3226 3227 Collective on TS 3228 3229 Input Parameters: 3230 . ts - The TS context obtained from TSCreate() 3231 3232 Notes: 3233 TSPostEvaluate() is typically used within time stepping implementations, 3234 most users would not generally call this routine themselves. 3235 3236 Level: developer 3237 3238 .keywords: TS, timestep 3239 .seealso: TSSetPostEvaluate(), TSSetPreStep(), TSPreStep(), TSPostStep() 3240 @*/ 3241 PetscErrorCode TSPostEvaluate(TS ts) 3242 { 3243 PetscErrorCode ierr; 3244 3245 PetscFunctionBegin; 3246 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3247 if (ts->postevaluate) { 3248 Vec U; 3249 PetscObjectState sprev,spost; 3250 3251 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3252 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3253 PetscStackCallStandard((*ts->postevaluate),(ts)); 3254 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3255 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3256 } 3257 PetscFunctionReturn(0); 3258 } 3259 3260 /*@C 3261 TSSetPostStep - Sets the general-purpose function 3262 called once at the end of each time step. 3263 3264 Logically Collective on TS 3265 3266 Input Parameters: 3267 + ts - The TS context obtained from TSCreate() 3268 - func - The function 3269 3270 Calling sequence of func: 3271 $ func (TS ts); 3272 3273 Notes: 3274 The function set by TSSetPostStep() is called after each successful step. The solution vector X 3275 obtained by TSGetSolution() may be different than that computed at the step end if the event handler 3276 locates an event and TSPostEvent() modifies it. Use TSSetPostEvaluate() if an unmodified solution is needed instead. 3277 3278 Level: intermediate 3279 3280 .keywords: TS, timestep 3281 .seealso: TSSetPreStep(), TSSetPreStage(), TSSetPostEvaluate(), TSGetTimeStep(), TSGetStepNumber(), TSGetTime(), TSRestartStep() 3282 @*/ 3283 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 3284 { 3285 PetscFunctionBegin; 3286 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3287 ts->poststep = func; 3288 PetscFunctionReturn(0); 3289 } 3290 3291 /*@ 3292 TSPostStep - Runs the user-defined post-step function. 3293 3294 Collective on TS 3295 3296 Input Parameters: 3297 . ts - The TS context obtained from TSCreate() 3298 3299 Notes: 3300 TSPostStep() is typically used within time stepping implementations, 3301 so most users would not generally call this routine themselves. 3302 3303 Level: developer 3304 3305 .keywords: TS, timestep 3306 @*/ 3307 PetscErrorCode TSPostStep(TS ts) 3308 { 3309 PetscErrorCode ierr; 3310 3311 PetscFunctionBegin; 3312 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3313 if (ts->poststep) { 3314 Vec U; 3315 PetscObjectState sprev,spost; 3316 3317 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3318 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3319 PetscStackCallStandard((*ts->poststep),(ts)); 3320 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3321 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3322 } 3323 PetscFunctionReturn(0); 3324 } 3325 3326 /* ------------ Routines to set performance monitoring options ----------- */ 3327 3328 /*@C 3329 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 3330 timestep to display the iteration's progress. 3331 3332 Logically Collective on TS 3333 3334 Input Parameters: 3335 + ts - the TS context obtained from TSCreate() 3336 . monitor - monitoring routine 3337 . mctx - [optional] user-defined context for private data for the 3338 monitor routine (use NULL if no context is desired) 3339 - monitordestroy - [optional] routine that frees monitor context 3340 (may be NULL) 3341 3342 Calling sequence of monitor: 3343 $ PetscErrorCode monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx) 3344 3345 + ts - the TS context 3346 . steps - iteration number (after the final time step the monitor routine may be called with a step of -1, this indicates the solution has been interpolated to this time) 3347 . time - current time 3348 . u - current iterate 3349 - mctx - [optional] monitoring context 3350 3351 Notes: 3352 This routine adds an additional monitor to the list of monitors that 3353 already has been loaded. 3354 3355 Fortran notes: Only a single monitor function can be set for each TS object 3356 3357 Level: intermediate 3358 3359 .keywords: TS, timestep, set, monitor 3360 3361 .seealso: TSMonitorDefault(), TSMonitorCancel() 3362 @*/ 3363 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 3364 { 3365 PetscErrorCode ierr; 3366 PetscInt i; 3367 PetscBool identical; 3368 3369 PetscFunctionBegin; 3370 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3371 for (i=0; i<ts->numbermonitors;i++) { 3372 ierr = PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical);CHKERRQ(ierr); 3373 if (identical) PetscFunctionReturn(0); 3374 } 3375 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3376 ts->monitor[ts->numbermonitors] = monitor; 3377 ts->monitordestroy[ts->numbermonitors] = mdestroy; 3378 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 3379 PetscFunctionReturn(0); 3380 } 3381 3382 /*@C 3383 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 3384 3385 Logically Collective on TS 3386 3387 Input Parameters: 3388 . ts - the TS context obtained from TSCreate() 3389 3390 Notes: 3391 There is no way to remove a single, specific monitor. 3392 3393 Level: intermediate 3394 3395 .keywords: TS, timestep, set, monitor 3396 3397 .seealso: TSMonitorDefault(), TSMonitorSet() 3398 @*/ 3399 PetscErrorCode TSMonitorCancel(TS ts) 3400 { 3401 PetscErrorCode ierr; 3402 PetscInt i; 3403 3404 PetscFunctionBegin; 3405 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3406 for (i=0; i<ts->numbermonitors; i++) { 3407 if (ts->monitordestroy[i]) { 3408 ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 3409 } 3410 } 3411 ts->numbermonitors = 0; 3412 PetscFunctionReturn(0); 3413 } 3414 3415 /*@C 3416 TSMonitorDefault - The Default monitor, prints the timestep and time for each step 3417 3418 Level: intermediate 3419 3420 .keywords: TS, set, monitor 3421 3422 .seealso: TSMonitorSet() 3423 @*/ 3424 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf) 3425 { 3426 PetscErrorCode ierr; 3427 PetscViewer viewer = vf->viewer; 3428 PetscBool iascii,ibinary; 3429 3430 PetscFunctionBegin; 3431 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 3432 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 3433 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 3434 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 3435 if (iascii) { 3436 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3437 if (step == -1){ /* this indicates it is an interpolated solution */ 3438 ierr = PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps);CHKERRQ(ierr); 3439 } else { 3440 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr); 3441 } 3442 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3443 } else if (ibinary) { 3444 PetscMPIInt rank; 3445 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 3446 if (!rank) { 3447 PetscBool skipHeader; 3448 PetscInt classid = REAL_FILE_CLASSID; 3449 3450 ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr); 3451 if (!skipHeader) { 3452 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 3453 } 3454 ierr = PetscRealView(1,&ptime,viewer);CHKERRQ(ierr); 3455 } else { 3456 ierr = PetscRealView(0,&ptime,viewer);CHKERRQ(ierr); 3457 } 3458 } 3459 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 3460 PetscFunctionReturn(0); 3461 } 3462 3463 /*@ 3464 TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval 3465 3466 Collective on TS 3467 3468 Input Argument: 3469 + ts - time stepping context 3470 - t - time to interpolate to 3471 3472 Output Argument: 3473 . U - state at given time 3474 3475 Level: intermediate 3476 3477 Developer Notes: 3478 TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints. 3479 3480 .keywords: TS, set 3481 3482 .seealso: TSSetExactFinalTime(), TSSolve() 3483 @*/ 3484 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U) 3485 { 3486 PetscErrorCode ierr; 3487 3488 PetscFunctionBegin; 3489 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3490 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3491 if (t < ts->ptime_prev || t > ts->ptime) SETERRQ3(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Requested time %g not in last time steps [%g,%g]",t,(double)ts->ptime_prev,(double)ts->ptime); 3492 if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name); 3493 ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr); 3494 PetscFunctionReturn(0); 3495 } 3496 3497 /*@ 3498 TSStep - Steps one time step 3499 3500 Collective on TS 3501 3502 Input Parameter: 3503 . ts - the TS context obtained from TSCreate() 3504 3505 Level: developer 3506 3507 Notes: 3508 The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine. 3509 3510 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 3511 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 3512 3513 This may over-step the final time provided in TSSetMaxTime() depending on the time-step used. TSSolve() interpolates to exactly the 3514 time provided in TSSetMaxTime(). One can use TSInterpolate() to determine an interpolated solution within the final timestep. 3515 3516 .keywords: TS, timestep, solve 3517 3518 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate() 3519 @*/ 3520 PetscErrorCode TSStep(TS ts) 3521 { 3522 PetscErrorCode ierr; 3523 static PetscBool cite = PETSC_FALSE; 3524 PetscReal ptime; 3525 3526 PetscFunctionBegin; 3527 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3528 ierr = PetscCitationsRegister("@techreport{tspaper,\n" 3529 " title = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n" 3530 " author = {Shrirang Abhyankar and Jed Brown and Emil Constantinescu and Debojyoti Ghosh and Barry F. Smith},\n" 3531 " type = {Preprint},\n" 3532 " number = {ANL/MCS-P5061-0114},\n" 3533 " institution = {Argonne National Laboratory},\n" 3534 " year = {2014}\n}\n",&cite);CHKERRQ(ierr); 3535 3536 ierr = TSSetUp(ts);CHKERRQ(ierr); 3537 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 3538 3539 if (ts->max_time >= PETSC_MAX_REAL && ts->max_steps == PETSC_MAX_INT) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetMaxTime() or TSSetMaxSteps(), or use -ts_max_time <time> or -ts_max_steps <steps>"); 3540 if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetExactFinalTime() or use -ts_exact_final_time <stepover,interpolate,matchstep> before calling TSStep()"); 3541 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP && !ts->adapt) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Since TS is not adaptive you cannot use TS_EXACTFINALTIME_MATCHSTEP, suggest TS_EXACTFINALTIME_INTERPOLATE"); 3542 3543 if (!ts->steps) ts->ptime_prev = ts->ptime; 3544 ptime = ts->ptime; ts->ptime_prev_rollback = ts->ptime_prev; 3545 ts->reason = TS_CONVERGED_ITERATING; 3546 if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3547 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3548 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 3549 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3550 ts->ptime_prev = ptime; 3551 ts->steps++; 3552 ts->steprollback = PETSC_FALSE; 3553 ts->steprestart = PETSC_FALSE; 3554 3555 if (ts->reason < 0) { 3556 if (ts->errorifstepfailed) { 3557 if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_snes_failures or make negative to attempt recovery",TSConvergedReasons[ts->reason]); 3558 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 3559 } 3560 } else if (!ts->reason) { 3561 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3562 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3563 } 3564 PetscFunctionReturn(0); 3565 } 3566 3567 /*@ 3568 TSEvaluateWLTE - Evaluate the weighted local truncation error norm 3569 at the end of a time step with a given order of accuracy. 3570 3571 Collective on TS 3572 3573 Input Arguments: 3574 + ts - time stepping context 3575 . wnormtype - norm type, either NORM_2 or NORM_INFINITY 3576 - order - optional, desired order for the error evaluation or PETSC_DECIDE 3577 3578 Output Arguments: 3579 + order - optional, the actual order of the error evaluation 3580 - wlte - the weighted local truncation error norm 3581 3582 Level: advanced 3583 3584 Notes: 3585 If the timestepper cannot evaluate the error in a particular step 3586 (eg. in the first step or restart steps after event handling), 3587 this routine returns wlte=-1.0 . 3588 3589 .seealso: TSStep(), TSAdapt, TSErrorWeightedNorm() 3590 @*/ 3591 PetscErrorCode TSEvaluateWLTE(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte) 3592 { 3593 PetscErrorCode ierr; 3594 3595 PetscFunctionBegin; 3596 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3597 PetscValidType(ts,1); 3598 PetscValidLogicalCollectiveEnum(ts,wnormtype,4); 3599 if (order) PetscValidIntPointer(order,3); 3600 if (order) PetscValidLogicalCollectiveInt(ts,*order,3); 3601 PetscValidRealPointer(wlte,4); 3602 if (wnormtype != NORM_2 && wnormtype != NORM_INFINITY) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 3603 if (!ts->ops->evaluatewlte) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateWLTE not implemented for type '%s'",((PetscObject)ts)->type_name); 3604 ierr = (*ts->ops->evaluatewlte)(ts,wnormtype,order,wlte);CHKERRQ(ierr); 3605 PetscFunctionReturn(0); 3606 } 3607 3608 /*@ 3609 TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy. 3610 3611 Collective on TS 3612 3613 Input Arguments: 3614 + ts - time stepping context 3615 . order - desired order of accuracy 3616 - done - whether the step was evaluated at this order (pass NULL to generate an error if not available) 3617 3618 Output Arguments: 3619 . U - state at the end of the current step 3620 3621 Level: advanced 3622 3623 Notes: 3624 This function cannot be called until all stages have been evaluated. 3625 It is normally called by adaptive controllers before a step has been accepted and may also be called by the user after TSStep() has returned. 3626 3627 .seealso: TSStep(), TSAdapt 3628 @*/ 3629 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done) 3630 { 3631 PetscErrorCode ierr; 3632 3633 PetscFunctionBegin; 3634 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3635 PetscValidType(ts,1); 3636 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3637 if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3638 ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr); 3639 PetscFunctionReturn(0); 3640 } 3641 3642 /*@ 3643 TSSolve - Steps the requested number of timesteps. 3644 3645 Collective on TS 3646 3647 Input Parameter: 3648 + ts - the TS context obtained from TSCreate() 3649 - u - the solution vector (can be null if TSSetSolution() was used and TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP) was not used, 3650 otherwise must contain the initial conditions and will contain the solution at the final requested time 3651 3652 Level: beginner 3653 3654 Notes: 3655 The final time returned by this function may be different from the time of the internally 3656 held state accessible by TSGetSolution() and TSGetTime() because the method may have 3657 stepped over the final time. 3658 3659 .keywords: TS, timestep, solve 3660 3661 .seealso: TSCreate(), TSSetSolution(), TSStep(), TSGetTime(), TSGetSolveTime() 3662 @*/ 3663 PetscErrorCode TSSolve(TS ts,Vec u) 3664 { 3665 Vec solution; 3666 PetscErrorCode ierr; 3667 3668 PetscFunctionBegin; 3669 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3670 if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2); 3671 3672 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && u) { /* Need ts->vec_sol to be distinct so it is not overwritten when we interpolate at the end */ 3673 if (!ts->vec_sol || u == ts->vec_sol) { 3674 ierr = VecDuplicate(u,&solution);CHKERRQ(ierr); 3675 ierr = TSSetSolution(ts,solution);CHKERRQ(ierr); 3676 ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */ 3677 } 3678 ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr); 3679 if (ts->forward_solve) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Sensitivity analysis does not support the mode TS_EXACTFINALTIME_INTERPOLATE"); 3680 } else if (u) { 3681 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 3682 } 3683 ierr = TSSetUp(ts);CHKERRQ(ierr); 3684 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 3685 3686 if (ts->max_time >= PETSC_MAX_REAL && ts->max_steps == PETSC_MAX_INT) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetMaxTime() or TSSetMaxSteps(), or use -ts_max_time <time> or -ts_max_steps <steps>"); 3687 if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetExactFinalTime() or use -ts_exact_final_time <stepover,interpolate,matchstep> before calling TSSolve()"); 3688 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP && !ts->adapt) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Since TS is not adaptive you cannot use TS_EXACTFINALTIME_MATCHSTEP, suggest TS_EXACTFINALTIME_INTERPOLATE"); 3689 3690 if (ts->forward_solve) { 3691 ierr = TSForwardSetUp(ts);CHKERRQ(ierr); 3692 } 3693 3694 /* reset number of steps only when the step is not restarted. ARKIMEX 3695 restarts the step after an event. Resetting these counters in such case causes 3696 TSTrajectory to incorrectly save the output files 3697 */ 3698 /* reset time step and iteration counters */ 3699 if (!ts->steps) { 3700 ts->ksp_its = 0; 3701 ts->snes_its = 0; 3702 ts->num_snes_failures = 0; 3703 ts->reject = 0; 3704 ts->steprestart = PETSC_TRUE; 3705 ts->steprollback = PETSC_FALSE; 3706 } 3707 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP && ts->ptime + ts->time_step > ts->max_time) ts->time_step = ts->max_time - ts->ptime; 3708 ts->reason = TS_CONVERGED_ITERATING; 3709 3710 ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr); 3711 3712 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 3713 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 3714 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 3715 ts->solvetime = ts->ptime; 3716 solution = ts->vec_sol; 3717 } else { /* Step the requested number of timesteps. */ 3718 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3719 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3720 3721 if (!ts->steps) { 3722 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3723 ierr = TSEventInitialize(ts->event,ts,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3724 } 3725 3726 while (!ts->reason) { 3727 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3728 if (!ts->steprollback) { 3729 ierr = TSPreStep(ts);CHKERRQ(ierr); 3730 } 3731 ierr = TSStep(ts);CHKERRQ(ierr); 3732 if (ts->testjacobian) { 3733 ierr = TSRHSJacobianTest(ts,NULL);CHKERRQ(ierr); 3734 } 3735 if (ts->testjacobiantranspose) { 3736 ierr = TSRHSJacobianTestTranspose(ts,NULL);CHKERRQ(ierr); 3737 } 3738 if (ts->vec_costintegral && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */ 3739 ierr = TSForwardCostIntegral(ts);CHKERRQ(ierr); 3740 } 3741 if (ts->forward_solve) { /* compute forward sensitivities before event handling because postevent() may change RHS and jump conditions may have to be applied */ 3742 ierr = TSForwardStep(ts);CHKERRQ(ierr); 3743 } 3744 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 3745 ierr = TSEventHandler(ts);CHKERRQ(ierr); /* The right-hand side may be changed due to event. Be careful with Any computation using the RHS information after this point. */ 3746 if (ts->steprollback) { 3747 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 3748 } 3749 if (!ts->steprollback) { 3750 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3751 ierr = TSPostStep(ts);CHKERRQ(ierr); 3752 } 3753 } 3754 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3755 3756 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) { 3757 ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr); 3758 ts->solvetime = ts->max_time; 3759 solution = u; 3760 ierr = TSMonitor(ts,-1,ts->solvetime,solution);CHKERRQ(ierr); 3761 } else { 3762 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 3763 ts->solvetime = ts->ptime; 3764 solution = ts->vec_sol; 3765 } 3766 } 3767 3768 ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr); 3769 ierr = VecViewFromOptions(solution,NULL,"-ts_view_solution");CHKERRQ(ierr); 3770 ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr); 3771 if (ts->adjoint_solve) { 3772 ierr = TSAdjointSolve(ts);CHKERRQ(ierr); 3773 } 3774 PetscFunctionReturn(0); 3775 } 3776 3777 /*@C 3778 TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet() 3779 3780 Collective on TS 3781 3782 Input Parameters: 3783 + ts - time stepping context obtained from TSCreate() 3784 . step - step number that has just completed 3785 . ptime - model time of the state 3786 - u - state at the current model time 3787 3788 Notes: 3789 TSMonitor() is typically used automatically within the time stepping implementations. 3790 Users would almost never call this routine directly. 3791 3792 A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions 3793 3794 Level: developer 3795 3796 .keywords: TS, timestep 3797 @*/ 3798 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u) 3799 { 3800 DM dm; 3801 PetscInt i,n = ts->numbermonitors; 3802 PetscErrorCode ierr; 3803 3804 PetscFunctionBegin; 3805 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3806 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 3807 3808 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 3809 ierr = DMSetOutputSequenceNumber(dm,step,ptime);CHKERRQ(ierr); 3810 3811 ierr = VecLockPush(u);CHKERRQ(ierr); 3812 for (i=0; i<n; i++) { 3813 ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr); 3814 } 3815 ierr = VecLockPop(u);CHKERRQ(ierr); 3816 PetscFunctionReturn(0); 3817 } 3818 3819 /* ------------------------------------------------------------------------*/ 3820 /*@C 3821 TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with 3822 TS to monitor the solution process graphically in various ways 3823 3824 Collective on TS 3825 3826 Input Parameters: 3827 + host - the X display to open, or null for the local machine 3828 . label - the title to put in the title bar 3829 . x, y - the screen coordinates of the upper left coordinate of the window 3830 . m, n - the screen width and height in pixels 3831 - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 3832 3833 Output Parameter: 3834 . ctx - the context 3835 3836 Options Database Key: 3837 + -ts_monitor_lg_timestep - automatically sets line graph monitor 3838 + -ts_monitor_lg_timestep_log - automatically sets line graph monitor 3839 . -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables()) 3840 . -ts_monitor_lg_error - monitor the error 3841 . -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep 3842 . -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep 3843 - -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true 3844 3845 Notes: 3846 Use TSMonitorLGCtxDestroy() to destroy. 3847 3848 One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform() 3849 3850 Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the 3851 first argument (if that TS object does not have a TSMonitorLGCtx associated with it the function call is ignored) and the second takes a TSMonitorLGCtx object 3852 as the first argument. 3853 3854 One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames() 3855 3856 Level: intermediate 3857 3858 .keywords: TS, monitor, line graph, residual 3859 3860 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(), 3861 TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 3862 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 3863 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 3864 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 3865 3866 @*/ 3867 PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx) 3868 { 3869 PetscDraw draw; 3870 PetscErrorCode ierr; 3871 3872 PetscFunctionBegin; 3873 ierr = PetscNew(ctx);CHKERRQ(ierr); 3874 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr); 3875 ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); 3876 ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr); 3877 ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr); 3878 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 3879 (*ctx)->howoften = howoften; 3880 PetscFunctionReturn(0); 3881 } 3882 3883 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx) 3884 { 3885 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 3886 PetscReal x = ptime,y; 3887 PetscErrorCode ierr; 3888 3889 PetscFunctionBegin; 3890 if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */ 3891 if (!step) { 3892 PetscDrawAxis axis; 3893 const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step"; 3894 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 3895 ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel);CHKERRQ(ierr); 3896 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 3897 } 3898 ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr); 3899 if (ctx->semilogy) y = PetscLog10Real(y); 3900 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 3901 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 3902 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 3903 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 3904 } 3905 PetscFunctionReturn(0); 3906 } 3907 3908 /*@C 3909 TSMonitorLGCtxDestroy - Destroys a line graph context that was created 3910 with TSMonitorLGCtxCreate(). 3911 3912 Collective on TSMonitorLGCtx 3913 3914 Input Parameter: 3915 . ctx - the monitor context 3916 3917 Level: intermediate 3918 3919 .keywords: TS, monitor, line graph, destroy 3920 3921 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 3922 @*/ 3923 PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 3924 { 3925 PetscErrorCode ierr; 3926 3927 PetscFunctionBegin; 3928 if ((*ctx)->transformdestroy) { 3929 ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr); 3930 } 3931 ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr); 3932 ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr); 3933 ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr); 3934 ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr); 3935 ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr); 3936 ierr = PetscFree(*ctx);CHKERRQ(ierr); 3937 PetscFunctionReturn(0); 3938 } 3939 3940 /*@ 3941 TSGetTime - Gets the time of the most recently completed step. 3942 3943 Not Collective 3944 3945 Input Parameter: 3946 . ts - the TS context obtained from TSCreate() 3947 3948 Output Parameter: 3949 . t - the current time. This time may not corresponds to the final time set with TSSetMaxTime(), use TSGetSolveTime(). 3950 3951 Level: beginner 3952 3953 Note: 3954 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 3955 TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 3956 3957 .seealso: TSGetSolveTime(), TSSetTime(), TSGetTimeStep() 3958 3959 .keywords: TS, get, time 3960 @*/ 3961 PetscErrorCode TSGetTime(TS ts,PetscReal *t) 3962 { 3963 PetscFunctionBegin; 3964 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3965 PetscValidRealPointer(t,2); 3966 *t = ts->ptime; 3967 PetscFunctionReturn(0); 3968 } 3969 3970 /*@ 3971 TSGetPrevTime - Gets the starting time of the previously completed step. 3972 3973 Not Collective 3974 3975 Input Parameter: 3976 . ts - the TS context obtained from TSCreate() 3977 3978 Output Parameter: 3979 . t - the previous time 3980 3981 Level: beginner 3982 3983 .seealso: TSGetTime(), TSGetSolveTime(), TSGetTimeStep() 3984 3985 .keywords: TS, get, time 3986 @*/ 3987 PetscErrorCode TSGetPrevTime(TS ts,PetscReal *t) 3988 { 3989 PetscFunctionBegin; 3990 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3991 PetscValidRealPointer(t,2); 3992 *t = ts->ptime_prev; 3993 PetscFunctionReturn(0); 3994 } 3995 3996 /*@ 3997 TSSetTime - Allows one to reset the time. 3998 3999 Logically Collective on TS 4000 4001 Input Parameters: 4002 + ts - the TS context obtained from TSCreate() 4003 - time - the time 4004 4005 Level: intermediate 4006 4007 .seealso: TSGetTime(), TSSetMaxSteps() 4008 4009 .keywords: TS, set, time 4010 @*/ 4011 PetscErrorCode TSSetTime(TS ts, PetscReal t) 4012 { 4013 PetscFunctionBegin; 4014 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4015 PetscValidLogicalCollectiveReal(ts,t,2); 4016 ts->ptime = t; 4017 PetscFunctionReturn(0); 4018 } 4019 4020 /*@C 4021 TSSetOptionsPrefix - Sets the prefix used for searching for all 4022 TS options in the database. 4023 4024 Logically Collective on TS 4025 4026 Input Parameter: 4027 + ts - The TS context 4028 - prefix - The prefix to prepend to all option names 4029 4030 Notes: 4031 A hyphen (-) must NOT be given at the beginning of the prefix name. 4032 The first character of all runtime options is AUTOMATICALLY the 4033 hyphen. 4034 4035 Level: advanced 4036 4037 .keywords: TS, set, options, prefix, database 4038 4039 .seealso: TSSetFromOptions() 4040 4041 @*/ 4042 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 4043 { 4044 PetscErrorCode ierr; 4045 SNES snes; 4046 4047 PetscFunctionBegin; 4048 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4049 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4050 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4051 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4052 PetscFunctionReturn(0); 4053 } 4054 4055 /*@C 4056 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 4057 TS options in the database. 4058 4059 Logically Collective on TS 4060 4061 Input Parameter: 4062 + ts - The TS context 4063 - prefix - The prefix to prepend to all option names 4064 4065 Notes: 4066 A hyphen (-) must NOT be given at the beginning of the prefix name. 4067 The first character of all runtime options is AUTOMATICALLY the 4068 hyphen. 4069 4070 Level: advanced 4071 4072 .keywords: TS, append, options, prefix, database 4073 4074 .seealso: TSGetOptionsPrefix() 4075 4076 @*/ 4077 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 4078 { 4079 PetscErrorCode ierr; 4080 SNES snes; 4081 4082 PetscFunctionBegin; 4083 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4084 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4085 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4086 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4087 PetscFunctionReturn(0); 4088 } 4089 4090 /*@C 4091 TSGetOptionsPrefix - Sets the prefix used for searching for all 4092 TS options in the database. 4093 4094 Not Collective 4095 4096 Input Parameter: 4097 . ts - The TS context 4098 4099 Output Parameter: 4100 . prefix - A pointer to the prefix string used 4101 4102 Notes: On the fortran side, the user should pass in a string 'prifix' of 4103 sufficient length to hold the prefix. 4104 4105 Level: intermediate 4106 4107 .keywords: TS, get, options, prefix, database 4108 4109 .seealso: TSAppendOptionsPrefix() 4110 @*/ 4111 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 4112 { 4113 PetscErrorCode ierr; 4114 4115 PetscFunctionBegin; 4116 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4117 PetscValidPointer(prefix,2); 4118 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4119 PetscFunctionReturn(0); 4120 } 4121 4122 /*@C 4123 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 4124 4125 Not Collective, but parallel objects are returned if TS is parallel 4126 4127 Input Parameter: 4128 . ts - The TS context obtained from TSCreate() 4129 4130 Output Parameters: 4131 + Amat - The (approximate) Jacobian J of G, where U_t = G(U,t) (or NULL) 4132 . Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat (or NULL) 4133 . func - Function to compute the Jacobian of the RHS (or NULL) 4134 - ctx - User-defined context for Jacobian evaluation routine (or NULL) 4135 4136 Notes: You can pass in NULL for any return argument you do not need. 4137 4138 Level: intermediate 4139 4140 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4141 4142 .keywords: TS, timestep, get, matrix, Jacobian 4143 @*/ 4144 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx) 4145 { 4146 PetscErrorCode ierr; 4147 DM dm; 4148 4149 PetscFunctionBegin; 4150 if (Amat || Pmat) { 4151 SNES snes; 4152 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4153 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4154 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4155 } 4156 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4157 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 4158 PetscFunctionReturn(0); 4159 } 4160 4161 /*@C 4162 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 4163 4164 Not Collective, but parallel objects are returned if TS is parallel 4165 4166 Input Parameter: 4167 . ts - The TS context obtained from TSCreate() 4168 4169 Output Parameters: 4170 + Amat - The (approximate) Jacobian of F(t,U,U_t) 4171 . Pmat - The matrix from which the preconditioner is constructed, often the same as Amat 4172 . f - The function to compute the matrices 4173 - ctx - User-defined context for Jacobian evaluation routine 4174 4175 Notes: You can pass in NULL for any return argument you do not need. 4176 4177 Level: advanced 4178 4179 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4180 4181 .keywords: TS, timestep, get, matrix, Jacobian 4182 @*/ 4183 PetscErrorCode TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx) 4184 { 4185 PetscErrorCode ierr; 4186 DM dm; 4187 4188 PetscFunctionBegin; 4189 if (Amat || Pmat) { 4190 SNES snes; 4191 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4192 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4193 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4194 } 4195 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4196 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 4197 PetscFunctionReturn(0); 4198 } 4199 4200 /*@C 4201 TSMonitorDrawSolution - Monitors progress of the TS solvers by calling 4202 VecView() for the solution at each timestep 4203 4204 Collective on TS 4205 4206 Input Parameters: 4207 + ts - the TS context 4208 . step - current time-step 4209 . ptime - current time 4210 - dummy - either a viewer or NULL 4211 4212 Options Database: 4213 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4214 4215 Notes: the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial 4216 will look bad 4217 4218 Level: intermediate 4219 4220 .keywords: TS, vector, monitor, view 4221 4222 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4223 @*/ 4224 PetscErrorCode TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4225 { 4226 PetscErrorCode ierr; 4227 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4228 PetscDraw draw; 4229 4230 PetscFunctionBegin; 4231 if (!step && ictx->showinitial) { 4232 if (!ictx->initialsolution) { 4233 ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr); 4234 } 4235 ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr); 4236 } 4237 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4238 4239 if (ictx->showinitial) { 4240 PetscReal pause; 4241 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 4242 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 4243 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 4244 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 4245 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 4246 } 4247 ierr = VecView(u,ictx->viewer);CHKERRQ(ierr); 4248 if (ictx->showtimestepandtime) { 4249 PetscReal xl,yl,xr,yr,h; 4250 char time[32]; 4251 4252 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4253 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4254 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4255 h = yl + .95*(yr - yl); 4256 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4257 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4258 } 4259 4260 if (ictx->showinitial) { 4261 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 4262 } 4263 PetscFunctionReturn(0); 4264 } 4265 4266 /*@C 4267 TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram 4268 4269 Collective on TS 4270 4271 Input Parameters: 4272 + ts - the TS context 4273 . step - current time-step 4274 . ptime - current time 4275 - dummy - either a viewer or NULL 4276 4277 Level: intermediate 4278 4279 .keywords: TS, vector, monitor, view 4280 4281 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4282 @*/ 4283 PetscErrorCode TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4284 { 4285 PetscErrorCode ierr; 4286 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4287 PetscDraw draw; 4288 PetscDrawAxis axis; 4289 PetscInt n; 4290 PetscMPIInt size; 4291 PetscReal U0,U1,xl,yl,xr,yr,h; 4292 char time[32]; 4293 const PetscScalar *U; 4294 4295 PetscFunctionBegin; 4296 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRQ(ierr); 4297 if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs"); 4298 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 4299 if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns"); 4300 4301 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4302 ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr); 4303 ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr); 4304 if (!step) { 4305 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 4306 ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr); 4307 } 4308 4309 ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr); 4310 U0 = PetscRealPart(U[0]); 4311 U1 = PetscRealPart(U[1]); 4312 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 4313 if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0); 4314 4315 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 4316 ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr); 4317 if (ictx->showtimestepandtime) { 4318 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4319 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4320 h = yl + .95*(yr - yl); 4321 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4322 } 4323 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 4324 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4325 ierr = PetscDrawPause(draw);CHKERRQ(ierr); 4326 ierr = PetscDrawSave(draw);CHKERRQ(ierr); 4327 PetscFunctionReturn(0); 4328 } 4329 4330 /*@C 4331 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 4332 4333 Collective on TS 4334 4335 Input Parameters: 4336 . ctx - the monitor context 4337 4338 Level: intermediate 4339 4340 .keywords: TS, vector, monitor, view 4341 4342 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 4343 @*/ 4344 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 4345 { 4346 PetscErrorCode ierr; 4347 4348 PetscFunctionBegin; 4349 ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr); 4350 ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr); 4351 ierr = PetscFree(*ictx);CHKERRQ(ierr); 4352 PetscFunctionReturn(0); 4353 } 4354 4355 /*@C 4356 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 4357 4358 Collective on TS 4359 4360 Input Parameter: 4361 . ts - time-step context 4362 4363 Output Patameter: 4364 . ctx - the monitor context 4365 4366 Options Database: 4367 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4368 4369 Level: intermediate 4370 4371 .keywords: TS, vector, monitor, view 4372 4373 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 4374 @*/ 4375 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 4376 { 4377 PetscErrorCode ierr; 4378 4379 PetscFunctionBegin; 4380 ierr = PetscNew(ctx);CHKERRQ(ierr); 4381 ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr); 4382 ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr); 4383 4384 (*ctx)->howoften = howoften; 4385 (*ctx)->showinitial = PETSC_FALSE; 4386 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr); 4387 4388 (*ctx)->showtimestepandtime = PETSC_FALSE; 4389 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr); 4390 PetscFunctionReturn(0); 4391 } 4392 4393 /*@C 4394 TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling 4395 VecView() for the solution provided by TSSetSolutionFunction() at each timestep 4396 4397 Collective on TS 4398 4399 Input Parameters: 4400 + ts - the TS context 4401 . step - current time-step 4402 . ptime - current time 4403 - dummy - either a viewer or NULL 4404 4405 Options Database: 4406 . -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 4407 4408 Level: intermediate 4409 4410 .keywords: TS, vector, monitor, view 4411 4412 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 4413 @*/ 4414 PetscErrorCode TSMonitorDrawSolutionFunction(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4415 { 4416 PetscErrorCode ierr; 4417 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 4418 PetscViewer viewer = ctx->viewer; 4419 Vec work; 4420 4421 PetscFunctionBegin; 4422 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4423 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 4424 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 4425 ierr = VecView(work,viewer);CHKERRQ(ierr); 4426 ierr = VecDestroy(&work);CHKERRQ(ierr); 4427 PetscFunctionReturn(0); 4428 } 4429 4430 /*@C 4431 TSMonitorDrawError - Monitors progress of the TS solvers by calling 4432 VecView() for the error at each timestep 4433 4434 Collective on TS 4435 4436 Input Parameters: 4437 + ts - the TS context 4438 . step - current time-step 4439 . ptime - current time 4440 - dummy - either a viewer or NULL 4441 4442 Options Database: 4443 . -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 4444 4445 Level: intermediate 4446 4447 .keywords: TS, vector, monitor, view 4448 4449 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 4450 @*/ 4451 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4452 { 4453 PetscErrorCode ierr; 4454 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 4455 PetscViewer viewer = ctx->viewer; 4456 Vec work; 4457 4458 PetscFunctionBegin; 4459 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4460 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 4461 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 4462 ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr); 4463 ierr = VecView(work,viewer);CHKERRQ(ierr); 4464 ierr = VecDestroy(&work);CHKERRQ(ierr); 4465 PetscFunctionReturn(0); 4466 } 4467 4468 #include <petsc/private/dmimpl.h> 4469 /*@ 4470 TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS 4471 4472 Logically Collective on TS and DM 4473 4474 Input Parameters: 4475 + ts - the ODE integrator object 4476 - dm - the dm, cannot be NULL 4477 4478 Level: intermediate 4479 4480 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 4481 @*/ 4482 PetscErrorCode TSSetDM(TS ts,DM dm) 4483 { 4484 PetscErrorCode ierr; 4485 SNES snes; 4486 DMTS tsdm; 4487 4488 PetscFunctionBegin; 4489 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4490 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 4491 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 4492 if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */ 4493 if (ts->dm->dmts && !dm->dmts) { 4494 ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr); 4495 ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr); 4496 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 4497 tsdm->originaldm = dm; 4498 } 4499 } 4500 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 4501 } 4502 ts->dm = dm; 4503 4504 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4505 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 4506 PetscFunctionReturn(0); 4507 } 4508 4509 /*@ 4510 TSGetDM - Gets the DM that may be used by some preconditioners 4511 4512 Not Collective 4513 4514 Input Parameter: 4515 . ts - the preconditioner context 4516 4517 Output Parameter: 4518 . dm - the dm 4519 4520 Level: intermediate 4521 4522 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 4523 @*/ 4524 PetscErrorCode TSGetDM(TS ts,DM *dm) 4525 { 4526 PetscErrorCode ierr; 4527 4528 PetscFunctionBegin; 4529 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4530 if (!ts->dm) { 4531 ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr); 4532 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 4533 } 4534 *dm = ts->dm; 4535 PetscFunctionReturn(0); 4536 } 4537 4538 /*@ 4539 SNESTSFormFunction - Function to evaluate nonlinear residual 4540 4541 Logically Collective on SNES 4542 4543 Input Parameter: 4544 + snes - nonlinear solver 4545 . U - the current state at which to evaluate the residual 4546 - ctx - user context, must be a TS 4547 4548 Output Parameter: 4549 . F - the nonlinear residual 4550 4551 Notes: 4552 This function is not normally called by users and is automatically registered with the SNES used by TS. 4553 It is most frequently passed to MatFDColoringSetFunction(). 4554 4555 Level: advanced 4556 4557 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 4558 @*/ 4559 PetscErrorCode SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx) 4560 { 4561 TS ts = (TS)ctx; 4562 PetscErrorCode ierr; 4563 4564 PetscFunctionBegin; 4565 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4566 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 4567 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 4568 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 4569 ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr); 4570 PetscFunctionReturn(0); 4571 } 4572 4573 /*@ 4574 SNESTSFormJacobian - Function to evaluate the Jacobian 4575 4576 Collective on SNES 4577 4578 Input Parameter: 4579 + snes - nonlinear solver 4580 . U - the current state at which to evaluate the residual 4581 - ctx - user context, must be a TS 4582 4583 Output Parameter: 4584 + A - the Jacobian 4585 . B - the preconditioning matrix (may be the same as A) 4586 - flag - indicates any structure change in the matrix 4587 4588 Notes: 4589 This function is not normally called by users and is automatically registered with the SNES used by TS. 4590 4591 Level: developer 4592 4593 .seealso: SNESSetJacobian() 4594 @*/ 4595 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx) 4596 { 4597 TS ts = (TS)ctx; 4598 PetscErrorCode ierr; 4599 4600 PetscFunctionBegin; 4601 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4602 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 4603 PetscValidPointer(A,3); 4604 PetscValidHeaderSpecific(A,MAT_CLASSID,3); 4605 PetscValidPointer(B,4); 4606 PetscValidHeaderSpecific(B,MAT_CLASSID,4); 4607 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 4608 ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr); 4609 PetscFunctionReturn(0); 4610 } 4611 4612 /*@C 4613 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only 4614 4615 Collective on TS 4616 4617 Input Arguments: 4618 + ts - time stepping context 4619 . t - time at which to evaluate 4620 . U - state at which to evaluate 4621 - ctx - context 4622 4623 Output Arguments: 4624 . F - right hand side 4625 4626 Level: intermediate 4627 4628 Notes: 4629 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 4630 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 4631 4632 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 4633 @*/ 4634 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx) 4635 { 4636 PetscErrorCode ierr; 4637 Mat Arhs,Brhs; 4638 4639 PetscFunctionBegin; 4640 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 4641 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 4642 ierr = MatMult(Arhs,U,F);CHKERRQ(ierr); 4643 PetscFunctionReturn(0); 4644 } 4645 4646 /*@C 4647 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 4648 4649 Collective on TS 4650 4651 Input Arguments: 4652 + ts - time stepping context 4653 . t - time at which to evaluate 4654 . U - state at which to evaluate 4655 - ctx - context 4656 4657 Output Arguments: 4658 + A - pointer to operator 4659 . B - pointer to preconditioning matrix 4660 - flg - matrix structure flag 4661 4662 Level: intermediate 4663 4664 Notes: 4665 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 4666 4667 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 4668 @*/ 4669 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx) 4670 { 4671 PetscFunctionBegin; 4672 PetscFunctionReturn(0); 4673 } 4674 4675 /*@C 4676 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 4677 4678 Collective on TS 4679 4680 Input Arguments: 4681 + ts - time stepping context 4682 . t - time at which to evaluate 4683 . U - state at which to evaluate 4684 . Udot - time derivative of state vector 4685 - ctx - context 4686 4687 Output Arguments: 4688 . F - left hand side 4689 4690 Level: intermediate 4691 4692 Notes: 4693 The assumption here is that the left hand side is of the form A*Udot (and not A*Udot + B*U). For other cases, the 4694 user is required to write their own TSComputeIFunction. 4695 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 4696 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 4697 4698 Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U 4699 4700 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear() 4701 @*/ 4702 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx) 4703 { 4704 PetscErrorCode ierr; 4705 Mat A,B; 4706 4707 PetscFunctionBegin; 4708 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 4709 ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr); 4710 ierr = MatMult(A,Udot,F);CHKERRQ(ierr); 4711 PetscFunctionReturn(0); 4712 } 4713 4714 /*@C 4715 TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE 4716 4717 Collective on TS 4718 4719 Input Arguments: 4720 + ts - time stepping context 4721 . t - time at which to evaluate 4722 . U - state at which to evaluate 4723 . Udot - time derivative of state vector 4724 . shift - shift to apply 4725 - ctx - context 4726 4727 Output Arguments: 4728 + A - pointer to operator 4729 . B - pointer to preconditioning matrix 4730 - flg - matrix structure flag 4731 4732 Level: advanced 4733 4734 Notes: 4735 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 4736 4737 It is only appropriate for problems of the form 4738 4739 $ M Udot = F(U,t) 4740 4741 where M is constant and F is non-stiff. The user must pass M to TSSetIJacobian(). The current implementation only 4742 works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing 4743 an implicit operator of the form 4744 4745 $ shift*M + J 4746 4747 where J is the Jacobian of -F(U). Support may be added in a future version of PETSc, but for now, the user must store 4748 a copy of M or reassemble it when requested. 4749 4750 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 4751 @*/ 4752 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx) 4753 { 4754 PetscErrorCode ierr; 4755 4756 PetscFunctionBegin; 4757 ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 4758 ts->ijacobian.shift = shift; 4759 PetscFunctionReturn(0); 4760 } 4761 4762 /*@ 4763 TSGetEquationType - Gets the type of the equation that TS is solving. 4764 4765 Not Collective 4766 4767 Input Parameter: 4768 . ts - the TS context 4769 4770 Output Parameter: 4771 . equation_type - see TSEquationType 4772 4773 Level: beginner 4774 4775 .keywords: TS, equation type 4776 4777 .seealso: TSSetEquationType(), TSEquationType 4778 @*/ 4779 PetscErrorCode TSGetEquationType(TS ts,TSEquationType *equation_type) 4780 { 4781 PetscFunctionBegin; 4782 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4783 PetscValidPointer(equation_type,2); 4784 *equation_type = ts->equation_type; 4785 PetscFunctionReturn(0); 4786 } 4787 4788 /*@ 4789 TSSetEquationType - Sets the type of the equation that TS is solving. 4790 4791 Not Collective 4792 4793 Input Parameter: 4794 + ts - the TS context 4795 - equation_type - see TSEquationType 4796 4797 Level: advanced 4798 4799 .keywords: TS, equation type 4800 4801 .seealso: TSGetEquationType(), TSEquationType 4802 @*/ 4803 PetscErrorCode TSSetEquationType(TS ts,TSEquationType equation_type) 4804 { 4805 PetscFunctionBegin; 4806 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4807 ts->equation_type = equation_type; 4808 PetscFunctionReturn(0); 4809 } 4810 4811 /*@ 4812 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 4813 4814 Not Collective 4815 4816 Input Parameter: 4817 . ts - the TS context 4818 4819 Output Parameter: 4820 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 4821 manual pages for the individual convergence tests for complete lists 4822 4823 Level: beginner 4824 4825 Notes: 4826 Can only be called after the call to TSSolve() is complete. 4827 4828 .keywords: TS, nonlinear, set, convergence, test 4829 4830 .seealso: TSSetConvergenceTest(), TSConvergedReason 4831 @*/ 4832 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 4833 { 4834 PetscFunctionBegin; 4835 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4836 PetscValidPointer(reason,2); 4837 *reason = ts->reason; 4838 PetscFunctionReturn(0); 4839 } 4840 4841 /*@ 4842 TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve. 4843 4844 Not Collective 4845 4846 Input Parameter: 4847 + ts - the TS context 4848 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 4849 manual pages for the individual convergence tests for complete lists 4850 4851 Level: advanced 4852 4853 Notes: 4854 Can only be called during TSSolve() is active. 4855 4856 .keywords: TS, nonlinear, set, convergence, test 4857 4858 .seealso: TSConvergedReason 4859 @*/ 4860 PetscErrorCode TSSetConvergedReason(TS ts,TSConvergedReason reason) 4861 { 4862 PetscFunctionBegin; 4863 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4864 ts->reason = reason; 4865 PetscFunctionReturn(0); 4866 } 4867 4868 /*@ 4869 TSGetSolveTime - Gets the time after a call to TSSolve() 4870 4871 Not Collective 4872 4873 Input Parameter: 4874 . ts - the TS context 4875 4876 Output Parameter: 4877 . ftime - the final time. This time corresponds to the final time set with TSSetMaxTime() 4878 4879 Level: beginner 4880 4881 Notes: 4882 Can only be called after the call to TSSolve() is complete. 4883 4884 .keywords: TS, nonlinear, set, convergence, test 4885 4886 .seealso: TSSetConvergenceTest(), TSConvergedReason 4887 @*/ 4888 PetscErrorCode TSGetSolveTime(TS ts,PetscReal *ftime) 4889 { 4890 PetscFunctionBegin; 4891 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4892 PetscValidPointer(ftime,2); 4893 *ftime = ts->solvetime; 4894 PetscFunctionReturn(0); 4895 } 4896 4897 /*@ 4898 TSGetSNESIterations - Gets the total number of nonlinear iterations 4899 used by the time integrator. 4900 4901 Not Collective 4902 4903 Input Parameter: 4904 . ts - TS context 4905 4906 Output Parameter: 4907 . nits - number of nonlinear iterations 4908 4909 Notes: 4910 This counter is reset to zero for each successive call to TSSolve(). 4911 4912 Level: intermediate 4913 4914 .keywords: TS, get, number, nonlinear, iterations 4915 4916 .seealso: TSGetKSPIterations() 4917 @*/ 4918 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 4919 { 4920 PetscFunctionBegin; 4921 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4922 PetscValidIntPointer(nits,2); 4923 *nits = ts->snes_its; 4924 PetscFunctionReturn(0); 4925 } 4926 4927 /*@ 4928 TSGetKSPIterations - Gets the total number of linear iterations 4929 used by the time integrator. 4930 4931 Not Collective 4932 4933 Input Parameter: 4934 . ts - TS context 4935 4936 Output Parameter: 4937 . lits - number of linear iterations 4938 4939 Notes: 4940 This counter is reset to zero for each successive call to TSSolve(). 4941 4942 Level: intermediate 4943 4944 .keywords: TS, get, number, linear, iterations 4945 4946 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 4947 @*/ 4948 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 4949 { 4950 PetscFunctionBegin; 4951 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4952 PetscValidIntPointer(lits,2); 4953 *lits = ts->ksp_its; 4954 PetscFunctionReturn(0); 4955 } 4956 4957 /*@ 4958 TSGetStepRejections - Gets the total number of rejected steps. 4959 4960 Not Collective 4961 4962 Input Parameter: 4963 . ts - TS context 4964 4965 Output Parameter: 4966 . rejects - number of steps rejected 4967 4968 Notes: 4969 This counter is reset to zero for each successive call to TSSolve(). 4970 4971 Level: intermediate 4972 4973 .keywords: TS, get, number 4974 4975 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 4976 @*/ 4977 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 4978 { 4979 PetscFunctionBegin; 4980 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4981 PetscValidIntPointer(rejects,2); 4982 *rejects = ts->reject; 4983 PetscFunctionReturn(0); 4984 } 4985 4986 /*@ 4987 TSGetSNESFailures - Gets the total number of failed SNES solves 4988 4989 Not Collective 4990 4991 Input Parameter: 4992 . ts - TS context 4993 4994 Output Parameter: 4995 . fails - number of failed nonlinear solves 4996 4997 Notes: 4998 This counter is reset to zero for each successive call to TSSolve(). 4999 5000 Level: intermediate 5001 5002 .keywords: TS, get, number 5003 5004 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 5005 @*/ 5006 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 5007 { 5008 PetscFunctionBegin; 5009 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5010 PetscValidIntPointer(fails,2); 5011 *fails = ts->num_snes_failures; 5012 PetscFunctionReturn(0); 5013 } 5014 5015 /*@ 5016 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 5017 5018 Not Collective 5019 5020 Input Parameter: 5021 + ts - TS context 5022 - rejects - maximum number of rejected steps, pass -1 for unlimited 5023 5024 Notes: 5025 The counter is reset to zero for each step 5026 5027 Options Database Key: 5028 . -ts_max_reject - Maximum number of step rejections before a step fails 5029 5030 Level: intermediate 5031 5032 .keywords: TS, set, maximum, number 5033 5034 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5035 @*/ 5036 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 5037 { 5038 PetscFunctionBegin; 5039 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5040 ts->max_reject = rejects; 5041 PetscFunctionReturn(0); 5042 } 5043 5044 /*@ 5045 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 5046 5047 Not Collective 5048 5049 Input Parameter: 5050 + ts - TS context 5051 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 5052 5053 Notes: 5054 The counter is reset to zero for each successive call to TSSolve(). 5055 5056 Options Database Key: 5057 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 5058 5059 Level: intermediate 5060 5061 .keywords: TS, set, maximum, number 5062 5063 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 5064 @*/ 5065 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 5066 { 5067 PetscFunctionBegin; 5068 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5069 ts->max_snes_failures = fails; 5070 PetscFunctionReturn(0); 5071 } 5072 5073 /*@ 5074 TSSetErrorIfStepFails - Error if no step succeeds 5075 5076 Not Collective 5077 5078 Input Parameter: 5079 + ts - TS context 5080 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 5081 5082 Options Database Key: 5083 . -ts_error_if_step_fails - Error if no step succeeds 5084 5085 Level: intermediate 5086 5087 .keywords: TS, set, error 5088 5089 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5090 @*/ 5091 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 5092 { 5093 PetscFunctionBegin; 5094 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5095 ts->errorifstepfailed = err; 5096 PetscFunctionReturn(0); 5097 } 5098 5099 /*@C 5100 TSMonitorSolution - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file or a PetscDraw object 5101 5102 Collective on TS 5103 5104 Input Parameters: 5105 + ts - the TS context 5106 . step - current time-step 5107 . ptime - current time 5108 . u - current state 5109 - vf - viewer and its format 5110 5111 Level: intermediate 5112 5113 .keywords: TS, vector, monitor, view 5114 5115 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5116 @*/ 5117 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 5118 { 5119 PetscErrorCode ierr; 5120 5121 PetscFunctionBegin; 5122 ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr); 5123 ierr = VecView(u,vf->viewer);CHKERRQ(ierr); 5124 ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr); 5125 PetscFunctionReturn(0); 5126 } 5127 5128 /*@C 5129 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 5130 5131 Collective on TS 5132 5133 Input Parameters: 5134 + ts - the TS context 5135 . step - current time-step 5136 . ptime - current time 5137 . u - current state 5138 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5139 5140 Level: intermediate 5141 5142 Notes: 5143 The VTK format does not allow writing multiple time steps in the same file, therefore a different file will be written for each time step. 5144 These are named according to the file name template. 5145 5146 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 5147 5148 .keywords: TS, vector, monitor, view 5149 5150 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5151 @*/ 5152 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate) 5153 { 5154 PetscErrorCode ierr; 5155 char filename[PETSC_MAX_PATH_LEN]; 5156 PetscViewer viewer; 5157 5158 PetscFunctionBegin; 5159 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 5160 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 5161 ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 5162 ierr = VecView(u,viewer);CHKERRQ(ierr); 5163 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5164 PetscFunctionReturn(0); 5165 } 5166 5167 /*@C 5168 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 5169 5170 Collective on TS 5171 5172 Input Parameters: 5173 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5174 5175 Level: intermediate 5176 5177 Note: 5178 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 5179 5180 .keywords: TS, vector, monitor, view 5181 5182 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 5183 @*/ 5184 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 5185 { 5186 PetscErrorCode ierr; 5187 5188 PetscFunctionBegin; 5189 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 5190 PetscFunctionReturn(0); 5191 } 5192 5193 /*@ 5194 TSGetAdapt - Get the adaptive controller context for the current method 5195 5196 Collective on TS if controller has not been created yet 5197 5198 Input Arguments: 5199 . ts - time stepping context 5200 5201 Output Arguments: 5202 . adapt - adaptive controller 5203 5204 Level: intermediate 5205 5206 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 5207 @*/ 5208 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 5209 { 5210 PetscErrorCode ierr; 5211 5212 PetscFunctionBegin; 5213 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5214 PetscValidPointer(adapt,2); 5215 if (!ts->adapt) { 5216 ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr); 5217 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr); 5218 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 5219 } 5220 *adapt = ts->adapt; 5221 PetscFunctionReturn(0); 5222 } 5223 5224 /*@ 5225 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 5226 5227 Logically Collective 5228 5229 Input Arguments: 5230 + ts - time integration context 5231 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 5232 . vatol - vector of absolute tolerances or NULL, used in preference to atol if present 5233 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 5234 - vrtol - vector of relative tolerances or NULL, used in preference to atol if present 5235 5236 Options Database keys: 5237 + -ts_rtol <rtol> - relative tolerance for local truncation error 5238 - -ts_atol <atol> Absolute tolerance for local truncation error 5239 5240 Notes: 5241 With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error 5242 (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be 5243 computed only for the differential or the algebraic part then this can be done using the vector of 5244 tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the 5245 differential part and infinity for the algebraic part, the LTE calculation will include only the 5246 differential variables. 5247 5248 Level: beginner 5249 5250 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances() 5251 @*/ 5252 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 5253 { 5254 PetscErrorCode ierr; 5255 5256 PetscFunctionBegin; 5257 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 5258 if (vatol) { 5259 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 5260 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 5261 ts->vatol = vatol; 5262 } 5263 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 5264 if (vrtol) { 5265 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 5266 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 5267 ts->vrtol = vrtol; 5268 } 5269 PetscFunctionReturn(0); 5270 } 5271 5272 /*@ 5273 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 5274 5275 Logically Collective 5276 5277 Input Arguments: 5278 . ts - time integration context 5279 5280 Output Arguments: 5281 + atol - scalar absolute tolerances, NULL to ignore 5282 . vatol - vector of absolute tolerances, NULL to ignore 5283 . rtol - scalar relative tolerances, NULL to ignore 5284 - vrtol - vector of relative tolerances, NULL to ignore 5285 5286 Level: beginner 5287 5288 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances() 5289 @*/ 5290 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 5291 { 5292 PetscFunctionBegin; 5293 if (atol) *atol = ts->atol; 5294 if (vatol) *vatol = ts->vatol; 5295 if (rtol) *rtol = ts->rtol; 5296 if (vrtol) *vrtol = ts->vrtol; 5297 PetscFunctionReturn(0); 5298 } 5299 5300 /*@ 5301 TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors 5302 5303 Collective on TS 5304 5305 Input Arguments: 5306 + ts - time stepping context 5307 . U - state vector, usually ts->vec_sol 5308 - Y - state vector to be compared to U 5309 5310 Output Arguments: 5311 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5312 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5313 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5314 5315 Level: developer 5316 5317 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity() 5318 @*/ 5319 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5320 { 5321 PetscErrorCode ierr; 5322 PetscInt i,n,N,rstart; 5323 PetscInt n_loc,na_loc,nr_loc; 5324 PetscReal n_glb,na_glb,nr_glb; 5325 const PetscScalar *u,*y; 5326 PetscReal sum,suma,sumr,gsum,gsuma,gsumr,diff; 5327 PetscReal tol,tola,tolr; 5328 PetscReal err_loc[6],err_glb[6]; 5329 5330 PetscFunctionBegin; 5331 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5332 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5333 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5334 PetscValidType(U,2); 5335 PetscValidType(Y,3); 5336 PetscCheckSameComm(U,2,Y,3); 5337 PetscValidPointer(norm,4); 5338 PetscValidPointer(norma,5); 5339 PetscValidPointer(normr,6); 5340 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5341 5342 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5343 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5344 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5345 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5346 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5347 sum = 0.; n_loc = 0; 5348 suma = 0.; na_loc = 0; 5349 sumr = 0.; nr_loc = 0; 5350 if (ts->vatol && ts->vrtol) { 5351 const PetscScalar *atol,*rtol; 5352 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5353 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5354 for (i=0; i<n; i++) { 5355 diff = PetscAbsScalar(y[i] - u[i]); 5356 tola = PetscRealPart(atol[i]); 5357 if(tola>0.){ 5358 suma += PetscSqr(diff/tola); 5359 na_loc++; 5360 } 5361 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5362 if(tolr>0.){ 5363 sumr += PetscSqr(diff/tolr); 5364 nr_loc++; 5365 } 5366 tol=tola+tolr; 5367 if(tol>0.){ 5368 sum += PetscSqr(diff/tol); 5369 n_loc++; 5370 } 5371 } 5372 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5373 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5374 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5375 const PetscScalar *atol; 5376 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5377 for (i=0; i<n; i++) { 5378 diff = PetscAbsScalar(y[i] - u[i]); 5379 tola = PetscRealPart(atol[i]); 5380 if(tola>0.){ 5381 suma += PetscSqr(diff/tola); 5382 na_loc++; 5383 } 5384 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5385 if(tolr>0.){ 5386 sumr += PetscSqr(diff/tolr); 5387 nr_loc++; 5388 } 5389 tol=tola+tolr; 5390 if(tol>0.){ 5391 sum += PetscSqr(diff/tol); 5392 n_loc++; 5393 } 5394 } 5395 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5396 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5397 const PetscScalar *rtol; 5398 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5399 for (i=0; i<n; i++) { 5400 diff = PetscAbsScalar(y[i] - u[i]); 5401 tola = ts->atol; 5402 if(tola>0.){ 5403 suma += PetscSqr(diff/tola); 5404 na_loc++; 5405 } 5406 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5407 if(tolr>0.){ 5408 sumr += PetscSqr(diff/tolr); 5409 nr_loc++; 5410 } 5411 tol=tola+tolr; 5412 if(tol>0.){ 5413 sum += PetscSqr(diff/tol); 5414 n_loc++; 5415 } 5416 } 5417 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5418 } else { /* scalar atol, scalar rtol */ 5419 for (i=0; i<n; i++) { 5420 diff = PetscAbsScalar(y[i] - u[i]); 5421 tola = ts->atol; 5422 if(tola>0.){ 5423 suma += PetscSqr(diff/tola); 5424 na_loc++; 5425 } 5426 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5427 if(tolr>0.){ 5428 sumr += PetscSqr(diff/tolr); 5429 nr_loc++; 5430 } 5431 tol=tola+tolr; 5432 if(tol>0.){ 5433 sum += PetscSqr(diff/tol); 5434 n_loc++; 5435 } 5436 } 5437 } 5438 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5439 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5440 5441 err_loc[0] = sum; 5442 err_loc[1] = suma; 5443 err_loc[2] = sumr; 5444 err_loc[3] = (PetscReal)n_loc; 5445 err_loc[4] = (PetscReal)na_loc; 5446 err_loc[5] = (PetscReal)nr_loc; 5447 5448 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5449 5450 gsum = err_glb[0]; 5451 gsuma = err_glb[1]; 5452 gsumr = err_glb[2]; 5453 n_glb = err_glb[3]; 5454 na_glb = err_glb[4]; 5455 nr_glb = err_glb[5]; 5456 5457 *norm = 0.; 5458 if(n_glb>0. ){*norm = PetscSqrtReal(gsum / n_glb );} 5459 *norma = 0.; 5460 if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 5461 *normr = 0.; 5462 if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 5463 5464 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5465 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5466 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5467 PetscFunctionReturn(0); 5468 } 5469 5470 /*@ 5471 TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors 5472 5473 Collective on TS 5474 5475 Input Arguments: 5476 + ts - time stepping context 5477 . U - state vector, usually ts->vec_sol 5478 - Y - state vector to be compared to U 5479 5480 Output Arguments: 5481 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5482 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5483 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5484 5485 Level: developer 5486 5487 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2() 5488 @*/ 5489 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5490 { 5491 PetscErrorCode ierr; 5492 PetscInt i,n,N,rstart; 5493 const PetscScalar *u,*y; 5494 PetscReal max,gmax,maxa,gmaxa,maxr,gmaxr; 5495 PetscReal tol,tola,tolr,diff; 5496 PetscReal err_loc[3],err_glb[3]; 5497 5498 PetscFunctionBegin; 5499 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5500 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5501 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5502 PetscValidType(U,2); 5503 PetscValidType(Y,3); 5504 PetscCheckSameComm(U,2,Y,3); 5505 PetscValidPointer(norm,4); 5506 PetscValidPointer(norma,5); 5507 PetscValidPointer(normr,6); 5508 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5509 5510 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5511 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5512 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5513 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5514 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5515 5516 max=0.; 5517 maxa=0.; 5518 maxr=0.; 5519 5520 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 5521 const PetscScalar *atol,*rtol; 5522 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5523 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5524 5525 for (i=0; i<n; i++) { 5526 diff = PetscAbsScalar(y[i] - u[i]); 5527 tola = PetscRealPart(atol[i]); 5528 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5529 tol = tola+tolr; 5530 if(tola>0.){ 5531 maxa = PetscMax(maxa,diff / tola); 5532 } 5533 if(tolr>0.){ 5534 maxr = PetscMax(maxr,diff / tolr); 5535 } 5536 if(tol>0.){ 5537 max = PetscMax(max,diff / tol); 5538 } 5539 } 5540 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5541 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5542 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5543 const PetscScalar *atol; 5544 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5545 for (i=0; i<n; i++) { 5546 diff = PetscAbsScalar(y[i] - u[i]); 5547 tola = PetscRealPart(atol[i]); 5548 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5549 tol = tola+tolr; 5550 if(tola>0.){ 5551 maxa = PetscMax(maxa,diff / tola); 5552 } 5553 if(tolr>0.){ 5554 maxr = PetscMax(maxr,diff / tolr); 5555 } 5556 if(tol>0.){ 5557 max = PetscMax(max,diff / tol); 5558 } 5559 } 5560 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5561 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5562 const PetscScalar *rtol; 5563 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5564 5565 for (i=0; i<n; i++) { 5566 diff = PetscAbsScalar(y[i] - u[i]); 5567 tola = ts->atol; 5568 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5569 tol = tola+tolr; 5570 if(tola>0.){ 5571 maxa = PetscMax(maxa,diff / tola); 5572 } 5573 if(tolr>0.){ 5574 maxr = PetscMax(maxr,diff / tolr); 5575 } 5576 if(tol>0.){ 5577 max = PetscMax(max,diff / tol); 5578 } 5579 } 5580 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5581 } else { /* scalar atol, scalar rtol */ 5582 5583 for (i=0; i<n; i++) { 5584 diff = PetscAbsScalar(y[i] - u[i]); 5585 tola = ts->atol; 5586 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5587 tol = tola+tolr; 5588 if(tola>0.){ 5589 maxa = PetscMax(maxa,diff / tola); 5590 } 5591 if(tolr>0.){ 5592 maxr = PetscMax(maxr,diff / tolr); 5593 } 5594 if(tol>0.){ 5595 max = PetscMax(max,diff / tol); 5596 } 5597 } 5598 } 5599 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5600 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5601 err_loc[0] = max; 5602 err_loc[1] = maxa; 5603 err_loc[2] = maxr; 5604 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5605 gmax = err_glb[0]; 5606 gmaxa = err_glb[1]; 5607 gmaxr = err_glb[2]; 5608 5609 *norm = gmax; 5610 *norma = gmaxa; 5611 *normr = gmaxr; 5612 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5613 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5614 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5615 PetscFunctionReturn(0); 5616 } 5617 5618 /*@ 5619 TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances 5620 5621 Collective on TS 5622 5623 Input Arguments: 5624 + ts - time stepping context 5625 . U - state vector, usually ts->vec_sol 5626 . Y - state vector to be compared to U 5627 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 5628 5629 Output Arguments: 5630 . norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 5631 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 5632 . normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 5633 5634 Options Database Keys: 5635 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 5636 5637 Level: developer 5638 5639 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2(), TSErrorWeightedENorm 5640 @*/ 5641 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5642 { 5643 PetscErrorCode ierr; 5644 5645 PetscFunctionBegin; 5646 if (wnormtype == NORM_2) { 5647 ierr = TSErrorWeightedNorm2(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 5648 } else if(wnormtype == NORM_INFINITY) { 5649 ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 5650 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 5651 PetscFunctionReturn(0); 5652 } 5653 5654 5655 /*@ 5656 TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances 5657 5658 Collective on TS 5659 5660 Input Arguments: 5661 + ts - time stepping context 5662 . E - error vector 5663 . U - state vector, usually ts->vec_sol 5664 - Y - state vector, previous time step 5665 5666 Output Arguments: 5667 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5668 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5669 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5670 5671 Level: developer 5672 5673 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENormInfinity() 5674 @*/ 5675 PetscErrorCode TSErrorWeightedENorm2(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5676 { 5677 PetscErrorCode ierr; 5678 PetscInt i,n,N,rstart; 5679 PetscInt n_loc,na_loc,nr_loc; 5680 PetscReal n_glb,na_glb,nr_glb; 5681 const PetscScalar *e,*u,*y; 5682 PetscReal err,sum,suma,sumr,gsum,gsuma,gsumr; 5683 PetscReal tol,tola,tolr; 5684 PetscReal err_loc[6],err_glb[6]; 5685 5686 PetscFunctionBegin; 5687 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5688 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 5689 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 5690 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 5691 PetscValidType(E,2); 5692 PetscValidType(U,3); 5693 PetscValidType(Y,4); 5694 PetscCheckSameComm(E,2,U,3); 5695 PetscCheckSameComm(U,2,Y,3); 5696 PetscValidPointer(norm,5); 5697 PetscValidPointer(norma,6); 5698 PetscValidPointer(normr,7); 5699 5700 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 5701 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 5702 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 5703 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 5704 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5705 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5706 sum = 0.; n_loc = 0; 5707 suma = 0.; na_loc = 0; 5708 sumr = 0.; nr_loc = 0; 5709 if (ts->vatol && ts->vrtol) { 5710 const PetscScalar *atol,*rtol; 5711 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5712 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5713 for (i=0; i<n; i++) { 5714 err = PetscAbsScalar(e[i]); 5715 tola = PetscRealPart(atol[i]); 5716 if(tola>0.){ 5717 suma += PetscSqr(err/tola); 5718 na_loc++; 5719 } 5720 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5721 if(tolr>0.){ 5722 sumr += PetscSqr(err/tolr); 5723 nr_loc++; 5724 } 5725 tol=tola+tolr; 5726 if(tol>0.){ 5727 sum += PetscSqr(err/tol); 5728 n_loc++; 5729 } 5730 } 5731 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5732 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5733 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5734 const PetscScalar *atol; 5735 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5736 for (i=0; i<n; i++) { 5737 err = PetscAbsScalar(e[i]); 5738 tola = PetscRealPart(atol[i]); 5739 if(tola>0.){ 5740 suma += PetscSqr(err/tola); 5741 na_loc++; 5742 } 5743 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5744 if(tolr>0.){ 5745 sumr += PetscSqr(err/tolr); 5746 nr_loc++; 5747 } 5748 tol=tola+tolr; 5749 if(tol>0.){ 5750 sum += PetscSqr(err/tol); 5751 n_loc++; 5752 } 5753 } 5754 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5755 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5756 const PetscScalar *rtol; 5757 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5758 for (i=0; i<n; i++) { 5759 err = PetscAbsScalar(e[i]); 5760 tola = ts->atol; 5761 if(tola>0.){ 5762 suma += PetscSqr(err/tola); 5763 na_loc++; 5764 } 5765 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5766 if(tolr>0.){ 5767 sumr += PetscSqr(err/tolr); 5768 nr_loc++; 5769 } 5770 tol=tola+tolr; 5771 if(tol>0.){ 5772 sum += PetscSqr(err/tol); 5773 n_loc++; 5774 } 5775 } 5776 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5777 } else { /* scalar atol, scalar rtol */ 5778 for (i=0; i<n; i++) { 5779 err = PetscAbsScalar(e[i]); 5780 tola = ts->atol; 5781 if(tola>0.){ 5782 suma += PetscSqr(err/tola); 5783 na_loc++; 5784 } 5785 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5786 if(tolr>0.){ 5787 sumr += PetscSqr(err/tolr); 5788 nr_loc++; 5789 } 5790 tol=tola+tolr; 5791 if(tol>0.){ 5792 sum += PetscSqr(err/tol); 5793 n_loc++; 5794 } 5795 } 5796 } 5797 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 5798 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5799 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5800 5801 err_loc[0] = sum; 5802 err_loc[1] = suma; 5803 err_loc[2] = sumr; 5804 err_loc[3] = (PetscReal)n_loc; 5805 err_loc[4] = (PetscReal)na_loc; 5806 err_loc[5] = (PetscReal)nr_loc; 5807 5808 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5809 5810 gsum = err_glb[0]; 5811 gsuma = err_glb[1]; 5812 gsumr = err_glb[2]; 5813 n_glb = err_glb[3]; 5814 na_glb = err_glb[4]; 5815 nr_glb = err_glb[5]; 5816 5817 *norm = 0.; 5818 if(n_glb>0. ){*norm = PetscSqrtReal(gsum / n_glb );} 5819 *norma = 0.; 5820 if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 5821 *normr = 0.; 5822 if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 5823 5824 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5825 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5826 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5827 PetscFunctionReturn(0); 5828 } 5829 5830 /*@ 5831 TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances 5832 Collective on TS 5833 5834 Input Arguments: 5835 + ts - time stepping context 5836 . E - error vector 5837 . U - state vector, usually ts->vec_sol 5838 - Y - state vector, previous time step 5839 5840 Output Arguments: 5841 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5842 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5843 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5844 5845 Level: developer 5846 5847 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENorm2() 5848 @*/ 5849 PetscErrorCode TSErrorWeightedENormInfinity(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5850 { 5851 PetscErrorCode ierr; 5852 PetscInt i,n,N,rstart; 5853 const PetscScalar *e,*u,*y; 5854 PetscReal err,max,gmax,maxa,gmaxa,maxr,gmaxr; 5855 PetscReal tol,tola,tolr; 5856 PetscReal err_loc[3],err_glb[3]; 5857 5858 PetscFunctionBegin; 5859 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5860 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 5861 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 5862 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 5863 PetscValidType(E,2); 5864 PetscValidType(U,3); 5865 PetscValidType(Y,4); 5866 PetscCheckSameComm(E,2,U,3); 5867 PetscCheckSameComm(U,2,Y,3); 5868 PetscValidPointer(norm,5); 5869 PetscValidPointer(norma,6); 5870 PetscValidPointer(normr,7); 5871 5872 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 5873 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 5874 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 5875 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 5876 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5877 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5878 5879 max=0.; 5880 maxa=0.; 5881 maxr=0.; 5882 5883 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 5884 const PetscScalar *atol,*rtol; 5885 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5886 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5887 5888 for (i=0; i<n; i++) { 5889 err = PetscAbsScalar(e[i]); 5890 tola = PetscRealPart(atol[i]); 5891 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5892 tol = tola+tolr; 5893 if(tola>0.){ 5894 maxa = PetscMax(maxa,err / tola); 5895 } 5896 if(tolr>0.){ 5897 maxr = PetscMax(maxr,err / tolr); 5898 } 5899 if(tol>0.){ 5900 max = PetscMax(max,err / tol); 5901 } 5902 } 5903 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5904 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5905 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5906 const PetscScalar *atol; 5907 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5908 for (i=0; i<n; i++) { 5909 err = PetscAbsScalar(e[i]); 5910 tola = PetscRealPart(atol[i]); 5911 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5912 tol = tola+tolr; 5913 if(tola>0.){ 5914 maxa = PetscMax(maxa,err / tola); 5915 } 5916 if(tolr>0.){ 5917 maxr = PetscMax(maxr,err / tolr); 5918 } 5919 if(tol>0.){ 5920 max = PetscMax(max,err / tol); 5921 } 5922 } 5923 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5924 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5925 const PetscScalar *rtol; 5926 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5927 5928 for (i=0; i<n; i++) { 5929 err = PetscAbsScalar(e[i]); 5930 tola = ts->atol; 5931 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5932 tol = tola+tolr; 5933 if(tola>0.){ 5934 maxa = PetscMax(maxa,err / tola); 5935 } 5936 if(tolr>0.){ 5937 maxr = PetscMax(maxr,err / tolr); 5938 } 5939 if(tol>0.){ 5940 max = PetscMax(max,err / tol); 5941 } 5942 } 5943 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5944 } else { /* scalar atol, scalar rtol */ 5945 5946 for (i=0; i<n; i++) { 5947 err = PetscAbsScalar(e[i]); 5948 tola = ts->atol; 5949 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5950 tol = tola+tolr; 5951 if(tola>0.){ 5952 maxa = PetscMax(maxa,err / tola); 5953 } 5954 if(tolr>0.){ 5955 maxr = PetscMax(maxr,err / tolr); 5956 } 5957 if(tol>0.){ 5958 max = PetscMax(max,err / tol); 5959 } 5960 } 5961 } 5962 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 5963 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5964 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5965 err_loc[0] = max; 5966 err_loc[1] = maxa; 5967 err_loc[2] = maxr; 5968 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5969 gmax = err_glb[0]; 5970 gmaxa = err_glb[1]; 5971 gmaxr = err_glb[2]; 5972 5973 *norm = gmax; 5974 *norma = gmaxa; 5975 *normr = gmaxr; 5976 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5977 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5978 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5979 PetscFunctionReturn(0); 5980 } 5981 5982 /*@ 5983 TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances 5984 5985 Collective on TS 5986 5987 Input Arguments: 5988 + ts - time stepping context 5989 . E - error vector 5990 . U - state vector, usually ts->vec_sol 5991 . Y - state vector, previous time step 5992 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 5993 5994 Output Arguments: 5995 . norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 5996 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 5997 . normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 5998 5999 Options Database Keys: 6000 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6001 6002 Level: developer 6003 6004 .seealso: TSErrorWeightedENormInfinity(), TSErrorWeightedENorm2(), TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2() 6005 @*/ 6006 PetscErrorCode TSErrorWeightedENorm(TS ts,Vec E,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6007 { 6008 PetscErrorCode ierr; 6009 6010 PetscFunctionBegin; 6011 if (wnormtype == NORM_2) { 6012 ierr = TSErrorWeightedENorm2(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6013 } else if(wnormtype == NORM_INFINITY) { 6014 ierr = TSErrorWeightedENormInfinity(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6015 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6016 PetscFunctionReturn(0); 6017 } 6018 6019 6020 /*@ 6021 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 6022 6023 Logically Collective on TS 6024 6025 Input Arguments: 6026 + ts - time stepping context 6027 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 6028 6029 Note: 6030 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 6031 6032 Level: intermediate 6033 6034 .seealso: TSGetCFLTime(), TSADAPTCFL 6035 @*/ 6036 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 6037 { 6038 PetscFunctionBegin; 6039 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6040 ts->cfltime_local = cfltime; 6041 ts->cfltime = -1.; 6042 PetscFunctionReturn(0); 6043 } 6044 6045 /*@ 6046 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 6047 6048 Collective on TS 6049 6050 Input Arguments: 6051 . ts - time stepping context 6052 6053 Output Arguments: 6054 . cfltime - maximum stable time step for forward Euler 6055 6056 Level: advanced 6057 6058 .seealso: TSSetCFLTimeLocal() 6059 @*/ 6060 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 6061 { 6062 PetscErrorCode ierr; 6063 6064 PetscFunctionBegin; 6065 if (ts->cfltime < 0) { 6066 ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6067 } 6068 *cfltime = ts->cfltime; 6069 PetscFunctionReturn(0); 6070 } 6071 6072 /*@ 6073 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 6074 6075 Input Parameters: 6076 . ts - the TS context. 6077 . xl - lower bound. 6078 . xu - upper bound. 6079 6080 Notes: 6081 If this routine is not called then the lower and upper bounds are set to 6082 PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp(). 6083 6084 Level: advanced 6085 6086 @*/ 6087 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 6088 { 6089 PetscErrorCode ierr; 6090 SNES snes; 6091 6092 PetscFunctionBegin; 6093 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 6094 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 6095 PetscFunctionReturn(0); 6096 } 6097 6098 #if defined(PETSC_HAVE_MATLAB_ENGINE) 6099 #include <mex.h> 6100 6101 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 6102 6103 /* 6104 TSComputeFunction_Matlab - Calls the function that has been set with 6105 TSSetFunctionMatlab(). 6106 6107 Collective on TS 6108 6109 Input Parameters: 6110 + snes - the TS context 6111 - u - input vector 6112 6113 Output Parameter: 6114 . y - function vector, as set by TSSetFunction() 6115 6116 Notes: 6117 TSComputeFunction() is typically used within nonlinear solvers 6118 implementations, so most users would not generally call this routine 6119 themselves. 6120 6121 Level: developer 6122 6123 .keywords: TS, nonlinear, compute, function 6124 6125 .seealso: TSSetFunction(), TSGetFunction() 6126 */ 6127 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx) 6128 { 6129 PetscErrorCode ierr; 6130 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6131 int nlhs = 1,nrhs = 7; 6132 mxArray *plhs[1],*prhs[7]; 6133 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 6134 6135 PetscFunctionBegin; 6136 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 6137 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 6138 PetscValidHeaderSpecific(udot,VEC_CLASSID,4); 6139 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 6140 PetscCheckSameComm(snes,1,u,3); 6141 PetscCheckSameComm(snes,1,y,5); 6142 6143 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 6144 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6145 ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr); 6146 ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr); 6147 6148 prhs[0] = mxCreateDoubleScalar((double)ls); 6149 prhs[1] = mxCreateDoubleScalar(time); 6150 prhs[2] = mxCreateDoubleScalar((double)lx); 6151 prhs[3] = mxCreateDoubleScalar((double)lxdot); 6152 prhs[4] = mxCreateDoubleScalar((double)ly); 6153 prhs[5] = mxCreateString(sctx->funcname); 6154 prhs[6] = sctx->ctx; 6155 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 6156 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6157 mxDestroyArray(prhs[0]); 6158 mxDestroyArray(prhs[1]); 6159 mxDestroyArray(prhs[2]); 6160 mxDestroyArray(prhs[3]); 6161 mxDestroyArray(prhs[4]); 6162 mxDestroyArray(prhs[5]); 6163 mxDestroyArray(plhs[0]); 6164 PetscFunctionReturn(0); 6165 } 6166 6167 /* 6168 TSSetFunctionMatlab - Sets the function evaluation routine and function 6169 vector for use by the TS routines in solving ODEs 6170 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 6171 6172 Logically Collective on TS 6173 6174 Input Parameters: 6175 + ts - the TS context 6176 - func - function evaluation routine 6177 6178 Calling sequence of func: 6179 $ func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx); 6180 6181 Level: beginner 6182 6183 .keywords: TS, nonlinear, set, function 6184 6185 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6186 */ 6187 PetscErrorCode TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx) 6188 { 6189 PetscErrorCode ierr; 6190 TSMatlabContext *sctx; 6191 6192 PetscFunctionBegin; 6193 /* currently sctx is memory bleed */ 6194 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6195 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6196 /* 6197 This should work, but it doesn't 6198 sctx->ctx = ctx; 6199 mexMakeArrayPersistent(sctx->ctx); 6200 */ 6201 sctx->ctx = mxDuplicateArray(ctx); 6202 6203 ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 6204 PetscFunctionReturn(0); 6205 } 6206 6207 /* 6208 TSComputeJacobian_Matlab - Calls the function that has been set with 6209 TSSetJacobianMatlab(). 6210 6211 Collective on TS 6212 6213 Input Parameters: 6214 + ts - the TS context 6215 . u - input vector 6216 . A, B - the matrices 6217 - ctx - user context 6218 6219 Level: developer 6220 6221 .keywords: TS, nonlinear, compute, function 6222 6223 .seealso: TSSetFunction(), TSGetFunction() 6224 @*/ 6225 PetscErrorCode TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx) 6226 { 6227 PetscErrorCode ierr; 6228 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6229 int nlhs = 2,nrhs = 9; 6230 mxArray *plhs[2],*prhs[9]; 6231 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 6232 6233 PetscFunctionBegin; 6234 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6235 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 6236 6237 /* call Matlab function in ctx with arguments u and y */ 6238 6239 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 6240 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6241 ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr); 6242 ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr); 6243 ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr); 6244 6245 prhs[0] = mxCreateDoubleScalar((double)ls); 6246 prhs[1] = mxCreateDoubleScalar((double)time); 6247 prhs[2] = mxCreateDoubleScalar((double)lx); 6248 prhs[3] = mxCreateDoubleScalar((double)lxdot); 6249 prhs[4] = mxCreateDoubleScalar((double)shift); 6250 prhs[5] = mxCreateDoubleScalar((double)lA); 6251 prhs[6] = mxCreateDoubleScalar((double)lB); 6252 prhs[7] = mxCreateString(sctx->funcname); 6253 prhs[8] = sctx->ctx; 6254 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 6255 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6256 mxDestroyArray(prhs[0]); 6257 mxDestroyArray(prhs[1]); 6258 mxDestroyArray(prhs[2]); 6259 mxDestroyArray(prhs[3]); 6260 mxDestroyArray(prhs[4]); 6261 mxDestroyArray(prhs[5]); 6262 mxDestroyArray(prhs[6]); 6263 mxDestroyArray(prhs[7]); 6264 mxDestroyArray(plhs[0]); 6265 mxDestroyArray(plhs[1]); 6266 PetscFunctionReturn(0); 6267 } 6268 6269 /* 6270 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 6271 vector for use by the TS routines in solving ODEs from MATLAB. Here the function is a string containing the name of a MATLAB function 6272 6273 Logically Collective on TS 6274 6275 Input Parameters: 6276 + ts - the TS context 6277 . A,B - Jacobian matrices 6278 . func - function evaluation routine 6279 - ctx - user context 6280 6281 Calling sequence of func: 6282 $ flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx); 6283 6284 Level: developer 6285 6286 .keywords: TS, nonlinear, set, function 6287 6288 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6289 */ 6290 PetscErrorCode TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx) 6291 { 6292 PetscErrorCode ierr; 6293 TSMatlabContext *sctx; 6294 6295 PetscFunctionBegin; 6296 /* currently sctx is memory bleed */ 6297 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6298 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6299 /* 6300 This should work, but it doesn't 6301 sctx->ctx = ctx; 6302 mexMakeArrayPersistent(sctx->ctx); 6303 */ 6304 sctx->ctx = mxDuplicateArray(ctx); 6305 6306 ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 6307 PetscFunctionReturn(0); 6308 } 6309 6310 /* 6311 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 6312 6313 Collective on TS 6314 6315 .seealso: TSSetFunction(), TSGetFunction() 6316 @*/ 6317 PetscErrorCode TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx) 6318 { 6319 PetscErrorCode ierr; 6320 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6321 int nlhs = 1,nrhs = 6; 6322 mxArray *plhs[1],*prhs[6]; 6323 long long int lx = 0,ls = 0; 6324 6325 PetscFunctionBegin; 6326 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6327 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 6328 6329 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 6330 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6331 6332 prhs[0] = mxCreateDoubleScalar((double)ls); 6333 prhs[1] = mxCreateDoubleScalar((double)it); 6334 prhs[2] = mxCreateDoubleScalar((double)time); 6335 prhs[3] = mxCreateDoubleScalar((double)lx); 6336 prhs[4] = mxCreateString(sctx->funcname); 6337 prhs[5] = sctx->ctx; 6338 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 6339 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6340 mxDestroyArray(prhs[0]); 6341 mxDestroyArray(prhs[1]); 6342 mxDestroyArray(prhs[2]); 6343 mxDestroyArray(prhs[3]); 6344 mxDestroyArray(prhs[4]); 6345 mxDestroyArray(plhs[0]); 6346 PetscFunctionReturn(0); 6347 } 6348 6349 /* 6350 TSMonitorSetMatlab - Sets the monitor function from Matlab 6351 6352 Level: developer 6353 6354 .keywords: TS, nonlinear, set, function 6355 6356 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6357 */ 6358 PetscErrorCode TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx) 6359 { 6360 PetscErrorCode ierr; 6361 TSMatlabContext *sctx; 6362 6363 PetscFunctionBegin; 6364 /* currently sctx is memory bleed */ 6365 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6366 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6367 /* 6368 This should work, but it doesn't 6369 sctx->ctx = ctx; 6370 mexMakeArrayPersistent(sctx->ctx); 6371 */ 6372 sctx->ctx = mxDuplicateArray(ctx); 6373 6374 ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 6375 PetscFunctionReturn(0); 6376 } 6377 #endif 6378 6379 /*@C 6380 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 6381 in a time based line graph 6382 6383 Collective on TS 6384 6385 Input Parameters: 6386 + ts - the TS context 6387 . step - current time-step 6388 . ptime - current time 6389 . u - current solution 6390 - dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate() 6391 6392 Options Database: 6393 . -ts_monitor_lg_solution_variables 6394 6395 Level: intermediate 6396 6397 Notes: Each process in a parallel run displays its component solutions in a separate window 6398 6399 .keywords: TS, vector, monitor, view 6400 6401 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 6402 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 6403 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 6404 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 6405 @*/ 6406 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 6407 { 6408 PetscErrorCode ierr; 6409 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dctx; 6410 const PetscScalar *yy; 6411 Vec v; 6412 6413 PetscFunctionBegin; 6414 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6415 if (!step) { 6416 PetscDrawAxis axis; 6417 PetscInt dim; 6418 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6419 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 6420 if (!ctx->names) { 6421 PetscBool flg; 6422 /* user provides names of variables to plot but no names has been set so assume names are integer values */ 6423 ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr); 6424 if (flg) { 6425 PetscInt i,n; 6426 char **names; 6427 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 6428 ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr); 6429 for (i=0; i<n; i++) { 6430 ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr); 6431 ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr); 6432 } 6433 names[n] = NULL; 6434 ctx->names = names; 6435 } 6436 } 6437 if (ctx->names && !ctx->displaynames) { 6438 char **displaynames; 6439 PetscBool flg; 6440 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6441 ierr = PetscMalloc1(dim+1,&displaynames);CHKERRQ(ierr); 6442 ierr = PetscMemzero(displaynames,(dim+1)*sizeof(char*));CHKERRQ(ierr); 6443 ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr); 6444 if (flg) { 6445 ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr); 6446 } 6447 ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr); 6448 } 6449 if (ctx->displaynames) { 6450 ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr); 6451 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr); 6452 } else if (ctx->names) { 6453 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6454 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6455 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr); 6456 } else { 6457 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6458 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6459 } 6460 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6461 } 6462 6463 if (!ctx->transform) v = u; 6464 else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);} 6465 ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr); 6466 if (ctx->displaynames) { 6467 PetscInt i; 6468 for (i=0; i<ctx->ndisplayvariables; i++) 6469 ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]); 6470 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr); 6471 } else { 6472 #if defined(PETSC_USE_COMPLEX) 6473 PetscInt i,n; 6474 PetscReal *yreal; 6475 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 6476 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6477 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6478 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6479 ierr = PetscFree(yreal);CHKERRQ(ierr); 6480 #else 6481 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6482 #endif 6483 } 6484 ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr); 6485 if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);} 6486 6487 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6488 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6489 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6490 } 6491 PetscFunctionReturn(0); 6492 } 6493 6494 /*@C 6495 TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 6496 6497 Collective on TS 6498 6499 Input Parameters: 6500 + ts - the TS context 6501 - names - the names of the components, final string must be NULL 6502 6503 Level: intermediate 6504 6505 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6506 6507 .keywords: TS, vector, monitor, view 6508 6509 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames() 6510 @*/ 6511 PetscErrorCode TSMonitorLGSetVariableNames(TS ts,const char * const *names) 6512 { 6513 PetscErrorCode ierr; 6514 PetscInt i; 6515 6516 PetscFunctionBegin; 6517 for (i=0; i<ts->numbermonitors; i++) { 6518 if (ts->monitor[i] == TSMonitorLGSolution) { 6519 ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr); 6520 break; 6521 } 6522 } 6523 PetscFunctionReturn(0); 6524 } 6525 6526 /*@C 6527 TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 6528 6529 Collective on TS 6530 6531 Input Parameters: 6532 + ts - the TS context 6533 - names - the names of the components, final string must be NULL 6534 6535 Level: intermediate 6536 6537 .keywords: TS, vector, monitor, view 6538 6539 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames() 6540 @*/ 6541 PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names) 6542 { 6543 PetscErrorCode ierr; 6544 6545 PetscFunctionBegin; 6546 ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr); 6547 ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr); 6548 PetscFunctionReturn(0); 6549 } 6550 6551 /*@C 6552 TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot 6553 6554 Collective on TS 6555 6556 Input Parameter: 6557 . ts - the TS context 6558 6559 Output Parameter: 6560 . names - the names of the components, final string must be NULL 6561 6562 Level: intermediate 6563 6564 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6565 6566 .keywords: TS, vector, monitor, view 6567 6568 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 6569 @*/ 6570 PetscErrorCode TSMonitorLGGetVariableNames(TS ts,const char *const **names) 6571 { 6572 PetscInt i; 6573 6574 PetscFunctionBegin; 6575 *names = NULL; 6576 for (i=0; i<ts->numbermonitors; i++) { 6577 if (ts->monitor[i] == TSMonitorLGSolution) { 6578 TSMonitorLGCtx ctx = (TSMonitorLGCtx) ts->monitorcontext[i]; 6579 *names = (const char *const *)ctx->names; 6580 break; 6581 } 6582 } 6583 PetscFunctionReturn(0); 6584 } 6585 6586 /*@C 6587 TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor 6588 6589 Collective on TS 6590 6591 Input Parameters: 6592 + ctx - the TSMonitorLG context 6593 . displaynames - the names of the components, final string must be NULL 6594 6595 Level: intermediate 6596 6597 .keywords: TS, vector, monitor, view 6598 6599 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 6600 @*/ 6601 PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames) 6602 { 6603 PetscInt j = 0,k; 6604 PetscErrorCode ierr; 6605 6606 PetscFunctionBegin; 6607 if (!ctx->names) PetscFunctionReturn(0); 6608 ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr); 6609 ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr); 6610 while (displaynames[j]) j++; 6611 ctx->ndisplayvariables = j; 6612 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr); 6613 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr); 6614 j = 0; 6615 while (displaynames[j]) { 6616 k = 0; 6617 while (ctx->names[k]) { 6618 PetscBool flg; 6619 ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr); 6620 if (flg) { 6621 ctx->displayvariables[j] = k; 6622 break; 6623 } 6624 k++; 6625 } 6626 j++; 6627 } 6628 PetscFunctionReturn(0); 6629 } 6630 6631 /*@C 6632 TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor 6633 6634 Collective on TS 6635 6636 Input Parameters: 6637 + ts - the TS context 6638 . displaynames - the names of the components, final string must be NULL 6639 6640 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6641 6642 Level: intermediate 6643 6644 .keywords: TS, vector, monitor, view 6645 6646 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 6647 @*/ 6648 PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames) 6649 { 6650 PetscInt i; 6651 PetscErrorCode ierr; 6652 6653 PetscFunctionBegin; 6654 for (i=0; i<ts->numbermonitors; i++) { 6655 if (ts->monitor[i] == TSMonitorLGSolution) { 6656 ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr); 6657 break; 6658 } 6659 } 6660 PetscFunctionReturn(0); 6661 } 6662 6663 /*@C 6664 TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed 6665 6666 Collective on TS 6667 6668 Input Parameters: 6669 + ts - the TS context 6670 . transform - the transform function 6671 . destroy - function to destroy the optional context 6672 - ctx - optional context used by transform function 6673 6674 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6675 6676 Level: intermediate 6677 6678 .keywords: TS, vector, monitor, view 6679 6680 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform() 6681 @*/ 6682 PetscErrorCode TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 6683 { 6684 PetscInt i; 6685 PetscErrorCode ierr; 6686 6687 PetscFunctionBegin; 6688 for (i=0; i<ts->numbermonitors; i++) { 6689 if (ts->monitor[i] == TSMonitorLGSolution) { 6690 ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr); 6691 } 6692 } 6693 PetscFunctionReturn(0); 6694 } 6695 6696 /*@C 6697 TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed 6698 6699 Collective on TSLGCtx 6700 6701 Input Parameters: 6702 + ts - the TS context 6703 . transform - the transform function 6704 . destroy - function to destroy the optional context 6705 - ctx - optional context used by transform function 6706 6707 Level: intermediate 6708 6709 .keywords: TS, vector, monitor, view 6710 6711 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform() 6712 @*/ 6713 PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 6714 { 6715 PetscFunctionBegin; 6716 ctx->transform = transform; 6717 ctx->transformdestroy = destroy; 6718 ctx->transformctx = tctx; 6719 PetscFunctionReturn(0); 6720 } 6721 6722 /*@C 6723 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error 6724 in a time based line graph 6725 6726 Collective on TS 6727 6728 Input Parameters: 6729 + ts - the TS context 6730 . step - current time-step 6731 . ptime - current time 6732 . u - current solution 6733 - dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate() 6734 6735 Level: intermediate 6736 6737 Notes: Each process in a parallel run displays its component errors in a separate window 6738 6739 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 6740 6741 Options Database Keys: 6742 . -ts_monitor_lg_error - create a graphical monitor of error history 6743 6744 .keywords: TS, vector, monitor, view 6745 6746 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 6747 @*/ 6748 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 6749 { 6750 PetscErrorCode ierr; 6751 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 6752 const PetscScalar *yy; 6753 Vec y; 6754 6755 PetscFunctionBegin; 6756 if (!step) { 6757 PetscDrawAxis axis; 6758 PetscInt dim; 6759 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6760 ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error");CHKERRQ(ierr); 6761 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6762 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6763 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6764 } 6765 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 6766 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 6767 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 6768 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 6769 #if defined(PETSC_USE_COMPLEX) 6770 { 6771 PetscReal *yreal; 6772 PetscInt i,n; 6773 ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); 6774 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6775 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6776 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6777 ierr = PetscFree(yreal);CHKERRQ(ierr); 6778 } 6779 #else 6780 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6781 #endif 6782 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 6783 ierr = VecDestroy(&y);CHKERRQ(ierr); 6784 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6785 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6786 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6787 } 6788 PetscFunctionReturn(0); 6789 } 6790 6791 /*@C 6792 TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep 6793 6794 Collective on TS 6795 6796 Input Parameters: 6797 + ts - the TS context 6798 . step - current time-step 6799 . ptime - current time 6800 . u - current solution 6801 - dctx - unused context 6802 6803 Level: intermediate 6804 6805 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 6806 6807 Options Database Keys: 6808 . -ts_monitor_error - create a graphical monitor of error history 6809 6810 .keywords: TS, vector, monitor, view 6811 6812 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 6813 @*/ 6814 PetscErrorCode TSMonitorError(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 6815 { 6816 PetscErrorCode ierr; 6817 Vec y; 6818 PetscReal nrm; 6819 PetscBool flg; 6820 6821 PetscFunctionBegin; 6822 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 6823 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 6824 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 6825 ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERASCII,&flg);CHKERRQ(ierr); 6826 if (flg) { 6827 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 6828 ierr = PetscViewerASCIIPrintf(vf->viewer,"2-norm of error %g\n",(double)nrm);CHKERRQ(ierr); 6829 } 6830 ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERDRAW,&flg);CHKERRQ(ierr); 6831 if (flg) { 6832 ierr = VecView(y,vf->viewer);CHKERRQ(ierr); 6833 } 6834 ierr = VecDestroy(&y);CHKERRQ(ierr); 6835 PetscFunctionReturn(0); 6836 } 6837 6838 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 6839 { 6840 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 6841 PetscReal x = ptime,y; 6842 PetscErrorCode ierr; 6843 PetscInt its; 6844 6845 PetscFunctionBegin; 6846 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6847 if (!n) { 6848 PetscDrawAxis axis; 6849 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6850 ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr); 6851 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6852 ctx->snes_its = 0; 6853 } 6854 ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr); 6855 y = its - ctx->snes_its; 6856 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 6857 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 6858 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6859 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6860 } 6861 ctx->snes_its = its; 6862 PetscFunctionReturn(0); 6863 } 6864 6865 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 6866 { 6867 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 6868 PetscReal x = ptime,y; 6869 PetscErrorCode ierr; 6870 PetscInt its; 6871 6872 PetscFunctionBegin; 6873 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6874 if (!n) { 6875 PetscDrawAxis axis; 6876 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6877 ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr); 6878 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6879 ctx->ksp_its = 0; 6880 } 6881 ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr); 6882 y = its - ctx->ksp_its; 6883 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 6884 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 6885 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6886 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6887 } 6888 ctx->ksp_its = its; 6889 PetscFunctionReturn(0); 6890 } 6891 6892 /*@ 6893 TSComputeLinearStability - computes the linear stability function at a point 6894 6895 Collective on TS and Vec 6896 6897 Input Parameters: 6898 + ts - the TS context 6899 - xr,xi - real and imaginary part of input arguments 6900 6901 Output Parameters: 6902 . yr,yi - real and imaginary part of function value 6903 6904 Level: developer 6905 6906 .keywords: TS, compute 6907 6908 .seealso: TSSetRHSFunction(), TSComputeIFunction() 6909 @*/ 6910 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi) 6911 { 6912 PetscErrorCode ierr; 6913 6914 PetscFunctionBegin; 6915 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6916 if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method"); 6917 ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr); 6918 PetscFunctionReturn(0); 6919 } 6920 6921 /* ------------------------------------------------------------------------*/ 6922 /*@C 6923 TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope() 6924 6925 Collective on TS 6926 6927 Input Parameters: 6928 . ts - the ODE solver object 6929 6930 Output Parameter: 6931 . ctx - the context 6932 6933 Level: intermediate 6934 6935 .keywords: TS, monitor, line graph, residual, seealso 6936 6937 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 6938 6939 @*/ 6940 PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx) 6941 { 6942 PetscErrorCode ierr; 6943 6944 PetscFunctionBegin; 6945 ierr = PetscNew(ctx);CHKERRQ(ierr); 6946 PetscFunctionReturn(0); 6947 } 6948 6949 /*@C 6950 TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution 6951 6952 Collective on TS 6953 6954 Input Parameters: 6955 + ts - the TS context 6956 . step - current time-step 6957 . ptime - current time 6958 . u - current solution 6959 - dctx - the envelope context 6960 6961 Options Database: 6962 . -ts_monitor_envelope 6963 6964 Level: intermediate 6965 6966 Notes: after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope 6967 6968 .keywords: TS, vector, monitor, view 6969 6970 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate() 6971 @*/ 6972 PetscErrorCode TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 6973 { 6974 PetscErrorCode ierr; 6975 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx; 6976 6977 PetscFunctionBegin; 6978 if (!ctx->max) { 6979 ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr); 6980 ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr); 6981 ierr = VecCopy(u,ctx->max);CHKERRQ(ierr); 6982 ierr = VecCopy(u,ctx->min);CHKERRQ(ierr); 6983 } else { 6984 ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr); 6985 ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr); 6986 } 6987 PetscFunctionReturn(0); 6988 } 6989 6990 /*@C 6991 TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution 6992 6993 Collective on TS 6994 6995 Input Parameter: 6996 . ts - the TS context 6997 6998 Output Parameter: 6999 + max - the maximum values 7000 - min - the minimum values 7001 7002 Notes: If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored 7003 7004 Level: intermediate 7005 7006 .keywords: TS, vector, monitor, view 7007 7008 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 7009 @*/ 7010 PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min) 7011 { 7012 PetscInt i; 7013 7014 PetscFunctionBegin; 7015 if (max) *max = NULL; 7016 if (min) *min = NULL; 7017 for (i=0; i<ts->numbermonitors; i++) { 7018 if (ts->monitor[i] == TSMonitorEnvelope) { 7019 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i]; 7020 if (max) *max = ctx->max; 7021 if (min) *min = ctx->min; 7022 break; 7023 } 7024 } 7025 PetscFunctionReturn(0); 7026 } 7027 7028 /*@C 7029 TSMonitorEnvelopeCtxDestroy - Destroys a context that was created with TSMonitorEnvelopeCtxCreate(). 7030 7031 Collective on TSMonitorEnvelopeCtx 7032 7033 Input Parameter: 7034 . ctx - the monitor context 7035 7036 Level: intermediate 7037 7038 .keywords: TS, monitor, line graph, destroy 7039 7040 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep() 7041 @*/ 7042 PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx) 7043 { 7044 PetscErrorCode ierr; 7045 7046 PetscFunctionBegin; 7047 ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr); 7048 ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr); 7049 ierr = PetscFree(*ctx);CHKERRQ(ierr); 7050 PetscFunctionReturn(0); 7051 } 7052 7053 /*@ 7054 TSRestartStep - Flags the solver to restart the next step 7055 7056 Collective on TS 7057 7058 Input Parameter: 7059 . ts - the TS context obtained from TSCreate() 7060 7061 Level: advanced 7062 7063 Notes: 7064 Multistep methods like BDF or Runge-Kutta methods with FSAL property require restarting the solver in the event of 7065 discontinuities. These discontinuities may be introduced as a consequence of explicitly modifications to the solution 7066 vector (which PETSc attempts to detect and handle) or problem coefficients (which PETSc is not able to detect). For 7067 the sake of correctness and maximum safety, users are expected to call TSRestart() whenever they introduce 7068 discontinuities in callback routines (e.g. prestep and poststep routines, or implicit/rhs function routines with 7069 discontinuous source terms). 7070 7071 .keywords: TS, timestep, restart 7072 7073 .seealso: TSSolve(), TSSetPreStep(), TSSetPostStep() 7074 @*/ 7075 PetscErrorCode TSRestartStep(TS ts) 7076 { 7077 PetscFunctionBegin; 7078 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7079 ts->steprestart = PETSC_TRUE; 7080 PetscFunctionReturn(0); 7081 } 7082 7083 /*@ 7084 TSRollBack - Rolls back one time step 7085 7086 Collective on TS 7087 7088 Input Parameter: 7089 . ts - the TS context obtained from TSCreate() 7090 7091 Level: advanced 7092 7093 .keywords: TS, timestep, rollback 7094 7095 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate() 7096 @*/ 7097 PetscErrorCode TSRollBack(TS ts) 7098 { 7099 PetscErrorCode ierr; 7100 7101 PetscFunctionBegin; 7102 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7103 if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called"); 7104 if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name); 7105 ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr); 7106 ts->time_step = ts->ptime - ts->ptime_prev; 7107 ts->ptime = ts->ptime_prev; 7108 ts->ptime_prev = ts->ptime_prev_rollback; 7109 ts->steps--; 7110 ts->steprollback = PETSC_TRUE; 7111 PetscFunctionReturn(0); 7112 } 7113 7114 /*@ 7115 TSGetStages - Get the number of stages and stage values 7116 7117 Input Parameter: 7118 . ts - the TS context obtained from TSCreate() 7119 7120 Level: advanced 7121 7122 .keywords: TS, getstages 7123 7124 .seealso: TSCreate() 7125 @*/ 7126 PetscErrorCode TSGetStages(TS ts,PetscInt *ns,Vec **Y) 7127 { 7128 PetscErrorCode ierr; 7129 7130 PetscFunctionBegin; 7131 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7132 PetscValidPointer(ns,2); 7133 7134 if (!ts->ops->getstages) *ns=0; 7135 else { 7136 ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr); 7137 } 7138 PetscFunctionReturn(0); 7139 } 7140 7141 /*@C 7142 TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity. 7143 7144 Collective on SNES 7145 7146 Input Parameters: 7147 + ts - the TS context 7148 . t - current timestep 7149 . U - state vector 7150 . Udot - time derivative of state vector 7151 . shift - shift to apply, see note below 7152 - ctx - an optional user context 7153 7154 Output Parameters: 7155 + J - Jacobian matrix (not altered in this routine) 7156 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 7157 7158 Level: intermediate 7159 7160 Notes: 7161 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 7162 7163 dF/dU + shift*dF/dUdot 7164 7165 Most users should not need to explicitly call this routine, as it 7166 is used internally within the nonlinear solvers. 7167 7168 This will first try to get the coloring from the DM. If the DM type has no coloring 7169 routine, then it will try to get the coloring from the matrix. This requires that the 7170 matrix have nonzero entries precomputed. 7171 7172 .keywords: TS, finite differences, Jacobian, coloring, sparse 7173 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction() 7174 @*/ 7175 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx) 7176 { 7177 SNES snes; 7178 MatFDColoring color; 7179 PetscBool hascolor, matcolor = PETSC_FALSE; 7180 PetscErrorCode ierr; 7181 7182 PetscFunctionBegin; 7183 ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr); 7184 ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr); 7185 if (!color) { 7186 DM dm; 7187 ISColoring iscoloring; 7188 7189 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 7190 ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr); 7191 if (hascolor && !matcolor) { 7192 ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr); 7193 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7194 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7195 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7196 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7197 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7198 } else { 7199 MatColoring mc; 7200 7201 ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr); 7202 ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr); 7203 ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr); 7204 ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 7205 ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr); 7206 ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 7207 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7208 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7209 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7210 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7211 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7212 } 7213 ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr); 7214 ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr); 7215 } 7216 ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr); 7217 ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr); 7218 if (J != B) { 7219 ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7220 ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7221 } 7222 PetscFunctionReturn(0); 7223 } 7224 7225 /*@ 7226 TSSetFunctionDomainError - Set the function testing if the current state vector is valid 7227 7228 Input Parameters: 7229 ts - the TS context 7230 func - function called within TSFunctionDomainError 7231 7232 Level: intermediate 7233 7234 .keywords: TS, state, domain 7235 .seealso: TSAdaptCheckStage(), TSFunctionDomainError() 7236 @*/ 7237 7238 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*)) 7239 { 7240 PetscFunctionBegin; 7241 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7242 ts->functiondomainerror = func; 7243 PetscFunctionReturn(0); 7244 } 7245 7246 /*@ 7247 TSFunctionDomainError - Check if the current state is valid 7248 7249 Input Parameters: 7250 ts - the TS context 7251 stagetime - time of the simulation 7252 Y - state vector to check. 7253 7254 Output Parameter: 7255 accept - Set to PETSC_FALSE if the current state vector is valid. 7256 7257 Note: 7258 This function should be used to ensure the state is in a valid part of the space. 7259 For example, one can ensure here all values are positive. 7260 7261 Level: advanced 7262 @*/ 7263 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept) 7264 { 7265 PetscErrorCode ierr; 7266 7267 PetscFunctionBegin; 7268 7269 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7270 *accept = PETSC_TRUE; 7271 if (ts->functiondomainerror) { 7272 PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept)); 7273 } 7274 PetscFunctionReturn(0); 7275 } 7276 7277 /*@C 7278 TSClone - This function clones a time step object. 7279 7280 Collective on MPI_Comm 7281 7282 Input Parameter: 7283 . tsin - The input TS 7284 7285 Output Parameter: 7286 . tsout - The output TS (cloned) 7287 7288 Notes: 7289 This function is used to create a clone of a TS object. It is used in ARKIMEX for initializing the slope for first stage explicit methods. It will likely be replaced in the future with a mechanism of switching methods on the fly. 7290 7291 When using TSDestroy() on a clone the user has to first reset the correct TS reference in the embedded SNES object: e.g.: by running SNES snes_dup=NULL; TSGetSNES(ts,&snes_dup); ierr = TSSetSNES(ts,snes_dup); 7292 7293 Level: developer 7294 7295 .keywords: TS, clone 7296 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType() 7297 @*/ 7298 PetscErrorCode TSClone(TS tsin, TS *tsout) 7299 { 7300 TS t; 7301 PetscErrorCode ierr; 7302 SNES snes_start; 7303 DM dm; 7304 TSType type; 7305 7306 PetscFunctionBegin; 7307 PetscValidPointer(tsin,1); 7308 *tsout = NULL; 7309 7310 ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr); 7311 7312 /* General TS description */ 7313 t->numbermonitors = 0; 7314 t->setupcalled = 0; 7315 t->ksp_its = 0; 7316 t->snes_its = 0; 7317 t->nwork = 0; 7318 t->rhsjacobian.time = -1e20; 7319 t->rhsjacobian.scale = 1.; 7320 t->ijacobian.shift = 1.; 7321 7322 ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr); 7323 ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr); 7324 7325 ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr); 7326 ierr = TSSetDM(t,dm);CHKERRQ(ierr); 7327 7328 t->adapt = tsin->adapt; 7329 ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr); 7330 7331 t->trajectory = tsin->trajectory; 7332 ierr = PetscObjectReference((PetscObject)t->trajectory);CHKERRQ(ierr); 7333 7334 t->event = tsin->event; 7335 if (t->event) t->event->refct++; 7336 7337 t->problem_type = tsin->problem_type; 7338 t->ptime = tsin->ptime; 7339 t->ptime_prev = tsin->ptime_prev; 7340 t->time_step = tsin->time_step; 7341 t->max_time = tsin->max_time; 7342 t->steps = tsin->steps; 7343 t->max_steps = tsin->max_steps; 7344 t->equation_type = tsin->equation_type; 7345 t->atol = tsin->atol; 7346 t->rtol = tsin->rtol; 7347 t->max_snes_failures = tsin->max_snes_failures; 7348 t->max_reject = tsin->max_reject; 7349 t->errorifstepfailed = tsin->errorifstepfailed; 7350 7351 ierr = TSGetType(tsin,&type);CHKERRQ(ierr); 7352 ierr = TSSetType(t,type);CHKERRQ(ierr); 7353 7354 t->vec_sol = NULL; 7355 7356 t->cfltime = tsin->cfltime; 7357 t->cfltime_local = tsin->cfltime_local; 7358 t->exact_final_time = tsin->exact_final_time; 7359 7360 ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr); 7361 7362 if (((PetscObject)tsin)->fortran_func_pointers) { 7363 PetscInt i; 7364 ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr); 7365 for (i=0; i<10; i++) { 7366 ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i]; 7367 } 7368 } 7369 *tsout = t; 7370 PetscFunctionReturn(0); 7371 } 7372 7373 static PetscErrorCode RHSWrapperFunction_TSRHSJacobianTest(void* ctx,Vec x,Vec y) 7374 { 7375 PetscErrorCode ierr; 7376 TS ts = (TS) ctx; 7377 7378 PetscFunctionBegin; 7379 ierr = TSComputeRHSFunction(ts,0,x,y);CHKERRQ(ierr); 7380 PetscFunctionReturn(0); 7381 } 7382 7383 /*@ 7384 TSRHSJacobianTest - Compares the multiply routine provided to the MATSHELL with differencing on the TS given RHS function. 7385 7386 Logically Collective on TS and Mat 7387 7388 Input Parameters: 7389 TS - the time stepping routine 7390 7391 Output Parameter: 7392 . flg - PETSC_TRUE if the multiply is likely correct 7393 7394 Options Database: 7395 . -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - run the test at each timestep of the integrator 7396 7397 Level: advanced 7398 7399 Notes: This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian 7400 7401 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTestTranspose() 7402 @*/ 7403 PetscErrorCode TSRHSJacobianTest(TS ts,PetscBool *flg) 7404 { 7405 Mat J,B; 7406 PetscErrorCode ierr; 7407 TSRHSJacobian func; 7408 void* ctx; 7409 7410 PetscFunctionBegin; 7411 ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr); 7412 ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr); 7413 ierr = MatShellTestMult(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr); 7414 PetscFunctionReturn(0); 7415 } 7416 7417 /*@C 7418 TSRHSJacobianTestTranspose - Compares the multiply transpose routine provided to the MATSHELL with differencing on the TS given RHS function. 7419 7420 Logically Collective on TS and Mat 7421 7422 Input Parameters: 7423 TS - the time stepping routine 7424 7425 Output Parameter: 7426 . flg - PETSC_TRUE if the multiply is likely correct 7427 7428 Options Database: 7429 . -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - run the test at each timestep of the integrator 7430 7431 Notes: This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian 7432 7433 Level: advanced 7434 7435 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTest() 7436 @*/ 7437 PetscErrorCode TSRHSJacobianTestTranspose(TS ts,PetscBool *flg) 7438 { 7439 Mat J,B; 7440 PetscErrorCode ierr; 7441 void *ctx; 7442 TSRHSJacobian func; 7443 7444 PetscFunctionBegin; 7445 ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr); 7446 ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr); 7447 ierr = MatShellTestMultTranspose(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr); 7448 PetscFunctionReturn(0); 7449 } 7450