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