WilkAndy / moose

Multiphysics Object Oriented Simulation Environment
GNU Lesser General Public License v2.1
0 stars 0 forks source link

EOS materials for phase properties #44

Open cpgr opened 8 years ago

cpgr commented 8 years ago

Tagging @WilkAndy, @jpek15, @TaraLaForce

Hi all,

At the moment, we can do immiscible problems like two component, two phase (one component per phase), and also multiple components per phase where phase properties like density don't depend on composition.

At some point, we need to consider cases where phase properties do depend on the composition (for example, density increase when CO2 is dissolved in brine).

Currently, we specify a fluid material for each individual phase. For example, to have a two component, two phase simulation we would put something like

[./dens0] type = PorousFlowMaterialDensityConstBulk density_P0 = 1000 bulk_modulus = 2E9 phase = 0 [../] [./dens1] type = PorousFlowMaterialDensityConstBulk density_P0 = 1 bulk_modulus = 2E6 phase = 1 [../] [./dens_all] type = PorousFlowMaterialJoinerOld material_property = PorousFlow_fluid_phase_density [../]

in the input file to make a std::vector material for density.

To implement a compositional case, I think we need to have a single EOS material that replaces the above three, specialised for each combination of fluids that we are interested in.

Brine and CO2 is a good example, as we require one of these for our work. I propose that we have a single PorousFlowMaterialBrineCO2 material that takes in pressure, temperature and mass fraction, and returns a std::vector of all required thermophysical properties for each phase.

The input file for that case would just be

[./brineco2] type = PorousFlowMaterialBrineCO2 [../]

This is the same approach as the EOS modules in TOUGH (DUMUX has a similar design too).

To implement this, I think that we should move the actual fluid property functions for density etc into a namespace, and use them in these EOS materials. We can still have individual fluid property materials for use in the immiscible cases using the functions in the appropriate namespace. This is what I ended up doing in quoll (but with user objects instead of materials), and something that Andy also suggested.

In each specialised EOS material, we can of course implement whatever form of dependence on composition as required.

Any thoughts on this approach? I can't really think of a better way at the moment.

WilkAndy commented 8 years ago

This sounds good.

I think a UserObject approach is generally preferred if we are imagining people will swap different UserObjects in and out of Materials (e.g., have the same Material and use it for CO2 and also methane depending on the simulation). However, i wonder whether that is actually very likely in our cases. I'll leave that up to you to decide - i'll just be using methane and methane+CO2 and pure water i think.

I think a namespace approach is generally preferred if we want to hard-code things more, e.g. have a PorousFlowDensityCO2 object that uses the CO2 namespace and a PorousFlowCO2Methane, etc. One advantage of namespaces is that they are more transparently tested in unit tests, but that's just my opinion - lots of other people would test values and derivatives using a moose input file with an exodus output.

My opinion is that we should concentrate on maintainability and code reuse and transparency rather than considering the user's perspective, since it will all look very similar to her.

WilkAndy commented 8 years ago

I meant to add: namespace or UserObject doesn't matter too much at this stage - it will be very easy to change from one to the other if we change our minds down the track as all the difficult coding (all those EOS functions) will have been done.

cpgr commented 8 years ago

I found the namespace easier as you can include whatever functions you want and don't have to worry about having a consistent way for the userobject to present that function to the other classes. For example, the brine fluid will have things related to salt that say methane won't need. This was one of the main reasons for me using namespaces in quoll.

WilkAndy commented 8 years ago

OK. So you're suggesting that the UseCase of where we have, e.g. PorousFlowPhaseDensity taking a UserObject that could be MethaneDensity or CO2Density, with each of those providing just "density(...)" and "ddensity_dp(...)", etc is actually quite rare. Or, another way of saying this is that the "etc" at the end of the last sentence varies too much between different UseCases.

I'm kind of glad. I like the self-contained nature of namespaces.

cpgr commented 8 years ago

Using UserObjects made it tricky as density for one fluid might only depend on pressure, for another it depends on pressure and temperature, while for brine it depends of pressure, temperature and salt mass fraction. The interface ended up messy to make sure that you could swap UserObjects and have the density function call the correct number of variables. Namespaces was much easier.

WilkAndy commented 8 years ago

Aha, that makes complete sense. Thanks Chris.

WilkAndy commented 8 years ago

But we should only use namespaces if the code is going to be used by >=2 other classes. Otherwise just use a Material