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

Solutionarray summary #1462

Merged
merged 7 commits into from
Apr 11, 2023
Merged

Solutionarray summary #1462

merged 7 commits into from
Apr 11, 2023

Conversation

ischoegl
Copy link
Member

@ischoegl ischoegl commented Mar 22, 2023

Changes proposed in this pull request

This PR adds a utility function SolutionArray::info, which provides a concise summary of the content. The styling is inspired by pandas' DataFrame.info, although it is implemented in C++ and thus available for all API's. Under the hood, the C++ library fmt is used to format content.

In addition, this PR fixes a glitch in the order of SolutionArray::componentNames, where the native storage mode TDY was alphabetically sorted as DTY (same fix is also added in #1464).

If applicable, provide an example illustrating new features this pull request is introducing

In [1]: import cantera as ct
   ...: gas = ct.Solution("h2o2.yaml")
   ...: arr = ct.SolutionArray(gas, 20, extra={"spam": "eggs"})

In [2]: arr
Out[2]:
      T          D   H2    H    O   O2   OH  H2O  HO2  H2O2   AR   N2  spam
0   300  0.0818939    1    0    0    0    0    0    0     0    0    0  eggs
1   300  0.0818939    1    0    0    0    0    0    0     0    0    0  eggs
2   300  0.0818939    1    0    0    0    0    0    0     0    0    0  eggs
3   300  0.0818939    1    0    0    0    0    0    0     0    0    0  eggs
4   300  0.0818939    1    0    0    0    0    0    0     0    0    0  eggs
..  ...        ...  ...  ...  ...  ...  ...  ...  ...   ...  ...  ...   ...
15  300  0.0818939    1    0    0    0    0    0    0     0    0    0  eggs
16  300  0.0818939    1    0    0    0    0    0    0     0    0    0  eggs
17  300  0.0818939    1    0    0    0    0    0    0     0    0    0  eggs
18  300  0.0818939    1    0    0    0    0    0    0     0    0    0  eggs
19  300  0.0818939    1    0    0    0    0    0    0     0    0    0  eggs

[20 rows x 13 components; state='TDY']

and

In [3]: import numpy as np
   ...: arr.set_equivalence_ratio(np.linspace(.5, 1.5, 20), "H2", "O2:1,N2:10")
   ...: arr.equilibrate("HP")
   ...: arr.spam = np.linspace(-1e-6, 1e-6, 20)

In [4]: print(arr.info(rows=7, width=100))
           T         D           H2            H  ...         H2O2   AR        N2         spam
0    975.173  0.341386  1.25945e-12  1.75212e-16  ...  4.62014e-11    0  0.891728 -1.00000e-06
1   1036.780  0.319853  9.06756e-12  2.40164e-15  ...  1.05086e-10    0  0.891126 -8.94737e-07
2   1096.955  0.301139  5.14047e-11  2.36240e-14  ...  2.12557e-10    0  0.890525 -7.89474e-07
3   1155.770  0.284717  2.40637e-10  1.77659e-13  ...  3.89439e-10    0  0.889925 -6.84211e-07
..       ...       ...          ...          ...  ...          ...  ...       ...          ...
17  1446.986  0.209250  5.00863e-03  9.17217e-08  ...  7.48958e-14    0  0.881604  7.89474e-07
18  1439.223  0.208801  5.67268e-03  8.85969e-08  ...  5.62427e-14    0  0.881016  8.94737e-07
19  1431.564  0.208357  6.33584e-03  8.50061e-08  ...  4.28479e-14    0  0.880428  1.00000e-06

[20 rows x 13 components; state='TDY']

Checklist

  • The pull request includes a clear description of this code change
  • Commit messages have short titles and reference relevant issues
  • Build passes (scons build & scons test) and unit tests address code coverage
  • Style & formatting of contributed code follows contributing guidelines
  • The pull request is ready for review

@codecov
Copy link

codecov bot commented Mar 22, 2023

Codecov Report

Merging #1462 (69e1a12) into main (839048d) will increase coverage by 0.07%.
The diff coverage is 87.81%.

❗ Current head 69e1a12 differs from pull request most recent head adc38f5. Consider uploading reports for the commit adc38f5 to get more accurate results

@@            Coverage Diff             @@
##             main    #1462      +/-   ##
==========================================
+ Coverage   69.90%   69.98%   +0.07%     
==========================================
  Files         377      377              
  Lines       57349    57586     +237     
  Branches    19201    19326     +125     
==========================================
+ Hits        40092    40301     +209     
- Misses      14706    14726      +20     
- Partials     2551     2559       +8     
Impacted Files Coverage Δ
include/cantera/base/SolutionArray.h 94.44% <ø> (ø)
interfaces/cython/cantera/solutionbase.pyx 88.57% <70.58%> (-1.07%) ⬇️
src/base/SolutionArray.cpp 78.42% <89.14%> (+2.25%) ⬆️

... and 1 file with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@ischoegl ischoegl force-pushed the solutionarray-show branch 2 times, most recently from 317689c to 387a77c Compare March 23, 2023 03:49
@ischoegl ischoegl marked this pull request as ready for review March 23, 2023 04:49
@ischoegl ischoegl requested a review from a team March 23, 2023 04:49
@ischoegl
Copy link
Member Author

ischoegl commented Mar 23, 2023

@speth and @bryanwweber … while there are some loose ends for related issues I just documented in Cantera/enhancements#166, the formatting itself is ready for a review. PS: the force push mainly took care of an edge case.

@ischoegl ischoegl marked this pull request as draft March 24, 2023 02:41
@ischoegl ischoegl removed the request for review from a team March 24, 2023 02:42
@ischoegl ischoegl marked this pull request as ready for review March 24, 2023 02:57
@ischoegl ischoegl requested a review from a team March 24, 2023 02:57
@ischoegl
Copy link
Member Author

ischoegl commented Mar 26, 2023

Loose ends uncovered here are resolved by #1464. PRs are almost completely independent, and I will resolve merge conflicts after merging whatever gets reviewed first.

Copy link
Member

@speth speth left a comment

Choose a reason for hiding this comment

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

Thanks, @ischoegl, this is a nice addition, and the implementation looks good to me.

I had one suggestion that I think might significantly extend its usefulness.
Looking at the way the Python method works on sliced solution arrays, would it make more sense to have a "include" list rather than a set of components to skip? With control over the column ordering, this would almost immediately provide a more attractive and flexible alternative to the output of Domain1D.show(). For example, with a FreeFlame object f:

print(f.to_solution_array()('H2', 'O2', 'H2O')[::5].info(rows=30, width=100))

Gives the output:

            T         D           H2         O2          H2O       grid  velocity
0     300.000  1.338612  9.47832e-03  0.1367637  7.40673e-19  0.0000000  0.727045
10    300.006  1.339040  9.45641e-03  0.1367666  3.52939e-08  0.0200625  0.726814
20    314.689  1.303354  8.10736e-03  0.1367547  3.88906e-04  0.0207891  0.746713
30    362.366  1.149201  7.04860e-03  0.1358127  2.22271e-03  0.0208711  0.846876
40    415.421  1.010257  6.43539e-03  0.1343538  4.52006e-03  0.0209062  0.963350
50    535.915  0.790700  5.52333e-03  0.1304149  1.00483e-02  0.0209531  1.230847
60    741.255  0.576925  4.34133e-03  0.1222623  2.04189e-02  0.0210117  1.686930
70    951.846  0.451853  3.20124e-03  0.1112773  3.29602e-02  0.0210703  2.153872
80   1167.908  0.369349  1.99580e-03  0.0957110  4.85175e-02  0.0211406  2.634995
90   1407.764  0.306713  7.83098e-04  0.0754498  6.65237e-02  0.0212578  3.173101
100  1588.912  0.272250  3.08697e-04  0.0658318  7.50175e-02  0.0214453  3.574766
110  1719.334  0.252370  1.70897e-04  0.0635787  7.82862e-02  0.0217969  3.856372
120  1810.158  0.240400  6.51822e-05  0.0630420  8.06377e-02  0.0226875  4.048379
130  1850.402  0.235543  1.26681e-05  0.0632889  8.18752e-02  0.0255000  4.131865

[14 rows x 7 components; state='TDY']

Comes pretty close already, with the exception that you would want the grid column to come first (and probably velocity before species).

test/python/test_composite.py Outdated Show resolved Hide resolved
src/base/SolutionArray.cpp Outdated Show resolved Hide resolved
@ischoegl
Copy link
Member Author

ischoegl commented Apr 8, 2023

Thanks for the review, @speth!

I had one suggestion that I think might significantly extend its usefulness.
Looking at the way the Python method works on sliced solution arrays, would it make more sense to have a "include" list rather than a set of components to skip? With control over the column ordering, this would almost immediately provide a more attractive and flexible alternative to the output of Domain1D.show().

Improving this exact part of the API was actually a major motivation for this PR, but #1464 was in the way. The include list makes sense, and I will adopt it.

[...] Comes pretty close already, with the exception that you would want the grid column to come first (and probably velocity before species).

The only reason this doesn't have the correct ordering already is that the 'vestigial' Python 1D API is in the way of the C++ implementation. From that viewpoint, I'd suggest to finalize/merge #1464 first, so I can rebase this one and can test accordingly.

@ischoegl
Copy link
Member Author

ischoegl commented Apr 9, 2023

@speth ... rebased and adopted the two minor suggestions. With #1464 merged, we now have

In [3]: f.to_array()('H2', 'O2', 'H2O')[::5]
Out[3]:
          grid  velocity         T         D           H2         O2          H2O
0    0.0000000  0.727045   300.000  1.338612  9.47832e-03  0.1367637 -4.65170e-19
5    0.0180000  0.727045   300.000  1.338613  9.47829e-03  0.1367637  3.25111e-13
10   0.0200625  0.726814   300.006  1.339040  9.45641e-03  0.1367666  3.52939e-08
15   0.0206250  0.725055   301.247  1.342287  9.03396e-03  0.1368145  1.88978e-05
20   0.0207891  0.746713   314.689  1.303354  8.10736e-03  0.1367547  3.88906e-04
..         ...       ...       ...       ...          ...        ...          ...
115  0.0221250  3.964611  1770.302  0.245480  1.14847e-04  0.0631696  7.95561e-02
120  0.0226875  4.048379  1810.158  0.240400  6.51822e-05  0.0630420  8.06377e-02
125  0.0236250  4.101003  1835.446  0.237316  3.16880e-05  0.0631228  8.13895e-02
130  0.0255000  4.131865  1850.402  0.235543  1.26681e-05  0.0632889  8.18752e-02
135  0.0330000  4.148673  1858.590  0.234589  4.06486e-06  0.0634496  8.21637e-02

[28 rows x 7 components; state='TDY']

I.e. ordering is indeed corrected, and __repr__ eliminates the need to call print. I also added a tweak to automatically detect the terminal width (which eliminates the need to provide width to info).

At this point

>>> f.to_array()('H2', 'O2', 'H2O')[::5]

and

>>> print(f.to_array()('H2', 'O2', 'H2O')[::5].info(width=100))

produce identical output.

@ischoegl
Copy link
Member Author

ischoegl commented Apr 10, 2023

@speth ... I updated the C++ core code to use an include list rather the exclude list, and added the following capability to the Python API:

In [4]: print(f.to_array()[::5].info(keys=['grid', 'H2', 'O2', 'H2O']))
          grid           H2         O2          H2O
0    0.0000000  9.47832e-03  0.1367637 -4.65170e-19
5    0.0180000  9.47829e-03  0.1367637  3.25111e-13
10   0.0200625  9.45641e-03  0.1367666  3.52939e-08
15   0.0206250  9.03396e-03  0.1368145  1.88978e-05
20   0.0207891  8.10736e-03  0.1367547  3.88906e-04
..         ...          ...        ...          ...
115  0.0221250  1.14847e-04  0.0631696  7.95561e-02
120  0.0226875  6.51822e-05  0.0630420  8.06377e-02
125  0.0236250  3.16880e-05  0.0631228  8.13895e-02
130  0.0255000  1.26681e-05  0.0632889  8.18752e-02
135  0.0330000  4.06486e-06  0.0634496  8.21637e-02

[28 rows x 4 components; state='TDY']

which I believe is what you suggested.

PS: While I am keenly aware that this is useful for the onedim API, I'd like to use the to_array() approach for the time being, despite not being opposed to revisiting Domain1D.show() before Cantera 3.0 (especially as this was just renamed from show_solution). The main hangup is that the SolutionArray formatting isn't ideal for boundaries, so I'd like to table the discussion and defer to another PR.

PPS: last force-push was to remove a couple of imports that weren't needed any longer.

@ischoegl ischoegl requested a review from speth April 10, 2023 13:17
Copy link
Member

@speth speth left a comment

Choose a reason for hiding this comment

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

Thanks, @ischoegl. Just a couple of small comments from my end.

I wasn't intending to suggest that using this to implement display of 1D domains should be part of this PR, just that the positive include list would make this easier eventually.

interfaces/cython/cantera/solutionbase.pyx Outdated Show resolved Hide resolved
interfaces/cython/cantera/solutionbase.pyx Show resolved Hide resolved
@ischoegl ischoegl force-pushed the solutionarray-show branch 2 times, most recently from b7bae9d to 36051a0 Compare April 10, 2023 23:18
@ischoegl ischoegl requested a review from speth April 10, 2023 23:22
@ischoegl
Copy link
Member Author

ischoegl commented Apr 10, 2023

@speth ... thanks for the comments. Both suggestions are addressed. (Update: apart from needing to update unit tests 😥)

@speth speth merged commit 1f1751b into Cantera:main Apr 11, 2023
@ischoegl ischoegl deleted the solutionarray-show branch April 11, 2023 02:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

2 participants