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