Skip to content

Commit

Permalink
owens optimization running
Browse files Browse the repository at this point in the history
  • Loading branch information
yqliaohk committed Dec 13, 2024
1 parent 3ca24b0 commit c53df4a
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 31 deletions.
11 changes: 10 additions & 1 deletion examples/18_owens/analysis_options_owens_DVs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,22 @@ design_variables:
aero_shape:
chord:
flag: True
n_opt: 5
index_start: 0
index_end: 5
# max: 20.0
rotor_radius_vawt:
flag: True
n_opt: 7
index_start: 1
index_end: 6
# max: 20.0
control:
tsr:
flag: True
minimum: 1.0
maximum: 10.0



merit_figure: vawt_pseudolcoe
Expand All @@ -37,7 +46,7 @@ driver:
# max_minor_iter: 100 # Maximum number of minor design iterations (SNOPT)
max_iter: 200 # Maximum number of iterations (SLSQP)
solver: SLSQP # Optimization solver. Other options are 'SLSQP' - 'CONMIN'
step_size: 1.e-4 # Step size for finite differencing
step_size: 1e-4 # Step size for finite differencing
form: forward # Finite differencing mode, either forward or central
setp_calc: rel_avg
# design_of_experiments:
Expand Down
5 changes: 3 additions & 2 deletions examples/18_owens/driver_weis_owens.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

analysis_override = {}
analysis_override['general'] = {}
analysis_override['general']['folder_output'] = os.path.join('outputs/18_OWENS_OptStudies/1_change_opt_chord_radius/',"slsqp")
analysis_override['general']['folder_output'] = os.path.join('outputs/18_OWENS_OptStudies/Opt_chord_radius_TSR/',"slsqp")
analysis_override['driver'] = {}
analysis_override['driver']['optimization'] = {}
analysis_override['driver']['optimization']['solver'] = "SLSQP"
Expand All @@ -38,6 +38,7 @@
rank = 0
if rank == 0:
# shutil.copyfile(os.path.join(analysis_options['general']['folder_output'],analysis_options['general']['fname_output']+'.yaml'), fname_wt_input)
print("Tower mass (kg) =", wt_opt["towerse.tower_mass"])
print("Mass (kg) =", wt_opt["owens.mass"])
print("Power =", wt_opt["owens.power"])
# print("Floating platform mass (kg) =", wt_opt["floatingse.platform_mass"])

4 changes: 2 additions & 2 deletions examples/18_owens/modeling_options_OWENS_windioExample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ OWENS:
analysisType: unsteady # unsteady, steady, modal
AeroModel: "DMS" # OWENSAero model "DMS" for double multiple streamtube or "AC" for actuator cylinder, or "AD" for aerodyn
structuralModel: "TNB" #Structural models available: TNB full timoshenko beam elements with time newmark beta time stepping, ROM reduced order modal model of the timoshenko elements, GX with GXBeam's methods for geometrically exact beam theory and more efficient methods and time stepping
controlStrategy: "prescribedRPM" # should be in WindIO?- yes,
controlStrategy: "tsrTracking" #"prescribedRPM" # should be in WindIO?- yes,
numTS: 20 # number of time steps TODO: change to sim time and make this derived
delta_t: 0.01 # time step in seconds
dataOutputFilename: "./InitialDataOutputs.out" # data output filename with path, set to nothing or don't specify to not output anything
Expand All @@ -39,7 +39,7 @@ OWENS:
VTKsaveName: "./vtk/windio" # Path and name of the VTK outputs, recommended to put it in its own folder (which it will automatically create if needed)
aeroLoadsOn: 2 # Level of aero coupling 0 structures only, 1 no deformation passed to the aero, 2 two-way coupling, 1.5 last time step's deformations passed to this timesteps aero and no internal iteration.
Prescribed_RPM_time_controlpoints: [0.0,100000.1]
Prescribed_RPM_RPM_controlpoints: [17.2,17.2]
Prescribed_RPM_RPM_controlpoints: [17.2,17.2] # This will be overwritten by the TSR-calculated RPM if tsrTracking is used in controlStrategy
Prescribed_Vinf_time_controlpoints: [0.0,100000.1]
Prescribed_Vinf_Vinf_controlpoints: [17.2,17.2]

Expand Down
2 changes: 1 addition & 1 deletion examples/18_owens/owens_land.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,7 @@ materials:
control: # This has to be here for connection to work. Copied from IEA22
supervisory: {Vin: 0.5, Vout: 4.0, maxTS: 60}
pitch: {PC_zeta: !!null '', PC_omega: !!null '', ps_percent: !!null '', max_pitch: !!null '', max_pitch_rate: 0.1745, min_pitch: 0.00088}
torque: {control_type: !!null '', tsr: 7.64, VS_zeta: !!null '', VS_omega: !!null '', max_torque_rate: 1500000.0, VS_minspd: 0.0, VS_maxspd: 1.26711}
torque: {control_type: tsr_tracking, tsr: 5.6, VS_zeta: !!null '', VS_omega: !!null '', max_torque_rate: 1500000.0, VS_minspd: 0.0, VS_maxspd: 1.26711}
setpoint_smooth: {ss_vsgain: !!null '', ss_pcgain: !!null ''}
shutdown: {limit_type: !!null '', limit_value: !!null ''}
environment: {air_density: 1.225, air_dyn_viscosity: 1.7894e-5, air_speed_sound: 350.0, shear_exp: 0.0, gravity: 9.80665, weib_shape_parameter: 2.0, water_density: 1025.0, water_dyn_viscosity: 0.0013351, soil_shear_modulus: 140000000.0, soil_poisson: 0.4, water_depth: 50.0, air_pressure: 101325.0, air_vapor_pressure: 2500.0, significant_wave_height: 1.0, significant_wave_period: 5.0}
Expand Down
4 changes: 4 additions & 0 deletions weis/glue_code/glue_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,10 @@ def setup(self):
self.connect("materials.wohler_intercept", "owens.wohler_A_mat")
self.connect("materials.ply_t_from_yaml", "owens.ply_t")

# control tsr
if modeling_options["OWENS"]["general"]["controlStrategy"] == "tsrTracking":
self.connect("control.rated_TSR", "owens.tsr")




16 changes: 0 additions & 16 deletions weis/inputs/modeling_schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,22 +80,6 @@ properties:
type: boolean
default: False
description: Flag whether to apply the Goodman correction for mean stress value to the stress amplitude value in fatigue calculations
owens_configuration:
type: object
default: {}
properties:
owens_path:
type: string
default: none
desciption: Path to owens project
master_input:
type: string
default: none
description: Path to the sample yaml file for initialization
adi_lib:
type: string
default: none
description: Path to the aerodyn interface library, "nothing" if you are using the one that is automatically built with OWENSOpenFASTWrappers.jl

WISDEM:
type: object
Expand Down
28 changes: 19 additions & 9 deletions weis/owens/openmdao_owens.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ def setup(self):
# Solver options (come from modeling options)

# Control inputs
if self.owens_modeling_options["OWENS_Options"]["controlStrategy"] == "prescribedRPM":
self.add_input("RPM", val=15.0, desc="RPM")
if self.owens_modeling_options["OWENS_Options"]["controlStrategy"] == "tsrTracking":
self.add_input("tsr", val=15.0, desc="TSR")

# Environmental conditions
# Maybe this fits better into load cases?
Expand Down Expand Up @@ -363,10 +363,10 @@ def initialize_model(self):

def setup_partials(self):
# This can be set analytically from julia AD
self.declare_partials("power", "*", method="fd")
self.declare_partials("lcoe", "*", method="fd")
self.declare_partials("SF", "*", method="fd")
self.declare_partials("fatigue_damage", "*", method="fd")
self.declare_partials("power", ["blade_chord_values", "blade_ref_axis", "tsr"], method="fd")
self.declare_partials("lcoe", ["blade_chord_values", "blade_ref_axis", "tsr"], method="fd")
self.declare_partials("SF", ["blade_chord_values", "blade_ref_axis", "tsr"], method="fd")
self.declare_partials("fatigue_damage", ["blade_chord_values", "blade_ref_axis", "tsr"], method="fd")

def compute(self, inputs, outputs):
modopt = self.options["modeling_options"]
Expand Down Expand Up @@ -411,7 +411,6 @@ def compute(self, inputs, outputs):
rho = inputs["rho"][0]
Vinf = inputs["Vinf"][0]

RPM = inputs["RPM"][0]

# TODO: depending on the owens_yaml option, we can either update the model options directly, or write the intermediate yaml
# and then update the model inputs
Expand Down Expand Up @@ -741,6 +740,16 @@ def compute(self, inputs, outputs):
# jl_ordered_dict = convert(jl.OrderedDict, yaml_dict)
FileTools.save_yaml(outdir="/Users/yliao/repos/WEIS/examples/18_owens", fname="data.yml", data_out=yaml_dict)

# Update RPM path based on the TSR input
print("controlStrategy is: ", self.owens_modeling_options["OWENS_Options"]["controlStrategy"])
if modopt["OWENS"]["general"]["controlStrategy"] == "tsrTracking":
TSR = inputs["tsr"][0]
Blade_Radius = np.max(blade_geo_dict["outer_shape_bem"]["reference_axis"]["x"]["values"])
self.owens_modeling_options["OWENS_Options"]["Prescribed_RPM_RPM_controlpoints"] = np.array(modopt["OWENS"]["general"]["Prescribed_Vinf_Vinf_controlpoints"])*TSR*30/np.pi/Blade_Radius
self.owens_modeling_options["OWENS_Options"]["controlStrategy"] = "prescribedRPM" # still use prescribedRPM for OWENS
self.owens_modeling_options["OWENS_Options"]["Prescribed_RPM_RPM_controlpoints"]
FileTools.save_yaml(outdir="./", fname="OWENS_Opt.yml", data_out=self.owens_modeling_options)


jl.OWENS.runOWENSWINDIO("./OWENS_Opt.yml", "/Users/yliao/repos/WEIS/examples/18_owens/data.yml",path)

Expand Down Expand Up @@ -954,8 +963,9 @@ def compute(self, inputs, outputs):

# Parse outputs using h5 files
output_path = os.path.join(path, "InitialDataOutputs.h5")
output_h5 = OWENSOutput(output_path, output_channels=["t", "FReactionHist", "massOwens", "topDamage_blade_U", "SF_ult_U"])
output_h5 = OWENSOutput(output_path, output_channels=["t", "FReactionHist", "OmegaHist", "massOwens", "topDamage_blade_U", "SF_ult_U"])
massOwens = output_h5["massOwens"]
omegaHist = output_h5["OmegaHist"]
FReactionHist = output_h5["FReactionHist"]
# print("shape of FReactionHist: ", FReactionHist.shape)
topDamage_blade_U = output_h5["topDamage_blade_U"]
Expand All @@ -966,7 +976,7 @@ def compute(self, inputs, outputs):
# # Note: Change the return line in topRunDLC in OWENS to "return mass_breakout_twr, genPower, massOwens"
# print("-FReactionHist[:,5]: ", -FReactionHist[:,5])
outputs["mass"] = massOwens
outputs["power"] = np.mean(-FReactionHist[:,5])*(RPM*2*np.pi/60)
outputs["power"] = np.mean(FReactionHist[:,5]*omegaHist)
outputs["lcoe"] = massOwens/outputs["power"]


Expand Down

0 comments on commit c53df4a

Please sign in to comment.