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