from __future__ import print_function

import numpy as np
from openmdao.api import IndepVarComp, Component, Group, Problem, ExecComp, ScipyOptimizer

class TubeAndPylon(Component):
    """
    Notes
    -----
    Estimates tube tunnel cost and pylon material cost
    Optimizes tunnel thickness, pylon radius, and pylon spacing

    Many parameters are currently taken from hyperloop alpha, will eventually pull from mission trajectory

    Params
    ------
    tube_area : float
        Inner tube radius. Default is 3.8013 m**2
    rho_tube : float
        Density of tube material. Default is 7820 kg/m**3
    E_tube : float
        Young's modulus of tube material. Default value is 200e9 Pa
    v_tube : float
        Poisson's ratio of tube material.  Default value is .3
    Su_tube : float
        Ultimate strength of tube material. Default value is 152e6 Pa
    sf : float
        Tube safety factor. Default value is 1.5
    g : float
        Gravitational acceleration. Default value is 9.81 m/s**2
    unit_cost_tube : float
        Cost of tube material per unit mass. Default value is .33 USD/kg
    p_tunnel : float
        Pressure of air in tube.  Default value is 850 Pa.  Value will come from vacuum component
    p_ambient : float
        Pressure of atmosphere. Default value is 101.3e3 Pa.
    alpha_tube : float
        Coefficient of thermal expansion of tube material. Default value is 0.0
    dT_tube : float
        Difference in tunnel temperature as compared ot a reference temperature. Default value is 0.0
    m_pod : float
        total mass of pod. Default value is 3100 kg. Value will come from weight component
    r : float
        Radius of tube. Default value is 1.1 m. Value will come from aero module
    t : float
        Thickness of the tube. Default value is 50 mm. Value is optimized in problem driver.
    rho_pylon : float
        Density of pylon material. Default value is 2400 kg/m**3
    E_pylon : float
        Young's modulus of pylon material. Default value is 41e9 Pa
    v_pylon : float
        Poisson's ratio of pylon material. Default value is .2
    Su_pylon : float
        Ultimate strength of pylon material. Default value is 40e6 Pa
    unit_cost_pylon : float
        Cost of pylon material per unit mass. Default value is .05 USD/kg
    h : float
        Height of each pylon. Default value is 10 m.
    r_pylon : float
        Radius of each pylon. Default value is 1 m. Value will be optimized in problem driver
    vac_weight : float
        Total weight of vacuums. Default value is 1500.0 kg. Value will come from vacuum component

    Returns
    -------
    m_pylon : float
        mass of individual pylon in kg/pylon
    m_prime: float
        Calculates mass per unit length of tube in kg/m
    von_mises : float
        Von Mises stress in the tube in Pa
    total_material_cost : float
        returns total cost of tube and pylon materials per unit distance in USD/m
    R : float
        Returns vertical component of force on each pylon in N
    delta : float
        Maximum deflection of tube between pylons in m
    dx : float
        outputs distance in between pylons in m
    t_crit :
        Minimum tube thickness to satisfy vacuum tube buckling condition in m

    Notes
    -----
    [1] USA. NASA. Buckling of Thin-Walled Circular Cylinders. N.p.: n.p., n.d. Web. 13 June 2016.
    """
    def __init__(self):
        super(TubeAndPylon, self).__init__()
        #Define material properties of tube
        self.add_param('rho_tube',
                       val=7820.0,
                       units='kg/m**3',
                       desc='density of steel')
        self.add_param('E_tube',
                       val=200.0 * (10**9),
                       units='Pa',
                       desc='Young\'s Modulus of tube')
        self.add_param('v_tube', val=.3, desc='Poisson\'s ratio of tube')
        self.add_param('Su_tube',
                       val=152.0e6,
                       units='Pa',
                       desc='ultimate strength of tube')
        self.add_param('sf', val=1.5, desc='safety factor')
        self.add_param('g', val=9.81, units='m/s**2', desc='gravity')
        self.add_param('unit_cost_tube',
                       val=.3307,
                       units='USD/kg',
                       desc='cost of tube materials per unit mass')
        self.add_param('p_tunnel',
                       val=100.0,
                       units='Pa',
                       desc='Tunnel Pressure')
        self.add_param('p_ambient',
                       val=101300.0,
                       units='Pa',
                       desc='Ambient Pressure')
        self.add_param('alpha_tube',
                       val=0.0,
                       desc='Coefficient of Thermal Expansion of tube')
        self.add_param(
            'dT_tube', val=0.0,
            units='K', desc='Temperature change')
        self.add_param('m_pod', val=3100.0, units='kg', desc='mass of pod')

        self.add_param('tube_area', val=3.8013, units='m**2', desc='inner tube area')
        #self.add_param('r', val=1.1, units='m', desc='inner tube radius')
        self.add_param('t', val=.05, units='m', desc='tube thickness')
        #self.add_param('dx', val = 500.0, units = 'm', desc = 'distance between pylons')

        #Define pylon material properties
        self.add_param('rho_pylon',