import os import sys import comtypes.client import pandas as pd pd.set_option('future.no_silent_downcasting', True) import itertools import tkinter as tk from tkinter import * from tkinter import ttk, messagebox, scrolledtext from tkinter.filedialog import askopenfilename import math import numpy as np import warnings warnings.filterwarnings('ignore', category=UserWarning, module='openpyxl') from extraer_comb import * import threading import time # Códigos ANSI de color ROJO = '\033[91m' VERDE = '\033[92m' AMARILLO = '\033[93m' AZUL = '\033[94m' RESET = '\033[0m' # Print iterations progress def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, length = 100, fill = '█', printEnd = "\r", clear_line = False): """ Call in a loop to create terminal progress bar @params: iteration - Required : current iteration (Int) total - Required : total iterations (Int) prefix - Optional : prefix string (Str) suffix - Optional : suffix string (Str) decimals - Optional : positive number of decimals in percent complete (Int) length - Optional : character length of bar (Int) fill - Optional : bar fill character (Str) printEnd - Optional : end character (e.g. "\r", "\r\n") (Str) clear_line - Optional : if True, clears the line instead of adding newline when complete (Bool) """ percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total))) filledLength = int(length * iteration // total) bar = fill * filledLength + '-' * (length - filledLength) line = f'{prefix} |{bar}| {percent}% {suffix}' # Agregar espacios al final para limpiar líneas anteriores más largas print(f'\r{line:<150}', end = printEnd) # Print New Line on Complete if iteration == total: if clear_line: print('\r' + ' ' * 150 + '\r', end = '') else: print() time.sleep(0.01) #diccionario donde se encuentran todos los coef de comb acciones de las normas normas = { "IAPF" : { "CoefVar" : { "Trafico" : { "psi0" : 0.8, "psi1" : { "1" : 0.8, "2" : 0.6, "3" : 0.4 }, "psi2" : 0 }, "Resto" : { "psi0" : 0.6, "psi1" : 0.5, "psi2" : 0.2 } }, "ELU" : { "Favorable" : { "Persistente" : { "Cte" : 1, "NoCte" : 1, "Variable" : 0 }, "Accidental" : { "Cte" : 1, "NoCte" : 1, "Variable" : 0, "Accidental" : 1 } }, "Desfavorable" : { "Persistente" : { "Cte" : 1.35, "NoCte" : 1.5, "Variable" : 1.5 }, "Accidental" : { "Cte" : 1, "NoCte" : 1, "Variable" : 1, "Accidental" : 1 } } }, "ELS" : { "Favorable" : { "Persistente" : { "Cte" : 1, "NoCte" : 1, "Variable" : 0 } }, "Desfavorable" : { "Persistente" : { "Cte" : 1, "NoCte" : 1, "Variable" : 1 } } } }, "IAP" : { "CoefVar" : { "SCUso" : { "CVerticales" : { "psi0" : 0.4, #cuidado que para vehiculos pesados es 0.75 "psi1" : 0.4, #cuidado que para vehiculos pesados es 0.75 "psi2" : 0 }, "CHorizontales" : { "psi0" : 0, "psi1" : 0, "psi2" : 0 }, }, "SCConstruccion" : { "psi0" : 1, "psi1" : 0, "psi2" : 1 }, }, "ELU" : { "Favorable" : { "Persistente" : { "Cte" : 1, "NoCte" : 1, "Variable" : 0 } }, "Desfavorable" : { "Persistente" : { "Cte" : 1.35, "NoCte" : 1.5, "Variable" : 1.5 } } }, "ELS" : { "Favorable" : { "Persistente" : { "Cte" : 1, "NoCte" : 1, "Variable" : 0 } }, "Desfavorable" : { "Persistente" : { "Cte" : 1, "NoCte" : 1, "Variable" : 1 } } } } } class TimeoutException(Exception): pass def raise_timeout(): raise TimeoutException() timer = threading.Timer(20.0, raise_timeout) #se crea un timer de 20 segundos timer.start() try: #Conexion con SAP2000 helper = comtypes.client.CreateObject('SAP2000v1.Helper') helper = helper.QueryInterface(comtypes.gen.SAP2000v1.cHelper) mySapObject = helper.GetObject("CSI.SAP2000.API.SapObject") SapModel = mySapObject.SapModel if not SapModel.GetModelisLocked(): SapModel.SetModelisLocked(False) except TimeoutException as exc: messagebox.showerror( "Error", "No se encuentra una instancia de SAP2000 abierta. Por favor, abra SAP2000 e intente de nuevo." ) sys.exit(1) finally: timer.cancel() #se pregunta si se desea borrar todo lo que hay en el SAP def borrar_combos_existentes(): comboNames = SapModel.RespCombo.GetNameList() if comboNames[0] > 0: for name in comboNames[1]: ret = SapModel.RespCombo.Delete(name) printProgressBar(comboNames[1].index(name)+1, comboNames[0], prefix = 'Borrando combinaciones existentes:', suffix = 'Completado', length = 50) def borrar_load_cases(): case_names = SapModel.LoadCases.GetNameList() if case_names[0] > 0: for name in case_names[1]: ret = SapModel.LoadCases.Delete(name) printProgressBar(case_names[1].index(name)+1, case_names[0], prefix = 'Borrando casos de carga existentes:', suffix = 'Completado', length = 50) def borrar_patrones_carga(): patternNames = SapModel.LoadPatterns.GetNameList() if patternNames[0] > 0: for name in patternNames[1]: ret = SapModel.LoadPatterns.Delete(name) printProgressBar(patternNames[1].index(name)+1, patternNames[0], prefix = 'Borrando patrones de carga existentes:', suffix = 'Completado', length = 50) def extraer_datos_excel(ruta_excel): compatibilidades_df = pd.read_excel(ruta_excel, sheet_name='Compatibilidades') compatibilidades_df = compatibilidades_df.astype(object) restricciones_df = pd.read_excel(ruta_excel, sheet_name='Restricciones') #Limpieza de filas vacias x, y = compatibilidades_df.shape for i in range(x): if (compatibilidades_df.loc[i, compatibilidades_df.columns.values[0]] == 0): compatibilidades_df=compatibilidades_df.drop(i) for i in range(y-1, 0, -1): col_name = compatibilidades_df.columns.values[i] if (isinstance(compatibilidades_df[col_name].name, int)): compatibilidades_df = compatibilidades_df.drop(col_name, axis=1) elif isinstance(col_name, str) and col_name.startswith("0"): compatibilidades_df = compatibilidades_df.drop(col_name, axis=1) x, y = compatibilidades_df.shape for i in range(1, x+1): for j in range(i-1): if not isinstance(compatibilidades_df.loc[j, compatibilidades_df.columns.values[i]], str): if math.isnan(compatibilidades_df.loc[j, compatibilidades_df.columns.values[i]]): compatibilidades_df.loc[j, compatibilidades_df.columns.values[i]] = 'x' #cambio de los valores Nan por 0 compatibilidades_df = compatibilidades_df.fillna(0).infer_objects(copy=False) restricciones_df = restricciones_df.fillna(0) return compatibilidades_df, restricciones_df def creaccion_acciones(restricciones_df): #creacion de load patterns for i in restricciones_df.loc[:, "Definición de 'Load Cases'"]: ret = SapModel.LoadPatterns.Add(i, 3) #el numero indica el tipo de carga: 1 dead, 3 live .. #funcion para comprobar que la combiacion de cargas es posible debido a las restricciones def validar_combinacion(comb, patrones, compatibilidad_df, restricciones_df): #se comprueba la matriz de compatibilidad buscando por cada carga que este activa en este combo #otra carga que este activa y se comprueba en la matriz buscando una 'r' for i in range(len(patrones)): if comb[i]: for j in range(i+1, len(patrones)): if comb[j]: if compatibilidad_df.iloc[i,j+1] == 'r': return False #se comprueba que la carga que esta activa esta con otra carga especificada como condicional #para que la primera exista restriccion = restricciones_df.loc[:,"Si y solo si"] for iter, res in enumerate(restriccion): if res: idx = patrones.index(res) if comb[iter] and not comb[idx]: return False #comprueba que las cargas especificadas como permanentes se encuentran en este caso de carga permanentes = restricciones_df.loc[:,"Permanentes"] for iter, per in enumerate(permanentes): if per != 0: if not(per=='x' and comb[iter]): return False #comprueba que no hay dos acciones accidentales en la misma combinacion accidentales = restricciones_df.loc[:,"Tipo"] num_acc = 0 for iter, acc in enumerate(accidentales): if acc == "Accidental": if comb[iter]: num_acc += 1 if num_acc > 1: return False #comprueba que con sismo solo hay una carga variable sismo = restricciones_df.loc[:,"Accion IAPF"] num_var = 0 for iter, sis in enumerate(sismo): if sis == "Sismo": if comb[iter]: for jter, _ in enumerate(comb): if (restricciones_df.loc[jter,"Tipo"] == "Variable") and comb[jter] != 0: num_var += 1 if num_var > 1: return False #si no cumple ninguna de las restricciones se considera válida la combinacion return True #funcion principal para crear y validar las combinaciones de cargas def crear_validar_combinaciones(restricciones_df, compatibilidades_df): #Se almacena en esta variable un diccionario indicando los estado en los que se puede encontrar la carga valores_por_patron = {} for index, row in restricciones_df.iterrows(): patron = restricciones_df.loc[:,restricciones_df.columns[0]] valores = [0, 1] if row["Bidireccional?"]: valores.append(-1) valores_por_patron[patron[index]] = list(set(valores)) #creacion del array donde se almancenan los nombres de las cargas patrones = list(valores_por_patron.keys()) #se hace con itertools todas las combinaciones de carga posibles sin ninguna restriccion todas_combinaciones = list(itertools.product(*[valores_por_patron[pat] for pat in patrones])) #comprobacion de la validez de las combinaciones combinaciones_validas = [] for comb in todas_combinaciones: if validar_combinacion(comb, patrones, compatibilidades_df, restricciones_df): combinaciones_validas.append(comb) return combinaciones_validas, patrones def limpiar_combos(combos, mascara, coef_comp): combos_limpios = [] for combo in combos: peligro = 0 combo_masc = np.multiply(combo, mascara) for i, _ in enumerate(combo_masc): if combo_masc[i] == coef_comp: peligro += 1 if peligro < 2: combos_limpios.append(combo) return np.array(combos_limpios) def generar_combinaciones_norma_IAPF(combinaciones_validas, restricciones_df, norma_proyecto, vias_cargadas, patrones): combos_ELUP = [] combos_ELUA = [] combos_ELUS = [] combos_ELSC = [] combos_ELSF = [] combos_ELSCP = [] minorados_ELUP = [] minorados_ELSC = [] minorados_ELSF = [] minorados_ELSCP = [] minorados_ELUA = [] minorados_ELUS = [] for combo in combinaciones_validas: coeficientes_ELUP = np.zeros(len(patrones)) coeficientes_ELUA = np.zeros(len(patrones)) coeficientes_ELUS = np.zeros(len(patrones)) coeficientes_ELSC = np.zeros(len(patrones)) coeficientes_ELSF = np.zeros(len(patrones)) coeficientes_ELSCP = np.zeros(len(patrones)) n_var = 0 n_acc = 0 for i in range(len(combo)): if norma_proyecto == "IAPF": #primero se comprueba si la carga es permanente o no if restricciones_df.loc[i,"Permanentes"]: #luego constante o no if restricciones_df.loc[i,"Tipo"] == "Constante": if restricciones_df.loc[i,"Direccion"] == "Desfavorable": #ELU coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Persistente"]["Cte"] coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Cte"] coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Cte"] #ELS coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Cte"] coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Cte"] coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Cte"] elif restricciones_df.loc[i,"Direccion"] == "Favorable": #ELU coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Favorable"]["Persistente"]["Cte"] coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Cte"] coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Cte"] #ELS coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Cte"] coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Cte"] coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Cte"] elif restricciones_df.loc[i,"Tipo"] == "No Constante": if restricciones_df.loc[i,"Direccion"] == "Desfavorable": #ELU coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Persistente"]["NoCte"] coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["NoCte"] coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["NoCte"] #ELS coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["NoCte"] coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["NoCte"] coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["NoCte"] elif restricciones_df.loc[i,"Direccion"] == "Favorable": coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Favorable"]["Persistente"]["NoCte"] coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["NoCte"] coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["NoCte"] #ELS coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["NoCte"] coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["NoCte"] coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["NoCte"] elif restricciones_df.loc[i,"Tipo"] == "Accidental": if combo[i] != 0: n_acc += 1 if restricciones_df.loc[i,"Direccion"] == "Desfavorable": #ELU coeficientes_ELUP[i] = 0 coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Accidental"] coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Accidental"] #ELS coeficientes_ELSC[i] = 0 coeficientes_ELSF[i] = 0 coeficientes_ELSCP[i] = 0 elif restricciones_df.loc[i,"Direccion"] == "Favorable": #ELU coeficientes_ELUP[i] = 0 coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Accidental"] coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Accidental"] #ELS coeficientes_ELSC[i] = 0 coeficientes_ELSF[i] = 0 coeficientes_ELSCP[i] = 0 elif restricciones_df.loc[i,"Tipo"] == "Variable": if combo[i] != 0: n_var += 1 if restricciones_df.loc[i,"Direccion"] == "Desfavorable": #ELU coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Persistente"]["Variable"] coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Variable"] coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Variable"] #ELS coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Variable"] coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Variable"] coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Variable"] elif restricciones_df.loc[i,"Direccion"] == "Favorable": #ELU coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Favorable"]["Persistente"]["Variable"] coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Variable"] coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Variable"] #ELS coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Variable"] coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Variable"] coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Variable"] elif norma_proyecto == "IAP": pass minorados_ELUP.clear() minorados_ELUA.clear() minorados_ELUS.clear() minorados_ELSC.clear() minorados_ELSF.clear() minorados_ELSCP.clear() if n_acc: coef_var_ELUS = np.ones(len(patrones)) coef_var_ELUA = np.ones(len(patrones)) for i in range(len(combo)): if (restricciones_df.loc[i,"Accion IAPF"] == "Sismo") and combo[i] != 0: for j in range(len(combo)): if (restricciones_df.loc[j,"Tipo"] == "Variable") and j: if restricciones_df.loc[j,"Accion IAPF"] == "Trafico": coef_var_ELUS[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"] if restricciones_df.loc[j,"Accion IAPF"] == "Resto": coef_var_ELUS[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"] minorados_ELUS.append(coef_var_ELUS) if (restricciones_df.loc[i,"Accion IAPF"] != "Sismo") and (restricciones_df.loc[i,"Tipo"] == "Accidental") and combo[i] != 0: appended_for_acc = False for k in range(len(combo)): coef_var_ELUA = np.ones(len(patrones)) if (restricciones_df.loc[k,"Tipo"] == "Variable") and combo[k] != 0: if restricciones_df.loc[k,"Accion IAPF"] == "Trafico": coef_var_ELUA[k] = normas["IAPF"]["CoefVar"]["Trafico"]["psi1"][vias_cargadas if int(vias_cargadas) < 4 else "3"] else: coef_var_ELUA[k] = normas["IAPF"]["CoefVar"]["Resto"]["psi1"] for j in range(len(combo)): if (restricciones_df.loc[j,"Tipo"] == "Variable") and (j != k): #se asigna el coeficiente de la variable al resto de variables if restricciones_df.loc[j,"Accion IAPF"] == "Trafico": coef_var_ELUA[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"] else: coef_var_ELUA[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"] minorados_ELUA.append(coef_var_ELUA) appended_for_acc = True # Si no se encontraron variables activas, añadimos el vector por defecto (unos) if not appended_for_acc: minorados_ELUA.append(np.ones(len(patrones))) else: if n_var == 1: coef_var_ELSF = np.ones(len(patrones)) coef_var_ELSCP = np.ones(len(patrones)) for i in range(len(combo)): if (restricciones_df.loc[i,"Tipo"] == "Variable") and combo[i] != 0: if restricciones_df.loc[i,"Accion IAPF"] == "Trafico": coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi1"][vias_cargadas if int(vias_cargadas) < 4 else "3"] coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"] else: coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi1"] coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"] while n_var > 1: n_var -= 1 #se busca la primera variable en el combo y se asigna el coeficiente for i in range(len(combo)): coef_var_ELUP = np.ones(len(patrones)) coef_var_ELSC = np.ones(len(patrones)) coef_var_ELSF = np.ones(len(patrones)) coef_var_ELSCP =np.ones(len(patrones)) if (restricciones_df.loc[i,"Tipo"] == "Variable") and combo[i] != 0: if restricciones_df.loc[i,"Accion IAPF"] == "Trafico": coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi1"][vias_cargadas if int(vias_cargadas) < 4 else "3"] coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"] else: coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi1"] coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"] for j in range(len(combo)): if (restricciones_df.loc[j,"Tipo"] == "Variable") and (j != i): #se asigna el coeficiente de la variable al resto de variables if restricciones_df.loc[j,"Accion IAPF"] == "Trafico": coef_var_ELUP[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi0"] coef_var_ELSC[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi0"] coef_var_ELSF[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"] coef_var_ELSCP[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"] else: coef_var_ELUP[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi0"] coef_var_ELSC[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi0"] coef_var_ELSF[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"] coef_var_ELSCP[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"] minorados_ELUP.append(coef_var_ELUP) minorados_ELSC.append(coef_var_ELSC) minorados_ELSF.append(coef_var_ELSF) minorados_ELSCP.append(coef_var_ELSCP) if minorados_ELUP: for minorado in minorados_ELUP: combos_ELUP.append(np.multiply(np.multiply(coeficientes_ELUP, combo),minorado)) for minorado in minorados_ELSC: combos_ELSC.append(np.multiply(np.multiply(coeficientes_ELSC, combo),minorado)) for minorado in minorados_ELSF: combos_ELSF.append(np.multiply(np.multiply(coeficientes_ELSF, combo),minorado)) for minorado in minorados_ELSCP: combos_ELSCP.append(np.multiply(np.multiply(coeficientes_ELSCP, combo),minorado)) else: combos_ELUP.append(np.multiply(coeficientes_ELUP, combo)) combos_ELSC.append(np.multiply(coeficientes_ELSC, combo)) combos_ELSF.append(np.multiply(coeficientes_ELSF, combo))if not n_var else combos_ELSF.append(np.multiply(np.multiply(coeficientes_ELSF, combo),coef_var_ELSF)) combos_ELSCP.append(np.multiply(coeficientes_ELSCP, combo)) if not n_var else combos_ELSCP.append(np.multiply(np.multiply(coeficientes_ELSCP, combo),coef_var_ELSCP)) if minorados_ELUS: for minorado in minorados_ELUS: combos_ELUS.append(np.multiply(np.multiply(coeficientes_ELUS, combo),minorado)) if minorados_ELUA: for minorado in minorados_ELUA: combos_ELUA.append(np.multiply(np.multiply(coeficientes_ELUA, combo),minorado)) combos_ELUP = np.unique(np.array(combos_ELUP), axis=0) combos_ELUA = np.unique(np.array(combos_ELUA), axis=0) combos_ELUS = np.unique(np.array(combos_ELUS), axis=0) combos_ELSC = np.unique(np.array(combos_ELSC), axis=0) combos_ELSF = np.unique(np.array(combos_ELSF), axis=0) combos_ELSCP = np.unique(np.array(combos_ELSCP), axis=0) restricciones_array = restricciones_df.loc[:,"Tipo"] mascara = np.multiply(np.ones(len(restricciones_array)), (restricciones_array == "Variable").astype(int)) combos_ELUP = limpiar_combos(combos_ELUP, mascara, 1.5) combos_ELSC = limpiar_combos(combos_ELSC, mascara, 1) combos_ELSF = limpiar_combos(combos_ELSF, mascara, 1) combos_ELSCP = limpiar_combos(combos_ELSCP, mascara, 1) return combos_ELUP, combos_ELUA, combos_ELUS, combos_ELSC, combos_ELSF, combos_ELSCP def agregar_combinaciones_carga(combos_data, nombre_tipo, total_combos, patrones, acum): combo_num = 0 for combo in combos_data: combo_name = f"{nombre_tipo}_{combo_num:03d}" ret = SapModel.RespCombo.Add(combo_name, 0) for idx, patron in enumerate(patrones): coeficiente = combo[idx] if coeficiente != 0: ret = SapModel.RespCombo.SetCaseList(combo_name, 0, patron, coeficiente) printProgressBar(combo_num + acum, total_combos, prefix = f'Creando combos {nombre_tipo}:', suffix = 'Completado', length = 50) combo_num += 1 return combo_num def crear_combo_envolvente(combo_name = "", busca = "", total_envolventes = 0, acumulador = 0): contador_envolvente = 0 comboNames = SapModel.RespCombo.GetNameList() patron = [] for j in range(comboNames[0]): if busca in comboNames[1][j]: patron.append(comboNames[1][j]) if len(patron): ret = SapModel.RespCombo.Add(combo_name, 1) for i, name in enumerate(patron): ret = SapModel.RespCombo.SetCaseList(combo_name, 1, name, 1) contador_envolvente += 1 printProgressBar(contador_envolvente + acumulador, total_envolventes, prefix = f'Creando {combo_name} envolvente:', suffix = 'Completado', length = 50) return len(patron) def main(ruta_excel, norma_proyecto, vias_cargadas): compatibilidades_df, restricciones_df =extraer_datos_excel(ruta_excel) creaccion_acciones(restricciones_df) combinaciones_validas, patrones = crear_validar_combinaciones(restricciones_df, compatibilidades_df) combos_ELUP, combos_ELUA, combos_ELUS, combos_ELSC, combos_ELSF, combos_ELSCP = \ generar_combinaciones_norma_IAPF(combinaciones_validas, restricciones_df, norma_proyecto, vias_cargadas, patrones) tot_combos = len(combos_ELUP) + len(combos_ELSC) + len(combos_ELSF) + len(combos_ELSCP) + len(combos_ELUA) + len(combos_ELUS) acum_c = agregar_combinaciones_carga(combos_ELUP, "ELU_P", tot_combos, patrones, 0) acum_c += agregar_combinaciones_carga(combos_ELUA, "ELU_ACC", tot_combos, patrones, acum_c) acum_c += agregar_combinaciones_carga(combos_ELUS, "ELU_SIS", tot_combos, patrones, acum_c) acum_c += agregar_combinaciones_carga(combos_ELSC, "ELS_C_", tot_combos, patrones, acum_c) acum_c += agregar_combinaciones_carga(combos_ELSF, "ELS_F_", tot_combos, patrones, acum_c) _ = agregar_combinaciones_carga(combos_ELSCP, "ELS_CP", tot_combos, patrones, acum_c) print("") total_envolventes = 0 temp_comboNames = SapModel.RespCombo.GetNameList() for combo_type in ["ELU_P", "ELU_ACC", "ELU_SIS", "ELS_C_", "ELS_F_", "ELS_CP"]: total_envolventes += sum(1 for idx in range(temp_comboNames[0]) if combo_type in temp_comboNames[1][idx]) acum = crear_combo_envolvente("1. ENV ELU P", "ELU_P", total_envolventes, 0) acum += crear_combo_envolvente("2. ENV ELU ACC", "ELU_ACC", total_envolventes, acum) acum += crear_combo_envolvente("3. ENV ELU SIS", "ELU_SIS", total_envolventes, acum) acum += crear_combo_envolvente("4. ENV ELS C", "ELS_C_", total_envolventes, acum) acum += crear_combo_envolvente("5. ENV ELS F", "ELS_F_", total_envolventes, acum) _ = crear_combo_envolvente("6. ENV ELS CP", "ELS_CP", total_envolventes, acum) def crear_ventana_configuracion(): """Crea una ventana gráfica para configuración inicial""" ventana = tk.Tk() ventana.title("Configuración de Combinaciones") ventana.geometry("600x800") ventana.attributes('-topmost', True) script_dir = os.path.dirname(os.path.abspath(__file__)) icon_path = os.path.join(script_dir, 'AYRE.ico') ventana.iconbitmap(icon_path) # Título titulo = tk.Label(ventana, text="Configuración Inicial", font=("Arial", 14, "bold")) titulo.pack(pady=10) # Checkbox 1: Borrar combinaciones var_combos = tk.BooleanVar(value=True) check_combos = tk.Checkbutton(ventana, text="Borrar combinaciones existentes", variable=var_combos, font=("Arial", 10)) check_combos.pack(anchor=tk.W, padx=20, pady=5) # Checkbox 2: Borrar cargas var_cargas = tk.BooleanVar(value=True) check_cargas = tk.Checkbutton(ventana, text="Borrar cargas existentes", variable=var_cargas, font=("Arial", 10)) check_cargas.pack(anchor=tk.W, padx=20, pady=5) # Botón Borrar Todo def on_borrar_todo(): if var_combos.get(): borrar_combos_existentes() if var_cargas.get(): borrar_load_cases() borrar_patrones_carga() boton_borrar = tk.Button(ventana, text="Borrar Selección", command=on_borrar_todo, font=("Arial", 11), bg="#f44336", fg="white", padx=10, pady=5) boton_borrar.pack() # Frame para norma frame_norma = tk.Frame(ventana) frame_norma.pack(anchor=tk.W, padx=20, pady=10) label_norma = tk.Label(frame_norma, text="Norma:", font=("Arial", 10)) label_norma.pack(side=tk.LEFT, padx=5) var_norma = tk.StringVar(value="IAPF") combo_norma = tk.ttk.Combobox(frame_norma, textvariable=var_norma, values=["IAPF", "IAP"], state="readonly", width=15) combo_norma.pack(side=tk.LEFT, padx=5) # Frame para vías frame_vias = tk.Frame(ventana) frame_vias.pack(anchor=tk.W, padx=20, pady=10) label_vias = tk.Label(frame_vias, text="Vías cargadas:", font=("Arial", 10)) label_vias.pack(side=tk.LEFT, padx=5) var_vias = tk.StringVar(value="1") combo_vias = tk.ttk.Combobox(frame_vias, textvariable=var_vias, values=["1", "2", "3", "Más de 3"], state="readonly", width=15) combo_vias.pack(side=tk.LEFT, padx=5) # Frame para selección de archivo Excel frame_excel = tk.Frame(ventana) frame_excel.pack(anchor=tk.W, padx=20, pady=10) label_excel = tk.Label(frame_excel, text="Archivo Excel:", font=("Arial", 10)) label_excel.pack(side=tk.LEFT, padx=5) var_excel = tk.StringVar() entry_excel = tk.Entry(frame_excel, textvariable=var_excel, width=40) entry_excel.pack(side=tk.LEFT, padx=5) def browse_excel(): ruta = askopenfilename(filetypes=[("Excel files", "*.xlsx *.xls")]) if ruta: var_excel.set(ruta) boton_ok.config(state=tk.NORMAL) boton_browse = tk.Button(frame_excel, text="Seleccionar", command=browse_excel, font=("Arial", 10)) boton_browse.pack(side=tk.LEFT, padx=5) # Botón OK def on_ok(): main(var_excel.get(), var_norma.get(), var_vias.get()) boton_ok = tk.Button(ventana, text="Crear combos", command=on_ok, font=("Arial", 11), bg="#4CAF50", fg="white", padx=10, pady=5) boton_ok.pack(pady=20) boton_ok.config(state=tk.DISABLED) # Boton extraer datos def on_extraer(): extraer_combinaciones_a_excel(SapModel, var_excel.get()) boton_extraer = tk.Button(ventana, text="Extraer datos", command=on_extraer, font=("Arial", 11), bg="#FF9800", fg="white", padx=10, pady=5) boton_extraer.pack(pady=20) # Boton extraer flechas def on_deflection(): extraer_flechas(SapModel, var_excel.get(), var_flechas.get()) # Frame para flechas frame_flechas = tk.Frame(ventana) frame_flechas.pack(anchor=tk.CENTER, padx=20, pady=10) var_flechas = tk.StringVar(value="1. ENV ELU P") combo_flechas = tk.ttk.Combobox(frame_flechas, textvariable=var_flechas, values=["1. ENV ELU P", "2. ENV ELU ACC", "3. ENV ELU SIS", "4. ENV ELS C", "5. ENV ELS F", "6. ENV ELS CP"], state="readonly", width=15) combo_flechas.pack(side=tk.RIGHT, padx=5) boton_deflection = tk.Button(ventana, text="Extraer flechas", command=on_deflection, font=("Arial", 11), bg="#2196F3", fg="white", padx=10, pady=5) boton_deflection.pack(pady=20) # Boton extraer esfuerzos def on_esfuerzos(): extraer_esfuerzos(SapModel, var_excel.get(), var_flechas.get()) # Frame para esfuerzos frame_esfuerzos = tk.Frame(ventana) frame_esfuerzos.pack(anchor=tk.CENTER, padx=20, pady=10) var_esfuerzos = tk.StringVar(value="1. ENV ELU P") combo_esfuerzos = tk.ttk.Combobox(frame_esfuerzos, textvariable=var_esfuerzos, values=["1. ENV ELU P", "2. ENV ELU ACC", "3. ENV ELU SIS", "4. ENV ELS C", "5. ENV ELS F", "6. ENV ELS CP"], state="readonly", width=15) combo_esfuerzos.pack(side=tk.RIGHT, padx=5) boton_esfuerzos = tk.Button(ventana, text="Extraer esfuerzos", command=on_esfuerzos, font=("Arial", 11), bg="#2196F3", fg="white", padx=10, pady=5) boton_esfuerzos.pack(pady=20) def comprobacion_SAP_cerrado(): try: ret = SapModel.Analyze.GetCaseStatus() if ret[0] > 0: estados = ret[2] if any(estado == 4 for estado in estados): boton_extraer.config(state=tk.NORMAL) boton_deflection.config(state=tk.NORMAL) boton_esfuerzos.config(state=tk.NORMAL) else: boton_extraer.config(state=tk.DISABLED) boton_deflection.config(state=tk.DISABLED) boton_esfuerzos.config(state=tk.DISABLED) except (comtypes.COMError, Exception) as e: sys.exit(0) # Cierra la aplicación si SAP2000 está cerrado ventana.after(1000, comprobacion_SAP_cerrado) # Verifica cada segundo comprobacion_SAP_cerrado() ventana.mainloop() # Mostrar ventana de configuración config = crear_ventana_configuracion()