HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
PetscError.cpp
Go to the documentation of this file.
1 #ifdef with_petsc
2 
8 #include <math.h>
9 #include <string>
10 #include <arrayfunctions.h>
11 #include <mpivars_cpp.h>
12 #include <simulation_object.h>
13 #include <petscinterface.h>
14 
15 #undef __FUNCT__
16 #define __FUNCT__ "PetscTimeError"
17 
20 int PetscTimeError(TS ts )
21 {
22  PetscErrorCode ierr;
23 
24  PETScContext* context(nullptr);
25  ierr = TSGetApplicationContext(ts,&context); CHKERRQ(ierr);
26  if (!context) {
27  fprintf(stderr,"Error in PetscError: Null context!\n");
28  return(1);
29  }
30 
31  SimulationObject* sim( (SimulationObject*)context->simobj );
32  int nsims( context->nsims );
33 
34  double dt;
35  ierr = TSGetTimeStep(ts,&dt); CHKERRQ(ierr);
36  TSType time_scheme;
37  ierr = TSGetType(ts,&time_scheme); CHKERRQ(ierr);
38  Vec Y;
39  ierr = TSGetSolution(ts,&Y); CHKERRQ(ierr);
40 
41  for (int ns = 0; ns < nsims; ns++) {
42  TransferVecFromPETSc( sim[ns].solver.u,
43  Y,
44  context,
45  ns,
46  context->offsets[ns] );
47  }
48 
49  if (std::string(time_scheme) == std::string(TSGLEE)) {
50 
51  Vec Z;
52  ierr = VecDuplicate(Y,&Z); CHKERRQ(ierr);
53  ierr = TSGetTimeError(ts,0,&Z);CHKERRQ(ierr);
54  for (int ns = 0; ns < nsims; ns++) {
55  TransferVecFromPETSc( sim[ns].solver.uref,
56  Z,
57  context,
58  ns,
59  context->offsets[ns] );
60  }
61  ierr = VecDestroy(&Z); CHKERRQ(ierr);
62 
63  for (int ns = 0; ns < nsims; ns++) {
64 
65  HyPar* solver = &(sim[ns].solver);
66  MPIVariables* mpi = &(sim[ns].mpi);
67 
68  int size = solver->npoints_local_wghosts * solver->nvars;
69  double sum = 0.0,
70  global_sum = 0.0,
71  *Uerr = solver->uref,
72  error[3] = {0,0,0};
73 
74  /* calculate solution norm for relative errors */
75  double sol_norm[3] = {0.0,0.0,0.0};
76  /* L1 */
77  sum = ArraySumAbsnD (solver->nvars,solver->ndims,solver->dim_local,
78  solver->ghosts,solver->index,solver->u);
79  global_sum = 0; MPISum_double(&global_sum,&sum,1,&mpi->world);
80  sol_norm[0] = global_sum/((double)solver->npoints_global);
81  /* L2 */
82  sum = ArraySumSquarenD(solver->nvars,solver->ndims,solver->dim_local,
83  solver->ghosts,solver->index,solver->u);
84  global_sum = 0; MPISum_double(&global_sum,&sum,1,&mpi->world);
85  sol_norm[1] = sqrt(global_sum/((double)solver->npoints_global));
86  /* Linf */
87  sum = ArrayMaxnD (solver->nvars,solver->ndims,solver->dim_local,
88  solver->ghosts,solver->index,solver->u);
89  global_sum = 0; MPIMax_double(&global_sum,&sum,1,&mpi->world);
90  sol_norm[2] = global_sum;
91 
92  /* calculate L1 norm of error */
93  sum = ArraySumAbsnD (solver->nvars,solver->ndims,solver->dim_local,
94  solver->ghosts,solver->index,Uerr);
95  global_sum = 0; MPISum_double(&global_sum,&sum,1,&mpi->world);
96  error[0] = global_sum/((double)solver->npoints_global);
97  /* calculate L2 norm of error */
98  sum = ArraySumSquarenD(solver->nvars,solver->ndims,solver->dim_local,
99  solver->ghosts,solver->index,Uerr);
100  global_sum = 0; MPISum_double(&global_sum,&sum,1,&mpi->world);
101  error[1] = sqrt(global_sum/((double)solver->npoints_global));
102  /* calculate Linf norm of error */
103  sum = ArrayMaxnD (solver->nvars,solver->ndims,solver->dim_local,
104  solver->ghosts,solver->index,Uerr);
105  global_sum = 0; MPIMax_double(&global_sum,&sum,1,&mpi->world);
106  error[2] = global_sum;
107 
108  if ( (sol_norm[0] > _MACHINE_ZERO_)
109  && (sol_norm[1] > _MACHINE_ZERO_)
110  && (sol_norm[2] > _MACHINE_ZERO_) ) {
111  error[0] /= sol_norm[0];
112  error[1] /= sol_norm[1];
113  error[2] /= sol_norm[2];
114  }
115 
116  /* write to file */
117  if (!mpi->rank) {
118  std::string fname = "glm_err";
119  if (nsims > 1) {
120  char idx_string[10];
121  sprintf(idx_string, "%3d", ns);
122  fname += ("_" + std::string(idx_string));
123  }
124  fname += ".dat";
125 
126  FILE *out;
127  out = fopen(fname.c_str(),"w");
128  fprintf(out,"%1.16E %1.16E %1.16E %1.16E ",dt,error[0],error[1],error[2]);
129  fclose(out);
130  if (nsims > 1) {
131  printf( "Estimated time integration errors (GLM-GEE time-integration) for simulation domain %d:-\n",
132  ns);
133  } else {
134  printf("Estimated time integration errors (GLM-GEE time-integration):-\n");
135  }
136  printf(" L1 Error : %1.16E\n",error[0]);
137  printf(" L2 Error : %1.16E\n",error[1]);
138  printf(" Linfinity Error : %1.16E\n",error[2]);
139  }
140  }
141  }
142 
143  return 0;
144 }
145 
146 #endif
int PetscTimeError(TS ts)
Definition: PetscError.cpp:20
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
#define _MACHINE_ZERO_
Definition: basic.h:26
long sum(const std::vector< int > &a_iv)
Definition: std_vec_ops.h:18
double * u
Definition: hypar.h:116
Simulation object.
int ndims
Definition: hypar.h:26
INLINE double ArraySumAbsnD(int, int, int *, int, int *, double *)
Structure containing all solver-specific variables and functions.
Definition: hypar.h:23
int MPIMax_double(double *, double *, int, void *)
Definition: MPIMax.c:38
int npoints_global
Definition: hypar.h:40
MPI_Comm world
int * index
Definition: hypar.h:102
Structure containing the variables for time-integration with PETSc.
int * dim_local
Definition: hypar.h:37
INLINE double ArrayMaxnD(int, int, int *, int, int *, double *)
int ghosts
Definition: hypar.h:52
Structure of MPI-related variables.
int npoints_local_wghosts
Definition: hypar.h:42
double * uref
Definition: hypar.h:397
INLINE double ArraySumSquarenD(int, int, int *, int, int *, double *)
Contains macros and function definitions for common array operations.
int TransferVecFromPETSc(double *const, const Vec, void *, const int, const int)