From dc463f928d2b15be6d11222d84c6330cccb4dd6c Mon Sep 17 00:00:00 2001 From: kbonney Date: Wed, 30 Aug 2023 15:01:02 -0400 Subject: [PATCH] Adding docstrings --- src/pynumad/__init__.py | 1 - src/pynumad/analysis/ansys/beamforce.py | 1 - src/pynumad/analysis/ansys/utility.py | 1 - src/pynumad/io/__init__.py | 5 ++ src/pynumad/objects/airfoil.py | 52 ++++++++-------- src/pynumad/objects/blade.py | 65 +++++++++++++++----- src/pynumad/objects/component.py | 5 -- src/pynumad/objects/definition.py | 39 ++++++++++++ src/pynumad/objects/geometry.py | 80 ++++++++----------------- src/pynumad/objects/material.py | 5 +- src/pynumad/objects/station.py | 15 ++--- 11 files changed, 154 insertions(+), 115 deletions(-) diff --git a/src/pynumad/__init__.py b/src/pynumad/__init__.py index b13185f..4b0af15 100644 --- a/src/pynumad/__init__.py +++ b/src/pynumad/__init__.py @@ -2,7 +2,6 @@ from pynumad.objects.airfoil import Airfoil from pynumad.objects.component import Component from pynumad.objects.material import Material -from pynumad.objects.elements import MatDBentry, BOM, Ply, Layer, Shearweb, Stack from pynumad.objects.station import Station from pynumad.io.mesh_to_yaml import mesh_to_yaml diff --git a/src/pynumad/analysis/ansys/beamforce.py b/src/pynumad/analysis/ansys/beamforce.py index a15e2b6..2fa82dd 100644 --- a/src/pynumad/analysis/ansys/beamforce.py +++ b/src/pynumad/analysis/ansys/beamforce.py @@ -4,7 +4,6 @@ from os.path import join import numpy as np -from pynumad.objects.elements import SkinArea from pynumad.analysis.ansys.read import * from pynumad.utils.fatigue import * from pynumad.utils.interpolation import * diff --git a/src/pynumad/analysis/ansys/utility.py b/src/pynumad/analysis/ansys/utility.py index 5d4dd64..a0dae83 100644 --- a/src/pynumad/analysis/ansys/utility.py +++ b/src/pynumad/analysis/ansys/utility.py @@ -4,7 +4,6 @@ from os.path import join import numpy as np -from pynumad.objects.elements import SkinArea from pynumad.utils.fatigue import * from pynumad.utils.interpolation import * diff --git a/src/pynumad/io/__init__.py b/src/pynumad/io/__init__.py index e69de29..702d67b 100644 --- a/src/pynumad/io/__init__.py +++ b/src/pynumad/io/__init__.py @@ -0,0 +1,5 @@ +from .airfoil_to_xml import airfoil_to_xml +from .excel_to_blade import excel_to_blade +from .mesh_to_yaml import mesh_to_yaml +from .xml_to_airfoil import xml_to_airfoil +from .yaml_to_blade import yaml_to_blade diff --git a/src/pynumad/objects/airfoil.py b/src/pynumad/objects/airfoil.py index 9060c11..0f94108 100644 --- a/src/pynumad/objects/airfoil.py +++ b/src/pynumad/objects/airfoil.py @@ -15,14 +15,6 @@ class Airfoil: """Airfoil object - Parameters - ---------- - coords : array - ref : string - Name of airfoil reference - filename : string - path to filename of airfoil (xml somewhat supported) - Attributes ---------- name : str @@ -49,7 +41,19 @@ class Airfoil: Options, 'round', 'sharp', or 'flat' """ - def __init__(self, filename=None, coords=None, ref=None): + def __init__(self, filename: str = None, coords: ndarray = None, reference: str = None): + """_summary_ + + Parameters + ---------- + filename : string + path to filename of airfoil (xml somewhat supported) + coords : array + reference : string + Name of airfoil reference + + """ + self.name: str = None self.reference: str = None self.coordinates: ndarray = None @@ -75,24 +79,20 @@ def __init__(self, filename=None, coords=None, ref=None): file_contents = f.read().splitlines() self.read_xml(file_contents) + elif reference is not None and coords is not None: + self.name = reference + self.reference = reference + self.coordinates = coords + else: - try: - # check if ref is a string and coords an array - ref * 5 - coords * 5 - # if so, assign as attributes - self.name = ref - self.reference = ref - self.coordinates = coords - except TypeError: - # otherwise, provide default AF profile - self.name = "circular" - self.reference = "" - theta = np.linspace(0, np.pi, 50) - theta = np.concatenate((theta, [np.pi], theta[1:-1])) - xcoord = 0.5 * np.cos(-1 * theta) + 0.5 - ycoord = 0.5 * np.sin(-1 * theta) - self.coordinates = np.stack((xcoord, ycoord), axis=1) + # otherwise, provide default AF profile + self.name = "circular" + self.reference = "" + theta = np.linspace(0, np.pi, 50) + theta = np.concatenate((theta, [np.pi], theta[1:-1])) + xcoord = 0.5 * np.cos(-1 * theta) + 0.5 + ycoord = 0.5 * np.sin(-1 * theta) + self.coordinates = np.stack((xcoord, ycoord), axis=1) self.manageTE() def _compare(self, other): diff --git a/src/pynumad/objects/blade.py b/src/pynumad/objects/blade.py index 64456c9..ae64e2c 100644 --- a/src/pynumad/objects/blade.py +++ b/src/pynumad/objects/blade.py @@ -20,27 +20,45 @@ class Blade: """BladeDef A class definition for wind & water turbine blades. - Parameters - ---------- - filename : string - Attributes ---------- + name : str + Name of the blade + definition : Definition + Object containing the definition of the blade. + ispan : ndarray + Array defining the interpolated stations from 0 to 1 + geometry : Geometry + Object containing the interpolated geometry of the blade + keypoints : KeyPoints + Object containing information about keypoint locations and areas + bill_of_materials : BillOfMaterials + stackdb : StackDatabase + materialdb : MaterialDatabase + settings : BladeSettings Example ------- - blade = BladeDef("path/to/blade.yaml") + blade = Blade("path/to/blade.yaml") """ def __init__(self, filename: str = None): + """ + Parameters + ---------- + filename : str, optional + Directory and filename of blade input file to load into the + Blade object. + """ + self.name: str = None + self.definition: Definition = Definition() + self.ispan: ndarray = None self.geometry: Geometry = Geometry() self.keypoints: KeyPoints = KeyPoints() - self.definition: Definition = Definition() - self.stackdb: StackDatabase = StackDatabase() - self.materialdb = MaterialDatabase() self.bill_of_materials: BillOfMaterials = BillOfMaterials() - self.ispan: ndarray = None - self.settings = BladeSettings() + self.stackdb: StackDatabase = StackDatabase() + self.materialdb: MaterialDatabase = MaterialDatabase() + self.settings: BladeSettings = BladeSettings() # read input file if filename: @@ -52,7 +70,9 @@ def __init__(self, filename: str = None): raise Exception( "Unknown filetype. Currently supported inputs are excel and yaml files." ) - + self.name = filename.split(".")[0] + else: + self.name = "blade" return def __str__(self): @@ -99,14 +119,15 @@ def read_excel(self, filename: str): return self def update_blade(self): - """ - TODO docstring + """Generates geometry, keypoints, bill of materials, + stacks database, and materials database based on the + blade definition. """ self.geometry.generate(self.definition) self.keypoints.generate(self.definition, self.geometry) self.bill_of_materials.generate(self.definition, self.keypoints) - self.stackdb.generate(self.keypoints) - self.materialdb.generate(self.materials) + self.stackdb.generate(self.keypoints, self.bill_of_materials) + self.materialdb.generate(self.definition.materials, self.stackdb) return self def expand_blade_geometry_te(self, min_edge_lengths): @@ -117,7 +138,19 @@ def expand_blade_geometry_te(self, min_edge_lengths): self.keypoints.generate(self.definition, self.geometry) return - def add_interpolated_station(self, span_location): + def add_interpolated_station(self, span_location: float): + """Adds an interpolated station to blade geometry + + Parameters + ---------- + span_location : float + location along span between 0 and 1. + + Returns + ------- + int + integer index where the new span was inserted + """ x0 = self.ispan if span_location < self.ispan[-1] and span_location > 0: diff --git a/src/pynumad/objects/component.py b/src/pynumad/objects/component.py index bfed892..d9b0029 100644 --- a/src/pynumad/objects/component.py +++ b/src/pynumad/objects/component.py @@ -14,10 +14,6 @@ class Component: """ComponentDef: A class definition for blade components. - Parameters - ---------- - None - Attributes ---------- group : int @@ -96,7 +92,6 @@ def _compare(self, other): return False return True - def get_control_points(self): if self.pinnedends: if np.any(self.control_points[:, 0] < 0) or np.any(self.control_points[:, 0] > 1): diff --git a/src/pynumad/objects/definition.py b/src/pynumad/objects/definition.py index e51bfac..a032e30 100644 --- a/src/pynumad/objects/definition.py +++ b/src/pynumad/objects/definition.py @@ -5,6 +5,45 @@ class Definition: + """Contains the definition of a blade object + + Attributes + ---------- + components : list + shearweb : list + materials : dict + stacks : ndarray + swstacks : array + ispan : ndarray + Spanwise locations of interpolated output + aerocenter : ndarray + Aerodynamic center of airfoil (used only by NuMAD->FAST) + chord : ndarray + Chord distribution [m] + chordoffset : ndarray + Chordwise offset (in addition to natural offset) + degreestwist : ndarray + Twist distribution [degrees] + leband : float + Location of keypoint a + percentthick : ndarray + Percent thickness of airfoil [%] + prebend : ndarray + Blade prebend, reference axis location along x2 [m] + span : ndarray + Spanwise location of distributed properties [m] + sparcapoffset : ndarray + sparcapwidth : ndarray + Locations of keypoints b & c, defines distance + between keypoints b & c [mm]. First entry is the HP spar cap. + Second entry is the LP spar cap + stations : list + list of station objects + sweep : ndarray + Blade Sweep, Reference axis location along x1 [m] + teband : float + te_type : list + """ def __init__(self): self.components: list = None self.shearweb: list = None diff --git a/src/pynumad/objects/geometry.py b/src/pynumad/objects/geometry.py index 29595bf..06d2cd0 100644 --- a/src/pynumad/objects/geometry.py +++ b/src/pynumad/objects/geometry.py @@ -13,66 +13,39 @@ class Geometry: """Contains the geometry of a blade object - Parameters - ---------- - shape: string - Attributes ---------- - aerocenter: array - Aerodynamic center of airfoil (used only by NuMAD->FAST) - chord : array - Chord distribution [m] - chordoffset : array - Chordwise offset (in addition to natural offset) - coordinates : array - actual x,y,z geometry - degreestwist : array - Twist distribution [degrees] - ispan : array - Spanwise locations of interpolated output - leband : float - Location of keypoint a - percentthick : array - Percent thickness of airfoil [%] - prebend : array - Blade prebend, reference axis location along x2 [m] - span : array - Spanwise location of distributed properties [m] - sparcapoffset : array - (Does Nothing) - sparcapwidth : array - Locations of keypoints b & c, defines distance - between keypoints b & c [mm]. First entry is the HP spar cap. - Second entry is the LP spar cap - sweep : array - Blade Sweep, Reference axis location along x1 [m] - teband : float - idegreestwist : array - interpolated twist - ichord : array - interpolated chord - ipercentthick : array - interpolated thickness - c : array + c : ndarray nondimensional (0-1) value of x axis - ic : array - icamber : array + camber : ndarray + thickness : ndarray + ic : ndarray + icamber : ndarray ithickness : array - ichordoffset : array + interpolated thickness + cpos : ndarray + x-axis parametrization for airfoil curve + ichord : ndarray + interpolated chord + ichordoffset : ndarray interpolated offset - iaerocenter : array + iaerocenter : ndarray interpolated aerocenter - isweep : array - interpolated sweep - iprebend : array - interpolated prebend - xoffset : array - natural offset + idegreestwist : ndarray + interpolated twist + ipercentthick : ndarray + interpolated percent thickness profiles : array normalized airfoil profiles - cpos : array - x-axis parametrization for airfoil curve + coordinates : ndarray + actual x,y,z geometry + xoffset : ndarray + natural offset + LEindex : ndarray + iprebend : ndarray + interpolated prebend + isweep : ndarray + interpolated sweep """ def __init__(self, settings=None): @@ -83,7 +56,6 @@ def __init__(self, settings=None): self.icamber: ndarray = None self.ithickness: ndarray = None self.cpos: ndarray = None - self.idegreestwist: ndarray = None self.ichord: ndarray = None self.ichordoffset: ndarray = None self.iaerocenter: ndarray = None @@ -189,7 +161,7 @@ def generate(self, definition): len(station.airfoil.c) == num_points ), "Station airfoils must have same number of samples." - self.cf = station.airfoil.c + self.c[:,k] = station.airfoil.c self.camber[:, k] = station.airfoil.camber self.thickness[:, k] = station.airfoil.thickness tetype[k] = station.airfoil.te_type diff --git a/src/pynumad/objects/material.py b/src/pynumad/objects/material.py index 53aa6e8..ab7bba6 100644 --- a/src/pynumad/objects/material.py +++ b/src/pynumad/objects/material.py @@ -8,9 +8,6 @@ class Material: """MaterialDef: A class for blade materials. - Parameters - ---------- - Attributes ---------- name : str @@ -80,6 +77,7 @@ class Material: def __init__(self): self.name: str = None self.type: str = None + self.reference: str = None self.layerthickness: float = None self.ex: float = None self.ey: float = None @@ -106,7 +104,6 @@ def __init__(self): self.m: list = None self.gamma_mf: list[float] = None self.gamma_ms: list[float] = None - self.reference: str = None def _compare(self, other): """ diff --git a/src/pynumad/objects/station.py b/src/pynumad/objects/station.py index 069e2af..117d14b 100644 --- a/src/pynumad/objects/station.py +++ b/src/pynumad/objects/station.py @@ -11,15 +11,10 @@ class Station: """ - Parameters - ---------- - af : AirfoilDef or string - airfoil - Attributes ---------- - airfoil - ``AirfoilDef`` object + airfoil : Airfoil + Airfoil corresponding to the station spanlocation Spanwise location where station is defined [m] parent @@ -27,6 +22,12 @@ class Station: """ def __init__(self, af=None): + """ + Parameters + ---------- + af : Airfoil, string + airfoil object or filename to airfoil coords + """ self.airfoil = None self.spanlocation = None self.parent = None