HOWTO use activity-based Phases

Activity-based phases such as PhaseActivity besides mass balances as the basic Phase objects can calculate activity coefficients and activities.

The model user should not normally handle low-level objects such as phases, but activity phases can be used to fit experimental data or to check binary parameters.

So here is a tutorial to show how you can operate on them.

Start from the HOWTO manipulate phases, and perform these steps:

  1. in the #include section, replace the header file PhaseIdeal with the followings:

     #include <libpf/phases/ActivityNRTL.h>
     #include <libpf/phases/PhaseActivity.h>
    
  2. in the main function, remove all the code between initializeLibpf(); and uninitializeLibpf(); statements and replace it as follows:

  3. define the components you need - in this example, water and ethylhexanol:

     components.addcomp(new purecomps::water);
     components.addcomp(new purecomps::Ethylhexanol("ETEX"));
    
  4. add the phases to be used, one for a water-rich liquid and one for an organic-rich liquid:

     PhaseActivity<Activity::NRTL1> wateryPhase;
     PhaseActivity<Activity::NRTL1> organicPhase;
    

    the phase type you use will determine the models it uses for the calculation of the fugacity - in this example we will use PhaseActivity parameterized by Activity::NRTL1, which calculates the fugacity with the activity coefficient model NRTL (Non Random Two Liquids), in the original temperature-independent formulation, useful to reproduce DECHEMA data:

    $tau_{i,j}=B_{i,j}/T$

  5. NRTL1 activity phases require to set the NRTL parameters as follow:

     Activity::NRTL1::setB(0, 1, 2371.13625, 173.11433);
     Activity::NRTL1::setA(0, 1, 0.2);
    
  6. Fill in phases molar flow rate and molar fraction composition (mass fraction or single component mass or molar flow are also optionally available):

     wateryPhase.ndot.set(100.0, "kmol/s");
     wateryPhase.clearcomposition(MassBalanceMode::Nx);
     wateryPhase.x[0].set(0.9998394314);
     wateryPhase.x[1].set(one - wateryPhase.x[0]);
     wateryPhase.calculate();
    
     organicPhase.ndot.set(100.0, "kmol/s");
     organicPhase.clearcomposition(MassBalanceMode::Nx);
     organicPhase.x[0].set(0.14757088);
     organicPhase.x[1].set(one - organicPhase.x[0]);
     organicPhase.calculate();
    

    Note: the ‘calculate()’ method is required in order to prepare phase compositions.

  7. Set state conditions (in this case only temperature is required) and prepare the phase properties calculation (this initializes certain internal temperature-dependent data structures):

     Value T(20.0+273.15,"K");
     wateryPhase.prepare(T, wateryPhase.x);
     organicPhase.prepare(T, organicPhase.x);
    
  8. Finally print some results:

     diagnostic(0, "Watery liquid phase:" << wateryPhase);
     diagnostic(0, "Organic liquid phase: " << organicPhase);
    
     diagnostic(0, "Activity coefficient (gamma)\tWater\tETEX");
     diagnostic(0, "watery\t" << wateryPhase.gamma(0).val() << "\t" << wateryPhase.gamma(1).val());
     diagnostic(0, "organic\t" << organicPhase.gamma(0).val() << "\t" << organicPhase.gamma(1).val());
    
     diagnostic(0, "Activity (gamma*x)\tWater\tETEX");
     diagnostic(0, "watery\t" << wateryPhase.gamma(0).val() * wateryPhase.x[0] << "\t" << wateryPhase.gamma(1).val() * wateryPhase.x[1]);
     diagnostic(0, "organic\t" << organicPhase.gamma(0).val() * organicPhase.x[0] << "\t" << organicPhase.gamma(1).val() * organicPhase.x[1]);
    
     diagnostic(0, "Water activity difference between the two phases:   " << wateryPhase.gamma(0).val() * wateryPhase.x[0]  - organicPhase.gamma(0).val() * organicPhase.x[0] );
     diagnostic(0, "ETEX activity difference between the two phases:   " << wateryPhase.gamma(1).val() * wateryPhase.x[1]  - organicPhase.gamma(1).val() * organicPhase.x[1] );
    

This is the expected output:

LIBPF is correctly activated for site it.libpf_1.0 on this computer.
main * Entered
* ****************** LIBPF 01.00.2338 [2016/03/20 20:20:19] ******************
* (C) Copyright 2004-2016 Paolo Greppi simevo s.r.l.
* ****************************************************************************
* All rights reserved; do not distribute without permission.
* ****************************************************************************

main * Watery liquid phase:{
  "fullTag": "",
  "type": "PhaseActivity<NRTL1>",
  "id": 0,
  "parent": 0,
  "I": {
    "nCalculations": "0"
  },
  "Q": {
    "AMW": "18.0333181573 kmol^-1 kg",
    "Cp": "232.6 kmol^-1 m^2 kg K^-1 s^-2",
    "H": "1 kmol^-1 m^2 kg s^-2",
    "S": "0 kmol^-1 m^2 kg K^-1 s^-2",
    "cp": "4186.8 m^2 K^-1 s^-2",
    "fraction": "1 ",
    "g": "0 m^2 s^-2",
    "h": "18 m^2 s^-2",
    "mdot": "1803.33181573 kg s^-1",
    "mdotcomps[0]": "1801.24073085 kg s^-1",
    "mdotcomps[1]": "2.0910848778 kg s^-1",
    "ndot": "100 kmol s^-1",
    "ndotcomps[0]": "99.98394314 kmol s^-1",
    "ndotcomps[1]": "0.01605686 kmol s^-1",
    "rho": "1000 m^-3 kg",
    "s": "0 m^2 K^-1 s^-2",
    "v": "0.018 kmol^-1 m^3",
    "vdot": "1.80333181573 m^3 s^-1",
    "w[0]": "0.998840432548 ",
    "w[1]": "0.00115956745152 ",
    "x[0]": "0.9998394314 ",
    "x[1]": "0.0001605686 "
  },
  "SV": {
    "errors": [],
    "warnings": []
  }
}
main * Organic liquid phase: {
  "fullTag": "",
  "type": "PhaseActivity<NRTL1>",
  "id": 0,
  "parent": 0,
  "I": {
    "nCalculations": "0"
  },
  "Q": {
    "AMW": "113.670377972 kmol^-1 kg",
    "Cp": "232.6 kmol^-1 m^2 kg K^-1 s^-2",
    "H": "1 kmol^-1 m^2 kg s^-2",
    "S": "0 kmol^-1 m^2 kg K^-1 s^-2",
    "cp": "4186.8 m^2 K^-1 s^-2",
    "fraction": "1 ",
    "g": "0 m^2 s^-2",
    "h": "18 m^2 s^-2",
    "mdot": "11367.0377972 kg s^-1",
    "mdotcomps[0]": "265.853367446 kg s^-1",
    "mdotcomps[1]": "11101.1844298 kg s^-1",
    "ndot": "100 kmol s^-1",
    "ndotcomps[0]": "14.757088 kmol s^-1",
    "ndotcomps[1]": "85.242912 kmol s^-1",
    "rho": "1000 m^-3 kg",
    "s": "0 m^2 K^-1 s^-2",
    "v": "0.018 kmol^-1 m^3",
    "vdot": "11.3670377972 m^3 s^-1",
    "w[0]": "0.0233880956666 ",
    "w[1]": "0.976611904333 ",
    "x[0]": "0.14757088 ",
    "x[1]": "0.85242912 "
  },
  "SV": {
    "errors": [],
    "warnings": []
  }
}
main * Activity coefficient (gamma)	Water	ETEX
main * watery	1	5431.61
main * organic	6.77532	1.02313
main * Activity (gamma*x)	Water	ETEX
main * watery	0.999840493231 	0.872145633524
main * organic	0.999840491384 	0.872145463159
main * Water activity difference between the two phases:   1.84647752643e-09
main * ETEX activity difference between the two phases:   1.70365110796e-07

How to get on

  1. check the phases chapter in the LIBPF® SDK Classes overview

  2. Proceed to the stream manipulation tutorial