Example #1
0
    def setup(self):
        n_height = self.options["n_height"]
        nFull = get_nfull(n_height)

        self.add_input("cylinder_mass", val=np.zeros(nFull - 1), units="kg")
        self.add_input("cylinder_cost", val=0.0, units="USD")
        self.add_input("cylinder_center_of_mass", val=0.0, units="m")
        self.add_input("cylinder_section_center_of_mass", val=np.zeros(nFull - 1), units="m")
        self.add_input("cylinder_I_base", np.zeros(6), units="kg*m**2")
        self.add_input("transition_piece_height", 0.0, units="m")
        self.add_input("transition_piece_mass", 0.0, units="kg")
        self.add_input("transition_piece_cost", 0.0, units="USD")
        self.add_input("gravity_foundation_mass", 0.0, units="kg")
        self.add_input("z_full", val=np.zeros(nFull), units="m")
        self.add_input("d_full", val=np.zeros(nFull), units="m")

        self.add_output("structural_cost", val=0.0, units="USD")
        self.add_output("structural_mass", val=0.0, units="kg")
        self.add_output("tower_cost", val=0.0, units="USD")
        self.add_output("tower_mass", val=0.0, units="kg")
        self.add_output("tower_center_of_mass", val=0.0, units="m")
        self.add_output("tower_section_center_of_mass", val=np.zeros(nFull - 1), units="m")
        self.add_output("tower_I_base", np.zeros(6), units="kg*m**2")
        self.add_output("monopile_mass", val=0.0, units="kg")
        self.add_output("monopile_cost", val=0.0, units="USD")
        self.add_output("transition_piece_I", np.zeros(6), units="kg*m**2")
        self.add_output("gravity_foundation_I", np.zeros(6), units="kg*m**2")
Example #2
0
    def setup(self):
        n_height = self.options["n_height"]
        nFull = get_nfull(n_height)

        self.add_input("z_full", np.zeros(nFull), units="m")

        # extra mass
        self.add_input("mass", 0.0, units="kg")
        self.add_input("mI", np.zeros(6), units="kg*m**2")
        self.add_input("mrho", np.zeros(3), units="m")
        self.add_input("transition_piece_mass", 0.0, units="kg")
        self.add_input("transition_piece_I", np.zeros(6), units="kg*m**2")
        self.add_input("gravity_foundation_I", np.zeros(6), units="kg*m**2")
        self.add_input("gravity_foundation_mass", 0.0, units="kg")
        self.add_input("transition_piece_height", 0.0, units="m")
        self.add_input("suctionpile_depth", 0.0, units="m")

        # point loads
        self.add_input("rna_F", np.zeros(3), units="N")
        self.add_input("rna_M", np.zeros(3), units="N*m")

        # Monopile handling
        self.add_input("z_soil", np.zeros(NPTS_SOIL), units="N/m")
        self.add_input("k_soil", np.zeros((NPTS_SOIL, 6)), units="N/m")

        # spring reaction data.
        nK = 4 if self.options[
            "monopile"] and not self.options["gravity_foundation"] else 1
        self.add_output("kidx", np.zeros(nK, dtype=np.int_))
        self.add_output("kx", np.zeros(nK), units="N/m")
        self.add_output("ky", np.zeros(nK), units="N/m")
        self.add_output("kz", np.zeros(nK), units="N/m")
        self.add_output("ktx", np.zeros(nK), units="N/m")
        self.add_output("kty", np.zeros(nK), units="N/m")
        self.add_output("ktz", np.zeros(nK), units="N/m")

        # extra mass
        nMass = 3
        self.add_output("midx", np.zeros(nMass, dtype=np.int_))
        self.add_output("m", np.zeros(nMass), units="kg")
        self.add_output("mIxx", np.zeros(nMass), units="kg*m**2")
        self.add_output("mIyy", np.zeros(nMass), units="kg*m**2")
        self.add_output("mIzz", np.zeros(nMass), units="kg*m**2")
        self.add_output("mIxy", np.zeros(nMass), units="kg*m**2")
        self.add_output("mIxz", np.zeros(nMass), units="kg*m**2")
        self.add_output("mIyz", np.zeros(nMass), units="kg*m**2")
        self.add_output("mrhox", np.zeros(nMass), units="m")
        self.add_output("mrhoy", np.zeros(nMass), units="m")
        self.add_output("mrhoz", np.zeros(nMass), units="m")

        # point loads (if addGravityLoadForExtraMass=True be sure not to double count by adding those force here also)
        nPL = 1
        self.add_output("plidx", np.zeros(nPL, dtype=np.int_))
        self.add_output("Fx", np.zeros(nPL), units="N")
        self.add_output("Fy", np.zeros(nPL), units="N")
        self.add_output("Fz", np.zeros(nPL), units="N")
        self.add_output("Mxx", np.zeros(nPL), units="N*m")
        self.add_output("Myy", np.zeros(nPL), units="N*m")
        self.add_output("Mzz", np.zeros(nPL), units="N*m")
Example #3
0
    def setup(self):
        n_height = self.options["modeling_options"]["n_height"]
        nFull = get_nfull(n_height)

        # effective geometry -- used for handbook methods to estimate hoop stress, buckling, fatigue
        self.add_input("z_full", np.zeros(nFull), units="m")
        self.add_input("d_full", np.zeros(nFull), units="m")
        self.add_input("t_full", np.zeros(nFull - 1), units="m")
        self.add_input("suctionpile_depth", 0.0, units="m")

        self.add_input("Az", val=np.zeros(nFull - 1), units="m**2")
        self.add_input("Asx", val=np.zeros(nFull - 1), units="m**2")
        self.add_input("Asy", val=np.zeros(nFull - 1), units="m**2")
        self.add_input("Jz", val=np.zeros(nFull - 1), units="m**4")
        self.add_input("Ixx", val=np.zeros(nFull - 1), units="m**4")
        self.add_input("Iyy", val=np.zeros(nFull - 1), units="m**4")

        # Material properties
        self.add_input("E_full", np.zeros(nFull - 1), units="N/m**2")
        self.add_input("G_full", np.zeros(nFull - 1), units="Pa")
        self.add_input("rho_full", np.zeros(nFull - 1), units="kg/m**3")
        self.add_input("sigma_y_full", np.zeros(nFull - 1), units="N/m**2")

        # Processed Frame3DD/OpenFAST outputs
        self.add_input("tower_Fz", val=np.zeros(nFull - 1), units="N")
        self.add_input("tower_Vx", val=np.zeros(nFull - 1), units="N")
        self.add_input("tower_Vy", val=np.zeros(nFull - 1), units="N")
        self.add_input("tower_Mxx", val=np.zeros(nFull - 1), units="N*m")
        self.add_input("tower_Myy", val=np.zeros(nFull - 1), units="N*m")
        self.add_input("tower_Mzz", val=np.zeros(nFull - 1), units="N*m")
        self.add_input("qdyn", val=np.zeros(nFull), units="N/m**2")

        # fatigue parameters
        self.add_input("life", 20.0)
        # self.add_input('m_SN', 4, desc='slope of S/N curve')
        # self.add_input('DC', 80.0, desc='standard value of stress')
        # self.add_input('z_DEL', np.zeros(nDEL), units='m', desc='absolute z coordinates of corresponding fatigue parameters')
        # self.add_input('M_DEL', np.zeros(nDEL), desc='fatigue parameters at corresponding z coordinates')

        # Load analysis
        self.add_output("axial_stress", val=np.zeros(nFull - 1), units="N/m**2")
        self.add_output("shear_stress", val=np.zeros(nFull - 1), units="N/m**2")
        self.add_output("hoop_stress", val=np.zeros(nFull - 1), units="N/m**2")

        self.add_output("hoop_stress_euro", val=np.zeros(nFull - 1), units="N/m**2")
        self.add_output("constr_stress", np.zeros(nFull - 1))
        self.add_output("constr_shell_buckling", np.zeros(nFull - 1))
        self.add_output("constr_global_buckling", np.zeros(nFull - 1))
        # self.add_output('constr_damage', np.zeros(nFull-1), desc='Fatigue damage at each tower section')
        self.add_output("turbine_F", val=np.zeros(3), units="N", desc="Total force on tower+rna")
        self.add_output("turbine_M", val=np.zeros(3), units="N*m", desc="Total x-moment on tower+rna measured at base")
Example #4
0
    def compute(self, inputs, outputs):
        n_height = self.options["n_height"]
        nFull = get_nfull(n_height)
        z = inputs["z_full"]

        # Prepare RNA, transition piece, and gravity foundation (if any applicable) for "extra node mass"
        itrans = util.find_nearest(z, inputs["transition_piece_height"])
        mtrans = inputs["transition_piece_mass"]
        Itrans = inputs["transition_piece_I"]
        mgrav = inputs["gravity_foundation_mass"]
        Igrav = inputs["gravity_foundation_I"]
        # Note, need len()-1 because Frame3DD crashes if mass add at end
        outputs["midx"] = np.array([nFull - 1, itrans, 0], dtype=np.int_)
        outputs["m"] = np.array([inputs["mass"], mtrans, mgrav]).flatten()
        outputs["mIxx"] = np.array([inputs["mI"][0], Itrans[0], Igrav[0]]).flatten()
        outputs["mIyy"] = np.array([inputs["mI"][1], Itrans[1], Igrav[1]]).flatten()
        outputs["mIzz"] = np.array([inputs["mI"][2], Itrans[2], Igrav[2]]).flatten()
        outputs["mIxy"] = np.array([inputs["mI"][3], Itrans[3], Igrav[3]]).flatten()
        outputs["mIxz"] = np.array([inputs["mI"][4], Itrans[4], Igrav[4]]).flatten()
        outputs["mIyz"] = np.array([inputs["mI"][5], Itrans[5], Igrav[5]]).flatten()
        outputs["mrhox"] = np.array([inputs["mrho"][0], 0.0, 0.0]).flatten()
        outputs["mrhoy"] = np.array([inputs["mrho"][1], 0.0, 0.0]).flatten()
        outputs["mrhoz"] = np.array([inputs["mrho"][2], 0.0, 0.0]).flatten()

        # Prepare point forces at RNA node
        outputs["plidx"] = np.array([nFull - 1], dtype=np.int_)  # -1 b/c same reason as above
        outputs["Fx"] = np.array([inputs["rna_F"][0]]).flatten()
        outputs["Fy"] = np.array([inputs["rna_F"][1]]).flatten()
        outputs["Fz"] = np.array([inputs["rna_F"][2]]).flatten()
        outputs["Mxx"] = np.array([inputs["rna_M"][0]]).flatten()
        outputs["Myy"] = np.array([inputs["rna_M"][1]]).flatten()
        outputs["Mzz"] = np.array([inputs["rna_M"][2]]).flatten()

        # Prepare for reactions: rigid at tower base
        if self.options["monopile"] and not self.options["gravity_foundation"]:
            if self.options["soil_springs"]:
                z_soil = inputs["z_soil"]
                k_soil = inputs["k_soil"]
                z_pile = z[z <= (z[0] + 1e-1 + np.abs(z_soil[0]))]
                if z_pile.size != 4:
                    print(z)
                    print(z_soil)
                    print(z_pile)
                    raise ValueError("Please use only one section for submerged pile for now")
                k_mono = np.zeros((z_pile.size, 6))
                for k in range(6):
                    k_mono[:, k] = np.interp(z_pile + np.abs(z_soil[0]), z_soil, k_soil[:, k])
                outputs["kidx"] = np.arange(len(z_pile), dtype=np.int_)
                outputs["kx"] = np.array([k_mono[:, 0]])
                outputs["ky"] = np.array([k_mono[:, 2]])
                outputs["kz"] = np.zeros(k_mono.shape[0])
                outputs["kz"][0] = np.array([k_mono[0, 4]])
                outputs["ktx"] = np.array([k_mono[:, 1]])
                outputs["kty"] = np.array([k_mono[:, 3]])
                outputs["ktz"] = np.array([k_mono[:, 5]])

            else:
                z_pile = z[z <= (z[0] + 1e-1 + inputs["suctionpile_depth"])]
                npile = z_pile.size
                if npile != 4:
                    print(z)
                    print(z_pile)
                    print(inputs["suctionpile_depth"])
                    raise ValueError("Please use only one section for submerged pile for now")
                outputs["kidx"] = np.arange(npile, dtype=np.int_)
                outputs["kx"] = outputs["ky"] = outputs["kz"] = RIGID * np.ones(npile)
                outputs["ktx"] = outputs["kty"] = outputs["ktz"] = RIGID * np.ones(npile)

        else:
            outputs["kidx"] = np.array([0], dtype=np.int_)
            outputs["kx"] = outputs["ky"] = outputs["kz"] = np.array([RIGID])
            outputs["ktx"] = outputs["kty"] = outputs["ktz"] = np.array([RIGID])
Example #5
0
    def setup(self):
        mod_opt = self.options["modeling_options"]["WISDEM"]["TowerSE"]

        n_height_tow = mod_opt["n_height_tower"]
        n_layers_tow = mod_opt["n_layers_tower"]
        n_height_mon = mod_opt["n_height_monopile"]
        n_layers_mon = mod_opt["n_layers_monopile"]
        if "n_height" in mod_opt:
            n_height = mod_opt["n_height"]
        else:
            n_height = mod_opt[
                "n_height"] = n_height_tow if n_height_mon == 0 else n_height_tow + n_height_mon - 1
        nFull = get_nfull(n_height)

        self.set_input_defaults("gravity_foundation_mass", 0.0, units="kg")
        self.set_input_defaults("transition_piece_mass", 0.0, units="kg")
        self.set_input_defaults("tower_outer_diameter",
                                np.ones(n_height),
                                units="m")
        self.set_input_defaults("tower_wall_thickness",
                                np.ones(n_height),
                                units="m")
        self.set_input_defaults("outfitting_factor", np.zeros(n_height - 1))
        self.set_input_defaults("water_depth", 0.0, units="m")
        self.set_input_defaults("hub_height", 0.0, units="m")
        self.set_input_defaults("rho", np.zeros(n_height - 1), units="kg/m**3")
        self.set_input_defaults("unit_cost",
                                np.zeros(n_height - 1),
                                units="USD/kg")
        self.set_input_defaults("labor_cost_rate", 0.0, units="USD/min")
        self.set_input_defaults("painting_cost_rate", 0.0, units="USD/m**2")

        # Inputs here are the outputs from the Tower component in load_IEA_yaml
        # TODO: Use reference axis and curvature, s, instead of assuming everything is vertical on z
        self.add_subsystem(
            "yaml",
            tp.DiscretizationYAML(
                n_height_tower=n_height_tow,
                n_height_monopile=n_height_mon,
                n_layers_tower=n_layers_tow,
                n_layers_monopile=n_layers_mon,
                n_mat=self.options["modeling_options"]["materials"]["n_mat"],
            ),
            promotes=["*"],
        )

        # Promote all but foundation_height so that we can override
        self.add_subsystem(
            "geometry",
            tp.CylinderDiscretization(nPoints=n_height),
            promotes=[
                "z_param",
                "z_full",
                "d_full",
                "t_full",
                ("section_height", "tower_section_height"),
                ("diameter", "tower_outer_diameter"),
                ("wall_thickness", "tower_wall_thickness"),
            ],
        )

        self.add_subsystem("props",
                           CylindricalShellProperties(nFull=nFull),
                           promotes=["Az", "Asx", "Asy", "Ixx", "Iyy", "Jz"])
        self.add_subsystem("tgeometry",
                           tp.TowerDiscretization(n_height=n_height),
                           promotes=["*"])

        self.add_subsystem(
            "cm",
            tp.CylinderMass(nPoints=nFull),
            promotes=[
                "z_full", "d_full", "t_full", "labor_cost_rate",
                "painting_cost_rate"
            ],
        )
        self.add_subsystem(
            "tm",
            tp.TowerMass(n_height=n_height),
            promotes=[
                "z_full",
                "d_full",
                "tower_mass",
                "tower_center_of_mass",
                "tower_section_center_of_mass",
                "tower_I_base",
                "tower_cost",
                "gravity_foundation_mass",
                "gravity_foundation_I",
                "transition_piece_mass",
                "transition_piece_cost",
                "transition_piece_height",
                "transition_piece_I",
                "monopile_mass",
                "monopile_cost",
                "structural_mass",
                "structural_cost",
            ],
        )
        self.add_subsystem(
            "gc",
            util_con.GeometricConstraints(nPoints=n_height),
            promotes=[
                "constr_taper",
                "constr_d_to_t",
                "slope",
                ("d", "tower_outer_diameter"),
                ("t", "tower_wall_thickness"),
            ],
        )

        self.add_subsystem(
            "turb",
            tp.TurbineMass(),
            promotes=[
                "turbine_mass",
                "monopile_mass",
                "tower_mass",
                "tower_center_of_mass",
                "tower_I_base",
                "rna_mass",
                "rna_cg",
                "rna_I",
                "hub_height",
            ],
        )

        # Connections for geometry and mass
        self.connect("z_start", "geometry.foundation_height")
        self.connect("d_full", "props.d")
        self.connect("t_full", "props.t")
        self.connect("rho_full", "cm.rho")
        self.connect("outfitting_full", "cm.outfitting_factor")
        self.connect("unit_cost_full", "cm.material_cost_rate")
        self.connect("cm.mass", "tm.cylinder_mass")
        self.connect("cm.cost", "tm.cylinder_cost")
        self.connect("cm.center_of_mass", "tm.cylinder_center_of_mass")
        self.connect("cm.section_center_of_mass",
                     "tm.cylinder_section_center_of_mass")
        self.connect("cm.I_base", "tm.cylinder_I_base")
Example #6
0
    def setup(self):
        mod_opt = self.options["modeling_options"]["WISDEM"]["TowerSE"]
        monopile = self.options["modeling_options"]["flags"]["monopile"]
        nLC = mod_opt["nLC"]  # not yet supported
        wind = mod_opt["wind"]  # not yet supported
        frame3dd_opt = mod_opt["frame3dd"]
        if "n_height" in mod_opt:
            n_height = mod_opt["n_height"]
        else:
            n_height_tow = mod_opt["n_height_tower"]
            n_height_mon = mod_opt["n_height_monopile"]
            n_height = mod_opt[
                "n_height"] = n_height_tow if n_height_mon == 0 else n_height_tow + n_height_mon - 1
        nFull = get_nfull(n_height)
        self.set_input_defaults("E", np.zeros(n_height - 1), units="N/m**2")
        self.set_input_defaults("G", np.zeros(n_height - 1), units="N/m**2")
        if monopile and mod_opt["soil_springs"]:
            self.set_input_defaults("G_soil", 0.0, units="N/m**2")
            self.set_input_defaults("nu_soil", 0.0)
        self.set_input_defaults("sigma_y",
                                np.zeros(n_height - 1),
                                units="N/m**2")
        self.set_input_defaults("rna_mass", 0.0, units="kg")
        self.set_input_defaults("rna_cg", np.zeros(3), units="m")
        self.set_input_defaults("rna_I", np.zeros(6), units="kg*m**2")
        self.set_input_defaults("life", 0.0)

        # Load baseline discretization
        self.add_subsystem(
            "geom",
            TowerLeanSE(modeling_options=self.options["modeling_options"]),
            promotes=["*"])

        if monopile and mod_opt["soil_springs"]:
            self.add_subsystem(
                "soil",
                TowerSoil(npts=NPTS_SOIL),
                promotes=[("G", "G_soil"), ("nu", "nu_soil"),
                          ("depth", "suctionpile_depth")],
            )
            self.connect("d_full", "soil.d0", src_indices=[0])

        # Add in all Components that drive load cases
        # Note multiple load cases have to be handled by replicating components and not groups/assemblies.
        # Replicating Groups replicates the IndepVarComps which doesn't play nicely in OpenMDAO
        prom = [("zref", "wind_reference_height"), "shearExp", "z0", "cd_usr",
                "yaw", "beta_wind", "rho_air", "mu_air"]
        if monopile:
            prom += [
                "beta_wave",
                "rho_water",
                "mu_water",
                "cm",
                "Uc",
                "Hsig_wave",
                "Tsig_wave",
                "water_depth",
            ]

        for iLC in range(nLC):
            lc = "" if nLC == 1 else str(iLC + 1)

            self.add_subsystem("wind" + lc,
                               CylinderEnvironment(nPoints=nFull,
                                                   water_flag=monopile,
                                                   wind=wind),
                               promotes=prom)

            self.add_subsystem(
                "pre" + lc,
                ts.TowerPreFrame(
                    n_height=n_height,
                    monopile=monopile,
                    soil_springs=mod_opt["soil_springs"],
                    gravity_foundation=mod_opt["gravity_foundation"],
                ),
                promotes=[
                    "transition_piece_mass",
                    "transition_piece_height",
                    "transition_piece_I",
                    "gravity_foundation_mass",
                    "gravity_foundation_I",
                    "z_full",
                    "suctionpile_depth",
                    ("mass", "rna_mass"),
                    ("mrho", "rna_cg"),
                    ("mI", "rna_I"),
                ],
            )
            self.add_subsystem(
                "tower" + lc,
                ts.CylinderFrame3DD(
                    nFull=nFull,
                    nK=4
                    if monopile and not mod_opt["gravity_foundation"] else 1,
                    nMass=3,
                    nPL=1,
                    frame3dd_opt=frame3dd_opt,
                ),
                promotes=["Az", "Asx", "Asy", "Ixx", "Iyy", "Jz"],
            )
            self.add_subsystem(
                "post" + lc,
                ts.TowerPostFrame(modeling_options=mod_opt),
                promotes=[
                    "life",
                    "z_full",
                    "d_full",
                    "t_full",
                    "rho_full",
                    "E_full",
                    "G_full",
                    "sigma_y_full",
                    "suctionpile_depth",
                    "Az",
                    "Asx",
                    "Asy",
                    "Ixx",
                    "Iyy",
                    "Jz",
                ],
            )

            self.connect("z_full", ["wind" + lc + ".z", "tower" + lc + ".z"])
            self.connect("d_full", ["wind" + lc + ".d", "tower" + lc + ".d"])
            self.connect("t_full", "tower" + lc + ".t")

            self.connect("rho_full", "tower" + lc + ".rho")
            self.connect("E_full", "tower" + lc + ".E")
            self.connect("G_full", "tower" + lc + ".G")

            self.connect("pre" + lc + ".kidx", "tower" + lc + ".kidx")
            self.connect("pre" + lc + ".kx", "tower" + lc + ".kx")
            self.connect("pre" + lc + ".ky", "tower" + lc + ".ky")
            self.connect("pre" + lc + ".kz", "tower" + lc + ".kz")
            self.connect("pre" + lc + ".ktx", "tower" + lc + ".ktx")
            self.connect("pre" + lc + ".kty", "tower" + lc + ".kty")
            self.connect("pre" + lc + ".ktz", "tower" + lc + ".ktz")
            self.connect("pre" + lc + ".midx", "tower" + lc + ".midx")
            self.connect("pre" + lc + ".m", "tower" + lc + ".m")
            self.connect("pre" + lc + ".mIxx", "tower" + lc + ".mIxx")
            self.connect("pre" + lc + ".mIyy", "tower" + lc + ".mIyy")
            self.connect("pre" + lc + ".mIzz", "tower" + lc + ".mIzz")
            self.connect("pre" + lc + ".mIxy", "tower" + lc + ".mIxy")
            self.connect("pre" + lc + ".mIxz", "tower" + lc + ".mIxz")
            self.connect("pre" + lc + ".mIyz", "tower" + lc + ".mIyz")
            self.connect("pre" + lc + ".mrhox", "tower" + lc + ".mrhox")
            self.connect("pre" + lc + ".mrhoy", "tower" + lc + ".mrhoy")
            self.connect("pre" + lc + ".mrhoz", "tower" + lc + ".mrhoz")

            self.connect("pre" + lc + ".plidx", "tower" + lc + ".plidx")
            self.connect("pre" + lc + ".Fx", "tower" + lc + ".Fx")
            self.connect("pre" + lc + ".Fy", "tower" + lc + ".Fy")
            self.connect("pre" + lc + ".Fz", "tower" + lc + ".Fz")
            self.connect("pre" + lc + ".Mxx", "tower" + lc + ".Mxx")
            self.connect("pre" + lc + ".Myy", "tower" + lc + ".Myy")
            self.connect("pre" + lc + ".Mzz", "tower" + lc + ".Mzz")
            if monopile and mod_opt["soil_springs"]:
                self.connect("soil.z_k", "pre" + lc + ".z_soil")
                self.connect("soil.k", "pre" + lc + ".k_soil")

            self.connect("wind" + lc + ".Px", "tower" + lc + ".Px")
            self.connect("wind" + lc + ".Py", "tower" + lc + ".Py")
            self.connect("wind" + lc + ".Pz", "tower" + lc + ".Pz")

            self.connect("wind" + lc + ".qdyn", "post" + lc + ".qdyn")

            self.connect("tower" + lc + ".tower_Fz", "post" + lc + ".tower_Fz")
            self.connect("tower" + lc + ".tower_Vx", "post" + lc + ".tower_Vx")
            self.connect("tower" + lc + ".tower_Vy", "post" + lc + ".tower_Vy")
            self.connect("tower" + lc + ".tower_Mxx",
                         "post" + lc + ".tower_Mxx")
            self.connect("tower" + lc + ".tower_Myy",
                         "post" + lc + ".tower_Myy")
            self.connect("tower" + lc + ".tower_Mzz",
                         "post" + lc + ".tower_Mzz")
Example #7
0
    def setup(self):
        n_height = self.options["n_height"]
        nFull = get_nfull(n_height)

        self.add_input("hub_height", val=0.0, units="m")
        self.add_input("z_param", np.zeros(n_height), units="m")
        self.add_input("z_full", val=np.zeros(nFull), units="m")
        self.add_input("rho", val=np.zeros(n_height - 1), units="kg/m**3")
        self.add_input("unit_cost", val=np.zeros(n_height - 1), units="USD/kg")
        self.add_input("outfitting_factor", val=np.zeros(n_height - 1))
        self.add_input("E", val=np.zeros(n_height - 1), units="Pa")
        self.add_input("G", val=np.zeros(n_height - 1), units="Pa")
        self.add_input("sigma_y", val=np.zeros(n_height - 1), units="Pa")

        self.add_input("Az", np.zeros(nFull - 1), units="m**2")
        self.add_input("Jz", np.zeros(nFull - 1), units="m**4")
        self.add_input("Ixx", np.zeros(nFull - 1), units="m**4")
        self.add_input("Iyy", np.zeros(nFull - 1), units="m**4")

        self.add_output("height_constraint", val=0.0, units="m")
        self.add_output("rho_full", val=np.zeros(nFull - 1), units="kg/m**3")
        self.add_output("unit_cost_full", val=np.zeros(nFull - 1), units="USD/kg")
        self.add_output("outfitting_full", val=np.zeros(nFull - 1))
        self.add_output("E_full", val=np.zeros(nFull - 1), units="Pa")
        self.add_output("G_full", val=np.zeros(nFull - 1), units="Pa")
        self.add_output("sigma_y_full", val=np.zeros(nFull - 1), units="Pa")

        # Tower Distributed Beam Properties (properties needed for ElastoDyn (OpenFAST) inputs or BModes inputs for verification purposes)
        self.add_output("sec_loc", np.zeros(n_height - 1), desc="normalized sectional location")
        self.add_output("str_tw", np.zeros(n_height - 1), units="deg", desc="structural twist of section")
        self.add_output("tw_iner", np.zeros(n_height - 1), units="deg", desc="inertial twist of section")
        self.add_output("mass_den", np.zeros(n_height - 1), units="kg/m", desc="sectional mass per unit length")
        self.add_output(
            "foreaft_iner",
            np.zeros(n_height - 1),
            units="kg*m",
            desc="sectional fore-aft intertia per unit length about the Y_G inertia axis",
        )
        self.add_output(
            "sideside_iner",
            np.zeros(n_height - 1),
            units="kg*m",
            desc="sectional side-side intertia per unit length about the Y_G inertia axis",
        )
        self.add_output(
            "foreaft_stff",
            np.zeros(n_height - 1),
            units="N*m**2",
            desc="sectional fore-aft bending stiffness per unit length about the Y_E elastic axis",
        )
        self.add_output(
            "sideside_stff",
            np.zeros(n_height - 1),
            units="N*m**2",
            desc="sectional side-side bending stiffness per unit length about the Y_E elastic axis",
        )
        self.add_output("tor_stff", np.zeros(n_height - 1), units="N*m**2", desc="sectional torsional stiffness")
        self.add_output("axial_stff", np.zeros(n_height - 1), units="N", desc="sectional axial stiffness")
        self.add_output("cg_offst", np.zeros(n_height - 1), units="m", desc="offset from the sectional center of mass")
        self.add_output("sc_offst", np.zeros(n_height - 1), units="m", desc="offset from the sectional shear center")
        self.add_output("tc_offst", np.zeros(n_height - 1), units="m", desc="offset from the sectional tension center")

        self.declare_partials("height_constraint", ["hub_height", "z_param"], method="fd")
        self.declare_partials("outfitting_full", ["outfitting_factor"], method="fd")
        self.declare_partials("rho_full", ["rho"], method="fd")
        self.declare_partials("unit_cost_full", ["unit_cost"], method="fd")