COSMO-RS¶
COSMO-RS can be run from PLAMS using the CRSJob class and the corresponding CRSResults,
both respectively being subclasses of SCMJob and SCMResults.
There are three ways to define a CRS job:
Input representation
|
+-- Settings
| |
| +-- job = CRSJob(settings=settings)
|
+-- typed CRS model
| |
| +-- job = CRSJob(settings=crs)
|
+-- CRS input builder
|
+-- job = builder.to_job()
| [equivalent to CRSJob(settings=builder.to_settings())]
|
+-- settings = builder.to_settings()
| +-- job = CRSJob(settings=settings)
|
+-- crs = builder.to_inputs()
+-- job = CRSJob(settings=crs)
For most workflows, use CRSJob.input_builder() followed by
builder.to_job(). Use to_settings() or to_inputs() when you need
to inspect or modify the generated input before creating the job.
Note
There is also a tutorial showing full code examples available in the COSMO-RS documentation. There are several templates available that can easily be customized for other problem types, workflows, etc.
Input builders¶
Use CRSJob.input_builder() to create a property-specific builder. The
builder provides the input keys, compound roles, and calculation modes
supported by the selected property type.
Basic example¶
The following example creates and runs a pure sigma-profile calculation
with CRSJob.input_builder():
from scm.plams import CRSJob
builder = CRSJob.input_builder("PURESIGMAPROFILE", method="COSMO-RS")
builder.nprofile = 50
builder.sigmamax = 0.025
builder.add_compound_from_adfcrs_database("Water.coskf")
job = builder.to_job()
results = job.run()
This builder generates the following COSMO-RS input:
method COSMO-RS
compound /path/to/file.coskf
end
property puresigmaprofile
nprofile 50
sigmamax 0.025
end
Configuring the input builder¶
The input builder is configured through the property type, method, mode, and compounds.
builder = CRSJob.input_builder("SOLUBILITY")
builder.method = "COSMO-RS"
builder.mode = "solid"
builder.temperature = 250
builder.add_solvent_from_adfcrs_database("Water.coskf", frac1=1.0)
builder.add_solute_from_adfcrs_database("Benzene.coskf", meltingpoint=278.7, hfusion=2.37)
Inspecting and setting builder input¶
Use builder.describe() to inspect the available input keys, their types,
units, and descriptions, as well as supported modes and required keys:
for line in builder.describe(include_values=True):
print(line)
The output is similar to:
SOLUBILITY: Solubility of solutes in a solvent mixture or under gas-pressure conditions.
method [top_level]: COSMO-RS
densitysolvent [property] float [kg/L]: Density of the solvent. value: None
massfraction [top_level] bool: Use mass fractions; by default, fractions are interpreted as molar fractions. value: None
pressure [top_level] float_list [bar]: Pressure value: None
temperature [top_level] float_list [Kelvin]: Temperature value: 250
mode: solid, liquid, gas
compound_keys [compound]: frac1, density, meltingpoint, hfusion, cpfusion, pvap, tvap, vp_equation, vp_params
required_keys [top_level]: temperature
required_keys [compound: solvent]: frac1
required_keys [compound: solute]: meltingpoint, hfusion
hint [densitysolvent, density]: Used for molar-volume estimates, volume-based solubility, and Henry's-law results; falls back to COSMO volume estimates.
hint [meltingpoint, hfusion, cpfusion]: Used for solid-solute fusion corrections; the heat capacity is optional.
hint [pvap, tvap, vp_equation, vp_params]: Used for gas-phase pseudochemical potential corrections in VLE, flash, and Henry's-law calculations.
The labels indicate where inputs belong and which values are required:
[property]identifies a key in thePROPERTYblock of the CRS input.[top_level]identifies a key at the top level of the CRS input.modelists the calculation modes supported by the selected property.compound_keys [compound]lists the compound keys that affect the result for the selected property type.required_keyslists mandatory keys for the current property, mode, and compound role. Other listed keys are optional.hintgives additional guidance for selected inputs, such as when they are used or how to choose their values.
Use include_values=True to also show the current builder values.
A value of None indicates that the input has not been set on the builder.
Use builder.describe(include_compound_details=True) to also show the
types, units, and descriptions of compound keys.
Set values directly on the builder. For gas-phase solubility, set the temperature, specify the solute partial pressure in bar, optionally provide the solvent density in kg/L, and select gas mode:
builder.mode = "gas"
builder.temperature = 298.15
builder.pressure = 1.01325
builder.densitysolvent = 1.0
Changing the mode may change the required keys. Call builder.describe()
again to inspect the updated requirements.
Calculation modes¶
The following table summarizes the supported modes and their defaults. Properties not listed here do not support a calculation mode.
Property type |
Available modes |
|---|---|
|
|
|
|
|
|
|
|
|
|
Adding compounds¶
The available compound roles and the number of compounds required depend on the selected property type.
The builder checks compound roles and count limits when compounds are added, and validates required counts and data when generating input.
Pass include_compounds=False to to_settings() or to_inputs()
to omit compounds and skip compound validation during conversion.
For mixture properties, use add_compound() with a COSKF file path or
add_compound_from_adfcrs_database() with an ADFCRS database filename:
from scm.plams import CRSJob
builder = CRSJob.input_builder("TERNARYMIX", temperature=298.15)
builder.add_compound_from_adfcrs_database("Water.coskf")
builder.add_compound_from_adfcrs_database("Ethanol.coskf")
builder.add_compound_from_adfcrs_database("Benzene.coskf")
settings = builder.to_settings()
For solvent and solute roles, use add_solvent() and add_solute() or
add_solvent_from_adfcrs_database and add_solute_from_adfcrs_database:
builder = CRSJob.input_builder("ACTIVITYCOEF", temperature=298.15)
builder.add_solvent_from_adfcrs_database("Water.coskf", frac1=1.0)
builder.add_solute_from_adfcrs_database("Benzene.coskf")
crs = builder.to_inputs()
Supported methods¶
The builder uses COSMO-RS by default. Use builder.method to select
another method. To list the supported methods:
print(CRSJob.methods())
Each method uses its default parameter set. To use a different parameter set, apply a preset to the generated input as described in Applying method parameter presets.
Creating and running a job¶
Use to_job() when no additional settings are required before running the
job:
job = builder.to_job()
results = job.run()
Converting to Settings¶
Use to_settings() when you want to inspect or modify the generated PLAMS
Settings object before creating the job:
settings = builder.to_settings()
job = CRSJob(settings=settings)
results = job.run()
Converting to typed CRS inputs¶
Use CRSInputBuilder.to_inputs() for advanced workflows. It converts the
builder state to a typed scm.inputs.CRS model, which gives you access
to CRS input options that are not exposed directly by the property-specific
builder.
For example, the following code changes an LLE convergence tolerance and enables debug output:
from scm.plams import CRSJob
builder = CRSJob.input_builder("LLE", temperature=298.15)
builder.add_compound_from_adfcrs_database("Water.coskf", frac1=0.33)
builder.add_compound_from_adfcrs_database("Ethanol.coskf", frac1=0.33)
builder.add_compound_from_adfcrs_database("Benzene.coskf", frac1=0.34)
crs = builder.to_inputs()
crs.TECHNICAL.LLE.eps_g = 1.0e-5
crs.TECHNICAL.LLE.debug = True
job = CRSJob(settings=crs)
results = job.run()
The object returned by to_inputs() is an independent
scm.inputs.CRS model. Changes to this object do not update the builder.
Create the job from the modified model, as shown above, instead of calling
builder.to_job().
For a general introduction to typed input models, see the “AMS input models” Python example in the AMS documentation.
Applying method parameter presets¶
Each CRS method uses a default parameter set. For example, COSMO-RS uses
adf-combi2005, and COSMOSAC2013 uses 2013-adf-xiong.
To use a different parameter set, first inspect the available presets:
from scm.plams import CRSJob
for method, parameter_sets in CRSJob.get_parameter_set_options().items():
print(method, parameter_sets)
Example output:
COSMO-RS ('adf-combi2005', 'adf-combi1998', 'adf-lei-2018', 'klamt', 'mopac-pm6')
COSMOSAC2013 ('2013-adf-xiong', '2013-adf-pure-xiong')
COSMOSACDHB ('dhb-adf-chen',)
COSMOSACDHB-MESP ('dhb-adf-mesp',)
COSMOSAC2016 ('2016-adf-chen',)
COSMOSAC2010 ('2010-hsieh',)
COSMOSAC2007 ('2007-wang',)
Select a parameter_set from the returned tuple and apply it to the CRS
input:
crs = builder.to_inputs()
CRSJob.apply_parameter_set_to_inputs(crs, "adf-lei-2018")
# Optionally override individual parameters.
crs.CRSPARAMETERS.chb = 9000.0
job = CRSJob(settings=crs)
You can apply the same parameter set to PLAMS settings:
settings = builder.to_settings()
CRSJob.apply_parameter_set_to_settings(settings, "adf-lei-2018")
settings.input.crsparameters.chb = 9000.0
job = CRSJob(settings=settings)
Both functions modify and return the supplied object. They set the method and replace its parameter blocks, removing parameter blocks that are absent from the selected preset. Other settings, including compounds and the selected property, are preserved.
ADF and CRSJob¶
A workflow is presented in the ADF and COSMO-RS workflow Python example. In this workflow, we follow the usual procedure of generating the inputs required to run COSMO-RS and COSMO-SAC calculations.
Data analysis¶
Use CRSResults.get_results() to read the results section of a .crskf
file as a dictionary. If no section is supplied, PLAMS uses the property section
from the most recent calculation.
from scm.plams import CRSJob
builder = CRSJob.input_builder("PURESIGMAPROFILE")
builder.nprofile = 50
builder.sigmamax = 0.025
builder.add_compound_from_adfcrs_database("Water.coskf")
results = builder.to_job().run()
data = results.get_results()
print(data["section"])
print(data["filename"])
print(data["chdval"])
print(data["profil"])
A complete overview of all available sections and keys can be printed from the KF file skeleton:
print(results._kf.get_skeleton())
API¶
- class CRSJob(**kwargs)[source]¶
A
SCMJobsubclass intended for running COSMO-RS jobs.- Parameters:
kwargs (Any) –
- static input_builder(property_type, *, method='COSMO-RS', mode=None, **kwargs)[source]¶
Return a property-specific CRS input builder.
The
property_typeargument selects the builder class. The returned builder validates the keys, modes, and compound roles supported by that property type.
- static apply_parameter_set_to_settings(settings, parameter_set)[source]¶
Apply a parameter preset in place and return the same job Settings.
parameter_setmust be one of the preset names returned byCRSJob.get_parameter_set_options().
- static apply_parameter_set_to_inputs(crs, parameter_set)[source]¶
Apply a parameter preset in place and return the same typed CRS model.
parameter_setmust be one of the preset names returned byCRSJob.get_parameter_set_options().- Parameters:
crs (CRS) –
parameter_set (str) –
- Return type:
CRS
- static adfcrs_database_path()[source]¶
Return the path to the bundled ADFCRS-2018 COSKF database directory.
- Return type:
- static coskf_from_adfcrs_database(name)[source]¶
Return the path to a COSKF file in the bundled ADFCRS-2018 database.
- class CRSResults(job)[source]¶
A
SCMResultssubclass for accessing results ofCRSJob.- Parameters:
job (SCMJob) –
- get_energy(energy_type='deltag', compound_idx=0, unit='kcal/mol')[source]¶
Returns the solute solvation energy from an Activity Coefficients calculation.
- get_activity_coefficient(compound_idx=0)[source]¶
Return the solute activity coefficient from an Activity Coefficients calculation.
- get_sigma_profile(subsection='profil', as_df=False)[source]¶
Grab all sigma profiles, returning a dictionary of Numpy Arrays.
Values of \(\sigma\) are stored under the
"σ (e/A**2)"key.Results can be returned as a Pandas DataFrame by settings as_df to
True.The returned results can be plotted by passing them to the
CRSResults.plot()method.Note
as_df =
Truerequires the Pandas package. Plotting requires the matplotlib package.
- get_sigma_potential(subsection='mu', unit='kcal/mol', as_df=False)[source]¶
Grab all sigma profiles, expressed in unit, and return a dictionary of Numpy Arrays.
Values of \(\sigma\) are stored under the
"σ (e/A**2)"key.Results can be returned as a Pandas DataFrame by settings as_df to
True.The returned results can be plotted by passing them to the
CRSResults.plot()method.Note
as_df =
Truerequires the Pandas package. Plotting requires the matplotlib package.
- get_prop_names(section=None)[source]¶
Read the section of the .crskf file and return a list of the properties that were calculated. The section argument can be supplied to look at previously-calculated results. If no section name is supplied, the function defaults to using the most recent property that was calculated.
- get_results(section=None)[source]¶
Read the section from the most recent calculation type and return the result as a dictionary.
- get_multispecies_dist()[source]¶
This function returns multispecies distribution for each (compound,structure) pair. The format is a list with indices corresponding to compound indices. Each item in the list is a dictionary with a structure name : list pair, where the structure name corresponds to a structure the compound can be exist as and the list is the distribution of that compound in that structure over the number of points (mole fractions, temperatures, pressures).
- get_structure_energy(as_df=False)[source]¶
Retrieve the energy information for each structure in multispecies. If OUTPUT_ENERGY_COMPONENTS is set to True in the input file, this function returns:
The energy of each structure in multispecies (units in kcal/mol).
Information related to association with other compound, if any.
- Parameters:
as_df (bool, optional) – If True, returns the result as a list of Pandas DataFrames. If False, returns the result as a list of dictionaries. Default is False.
- Returns:
A list containing the energy data and association information for each structure.
- Return type:
List[dict] or List[pandas.DataFrame]
- Energy Abbreviations:
s_idx: the index for each unique structure
CompIdx: the compound index in multispecies
FormIdx: the form index in multispecies
SpecIdx: the species index in multispecies
StrucIdx: the structure index in multispecies
z: the equilibrium concentration in multispecies
coskf: the corresponding coskf file for each s_idx
mu_res: the residual part of the pseudo-chemical potential
mu_comb: the combinatorial part of the pseudo-chemical potential
mu_disp: the energy contribution from the dispersive interaction
mu_pdh: the energy contribution from the Pitzer-Debye-Hückel term
mu_RTlnz: the energy contribution from the ideal mixing
mu_Ecosmo: the Ecosmo energy
mu_res_misfit : the electrostatic interaction in residual part of the pseudo-chemical potential
mu_res_hb : the hydrogen bond interaction in residual part of the pseudo-chemical potential
Assoc: True if the structure has any association with other compound
NumRepMonomer: the number of repeated monomers used for polymers
NumStrucPerComp: the number of structures per compound used for dimers, trimers
- Association Information Abbreviations:
ReqCompNameAssoc: the required compound name for the associating structure
ReqCompIdxAssoc: the required compound index (CompIdx) for the associating structure
NumReqCompAssoc: the number of the required compounds in the associating structure
- plot(*arrays, x_axis=None, plot_fig=True, x_label=None, y_label=None)[source]¶
Plot, show and return a series of COSMO-RS results as a matplotlib Figure instance.
Accepts the output of, e.g.,
CRSResults.get_sigma_profile(): A dictionary of Numpy arrays or a Pandas DataFrame.Returns a matplotlib Figure instance which can be further modified to the users liking. Automatic plotting of the resulting figure can be disabled with the plot_fig argument.
Note
This method requires the matplotlib package.
Note
The name of the dictionary/DataFrame key containing the index (i.e. the x-axis) can, and should, be manually specified in x_axis if a custom x_axis is passed to
CRSResults._get_array_dict(). This argument can be ignored otherwise.