from os.path import join
import numpy as np
import inductiva
import math

# Defining the Damping Function
def damping(Ti, Tj, ksi):
    """
    Calculate damping coefficients alpha and beta.

    Parameters:
        Ti (float): Period of the first mode.
        Tj (float): Period of the second mode.
        ksi (float): Damping ratio.

    Returns:
        tuple: (alpha, beta) damping coefficients.
    """
    fi = 1 / Ti
    fj = 1 / Tj

    wi = 2 * math.pi * fi
    wj = 2 * math.pi * fj

    alpha = ksi * 2 * wi * wj / (wi + wj)
    beta = ksi * 2 / (wi + wj)

    return alpha, beta

# Organize all data into a Project
project_name = "B2_3P_Tutorial"

# ---- Path's ----
# Path to the Tutorial Folder
tutorial_folder = r"/Path/to/IDA-at-scale"

# Name of the main tcl file
tcl_file = "Prototype_b2_3p_batch.tcl"

# Path to the template folder inside the tutorial
input_files_template = join(tutorial_folder, "inputFiles_template")
# Path to the simulation files after render inside the tutorial
simulation_files = join(tutorial_folder, "simulation_files")
# Path to the records file inside the tutorial
records_duration_file = join(tutorial_folder, "records_duration.txt")
# Load records into memory
records_duration = np.loadtxt(records_duration_file, delimiter=' ')
# ---- Paths ----


# ---- Analysis variables ----
# 30 bidirectional acceleration time-series to perform IDA
analysis_range = range(1,31)

# Scaling factor for the earthquake time-series
EQfactor_values = [
    0.05, 0.10, 0.15,
    0.20, 0.25, 0.30,
    0.35, 0.40, 0.45,
    0.50]

# Computing the parameters for a 5% fraction
# damping based on the 1st and 6th frequencies
damping_percentage = 0.05
Ti = 0.09970895596567399 # 1st vibration period
Tj = 0.04970502055069268 # 6th vibration period

alpha, beta = damping(Ti, Tj, damping_percentage)
# ---- Analysis variables ----


# Allocating the Cloud Machine Group
cloud_machine = inductiva.resources.ElasticMachineGroup(
    provider="GCP",
    machine_type="c2d-highcpu-2",
    spot=True,
    min_machines=1,
    max_machines=50)

# Initialize the Simulator
opensees = inductiva.simulators.OpenSees(
    interface="eesd",
    version="3.0.2")

# Initializing the Simulation Loop
# Loop over all combinations of ii and EQfactor
for ii in analysis_range:
    for EQfactor in EQfactor_values:

        print(f"Processing ii={ii}, EQfactor={EQfactor:.2f}")
        max_time = records_duration[ii - 1]

        #Render the templates into simulation files with
        #EQfactor, alpha, beta, ii and max_time values replaced
        inductiva.TemplateManager.render_dir(source_dir=input_files_template,
                                             target_dir=simulation_files,
                                             overwrite=True,
                                             EQfactor=EQfactor,
                                             alpha=alpha,
                                             beta=beta,
                                             ii=ii,
                                             max_time=max_time)
        # Running the Simulations
        task = opensees.run(input_dir=simulation_files,
                            sim_config_filename=tcl_file,
                            on=cloud_machine,
                            project=project_name,
                            resubmit_on_preemption=True)

        #Assigning Metadata
        task.set_metadata({
            "factor": str(EQfactor),
            "Current_Analysis": str(ii),
            "Record_duration": str(max_time),
            "Project_name": project_name
        })

# Monitoring Progress and Downloading Results
inductiva.projects.Project(project_name).wait()
inductiva.projects.Project(project_name).download_outputs()
cloud_machine.terminate()
