@@ -217,6 +217,7 @@ def __init__(
217217 interpolation_method = "linear" ,
218218 coordinate_system_orientation = "nozzle_to_combustion_chamber" ,
219219 reference_pressure = None ,
220+ only_radial_burn = False ,
220221 ):
221222 """Initialize Motor class, process thrust curve and geometrical
222223 parameters and store results.
@@ -314,6 +315,11 @@ class Function. Thrust units are Newtons.
314315 "nozzle_to_combustion_chamber".
315316 reference_pressure : int, float, optional
316317 Atmospheric pressure in Pa at which the thrust data was recorded.
318+ only_radial_burn : boolean, optional
319+ If True, inhibits the grain from burning axially, only computing
320+ radial burn. If False, allows the grain to also burn
321+ axially. May be useful for axially inhibited grains or hybrid motors.
322+ Default is False.
317323
318324 Returns
319325 -------
@@ -353,6 +359,9 @@ class Function. Thrust units are Newtons.
353359 )
354360 self .grain_initial_mass = self .grain_density * self .grain_initial_volume
355361
362+ # Burn surface definition
363+ self .only_radial_burn = only_radial_burn
364+
356365 self .evaluate_geometry ()
357366
358367 # Initialize plots and prints object
@@ -500,17 +509,25 @@ def geometry_dot(t, y):
500509
501510 # Compute state vector derivative
502511 grain_inner_radius , grain_height = y
503- burn_area = (
504- 2
505- * np .pi
506- * (
507- grain_outer_radius ** 2
508- - grain_inner_radius ** 2
509- + grain_inner_radius * grain_height
512+ if self .only_radial_burn :
513+ burn_area = 2 * np .pi * (grain_inner_radius * grain_height )
514+
515+ grain_inner_radius_derivative = - volume_diff / burn_area
516+ grain_height_derivative = 0 # Set to zero to disable axial burning
517+
518+ else :
519+ burn_area = (
520+ 2
521+ * np .pi
522+ * (
523+ grain_outer_radius ** 2
524+ - grain_inner_radius ** 2
525+ + grain_inner_radius * grain_height
526+ )
510527 )
511- )
512- grain_inner_radius_derivative = - volume_diff / burn_area
513- grain_height_derivative = - 2 * grain_inner_radius_derivative
528+
529+ grain_inner_radius_derivative = - volume_diff / burn_area
530+ grain_height_derivative = - 2 * grain_inner_radius_derivative
514531
515532 return [grain_inner_radius_derivative , grain_height_derivative ]
516533
@@ -521,32 +538,56 @@ def geometry_jacobian(t, y):
521538
522539 # Compute jacobian
523540 grain_inner_radius , grain_height = y
524- factor = volume_diff / (
525- 2
526- * np .pi
527- * (
528- grain_outer_radius ** 2
529- - grain_inner_radius ** 2
530- + grain_inner_radius * grain_height
541+ if self .only_radial_burn :
542+ factor = volume_diff / (
543+ 2 * np .pi * (grain_inner_radius * grain_height ) ** 2
531544 )
532- ** 2
533- )
534- inner_radius_derivative_wrt_inner_radius = factor * (
535- grain_height - 2 * grain_inner_radius
536- )
537- inner_radius_derivative_wrt_height = factor * grain_inner_radius
538- height_derivative_wrt_inner_radius = (
539- - 2 * inner_radius_derivative_wrt_inner_radius
540- )
541- height_derivative_wrt_height = - 2 * inner_radius_derivative_wrt_height
542545
543- return [
544- [
545- inner_radius_derivative_wrt_inner_radius ,
546- inner_radius_derivative_wrt_height ,
547- ],
548- [height_derivative_wrt_inner_radius , height_derivative_wrt_height ],
549- ]
546+ inner_radius_derivative_wrt_inner_radius = factor * (
547+ grain_height - 2 * grain_inner_radius
548+ )
549+ inner_radius_derivative_wrt_height = 0
550+ height_derivative_wrt_inner_radius = 0
551+ height_derivative_wrt_height = 0
552+ # Height is constant when only radial burning is enabled,
553+ # so all derivatives with respect to height are zero
554+
555+ return [
556+ [
557+ inner_radius_derivative_wrt_inner_radius ,
558+ inner_radius_derivative_wrt_height ,
559+ ],
560+ [height_derivative_wrt_inner_radius , height_derivative_wrt_height ],
561+ ]
562+
563+ else :
564+ factor = volume_diff / (
565+ 2
566+ * np .pi
567+ * (
568+ grain_outer_radius ** 2
569+ - grain_inner_radius ** 2
570+ + grain_inner_radius * grain_height
571+ )
572+ ** 2
573+ )
574+
575+ inner_radius_derivative_wrt_inner_radius = factor * (
576+ grain_height - 2 * grain_inner_radius
577+ )
578+ inner_radius_derivative_wrt_height = factor * grain_inner_radius
579+ height_derivative_wrt_inner_radius = (
580+ - 2 * inner_radius_derivative_wrt_inner_radius
581+ )
582+ height_derivative_wrt_height = - 2 * inner_radius_derivative_wrt_height
583+
584+ return [
585+ [
586+ inner_radius_derivative_wrt_inner_radius ,
587+ inner_radius_derivative_wrt_height ,
588+ ],
589+ [height_derivative_wrt_inner_radius , height_derivative_wrt_height ],
590+ ]
550591
551592 def terminate_burn (t , y ): # pylint: disable=unused-argument
552593 end_function = (self .grain_outer_radius - y [0 ]) * y [1 ]
@@ -597,16 +638,24 @@ def burn_area(self):
597638 burn_area : Function
598639 Function representing the burn area progression with the time.
599640 """
600- burn_area = (
601- 2
602- * np .pi
603- * (
604- self .grain_outer_radius ** 2
605- - self .grain_inner_radius ** 2
606- + self .grain_inner_radius * self .grain_height
641+ if self .only_radial_burn :
642+ burn_area = (
643+ 2
644+ * np .pi
645+ * (self .grain_inner_radius * self .grain_height )
646+ * self .grain_number
647+ )
648+ else :
649+ burn_area = (
650+ 2
651+ * np .pi
652+ * (
653+ self .grain_outer_radius ** 2
654+ - self .grain_inner_radius ** 2
655+ + self .grain_inner_radius * self .grain_height
656+ )
657+ * self .grain_number
607658 )
608- * self .grain_number
609- )
610659 return burn_area
611660
612661 @funcify_method ("Time (s)" , "burn rate (m/s)" )
@@ -778,6 +827,7 @@ def to_dict(self, include_outputs=False):
778827 "grain_initial_height" : self .grain_initial_height ,
779828 "grain_separation" : self .grain_separation ,
780829 "grains_center_of_mass_position" : self .grains_center_of_mass_position ,
830+ "only_radial_burn" : self .only_radial_burn ,
781831 }
782832 )
783833
@@ -822,4 +872,5 @@ def from_dict(cls, data):
822872 interpolation_method = data ["interpolate" ],
823873 coordinate_system_orientation = data ["coordinate_system_orientation" ],
824874 reference_pressure = data .get ("reference_pressure" ),
875+ only_radial_burn = data .get ("only_radial_burn" , False ),
825876 )
0 commit comments