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