def generate_multibody_file():
    LC2 = gc.LagrangeConstraint()
    LC2.behaviour = 'hinge_FoR'
    LC2.rot_axis_AFoR = np.array([1.0, 0.0, 0.0])
    LC2.body_FoR = 0
    # LC2.node_number = int(0)

    LC = []
    LC.append(LC2)

    MB1 = gc.BodyInformation()
    MB1.body_number = 0
    MB1.FoR_position = np.zeros((6, ))
    MB1.FoR_velocity = np.zeros((6, ))
    MB1.FoR_acceleration = np.zeros((6, ))
    MB1.FoR_movement = 'free'
    MB1.quat = np.array([1.0, 0.0, 0.0, 0.0])

    MB = []
    MB.append(MB1)
    gc.clean_test_files(route, case_name)
    gc.generate_multibody_file(LC, MB, route, case_name)
Пример #2
0
    'BeamPlot', 'AerogridPlot', 'WriteVariablesTime', 'Cleanup'
]
SimInfo.solvers['DynamicCoupled']['postprocessors_settings'] = {
    'BeamPlot': SimInfo.solvers['BeamPlot'],
    'AerogridPlot': SimInfo.solvers['AerogridPlot'],
    'WriteVariablesTime': SimInfo.solvers['WriteVariablesTime'],
    'Cleanup': SimInfo.solvers['Cleanup']
}
SimInfo.solvers['DynamicCoupled']['minimum_steps'] = 0

SimInfo.define_num_steps(time_steps)

# Define dynamic simulation
SimInfo.with_forced_vel = True
SimInfo.for_vel = np.zeros((time_steps, 6), dtype=float)
SimInfo.for_vel[:, 5] = rotation_velocity
SimInfo.for_acc = np.zeros((time_steps, 6), dtype=float)
SimInfo.with_dynamic_forces = True
SimInfo.dynamic_forces = np.zeros(
    (time_steps, rotor.StructuralInformation.num_node, 6), dtype=float)

######################################################################
#######################  GENERATE FILES  #############################
######################################################################
gc.clean_test_files(SimInfo.solvers['SHARPy']['route'],
                    SimInfo.solvers['SHARPy']['case'])
rotor.generate_h5_files(SimInfo.solvers['SHARPy']['route'],
                        SimInfo.solvers['SHARPy']['case'])
SimInfo.generate_solver_file()
SimInfo.generate_dyn_file(time_steps)
Пример #3
0
    def setUp(self):
        # remove_terminal_output = True
        ######################################################################
        ###########################  PARAMETERS  #############################
        ######################################################################
        # Case
        global case
        case = 'rotor'
        route = os.path.abspath(os.path.dirname(
            os.path.realpath(__file__))) + '/'

        # Geometry discretization
        chord_panels = np.array([4], dtype=int)
        revs_in_wake = 5

        # Operation
        rotation_velocity = 1.366190
        pitch_deg = 0.  #degrees

        # Wind
        WSP = 11.4
        air_density = 1.225

        # Simulation
        dphi = 4. * deg2rad
        revs_to_simulate = 5

        ######################################################################
        ##########################  GENERATE WT  #############################
        ######################################################################
        dt = dphi / rotation_velocity
        time_steps = int(revs_to_simulate * 2. * np.pi / dphi)
        time_steps = 1  # For the test cases
        mstar = int(revs_in_wake * 2. * np.pi / dphi)
        mstar = 2  # For the test cases

        # Remove screen output
        # if remove_terminal_output:
        #     sys.stdout = open(os.devnull, "w")

        op_params = {
            'rotation_velocity': rotation_velocity,
            'pitch_deg': pitch_deg,
            'wsp': WSP,
            'dt': dt
        }

        geom_params = {
            'chord_panels': chord_panels,
            'tol_remove_points': 1e-8,
            'n_points_camber': 100,
            'm_distribution': 'uniform'
        }

        excel_description = {
            'excel_file_name': route +
            '../../docs/source/content/example_notebooks/source/type02_db_NREL5MW_v01.xlsx',
            'excel_sheet_parameters': 'parameters',
            'excel_sheet_structural_blade': 'structural_blade',
            'excel_sheet_discretization_blade': 'discretization_blade',
            'excel_sheet_aero_blade': 'aero_blade',
            'excel_sheet_airfoil_info': 'airfoil_info',
            'excel_sheet_airfoil_chord': 'airfoil_coord'
        }

        options = {
            'camber_effect_on_twist': False,
            'user_defined_m_distribution_type': None,
            'include_polars': False
        }

        rotor = template_wt.rotor_from_excel_type03(op_params, geom_params,
                                                    excel_description, options)

        # Return the standard output to the terminal
        # if remove_terminal_output:
        #     sys.stdout.close()
        #     sys.stdout = sys.__stdout__

        ######################################################################
        ######################  DEFINE SIMULATION  ###########################
        ######################################################################
        SimInfo = gc.SimulationInformation()
        SimInfo.set_default_values()

        SimInfo.solvers['SHARPy']['flow'] = [
            'BeamLoader', 'AerogridLoader', 'StaticCoupledRBM',
            'DynamicCoupled', 'SaveData'
        ]

        SimInfo.solvers['SHARPy']['case'] = case
        SimInfo.solvers['SHARPy']['write_screen'] = 'off'
        SimInfo.solvers['SHARPy']['route'] = route
        SimInfo.solvers['SHARPy']['write_log'] = True
        SimInfo.solvers['SHARPy']['log_folder'] = os.path.abspath(
            os.path.dirname(os.path.realpath(__file__))) + '/'
        SimInfo.set_variable_all_dicts('dt', dt)
        SimInfo.set_variable_all_dicts('rho', air_density)

        SimInfo.solvers['SteadyVelocityField']['u_inf'] = WSP
        SimInfo.solvers['SteadyVelocityField']['u_inf_direction'] = np.array(
            [0., 0., 1.])
        SimInfo.set_variable_all_dicts('velocity_field_input',
                                       SimInfo.solvers['SteadyVelocityField'])
        SimInfo.set_variable_all_dicts(
            'output',
            os.path.abspath(os.path.dirname(os.path.realpath(__file__))))

        SimInfo.solvers['BeamLoader']['unsteady'] = 'on'

        SimInfo.solvers['AerogridLoader']['unsteady'] = 'on'
        SimInfo.solvers['AerogridLoader']['mstar'] = mstar
        SimInfo.solvers['AerogridLoader']['freestream_dir'] = np.array(
            [0., 0., 0.])
        SimInfo.solvers['AerogridLoader'][
            'wake_shape_generator'] = 'HelicoidalWake'
        SimInfo.solvers['AerogridLoader']['wake_shape_generator_input'] = {
            'u_inf': WSP,
            'u_inf_direction': np.array([0., 0., 1.]),
            'dt': dt,
            'rotation_velocity': rotation_velocity * np.array([0., 0., 1.])
        }

        SimInfo.solvers['StaticCoupledRBM'][
            'structural_solver'] = 'RigidDynamicPrescribedStep'
        SimInfo.solvers['StaticCoupledRBM'][
            'structural_solver_settings'] = SimInfo.solvers[
                'RigidDynamicPrescribedStep']
        # SimInfo.solvers['StaticCoupledRBM']['structural_solver'] = 'NonLinearDynamicPrescribedStep'
        # SimInfo.solvers['StaticCoupledRBM']['structural_solver_settings'] = SimInfo.solvers['NonLinearDynamicPrescribedStep']
        SimInfo.solvers['StaticCoupledRBM']['aero_solver'] = 'SHWUvlm'
        SimInfo.solvers['StaticCoupledRBM'][
            'aero_solver_settings'] = SimInfo.solvers['SHWUvlm']

        SimInfo.solvers['StaticCoupledRBM']['tolerance'] = 1e-6
        SimInfo.solvers['StaticCoupledRBM']['n_load_steps'] = 0
        SimInfo.solvers['StaticCoupledRBM']['relaxation_factor'] = 0.

        SimInfo.solvers['SHWUvlm']['convection_scheme'] = 2
        SimInfo.solvers['SHWUvlm']['rot_vel'] = rotation_velocity
        SimInfo.solvers['SHWUvlm']['rot_axis'] = np.array([0., 0., 1.])
        SimInfo.solvers['SHWUvlm']['rot_center'] = np.zeros((3), )

        SimInfo.solvers['StepUvlm']['convection_scheme'] = 2
        SimInfo.solvers['StepUvlm']['num_cores'] = 1
        SimInfo.solvers['StepUvlm']['cfl1'] = False

        # SimInfo.solvers['DynamicCoupled']['structural_solver'] = 'NonLinearDynamicMultibody'
        # SimInfo.solvers['DynamicCoupled']['structural_solver_settings'] = SimInfo.solvers['NonLinearDynamicMultibody']
        SimInfo.solvers['DynamicCoupled'][
            'structural_solver'] = 'RigidDynamicPrescribedStep'
        SimInfo.solvers['DynamicCoupled'][
            'structural_solver_settings'] = SimInfo.solvers[
                'RigidDynamicPrescribedStep']
        SimInfo.solvers['DynamicCoupled']['aero_solver'] = 'StepUvlm'
        SimInfo.solvers['DynamicCoupled'][
            'aero_solver_settings'] = SimInfo.solvers['StepUvlm']
        SimInfo.solvers['DynamicCoupled']['postprocessors'] = [
            'BeamPlot', 'AerogridPlot', 'Cleanup', 'SaveData'
        ]
        SimInfo.solvers['DynamicCoupled']['postprocessors_settings'] = {
            'BeamPlot': SimInfo.solvers['BeamPlot'],
            'AerogridPlot': SimInfo.solvers['AerogridPlot'],
            'Cleanup': SimInfo.solvers['Cleanup'],
            'SaveData': SimInfo.solvers['SaveData']
        }
        SimInfo.solvers['DynamicCoupled']['minimum_steps'] = 0
        SimInfo.solvers['DynamicCoupled'][
            'include_unsteady_force_contribution'] = True
        SimInfo.solvers['DynamicCoupled']['relaxation_factor'] = 0.
        SimInfo.solvers['DynamicCoupled']['final_relaxation_factor'] = 0.
        SimInfo.solvers['DynamicCoupled']['dynamic_relaxation'] = False
        SimInfo.solvers['DynamicCoupled']['relaxation_steps'] = 0

        SimInfo.solvers['DynamicCoupled']['postprocessors_settings'][
            'BeamPlot']['folder'] = os.path.abspath(
                os.path.dirname(os.path.realpath(__file__))) + '/output/'
        SimInfo.solvers['DynamicCoupled']['postprocessors_settings'][
            'AerogridPlot']['folder'] = os.path.abspath(
                os.path.dirname(os.path.realpath(__file__))) + '/output/'
        SimInfo.solvers['DynamicCoupled']['postprocessors_settings'][
            'SaveData']['folder'] = os.path.abspath(
                os.path.dirname(os.path.realpath(__file__))) + '/output/'
        SimInfo.define_num_steps(time_steps)

        # Define dynamic simulation
        SimInfo.with_forced_vel = True
        SimInfo.for_vel = np.zeros((time_steps, 6), dtype=float)
        SimInfo.for_vel[:, 5] = rotation_velocity
        SimInfo.for_acc = np.zeros((time_steps, 6), dtype=float)
        SimInfo.with_dynamic_forces = True
        SimInfo.dynamic_forces = np.zeros(
            (time_steps, rotor.StructuralInformation.num_node, 6), dtype=float)

        ######################################################################
        #######################  GENERATE FILES  #############################
        ######################################################################
        gc.clean_test_files(SimInfo.solvers['SHARPy']['route'],
                            SimInfo.solvers['SHARPy']['case'])
        rotor.generate_h5_files(SimInfo.solvers['SHARPy']['route'],
                                SimInfo.solvers['SHARPy']['case'])
        SimInfo.generate_solver_file()
        SimInfo.generate_dyn_file(time_steps)
Пример #4
0
    def setUp(self):
        import sharpy.utils.generate_cases as gc
        import cases.templates.template_wt as template_wt
        from sharpy.utils.constants import deg2rad

        ######################################################################
        ###########################  PARAMETERS  #############################
        ######################################################################
        # Case
        global case
        route = folder + '/'
        case = 'rotor'

        # Geometry discretization
        chord_panels = np.array([8], dtype=int)
        revs_in_wake = 1

        # Operation
        rotation_velocity = 1.366190
        pitch_deg = 0.  #degrees

        # Wind
        WSP = 11.4
        air_density = 1.225

        # Simulation
        dphi = 4. * deg2rad
        revs_to_simulate = 5

        ######################################################################
        ##########################  GENERATE WT  #############################
        ######################################################################
        dt = dphi / rotation_velocity
        # time_steps = int(revs_to_simulate*2.*np.pi/dphi)
        time_steps = 2  # For the test cases

        mstar = int(revs_in_wake * 2. * np.pi / dphi)

        op_params = {
            'rotation_velocity': rotation_velocity,
            'pitch_deg': pitch_deg,
            'wsp': WSP,
            'dt': dt
        }

        geom_params = {
            'chord_panels': chord_panels,
            'tol_remove_points': 1e-8,
            'n_points_camber': 100,
            'm_distribution': 'uniform'
        }

        excel_description = {
            'excel_file_name': route +
            '../../../../docs/source/content/example_notebooks/source/type02_db_NREL5MW_v01.xlsx',
            'excel_sheet_parameters': 'parameters',
            'excel_sheet_structural_blade': 'structural_blade',
            'excel_sheet_discretization_blade': 'discretization_blade',
            'excel_sheet_aero_blade': 'aero_blade',
            'excel_sheet_airfoil_info': 'airfoil_info',
            'excel_sheet_airfoil_chord': 'airfoil_coord'
        }

        options = {
            'camber_effect_on_twist': False,
            'user_defined_m_distribution_type': None,
            'include_polars': False
        }

        rotor = template_wt.rotor_from_excel_type03(op_params, geom_params,
                                                    excel_description, options)

        ######################################################################
        ######################  DEFINE SIMULATION  ###########################
        ######################################################################
        SimInfo = gc.SimulationInformation()
        SimInfo.set_default_values()

        SimInfo.solvers['SHARPy']['flow'] = ['BeamLoader', 'Modal']
        SimInfo.solvers['SHARPy']['case'] = case
        SimInfo.solvers['SHARPy']['route'] = route
        SimInfo.solvers['SHARPy']['write_log'] = True
        SimInfo.solvers['SHARPy']['write_screen'] = 'off'
        SimInfo.solvers['SHARPy']['log_folder'] = os.path.abspath(
            os.path.dirname(os.path.realpath(__file__))) + '/'
        SimInfo.set_variable_all_dicts('dt', dt)
        SimInfo.set_variable_all_dicts('rho', air_density)

        SimInfo.solvers['BeamLoader']['unsteady'] = 'on'

        SimInfo.solvers['Modal']['write_modes_vtk'] = False
        SimInfo.solvers['Modal']['write_dat'] = True
        SimInfo.solvers['Modal']['folder'] = folder + '/output/'

        ######################################################################
        #######################  GENERATE FILES  #############################
        ######################################################################
        gc.clean_test_files(SimInfo.solvers['SHARPy']['route'],
                            SimInfo.solvers['SHARPy']['case'])
        rotor.generate_h5_files(SimInfo.solvers['SHARPy']['route'],
                                SimInfo.solvers['SHARPy']['case'])
        SimInfo.generate_solver_file()
Пример #5
0
    def setUp(self):

        nodes_per_elem = 3

        # beam1: uniform and symmetric with aerodynamic properties equal to zero
        nnodes1 = 11
        length1  = 10.
        mass_per_unit_length = 0.1
        mass_iner = 1e-4
        EA = 1e9
        GA = 1e9
        GJ = 1e3
        EI = 1e4

        # Create beam1
        beam1 = gc.AeroelasticInformation()
        # Structural information
        beam1.StructuralInformation.num_node = nnodes1
        beam1.StructuralInformation.num_node_elem = nodes_per_elem
        beam1.StructuralInformation.compute_basic_num_elem()
        beam1.StructuralInformation.set_to_zero(beam1.StructuralInformation.num_node_elem, beam1.StructuralInformation.num_node, beam1.StructuralInformation.num_elem)
        node_pos = np.zeros((nnodes1, 3), )
        node_pos[:, 0] = np.linspace(0.0, length1, nnodes1)
        beam1.StructuralInformation.generate_uniform_sym_beam(node_pos, mass_per_unit_length, mass_iner, EA, GA, GJ, EI, num_node_elem = 3, y_BFoR = 'y_AFoR', num_lumped_mass=2)
        beam1.StructuralInformation.boundary_conditions[0] = 1
        beam1.StructuralInformation.boundary_conditions[-1] = -1
        beam1.StructuralInformation.lumped_mass_nodes = np.array([0, nnodes1-1], dtype=int)
        beam1.StructuralInformation.lumped_mass = np.array([2., 1.])
        beam1.StructuralInformation.lumped_mass_inertia = np.zeros((2, 3, 3),)
        beam1.StructuralInformation.lumped_mass_position = np.zeros((2, 3),)

        # Aerodynamic information
        airfoil = np.zeros((1, 20, 2),)
        airfoil[0, :, 0] = np.linspace(0., 1., 20)
        beam1.AerodynamicInformation.create_one_uniform_aerodynamics(
            beam1.StructuralInformation,
            chord=1.,
            twist=0.,
            sweep=0.,
            num_chord_panels=4,
            m_distribution='uniform',
            elastic_axis=0.5,
            num_points_camber=20,
            airfoil=airfoil)

        # SOLVER CONFIGURATION
        SimInfo = gc.SimulationInformation()
        SimInfo.set_default_values()

        SimInfo.define_uinf(np.array([0.0,1.0,0.0]), 10.)

        SimInfo.solvers['SHARPy']['flow'] = ['BeamLoader',
                                             'AerogridLoader',
                                             'StaticCoupled',
                                             'DynamicCoupled']
        self.name = 'fix_node_velocity_wrtG'
        SimInfo.solvers['SHARPy']['case'] = self.name
        SimInfo.solvers['SHARPy']['write_screen'] = 'off'
        SimInfo.solvers['SHARPy']['route'] = folder + '/'
        SimInfo.set_variable_all_dicts('dt', 0.1)
        SimInfo.set_variable_all_dicts('rho', 0.0)
        SimInfo.set_variable_all_dicts('velocity_field_input', SimInfo.solvers['SteadyVelocityField'])
        SimInfo.set_variable_all_dicts('folder', folder + '/output/')

        SimInfo.solvers['BeamLoader']['unsteady'] = 'on'

        SimInfo.solvers['AerogridLoader']['unsteady'] = 'on'
        SimInfo.solvers['AerogridLoader']['mstar'] = 2
        SimInfo.solvers['AerogridLoader']['wake_shape_generator'] = 'StraightWake'
        SimInfo.solvers['AerogridLoader']['wake_shape_generator_input'] = {'u_inf':10.,
                                                                           'u_inf_direction': np.array([0., 1., 0.]),
                                                                           'dt': 0.1}


        SimInfo.solvers['NonLinearStatic']['print_info'] = False

        SimInfo.solvers['StaticCoupled']['structural_solver'] = 'NonLinearStatic'
        SimInfo.solvers['StaticCoupled']['structural_solver_settings'] = SimInfo.solvers['NonLinearStatic']
        SimInfo.solvers['StaticCoupled']['aero_solver'] = 'StaticUvlm'
        SimInfo.solvers['StaticCoupled']['aero_solver_settings'] = SimInfo.solvers['StaticUvlm']

        SimInfo.solvers['WriteVariablesTime']['structure_nodes'] = np.array([0,  int((nnodes1-1)/2), -1], dtype = int)
        SimInfo.solvers['WriteVariablesTime']['structure_variables'] = ['pos']

        SimInfo.solvers['BeamPlot']['include_FoR'] = True

        SimInfo.solvers['NonLinearDynamicMultibody']['relaxation_factor'] = 0.0
        SimInfo.solvers['NonLinearDynamicMultibody']['min_delta'] = 1e-5
        SimInfo.solvers['NonLinearDynamicMultibody']['max_iterations'] = 200
        SimInfo.solvers['NonLinearDynamicMultibody']['newmark_damp'] = 1e-3
        # SimInfo.solvers['NonLinearDynamicMultibody']['gravity_on'] = 'off'

        SimInfo.solvers['NonLinearDynamicMultibody']['relaxation_factor'] = 0.0

        SimInfo.solvers['DynamicCoupled']['structural_solver'] = 'NonLinearDynamicMultibody'
        SimInfo.solvers['DynamicCoupled']['structural_solver_settings'] = SimInfo.solvers['NonLinearDynamicMultibody']
        SimInfo.solvers['DynamicCoupled']['aero_solver'] = 'StepUvlm'
        SimInfo.solvers['DynamicCoupled']['aero_solver_settings'] = SimInfo.solvers['StepUvlm']
        SimInfo.solvers['DynamicCoupled']['postprocessors'] = ['WriteVariablesTime', 'BeamPlot', 'AerogridPlot']
        SimInfo.solvers['DynamicCoupled']['postprocessors_settings'] = {'WriteVariablesTime': SimInfo.solvers['WriteVariablesTime'],
                                                                        'BeamPlot': SimInfo.solvers['BeamPlot'],
                                                                        'AerogridPlot': SimInfo.solvers['AerogridPlot']}

        ntimesteps = 10

        SimInfo.define_num_steps(ntimesteps)

        # Define dynamic simulation
        SimInfo.with_forced_vel = False
        SimInfo.with_dynamic_forces = False

        LC2 = gc.LagrangeConstraint()
        LC2.behaviour = 'lin_vel_node_wrtG'
        LC2.velocity = np.zeros((ntimesteps, 3))
        LC2.velocity[:int(ntimesteps/2),1] = 0.5
        LC2.velocity[int(ntimesteps/2):,1] = -0.5
        LC2.body_number = 0
        LC2.node_number = int((nnodes1-1)/2)

        LC = []
        # LC.append(LC1)
        LC.append(LC2)

        # Define the multibody infromation for the tower and the rotor
        MB1 = gc.BodyInformation()
        MB1.body_number = 0
        MB1.FoR_position = np.zeros((6,),)
        MB1.FoR_velocity = np.zeros((6,),)
        MB1.FoR_acceleration = np.zeros((6,),)
        MB1.FoR_movement = 'free'
        MB1.quat = np.array([1.0,0.0,0.0,0.0])

        MB = []
        MB.append(MB1)


        gc.clean_test_files(
            SimInfo.solvers['SHARPy']['route'],
            SimInfo.solvers['SHARPy']['case'])
        SimInfo.generate_solver_file()
        SimInfo.generate_dyn_file(ntimesteps)
        beam1.generate_h5_files(
            SimInfo.solvers['SHARPy']['route'],
            SimInfo.solvers['SHARPy']['case'])
        gc.generate_multibody_file(LC,
                                   MB,SimInfo.solvers['SHARPy']['route'],
                                   SimInfo.solvers['SHARPy']['case'])
Пример #6
0
    def setUp(self):
        import sharpy.utils.generate_cases as gc

        deg2rad = np.pi/180.

        # Structural properties
        mass_per_unit_length = 1.
        mass_iner = 1e-4
        EA = 1e9
        GA = 1e9
        GJ = 1e9
        EI = 1e9

        # Beam1
        global nnodes1
        nnodes1 = 11
        l1 = 1.0
        m1 = 1.0
        theta_ini1 = 90.*deg2rad

        # Beam2
        nnodes2 = nnodes1
        l2 = l1
        m2 = m1
        theta_ini2 = 00.*deg2rad

        # airfoils
        airfoil = np.zeros((1,20,2),)
        airfoil[0,:,0] = np.linspace(0.,1.,20)

        # Simulation
        numtimesteps = 10
        dt = 0.01

        # Create the structure
        beam1 = gc.AeroelasticInformation()
        r1 = np.linspace(0.0, l1, nnodes1)
        node_pos1 = np.zeros((nnodes1,3),)
        node_pos1[:, 0] = r1*np.sin(theta_ini1)
        node_pos1[:, 2] = -r1*np.cos(theta_ini1)
        beam1.StructuralInformation.generate_uniform_sym_beam(node_pos1, mass_per_unit_length, mass_iner, EA, GA, GJ, EI, num_node_elem = 3, y_BFoR = 'y_AFoR', num_lumped_mass=1)
        beam1.StructuralInformation.body_number = np.zeros((beam1.StructuralInformation.num_elem,), dtype = int)
        beam1.StructuralInformation.boundary_conditions[0] = 1
        beam1.StructuralInformation.boundary_conditions[-1] = -1
        beam1.StructuralInformation.lumped_mass_nodes = np.array([nnodes1-1], dtype = int)
        beam1.StructuralInformation.lumped_mass = np.ones((1,))*m1
        beam1.StructuralInformation.lumped_mass_inertia = np.zeros((1,3,3))
        beam1.StructuralInformation.lumped_mass_position = np.zeros((1,3))
        beam1.AerodynamicInformation.create_one_uniform_aerodynamics(
                                            beam1.StructuralInformation,
                                            chord = 1.,
                                            twist = 0.,
                                            sweep = 0.,
                                            num_chord_panels = 4,
                                            m_distribution = 'uniform',
                                            elastic_axis = 0.25,
                                            num_points_camber = 20,
                                            airfoil = airfoil)

        beam2 = gc.AeroelasticInformation()
        r2 = np.linspace(0.0, l2, nnodes2)
        node_pos2 = np.zeros((nnodes2,3),)
        node_pos2[:, 0] = r2*np.sin(theta_ini2) + node_pos1[-1, 0]
        node_pos2[:, 2] = -r2*np.cos(theta_ini2) + node_pos1[-1, 2]
        beam2.StructuralInformation.generate_uniform_sym_beam(node_pos2, mass_per_unit_length, mass_iner, EA, GA, GJ, EI, num_node_elem = 3, y_BFoR = 'y_AFoR', num_lumped_mass=1)
        beam2.StructuralInformation.body_number = np.zeros((beam1.StructuralInformation.num_elem,), dtype = int)
        beam2.StructuralInformation.boundary_conditions[0] = 1
        beam2.StructuralInformation.boundary_conditions[-1] = -1
        beam2.StructuralInformation.lumped_mass_nodes = np.array([nnodes2-1], dtype = int)
        beam2.StructuralInformation.lumped_mass = np.ones((1,))*m2
        beam2.StructuralInformation.lumped_mass_inertia = np.zeros((1,3,3))
        beam2.StructuralInformation.lumped_mass_position = np.zeros((1,3))
        beam2.AerodynamicInformation.create_one_uniform_aerodynamics(
                                            beam2.StructuralInformation,
                                            chord = 1.,
                                            twist = 0.,
                                            sweep = 0.,
                                            num_chord_panels = 4,
                                            m_distribution = 'uniform',
                                            elastic_axis = 0.25,
                                            num_points_camber = 20,
                                            airfoil = airfoil)

        beam1.assembly(beam2)

        # Simulation details
        SimInfo = gc.SimulationInformation()
        SimInfo.set_default_values()

        SimInfo.define_uinf(np.array([0.0,1.0,0.0]), 1.)

        SimInfo.solvers['SHARPy']['flow'] = ['BeamLoader',
                                'AerogridLoader',
                                # 'InitializeMultibody',
                                'DynamicCoupled']
        global name
        name = 'double_pendulum_geradin'
        SimInfo.solvers['SHARPy']['case'] = 'double_pendulum_geradin'
        SimInfo.solvers['SHARPy']['write_screen'] = 'off'
        SimInfo.solvers['SHARPy']['route'] = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) + '/'
        SimInfo.solvers['SHARPy']['log_folder'] = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) + '/'
        SimInfo.set_variable_all_dicts('dt', dt)
        SimInfo.define_num_steps(numtimesteps)
        SimInfo.set_variable_all_dicts('rho', 0.0)
        SimInfo.set_variable_all_dicts('velocity_field_input', SimInfo.solvers['SteadyVelocityField'])
        SimInfo.set_variable_all_dicts('output', os.path.abspath(os.path.dirname(os.path.realpath(__file__))) + '/output/')

        SimInfo.solvers['BeamLoader']['unsteady'] = 'on'

        SimInfo.solvers['AerogridLoader']['unsteady'] = 'on'
        SimInfo.solvers['AerogridLoader']['mstar'] = 2

        SimInfo.solvers['WriteVariablesTime']['FoR_number'] = np.array([0, 1], dtype = int)
        SimInfo.solvers['WriteVariablesTime']['FoR_variables'] = ['mb_quat']
        SimInfo.solvers['WriteVariablesTime']['structure_nodes'] = np.array([nnodes1-1, nnodes1+nnodes2-1], dtype = int)
        SimInfo.solvers['WriteVariablesTime']['structure_variables'] = ['pos']

        SimInfo.solvers['NonLinearDynamicMultibody']['gravity_on'] = True
        SimInfo.solvers['NonLinearDynamicMultibody']['newmark_damp'] = 0.15

        SimInfo.solvers['BeamPlot']['include_FoR'] = True

        SimInfo.solvers['DynamicCoupled']['structural_solver'] = 'NonLinearDynamicMultibody'
        SimInfo.solvers['DynamicCoupled']['structural_solver_settings'] = SimInfo.solvers['NonLinearDynamicMultibody']
        SimInfo.solvers['DynamicCoupled']['aero_solver'] = 'StepUvlm'
        SimInfo.solvers['DynamicCoupled']['aero_solver_settings'] = SimInfo.solvers['StepUvlm']
        SimInfo.solvers['DynamicCoupled']['postprocessors'] = ['WriteVariablesTime', 'BeamPlot', 'AerogridPlot']
        SimInfo.solvers['DynamicCoupled']['postprocessors_settings'] = {'WriteVariablesTime': SimInfo.solvers['WriteVariablesTime'],
                                                                        'BeamPlot': SimInfo.solvers['BeamPlot'],
                                                                        'AerogridPlot': SimInfo.solvers['AerogridPlot']}

        SimInfo.solvers['DynamicCoupled']['postprocessors_settings']['WriteVariablesTime']['folder'] = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) + '/output/'
        SimInfo.solvers['DynamicCoupled']['postprocessors_settings']['BeamPlot']['folder'] = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) + '/output/'
        SimInfo.solvers['DynamicCoupled']['postprocessors_settings']['AerogridPlot']['folder'] = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) + '/output/'
        SimInfo.with_forced_vel = False
        SimInfo.with_dynamic_forces = False

        # Create the MB and BC files
        LC1 = gc.LagrangeConstraint()
        LC1.behaviour = 'hinge_FoR'
        LC1.body_FoR = 0
        LC1.rot_axis_AFoR = np.array([0.0,1.0,0.0])

        LC2 = gc.LagrangeConstraint()
        LC2.behaviour = 'hinge_node_FoR'
        LC2.node_in_body = nnodes1-1
        LC2.body = 0
        LC2.body_FoR = 1
        LC2.rot_axisB = np.array([0.0,1.0,0.0])

        LC = []
        LC.append(LC1)
        LC.append(LC2)

        MB1 = gc.BodyInformation()
        MB1.body_number = 0
        MB1.FoR_position = np.zeros((6,),)
        MB1.FoR_velocity = np.zeros((6,),)
        MB1.FoR_acceleration = np.zeros((6,),)
        MB1.FoR_movement = 'free'
        MB1.quat = np.array([1.0,0.0,0.0,0.0])

        MB2 = gc.BodyInformation()
        MB2.body_number = 1
        MB2.FoR_position = np.array([node_pos2[0, 0], node_pos2[0, 1], node_pos2[0, 2], 0.0, 0.0, 0.0])
        MB2.FoR_velocity = np.zeros((6,),)
        MB2.FoR_acceleration = np.zeros((6,),)
        MB2.FoR_movement = 'free'
        MB2.quat = np.array([1.0,0.0,0.0,0.0])

        MB = []
        MB.append(MB1)
        MB.append(MB2)

        # Write files
        gc.clean_test_files(SimInfo.solvers['SHARPy']['route'], SimInfo.solvers['SHARPy']['case'])
        SimInfo.generate_solver_file()
        SimInfo.generate_dyn_file(numtimesteps)
        beam1.generate_h5_files(SimInfo.solvers['SHARPy']['route'], SimInfo.solvers['SHARPy']['case'])
        gc.generate_multibody_file(LC, MB,SimInfo.solvers['SHARPy']['route'], SimInfo.solvers['SHARPy']['case'])
Пример #7
0
    def setUp(self):
        import sharpy.utils.generate_cases as gc
        import cases.templates.template_wt as template_wt
        import sharpy.utils.algebra as algebra

        deg2rad = np.pi/180.
        ######################################################################
        ###########################  PARAMETERS  #############################
        ######################################################################
        # Case
        global case
        route = folder + '/'
        case = 'rotor'

        # Geometry discretization
        chord_panels = np.array([8], dtype=int)
        revs_in_wake = 1

        # Operation
        rotation_velocity = 1.366190
        pitch_deg = 0. #degrees

        # Wind
        WSP = 11.4
        air_density = 1.225

        # Simulation
        dphi = 4.*deg2rad
        revs_to_simulate = 5

        ######################################################################
        ##########################  GENERATE WT  #############################
        ######################################################################
        dt = dphi/rotation_velocity
        # time_steps = int(revs_to_simulate*2.*np.pi/dphi)
        time_steps = 2 # For the test cases

        mstar = int(revs_in_wake*2.*np.pi/dphi)

        rotor = template_wt.rotor_from_excel_type02(
                                          chord_panels,
                                          rotation_velocity,
                                          pitch_deg,
                                          excel_file_name= folder + '/type02_db_NREL_5MW.xlsx',
                                          excel_sheet_parameters = 'parameters',
                                          excel_sheet_structural_blade = 'structural_blade',
                                          excel_sheet_discretization_blade = 'discretization_blade',
                                          excel_sheet_aero_blade = 'aero_blade',
                                          excel_sheet_airfoil_info = 'airfoil_info',
                                          excel_sheet_airfoil_coord = 'airfoil_coord',
                                          m_distribution = 'uniform',
                                          n_points_camber = 100,
                                          tol_remove_points = 1e-8)

        ######################################################################
        ######################  DEFINE SIMULATION  ###########################
        ######################################################################
        SimInfo = gc.SimulationInformation()
        SimInfo.set_default_values()

        SimInfo.solvers['SHARPy']['flow'] = ['BeamLoader',
                                'AerogridLoader',
                                'Modal']
        SimInfo.solvers['SHARPy']['case'] = case
        SimInfo.solvers['SHARPy']['route'] = route
        SimInfo.solvers['SHARPy']['write_log'] = True
        SimInfo.solvers['SHARPy']['write_screen'] = 'off'
        SimInfo.solvers['SHARPy']['log_folder'] = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) + '/'
        SimInfo.set_variable_all_dicts('dt', dt)
        SimInfo.set_variable_all_dicts('rho', air_density)

        SimInfo.solvers['BeamLoader']['unsteady'] = 'on'

        SimInfo.solvers['AerogridLoader']['unsteady'] = 'on'
        SimInfo.solvers['AerogridLoader']['mstar'] = mstar
        SimInfo.solvers['AerogridLoader']['freestream_dir'] = np.array([0.,0.,0.])

        SimInfo.solvers['Modal']['write_modes_vtk'] = False
        SimInfo.solvers['Modal']['write_dat'] = True
        SimInfo.solvers['Modal']['folder'] = folder + '/output/'

        ######################################################################
        #######################  GENERATE FILES  #############################
        ######################################################################
        gc.clean_test_files(SimInfo.solvers['SHARPy']['route'], SimInfo.solvers['SHARPy']['case'])
        rotor.generate_h5_files(SimInfo.solvers['SHARPy']['route'], SimInfo.solvers['SHARPy']['case'])
        SimInfo.generate_solver_file()
Пример #8
0
def generate(x_dict={}, case_name=None):
    """

    """
    if case_name is None:
        case_name = 'base'
    route = os.path.dirname(os.path.realpath(__file__)) + '/'

    case_notes = str(x_dict)

    # EXECUTION
    flow = [
        'BeamLoader',
        'AerogridLoader',
        # 'StaticTrim',
        'StaticCoupled',
        'BeamLoads',
        'DynamicCoupled',
        'PickleData'
    ]

    # FLIGHT CONDITIONS
    # the simulation is set such that the aircraft flies at a u_inf velocity while
    # the air is calm.
    try:
        u_inf = x_dict['release_velocity']
    except KeyError:
        print('Using default value of 10 for u_inf')
        u_inf = 10

    u_inf_cruise = 10
    original_u_inf = u_inf
    u_background = 0.5
    rho = 1.225

    # trim sigma = 1.5
    try:
        alpha_cato_delta = x_dict['dAoA'] * np.pi / 180
    except KeyError:
        print('Using default value of 0 for dAoA')
        alpha_cato_delta = 0 * np.pi / 180

    try:
        ramp_angle = x_dict['ramp_angle'] * np.pi / 180
    except KeyError:
        print('Using default value of 0 for ramp_angle')
        ramp_angle = 0.0

    alpha = 4.0782 * np.pi / 180 + alpha_cato_delta
    beta = 0
    roll = 0
    gravity = 'on'
    cs_deflection = -1.2703 * np.pi / 180
    rudder_static_deflection = 0.0
    # rudder_step = 0.0*np.pi/180
    thrust = 3.8682
    sigma = 1.5
    lambda_dihedral = 20 * np.pi / 180

    # trajectory
    t_start = 1.5

    try:
        acceleration = x_dict['acceleration']
    except KeyError:
        print('Using default value of 3 for acceleration')
        acceleration = 3.

    t_ramp = u_inf / acceleration
    t_finish = t_start + t_ramp
    t_free = 8
    controller_ramp = -1

    # numerics
    n_step = 1
    relaxation_factor = 0.4
    tolerance = 1e-6
    fsi_tolerance = 1e-5
    structural_substeps = 1

    num_cores = 4

    # MODEL GEOMETRY
    # beam
    span_main = 16.0
    lambda_main = 0.25
    ea_main = 0.3

    ea = 1e7
    ga = 1e5
    gj = 1e4
    eiy = 2e4
    eiz = 4e5
    m_bar_main = 0.75
    j_bar_main = 0.075

    length_fuselage = 10
    offset_fuselage = 0
    sigma_fuselage = 10
    m_bar_fuselage = 0.2
    j_bar_fuselage = 0.08

    span_tail = 2.5
    ea_tail = 0.5
    fin_height = 2.5
    ea_fin = 0.5
    sigma_tail = 10
    m_bar_tail = 0.3
    j_bar_tail = 0.08

    # lumped masses
    n_lumped_mass = 1
    lumped_mass_nodes = np.zeros((n_lumped_mass, ), dtype=int)
    lumped_mass = np.zeros((n_lumped_mass, ))
    lumped_mass[0] = 50
    lumped_mass_inertia = np.zeros((n_lumped_mass, 3, 3))
    lumped_mass_position = np.zeros((n_lumped_mass, 3))

    # aero
    chord_main = 1.0
    chord_tail = 0.5
    chord_fin = 0.5

    # DISCRETISATION
    # spatial discretisation
    # chordiwse panels
    m = 4
    # spanwise elements
    n_elem_multiplier = 2
    n_elem_main = int(4 * n_elem_multiplier)
    n_elem_tail = int(2 * n_elem_multiplier)
    n_elem_fin = int(2 * n_elem_multiplier)
    n_elem_fuselage = int(2 * n_elem_multiplier)
    n_surfaces = 5

    # temporal discretisation
    physical_time = t_finish + t_free
    tstep_factor = 1.
    dt = 1.0 / m / u_inf_cruise * tstep_factor
    n_tstep = int(round(physical_time / dt))

    # END OF INPUT-----------------------------------------------------------------

    end_of_fuselage_node = 0
    flat_end_node = np.zeros((2, ), dtype=int) - 1

    # beam processing
    n_node_elem = 3
    span_main1 = (1.0 - lambda_main) * span_main
    span_main2 = lambda_main * span_main

    n_elem_main1 = round(n_elem_main * (1 - lambda_main))
    n_elem_main2 = n_elem_main - n_elem_main1

    # total number of elements
    n_elem = 0
    n_elem += n_elem_main1 + n_elem_main1
    n_elem += n_elem_main2 + n_elem_main2
    n_elem += n_elem_fuselage
    n_elem += n_elem_fin
    n_elem += n_elem_tail + n_elem_tail

    # number of nodes per part
    n_node_main1 = n_elem_main1 * (n_node_elem - 1) + 1
    n_node_main2 = n_elem_main2 * (n_node_elem - 1) + 1
    n_node_main = n_node_main1 + n_node_main2 - 1
    n_node_fuselage = n_elem_fuselage * (n_node_elem - 1) + 1
    n_node_fin = n_elem_fin * (n_node_elem - 1) + 1
    n_node_tail = n_elem_tail * (n_node_elem - 1) + 1

    # total number of nodes
    n_node = 0
    n_node += n_node_main1 + n_node_main1 - 1
    n_node += n_node_main2 - 1 + n_node_main2 - 1
    n_node += n_node_fuselage - 1
    n_node += n_node_fin - 1
    n_node += n_node_tail - 1
    n_node += n_node_tail - 1

    # stiffness and mass matrices
    n_stiffness = 3
    base_stiffness_main = sigma * np.diag([ea, ga, ga, gj, eiy, eiz])
    base_stiffness_fuselage = base_stiffness_main.copy() * sigma_fuselage
    base_stiffness_fuselage[4, 4] = base_stiffness_fuselage[5, 5]
    base_stiffness_tail = base_stiffness_main.copy() * sigma_tail
    base_stiffness_tail[4, 4] = base_stiffness_tail[5, 5]

    n_mass = 3
    base_mass_main = np.diag([
        m_bar_main, m_bar_main, m_bar_main, j_bar_main, 0.5 * j_bar_main,
        0.5 * j_bar_main
    ])
    base_mass_fuselage = np.diag([
        m_bar_fuselage, m_bar_fuselage, m_bar_fuselage, j_bar_fuselage,
        j_bar_fuselage * 0.5, j_bar_fuselage * 0.5
    ])
    base_mass_tail = np.diag([
        m_bar_tail, m_bar_tail, m_bar_tail, j_bar_tail, j_bar_tail * 0.5,
        j_bar_tail * 0.5
    ])

    # PLACEHOLDERS
    # beam
    x = np.zeros((n_node, ))
    y = np.zeros((n_node, ))
    z = np.zeros((n_node, ))
    beam_number = np.zeros((n_elem, ), dtype=int)
    frame_of_reference_delta = np.zeros((n_elem, n_node_elem, 3))
    structural_twist = np.zeros((n_elem, n_node_elem))
    conn = np.zeros((n_elem, n_node_elem), dtype=int)
    stiffness = np.zeros((n_stiffness, 6, 6))
    elem_stiffness = np.zeros((n_elem, ), dtype=int)
    mass = np.zeros((n_mass, 6, 6))
    elem_mass = np.zeros((n_elem, ), dtype=int)
    boundary_conditions = np.zeros((n_node, ), dtype=int)
    app_forces = np.zeros((n_node, 6))

    trajectory_file = route + '/' + case_name + '.traj.csv'
    LC = None
    first_node_centre = np.zeros((2, ), dtype=int)

    # aero
    airfoil_distribution = np.zeros((n_elem, n_node_elem), dtype=int)
    surface_distribution = np.zeros((n_elem, ), dtype=int) - 1
    surface_m = np.zeros((n_surfaces, ), dtype=int)
    m_distribution = 'uniform'
    aero_node = np.zeros((n_node, ), dtype=bool)
    twist = np.zeros((n_elem, n_node_elem))
    sweep = np.zeros((n_elem, n_node_elem))
    chord = np.zeros((
        n_elem,
        n_node_elem,
    ))
    elastic_axis = np.zeros((
        n_elem,
        n_node_elem,
    ))

    # FUNCTIONS-------------------------------------------------------------
    def clean_test_files():
        fem_file_name = route + '/' + case_name + '.fem.h5'
        if os.path.isfile(fem_file_name):
            os.remove(fem_file_name)

        dyn_file_name = route + '/' + case_name + '.dyn.h5'
        if os.path.isfile(dyn_file_name):
            os.remove(dyn_file_name)

        aero_file_name = route + '/' + case_name + '.aero.h5'
        if os.path.isfile(aero_file_name):
            os.remove(aero_file_name)

        solver_file_name = route + '/' + case_name + '.sharpy'
        if os.path.isfile(solver_file_name):
            os.remove(solver_file_name)

        traj_file_name = route + '/' + case_name + '.traj.csv'
        if os.path.isfile(traj_file_name):
            os.remove(traj_file_name)

        flightcon_file_name = route + '/' + case_name + '.flightcon.txt'
        if os.path.isfile(flightcon_file_name):
            os.remove(flightcon_file_name)

    def generate_trajectory_file():
        it_start = math.ceil(t_start / dt)
        it_ramp = math.ceil(t_ramp / dt)
        it_total = it_start + it_ramp
        out_t = np.linspace(0, it_total * dt, it_total)
        out_x = np.zeros((it_total, ))
        out_y = np.zeros((it_total, ))
        out_z = np.zeros((it_total, ))

        t_hist_ramp = np.linspace(0, dt * it_ramp, it_ramp)
        x_ramp = -0.5 * np.cos(ramp_angle) * acceleration * t_hist_ramp**2
        z_ramp = 0.5 * np.sin(ramp_angle) * acceleration * t_hist_ramp**2

        out_x[:it_start] = 0.0
        out_x[it_start:] = x_ramp
        out_z[it_start:] = z_ramp

        out = np.zeros((it_total, 4))
        out[:, 0] = out_t
        out[:, 1] = out_x
        out[:, 2] = out_y
        out[:, 3] = out_z
        np.savetxt(trajectory_file, out, delimiter=',')

    def generate_dyn_file():
        global dt
        global n_tstep
        global route
        global case_name
        global num_elem
        global num_node_elem
        global num_node
        global amplitude
        global period

        dynamic_forces_time = None
        with_dynamic_forces = False
        with_forced_vel = False

        if with_dynamic_forces:
            f1 = 100
            dynamic_forces = np.zeros((num_node, 6))
            app_node = [int(num_node_main - 1), int(num_node_main)]
            dynamic_forces[app_node, 2] = f1
            force_time = np.zeros((n_tstep, ))
            limit = round(0.05 / dt)
            force_time[50:61] = 1

            dynamic_forces_time = np.zeros((n_tstep, num_node, 6))
            for it in range(n_tstep):
                dynamic_forces_time[it, :, :] = force_time[it] * dynamic_forces

        forced_for_vel = None
        if with_forced_vel:
            forced_for_vel = np.zeros((n_tstep, 6))
            forced_for_acc = np.zeros((n_tstep, 6))
            for it in range(n_tstep):
                # if dt*it < period:
                # forced_for_vel[it, 2] = 2*np.pi/period*amplitude*np.sin(2*np.pi*dt*it/period)
                # forced_for_acc[it, 2] = (2*np.pi/period)**2*amplitude*np.cos(2*np.pi*dt*it/period)

                forced_for_vel[it,
                               3] = 2 * np.pi / period * amplitude * np.sin(
                                   2 * np.pi * dt * it / period)
                forced_for_acc[it, 3] = (2 * np.pi /
                                         period)**2 * amplitude * np.cos(
                                             2 * np.pi * dt * it / period)

        if with_dynamic_forces or with_forced_vel:
            with h5.File(route + '/' + case_name + '.dyn.h5', 'a') as h5file:
                if with_dynamic_forces:
                    h5file.create_dataset('dynamic_forces',
                                          data=dynamic_forces_time)
                if with_forced_vel:
                    h5file.create_dataset('for_vel', data=forced_for_vel)
                    h5file.create_dataset('for_acc', data=forced_for_acc)
                h5file.create_dataset('num_steps', data=n_tstep)

    def generate_fem():
        stiffness[0, ...] = base_stiffness_main
        stiffness[1, ...] = base_stiffness_fuselage
        stiffness[2, ...] = base_stiffness_tail

        mass[0, ...] = base_mass_main
        mass[1, ...] = base_mass_fuselage
        mass[2, ...] = base_mass_tail

        we = 0
        wn = 0
        # inner right wing
        beam_number[we:we + n_elem_main1] = 0
        y[wn:wn + n_node_main1] = np.linspace(0.0, span_main1, n_node_main1)

        for ielem in range(n_elem_main1):
            conn[we + ielem, :] = ((np.ones(
                (3, )) * (we + ielem) * (n_node_elem - 1)) + [0, 2, 1])
            for inode in range(n_node_elem):
                frame_of_reference_delta[we + ielem,
                                         inode, :] = [-1.0, 0.0, 0.0]

        elem_stiffness[we:we + n_elem_main1] = 0
        elem_mass[we:we + n_elem_main1] = 0
        flat_end_node[0] = n_node_main1 - 1
        first_node_centre[0] = wn + 1 + 1
        boundary_conditions[0] = 1
        # remember this is in B FoR
        app_forces[0] = [0, thrust, 0, 0, 0, 0]
        we += n_elem_main1
        wn += n_node_main1

        # outer right wing
        beam_number[we:we + n_elem_main1] = 0
        y[wn:wn + n_node_main2 - 1] = y[wn - 1] + np.linspace(
            0.0,
            np.cos(lambda_dihedral) * span_main2, n_node_main2)[1:]
        z[wn:wn + n_node_main2 - 1] = z[wn - 1] + np.linspace(
            0.0,
            np.sin(lambda_dihedral) * span_main2, n_node_main2)[1:]
        for ielem in range(n_elem_main2):
            conn[we + ielem, :] = ((np.ones(
                (3, )) * (we + ielem) * (n_node_elem - 1)) + [0, 2, 1])
            for inode in range(n_node_elem):
                frame_of_reference_delta[we + ielem,
                                         inode, :] = [-1.0, 0.0, 0.0]
        elem_stiffness[we:we + n_elem_main2] = 0
        elem_mass[we:we + n_elem_main2] = 0
        boundary_conditions[wn + n_node_main2 - 2] = -1
        we += n_elem_main2
        wn += n_node_main2 - 1

        # inner left wing
        beam_number[we:we + n_elem_main1 - 1] = 1
        y[wn:wn + n_node_main1 - 1] = np.linspace(0.0, -span_main1,
                                                  n_node_main1)[1:]
        for ielem in range(n_elem_main1):
            conn[we + ielem, :] = ((np.ones(
                (3, )) * (we + ielem) * (n_node_elem - 1)) + [0, 2, 1])
            for inode in range(n_node_elem):
                frame_of_reference_delta[we + ielem,
                                         inode, :] = [1.0, 0.0, 0.0]
        conn[we, 0] = 0
        elem_stiffness[we:we + n_elem_main1] = 0
        elem_mass[we:we + n_elem_main1] = 0
        flat_end_node[1] = wn + n_node_main1 - 1 - 1
        first_node_centre[1] = wn + 1
        we += n_elem_main1
        wn += n_node_main1 - 1

        # outer left wing
        beam_number[we:we + n_elem_main2] = 1
        y[wn:wn + n_node_main2 - 1] = y[wn - 1] + np.linspace(
            0.0, -np.cos(lambda_dihedral) * span_main2, n_node_main2)[1:]
        z[wn:wn + n_node_main2 - 1] = z[wn - 1] + np.linspace(
            0.0,
            np.sin(lambda_dihedral) * span_main2, n_node_main2)[1:]
        for ielem in range(n_elem_main2):
            conn[we + ielem, :] = ((np.ones(
                (3, )) * (we + ielem) * (n_node_elem - 1)) + [0, 2, 1])
            for inode in range(n_node_elem):
                frame_of_reference_delta[we + ielem,
                                         inode, :] = [1.0, 0.0, 0.0]
        elem_stiffness[we:we + n_elem_main2] = 0
        elem_mass[we:we + n_elem_main2] = 0
        boundary_conditions[wn + n_node_main2 - 2] = -1
        we += n_elem_main2
        wn += n_node_main2 - 1

        # fuselage
        beam_number[we:we + n_elem_fuselage] = 2
        x[wn:wn + n_node_fuselage - 1] = np.linspace(0.0, length_fuselage,
                                                     n_node_fuselage)[1:]
        z[wn:wn + n_node_fuselage - 1] = np.linspace(0.0, offset_fuselage,
                                                     n_node_fuselage)[1:]
        for ielem in range(n_elem_fuselage):
            conn[we + ielem, :] = ((np.ones(
                (3, )) * (we + ielem) * (n_node_elem - 1)) + [0, 2, 1])
            for inode in range(n_node_elem):
                frame_of_reference_delta[we + ielem,
                                         inode, :] = [0.0, 1.0, 0.0]
        conn[we, 0] = 0
        elem_stiffness[we:we + n_elem_fuselage] = 1
        elem_mass[we:we + n_elem_fuselage] = 1
        we += n_elem_fuselage
        wn += n_node_fuselage - 1
        global end_of_fuselage_node
        end_of_fuselage_node = wn - 1

        # fin
        beam_number[we:we + n_elem_fin] = 3
        x[wn:wn + n_node_fin - 1] = x[end_of_fuselage_node]
        z[wn:wn + n_node_fin - 1] = z[end_of_fuselage_node] + np.linspace(
            0.0, fin_height, n_node_fin)[1:]
        for ielem in range(n_elem_fin):
            conn[we + ielem, :] = ((np.ones(
                (3, )) * (we + ielem) * (n_node_elem - 1)) + [0, 2, 1])
            for inode in range(n_node_elem):
                frame_of_reference_delta[we + ielem,
                                         inode, :] = [-1.0, 0.0, 0.0]
        conn[we, 0] = end_of_fuselage_node
        elem_stiffness[we:we + n_elem_fin] = 2
        elem_mass[we:we + n_elem_fin] = 2
        we += n_elem_fin
        wn += n_node_fin - 1
        end_of_fin_node = wn - 1

        # right tail
        beam_number[we:we + n_elem_tail] = 4
        x[wn:wn + n_node_tail - 1] = x[end_of_fin_node]
        y[wn:wn + n_node_tail - 1] = np.linspace(0.0, span_tail,
                                                 n_node_tail)[1:]
        z[wn:wn + n_node_tail - 1] = z[end_of_fin_node]
        for ielem in range(n_elem_tail):
            conn[we + ielem, :] = ((np.ones(
                (3, )) * (we + ielem) * (n_node_elem - 1)) + [0, 2, 1])
            for inode in range(n_node_elem):
                frame_of_reference_delta[we + ielem,
                                         inode, :] = [-1.0, 0.0, 0.0]
        conn[we, 0] = end_of_fin_node
        elem_stiffness[we:we + n_elem_tail] = 2
        elem_mass[we:we + n_elem_tail] = 2
        boundary_conditions[wn + n_node_tail - 2] = -1
        we += n_elem_tail
        wn += n_node_tail - 1

        # left tail
        beam_number[we:we + n_elem_tail] = 5
        x[wn:wn + n_node_tail - 1] = x[end_of_fin_node]
        y[wn:wn + n_node_tail - 1] = np.linspace(0.0, -span_tail,
                                                 n_node_tail)[1:]
        z[wn:wn + n_node_tail - 1] = z[end_of_fin_node]
        for ielem in range(n_elem_tail):
            conn[we + ielem, :] = ((np.ones(
                (3, )) * (we + ielem) * (n_node_elem - 1)) + [0, 2, 1])
            for inode in range(n_node_elem):
                frame_of_reference_delta[we + ielem,
                                         inode, :] = [1.0, 0.0, 0.0]
        conn[we, 0] = end_of_fin_node
        elem_stiffness[we:we + n_elem_tail] = 2
        elem_mass[we:we + n_elem_tail] = 2
        boundary_conditions[wn + n_node_tail - 2] = -1
        we += n_elem_tail
        wn += n_node_tail - 1

        with h5.File(route + '/' + case_name + '.fem.h5', 'a') as h5file:
            coordinates = h5file.create_dataset('coordinates',
                                                data=np.column_stack(
                                                    (x, y, z)))
            conectivities = h5file.create_dataset('connectivities', data=conn)
            num_nodes_elem_handle = h5file.create_dataset('num_node_elem',
                                                          data=n_node_elem)
            num_nodes_handle = h5file.create_dataset('num_node', data=n_node)
            num_elem_handle = h5file.create_dataset('num_elem', data=n_elem)
            stiffness_db_handle = h5file.create_dataset('stiffness_db',
                                                        data=stiffness)
            stiffness_handle = h5file.create_dataset('elem_stiffness',
                                                     data=elem_stiffness)
            mass_db_handle = h5file.create_dataset('mass_db', data=mass)
            mass_handle = h5file.create_dataset('elem_mass', data=elem_mass)
            frame_of_reference_delta_handle = h5file.create_dataset(
                'frame_of_reference_delta', data=frame_of_reference_delta)
            structural_twist_handle = h5file.create_dataset(
                'structural_twist', data=structural_twist)
            bocos_handle = h5file.create_dataset('boundary_conditions',
                                                 data=boundary_conditions)
            beam_handle = h5file.create_dataset('beam_number',
                                                data=beam_number)
            app_forces_handle = h5file.create_dataset('app_forces',
                                                      data=app_forces)
            lumped_mass_nodes_handle = h5file.create_dataset(
                'lumped_mass_nodes', data=lumped_mass_nodes)
            lumped_mass_handle = h5file.create_dataset('lumped_mass',
                                                       data=lumped_mass)
            lumped_mass_inertia_handle = h5file.create_dataset(
                'lumped_mass_inertia', data=lumped_mass_inertia)
            lumped_mass_position_handle = h5file.create_dataset(
                'lumped_mass_position', data=lumped_mass_position)

    def generate_aero_file():
        global x, y, z
        # control surfaces
        n_control_surfaces = 2
        control_surface = np.zeros((n_elem, n_node_elem), dtype=int) - 1
        control_surface_type = np.zeros((n_control_surfaces, ), dtype=int)
        control_surface_deflection = np.zeros((n_control_surfaces, ))
        control_surface_chord = np.zeros((n_control_surfaces, ), dtype=int)
        control_surface_hinge_coord = np.zeros((n_control_surfaces, ),
                                               dtype=float)

        # control surface type 0 = static
        # control surface type 1 = dynamic
        control_surface_type[0] = 0
        control_surface_deflection[0] = cs_deflection
        control_surface_chord[0] = m
        control_surface_hinge_coord[
            0] = -0.25  # nondimensional wrt elastic axis (+ towards the trailing edge)

        control_surface_type[1] = 0
        control_surface_deflection[1] = rudder_static_deflection
        control_surface_chord[1] = 1
        control_surface_hinge_coord[
            1] = -0.  # nondimensional wrt elastic axis (+ towards the trailing edge)

        we = 0
        wn = 0
        # right wing (surface 0, beam 0)
        i_surf = 0
        airfoil_distribution[we:we + n_elem_main, :] = 0
        surface_distribution[we:we + n_elem_main] = i_surf
        surface_m[i_surf] = m
        aero_node[wn:wn + n_node_main] = True
        temp_chord = np.linspace(chord_main, chord_main, n_node_main)
        temp_sweep = np.linspace(0.0, 0 * np.pi / 180, n_node_main)
        node_counter = 0
        for i_elem in range(we, we + n_elem_main):
            for i_local_node in range(n_node_elem):
                if not i_local_node == 0:
                    node_counter += 1
                chord[i_elem, i_local_node] = temp_chord[node_counter]
                elastic_axis[i_elem, i_local_node] = ea_main
                sweep[i_elem, i_local_node] = temp_sweep[node_counter]

        we += n_elem_main
        wn += n_node_main

        # left wing (surface 1, beam 1)
        i_surf = 1
        airfoil_distribution[we:we + n_elem_main, :] = 0
        # airfoil_distribution[wn:wn + n_node_main - 1] = 0
        surface_distribution[we:we + n_elem_main] = i_surf
        surface_m[i_surf] = m
        aero_node[wn:wn + n_node_main - 1] = True
        # chord[wn:wn + num_node_main - 1] = np.linspace(main_chord, main_tip_chord, num_node_main)[1:]
        # chord[wn:wn + num_node_main - 1] = main_chord
        # elastic_axis[wn:wn + num_node_main - 1] = main_ea
        temp_chord = np.linspace(chord_main, chord_main, n_node_main)
        node_counter = 0
        for i_elem in range(we, we + n_elem_main):
            for i_local_node in range(n_node_elem):
                if not i_local_node == 0:
                    node_counter += 1
                chord[i_elem, i_local_node] = temp_chord[node_counter]
                elastic_axis[i_elem, i_local_node] = ea_main
                sweep[i_elem, i_local_node] = -temp_sweep[node_counter]

        we += n_elem_main
        wn += n_node_main - 1

        we += n_elem_fuselage
        wn += n_node_fuselage - 1 - 1

        # fin (surface 2, beam 3)
        i_surf = 2
        airfoil_distribution[we:we + n_elem_fin, :] = 1
        # airfoil_distribution[wn:wn + n_node_fin] = 0
        surface_distribution[we:we + n_elem_fin] = i_surf
        surface_m[i_surf] = m
        aero_node[wn:wn + n_node_fin] = True
        # chord[wn:wn + num_node_fin] = fin_chord
        for i_elem in range(we, we + n_elem_fin):
            for i_local_node in range(n_node_elem):
                chord[i_elem, i_local_node] = chord_fin
                elastic_axis[i_elem, i_local_node] = ea_fin
                control_surface[i_elem, i_local_node] = 1
                # twist[end_of_fuselage_node] = 0
                # twist[wn:] = 0
                # elastic_axis[wn:wn + num_node_main] = fin_ea
        we += n_elem_fin
        wn += n_node_fin - 1
        #
        # # # right tail (surface 3, beam 4)
        i_surf = 3
        airfoil_distribution[we:we + n_elem_tail, :] = 2
        # airfoil_distribution[wn:wn + n_node_tail] = 0
        surface_distribution[we:we + n_elem_tail] = i_surf
        surface_m[i_surf] = m
        # XXX not very elegant
        aero_node[wn:] = True
        # chord[wn:wn + num_node_tail] = tail_chord
        # elastic_axis[wn:wn + num_node_main] = tail_ea
        for i_elem in range(we, we + n_elem_tail):
            for i_local_node in range(n_node_elem):
                twist[i_elem, i_local_node] = -0
        for i_elem in range(we, we + n_elem_tail):
            for i_local_node in range(n_node_elem):
                chord[i_elem, i_local_node] = chord_tail
                elastic_axis[i_elem, i_local_node] = ea_tail
                control_surface[i_elem, i_local_node] = 0

        we += n_elem_tail
        wn += n_node_tail
        #
        # # left tail (surface 4, beam 5)
        i_surf = 4
        airfoil_distribution[we:we + n_elem_tail, :] = 2
        # airfoil_distribution[wn:wn + n_node_tail - 1] = 0
        surface_distribution[we:we + n_elem_tail] = i_surf
        surface_m[i_surf] = m
        aero_node[wn:wn + n_node_tail - 1] = True
        # chord[wn:wn + num_node_tail] = tail_chord
        # elastic_axis[wn:wn + num_node_main] = tail_ea
        # twist[we:we + num_elem_tail] = -tail_twist
        for i_elem in range(we, we + n_elem_tail):
            for i_local_node in range(n_node_elem):
                twist[i_elem, i_local_node] = -0
        for i_elem in range(we, we + n_elem_tail):
            for i_local_node in range(n_node_elem):
                chord[i_elem, i_local_node] = chord_tail
                elastic_axis[i_elem, i_local_node] = ea_tail
                control_surface[i_elem, i_local_node] = 0
        we += n_elem_tail
        wn += n_node_tail

        with h5.File(route + '/' + case_name + '.aero.h5', 'a') as h5file:
            airfoils_group = h5file.create_group('airfoils')
            # add one airfoil
            naca_airfoil_main = airfoils_group.create_dataset(
                '0', data=np.column_stack(generate_naca_camber(P=0, M=0)))
            naca_airfoil_tail = airfoils_group.create_dataset(
                '1', data=np.column_stack(generate_naca_camber(P=0, M=0)))
            naca_airfoil_fin = airfoils_group.create_dataset(
                '2', data=np.column_stack(generate_naca_camber(P=0, M=0)))

            # chord
            chord_input = h5file.create_dataset('chord', data=chord)
            dim_attr = chord_input.attrs['units'] = 'm'

            # twist
            twist_input = h5file.create_dataset('twist', data=twist)
            dim_attr = twist_input.attrs['units'] = 'rad'

            # sweep
            sweep_input = h5file.create_dataset('sweep', data=sweep)
            dim_attr = sweep_input.attrs['units'] = 'rad'

            # airfoil distribution
            airfoil_distribution_input = h5file.create_dataset(
                'airfoil_distribution', data=airfoil_distribution)

            surface_distribution_input = h5file.create_dataset(
                'surface_distribution', data=surface_distribution)
            surface_m_input = h5file.create_dataset('surface_m',
                                                    data=surface_m)
            m_distribution_input = h5file.create_dataset(
                'm_distribution',
                data=m_distribution.encode('ascii', 'ignore'))

            aero_node_input = h5file.create_dataset('aero_node',
                                                    data=aero_node)
            elastic_axis_input = h5file.create_dataset('elastic_axis',
                                                       data=elastic_axis)

            control_surface_input = h5file.create_dataset('control_surface',
                                                          data=control_surface)
            control_surface_deflection_input = h5file.create_dataset(
                'control_surface_deflection', data=control_surface_deflection)
            control_surface_chord_input = h5file.create_dataset(
                'control_surface_chord', data=control_surface_chord)
            control_surface_hinge_coord_input = h5file.create_dataset(
                'control_surface_hinge_coord',
                data=control_surface_hinge_coord)
            control_surface_types_input = h5file.create_dataset(
                'control_surface_type', data=control_surface_type)

    def generate_naca_camber(M=0, P=0):
        mm = M * 1e-2
        p = P * 1e-1

        def naca(x, mm, p):
            if x < 1e-6:
                return 0.0
            elif x < p:
                return mm / (p * p) * (2 * p * x - x * x)
            elif x > p and x < 1 + 1e-6:
                return mm / ((1 - p) *
                             (1 - p)) * (1 - 2 * p + 2 * p * x - x * x)

        x_vec = np.linspace(0, 1, 1000)
        y_vec = np.array([naca(x, mm, p) for x in x_vec])
        return x_vec, y_vec

    def generate_multibody_file():
        global end_of_fuselage_node
        global LC
        # LCR = gc.LagrangeConstraint()
        # LCR.behaviour = 'lin_vel_node_wrtG'
        # LCR.velocity = np.zeros((3,))
        # LCR.body_number = 0
        # LCR.node_number = flat_end_node[0]

        # LCL = gc.LagrangeConstraint()
        # LCL.behaviour = 'lin_vel_node_wrtG'
        # LCL.velocity = np.zeros((3,))
        # LCL.body_number = 0
        # LCL.node_number = flat_end_node[1]

        LCF = gc.LagrangeConstraint()
        LCF.behaviour = 'lin_vel_node_wrtG'
        LCF.velocity = np.zeros((3, ))
        LCF.body_number = 0
        LCF.node_number = end_of_fuselage_node

        LCCR = gc.LagrangeConstraint()
        LCCR.behaviour = 'lin_vel_node_wrtG'
        LCCR.velocity = np.zeros((3, ))
        LCCR.body_number = 0
        LCCR.node_number = first_node_centre[0]

        LCCL = gc.LagrangeConstraint()
        LCCL.behaviour = 'lin_vel_node_wrtG'
        LCCL.velocity = np.zeros((3, ))
        LCCL.body_number = 0
        LCCL.node_number = first_node_centre[1]

        # LC = [LCR, LCL, LCF, LCCR, LCCL]
        LC = [LCF, LCCR, LCCL]

        MB1 = gc.BodyInformation()
        MB1.body_number = 0
        MB1.FoR_position = np.zeros((6, ))
        MB1.FoR_velocity = np.zeros((6, ))
        MB1.FoR_acceleration = np.zeros((6, ))
        MB1.FoR_movement = 'free'
        MB1.quat = np.array([1.0, 0.0, 0.0, 0.0])

        MB = [MB1]
        gc.generate_multibody_file(LC, MB, route, case_name)

    def generate_solver_file():
        file_name = route + '/' + case_name + '.sharpy'
        settings = dict()
        settings['SHARPy'] = {
            'case': case_name,
            'route': route,
            'flow': flow,
            'write_screen': 'off',
            'write_log': 'on',
            'log_folder': route + '/output/',
            'log_file': case_name + '.log'
        }

        settings['BeamLoader'] = {
            'unsteady': 'on',
            'orientation': algebra.euler2quat(np.array([roll, alpha, beta]))
        }
        settings['AerogridLoader'] = {
            'unsteady': 'on',
            'aligned_grid': 'on',
            # 'mstar': int(160/tstep_factor),
            'mstar': int(100 / tstep_factor),
            'freestream_dir': ['1', '0', '0'],
            'control_surface_deflection': ['', ''],
            'control_surface_deflection_generator': {
                '0': {},
                '1': {}
            }
        }

        settings['NonLinearStatic'] = {
            'print_info': 'off',
            'max_iterations': 150,
            'num_load_steps': 1,
            'delta_curved': 1e-1,
            'min_delta': tolerance,
            'gravity_on': gravity,
            'gravity': 0 * 9.81
        }

        settings['StaticUvlm'] = {
            'print_info': 'off',
            'horseshoe': 'off',
            'num_cores': num_cores,
            'n_rollup': 0,
            'rollup_dt': dt,
            'rollup_aic_refresh': 1,
            'rollup_tolerance': 1e-4,
            'velocity_field_generator': 'SteadyVelocityField',
            'velocity_field_input': {
                'u_inf': u_background,
                'u_inf_direction': [1., 0, 0]
            },
            'rho': 0 * rho
        }

        settings['StaticCoupled'] = {
            'print_info': 'off',
            'structural_solver': 'NonLinearStatic',
            'structural_solver_settings': settings['NonLinearStatic'],
            'aero_solver': 'StaticUvlm',
            'aero_solver_settings': settings['StaticUvlm'],
            'max_iter': 100,
            'n_load_steps': n_step,
            'tolerance': fsi_tolerance,
            'relaxation_factor': relaxation_factor
        }

        settings['StaticTrim'] = {
            'solver': 'StaticCoupled',
            'solver_settings': settings['StaticCoupled'],
            'initial_alpha': alpha,
            'initial_deflection': cs_deflection,
            'initial_thrust': thrust
        }

        settings['NonLinearDynamicCoupledStep'] = {
            'print_info': 'off',
            'max_iterations': 950,
            'delta_curved': 1e-1,
            'min_delta': tolerance,
            'newmark_damp': 1e-2,
            'gravity_on': gravity,
            'gravity': 9.81,
            'num_steps': n_tstep,
            'dt': dt,
            'initial_velocity': 0
        }

        settings['NonLinearDynamicMultibody'] = {
            'print_info': 'off',
            'max_iterations': 950,
            'delta_curved': 1e-1,
            'min_delta': tolerance,
            'newmark_damp': 1e-2,
            'gravity_on': gravity,
            'gravity': 9.81,
            'num_steps': n_tstep,
            'dt': dt
        }

        relative_motion = 'off'
        settings['StepUvlm'] = {
            'print_info': 'off',
            'horseshoe': 'off',
            'num_cores': num_cores,
            'n_rollup': 0,
            'convection_scheme': 2,
            'rollup_dt': dt,
            'rollup_aic_refresh': 1,
            'rollup_tolerance': 1e-4,
            'gamma_dot_filtering': 6,
            'velocity_field_generator': 'SteadyVelocityField',
            'velocity_field_input': {
                'u_inf': u_background,
                'u_inf_direction': [1., 0, 0]
            },
            'rho': rho,
            'n_time_steps': n_tstep,
            'dt': dt
        }

        solver = 'NonLinearDynamicMultibody'
        settings['PickleData'] = {'folder': route + '/'}
        settings['DynamicCoupled'] = {'structural_solver': solver,
                                      'structural_solver_settings': settings[solver],
                                      'aero_solver': 'StepUvlm',
                                      'aero_solver_settings': settings['StepUvlm'],
                                      'fsi_substeps': 200,
                                      'fsi_tolerance': fsi_tolerance,
                                      'relaxation_factor': relaxation_factor,
                                      'minimum_steps': 2,
                                      'relaxation_steps': 150,
                                      'dynamic_relaxation': 'off',
                                      'final_relaxation_factor': 0.5,
                                      'n_time_steps': n_tstep,
                                      'dt': dt,
                                      'structural_substeps': structural_substeps,
                                      'include_unsteady_force_contribution': 'on',
                                      'steps_without_unsteady_force': 9,
                                      'controller_id': {#'controller_right': 'TakeOffTrajectoryController',
                                                        # 'controller_left': 'TakeOffTrajectoryController',
                                                        'controller_tail': 'TakeOffTrajectoryController',
                                                        'controller_cright': 'TakeOffTrajectoryController',
                                                        'controller_cleft': 'TakeOffTrajectoryController',
                                                        },
                                      'controller_settings': {
                                      # 'controller_right':
                                      # {
                                      # 'trajectory_input_file': trajectory_file,
                                      # 'dt': dt,
                                      # 'trajectory_method': 'lagrange',
                                      # 'controlled_constraint': 'constraint_00',
                                      # 'initial_ramp_length_structural_substeps': controller_ramp,
                                      # 'write_controller_log': 'off',
                                      # },
                                      # 'controller_left':
                                      # {
                                      # 'trajectory_input_file': trajectory_file,
                                      # 'dt': dt,
                                      # 'trajectory_method': 'lagrange',
                                      # 'controlled_constraint': 'constraint_01',
                                      # 'initial_ramp_length_structural_substeps': controller_ramp,
                                      # 'write_controller_log': 'off',
                                      # },
                                      'controller_tail':
                                      {
                                          'trajectory_input_file': trajectory_file,
                                          'dt': dt,
                                          'trajectory_method': 'lagrange',
                                          'controlled_constraint': 'constraint_00',
                                          'initial_ramp_length_structural_substeps': controller_ramp,
                                          'write_controller_log': 'off',
                                      }, 'controller_cright':
                                      {
                                          'trajectory_input_file': trajectory_file,
                                          'dt': dt,
                                          'trajectory_method': 'lagrange',
                                          'controlled_constraint': 'constraint_01',
                                          'initial_ramp_length_structural_substeps': controller_ramp,
                                          'write_controller_log': 'off',
                                      }, 'controller_cleft':
                                      {
                                          'trajectory_input_file': trajectory_file,
                                          'dt': dt,
                                          'trajectory_method': 'lagrange',
                                          'controlled_constraint': 'constraint_02',
                                          'initial_ramp_length_structural_substeps': controller_ramp,
                                          'write_controller_log': 'off',
                                      }},
                                      'postprocessors': ['BeamLoads'],
                                      'postprocessors_settings': {'BeamLoads': {'folder': route + '/output/',
                                                                                'csv_output': 'off'},
                                                                  'BeamPlot': {'folder': route + '/output/',
                                                                               'include_rbm': 'on',
                                                                               'include_applied_forces': 'on'},
                                                                  'AerogridPlot': {
                                                                      'folder': route + '/output/',
                                                                      'include_rbm': 'on',
                                                                      'include_applied_forces': 'on',
                                                                      'minus_m_star': 0},
                                                                 }
                                      }

        settings['BeamLoads'] = {
            'folder': route + '/output/',
            'csv_output': 'off'
        }

        settings['BeamPlot'] = {
            'folder': route + '/output/',
            'include_rbm': 'on',
            'include_applied_forces': 'on',
            'include_forward_motion': 'on'
        }

        settings['AerogridPlot'] = {
            'folder': route + '/output/',
            'include_rbm': 'on',
            'include_forward_motion': 'off',
            'include_applied_forces': 'on',
            'minus_m_star': 0,
            'u_inf': 0,
            'dt': dt
        }

        settings['Notes'] = {'note': case_notes}

        import configobj
        config = configobj.ConfigObj()
        config.filename = file_name
        for k, v in settings.items():
            config[k] = v
        config.write()

    gc.clean_test_files(route, case_name)
    generate_fem()
    generate_multibody_file()
    generate_aero_file()
    generate_solver_file()
    generate_dyn_file()
    if 'StaticTrim' not in flow:
        generate_trajectory_file()

    return {'sharpy': route + '/' + case_name + '.sharpy'}