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