@@ -469,18 +469,35 @@ def evaluate_geometry(self):
469469
470470 density = self .grain_density
471471 rO = self .grain_outer_radius
472+ n_grain = self .grain_number
472473
473474 # Define system of differential equations
474475 def geometry_dot (t , y ):
475- grain_mass_dot = self .mass_flow_rate (t ) / self .grain_number
476+ # Store physical parameters
477+ volume_diff = self .mass_flow_rate (t ) / (n_grain * density )
478+
479+ # Compute state vector derivative
476480 rI , h = y
477- rIDot = (
478- - 0.5 * grain_mass_dot / (density * np .pi * (rO ** 2 - rI ** 2 + rI * h ))
479- )
480- hDot = (
481- 1.0 * grain_mass_dot / (density * np .pi * (rO ** 2 - rI ** 2 + rI * h ))
482- )
483- return [rIDot , hDot ]
481+ burn_area = 2 * np .pi * (rO ** 2 - rI ** 2 + rI * h )
482+ rI_dot = - volume_diff / burn_area
483+ h_dot = - 2 * rI_dot
484+
485+ return [rI_dot , h_dot ]
486+
487+ # Define jacobian of the system of differential equations
488+ def geometry_jacobian (t , y ):
489+ # Store physical parameters
490+ volume_diff = self .mass_flow_rate (t ) / (n_grain * density )
491+
492+ # Compute jacobian
493+ rI , h = y
494+ factor = volume_diff / (2 * np .pi * (rO ** 2 - rI ** 2 + rI * h ) ** 2 )
495+ drI_dot_drI = factor * (h - 2 * rI )
496+ drI_dot_dh = factor * rI
497+ dh_dot_drI = - 2 * drI_dot_drI
498+ dh_dot_dh = - 2 * drI_dot_dh
499+
500+ return [[drI_dot_drI , drI_dot_dh ], [dh_dot_drI , dh_dot_dh ]]
484501
485502 def terminate_burn (t , y ):
486503 end_function = (self .grain_outer_radius - y [0 ]) * y [1 ]
@@ -494,6 +511,7 @@ def terminate_burn(t, y):
494511 geometry_dot ,
495512 t_span ,
496513 y0 ,
514+ jac = geometry_jacobian ,
497515 events = terminate_burn ,
498516 atol = 1e-12 ,
499517 rtol = 1e-11 ,
0 commit comments