From 29a284ec379224578fa483ae7aac81cbbcb38900 Mon Sep 17 00:00:00 2001 From: Lucas Kierulff Balabram Date: Sun, 26 Sep 2021 16:52:44 -0300 Subject: [PATCH 01/10] ENH: add `evaluateViscousFrictionCoefficient` method Add method to calculate the viscous friction coefficient in Rocket class to be used in the drag coefficient estimations. The calculations required the addition of new parameters to `__init__`. --- rocketpy/Rocket.py | 78 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 4 deletions(-) diff --git a/rocketpy/Rocket.py b/rocketpy/Rocket.py index ea88a0bc0..cadea85c4 100644 --- a/rocketpy/Rocket.py +++ b/rocketpy/Rocket.py @@ -19,7 +19,7 @@ import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm -from numpy import genfromtxt +from numpy import genfromtxt, sqrt from .Function import Function @@ -165,8 +165,12 @@ def __init__( radius, distanceRocketNozzle, distanceRocketPropellant, - powerOffDrag, - powerOnDrag, + powerOffDrag=None, + powerOnDrag=None, + rocket_length=None, + speed_of_sound=340.293988026089, + air_density=1.225000018124288, + dynamic_viscosity=1.789380278077583e-05, ): """Initializes Rocket class, process inertial, geometrical and aerodynamic parameters. @@ -207,16 +211,36 @@ def __init__( information. If int or float is given, it is assumed constant. If callable, string or array is given, it must be a function of Mach number only. - + rocket_length : int, float, optional + Rocket length used in the expressions for estimating drag coefficients + in meters (m). + Air density used in the expressions for estimating drag coefficients + in kg/m³. + speed_of_sound : int, float, optional + Speed of sound used for estimating drag coefficients, in + meters per second (m/s). The default value was obtained from the + Environment class at sea level and standard atmosphere. + air_density : int, float, optional + Air density used in the expressions for estimating drag coefficients + in kg/m³. + dynamic_viscosity : int, float, optional + Dynamic viscosity of the fluid used in the expressions for + estimating drag coefficients in Pa s. Returns ------- None """ + # Define relavant physical constants + self.speed_of_sound = speed_of_sound + self.air_density = air_density + self.dynamic_viscosity = dynamic_viscosity + # Define rocket inertia attributes in SI units self.mass = mass self.inertiaI = inertiaI self.inertiaZ = inertiaZ self.centerOfMass = distanceRocketPropellant * motor.mass / (mass + motor.mass) + self.rocket_length = rocket_length # Define rocket geometrical parameters in SI units self.radius = radius @@ -280,6 +304,49 @@ def __init__( return None + def evaluateViscousFrictionCoefficient(self): + """Calculates and returns the viscous friction coefficient as + a function of the Mach number. The viscous friction coefficient + depends on the Reynolds number and given by a mathematical + expression. Some assumptions for calculating this coefficient + are that the angle of attack equals zero and the speed of sound + is constant and equal to the value passed in init. + + Parameters + ---------- + None + + Returns + ------- + self.viscous_friction_coefficient : Function + Function of mach number expressing the viscous friction coefficient, + defined as in the literature. + """ + + def calculations(mach): + reynolds = ( + (self.air_density ** 2) + * self.speed_of_sound + * self.rocket_length + * mach + / self.dynamic_viscosity + ) + reynolds_critical = 5e5 + + if reynolds <= reynolds_critical: + return 1.328 / sqrt(reynolds) + else: + B = reynolds_critical * ( + 0.074 / (reynolds ** (1 / 5)) - 1.328 / sqrt(reynolds) + ) + return 0.074 / (reynolds ** (1 / 5)) - B / reynolds + + self.viscous_friction_coefficient = Function( + calculations, "Mach Number", "Viscous Friction Coefficient" + ) + + return self.viscous_friction_coefficient + def evaluateReducedMass(self): """Calculates and returns the rocket's total reduced mass. The reduced mass is defined as the product of the propellant mass @@ -439,6 +506,9 @@ def addTail(self, topRadius, bottomRadius, length, distanceToCM): lambda x: clalpha * x, "Alpha (rad)", "Cl", interpolation="linear" ) + # Calculate Cd + # drag_coefficient = + # Store values as new aerodynamic surface tail = [(0, 0, cpz), cldata, "Tail"] self.aerodynamicSurfaces.append(tail) From 27edff0443fe590a8dbd399256b849386565b3cd Mon Sep 17 00:00:00 2001 From: lucasfourier <69172945+lucasfourier@users.noreply.github.com> Date: Sun, 3 Oct 2021 17:32:26 -0300 Subject: [PATCH 02/10] ENH: add tail and fin drag coefficients estimations to rocketpy.Rocket Added formulas for estimations of the drag coefficients regarding the fins and tail. Also, the method `evaluateForebodyDragCoefficient` still needs to be completed. --- rocketpy/Rocket.py | 91 +++++++++++++++++++++++++++++++++------------- 1 file changed, 65 insertions(+), 26 deletions(-) diff --git a/rocketpy/Rocket.py b/rocketpy/Rocket.py index cadea85c4..b0546a588 100644 --- a/rocketpy/Rocket.py +++ b/rocketpy/Rocket.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -__author__ = "Giovani Hidalgo Ceotto, Franz Masatoshi Yuri" +__author__ = "Giovani Hidalgo Ceotto, Franz Masatoshi Yuri, Lucas Azevedo Pezente, Lucas Kierulff Balabram" __copyright__ = "Copyright 20XX, Projeto Jupiter" __license__ = "MIT" @@ -230,7 +230,7 @@ def __init__( ------- None """ - # Define relavant physical constants + # Define relevant physical constants self.speed_of_sound = speed_of_sound self.air_density = air_density self.dynamic_viscosity = dynamic_viscosity @@ -347,6 +347,27 @@ def calculations(mach): return self.viscous_friction_coefficient + def evaluateForebodyDragCoefficient(self): + """Calculates and returns the tail drag coefficient as a function + of the Mach number. The tail drag coefficient depends on geometric + parameters such as the total length of the rocket body, the length + of the boat tail, the maximum body diamater, and the diamater of the + rocket base. + + Parameters + ---------- + None + + Returns + ------- + self.forebody_drag_coefficient : Function + Function of mach number expressing the tail drag coefficient, + defined as in the literature. + """ + + # Return something for mock purposes + self.forebody_drag_coefficient = Function(lambda mach: 1) + def evaluateReducedMass(self): """Calculates and returns the rocket's total reduced mass. The reduced mass is defined as the product of the propellant mass @@ -457,7 +478,9 @@ def evaluateStaticMargin(self): # Return self return self - def addTail(self, topRadius, bottomRadius, length, distanceToCM): + def addTail( + self, topRadius, bottomRadius, length, distanceToCM, drag_coefficient=None + ): """Create a new tail or rocket diameter change, storing its parameters as part of the aerodynamicSurfaces list. Its parameters are the axial position along the rocket and its @@ -507,10 +530,15 @@ def addTail(self, topRadius, bottomRadius, length, distanceToCM): ) # Calculate Cd - # drag_coefficient = + if drag_coefficient is None: + drag_coefficient = ( + 0.029 + * ((bottomRadius / self.radius) ** 3) + / (self.evaluateForebodyDragCoefficient() ** 0.5) + ) # Store values as new aerodynamic surface - tail = [(0, 0, cpz), cldata, "Tail"] + tail = [(0, 0, cpz), cldata, drag_coefficient, "Tail"] self.aerodynamicSurfaces.append(tail) # Refresh static margin calculation @@ -584,7 +612,16 @@ def addNose(self, length, kind, distanceToCM): return self.aerodynamicSurfaces[-1] def addFins( - self, n, span, rootChord, tipChord, distanceToCM, radius=0, airfoil=None + self, + n, + span, + rootChord, + tipChord, + distanceToCM, + drag_coefficient=None, + thickness=None, + radius=0, + airfoil=None, ): """Create a fin set, storing its parameters as part of the aerodynamicSurfaces list. Its parameters are the axial position @@ -663,16 +700,6 @@ def addFins( lambda x: clalpha * x, "Alpha (rad)", "Cl", interpolation="linear" ) - # Store values - fin = [(0, 0, cpz), cldata, "Fins"] - self.aerodynamicSurfaces.append(fin) - - # Refresh static margin calculation - self.evaluateStaticMargin() - - # Return self - return self.aerodynamicSurfaces[-1] - else: def cnalfa1(cn): @@ -709,7 +736,7 @@ def cnalfa1(cn): # Import the lift curve as a function of lift values by attack angle read = genfromtxt(airfoil, delimiter=",") - # Aplies number of fins to lift coefficient data + # Applies number of fins to lift coefficient data data = [[cl[0], (n / 2) * cnalfa1(cl[1])] for cl in read] cldata = Function( data, @@ -719,18 +746,30 @@ def cnalfa1(cn): extrapolation="natural", ) - # Takes an approximation to an angular coefficient - clalpha = cldata.differentiate(x=0, dx=1e-2) + # Calculate Cd + if drag_coefficient is None: + exposed_area = (1 / 2) * (rootChord + tipChord) * span + total_area = exposed_area + self.radius * rootChord + + # In the formula, instead of span, it should be the distance between the + # midpoint of the root and the tip of the fin, but we are using + # span for now. + drag_coefficient = ( + 2 + * self.evaluateViscousFrictionCoefficient() + * (1 + 2 * (thickness / span)) + * (n * total_area / (np.pi * self.radius ** 2)) + ) - # Store values - fin = [(0, 0, cpz), cldata, "Fins"] - self.aerodynamicSurfaces.append(fin) + # Store values as new aerodynamic surface + fin = [(0, 0, cpz), cldata, drag_coefficient, "Fins"] + self.aerodynamicSurfaces.append(fin) - # Refresh static margin calculation - self.evaluateStaticMargin() + # Refresh static margin calculation + self.evaluateStaticMargin() - # Return self - return self.aerodynamicSurfaces[-1] + # Return self + return self.aerodynamicSurfaces[-1] def addParachute( self, name, CdS, trigger, samplingRate=100, lag=0, noise=(0, 0, 0) From 83d300a4e01e2b225245f5d3e5fb4f47216bf0da Mon Sep 17 00:00:00 2001 From: Lucas Kierulff Balabram Date: Mon, 11 Oct 2021 16:38:27 -0300 Subject: [PATCH 03/10] ENH: add drag coefficient estimation to rocketpy.Rocket Now the drag coefficient estimation is supposedly finished, but testing and validation is still needed. --- rocketpy/Rocket.py | 115 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 96 insertions(+), 19 deletions(-) diff --git a/rocketpy/Rocket.py b/rocketpy/Rocket.py index b0546a588..1abec52ff 100644 --- a/rocketpy/Rocket.py +++ b/rocketpy/Rocket.py @@ -240,11 +240,14 @@ def __init__( self.inertiaI = inertiaI self.inertiaZ = inertiaZ self.centerOfMass = distanceRocketPropellant * motor.mass / (mass + motor.mass) - self.rocket_length = rocket_length # Define rocket geometrical parameters in SI units self.radius = radius self.area = np.pi * self.radius ** 2 + self.rocket_length = rocket_length + self.nose_length = 0 + self.tail_length = 0 + self.tail_bottom_radius = 0 # Center of mass distance to points of interest self.distanceRocketNozzle = distanceRocketNozzle @@ -270,20 +273,24 @@ def __init__( ) # Define aerodynamic drag coefficients - self.powerOffDrag = Function( - powerOffDrag, - "Mach Number", - "Drag Coefficient with Power Off", - "spline", - "constant", - ) - self.powerOnDrag = Function( - powerOnDrag, - "Mach Number", - "Drag Coefficient with Power On", - "spline", - "constant", - ) + self.power_off_drag_as_input = powerOffDrag is not None + if self.power_off_drag_as_input: + self.powerOffDrag = Function( + powerOffDrag, + "Mach Number", + "Drag Coefficient with Power Off", + "spline", + "constant", + ) + self.power_on_drag_as_input = powerOnDrag is not None + if self.power_on_drag_as_input: + self.powerOnDrag = Function( + powerOnDrag, + "Mach Number", + "Drag Coefficient with Power On", + "spline", + "constant", + ) # Define motor to be used self.motor = motor @@ -304,6 +311,34 @@ def __init__( return None + def evaluateDragCoefficient(self): + """Calculates and returns the drag coefficient as the sum of + of the individual drag coefficients at zero angle of attack + as a function of the Mach number. The angle of attack is + assumed to be zero. + + Parameters + ---------- + None + + Returns + ------- + self.viscous_friction_coefficient : Function + Function of mach number expressing the viscous friction coefficient, + defined as in the literature. + """ + self.drag_coefficient_estimate = ( + self.evaluateForebodyDragCoefficient() + + np.sum(self.aerodynamicSurfaces[:, 2]) + ) + + if not self.power_off_drag_as_input: + self.powerOffDrag = self.drag_coefficient_estimate + if not self.power_on_drag_as_input: + self.powerOnDrag = self.drag_coefficient_estimate + + return self.drag_coefficient_estimate + def evaluateViscousFrictionCoefficient(self): """Calculates and returns the viscous friction coefficient as a function of the Mach number. The viscous friction coefficient @@ -366,7 +401,36 @@ def evaluateForebodyDragCoefficient(self): """ # Return something for mock purposes - self.forebody_drag_coefficient = Function(lambda mach: 1) + + def calculations(mach): + forebody_drag_coefficient = ( + ( + 1 + + 60 / ((self.rocket_length / (2 * self.radius)) ** 3) + + 0.00125 + * (self.rocket_length - self.nose_length - self.tail_length) + / self.radius + ) + * ( + 2.7 * self.nose_length / (self.radius) + + 2 + * (self.rocket_length - self.nose_length - self.tail_length) + / self.radius + + 2 + * (1 - self.tail_bottom_radius / self.radius) + * self.tail_length + / (2 * self.radius) + ) + * self.evaluateViscousFrictionCoefficient() + ) + + return forebody_drag_coefficient + + self.forebody_drag_coefficient = Function( + calculations, "Mach Number", "Forebody Drag Coefficient" + ) + + return self.forebody_drag_coefficient def evaluateReducedMass(self): """Calculates and returns the rocket's total reduced mass. The @@ -523,6 +587,10 @@ def addTail( else: cpz = distanceToCM + (length / 3) * (1 + (1 - r) / (1 - r ** 2)) + # Save tail length + self.tail_length = length + self.tail_bottom_radius = bottomRadius + # Calculate clalpha clalpha = -2 * (1 - r ** (-2)) * (topRadius / rref) ** 2 cldata = Function( @@ -591,6 +659,9 @@ def addNose(self, length, kind, distanceToCM): else: cpz = distanceToCM - k * length + # Save nose cone length + self.nose_length = length + # Calculate clalpha clalpha = 2 cldata = Function( @@ -602,7 +673,13 @@ def addNose(self, length, kind, distanceToCM): ) # Store values - nose = [(0, 0, cpz), cldata, "Nose Cone"] + # Nose cone drag coefficient is given as a constant and equals zero as it has already been accounted for in the forebody. + nose = [ + (0, 0, cpz), + cldata, + Function(lambda mach: 0, "Mach Number", "Nose Cone Drag Coefficient"), + "Nose Cone", + ] self.aerodynamicSurfaces.append(nose) # Refresh static margin calculation @@ -747,7 +824,7 @@ def cnalfa1(cn): ) # Calculate Cd - if drag_coefficient is None: + if drag_coefficient is None and thickness is not None: exposed_area = (1 / 2) * (rootChord + tipChord) * span total_area = exposed_area + self.radius * rootChord @@ -758,7 +835,7 @@ def cnalfa1(cn): 2 * self.evaluateViscousFrictionCoefficient() * (1 + 2 * (thickness / span)) - * (n * total_area / (np.pi * self.radius ** 2)) + * (n * (2 * total_area - exposed_area) / (np.pi * self.radius ** 2)) ) # Store values as new aerodynamic surface From 9af8af5a96f092f050934790c3d1f5aa2bbe0da7 Mon Sep 17 00:00:00 2001 From: lucasfourier <69172945+lucasfourier@users.noreply.github.com> Date: Tue, 9 Nov 2021 14:37:22 -0300 Subject: [PATCH 04/10] BUG: Fixed programming issues in rocketpy.Rocket Some issues with the code were corrected. --- rocketpy/Function.py | 1 + rocketpy/Rocket.py | 26 ++++++++++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/rocketpy/Function.py b/rocketpy/Function.py index fd01cad74..1b437408d 100644 --- a/rocketpy/Function.py +++ b/rocketpy/Function.py @@ -534,6 +534,7 @@ def getValue(self, *args): if isinstance(args[0][0], (tuple, list)): return [self.source(*arg) for arg in args[0]] else: + print(self.source(args[0][0])) return [self.source(arg) for arg in args[0]] elif len(args) == 1 and isinstance(args[0], np.ndarray): return self.source(args[0]) diff --git a/rocketpy/Rocket.py b/rocketpy/Rocket.py index 1abec52ff..4f675fc2d 100644 --- a/rocketpy/Rocket.py +++ b/rocketpy/Rocket.py @@ -309,6 +309,8 @@ def __init__( # Evaluate static margin (even though no aerodynamic surfaces are present yet) self.evaluateStaticMargin() + self.evaluateDragCoefficient() + return None def evaluateDragCoefficient(self): @@ -327,9 +329,12 @@ def evaluateDragCoefficient(self): Function of mach number expressing the viscous friction coefficient, defined as in the literature. """ + + self.evaluateViscousFrictionCoefficient() + self.drag_coefficient_estimate = ( self.evaluateForebodyDragCoefficient() - + np.sum(self.aerodynamicSurfaces[:, 2]) + + np.sum([self.aerodynamicSurfaces[i][2] for i in range(len(self.aerodynamicSurfaces))]) ) if not self.power_off_drag_as_input: @@ -369,12 +374,12 @@ def calculations(mach): reynolds_critical = 5e5 if reynolds <= reynolds_critical: - return 1.328 / sqrt(reynolds) + return 1.328 / (sqrt(reynolds)) else: B = reynolds_critical * ( - 0.074 / (reynolds ** (1 / 5)) - 1.328 / sqrt(reynolds) + 0.074 / (reynolds ** (1 / 5)) - (1.328 / (sqrt(reynolds))) ) - return 0.074 / (reynolds ** (1 / 5)) - B / reynolds + return 0.074 / (reynolds ** (1 / 5)) - (B / reynolds) self.viscous_friction_coefficient = Function( calculations, "Mach Number", "Viscous Friction Coefficient" @@ -412,7 +417,7 @@ def calculations(mach): / self.radius ) * ( - 2.7 * self.nose_length / (self.radius) + 2.7 * self.nose_length / (2 * self.radius) + 2 * (self.rocket_length - self.nose_length - self.tail_length) / self.radius @@ -421,7 +426,7 @@ def calculations(mach): * self.tail_length / (2 * self.radius) ) - * self.evaluateViscousFrictionCoefficient() + * self.viscous_friction_coefficient(mach) ) return forebody_drag_coefficient @@ -612,6 +617,9 @@ def addTail( # Refresh static margin calculation self.evaluateStaticMargin() + # Refresh Drag coefficient calculation + self.evaluateDragCoefficient() + # Return self return self.aerodynamicSurfaces[-1] @@ -685,6 +693,9 @@ def addNose(self, length, kind, distanceToCM): # Refresh static margin calculation self.evaluateStaticMargin() + # Refresh Drag coefficient calculation + self.evaluateDragCoefficient() + # Return self return self.aerodynamicSurfaces[-1] @@ -845,6 +856,9 @@ def cnalfa1(cn): # Refresh static margin calculation self.evaluateStaticMargin() + # Refresh Drag coefficient calculation + self.evaluateDragCoefficient() + # Return self return self.aerodynamicSurfaces[-1] From 044bd7932eaebc96e410d906be06635289d6e917 Mon Sep 17 00:00:00 2001 From: Lucas Kierulff Balabram Date: Mon, 15 Nov 2021 16:47:53 -0300 Subject: [PATCH 05/10] BUG: fix viscous drag coefficient estimation Add a new branch in the calculation to correct when Reynolds number is less than 10^4. --- rocketpy/Rocket.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/rocketpy/Rocket.py b/rocketpy/Rocket.py index 4f675fc2d..6471f10e2 100644 --- a/rocketpy/Rocket.py +++ b/rocketpy/Rocket.py @@ -329,12 +329,13 @@ def evaluateDragCoefficient(self): Function of mach number expressing the viscous friction coefficient, defined as in the literature. """ - self.evaluateViscousFrictionCoefficient() - self.drag_coefficient_estimate = ( - self.evaluateForebodyDragCoefficient() - + np.sum([self.aerodynamicSurfaces[i][2] for i in range(len(self.aerodynamicSurfaces))]) + self.drag_coefficient_estimate = self.viscous_friction_coefficient + np.sum( + [ + self.aerodynamicSurfaces[i][2] + for i in range(len(self.aerodynamicSurfaces)) + ] ) if not self.power_off_drag_as_input: @@ -373,7 +374,9 @@ def calculations(mach): ) reynolds_critical = 5e5 - if reynolds <= reynolds_critical: + if reynolds <= 1e4: + return 1.328e-2 + elif reynolds <= reynolds_critical: return 1.328 / (sqrt(reynolds)) else: B = reynolds_critical * ( @@ -609,6 +612,8 @@ def addTail( * ((bottomRadius / self.radius) ** 3) / (self.evaluateForebodyDragCoefficient() ** 0.5) ) + drag_coefficient.setInputs("Mach Number") + drag_coefficient.setOutputs("Tail Drag Coefficient") # Store values as new aerodynamic surface tail = [(0, 0, cpz), cldata, drag_coefficient, "Tail"] @@ -848,6 +853,8 @@ def cnalfa1(cn): * (1 + 2 * (thickness / span)) * (n * (2 * total_area - exposed_area) / (np.pi * self.radius ** 2)) ) + drag_coefficient.setInputs("Mach Number") + drag_coefficient.setOutputs("Fins Drag Coefficient") # Store values as new aerodynamic surface fin = [(0, 0, cpz), cldata, drag_coefficient, "Fins"] From 16f479f1bee22eae35b026331276e3af1e7a58e1 Mon Sep 17 00:00:00 2001 From: Lucas Kierulff Balabram Date: Thu, 18 Nov 2021 21:20:29 -0300 Subject: [PATCH 06/10] BUG: add the forebody drag coefficient to the sum The forebody drag coefficient was forgotten on the sum of all drag coefficients. It is now fixed. --- rocketpy/Rocket.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rocketpy/Rocket.py b/rocketpy/Rocket.py index 6471f10e2..895f8f983 100644 --- a/rocketpy/Rocket.py +++ b/rocketpy/Rocket.py @@ -330,8 +330,9 @@ def evaluateDragCoefficient(self): defined as in the literature. """ self.evaluateViscousFrictionCoefficient() + self.evaluateForebodyDragCoefficient() - self.drag_coefficient_estimate = self.viscous_friction_coefficient + np.sum( + self.drag_coefficient_estimate = self.forebody_drag_coefficient + np.sum( [ self.aerodynamicSurfaces[i][2] for i in range(len(self.aerodynamicSurfaces)) From 49d96531908c1d08f3fe5ddeb22fa39cb8fc3872 Mon Sep 17 00:00:00 2001 From: Lucas Kierulff Balabram Date: Thu, 18 Nov 2021 21:46:52 -0300 Subject: [PATCH 07/10] MAINT: remove print used for debug and forgotten --- rocketpy/Function.py | 1 - 1 file changed, 1 deletion(-) diff --git a/rocketpy/Function.py b/rocketpy/Function.py index 1b437408d..fd01cad74 100644 --- a/rocketpy/Function.py +++ b/rocketpy/Function.py @@ -534,7 +534,6 @@ def getValue(self, *args): if isinstance(args[0][0], (tuple, list)): return [self.source(*arg) for arg in args[0]] else: - print(self.source(args[0][0])) return [self.source(arg) for arg in args[0]] elif len(args) == 1 and isinstance(args[0], np.ndarray): return self.source(args[0]) From 2db3f4cc8e45a0914216d078e8c0832efa3ed3cf Mon Sep 17 00:00:00 2001 From: Lint Action Date: Fri, 19 Nov 2021 01:06:16 +0000 Subject: [PATCH 08/10] Fix code style issues with Black --- data/weather/fetchAlcantara.py | 114 +++++++++++++++++--------- data/weather/fetchCLBI.py | 114 +++++++++++++++++--------- data/weather/fetchSpaceportAmerica.py | 114 +++++++++++++++++--------- docs/conf.py | 55 ++++++------- setup.py | 11 +-- tests/test_solidmotor.py | 30 +++++-- 6 files changed, 274 insertions(+), 164 deletions(-) diff --git a/data/weather/fetchAlcantara.py b/data/weather/fetchAlcantara.py index 2a65d561b..9d210d73a 100644 --- a/data/weather/fetchAlcantara.py +++ b/data/weather/fetchAlcantara.py @@ -2,55 +2,89 @@ c = cdsapi.Client() -years = ['2015', '2016', '2017', '2018'] +years = ["2015", "2016", "2017", "2018"] for year in years: print() print(year) print() c.retrieve( - 'reanalysis-era5-pressure-levels', + "reanalysis-era5-pressure-levels", { - 'product_type':'reanalysis', - 'format':'netcdf', - 'variable':[ - 'geopotential','temperature','u_component_of_wind', - 'v_component_of_wind' + "product_type": "reanalysis", + "format": "netcdf", + "variable": [ + "geopotential", + "temperature", + "u_component_of_wind", + "v_component_of_wind", ], - 'pressure_level':[ - '600', - '650','700','750', - '775','800','825', - '850','875','900', - '925','950','975', - '1000' + "pressure_level": [ + "600", + "650", + "700", + "750", + "775", + "800", + "825", + "850", + "875", + "900", + "925", + "950", + "975", + "1000", ], - 'year':[ - year + "year": [year], + "month": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10", + "11", + "12", ], - 'month':[ - '01','02','03', - '04','05','06', - '07','08','09', - '10','11','12' + "day": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "20", + "21", + "22", + "23", + "24", + "25", + "26", + "27", + "28", + "29", + "30", + "31", ], - 'day':[ - '01','02','03', - '04','05','06', - '07','08','09', - '10','11','12', - '13','14','15', - '16','17','18', - '19','20','21', - '22','23','24', - '25','26','27', - '28','29','30', - '31' - ], - 'time':[ - '00:00','06:00','12:00', - '18:00' - ], - 'area': '1.5/314.25/-3.75/317.25' + "time": ["00:00", "06:00", "12:00", "18:00"], + "area": "1.5/314.25/-3.75/317.25", }, - 'Alcantara_' + year + '_ERA-5.nc') \ No newline at end of file + "Alcantara_" + year + "_ERA-5.nc", + ) diff --git a/data/weather/fetchCLBI.py b/data/weather/fetchCLBI.py index c69face49..dd27c4e8c 100644 --- a/data/weather/fetchCLBI.py +++ b/data/weather/fetchCLBI.py @@ -2,55 +2,89 @@ c = cdsapi.Client() -years = ['2015', '2016', '2017', '2018'] +years = ["2015", "2016", "2017", "2018"] for year in years: print() print(year) print() c.retrieve( - 'reanalysis-era5-pressure-levels', + "reanalysis-era5-pressure-levels", { - 'product_type':'reanalysis', - 'format':'netcdf', - 'variable':[ - 'geopotential','temperature','u_component_of_wind', - 'v_component_of_wind' + "product_type": "reanalysis", + "format": "netcdf", + "variable": [ + "geopotential", + "temperature", + "u_component_of_wind", + "v_component_of_wind", ], - 'pressure_level':[ - '600', - '650','700','750', - '775','800','825', - '850','875','900', - '925','950','975', - '1000' + "pressure_level": [ + "600", + "650", + "700", + "750", + "775", + "800", + "825", + "850", + "875", + "900", + "925", + "950", + "975", + "1000", ], - 'year':[ - year + "year": [year], + "month": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10", + "11", + "12", ], - 'month':[ - '01','02','03', - '04','05','06', - '07','08','09', - '10','11','12' + "day": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "20", + "21", + "22", + "23", + "24", + "25", + "26", + "27", + "28", + "29", + "30", + "31", ], - 'day':[ - '01','02','03', - '04','05','06', - '07','08','09', - '10','11','12', - '13','14','15', - '16','17','18', - '19','20','21', - '22','23','24', - '25','26','27', - '28','29','30', - '31' - ], - 'time':[ - '00:00','06:00','12:00', - '18:00' - ], - 'area': '-4.5/324/-7.5/326.25' + "time": ["00:00", "06:00", "12:00", "18:00"], + "area": "-4.5/324/-7.5/326.25", }, - 'CLBI_' + year + '_ERA-5.nc') \ No newline at end of file + "CLBI_" + year + "_ERA-5.nc", + ) diff --git a/data/weather/fetchSpaceportAmerica.py b/data/weather/fetchSpaceportAmerica.py index b5e5f01dd..9823c2f25 100644 --- a/data/weather/fetchSpaceportAmerica.py +++ b/data/weather/fetchSpaceportAmerica.py @@ -2,55 +2,89 @@ c = cdsapi.Client() -years = ['2015', '2016', '2017', '2018'] +years = ["2015", "2016", "2017", "2018"] for year in years: print() print(year) print() c.retrieve( - 'reanalysis-era5-pressure-levels', + "reanalysis-era5-pressure-levels", { - 'product_type':'reanalysis', - 'format':'netcdf', - 'variable':[ - 'geopotential','temperature','u_component_of_wind', - 'v_component_of_wind' + "product_type": "reanalysis", + "format": "netcdf", + "variable": [ + "geopotential", + "temperature", + "u_component_of_wind", + "v_component_of_wind", ], - 'pressure_level':[ - '600', - '650','700','750', - '775','800','825', - '850','875','900', - '925','950','975', - '1000' + "pressure_level": [ + "600", + "650", + "700", + "750", + "775", + "800", + "825", + "850", + "875", + "900", + "925", + "950", + "975", + "1000", ], - 'year':[ - year + "year": [year], + "month": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10", + "11", + "12", ], - 'month':[ - '01','02','03', - '04','05','06', - '07','08','09', - '10','11','12' + "day": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "20", + "21", + "22", + "23", + "24", + "25", + "26", + "27", + "28", + "29", + "30", + "31", ], - 'day':[ - '01','02','03', - '04','05','06', - '07','08','09', - '10','11','12', - '13','14','15', - '16','17','18', - '19','20','21', - '22','23','24', - '25','26','27', - '28','29','30', - '31' - ], - 'time':[ - '00:00','06:00','12:00', - '18:00' - ], - 'area': '34.5/252/31.5/254.25' + "time": ["00:00", "06:00", "12:00", "18:00"], + "area": "34.5/252/31.5/254.25", }, - 'SpaceportAmerica_' + year + '_ERA-5.nc') \ No newline at end of file + "SpaceportAmerica_" + year + "_ERA-5.nc", + ) diff --git a/docs/conf.py b/docs/conf.py index 77d49886c..cf117478d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,49 +12,50 @@ # import os import sys -sys.path.insert(0, os.path.abspath('../')) + +sys.path.insert(0, os.path.abspath("../")) # -- Project information ----------------------------------------------------- -project = 'RocketPy' -copyright = '2020, Projeto Jupiter' -author = 'Giovani Hdalgo Ceotto' +project = "RocketPy" +copyright = "2020, Projeto Jupiter" +author = "Giovani Hdalgo Ceotto" # The full version, including alpha/beta/rc tags -release = '0.9.7' +release = "0.9.7" # -- General configuration --------------------------------------------------- -master_doc = 'index' +master_doc = "index" # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.napoleon', - 'sphinx.ext.viewcode', - 'nbsphinx', - 'm2r2', + "sphinx.ext.autodoc", + "sphinx.ext.napoleon", + "sphinx.ext.viewcode", + "nbsphinx", + "m2r2", ] # source_suffix = '.rst' # source_suffix = ['.rst', '.md'] # Don't run notebooks -nbsphinx_execute = 'never' +nbsphinx_execute = "never" # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] napoleon_numpy_docstring = True -autodoc_member_order = 'bysource' -autoclass_content = 'both' +autodoc_member_order = "bysource" +autoclass_content = "both" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # -- Options for HTML output ------------------------------------------------- @@ -62,31 +63,29 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'pydata_sphinx_theme' +html_theme = "pydata_sphinx_theme" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['static'] +html_static_path = ["static"] html_logo = "static/RocketPy_Logo_Black.svg" -html_favicon = 'static/favicon.ico' +html_favicon = "static/favicon.ico" html_theme_options = { - "logo_link": "index", - "github_url": "https://github.com/Projeto-Jupiter/RocketPy", - "collapse_navigation": True, - "show_toc_level": 3, + "logo_link": "index", + "github_url": "https://github.com/Projeto-Jupiter/RocketPy", + "collapse_navigation": True, + "show_toc_level": 3, } html_sidebars = { "**": ["search-field.html", "sidebar-nav-bs.html", "sidebar-ethical-ads.html"] } -html_theme_options = { - "navbar_end": ["navbar-icon-links.html", "search-field.html"] -} +html_theme_options = {"navbar_end": ["navbar-icon-links.html", "search-field.html"]} html_use_modindex = True html_copy_source = False html_domain_indices = False -html_file_suffix = '.html' +html_file_suffix = ".html" -htmlhelp_basename = 'rocketpy' +htmlhelp_basename = "rocketpy" diff --git a/setup.py b/setup.py index b971b83fa..c4ecc1927 100644 --- a/setup.py +++ b/setup.py @@ -4,14 +4,9 @@ long_description = fh.read() setuptools.setup( - name="rocketpy", + name="rocketpy", version="0.9.8", - install_requires = [ - 'numpy>=1.0', - 'scipy>=1.0', - 'matplotlib>=3.0', - 'requests' - ], + install_requires=["numpy>=1.0", "scipy>=1.0", "matplotlib>=3.0", "requests"], maintainer="RocketPy Developers", author="Giovani Hidalgo Ceotto", author_email="ghceotto@gmail.com", @@ -25,5 +20,5 @@ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ], - python_requires='>=3.6', + python_requires=">=3.6", ) diff --git a/tests/test_solidmotor.py b/tests/test_solidmotor.py index f7ba68759..e5fba2175 100644 --- a/tests/test_solidmotor.py +++ b/tests/test_solidmotor.py @@ -16,6 +16,7 @@ nozzleRadius = 33 / 1000 throatRadius = 11 / 1000 + @patch("matplotlib.pyplot.show") def test_motor(mock_show): example_motor = SolidMotor( @@ -36,14 +37,18 @@ def test_motor(mock_show): def test_initilize_motor_asserts_dynamic_values(solid_motor): - grain_vol = grainInitialHeight * (np.pi * (grainOuterRadius ** 2 - grainInitialInnerRadius ** 2)) + grain_vol = grainInitialHeight * ( + np.pi * (grainOuterRadius ** 2 - grainInitialInnerRadius ** 2) + ) grain_mass = grain_vol * grainDensity assert solid_motor.maxThrust == 2200.0 assert solid_motor.maxThrustTime == 0.15 assert solid_motor.burnOutTime == burnOut assert solid_motor.totalImpulse == solid_motor.thrust.integral(0, burnOut) - assert solid_motor.averageThrust == solid_motor.thrust.integral(0, burnOut) / burnOut + assert ( + solid_motor.averageThrust == solid_motor.thrust.integral(0, burnOut) / burnOut + ) assert solid_motor.grainInitialVolume == grain_vol assert solid_motor.grainInitialMass == grain_mass assert solid_motor.propellantInitialMass == grainNumber * grain_mass @@ -67,7 +72,9 @@ def test_grain_geometry_progession_asserts_extreme_values(solid_motor): def test_mass_curve_asserts_extreme_values(solid_motor): - grain_vol = grainInitialHeight * (np.pi * (grainOuterRadius ** 2 - grainInitialInnerRadius ** 2)) + grain_vol = grainInitialHeight * ( + np.pi * (grainOuterRadius ** 2 - grainInitialInnerRadius ** 2) + ) grain_mass = grain_vol * grainDensity assert np.allclose(solid_motor.mass.getSource()[-1][-1], 0) @@ -100,11 +107,14 @@ def test_burn_area_asserts_extreme_values(solid_motor): def test_evaluate_inertia_I_asserts_extreme_values(solid_motor): - grain_vol = grainInitialHeight * (np.pi * (grainOuterRadius ** 2 - grainInitialInnerRadius ** 2)) + grain_vol = grainInitialHeight * ( + np.pi * (grainOuterRadius ** 2 - grainInitialInnerRadius ** 2) + ) grain_mass = grain_vol * grainDensity grainInertiaI_initial = grain_mass * ( - (1 / 4) * (grainOuterRadius ** 2 + grainInitialInnerRadius ** 2) + (1 / 12) * grainInitialHeight ** 2 + (1 / 4) * (grainOuterRadius ** 2 + grainInitialInnerRadius ** 2) + + (1 / 12) * grainInitialHeight ** 2 ) initialValue = (grainNumber - 1) / 2 @@ -120,10 +130,14 @@ def test_evaluate_inertia_I_asserts_extreme_values(solid_motor): def test_evaluate_inertia_Z_asserts_extreme_values(solid_motor): - grain_vol = grainInitialHeight * (np.pi * (grainOuterRadius ** 2 - grainInitialInnerRadius ** 2)) + grain_vol = grainInitialHeight * ( + np.pi * (grainOuterRadius ** 2 - grainInitialInnerRadius ** 2) + ) grain_mass = grain_vol * grainDensity - grainInertiaZ_initial = grain_mass * (1 / 2.0) * (grainInitialInnerRadius ** 2 + grainOuterRadius ** 2) + grainInertiaZ_initial = ( + grain_mass * (1 / 2.0) * (grainInitialInnerRadius ** 2 + grainOuterRadius ** 2) + ) assert np.allclose( solid_motor.inertiaZ.getSource()[0][-1], grainInertiaZ_initial, atol=0.01 @@ -174,7 +188,7 @@ def tests_export_eng_asserts_exported_values_correct(solid_motor): "0", "{:2.3}".format(grain_mass), "{:2.3}".format(grain_mass), - "RocketPy" + "RocketPy", ] assert dataPoints == [ From 6473bb261f6983df7092662bcb78c80aaf4e942e Mon Sep 17 00:00:00 2001 From: lucasfourier <69172945+lucasfourier@users.noreply.github.com> Date: Sat, 20 Nov 2021 18:25:08 -0300 Subject: [PATCH 09/10] MAINT: Fixing code documentation and plots Documentation was fixed and some lines of code were added to make sure plots worked fine. --- rocketpy/Rocket.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/rocketpy/Rocket.py b/rocketpy/Rocket.py index 895f8f983..6bf44e116 100644 --- a/rocketpy/Rocket.py +++ b/rocketpy/Rocket.py @@ -168,9 +168,9 @@ def __init__( powerOffDrag=None, powerOnDrag=None, rocket_length=None, - speed_of_sound=340.293988026089, - air_density=1.225000018124288, - dynamic_viscosity=1.789380278077583e-05, + speed_of_sound=340.29, + air_density=1.2250, + dynamic_viscosity=1.7893e-05, ): """Initializes Rocket class, process inertial, geometrical and aerodynamic parameters. @@ -214,8 +214,6 @@ def __init__( rocket_length : int, float, optional Rocket length used in the expressions for estimating drag coefficients in meters (m). - Air density used in the expressions for estimating drag coefficients - in kg/m³. speed_of_sound : int, float, optional Speed of sound used for estimating drag coefficients, in meters per second (m/s). The default value was obtained from the @@ -315,9 +313,9 @@ def __init__( def evaluateDragCoefficient(self): """Calculates and returns the drag coefficient as the sum of - of the individual drag coefficients at zero angle of attack - as a function of the Mach number. The angle of attack is - assumed to be zero. + the individual drag coefficients at zero angle of attack as + a function of the Mach number. The angle of attack is assumed + to be zero. Parameters ---------- @@ -325,8 +323,8 @@ def evaluateDragCoefficient(self): Returns ------- - self.viscous_friction_coefficient : Function - Function of mach number expressing the viscous friction coefficient, + self.drag_coefficient_estimate : Function + Function of mach number expressing the estimate for the drag coefficient, defined as in the literature. """ self.evaluateViscousFrictionCoefficient() @@ -339,6 +337,10 @@ def evaluateDragCoefficient(self): ] ) + if self.drag_coefficient_estimate is not None: + self.drag_coefficient_estimate.setInputs("Mach Number") + self.drag_coefficient_estimate.setOutputs("Drag Coefficient") + if not self.power_off_drag_as_input: self.powerOffDrag = self.drag_coefficient_estimate if not self.power_on_drag_as_input: From 5466444443e23ed9ec2c7cecc6a6ce9bbe9107cd Mon Sep 17 00:00:00 2001 From: Lucas Kierulff Balabram Date: Thu, 25 Nov 2021 18:13:09 -0300 Subject: [PATCH 10/10] BUG: fix Reynolds number equation --- rocketpy/Rocket.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocketpy/Rocket.py b/rocketpy/Rocket.py index 6bf44e116..e51aeec96 100644 --- a/rocketpy/Rocket.py +++ b/rocketpy/Rocket.py @@ -369,7 +369,7 @@ def evaluateViscousFrictionCoefficient(self): def calculations(mach): reynolds = ( - (self.air_density ** 2) + self.air_density * self.speed_of_sound * self.rocket_length * mach