Start of topic | Skip to actions

Two classes, WENOStatistics [bad link?] and StatParser [bad link?], have been created to incorporate quite flexible statistics and sampling gathering. Of these classes, only the first is directly exposed to the user.

In order to use this class (WENOStatistics) the user must make the following modification to the Problem.h. Note that statistics gathering is not set by default in the current solver, so a little of C++ must be done.

- include
#include "AMRInterpolation.h" #include "WENOStatistics.h"

- derive your own solver class by defining
#define OWN_AMRSOLVER

- include the following protected variables in SolverSpecific
interpolation_type* _Interpolation; stat_type* _Stats;

- add the following to the bottom of the SolverSpecific constructor
_Interpolation = new interpolation_type(); _Stats = new stat_type(_Interpolation, (output_type*)_FileOutput);

- same for destructor
delete _Interpolation; delete _Stats;

- register a parser key with register_at(...)
if (_Stats) _Stats->register_at(base::LocCtrl, "");

- add the following to SetupData()
_Interpolation->SetupData(base::PGH(), base::NGhosts()); _Stats->SetupData(base::PGH(), base::NGhosts(), base::shape, base::geom);

- add an Evaluate call to Advance
_Stats->Evaluate(base::t, base::U(), base::Work());

- add a hook to Initialize_
_Stats->Evaluate(base::t, base::U(), base::Work());

A full Problem.h example looks like this:

// -*- C++ -*- #ifndef AMROC_PROBLEM_H #define AMROC_PROBLEM_H #define DIM 3 #define NEQUATIONS 15 // Euler equations for gases in 3D (5 fields), // +4 fields for passive scalars // +1 field for temperature // +1 field to output dcflag and // +1 field for subgrid kinetic energy // +2 field for subgrid stress components // +1 field for sgs eps #define NVARS 9 // Total number of active variables #define NAUX 3 #define LESSVM_SGSEPS -2 #define LESSVM_SGS11 -8 #define LESSVM_SGS22 -7 #define LESSVM_SGS33 -6 #define LESSVM_SGS12 -5 #define LESSVM_SGS13 -4 #define LESSVM_SGS23 -3 #define CLES_IAUX_DEFINITION {LESSVM_SGS12, LESSVM_SGS23, LESSVM_SGSEPS} #define OWN_AMRSOLVER #include "WENOProblem.h" #ifdef SYNCTIME #include "WENOStdSyncTimeProblem.h" #else #include "WENOStdProblem.h" #endif #include "AMRInterpolation.h" #include "WENOStatistics.h" #define f_init_commongm FORTRAN_NAME(comblgm, COMBLGM) extern "C" { void f_init_commongm(const INTEGER& meqn, DOUBLE* geom); } #ifdef OWN_AMRSOLVER class SolverSpecific : #ifdef SYNCTIME public AMRSolverSyncTime<VectorType,FixupType,FlagType,DIM> { typedef AMRSolverSyncTime<VectorType,FixupType,FlagType,DIM> base; #else public AMRSolver<VectorType,FixupType,FlagType,DIM> { typedef AMRSolver<VectorType,FixupType,FlagType,DIM> base; #endif typedef AMRInterpolation<VectorType,DIM> interpolation_type; typedef F77FileOutput<VectorType,DIM> output_type; typedef WENOStatistics<VectorType,interpolation_type,output_type,DIM> stat_type; public: SolverSpecific(IntegratorSpecific& integ, base::initial_condition_type& init, base::boundary_conditions_type& bc) : #ifdef SYNCTIME AMRSolverSyncTime<VectorType,FixupType,FlagType,DIM>(integ, init, bc) { #else AMRSolver<VectorType,FixupType,FlagType,DIM>(integ, init, bc) { #endif SetLevelTransfer(new F77LevelTransfer<VectorType,DIM>(f_prolong, f_restrict)); #ifdef f_flgout SetFileOutput(new F77FileOutput<VectorType,DIM>(f_flgout)); #else SetFileOutput(new FileOutput<VectorType,DIM>()); #endif SetFixup(new FixupSpecific()); SetFlagging(new FlaggingSpecific(*this)); _Interpolation = new interpolation_type(); _Stats = new stat_type(_Interpolation, (output_type*)_FileOutput); } ~SolverSpecific() { delete _LevelTransfer; delete _Flagging; delete _Fixup; delete _FileOutput; delete _Interpolation; delete _Stats; } virtual void register_at(ControlDevice& Ctrl) { base::register_at(Ctrl); } virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) { base::register_at(Ctrl, prefix); if (_Stats) _Stats->register_at(base::LocCtrl, ""); } virtual void SetupData() { base::SetupData(); f_init_commongm(DIM,geom); _Interpolation->SetupData(base::PGH(), base::NGhosts()); _Stats->SetupData(base::PGH(), base::NGhosts(), base::shape, base::geom); } virtual void Advance(double& t, double& dt) { base::Advance(t, dt); _Stats->Evaluate(base::t, base::U(), base::Work()); } virtual void Initialize_(const double& dt_start) { base::Initialize_(dt_start); _Stats->Evaluate(base::t, base::U(), base::Work()); } protected: interpolation_type* _Interpolation; stat_type* _Stats; }; #endif #endif

The user can control the behavior of the statistics package by specifing the following options within the AMRSolver section of solver.in:

Statistics { DefinitionFile stats.def OutputFile stats Step 1000 }

where the key **DefinitionFile** specifies the name of a text file containing all the definitions
of statistcs to be extracted. **OutputFile** is the root name of the statistics files that will be
produced. The timestep at which the statistics are written is attached to the root name. The
key **Step** denotes the number of coarse steps to take between actual sampling.

The statistic language specified in **DefinitionFile** must conform to the following specification:

- each statistics ensamble is defined using the
**group**keyword with matched curly braces enclosing all defintions.group { .... }

- you can specify an arbitrary number of comma separated expressions using the
**keys**keyword.keys { exp1, exp2, exp3 }

- expresions are defined as arbitrary length mathematical expressions. The scanner/parser is able to recognize mixed
Fortran and C style mathematical expressions. All variables accessible to the patch solver can be used (see bellow
for a list). There are also a number of predefined constants that can be used.
keys { u, v, w, u^2, v**2, u*w/2.0d0 }

- standard mathematic functions are also available and can be used within the expressions.
- an arbitrary number of one-dimensional samples of the predefined keys can the specified with the
**thread**keyword. All threads are defined as a parametric curve with parametric coordinate**a**ranging from 0 to 1. The 2d or 3d coordinates of the points along the thread are sampled n times, at uniform intervals of**a**from 0 to 1. Two formats are accepted:thread { a, 0, 1 } @ 10 thread { 0, a, 0 } @ <12>

In the first case, 10 samplings are performed and the values are then reported in the output. In the second case, 12 samples are performed and the averaged such that a single value for each expression is written to the statistics file. - analogous to threads, it is possible to define an arbitrary number of two-dimensional objects called surfaces, the
corresponding keyword
**surface**is then used. Like with threads, we must specify the bi-parametric representation of the surface in terms of**a**(the first parametric coordinate) and**b**(the second parametric coordinate). Like in the previous case,**a**and**b**vary from 0 to 1 in the number of steps specified, for example:surface {2*a, 1, b*zmax*39/40 } @ 20 <40> surface {0.845, 0.83+(1.17-0.83)*a, b*zmax*39/40 } @ <20> <40>

In the first example, the second parametric coordinate is sampled over 40 points and the result is the averaged. So the output will contain only 20 points per expression. In the second case, both parametric coordinates are averaged, leading to a single value per expression. - there is still a lightweight version of surface refered with the
**planes**keyword. This allows a quick definition of planes aligned with the cartesian coordinates of the domain in a compact manner. Planes expect a comma separated definition of planes over which to perform statistics.planes { x = xmin , x = 1, y = 0, z = [zmin , zmax/2] @ 20 } planes { x @ nx, y @ 10 } # equaly sampled planar statistics.

In the first case, we define 23 planes, the first 3 are single plane definitions (arbitrary scalar expression can also be used here). The last 20 planes are defined as a range from zmin to zmax/2. All values samples on these planes are averaged so that the first plane definition is equivalent and will be executed literally assurface {xmin, ymin+(ymax-ymin)*a, zmin+(zmax-zmin)*b } @ <ny> <nz>

In the second case, we use a similar notation but when the range is ommited, it is assumed that the range is from the minimum to the maximum of the domain size. This line also shows use of comments with the**#**keyword.

Here is a more general example of a statistics definition file

# # Example of a statistics definition file. One should be able to get # almost anything derived from the conservative or primitive vector # of state with this approach. # group { # variables that will be measured. keys { u, v, w, rho * ((u^2 + v^2 + w^2)/2.0 + sgske), Y1, Y1^2, q(2)*q(3)/rho } # for 1d, 2d and 3d sampling (rack, surface and volume) we use # the dummy variables a and b (plane is a special form of surface). thread { cos( 2 * pi * a), sin(2 * pi *a), 0 } @ 10 surface { a, 1, b } @ 20 15 surface { a, 2.,b } @ 20 <14> planes { x = xmin , x = 1, y = 0, z = [zmin , zmax/2] @ 20 } planes { x @ nx, y @ 10 } # equaly sampled planar statistics. volume # the whole volume. volume { [0, 1], [0, 2], [1, 2] } # part of a volume } group { keys { T, p, E } surface {a + b, a - b, a } @ 20 20 }

the **volume** keyword is currently not implemented.

Variables | Comments |
---|---|

rho,r | density |

u | x velocity |

v | y velocity |

w | z velocity |

p | pressure |

T | temperature |

E | total energy |

sgskin | subgrid kinetic energy |

Y1, Y2, ... | scalars |

gamma | ratio of specific heats |

q(i) | ith component of the conservative vector of state |

Functions | Comments |
---|---|

sin() | |

cos() | |

tan() | |

ln() | natural logarithm |

exp() | |

sqrt() | |

log() | logarithm base 10 |

abs() | absolute value |

asin() | |

acos() | |

atan() | |

cosh() | |

sinh() | |

tanh() | |

min(,) | |

max(,) | |

pow(,) |

Constants | Comments |
---|---|

pi | |

nx, ny, nz | coarse grid sizes |

xmin, xmax, ymin, ymax, zmin, zmax | minimum and maximum coordinates of the domain in each direction |

-- CarlosPantano - 07 Dec 2005

Copyright © 1997-2022 California Institute of Technology.