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