HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
PetscPostTimeStep.cpp
Go to the documentation of this file.
1 
6 #ifdef with_petsc
7 
8 #include <stdio.h>
9 #include <basic.h>
10 #include <arrayfunctions.h>
11 #include <mpivars_cpp.h>
12 #include <simulation_object.h>
13 #include <petscinterface.h>
14 
15 int OutputSolution (void*,int,double);
17 #undef __FUNCT__
18 #define __FUNCT__ "PetscPostTimeStep"
19 
21 PetscErrorCode PetscPostTimeStep(TS ts )
22 {
23  PETScContext* context(nullptr);
24 
25  PetscFunctionBegin;
26 
27  TSGetApplicationContext(ts,&context);
28  if (!context) {
29  fprintf(stderr,"Error in PetscPreTimeStep: Null context!\n");
30  return(1);
31  }
32  SimulationObject* sim = (SimulationObject*) context->simobj;
33  int nsims = context->nsims;
34 
35  Vec Y;
36  TSGetSolution(ts,&Y);
37 
38  double waqt;
39  TSGetTime(ts,&waqt);
40  int iter;
41  TSGetStepNumber(ts,&iter);
42  double dt;
43  TSGetTimeStep(ts,&dt);
44 
45  context->tic++;
46 
47  double max_cfl = 0.0;
48  double total_norm = 0.0;
49  for (int ns = 0; ns < nsims; ns++) {
50 
51  HyPar* solver = &(sim[ns].solver);
52  MPIVariables* mpi = &(sim[ns].mpi);
53 
54  /* get solution */
55  TransferVecFromPETSc(solver->u,Y,context,ns,context->offsets[ns]);
56 
57  /* Call any physics-specific post-step function */
58  if (solver->PostStep) solver->PostStep(solver->u,solver,mpi,waqt,iter);
59 
60  /* Calculate CFL and diffusion number */
61  double local_max_cfl = -1.0, global_max_cfl = -1.0;
62  if (solver->ComputeCFL) local_max_cfl = solver->ComputeCFL(solver,mpi,dt,waqt);
63  MPIMax_double(&global_max_cfl ,&local_max_cfl ,1,&mpi->world);
64  if (global_max_cfl > max_cfl) max_cfl = global_max_cfl;
65 
66  /* Calculate norm of the change in the solution for this time step */
67  _ArrayAXPY_(solver->u,-1.0,solver->u0,(solver->npoints_local_wghosts*solver->nvars));
68  double sum = ArraySumSquarenD(solver->nvars,solver->ndims,solver->dim_local,
69  solver->ghosts,solver->index,solver->u0);
70  double global_sum = 0; MPISum_double(&global_sum,&sum,1,&mpi->world);
71  double norm = sqrt((global_sum/(double)solver->npoints_global));
72  total_norm += norm;
73 
74  if (!strcmp(solver->ConservationCheck,"yes")) {
75  /* calculate volume integral of the solution at this time step */
76  solver->VolumeIntegralFunction(solver->VolumeIntegral,solver->u,solver,mpi);
77  /* calculate surface integral of the flux at this time step */
78  solver->BoundaryIntegralFunction(solver,mpi);
79  /* calculate the conservation error at this time step */
80  solver->CalculateConservationError(solver,mpi);
81  }
82 
83  }
84 
85  gettimeofday(&context->iter_end_time,NULL);
86  long long walltime;
87  walltime = ( (context->iter_end_time.tv_sec * 1000000 + context->iter_end_time.tv_usec)
88  - (context->iter_start_time.tv_sec * 1000000 + context->iter_start_time.tv_usec));
89  context->iter_wctime = (double) walltime / 1000000.0;
90  context->ti_runtime += context->iter_wctime;
91 
92  if ((!context->rank) && (iter%sim[0].solver.screen_op_iter == 0)) {
93 
94  if (nsims > 1) {
95  printf("--\n");
96  printf("iter=%7d, t=%1.3e\n", iter, waqt);
97  printf(" dt=%1.3E ", dt);
98  printf(" CFL=%1.3E, ", max_cfl);
99  printf(" norm=%1.4E\n", total_norm);
100  printf(" wctime=%1.1E (s)\n",context->iter_wctime);
101  } else {
102  printf("iter=%7d ", iter);
103  printf("dt=%1.3E ", dt);
104  printf("t=%1.3E ", waqt);
105  printf("CFL=%1.3E ", max_cfl );
106  printf("norm=%1.4E ", total_norm);
107  printf("wctime: %1.1E (s) ",context->iter_wctime);
108  }
109 
110  /* calculate and print conservation error */
111  if (!strcmp(sim[0].solver.ConservationCheck,"yes")) {
112 
113  double error = 0;
114  for (int ns = 0; ns < nsims; ns++) {
115  for (int v=0; v<sim[ns].solver.nvars; v++) {
116  error += (sim[ns].solver.ConservationError[v] * sim[ns].solver.ConservationError[v]);
117  }
118  }
119  error = sqrt(error);
120  printf(" cons_err=%1.4E\n", error);
121 
122  } else {
123 
124  if (nsims == 1) printf("\n");
125 
126  }
127 
128  /* print physics-specific info, if available */
129  for( int ns = 0; ns < nsims; ns++) {
130  if (sim[ns].solver.PrintStep) {
131  if (nsims > 1) printf("Physics-specific output for domain %d:\n", ns);
132  sim[ns].solver.PrintStep( &(sim[ns].solver),
133  &(sim[ns].mpi),
134  waqt );
135  }
136  }
137 
138  if (nsims > 1) {
139  printf("--\n");
140  printf("\n");
141  }
142 
143  }
144 
145  /* Write intermediate solution to file */
146  if (iter%sim[0].solver.file_op_iter == 0) {
147  for (int ns = 0; ns < nsims; ns++) {
148  HyPar* solver = &(sim[ns].solver);
149  MPIVariables* mpi = &(sim[ns].mpi);
150  if (solver->PhysicsOutput) solver->PhysicsOutput(solver,mpi,waqt);
151  }
152  OutputSolution(sim,nsims,waqt);
153 #ifdef with_librom
154  context->op_times_arr.push_back(waqt);
155 #endif
156  context->tic=0;
157  }
158 
159  PetscFunctionReturn(0);
160 }
161 
162 #endif
int(* PrintStep)(void *, void *, double)
Definition: hypar.h:344
int(* PhysicsOutput)(void *, void *, double)
Definition: hypar.h:347
int nvars
Definition: hypar.h:29
Structure defining a simulation.
C++ declarations for MPI-related functions.
int MPISum_double(double *, double *, int, void *)
Definition: MPISum.c:39
long sum(const std::vector< int > &a_iv)
Definition: std_vec_ops.h:18
double * u
Definition: hypar.h:116
Some basic definitions and macros.
double * ConservationError
Definition: hypar.h:374
Simulation object.
int(* CalculateConservationError)(void *, void *)
Definition: hypar.h:392
double * u0
Definition: hypar.h:396
int ndims
Definition: hypar.h:26
struct timeval iter_start_time
struct timeval iter_end_time
int(* VolumeIntegralFunction)(double *, double *, void *, void *)
Definition: hypar.h:388
double(* ComputeCFL)(void *, void *, double, double)
Definition: hypar.h:269
Structure containing all solver-specific variables and functions.
Definition: hypar.h:23
char ConservationCheck[_MAX_STRING_SIZE_]
Definition: hypar.h:376
int MPIMax_double(double *, double *, int, void *)
Definition: MPIMax.c:38
#define _ArrayAXPY_(x, a, y, size)
int(* BoundaryIntegralFunction)(void *, void *)
Definition: hypar.h:390
int npoints_global
Definition: hypar.h:40
MPI_Comm world
std::vector< double > op_times_arr
int * index
Definition: hypar.h:102
int OutputSolution(void *, int, double)
Structure containing the variables for time-integration with PETSc.
int * dim_local
Definition: hypar.h:37
int(* PostStep)(double *, void *, void *, double, int)
Definition: hypar.h:341
int ghosts
Definition: hypar.h:52
Structure of MPI-related variables.
int npoints_local_wghosts
Definition: hypar.h:42
INLINE double ArraySumSquarenD(int, int, int *, int, int *, double *)
Contains macros and function definitions for common array operations.
double * VolumeIntegral
Definition: hypar.h:378
int TransferVecFromPETSc(double *const, const Vec, void *, const int, const int)
int screen_op_iter
Definition: hypar.h:168
PetscErrorCode PetscPostTimeStep(TS ts)