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 PetscInt i; 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 for (i=0; i<ts->num_rhs_splits; i++) { 2619 ierr = TSDestroy(&ts->tsrhssplit[i]->ts);CHKERRQ(ierr); 2620 ierr = PetscFree(ts->tsrhssplit[i]->splitname);CHKERRQ(ierr); 2621 ierr = ISDestroy(&ts->tsrhssplit[i]->is);CHKERRQ(ierr); 2622 ierr = PetscFree(ts->tsrhssplit[i]);CHKERRQ(ierr); 2623 } 2624 ts->num_rhs_splits = 0; 2625 ts->setupcalled = PETSC_FALSE; 2626 PetscFunctionReturn(0); 2627 } 2628 2629 /*@ 2630 TSDestroy - Destroys the timestepper context that was created 2631 with TSCreate(). 2632 2633 Collective on TS 2634 2635 Input Parameter: 2636 . ts - the TS context obtained from TSCreate() 2637 2638 Level: beginner 2639 2640 .keywords: TS, timestepper, destroy 2641 2642 .seealso: TSCreate(), TSSetUp(), TSSolve() 2643 @*/ 2644 PetscErrorCode TSDestroy(TS *ts) 2645 { 2646 PetscErrorCode ierr; 2647 2648 PetscFunctionBegin; 2649 if (!*ts) PetscFunctionReturn(0); 2650 PetscValidHeaderSpecific((*ts),TS_CLASSID,1); 2651 if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);} 2652 2653 ierr = TSReset((*ts));CHKERRQ(ierr); 2654 2655 /* if memory was published with SAWs then destroy it */ 2656 ierr = PetscObjectSAWsViewOff((PetscObject)*ts);CHKERRQ(ierr); 2657 if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);} 2658 2659 ierr = TSTrajectoryDestroy(&(*ts)->trajectory);CHKERRQ(ierr); 2660 2661 ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr); 2662 ierr = TSEventDestroy(&(*ts)->event);CHKERRQ(ierr); 2663 2664 ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr); 2665 ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr); 2666 ierr = TSMonitorCancel((*ts));CHKERRQ(ierr); 2667 ierr = TSAdjointMonitorCancel((*ts));CHKERRQ(ierr); 2668 2669 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 2670 PetscFunctionReturn(0); 2671 } 2672 2673 /*@ 2674 TSGetSNES - Returns the SNES (nonlinear solver) associated with 2675 a TS (timestepper) context. Valid only for nonlinear problems. 2676 2677 Not Collective, but SNES is parallel if TS is parallel 2678 2679 Input Parameter: 2680 . ts - the TS context obtained from TSCreate() 2681 2682 Output Parameter: 2683 . snes - the nonlinear solver context 2684 2685 Notes: 2686 The user can then directly manipulate the SNES context to set various 2687 options, etc. Likewise, the user can then extract and manipulate the 2688 KSP, KSP, and PC contexts as well. 2689 2690 TSGetSNES() does not work for integrators that do not use SNES; in 2691 this case TSGetSNES() returns NULL in snes. 2692 2693 Level: beginner 2694 2695 .keywords: timestep, get, SNES 2696 @*/ 2697 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 2698 { 2699 PetscErrorCode ierr; 2700 2701 PetscFunctionBegin; 2702 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2703 PetscValidPointer(snes,2); 2704 if (!ts->snes) { 2705 ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr); 2706 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2707 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);CHKERRQ(ierr); 2708 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 2709 if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 2710 if (ts->problem_type == TS_LINEAR) { 2711 ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); 2712 } 2713 } 2714 *snes = ts->snes; 2715 PetscFunctionReturn(0); 2716 } 2717 2718 /*@ 2719 TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context 2720 2721 Collective 2722 2723 Input Parameter: 2724 + ts - the TS context obtained from TSCreate() 2725 - snes - the nonlinear solver context 2726 2727 Notes: 2728 Most users should have the TS created by calling TSGetSNES() 2729 2730 Level: developer 2731 2732 .keywords: timestep, set, SNES 2733 @*/ 2734 PetscErrorCode TSSetSNES(TS ts,SNES snes) 2735 { 2736 PetscErrorCode ierr; 2737 PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*); 2738 2739 PetscFunctionBegin; 2740 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2741 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 2742 ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr); 2743 ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr); 2744 2745 ts->snes = snes; 2746 2747 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2748 ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr); 2749 if (func == SNESTSFormJacobian) { 2750 ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr); 2751 } 2752 PetscFunctionReturn(0); 2753 } 2754 2755 /*@ 2756 TSGetKSP - Returns the KSP (linear solver) associated with 2757 a TS (timestepper) context. 2758 2759 Not Collective, but KSP is parallel if TS is parallel 2760 2761 Input Parameter: 2762 . ts - the TS context obtained from TSCreate() 2763 2764 Output Parameter: 2765 . ksp - the nonlinear solver context 2766 2767 Notes: 2768 The user can then directly manipulate the KSP context to set various 2769 options, etc. Likewise, the user can then extract and manipulate the 2770 KSP and PC contexts as well. 2771 2772 TSGetKSP() does not work for integrators that do not use KSP; 2773 in this case TSGetKSP() returns NULL in ksp. 2774 2775 Level: beginner 2776 2777 .keywords: timestep, get, KSP 2778 @*/ 2779 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 2780 { 2781 PetscErrorCode ierr; 2782 SNES snes; 2783 2784 PetscFunctionBegin; 2785 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2786 PetscValidPointer(ksp,2); 2787 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 2788 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 2789 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2790 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 2791 PetscFunctionReturn(0); 2792 } 2793 2794 /* ----------- Routines to set solver parameters ---------- */ 2795 2796 /*@ 2797 TSSetMaxSteps - Sets the maximum number of steps to use. 2798 2799 Logically Collective on TS 2800 2801 Input Parameters: 2802 + ts - the TS context obtained from TSCreate() 2803 - maxsteps - maximum number of steps to use 2804 2805 Options Database Keys: 2806 . -ts_max_steps <maxsteps> - Sets maxsteps 2807 2808 Notes: 2809 The default maximum number of steps is 5000 2810 2811 Level: intermediate 2812 2813 .keywords: TS, timestep, set, maximum, steps 2814 2815 .seealso: TSGetMaxSteps(), TSSetMaxTime(), TSSetExactFinalTime() 2816 @*/ 2817 PetscErrorCode TSSetMaxSteps(TS ts,PetscInt maxsteps) 2818 { 2819 PetscFunctionBegin; 2820 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2821 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 2822 if (maxsteps < 0 ) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of steps must be non-negative"); 2823 ts->max_steps = maxsteps; 2824 PetscFunctionReturn(0); 2825 } 2826 2827 /*@ 2828 TSGetMaxSteps - Gets the maximum number of steps to use. 2829 2830 Not Collective 2831 2832 Input Parameters: 2833 . ts - the TS context obtained from TSCreate() 2834 2835 Output Parameter: 2836 . maxsteps - maximum number of steps to use 2837 2838 Level: advanced 2839 2840 .keywords: TS, timestep, get, maximum, steps 2841 2842 .seealso: TSSetMaxSteps(), TSGetMaxTime(), TSSetMaxTime() 2843 @*/ 2844 PetscErrorCode TSGetMaxSteps(TS ts,PetscInt *maxsteps) 2845 { 2846 PetscFunctionBegin; 2847 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2848 PetscValidIntPointer(maxsteps,2); 2849 *maxsteps = ts->max_steps; 2850 PetscFunctionReturn(0); 2851 } 2852 2853 /*@ 2854 TSSetMaxTime - Sets the maximum (or final) time for timestepping. 2855 2856 Logically Collective on TS 2857 2858 Input Parameters: 2859 + ts - the TS context obtained from TSCreate() 2860 - maxtime - final time to step to 2861 2862 Options Database Keys: 2863 . -ts_max_time <maxtime> - Sets maxtime 2864 2865 Notes: 2866 The default maximum time is 5.0 2867 2868 Level: intermediate 2869 2870 .keywords: TS, timestep, set, maximum, time 2871 2872 .seealso: TSGetMaxTime(), TSSetMaxSteps(), TSSetExactFinalTime() 2873 @*/ 2874 PetscErrorCode TSSetMaxTime(TS ts,PetscReal maxtime) 2875 { 2876 PetscFunctionBegin; 2877 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2878 PetscValidLogicalCollectiveReal(ts,maxtime,2); 2879 ts->max_time = maxtime; 2880 PetscFunctionReturn(0); 2881 } 2882 2883 /*@ 2884 TSGetMaxTime - Gets the maximum (or final) time for timestepping. 2885 2886 Not Collective 2887 2888 Input Parameters: 2889 . ts - the TS context obtained from TSCreate() 2890 2891 Output Parameter: 2892 . maxtime - final time to step to 2893 2894 Level: advanced 2895 2896 .keywords: TS, timestep, get, maximum, time 2897 2898 .seealso: TSSetMaxTime(), TSGetMaxSteps(), TSSetMaxSteps() 2899 @*/ 2900 PetscErrorCode TSGetMaxTime(TS ts,PetscReal *maxtime) 2901 { 2902 PetscFunctionBegin; 2903 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2904 PetscValidRealPointer(maxtime,2); 2905 *maxtime = ts->max_time; 2906 PetscFunctionReturn(0); 2907 } 2908 2909 /*@ 2910 TSSetInitialTimeStep - Deprecated, use TSSetTime() and TSSetTimeStep(). 2911 2912 Level: deprecated 2913 2914 @*/ 2915 PetscErrorCode TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step) 2916 { 2917 PetscErrorCode ierr; 2918 PetscFunctionBegin; 2919 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2920 ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr); 2921 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 2922 PetscFunctionReturn(0); 2923 } 2924 2925 /*@ 2926 TSGetDuration - Deprecated, use TSGetMaxSteps() and TSGetMaxTime(). 2927 2928 Level: deprecated 2929 2930 @*/ 2931 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 2932 { 2933 PetscFunctionBegin; 2934 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2935 if (maxsteps) { 2936 PetscValidIntPointer(maxsteps,2); 2937 *maxsteps = ts->max_steps; 2938 } 2939 if (maxtime) { 2940 PetscValidScalarPointer(maxtime,3); 2941 *maxtime = ts->max_time; 2942 } 2943 PetscFunctionReturn(0); 2944 } 2945 2946 /*@ 2947 TSSetDuration - Deprecated, use TSSetMaxSteps() and TSSetMaxTime(). 2948 2949 Level: deprecated 2950 2951 @*/ 2952 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 2953 { 2954 PetscFunctionBegin; 2955 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2956 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 2957 PetscValidLogicalCollectiveReal(ts,maxtime,2); 2958 if (maxsteps >= 0) ts->max_steps = maxsteps; 2959 if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime; 2960 PetscFunctionReturn(0); 2961 } 2962 2963 /*@ 2964 TSGetTimeStepNumber - Deprecated, use TSGetStepNumber(). 2965 2966 Level: deprecated 2967 2968 @*/ 2969 PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt *steps) { return TSGetStepNumber(ts,steps); } 2970 2971 /*@ 2972 TSGetTotalSteps - Deprecated, use TSGetStepNumber(). 2973 2974 Level: deprecated 2975 2976 @*/ 2977 PetscErrorCode TSGetTotalSteps(TS ts,PetscInt *steps) { return TSGetStepNumber(ts,steps); } 2978 2979 /*@ 2980 TSSetSolution - Sets the initial solution vector 2981 for use by the TS routines. 2982 2983 Logically Collective on TS and Vec 2984 2985 Input Parameters: 2986 + ts - the TS context obtained from TSCreate() 2987 - u - the solution vector 2988 2989 Level: beginner 2990 2991 .keywords: TS, timestep, set, solution, initial values 2992 2993 .seealso: TSSetSolutionFunction(), TSGetSolution(), TSCreate() 2994 @*/ 2995 PetscErrorCode TSSetSolution(TS ts,Vec u) 2996 { 2997 PetscErrorCode ierr; 2998 DM dm; 2999 3000 PetscFunctionBegin; 3001 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3002 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 3003 ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr); 3004 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 3005 ts->vec_sol = u; 3006 3007 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 3008 ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr); 3009 PetscFunctionReturn(0); 3010 } 3011 3012 /*@C 3013 TSSetPreStep - Sets the general-purpose function 3014 called once at the beginning of each time step. 3015 3016 Logically Collective on TS 3017 3018 Input Parameters: 3019 + ts - The TS context obtained from TSCreate() 3020 - func - The function 3021 3022 Calling sequence of func: 3023 . func (TS ts); 3024 3025 Level: intermediate 3026 3027 .keywords: TS, timestep 3028 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep(), TSRestartStep() 3029 @*/ 3030 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 3031 { 3032 PetscFunctionBegin; 3033 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3034 ts->prestep = func; 3035 PetscFunctionReturn(0); 3036 } 3037 3038 /*@ 3039 TSPreStep - Runs the user-defined pre-step function. 3040 3041 Collective on TS 3042 3043 Input Parameters: 3044 . ts - The TS context obtained from TSCreate() 3045 3046 Notes: 3047 TSPreStep() is typically used within time stepping implementations, 3048 so most users would not generally call this routine themselves. 3049 3050 Level: developer 3051 3052 .keywords: TS, timestep 3053 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep() 3054 @*/ 3055 PetscErrorCode TSPreStep(TS ts) 3056 { 3057 PetscErrorCode ierr; 3058 3059 PetscFunctionBegin; 3060 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3061 if (ts->prestep) { 3062 Vec U; 3063 PetscObjectState sprev,spost; 3064 3065 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3066 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3067 PetscStackCallStandard((*ts->prestep),(ts)); 3068 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3069 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3070 } 3071 PetscFunctionReturn(0); 3072 } 3073 3074 /*@C 3075 TSSetPreStage - Sets the general-purpose function 3076 called once at the beginning of each stage. 3077 3078 Logically Collective on TS 3079 3080 Input Parameters: 3081 + ts - The TS context obtained from TSCreate() 3082 - func - The function 3083 3084 Calling sequence of func: 3085 . PetscErrorCode func(TS ts, PetscReal stagetime); 3086 3087 Level: intermediate 3088 3089 Note: 3090 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3091 The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being 3092 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3093 3094 .keywords: TS, timestep 3095 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3096 @*/ 3097 PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal)) 3098 { 3099 PetscFunctionBegin; 3100 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3101 ts->prestage = func; 3102 PetscFunctionReturn(0); 3103 } 3104 3105 /*@C 3106 TSSetPostStage - Sets the general-purpose function 3107 called once at the end of each stage. 3108 3109 Logically Collective on TS 3110 3111 Input Parameters: 3112 + ts - The TS context obtained from TSCreate() 3113 - func - The function 3114 3115 Calling sequence of func: 3116 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y); 3117 3118 Level: intermediate 3119 3120 Note: 3121 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3122 The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being 3123 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3124 3125 .keywords: TS, timestep 3126 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3127 @*/ 3128 PetscErrorCode TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*)) 3129 { 3130 PetscFunctionBegin; 3131 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3132 ts->poststage = func; 3133 PetscFunctionReturn(0); 3134 } 3135 3136 /*@C 3137 TSSetPostEvaluate - Sets the general-purpose function 3138 called once at the end of each step evaluation. 3139 3140 Logically Collective on TS 3141 3142 Input Parameters: 3143 + ts - The TS context obtained from TSCreate() 3144 - func - The function 3145 3146 Calling sequence of func: 3147 . PetscErrorCode func(TS ts); 3148 3149 Level: intermediate 3150 3151 Note: 3152 Semantically, TSSetPostEvaluate() differs from TSSetPostStep() since the function it sets is called before event-handling 3153 thus guaranteeing the same solution (computed by the time-stepper) will be passed to it. On the other hand, TSPostStep() 3154 may be passed a different solution, possibly changed by the event handler. TSPostEvaluate() is called after the next step 3155 solution is evaluated allowing to modify it, if need be. The solution can be obtained with TSGetSolution(), the time step 3156 with TSGetTimeStep(), and the time at the start of the step is available via TSGetTime() 3157 3158 .keywords: TS, timestep 3159 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3160 @*/ 3161 PetscErrorCode TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS)) 3162 { 3163 PetscFunctionBegin; 3164 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3165 ts->postevaluate = func; 3166 PetscFunctionReturn(0); 3167 } 3168 3169 /*@ 3170 TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage() 3171 3172 Collective on TS 3173 3174 Input Parameters: 3175 . ts - The TS context obtained from TSCreate() 3176 stagetime - The absolute time of the current stage 3177 3178 Notes: 3179 TSPreStage() is typically used within time stepping implementations, 3180 most users would not generally call this routine themselves. 3181 3182 Level: developer 3183 3184 .keywords: TS, timestep 3185 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3186 @*/ 3187 PetscErrorCode TSPreStage(TS ts, PetscReal stagetime) 3188 { 3189 PetscErrorCode ierr; 3190 3191 PetscFunctionBegin; 3192 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3193 if (ts->prestage) { 3194 PetscStackCallStandard((*ts->prestage),(ts,stagetime)); 3195 } 3196 PetscFunctionReturn(0); 3197 } 3198 3199 /*@ 3200 TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage() 3201 3202 Collective on TS 3203 3204 Input Parameters: 3205 . ts - The TS context obtained from TSCreate() 3206 stagetime - The absolute time of the current stage 3207 stageindex - Stage number 3208 Y - Array of vectors (of size = total number 3209 of stages) with the stage solutions 3210 3211 Notes: 3212 TSPostStage() is typically used within time stepping implementations, 3213 most users would not generally call this routine themselves. 3214 3215 Level: developer 3216 3217 .keywords: TS, timestep 3218 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3219 @*/ 3220 PetscErrorCode TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y) 3221 { 3222 PetscErrorCode ierr; 3223 3224 PetscFunctionBegin; 3225 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3226 if (ts->poststage) { 3227 PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y)); 3228 } 3229 PetscFunctionReturn(0); 3230 } 3231 3232 /*@ 3233 TSPostEvaluate - Runs the user-defined post-evaluate function set using TSSetPostEvaluate() 3234 3235 Collective on TS 3236 3237 Input Parameters: 3238 . ts - The TS context obtained from TSCreate() 3239 3240 Notes: 3241 TSPostEvaluate() is typically used within time stepping implementations, 3242 most users would not generally call this routine themselves. 3243 3244 Level: developer 3245 3246 .keywords: TS, timestep 3247 .seealso: TSSetPostEvaluate(), TSSetPreStep(), TSPreStep(), TSPostStep() 3248 @*/ 3249 PetscErrorCode TSPostEvaluate(TS ts) 3250 { 3251 PetscErrorCode ierr; 3252 3253 PetscFunctionBegin; 3254 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3255 if (ts->postevaluate) { 3256 Vec U; 3257 PetscObjectState sprev,spost; 3258 3259 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3260 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3261 PetscStackCallStandard((*ts->postevaluate),(ts)); 3262 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3263 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3264 } 3265 PetscFunctionReturn(0); 3266 } 3267 3268 /*@C 3269 TSSetPostStep - Sets the general-purpose function 3270 called once at the end of each time step. 3271 3272 Logically Collective on TS 3273 3274 Input Parameters: 3275 + ts - The TS context obtained from TSCreate() 3276 - func - The function 3277 3278 Calling sequence of func: 3279 $ func (TS ts); 3280 3281 Notes: 3282 The function set by TSSetPostStep() is called after each successful step. The solution vector X 3283 obtained by TSGetSolution() may be different than that computed at the step end if the event handler 3284 locates an event and TSPostEvent() modifies it. Use TSSetPostEvaluate() if an unmodified solution is needed instead. 3285 3286 Level: intermediate 3287 3288 .keywords: TS, timestep 3289 .seealso: TSSetPreStep(), TSSetPreStage(), TSSetPostEvaluate(), TSGetTimeStep(), TSGetStepNumber(), TSGetTime(), TSRestartStep() 3290 @*/ 3291 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 3292 { 3293 PetscFunctionBegin; 3294 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3295 ts->poststep = func; 3296 PetscFunctionReturn(0); 3297 } 3298 3299 /*@ 3300 TSPostStep - Runs the user-defined post-step function. 3301 3302 Collective on TS 3303 3304 Input Parameters: 3305 . ts - The TS context obtained from TSCreate() 3306 3307 Notes: 3308 TSPostStep() is typically used within time stepping implementations, 3309 so most users would not generally call this routine themselves. 3310 3311 Level: developer 3312 3313 .keywords: TS, timestep 3314 @*/ 3315 PetscErrorCode TSPostStep(TS ts) 3316 { 3317 PetscErrorCode ierr; 3318 3319 PetscFunctionBegin; 3320 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3321 if (ts->poststep) { 3322 Vec U; 3323 PetscObjectState sprev,spost; 3324 3325 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3326 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3327 PetscStackCallStandard((*ts->poststep),(ts)); 3328 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3329 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3330 } 3331 PetscFunctionReturn(0); 3332 } 3333 3334 /* ------------ Routines to set performance monitoring options ----------- */ 3335 3336 /*@C 3337 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 3338 timestep to display the iteration's progress. 3339 3340 Logically Collective on TS 3341 3342 Input Parameters: 3343 + ts - the TS context obtained from TSCreate() 3344 . monitor - monitoring routine 3345 . mctx - [optional] user-defined context for private data for the 3346 monitor routine (use NULL if no context is desired) 3347 - monitordestroy - [optional] routine that frees monitor context 3348 (may be NULL) 3349 3350 Calling sequence of monitor: 3351 $ PetscErrorCode monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx) 3352 3353 + ts - the TS context 3354 . 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) 3355 . time - current time 3356 . u - current iterate 3357 - mctx - [optional] monitoring context 3358 3359 Notes: 3360 This routine adds an additional monitor to the list of monitors that 3361 already has been loaded. 3362 3363 Fortran Notes: 3364 Only a single monitor function can be set for each TS object 3365 3366 Level: intermediate 3367 3368 .keywords: TS, timestep, set, monitor 3369 3370 .seealso: TSMonitorDefault(), TSMonitorCancel() 3371 @*/ 3372 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 3373 { 3374 PetscErrorCode ierr; 3375 PetscInt i; 3376 PetscBool identical; 3377 3378 PetscFunctionBegin; 3379 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3380 for (i=0; i<ts->numbermonitors;i++) { 3381 ierr = PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical);CHKERRQ(ierr); 3382 if (identical) PetscFunctionReturn(0); 3383 } 3384 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3385 ts->monitor[ts->numbermonitors] = monitor; 3386 ts->monitordestroy[ts->numbermonitors] = mdestroy; 3387 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 3388 PetscFunctionReturn(0); 3389 } 3390 3391 /*@C 3392 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 3393 3394 Logically Collective on TS 3395 3396 Input Parameters: 3397 . ts - the TS context obtained from TSCreate() 3398 3399 Notes: 3400 There is no way to remove a single, specific monitor. 3401 3402 Level: intermediate 3403 3404 .keywords: TS, timestep, set, monitor 3405 3406 .seealso: TSMonitorDefault(), TSMonitorSet() 3407 @*/ 3408 PetscErrorCode TSMonitorCancel(TS ts) 3409 { 3410 PetscErrorCode ierr; 3411 PetscInt i; 3412 3413 PetscFunctionBegin; 3414 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3415 for (i=0; i<ts->numbermonitors; i++) { 3416 if (ts->monitordestroy[i]) { 3417 ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 3418 } 3419 } 3420 ts->numbermonitors = 0; 3421 PetscFunctionReturn(0); 3422 } 3423 3424 /*@C 3425 TSMonitorDefault - The Default monitor, prints the timestep and time for each step 3426 3427 Level: intermediate 3428 3429 .keywords: TS, set, monitor 3430 3431 .seealso: TSMonitorSet() 3432 @*/ 3433 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf) 3434 { 3435 PetscErrorCode ierr; 3436 PetscViewer viewer = vf->viewer; 3437 PetscBool iascii,ibinary; 3438 3439 PetscFunctionBegin; 3440 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 3441 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 3442 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 3443 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 3444 if (iascii) { 3445 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3446 if (step == -1){ /* this indicates it is an interpolated solution */ 3447 ierr = PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps);CHKERRQ(ierr); 3448 } else { 3449 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr); 3450 } 3451 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3452 } else if (ibinary) { 3453 PetscMPIInt rank; 3454 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 3455 if (!rank) { 3456 PetscBool skipHeader; 3457 PetscInt classid = REAL_FILE_CLASSID; 3458 3459 ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr); 3460 if (!skipHeader) { 3461 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 3462 } 3463 ierr = PetscRealView(1,&ptime,viewer);CHKERRQ(ierr); 3464 } else { 3465 ierr = PetscRealView(0,&ptime,viewer);CHKERRQ(ierr); 3466 } 3467 } 3468 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 3469 PetscFunctionReturn(0); 3470 } 3471 3472 /*@ 3473 TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval 3474 3475 Collective on TS 3476 3477 Input Argument: 3478 + ts - time stepping context 3479 - t - time to interpolate to 3480 3481 Output Argument: 3482 . U - state at given time 3483 3484 Level: intermediate 3485 3486 Developer Notes: 3487 TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints. 3488 3489 .keywords: TS, set 3490 3491 .seealso: TSSetExactFinalTime(), TSSolve() 3492 @*/ 3493 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U) 3494 { 3495 PetscErrorCode ierr; 3496 3497 PetscFunctionBegin; 3498 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3499 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3500 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); 3501 if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name); 3502 ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr); 3503 PetscFunctionReturn(0); 3504 } 3505 3506 /*@ 3507 TSStep - Steps one time step 3508 3509 Collective on TS 3510 3511 Input Parameter: 3512 . ts - the TS context obtained from TSCreate() 3513 3514 Level: developer 3515 3516 Notes: 3517 The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine. 3518 3519 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 3520 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 3521 3522 This may over-step the final time provided in TSSetMaxTime() depending on the time-step used. TSSolve() interpolates to exactly the 3523 time provided in TSSetMaxTime(). One can use TSInterpolate() to determine an interpolated solution within the final timestep. 3524 3525 .keywords: TS, timestep, solve 3526 3527 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate() 3528 @*/ 3529 PetscErrorCode TSStep(TS ts) 3530 { 3531 PetscErrorCode ierr; 3532 static PetscBool cite = PETSC_FALSE; 3533 PetscReal ptime; 3534 3535 PetscFunctionBegin; 3536 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3537 ierr = PetscCitationsRegister("@techreport{tspaper,\n" 3538 " title = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n" 3539 " author = {Shrirang Abhyankar and Jed Brown and Emil Constantinescu and Debojyoti Ghosh and Barry F. Smith},\n" 3540 " type = {Preprint},\n" 3541 " number = {ANL/MCS-P5061-0114},\n" 3542 " institution = {Argonne National Laboratory},\n" 3543 " year = {2014}\n}\n",&cite);CHKERRQ(ierr); 3544 3545 ierr = TSSetUp(ts);CHKERRQ(ierr); 3546 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 3547 3548 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>"); 3549 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()"); 3550 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"); 3551 3552 if (!ts->steps) ts->ptime_prev = ts->ptime; 3553 ptime = ts->ptime; ts->ptime_prev_rollback = ts->ptime_prev; 3554 ts->reason = TS_CONVERGED_ITERATING; 3555 if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3556 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3557 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 3558 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3559 ts->ptime_prev = ptime; 3560 ts->steps++; 3561 ts->steprollback = PETSC_FALSE; 3562 ts->steprestart = PETSC_FALSE; 3563 3564 if (ts->reason < 0) { 3565 if (ts->errorifstepfailed) { 3566 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]); 3567 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 3568 } 3569 } else if (!ts->reason) { 3570 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3571 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3572 } 3573 PetscFunctionReturn(0); 3574 } 3575 3576 /*@ 3577 TSEvaluateWLTE - Evaluate the weighted local truncation error norm 3578 at the end of a time step with a given order of accuracy. 3579 3580 Collective on TS 3581 3582 Input Arguments: 3583 + ts - time stepping context 3584 . wnormtype - norm type, either NORM_2 or NORM_INFINITY 3585 - order - optional, desired order for the error evaluation or PETSC_DECIDE 3586 3587 Output Arguments: 3588 + order - optional, the actual order of the error evaluation 3589 - wlte - the weighted local truncation error norm 3590 3591 Level: advanced 3592 3593 Notes: 3594 If the timestepper cannot evaluate the error in a particular step 3595 (eg. in the first step or restart steps after event handling), 3596 this routine returns wlte=-1.0 . 3597 3598 .seealso: TSStep(), TSAdapt, TSErrorWeightedNorm() 3599 @*/ 3600 PetscErrorCode TSEvaluateWLTE(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte) 3601 { 3602 PetscErrorCode ierr; 3603 3604 PetscFunctionBegin; 3605 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3606 PetscValidType(ts,1); 3607 PetscValidLogicalCollectiveEnum(ts,wnormtype,4); 3608 if (order) PetscValidIntPointer(order,3); 3609 if (order) PetscValidLogicalCollectiveInt(ts,*order,3); 3610 PetscValidRealPointer(wlte,4); 3611 if (wnormtype != NORM_2 && wnormtype != NORM_INFINITY) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 3612 if (!ts->ops->evaluatewlte) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateWLTE not implemented for type '%s'",((PetscObject)ts)->type_name); 3613 ierr = (*ts->ops->evaluatewlte)(ts,wnormtype,order,wlte);CHKERRQ(ierr); 3614 PetscFunctionReturn(0); 3615 } 3616 3617 /*@ 3618 TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy. 3619 3620 Collective on TS 3621 3622 Input Arguments: 3623 + ts - time stepping context 3624 . order - desired order of accuracy 3625 - done - whether the step was evaluated at this order (pass NULL to generate an error if not available) 3626 3627 Output Arguments: 3628 . U - state at the end of the current step 3629 3630 Level: advanced 3631 3632 Notes: 3633 This function cannot be called until all stages have been evaluated. 3634 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. 3635 3636 .seealso: TSStep(), TSAdapt 3637 @*/ 3638 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done) 3639 { 3640 PetscErrorCode ierr; 3641 3642 PetscFunctionBegin; 3643 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3644 PetscValidType(ts,1); 3645 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3646 if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3647 ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr); 3648 PetscFunctionReturn(0); 3649 } 3650 3651 /*@ 3652 TSSolve - Steps the requested number of timesteps. 3653 3654 Collective on TS 3655 3656 Input Parameter: 3657 + ts - the TS context obtained from TSCreate() 3658 - u - the solution vector (can be null if TSSetSolution() was used and TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP) was not used, 3659 otherwise must contain the initial conditions and will contain the solution at the final requested time 3660 3661 Level: beginner 3662 3663 Notes: 3664 The final time returned by this function may be different from the time of the internally 3665 held state accessible by TSGetSolution() and TSGetTime() because the method may have 3666 stepped over the final time. 3667 3668 .keywords: TS, timestep, solve 3669 3670 .seealso: TSCreate(), TSSetSolution(), TSStep(), TSGetTime(), TSGetSolveTime() 3671 @*/ 3672 PetscErrorCode TSSolve(TS ts,Vec u) 3673 { 3674 Vec solution; 3675 PetscErrorCode ierr; 3676 3677 PetscFunctionBegin; 3678 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3679 if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2); 3680 3681 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 */ 3682 if (!ts->vec_sol || u == ts->vec_sol) { 3683 ierr = VecDuplicate(u,&solution);CHKERRQ(ierr); 3684 ierr = TSSetSolution(ts,solution);CHKERRQ(ierr); 3685 ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */ 3686 } 3687 ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr); 3688 if (ts->forward_solve) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Sensitivity analysis does not support the mode TS_EXACTFINALTIME_INTERPOLATE"); 3689 } else if (u) { 3690 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 3691 } 3692 ierr = TSSetUp(ts);CHKERRQ(ierr); 3693 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 3694 3695 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>"); 3696 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()"); 3697 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"); 3698 3699 if (ts->forward_solve) { 3700 ierr = TSForwardSetUp(ts);CHKERRQ(ierr); 3701 } 3702 3703 /* reset number of steps only when the step is not restarted. ARKIMEX 3704 restarts the step after an event. Resetting these counters in such case causes 3705 TSTrajectory to incorrectly save the output files 3706 */ 3707 /* reset time step and iteration counters */ 3708 if (!ts->steps) { 3709 ts->ksp_its = 0; 3710 ts->snes_its = 0; 3711 ts->num_snes_failures = 0; 3712 ts->reject = 0; 3713 ts->steprestart = PETSC_TRUE; 3714 ts->steprollback = PETSC_FALSE; 3715 } 3716 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP && ts->ptime + ts->time_step > ts->max_time) ts->time_step = ts->max_time - ts->ptime; 3717 ts->reason = TS_CONVERGED_ITERATING; 3718 3719 ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr); 3720 3721 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 3722 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 3723 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 3724 ts->solvetime = ts->ptime; 3725 solution = ts->vec_sol; 3726 } else { /* Step the requested number of timesteps. */ 3727 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3728 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3729 3730 if (!ts->steps) { 3731 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3732 ierr = TSEventInitialize(ts->event,ts,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3733 } 3734 3735 while (!ts->reason) { 3736 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3737 if (!ts->steprollback) { 3738 ierr = TSPreStep(ts);CHKERRQ(ierr); 3739 } 3740 ierr = TSStep(ts);CHKERRQ(ierr); 3741 if (ts->testjacobian) { 3742 ierr = TSRHSJacobianTest(ts,NULL);CHKERRQ(ierr); 3743 } 3744 if (ts->testjacobiantranspose) { 3745 ierr = TSRHSJacobianTestTranspose(ts,NULL);CHKERRQ(ierr); 3746 } 3747 if (ts->vec_costintegral && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */ 3748 ierr = TSForwardCostIntegral(ts);CHKERRQ(ierr); 3749 } 3750 if (ts->forward_solve) { /* compute forward sensitivities before event handling because postevent() may change RHS and jump conditions may have to be applied */ 3751 ierr = TSForwardStep(ts);CHKERRQ(ierr); 3752 } 3753 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 3754 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. */ 3755 if (ts->steprollback) { 3756 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 3757 } 3758 if (!ts->steprollback) { 3759 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3760 ierr = TSPostStep(ts);CHKERRQ(ierr); 3761 } 3762 } 3763 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3764 3765 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) { 3766 ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr); 3767 ts->solvetime = ts->max_time; 3768 solution = u; 3769 ierr = TSMonitor(ts,-1,ts->solvetime,solution);CHKERRQ(ierr); 3770 } else { 3771 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 3772 ts->solvetime = ts->ptime; 3773 solution = ts->vec_sol; 3774 } 3775 } 3776 3777 ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr); 3778 ierr = VecViewFromOptions(solution,NULL,"-ts_view_solution");CHKERRQ(ierr); 3779 ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr); 3780 if (ts->adjoint_solve) { 3781 ierr = TSAdjointSolve(ts);CHKERRQ(ierr); 3782 } 3783 PetscFunctionReturn(0); 3784 } 3785 3786 /*@C 3787 TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet() 3788 3789 Collective on TS 3790 3791 Input Parameters: 3792 + ts - time stepping context obtained from TSCreate() 3793 . step - step number that has just completed 3794 . ptime - model time of the state 3795 - u - state at the current model time 3796 3797 Notes: 3798 TSMonitor() is typically used automatically within the time stepping implementations. 3799 Users would almost never call this routine directly. 3800 3801 A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions 3802 3803 Level: developer 3804 3805 .keywords: TS, timestep 3806 @*/ 3807 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u) 3808 { 3809 DM dm; 3810 PetscInt i,n = ts->numbermonitors; 3811 PetscErrorCode ierr; 3812 3813 PetscFunctionBegin; 3814 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3815 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 3816 3817 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 3818 ierr = DMSetOutputSequenceNumber(dm,step,ptime);CHKERRQ(ierr); 3819 3820 ierr = VecLockPush(u);CHKERRQ(ierr); 3821 for (i=0; i<n; i++) { 3822 ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr); 3823 } 3824 ierr = VecLockPop(u);CHKERRQ(ierr); 3825 PetscFunctionReturn(0); 3826 } 3827 3828 /* ------------------------------------------------------------------------*/ 3829 /*@C 3830 TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with 3831 TS to monitor the solution process graphically in various ways 3832 3833 Collective on TS 3834 3835 Input Parameters: 3836 + host - the X display to open, or null for the local machine 3837 . label - the title to put in the title bar 3838 . x, y - the screen coordinates of the upper left coordinate of the window 3839 . m, n - the screen width and height in pixels 3840 - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 3841 3842 Output Parameter: 3843 . ctx - the context 3844 3845 Options Database Key: 3846 + -ts_monitor_lg_timestep - automatically sets line graph monitor 3847 + -ts_monitor_lg_timestep_log - automatically sets line graph monitor 3848 . -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables()) 3849 . -ts_monitor_lg_error - monitor the error 3850 . -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep 3851 . -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep 3852 - -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true 3853 3854 Notes: 3855 Use TSMonitorLGCtxDestroy() to destroy. 3856 3857 One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform() 3858 3859 Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the 3860 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 3861 as the first argument. 3862 3863 One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames() 3864 3865 Level: intermediate 3866 3867 .keywords: TS, monitor, line graph, residual 3868 3869 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(), 3870 TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 3871 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 3872 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 3873 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 3874 3875 @*/ 3876 PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx) 3877 { 3878 PetscDraw draw; 3879 PetscErrorCode ierr; 3880 3881 PetscFunctionBegin; 3882 ierr = PetscNew(ctx);CHKERRQ(ierr); 3883 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr); 3884 ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); 3885 ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr); 3886 ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr); 3887 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 3888 (*ctx)->howoften = howoften; 3889 PetscFunctionReturn(0); 3890 } 3891 3892 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx) 3893 { 3894 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 3895 PetscReal x = ptime,y; 3896 PetscErrorCode ierr; 3897 3898 PetscFunctionBegin; 3899 if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */ 3900 if (!step) { 3901 PetscDrawAxis axis; 3902 const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step"; 3903 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 3904 ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel);CHKERRQ(ierr); 3905 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 3906 } 3907 ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr); 3908 if (ctx->semilogy) y = PetscLog10Real(y); 3909 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 3910 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 3911 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 3912 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 3913 } 3914 PetscFunctionReturn(0); 3915 } 3916 3917 /*@C 3918 TSMonitorLGCtxDestroy - Destroys a line graph context that was created 3919 with TSMonitorLGCtxCreate(). 3920 3921 Collective on TSMonitorLGCtx 3922 3923 Input Parameter: 3924 . ctx - the monitor context 3925 3926 Level: intermediate 3927 3928 .keywords: TS, monitor, line graph, destroy 3929 3930 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 3931 @*/ 3932 PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 3933 { 3934 PetscErrorCode ierr; 3935 3936 PetscFunctionBegin; 3937 if ((*ctx)->transformdestroy) { 3938 ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr); 3939 } 3940 ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr); 3941 ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr); 3942 ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr); 3943 ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr); 3944 ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr); 3945 ierr = PetscFree(*ctx);CHKERRQ(ierr); 3946 PetscFunctionReturn(0); 3947 } 3948 3949 /*@ 3950 TSGetTime - Gets the time of the most recently completed step. 3951 3952 Not Collective 3953 3954 Input Parameter: 3955 . ts - the TS context obtained from TSCreate() 3956 3957 Output Parameter: 3958 . t - the current time. This time may not corresponds to the final time set with TSSetMaxTime(), use TSGetSolveTime(). 3959 3960 Level: beginner 3961 3962 Note: 3963 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 3964 TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 3965 3966 .seealso: TSGetSolveTime(), TSSetTime(), TSGetTimeStep() 3967 3968 .keywords: TS, get, time 3969 @*/ 3970 PetscErrorCode TSGetTime(TS ts,PetscReal *t) 3971 { 3972 PetscFunctionBegin; 3973 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3974 PetscValidRealPointer(t,2); 3975 *t = ts->ptime; 3976 PetscFunctionReturn(0); 3977 } 3978 3979 /*@ 3980 TSGetPrevTime - Gets the starting time of the previously completed step. 3981 3982 Not Collective 3983 3984 Input Parameter: 3985 . ts - the TS context obtained from TSCreate() 3986 3987 Output Parameter: 3988 . t - the previous time 3989 3990 Level: beginner 3991 3992 .seealso: TSGetTime(), TSGetSolveTime(), TSGetTimeStep() 3993 3994 .keywords: TS, get, time 3995 @*/ 3996 PetscErrorCode TSGetPrevTime(TS ts,PetscReal *t) 3997 { 3998 PetscFunctionBegin; 3999 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4000 PetscValidRealPointer(t,2); 4001 *t = ts->ptime_prev; 4002 PetscFunctionReturn(0); 4003 } 4004 4005 /*@ 4006 TSSetTime - Allows one to reset the time. 4007 4008 Logically Collective on TS 4009 4010 Input Parameters: 4011 + ts - the TS context obtained from TSCreate() 4012 - time - the time 4013 4014 Level: intermediate 4015 4016 .seealso: TSGetTime(), TSSetMaxSteps() 4017 4018 .keywords: TS, set, time 4019 @*/ 4020 PetscErrorCode TSSetTime(TS ts, PetscReal t) 4021 { 4022 PetscFunctionBegin; 4023 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4024 PetscValidLogicalCollectiveReal(ts,t,2); 4025 ts->ptime = t; 4026 PetscFunctionReturn(0); 4027 } 4028 4029 /*@C 4030 TSSetOptionsPrefix - Sets the prefix used for searching for all 4031 TS options in the database. 4032 4033 Logically Collective on TS 4034 4035 Input Parameter: 4036 + ts - The TS context 4037 - prefix - The prefix to prepend to all option names 4038 4039 Notes: 4040 A hyphen (-) must NOT be given at the beginning of the prefix name. 4041 The first character of all runtime options is AUTOMATICALLY the 4042 hyphen. 4043 4044 Level: advanced 4045 4046 .keywords: TS, set, options, prefix, database 4047 4048 .seealso: TSSetFromOptions() 4049 4050 @*/ 4051 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 4052 { 4053 PetscErrorCode ierr; 4054 SNES snes; 4055 4056 PetscFunctionBegin; 4057 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4058 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4059 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4060 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4061 PetscFunctionReturn(0); 4062 } 4063 4064 /*@C 4065 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 4066 TS options in the database. 4067 4068 Logically Collective on TS 4069 4070 Input Parameter: 4071 + ts - The TS context 4072 - prefix - The prefix to prepend to all option names 4073 4074 Notes: 4075 A hyphen (-) must NOT be given at the beginning of the prefix name. 4076 The first character of all runtime options is AUTOMATICALLY the 4077 hyphen. 4078 4079 Level: advanced 4080 4081 .keywords: TS, append, options, prefix, database 4082 4083 .seealso: TSGetOptionsPrefix() 4084 4085 @*/ 4086 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 4087 { 4088 PetscErrorCode ierr; 4089 SNES snes; 4090 4091 PetscFunctionBegin; 4092 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4093 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4094 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4095 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4096 PetscFunctionReturn(0); 4097 } 4098 4099 /*@C 4100 TSGetOptionsPrefix - Sets the prefix used for searching for all 4101 TS options in the database. 4102 4103 Not Collective 4104 4105 Input Parameter: 4106 . ts - The TS context 4107 4108 Output Parameter: 4109 . prefix - A pointer to the prefix string used 4110 4111 Notes: 4112 On the fortran side, the user should pass in a string 'prifix' of 4113 sufficient length to hold the prefix. 4114 4115 Level: intermediate 4116 4117 .keywords: TS, get, options, prefix, database 4118 4119 .seealso: TSAppendOptionsPrefix() 4120 @*/ 4121 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 4122 { 4123 PetscErrorCode ierr; 4124 4125 PetscFunctionBegin; 4126 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4127 PetscValidPointer(prefix,2); 4128 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4129 PetscFunctionReturn(0); 4130 } 4131 4132 /*@C 4133 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 4134 4135 Not Collective, but parallel objects are returned if TS is parallel 4136 4137 Input Parameter: 4138 . ts - The TS context obtained from TSCreate() 4139 4140 Output Parameters: 4141 + Amat - The (approximate) Jacobian J of G, where U_t = G(U,t) (or NULL) 4142 . Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat (or NULL) 4143 . func - Function to compute the Jacobian of the RHS (or NULL) 4144 - ctx - User-defined context for Jacobian evaluation routine (or NULL) 4145 4146 Notes: 4147 You can pass in NULL for any return argument you do not need. 4148 4149 Level: intermediate 4150 4151 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4152 4153 .keywords: TS, timestep, get, matrix, Jacobian 4154 @*/ 4155 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx) 4156 { 4157 PetscErrorCode ierr; 4158 DM dm; 4159 4160 PetscFunctionBegin; 4161 if (Amat || Pmat) { 4162 SNES snes; 4163 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4164 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4165 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4166 } 4167 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4168 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 4169 PetscFunctionReturn(0); 4170 } 4171 4172 /*@C 4173 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 4174 4175 Not Collective, but parallel objects are returned if TS is parallel 4176 4177 Input Parameter: 4178 . ts - The TS context obtained from TSCreate() 4179 4180 Output Parameters: 4181 + Amat - The (approximate) Jacobian of F(t,U,U_t) 4182 . Pmat - The matrix from which the preconditioner is constructed, often the same as Amat 4183 . f - The function to compute the matrices 4184 - ctx - User-defined context for Jacobian evaluation routine 4185 4186 Notes: 4187 You can pass in NULL for any return argument you do not need. 4188 4189 Level: advanced 4190 4191 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4192 4193 .keywords: TS, timestep, get, matrix, Jacobian 4194 @*/ 4195 PetscErrorCode TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx) 4196 { 4197 PetscErrorCode ierr; 4198 DM dm; 4199 4200 PetscFunctionBegin; 4201 if (Amat || Pmat) { 4202 SNES snes; 4203 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4204 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4205 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4206 } 4207 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4208 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 4209 PetscFunctionReturn(0); 4210 } 4211 4212 /*@C 4213 TSMonitorDrawSolution - Monitors progress of the TS solvers by calling 4214 VecView() for the solution at each timestep 4215 4216 Collective on TS 4217 4218 Input Parameters: 4219 + ts - the TS context 4220 . step - current time-step 4221 . ptime - current time 4222 - dummy - either a viewer or NULL 4223 4224 Options Database: 4225 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4226 4227 Notes: 4228 the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial 4229 will look bad 4230 4231 Level: intermediate 4232 4233 .keywords: TS, vector, monitor, view 4234 4235 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4236 @*/ 4237 PetscErrorCode TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4238 { 4239 PetscErrorCode ierr; 4240 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4241 PetscDraw draw; 4242 4243 PetscFunctionBegin; 4244 if (!step && ictx->showinitial) { 4245 if (!ictx->initialsolution) { 4246 ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr); 4247 } 4248 ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr); 4249 } 4250 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4251 4252 if (ictx->showinitial) { 4253 PetscReal pause; 4254 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 4255 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 4256 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 4257 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 4258 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 4259 } 4260 ierr = VecView(u,ictx->viewer);CHKERRQ(ierr); 4261 if (ictx->showtimestepandtime) { 4262 PetscReal xl,yl,xr,yr,h; 4263 char time[32]; 4264 4265 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4266 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4267 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4268 h = yl + .95*(yr - yl); 4269 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4270 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4271 } 4272 4273 if (ictx->showinitial) { 4274 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 4275 } 4276 PetscFunctionReturn(0); 4277 } 4278 4279 /*@C 4280 TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram 4281 4282 Collective on TS 4283 4284 Input Parameters: 4285 + ts - the TS context 4286 . step - current time-step 4287 . ptime - current time 4288 - dummy - either a viewer or NULL 4289 4290 Level: intermediate 4291 4292 .keywords: TS, vector, monitor, view 4293 4294 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4295 @*/ 4296 PetscErrorCode TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4297 { 4298 PetscErrorCode ierr; 4299 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4300 PetscDraw draw; 4301 PetscDrawAxis axis; 4302 PetscInt n; 4303 PetscMPIInt size; 4304 PetscReal U0,U1,xl,yl,xr,yr,h; 4305 char time[32]; 4306 const PetscScalar *U; 4307 4308 PetscFunctionBegin; 4309 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRQ(ierr); 4310 if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs"); 4311 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 4312 if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns"); 4313 4314 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4315 ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr); 4316 ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr); 4317 if (!step) { 4318 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 4319 ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr); 4320 } 4321 4322 ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr); 4323 U0 = PetscRealPart(U[0]); 4324 U1 = PetscRealPart(U[1]); 4325 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 4326 if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0); 4327 4328 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 4329 ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr); 4330 if (ictx->showtimestepandtime) { 4331 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4332 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4333 h = yl + .95*(yr - yl); 4334 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4335 } 4336 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 4337 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4338 ierr = PetscDrawPause(draw);CHKERRQ(ierr); 4339 ierr = PetscDrawSave(draw);CHKERRQ(ierr); 4340 PetscFunctionReturn(0); 4341 } 4342 4343 /*@C 4344 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 4345 4346 Collective on TS 4347 4348 Input Parameters: 4349 . ctx - the monitor context 4350 4351 Level: intermediate 4352 4353 .keywords: TS, vector, monitor, view 4354 4355 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 4356 @*/ 4357 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 4358 { 4359 PetscErrorCode ierr; 4360 4361 PetscFunctionBegin; 4362 ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr); 4363 ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr); 4364 ierr = PetscFree(*ictx);CHKERRQ(ierr); 4365 PetscFunctionReturn(0); 4366 } 4367 4368 /*@C 4369 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 4370 4371 Collective on TS 4372 4373 Input Parameter: 4374 . ts - time-step context 4375 4376 Output Patameter: 4377 . ctx - the monitor context 4378 4379 Options Database: 4380 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4381 4382 Level: intermediate 4383 4384 .keywords: TS, vector, monitor, view 4385 4386 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 4387 @*/ 4388 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 4389 { 4390 PetscErrorCode ierr; 4391 4392 PetscFunctionBegin; 4393 ierr = PetscNew(ctx);CHKERRQ(ierr); 4394 ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr); 4395 ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr); 4396 4397 (*ctx)->howoften = howoften; 4398 (*ctx)->showinitial = PETSC_FALSE; 4399 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr); 4400 4401 (*ctx)->showtimestepandtime = PETSC_FALSE; 4402 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr); 4403 PetscFunctionReturn(0); 4404 } 4405 4406 /*@C 4407 TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling 4408 VecView() for the solution provided by TSSetSolutionFunction() at each timestep 4409 4410 Collective on TS 4411 4412 Input Parameters: 4413 + ts - the TS context 4414 . step - current time-step 4415 . ptime - current time 4416 - dummy - either a viewer or NULL 4417 4418 Options Database: 4419 . -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 4420 4421 Level: intermediate 4422 4423 .keywords: TS, vector, monitor, view 4424 4425 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 4426 @*/ 4427 PetscErrorCode TSMonitorDrawSolutionFunction(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4428 { 4429 PetscErrorCode ierr; 4430 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 4431 PetscViewer viewer = ctx->viewer; 4432 Vec work; 4433 4434 PetscFunctionBegin; 4435 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4436 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 4437 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 4438 ierr = VecView(work,viewer);CHKERRQ(ierr); 4439 ierr = VecDestroy(&work);CHKERRQ(ierr); 4440 PetscFunctionReturn(0); 4441 } 4442 4443 /*@C 4444 TSMonitorDrawError - Monitors progress of the TS solvers by calling 4445 VecView() for the error at each timestep 4446 4447 Collective on TS 4448 4449 Input Parameters: 4450 + ts - the TS context 4451 . step - current time-step 4452 . ptime - current time 4453 - dummy - either a viewer or NULL 4454 4455 Options Database: 4456 . -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 4457 4458 Level: intermediate 4459 4460 .keywords: TS, vector, monitor, view 4461 4462 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 4463 @*/ 4464 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4465 { 4466 PetscErrorCode ierr; 4467 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 4468 PetscViewer viewer = ctx->viewer; 4469 Vec work; 4470 4471 PetscFunctionBegin; 4472 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4473 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 4474 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 4475 ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr); 4476 ierr = VecView(work,viewer);CHKERRQ(ierr); 4477 ierr = VecDestroy(&work);CHKERRQ(ierr); 4478 PetscFunctionReturn(0); 4479 } 4480 4481 #include <petsc/private/dmimpl.h> 4482 /*@ 4483 TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS 4484 4485 Logically Collective on TS and DM 4486 4487 Input Parameters: 4488 + ts - the ODE integrator object 4489 - dm - the dm, cannot be NULL 4490 4491 Level: intermediate 4492 4493 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 4494 @*/ 4495 PetscErrorCode TSSetDM(TS ts,DM dm) 4496 { 4497 PetscErrorCode ierr; 4498 SNES snes; 4499 DMTS tsdm; 4500 4501 PetscFunctionBegin; 4502 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4503 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 4504 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 4505 if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */ 4506 if (ts->dm->dmts && !dm->dmts) { 4507 ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr); 4508 ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr); 4509 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 4510 tsdm->originaldm = dm; 4511 } 4512 } 4513 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 4514 } 4515 ts->dm = dm; 4516 4517 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4518 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 4519 PetscFunctionReturn(0); 4520 } 4521 4522 /*@ 4523 TSGetDM - Gets the DM that may be used by some preconditioners 4524 4525 Not Collective 4526 4527 Input Parameter: 4528 . ts - the preconditioner context 4529 4530 Output Parameter: 4531 . dm - the dm 4532 4533 Level: intermediate 4534 4535 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 4536 @*/ 4537 PetscErrorCode TSGetDM(TS ts,DM *dm) 4538 { 4539 PetscErrorCode ierr; 4540 4541 PetscFunctionBegin; 4542 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4543 if (!ts->dm) { 4544 ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr); 4545 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 4546 } 4547 *dm = ts->dm; 4548 PetscFunctionReturn(0); 4549 } 4550 4551 /*@ 4552 SNESTSFormFunction - Function to evaluate nonlinear residual 4553 4554 Logically Collective on SNES 4555 4556 Input Parameter: 4557 + snes - nonlinear solver 4558 . U - the current state at which to evaluate the residual 4559 - ctx - user context, must be a TS 4560 4561 Output Parameter: 4562 . F - the nonlinear residual 4563 4564 Notes: 4565 This function is not normally called by users and is automatically registered with the SNES used by TS. 4566 It is most frequently passed to MatFDColoringSetFunction(). 4567 4568 Level: advanced 4569 4570 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 4571 @*/ 4572 PetscErrorCode SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx) 4573 { 4574 TS ts = (TS)ctx; 4575 PetscErrorCode ierr; 4576 4577 PetscFunctionBegin; 4578 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4579 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 4580 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 4581 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 4582 ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr); 4583 PetscFunctionReturn(0); 4584 } 4585 4586 /*@ 4587 SNESTSFormJacobian - Function to evaluate the Jacobian 4588 4589 Collective on SNES 4590 4591 Input Parameter: 4592 + snes - nonlinear solver 4593 . U - the current state at which to evaluate the residual 4594 - ctx - user context, must be a TS 4595 4596 Output Parameter: 4597 + A - the Jacobian 4598 . B - the preconditioning matrix (may be the same as A) 4599 - flag - indicates any structure change in the matrix 4600 4601 Notes: 4602 This function is not normally called by users and is automatically registered with the SNES used by TS. 4603 4604 Level: developer 4605 4606 .seealso: SNESSetJacobian() 4607 @*/ 4608 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx) 4609 { 4610 TS ts = (TS)ctx; 4611 PetscErrorCode ierr; 4612 4613 PetscFunctionBegin; 4614 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4615 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 4616 PetscValidPointer(A,3); 4617 PetscValidHeaderSpecific(A,MAT_CLASSID,3); 4618 PetscValidPointer(B,4); 4619 PetscValidHeaderSpecific(B,MAT_CLASSID,4); 4620 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 4621 ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr); 4622 PetscFunctionReturn(0); 4623 } 4624 4625 /*@C 4626 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only 4627 4628 Collective on TS 4629 4630 Input Arguments: 4631 + ts - time stepping context 4632 . t - time at which to evaluate 4633 . U - state at which to evaluate 4634 - ctx - context 4635 4636 Output Arguments: 4637 . F - right hand side 4638 4639 Level: intermediate 4640 4641 Notes: 4642 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 4643 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 4644 4645 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 4646 @*/ 4647 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx) 4648 { 4649 PetscErrorCode ierr; 4650 Mat Arhs,Brhs; 4651 4652 PetscFunctionBegin; 4653 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 4654 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 4655 ierr = MatMult(Arhs,U,F);CHKERRQ(ierr); 4656 PetscFunctionReturn(0); 4657 } 4658 4659 /*@C 4660 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 4661 4662 Collective on TS 4663 4664 Input Arguments: 4665 + ts - time stepping context 4666 . t - time at which to evaluate 4667 . U - state at which to evaluate 4668 - ctx - context 4669 4670 Output Arguments: 4671 + A - pointer to operator 4672 . B - pointer to preconditioning matrix 4673 - flg - matrix structure flag 4674 4675 Level: intermediate 4676 4677 Notes: 4678 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 4679 4680 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 4681 @*/ 4682 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx) 4683 { 4684 PetscFunctionBegin; 4685 PetscFunctionReturn(0); 4686 } 4687 4688 /*@C 4689 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 4690 4691 Collective on TS 4692 4693 Input Arguments: 4694 + ts - time stepping context 4695 . t - time at which to evaluate 4696 . U - state at which to evaluate 4697 . Udot - time derivative of state vector 4698 - ctx - context 4699 4700 Output Arguments: 4701 . F - left hand side 4702 4703 Level: intermediate 4704 4705 Notes: 4706 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 4707 user is required to write their own TSComputeIFunction. 4708 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 4709 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 4710 4711 Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U 4712 4713 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear() 4714 @*/ 4715 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx) 4716 { 4717 PetscErrorCode ierr; 4718 Mat A,B; 4719 4720 PetscFunctionBegin; 4721 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 4722 ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr); 4723 ierr = MatMult(A,Udot,F);CHKERRQ(ierr); 4724 PetscFunctionReturn(0); 4725 } 4726 4727 /*@C 4728 TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE 4729 4730 Collective on TS 4731 4732 Input Arguments: 4733 + ts - time stepping context 4734 . t - time at which to evaluate 4735 . U - state at which to evaluate 4736 . Udot - time derivative of state vector 4737 . shift - shift to apply 4738 - ctx - context 4739 4740 Output Arguments: 4741 + A - pointer to operator 4742 . B - pointer to preconditioning matrix 4743 - flg - matrix structure flag 4744 4745 Level: advanced 4746 4747 Notes: 4748 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 4749 4750 It is only appropriate for problems of the form 4751 4752 $ M Udot = F(U,t) 4753 4754 where M is constant and F is non-stiff. The user must pass M to TSSetIJacobian(). The current implementation only 4755 works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing 4756 an implicit operator of the form 4757 4758 $ shift*M + J 4759 4760 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 4761 a copy of M or reassemble it when requested. 4762 4763 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 4764 @*/ 4765 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx) 4766 { 4767 PetscErrorCode ierr; 4768 4769 PetscFunctionBegin; 4770 ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 4771 ts->ijacobian.shift = shift; 4772 PetscFunctionReturn(0); 4773 } 4774 4775 /*@ 4776 TSGetEquationType - Gets the type of the equation that TS is solving. 4777 4778 Not Collective 4779 4780 Input Parameter: 4781 . ts - the TS context 4782 4783 Output Parameter: 4784 . equation_type - see TSEquationType 4785 4786 Level: beginner 4787 4788 .keywords: TS, equation type 4789 4790 .seealso: TSSetEquationType(), TSEquationType 4791 @*/ 4792 PetscErrorCode TSGetEquationType(TS ts,TSEquationType *equation_type) 4793 { 4794 PetscFunctionBegin; 4795 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4796 PetscValidPointer(equation_type,2); 4797 *equation_type = ts->equation_type; 4798 PetscFunctionReturn(0); 4799 } 4800 4801 /*@ 4802 TSSetEquationType - Sets the type of the equation that TS is solving. 4803 4804 Not Collective 4805 4806 Input Parameter: 4807 + ts - the TS context 4808 - equation_type - see TSEquationType 4809 4810 Level: advanced 4811 4812 .keywords: TS, equation type 4813 4814 .seealso: TSGetEquationType(), TSEquationType 4815 @*/ 4816 PetscErrorCode TSSetEquationType(TS ts,TSEquationType equation_type) 4817 { 4818 PetscFunctionBegin; 4819 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4820 ts->equation_type = equation_type; 4821 PetscFunctionReturn(0); 4822 } 4823 4824 /*@ 4825 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 4826 4827 Not Collective 4828 4829 Input Parameter: 4830 . ts - the TS context 4831 4832 Output Parameter: 4833 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 4834 manual pages for the individual convergence tests for complete lists 4835 4836 Level: beginner 4837 4838 Notes: 4839 Can only be called after the call to TSSolve() is complete. 4840 4841 .keywords: TS, nonlinear, set, convergence, test 4842 4843 .seealso: TSSetConvergenceTest(), TSConvergedReason 4844 @*/ 4845 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 4846 { 4847 PetscFunctionBegin; 4848 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4849 PetscValidPointer(reason,2); 4850 *reason = ts->reason; 4851 PetscFunctionReturn(0); 4852 } 4853 4854 /*@ 4855 TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve. 4856 4857 Not Collective 4858 4859 Input Parameter: 4860 + ts - the TS context 4861 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 4862 manual pages for the individual convergence tests for complete lists 4863 4864 Level: advanced 4865 4866 Notes: 4867 Can only be called during TSSolve() is active. 4868 4869 .keywords: TS, nonlinear, set, convergence, test 4870 4871 .seealso: TSConvergedReason 4872 @*/ 4873 PetscErrorCode TSSetConvergedReason(TS ts,TSConvergedReason reason) 4874 { 4875 PetscFunctionBegin; 4876 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4877 ts->reason = reason; 4878 PetscFunctionReturn(0); 4879 } 4880 4881 /*@ 4882 TSGetSolveTime - Gets the time after a call to TSSolve() 4883 4884 Not Collective 4885 4886 Input Parameter: 4887 . ts - the TS context 4888 4889 Output Parameter: 4890 . ftime - the final time. This time corresponds to the final time set with TSSetMaxTime() 4891 4892 Level: beginner 4893 4894 Notes: 4895 Can only be called after the call to TSSolve() is complete. 4896 4897 .keywords: TS, nonlinear, set, convergence, test 4898 4899 .seealso: TSSetConvergenceTest(), TSConvergedReason 4900 @*/ 4901 PetscErrorCode TSGetSolveTime(TS ts,PetscReal *ftime) 4902 { 4903 PetscFunctionBegin; 4904 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4905 PetscValidPointer(ftime,2); 4906 *ftime = ts->solvetime; 4907 PetscFunctionReturn(0); 4908 } 4909 4910 /*@ 4911 TSGetSNESIterations - Gets the total number of nonlinear iterations 4912 used by the time integrator. 4913 4914 Not Collective 4915 4916 Input Parameter: 4917 . ts - TS context 4918 4919 Output Parameter: 4920 . nits - number of nonlinear iterations 4921 4922 Notes: 4923 This counter is reset to zero for each successive call to TSSolve(). 4924 4925 Level: intermediate 4926 4927 .keywords: TS, get, number, nonlinear, iterations 4928 4929 .seealso: TSGetKSPIterations() 4930 @*/ 4931 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 4932 { 4933 PetscFunctionBegin; 4934 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4935 PetscValidIntPointer(nits,2); 4936 *nits = ts->snes_its; 4937 PetscFunctionReturn(0); 4938 } 4939 4940 /*@ 4941 TSGetKSPIterations - Gets the total number of linear iterations 4942 used by the time integrator. 4943 4944 Not Collective 4945 4946 Input Parameter: 4947 . ts - TS context 4948 4949 Output Parameter: 4950 . lits - number of linear iterations 4951 4952 Notes: 4953 This counter is reset to zero for each successive call to TSSolve(). 4954 4955 Level: intermediate 4956 4957 .keywords: TS, get, number, linear, iterations 4958 4959 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 4960 @*/ 4961 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 4962 { 4963 PetscFunctionBegin; 4964 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4965 PetscValidIntPointer(lits,2); 4966 *lits = ts->ksp_its; 4967 PetscFunctionReturn(0); 4968 } 4969 4970 /*@ 4971 TSGetStepRejections - Gets the total number of rejected steps. 4972 4973 Not Collective 4974 4975 Input Parameter: 4976 . ts - TS context 4977 4978 Output Parameter: 4979 . rejects - number of steps rejected 4980 4981 Notes: 4982 This counter is reset to zero for each successive call to TSSolve(). 4983 4984 Level: intermediate 4985 4986 .keywords: TS, get, number 4987 4988 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 4989 @*/ 4990 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 4991 { 4992 PetscFunctionBegin; 4993 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4994 PetscValidIntPointer(rejects,2); 4995 *rejects = ts->reject; 4996 PetscFunctionReturn(0); 4997 } 4998 4999 /*@ 5000 TSGetSNESFailures - Gets the total number of failed SNES solves 5001 5002 Not Collective 5003 5004 Input Parameter: 5005 . ts - TS context 5006 5007 Output Parameter: 5008 . fails - number of failed nonlinear solves 5009 5010 Notes: 5011 This counter is reset to zero for each successive call to TSSolve(). 5012 5013 Level: intermediate 5014 5015 .keywords: TS, get, number 5016 5017 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 5018 @*/ 5019 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 5020 { 5021 PetscFunctionBegin; 5022 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5023 PetscValidIntPointer(fails,2); 5024 *fails = ts->num_snes_failures; 5025 PetscFunctionReturn(0); 5026 } 5027 5028 /*@ 5029 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 5030 5031 Not Collective 5032 5033 Input Parameter: 5034 + ts - TS context 5035 - rejects - maximum number of rejected steps, pass -1 for unlimited 5036 5037 Notes: 5038 The counter is reset to zero for each step 5039 5040 Options Database Key: 5041 . -ts_max_reject - Maximum number of step rejections before a step fails 5042 5043 Level: intermediate 5044 5045 .keywords: TS, set, maximum, number 5046 5047 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5048 @*/ 5049 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 5050 { 5051 PetscFunctionBegin; 5052 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5053 ts->max_reject = rejects; 5054 PetscFunctionReturn(0); 5055 } 5056 5057 /*@ 5058 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 5059 5060 Not Collective 5061 5062 Input Parameter: 5063 + ts - TS context 5064 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 5065 5066 Notes: 5067 The counter is reset to zero for each successive call to TSSolve(). 5068 5069 Options Database Key: 5070 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 5071 5072 Level: intermediate 5073 5074 .keywords: TS, set, maximum, number 5075 5076 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 5077 @*/ 5078 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 5079 { 5080 PetscFunctionBegin; 5081 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5082 ts->max_snes_failures = fails; 5083 PetscFunctionReturn(0); 5084 } 5085 5086 /*@ 5087 TSSetErrorIfStepFails - Error if no step succeeds 5088 5089 Not Collective 5090 5091 Input Parameter: 5092 + ts - TS context 5093 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 5094 5095 Options Database Key: 5096 . -ts_error_if_step_fails - Error if no step succeeds 5097 5098 Level: intermediate 5099 5100 .keywords: TS, set, error 5101 5102 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5103 @*/ 5104 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 5105 { 5106 PetscFunctionBegin; 5107 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5108 ts->errorifstepfailed = err; 5109 PetscFunctionReturn(0); 5110 } 5111 5112 /*@C 5113 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 5114 5115 Collective on TS 5116 5117 Input Parameters: 5118 + ts - the TS context 5119 . step - current time-step 5120 . ptime - current time 5121 . u - current state 5122 - vf - viewer and its format 5123 5124 Level: intermediate 5125 5126 .keywords: TS, vector, monitor, view 5127 5128 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5129 @*/ 5130 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 5131 { 5132 PetscErrorCode ierr; 5133 5134 PetscFunctionBegin; 5135 ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr); 5136 ierr = VecView(u,vf->viewer);CHKERRQ(ierr); 5137 ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr); 5138 PetscFunctionReturn(0); 5139 } 5140 5141 /*@C 5142 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 5143 5144 Collective on TS 5145 5146 Input Parameters: 5147 + ts - the TS context 5148 . step - current time-step 5149 . ptime - current time 5150 . u - current state 5151 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5152 5153 Level: intermediate 5154 5155 Notes: 5156 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. 5157 These are named according to the file name template. 5158 5159 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 5160 5161 .keywords: TS, vector, monitor, view 5162 5163 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5164 @*/ 5165 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate) 5166 { 5167 PetscErrorCode ierr; 5168 char filename[PETSC_MAX_PATH_LEN]; 5169 PetscViewer viewer; 5170 5171 PetscFunctionBegin; 5172 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 5173 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 5174 ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 5175 ierr = VecView(u,viewer);CHKERRQ(ierr); 5176 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5177 PetscFunctionReturn(0); 5178 } 5179 5180 /*@C 5181 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 5182 5183 Collective on TS 5184 5185 Input Parameters: 5186 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5187 5188 Level: intermediate 5189 5190 Note: 5191 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 5192 5193 .keywords: TS, vector, monitor, view 5194 5195 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 5196 @*/ 5197 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 5198 { 5199 PetscErrorCode ierr; 5200 5201 PetscFunctionBegin; 5202 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 5203 PetscFunctionReturn(0); 5204 } 5205 5206 /*@ 5207 TSGetAdapt - Get the adaptive controller context for the current method 5208 5209 Collective on TS if controller has not been created yet 5210 5211 Input Arguments: 5212 . ts - time stepping context 5213 5214 Output Arguments: 5215 . adapt - adaptive controller 5216 5217 Level: intermediate 5218 5219 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 5220 @*/ 5221 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 5222 { 5223 PetscErrorCode ierr; 5224 5225 PetscFunctionBegin; 5226 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5227 PetscValidPointer(adapt,2); 5228 if (!ts->adapt) { 5229 ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr); 5230 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr); 5231 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 5232 } 5233 *adapt = ts->adapt; 5234 PetscFunctionReturn(0); 5235 } 5236 5237 /*@ 5238 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 5239 5240 Logically Collective 5241 5242 Input Arguments: 5243 + ts - time integration context 5244 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 5245 . vatol - vector of absolute tolerances or NULL, used in preference to atol if present 5246 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 5247 - vrtol - vector of relative tolerances or NULL, used in preference to atol if present 5248 5249 Options Database keys: 5250 + -ts_rtol <rtol> - relative tolerance for local truncation error 5251 - -ts_atol <atol> Absolute tolerance for local truncation error 5252 5253 Notes: 5254 With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error 5255 (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be 5256 computed only for the differential or the algebraic part then this can be done using the vector of 5257 tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the 5258 differential part and infinity for the algebraic part, the LTE calculation will include only the 5259 differential variables. 5260 5261 Level: beginner 5262 5263 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances() 5264 @*/ 5265 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 5266 { 5267 PetscErrorCode ierr; 5268 5269 PetscFunctionBegin; 5270 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 5271 if (vatol) { 5272 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 5273 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 5274 ts->vatol = vatol; 5275 } 5276 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 5277 if (vrtol) { 5278 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 5279 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 5280 ts->vrtol = vrtol; 5281 } 5282 PetscFunctionReturn(0); 5283 } 5284 5285 /*@ 5286 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 5287 5288 Logically Collective 5289 5290 Input Arguments: 5291 . ts - time integration context 5292 5293 Output Arguments: 5294 + atol - scalar absolute tolerances, NULL to ignore 5295 . vatol - vector of absolute tolerances, NULL to ignore 5296 . rtol - scalar relative tolerances, NULL to ignore 5297 - vrtol - vector of relative tolerances, NULL to ignore 5298 5299 Level: beginner 5300 5301 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances() 5302 @*/ 5303 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 5304 { 5305 PetscFunctionBegin; 5306 if (atol) *atol = ts->atol; 5307 if (vatol) *vatol = ts->vatol; 5308 if (rtol) *rtol = ts->rtol; 5309 if (vrtol) *vrtol = ts->vrtol; 5310 PetscFunctionReturn(0); 5311 } 5312 5313 /*@ 5314 TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors 5315 5316 Collective on TS 5317 5318 Input Arguments: 5319 + ts - time stepping context 5320 . U - state vector, usually ts->vec_sol 5321 - Y - state vector to be compared to U 5322 5323 Output Arguments: 5324 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5325 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5326 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5327 5328 Level: developer 5329 5330 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity() 5331 @*/ 5332 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5333 { 5334 PetscErrorCode ierr; 5335 PetscInt i,n,N,rstart; 5336 PetscInt n_loc,na_loc,nr_loc; 5337 PetscReal n_glb,na_glb,nr_glb; 5338 const PetscScalar *u,*y; 5339 PetscReal sum,suma,sumr,gsum,gsuma,gsumr,diff; 5340 PetscReal tol,tola,tolr; 5341 PetscReal err_loc[6],err_glb[6]; 5342 5343 PetscFunctionBegin; 5344 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5345 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5346 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5347 PetscValidType(U,2); 5348 PetscValidType(Y,3); 5349 PetscCheckSameComm(U,2,Y,3); 5350 PetscValidPointer(norm,4); 5351 PetscValidPointer(norma,5); 5352 PetscValidPointer(normr,6); 5353 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5354 5355 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5356 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5357 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5358 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5359 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5360 sum = 0.; n_loc = 0; 5361 suma = 0.; na_loc = 0; 5362 sumr = 0.; nr_loc = 0; 5363 if (ts->vatol && ts->vrtol) { 5364 const PetscScalar *atol,*rtol; 5365 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5366 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5367 for (i=0; i<n; i++) { 5368 diff = PetscAbsScalar(y[i] - u[i]); 5369 tola = PetscRealPart(atol[i]); 5370 if(tola>0.){ 5371 suma += PetscSqr(diff/tola); 5372 na_loc++; 5373 } 5374 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5375 if(tolr>0.){ 5376 sumr += PetscSqr(diff/tolr); 5377 nr_loc++; 5378 } 5379 tol=tola+tolr; 5380 if(tol>0.){ 5381 sum += PetscSqr(diff/tol); 5382 n_loc++; 5383 } 5384 } 5385 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5386 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5387 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5388 const PetscScalar *atol; 5389 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5390 for (i=0; i<n; i++) { 5391 diff = PetscAbsScalar(y[i] - u[i]); 5392 tola = PetscRealPart(atol[i]); 5393 if(tola>0.){ 5394 suma += PetscSqr(diff/tola); 5395 na_loc++; 5396 } 5397 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5398 if(tolr>0.){ 5399 sumr += PetscSqr(diff/tolr); 5400 nr_loc++; 5401 } 5402 tol=tola+tolr; 5403 if(tol>0.){ 5404 sum += PetscSqr(diff/tol); 5405 n_loc++; 5406 } 5407 } 5408 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5409 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5410 const PetscScalar *rtol; 5411 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5412 for (i=0; i<n; i++) { 5413 diff = PetscAbsScalar(y[i] - u[i]); 5414 tola = ts->atol; 5415 if(tola>0.){ 5416 suma += PetscSqr(diff/tola); 5417 na_loc++; 5418 } 5419 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5420 if(tolr>0.){ 5421 sumr += PetscSqr(diff/tolr); 5422 nr_loc++; 5423 } 5424 tol=tola+tolr; 5425 if(tol>0.){ 5426 sum += PetscSqr(diff/tol); 5427 n_loc++; 5428 } 5429 } 5430 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5431 } else { /* scalar atol, scalar rtol */ 5432 for (i=0; i<n; i++) { 5433 diff = PetscAbsScalar(y[i] - u[i]); 5434 tola = ts->atol; 5435 if(tola>0.){ 5436 suma += PetscSqr(diff/tola); 5437 na_loc++; 5438 } 5439 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5440 if(tolr>0.){ 5441 sumr += PetscSqr(diff/tolr); 5442 nr_loc++; 5443 } 5444 tol=tola+tolr; 5445 if(tol>0.){ 5446 sum += PetscSqr(diff/tol); 5447 n_loc++; 5448 } 5449 } 5450 } 5451 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5452 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5453 5454 err_loc[0] = sum; 5455 err_loc[1] = suma; 5456 err_loc[2] = sumr; 5457 err_loc[3] = (PetscReal)n_loc; 5458 err_loc[4] = (PetscReal)na_loc; 5459 err_loc[5] = (PetscReal)nr_loc; 5460 5461 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5462 5463 gsum = err_glb[0]; 5464 gsuma = err_glb[1]; 5465 gsumr = err_glb[2]; 5466 n_glb = err_glb[3]; 5467 na_glb = err_glb[4]; 5468 nr_glb = err_glb[5]; 5469 5470 *norm = 0.; 5471 if(n_glb>0. ){*norm = PetscSqrtReal(gsum / n_glb );} 5472 *norma = 0.; 5473 if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 5474 *normr = 0.; 5475 if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 5476 5477 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5478 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5479 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5480 PetscFunctionReturn(0); 5481 } 5482 5483 /*@ 5484 TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors 5485 5486 Collective on TS 5487 5488 Input Arguments: 5489 + ts - time stepping context 5490 . U - state vector, usually ts->vec_sol 5491 - Y - state vector to be compared to U 5492 5493 Output Arguments: 5494 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5495 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5496 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5497 5498 Level: developer 5499 5500 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2() 5501 @*/ 5502 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5503 { 5504 PetscErrorCode ierr; 5505 PetscInt i,n,N,rstart; 5506 const PetscScalar *u,*y; 5507 PetscReal max,gmax,maxa,gmaxa,maxr,gmaxr; 5508 PetscReal tol,tola,tolr,diff; 5509 PetscReal err_loc[3],err_glb[3]; 5510 5511 PetscFunctionBegin; 5512 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5513 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5514 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5515 PetscValidType(U,2); 5516 PetscValidType(Y,3); 5517 PetscCheckSameComm(U,2,Y,3); 5518 PetscValidPointer(norm,4); 5519 PetscValidPointer(norma,5); 5520 PetscValidPointer(normr,6); 5521 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5522 5523 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5524 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5525 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5526 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5527 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5528 5529 max=0.; 5530 maxa=0.; 5531 maxr=0.; 5532 5533 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 5534 const PetscScalar *atol,*rtol; 5535 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5536 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5537 5538 for (i=0; i<n; i++) { 5539 diff = PetscAbsScalar(y[i] - u[i]); 5540 tola = PetscRealPart(atol[i]); 5541 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5542 tol = tola+tolr; 5543 if(tola>0.){ 5544 maxa = PetscMax(maxa,diff / tola); 5545 } 5546 if(tolr>0.){ 5547 maxr = PetscMax(maxr,diff / tolr); 5548 } 5549 if(tol>0.){ 5550 max = PetscMax(max,diff / tol); 5551 } 5552 } 5553 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5554 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5555 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5556 const PetscScalar *atol; 5557 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5558 for (i=0; i<n; i++) { 5559 diff = PetscAbsScalar(y[i] - u[i]); 5560 tola = PetscRealPart(atol[i]); 5561 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5562 tol = tola+tolr; 5563 if(tola>0.){ 5564 maxa = PetscMax(maxa,diff / tola); 5565 } 5566 if(tolr>0.){ 5567 maxr = PetscMax(maxr,diff / tolr); 5568 } 5569 if(tol>0.){ 5570 max = PetscMax(max,diff / tol); 5571 } 5572 } 5573 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5574 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5575 const PetscScalar *rtol; 5576 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5577 5578 for (i=0; i<n; i++) { 5579 diff = PetscAbsScalar(y[i] - u[i]); 5580 tola = ts->atol; 5581 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5582 tol = tola+tolr; 5583 if(tola>0.){ 5584 maxa = PetscMax(maxa,diff / tola); 5585 } 5586 if(tolr>0.){ 5587 maxr = PetscMax(maxr,diff / tolr); 5588 } 5589 if(tol>0.){ 5590 max = PetscMax(max,diff / tol); 5591 } 5592 } 5593 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5594 } else { /* scalar atol, scalar rtol */ 5595 5596 for (i=0; i<n; i++) { 5597 diff = PetscAbsScalar(y[i] - u[i]); 5598 tola = ts->atol; 5599 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5600 tol = tola+tolr; 5601 if(tola>0.){ 5602 maxa = PetscMax(maxa,diff / tola); 5603 } 5604 if(tolr>0.){ 5605 maxr = PetscMax(maxr,diff / tolr); 5606 } 5607 if(tol>0.){ 5608 max = PetscMax(max,diff / tol); 5609 } 5610 } 5611 } 5612 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5613 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5614 err_loc[0] = max; 5615 err_loc[1] = maxa; 5616 err_loc[2] = maxr; 5617 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5618 gmax = err_glb[0]; 5619 gmaxa = err_glb[1]; 5620 gmaxr = err_glb[2]; 5621 5622 *norm = gmax; 5623 *norma = gmaxa; 5624 *normr = gmaxr; 5625 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5626 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5627 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5628 PetscFunctionReturn(0); 5629 } 5630 5631 /*@ 5632 TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances 5633 5634 Collective on TS 5635 5636 Input Arguments: 5637 + ts - time stepping context 5638 . U - state vector, usually ts->vec_sol 5639 . Y - state vector to be compared to U 5640 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 5641 5642 Output Arguments: 5643 . norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 5644 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 5645 . normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 5646 5647 Options Database Keys: 5648 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 5649 5650 Level: developer 5651 5652 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2(), TSErrorWeightedENorm 5653 @*/ 5654 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5655 { 5656 PetscErrorCode ierr; 5657 5658 PetscFunctionBegin; 5659 if (wnormtype == NORM_2) { 5660 ierr = TSErrorWeightedNorm2(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 5661 } else if(wnormtype == NORM_INFINITY) { 5662 ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 5663 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 5664 PetscFunctionReturn(0); 5665 } 5666 5667 5668 /*@ 5669 TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances 5670 5671 Collective on TS 5672 5673 Input Arguments: 5674 + ts - time stepping context 5675 . E - error vector 5676 . U - state vector, usually ts->vec_sol 5677 - Y - state vector, previous time step 5678 5679 Output Arguments: 5680 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5681 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5682 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5683 5684 Level: developer 5685 5686 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENormInfinity() 5687 @*/ 5688 PetscErrorCode TSErrorWeightedENorm2(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5689 { 5690 PetscErrorCode ierr; 5691 PetscInt i,n,N,rstart; 5692 PetscInt n_loc,na_loc,nr_loc; 5693 PetscReal n_glb,na_glb,nr_glb; 5694 const PetscScalar *e,*u,*y; 5695 PetscReal err,sum,suma,sumr,gsum,gsuma,gsumr; 5696 PetscReal tol,tola,tolr; 5697 PetscReal err_loc[6],err_glb[6]; 5698 5699 PetscFunctionBegin; 5700 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5701 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 5702 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 5703 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 5704 PetscValidType(E,2); 5705 PetscValidType(U,3); 5706 PetscValidType(Y,4); 5707 PetscCheckSameComm(E,2,U,3); 5708 PetscCheckSameComm(U,2,Y,3); 5709 PetscValidPointer(norm,5); 5710 PetscValidPointer(norma,6); 5711 PetscValidPointer(normr,7); 5712 5713 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 5714 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 5715 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 5716 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 5717 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5718 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5719 sum = 0.; n_loc = 0; 5720 suma = 0.; na_loc = 0; 5721 sumr = 0.; nr_loc = 0; 5722 if (ts->vatol && ts->vrtol) { 5723 const PetscScalar *atol,*rtol; 5724 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5725 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5726 for (i=0; i<n; i++) { 5727 err = PetscAbsScalar(e[i]); 5728 tola = PetscRealPart(atol[i]); 5729 if(tola>0.){ 5730 suma += PetscSqr(err/tola); 5731 na_loc++; 5732 } 5733 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5734 if(tolr>0.){ 5735 sumr += PetscSqr(err/tolr); 5736 nr_loc++; 5737 } 5738 tol=tola+tolr; 5739 if(tol>0.){ 5740 sum += PetscSqr(err/tol); 5741 n_loc++; 5742 } 5743 } 5744 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5745 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5746 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5747 const PetscScalar *atol; 5748 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5749 for (i=0; i<n; i++) { 5750 err = PetscAbsScalar(e[i]); 5751 tola = PetscRealPart(atol[i]); 5752 if(tola>0.){ 5753 suma += PetscSqr(err/tola); 5754 na_loc++; 5755 } 5756 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5757 if(tolr>0.){ 5758 sumr += PetscSqr(err/tolr); 5759 nr_loc++; 5760 } 5761 tol=tola+tolr; 5762 if(tol>0.){ 5763 sum += PetscSqr(err/tol); 5764 n_loc++; 5765 } 5766 } 5767 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5768 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5769 const PetscScalar *rtol; 5770 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5771 for (i=0; i<n; i++) { 5772 err = PetscAbsScalar(e[i]); 5773 tola = ts->atol; 5774 if(tola>0.){ 5775 suma += PetscSqr(err/tola); 5776 na_loc++; 5777 } 5778 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5779 if(tolr>0.){ 5780 sumr += PetscSqr(err/tolr); 5781 nr_loc++; 5782 } 5783 tol=tola+tolr; 5784 if(tol>0.){ 5785 sum += PetscSqr(err/tol); 5786 n_loc++; 5787 } 5788 } 5789 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5790 } else { /* scalar atol, scalar rtol */ 5791 for (i=0; i<n; i++) { 5792 err = PetscAbsScalar(e[i]); 5793 tola = ts->atol; 5794 if(tola>0.){ 5795 suma += PetscSqr(err/tola); 5796 na_loc++; 5797 } 5798 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5799 if(tolr>0.){ 5800 sumr += PetscSqr(err/tolr); 5801 nr_loc++; 5802 } 5803 tol=tola+tolr; 5804 if(tol>0.){ 5805 sum += PetscSqr(err/tol); 5806 n_loc++; 5807 } 5808 } 5809 } 5810 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 5811 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5812 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5813 5814 err_loc[0] = sum; 5815 err_loc[1] = suma; 5816 err_loc[2] = sumr; 5817 err_loc[3] = (PetscReal)n_loc; 5818 err_loc[4] = (PetscReal)na_loc; 5819 err_loc[5] = (PetscReal)nr_loc; 5820 5821 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5822 5823 gsum = err_glb[0]; 5824 gsuma = err_glb[1]; 5825 gsumr = err_glb[2]; 5826 n_glb = err_glb[3]; 5827 na_glb = err_glb[4]; 5828 nr_glb = err_glb[5]; 5829 5830 *norm = 0.; 5831 if(n_glb>0. ){*norm = PetscSqrtReal(gsum / n_glb );} 5832 *norma = 0.; 5833 if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 5834 *normr = 0.; 5835 if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 5836 5837 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5838 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5839 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5840 PetscFunctionReturn(0); 5841 } 5842 5843 /*@ 5844 TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances 5845 Collective on TS 5846 5847 Input Arguments: 5848 + ts - time stepping context 5849 . E - error vector 5850 . U - state vector, usually ts->vec_sol 5851 - Y - state vector, previous time step 5852 5853 Output Arguments: 5854 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5855 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5856 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5857 5858 Level: developer 5859 5860 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENorm2() 5861 @*/ 5862 PetscErrorCode TSErrorWeightedENormInfinity(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5863 { 5864 PetscErrorCode ierr; 5865 PetscInt i,n,N,rstart; 5866 const PetscScalar *e,*u,*y; 5867 PetscReal err,max,gmax,maxa,gmaxa,maxr,gmaxr; 5868 PetscReal tol,tola,tolr; 5869 PetscReal err_loc[3],err_glb[3]; 5870 5871 PetscFunctionBegin; 5872 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5873 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 5874 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 5875 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 5876 PetscValidType(E,2); 5877 PetscValidType(U,3); 5878 PetscValidType(Y,4); 5879 PetscCheckSameComm(E,2,U,3); 5880 PetscCheckSameComm(U,2,Y,3); 5881 PetscValidPointer(norm,5); 5882 PetscValidPointer(norma,6); 5883 PetscValidPointer(normr,7); 5884 5885 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 5886 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 5887 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 5888 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 5889 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5890 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5891 5892 max=0.; 5893 maxa=0.; 5894 maxr=0.; 5895 5896 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 5897 const PetscScalar *atol,*rtol; 5898 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5899 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5900 5901 for (i=0; i<n; i++) { 5902 err = PetscAbsScalar(e[i]); 5903 tola = PetscRealPart(atol[i]); 5904 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5905 tol = tola+tolr; 5906 if(tola>0.){ 5907 maxa = PetscMax(maxa,err / tola); 5908 } 5909 if(tolr>0.){ 5910 maxr = PetscMax(maxr,err / tolr); 5911 } 5912 if(tol>0.){ 5913 max = PetscMax(max,err / tol); 5914 } 5915 } 5916 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5917 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5918 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5919 const PetscScalar *atol; 5920 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5921 for (i=0; i<n; i++) { 5922 err = PetscAbsScalar(e[i]); 5923 tola = PetscRealPart(atol[i]); 5924 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5925 tol = tola+tolr; 5926 if(tola>0.){ 5927 maxa = PetscMax(maxa,err / tola); 5928 } 5929 if(tolr>0.){ 5930 maxr = PetscMax(maxr,err / tolr); 5931 } 5932 if(tol>0.){ 5933 max = PetscMax(max,err / tol); 5934 } 5935 } 5936 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5937 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5938 const PetscScalar *rtol; 5939 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5940 5941 for (i=0; i<n; i++) { 5942 err = PetscAbsScalar(e[i]); 5943 tola = ts->atol; 5944 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5945 tol = tola+tolr; 5946 if(tola>0.){ 5947 maxa = PetscMax(maxa,err / tola); 5948 } 5949 if(tolr>0.){ 5950 maxr = PetscMax(maxr,err / tolr); 5951 } 5952 if(tol>0.){ 5953 max = PetscMax(max,err / tol); 5954 } 5955 } 5956 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5957 } else { /* scalar atol, scalar rtol */ 5958 5959 for (i=0; i<n; i++) { 5960 err = PetscAbsScalar(e[i]); 5961 tola = ts->atol; 5962 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5963 tol = tola+tolr; 5964 if(tola>0.){ 5965 maxa = PetscMax(maxa,err / tola); 5966 } 5967 if(tolr>0.){ 5968 maxr = PetscMax(maxr,err / tolr); 5969 } 5970 if(tol>0.){ 5971 max = PetscMax(max,err / tol); 5972 } 5973 } 5974 } 5975 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 5976 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5977 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5978 err_loc[0] = max; 5979 err_loc[1] = maxa; 5980 err_loc[2] = maxr; 5981 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5982 gmax = err_glb[0]; 5983 gmaxa = err_glb[1]; 5984 gmaxr = err_glb[2]; 5985 5986 *norm = gmax; 5987 *norma = gmaxa; 5988 *normr = gmaxr; 5989 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5990 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5991 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5992 PetscFunctionReturn(0); 5993 } 5994 5995 /*@ 5996 TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances 5997 5998 Collective on TS 5999 6000 Input Arguments: 6001 + ts - time stepping context 6002 . E - error vector 6003 . U - state vector, usually ts->vec_sol 6004 . Y - state vector, previous time step 6005 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 6006 6007 Output Arguments: 6008 . norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 6009 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 6010 . normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 6011 6012 Options Database Keys: 6013 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6014 6015 Level: developer 6016 6017 .seealso: TSErrorWeightedENormInfinity(), TSErrorWeightedENorm2(), TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2() 6018 @*/ 6019 PetscErrorCode TSErrorWeightedENorm(TS ts,Vec E,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6020 { 6021 PetscErrorCode ierr; 6022 6023 PetscFunctionBegin; 6024 if (wnormtype == NORM_2) { 6025 ierr = TSErrorWeightedENorm2(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6026 } else if(wnormtype == NORM_INFINITY) { 6027 ierr = TSErrorWeightedENormInfinity(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6028 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6029 PetscFunctionReturn(0); 6030 } 6031 6032 6033 /*@ 6034 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 6035 6036 Logically Collective on TS 6037 6038 Input Arguments: 6039 + ts - time stepping context 6040 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 6041 6042 Note: 6043 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 6044 6045 Level: intermediate 6046 6047 .seealso: TSGetCFLTime(), TSADAPTCFL 6048 @*/ 6049 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 6050 { 6051 PetscFunctionBegin; 6052 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6053 ts->cfltime_local = cfltime; 6054 ts->cfltime = -1.; 6055 PetscFunctionReturn(0); 6056 } 6057 6058 /*@ 6059 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 6060 6061 Collective on TS 6062 6063 Input Arguments: 6064 . ts - time stepping context 6065 6066 Output Arguments: 6067 . cfltime - maximum stable time step for forward Euler 6068 6069 Level: advanced 6070 6071 .seealso: TSSetCFLTimeLocal() 6072 @*/ 6073 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 6074 { 6075 PetscErrorCode ierr; 6076 6077 PetscFunctionBegin; 6078 if (ts->cfltime < 0) { 6079 ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6080 } 6081 *cfltime = ts->cfltime; 6082 PetscFunctionReturn(0); 6083 } 6084 6085 /*@ 6086 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 6087 6088 Input Parameters: 6089 . ts - the TS context. 6090 . xl - lower bound. 6091 . xu - upper bound. 6092 6093 Notes: 6094 If this routine is not called then the lower and upper bounds are set to 6095 PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp(). 6096 6097 Level: advanced 6098 6099 @*/ 6100 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 6101 { 6102 PetscErrorCode ierr; 6103 SNES snes; 6104 6105 PetscFunctionBegin; 6106 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 6107 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 6108 PetscFunctionReturn(0); 6109 } 6110 6111 #if defined(PETSC_HAVE_MATLAB_ENGINE) 6112 #include <mex.h> 6113 6114 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 6115 6116 /* 6117 TSComputeFunction_Matlab - Calls the function that has been set with 6118 TSSetFunctionMatlab(). 6119 6120 Collective on TS 6121 6122 Input Parameters: 6123 + snes - the TS context 6124 - u - input vector 6125 6126 Output Parameter: 6127 . y - function vector, as set by TSSetFunction() 6128 6129 Notes: 6130 TSComputeFunction() is typically used within nonlinear solvers 6131 implementations, so most users would not generally call this routine 6132 themselves. 6133 6134 Level: developer 6135 6136 .keywords: TS, nonlinear, compute, function 6137 6138 .seealso: TSSetFunction(), TSGetFunction() 6139 */ 6140 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx) 6141 { 6142 PetscErrorCode ierr; 6143 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6144 int nlhs = 1,nrhs = 7; 6145 mxArray *plhs[1],*prhs[7]; 6146 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 6147 6148 PetscFunctionBegin; 6149 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 6150 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 6151 PetscValidHeaderSpecific(udot,VEC_CLASSID,4); 6152 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 6153 PetscCheckSameComm(snes,1,u,3); 6154 PetscCheckSameComm(snes,1,y,5); 6155 6156 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 6157 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6158 ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr); 6159 ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr); 6160 6161 prhs[0] = mxCreateDoubleScalar((double)ls); 6162 prhs[1] = mxCreateDoubleScalar(time); 6163 prhs[2] = mxCreateDoubleScalar((double)lx); 6164 prhs[3] = mxCreateDoubleScalar((double)lxdot); 6165 prhs[4] = mxCreateDoubleScalar((double)ly); 6166 prhs[5] = mxCreateString(sctx->funcname); 6167 prhs[6] = sctx->ctx; 6168 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 6169 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6170 mxDestroyArray(prhs[0]); 6171 mxDestroyArray(prhs[1]); 6172 mxDestroyArray(prhs[2]); 6173 mxDestroyArray(prhs[3]); 6174 mxDestroyArray(prhs[4]); 6175 mxDestroyArray(prhs[5]); 6176 mxDestroyArray(plhs[0]); 6177 PetscFunctionReturn(0); 6178 } 6179 6180 /* 6181 TSSetFunctionMatlab - Sets the function evaluation routine and function 6182 vector for use by the TS routines in solving ODEs 6183 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 6184 6185 Logically Collective on TS 6186 6187 Input Parameters: 6188 + ts - the TS context 6189 - func - function evaluation routine 6190 6191 Calling sequence of func: 6192 $ func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx); 6193 6194 Level: beginner 6195 6196 .keywords: TS, nonlinear, set, function 6197 6198 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6199 */ 6200 PetscErrorCode TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx) 6201 { 6202 PetscErrorCode ierr; 6203 TSMatlabContext *sctx; 6204 6205 PetscFunctionBegin; 6206 /* currently sctx is memory bleed */ 6207 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6208 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6209 /* 6210 This should work, but it doesn't 6211 sctx->ctx = ctx; 6212 mexMakeArrayPersistent(sctx->ctx); 6213 */ 6214 sctx->ctx = mxDuplicateArray(ctx); 6215 6216 ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 6217 PetscFunctionReturn(0); 6218 } 6219 6220 /* 6221 TSComputeJacobian_Matlab - Calls the function that has been set with 6222 TSSetJacobianMatlab(). 6223 6224 Collective on TS 6225 6226 Input Parameters: 6227 + ts - the TS context 6228 . u - input vector 6229 . A, B - the matrices 6230 - ctx - user context 6231 6232 Level: developer 6233 6234 .keywords: TS, nonlinear, compute, function 6235 6236 .seealso: TSSetFunction(), TSGetFunction() 6237 @*/ 6238 PetscErrorCode TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx) 6239 { 6240 PetscErrorCode ierr; 6241 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6242 int nlhs = 2,nrhs = 9; 6243 mxArray *plhs[2],*prhs[9]; 6244 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 6245 6246 PetscFunctionBegin; 6247 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6248 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 6249 6250 /* call Matlab function in ctx with arguments u and y */ 6251 6252 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 6253 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6254 ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr); 6255 ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr); 6256 ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr); 6257 6258 prhs[0] = mxCreateDoubleScalar((double)ls); 6259 prhs[1] = mxCreateDoubleScalar((double)time); 6260 prhs[2] = mxCreateDoubleScalar((double)lx); 6261 prhs[3] = mxCreateDoubleScalar((double)lxdot); 6262 prhs[4] = mxCreateDoubleScalar((double)shift); 6263 prhs[5] = mxCreateDoubleScalar((double)lA); 6264 prhs[6] = mxCreateDoubleScalar((double)lB); 6265 prhs[7] = mxCreateString(sctx->funcname); 6266 prhs[8] = sctx->ctx; 6267 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 6268 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6269 mxDestroyArray(prhs[0]); 6270 mxDestroyArray(prhs[1]); 6271 mxDestroyArray(prhs[2]); 6272 mxDestroyArray(prhs[3]); 6273 mxDestroyArray(prhs[4]); 6274 mxDestroyArray(prhs[5]); 6275 mxDestroyArray(prhs[6]); 6276 mxDestroyArray(prhs[7]); 6277 mxDestroyArray(plhs[0]); 6278 mxDestroyArray(plhs[1]); 6279 PetscFunctionReturn(0); 6280 } 6281 6282 /* 6283 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 6284 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 6285 6286 Logically Collective on TS 6287 6288 Input Parameters: 6289 + ts - the TS context 6290 . A,B - Jacobian matrices 6291 . func - function evaluation routine 6292 - ctx - user context 6293 6294 Calling sequence of func: 6295 $ flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx); 6296 6297 Level: developer 6298 6299 .keywords: TS, nonlinear, set, function 6300 6301 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6302 */ 6303 PetscErrorCode TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx) 6304 { 6305 PetscErrorCode ierr; 6306 TSMatlabContext *sctx; 6307 6308 PetscFunctionBegin; 6309 /* currently sctx is memory bleed */ 6310 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6311 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6312 /* 6313 This should work, but it doesn't 6314 sctx->ctx = ctx; 6315 mexMakeArrayPersistent(sctx->ctx); 6316 */ 6317 sctx->ctx = mxDuplicateArray(ctx); 6318 6319 ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 6320 PetscFunctionReturn(0); 6321 } 6322 6323 /* 6324 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 6325 6326 Collective on TS 6327 6328 .seealso: TSSetFunction(), TSGetFunction() 6329 @*/ 6330 PetscErrorCode TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx) 6331 { 6332 PetscErrorCode ierr; 6333 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6334 int nlhs = 1,nrhs = 6; 6335 mxArray *plhs[1],*prhs[6]; 6336 long long int lx = 0,ls = 0; 6337 6338 PetscFunctionBegin; 6339 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6340 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 6341 6342 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 6343 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6344 6345 prhs[0] = mxCreateDoubleScalar((double)ls); 6346 prhs[1] = mxCreateDoubleScalar((double)it); 6347 prhs[2] = mxCreateDoubleScalar((double)time); 6348 prhs[3] = mxCreateDoubleScalar((double)lx); 6349 prhs[4] = mxCreateString(sctx->funcname); 6350 prhs[5] = sctx->ctx; 6351 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 6352 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6353 mxDestroyArray(prhs[0]); 6354 mxDestroyArray(prhs[1]); 6355 mxDestroyArray(prhs[2]); 6356 mxDestroyArray(prhs[3]); 6357 mxDestroyArray(prhs[4]); 6358 mxDestroyArray(plhs[0]); 6359 PetscFunctionReturn(0); 6360 } 6361 6362 /* 6363 TSMonitorSetMatlab - Sets the monitor function from Matlab 6364 6365 Level: developer 6366 6367 .keywords: TS, nonlinear, set, function 6368 6369 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6370 */ 6371 PetscErrorCode TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx) 6372 { 6373 PetscErrorCode ierr; 6374 TSMatlabContext *sctx; 6375 6376 PetscFunctionBegin; 6377 /* currently sctx is memory bleed */ 6378 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6379 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6380 /* 6381 This should work, but it doesn't 6382 sctx->ctx = ctx; 6383 mexMakeArrayPersistent(sctx->ctx); 6384 */ 6385 sctx->ctx = mxDuplicateArray(ctx); 6386 6387 ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 6388 PetscFunctionReturn(0); 6389 } 6390 #endif 6391 6392 /*@C 6393 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 6394 in a time based line graph 6395 6396 Collective on TS 6397 6398 Input Parameters: 6399 + ts - the TS context 6400 . step - current time-step 6401 . ptime - current time 6402 . u - current solution 6403 - dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate() 6404 6405 Options Database: 6406 . -ts_monitor_lg_solution_variables 6407 6408 Level: intermediate 6409 6410 Notes: 6411 Each process in a parallel run displays its component solutions in a separate window 6412 6413 .keywords: TS, vector, monitor, view 6414 6415 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 6416 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 6417 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 6418 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 6419 @*/ 6420 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 6421 { 6422 PetscErrorCode ierr; 6423 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dctx; 6424 const PetscScalar *yy; 6425 Vec v; 6426 6427 PetscFunctionBegin; 6428 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6429 if (!step) { 6430 PetscDrawAxis axis; 6431 PetscInt dim; 6432 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6433 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 6434 if (!ctx->names) { 6435 PetscBool flg; 6436 /* user provides names of variables to plot but no names has been set so assume names are integer values */ 6437 ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr); 6438 if (flg) { 6439 PetscInt i,n; 6440 char **names; 6441 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 6442 ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr); 6443 for (i=0; i<n; i++) { 6444 ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr); 6445 ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr); 6446 } 6447 names[n] = NULL; 6448 ctx->names = names; 6449 } 6450 } 6451 if (ctx->names && !ctx->displaynames) { 6452 char **displaynames; 6453 PetscBool flg; 6454 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6455 ierr = PetscMalloc1(dim+1,&displaynames);CHKERRQ(ierr); 6456 ierr = PetscMemzero(displaynames,(dim+1)*sizeof(char*));CHKERRQ(ierr); 6457 ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr); 6458 if (flg) { 6459 ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr); 6460 } 6461 ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr); 6462 } 6463 if (ctx->displaynames) { 6464 ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr); 6465 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr); 6466 } else if (ctx->names) { 6467 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6468 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6469 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr); 6470 } else { 6471 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6472 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6473 } 6474 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6475 } 6476 6477 if (!ctx->transform) v = u; 6478 else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);} 6479 ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr); 6480 if (ctx->displaynames) { 6481 PetscInt i; 6482 for (i=0; i<ctx->ndisplayvariables; i++) 6483 ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]); 6484 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr); 6485 } else { 6486 #if defined(PETSC_USE_COMPLEX) 6487 PetscInt i,n; 6488 PetscReal *yreal; 6489 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 6490 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6491 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6492 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6493 ierr = PetscFree(yreal);CHKERRQ(ierr); 6494 #else 6495 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6496 #endif 6497 } 6498 ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr); 6499 if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);} 6500 6501 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6502 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6503 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6504 } 6505 PetscFunctionReturn(0); 6506 } 6507 6508 /*@C 6509 TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 6510 6511 Collective on TS 6512 6513 Input Parameters: 6514 + ts - the TS context 6515 - names - the names of the components, final string must be NULL 6516 6517 Level: intermediate 6518 6519 Notes: 6520 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6521 6522 .keywords: TS, vector, monitor, view 6523 6524 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames() 6525 @*/ 6526 PetscErrorCode TSMonitorLGSetVariableNames(TS ts,const char * const *names) 6527 { 6528 PetscErrorCode ierr; 6529 PetscInt i; 6530 6531 PetscFunctionBegin; 6532 for (i=0; i<ts->numbermonitors; i++) { 6533 if (ts->monitor[i] == TSMonitorLGSolution) { 6534 ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr); 6535 break; 6536 } 6537 } 6538 PetscFunctionReturn(0); 6539 } 6540 6541 /*@C 6542 TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 6543 6544 Collective on TS 6545 6546 Input Parameters: 6547 + ts - the TS context 6548 - names - the names of the components, final string must be NULL 6549 6550 Level: intermediate 6551 6552 .keywords: TS, vector, monitor, view 6553 6554 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames() 6555 @*/ 6556 PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names) 6557 { 6558 PetscErrorCode ierr; 6559 6560 PetscFunctionBegin; 6561 ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr); 6562 ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr); 6563 PetscFunctionReturn(0); 6564 } 6565 6566 /*@C 6567 TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot 6568 6569 Collective on TS 6570 6571 Input Parameter: 6572 . ts - the TS context 6573 6574 Output Parameter: 6575 . names - the names of the components, final string must be NULL 6576 6577 Level: intermediate 6578 6579 Notes: 6580 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6581 6582 .keywords: TS, vector, monitor, view 6583 6584 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 6585 @*/ 6586 PetscErrorCode TSMonitorLGGetVariableNames(TS ts,const char *const **names) 6587 { 6588 PetscInt i; 6589 6590 PetscFunctionBegin; 6591 *names = NULL; 6592 for (i=0; i<ts->numbermonitors; i++) { 6593 if (ts->monitor[i] == TSMonitorLGSolution) { 6594 TSMonitorLGCtx ctx = (TSMonitorLGCtx) ts->monitorcontext[i]; 6595 *names = (const char *const *)ctx->names; 6596 break; 6597 } 6598 } 6599 PetscFunctionReturn(0); 6600 } 6601 6602 /*@C 6603 TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor 6604 6605 Collective on TS 6606 6607 Input Parameters: 6608 + ctx - the TSMonitorLG context 6609 . displaynames - the names of the components, final string must be NULL 6610 6611 Level: intermediate 6612 6613 .keywords: TS, vector, monitor, view 6614 6615 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 6616 @*/ 6617 PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames) 6618 { 6619 PetscInt j = 0,k; 6620 PetscErrorCode ierr; 6621 6622 PetscFunctionBegin; 6623 if (!ctx->names) PetscFunctionReturn(0); 6624 ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr); 6625 ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr); 6626 while (displaynames[j]) j++; 6627 ctx->ndisplayvariables = j; 6628 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr); 6629 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr); 6630 j = 0; 6631 while (displaynames[j]) { 6632 k = 0; 6633 while (ctx->names[k]) { 6634 PetscBool flg; 6635 ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr); 6636 if (flg) { 6637 ctx->displayvariables[j] = k; 6638 break; 6639 } 6640 k++; 6641 } 6642 j++; 6643 } 6644 PetscFunctionReturn(0); 6645 } 6646 6647 /*@C 6648 TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor 6649 6650 Collective on TS 6651 6652 Input Parameters: 6653 + ts - the TS context 6654 . displaynames - the names of the components, final string must be NULL 6655 6656 Notes: 6657 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6658 6659 Level: intermediate 6660 6661 .keywords: TS, vector, monitor, view 6662 6663 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 6664 @*/ 6665 PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames) 6666 { 6667 PetscInt i; 6668 PetscErrorCode ierr; 6669 6670 PetscFunctionBegin; 6671 for (i=0; i<ts->numbermonitors; i++) { 6672 if (ts->monitor[i] == TSMonitorLGSolution) { 6673 ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr); 6674 break; 6675 } 6676 } 6677 PetscFunctionReturn(0); 6678 } 6679 6680 /*@C 6681 TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed 6682 6683 Collective on TS 6684 6685 Input Parameters: 6686 + ts - the TS context 6687 . transform - the transform function 6688 . destroy - function to destroy the optional context 6689 - ctx - optional context used by transform function 6690 6691 Notes: 6692 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6693 6694 Level: intermediate 6695 6696 .keywords: TS, vector, monitor, view 6697 6698 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform() 6699 @*/ 6700 PetscErrorCode TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 6701 { 6702 PetscInt i; 6703 PetscErrorCode ierr; 6704 6705 PetscFunctionBegin; 6706 for (i=0; i<ts->numbermonitors; i++) { 6707 if (ts->monitor[i] == TSMonitorLGSolution) { 6708 ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr); 6709 } 6710 } 6711 PetscFunctionReturn(0); 6712 } 6713 6714 /*@C 6715 TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed 6716 6717 Collective on TSLGCtx 6718 6719 Input Parameters: 6720 + ts - the TS context 6721 . transform - the transform function 6722 . destroy - function to destroy the optional context 6723 - ctx - optional context used by transform function 6724 6725 Level: intermediate 6726 6727 .keywords: TS, vector, monitor, view 6728 6729 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform() 6730 @*/ 6731 PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 6732 { 6733 PetscFunctionBegin; 6734 ctx->transform = transform; 6735 ctx->transformdestroy = destroy; 6736 ctx->transformctx = tctx; 6737 PetscFunctionReturn(0); 6738 } 6739 6740 /*@C 6741 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error 6742 in a time based line graph 6743 6744 Collective on TS 6745 6746 Input Parameters: 6747 + ts - the TS context 6748 . step - current time-step 6749 . ptime - current time 6750 . u - current solution 6751 - dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate() 6752 6753 Level: intermediate 6754 6755 Notes: 6756 Each process in a parallel run displays its component errors in a separate window 6757 6758 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 6759 6760 Options Database Keys: 6761 . -ts_monitor_lg_error - create a graphical monitor of error history 6762 6763 .keywords: TS, vector, monitor, view 6764 6765 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 6766 @*/ 6767 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 6768 { 6769 PetscErrorCode ierr; 6770 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 6771 const PetscScalar *yy; 6772 Vec y; 6773 6774 PetscFunctionBegin; 6775 if (!step) { 6776 PetscDrawAxis axis; 6777 PetscInt dim; 6778 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6779 ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error");CHKERRQ(ierr); 6780 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6781 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6782 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6783 } 6784 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 6785 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 6786 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 6787 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 6788 #if defined(PETSC_USE_COMPLEX) 6789 { 6790 PetscReal *yreal; 6791 PetscInt i,n; 6792 ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); 6793 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6794 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6795 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6796 ierr = PetscFree(yreal);CHKERRQ(ierr); 6797 } 6798 #else 6799 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6800 #endif 6801 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 6802 ierr = VecDestroy(&y);CHKERRQ(ierr); 6803 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6804 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6805 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6806 } 6807 PetscFunctionReturn(0); 6808 } 6809 6810 /*@C 6811 TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep 6812 6813 Collective on TS 6814 6815 Input Parameters: 6816 + ts - the TS context 6817 . step - current time-step 6818 . ptime - current time 6819 . u - current solution 6820 - dctx - unused context 6821 6822 Level: intermediate 6823 6824 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 6825 6826 Options Database Keys: 6827 . -ts_monitor_error - create a graphical monitor of error history 6828 6829 .keywords: TS, vector, monitor, view 6830 6831 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 6832 @*/ 6833 PetscErrorCode TSMonitorError(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 6834 { 6835 PetscErrorCode ierr; 6836 Vec y; 6837 PetscReal nrm; 6838 PetscBool flg; 6839 6840 PetscFunctionBegin; 6841 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 6842 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 6843 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 6844 ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERASCII,&flg);CHKERRQ(ierr); 6845 if (flg) { 6846 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 6847 ierr = PetscViewerASCIIPrintf(vf->viewer,"2-norm of error %g\n",(double)nrm);CHKERRQ(ierr); 6848 } 6849 ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERDRAW,&flg);CHKERRQ(ierr); 6850 if (flg) { 6851 ierr = VecView(y,vf->viewer);CHKERRQ(ierr); 6852 } 6853 ierr = VecDestroy(&y);CHKERRQ(ierr); 6854 PetscFunctionReturn(0); 6855 } 6856 6857 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 6858 { 6859 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 6860 PetscReal x = ptime,y; 6861 PetscErrorCode ierr; 6862 PetscInt its; 6863 6864 PetscFunctionBegin; 6865 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6866 if (!n) { 6867 PetscDrawAxis axis; 6868 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6869 ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr); 6870 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6871 ctx->snes_its = 0; 6872 } 6873 ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr); 6874 y = its - ctx->snes_its; 6875 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 6876 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 6877 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6878 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6879 } 6880 ctx->snes_its = its; 6881 PetscFunctionReturn(0); 6882 } 6883 6884 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 6885 { 6886 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 6887 PetscReal x = ptime,y; 6888 PetscErrorCode ierr; 6889 PetscInt its; 6890 6891 PetscFunctionBegin; 6892 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6893 if (!n) { 6894 PetscDrawAxis axis; 6895 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6896 ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr); 6897 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6898 ctx->ksp_its = 0; 6899 } 6900 ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr); 6901 y = its - ctx->ksp_its; 6902 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 6903 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 6904 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6905 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6906 } 6907 ctx->ksp_its = its; 6908 PetscFunctionReturn(0); 6909 } 6910 6911 /*@ 6912 TSComputeLinearStability - computes the linear stability function at a point 6913 6914 Collective on TS and Vec 6915 6916 Input Parameters: 6917 + ts - the TS context 6918 - xr,xi - real and imaginary part of input arguments 6919 6920 Output Parameters: 6921 . yr,yi - real and imaginary part of function value 6922 6923 Level: developer 6924 6925 .keywords: TS, compute 6926 6927 .seealso: TSSetRHSFunction(), TSComputeIFunction() 6928 @*/ 6929 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi) 6930 { 6931 PetscErrorCode ierr; 6932 6933 PetscFunctionBegin; 6934 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6935 if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method"); 6936 ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr); 6937 PetscFunctionReturn(0); 6938 } 6939 6940 /* ------------------------------------------------------------------------*/ 6941 /*@C 6942 TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope() 6943 6944 Collective on TS 6945 6946 Input Parameters: 6947 . ts - the ODE solver object 6948 6949 Output Parameter: 6950 . ctx - the context 6951 6952 Level: intermediate 6953 6954 .keywords: TS, monitor, line graph, residual, seealso 6955 6956 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 6957 6958 @*/ 6959 PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx) 6960 { 6961 PetscErrorCode ierr; 6962 6963 PetscFunctionBegin; 6964 ierr = PetscNew(ctx);CHKERRQ(ierr); 6965 PetscFunctionReturn(0); 6966 } 6967 6968 /*@C 6969 TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution 6970 6971 Collective on TS 6972 6973 Input Parameters: 6974 + ts - the TS context 6975 . step - current time-step 6976 . ptime - current time 6977 . u - current solution 6978 - dctx - the envelope context 6979 6980 Options Database: 6981 . -ts_monitor_envelope 6982 6983 Level: intermediate 6984 6985 Notes: 6986 after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope 6987 6988 .keywords: TS, vector, monitor, view 6989 6990 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate() 6991 @*/ 6992 PetscErrorCode TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 6993 { 6994 PetscErrorCode ierr; 6995 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx; 6996 6997 PetscFunctionBegin; 6998 if (!ctx->max) { 6999 ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr); 7000 ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr); 7001 ierr = VecCopy(u,ctx->max);CHKERRQ(ierr); 7002 ierr = VecCopy(u,ctx->min);CHKERRQ(ierr); 7003 } else { 7004 ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr); 7005 ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr); 7006 } 7007 PetscFunctionReturn(0); 7008 } 7009 7010 /*@C 7011 TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution 7012 7013 Collective on TS 7014 7015 Input Parameter: 7016 . ts - the TS context 7017 7018 Output Parameter: 7019 + max - the maximum values 7020 - min - the minimum values 7021 7022 Notes: 7023 If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored 7024 7025 Level: intermediate 7026 7027 .keywords: TS, vector, monitor, view 7028 7029 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 7030 @*/ 7031 PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min) 7032 { 7033 PetscInt i; 7034 7035 PetscFunctionBegin; 7036 if (max) *max = NULL; 7037 if (min) *min = NULL; 7038 for (i=0; i<ts->numbermonitors; i++) { 7039 if (ts->monitor[i] == TSMonitorEnvelope) { 7040 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i]; 7041 if (max) *max = ctx->max; 7042 if (min) *min = ctx->min; 7043 break; 7044 } 7045 } 7046 PetscFunctionReturn(0); 7047 } 7048 7049 /*@C 7050 TSMonitorEnvelopeCtxDestroy - Destroys a context that was created with TSMonitorEnvelopeCtxCreate(). 7051 7052 Collective on TSMonitorEnvelopeCtx 7053 7054 Input Parameter: 7055 . ctx - the monitor context 7056 7057 Level: intermediate 7058 7059 .keywords: TS, monitor, line graph, destroy 7060 7061 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep() 7062 @*/ 7063 PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx) 7064 { 7065 PetscErrorCode ierr; 7066 7067 PetscFunctionBegin; 7068 ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr); 7069 ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr); 7070 ierr = PetscFree(*ctx);CHKERRQ(ierr); 7071 PetscFunctionReturn(0); 7072 } 7073 7074 /*@ 7075 TSRestartStep - Flags the solver to restart the next step 7076 7077 Collective on TS 7078 7079 Input Parameter: 7080 . ts - the TS context obtained from TSCreate() 7081 7082 Level: advanced 7083 7084 Notes: 7085 Multistep methods like BDF or Runge-Kutta methods with FSAL property require restarting the solver in the event of 7086 discontinuities. These discontinuities may be introduced as a consequence of explicitly modifications to the solution 7087 vector (which PETSc attempts to detect and handle) or problem coefficients (which PETSc is not able to detect). For 7088 the sake of correctness and maximum safety, users are expected to call TSRestart() whenever they introduce 7089 discontinuities in callback routines (e.g. prestep and poststep routines, or implicit/rhs function routines with 7090 discontinuous source terms). 7091 7092 .keywords: TS, timestep, restart 7093 7094 .seealso: TSSolve(), TSSetPreStep(), TSSetPostStep() 7095 @*/ 7096 PetscErrorCode TSRestartStep(TS ts) 7097 { 7098 PetscFunctionBegin; 7099 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7100 ts->steprestart = PETSC_TRUE; 7101 PetscFunctionReturn(0); 7102 } 7103 7104 /*@ 7105 TSRollBack - Rolls back one time step 7106 7107 Collective on TS 7108 7109 Input Parameter: 7110 . ts - the TS context obtained from TSCreate() 7111 7112 Level: advanced 7113 7114 .keywords: TS, timestep, rollback 7115 7116 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate() 7117 @*/ 7118 PetscErrorCode TSRollBack(TS ts) 7119 { 7120 PetscErrorCode ierr; 7121 7122 PetscFunctionBegin; 7123 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7124 if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called"); 7125 if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name); 7126 ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr); 7127 ts->time_step = ts->ptime - ts->ptime_prev; 7128 ts->ptime = ts->ptime_prev; 7129 ts->ptime_prev = ts->ptime_prev_rollback; 7130 ts->steps--; 7131 ts->steprollback = PETSC_TRUE; 7132 PetscFunctionReturn(0); 7133 } 7134 7135 /*@ 7136 TSGetStages - Get the number of stages and stage values 7137 7138 Input Parameter: 7139 . ts - the TS context obtained from TSCreate() 7140 7141 Level: advanced 7142 7143 .keywords: TS, getstages 7144 7145 .seealso: TSCreate() 7146 @*/ 7147 PetscErrorCode TSGetStages(TS ts,PetscInt *ns,Vec **Y) 7148 { 7149 PetscErrorCode ierr; 7150 7151 PetscFunctionBegin; 7152 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7153 PetscValidPointer(ns,2); 7154 7155 if (!ts->ops->getstages) *ns=0; 7156 else { 7157 ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr); 7158 } 7159 PetscFunctionReturn(0); 7160 } 7161 7162 /*@C 7163 TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity. 7164 7165 Collective on SNES 7166 7167 Input Parameters: 7168 + ts - the TS context 7169 . t - current timestep 7170 . U - state vector 7171 . Udot - time derivative of state vector 7172 . shift - shift to apply, see note below 7173 - ctx - an optional user context 7174 7175 Output Parameters: 7176 + J - Jacobian matrix (not altered in this routine) 7177 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 7178 7179 Level: intermediate 7180 7181 Notes: 7182 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 7183 7184 dF/dU + shift*dF/dUdot 7185 7186 Most users should not need to explicitly call this routine, as it 7187 is used internally within the nonlinear solvers. 7188 7189 This will first try to get the coloring from the DM. If the DM type has no coloring 7190 routine, then it will try to get the coloring from the matrix. This requires that the 7191 matrix have nonzero entries precomputed. 7192 7193 .keywords: TS, finite differences, Jacobian, coloring, sparse 7194 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction() 7195 @*/ 7196 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx) 7197 { 7198 SNES snes; 7199 MatFDColoring color; 7200 PetscBool hascolor, matcolor = PETSC_FALSE; 7201 PetscErrorCode ierr; 7202 7203 PetscFunctionBegin; 7204 ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr); 7205 ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr); 7206 if (!color) { 7207 DM dm; 7208 ISColoring iscoloring; 7209 7210 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 7211 ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr); 7212 if (hascolor && !matcolor) { 7213 ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr); 7214 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7215 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7216 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7217 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7218 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7219 } else { 7220 MatColoring mc; 7221 7222 ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr); 7223 ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr); 7224 ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr); 7225 ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 7226 ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr); 7227 ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 7228 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7229 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7230 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7231 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7232 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7233 } 7234 ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr); 7235 ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr); 7236 } 7237 ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr); 7238 ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr); 7239 if (J != B) { 7240 ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7241 ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7242 } 7243 PetscFunctionReturn(0); 7244 } 7245 7246 /*@ 7247 TSSetFunctionDomainError - Set the function testing if the current state vector is valid 7248 7249 Input Parameters: 7250 ts - the TS context 7251 func - function called within TSFunctionDomainError 7252 7253 Level: intermediate 7254 7255 .keywords: TS, state, domain 7256 .seealso: TSAdaptCheckStage(), TSFunctionDomainError() 7257 @*/ 7258 7259 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*)) 7260 { 7261 PetscFunctionBegin; 7262 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7263 ts->functiondomainerror = func; 7264 PetscFunctionReturn(0); 7265 } 7266 7267 /*@ 7268 TSFunctionDomainError - Check if the current state is valid 7269 7270 Input Parameters: 7271 ts - the TS context 7272 stagetime - time of the simulation 7273 Y - state vector to check. 7274 7275 Output Parameter: 7276 accept - Set to PETSC_FALSE if the current state vector is valid. 7277 7278 Note: 7279 This function should be used to ensure the state is in a valid part of the space. 7280 For example, one can ensure here all values are positive. 7281 7282 Level: advanced 7283 @*/ 7284 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept) 7285 { 7286 PetscErrorCode ierr; 7287 7288 PetscFunctionBegin; 7289 7290 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7291 *accept = PETSC_TRUE; 7292 if (ts->functiondomainerror) { 7293 PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept)); 7294 } 7295 PetscFunctionReturn(0); 7296 } 7297 7298 /*@C 7299 TSClone - This function clones a time step object. 7300 7301 Collective on MPI_Comm 7302 7303 Input Parameter: 7304 . tsin - The input TS 7305 7306 Output Parameter: 7307 . tsout - The output TS (cloned) 7308 7309 Notes: 7310 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. 7311 7312 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); 7313 7314 Level: developer 7315 7316 .keywords: TS, clone 7317 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType() 7318 @*/ 7319 PetscErrorCode TSClone(TS tsin, TS *tsout) 7320 { 7321 TS t; 7322 PetscErrorCode ierr; 7323 SNES snes_start; 7324 DM dm; 7325 TSType type; 7326 7327 PetscFunctionBegin; 7328 PetscValidPointer(tsin,1); 7329 *tsout = NULL; 7330 7331 ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr); 7332 7333 /* General TS description */ 7334 t->numbermonitors = 0; 7335 t->setupcalled = 0; 7336 t->ksp_its = 0; 7337 t->snes_its = 0; 7338 t->nwork = 0; 7339 t->rhsjacobian.time = -1e20; 7340 t->rhsjacobian.scale = 1.; 7341 t->ijacobian.shift = 1.; 7342 7343 ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr); 7344 ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr); 7345 7346 ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr); 7347 ierr = TSSetDM(t,dm);CHKERRQ(ierr); 7348 7349 t->adapt = tsin->adapt; 7350 ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr); 7351 7352 t->trajectory = tsin->trajectory; 7353 ierr = PetscObjectReference((PetscObject)t->trajectory);CHKERRQ(ierr); 7354 7355 t->event = tsin->event; 7356 if (t->event) t->event->refct++; 7357 7358 t->problem_type = tsin->problem_type; 7359 t->ptime = tsin->ptime; 7360 t->ptime_prev = tsin->ptime_prev; 7361 t->time_step = tsin->time_step; 7362 t->max_time = tsin->max_time; 7363 t->steps = tsin->steps; 7364 t->max_steps = tsin->max_steps; 7365 t->equation_type = tsin->equation_type; 7366 t->atol = tsin->atol; 7367 t->rtol = tsin->rtol; 7368 t->max_snes_failures = tsin->max_snes_failures; 7369 t->max_reject = tsin->max_reject; 7370 t->errorifstepfailed = tsin->errorifstepfailed; 7371 7372 ierr = TSGetType(tsin,&type);CHKERRQ(ierr); 7373 ierr = TSSetType(t,type);CHKERRQ(ierr); 7374 7375 t->vec_sol = NULL; 7376 7377 t->cfltime = tsin->cfltime; 7378 t->cfltime_local = tsin->cfltime_local; 7379 t->exact_final_time = tsin->exact_final_time; 7380 7381 ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr); 7382 7383 if (((PetscObject)tsin)->fortran_func_pointers) { 7384 PetscInt i; 7385 ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr); 7386 for (i=0; i<10; i++) { 7387 ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i]; 7388 } 7389 } 7390 *tsout = t; 7391 PetscFunctionReturn(0); 7392 } 7393 7394 static PetscErrorCode RHSWrapperFunction_TSRHSJacobianTest(void* ctx,Vec x,Vec y) 7395 { 7396 PetscErrorCode ierr; 7397 TS ts = (TS) ctx; 7398 7399 PetscFunctionBegin; 7400 ierr = TSComputeRHSFunction(ts,0,x,y);CHKERRQ(ierr); 7401 PetscFunctionReturn(0); 7402 } 7403 7404 /*@ 7405 TSRHSJacobianTest - Compares the multiply routine provided to the MATSHELL with differencing on the TS given RHS function. 7406 7407 Logically Collective on TS and Mat 7408 7409 Input Parameters: 7410 TS - the time stepping routine 7411 7412 Output Parameter: 7413 . flg - PETSC_TRUE if the multiply is likely correct 7414 7415 Options Database: 7416 . -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - run the test at each timestep of the integrator 7417 7418 Level: advanced 7419 7420 Notes: 7421 This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian 7422 7423 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTestTranspose() 7424 @*/ 7425 PetscErrorCode TSRHSJacobianTest(TS ts,PetscBool *flg) 7426 { 7427 Mat J,B; 7428 PetscErrorCode ierr; 7429 TSRHSJacobian func; 7430 void* ctx; 7431 7432 PetscFunctionBegin; 7433 ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr); 7434 ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr); 7435 ierr = MatShellTestMult(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr); 7436 PetscFunctionReturn(0); 7437 } 7438 7439 /*@C 7440 TSRHSJacobianTestTranspose - Compares the multiply transpose routine provided to the MATSHELL with differencing on the TS given RHS function. 7441 7442 Logically Collective on TS and Mat 7443 7444 Input Parameters: 7445 TS - the time stepping routine 7446 7447 Output Parameter: 7448 . flg - PETSC_TRUE if the multiply is likely correct 7449 7450 Options Database: 7451 . -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - run the test at each timestep of the integrator 7452 7453 Notes: 7454 This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian 7455 7456 Level: advanced 7457 7458 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTest() 7459 @*/ 7460 PetscErrorCode TSRHSJacobianTestTranspose(TS ts,PetscBool *flg) 7461 { 7462 Mat J,B; 7463 PetscErrorCode ierr; 7464 void *ctx; 7465 TSRHSJacobian func; 7466 7467 PetscFunctionBegin; 7468 ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr); 7469 ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr); 7470 ierr = MatShellTestMultTranspose(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr); 7471 PetscFunctionReturn(0); 7472 } 7473