@@ -38,12 +38,15 @@ def __init__(self, kind, apparatus, meta, properties,target_species_name):
38
38
:type meta: dict
39
39
:param properties: set of properties for this case
40
40
:type properties: pyked.chemked.DataPoint
41
+ :param target_species_name: target outlet species name as given ChemKED files
42
+ :type target_species_name:: str
41
43
"""
42
44
self .kind = kind
43
45
self .apparatus = apparatus
44
46
self .meta = meta
45
47
self .properties = properties
46
48
self .target_species_name = target_species_name
49
+
47
50
def setup_case (self , model_file , species_key , path = '' ):
48
51
"""Sets up the simulation case to be run.
49
52
@@ -56,20 +59,49 @@ def setup_case(self, model_file, species_key, path=''):
56
59
self .species_key = species_key
57
60
# Set max simulation time, pressure valve coefficient, and max pressure rise for Cantera
58
61
# These could be set to something in ChemKED file, but haven't seen these specified at all....
59
- self .maxsimulationtime = 50
62
+ self .maxsimulationtime = 60
60
63
self .pressurevalcof = 0.01
61
64
self .maxpressurerise = 0.01
62
-
63
65
# Reactor volume needed in m^3 for Cantera
64
66
self .volume = self .properties .reactor_volume .magnitude
65
67
print (self .properties .reactor_volume .units )
66
68
print (self .volume )
67
-
68
69
# Residence time needed in s for Cantera
69
70
self .restime = self .properties .residence_time .magnitude
70
71
print (self .properties .residence_time .units )
71
72
print (self .restime )
72
-
73
+ #Create reactants from chemked file
74
+ reactants = [self .species_key [self .properties .inlet_composition [spec ].species_name ] + ':' +
75
+ str (self .properties .inlet_composition [spec ].amount .magnitude .nominal_value )
76
+ for spec in self .properties .inlet_composition
77
+ ]
78
+ #Krishna: Need to double check these numbers
79
+ reactants = ',' .join (reactants )
80
+ print (reactants )
81
+ self .properties .pressure .ito ('pascal' )
82
+ # Need to extract values from quantity or measurement object
83
+ if hasattr (self .properties .pressure , 'value' ):
84
+ pres = self .properties .pressure .value .magnitude
85
+ elif hasattr (self .properties .pressure , 'nominal_value' ):
86
+ pres = self .properties .pressure .nominal_value
87
+ else :
88
+ pres = self .properties .pressure .magnitude
89
+ temperature = self .properties .temperature [int (self .meta ['id' ].split ('_' )[2 ])]
90
+ temperature .ito ('kelvin' )
91
+ if hasattr (temperature , 'value' ):
92
+ temp = temperature .value .magnitude
93
+ elif hasattr (temperature , 'nominal_value' ):
94
+ temp = temperature .nominal_value
95
+ else :
96
+ temp = temperature .magnitude
97
+ print (temp ,pres )
98
+ if self .properties .inlet_composition_type in ['mole fraction' , 'mole percent' ]:
99
+ self .gas .TPX = temp ,pres ,reactants
100
+ elif self .properties .inlet_composition_type == 'mass fraction' :
101
+ self .gas .TPY = temp ,pres ,reactants
102
+ else :
103
+ raise (BaseException ('error: not supported' ))
104
+ return
73
105
# Upstream and exhaust
74
106
self .fuelairmix = ct .Reservoir (self .gas )
75
107
self .exhaust = ct .Reservoir (self .gas )
@@ -81,11 +113,9 @@ def setup_case(self, model_file, species_key, path=''):
81
113
82
114
# Create reactor newtork
83
115
self .reactor_net = ct .ReactorNet ([self .reactor ])
84
-
85
- # Set file path
86
116
file_path = os .path .join (path , self .meta ['id' ] + '.h5' )
87
117
self .meta ['save-file' ] = file_path
88
- self .meta ['target-species-index' ] = self .gas .species_index (self . gas . species_index ( species_key [self .target_species_name ]) )
118
+ self .meta ['target-species-index' ] = self .gas .species_index (species_key [self .target_species_name ])
89
119
def run_case (self , restart = False ):
90
120
"""Run simulation case set up ``setup_case``.
91
121
@@ -96,98 +126,62 @@ def run_case(self, restart=False):
96
126
print ('Skipped existing case ' , self .meta ['id' ])
97
127
return
98
128
99
- # Convert reactant names to those needed for model
100
- reactants = [self .species_key [self .properties .inlet_composition [spec ].species_name ] + ':' +
101
- str (self .properties .inlet_composition [spec ].amount .magnitude .nominal_value )
102
- for spec in self .properties .inlet_composition
103
- ]
104
- #Krishna: Need to double check these numbers
105
- reactants = ',' .join (reactants )
106
- print (reactants )
107
- temperatures = []
108
- for measurement in self .properties .temperature :
109
- if hasattr (measurement , 'value' ):
110
- temperatures .append (measurement .value .magnitude )
111
- elif hasattr (measurement , 'nominal_value' ):
112
- temperatures .append (measurement .nominal_value )
113
- else :
114
- temperatures .append (measurement .magnitude )
115
- mole_fractions_stack = numpy .zeros ([len (temperatures ),self .reactor .thermo .n_species ])
116
- self .meta ['reshape-size' ] = [len (temperatures ),self .reactor .thermo .n_species ]
117
- print (mole_fractions_stack .shape )
118
- # Need to extract values from quantity or measurement object
119
- if hasattr (self .properties .pressure , 'value' ):
120
- pres = self .properties .pressure .value .magnitude
121
- elif hasattr (self .properties .pressure , 'nominal_value' ):
122
- pres = self .properties .pressure .nominal_value
123
- else :
124
- pres = self .properties .pressure .magnitude
129
+
125
130
# Save simulation results in hdf5 table format
126
131
table_def = {'time' : tables .Float64Col (pos = 0 ),
127
132
'temperature' : tables .Float64Col (pos = 1 ),
128
133
'pressure' : tables .Float64Col (pos = 2 ),
129
134
'volume' : tables .Float64Col (pos = 3 ),
130
135
'mole_fractions' : tables .Float64Col (
131
- shape = (len ( temperatures ), self .reactor .thermo .n_species ), pos = 4
136
+ shape = (self .reactor .thermo .n_species ), pos = 4
132
137
),
133
138
}
134
- for idx ,temp in enumerate (temperatures ):
135
- if self .properties .inlet_composition_type in ['mole fraction' , 'mole percent' ]:
136
- self .gas .TPX = temp ,pres ,reactants
137
- elif self .properties .inlet_composition_type == 'mass fraction' :
138
- self .gas .TPY = temp ,pres ,reactants
139
- else :
140
- raise (BaseException ('error: not supported' ))
141
- return
142
- with tables .open_file (self .meta ['save-file' ], mode = 'w' ,
143
- title = self .meta ['id' ]
144
- ) as h5file :
145
-
146
- table = h5file .create_table (where = h5file .root ,
147
- name = 'simulation' ,
148
- description = table_def
149
- )
139
+
140
+ with tables .open_file (self .meta ['save-file' ], mode = 'w' ,
141
+ title = self .meta ['id' ]
142
+ ) as h5file :
143
+
144
+ table = h5file .create_table (where = h5file .root ,
145
+ name = 'simulation' ,
146
+ description = table_def
147
+ )
150
148
# Row instance to save timestep information to
151
- timestep = table .row
152
- # Save initial conditions
149
+ timestep = table .row
150
+ # Save initial conditions
151
+ timestep ['time' ] = self .reactor_net .time
152
+ timestep ['temperature' ] = self .reactor .T
153
+ timestep ['pressure' ] = self .reactor .thermo .P
154
+ timestep ['volume' ] = self .reactor .volume
155
+ timestep ['mole_fractions' ] = self .reactor .thermo .X
156
+ # Add ``timestep`` to table
157
+ timestep .append ()
158
+
159
+ # Main time integration loop; continue integration while time of
160
+ # the ``ReactorNet`` is less than specified end time.
161
+ while self .reactor_net .time < self .maxsimulationtime :
162
+ self .reactor_net .step ()
163
+ # Save new timestep information
153
164
timestep ['time' ] = self .reactor_net .time
154
165
timestep ['temperature' ] = self .reactor .T
155
166
timestep ['pressure' ] = self .reactor .thermo .P
156
167
timestep ['volume' ] = self .reactor .volume
157
- mole_fractions_stack [idx :] = self .reactor .thermo .X
158
- timestep ['mole_fractions' ] = mole_fractions_stack
168
+ timestep ['mole_fractions' ] = self .reactor .thermo .X
159
169
# Add ``timestep`` to table
160
170
timestep .append ()
161
171
162
- # Main time integration loop; continue integration while time of
163
- # the ``ReactorNet`` is less than specified end time.
164
- while self .reactor_net .time < self .maxsimulationtime :
165
- self .reactor_net .step ()
166
-
167
- # Save new timestep information
168
- timestep ['time' ] = self .reactor_net .time
169
- timestep ['temperature' ] = self .reactor .T
170
- timestep ['pressure' ] = self .reactor .thermo .P
171
- timestep ['volume' ] = self .reactor .volume
172
- mole_fractions_stack [idx :] = self .reactor .thermo .X
173
- timestep ['mole_fractions' ] = mole_fractions_stack
174
-
175
- # Add ``timestep`` to table
176
- timestep .append ()
177
-
178
- # Write ``table`` to disk
179
- table .flush ()
172
+ # Write ``table`` to disk
173
+ table .flush ()
180
174
181
175
print ('Done with case ' , self .meta ['id' ])
182
176
183
177
def process_results (self ):
184
- """Process integration results to obtain concentrations.
185
178
"""
186
-
179
+ Process integration results to obtain concentrations.
180
+ """
187
181
# Load saved integration results
188
182
with tables .open_file (self .meta ['save-file' ], 'r' ) as h5file :
189
183
# Load Table with Group name simulation
190
184
table = h5file .root .simulation
191
- concentrations = table .col ('mole_fractions' )
192
- print ( self . meta [ 'target-species-index' ])
193
- self . meta [ 'simulated_species_profiles' ] = concentrations . reshape ( self . meta [ 'reshape-size' ][ 0 ], self . meta [ 'reshape-size' ][ 1 ])[:, self . meta [ 'target-species-index' ]]
185
+ concentration = table .col ('mole_fractions' )[:, self . meta [ 'target-species-index' ]]
186
+ return concentration [ - 1 ]
187
+
0 commit comments