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

Use YAML for saving and loading 1D flame simulations #1112

Merged
merged 26 commits into from
Oct 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a2eaa75
[Input] Add a function for clearing cached input files
speth Sep 17, 2021
6d3898c
[1D] Add basic framework for saving to YAML files
speth Sep 20, 2021
4f99073
[1D] Implement serialization of Boundary1D objects to YAML
speth Sep 20, 2021
599ad47
[1D] Improve serialization of absolute/relative tolerances
speth Sep 21, 2021
d141a23
[1D] Serialize StFlow to YAML
speth Sep 21, 2021
5cbafcb
[1D] Make StFlow::flowType a const function
speth Sep 21, 2021
34a968e
[1D] Remove unused member variable Domain1D::m_desc
speth Sep 21, 2021
2a5e980
[1D] Add description and timestamp to YAML output files
speth Sep 22, 2021
56aedb5
[1D] Implement restoring flame solutions from YAML files
speth Sep 22, 2021
1138b89
[1D/Test] Add tests of saving and restoring 1D solutions with YAML
speth Sep 22, 2021
7f686cf
[1D] Add generator and Cantera version to YAML output
speth Oct 6, 2021
7a3465d
[1D] Update samples to use YAML output instead of XML
speth Oct 6, 2021
adddba3
[Matlab/1D] Fix usage of outdated component names
speth Oct 6, 2021
8dab8cb
[1D] Improve test coverage for YAML-based save/restore
speth Oct 7, 2021
2635009
[1D] Move domains to top level of saved flame solution
speth Oct 17, 2021
3c2f26f
[1D] Update YAML metadata fields
speth Oct 17, 2021
afa3801
[1D] Include radiation-related properties in YAML output
speth Oct 17, 2021
f2d272d
[1D] Include max grid point setting in YAML input/output
speth Oct 17, 2021
4501888
[1D] Save phase name and source file in YAML output
speth Oct 17, 2021
bafb6c0
[1D] Include Soret-enabled flag in YAML input/output
speth Oct 17, 2021
3ce60a3
[1D] Update Python examples to use YAML output instead of XML
speth Oct 17, 2021
8a70fe6
[1D] Rename tolerances stored in YAML output files
speth Oct 20, 2021
7af8607
[1D] Improve ordering of keys in YAML output
speth Oct 20, 2021
950ea20
[YAML] Increase maximum line length when serializing
speth Oct 20, 2021
12b8829
[1D] Avoid serializing components that are not used in a given model
speth Oct 20, 2021
3268e96
[Input] Improve documentation of AnyMap YAML emitters
speth Oct 26, 2021
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
3 changes: 3 additions & 0 deletions include/cantera/base/AnyMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,9 @@ class AnyMap : public AnyBase
static bool addOrderingRules(const std::string& objectType,
const std::vector<std::vector<std::string>>& specs);

//! Remove the specified file from the input cache if it is present
static void clearCachedFile(const std::string& filename);

private:
//! The stored data
std::unordered_map<std::string, AnyValue> m_data;
Expand Down
11 changes: 11 additions & 0 deletions include/cantera/oneD/Boundary1D.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ class Inlet1D : public Boundary1D
integer* diagg, double rdt);
virtual XML_Node& save(XML_Node& o, const double* const soln);
virtual void restore(const XML_Node& dom, double* soln, int loglevel);
virtual AnyMap serialize(const double* soln) const;
virtual void restore(const AnyMap& state, double* soln, int loglevel);

protected:
int m_ilr;
Expand Down Expand Up @@ -163,6 +165,7 @@ class Empty1D : public Boundary1D

virtual XML_Node& save(XML_Node& o, const double* const soln);
virtual void restore(const XML_Node& dom, double* soln, int loglevel);
virtual AnyMap serialize(const double* soln) const;
};

/**
Expand All @@ -184,6 +187,7 @@ class Symm1D : public Boundary1D

virtual XML_Node& save(XML_Node& o, const double* const soln);
virtual void restore(const XML_Node& dom, double* soln, int loglevel);
virtual AnyMap serialize(const double* soln) const;
};


Expand All @@ -205,6 +209,7 @@ class Outlet1D : public Boundary1D

virtual XML_Node& save(XML_Node& o, const double* const soln);
virtual void restore(const XML_Node& dom, double* soln, int loglevel);
virtual AnyMap serialize(const double* soln) const;
};


Expand Down Expand Up @@ -233,6 +238,8 @@ class OutletRes1D : public Boundary1D
integer* diagg, double rdt);
virtual XML_Node& save(XML_Node& o, const double* const soln);
virtual void restore(const XML_Node& dom, double* soln, int loglevel);
virtual AnyMap serialize(const double* soln) const;
virtual void restore(const AnyMap& state, double* soln, int loglevel);

protected:
size_t m_nsp;
Expand Down Expand Up @@ -261,6 +268,8 @@ class Surf1D : public Boundary1D

virtual XML_Node& save(XML_Node& o, const double* const soln);
virtual void restore(const XML_Node& dom, double* soln, int loglevel);
virtual AnyMap serialize(const double* soln) const;
virtual void restore(const AnyMap& state, double* soln, int loglevel);

virtual void showSolution_s(std::ostream& s, const double* x);

Expand Down Expand Up @@ -296,6 +305,8 @@ class ReactingSurf1D : public Boundary1D

virtual XML_Node& save(XML_Node& o, const double* const soln);
virtual void restore(const XML_Node& dom, double* soln, int loglevel);
virtual AnyMap serialize(const double* soln) const;
virtual void restore(const AnyMap& state, double* soln, int loglevel);

virtual void _getInitialSoln(double* x) {
m_sphase->getCoverages(x);
Expand Down
17 changes: 16 additions & 1 deletion include/cantera/oneD/Domain1D.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const int cPorousType = 109;
class MultiJac;
class OneDim;
class Refiner;
class AnyMap;
class XML_Node;

/**
Expand Down Expand Up @@ -340,6 +341,21 @@ class Domain1D
*/
virtual void restore(const XML_Node& dom, doublereal* soln, int loglevel);

//! Save the state of this domain as an AnyMap
/*!
* @param soln local solution vector for this domain
*/
virtual AnyMap serialize(const double* soln) const;
ischoegl marked this conversation as resolved.
Show resolved Hide resolved

//! Restore the solution for this domain from an AnyMap
/*!
* @param[in] state AnyMap defining the state of this domain
* @param[out] soln Value of the solution vector, local to this domain
* @param[in] loglevel 0 to suppress all output; 1 to show warnings; 2 for
* verbose output
*/
virtual void restore(const AnyMap& state, double* soln, int loglevel);

size_t size() const {
return m_nv*m_points;
}
Expand Down Expand Up @@ -511,7 +527,6 @@ class Domain1D

//! Identity tag for the domain
std::string m_id;
std::string m_desc;
std::unique_ptr<Refiner> m_refiner;
std::vector<std::string> m_name;
int m_bw;
Expand Down
1 change: 1 addition & 0 deletions include/cantera/oneD/IonFlow.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class IonFlow : public StFlow
virtual void setSolvingStage(const size_t phase);

virtual void resize(size_t components, size_t points);
virtual bool componentActive(size_t n) const;

virtual void _finalize(const double* x);
//! set to solve electric field on a point
Expand Down
3 changes: 3 additions & 0 deletions include/cantera/oneD/OneDim.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace Cantera

class Func1;
class MultiNewton;
class AnyMap;

/**
* Container class for multiple-domain 1D problems. Each domain is
Expand Down Expand Up @@ -227,6 +228,8 @@ class OneDim
void save(const std::string& fname, std::string id,
const std::string& desc, doublereal* sol, int loglevel);

AnyMap serialize(const double* soln) const;

// options
void setMinTimeStep(doublereal tmin) {
m_tmin = tmin;
Expand Down
8 changes: 7 additions & 1 deletion include/cantera/oneD/StFlow.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ class StFlow : public Domain1D

virtual size_t componentIndex(const std::string& name) const;

//! Returns true if the specified component is an active part of the solver state
virtual bool componentActive(size_t n) const;

//! Print the solution.
virtual void showSolution(const doublereal* x);

Expand All @@ -155,6 +158,9 @@ class StFlow : public Domain1D
virtual void restore(const XML_Node& dom, doublereal* soln,
int loglevel);

virtual AnyMap serialize(const double* soln) const;
virtual void restore(const AnyMap& state, double* soln, int loglevel);

//! Set flow configuration for freely-propagating flames, using an internal
//! point with a fixed temperature as the condition to determine the inlet
//! mass flux.
Expand All @@ -173,7 +179,7 @@ class StFlow : public Domain1D
//! Return the type of flow domain being represented, either "Free Flame" or
//! "Axisymmetric Stagnation".
//! @see setFreeFlow setAxisymmetricFlow
virtual std::string flowType() {
virtual std::string flowType() const {
if (m_type == cFreeFlow) {
return "Free Flame";
} else if (m_type == cAxisymmetricStagnationFlow) {
Expand Down
4 changes: 2 additions & 2 deletions interfaces/cython/cantera/examples/onedim/adiabatic_flame.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
f.write_hdf('adiabatic_flame.h5', group='mix', mode='w',
description='solution with mixture-averaged transport')
except ImportError:
f.save('adiabatic_flame.xml', 'mix',
f.save('adiabatic_flame.yaml', 'mix',
'solution with mixture-averaged transport')

f.show_solution()
Expand All @@ -49,7 +49,7 @@
f.write_hdf('adiabatic_flame.h5', group='multi',
description='solution with multicomponent transport')
except ImportError:
f.save('adiabatic_flame.xml', 'multi',
f.save('adiabatic_flame.yaml', 'multi',
'solution with multicomponent transport')

# write the velocity, temperature, density, and mole fractions to a CSV file
Expand Down
4 changes: 2 additions & 2 deletions interfaces/cython/cantera/examples/onedim/burner_flame.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
f.write_hdf('burner_flame.h5', group='mix', mode='w',
description='solution with mixture-averaged transport')
except ImportError:
f.save('burner_flame.xml', 'mix', 'solution with mixture-averaged transport')
f.save('burner_flame.yaml', 'mix', 'solution with mixture-averaged transport')

f.transport_model = 'Multi'
f.solve(loglevel) # don't use 'auto' on subsequent solves
Expand All @@ -37,6 +37,6 @@
f.write_hdf('burner_flame.h5', group='multi',
description='solution with multicomponent transport')
except ImportError:
f.save('burner_flame.xml', 'multi', 'solution with multicomponent transport')
f.save('burner_flame.yaml', 'multi', 'solution with multicomponent transport')

f.write_csv('burner_flame.csv', quiet=False)
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
# save to HDF container file if h5py is installed
f.write_hdf('diffusion_flame.h5', mode='w')
except ImportError:
f.save('diffusion_flame.xml')
f.save('diffusion_flame.yaml')

# write the velocity, temperature, and mole fractions to a CSV file
f.write_csv('diffusion_flame.csv', quiet=False)
Expand Down
22 changes: 10 additions & 12 deletions interfaces/cython/cantera/examples/onedim/diffusion_flame_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ def interrupt_extinction(t):
description=('Initial hydrogen-oxygen counterflow flame '
'at 1 bar and low strain rate'))
else:
file_name = 'initial_solution.xml'
file_name = 'initial_solution.yaml'
f.save(os.path.join(data_directory, file_name), name='solution',
description='Cantera version ' + ct.__version__ +
', reaction mechanism ' + reaction_mechanism)
description='Initial hydrogen-oxygen counterflow flame '
'at 1 bar and low strain rate')


# PART 2: BATCH PRESSURE LOOP
Expand Down Expand Up @@ -142,10 +142,9 @@ def interrupt_extinction(t):
f.write_hdf(file_name, group=group, quiet=False,
description='pressure = {0} bar'.format(p))
else:
file_name = 'pressure_loop_' + format(p, '05.1f') + '.xml'
file_name = 'pressure_loop_' + format(p, '05.1f') + '.yaml'
f.save(os.path.join(data_directory, file_name), name='solution', loglevel=1,
description='Cantera version ' + ct.__version__ +
', reaction mechanism ' + reaction_mechanism)
description='pressure = {0} bar'.format(p))
p_previous = p
except ct.CanteraError as e:
print('Error occurred while solving:', e, 'Try next pressure level')
Expand Down Expand Up @@ -176,7 +175,7 @@ def interrupt_extinction(t):
if hdf_output:
f.read_hdf(file_name, group='initial_solution')
else:
file_name = 'initial_solution.xml'
file_name = 'initial_solution.yaml'
f.restore(filename=os.path.join(data_directory, file_name), name='solution', loglevel=0)

# Counter to identify the loop
Expand Down Expand Up @@ -207,10 +206,9 @@ def interrupt_extinction(t):
f.write_hdf(file_name, group=group, quiet=False,
description='strain rate iteration {}'.format(n))
else:
file_name = 'strain_loop_' + format(n, '02d') + '.xml'
file_name = 'strain_loop_' + format(n, '02d') + '.yaml'
f.save(os.path.join(data_directory, file_name), name='solution', loglevel=1,
description='Cantera version ' + ct.__version__ +
', reaction mechanism ' + reaction_mechanism)
description='strain rate iteration {}'.format(n))
except FlameExtinguished:
print('Flame extinguished')
break
Expand All @@ -232,7 +230,7 @@ def interrupt_extinction(t):
group = 'pressure_loop/{0:05.1f}'.format(p)
f.read_hdf(file_name, group=group)
else:
file_name = 'pressure_loop_{0:05.1f}.xml'.format(p)
file_name = 'pressure_loop_{0:05.1f}.yaml'.format(p)
f.restore(filename=os.path.join(data_directory, file_name), name='solution', loglevel=0)

# Plot the temperature profiles for selected pressures
Expand Down Expand Up @@ -263,7 +261,7 @@ def interrupt_extinction(t):
group = 'strain_loop/{0:02d}'.format(n)
f.read_hdf(file_name, group=group)
else:
file_name = 'strain_loop_{0:02d}.xml'.format(n)
file_name = 'strain_loop_{0:02d}.yaml'.format(n)
f.restore(filename=os.path.join(data_directory, file_name),
name='solution', loglevel=0)
a_max = f.strain_rate('max') # the maximum axial strain rate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,9 @@
description=('Initial solution'))
else:
# Save to data directory
file_name = 'initial_solution.xml'
file_name = 'initial_solution.yaml'
f.save(os.path.join(data_directory, file_name), name='solution',
description='Cantera version ' + ct.__version__ +
', reaction mechanism ' + reaction_mechanism)
description="Initial solution")


# PART 2: COMPUTE EXTINCTION STRAIN
Expand Down Expand Up @@ -138,11 +137,10 @@
group = 'extinction/{0:04d}'.format(n)
f.write_hdf(file_name, group=group, quiet=True)
else:
file_name = 'extinction_{0:04d}.xml'.format(n)
file_name = 'extinction_{0:04d}.yaml'.format(n)
f.save(os.path.join(data_directory, file_name),
name='solution', loglevel=0,
description='Cantera version ' + ct.__version__ +
', reaction mechanism ' + reaction_mechanism)
description=f"Solution at alpha = {alpha[-1]}")
T_max.append(np.max(f.T))
a_max.append(np.max(np.abs(np.gradient(f.velocity) / np.gradient(f.grid))))
print('Flame burning at alpha = {:8.4F}. Proceeding to the next iteration, '
Expand All @@ -157,7 +155,7 @@
group = 'extinction/{0:04d}'.format(n)
f.write_hdf(file_name, group=group, quiet=True)
else:
file_name = 'extinction_{0:04d}.xml'.format(n)
file_name = 'extinction_{0:04d}.yaml'.format(n)
f.save(os.path.join(data_directory, file_name), name='solution', loglevel=0)
print('Flame extinguished at alpha = {0:8.4F}.'.format(alpha[-1]),
'Abortion criterion satisfied.')
Expand All @@ -176,7 +174,7 @@
group = 'extinction/{0:04d}'.format(n_last_burning)
f.read_hdf(file_name, group=group)
else:
file_name = 'extinction_{0:04d}.xml'.format(n_last_burning)
file_name = 'extinction_{0:04d}.yaml'.format(n_last_burning)
f.restore(os.path.join(data_directory, file_name),
name='solution', loglevel=0)

Expand All @@ -187,7 +185,7 @@
group = 'extinction/{0:04d}'.format(n_last_burning)
f.read_hdf(file_name, group=group)
else:
file_name = 'extinction_{0:04d}.xml'.format(n_last_burning)
file_name = 'extinction_{0:04d}.yaml'.format(n_last_burning)
f.restore(os.path.join(data_directory, file_name),
name='solution', loglevel=0)
print('----------------------------------------------------------------------')
Expand Down
4 changes: 2 additions & 2 deletions interfaces/cython/cantera/examples/onedim/flame_fixed_T.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
f.write_hdf('flame_fixed_T.h5', group='mix', mode='w',
description='solution with mixture-averaged transport')
except ImportError:
f.save('flame_fixed_T.xml','mixav',
f.save('flame_fixed_T.yaml','mixav',
'solution with mixture-averaged transport')

print('\n\n switching to multicomponent transport...\n\n')
Expand All @@ -75,7 +75,7 @@
f.write_hdf('flame_fixed_T.h5', group='multi',
description='solution with multicomponent transport')
except ImportError:
f.save('flame_fixed_T.xml','multi',
f.save('flame_fixed_T.yaml','multi',
'solution with multicomponent transport')

# write the velocity, temperature, density, and mole fractions to a CSV file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@
f.write_hdf('ion_burner_flame.h5', group='ion', mode='w',
description='solution with ionized gas transport')
except ImportError:
f.save('ion_burner_flame.xml', 'mix', 'solution with mixture-averaged transport')
f.save('ion_burner_flame.yaml', 'mix', 'solution with mixture-averaged transport')

f.write_csv('ion_burner_flame.csv', quiet=False)
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
f.write_hdf('ion_free_flame.h5', group='ion', mode='w',
description='solution with ionized gas transport')
except ImportError:
f.save('ion_free_flame.xml', 'ion', 'solution with ionized gas transport')
f.save('ion_free_flame.yaml', 'ion', 'solution with ionized gas transport')

f.show_solution()
print('mixture-averaged flamespeed = {0:7f} m/s'.format(f.velocity[0]))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
if hdf_output:
outfile = 'stagnation_flame.h5'
else:
outfile = 'stagnation_flame.xml'
outfile = 'stagnation_flame.yaml'
if os.path.exists(outfile):
os.remove(outfile)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,13 @@
# show the solution
sim.show_solution()

# save the solution in XML format. The 'restore' method can be used to restart
# save the full solution. The 'restore' method can be used to restart
# a simulation from a solution stored in this form.
try:
sim.write_hdf('catalytic_combustion.h5', group='soln1', mode='w',
description='catalytic combustion example')
except ImportError:
sim.save("catalytic_combustion.xml", "soln1")
sim.save("catalytic_combustion.yaml", "soln1")

# save selected solution components in a CSV file for plotting in
# Excel or MATLAB.
Expand Down
Loading