Cantera / enhancements

Repository for proposed and ongoing enhancements to Cantera
11 stars 5 forks source link

Soave-Redlich-Kwong (SRK) EOS #159

Open corykinney opened 1 year ago

corykinney commented 1 year ago

Abstract

Cantera currently offers the Redlich-Kwong and Peng-Robinson equations of state. Addition of a Soave-Redlich-Kwong model should not be too difficult as the implementation would largely parallel the other two equations of state.

Motivation

Addition of SRK support would allow for chemical kinetics simulations with Cantera for conditions and mixtures that are best modeled by this EOS (for example, supercritical CO2 cycle conditions).

I've started working on this over at corykinney:SRK but it'll likely take me a while as I'm not as experienced with C++ and thus I'll be leaning quite heavily on the PengRobinson implementation.

bryanwweber commented 1 year ago

@corykinney Awesome, thanks for taking this on! Please feel free to reach out directly to me if you want to set up a meeting to go over the code structure or how to make additions to C++ 😄

corykinney commented 1 year ago

@bryanwweber Thanks! I will most likely take you up on that once I have a chance to experiment a bit more and figure out the right questions to ask.

Regarding the input file structure, I see on the example yaml files for the PR and RK equations of state that the a and b values are specified by the user with the model hard-coded as either Redlich-Kwong or Peng-Robinson. Is it expected that additional models would follow this approach?

I would think it would be most flexible if the critical temperature, pressure (and optionally acentric factor) were included in the yaml file and the user could set the equation of state upon loading the mechanism so that the files could be reused as much as possible, the a and b values required by each model would then be calculated from the critical properties. Otherwise, if I wanted to compare predictions from multiple models, I'd have to make multiple input files originating from the same critical property data to begin with.

decaluwe commented 1 year ago

Hi @corykinney Glad you are tacklling this! The code is set up to calculate a and b, as needed, from critical properties. You can see here where the input file is processes and looks for either an a and b value first, then looks for critical-parameters here. We also created a database of known or estimated critical parameters (crit-properties.yaml) for a wide range of species, so if no inputs are given we try to look them up as a last-ditch effort.

corykinney commented 1 year ago

@decaluwe Thanks for the explanation and the links to the code segments. I was aware of the crit-properties.yaml database lookup, but didn't realize that instead of specifiying a and b for the model that you could also specify the critical-parameters in the file instead based on looking at the example files.

Do you have any thoughts on reusing input files and specifying equation of state when the Solution is initialized? I think it would be very useful to enable comparisons across EOS. For example, performing IDT simulations with a mechanism and doing something like:

gas_ideal = ct.Solution("input.yaml", eos="ideal")
gas_PR = ct.Solution("input.yaml", eos="PR")
decaluwe commented 1 year ago

I certainly see the value there. It would be a slight departure from current Cantera norms. Currently, to do this, you'd have a phase declaration for each phase, and just load that phase. Which is not a huge amount of extra work, if you just have the repeat the phase declarations in the input file, but can re-use the same species definitions. I actually don't know if this is possible, currently - can the ideal gas model use a species defined for a real gas phase? I'll try and look into it, when I've got a minute.

ischoegl commented 1 year ago

Likewise thanks for taking this on! I am linking #20 and #107 as there was some discussion that is pertinent. YAML does support multiple thermo models in a single file (the implemented version is option 4 in #20)

corykinney commented 1 year ago

YAML does support multiple thermo models in a single file (the implemented version is option 4 in #20)

@ischoegl So if the currenty YAML implementation supports multiple thermo models, would the current approach require copies of the file with different values for the thermo key at the top of the file? So if I wanted to compare equations of state, I'd either have to keep multiple copies of the file or do some file IO to automatically modify it before initializing the Solution objects?

Also, as a side note, I'll take an approach similar to @gkogekar did in documenting her approach with PengRobinson, which I will try to keep updated at corykinney/Soave-Redlich-Kwong. Due to the similarities between the SRK and PR equations, it looks like I should be able to reuse a lot of the code that was written there.

decaluwe commented 1 year ago

Hi @corykinney -- as in @gkogekar's input file, there, I think the prefered approach is to just have one input file. In this file, each species is defined just once, and each species definition can contain all the necessary info for multiple EoS options.

Then in the phases section, you can have a phase declaration for each type of phase. In your model file, then, you can load each phase separately:

gas_RK = ct.Solution('input.yaml', 'RK_phase')
gas_SRK = ct.Solution('input.yaml', 'SRK_phase')

where RK_phase and SRK_phase, respectively, are the names given in the yaml file for the Redlich-Kwong and Soave-Redlich-Kwong phase declarations, for example.

Hopefully I'm understanding your question correctly - let me know, if not!

speth commented 1 year ago

To provide a concrete example, the following is how you can currently define a species that can be used in either a Redlich-Kwong or Peng-Robinson thermo model:

- name: H2O
  composition: {H: 2, O: 1}
  thermo:
    model: NASA7
    temperature-ranges: [200.0, 1000.0, 3500.0]
    data:
    - [4.19864056, -0.0020364341, 6.52040211e-06, -5.48797062e-09, 1.77197817e-12,
      -30293.7267, -0.849032208]
    - [3.03399249, 0.00217691804, -1.64072518e-07, -9.7041987e-11, 1.68200992e-14,
      -30004.2971, 4.9667701]
  critical-parameters:
    critical-temperature: 647.096
    critical-pressure: 22.064 MPa
    acentric-factor: 0.344
  equation-of-state:
  - model: Peng-Robinson
    binary-a:
      H2: 4 bar*cm^6/mol^2
      CO2: 7.897e7 bar*cm^6/mol^2
  - model: Redlich-Kwong
    a: [1.14972e+14, 0]
    b: 166.7180412

This definition would also work if either the critical-parameters or equation-of-state field was removed (but not both). The model-specific coefficients are used preferentially, with the critical state parameters being used as a fallback. This is the format that is described in the YAML API Docs. You should be able to achieve the same for SRK if you follow structure of PengRobinson::initThermo.

For phase definitions, to enable the use like in @decaluwe's example, the phases section of the input file would look something like:

phases:
- name: RK_phase
  thermo: Redlich-Kwong
  kinetics: gas
  state:
    T: 300.0
    P: 1.01325e+05
- name: SRK_phase
  thermo: Soave-Redlich-Kwong
  kinetics: gas
  state:
    T: 300.0
    P: 1.01325e+05

Given the relatively small differences between the R-K and SRK equations of state, I hope this implementation can be done in a way that keeps as much functionality as possible in a common base class and avoids copy-pasting large chunks of the existing R-K implementation.

corykinney commented 1 year ago

@decaluwe @speth Thanks for the information, I didn't know it could be done that way! That's more or less what I was asking if was possible (aside maybe the explicit definition of compatible phases, but that's not inconvenient).

Given the relatively small differences between the R-K and SRK equations of state, I hope this implementation can be done in a way that keeps as much functionality as possible in a common base class and avoids copy-pasting large chunks of the existing R-K implementation.

Right now I'm thinking about getting it working through large amounts of copying with the idea of writing test cases and then working back toward maybe a CubicBase class that could remove the overlap between existing PengRobinson and RedlichKwongMFTP classes (on a related note, I think dropping the MFTP and just having RedlichKwong would be nice, but I'm sure there was probably a reason it wasn't named that way to start with), but that would be a ways away. The SRK is really closer to the PR than the original RK in terms of implementation since they share the very similar temperature dependent parameter $\alpha (T)$.

speth commented 1 year ago

As you may have already noticed, there is a common base class used by the PengRobinson and RedlichKwongMFTP classes, which is MixtureFugacityTP. As confusing as this name is (at least to me), I think it's probably a fine place for any common functionality that's relevant for all of these models. For instance, this is already where the solver for the cubic EOS is implemented.

I'm not opposed to dropping the incomprehensible suffix from RedlichKwong (it just describes the class inheritance, i.e. mixture fugacity thermo phase), but that does require some care to provide a smooth transition, and I doubt it's worth the effort.

corykinney commented 1 year ago

@speth so it can be assumed that the MixtureFugacityTP will only be used by cubic equations of state and thus it would be safe to put all common code there?

speth commented 1 year ago

At present, I think that's probably a safe assumption.