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