Loading...
Searching...
No Matches
pvsmodel.hh
Go to the documentation of this file.
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
#ifndef EWOMS_PVS_MODEL_HH
#define EWOMS_PVS_MODEL_HH
#include <opm/common/Exceptions.hpp>
#include <opm/material/densead/Math.hpp>
#include <opm/material/fluidmatrixinteractions/MaterialTraits.hpp>
#include <opm/material/fluidmatrixinteractions/NullMaterial.hpp>
#include <opm/models/common/diffusionmodule.hh>
#include <opm/models/common/energymodule.hh>
#include <opm/models/common/multiphasebasemodel.hh>
#include <opm/models/io/vtkcompositionmodule.hpp>
#include <opm/models/io/vtkenergymodule.hpp>
#include <opm/models/io/vtkdiffusionmodule.hpp>
#include <opm/models/io/vtkphasepresencemodule.hpp>
#include <opm/models/pvs/pvsboundaryratevector.hh>
#include <opm/models/pvs/pvsextensivequantities.hh>
#include <opm/models/pvs/pvsindices.hh>
#include <opm/models/pvs/pvsintensivequantities.hh>
#include <opm/models/pvs/pvslocalresidual.hh>
#include <opm/models/pvs/pvsnewtonmethod.hh>
#include <opm/models/pvs/pvsprimaryvariables.hh>
#include <opm/models/pvs/pvsproperties.hh>
#include <opm/models/pvs/pvsratevector.hh>
#include <cassert>
#include <cstddef>
#include <iostream>
#include <memory>
#include <sstream>
#include <stdexcept>
#include <string>
#include <tuple>
#include <vector>
namespace Opm {
template <class TypeTag>
class PvsModel;
}
namespace Opm::Properties {
namespace TTag {
struct PvsModel
{ using InheritsFrom = std::tuple<MultiPhaseBaseModel>; };
} // namespace TTag
template<class TypeTag>
struct LocalResidual<TypeTag, TTag::PvsModel>
{ using type = Opm::PvsLocalResidual<TypeTag>; };
template<class TypeTag>
struct NewtonMethod<TypeTag, TTag::PvsModel>
{ using type = Opm::PvsNewtonMethod<TypeTag>; };
template<class TypeTag>
struct Model<TypeTag, TTag::PvsModel>
{ using type = Opm::PvsModel<TypeTag>; };
template<class TypeTag>
struct PrimaryVariables<TypeTag, TTag::PvsModel>
{ using type = Opm::PvsPrimaryVariables<TypeTag>; };
template<class TypeTag>
struct RateVector<TypeTag, TTag::PvsModel>
{ using type = Opm::PvsRateVector<TypeTag>; };
template<class TypeTag>
struct BoundaryRateVector<TypeTag, TTag::PvsModel>
{ using type = Opm::PvsBoundaryRateVector<TypeTag>; };
template<class TypeTag>
struct IntensiveQuantities<TypeTag, TTag::PvsModel>
{ using type = Opm::PvsIntensiveQuantities<TypeTag>; };
template<class TypeTag>
struct ExtensiveQuantities<TypeTag, TTag::PvsModel>
{ using type = Opm::PvsExtensiveQuantities<TypeTag>; };
template<class TypeTag>
struct Indices<TypeTag, TTag::PvsModel>
{ using type = Opm::PvsIndices<TypeTag, /*PVIdx=*/0>; };
template<class TypeTag>
struct EnableEnergy<TypeTag, TTag::PvsModel>
{ static constexpr bool value = false; };
// disable molecular diffusion by default
template<class TypeTag>
struct EnableDiffusion<TypeTag, TTag::PvsModel>
{ static constexpr bool value = false; };
template<class TypeTag>
struct PvsPressureBaseWeight<TypeTag, TTag::PvsModel>
{
using type = GetPropType<TypeTag, Scalar>;
static constexpr type value = 1.0;
};
template<class TypeTag>
struct PvsSaturationsBaseWeight<TypeTag, TTag::PvsModel>
{
using type = GetPropType<TypeTag, Scalar>;
static constexpr type value = 1.0;
};
template<class TypeTag>
struct PvsMoleFractionsBaseWeight<TypeTag, TTag::PvsModel>
{
using type = GetPropType<TypeTag, Scalar>;
static constexpr type value = 1.0;
};
} // namespace Opm::Properties
namespace Opm::Parameters {
struct PvsVerbosity
{ static constexpr int value = 1; };
} // namespace Opm::Parameters
namespace Opm {
template <class TypeTag>
class PvsModel
: public MultiPhaseBaseModel<TypeTag>
{
using ParentType = MultiPhaseBaseModel<TypeTag>;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using Simulator = GetPropType<TypeTag, Properties::Simulator>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
using GridView = GetPropType<TypeTag, Properties::GridView>;
using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
using IntensiveQuantities = GetPropType<TypeTag, Properties::IntensiveQuantities>;
using ElementContext = GetPropType<TypeTag, Properties::ElementContext>;
using Indices = GetPropType<TypeTag, Properties::Indices>;
enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
enum { numComponents = getPropValue<TypeTag, Properties::NumComponents>() };
enum { enableDiffusion = getPropValue<TypeTag, Properties::EnableDiffusion>() };
enum { enableEnergy = getPropValue<TypeTag, Properties::EnableEnergy>() };
using Element = typename GridView::template Codim<0>::Entity;
using ElementIterator = typename GridView::template Codim<0>::Iterator;
using EnergyModule = ::Opm::EnergyModule<TypeTag, enableEnergy>;
public:
explicit PvsModel(Simulator& simulator)
: ParentType(simulator)
{
verbosity_ = Parameters::Get<Parameters::PvsVerbosity>();
numSwitched_ = 0;
}
static void registerParameters()
{
ParentType::registerParameters();
// register runtime parameters of the VTK output modules
VtkPhasePresenceModule<TypeTag>::registerParameters();
VtkCompositionModule<TypeTag>::registerParameters();
if constexpr (enableDiffusion) {
VtkDiffusionModule<TypeTag>::registerParameters();
}
if constexpr (enableEnergy) {
VtkEnergyModule<TypeTag>::registerParameters();
}
Parameters::Register<Parameters::PvsVerbosity>
("The verbosity level of the primary variable "
"switching model");
}
static std::string name()
{ return "pvs"; }
std::string primaryVarName(unsigned pvIdx) const
{
const std::string s = EnergyModule::primaryVarName(pvIdx);
if (!s.empty()) {
return s;
}
std::ostringstream oss;
if (pvIdx == Indices::pressure0Idx) {
oss << "pressure_" << FluidSystem::phaseName(/*phaseIdx=*/0);
}
else if (Indices::switch0Idx <= pvIdx &&
pvIdx < Indices::switch0Idx + numPhases - 1)
{
oss << "switch_" << pvIdx - Indices::switch0Idx;
}
else if (Indices::switch0Idx + numPhases - 1 <= pvIdx &&
pvIdx < Indices::switch0Idx + numComponents - 1)
{
oss << "auxMoleFrac^" << FluidSystem::componentName(pvIdx);
} else {
assert(false);
}
return oss.str();
}
std::string eqName(unsigned eqIdx) const
{
const std::string s = EnergyModule::eqName(eqIdx);
if (!s.empty()) {
return s;
}
std::ostringstream oss;
if (Indices::conti0EqIdx <= eqIdx &&
eqIdx < Indices::conti0EqIdx + numComponents)
{
const unsigned compIdx = eqIdx - Indices::conti0EqIdx;
oss << "continuity^" << FluidSystem::componentName(compIdx);
}
else {
assert(false);
}
return oss.str();
}
void updateFailed()
{
ParentType::updateFailed();
numSwitched_ = 0;
}
void updateBegin()
{
ParentType::updateBegin();
// find the a reference pressure. The first degree of freedom
// might correspond to non-interior entities which would lead
// to an undefined value, so we have to iterate...
const std::size_t nDof = this->numTotalDof();
for (unsigned dofIdx = 0; dofIdx < nDof; ++dofIdx) {
if (this->dofTotalVolume(dofIdx) > 0.0) {
referencePressure_ =
this->solution(/*timeIdx=*/0)[dofIdx][/*pvIdx=*/Indices::pressure0Idx];
if (referencePressure_ > 0.0) {
break;
}
}
}
}
Scalar primaryVarWeight(unsigned globalDofIdx, unsigned pvIdx) const
{
const Scalar tmp = EnergyModule::primaryVarWeight(*this, globalDofIdx, pvIdx);
if (tmp > 0) {
// energy related quantity
return tmp;
}
if (Indices::pressure0Idx == pvIdx) {
return 10 / referencePressure_;
}
if (Indices::switch0Idx <= pvIdx &&
pvIdx < Indices::switch0Idx + numPhases - 1)
{
const unsigned phaseIdx = pvIdx - Indices::switch0Idx;
if (!this->solution(/*timeIdx=*/0)[globalDofIdx].phaseIsPresent(phaseIdx)) {
// for saturations, the weight is always 1
return 1;
}
// for saturations, the PvsMoleSaturationsBaseWeight
// property determines the weight
return getPropValue<TypeTag, Properties::PvsSaturationsBaseWeight>();
}
// for mole fractions, the PvsMoleFractionsBaseWeight
// property determines the weight
return getPropValue<TypeTag, Properties::PvsMoleFractionsBaseWeight>();
}
Scalar eqWeight(unsigned globalDofIdx, unsigned eqIdx) const
{
const Scalar tmp = EnergyModule::eqWeight(*this, globalDofIdx, eqIdx);
if (tmp > 0) {
// energy related equation
return tmp;
}
const unsigned compIdx = eqIdx - Indices::conti0EqIdx;
assert(compIdx <= numComponents);
// make all kg equal
return FluidSystem::molarMass(compIdx);
}
void advanceTimeLevel()
{
ParentType::advanceTimeLevel();
numSwitched_ = 0;
}
bool switched() const
{ return numSwitched_ > 0; }
template <class DofEntity>
void serializeEntity(std::ostream& outstream, const DofEntity& dofEntity)
{
// write primary variables
ParentType::serializeEntity(outstream, dofEntity);
const unsigned dofIdx = static_cast<unsigned>(this->dofMapper().index(dofEntity));
if (!outstream.good()) {
throw std::runtime_error("Could not serialize DOF " + std::to_string(dofIdx));
}
outstream << this->solution(/*timeIdx=*/0)[dofIdx].phasePresence() << " ";
}
template <class DofEntity>
void deserializeEntity(std::istream& instream, const DofEntity& dofEntity)
{
// read primary variables
ParentType::deserializeEntity(instream, dofEntity);
// read phase presence
const unsigned dofIdx = static_cast<unsigned>(this->dofMapper().index(dofEntity));
if (!instream.good()) {
throw std::runtime_error("Could not deserialize DOF " + std::to_string(dofIdx));
}
short tmp;
instream >> tmp;
this->solution(/*timeIdx=*/0)[dofIdx].setPhasePresence(tmp);
this->solution(/*timeIdx=*/1)[dofIdx].setPhasePresence(tmp);
}
void switchPrimaryVars_()
{
numSwitched_ = 0;
int succeeded;
try {
std::vector<bool> visited(this->numGridDof(), false);
ElementContext elemCtx(this->simulator_);
for (const auto& elem : elements(this->gridView_, Dune::Partitions::interior)) {
elemCtx.updateStencil(elem);
const std::size_t numLocalDof = elemCtx.stencil(/*timeIdx=*/0).numPrimaryDof();
for (unsigned dofIdx = 0; dofIdx < numLocalDof; ++dofIdx) {
unsigned globalIdx = elemCtx.globalSpaceIndex(dofIdx, /*timeIdx=*/0);
if (visited[globalIdx]) {
continue;
}
visited[globalIdx] = true;
// compute the intensive quantities of the current degree of freedom
auto& priVars = this->solution(/*timeIdx=*/0)[globalIdx];
elemCtx.updateIntensiveQuantities(priVars, dofIdx, /*timeIdx=*/0);
const IntensiveQuantities& intQuants = elemCtx.intensiveQuantities(dofIdx, /*timeIdx=*/0);
// evaluate primary variable switch
const short oldPhasePresence = priVars.phasePresence();
// set the primary variables and the new phase state
// from the current fluid state
priVars.assignNaive(intQuants.fluidState());
if (oldPhasePresence != priVars.phasePresence()) {
if (verbosity_ > 1) {
printSwitchedPhases_(elemCtx,
dofIdx,
intQuants.fluidState(),
oldPhasePresence,
priVars);
}
++numSwitched_;
}
}
}
succeeded = 1;
}
catch (...)
{
std::cout << "rank " << this->simulator_.gridView().comm().rank()
<< " caught an exception during primary variable switching"
<< "\n" << std::flush;
succeeded = 0;
}
succeeded = this->simulator_.gridView().comm().min(succeeded);
if (!succeeded) {
throw NumericalProblem("A process did not succeed in adapting the primary variables");
}
// make sure that if there was a variable switch in an
// other partition we will also set the switch flag
// for our partition.
numSwitched_ = this->gridView_.comm().sum(numSwitched_);
if (verbosity_ > 0) {
this->simulator_.model().newtonMethod().endIterMsg()
<< ", num switched=" << numSwitched_;
}
}
template <class FluidState>
void printSwitchedPhases_(const ElementContext& elemCtx,
unsigned dofIdx,
const FluidState& fs,
short oldPhasePresence,
const PrimaryVariables& newPv) const
{
using FsToolbox = MathToolbox<typename FluidState::Scalar>;
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
const bool oldPhasePresent = (oldPhasePresence & (1 << phaseIdx)) > 0;
const bool newPhasePresent = newPv.phaseIsPresent(phaseIdx);
if (oldPhasePresent == newPhasePresent) {
continue;
}
const auto& pos = elemCtx.pos(dofIdx, /*timeIdx=*/0);
if (oldPhasePresent) {
std::cout << "'" << FluidSystem::phaseName(phaseIdx)
<< "' phase disappears at position " << pos
<< ". saturation=" << fs.saturation(phaseIdx)
<< std::flush;
}
else {
Scalar sumx = 0;
for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
sumx += FsToolbox::value(fs.moleFraction(phaseIdx, compIdx));
}
std::cout << "'" << FluidSystem::phaseName(phaseIdx)
<< "' phase appears at position " << pos
<< " sum x = " << sumx << std::flush;
}
}
std::cout << ", new primary variables: ";
newPv.print(std::cout);
std::cout << "\n" << std::flush;
}
void registerOutputModules_()
{
ParentType::registerOutputModules_();
// add the VTK output modules which are meaningful for the model
this->addOutputModule(std::make_unique<VtkPhasePresenceModule<TypeTag>>(this->simulator_));
this->addOutputModule(std::make_unique<VtkCompositionModule<TypeTag>>(this->simulator_));
if constexpr (enableDiffusion) {
this->addOutputModule(std::make_unique<VtkDiffusionModule<TypeTag>>(this->simulator_));
}
if constexpr (enableEnergy) {
this->addOutputModule(std::make_unique<VtkEnergyModule<TypeTag>>(this->simulator_));
}
}
Scalar referencePressure_{};
// number of switches of the phase state in the last Newton
// iteration
unsigned numSwitched_;
// verbosity of the model
int verbosity_;
};
} // namespace Opm
#endif
Opm::EnergyModule
Provides the auxiliary methods required for consideration of the energy equation.
Definition energymodule.hh:54
Opm::MultiPhaseBaseModel::registerParameters
static void registerParameters()
Register all run-time parameters for the immiscible model.
Definition multiphasebasemodel.hh:190
Opm::PvsBoundaryRateVector
Implements a rate vector on the boundary for the fully implicit compositional multi-phase primary var...
Definition pvsboundaryratevector.hh:51
Opm::PvsExtensiveQuantities
Contains all data which is required to calculate all fluxes at a flux integration point for the prima...
Definition pvsextensivequantities.hh:54
Opm::PvsIndices
The indices for the compositional multi-phase primary variable switching model.
Definition pvsindices.hh:48
Opm::PvsIntensiveQuantities
Contains the quantities which are are constant within a finite volume in the compositional multi-phas...
Definition pvsintensivequantities.hh:62
Opm::PvsLocalResidual
Element-wise calculation of the local residual for the compositional multi-phase primary variable swi...
Definition pvslocalresidual.hh:49
Opm::PvsModel
A generic compositional multi-phase model using primary-variable switching.
Definition pvsmodel.hh:273
Opm::PvsModel::advanceTimeLevel
void advanceTimeLevel()
Called by the problem if a time integration was successful, post processing of the solution is done a...
Definition pvsmodel.hh:478
Opm::PvsModel::serializeEntity
void serializeEntity(std::ostream &outstream, const DofEntity &dofEntity)
Write the current solution for a degree of freedom to a restart file.
Definition pvsmodel.hh:498
Opm::PvsModel::eqName
std::string eqName(unsigned eqIdx) const
Given an equation index, return a human readable name.
Definition pvsmodel.hh:367
Opm::PvsModel::primaryVarName
std::string primaryVarName(unsigned pvIdx) const
Given an primary variable index, return a human readable name.
Definition pvsmodel.hh:337
Opm::PvsModel::updateBegin
void updateBegin()
Called by the update() method before it tries to apply the newton method.
Definition pvsmodel.hh:400
Opm::PvsModel::eqWeight
Scalar eqWeight(unsigned globalDofIdx, unsigned eqIdx) const
Returns the relative weight of an equation.
Definition pvsmodel.hh:460
Opm::PvsModel::name
static std::string name()
Definition pvsmodel.hh:331
Opm::PvsModel::switched
bool switched() const
Return true if the primary variables were switched for at least one vertex after the last timestep.
Definition pvsmodel.hh:488
Opm::PvsModel::registerParameters
static void registerParameters()
Register all run-time parameters for the PVS compositional model.
Definition pvsmodel.hh:307
Opm::PvsModel::primaryVarWeight
Scalar primaryVarWeight(unsigned globalDofIdx, unsigned pvIdx) const
Returns the relative weight of a primary variable for calculating relative errors.
Definition pvsmodel.hh:422
Opm::PvsModel::deserializeEntity
void deserializeEntity(std::istream &instream, const DofEntity &dofEntity)
Reads the current solution variables for a degree of freedom from a restart file.
Definition pvsmodel.hh:518
Opm::PvsModel::updateFailed
void updateFailed()
Called by the update() method if it was unsuccessful.
Definition pvsmodel.hh:391
Opm::PvsNewtonMethod
A newton solver which is specific to the compositional multi-phase PVS model.
Definition pvsnewtonmethod.hh:54
Opm::PvsPrimaryVariables
Represents the primary variables used in the primary variable switching compositional model.
Definition pvsprimaryvariables.hh:62
Opm::PvsRateVector
Implements a vector representing molar, mass or volumetric rates.
Definition pvsratevector.hh:53
Opm::VtkCompositionModule::registerParameters
static void registerParameters()
Register all run-time parameters for the Vtk output module.
Definition vtkcompositionmodule.hpp:87
Opm::VtkDiffusionModule::registerParameters
static void registerParameters()
Register all run-time parameters for the Vtk output module.
Definition vtkdiffusionmodule.hpp:88
Opm::VtkEnergyModule::registerParameters
static void registerParameters()
Register all run-time parameters for the Vtk output module.
Definition vtkenergymodule.hpp:87
Opm::VtkPhasePresenceModule::registerParameters
static void registerParameters()
Register all run-time parameters for the Vtk output module.
Definition vtkphasepresencemodule.hpp:71
diffusionmodule.hh
Classes required for molecular diffusion.
energymodule.hh
Contains the classes required to consider energy as a conservation quantity in a multi-phase module.
multiphasebasemodel.hh
A base class for fully-implicit multi-phase porous-media flow models which assume multiple fluid phas...
Opm::Properties::TTag
The generic type tag for problems using the immiscible multi-phase model.
Definition blackoilmodel.hh:81
Opm
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition blackoilbioeffectsmodules.hh:43
Opm::GetPropType
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition propertysystem.hh:233
Opm::getPropValue
constexpr auto getPropValue()
get the value data member of a property
Definition propertysystem.hh:240
Opm::Parameters::Register
void Register(const char *usageString)
Register a run-time parameter.
Definition parametersystem.hpp:292
Opm::Parameters::Get
auto Get(bool errorIfNotRegistered=true)
Retrieve a runtime parameter.
Definition parametersystem.hpp:187
pvsboundaryratevector.hh
Implements a rate vector on the boundary for the fully implicit compositional multi-phase primary var...
pvsextensivequantities.hh
Contains all data which is required to calculate all fluxes at a flux integration point for the prima...
pvsindices.hh
The indices for the compositional multi-phase primary variable switching model.
pvsintensivequantities.hh
Contains the quantities which are are constant within a finite volume in the compositional multi-phas...
pvslocalresidual.hh
Element-wise calculation of the local residual for the compositional multi-phase primary variable swi...
pvsnewtonmethod.hh
A newton solver which is specific to the compositional multi-phase PVS model.
pvsprimaryvariables.hh
Represents the primary variables used in the primary variable switching compositional model.
pvsproperties.hh
Declares the properties required for the compositional multi-phase primary variable switching model.
pvsratevector.hh
Implements a vector representing molar, mass or volumetric rates.
Opm::Parameters::PvsVerbosity
The verbosity of the model (0 -> do not print anything, 2 -> spam stdout a lot).
Definition pvsmodel.hh:168
Opm::Properties::BoundaryRateVector
Type of object for specifying boundary conditions.
Definition fvbaseproperties.hh:119
Opm::Properties::EnableDiffusion
Enable diffusive fluxes?
Definition multiphasebaseproperties.hh:91
Opm::Properties::EnableEnergy
Specify whether energy should be considered as a conservation quantity or not.
Definition multiphasebaseproperties.hh:87
Opm::Properties::ExtensiveQuantities
Data required to calculate a flux over a face.
Definition fvbaseproperties.hh:149
Opm::Properties::Indices
Enumerations used by the model.
Definition multiphasebaseproperties.hh:51
Opm::Properties::IntensiveQuantities
The secondary variables within a sub-control volume.
Definition fvbaseproperties.hh:133
Opm::Properties::LocalResidual
The type of the local residual function.
Definition fvbaseproperties.hh:94
Opm::Properties::Model
The type of the model.
Definition basicproperties.hh:88
Opm::Properties::NewtonMethod
Specifies the type of the actual Newton method.
Definition newtonmethodproperties.hh:32
Opm::Properties::PrimaryVariables
A vector of primary variables within a sub-control volume.
Definition fvbaseproperties.hh:130
Opm::Properties::PvsMoleFractionsBaseWeight
The basis value for the weight of the mole fraction primary variables.
Definition pvsproperties.hh:45
Opm::Properties::PvsPressureBaseWeight
The basis value for the weight of the pressure primary variable.
Definition pvsproperties.hh:39
Opm::Properties::PvsSaturationsBaseWeight
The basis value for the weight of the saturation primary variables.
Definition pvsproperties.hh:42
Opm::Properties::RateVector
Vector containing volumetric or areal rates of quantities.
Definition fvbaseproperties.hh:116
Opm::Properties::TTag::PvsModel
The type tag for the isothermal single phase problems.
Definition pvsmodel.hh:79
vtkcompositionmodule.hpp
VTK output module for the fluid composition.
vtkdiffusionmodule.hpp
VTK output module for quantities which make sense for models which incorperate molecular diffusion.
vtkenergymodule.hpp
VTK output module for quantities which make sense for models which assume thermal equilibrium.
vtkphasepresencemodule.hpp
VTK output module for the fluid composition.