libantioch/antioch — pull request #79 by SylvainPlessis (2014-09-23 17:02:53+00:00)
Title: Transport

This is the transport branch, it contains basically the kinetics theory for the viscosity, thermal conduction and diffusion. It's pretty big, I'll try to explain it as good as I can.

#### Big picture

This is the fully templated, no virtual method, no vtable lookup version.
The big picture is:
the ```WilkeEvaluator``` contains a ```WilkeMixture``` object which contains ```PhysicalSet``` objects, which is the fork point between the models, a _Mixture_ object (```TransportMixture```, it's templated because it is lighter in terms of template this way, and more general), and a _ThermoEvaluator_ object (typically the NASA polynoms, I'll write on the thermo a little bit).

#### The fun

The fork between the ```PhysicalSet``` and the models is where the fun (horror?) is. The method I have chosen (well, I didn't really find any other) is to have generic methods and tags to chose the proper one. The methods are ```void``` so the default is that they are empty, and thus hopefully suppressed by the compiler (and if not, nothing happens anyway).
The ```PhysicalSet``` object is built upon the following pattern:
- a ```SetOrEquation``` object will properly choose between either just one instantiation of the model (as ```ConstantLewisDiffusivity```) or a set of models (as ```BlottnerViscosity```),
- the constructor calls the global ```physical_set_initialize``` method, which is tagged and thus, any model not being the default (default is one instantiation of the model or a vector of ```n_species``` of models) can be properly initialize (see for instance the corresponding method in _src/diffusion/include/antioch/molecular_binary_diffusion_utils.h_)
- then in quite the same idea, ```physical_set_add_model``` methods are defined also, with defaults for a vector of models or one instantiation of the model.
- the operators. This is the not-very-elegant part. I could't find a way to have a few of them, as models require different parameters. So I have two methods for viscosity and thermal conduction and four for diffusion. This comes from the description of the system: at the species level, typically one species have one value, thus a method to obtain that value and one method to obtain the vector of values. The diffusion is quite different in the fact that at the mixture level it's one value per species and at the species level a matrix of species. The ```ConstantLewisDiffusivity``` actually gives the mixture level value, so the operator corresponding to it has not the same signature that the ```MolecularBinaryDiffusion``` one. Thus double dose operator. The corresponding global methods (```physical_set_operator_viscosity/thermal_conduction/diffusion```) are defaulted to nothing, and are explicitely described for each model, using tag.
- a ```physical_set_reset``` and ```physical_set_delete``` for resetting and the desctuctor, same fashion.

The defaults are given in terms of tags, there is this big tagged object:
```
// gives the tag of the model for any interesting
// action, base class so we don't rewrite everything
template
struct physical_tag_base
{
// tag
typedef default_physical_tag type;
// kind of set tag
typedef typename if_else_type::value,
default_physical_set_tag,
default_physical_tag
>::type set_type;
// some models require specific initialization
// (typically automatic initialization)
typedef typename if_else_type::value,
default_physical_set_tag,
default_physical_tag
>::type init_type;
// some models require specific initialization
// but not specific deletion
typedef typename if_else_type::value,
default_physical_set_tag,
default_physical_tag
>::type del_type;
// for operators, diffusion is special, see comment below
typedef default_physical_tag viscosity_type;
typedef default_physical_tag diffusion_species_type;
typedef default_physical_tag diffusion_mixture_type;
typedef default_physical_tag thermal_conductivity_type;
};
```
that will produced the default method and ensure that if a model do not have a required method defined, it will complain at compile time as the method won't exist.

All those templated-tagged-specific methods are declared in files _src/Physics/include/antioch/model_utils_decl.h_ and defined in _src/Physics/include/antioch/model_utils.h_, I just copy/pasted the metaprogramming design.

The parsing is not changed, except that it takes a ```PhysicalSet``` object, and that as typically, kinetics therory objects can be build without the user, they are called in the corresponding ```physical_set_initialize```, the name of the method/file use the word *build* instead of *parse* to notice the difference.

#### GSL and the spline

Some models (bimolecular diffusion & kinetics theory viscosity) requires an interpolated value of a surface (the Stockmayer potential). The spline by default is GSL cspline, thus we have a requirement of GSL.

#### The thermo

This is annoying, there are two very different thermo way of life: the NASA polynomials or statistical thermo. The last one is needed solely for thermal conduction (and only if not ideal gas). The thing is that we require Cp to be computed for the Lewis diffusion model, this Cp typically comes from the NASA polynomials, and we have and the different Cvs for thermal conduction. So I just couldn't find a way of making all models and possibilities happy other than having a reference to a thermo object in the mixture (thus the choice for Lewis, the NASA) and thermo in the ```TransportMixture```, the statistical, for the thermal conduction. This is weird, kinda annoying, I don't have any better idea.

#### What's nice

This is a pretty nice way of dealing with various models, tags and all, and normally only the required code will be produced. Thus adding more physics should be painless.

#### What's annoying

Well, just look at *test/wilke_mixture_unit.C*... The templates are terrible... The vectorized version uses typedef to lighten things.

#### What we'd probably want

I think we need to put all the mixture equations from the ```WilkeEvaluator``` object into the ```WilkeMixture``` object, so then we can very well use interpolants instead of physical models. It would require to treat interpolation just like physical models: initialization with some physics, a temperature/pressure interval using tags. It does not require any change in the design.
Not done yet because I don't have the time to code the interpolation initialization (yet) and I want more opinions than just mine on what interpolation methods/libraries we want.