@@ -182,6 +182,61 @@ def test_finite_difference_jacobian(self):
182182 if name in constant :
183183 assert all (J [i , species_start :] == 0 ), (i , name )
184184
185+ def test_network_finite_difference_jacobian (self ):
186+ self .make_reactors (T1 = 900 , P1 = 101325 , X1 = "H2:0.4, O2:0.4, N2:0.2" )
187+ k1H2 = self .gas1 .species_index ("H2" )
188+ k2H2 = self .gas1 .species_index ("H2" )
189+ while self .r1 .thermo .X [k1H2 ] > 0.3 or self .r2 .thermo .X [k2H2 ] > 0.3 :
190+ self .net .step ()
191+
192+ J = self .net .finite_difference_jacobian
193+ assert J .shape == (self .net .n_vars , self .net .n_vars )
194+
195+ # state variables that should be constant, depending on reactor type
196+ constant = {"mass" , "volume" , "int_energy" , "enthalpy" , "pressure" }
197+ variable = {"temperature" }
198+ for i in range (3 ):
199+ name = self .r1 .component_name (i )
200+ if name in constant :
201+ assert all (J [i ,:] == 0 ), (i , name )
202+ elif name in variable :
203+ assert any (J [i ,:] != 0 )
204+ # check in second reactor
205+ name = self .r2 .component_name (i )
206+ if name in constant :
207+ assert all (J [i + self .r1 .n_vars ,:] == 0 ), (i , name )
208+ elif name in variable :
209+ assert any (J [i + self .r1 .n_vars ,:] != 0 )
210+
211+ # Disabling energy equation should zero these terms
212+ self .r1 .energy_enabled = False
213+ self .r2 .energy_enabled = False
214+ J = self .net .finite_difference_jacobian
215+ for i in range (3 ):
216+ name = self .r1 .component_name (i )
217+ if name == "temperature" :
218+ assert all (J [i ,:] == 0 )
219+ name = self .r2 .component_name (i )
220+ if name == "temperature" :
221+ assert all (J [i + self .r1 .n_vars ,:] == 0 )
222+
223+ # Disabling species equations should zero these terms
224+ self .r1 .energy_enabled = True
225+ self .r1 .chemistry_enabled = False
226+ self .r2 .energy_enabled = True
227+ self .r2 .chemistry_enabled = False
228+ J = self .net .finite_difference_jacobian
229+ constant = set (self .gas1 .species_names + self .gas2 .species_names )
230+ r1_species_start = self .r1 .component_index (self .gas1 .species_name (0 ))
231+ r2_species_start = self .r2 .component_index (self .gas2 .species_name (0 ))
232+ for i in range (self .r1 .n_vars ):
233+ name = self .r1 .component_name (i )
234+ if name in constant :
235+ assert all (J [i , r1_species_start :] == 0 ), (i , name )
236+ name = self .r2 .component_name (i )
237+ if name in constant :
238+ assert all (J [i + self .r1 .n_vars , (r2_species_start + self .r1 .n_vars ):] == 0 ), (i , name )
239+
185240 def test_timestepping (self ):
186241 self .make_reactors ()
187242
@@ -1429,14 +1484,26 @@ def create_reactors(self, **kwargs):
14291484 self .precon = ct .AdaptivePreconditioner ()
14301485 self .net2 .preconditioner = self .precon
14311486 self .net2 .derivative_settings = {"skip-third-bodies" :True , "skip-falloff" :True ,
1432- "skip-coverage-dependence" :True }
1487+ "skip-coverage-dependence" :True , "skip-flow-devices" : True }
14331488
14341489 def test_get_solver_type (self ):
14351490 self .create_reactors ()
14361491 assert self .precon .side == "right"
14371492 self .net2 .initialize ()
14381493 assert self .net2 .linear_solver_type == "GMRES"
14391494
1495+ def test_mass_flow_jacobian (self ):
1496+ self .create_reactors (add_mdot = True )
1497+ # reset derivative settings
1498+ self .net2 .derivative_settings = {"skip-third-bodies" :True , "skip-falloff" :True ,
1499+ "skip-coverage-dependence" :True , "skip-flow-devices" : False }
1500+
1501+ with pytest .raises (NotImplementedError , match = "MassFlowController::buildReactorJacobian" ):
1502+ J = self .net2 .jacobian
1503+
1504+ with pytest .raises (NotImplementedError , match = "MassFlowController::buildReactorJacobian" ):
1505+ J = self .r2 .jacobian
1506+
14401507 def test_heat_transfer_network (self ):
14411508 # create first reactor
14421509 gas1 = ct .Solution ("h2o2.yaml" , "ohmech" )
0 commit comments