HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
PetscPostTimeStep.cpp File Reference

Post-time-step function. More...

#include <stdio.h>
#include <basic.h>
#include <arrayfunctions.h>
#include <mpivars_cpp.h>
#include <simulation_object.h>
#include <petscinterface.h>

Go to the source code of this file.

Macros

#define __FUNCT__   "PetscPostTimeStep"
 

Functions

int OutputSolution (void *, int, double)
 
PetscErrorCode PetscPostTimeStep (TS ts)
 

Detailed Description

Post-time-step function.

Author
Debojyoti Ghosh

Definition in file PetscPostTimeStep.cpp.

Macro Definition Documentation

◆ __FUNCT__

#define __FUNCT__   "PetscPostTimeStep"

Definition at line 18 of file PetscPostTimeStep.cpp.

Function Documentation

◆ OutputSolution()

int OutputSolution ( void *  s,
int  nsims,
double  a_time 
)

Write solutions to file

Write out the solution to file

Parameters
sArray of simulation objects of type SimulationObject
nsimsNumber of simulation objects
a_timeCurrent simulation time

Definition at line 27 of file OutputSolution.cpp.

30 {
31  SimulationObject* simobj = (SimulationObject*) s;
32  int ns;
34 
35  for (ns = 0; ns < nsims; ns++) {
36 
37  HyPar* solver = &(simobj[ns].solver);
38  MPIVariables* mpi = &(simobj[ns].mpi);
39 
40  if ((!solver->WriteOutput) && (strcmp(solver->plot_solution,"yes"))) continue;
41 
42  /* time integration module may have auxiliary arrays to write out, so get them */
43  int NSolutions = 0;
44  IERR TimeGetAuxSolutions(&NSolutions,NULL,solver,-1,ns); CHECKERR(ierr);
45  if (NSolutions > 10) NSolutions = 10;
46 
47  int nu;
48  char fname_root[_MAX_STRING_SIZE_];
49  char aux_fname_root[_MAX_STRING_SIZE_];
50  strcpy(fname_root, solver->op_fname_root);
51  strcpy(aux_fname_root, solver->aux_op_fname_root);
52 
53  if (nsims > 1) {
54  char index[_MAX_STRING_SIZE_];
55  GetStringFromInteger(ns, index, (int)log10(nsims)+1);
56  strcat(fname_root, "_");
57  strcat(fname_root, index);
58  strcat(aux_fname_root, "_");
59  strcat(aux_fname_root, index);
60  }
61 
62  for (nu=0; nu<NSolutions; nu++) {
63 
64  double *uaux = NULL;
65  IERR TimeGetAuxSolutions(&NSolutions,&uaux,solver,nu,ns); CHECKERR(ierr);
66 
67  IERR WriteArray( solver->ndims,
68  solver->nvars,
69  solver->dim_global,
70  solver->dim_local,
71  solver->ghosts,
72  solver->x,
73  uaux,
74  solver,
75  mpi,
76  aux_fname_root ); CHECKERR(ierr);
77 
78  aux_fname_root[2]++;
79  }
80 
81 #if defined(HAVE_CUDA)
82  if (solver->use_gpu) {
83  /* Copy values from GPU memory to CPU memory for writing. */
84  gpuMemcpy(solver->x, solver->gpu_x, sizeof(double)*solver->size_x, gpuMemcpyDeviceToHost);
85 
86 #ifdef CUDA_VAR_ORDERDING_AOS
87  gpuMemcpy( solver->u,
88  solver->gpu_u,
89  sizeof(double)*solver->ndof_cells_wghosts,
91 #else
92  double *h_u = (double *) malloc(sizeof(double)*solver->ndof_cells_wghosts);
93  gpuMemcpy(h_u, solver->gpu_u, sizeof(double)*solver->ndof_cells_wghosts, gpuMemcpyDeviceToHost);
94  for (int i=0; i<solver->npoints_local_wghosts; i++) {
95  for (int v=0; v<solver->nvars; v++) {
96  solver->u[i*solver->nvars+v] = h_u[i+v*solver->npoints_local_wghosts];
97  }
98  }
99  free(h_u);
100 #endif
101  }
102 #endif
103 
104  WriteArray( solver->ndims,
105  solver->nvars,
106  solver->dim_global,
107  solver->dim_local,
108  solver->ghosts,
109  solver->x,
110  solver->u,
111  solver,
112  mpi,
113  fname_root );
114 
115  if (!strcmp(solver->plot_solution, "yes")) {
116  PlotArray( solver->ndims,
117  solver->nvars,
118  solver->dim_global,
119  solver->dim_local,
120  solver->ghosts,
121  solver->x,
122  solver->u,
123  a_time,
124  solver,
125  mpi,
126  fname_root );
127  }
128 
129  /* increment the index string, if required */
130  if ((!strcmp(solver->output_mode,"serial")) && (!strcmp(solver->op_overwrite,"no"))) {
132  }
133 
134  }
135 
136  return(0);
137 }
char plot_solution[_MAX_STRING_SIZE_]
Definition: hypar.h:194
int nvars
Definition: hypar.h:29
#define IERR
Definition: basic.h:16
char * filename_index
Definition: hypar.h:197
#define CHECKERR(ierr)
Definition: basic.h:18
Structure defining a simulation.
int PlotArray(int, int, int *, int *, int, double *, double *, double, void *, void *, char *)
Definition: PlotArray.c:31
int TimeGetAuxSolutions(int *, double **, void *, int, int)
double * u
Definition: hypar.h:116
char output_mode[_MAX_STRING_SIZE_]
Definition: hypar.h:183
double * x
Definition: hypar.h:107
int size_x
Definition: hypar.h:48
double * gpu_x
Definition: hypar.h:457
char aux_op_fname_root[_MAX_STRING_SIZE_]
Definition: hypar.h:208
int ndims
Definition: hypar.h:26
int ndof_cells_wghosts
Definition: hypar.h:47
Structure containing all solver-specific variables and functions.
Definition: hypar.h:23
#define _MAX_STRING_SIZE_
Definition: basic.h:14
double * gpu_u
Definition: hypar.h:459
char op_overwrite[_MAX_STRING_SIZE_]
Definition: hypar.h:191
int WriteArray(int, int, int *, int *, int, double *, double *, void *, void *, char *)
Definition: WriteArray.c:27
void GetStringFromInteger(int, char *, int)
int index_length
Definition: hypar.h:199
char op_fname_root[_MAX_STRING_SIZE_]
Definition: hypar.h:206
int * dim_local
Definition: hypar.h:37
void gpuMemcpy(void *, const void *, size_t, enum gpuMemcpyKind)
void IncrementFilenameIndex(char *, int)
int(* WriteOutput)(int, int, int *, double *, double *, char *, int *)
Definition: hypar.h:211
int ghosts
Definition: hypar.h:52
Structure of MPI-related variables.
int use_gpu
Definition: hypar.h:449
int npoints_local_wghosts
Definition: hypar.h:42
#define _DECLARE_IERR_
Definition: basic.h:17
int * dim_global
Definition: hypar.h:33

◆ PetscPostTimeStep()

PetscErrorCode PetscPostTimeStep ( TS  ts)

Function called after every time step

Parameters
tsTime integrator object

Definition at line 21 of file PetscPostTimeStep.cpp.

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 }
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.
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
double * ConservationError
Definition: hypar.h:374
int(* CalculateConservationError)(void *, void *)
Definition: hypar.h:392
double * u0
Definition: hypar.h:396
int ndims
Definition: hypar.h:26
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
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 *)
double * VolumeIntegral
Definition: hypar.h:378
int TransferVecFromPETSc(double *const, const Vec, void *, const int, const int)
int file_op_iter
Definition: hypar.h:171
int screen_op_iter
Definition: hypar.h:168