-
Notifications
You must be signed in to change notification settings - Fork 230
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
Dms oxy changes #1751
Dms oxy changes #1751
Conversation
I would add that it seems to have failed the Travis testing which is strange because it passes locally. Specifically it seems to time out on the the database test, but it is not clear to me why/it doesn't do this on my local test. Maybe Xiaorui could try this and see if it works for him? |
rmgpy/data/thermo.py
Outdated
m = 0 | ||
#Pushes all charged species to the back of the list, as a result the lowest enthalpy non-charged resonance form is used for GAV estimation | ||
for i in range(len(species.molecule)): | ||
if species.molecule[i-m].has_Charge() is True: | ||
species.molecule.append(species.molecule[i-m]) | ||
thermo.append(thermo[i-m]) | ||
del species.molecule[i-m] | ||
del thermo[i-m] | ||
m += 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest updating the prioritize_thermo
method instead, similar to what I did in 85235dd. You can add has_charge
as another value in the sorting algorithm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, Ryan. It looks good, I just have a few comments about formatting, since we want to keep the PEP-8 formatting in RMG-Py. Thanks.
rmgpy/molecule/molecule.py
Outdated
@@ -2066,6 +2066,12 @@ def has_lone_pairs(self): | |||
if atom.lone_pairs > 0: | |||
return True | |||
return False | |||
|
|||
def has_Charge(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a little comment: has_charge
instead of has_Charge
.
rmgpy/rmg/input.py
Outdated
if constantSpecie not in species_dict: | ||
raise InputError('Species {0} not found in the input file'.format(constantSpecie)) | ||
|
||
if not isinstance(T,list): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: add a space toT,list
=> T, list
rmgpy/rmg/input.py
Outdated
#Check the constant species exist | ||
if constantSpecies is not None: | ||
logging.debug(' Generation with constant species:') | ||
for constantSpecie in constantSpecies: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"specie" looks a little bit weird. Do you mind changing it to something else? Maybe like const_spc
?
rmgpy/solver/simple.pyx
Outdated
@@ -125,6 +127,10 @@ cdef class SimpleReactor(ReactionSystem): | |||
|
|||
self.initial_mole_fractions = initial_mole_fractions | |||
|
|||
#Constant Species Properties | |||
self.const_spc_indices=None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
space before and after =
.
rmgpy/solver/simple.pyx
Outdated
"Allow to identify constant Species position in solver" | ||
for spc in self.const_spc_names: | ||
if self.const_spc_indices is None: #initialize once the list if constant SPC declared | ||
self.const_spc_indices=[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
space before and after =
1b97fb6
to
041c19e
Compare
OK this new version responds to each of your concerns, both stylistic and structural. Let me know if you see anything else that is off. Again, the branches pass all tests locally but the change to allow valence 12 species seems to slow down test-database significantly to the point that it times out. I don't know why having a few more resonance forms to grab thermo for when you are loading libraries would cause such a slowdown, but I can't think of why else loading the libraries would be so slow with the new changes. |
@alongd might have the most insight regarding the effects of allowing valence 12 sulfur species. I think you could try loading the library in question manually to see if you can narrow down the exact species which is taking so much time. It could be either inherent difficulties in generating resonance structures or a bug. |
So after some investigation I've found that the problem is that the number of resonance forms in species like cyclic S6, S7, and S8 explodes when you allow valence 12 states because it creates a ton of resonance forms with S#S... In this case these are obvious imaginary, but I think that sulfur doesn't form a triple bond with sulfur ever (why would it when it could be a single bond with lone pairs). I think we should amend resonance generation to prevent specifically S#S from lone pairs. @alongd do you have thoughts or strong opinions on this? |
I'm unaware of cases where |
Ok. I've added another commit that stops the formation of S#S resonance structures from lone pair/multiple bond resonance transitions. This solved the timing issue with large sulfur chains and prevents the timing out observed in the testing. I think these are all ready to merge, but I am happy to change anything else that you see that needs amendment. |
Codecov Report
@@ Coverage Diff @@
## master #1751 +/- ##
=========================================
- Coverage 32.61% 32.6% -0.01%
=========================================
Files 87 87
Lines 26103 26115 +12
Branches 6869 6875 +6
=========================================
+ Hits 8514 8516 +2
+ Misses 16631 16629 -2
- Partials 958 970 +12
Continue to review full report at Codecov.
|
Thanks! I went through the code as well as the test (I also did the tests locally). They look good to me. |
self.const_spc_indices = None | ||
self.const_spc_names = const_spc_names #store index of constant species |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's good. Just a minor modification on the commented description.
Might be " self.const_spc_indices = None #store index of constant species"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made some minor comments, mostly regarding code style.
It would also be nice to add a unit test confirming the resonance changes work as expected.
rmgpy/molecule/pathfinder.py
Outdated
#if both atom1 and atom2 are sulfur then don't do this type of resonance | ||
if not atom1.is_sulfur() or not atom2.is_sulfur(): | ||
# Bond must be capable of gaining an order | ||
if bond12.is_single() or bond12.is_double(): | ||
for atom3, bond23 in atom2.edges.items(): | ||
# Bond must be capable of losing an order without breaking, atom3 must be able to gain a lone pair | ||
if atom1 is not atom3 and (bond23.is_double() or bond23.is_triple()) \ | ||
and (atom3.is_carbon() or is_atom_able_to_gain_lone_pair(atom3)): | ||
paths.append([atom1, atom2, atom3, bond12, bond23]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can combine the top two if statements:
if (not atom1.is_sulfur() or not atom2.is_sulfur()) and (bond12.is_single() or bond12.is_double()):
Also line 297 is indented by 3 spaces instead of 4.
rmgpy/molecule/pathfinder.py
Outdated
@@ -382,7 +384,7 @@ def find_adj_lone_pair_multiple_bond_delocalization_paths(atom1): | |||
# Find paths in the direction <increasing> the bond order, | |||
# atom1 must posses at least one lone pair to loose it | |||
if ((bond12.is_single() or bond12.is_double()) | |||
and is_atom_able_to_lose_lone_pair(atom1)): | |||
and is_atom_able_to_lose_lone_pair(atom1)) and not (atom1.is_sulfur() and atom2.is_sulfur() and bond12.is_double()): #the final clause of this prevents S#S from forming by this resonance pathway |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this line might be too long.
rmgpy/solver/simple.pyx
Outdated
@@ -163,6 +169,15 @@ cdef class SimpleReactor(ReactionSystem): | |||
conditions[species_dict[label]] = value | |||
self.sens_conditions = conditions | |||
|
|||
def get_const_spc_indices (self, coreSpecies): | |||
"Allow to identify constant Species position in solver" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docstrings should be enclosed in triple quotes """docstring"""
rmgpy/solver/simple.pyx
Outdated
@@ -163,6 +169,15 @@ cdef class SimpleReactor(ReactionSystem): | |||
conditions[species_dict[label]] = value | |||
self.sens_conditions = conditions | |||
|
|||
def get_const_spc_indices (self, coreSpecies): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use underscore naming for variables: core_species
rmgpy/solver/simple.pyx
Outdated
for spc in self.const_spc_names: | ||
if self.const_spc_indices is None: #initialize once the list if constant SPC declared | ||
self.const_spc_indices = [] | ||
for iter in coreSpecies: #Need to identify the species object corresponding to the the string written in the input file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iter
is a reserved word. Perhaps change to spc
or core_spc
?
rmgpy/solver/simple.pyx
Outdated
self.const_spc_indices = [] | ||
for iter in coreSpecies: #Need to identify the species object corresponding to the the string written in the input file | ||
if iter.label == spc: | ||
self.const_spc_indices.append(coreSpecies.index(iter))#get |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The #get
comment doesn't seem to make sense.
rmgpy/solver/simple.pyx
Outdated
@@ -504,6 +519,10 @@ cdef class SimpleReactor(ReactionSystem): | |||
reaction_rate = k * C[inet[j, 0]] * C[inet[j, 1]] * C[inet[j, 2]] | |||
network_leak_rates[j] = reaction_rate | |||
|
|||
if self.const_spc_indices is not None: | |||
for spcIndice in self.const_spc_indices: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use underscores for variable names, perhaps spc_index
?
rmgpy/tools/simulate.py
Outdated
elif rmg.uncertainty is not None: | ||
rmg.verbose_comments = True | ||
rmg.load_database() | ||
|
||
# Store constant species indices |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation should match the following line.
rmgpy/solver/simple.pyx
Outdated
def get_const_spc_indices (self, coreSpecies): | ||
"Allow to identify constant Species position in solver" | ||
for spc in self.const_spc_names: | ||
if self.const_spc_indices is None: #initialize once the list if constant SPC declared |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, this is quite picky, but comments should have two spaces before the #
and one space after:
if self.const_spc_indices is None: # initialize
5075f1e
to
bfd40e7
Compare
I think that this solves all the problems mentioned by Max? Let me know if you see any other dumb mistakes. The unit test works by comparing the number of resonance structures generated for S1SSS1. Previously it made 34, but elminating the S#S has reduced this number to 10. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making all of the changes. I made one more comment. You can also rebase on to master after fixing it.
rmgpy/molecule/resonanceTest.py
Outdated
@@ -1419,3 +1419,11 @@ def test_surface_o(self): | |||
1 X u0 p0 c0 {2,D} | |||
2 O u0 p2 c0 {1,D}""")) | |||
self.assertEquals(len(mol_list), 1) | |||
|
|||
def sulfur_triple_bond(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think tests have to start with test
in order to be recognized and run as a test.
…hat do not contain charged atoms
…tiplebond_paths and find_adj_lone_pair_multiple_bond_delocalization_paths
…ultiple bond resonance pathways
bfd40e7
to
f61752e
Compare
Ok. I think this resolves the remaining issues. It should be rebased to current master. |
This short pull request does 3 things, all related to my work on sulfur oxidation systems.
It allows Group Additivity Estimation for sulfur species with hypervalence up to 12 (the previous max was 10, which caused it to be very awkward when GAV was predicting species like CS(=O)(=O)C or the like.
When estimating species thermochemistry by GAV, RMG will now prioritize non-charged resonance forms. If there are multiple non-charged resonance forms then the form with the lowest enthalpy of formation will be selected as the representative thermochemistry. This solves problems where RMG would overestimate the stability of molecules that have charged resonance forms because when GAV is used to estimate the thermo of charged molecules it generally defaults to the top nodes. A test of this is also included to make sure that in the case of multiple non-charged resonance forms, the lower enthalpy form is selected as representative.
It allows simple gas phase reactors to also have constant species (similar to how liquid reactors can have constant species).
Motivation or Problem
A clear and concise description of what what you're trying to fix or improve. Please reference any issues that this addresses.
Description of Changes
A clear and concise description of what what you've changed or added.
Testing
A clear and concise description of testing that you've done or plan to do.
Reviewer Tips
Suggestions for verifying that this PR works or other notes for the reviewer.