mnspy 0.9.14__tar.gz → 0.9.16__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 (76) hide show
  1. {mnspy-0.9.14 → mnspy-0.9.16}/PKG-INFO +1 -1
  2. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/mef/marco.py +63 -67
  3. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/mef/viga.py +61 -84
  4. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy.egg-info/PKG-INFO +1 -1
  5. {mnspy-0.9.14 → mnspy-0.9.16}/setup.py +1 -1
  6. {mnspy-0.9.14 → mnspy-0.9.16}/LICENSE +0 -0
  7. {mnspy-0.9.14 → mnspy-0.9.16}/README.md +0 -0
  8. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/__init__.py +0 -0
  9. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/derivada/__init__.py +0 -0
  10. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/derivada/derivada.py +0 -0
  11. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/derivada/derivada_discreta.py +0 -0
  12. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/derivada/richardson.py +0 -0
  13. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_algebraicas_lineales/__init__.py +0 -0
  14. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_algebraicas_lineales/cramer.py +0 -0
  15. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_algebraicas_lineales/descomposicion_LU.py +0 -0
  16. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_algebraicas_lineales/descomposicion_cholesky.py +0 -0
  17. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_algebraicas_lineales/ecuaciones_algebraicas_lineales.py +0 -0
  18. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_algebraicas_lineales/gauss.py +0 -0
  19. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_algebraicas_lineales/gauss_jordan.py +0 -0
  20. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_algebraicas_lineales/gauss_sediel.py +0 -0
  21. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_algebraicas_lineales/tridiagonal.py +0 -0
  22. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_ordinarias/__init__.py +0 -0
  23. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_ordinarias/ecuaciones_diferenciales_ordinarias.py +0 -0
  24. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_ordinarias/euler.py +0 -0
  25. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_ordinarias/heun.py +0 -0
  26. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_ordinarias/punto_medio.py +0 -0
  27. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_ordinarias/runge_kutta.py +0 -0
  28. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/__init__.py +0 -0
  29. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/ecuaciones_diferenciales_parciales.py +0 -0
  30. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/liebmann.py +0 -0
  31. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/mdf/__init__.py +0 -0
  32. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/mdf/mdf.py +0 -0
  33. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/mef/__init__.py +0 -0
  34. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/mef/armadura.py +0 -0
  35. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/mef/barra.py +0 -0
  36. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/mef/ensamble.py +0 -0
  37. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/mef/mef.py +0 -0
  38. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/mef/resorte.py +0 -0
  39. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/mef/triangular_cst.py +0 -0
  40. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/mvf/__init__.py +0 -0
  41. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/mvf/mvf.py +0 -0
  42. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ecuaciones_diferenciales_parciales/mvf/volumen_finito.py +0 -0
  43. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/integrales/__init__.py +0 -0
  44. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/integrales/cuadratura_adaptativa.py +0 -0
  45. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/integrales/gauss_legendre.py +0 -0
  46. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/integrales/integral.py +0 -0
  47. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/integrales/romberg.py +0 -0
  48. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/integrales/simpson_1_3.py +0 -0
  49. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/integrales/simpson_3_8.py +0 -0
  50. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/integrales/trapezoidal.py +0 -0
  51. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/integrales/trapezoidal_desigual.py +0 -0
  52. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/integrales/trapezoidal_desigual_acumulado.py +0 -0
  53. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/interpolaci/303/263n/__init__.py" +0 -0
  54. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/interpolaci/303/263n/inter_Lagrange.py" +0 -0
  55. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/interpolaci/303/263n/inter_Newton.py" +0 -0
  56. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/interpolaci/303/263n/inter_spline_cubica.py" +0 -0
  57. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/interpolaci/303/263n/inter_spline_lineal.py" +0 -0
  58. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/interpolaci/303/263n/interpolacion.py" +0 -0
  59. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ra/303/255ces/__init__.py" +0 -0
  60. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ra/303/255ces/bisecci/303/263n.py" +0 -0
  61. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ra/303/255ces/brent.py" +0 -0
  62. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ra/303/255ces/falsa_posicion.py" +0 -0
  63. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ra/303/255ces/muller.py" +0 -0
  64. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ra/303/255ces/newton_raphson.py" +0 -0
  65. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ra/303/255ces/punto_fijo.py" +0 -0
  66. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ra/303/255ces/raices.py" +0 -0
  67. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ra/303/255ces/secante.py" +0 -0
  68. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ra/303/255ces/secante_modificada.py" +0 -0
  69. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/ra/303/255ces/wegstein.py" +0 -0
  70. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy/utilidades.py +0 -0
  71. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy.egg-info/SOURCES.txt +0 -0
  72. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy.egg-info/dependency_links.txt +0 -0
  73. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy.egg-info/requires.txt +0 -0
  74. {mnspy-0.9.14 → mnspy-0.9.16}/mnspy.egg-info/top_level.txt +0 -0
  75. {mnspy-0.9.14 → mnspy-0.9.16}/pyproject.toml +0 -0
  76. {mnspy-0.9.14 → mnspy-0.9.16}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mnspy
3
- Version: 0.9.14
3
+ Version: 0.9.16
4
4
  Summary: Paquete didáctico para métodos numéricos
5
5
  Home-page: https://github.com/EdwinSoft/mnspy
6
6
  Author: Edwin Córdoba
@@ -215,28 +215,18 @@ class Marco(Elemento):
215
215
  # Esto se hace aplicando un momento corrector en el nodo i y las fuerzas
216
216
  # cortantes correspondientes en ambos nodos para mantener el equilibrio.
217
217
  if self._nodo_j.es_rotula:
218
- # Momento de empotramiento en el extremo j (a liberar)
219
- m_fem_j = -q * self._L ** 2 / 12
220
- # Momento transferido al nodo i (carry-over) y fuerzas cortantes resultantes
221
- m_corrector_i = -0.5 * m_fem_j
222
- v_corrector = m_fem_j * 3.0 / (2.0 * self._L)
223
-
224
- # Aplicar correcciones a las fuerzas nodales globales
225
- self._nodo_i.grados_libertad['x'].fuerza -= -self._s * v_corrector
226
- self._fuerzas_i_rot[0, 0] -= -self._s * v_corrector
227
- self._nodo_i.grados_libertad['y'].fuerza -= self._c * v_corrector
228
- self._fuerzas_i_rot[1, 0] -= self._c * v_corrector
229
- self._nodo_i.grados_libertad['eje_z'].fuerza -= m_corrector_i
230
- self._fuerzas_i_rot[2, 0] -= m_corrector_i
231
-
232
- self._nodo_j.grados_libertad['x'].fuerza -= -self._s * -v_corrector
233
- self._fuerzas_j_rot[0, 0] -= -self._s * -v_corrector
234
- self._nodo_j.grados_libertad['y'].fuerza -= self._c * -v_corrector
235
- self._fuerzas_j_rot[1, 0] -= self._c * -v_corrector
236
-
237
- # La fuerza de momento en el nodo j se anula completamente.
238
- self._nodo_j.grados_libertad['eje_z'].fuerza -= m_fem_j
239
- self._fuerzas_j_rot[2, 0] -= m_fem_j
218
+ self._nodo_i.grados_libertad['x'].fuerza -= -self._s * (-q * self._L ** 2 / 12) * 3.0 / (2.0 * self._L)
219
+ self._fuerzas_i_rot[0, 0] -= -self._s * (-q * self._L ** 2 / 12) * 3.0 / (2.0 * self._L)
220
+ self._nodo_i.grados_libertad['y'].fuerza -= self._c * (-q * self._L ** 2 / 12) * 3.0 / (2.0 * self._L)
221
+ self._fuerzas_i_rot[1, 0] -= self._c * (-q * self._L ** 2 / 12) * 3.0 / (2.0 * self._L)
222
+ self._nodo_i.grados_libertad['eje_z'].fuerza -= 0.5 * (-q * self._L ** 2 / 12)
223
+ self._fuerzas_i_rot[2, 0] -= 0.5 * (-q * self._L ** 2 / 12)
224
+ self._nodo_j.grados_libertad['x'].fuerza -= -self._s * -(-q * self._L ** 2 / 12) * 3.0 / (2.0 * self._L)
225
+ self._fuerzas_j_rot[0, 0] -= -self._s * -(-q * self._L ** 2 / 12) * 3.0 / (2.0 * self._L)
226
+ self._nodo_j.grados_libertad['y'].fuerza -= self._c * -(-q * self._L ** 2 / 12) * 3.0 / (2.0 * self._L)
227
+ self._fuerzas_j_rot[1, 0] -= self._c * -(-q * self._L ** 2 / 12) * 3.0 / (2.0 * self._L)
228
+ self._nodo_j.grados_libertad['eje_z'].fuerza -= -q * self._L ** 2 / 12
229
+ self._fuerzas_j_rot[2, 0] -= -q * self._L ** 2 / 12
240
230
 
241
231
  def agregar_carga_trapezoidal(self, q_1: float, q_2: float):
242
232
  """Agrega una carga trapezoidalmente distribuida perpendicular al elemento.
@@ -273,25 +263,31 @@ class Marco(Elemento):
273
263
 
274
264
  # Corrección por rótula en el nodo j
275
265
  if self._nodo_j.es_rotula:
276
- # Momento de empotramiento en j (a liberar)
277
- m_fem_j = -q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20
278
- m_corrector_i = -0.5 * m_fem_j
279
- v_corrector = m_fem_j * 3.0 / (2.0 * self._L)
280
-
281
- self._nodo_i.grados_libertad['x'].fuerza -= -self._s * v_corrector
282
- self._fuerzas_i_rot[0, 0] -= -self._s * v_corrector
283
- self._nodo_i.grados_libertad['y'].fuerza -= self._c * v_corrector
284
- self._fuerzas_i_rot[1, 0] -= self._c * v_corrector
285
- self._nodo_i.grados_libertad['eje_z'].fuerza -= m_corrector_i
286
- self._fuerzas_i_rot[2, 0] -= m_corrector_i
287
-
288
- self._nodo_j.grados_libertad['x'].fuerza -= -self._s * -v_corrector
289
- self._fuerzas_j_rot[0, 0] -= -self._s * -v_corrector
290
- self._nodo_j.grados_libertad['y'].fuerza -= self._c * -v_corrector
291
- self._fuerzas_j_rot[1, 0] -= self._c * -v_corrector
292
-
293
- self._nodo_j.grados_libertad['eje_z'].fuerza -= m_fem_j
294
- self._fuerzas_j_rot[2, 0] -= m_fem_j
266
+ self._nodo_i.grados_libertad['x'].fuerza -= -self._s * (-q_1 * self._L ** 2 / 12 - (
267
+ q_2 - q_1) * self._L ** 2 / 20) * 3.0 / (2.0 * self._L)
268
+ self._fuerzas_i_rot[0, 0] -= -self._s * (
269
+ -q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20) * 3.0 / (
270
+ 2.0 * self._L)
271
+ self._nodo_i.grados_libertad['y'].fuerza -= self._c * (-q_1 * self._L ** 2 / 12 - (
272
+ q_2 - q_1) * self._L ** 2 / 20) * 3.0 / (2.0 * self._L)
273
+ self._fuerzas_i_rot[1, 0] -= self._c * (
274
+ -q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20) * 3.0 / (
275
+ 2.0 * self._L)
276
+ self._nodo_i.grados_libertad['eje_z'].fuerza -= 0.5 * (
277
+ -q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20)
278
+ self._fuerzas_i_rot[2, 0] -= 0.5 * (-q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20)
279
+ self._nodo_j.grados_libertad['x'].fuerza -= -self._s * -(
280
+ -q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20) * 3.0 / (2.0 * self._L)
281
+ self._fuerzas_j_rot[0, 0] -= -self._s * -(
282
+ -q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20) * 3.0 / (
283
+ 2.0 * self._L)
284
+ self._nodo_j.grados_libertad['y'].fuerza -= self._c * -(
285
+ -q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20) * 3.0 / (2.0 * self._L)
286
+ self._fuerzas_j_rot[1, 0] -= self._c * -(
287
+ -q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20) * 3.0 / (
288
+ 2.0 * self._L)
289
+ self._nodo_j.grados_libertad['eje_z'].fuerza -= -q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20
290
+ self._fuerzas_j_rot[2, 0] -= -q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20
295
291
 
296
292
  def agregar_carga_puntual(self, p: float, a: float = None):
297
293
  """Agrega una carga puntual perpendicular al elemento a una distancia 'a'.
@@ -332,24 +328,25 @@ class Marco(Elemento):
332
328
 
333
329
  # Corrección por rótula en el nodo j
334
330
  if self._nodo_j.es_rotula:
335
- m_fem_j = -p * (self._L - a) * a ** 2 / self._L ** 2
336
- m_corrector_i = -0.5 * m_fem_j
337
- v_corrector = m_fem_j * 3.0 / (2.0 * self._L)
338
-
339
- self._nodo_i.grados_libertad['x'].fuerza -= -self._s * v_corrector
340
- self._fuerzas_i_rot[0, 0] -= -self._s * v_corrector
341
- self._nodo_i.grados_libertad['y'].fuerza -= self._c * v_corrector
342
- self._fuerzas_i_rot[1, 0] -= self._c * v_corrector
343
- self._nodo_i.grados_libertad['eje_z'].fuerza -= m_corrector_i
344
- self._fuerzas_i_rot[2, 0] -= m_corrector_i
345
-
346
- self._nodo_j.grados_libertad['x'].fuerza -= -self._s * -v_corrector
347
- self._fuerzas_j_rot[0, 0] -= -self._s * -v_corrector
348
- self._nodo_j.grados_libertad['y'].fuerza -= self._c * -v_corrector
349
- self._fuerzas_j_rot[1, 0] -= self._c * -v_corrector
350
-
351
- self._nodo_j.grados_libertad['eje_z'].fuerza -= m_fem_j
352
- self._fuerzas_j_rot[2, 0] -= m_fem_j
331
+ self._nodo_i.grados_libertad['x'].fuerza -= -self._s * (
332
+ -p * (self._L - a) * a ** 2 / self._L ** 2) * 3.0 / (
333
+ 2.0 * self._L)
334
+ self._fuerzas_i_rot[0, 0] -= -self._s * (-p * (self._L - a) * a ** 2 / self._L ** 2) * 3.0 / (2.0 * self._L)
335
+ self._nodo_i.grados_libertad['y'].fuerza -= self._c * (-p * (self._L - a) * a ** 2 / self._L ** 2) * 3.0 / (
336
+ 2.0 * self._L)
337
+ self._fuerzas_i_rot[1, 0] -= self._c * (-p * (self._L - a) * a ** 2 / self._L ** 2) * 3.0 / (2.0 * self._L)
338
+ self._nodo_i.grados_libertad['eje_z'].fuerza -= 0.5 * (-p * (self._L - a) * a ** 2 / self._L ** 2)
339
+ self._fuerzas_i_rot[2, 0] -= 0.5 * (-p * (self._L - a) * a ** 2 / self._L ** 2)
340
+ self._nodo_j.grados_libertad['x'].fuerza -= -self._s * -(
341
+ -p * (self._L - a) * a ** 2 / self._L ** 2) * 3.0 / (2.0 * self._L)
342
+ self._fuerzas_j_rot[0, 0] -= -self._s * -(-p * (self._L - a) * a ** 2 / self._L ** 2) * 3.0 / (
343
+ 2.0 * self._L)
344
+ self._nodo_j.grados_libertad['y'].fuerza -= self._c * -(
345
+ -p * (self._L - a) * a ** 2 / self._L ** 2) * 3.0 / (
346
+ 2.0 * self._L)
347
+ self._fuerzas_j_rot[1, 0] -= self._c * -(-p * (self._L - a) * a ** 2 / self._L ** 2) * 3.0 / (2.0 * self._L)
348
+ self._nodo_j.grados_libertad['eje_z'].fuerza -= -p * (self._L - a) * a ** 2 / self._L ** 2
349
+ self._fuerzas_j_rot[2, 0] -= -p * (self._L - a) * a ** 2 / self._L ** 2
353
350
 
354
351
  def agregar_momento(self, m: float, a: float = None):
355
352
  m *= -1.0
@@ -708,8 +705,8 @@ class Marco(Elemento):
708
705
  return lista_x, lista_m, lista_p
709
706
 
710
707
  def _obtener_arrays_angulos(self, n_puntos: int = 100):
711
- x = sp.symbols('x', real=True)
712
- f = self.ecuacion_de_giro() #TODO: Check
708
+ x = sp.symbols('x')
709
+ f = self.ecuacion_de_giro()
713
710
  x_1 = 0.0
714
711
  x_2 = self._L
715
712
  lista_x = np.linspace(x_1, x_2, n_puntos)
@@ -1054,12 +1051,11 @@ class Marco(Elemento):
1054
1051
  else:
1055
1052
  desplazamiento = np.hstack((desplazamiento, d_i))
1056
1053
  b = np.array(desplazamiento).reshape(-1, 1)
1057
-
1058
- # NOTA: La lógica original contenía un cálculo especial para la rotación en
1059
- # la rótula, pero fue eliminada por ser conceptualmente
1060
- # incorrecta en este contexto, ya que los desplazamientos deben ser
1061
- # resueltos por el sistema global, no recalculados aquí.
1062
-
1054
+ # Si hay una rotula en el nodo derecho, se ajusta el ángulo
1055
+ if self._nodo_j.es_rotula:
1056
+ b[5] = (self._fuerzas_j[2] * self._L / self._E - np.matmul(np.array(
1057
+ [[- 6 * self._I * self._s / self._L, 6 * self._I * self._c / self._L, 2 * self._I,
1058
+ 6 * self._I * self._s / self._L, -6 * self._I * self._c / self._L]]), b[0:5, ])) / 4 / self._I
1063
1059
  return b
1064
1060
 
1065
1061
  def mostrar_sistema(self, reducida: bool = False):
@@ -163,25 +163,14 @@ class Viga(Elemento):
163
163
  # Esto se hace aplicando un momento corrector y las fuerzas cortantes
164
164
  # correspondientes para mantener el equilibrio.
165
165
  if self._nodo_j.es_rotula:
166
- # Momento de empotramiento en j (a liberar)
167
- m_fem_j = -q * self._L ** 2 / 12
168
- # Momento corrector para anular el momento en j
169
- m_corrector = -m_fem_j
170
- # Momento transferido al nodo i (carry-over)
171
- m_carry_over_i = 0.5 * m_corrector
172
- # Fuerzas cortantes de corrección
173
- v_corrector = 1.5 * m_corrector / self._L
174
-
175
- # Aplicar correcciones a las fuerzas nodales
176
- self._nodo_i.grados_libertad['y'].fuerza += v_corrector
177
- self._fuerzas_i_rot[0, 0] += v_corrector
178
- self._nodo_i.grados_libertad['eje_z'].fuerza += m_carry_over_i
179
- self._fuerzas_i_rot[1, 0] += m_carry_over_i
180
-
181
- self._nodo_j.grados_libertad['y'].fuerza -= v_corrector
182
- self._fuerzas_j_rot[0, 0] -= v_corrector
183
- self._nodo_j.grados_libertad['eje_z'].fuerza += m_corrector
184
- self._fuerzas_j_rot[1, 0] += m_corrector
166
+ self._nodo_i.grados_libertad['y'].fuerza -= (-q * self._L ** 2 / 12) * 3.0 / (2.0 * self._L)
167
+ self._fuerzas_i_rot[0, 0] -= (-q * self._L ** 2 / 12) * 3.0 / (2.0 * self._L)
168
+ self._nodo_i.grados_libertad['eje_z'].fuerza -= 0.5 * (-q * self._L ** 2 / 12)
169
+ self._fuerzas_i_rot[1, 0] -= 0.5 * (-q * self._L ** 2 / 12)
170
+ self._nodo_j.grados_libertad['y'].fuerza -= -(-q * self._L ** 2 / 12) * 3.0 / (2.0 * self._L)
171
+ self._fuerzas_j_rot[0, 0] -= -(-q * self._L ** 2 / 12) * 3.0 / (2.0 * self._L)
172
+ self._nodo_j.grados_libertad['eje_z'].fuerza -= -q * self._L ** 2 / 12
173
+ self._fuerzas_j_rot[1, 0] -= -q * self._L ** 2 / 12
185
174
 
186
175
  def agregar_carga_trapezoidal(self, q_1: float, q_2: float):
187
176
  """Agrega una carga trapezoidalmente distribuida."""
@@ -199,20 +188,19 @@ class Viga(Elemento):
199
188
 
200
189
  # Corrección por rótula en el nodo j
201
190
  if self._nodo_j.es_rotula:
202
- m_fem_j = -q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20
203
- m_corrector = -m_fem_j
204
- m_carry_over_i = 0.5 * m_corrector
205
- v_corrector = 1.5 * m_corrector / self._L
206
-
207
- self._nodo_i.grados_libertad['y'].fuerza += v_corrector
208
- self._fuerzas_i_rot[0, 0] += v_corrector
209
- self._nodo_i.grados_libertad['eje_z'].fuerza += m_carry_over_i
210
- self._fuerzas_i_rot[1, 0] += m_carry_over_i
211
-
212
- self._nodo_j.grados_libertad['y'].fuerza -= v_corrector
213
- self._fuerzas_j_rot[0, 0] -= v_corrector
214
- self._nodo_j.grados_libertad['eje_z'].fuerza += m_corrector
215
- self._fuerzas_j_rot[1, 0] += m_corrector
191
+ self._nodo_i.grados_libertad['y'].fuerza -= (-q_1 * self._L ** 2 / 12 - (
192
+ q_2 - q_1) * self._L ** 2 / 20) * 3.0 / (2.0 * self._L)
193
+ self._fuerzas_i_rot[0, 0] -= (-q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20) * 3.0 / (
194
+ 2.0 * self._L)
195
+ self._nodo_i.grados_libertad['eje_z'].fuerza -= 0.5 * (
196
+ -q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20)
197
+ self._fuerzas_i_rot[1, 0] -= 0.5 * (-q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20)
198
+ self._nodo_j.grados_libertad['y'].fuerza -= -(
199
+ -q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20) * 3.0 / (2.0 * self._L)
200
+ self._fuerzas_j_rot[0, 0] -= -(-q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20) * 3.0 / (
201
+ 2.0 * self._L)
202
+ self._nodo_j.grados_libertad['eje_z'].fuerza -= -q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20
203
+ self._fuerzas_j_rot[1, 0] -= -q_1 * self._L ** 2 / 12 - (q_2 - q_1) * self._L ** 2 / 20
216
204
 
217
205
  def agregar_carga_puntual(self, p: float, a: float = None):
218
206
  """Agrega una carga puntual perpendicular a una distancia 'a'."""
@@ -232,20 +220,16 @@ class Viga(Elemento):
232
220
 
233
221
  # Corrección por rótula en el nodo j
234
222
  if self._nodo_j.es_rotula:
235
- m_fem_j = -p * (self._L - a) * a ** 2 / self._L ** 2
236
- m_corrector = -m_fem_j
237
- m_carry_over_i = 0.5 * m_corrector
238
- v_corrector = 1.5 * m_corrector / self._L
239
-
240
- self._nodo_i.grados_libertad['y'].fuerza += v_corrector
241
- self._fuerzas_i_rot[0, 0] += v_corrector
242
- self._nodo_i.grados_libertad['eje_z'].fuerza += m_carry_over_i
243
- self._fuerzas_i_rot[1, 0] += m_carry_over_i
244
-
245
- self._nodo_j.grados_libertad['y'].fuerza -= v_corrector
246
- self._fuerzas_j_rot[0, 0] -= v_corrector
247
- self._nodo_j.grados_libertad['eje_z'].fuerza += m_corrector
248
- self._fuerzas_j_rot[1, 0] += m_corrector
223
+ self._nodo_i.grados_libertad['y'].fuerza -= (-p * (self._L - a) * a ** 2 / self._L ** 2) * 3.0 / (
224
+ 2.0 * self._L)
225
+ self._fuerzas_i_rot[0, 0] -= (-p * (self._L - a) * a ** 2 / self._L ** 2) * 3.0 / (2.0 * self._L)
226
+ self._nodo_i.grados_libertad['eje_z'].fuerza -= 0.5 * (-p * (self._L - a) * a ** 2 / self._L ** 2)
227
+ self._fuerzas_i_rot[1, 0] -= 0.5 * (-p * (self._L - a) * a ** 2 / self._L ** 2)
228
+ self._nodo_j.grados_libertad['y'].fuerza -= -(-p * (self._L - a) * a ** 2 / self._L ** 2) * 3.0 / (
229
+ 2.0 * self._L)
230
+ self._fuerzas_j_rot[0, 0] -= -(-p * (self._L - a) * a ** 2 / self._L ** 2) * 3.0 / (2.0 * self._L)
231
+ self._nodo_j.grados_libertad['eje_z'].fuerza -= -p * (self._L - a) * a ** 2 / self._L ** 2
232
+ self._fuerzas_j_rot[1, 0] -= -p * (self._L - a) * a ** 2 / self._L ** 2
249
233
 
250
234
  def agregar_momento(self, m: float, a: float = None):
251
235
  """Agrega un momento concentrado a una distancia 'a'."""
@@ -266,20 +250,16 @@ class Viga(Elemento):
266
250
 
267
251
  # Corrección por rótula en el nodo j
268
252
  if self._nodo_j.es_rotula:
269
- m_fem_j = m * a * (2 * self._L - 3 * a) / self._L ** 2
270
- m_corrector = -m_fem_j
271
- m_carry_over_i = 0.5 * m_corrector
272
- v_corrector = 1.5 * m_corrector / self._L
273
-
274
- self._nodo_i.grados_libertad['y'].fuerza += v_corrector
275
- self._fuerzas_i_rot[0, 0] += v_corrector
276
- self._nodo_i.grados_libertad['eje_z'].fuerza += m_carry_over_i
277
- self._fuerzas_i_rot[1, 0] += m_carry_over_i
278
-
279
- self._nodo_j.grados_libertad['y'].fuerza -= v_corrector
280
- self._fuerzas_j_rot[0, 0] -= v_corrector
281
- self._nodo_j.grados_libertad['eje_z'].fuerza += m_corrector
282
- self._fuerzas_j_rot[1, 0] += m_corrector
253
+ self._nodo_i.grados_libertad['y'].fuerza -= (m * a * (2 * self._L - 3 * a) / self._L ** 2) * 3.0 / (
254
+ 2.0 * self._L)
255
+ self._fuerzas_i_rot[0, 0] -= (m * a * (2 * self._L - 3 * a) / self._L ** 2) * 3.0 / (2.0 * self._L)
256
+ self._nodo_i.grados_libertad['eje_z'].fuerza -= 0.5 * (m * a * (2 * self._L - 3 * a) / self._L ** 2)
257
+ self._fuerzas_i_rot[1, 0] -= 0.5 * (m * a * (2 * self._L - 3 * a) / self._L ** 2)
258
+ self._nodo_j.grados_libertad['y'].fuerza -= -(m * a * (2 * self._L - 3 * a) / self._L ** 2) * 3.0 / (
259
+ 2.0 * self._L)
260
+ self._fuerzas_j_rot[0, 0] -= -(m * a * (2 * self._L - 3 * a) / self._L ** 2) * 3.0 / (2.0 * self._L)
261
+ self._nodo_j.grados_libertad['eje_z'].fuerza -= m * a * (2 * self._L - 3 * a) / self._L ** 2
262
+ self._fuerzas_j_rot[1, 0] -= m * a * (2 * self._L - 3 * a) / self._L ** 2
283
263
 
284
264
  def agregar_carga_triangular_descendente(self, q: float):
285
265
  """Agrega una carga triangular con valor máximo en el nodo i."""
@@ -296,15 +276,14 @@ class Viga(Elemento):
296
276
 
297
277
  # Corrección por rótula en el nodo j
298
278
  if self._nodo_j.es_rotula:
299
- m_fem_j = -q * self._L ** 2 / 30
300
- m_corrector = -m_fem_j
301
- m_carry_over_i = 0.5 * m_corrector
302
- v_corrector = 1.5 * m_corrector / self._L
303
-
304
- self._nodo_i.grados_libertad['y'].fuerza += v_corrector
305
- self._fuerzas_i_rot[0, 0] += v_corrector
306
- self._nodo_i.grados_libertad['eje_z'].fuerza += m_carry_over_i
307
- self._fuerzas_i_rot[1, 0] += m_carry_over_i
279
+ self._nodo_i.grados_libertad['y'].fuerza -= (-q * self._L ** 2 / 30) * 3.0 / (2.0 * self._L)
280
+ self._fuerzas_i_rot[0, 0] -= (-q * self._L ** 2 / 30) * 3.0 / (2.0 * self._L)
281
+ self._nodo_i.grados_libertad['eje_z'].fuerza -= 0.5 * (-q * self._L ** 2 / 30)
282
+ self._fuerzas_i_rot[1, 0] -= 0.5 * (-q * self._L ** 2 / 30)
283
+ self._nodo_j.grados_libertad['y'].fuerza -= -(-q * self._L ** 2 / 30) * 3.0 / (2.0 * self._L)
284
+ self._fuerzas_j_rot[0, 0] -= -(-q * self._L ** 2 / 30) * 3.0 / (2.0 * self._L)
285
+ self._nodo_j.grados_libertad['eje_z'].fuerza -= -q * self._L ** 2 / 30
286
+ self._fuerzas_j_rot[1, 0] -= -q * self._L ** 2 / 30
308
287
 
309
288
  def agregar_carga_triangular_ascendente(self, q: float):
310
289
  """Agrega una carga triangular con valor máximo en el nodo j."""
@@ -321,15 +300,14 @@ class Viga(Elemento):
321
300
 
322
301
  # Corrección por rótula en el nodo j
323
302
  if self._nodo_j.es_rotula:
324
- m_fem_j = -q * self._L ** 2 / 20
325
- m_corrector = -m_fem_j
326
- m_carry_over_i = 0.5 * m_corrector
327
- v_corrector = 1.5 * m_corrector / self._L
328
-
329
- self._nodo_i.grados_libertad['y'].fuerza += v_corrector
330
- self._fuerzas_i_rot[0, 0] += v_corrector
331
- self._nodo_i.grados_libertad['eje_z'].fuerza += m_carry_over_i
332
- self._fuerzas_i_rot[1, 0] += m_carry_over_i
303
+ self._nodo_i.grados_libertad['y'].fuerza -= (-q * self._L ** 2 / 20) * 3.0 / (2.0 * self._L)
304
+ self._fuerzas_i_rot[0, 0] -= (-q * self._L ** 2 / 20) * 3.0 / (2.0 * self._L)
305
+ self._nodo_i.grados_libertad['eje_z'].fuerza -= 0.5 * (-q * self._L ** 2 / 20)
306
+ self._fuerzas_i_rot[1, 0] -= 0.5 * (-q * self._L ** 2 / 20)
307
+ self._nodo_j.grados_libertad['y'].fuerza -= -(-q * self._L ** 2 / 20) * 3.0 / (2.0 * self._L)
308
+ self._fuerzas_j_rot[0, 0] -= -(-q * self._L ** 2 / 20) * 3.0 / (2.0 * self._L)
309
+ self._nodo_j.grados_libertad['eje_z'].fuerza -= -q * self._L ** 2 / 20
310
+ self._fuerzas_j_rot[1, 0] -= -q * self._L ** 2 / 20
333
311
 
334
312
  def _obtener_cargas(self) -> dict:
335
313
  return self._cargas
@@ -720,11 +698,10 @@ class Viga(Elemento):
720
698
  else:
721
699
  desplazamiento = np.hstack((desplazamiento, d_i))
722
700
  b = np.array(desplazamiento).reshape(-1, 1)
723
-
724
- # NOTA: La lógica original contenía un cálculo especial para la rotación en
725
- # la rótula, pero fue eliminada por ser conceptualmente
726
- # incorrecta. Los desplazamientos nodales son resueltos por el
727
- # sistema global y esta función solo debe recolectarlos.
701
+ # Si hay una rotula en el nodo derecho, se ajusta el ángulo
702
+ if self._nodo_j.es_rotula:
703
+ b[3] = (self._fuerzas_j[1] * self._L ** 3 / self._E / self._I - np.matmul(np.array(
704
+ [[6 * self._L, 2 * self._L ** 2, - 6 * self._L]]), b[0:3, ])) / 4 / self._L ** 2
728
705
  return b
729
706
 
730
707
  def __obtener_path_elemento(self, espesor: float) -> Path:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mnspy
3
- Version: 0.9.14
3
+ Version: 0.9.16
4
4
  Summary: Paquete didáctico para métodos numéricos
5
5
  Home-page: https://github.com/EdwinSoft/mnspy
6
6
  Author: Edwin Córdoba
@@ -2,7 +2,7 @@ from setuptools import setup
2
2
 
3
3
  setup(
4
4
  name='mnspy',
5
- version='0.9.14',
5
+ version='0.9.16',
6
6
  packages=['mnspy', 'mnspy.raíces', 'mnspy.derivada', 'mnspy.integrales', 'mnspy.interpolación',
7
7
  'mnspy.ecuaciones_algebraicas_lineales', 'mnspy.ecuaciones_diferenciales_ordinarias',
8
8
  'mnspy.ecuaciones_diferenciales_parciales', 'mnspy.ecuaciones_diferenciales_parciales.mdf',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes