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