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