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

Export Solution to Chemkin Format #52

Closed
tsikes opened this issue Jun 11, 2020 · 35 comments
Closed

Export Solution to Chemkin Format #52

tsikes opened this issue Jun 11, 2020 · 35 comments
Labels
work-in-progress An enhancement that someone is currently working on

Comments

@tsikes
Copy link

tsikes commented Jun 11, 2020

Abstract

As we all know the Chemkin format is ubiquitous in chemical kinetics simulations. There are a number of reasons that it would be beneficial for Cantera to be able to export into this format from being able to export a modified reaction mechanism for use by the community to being able to use with CFD software.

Motivation

Describe the need for the work being done:

  • Output solution object into Chemkin format
  • This effects only those that would use such a function
  • This adds new functionality to Cantera

Description

My code builds off of soln2ck from Kyle Niemeyer's pyMARS. In it I have added additional functionality of printing notes from a yaml style input file, a few bug fixes, and improved formatting. I use this function to output modified kinetics mechanisms that have been optimized to experiments. I have seen this functionality requested before and think that a unified approach will help more people adopt Cantera in the community.

Alternatives

I have considered outputting to the yaml format; however, this lacks the compatibility that I have mentioned.

References

My version of soln2ck

@tsikes tsikes added the work-in-progress An enhancement that someone is currently working on label Jun 11, 2020
@tsikes
Copy link
Author

tsikes commented Jun 11, 2020

Something that would make this much smoother would be if it were possible for Cantera to load the notes from the yaml format. My method of reparsing the yaml file for these notes has holes in it if there are duplicate reactions, specified or unspecified.

@jiweiqi
Copy link

jiweiqi commented Jun 19, 2020

I actually think it is not a big deal whether the notes are preserved during format conversion. Normally, the situation that you want to get a Chemkin format is for uncertainty quantification and optimization. Those checkin mech files are temporal files and you can also look up the notes from the original mechanism. As long as users can find a copy of the original mechanism, the missing notes in checkin file is not a problem. It might also helpful that if we set a hub for reaction mechanisms and put different formats together. For example, https://github.com/jiweiqi/CollectionOfMechanisms

@tsikes
Copy link
Author

tsikes commented Jun 20, 2020

I don't view the CK files as temp files. A CK mechanism is the final product that others in the community will use because it is the de facto standard, for better or worse. In my experience, the link between reaction and source are often lost in published mechanisms. From my perspective, why create an opportunity for loss of information if there's no reason to? Every reaction should have a source, even if that source is present work: analogy to X, or else it's just numbers.

Hubs and whatnot are always useful if you have someone with the time/funding to maintain them.

Would it be more appropriate for this functionality to be more basic aka written in C++?

@bryanwweber
Copy link
Member

@tsikes

Would it be more appropriate for this functionality to be more basic aka written in C++?

This would likely be the best case. In the development version, @speth introduced a class called AnyMap which is a map of, well, anything to anything, kind of like a Python dictionary (at least to my rudimentary understanding). In any case, the point is that this can be some sort of intermediate representation, for which we can have multiple serialization options (to YAML, to CK, to the next big format, etc.).

@speth
Copy link
Member

speth commented Jun 20, 2020

I think supporting conversion of Cantera YAML files (or Solution objects) to Chemkin format is important because that would allow the Cantera YAML format to serve as an extensible interchange format. Without that capability, we're stuck with the Chemkin format being the only thing that can be converted to every other format.

In addition to working towards YAML serialization (#11), I am working on making all of the YAML input data (not just the fields used by Cantera) available in the Python interface, which should make writing a script to output to any desired format relatively easy.

I don't think it would make sense to add output capabilities to any format besides YAML at the C++ level.

@bryanwweber
Copy link
Member

bryanwweber commented Jun 20, 2020

I don't think it would make sense to add output capabilities to any format besides YAML at the C++ level.

Doesn't this effectively limit CK export to the Python interface? I know we don't get to spend as much effort on the other interfaces, but I think it would be very useful to be able to export other formats from, say, the MATLAB or Fortran interface. Presumably, that would be easier if the functionality were wrapped up in the C++ layer rather than delegating to each interface independently.

On the other side, the only way to import CK files is by converting them with a Python script. I would say that the distinction is that the conversion script is more-or-less independent of Cantera functionality, whereas the output to CK format is most useful after some work has been done within Cantera.

@ischoegl
Copy link
Member

ischoegl commented Jun 20, 2020

I believe that emitting Solution objects to YAML using #11 (which happens at the C++ layer afaik), and subsequently converting YAML to CK would be preferable. This could be easily done using Python, similar to the other conversion scripts. It could be done outside of Cantera, although I'm not sure that this is the most efficient solution (i.e. as opposed to loading YAML from Python, and converting it to CK, or emitting directly like the current soln2ck).

Would it make sense to create a function yaml2ck?

@tsikes
Copy link
Author

tsikes commented Jun 20, 2020

My thoughts are summed up well by @bryanwweber. It seems to be a question of how core this functionality should be because if it's something that each interface is going to want then the redundancy of writing the same function in multiple languages would be a hindrance.

@ischoegl one possible downfall of going directly from yaml2ck is that the yaml mechanism isn't necessarily a functioning mechanism if it's created by the user. This is only a problem in the sense that error checking would have to be included as well. I'm not sure Why someone would do this, but it's possible. Would there be an advantage to going directly from yaml to ck?

@speth
Copy link
Member

speth commented Jun 20, 2020

I guess the way I think of the input file converters, both to and from Cantera formats, is as utilities that exist outside of using any particular Cantera interface. I'm not trying to relegate them to the Python interface -- they're packaged as scripts rather than just functions in the Python module for exactly this reason, and I don't think this functionality should be duplicated in multiple interfaces, either.

The main reason I think a yaml2ck script should be implemented in Python (either using Cantera Solution objects as an intermediate or not) is because we have so few developers who are proficient with C++, and even for them, the time involved in writing and maintaining this capability in C++ will be much higher compared to doing so in Python.

@kyleniemeyer
Copy link
Member

What @speth said makes a lot of sense I think.

Since we already wrote a Solution -> Chemkin converter for pyMARS (https://github.com/Niemeyer-Research-Group/pyMARS/blob/master/pymars/soln2ck.py), that might be a good starting point for a yaml2ck script in Cantera.

@ischoegl
Copy link
Member

ischoegl commented Jun 20, 2020

I agree with both @speth and @kyleniemeyer ... C++ is efficient/fast whereas Python is convenient and easier to maintain. As the conversion is presumably not done very often, speed is not a primary concern. Regarding porting this to multiple platforms (beyond Python) I do not believe that the benefit justifies the effort.

@ischoegl
Copy link
Member

ischoegl commented Jun 27, 2020

@tsikes ... I created a draft PR that makes the annotations you re-read from YAML (in the get_notes function of your soln2ck implementation) accessible from a Solution object. See Cantera/cantera#881

I realize that there are plans to add custom user-defined fields to YAML down the road. However, imho description and note fields are de-facto part of the standard YAML implementation (ck2yaml specifically uses them), and an explicit inclusion makes sure that docstrings are available.

@tsikes
Copy link
Author

tsikes commented Jun 27, 2020

@ischoegl, Fantastic! Thank you for the help with this. I was not happy with my solution to this part of the problem.

@ischoegl
Copy link
Member

@tsikes ... you’re welcome. But let’s see ... there may be some overlap with @speth’s plans for #11. As mentioned, I do believe that description and note fields are de facto part of the standard YAML format. Thus, I am pretty hesitant to lump them together with true custom fields.

@tsikes
Copy link
Author

tsikes commented Jul 6, 2020

I created an initial implementation of yaml2ck here. This version is based upon Cantera/cantera#881. If this PR doesn't end up being merged, then I can revert the notes part of yaml2ck to my prior implementation.

I have a few open questions/remarks:

  • What is the CK format for NASA9 including the header declaration? I've searched around a bit for it but I can't seem to find one like I can for NASA7.

  • On the same lines, does CK format allow for NASA7 and NASA9 to be mixed? If not, then the best solution will probably be to make psuedo NASA9 thermo from NASA7.

  • If going from ck -> yaml -> ck I have found that the notes are not able to be reprinted as in the original ck file in some instances due to ck2yaml not keeping track of which notes/comments exist prior to the reaction/in line with the reaction/after the reaction. To fix this I'd have to modify ck2yaml to keep track of this information.

  • I don't know how to handle the copyrights to this function as it is from pyMARS with modifications for Frhodo.

@speth
Copy link
Member

speth commented Jul 8, 2020

  • What is the CK format for NASA9 including the header declaration?

I could be wrong, but I don't think CK supports the 9-coefficient NASA format. Rather, that format is used by the NASA CEA code and related tools.

  • If going from ck -> yaml -> ck I have found that the notes are not able to be reprinted as in the original ck file in some instances due to ck2yaml not keeping track of which notes/comments exist prior to the reaction/in line with the reaction/after the reaction. To fix this I'd have to modify ck2yaml to keep track of this information.

I know @ischoegl will probably disagree with me, but I think the lack of regularity in CK files makes trying to do this with any degree of precision impossible. ck2yaml tries to guess which reaction to associate a comment with, but it can easily be wrong. My aim has been mainly to try not to throw away any comments. For output, perhaps we could think about tagging the comment in a way that is then parsed in a repeatable way by ck2yaml, e.g. as ct:note: blah blah blah or something along those lines, just to throw an idea out there.

  • I don't know how to handle the copyrights to this function as it is from pyMARS with modifications for Frhodo.

If you and @kyleniemeyer agree, the copyright could be reassigned to Cantera, which would probably be the simplest solution.

@ischoegl
Copy link
Member

ischoegl commented Jul 8, 2020

I know @ischoegl will probably disagree with me, but I think the lack of regularity in CK files makes trying to do this with any degree of precision impossible. ck2yaml tries to guess which reaction to associate a comment with, but it can easily be wrong.

I'm actually not disagreeing here 😉 ... I think that exactly reproducing CK input (as in a round-trip conversion) is likely unnecessary. As long as ck2yaml does a decent job guessing, merging comments into metadata should be fine. I view this similar to comments in most programming languages where you have the choice of comments after a statement, or comments on their own line ... using both muddles things, and I don't think it deserves to be preserved (except by, perhaps, including a \n as separation).

@tsikes
Copy link
Author

tsikes commented Jul 8, 2020

I could be wrong, but I don't think CK supports the 9-coefficient NASA format. Rather, that format is used by the NASA CEA code and related tools.

It looks like I'll have to implement a refit procedure then. I have written one of those already, but the downside of it is that it requires scipy's optimization functions to work. This was the easiest way to solve the matrix with constraints on continuity of Cp, H, S and their 1st/2nd derivatives. Alternatively, yaml2ck could simply throw an error warning that it doesn't support NASA9.

As long as ck2yaml does a decent job guessing, merging comments into metadata should be fine.

I'd like to make it reproduce as faithfully as possible; however, I don't think it's a great use of time, hah. Right now it does preserve all comments. The logic in place is that if a comment is a single line long, assume that it's an inline comment. If it is multiple lines long, assume that the last line is an inline comment. This works reasonably well with the mechanisms I've played with. If "just preserve comments" is the prevailing opinion, I'll leave it how it is.

If you and @kyleniemeyer agree, the copyright could be reassigned to Cantera, which would probably be the simplest solution.

I have no issue with this.

@kyleniemeyer
Copy link
Member

Regarding the copyright question, mostly it would be nice if the original authors (me and a few students here) could be credited in the git history, but I'm not sure if this is possible or how hard it would be.

@speth
Copy link
Member

speth commented Jul 9, 2020

Regarding the copyright question, mostly it would be nice if the original authors (me and a few students here) could be credited in the git history, but I'm not sure if this is possible or how hard it would be.

Yes, absolutely, credit where credit is due. There is a convention for this that GitHub recognizes, which is to add lines like Co-authored-by: Firstname Lastname <[email protected]> to the commit message to whatever commit first adds this file, which does show up when looking at the commit on GitHub. One example is here: Cantera/cantera@f973215. And any contributors to this should be added to the AUTHORS file as well.

@bryanwweber
Copy link
Member

@tsikes

It looks like I'll have to implement a refit procedure then. I have written one of those already, but the downside of it is that it requires scipy's optimization functions to work. This was the easiest way to solve the matrix with constraints on continuity of Cp, H, S and their 1st/2nd derivatives. Alternatively, yaml2ck could simply throw an error warning that it doesn't support NASA9.

My personal preference is that yaml2ck should throw an error, and that we add an example of the refit procedure that people can follow if they want. This avoids adding a dependency for Cantera and simplifies the yaml2ck script. Plus, I think the example would be a good demonstration of the data you can get from a Species instance in Python as well, so it'd be good to have anyways.

@ischoegl
Copy link
Member

ischoegl commented Jul 9, 2020

Everyone: what's the suggested way forward regarding Cantera/cantera#881? The implementation would work for Cantera 2.5 and enable yaml2ck in the near future (at least without parsing YAML twice). The sticking point appears to be long-term support of note and description fields, as there may be changes in metadata support in the future (see also #56).

If there's a consensus to wait for #11, I'll simply close the PR.

@bryanwweber
Copy link
Member

My vote is to wait for #11. It means that yaml2ck won't be feature-complete until #11 is done, but I'd rather keep our flexibility with the YAML format and get 2.5.0 out the door, than either remove flexibility or wait for #11.

@ischoegl
Copy link
Member

ischoegl commented Jul 10, 2020

Alright: while I do not see the actual conflict with #11, I closed Cantera/cantera#881.

@ischoegl
Copy link
Member

Now that #11 is implemented via Cantera/cantera#984, I reopened and updated Cantera/cantera#881, which now draws directly on the YAML parameters.

@ischoegl
Copy link
Member

@tsikes ... I believe with Cantera/cantera#1031 and Cantera/cantera#1129 all YAML data are now accessible from within Cantera, so I believe everything should be ready for adding yaml2ck to Cantera at this point.

@tsikes
Copy link
Author

tsikes commented Dec 14, 2021

@ischoegl That's great. I'll take a look at it.

@tsikes
Copy link
Author

tsikes commented Feb 1, 2022

@ischoegl I've updated yaml2ck to use Cantera/cantera#1031 and Cantera/cantera#1129. I've done a few tests with a mock mechanism to go from CK to YAML and back.

Few notes:

  1. Transport data is untested
  2. NASA9 is not included, as discussed prior
  3. Notes on elements are not saved in YAML and as such cannot be passed back to CK. This is an extremely minor edge case.

@ischoegl
Copy link
Member

ischoegl commented Feb 1, 2022

@tsikes That’s great to hear! Per prior discussion, it would be great if you were willing to add the converter to Cantera. So I hope to see a PR soon!

@ischoegl
Copy link
Member

ischoegl commented Aug 4, 2022

Closed via Cantera/cantera#1286

@ischoegl ischoegl closed this as completed Aug 4, 2022
@khaledcomb
Copy link

Dear @tsikes I tried to compile the soln2ck that you provided using python and add this command to it

gas= ct.Solution('gri30-reduced-40-reaction.yaml')
soln2ck.py
gri30-reduced-40-reaction.inp

I get the following msg:

PS C:\Users\DELL\Desktop\python-folder\Mechanism\propane> & C:/Users/DELL/AppData/Local/Programs/Python/Python310/python.exe c:/Users/DELL/Desktop/python-folder/Mechanism/propane/soln2ck.py
Traceback (most recent call last):
File "c:\Users\DELL\Desktop\python-folder\Mechanism\propane\soln2ck.py", line 22, in
gas= ct.Solution('gri30-reduced-40-reaction.yaml')
File "cantera/base.pyx", line 71, in cantera._cantera._SolutionBase.cinit
File "cantera/base.pyx", line 128, in cantera._cantera._SolutionBase._cinit
File "cantera/base.pyx", line 215, in cantera._cantera._SolutionBase._init_yaml
cantera._cantera.CanteraError:


InputFileError thrown by Kinetics::checkDuplicates:
Error on line 529 of ./gri30-reduced-40-reaction.yaml:
No duplicate found for declared duplicate reaction number 21 (CO + OH <=> CO2 + H)
| Line |
| 524 | rate-constant: {A: 2.397e+48, b: -9.9, Ea: 3.4342272e+08}
| 525 | - equation: C2H2 + CH3 <=> C3H4-P + H
| 526 | rate-constant: {A: 1.211e+14, b: -1.2, Ea: 6.978912e+07}
| 527 | - equation: H2 + OH <=> H + H2O
| 528 | rate-constant: {A: 2.16e+05, b: 1.51, Ea: 1.435112e+07}

529 > - equation: CO + OH <=> CO2 + H
^
| 530 | rate-constant: {A: 70.46, b: 2.053, Ea: -1.48812328e+06}
| 531 | duplicate: true
| 532 | - equation: C3H6 + H <=> C2H4 + CH3


PS C:\Users\DELL\Desktop\python-folder\Mechanism\propane>

Any help with this error?
for your info I use python -m cantera.ck2yaml --input=chem.inp --thermo=therm.dat --transport=tran.dat
to convert from ck to yaml

I tried Another option pymars --convert -m model.cti but I got this msg:

#!/bin/sh
'''exec' C:/Users/DELL/anaconda3/bin/python "$0" "$@"
' '''

-- coding: utf-8 --

import re
import sys

from pymars.main import main

if name == 'main':
sys.argv[0] = re.sub(r'(-script.pyw?|.exe)?$', '', sys.argv[0])
sys.exit(main())

So please if you have any suggestion say me it

Thanks

@bryanwweber
Copy link
Member

@khaledcomb If you have questions about using Cantera, please direct them to our Google Group at https://groups.google.com/g/cantera-users instead of posting on closed GitHub issues. Thank you!

@khaledcomb
Copy link

Thank you

@sthakris
Copy link

Can you please adivise how to use this script.
I did
python3 sol2ck.py mechanism.cti
and gives error.
Traceback (most recent call last):
File "/home/krishna/Desktop/Cantera/soln2ck.py", line 23, in
import cantera as ct
File "/home/krishna/anaconda3/envs/ct-env/lib/python3.10/site-packages/cantera/init.py", line 4, in
from ._cantera import *

The proper procedure to use this a script as stand alone would be good.
I am using the script inside the cantera environment ct-env.

Thank you!

@speth
Copy link
Member

speth commented Feb 24, 2023

Please direct questions to the Cantera Users' Group. soln2ck.py is a now-outdated prototype of the feature that is now integrated into Cantera, where it is now named yaml2ck. You will need to compile and install the current development version of Cantera to use it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
work-in-progress An enhancement that someone is currently working on
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants