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.
- milcapy-0.1.0/PKG-INFO +627 -0
- milcapy-0.1.0/README.md +614 -0
- milcapy-0.1.0/milcapy/__init__.py +29 -0
- milcapy-0.1.0/milcapy/analysis/__init__.py +0 -0
- milcapy-0.1.0/milcapy/analysis/linear_static.py +392 -0
- milcapy-0.1.0/milcapy/analysis/manager.py +101 -0
- milcapy-0.1.0/milcapy/core/__init__.py +0 -0
- milcapy-0.1.0/milcapy/core/node.py +94 -0
- milcapy-0.1.0/milcapy/core/results.py +256 -0
- milcapy-0.1.0/milcapy/elements/CST.py +137 -0
- milcapy-0.1.0/milcapy/elements/MQ6.py +330 -0
- milcapy-0.1.0/milcapy/elements/MQ6I.py +246 -0
- milcapy-0.1.0/milcapy/elements/MQ6IMod.py +40 -0
- milcapy-0.1.0/milcapy/elements/__init__.py +0 -0
- milcapy-0.1.0/milcapy/elements/member.py +390 -0
- milcapy-0.1.0/milcapy/elements/truss.py +133 -0
- milcapy-0.1.0/milcapy/loads/__init__.py +9 -0
- milcapy-0.1.0/milcapy/loads/load.py +1100 -0
- milcapy-0.1.0/milcapy/loads/load_pattern.py +419 -0
- milcapy-0.1.0/milcapy/material/__init__.py +0 -0
- milcapy-0.1.0/milcapy/material/material.py +68 -0
- milcapy-0.1.0/milcapy/model/__init__.py +0 -0
- milcapy-0.1.0/milcapy/model/model.py +1482 -0
- milcapy-0.1.0/milcapy/plotter/UIdisplay.py +926 -0
- milcapy-0.1.0/milcapy/plotter/__init__.py +0 -0
- milcapy-0.1.0/milcapy/plotter/load.py +454 -0
- milcapy-0.1.0/milcapy/plotter/options.py +450 -0
- milcapy-0.1.0/milcapy/plotter/plotter.py +2115 -0
- milcapy-0.1.0/milcapy/plotter/plotter_values.py +219 -0
- milcapy-0.1.0/milcapy/plotter/suports.py +322 -0
- milcapy-0.1.0/milcapy/plotter/utils.py +103 -0
- milcapy-0.1.0/milcapy/plotter/widgets.py +569 -0
- milcapy-0.1.0/milcapy/postprocess/CST_pp.py +55 -0
- milcapy-0.1.0/milcapy/postprocess/__init__.py +0 -0
- milcapy-0.1.0/milcapy/postprocess/membranebQ6.py +7 -0
- milcapy-0.1.0/milcapy/postprocess/post_processing.py +220 -0
- milcapy-0.1.0/milcapy/postprocess/segment_member.py +406 -0
- milcapy-0.1.0/milcapy/report/__init__.py +0 -0
- milcapy-0.1.0/milcapy/report/report.py +26 -0
- milcapy-0.1.0/milcapy/section/__init__.py +0 -0
- milcapy-0.1.0/milcapy/section/section.py +304 -0
- milcapy-0.1.0/milcapy/utils/__init__.py +24 -0
- milcapy-0.1.0/milcapy/utils/element.py +283 -0
- milcapy-0.1.0/milcapy/utils/geometry.py +106 -0
- milcapy-0.1.0/milcapy/utils/types.py +96 -0
- milcapy-0.1.0/milcapy.egg-info/PKG-INFO +627 -0
- milcapy-0.1.0/milcapy.egg-info/SOURCES.txt +49 -0
- milcapy-0.1.0/milcapy.egg-info/dependency_links.txt +1 -0
- milcapy-0.1.0/milcapy.egg-info/top_level.txt +1 -0
- milcapy-0.1.0/pyproject.toml +26 -0
- 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
|
+

|
|
610
|
+
|
|
611
|
+
##### deformada
|
|
612
|
+

|
|
613
|
+
|
|
614
|
+
##### deformada rigida
|
|
615
|
+

|
|
616
|
+
|
|
617
|
+
##### reacciones
|
|
618
|
+

|
|
619
|
+
|
|
620
|
+
##### Diagramas de fuerzas axiales
|
|
621
|
+

|
|
622
|
+
|
|
623
|
+
##### Diagramas de fuerzas cortantes
|
|
624
|
+

|
|
625
|
+
|
|
626
|
+
##### Diagramas de fuerzas cortantes
|
|
627
|
+

|