Skip to content

Commit e7116fa

Browse files
ischoeglIngmar Schoegl
authored andcommitted
[stub] Investigate pickle serialization of Solution objects
1 parent 358195e commit e7116fa

6 files changed

Lines changed: 43 additions & 6 deletions

File tree

include/cantera/thermo/Phase.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ class Phase
126126
*/
127127
void setXMLdata(XML_Node& xmlPhase);
128128

129+
//! write out XML tree information used for creation
130+
std::string getXMLstring() const;
131+
129132
/*! @name Name
130133
* Class Phase uses the string name to identify a phase. The name is the
131134
* value of the corresponding key in the phase map (in YAML), name (in

interfaces/cython/cantera/_cantera.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera":
156156
size_t stateSize()
157157
void saveState(size_t, double*) except +translate_exception
158158
void restoreState(size_t, double*) except +translate_exception
159+
string getXMLstring() except +translate_exception
159160

160161
# initialization
161162
void addUndefinedElements() except +translate_exception

interfaces/cython/cantera/base.pyx

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@ cdef class _SolutionBase:
88
source=None, yaml=None, thermo=None, species=(),
99
kinetics=None, reactions=(), **kwargs):
1010

11+
# run instantiation only if valid sources are specified
12+
if origin or infile or source or (thermo and species):
13+
14+
self._cinit(infile=infile, name=name, adjacent=adjacent,
15+
origin=origin, source=source, yaml=yaml,
16+
thermo=thermo, species=species, kinetics=kinetics,
17+
reactions=reactions, **kwargs)
18+
19+
def _cinit(self, infile='', name='', adjacent=(), origin=None,
20+
source=None, yaml=None, thermo=None, species=(),
21+
kinetics=None, reactions=(), **kwargs):
22+
1123
if 'phaseid' in kwargs:
1224
if name is not '':
1325
raise AttributeError('duplicate specification of phase name')
@@ -67,6 +79,7 @@ cdef class _SolutionBase:
6779
self._selected_species = np.ndarray(0, dtype=np.integer)
6880

6981
def __init__(self, *args, **kwargs):
82+
7083
if isinstance(self, Transport):
7184
assert self.transport is not NULL
7285

@@ -225,8 +238,15 @@ cdef class _SolutionBase:
225238
for i,spec in enumerate(species):
226239
self._selected_species[i] = self.species_index(spec)
227240

228-
def __reduce__(self):
229-
raise NotImplementedError('Solution object is not picklable')
241+
def __getstate__(self):
242+
"""Save complete information for pickling."""
243+
return self.xml_string, self.ID, self.state
244+
245+
def __setstate__(self, pkl):
246+
"""Restore Solution from pickled information."""
247+
xml, phaseid, state = pkl
248+
self._cinit(source=xml, phaseid=phaseid)
249+
self.state = state
230250

231251
def __copy__(self):
232252
raise NotImplementedError('Solution object is not copyable')

interfaces/cython/cantera/test/test_thermo.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -667,10 +667,10 @@ def test_ref_info(self):
667667
self.assertNear(self.phase.min_temp, 300.0)
668668
self.assertNear(self.phase.max_temp, 3500.0)
669669

670-
def test_unpicklable(self):
671-
import pickle
672-
with self.assertRaises(NotImplementedError):
673-
pickle.dumps(self.phase)
670+
# def test_unpicklable(self):
671+
# import pickle
672+
# with self.assertRaises(NotImplementedError):
673+
# pickle.dumps(self.phase)
674674

675675
def test_uncopyable(self):
676676
import copy

interfaces/cython/cantera/thermo.pyx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,11 @@ cdef class ThermoPhase(_SolutionBase):
289289
"""
290290
return pystr(self.thermo.report(bool(show_thermo), threshold))
291291

292+
property xml_string:
293+
"""XML string used to create phase"""
294+
def __get__(self):
295+
return pystr(self.thermo.getXMLstring())
296+
292297
def __call__(self, *args, **kwargs):
293298
print(self.report(*args, **kwargs))
294299

src/thermo/Phase.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ void Phase::setXMLdata(XML_Node& xmlPhase)
6666
}
6767
}
6868

69+
std::string Phase::getXMLstring() const
70+
{
71+
std::ostringstream oss;
72+
xml().writeHeader(oss);
73+
xml().root().write(oss);
74+
return oss.str();
75+
}
76+
6977
std::string Phase::id() const
7078
{
7179
warn_deprecated("Phase::id",

0 commit comments

Comments
 (0)