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