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