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