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

Implement C++ SolutionArray::save for CSV output #1508

Merged
merged 19 commits into from
Jun 22, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
9588f3e
[base] Create framework for SolutionArray::save CSV output
ischoegl Jun 19, 2023
796c354
[base] Write CSV header line for SolutionArray::save
ischoegl Jun 20, 2023
f16a1d8
[base] Write CSV body for SolutionArray::save
ischoegl Jun 20, 2023
b3021d0
[Python] Make SolutionArray.from_pandas more flexible
ischoegl Jun 20, 2023
a3137eb
[base] Simplify CSV SolutionArray::save
ischoegl Jun 20, 2023
48cbdcc
[base] Improve exception handling for CSV SolutionArray::save
ischoegl Jun 20, 2023
1df5287
[base] Enable flexible species base for CSV output
ischoegl Jun 20, 2023
e727e19
Implement flexible basis for SolutionArray::save CSV
ischoegl Jun 20, 2023
a3b57c2
[base] Clarify exception for CSV SolutionArray::restore
ischoegl Jun 20, 2023
8c4e410
[base] Increase precision for CSV output
ischoegl Jun 20, 2023
a479693
[Python] Add missing SolutionArrayBase.resize method
ischoegl Jun 20, 2023
2f00a0b
[Python] Deprecate SolutionArray.write_csv
ischoegl Jun 20, 2023
894afa2
[samples] Replace write_csv with save
ischoegl Jun 20, 2023
fdb4367
[oneD] Replace write_csv by save
ischoegl Jun 20, 2023
24934ae
[unittests] Add coverage for CSV SolutionArray.save
ischoegl Jun 20, 2023
8f3882c
Improve SolutionArray IO documentation and exceptions
ischoegl Jun 21, 2023
39f1bfb
Resolve discrepancies of nomenclature in C++/Python
ischoegl Jun 21, 2023
0a2dbce
Additional documentation updates for Sim1D file IO
ischoegl Jun 21, 2023
4800cd4
[samples] Update keyword in failing test
ischoegl Jun 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 89 additions & 49 deletions include/cantera/base/SolutionArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ class ThermoPhase;
* stored, reshaping operations need to be implemented in high-level API's.
*
* @since New in Cantera 3.0.
* @warning This class is an experimental part of the %Cantera API and may be
* changed or removed without notice.
*/
class SolutionArray
{
Expand Down Expand Up @@ -189,105 +187,147 @@ class SolutionArray
void append(const vector<double>& state, const AnyMap& extra);

/*!
* Write header data to container file.
* Write header data to a HDF container file.
*
* @param fname Name of HDF container file
* @param id Identifier of root location within the container file
* @param desc Description
* @param overwrite Force overwrite if id exists; optional (default=false)
* @param name Identifier of group holding header information
* @param desc Custom comment describing dataset
* @param overwrite Force overwrite if file/group exists; optional (default=false)
*/
static void writeHeader(const string& fname, const string& id, const string& desc,
static void writeHeader(const string& fname, const string& name, const string& desc,
bool overwrite=false);

/*!
* Write header data to AnyMap.
* Write header data to AnyMap; used by YAML serialization.
*
* @param root Root node of AnyMap structure
* @param id Identifier of root location within the container file
* @param desc Description
* @param overwrite Force overwrite if id exists; optional (default=false)
* @param name Identifier of node holding header information
* @param desc Custom comment describing dataset
* @param overwrite Force overwrite if node exists; optional (default=false)
*/
static void writeHeader(AnyMap& root, const string& id, const string& desc,
static void writeHeader(AnyMap& root, const string& name, const string& desc,
bool overwrite=false);

/*!
* Write SolutionArray data to container file.
* Write SolutionArray data to a CSV file.
*
* @param fname Name of CSV file
* @param overwrite Force overwrite if file exists; optional (default=false)
* @param basis Output mass ("Y"/"mass") or mole ("X"/"mole") fractions;
* if omitted (default=""), the native basis of the underlying ThermoPhase
* manager is used - @see nativeState
*/
void writeEntry(const string& fname, bool overwrite=false, const string& basis="");

/*!
* Write SolutionArray data to a HDF container file.
*
* @param fname Name of HDF container file
* @param id Identifier of root location within the container file
* @param sub Name identifier for the subgroup holding actual data
* @param overwrite Force overwrite if sub exists; optional (default=false)
* @param name Identifier of group holding header information
* @param sub Name identifier of subgroup holding SolutionArray data
* @param overwrite Force overwrite if subgroup exists; optional (default=false)
* @param compression Compression level; optional (default=0; HDF only)
*/
void writeEntry(const string& fname, const string& id, const string& sub,
void writeEntry(const string& fname, const string& name, const string& sub,
bool overwrite=false, int compression=0);

/*!
* Write SolutionArray data to AnyMap.
* Write SolutionArray data to AnyMap; used by YAML serialization.
*
* @param root Root node of AnyMap structure
* @param id Identifier of root location within the container file
* @param sub Name identifier for the subgroup holding actual data
* @param overwrite Force overwrite if sub exists; optional (default=false)
* @param name Identifier of node holding header information and subgroup
* @param sub Name identifier of subgroup holding SolutionArray data
* @param overwrite Force overwrite if subgroup exists; optional (default=false)
*/
void writeEntry(AnyMap& root, const string& id, const string& sub,
void writeEntry(AnyMap& root, const string& name, const string& sub,
bool overwrite=false);

/*!
* Save current SolutionArray and header to a container file.
* Save current SolutionArray contents to a data file.
*
* @param fname Name of output container file (YAML or HDF)
* @param id Identifier of root location within the container file
* @param sub Name identifier for the subgroup holding actual data
* @param desc Custom comment describing the dataset to be stored
* @param overwrite Force overwrite if sub exists; optional (default=false)
* @param compression Compression level; optional (default=0; HDF only)
* Data can be saved either in CSV format (extension '*.csv'), YAML container
* format (extension '*.yaml'/'*.yml') or HDF container format (extension
* '*.h5'/'*.hdf5'/'*.hdf'). The output format is automatically inferred from the
* file extension.
*
* CSV files preserve state data and auxiliary data for a single SolutionArray in a
* comma-separated text format, container files may hold multiple SolutionArray
* entries in an internal hierarchical structure. While YAML is a human-readable
* text format, HDF is a binary format that supports compression and is recommended
* for large datasets.
*
* For container files (YAML and HDF), header information contains automatically
* generated time stamps, version information and an optional description.
* Container files also preserve SolutionArray metadata (example: SolutionArray
* objects generated by Sim1D hold simulation settings).
*
* @param fname Name of output file (CSV, YAML or HDF)
* @param name Identifier of location within the container file; this node/group
* contains header information and a subgroup holding actual SolutionArray data
* (YAML/HDF only)
* @param sub Name identifier for the subgroup holding the SolutionArray data and
* metadata objects. If omitted (""), the subgroup name defaults to "data"
* (YAML/HDF only)
* @param desc Custom comment describing dataset to be stored (YAML/HDF only)
* @param overwrite Force overwrite if file and/or data entry exists; optional
* (default=false)
* @param compression Compression level (0-9); (default=0; HDF only)
* @param basis Output mass ("Y"/"mass") or mole ("X"/"mole") fractions;
* if not specified (default=""), the native basis of the underlying
* ThermoPhase manager is used - @see nativeState (CSV only)
*/
void save(const string& fname, const string& id, const string& sub,
const string& desc, bool overwrite=false, int compression=0);
void save(const string& fname, const string& name="", const string& sub="",
const string& desc="", bool overwrite=false, int compression=0,
const string& basis="");

/*!
* Read header data from container file.
* Read header information from a HDF container file.
*
* @param fname Name of HDF container file
* @param id Identifier of root location within the container file
* @param name Identifier of group holding header information
*/
static AnyMap readHeader(const string& fname, const string& id);
static AnyMap readHeader(const string& fname, const string& name);

/*!
* Read header data from AnyMap.
* Read header information from AnyMap; used by YAML serialization.
*
* @param root Root node of AnyMap structure
* @param id Identifier of root location within the container file
* @param name Identifier of node holding header information
*/
static AnyMap readHeader(const AnyMap& root, const string& id);
static AnyMap readHeader(const AnyMap& root, const string& name);

/*!
* Restore SolutionArray entry from a container file.
* Restore SolutionArray data from a HDF container file.
*
* @param fname Name of HDF container file
* @param id Identifier of root location within the container file
* @param sub Name of the subgroup holding actual data
* @param name Identifier of group holding header information
* @param sub Name identifier of subgroup holding SolutionArray data
*/
void readEntry(const string& fname, const string& id, const string& sub);
void readEntry(const string& fname, const string& name, const string& sub);

/*!
* Restore SolutionArray entry from AnyMap.
* Restore SolutionArray data from AnyMap; used by YAML serialization.
*
* @param root Root node of AnyMap structure
* @param id Identifier of root location within the container file
* @param sub Name of the subgroup holding actual data
* @param name Identifier of node holding header information
* @param sub Name identifier of subgroup holding SolutionArray data
*/
void readEntry(const AnyMap& root, const string& id, const string& sub);
void readEntry(const AnyMap& root, const string& name, const string& sub);

/*!
* Restore SolutionArray entry and header from a container file.
* Restore SolutionArray data and header information from a container file.
*
* This method retrieves data from a YAML or HDF files that were previously saved
* using the @see save method.
*
* @param fname Name of container file (YAML or HDF)
* @param id Identifier of SolutionArray within the container file
* @param sub Name of the subgroup holding actual data
* @param name Identifier of location within the container file; this node/group
* contains header information and a subgroup holding actual SolutionArray data
* @param sub Name identifier for the subgroup holding the SolutionArray data and
* metadata objects. If omitted (""), the subgroup name defaults to "data"
* @return AnyMap containing header information
*/
AnyMap restore(const string& fname, const string& id, const string& sub);
AnyMap restore(const string& fname, const string& name, const string& sub="");

protected:
//! Service function used to resize SolutionArray
Expand Down
23 changes: 15 additions & 8 deletions include/cantera/oneD/Sim1D.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,22 @@ class Sim1D : public OneDim
const std::string& desc, int loglevel);

/**
* Save the current solution to a container file.
* Save the current solution to a container or CSV file.
*
* For HDF and YAML, the entire content of the object is saved; for CSV, only the
* main 1D domain is saved.
*
* @param fname Name of output container file
* @param id Identifier of solution within the container file
* @param name Identifier of solution within the container file
* @param desc Description of the solution
* @param overwrite Force overwrite if name exists; optional (default=false)
* @param compression Compression level (optional; HDF only)
* @param basis Output mass ("Y"/"mass") or mole ("X"/"mole") fractions (CSV only);
* if omitted (default=""), the native storage mode is used
bryanwweber marked this conversation as resolved.
Show resolved Hide resolved
*/
void save(const std::string& fname, const std::string& id,
const std::string& desc, bool overwrite=false, int compression=0);
void save(const std::string& fname, const std::string& name,
const std::string& desc, bool overwrite=false, int compression=0,
const string& basis="");

/**
* Save the residual of the current solution to a container file.
Expand All @@ -166,12 +173,12 @@ class Sim1D : public OneDim
/**
* Save the residual of the current solution to a container file.
* @param fname Name of output container file
* @param id Identifier of solution within the container file
* @param name Identifier of solution within the container file
* @param desc Description of the solution
* @param overwrite Force overwrite if name exists; optional (default=false)
* @param compression Compression level (optional; HDF only)
*/
void saveResidual(const std::string& fname, const std::string& id,
void saveResidual(const std::string& fname, const std::string& name,
const std::string& desc, bool overwrite=false, int compression=0);

/**
Expand All @@ -187,10 +194,10 @@ class Sim1D : public OneDim
/**
* Initialize the solution with a previously-saved solution.
* @param fname Name of container file
* @param id Identifier of solution within the container file
* @param name Identifier of solution within the container file
* @return AnyMap containing header information
*/
AnyMap restore(const std::string& fname, const std::string& id);
AnyMap restore(const std::string& fname, const std::string& name);

//! @}

Expand Down
2 changes: 1 addition & 1 deletion interfaces/cython/cantera/_onedim.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ cdef extern from "cantera/oneD/Sim1D.h":
void refine(int) except +translate_exception
void setRefineCriteria(size_t, double, double, double, double) except +translate_exception
vector[double] getRefineCriteria(int) except +translate_exception
void save(string&, string&, string&, cbool, int) except +translate_exception
void save(string&, string&, string&, cbool, int, string&) except +translate_exception
CxxAnyMap restore(string&, string&) except +translate_exception
void writeStats(int) except +translate_exception
void clearStats()
Expand Down
20 changes: 15 additions & 5 deletions interfaces/cython/cantera/_onedim.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1537,20 +1537,30 @@ cdef class Sim1D:
return self.sim.fixedTemperatureLocation()

def save(self, filename='soln.yaml', name='solution', description=None,
loglevel=None, overwrite=False, compression=0):
loglevel=None, *, overwrite=False, compression=0, basis=None):
bryanwweber marked this conversation as resolved.
Show resolved Hide resolved
"""
Save the solution in YAML or HDF format.
Save the solution to a container or CSV format.

In order to save the content of a `Sim1D` object, individual domains are
converted to `SolutionArray` objects and saved using the `SolutionArray.save`
method. For HDF and YAML output, all domains are written to a single container
file with shared header information. Simulation settings of individual domains
are preserved as meta data of the corresponding `SolutionArray` objects.
For CSV files, only state and auxiliary data of the main 1D domain are saved.

:param filename:
solution file
:param name:
solution name within the file
solution name within the file (HDF/YAML only)
:param description:
custom description text
custom description text (HDF/YAML only)
:param overwrite:
Force overwrite if name exists; optional (default=`False`)
:param compression:
compression level 0..9; optional (HDF only)
:param basis:
Output mass (``Y``/``mass``) or mole (``X``/``mole``) fractions (CSV only);
if not specified (`None`), the native storage mode is used

>>> s.save(filename='save.yaml', name='energy_off',
... description='solution with energy eqn. disabled')
Expand All @@ -1562,7 +1572,7 @@ cdef class Sim1D:
warnings.warn("Argument 'loglevel' is deprecated and will be ignored.",
DeprecationWarning)
self.sim.save(stringify(str(filename)), stringify(name),
stringify(description), overwrite, compression)
stringify(description), overwrite, compression, stringify(basis))

def restore(self, filename='soln.yaml', name='solution', loglevel=None):
"""Set the solution vector to a previously-saved solution.
Expand Down
Loading