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