Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove penalization in fugacity computations and improve Gibbs energy calculation #5

Draft
wants to merge 64 commits into
base: master
Choose a base branch
from

Conversation

volpatto
Copy link
Member

RES-166

volpatto and others added 30 commits January 29, 2021 16:46
This is an intermediate step required to define a BIP function wrapper, since the result has to provide k, kT and kTT as attributes
This default values allow the user to provide, for instance, only k values without the need to define kT and kTT when there is no T dependency
Asserts to check that kT and kTT are empty are now added
To compare such results, a custom database is defined containing the hydrocarbon data. See tests/data/hydrocarbons.xml
Diego Tavares Volpatto added 4 commits March 9, 2021 22:05
The pip option --force-reinstall is passed in order to reinstall reaktoro python bindings in every build
Such tests are failing due to the changes in the fugacity calculations. The workaround using a penalization is now removed.

(RES-166)
Comment on lines 12 to 14
- jupyter
- jupyter_contrib_nbextensions
- jupyter_nbextensions_configurator
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be removed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

ChemicalScalar Z(nspecies);
// Z = selectCompressibilityFactorByGibbsEnergy(nspecies, Zs, P, T, x, abar, bbar, abarT, amix, amixT, bmix, A, B, C, epsilon, sigma);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm.. I don't remember why I commented here. Needs investigation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great ideia,
Selecting the Z factor based on the GibbsEnergy seems to be much more consistent instead of getting min values if is liquid and max if it is gas.
But I realy don't know what would happen if we were computing properties of a liquid and selectCompressibilityFactorByGibbsEnergy return the max(Z1, Z2). Especialy considering that the output will say to the user that this phase is liquid but their properties will be computed as they were a gas 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a great idea but, since it will affect the selection of Z even for problems that has only Water and Gas, the use of selectCompressibilityFactorByGibbsEnergy broke more than 80 test :/
That made me decided to keep this line commented and make the selection of Z based on min and max of the computed Z values.

I also got some great results of test_pedersen63.py by making PhaseIdentificationMethod = PhaseIdentificationMethod:None which makes the solver not penalize any phase

image
image
image
image

Copy link
Member

@alexandrebbruno alexandrebbruno left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done,
I only added some minor comments which could add more value to the work

Reaktoro/Thermodynamics/EOS/CubicEOS.hpp Show resolved Hide resolved
@@ -0,0 +1,380 @@
import numpy as np
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job,
I think that would be nice to add the reference used to make this test. Maybe as documentation in one of the tests

@@ -0,0 +1,375 @@
import numpy as np
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

tests/test_oil_equilibrium.py Show resolved Hide resolved
ChemicalScalar Z(nspecies);
// Z = selectCompressibilityFactorByGibbsEnergy(nspecies, Zs, P, T, x, abar, bbar, abarT, amix, amixT, bmix, A, B, C, epsilon, sigma);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great ideia,
Selecting the Z factor based on the GibbsEnergy seems to be much more consistent instead of getting min values if is liquid and max if it is gas.
But I realy don't know what would happen if we were computing properties of a liquid and selectCompressibilityFactorByGibbsEnergy return the max(Z1, Z2). Especialy considering that the output will say to the user that this phase is liquid but their properties will be computed as they were a gas 🤔

@volpatto volpatto marked this pull request as draft June 14, 2021 01:22
Z.val = *std::max_element(cubicEOS_roots.begin(), cubicEOS_roots.end());
else
Z.val = *std::min_element(cubicEOS_roots.begin(), cubicEOS_roots.end());
Z = selectCompressibilityFactorByGibbsEnergy(nspecies, Zs, P, T, x, abar, bbar, abarT, amix, amixT, bmix, A, B, C, epsilon, sigma);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note that I have enabled this part, so more tests are now failing.

Comment on lines 497 to 500
// When using selectCompressibilityFactorByGibbsEnergy, the switch-case below
// is not necessary.
// TODO: remove switch-case if selectCompressibilityFactorByGibbsEnergy is used
auto identified_phase_type = input_phase_type;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please have a look on this. The cubic EoS model is attributed to a phase. When calculating Z for such phase, a cubic equation is solved and the root is selected according to Gibbs Energy criterion, so there is no need to identify the phase here anymore. For thermodynamic consistency, the Z related to the minimum Gibbs energy is always selected despite of the phase.

@volpatto
Copy link
Member Author

volpatto commented Jul 1, 2021

Nicely done,
I only added some minor comments which could add more value to the work

Thanks!

@alexandrebbruno alexandrebbruno changed the title [WIP] Remove penalization in fugacity computations and improve Gibbs energy calculation Remove penalization in fugacity computations and improve Gibbs energy calculation Jul 5, 2021
result.ln_fugacity_coefficients.fill(100.0);
return result;
}
if (identified_phase_type != input_phase_type) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems there is more indentation than is needed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's because spaces were converted to tabs (probably because of editor configuration). It seems that these lines 524-538 could be reset.

@@ -321,6 +321,13 @@ auto ChemicalProperties::phaseSpecificVolumes() const -> ChemicalVector
return phaseAmounts()/phaseMasses() % phaseMolarVolumes();
}

auto ChemicalProperties::phaseCompressibilityFactors() const -> ChemicalVector
{
const auto& R = universalGasConstant;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am curious. Why did you use const auto& since universalGasConstant is just a const double? Maybe const auto fit better here.

{
const double R = universalGasConstant;

const double almost_zero = 1e-20;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix indentation


// Calculate the integration factor I
ChemicalScalar I;
if(std::abs(epsilon - sigma) > almost_zero) I = log((Z + sigma*beta)/(Z + epsilon*beta))/(sigma - epsilon);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO, assignments like this would be more legible if you use a ternary operator, or even curly brackets in each block.


// Calculate the integration factor I for each component
ChemicalScalar Ii;
if(std::abs(epsilon - sigma) > almost_zero) Ii = I + ((Zi + sigma*betai)/(Z + sigma*beta) - (Zi + epsilon*betai)/(Z + epsilon*beta))/(sigma - epsilon);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

{
auto xi = x[i];
auto fi = computeSpeciesFugacity(P, T, xi, abar[i], bbar[i], abarT[i], amix, amixT, bmix, A, B, C, Z, epsilon, sigma);
G_normalized += xi.val * log(fi).val;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix indentation

Zs.push_back(ChemicalScalar(nspecies, cubicEOS_roots[0]));
}
else if (cubic_size == 2)
{
Zs.push_back(ChemicalScalar(nspecies, cubicEOS_roots[0]));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid temporary objects, use emplace_back instead of push_back

ChemicalScalar Z(nspecies);

// Selecting compressibility factor - Z_liq < Z_gas
//TODO: study the possibilty to use selectCompressibilityFactorByGibbsEnergy for Z selection
Copy link

@OtavioPellicano OtavioPellicano Jul 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally TODO must be followed by the Task number

if (isvapor)
Z.val = *std::max_element(cubicEOS_roots.begin(), cubicEOS_roots.end());
else
Z.val = *std::min_element(cubicEOS_roots.begin(), cubicEOS_roots.end());
Z.val = *std::min_element(cubicEOS_roots.begin(), cubicEOS_roots.end());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix indentation


solver.setOptions(options)

state = ChemicalState(system)
state.setSpeciesAmounts(0.001) # start will all having 0.001 moles
state.setSpeciesAmount("CH4(g)", overall_composition[0]) # overwrite amount of C1(g) (same below)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't get C1(g). That means Carbon dissociated? If so, the dissociation should be C4+, ins't it?

@@ -3,6 +3,7 @@
dependencies:
- numpy
- pandas
- matplotlib
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this one could also be removed?

solver.setOptions(options)

state = ChemicalState(system)
state.setSpeciesAmounts(0.001) # start will all having 0.001 moles
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will -> with?

auto const& T = temperature;

// Computing the values of residual Gibbs energy for all Zs
ChemicalScalar Gs;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor, but it doesn't seem necessary to have this uninitialized variable here, line 138 could be ChemicalScalar Gs = R * temperature*(Z - 1 - log(Z - beta) - q * I); or line 140 could be return R * temperature*(Z - 1 - log(Z - beta) - q * I).

return G_normalized;
}

auto selectCompressibilityFactorByGibbsEnergy(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this function unused?

result.ln_fugacity_coefficients.fill(100.0);
return result;
}
if (identified_phase_type != input_phase_type) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's because spaces were converted to tabs (probably because of editor configuration). It seems that these lines 524-538 could be reset.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants