Skip to content

Commit

Permalink
Merge 6032907 into 3bebb10
Browse files Browse the repository at this point in the history
  • Loading branch information
helo9 committed Jan 22, 2019
2 parents 3bebb10 + 6032907 commit 4772f5c
Show file tree
Hide file tree
Showing 4 changed files with 240 additions and 63 deletions.
158 changes: 136 additions & 22 deletions examples/Section.ipynb

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions examples/test.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
64 changes: 59 additions & 5 deletions wingstructure/structure/polygon.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def calcarea(outline):
return A


def staticmoments(outline):
def calcstaticmoments(outline):

x_i, y_i = outline.T
x_ip1, y_ip1 = np.roll(outline.T, 1, axis=1)
Expand All @@ -22,7 +22,7 @@ def staticmoments(outline):
return S_x, S_y


def inertiamoments(outline):
def calcinertiamoments(outline):

x_i, y_i = outline.T
x_ip1, y_ip1 = np.roll(outline.T, 1, axis=1)
Expand All @@ -37,13 +37,67 @@ def inertiamoments(outline):
return I_xx, I_yy, I_xy


def neutralcenter(outline):
def calcneutralcenter(outline):

area_ = calcarea(outline)

S_x, S_y = staticmoments(outline)
S_x, S_y = calcstaticmoments(outline)

x_nc = S_y/area_
y_nc = S_x/area_

return x_nc, y_nc
return x_nc, y_nc


def calcgeom(geom, property_functions):

properties = {propfun:None for propfun in property_functions}

isexterior = True
for outline in (geom.exterior, *geom.interiors):
if isexterior:
for propfun in property_functions:
properties[propfun] = np.array(propfun(outline))
isexterior = False
else:
for propfun in property_functions:
properties[propfun] -= np.array(propfun(outline))

return [properties[propfun] for propfun in property_functions]


# TODO implement AnalaysisClass
class StructuralAnalysis:
def __init__(self, secbase):
self._secbase = secbase
self.nc = None
self.staticmoments = None
self.intertiamoments = None

def update(self):
# calculate normal center

self.area = 0

weighted_area_ = 0
weighted_staticmoment_ = np.zeros((2))

for feature in self._secbase.features:
for geom in feature.exportgeometry():
area, staticmoment = calcgeom(geom, [calcarea, calcstaticmoments])

self.area += area
weighted_area_ += geom.material.E*area
weighted_staticmoment_ += geom.material.E*staticmoment

self.nc = weighted_staticmoment_/weighted_area_

#TODO: calculate properties regarding normal center

self.bendingstiffness = np.zeros(3)

for feature in self._secbase.features:
for geom in feature.exportgeometry(self.nc):
inertiamoment = calcgeom(geom, [calcinertiamoments])[0]

self.bendingstiffness += inertiamoment*geom.material.E
80 changes: 44 additions & 36 deletions wingstructure/structure/section.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,24 @@
foam = Material(1.225)
sandwich = Material(1.225)
# Add layers
outerlayer = structure.Layer(sectionbase, carbonfabric, 5e-4)
core = structure.Layer(outerlayer, foam, 1e-2)
innerlayer = structure.Layer(core, carbonfabric, 5e-4)
# Add Spar
spar = structure.ISpar(parent=innerlayer,
material={'flange': carbonfabric, 'web': sandwich},
# create layers
outerlayer = structure.Layer(carbonfabric, 5e-4)
core = structure.Layer(foam, 1e-2)
innerlayer = structure.Layer(carbonfabric, 5e-4)
# create Spar
spar = structure.ISpar(material={'flange': carbonfabric, 'web': sandwich},
midpos=0.45,
flangewidth=0.2,
flangethickness=0.03,
webpos=0.5,
webthickness=0.02)
# add to sectionbase
sectionbase.extend([outerlayer, core, innerlayer, spar])
# Analyse Mass
massana = structure.MassAnalysis(spar)
massana = structure.MassAnalysis(sectionbase)
cg, mass = massana.massproperties()
"""

Expand All @@ -53,17 +55,6 @@
from shapely.algorithms import cga


def updatetrigger(f):
@wraps
def f_withupdate(self, *args, **kwds):
res = f(self, *args, **kwds)

self._trigger_update()

return res

return f_withupdate

class _AbstractBaseStructure:
def __init__(self, material):
super().__init__()
Expand All @@ -73,20 +64,18 @@ def __init__(self, material):

self.interior = None
self.geometry = None
self._updatecallbacks = []
self._updatecallback = None

def _add_updatecallback(self, callback):
if callback not in self._updatecallbacks:
self._updatecallbacks.append(callback)
def _set_updatecallback(self, callback):
if self._updatecallback is None:
self._updatecallback = callback

def _rm_updatecallback(self, callback):
try:
self._updatecallbacks.remove(callback)
except ValueError:
return
def _unset_updatecallback(self):
self._updatecallback = None

def _trigger_update(self):
for callback in self._updatecallbacks:
if self._updatecallback is not None:
callback = self._updatecallback
callback(self)

@abstractmethod
Expand Down Expand Up @@ -135,6 +124,10 @@ def _create_offset_box(self, line, thickness, side, bevel=0.0,
def cut_elements(self):
return self._cut_elements

def exportgeometry(self, refpoint=np.zeros(2)):
arraygeom = geom2array(self.geometry, refpoint)

return [arraygeom._replace(material=self.material)]

class SectionBase:
"""Foundation for section's wing structure description
Expand Down Expand Up @@ -167,7 +160,7 @@ def append(self, newfeature):
parentgeometry = self.features[-2].interior

self.features[-1]._update_geometry(parentgeometry)
self.features[-1]._add_updatecallback(self._update_callback)
self.features[-1]._set_updatecallback(self._update_callback)

def insert(self, index, newfeature):
self.features.insert(index, newfeature)
Expand All @@ -181,12 +174,12 @@ def remove(self, feature):
if feature not in self.features:
raise Exception('No feature {} found.'.format(feature))

feature._rm_updatecallback(self._update_callback)
feature._unset_updatecallback()
self.features.remove(feature)

def pop(self):
popped = self.features.pop()
popped._rm_updatecallback(self._update_callback)
popped._unset_updatecallback()

def _update_callback(self, updated_feature):
try:
Expand Down Expand Up @@ -480,8 +473,6 @@ def _update_geometry(self, exterior):

cutgeom = cutbox.intersection(exterior)

self.tmp = cutgeom

offsetside = self._get_inside_direction(exterior)

flangegeoms = []
Expand Down Expand Up @@ -866,4 +857,21 @@ def rework_svg(svg:str, width:float, height:float=100.0, stroke_width:float=None
'stroke-width="{:f}"'.format(stroke_width),
svg)

return svg
return svg


def geom2array(geometry, refpoint=np.zeros(2)):

from collections import namedtuple

ArrayGeom = namedtuple('ArrayGeom', ['exterior','interiors','material'])

if geometry.type != 'Polygon':
raise ValueError('Geometry must be of type \'Polygon\'')

exterior = np.array(geometry.exterior.coords) - refpoint.flat

interiors = [np.array(interior.coords) - refpoint.flat for interior in geometry.interiors]

return ArrayGeom(exterior, interiors, None)

0 comments on commit 4772f5c

Please sign in to comment.