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