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