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