Comb_acciones.py 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830
  1. import os
  2. import sys
  3. import comtypes.client
  4. import pandas as pd
  5. pd.set_option('future.no_silent_downcasting', True)
  6. import itertools
  7. import tkinter as tk
  8. from tkinter import *
  9. from tkinter import ttk, messagebox, scrolledtext
  10. from tkinter.filedialog import askopenfilename
  11. import math
  12. import numpy as np
  13. import warnings
  14. warnings.filterwarnings('ignore', category=UserWarning, module='openpyxl')
  15. from extraer_comb import *
  16. import threading
  17. import time
  18. # Códigos ANSI de color
  19. ROJO = '\033[91m'
  20. VERDE = '\033[92m'
  21. AMARILLO = '\033[93m'
  22. AZUL = '\033[94m'
  23. RESET = '\033[0m'
  24. # Print iterations progress
  25. def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, length = 100, fill = '█', printEnd = "\r", clear_line = False):
  26. """
  27. Call in a loop to create terminal progress bar
  28. @params:
  29. iteration - Required : current iteration (Int)
  30. total - Required : total iterations (Int)
  31. prefix - Optional : prefix string (Str)
  32. suffix - Optional : suffix string (Str)
  33. decimals - Optional : positive number of decimals in percent complete (Int)
  34. length - Optional : character length of bar (Int)
  35. fill - Optional : bar fill character (Str)
  36. printEnd - Optional : end character (e.g. "\r", "\r\n") (Str)
  37. clear_line - Optional : if True, clears the line instead of adding newline when complete (Bool)
  38. """
  39. percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
  40. filledLength = int(length * iteration // total)
  41. bar = fill * filledLength + '-' * (length - filledLength)
  42. line = f'{prefix} |{bar}| {percent}% {suffix}'
  43. # Agregar espacios al final para limpiar líneas anteriores más largas
  44. print(f'\r{line:<150}', end = printEnd)
  45. # Print New Line on Complete
  46. if iteration == total:
  47. if clear_line:
  48. print('\r' + ' ' * 150 + '\r', end = '')
  49. else:
  50. print()
  51. time.sleep(0.01)
  52. #diccionario donde se encuentran todos los coef de comb acciones de las normas
  53. normas = {
  54. "IAPF" : {
  55. "CoefVar" : {
  56. "Trafico" : {
  57. "psi0" : 0.8,
  58. "psi1" : {
  59. "1" : 0.8,
  60. "2" : 0.6,
  61. "3" : 0.4
  62. },
  63. "psi2" : 0
  64. },
  65. "Resto" : {
  66. "psi0" : 0.6,
  67. "psi1" : 0.5,
  68. "psi2" : 0.2
  69. }
  70. },
  71. "ELU" : {
  72. "Favorable" : {
  73. "Persistente" : {
  74. "Cte" : 1,
  75. "NoCte" : 1,
  76. "Variable" : 0
  77. },
  78. "Accidental" : {
  79. "Cte" : 1,
  80. "NoCte" : 1,
  81. "Variable" : 0,
  82. "Accidental" : 1
  83. }
  84. },
  85. "Desfavorable" : {
  86. "Persistente" : {
  87. "Cte" : 1.35,
  88. "NoCte" : 1.5,
  89. "Variable" : 1.5
  90. },
  91. "Accidental" : {
  92. "Cte" : 1,
  93. "NoCte" : 1,
  94. "Variable" : 1,
  95. "Accidental" : 1
  96. }
  97. }
  98. },
  99. "ELS" : {
  100. "Favorable" : {
  101. "Persistente" : {
  102. "Cte" : 1,
  103. "NoCte" : 1,
  104. "Variable" : 0
  105. }
  106. },
  107. "Desfavorable" : {
  108. "Persistente" : {
  109. "Cte" : 1,
  110. "NoCte" : 1,
  111. "Variable" : 1
  112. }
  113. }
  114. }
  115. },
  116. "IAP" : {
  117. "CoefVar" : {
  118. "SCUso" : {
  119. "CVerticales" : {
  120. "psi0" : 0.4, #cuidado que para vehiculos pesados es 0.75
  121. "psi1" : 0.4, #cuidado que para vehiculos pesados es 0.75
  122. "psi2" : 0
  123. },
  124. "CHorizontales" : {
  125. "psi0" : 0,
  126. "psi1" : 0,
  127. "psi2" : 0
  128. },
  129. },
  130. "SCConstruccion" : {
  131. "psi0" : 1,
  132. "psi1" : 0,
  133. "psi2" : 1
  134. },
  135. },
  136. "ELU" : {
  137. "Favorable" : {
  138. "Persistente" : {
  139. "Cte" : 1,
  140. "NoCte" : 1,
  141. "Variable" : 0
  142. }
  143. },
  144. "Desfavorable" : {
  145. "Persistente" : {
  146. "Cte" : 1.35,
  147. "NoCte" : 1.5,
  148. "Variable" : 1.5
  149. }
  150. }
  151. },
  152. "ELS" : {
  153. "Favorable" : {
  154. "Persistente" : {
  155. "Cte" : 1,
  156. "NoCte" : 1,
  157. "Variable" : 0
  158. }
  159. },
  160. "Desfavorable" : {
  161. "Persistente" : {
  162. "Cte" : 1,
  163. "NoCte" : 1,
  164. "Variable" : 1
  165. }
  166. }
  167. }
  168. }
  169. }
  170. class TimeoutException(Exception):
  171. pass
  172. def raise_timeout():
  173. raise TimeoutException()
  174. timer = threading.Timer(20.0, raise_timeout) #se crea un timer de 20 segundos
  175. timer.start()
  176. try:
  177. #Conexion con SAP2000
  178. helper = comtypes.client.CreateObject('SAP2000v1.Helper')
  179. helper = helper.QueryInterface(comtypes.gen.SAP2000v1.cHelper)
  180. mySapObject = helper.GetObject("CSI.SAP2000.API.SapObject")
  181. SapModel = mySapObject.SapModel
  182. if not SapModel.GetModelisLocked(): SapModel.SetModelisLocked(False)
  183. except TimeoutException as exc:
  184. messagebox.showerror(
  185. "Error",
  186. "No se encuentra una instancia de SAP2000 abierta. Por favor, abra SAP2000 e intente de nuevo."
  187. )
  188. sys.exit(1)
  189. finally:
  190. timer.cancel()
  191. #se pregunta si se desea borrar todo lo que hay en el SAP
  192. def borrar_combos_existentes():
  193. comboNames = SapModel.RespCombo.GetNameList()
  194. if comboNames[0] > 0:
  195. for name in comboNames[1]:
  196. ret = SapModel.RespCombo.Delete(name)
  197. printProgressBar(comboNames[1].index(name)+1, comboNames[0], prefix = 'Borrando combinaciones existentes:', suffix = 'Completado', length = 50)
  198. def borrar_load_cases():
  199. case_names = SapModel.LoadCases.GetNameList()
  200. if case_names[0] > 0:
  201. for name in case_names[1]:
  202. ret = SapModel.LoadCases.Delete(name)
  203. printProgressBar(case_names[1].index(name)+1, case_names[0], prefix = 'Borrando casos de carga existentes:', suffix = 'Completado', length = 50)
  204. def borrar_patrones_carga():
  205. patternNames = SapModel.LoadPatterns.GetNameList()
  206. if patternNames[0] > 0:
  207. for name in patternNames[1]:
  208. ret = SapModel.LoadPatterns.Delete(name)
  209. printProgressBar(patternNames[1].index(name)+1, patternNames[0], prefix = 'Borrando patrones de carga existentes:', suffix = 'Completado', length = 50)
  210. def extraer_datos_excel(ruta_excel):
  211. compatibilidades_df = pd.read_excel(ruta_excel,
  212. sheet_name='Compatibilidades')
  213. compatibilidades_df = compatibilidades_df.astype(object)
  214. restricciones_df = pd.read_excel(ruta_excel,
  215. sheet_name='Restricciones')
  216. #Limpieza de filas vacias
  217. x, y = compatibilidades_df.shape
  218. for i in range(x):
  219. if (compatibilidades_df.loc[i, compatibilidades_df.columns.values[0]] == 0):
  220. compatibilidades_df=compatibilidades_df.drop(i)
  221. for i in range(y-1, 0, -1):
  222. col_name = compatibilidades_df.columns.values[i]
  223. if (isinstance(compatibilidades_df[col_name].name, int)):
  224. compatibilidades_df = compatibilidades_df.drop(col_name, axis=1)
  225. elif isinstance(col_name, str) and col_name.startswith("0"):
  226. compatibilidades_df = compatibilidades_df.drop(col_name, axis=1)
  227. x, y = compatibilidades_df.shape
  228. for i in range(1, x+1):
  229. for j in range(i-1):
  230. if not isinstance(compatibilidades_df.loc[j, compatibilidades_df.columns.values[i]], str):
  231. if math.isnan(compatibilidades_df.loc[j, compatibilidades_df.columns.values[i]]):
  232. compatibilidades_df.loc[j, compatibilidades_df.columns.values[i]] = 'x'
  233. #cambio de los valores Nan por 0
  234. compatibilidades_df = compatibilidades_df.fillna(0).infer_objects(copy=False)
  235. restricciones_df = restricciones_df.fillna(0)
  236. return compatibilidades_df, restricciones_df
  237. def creaccion_acciones(restricciones_df):
  238. #creacion de load patterns
  239. for i in restricciones_df.loc[:, "Definición de 'Load Cases'"]:
  240. ret = SapModel.LoadPatterns.Add(i, 3) #el numero indica el tipo de carga: 1 dead, 3 live ..
  241. #funcion para comprobar que la combiacion de cargas es posible debido a las restricciones
  242. def validar_combinacion(comb, patrones, compatibilidad_df, restricciones_df):
  243. #se comprueba la matriz de compatibilidad buscando por cada carga que este activa en este combo
  244. #otra carga que este activa y se comprueba en la matriz buscando una 'r'
  245. for i in range(len(patrones)):
  246. if comb[i]:
  247. for j in range(i+1, len(patrones)):
  248. if comb[j]:
  249. if compatibilidad_df.iloc[i,j+1] == 'r':
  250. return False
  251. #se comprueba que la carga que esta activa esta con otra carga especificada como condicional
  252. #para que la primera exista
  253. restriccion = restricciones_df.loc[:,"Si y solo si"]
  254. for iter, res in enumerate(restriccion):
  255. if res:
  256. idx = patrones.index(res)
  257. if comb[iter] and not comb[idx]:
  258. return False
  259. #comprueba que las cargas especificadas como permanentes se encuentran en este caso de carga
  260. permanentes = restricciones_df.loc[:,"Permanentes"]
  261. for iter, per in enumerate(permanentes):
  262. if per != 0:
  263. if not(per=='x' and comb[iter]):
  264. return False
  265. #comprueba que no hay dos acciones accidentales en la misma combinacion
  266. accidentales = restricciones_df.loc[:,"Tipo"]
  267. num_acc = 0
  268. for iter, acc in enumerate(accidentales):
  269. if acc == "Accidental":
  270. if comb[iter]:
  271. num_acc += 1
  272. if num_acc > 1:
  273. return False
  274. #comprueba que con sismo solo hay una carga variable
  275. sismo = restricciones_df.loc[:,"Accion IAPF"]
  276. num_var = 0
  277. for iter, sis in enumerate(sismo):
  278. if sis == "Sismo":
  279. if comb[iter]:
  280. for jter, _ in enumerate(comb):
  281. if (restricciones_df.loc[jter,"Tipo"] == "Variable") and comb[jter] != 0:
  282. num_var += 1
  283. if num_var > 1:
  284. return False
  285. #si no cumple ninguna de las restricciones se considera válida la combinacion
  286. return True
  287. #funcion principal para crear y validar las combinaciones de cargas
  288. def crear_validar_combinaciones(restricciones_df, compatibilidades_df):
  289. #Se almacena en esta variable un diccionario indicando los estado en los que se puede encontrar la carga
  290. valores_por_patron = {}
  291. for index, row in restricciones_df.iterrows():
  292. patron = restricciones_df.loc[:,restricciones_df.columns[0]]
  293. valores = [0, 1]
  294. if row["Bidireccional?"]:
  295. valores.append(-1)
  296. valores_por_patron[patron[index]] = list(set(valores))
  297. #creacion del array donde se almancenan los nombres de las cargas
  298. patrones = list(valores_por_patron.keys())
  299. #se hace con itertools todas las combinaciones de carga posibles sin ninguna restriccion
  300. todas_combinaciones = list(itertools.product(*[valores_por_patron[pat] for pat in patrones]))
  301. #comprobacion de la validez de las combinaciones
  302. combinaciones_validas = []
  303. for comb in todas_combinaciones:
  304. if validar_combinacion(comb, patrones, compatibilidades_df, restricciones_df):
  305. combinaciones_validas.append(comb)
  306. return combinaciones_validas, patrones
  307. def limpiar_combos(combos, mascara, coef_comp):
  308. combos_limpios = []
  309. for combo in combos:
  310. peligro = 0
  311. combo_masc = np.multiply(combo, mascara)
  312. for i, _ in enumerate(combo_masc):
  313. if combo_masc[i] == coef_comp:
  314. peligro += 1
  315. if peligro < 2:
  316. combos_limpios.append(combo)
  317. return np.array(combos_limpios)
  318. def generar_combinaciones_norma_IAPF(combinaciones_validas, restricciones_df, norma_proyecto, vias_cargadas, patrones):
  319. combos_ELUP = []
  320. combos_ELUA = []
  321. combos_ELUS = []
  322. combos_ELSC = []
  323. combos_ELSF = []
  324. combos_ELSCP = []
  325. minorados_ELUP = []
  326. minorados_ELSC = []
  327. minorados_ELSF = []
  328. minorados_ELSCP = []
  329. minorados_ELUA = []
  330. minorados_ELUS = []
  331. for combo in combinaciones_validas:
  332. coeficientes_ELUP = np.zeros(len(patrones))
  333. coeficientes_ELUA = np.zeros(len(patrones))
  334. coeficientes_ELUS = np.zeros(len(patrones))
  335. coeficientes_ELSC = np.zeros(len(patrones))
  336. coeficientes_ELSF = np.zeros(len(patrones))
  337. coeficientes_ELSCP = np.zeros(len(patrones))
  338. n_var = 0
  339. n_acc = 0
  340. for i in range(len(combo)):
  341. if norma_proyecto == "IAPF":
  342. #primero se comprueba si la carga es permanente o no
  343. if restricciones_df.loc[i,"Permanentes"]:
  344. #luego constante o no
  345. if restricciones_df.loc[i,"Tipo"] == "Constante":
  346. if restricciones_df.loc[i,"Direccion"] == "Desfavorable":
  347. #ELU
  348. coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Persistente"]["Cte"]
  349. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Cte"]
  350. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Cte"]
  351. #ELS
  352. coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Cte"]
  353. coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Cte"]
  354. coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Cte"]
  355. elif restricciones_df.loc[i,"Direccion"] == "Favorable":
  356. #ELU
  357. coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Favorable"]["Persistente"]["Cte"]
  358. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Cte"]
  359. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Cte"]
  360. #ELS
  361. coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Cte"]
  362. coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Cte"]
  363. coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Cte"]
  364. elif restricciones_df.loc[i,"Tipo"] == "No Constante":
  365. if restricciones_df.loc[i,"Direccion"] == "Desfavorable":
  366. #ELU
  367. coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Persistente"]["NoCte"]
  368. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["NoCte"]
  369. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["NoCte"]
  370. #ELS
  371. coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["NoCte"]
  372. coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["NoCte"]
  373. coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["NoCte"]
  374. elif restricciones_df.loc[i,"Direccion"] == "Favorable":
  375. coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Favorable"]["Persistente"]["NoCte"]
  376. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["NoCte"]
  377. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["NoCte"]
  378. #ELS
  379. coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["NoCte"]
  380. coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["NoCte"]
  381. coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["NoCte"]
  382. elif restricciones_df.loc[i,"Tipo"] == "Accidental":
  383. if combo[i] != 0: n_acc += 1
  384. if restricciones_df.loc[i,"Direccion"] == "Desfavorable":
  385. #ELU
  386. coeficientes_ELUP[i] = 0
  387. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Accidental"]
  388. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Accidental"]
  389. #ELS
  390. coeficientes_ELSC[i] = 0
  391. coeficientes_ELSF[i] = 0
  392. coeficientes_ELSCP[i] = 0
  393. elif restricciones_df.loc[i,"Direccion"] == "Favorable":
  394. #ELU
  395. coeficientes_ELUP[i] = 0
  396. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Accidental"]
  397. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Accidental"]
  398. #ELS
  399. coeficientes_ELSC[i] = 0
  400. coeficientes_ELSF[i] = 0
  401. coeficientes_ELSCP[i] = 0
  402. elif restricciones_df.loc[i,"Tipo"] == "Variable":
  403. if combo[i] != 0: n_var += 1
  404. if restricciones_df.loc[i,"Direccion"] == "Desfavorable":
  405. #ELU
  406. coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Persistente"]["Variable"]
  407. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Variable"]
  408. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Variable"]
  409. #ELS
  410. coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Variable"]
  411. coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Variable"]
  412. coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Variable"]
  413. elif restricciones_df.loc[i,"Direccion"] == "Favorable":
  414. #ELU
  415. coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Favorable"]["Persistente"]["Variable"]
  416. coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Variable"]
  417. coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Variable"]
  418. #ELS
  419. coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Variable"]
  420. coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Variable"]
  421. coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Variable"]
  422. elif norma_proyecto == "IAP":
  423. pass
  424. minorados_ELUP.clear()
  425. minorados_ELUA.clear()
  426. minorados_ELUS.clear()
  427. minorados_ELSC.clear()
  428. minorados_ELSF.clear()
  429. minorados_ELSCP.clear()
  430. if n_acc:
  431. coef_var_ELUS = np.ones(len(patrones))
  432. coef_var_ELUA = np.ones(len(patrones))
  433. for i in range(len(combo)):
  434. if (restricciones_df.loc[i,"Accion IAPF"] == "Sismo") and combo[i] != 0:
  435. for j in range(len(combo)):
  436. if (restricciones_df.loc[j,"Tipo"] == "Variable") and j:
  437. if restricciones_df.loc[j,"Accion IAPF"] == "Trafico":
  438. coef_var_ELUS[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
  439. if restricciones_df.loc[j,"Accion IAPF"] == "Resto":
  440. coef_var_ELUS[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
  441. minorados_ELUS.append(coef_var_ELUS)
  442. if (restricciones_df.loc[i,"Accion IAPF"] != "Sismo") and (restricciones_df.loc[i,"Tipo"] == "Accidental") and combo[i] != 0:
  443. appended_for_acc = False
  444. for k in range(len(combo)):
  445. coef_var_ELUA = np.ones(len(patrones))
  446. if (restricciones_df.loc[k,"Tipo"] == "Variable") and combo[k] != 0:
  447. if restricciones_df.loc[k,"Accion IAPF"] == "Trafico":
  448. coef_var_ELUA[k] = normas["IAPF"]["CoefVar"]["Trafico"]["psi1"][vias_cargadas if int(vias_cargadas) < 4 else "3"]
  449. else:
  450. coef_var_ELUA[k] = normas["IAPF"]["CoefVar"]["Resto"]["psi1"]
  451. for j in range(len(combo)):
  452. if (restricciones_df.loc[j,"Tipo"] == "Variable") and (j != k):
  453. #se asigna el coeficiente de la variable al resto de variables
  454. if restricciones_df.loc[j,"Accion IAPF"] == "Trafico":
  455. coef_var_ELUA[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
  456. else:
  457. coef_var_ELUA[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
  458. minorados_ELUA.append(coef_var_ELUA)
  459. appended_for_acc = True
  460. # Si no se encontraron variables activas, añadimos el vector por defecto (unos)
  461. if not appended_for_acc:
  462. minorados_ELUA.append(np.ones(len(patrones)))
  463. else:
  464. if n_var == 1:
  465. coef_var_ELSF = np.ones(len(patrones))
  466. coef_var_ELSCP = np.ones(len(patrones))
  467. for i in range(len(combo)):
  468. if (restricciones_df.loc[i,"Tipo"] == "Variable") and combo[i] != 0:
  469. if restricciones_df.loc[i,"Accion IAPF"] == "Trafico":
  470. coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi1"][vias_cargadas if int(vias_cargadas) < 4 else "3"]
  471. coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
  472. else:
  473. coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi1"]
  474. coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
  475. while n_var > 1:
  476. n_var -= 1
  477. #se busca la primera variable en el combo y se asigna el coeficiente
  478. for i in range(len(combo)):
  479. coef_var_ELUP = np.ones(len(patrones))
  480. coef_var_ELSC = np.ones(len(patrones))
  481. coef_var_ELSF = np.ones(len(patrones))
  482. coef_var_ELSCP =np.ones(len(patrones))
  483. if (restricciones_df.loc[i,"Tipo"] == "Variable") and combo[i] != 0:
  484. if restricciones_df.loc[i,"Accion IAPF"] == "Trafico":
  485. coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi1"][vias_cargadas if int(vias_cargadas) < 4 else "3"]
  486. coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
  487. else:
  488. coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi1"]
  489. coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
  490. for j in range(len(combo)):
  491. if (restricciones_df.loc[j,"Tipo"] == "Variable") and (j != i):
  492. #se asigna el coeficiente de la variable al resto de variables
  493. if restricciones_df.loc[j,"Accion IAPF"] == "Trafico":
  494. coef_var_ELUP[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi0"]
  495. coef_var_ELSC[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi0"]
  496. coef_var_ELSF[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
  497. coef_var_ELSCP[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
  498. else:
  499. coef_var_ELUP[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi0"]
  500. coef_var_ELSC[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi0"]
  501. coef_var_ELSF[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
  502. coef_var_ELSCP[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
  503. minorados_ELUP.append(coef_var_ELUP)
  504. minorados_ELSC.append(coef_var_ELSC)
  505. minorados_ELSF.append(coef_var_ELSF)
  506. minorados_ELSCP.append(coef_var_ELSCP)
  507. if minorados_ELUP:
  508. for minorado in minorados_ELUP:
  509. combos_ELUP.append(np.multiply(np.multiply(coeficientes_ELUP, combo),minorado))
  510. for minorado in minorados_ELSC:
  511. combos_ELSC.append(np.multiply(np.multiply(coeficientes_ELSC, combo),minorado))
  512. for minorado in minorados_ELSF:
  513. combos_ELSF.append(np.multiply(np.multiply(coeficientes_ELSF, combo),minorado))
  514. for minorado in minorados_ELSCP:
  515. combos_ELSCP.append(np.multiply(np.multiply(coeficientes_ELSCP, combo),minorado))
  516. else:
  517. combos_ELUP.append(np.multiply(coeficientes_ELUP, combo))
  518. combos_ELSC.append(np.multiply(coeficientes_ELSC, combo))
  519. 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))
  520. 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))
  521. if minorados_ELUS:
  522. for minorado in minorados_ELUS:
  523. combos_ELUS.append(np.multiply(np.multiply(coeficientes_ELUS, combo),minorado))
  524. if minorados_ELUA:
  525. for minorado in minorados_ELUA:
  526. combos_ELUA.append(np.multiply(np.multiply(coeficientes_ELUA, combo),minorado))
  527. combos_ELUP = np.unique(np.array(combos_ELUP), axis=0)
  528. combos_ELUA = np.unique(np.array(combos_ELUA), axis=0)
  529. combos_ELUS = np.unique(np.array(combos_ELUS), axis=0)
  530. combos_ELSC = np.unique(np.array(combos_ELSC), axis=0)
  531. combos_ELSF = np.unique(np.array(combos_ELSF), axis=0)
  532. combos_ELSCP = np.unique(np.array(combos_ELSCP), axis=0)
  533. restricciones_array = restricciones_df.loc[:,"Tipo"]
  534. mascara = np.multiply(np.ones(len(restricciones_array)), (restricciones_array == "Variable").astype(int))
  535. combos_ELUP = limpiar_combos(combos_ELUP, mascara, 1.5)
  536. combos_ELSC = limpiar_combos(combos_ELSC, mascara, 1)
  537. combos_ELSF = limpiar_combos(combos_ELSF, mascara, 1)
  538. combos_ELSCP = limpiar_combos(combos_ELSCP, mascara, 1)
  539. return combos_ELUP, combos_ELUA, combos_ELUS, combos_ELSC, combos_ELSF, combos_ELSCP
  540. def agregar_combinaciones_carga(combos_data, nombre_tipo, total_combos, patrones, acum):
  541. combo_num = 0
  542. for combo in combos_data:
  543. combo_name = f"{nombre_tipo}_{combo_num:03d}"
  544. ret = SapModel.RespCombo.Add(combo_name, 0)
  545. for idx, patron in enumerate(patrones):
  546. coeficiente = combo[idx]
  547. if coeficiente != 0:
  548. ret = SapModel.RespCombo.SetCaseList(combo_name, 0, patron, coeficiente)
  549. printProgressBar(combo_num + acum, total_combos, prefix = f'Creando combos {nombre_tipo}:', suffix = 'Completado', length = 50)
  550. combo_num += 1
  551. return combo_num
  552. def crear_combo_envolvente(combo_name = "", busca = "", total_envolventes = 0, acumulador = 0):
  553. contador_envolvente = 0
  554. comboNames = SapModel.RespCombo.GetNameList()
  555. patron = []
  556. for j in range(comboNames[0]):
  557. if busca in comboNames[1][j]: patron.append(comboNames[1][j])
  558. if len(patron):
  559. ret = SapModel.RespCombo.Add(combo_name, 1)
  560. for i, name in enumerate(patron):
  561. ret = SapModel.RespCombo.SetCaseList(combo_name, 1, name, 1)
  562. contador_envolvente += 1
  563. printProgressBar(contador_envolvente + acumulador, total_envolventes, prefix = f'Creando {combo_name} envolvente:', suffix = 'Completado', length = 50)
  564. return len(patron)
  565. def main(ruta_excel, norma_proyecto, vias_cargadas):
  566. compatibilidades_df, restricciones_df =extraer_datos_excel(ruta_excel)
  567. creaccion_acciones(restricciones_df)
  568. combinaciones_validas, patrones = crear_validar_combinaciones(restricciones_df, compatibilidades_df)
  569. combos_ELUP, combos_ELUA, combos_ELUS, combos_ELSC, combos_ELSF, combos_ELSCP = \
  570. generar_combinaciones_norma_IAPF(combinaciones_validas, restricciones_df, norma_proyecto, vias_cargadas, patrones)
  571. tot_combos = len(combos_ELUP) + len(combos_ELSC) + len(combos_ELSF) + len(combos_ELSCP) + len(combos_ELUA) + len(combos_ELUS)
  572. acum_c = agregar_combinaciones_carga(combos_ELUP, "ELU_P", tot_combos, patrones, 0)
  573. acum_c += agregar_combinaciones_carga(combos_ELUA, "ELU_ACC", tot_combos, patrones, acum_c)
  574. acum_c += agregar_combinaciones_carga(combos_ELUS, "ELU_SIS", tot_combos, patrones, acum_c)
  575. acum_c += agregar_combinaciones_carga(combos_ELSC, "ELS_C_", tot_combos, patrones, acum_c)
  576. acum_c += agregar_combinaciones_carga(combos_ELSF, "ELS_F_", tot_combos, patrones, acum_c)
  577. _ = agregar_combinaciones_carga(combos_ELSCP, "ELS_CP", tot_combos, patrones, acum_c)
  578. print("")
  579. total_envolventes = 0
  580. temp_comboNames = SapModel.RespCombo.GetNameList()
  581. for combo_type in ["ELU_P", "ELU_ACC", "ELU_SIS", "ELS_C_", "ELS_F_", "ELS_CP"]:
  582. total_envolventes += sum(1 for idx in range(temp_comboNames[0]) if combo_type in temp_comboNames[1][idx])
  583. acum = crear_combo_envolvente("1. ENV ELU P", "ELU_P", total_envolventes, 0)
  584. acum += crear_combo_envolvente("2. ENV ELU ACC", "ELU_ACC", total_envolventes, acum)
  585. acum += crear_combo_envolvente("3. ENV ELU SIS", "ELU_SIS", total_envolventes, acum)
  586. acum += crear_combo_envolvente("4. ENV ELS C", "ELS_C_", total_envolventes, acum)
  587. acum += crear_combo_envolvente("5. ENV ELS F", "ELS_F_", total_envolventes, acum)
  588. _ = crear_combo_envolvente("6. ENV ELS CP", "ELS_CP", total_envolventes, acum)
  589. def crear_ventana_configuracion():
  590. """Crea una ventana gráfica para configuración inicial"""
  591. ventana = tk.Tk()
  592. ventana.title("Configuración de Combinaciones")
  593. ventana.geometry("600x800")
  594. ventana.attributes('-topmost', True)
  595. script_dir = os.path.dirname(os.path.abspath(__file__))
  596. icon_path = os.path.join(script_dir, 'AYRE.ico')
  597. ventana.iconbitmap(icon_path)
  598. # Título
  599. titulo = tk.Label(ventana, text="Configuración Inicial", font=("Arial", 14, "bold"))
  600. titulo.pack(pady=10)
  601. # Checkbox 1: Borrar combinaciones
  602. var_combos = tk.BooleanVar(value=True)
  603. check_combos = tk.Checkbutton(ventana, text="Borrar combinaciones existentes", variable=var_combos, font=("Arial", 10))
  604. check_combos.pack(anchor=tk.W, padx=20, pady=5)
  605. # Checkbox 2: Borrar cargas
  606. var_cargas = tk.BooleanVar(value=True)
  607. check_cargas = tk.Checkbutton(ventana, text="Borrar cargas existentes", variable=var_cargas, font=("Arial", 10))
  608. check_cargas.pack(anchor=tk.W, padx=20, pady=5)
  609. # Botón Borrar Todo
  610. def on_borrar_todo():
  611. if var_combos.get():
  612. borrar_combos_existentes()
  613. if var_cargas.get():
  614. borrar_load_cases()
  615. borrar_patrones_carga()
  616. boton_borrar = tk.Button(ventana, text="Borrar Selección", command=on_borrar_todo, font=("Arial", 11), bg="#f44336", fg="white", padx=10, pady=5)
  617. boton_borrar.pack()
  618. # Frame para norma
  619. frame_norma = tk.Frame(ventana)
  620. frame_norma.pack(anchor=tk.W, padx=20, pady=10)
  621. label_norma = tk.Label(frame_norma, text="Norma:", font=("Arial", 10))
  622. label_norma.pack(side=tk.LEFT, padx=5)
  623. var_norma = tk.StringVar(value="IAPF")
  624. combo_norma = tk.ttk.Combobox(frame_norma, textvariable=var_norma, values=["IAPF", "IAP"], state="readonly", width=15)
  625. combo_norma.pack(side=tk.LEFT, padx=5)
  626. # Frame para vías
  627. frame_vias = tk.Frame(ventana)
  628. frame_vias.pack(anchor=tk.W, padx=20, pady=10)
  629. label_vias = tk.Label(frame_vias, text="Vías cargadas:", font=("Arial", 10))
  630. label_vias.pack(side=tk.LEFT, padx=5)
  631. var_vias = tk.StringVar(value="1")
  632. combo_vias = tk.ttk.Combobox(frame_vias, textvariable=var_vias, values=["1", "2", "3", "Más de 3"], state="readonly", width=15)
  633. combo_vias.pack(side=tk.LEFT, padx=5)
  634. # Frame para selección de archivo Excel
  635. frame_excel = tk.Frame(ventana)
  636. frame_excel.pack(anchor=tk.W, padx=20, pady=10)
  637. label_excel = tk.Label(frame_excel, text="Archivo Excel:", font=("Arial", 10))
  638. label_excel.pack(side=tk.LEFT, padx=5)
  639. var_excel = tk.StringVar()
  640. entry_excel = tk.Entry(frame_excel, textvariable=var_excel, width=40)
  641. entry_excel.pack(side=tk.LEFT, padx=5)
  642. def browse_excel():
  643. ruta = askopenfilename(filetypes=[("Excel files", "*.xlsx *.xls")])
  644. if ruta:
  645. var_excel.set(ruta)
  646. boton_ok.config(state=tk.NORMAL)
  647. boton_browse = tk.Button(frame_excel, text="Seleccionar", command=browse_excel, font=("Arial", 10))
  648. boton_browse.pack(side=tk.LEFT, padx=5)
  649. # Botón OK
  650. def on_ok():
  651. main(var_excel.get(), var_norma.get(), var_vias.get())
  652. boton_ok = tk.Button(ventana, text="Crear combos", command=on_ok, font=("Arial", 11), bg="#4CAF50", fg="white", padx=10, pady=5)
  653. boton_ok.pack(pady=20)
  654. boton_ok.config(state=tk.DISABLED)
  655. # Boton extraer datos
  656. def on_extraer():
  657. extraer_combinaciones_a_excel(SapModel, var_excel.get())
  658. boton_extraer = tk.Button(ventana, text="Extraer datos", command=on_extraer, font=("Arial", 11), bg="#FF9800", fg="white", padx=10, pady=5)
  659. boton_extraer.pack(pady=20)
  660. # Boton extraer flechas
  661. def on_deflection():
  662. extraer_flechas(SapModel, var_excel.get(), var_flechas.get())
  663. # Frame para flechas
  664. frame_flechas = tk.Frame(ventana)
  665. frame_flechas.pack(anchor=tk.CENTER, padx=20, pady=10)
  666. var_flechas = tk.StringVar(value="1. ENV ELU P")
  667. combo_flechas = tk.ttk.Combobox(frame_flechas, textvariable=var_flechas,
  668. 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"],
  669. state="readonly", width=15)
  670. combo_flechas.pack(side=tk.RIGHT, padx=5)
  671. boton_deflection = tk.Button(ventana, text="Extraer flechas", command=on_deflection, font=("Arial", 11), bg="#2196F3", fg="white", padx=10, pady=5)
  672. boton_deflection.pack(pady=20)
  673. # Boton extraer esfuerzos
  674. def on_esfuerzos():
  675. extraer_esfuerzos(SapModel, var_excel.get(), var_flechas.get())
  676. # Frame para esfuerzos
  677. frame_esfuerzos = tk.Frame(ventana)
  678. frame_esfuerzos.pack(anchor=tk.CENTER, padx=20, pady=10)
  679. var_esfuerzos = tk.StringVar(value="1. ENV ELU P")
  680. combo_esfuerzos = tk.ttk.Combobox(frame_esfuerzos, textvariable=var_esfuerzos,
  681. 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"],
  682. state="readonly", width=15)
  683. combo_esfuerzos.pack(side=tk.RIGHT, padx=5)
  684. boton_esfuerzos = tk.Button(ventana, text="Extraer esfuerzos", command=on_esfuerzos, font=("Arial", 11), bg="#2196F3", fg="white", padx=10, pady=5)
  685. boton_esfuerzos.pack(pady=20)
  686. def comprobacion_SAP_cerrado():
  687. try:
  688. ret = SapModel.Analyze.GetCaseStatus()
  689. if ret[0] > 0:
  690. estados = ret[2]
  691. if any(estado == 4 for estado in estados):
  692. boton_extraer.config(state=tk.NORMAL)
  693. boton_deflection.config(state=tk.NORMAL)
  694. boton_esfuerzos.config(state=tk.NORMAL)
  695. else:
  696. boton_extraer.config(state=tk.DISABLED)
  697. boton_deflection.config(state=tk.DISABLED)
  698. boton_esfuerzos.config(state=tk.DISABLED)
  699. except (comtypes.COMError, Exception) as e:
  700. sys.exit(0) # Cierra la aplicación si SAP2000 está cerrado
  701. ventana.after(1000, comprobacion_SAP_cerrado) # Verifica cada segundo
  702. comprobacion_SAP_cerrado()
  703. ventana.mainloop()
  704. # Mostrar ventana de configuración
  705. config = crear_ventana_configuracion()