milcapy 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. milcapy-0.1.0/PKG-INFO +627 -0
  2. milcapy-0.1.0/README.md +614 -0
  3. milcapy-0.1.0/milcapy/__init__.py +29 -0
  4. milcapy-0.1.0/milcapy/analysis/__init__.py +0 -0
  5. milcapy-0.1.0/milcapy/analysis/linear_static.py +392 -0
  6. milcapy-0.1.0/milcapy/analysis/manager.py +101 -0
  7. milcapy-0.1.0/milcapy/core/__init__.py +0 -0
  8. milcapy-0.1.0/milcapy/core/node.py +94 -0
  9. milcapy-0.1.0/milcapy/core/results.py +256 -0
  10. milcapy-0.1.0/milcapy/elements/CST.py +137 -0
  11. milcapy-0.1.0/milcapy/elements/MQ6.py +330 -0
  12. milcapy-0.1.0/milcapy/elements/MQ6I.py +246 -0
  13. milcapy-0.1.0/milcapy/elements/MQ6IMod.py +40 -0
  14. milcapy-0.1.0/milcapy/elements/__init__.py +0 -0
  15. milcapy-0.1.0/milcapy/elements/member.py +390 -0
  16. milcapy-0.1.0/milcapy/elements/truss.py +133 -0
  17. milcapy-0.1.0/milcapy/loads/__init__.py +9 -0
  18. milcapy-0.1.0/milcapy/loads/load.py +1100 -0
  19. milcapy-0.1.0/milcapy/loads/load_pattern.py +419 -0
  20. milcapy-0.1.0/milcapy/material/__init__.py +0 -0
  21. milcapy-0.1.0/milcapy/material/material.py +68 -0
  22. milcapy-0.1.0/milcapy/model/__init__.py +0 -0
  23. milcapy-0.1.0/milcapy/model/model.py +1482 -0
  24. milcapy-0.1.0/milcapy/plotter/UIdisplay.py +926 -0
  25. milcapy-0.1.0/milcapy/plotter/__init__.py +0 -0
  26. milcapy-0.1.0/milcapy/plotter/load.py +454 -0
  27. milcapy-0.1.0/milcapy/plotter/options.py +450 -0
  28. milcapy-0.1.0/milcapy/plotter/plotter.py +2115 -0
  29. milcapy-0.1.0/milcapy/plotter/plotter_values.py +219 -0
  30. milcapy-0.1.0/milcapy/plotter/suports.py +322 -0
  31. milcapy-0.1.0/milcapy/plotter/utils.py +103 -0
  32. milcapy-0.1.0/milcapy/plotter/widgets.py +569 -0
  33. milcapy-0.1.0/milcapy/postprocess/CST_pp.py +55 -0
  34. milcapy-0.1.0/milcapy/postprocess/__init__.py +0 -0
  35. milcapy-0.1.0/milcapy/postprocess/membranebQ6.py +7 -0
  36. milcapy-0.1.0/milcapy/postprocess/post_processing.py +220 -0
  37. milcapy-0.1.0/milcapy/postprocess/segment_member.py +406 -0
  38. milcapy-0.1.0/milcapy/report/__init__.py +0 -0
  39. milcapy-0.1.0/milcapy/report/report.py +26 -0
  40. milcapy-0.1.0/milcapy/section/__init__.py +0 -0
  41. milcapy-0.1.0/milcapy/section/section.py +304 -0
  42. milcapy-0.1.0/milcapy/utils/__init__.py +24 -0
  43. milcapy-0.1.0/milcapy/utils/element.py +283 -0
  44. milcapy-0.1.0/milcapy/utils/geometry.py +106 -0
  45. milcapy-0.1.0/milcapy/utils/types.py +96 -0
  46. milcapy-0.1.0/milcapy.egg-info/PKG-INFO +627 -0
  47. milcapy-0.1.0/milcapy.egg-info/SOURCES.txt +49 -0
  48. milcapy-0.1.0/milcapy.egg-info/dependency_links.txt +1 -0
  49. milcapy-0.1.0/milcapy.egg-info/top_level.txt +1 -0
  50. milcapy-0.1.0/pyproject.toml +26 -0
  51. milcapy-0.1.0/setup.cfg +4 -0
milcapy-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,627 @@
1
+ Metadata-Version: 2.4
2
+ Name: milcapy
3
+ Version: 0.1.0
4
+ Summary: Librería para el análisis de estructuras 2D (Frame, Truss, CST, Membrana Q6, Q6i).
5
+ Author-email: Amilcar Machacca Mayo <200190@unsaac.edu.pe>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Milca-py/MilcaStructures
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+
14
+ # Milca Structures
15
+ ---
16
+
17
+ ## milcapy
18
+ ## <img src="assets/logo.png" alt="Logo" width="100" height="100">
19
+ Biblioteca para el análisis estructural de **marcos en 2D**, con soporte para elementos **membrana Q6**, **CST** y elementos con **modos incompatibles** para evitar el bloqueo por cortante.
20
+
21
+ Implementa el **método de rigidez directa** y el **método de los elementos finitos** para membranas, con **solución cerrada** en elementos unidimensionales (1D).
22
+ Además, incorpora conceptos avanzados de **análisis matricial de estructuras**.
23
+
24
+ Desarrollado por **Amilcar Machacca Mayo**
25
+
26
+ ---
27
+
28
+ ### Características principales
29
+
30
+ - **Definición de materiales**
31
+ - **Definición de secciones**
32
+ - Rectangulares
33
+ - Circulares
34
+ - Genéricas
35
+ - Tipo cáscara
36
+ - **Definición de nodos**
37
+ - **Definición de elementos**
38
+ - Vigas (marcos)
39
+ - Vigas de **Timoshenko**
40
+ - Vigas de **Euler-Bernoulli**
41
+ - Armaduras
42
+ - Membranas
43
+ - CST (Constant Strain Triangle)
44
+ - Q6 (Quadrilateral 4 nodos & 3dof por nodo)
45
+ - Q6i (Q6 con modos incompatibles)
46
+ - **Patrones de carga**
47
+ - **Modificadores de propiedades de sección**
48
+ - **Condiciones de frontera**
49
+ - Restricciones convencionales
50
+ - Apoyos elásticos
51
+ - Definición de eje local para nodos
52
+ - **Cargas**
53
+ - Cargas nodales
54
+ - Cargas distribuidas
55
+ - Peso propio
56
+ - **Opciones avanzadas**
57
+ - Desfase de extremos (brazos rígidos)
58
+ - Liberaciones
59
+ - **Resultados**
60
+ - Obtención de la matriz de rigidez global
61
+ - Vector de cargas por patrón de carga
62
+ - Resultados de los nodos
63
+ - Resultados de los miembros
64
+ - **Visualización interactiva** del modelo
65
+
66
+ ---
67
+
68
+ ### Instalación
69
+
70
+ ```bash
71
+ pip install milcapy
72
+ ```
73
+
74
+ ### Comandos de importacion
75
+
76
+ ```python
77
+ from milcapy import (
78
+ SystemModel,
79
+ BeamTheoriesType,
80
+ CoordinateSystemType,
81
+ DirectionType,
82
+ StateType,
83
+ LoadType,
84
+ model_viewer,
85
+ FieldTypeMembrane,
86
+ ConstitutiveModel,
87
+ )
88
+ ```
89
+ > - `SystemModel` → Plano de contruccion para crear el modelo
90
+ > - `BeamTheoriesType` → Tipos de teorías de vigas
91
+ > - `CoordinateSystemType` → Tipos de sistemas de coordenadas
92
+ > - `DirectionType` → Tipos de direcciones
93
+ > - `StateType` → Tipos de estados
94
+ > - `LoadType` → Tipos de cargas
95
+ > - `model_viewer` → Para visualizar el modelo
96
+ > - `FieldTypeMembrane` → Tipos de campos para membranas
97
+ > - `ConstitutiveModel` → Tipos de estados constitutivos para membranas
98
+
99
+ ### 1. Comandos de modelo
100
+
101
+ ```python
102
+ model = SystemModel()
103
+ ```
104
+
105
+ > - `model` (`SystemModel`) → Modelo vacio creado
106
+
107
+ ### 2. comando de material
108
+
109
+ ```python
110
+ model.add_material('name', 'modulus_elasticity', 'poisson_ratio', 'specific_weight=0')
111
+ ```
112
+
113
+ > - `name` (`str`) → Nombre del material
114
+ > - `modulus_elasticity` (`float`) → Módulo de elasticidad
115
+ > - `poisson_ratio` (`float`) → Coeficiente de Poisson
116
+ > - `specific_weight` (`float`) → Peso específico (opcional)
117
+
118
+ ### 3. Comando de seccion
119
+
120
+ #### 3.1. Comando de seccion rectangular
121
+
122
+ ```python
123
+ model.add_rectangular_section('name', 'material_name', 'base', 'height')
124
+ ```
125
+
126
+ > - `name` (`str`) → Nombre de la sección
127
+ > - `material_name` (`str`) → Nombre del material
128
+ > - `base` (`float`) → Base de la sección
129
+ > - `height` (`float`) → Altura de la sección
130
+
131
+ #### 3.2. Comando de seccion circular
132
+
133
+ ```python
134
+ model.add_circular_section('name', 'material_name', 'diameter')
135
+ ```
136
+
137
+ > - `name` (`str`) → Nombre de la sección
138
+ > - `material_name` (`str`) → Nombre del material
139
+ > - `diameter` (`float`) → Diámetro de la sección
140
+
141
+ #### 3.3. Comando de seccion generica
142
+
143
+ ```python
144
+ model.add_generic_section('name', 'material_name', 'area', 'inertia', 'k_factor')
145
+ ```
146
+
147
+ > - `name` (`str`) → Nombre de la sección
148
+ > - `material_name` (`str`) → Nombre del material
149
+ > - `area` (`float`) → Área de la sección
150
+ > - `inertia` (`float`) → Momento de inercia de la sección
151
+ > - `k_factor` (`float`) → Coeficiente de corte de la sección (Ac = A * k_factor)
152
+
153
+ #### 3.4. Comando de seccion de cascaras
154
+
155
+ ```python
156
+ model.add_shell_section('name', 'material_name', 'thickness')
157
+ ```
158
+
159
+ > - `name` (`str`) → Nombre de la sección
160
+ > - `material_name` (`str`) → Nombre del material
161
+ > - `thickness` (`float`) → Grosor de la sección
162
+
163
+ ### 4. Comando de nodo
164
+
165
+ ```python
166
+ model.add_node('id', 'x', 'y')
167
+ ```
168
+
169
+ > - `id` (`int`) → ID del nodo
170
+ > - `x` (`float`) → Coordenada x del nodo
171
+ > - `y` (`float`) → Coordenada y del nodo
172
+ >> **⚠️ NOTA IMPORTANTE:** los ID's deben ser ordenados y secuenciales (1, 2, 3, ...)
173
+
174
+ ### 5. Comando de elemento marco
175
+
176
+ #### 5.1. Comando de marco implemetadas con las teorías de viga de Timoshenko y Euler-Bernoulli
177
+
178
+
179
+ ```python
180
+ model.add_member('id', 'node_i_id', 'node_j_id', 'section_name', 'beam_theory=BeamTheoriesType.TIMOSHENKO')
181
+ ```
182
+
183
+ > - `id` (`int`) → ID del miembro
184
+ > - `node_i_id` (`int`) → ID del nodo inicial
185
+ > - `node_j_id` (`int`) → ID del nodo final
186
+ > - `section_name` (`str`) → Nombre de la sección
187
+ > - `beam_theory` (`str` ó `BeamTheoriesType`) → Teoría de la viga (opcional)
188
+ >> **VIGAS DISPONIBLES:** 'TIMOSHENKO', 'EULER_BERNOULLI'
189
+
190
+ #### 5.2. Comando de viga de Timoshenko (marco)
191
+
192
+ ```python
193
+ model.add_elastic_timoshenko_beam('id', 'node_i_id', 'node_j_id', 'section_name')
194
+ ```
195
+
196
+ > - `id` (`int`) → ID del miembro
197
+ > - `node_i_id` (`int`) → ID del nodo inicial
198
+ > - `node_j_id` (`int`) → ID del nodo final
199
+ > - `section_name` (`str`) → Nombre de la sección
200
+
201
+ #### 5.3. Comando de viga de Euler-Bernoulli (marco)
202
+
203
+ ```python
204
+ model.add_elastic_euler_bernoulli_beam('id', 'node_i_id', 'node_j_id', 'section_name')
205
+ ```
206
+
207
+ > - `id` (`int`) → ID del miembro
208
+ > - `node_i_id` (`int`) → ID del nodo inicial
209
+ > - `node_j_id` (`int`) → ID del nodo final
210
+ > - `section_name` (`str`) → Nombre de la sección
211
+
212
+ ### 6. Comando de elemento de Armadura
213
+
214
+ ```python
215
+ model.add_truss('id', 'node_i_id', 'node_j_id', 'section_name')
216
+ ```
217
+
218
+ > - `id` (`int`) → ID del miembro
219
+ > - `node_i_id` (`int`) → ID del nodo inicial
220
+ > - `node_j_id` (`int`) → ID del nodo final
221
+ > - `section_name` (`str`) → Nombre de la sección
222
+
223
+
224
+ ### 7. Comando de elemento de **membrana**
225
+ #### 7.1. Comando de elemento de membrana CST
226
+ El elemento de membrana CST (*Constant Strain Triangle*) es un elemento finito bidimensional de tres nodos.
227
+ Se utiliza para modelar membranas planas sometidas a esfuerzos en su plano.
228
+
229
+ Cada nodo posee dos grados de libertad de traslación (en `x` y `y`). La deformación se considera constante dentro del triángulo,
230
+ por lo que es adecuado para geometrías simples o como base en mallados más refinados.
231
+
232
+ ```python
233
+ model.add_cst('id', 'node_i_id', 'node_j_id', 'node_k_id', 'section_name', 'state=ConstitutiveModel.PLANE_STRESS')
234
+ ```
235
+
236
+ > - `id` (`int`) → ID del miembro
237
+ > - `node_i_id` (`int`) → ID del nodo inicial
238
+ > - `node_j_id` (`int`) → ID del nodo final
239
+ > - `node_k_id` (`int`) → ID del nodo final
240
+ > - `section_name` (`str`) → Nombre de la sección
241
+ > - `state` (`ConstitutiveModel`) → Estado constitutivo del elemento
242
+ >> ⚠️ **Nota:** La enumeración de los nodos debe realizarse en sentido antihorario para garantizar una formulación correcta.
243
+ >> **ESTADOS DISPONIBLES:** 'PLANE_STRESS', 'PLANE_STRAIN'
244
+
245
+ #### 7.2. Comando de elemento de membrana Q6
246
+ El elemento de membrana Q6 (*Quadrilateral with degrees of freedom of perforation*) es un elemento finito bidimensional de cuatro nodos.
247
+
248
+ Cada nodo posee tres grados de libertad; traslacion en `x`, `y` y rotacion en `z`.
249
+
250
+ ```python
251
+ model.add_membrane_q6('id', 'node_i_id', 'node_j_id', 'node_k_id', 'node_l_id', 'section_name')
252
+ ```
253
+
254
+ > - `id` (`int`) → ID del miembro
255
+ > - `node_i_id` (`int`) → ID del nodo inicial
256
+ > - `node_j_id` (`int`) → ID del nodo final
257
+ > - `node_k_id` (`int`) → ID del nodo final
258
+ > - `node_l_id` (`int`) → ID del nodo final
259
+ > - `section_name` (`str`) → Nombre de la sección
260
+ >> ⚠️ **Nota:** La enumeración de los nodos debe realizarse en sentido antihorario para garantizar una formulación correcta.
261
+
262
+
263
+ #### 7.3. Comando de elemento de membrana Q6I
264
+ El elemento de membrana Q6I (*Quadrilateral with Incompatible Modes*) es un elemento finito bidimensional de cuatro nodos.
265
+ Se utiliza para modelar membranas planas sometidas a esfuerzos en su plano.
266
+
267
+ Cada nodo posee dos grados de libertad de traslación (en `x` y `y`).
268
+
269
+ ```python
270
+ model.add_membrane_q6i('id', 'node_i_id', 'node_j_id', 'node_k_id', 'node_l_id', 'section_name')
271
+ ```
272
+
273
+ > - `id` (`int`) → ID del miembro
274
+ > - `node_i_id` (`int`) → ID del nodo inicial
275
+ > - `node_j_id` (`int`) → ID del nodo final
276
+ > - `node_k_id` (`int`) → ID del nodo final
277
+ > - `node_l_id` (`int`) → ID del nodo final
278
+ > - `section_name` (`str`) → Nombre de la sección
279
+ >> ⚠️ **Nota:** La enumeración de los nodos debe realizarse en sentido antihorario para garantizar una formulación correcta.
280
+
281
+
282
+ ### 8. Comando de patron de carga
283
+
284
+ ```python
285
+ model.add_load_pattern('name', 'self_weight_multiplier=0', 'state=StateType.ACTIVE')
286
+ ```
287
+
288
+ > - `name` (`str`) → Nombre del patron de carga
289
+ > - `self_weight_multiplier` (`float`) → Multiplicador del peso propio (opcional)
290
+ > - `state` (`str` ó `StateType`) → Estado del patron de carga (opcional)
291
+ >> **ESTADOS DISPONIBLES:** 'ACTIVE', 'INACTIVE'
292
+
293
+ ```python
294
+ model.set_state_load_pattern('name', 'state=StateType.ACTIVE')
295
+ ```
296
+
297
+ > - `name` (`str`) → Nombre del patron de carga
298
+ > - `state` (`str` ó `StateType`) → Estado del patron de carga
299
+ >> **ESTADOS DISPONIBLES:** 'ACTIVE', 'INACTIVE'
300
+
301
+
302
+
303
+
304
+ ### 9. Comandos de asignacion
305
+ #### 9.1. Comandos de asignacion modificador de propiedades
306
+ ```python
307
+ model.set_property_modifiers('section_name', 'axial_area=1', 'shear_area=1', 'moment_inertia=1', 'weight=1')
308
+ ```
309
+
310
+ > - `section_name` (`str`) → Nombre de la sección
311
+ > - `axial_area` (`float`) → Modificador de área transversal (Opcional)
312
+ > - `shear_area` (`float`) → Modificador de área de corte (Opcional)
313
+ > - `moment_inertia` (`float`) → Modificador de momento de inercia (Opcional)
314
+ > - `weight` (`float`) → Modificador de peso (Opcional)
315
+
316
+
317
+ #### 9.2. Comando de condiciones de frontera
318
+ ##### 9.2.1. Comando de restricciones
319
+ ```python
320
+ model.add_restraint('node_id', 'ux', 'uy', 'rz')
321
+ ```
322
+
323
+ > - `node_id` (`int`) → ID del nodo
324
+ > - `ux` (`bool`) → Restricción de traslación en el eje x
325
+ > - `uy` (`bool`) → Restricción de traslación en el eje y
326
+ > - `rz` (`bool`) → Restricción de rotación en el eje z
327
+
328
+ ##### 9.2.2. Comando de apoyos elásticos
329
+ ```python
330
+ model.add_elastic_support('node_id', 'kx=None', 'ky=None', 'krz=None', 'CSys=CoordinateSystemType.GLOBAL')
331
+ ```
332
+
333
+ > - `node_id` (`int`) → ID del nodo
334
+ > - `kx` (`float`) → Constante de rigidez en X
335
+ > - `ky` (`float`) → Constante de rigidez en Y
336
+ > - `krz` (`float`) → Constante de rigidez en Z
337
+ > - `CSys` (`str` ó `CoordinateSystemType`) → Sistema de coordenadas (opcional)
338
+ >> **CSYS DISPONIBLES:** 'GLOBAL', 'LOCAL'
339
+
340
+ ##### 9.2.3. Comando de eje local
341
+ ```python
342
+ model.add_local_axis_for_node('node_id', 'angle')
343
+ ```
344
+
345
+ > - `node_id` (`int`) → ID del nodo
346
+ > - `angle` (`float`) → Ángulo del eje local en grados
347
+
348
+
349
+
350
+ ##### 9.3. Comando de cargas
351
+
352
+ ###### 9.3.1. Comando de cargas puntuales
353
+ ```python
354
+ model.add_point_load('node_id', 'load_pattern_name', 'fx=0', 'fy=0', 'mz=0', 'CSys=CoordinateSystemType.GLOBAL', 'replace=False')
355
+ ```
356
+
357
+ > - `node_id` (`int`) → ID del nodo
358
+ > - `load_pattern_name` (`str`) → Nombre del patron de carga
359
+ > - `fx` (`float`) → Fuerza en X (opcional)
360
+ > - `fy` (`float`) → Fuerza en Y (opcional)
361
+ > - `mz` (`float`) → Momento en Z (opcional)
362
+ > - `CSys` (`str` ó `CoordinateSystemType`) → Sistema de coordenadas (opcional)
363
+ > - `replace` (`bool`) → Reemplazar la carga existente (opcional)
364
+ >> **CSYS DISPONIBLES:** 'GLOBAL', 'LOCAL'
365
+
366
+
367
+ ###### 9.3.2. Comando de asignacion de desplazamientos
368
+ ```python
369
+ model.add_prescribed_dof('node_id', 'load_pattern_name', 'ux=None', 'uy=None', 'rz=None', 'CSys=CoordinateSystemType.GLOBAL')
370
+ ```
371
+
372
+ > - `node_id` (`int`) → ID del nodo
373
+ > - `load_pattern_name` (`str`) → Nombre del patron de carga
374
+ > - `ux` (`float`) → Desplazamiento en X (opcional)
375
+ > - `uy` (`float`) → Desplazamiento en Y (opcional)
376
+ > - `rz` (`float`) → Rotacion en Z (opcional)
377
+ > - `CSys` (`str` ó `CoordinateSystemType`) → Sistema de coordenadas (opcional)
378
+ >> **CSYS DISPONIBLES:** 'GLOBAL', 'LOCAL'
379
+
380
+
381
+ ###### 9.3.3. Comando de cargas distribuidas
382
+ ```python
383
+ model.add_distributed_load('member_id', 'load_pattern_name', 'load_start=0', 'load_end=0', 'CSys=CoordinateSystemType.GLOBAL', 'direction=DirectionType.LOCAL_2', 'load_type=LoadType.FORCE', 'replace=False')
384
+ ```
385
+
386
+ > - `member_id` (`int`) → ID del miembro
387
+ > - `load_pattern_name` (`str`) → Nombre del patron de carga
388
+ > - `load_start` (`float`) → Magnitud de la carga en el inicio (opcional)
389
+ > - `load_end` (`float`) → Magnitud de la carga en el final (opcional)
390
+ > - `CSys` (`str` ó `CoordinateSystemType`) → Sistema de coordenadas (opcional)
391
+ > - `direction` (`str` ó `DirectionType`) → Dirección de la carga (opcional)
392
+ > - `load_type` (`str` ó `LoadType`) → Tipo de carga (opcional)
393
+ > - `replace` (`bool`) → Reemplazar la carga existente (opcional)
394
+ >> **CSYS DISPONIBLES:** 'GLOBAL', 'LOCAL'
395
+ >> **DIRECCION DISPONIBLES:**
396
+ >>> - **LOCAL:** 'LOCAL_1', 'LOCAL_2', 'LOCAL_3'
397
+ >>> - **GLOBAL:** 'X', 'Y', 'Z', 'X_PROJ', 'Y_PROJ', 'GRAVITY', 'GRAVITY_PROJ'
398
+ >>
399
+ >> **TIPO DE CARGA DISPONIBLES:** 'FORCE'
400
+
401
+ ###### 9.3.4. Comando de cargas de peso propio
402
+ ```python
403
+ model.add_self_weight('load_pattern_name', 'factor=1')
404
+ ```
405
+
406
+ > - `load_pattern_name` (`str`) → Nombre del patron de carga
407
+ > - `factor` (`float`) → Factor de escala para el peso propio (opcional)
408
+
409
+
410
+ #### 9.4. Comando de desface de exremos (brazos rigidos)
411
+ ```python
412
+ model.add_end_length_offset('member_id', 'la=0', 'lb=0', 'qla=True', 'qlb=True', 'fla=1', 'flb=1')
413
+ ```
414
+
415
+ > - `member_id` (`int`) → ID del miembro
416
+ > - `la` (`float`) → Desface de longitud final en el nodo inicial (opcional)
417
+ > - `lb` (`float`) → Desface de longitud final en el nodo final (opcional)
418
+ > - `qla` (`bool`) → Si se aplica la carga en el brazo inicial (opcional)
419
+ > - `qlb` (`bool`) → Si se aplica la carga en el brazo final (opcional)
420
+ > - `fla` (`float`) → Factor de zona rigida del brazo inicial (opcional)
421
+ > - `flb` (`float`) → Factor de zona rigida del brazo final (opcional)
422
+
423
+
424
+ #### 9.5. Comando de liberaciones
425
+ ```python
426
+ model.add_releases('member_id', 'pi=False', 'vi=False', 'mi=False', 'pj=False', 'vj=False', 'mj=False')
427
+ ```
428
+
429
+ > - `member_id` (`int`) → ID del miembro
430
+ > - `pi` (`bool`) → Liberación de fuerza Axial del nodo inicial (opcional)
431
+ > - `vi` (`bool`) → Liberación de cortante del nodo inicial (opcional)
432
+ > - `mi` (`bool`) → Liberación de momento del nodo inicial (opcional)
433
+ > - `pj` (`bool`) → Liberación de fuerza Axial del nodo final (opcional)
434
+ > - `vj` (`bool`) → Liberación de cortante del nodo final (opcional)
435
+ > - `mj` (`bool`) → Liberación de momento del nodo final (opcional)
436
+
437
+ ### 10. Comandos de analisis
438
+ ```python
439
+ model.solve(load_pattern_name=None)
440
+ ```
441
+
442
+ > - `load_pattern_name` (`list[str]` ó `None`) → Nombre de los patrones de carga a resolver (opcional), si es None se resuelve para todos los patrones de carga
443
+
444
+ ### 11. Comandos de postprocesamiento
445
+ #### 11.1. Comando de matriz de rigidez global
446
+ ```python
447
+ matrix: NDAarray = model.get_global_stiffness_matrix()
448
+ ```
449
+
450
+ #### 11.2. Comando de vector de fuerzas global
451
+ ```python
452
+ vector: NDAarray = model.get_global_load_vector('load_pattern_name')
453
+ ```
454
+
455
+ > - `load_pattern_name` (`str`) → Nombre del patron de carga
456
+
457
+ #### 11.3. Comando de graficos
458
+ Este comando abre una ventana interactiva para visualizar el modelo.
459
+ ```python
460
+ model.show()
461
+ ```
462
+
463
+
464
+ ### 12. Comando de resultados
465
+ ```python
466
+ results: Results = model.get_results('load_pattern_name')
467
+ ```
468
+
469
+ > - `results` (`Results`) → Objeto que almacena todos los resultados del análisis.
470
+ > - `load_pattern_name` (`str`) → Nombre del patrón de carga.
471
+
472
+ ---
473
+
474
+ **METODOS DE `Results`**
475
+
476
+ #### 12.1. Resultados a nivel de modelo
477
+ ```python
478
+ displacements: np.ndarray = results.get_model_displacements()
479
+ reactions: np.ndarray = results.get_model_reactions()
480
+ ```
481
+
482
+ > - `displacements` (`np.ndarray`) → Desplazamientos globales del modelo.
483
+ > - `reactions` (`np.ndarray`) → Reacciones globales del modelo.
484
+
485
+ ---
486
+
487
+ #### 12.2. Resultados a nivel de nodos
488
+ ```python
489
+ displacements: np.ndarray = results.get_node_displacements(node_id)
490
+ reactions: np.ndarray = results.get_node_reactions(node_id)
491
+ ```
492
+
493
+ > - `node_id` (`int`) → Identificador del nodo.
494
+ > - `displacements` (`np.ndarray`) → Desplazamientos del nodo.
495
+ > - `reactions` (`np.ndarray`) → Reacciones en el nodo.
496
+
497
+ ---
498
+
499
+ #### 12.3. Resultados a nivel de miembros
500
+ ```python
501
+ displacements: np.ndarray = results.get_member_displacements(member_id)
502
+ internal_forces: np.ndarray = results.get_member_internal_forces(member_id)
503
+ x_val: np.ndarray = results.get_member_x_val(member_id)
504
+ axial_force: np.ndarray = results.get_member_axial_force(member_id)
505
+ shear_force: np.ndarray = results.get_member_shear_force(member_id)
506
+ bending_moment: np.ndarray = results.get_member_bending_moment(member_id)
507
+ deflection: np.ndarray = results.get_member_deflection(member_id)
508
+ slope: np.ndarray = results.get_member_slope(member_id)
509
+ axial_displacement: np.ndarray = results.get_member_axial_displacement(member_id)
510
+ ```
511
+
512
+ > - `member_id` (`int`) → Identificador del miembro.
513
+ > - Cada propiedad retorna un `np.ndarray` con los resultados correspondientes.
514
+
515
+ ---
516
+
517
+ #### 12.4. Resultados de elementos CST (triángulos finitos)
518
+ ```python
519
+ displacements: np.ndarray = results.get_cst_displacements(cst_id)
520
+ strains: np.ndarray = results.get_cst_strains(cst_id)
521
+ stresses: np.ndarray = results.get_cst_stresses(cst_id)
522
+ ```
523
+
524
+ > - `cst_id` (`int`) → Identificador del elemento CST.
525
+ > - `displacements` (`np.ndarray`) → Desplazamientos.
526
+ > - `strains` (`np.ndarray`) → Deformaciones.
527
+ > - `stresses` (`np.ndarray`) → Esfuerzos.
528
+
529
+ ---
530
+
531
+ #### 12.5. Resultados de elementos Membrane Q6
532
+ ```python
533
+ displacements: np.ndarray = results.get_membrane_q6_displacements(membrane_q6_id)
534
+ ```
535
+
536
+ > - `membrane_q6_id` (`int`) → Identificador del elemento Q6.
537
+ > - `displacements` (`np.ndarray`) → Desplazamientos.
538
+
539
+ ---
540
+
541
+ #### 12.6. Resultados de elementos Membrane Q6i
542
+ ```python
543
+ displacements: np.ndarray = results.get_membrane_q6i_displacements(membrane_q6i_id)
544
+ ```
545
+
546
+ > - `membrane_q6i_id` (`int`) → Identificador del elemento Q6i.
547
+ > - `displacements` (`np.ndarray`) → Desplazamientos.
548
+
549
+
550
+
551
+ ### Ejemplo de uso
552
+ ```python
553
+ from milcapy import SystemModel, BeamTheoriesType, model_viewer
554
+
555
+ model = SystemModel()
556
+
557
+ model.add_material(name="concreto", modulus_elasticity=2.1e6, poisson_ratio=0.2)
558
+ model.add_rectangular_section(name="vigas", material_name="concreto", base=0.3, height=0.5)
559
+ model.add_rectangular_section(name="muros", material_name="concreto", base=0.3, height=2.0)
560
+
561
+ model.add_node(1, 0, 0)
562
+ model.add_node(2, 0, 5)
563
+ model.add_node(3, 7, 8.5)
564
+ model.add_node(4, 14, 5)
565
+ model.add_node(5, 14, 0)
566
+
567
+ model.add_member(1, 1, 2, "muros", BeamTheoriesType.TIMOSHENKO)
568
+ model.add_member(2, 2, 3, "vigas", BeamTheoriesType.EULER_BERNOULLI)
569
+ model.add_member(3, 3, 4, "vigas", BeamTheoriesType.EULER_BERNOULLI)
570
+ model.add_member(4, 4, 5, "muros", BeamTheoriesType.TIMOSHENKO)
571
+ model.add_member(5, 2, 4, "vigas", BeamTheoriesType.EULER_BERNOULLI)
572
+
573
+ model.add_restraint(1, (False, True, True))
574
+ model.add_restraint(5, (False, True, True))
575
+
576
+ model.add_local_axis_for_node(1, -37*3.1416/180)
577
+ model.add_local_axis_for_node(5, +37*3.1416/180)
578
+
579
+ lengthOffset = 1
580
+
581
+ model.add_elastic_support(3, ky=10)
582
+ model.add_end_length_offset(2, la=lengthOffset, qla=True)
583
+ model.add_end_length_offset(3, lb=lengthOffset, qlb=True)
584
+ model.add_end_length_offset(5, la=lengthOffset, lb=lengthOffset, qla=True)
585
+
586
+ model.add_releases(5, mi=True, mj=True)
587
+
588
+ model.add_load_pattern("Live Load")
589
+ model.add_point_load(3, "Live Load", 0, -50, 0)
590
+ model.add_distributed_load(2, "Live Load", -10, -5)
591
+ model.add_distributed_load(3, "Live Load", -5, -10)
592
+ model.add_distributed_load(5, "Live Load", -5, -5)
593
+ model.add_load_pattern("Dead Load")
594
+ model.add_point_load(3, "Dead Load", 40, -50, 10)
595
+ model.add_distributed_load(5, "Dead Load", -5, -5)
596
+
597
+ model.add_prescribed_dof(1, "Live Load", uy=-0.01, CSys="LOCAL")
598
+ model.add_prescribed_dof(5, "Live Load", uy=-0.01, CSys="LOCAL")
599
+
600
+ model.postprocessing_options.n = 100
601
+
602
+ model.solve()
603
+
604
+ model_viewer(model)
605
+ ```
606
+
607
+ #### model_viewer
608
+ ##### modelo
609
+ ![Resultados](assets/modelo.png)
610
+
611
+ ##### deformada
612
+ ![Resultados](assets/deformada.png)
613
+
614
+ ##### deformada rigida
615
+ ![Resultados](assets/deformada_rigida.png)
616
+
617
+ ##### reacciones
618
+ ![Resultados](assets/reacciones.png)
619
+
620
+ ##### Diagramas de fuerzas axiales
621
+ ![Resultados](assets/diag_axiales.png)
622
+
623
+ ##### Diagramas de fuerzas cortantes
624
+ ![Resultados](assets/diag_cortantes.png)
625
+
626
+ ##### Diagramas de fuerzas cortantes
627
+ ![Resultados](assets/diag_momentos.png)