Commit 33a24eec authored by Frederik Zahle's avatar Frederik Zahle
Browse files

updated assembly with working design code

parent 17c9c376
from openmdao.main.api import Assembly
from openmdao.lib.datatypes.api import Float, Enum, Array
from openmdao.lib.datatypes.api import Float, Enum, Array, Int, Bool
# from SEAMAero.aero_design import AerodynamicDesign
from SEAMCosts.SEAMCAPEX import SEAMCAPEX
from SEAMCosts.costs_scaling import OPEXSimple
from SEAMLoads.SEAMLoads import SEAMLoads
from SEAMTower.SEAMTower import SEAMTower
from SEAMAero.SEAM_AEP import SEAMAEP
from SEAMRotor.SEAMRotor import SEAMBladeStructure
# from SEAMGeometry.SEAMGeometry import SEAMGeometry
def connect_io(top, cls):
cls_name = cls.name
for name in cls.list_inputs():
try:
top.connect(name, cls_name + '.%s' % name)
except:
# print 'failed connecting', cls_name, name
pass
for name in cls.list_outputs():
try:
top.connect(cls_name + '.%s' % name, name)
except:
pass
class SEAMAssembly(Assembly):
d2e = Float(0.73, iotype='in', desc='Dollars to Euro ratio')
rated_power = Float(3., iotype='in', units='W', desc='Turbine rated power')
rated_power = Float(3., iotype='in', units='MW', desc='Turbine rated power')
hub_height = Float(100., iotype='in', units='m', desc='Hub height')
rotor_diameter = Float(110., iotype='in', units='m', desc='Rotor diameter')
site_type = Enum('onshore', values=('onshore', 'offshore'), iotype='in',
......@@ -29,7 +48,6 @@ class SEAMAssembly(Assembly):
total_cost = Float(iotype='out', desc='Total CAPEX')
rho_steel = Float(7.8e3, iotype='in', desc='density of steel')
hub_height = Float(100., iotype='in', desc='Hub height')
D_bottom = Float(4., iotype='in', desc='Tower bottom diameter')
D_top = Float(2., iotype='in', desc='Tower top diameter')
......@@ -44,48 +62,116 @@ class SEAMAssembly(Assembly):
t = Array(iotype='out', desc='Wall thickness')
mass = Float(iotype='out', desc='Tower mass')
tsr = Float(iotype='in', units='m', desc='Design tip speed ratio')
F = Float(iotype='in', desc='')
WohlerExpFlap = Float(iotype='in', desc='Wohler Exponent blade flap')
WohlerExpTower = Float(iotype='in', desc='Wohler Exponent tower bottom')
nSigma4fatFlap = Float(iotype='in', desc='')
nSigma4fatTower = Float(iotype='in', desc='')
dLoaddUfactorFlap = Float(iotype='in', desc='')
dLoaddUfactorTower = Float(iotype='in', desc='')
Neq = Float(iotype='in', desc='')
EdgeExtDynFact = Float(iotype='in', desc='')
EdgeFatDynFact = Float(iotype='in', desc='')
max_tipspeed = Float(iotype='in', desc='Maximum tip speed')
n_wsp = Int(iotype='in', desc='Number of wind speed bins')
min_wsp = Float(0.0, iotype = 'in', units = 'm/s', desc = 'min wind speed')
max_wsp = Float(iotype = 'in', units = 'm/s', desc = 'max wind speed')
Iref = Float(iotype='in', desc='Reference turbulence intensity')
WeibullInput = Bool(iotype='in', desc='Flag for Weibull input')
WeiA_input = Float(iotype = 'in', units='m/s', desc = 'Weibull A')
WeiC_input = Float(iotype = 'in', desc='Weibull C')
NYears = Float(iotype = 'in', desc='Operating years')
overallMaxTower = Float(iotype='out', units='kN*m', desc='Max tower bottom moment')
overallMaxFlap = Float(iotype='out', units='kN*m', desc='Max blade root flap moment')
FlapLEQ = Float(iotype='out', units='kN*m', desc='Blade root flap lifetime eq. moment')
TowerLEQ = Float(iotype='out', units='kN*m', desc='Tower bottom lifetime eq. moment')
Nsections = Int(iotype='in', desc='number of sections')
Neq = Float(1.e7, iotype='in', desc='')
WohlerExpFlap = Float(iotype='in', desc='')
PMtarget = Float(iotype='in', desc='')
rotor_diameter = Float(iotype='in', units='m', desc='') #[m]
MaxChordrR = Float(iotype='in', units='m', desc='') #[m]
OverallMaxFlap = Float(iotype='in', desc='')
OverallMaxEdge = Float(iotype='in', desc='')
TIF_FLext = Float(iotype='in', desc='') # Tech Impr Factor _ flap extreme
TIF_EDext = Float(iotype='in', desc='')
FlapLEQ = Float(iotype='in', desc='')
EdgeLEQ = Float(iotype='in', desc='')
TIF_FLfat = Float(iotype='in', desc='')
sc_frac_flap = Float(iotype='in', desc='') # sparcap fraction of chord flap
sc_frac_edge = Float(iotype='in', desc='') # sparcap fraction of thickness edge
SF_blade = Float(iotype='in', desc='') #[factor]
Slim_ext_blade = Float(iotype='in', units='MPa', desc='')
Slim_fat_blade = Float(iotype='in', units='MPa', desc='')
AddWeightFactorBlade = Float(iotype='in', desc='') # Additional weight factor for blade shell
BladeDens = Float(iotype='in', units='kg/m**3', desc='density of blades') # [kg / m^3]
BladeCostPerMass = Float(iotype='in', desc='') #[e/kg]
HubCostPerMass = Float(iotype='in', desc='') #[e/kg]
SpinnerCostPerMass = Float(iotype='in', desc='') #[e/kg]
BladeWeight = Float(iotype = 'out', units = 'kg', desc = 'BladeMass' )
mean_wsp = Float(iotype = 'in', units = 'm/s', desc = 'mean wind speed') # [m/s]
air_density = Float(iotype = 'in', units = 'kg/m**3', desc = 'density of air') # [kg / m^3]
turbulence_int = Float(iotype = 'in', desc = '')
max_Cp = Float(iotype = 'in', desc = 'max CP')
gearloss_const = Float(iotype = 'in', desc = 'Gear loss constant')
gearloss_var = Float(iotype = 'in', desc = 'Gear loss variable')
genloss = Float(iotype = 'in', desc = 'Generator loss')
convloss = Float(iotype = 'in', desc = 'Converter loss')
# Outputs
rated_wind_speed = Float(units = 'm / s', iotype='out', desc='wind speed for rated power')
ideal_power_curve = Array(iotype='out', units='kW', desc='total power before losses and turbulence')
power_curve = Array(iotype='out', units='kW', desc='total power including losses and turbulence')
wind_curve = Array(iotype='out', units='m/s', desc='wind curve associated with power curve')
NYears = Float(iotype = 'in', desc='Operating years') # move this to COE calculation
aep = Float(iotype = 'out', units='mW*h', desc='Annual energy production in mWh')
total_aep = Float(iotype = 'out', units='mW*h', desc='AEP for total years of production')
def configure(self):
# self.add('aero', AerodynamicDesign())
# self.driver.workflow.add('aero')
#
self.add('aep_calc', SEAMAEP())
self.add('loads', SEAMLoads())
self.driver.workflow.add('loads')
self.add('tower_design', SEAMTower(21))
self.driver.workflow.add('tower_design')
self.add('blade_design', SEAMBladeStructure())
self.driver.workflow.add(['aep_calc', 'loads', 'tower_design', 'blade_design'])
self.connect('loads.M_bottom', 'tower_design.M_bottom')
self.connect('loads.M_leq', 'tower_design.M_leq')
self.connect('loads.overallMaxTower', 'tower_design.overallMaxTower')
self.connect('loads.TowerLEQ', 'tower_design.TowerLEQ')
self.add('capex', SEAMCAPEX())
self.driver.workflow.add('capex')
self.connect('loads.overallMaxFlap', 'blade_design.overallMaxFlap')
self.connect('loads.overallMaxEdge', 'blade_design.overallMaxEdge')
self.connect('loads.FlapLEQ', 'blade_design.FlapLEQ')
self.connect('loads.EdgeLEQ', 'blade_design.EdgeLEQ')
self.add('opex', OPEXSimple())
self.driver.workflow.add('opex')
for name in self.list_inputs():
try:
self.connect(name, 'capex.%s' % name)
except:
pass
for name in self.list_outputs():
try:
self.connect('capex.%s' % name, name)
except:
pass
for name in self.tower_design.list_inputs():
# self.add('capex', SEAMCAPEX())
# self.driver.workflow.add('capex')
#
# self.add('opex', OPEXSimple())
# self.driver.workflow.add('opex')
#
try:
self.connect(name, 'tower_design.%s' % name)
except:
pass
for name in self.tower_design.list_outputs():
try:
self.connect('tower_design.%s' % name, name)
except:
pass
connect_io(self, self.aep_calc)
connect_io(self, self.loads)
connect_io(self, self.tower_design)
connect_io(self, self.blade_design)
import unittest
from SEAM.seam_assemblies import SEAMAssembly
class SEAMTestCase(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
# add some tests here...
#def test_SEAM(self):
#pass
if __name__ == "__main__":
unittest.main()
\ No newline at end of file
top = SEAMAssembly()
top.BladeCostPerMass = 15.0
top.HubCostPerMass = 3.5
top.SpinnerCostPerMass = 4.5
top.hub_cost_per_mass = 3.5
top.spinner_cost_per_mass = 4.5
top.tower_cost_per_mass = 4.0
top.AddWeightFactorBlade = 1.2
top.BladeDens = 2100.0
top.D_bottom = 8.3
top.D_top = 5.5
top.EdgeExtDynFact = 2.5
top.EdgeFatDynFact = 0.75
top.F = 0.777
top.Iref = 0.16
top.MaxChordrR = 0.2
top.NYears = 20.0
top.Neq = 10000000.0
top.Nsections = 21
top.PMtarget = 1.0
top.SF_blade = 1.1
top.SF_tower = 1.5
top.Slim_ext = 235.0
top.Slim_fat = 14.885
top.Slim_ext_blade = 200.0
top.Slim_fat_blade = 27.0
top.TIF_EDext = 1.0
top.TIF_FLext = 1.0
top.TIF_FLfat = 1.0
top.WeiA_input = 11.0
top.WeiC_input = 2.0
top.WeibullInput = True
top.WohlerExpFlap = 10.0
top.WohlerExpTower = 4.0
top.bearing_cost_per_mass = 14.0
top.blade_cost_per_mass = 15.0
top.d2e = 0.73
top.dLoaddUfactorFlap = 0.9
top.dLoaddUfactorTower = 0.8
top.hub_height = 120.0
top.max_tipspeed = 90.0
top.n_wsp = 26
top.min_wsp = 0.0
top.max_wsp = 25.0
top.nSigma4fatFlap = 1.2
top.nSigma4fatTower = 0.8
top.rated_power = 10.0
top.rho_steel = 7800.0
top.rotor_diameter = 178.0
top.sc_frac_edge = 0.8
top.sc_frac_flap = 0.3
top.site_type = 'onshore'
top.tsr = 8.0
top.air_density = 1.225
top.turbulence_int = 0.1
top.max_Cp = 0.49
top.gearloss_const = 0.01 # Fraction
top.gearloss_var = 0.014 # Fraction
top.genloss = 0.03 # Fraction
top.convloss = 0.03 # Fraction
top.run()
# class SEAMTestCase(unittest.TestCase) =
#
# def setUp(self) =
# pass
#
# def tearDown(self) =
# pass
#
# # add some tests here...
#
# #def test_SEAM(self) =
# #pass
#
# if __name__ == "__main__" =
# unittest.main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment