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

Fix restoring ImpingingJet from HDF5 #1585

Merged
merged 3 commits into from
Aug 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 2 additions & 3 deletions include/cantera/oneD/Boundary1D.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ class Boundary1D : public Domain1D

virtual void setupGrid(size_t n, const double* z) {}

virtual void fromArray(SolutionArray& arr, double* soln);

protected:
void _init(size_t n);

Expand Down Expand Up @@ -201,7 +203,6 @@ class Empty1D : public Boundary1D
integer* diagg, double rdt);

virtual shared_ptr<SolutionArray> asArray(const double* soln) const;
virtual void fromArray(SolutionArray& arr, double* soln) {}
};

/**
Expand Down Expand Up @@ -230,7 +231,6 @@ class Symm1D : public Boundary1D
integer* diagg, double rdt);

virtual shared_ptr<SolutionArray> asArray(const double* soln) const;
virtual void fromArray(SolutionArray& arr, double* soln) {}
};


Expand Down Expand Up @@ -259,7 +259,6 @@ class Outlet1D : public Boundary1D
integer* diagg, double rdt);

virtual shared_ptr<SolutionArray> asArray(const double* soln) const;
virtual void fromArray(SolutionArray& arr, double* soln) {}
};


Expand Down
12 changes: 9 additions & 3 deletions src/oneD/Boundary1D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ void Boundary1D::_init(size_t n)
}
}

void Boundary1D::fromArray(SolutionArray& arr, double* soln)
{
setMeta(arr.meta());
}

// ---------------- Inlet1D methods ----------------

Inlet1D::Inlet1D()
Expand Down Expand Up @@ -574,9 +579,10 @@ shared_ptr<SolutionArray> Surf1D::asArray(const double* soln) const

void Surf1D::fromArray(SolutionArray& arr, double* soln)
{
Boundary1D::setMeta(arr.meta());
arr.setLoc(0);
m_temp = arr.thermo()->temperature();
auto meta = arr.meta();
m_temp = meta["temperature"].asDouble();
meta.erase("temperature");
Boundary1D::setMeta(meta);
}

void Surf1D::show(std::ostream& s, const double* x)
Expand Down
32 changes: 28 additions & 4 deletions src/oneD/Sim1D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,13 @@

for (auto dom : m_dom) {
auto arr = SolutionArray::create(dom->solution());
arr->readEntry(fname, name, dom->id());
try {
arr->readEntry(fname, name, dom->id());
} catch (CanteraError& err) {
throw CanteraError("Sim1D::restore",
"Encountered exception when reading entry '{}' from '{}':\n{}",
name, fname, err.getMessage());
}

Check warning on line 317 in src/oneD/Sim1D.cpp

View check run for this annotation

Codecov / codecov/patch

src/oneD/Sim1D.cpp#L317

Added line #L317 was not covered by tests
dom->resize(dom->nComponents(), arr->size());
if (!header.hasKey("generator")) {
arr->meta() = legacyH5(arr, header);
Expand All @@ -318,7 +324,13 @@
resize();
m_xlast_ts.clear();
for (auto dom : m_dom) {
dom->fromArray(*arrs[dom->id()], m_state->data() + dom->loc());
try {
dom->fromArray(*arrs[dom->id()], m_state->data() + dom->loc());
} catch (CanteraError& err) {
throw CanteraError("Sim1D::restore",
"Encountered exception when restoring domain '{}' from HDF:\n{}",
dom->id(), err.getMessage());
}

Check warning on line 333 in src/oneD/Sim1D.cpp

View check run for this annotation

Codecov / codecov/patch

src/oneD/Sim1D.cpp#L333

Added line #L333 was not covered by tests
}
finalize();
} else if (extension == "yaml" || extension == "yml") {
Expand All @@ -328,14 +340,26 @@

for (auto dom : m_dom) {
auto arr = SolutionArray::create(dom->solution());
arr->readEntry(root, name, dom->id());
try {
arr->readEntry(root, name, dom->id());
} catch (CanteraError& err) {
throw CanteraError("Sim1D::restore",
"Encountered exception when reading entry '{}' from '{}':\n{}",
name, fname, err.getMessage());
}

Check warning on line 349 in src/oneD/Sim1D.cpp

View check run for this annotation

Codecov / codecov/patch

src/oneD/Sim1D.cpp#L349

Added line #L349 was not covered by tests
dom->resize(dom->nComponents(), arr->size());
arrs[dom->id()] = arr;
}
resize();
m_xlast_ts.clear();
for (auto dom : m_dom) {
dom->fromArray(*arrs[dom->id()], m_state->data() + dom->loc());
try {
dom->fromArray(*arrs[dom->id()], m_state->data() + dom->loc());
} catch (CanteraError& err) {
throw CanteraError("Sim1D::restore",
"Encountered exception when restoring domain '{}' from YAML:\n{}",
dom->id(), err.getMessage());
}

Check warning on line 362 in src/oneD/Sim1D.cpp

View check run for this annotation

Codecov / codecov/patch

src/oneD/Sim1D.cpp#L362

Added line #L362 was not covered by tests
}
finalize();
} else {
Expand Down
81 changes: 81 additions & 0 deletions test/python/test_onedim.py
Original file line number Diff line number Diff line change
Expand Up @@ -1502,6 +1502,87 @@ def test_restart(self):
for rhou_j in sim.density * sim.velocity:
self.assertNear(rhou_j, rhou, 1e-4)


class TestStagnationFlame(utilities.CanteraTest):
def setUp(self):
self.gas = ct.Solution("h2o2.yaml")

def create_stagnation(self, comp, tsurf, tinlet, mdot, width):
p = 0.05 * ct.one_atm # pressure
self.gas.TPX = tinlet, p, comp

sim = ct.ImpingingJet(gas=self.gas, width=width)
sim.inlet.mdot = mdot
sim.surface.T = tsurf
return sim

def run_stagnation(self, xh2, mdot, width):
# Simplified version of the example 'stagnation_flame.py'
tburner = 373.0 # burner temperature
tsurf = 500.0
comp = {'H2': xh2, 'O2': 1, 'AR': 7}
sim = self.create_stagnation(comp, tsurf, tburner, mdot, width)

sim.set_grid_min(1e-4)
sim.set_refine_criteria(3., 0.1, 0.2, 0.06)
sim.set_initial_guess(products='equil') # assume adiabatic equilibrium products

sim.solve(loglevel=0, auto=True)

assert sim.T.max() > tburner + tsurf
self.sim = sim

def test_stagnation_case1(self):
self.run_stagnation(xh2=1.8, mdot=0.06, width=0.2)

@pytest.mark.skipif("native" not in ct.hdf_support(),
reason="Cantera compiled without HDF support")
def test_restore_hdf(self):
self.run_save_restore("h5")

def test_restore_yaml(self):
self.run_save_restore("yaml")

def run_save_restore(self, mode):
filename = self.test_work_path / f"stagnation.{mode}"
filename.unlink(missing_ok=True)

self.run_stagnation(xh2=1.8, mdot=0.06, width=0.1)
self.sim.save(filename, "test")

jet = ct.ImpingingJet(gas=self.gas)
jet.restore(filename, "test")

self.check_save_restore(jet)

def check_save_restore(self, jet):
# pytest.approx is used as equality for floats cannot be guaranteed for loaded
# HDF5 files if they were created on a different OS and/or architecture
assert list(jet.grid) == pytest.approx(list(self.sim.grid))
assert list(jet.T) == pytest.approx(list(self.sim.T), 1e-3)
k = self.sim.gas.species_index('H2')
assert list(jet.X[k, :]) == pytest.approx(list(self.sim.X[k, :]), 1e-4)

settings = self.sim.flame.get_settings3()
for k, v in jet.flame.get_settings3().items():
assert k in settings
if k == "fixed_temperature":
# fixed temperature is NaN
continue
if isinstance(v, dict):
for kk, vv in v.items():
if isinstance(vv, float):
assert settings[k][kk] == pytest.approx(vv)
else:
assert settings[k][kk] == vv
if isinstance(k, float):
assert settings[k] == pytest.approx(v)
else:
assert settings[k] == v

jet.solve(loglevel=0)


class TestImpingingJet(utilities.CanteraTest):
def setUp(self):
self.gas = ct.Solution("ptcombust-simple.yaml", "gas")
Expand Down
Loading