PVT Driver
Introduction
When calibrating fluid material parameters to experimental or other reference data, it can be a hassle to launch a full flow simulation just to confirm density, viscosity, and other fluid properties are behaving as expected.
Instead, GEOS provides a PVTDriver
allowing the user to test fluid property models for a well defined set of pressure, temperature, and composition conditions.
The driver itself is launched like any other GEOS simulation, but with a particular XML structure:
./bin/geosx -i myFluidTest.xml
This driver will work for any multi-phase fluid model (e.g. black-oil, co2-brine, compositional multiphase) enabled within GEOS.
XML Structure
A typical XML file to run the driver will have several key elements. Here, we will walk through an example file included in the source tree at
src/coreComponents/unitTests/constitutiveTests/testPVT_docExample.xml
The first thing to note is that the XML file structure is identical to a standard GEOS input deck. In fact, once the constitutive block is calibrated, one could start adding solver and discretization blocks to the same file to create a proper field simulation. This makes it easy to go back and forth between calibration and simulation.
The first step is to define a parameterized fluid model to test. Here, we create a particular type of CO2-Brine mixture:
<Constitutive>
<CO2BrinePhillipsFluid
name="co2Mixture"
phaseNames="{ gas, water }"
componentNames="{ co2, water }"
componentMolarWeight="{ 44e-3, 18e-3 }"
phasePVTParaFiles="{ testPVT_data/carbonDioxidePVT.txt, testPVT_data/brinePVT.txt }"
flashModelParaFile="testPVT_data/carbonDioxideFlash.txt"/>
</Constitutive>
We also define two time-history functions for the pressure (Pascal units) and temperature (Kelvin units) conditions we want to explore.
<Functions>
<TableFunction
name="pressureFunction"
inputVarNames="{ time }"
coordinates="{ 0.0, 1.0 }"
values="{ 1e6, 50e6 }"/>
<TableFunction
name="temperatureFunction"
inputVarNames="{ time }"
coordinates="{ 0.0, 1.0 }"
values="{ 350, 350 }"/>
</Functions>
Note that the time-axis here is just a pseudo-time, allowing us to parameterize arbitrarily complicated paths through a (pressure,temperature) diagram. The actual time values have no impact on the resulting fluid properties. Here, we fix the temperature at 350K and simply ramp up pressure from 1 MPa to 50 MPa:
A PVTDriver
is then added as a Task
, a particular type of executable event often used for simple actions.
<Tasks>
<PVTDriver
name="testCO2"
fluid="co2Mixture"
feedComposition="{ 1.0, 0.0 }"
pressureControl="pressureFunction"
temperatureControl="temperatureFunction"
steps="49"
output="pvtOutput.txt"
logLevel="1"/>
</Tasks>
The driver itself takes as input the fluid model, the pressure and temperature control functions, and a “feed composition.”
The latter is the mole fraction of each component in the mixture to be tested.
The steps
parameter controls how many steps are taken along the parametric (P,T) path.
Results will be written in a simple ASCII table format (described below) to the file output
.
The logLevel
parameter controls the verbosity of log output during execution.
The driver task is added as a SoloEvent
to the event queue.
This leads to a trivial event queue, since all we do is launch the driver and then quit.
<Events
maxTime="1">
<SoloEvent
name="eventA"
target="/Tasks/testCO2"/>
</Events>
Internally, the driver uses a simple form of time-stepping to advance through the (P,T) steps.
This timestepping is handled independently of the more complicated time-stepping pattern used by physics Solvers
and coordinated by the EventManager
.
In particular, in the XML file above, the maxTime
parameter in the Events
block is an event manager control, controlling when/if certain events occur.
Once launched, the PVTDriver internally determines its own max time and timestep size using a combination of the input functions’ time coordinates and the requested number of loadsteps.
It is therefore helpful to think of the driver as an instantaneous event (from the event manager’s point of view), but one which has a separate, internal clock.
Parameters
The key XML parameters for the PVTDriver are summarized in the following table:
XML Element: PVTDriver
Name |
Type |
Default |
Description |
---|---|---|---|
baseline |
path |
none |
Baseline file |
feedComposition |
real64_array |
required |
Feed composition array [mol fraction] |
fluid |
groupNameRef |
required |
Fluid to test |
logLevel |
integer |
0 |
Log level |
name |
groupName |
required |
A name is required for any non-unique nodes |
output |
string |
none |
Output file |
outputCompressibility |
integer |
0 |
Flag to indicate that the total compressibility should be output |
outputMassDensity |
integer |
0 |
Flag to indicate that the mass density of each phase should be output |
outputPhaseComposition |
integer |
0 |
Flag to indicate that phase compositions should be output |
pressureControl |
groupNameRef |
required |
Function controlling pressure time history |
steps |
integer |
required |
Number of load steps to take |
temperatureControl |
groupNameRef |
required |
Function controlling temperature time history |
Output Format
The output
key is used to identify a file to which the results of the simulation are written.
If this key is omitted, or the user specifies output="none"
, file output will be suppressed.
The file is a simple ASCII format with a brief header followed by test data:
# column 1 = time
# column 2 = pressure
# column 3 = temperature
# column 4 = density
# columns 5-6 = phase fractions
# columns 7-8 = phase densities
# columns 9-10 = phase viscosities
0.0000e+00 1.0000e+06 3.5000e+02 1.5581e+01 1.0000e+00 4.1138e-11 1.5581e+01 1.0033e+03 1.7476e-05 9.9525e-04
2.0408e-02 2.0000e+06 3.5000e+02 3.2165e+01 1.0000e+00 4.1359e-11 3.2165e+01 1.0050e+03 1.7601e-05 9.9525e-04
4.0816e-02 3.0000e+06 3.5000e+02 4.9901e+01 1.0000e+00 4.1563e-11 4.9901e+01 1.0066e+03 1.7778e-05 9.9525e-04
...
Note that the number of columns will depend on how many phases and components are present.
In this case, we have a two-phase, two-component mixture.
The total density is reported in column 4, while phase fractions, phase densities, and phase viscosities are reported in subsequent columns.
If the outputCompressibility
flag is activated, an extra column will be added for the total fluid compressibility after the density.
This is defined as where is the total density.
If the outputMassDensity
flag is activated, extra columns will be added for the mass density of each phase.
The number of columns will also depend on whether the outputPhaseComposition
flag is activated or not. If it is activated, there will be an extra column for the mole fraction of each component in each phase.
The phase order will match the one defined in the input XML (here, the co2-rich phase followed by the water-rich phase).
This file can be readily plotted using any number of plotting tools. Each row corresponds to one timestep of the driver, starting from initial conditions in the first row.
Unit Testing
The development team also uses the PVTDriver to perform unit testing on the various fluid models within GEOS.
The optional argument baseline
can be used to point to a previous output file that has been validated (e.g. against experimental benchmarks or reference codes).
If such a file is specified, the driver will perform a testing run and then compare the new results against the baseline.
In this way, any regressions in the fluid models can be quickly identified.
Developers of new models are encouraged to add their own baselines to src/coreComponents/constitutive/unitTests
.
Adding additional tests is straightforward:
1. Create a new xml file for your test in src/coreComponents/constitutive/unitTests
or (easier) add extra blocks to the existing XML at src/coreComponents/constitutive/unitTests/testPVT.xml
.
For new XMLs, we suggest using the naming convention testPVT_myTest.xml
, so that all tests will be grouped together alphabetically.
Set the output
file to testPVT_myTest.txt
, and run your test.
Validate the results however is appropriate.
If you have reference data available for this validation, we suggest archiving it in the testPVT_data/
subdirectory, with a description of the source and formatting in the file header.
Several reference datasets are included already as examples.
This directory is also a convenient place to store auxiliary input files like PVT tables.
2. This output file will now become your new baseline.
Replace the output
key with baseline
so that the driver can read in your file as a baseline for comparison.
Make sure there is no remaining output
key, or set output=none
, to suppress further file output.
While you can certainly write a new output for debugging purposes, during our automated unit tests we prefer to suppress file output.
Re-run the driver to confirm that the comparison test passes.
3. Modify src/coreComponents/constitutive/unitTests/CMakeLists.txt
to enable your new test in the unit test suite.
In particular, you will need to add your new XML file to the existing list in the gtest_pvt_xmls
variable.
Note that if you simply added your test to the existing testPVT.xml
file, no changes are needed.
set( gtest_pvt_xmls
testPVT.xml
testPVT_myTest.xml
)
Run
make
in your build directory to make sure the CMake syntax is correctRun
ctest -V -R PVT
to run the PVT unit tests. Confirm your test is included and passes properly.
If you run into troubles, do not hesitate to contact the development team for help.