mnspy 0.9.15__py3-none-any.whl → 0.9.17__py3-none-any.whl

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.
@@ -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
@@ -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
@@ -88,17 +88,15 @@ class Biseccion(Raices):
88
88
  print("La raíz no está dentro de este rango, pruebe con otro rango de datos")
89
89
  sys.exit()
90
90
 
91
- # Bucle de iteración para evitar recursión profunda
92
- while True:
93
- self.x = (self._x_min + self._x_max) / 2
94
-
95
- if self._fin_iteracion():
96
- break # Convergencia o máximo de iteraciones alcanzado
97
-
98
- if np.sign(self._f(self._x_min)) == np.sign(self._f(self.x)):
99
- self._x_min = self.x
100
- else:
101
- self._x_max = self.x
91
+ self.x = (self._x_min + self._x_max) / 2
92
+ if self._fin_iteracion():
93
+ return
94
+ elif np.sign(self._f(self._x_min)) == np.sign(self._f(self.x)):
95
+ self._x_min = self.x
96
+ self._calcular()
97
+ elif np.sign(self._f(self._x_max)) == np.sign(self._f(self.x)):
98
+ self._x_max = self.x
99
+ self._calcular()
102
100
 
103
101
  def graficar(self, mostrar_sol: bool = True, mostrar_iter: bool = True, mostrar_lin_iter: bool = True,
104
102
  n_puntos: int = 100):
@@ -99,53 +99,48 @@ class Brent(Raices):
99
99
  "signos diferentes")
100
100
  sys.exit()
101
101
 
102
- # Bucle de iteración para evitar recursión profunda
103
- while True:
104
- x_a, x_b, x_c = self._val
105
- y_a, y_b, y_c = self._val_f
106
- x_d = 0 # No se usa en la lógica actual, pero se mantiene por si se reimplementa una condición
107
-
108
- self._x_min = min([x_a, x_b])
109
- self._x_max = max([x_a, x_b])
110
-
111
- if len(self._val_f) == len(set(self._val_f)):
112
- # Si los valores de y son distintos, se usa interpolación cuadrática inversa
113
- self.x = (x_a * y_b * y_c / ((y_a - y_b) * (y_a - y_c)) +
114
- x_b * y_a * y_c / ((y_b - y_a) * (y_b - y_c)) +
115
- x_c * y_a * y_b / ((y_c - y_a) * (y_c - y_b)))
116
- else:
117
- # Si hay valores de y repetidos, se usa el método de la secante (falsa posición)
118
- self.x = (y_a * x_b - y_b * x_a) / (y_a - y_b)
119
-
120
- # Se verifica si el paso de interpolación es aceptable, si no, se usa bisección
121
- cond1 = (self.x - (3 * x_a + x_b) / 4) * (self.x - x_b) >= 0
122
- cond2 = self._biseccion_usada and abs(self.x - x_b) >= abs(x_b - x_c) / 2
123
- cond3 = not self._biseccion_usada and abs(self.x - x_b) >= abs(x_c - x_d) / 2
124
-
125
- if cond1 or cond2 or cond3:
126
- self.x = (x_a + x_b) / 2
127
- self._biseccion_usada = True
128
- else:
129
- self._biseccion_usada = False
130
-
131
- if self._fin_iteracion():
132
- break
133
-
134
- y_x = self._f(self.x)
135
- x_c, y_c = x_b, y_b # Actualizar el punto previo
136
-
137
- if np.sign(y_a) == np.sign(y_x):
138
- x_a, y_a = self.x, y_x
139
- else:
140
- x_b, y_b = self.x, y_x
141
-
142
- # Se asegura de nuevo que |f(a)| > |f(b)| para la siguiente iteración
143
- if abs(y_a) < abs(y_b):
144
- x_a, x_b = x_b, x_a
145
- y_a, y_b = y_b, y_a
146
-
147
- self._val = x_a, x_b, x_c
148
- self._val_f = y_a, y_b, y_c
102
+ x_a, x_b, x_c = self._val
103
+ y_a, y_b, y_c = self._val_f
104
+ x_d = 0
105
+ self._x_min = min([x_a, x_b])
106
+ self._x_max = max([x_a, x_b])
107
+ if len(self._val_f) == len(set(self._val_f)):
108
+ # si los y son diferentes se usa el método de la cuadrática inversa
109
+ self.x = x_a * y_b * y_c / ((y_a - y_b) * (y_a - y_c)) + x_b * y_a * y_c / (
110
+ (y_b - y_a) * (y_b - y_c)) + x_c * y_a * y_b / ((y_c - y_a) * (y_c - y_b))
111
+ else:
112
+ # Se usa el método de la falsa posición
113
+ self.x = (y_a * x_b - y_b * x_a) / (y_a - y_b)
114
+ if (self.x - (3 * x_a + x_b) / 4) * (self.x - x_b) >= 0 or (
115
+ self._biseccion_usada and abs(self.x - x_b) >= abs(x_b - x_c) / 2) or (
116
+ not self._biseccion_usada and abs(self.x - x_b) >= abs(x_c - x_d) / 2):
117
+ self.x = (x_a + x_b) / 2
118
+ self._biseccion_usada = True
119
+ else:
120
+ self._biseccion_usada = False
121
+ y_x = self._f(self.x)
122
+ # x_d = x_c # TODO Revisar el código esta variable porque no se usa
123
+ x_c = x_b
124
+ y_c = y_b
125
+ if np.sign(y_a) == np.sign(y_x):
126
+ x_a = self.x
127
+ y_a = y_x
128
+ else:
129
+ x_b = self.x
130
+ y_b = y_x
131
+ if abs(y_a) < abs(y_b):
132
+ x_t = x_a
133
+ y_t = y_a
134
+ x_a = x_b
135
+ y_a = y_b
136
+ x_b = x_t
137
+ y_b = y_t
138
+ self._val = x_a, x_b, x_c
139
+ self._val_f = y_a, y_b, y_c
140
+ if self._fin_iteracion():
141
+ return
142
+ else:
143
+ self._calcular()
149
144
 
150
145
  def graficar(self, mostrar_sol: bool = True, mostrar_iter: bool = True, mostrar_lin_iter: bool = False,
151
146
  n_puntos: int = 100):
@@ -86,18 +86,16 @@ class FalsaPosicion(Raices):
86
86
  print("La raíz no está dentro de este rango, pruebe con otro rango de datos")
87
87
  sys.exit()
88
88
 
89
- # Bucle de iteración para evitar recursión profunda
90
- while True:
91
- self.x = self._x_max - (self._f(self._x_max) * (self._x_min - self._x_max)) / (
92
- self._f(self._x_min) - self._f(self._x_max))
93
-
94
- if self._fin_iteracion():
95
- break # Convergencia o máximo de iteraciones alcanzado
96
-
97
- if np.sign(self._f(self._x_min)) == np.sign(self._f(self.x)):
98
- self._x_min = self.x
99
- else:
100
- self._x_max = self.x
89
+ self.x = self._x_max - (self._f(self._x_max) * (self._x_min - self._x_max)) / (
90
+ self._f(self._x_min) - self._f(self._x_max))
91
+ if self._fin_iteracion():
92
+ return
93
+ elif np.sign(self._f(self._x_min)) == np.sign(self._f(self.x)):
94
+ self._x_min = self.x
95
+ self._calcular()
96
+ elif np.sign(self._f(self._x_max)) == np.sign(self._f(self.x)):
97
+ self._x_max = self.x
98
+ self._calcular()
101
99
 
102
100
  def graficar(self, mostrar_sol: bool = True, mostrar_iter: bool = True, mostrar_lin_iter: bool = True,
103
101
  n_puntos: int = 100):
@@ -88,40 +88,34 @@ class Muller(Raices):
88
88
  -------
89
89
  None
90
90
  """
91
- # Bucle de iteración para evitar recursión profunda
92
- while True:
93
- h_0 = self._x_1_i - self._x_0_i
94
- h_1 = self._x_2_i - self._x_1_i
95
- d_0 = (self._f(self._x_1_i) - self._f(self._x_0_i)) / h_0
96
- d_1 = (self._f(self._x_2_i) - self._f(self._x_1_i)) / h_1
97
-
98
- # Coeficientes de la parábola a*x^2 + b*x + c
99
- a = (d_1 - d_0) / (h_1 + h_0)
100
- b = a * h_1 + d_1
101
- c = self._f(self._x_2_i)
102
-
103
- # Guardar coeficientes para graficar
104
- self._a_2.append(a)
105
- self._a_1.append(d_0)
106
- self._a_0.append(self._f(self._x_0_i))
107
- self._list_x_0.append(self._x_0_i)
108
- self._list_x_1.append(self._x_1_i)
109
- self._list_x_2.append(self._x_2_i)
110
-
111
- # Fórmula cuadrática, se elige el denominador más grande para evitar restas catastróficas.
112
- rad = np.sqrt(b ** 2 - 4 * a * c)
113
- if abs(b + rad) > abs(b - rad):
114
- den = b + rad
115
- else:
116
- den = b - rad
117
-
118
- self.x = self._x_2_i - (2 * c / den)
119
-
120
- if self._fin_iteracion():
121
- break # Convergencia o máximo de iteraciones alcanzado
122
-
123
- # Actualizar los puntos para la siguiente iteración
124
- self._x_0_i, self._x_1_i, self._x_2_i = self._x_1_i, self._x_2_i, self.x
91
+ h_0 = self._x_1_i - self._x_0_i
92
+ h_1 = self._x_2_i - self._x_1_i
93
+ d_0 = (self._f(self._x_1_i) - self._f(self._x_0_i)) / h_0
94
+ d_1 = (self._f(self._x_2_i) - self._f(self._x_1_i)) / h_1
95
+ a = (d_1 - d_0) / (h_1 + h_0)
96
+ b = a * h_1 + d_1
97
+ c = self._f(self._x_2_i)
98
+ # ***
99
+ self._a_2 += [a]
100
+ self._a_1 += [d_0]
101
+ self._a_0 += [self._f(self._x_0_i)]
102
+ self._list_x_0 += [self._x_0_i]
103
+ self._list_x_1 += [self._x_1_i]
104
+ self._list_x_2 += [self._x_2_i]
105
+ # ***
106
+ rad = np.sqrt(b ** 2 - 4 * a * c)
107
+ if abs(b + rad) > abs(b - rad):
108
+ den = b + rad
109
+ else:
110
+ den = b - rad
111
+ self.x = self._x_2_i - 2 * c / den
112
+ if self._fin_iteracion():
113
+ return
114
+ else:
115
+ self._x_0_i = self._x_1_i
116
+ self._x_1_i = self._x_2_i
117
+ self._x_2_i = self.x
118
+ self._calcular()
125
119
 
126
120
  def graficar(self, mostrar_sol: bool = True, mostrar_iter: bool = True, mostrar_lin_iter: bool = True,
127
121
  n_puntos: int = 100):
@@ -117,9 +117,11 @@ class NewtonRaphson(Raices):
117
117
  -------
118
118
  None
119
119
  """
120
- # Bucle de iteración para evitar recursión profunda
121
- while not self._fin_iteracion():
122
- self.x -= self._f(self.x) / self._df(self.x)
120
+ self.x -= self._f(self.x) / self._df(self.x)
121
+ if self._fin_iteracion():
122
+ return
123
+ else:
124
+ self._calcular()
123
125
 
124
126
  def graficar(self, mostrar_sol: bool = True, mostrar_iter: bool = True, mostrar_lin_iter: bool = True,
125
127
  n_puntos: int = 100):
@@ -74,10 +74,11 @@ class PuntoFijo(Raices):
74
74
  -------
75
75
  None
76
76
  """
77
- # Bucle de iteración para evitar recursión profunda
78
- while not self._fin_iteracion():
79
- # self.x = self._f(self.x) # La función f es en realidad g(x)
80
- self.x = self._f(self.x)
77
+ self.x += self._f(self.x) - self.x
78
+ if self._fin_iteracion():
79
+ return
80
+ else:
81
+ self._calcular()
81
82
 
82
83
  def graficar(self, mostrar_sol: bool = True, mostrar_iter: bool = True, mostrar_lin_iter: bool = True,
83
84
  n_puntos: int = 100):
@@ -82,7 +82,7 @@ class Raices:
82
82
  Tipo de error a utilizar para la convergencia:
83
83
  - ``'%'``: Error relativo porcentual (por defecto).
84
84
  - ``'/'``: Error relativo.
85
- - ``'n'``: Número de cifras significativas.
85
+ - ``'n'``: Número de cifras significativas. εs = (0.5 * 10^(2-n)) % (Scarborough, 1966)
86
86
  """
87
87
  self._f = f
88
88
  self._tol = tol
@@ -80,13 +80,14 @@ class Secante(Raices):
80
80
  -------
81
81
  None
82
82
  """
83
- # Bucle de iteración para evitar recursión profunda
84
- while not self._fin_iteracion():
85
- # Fórmula del método de la secante
86
- self.x = self._x_1_i - (self._f(self._x_1_i) * (self._x_1_i - self._x_0_i)) / (
87
- self._f(self._x_1_i) - self._f(self._x_0_i))
88
- # Actualizar los puntos para la siguiente iteración
89
- self._x_0_i, self._x_1_i = self._x_1_i, self.x
83
+ self.x -= (self._f(self._x_1_i) * (self._x_1_i - self._x_0_i)) / (
84
+ self._f(self._x_1_i) - self._f(self._x_0_i))
85
+ self._x_0_i = self._x_1_i
86
+ self._x_1_i = self.x
87
+ if self._fin_iteracion():
88
+ return
89
+ else:
90
+ self._calcular()
90
91
 
91
92
  def graficar(self, mostrar_sol: bool = True, mostrar_iter: bool = True, mostrar_lin_iter: bool = True,
92
93
  n_puntos: int = 100):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mnspy
3
- Version: 0.9.15
3
+ Version: 0.9.17
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
@@ -28,11 +28,11 @@ mnspy/ecuaciones_diferenciales_parciales/mef/__init__.py,sha256=-ZqVb1Pn4CGcUKL5
28
28
  mnspy/ecuaciones_diferenciales_parciales/mef/armadura.py,sha256=J0Og6NCSBLcwZCsb2_tzPdZAnUfLiSO-BZ82b86GC7Q,14761
29
29
  mnspy/ecuaciones_diferenciales_parciales/mef/barra.py,sha256=FB8dVdtRSMRAQYCjYgC8_yO8nShk8_uDBt5meHrAz9c,9867
30
30
  mnspy/ecuaciones_diferenciales_parciales/mef/ensamble.py,sha256=U6OrhxMubrmnIKkXyfTdM9UoQcAunTqRUcfxMGWtx30,105934
31
- mnspy/ecuaciones_diferenciales_parciales/mef/marco.py,sha256=60KMFmHB3fKd-W3Zdz4uZAQU42cYO_gV_0FzHjc1CcE,69041
31
+ mnspy/ecuaciones_diferenciales_parciales/mef/marco.py,sha256=LGTZ--wfC3Bytp242aCX4iVQ4okD69tC04dIbaX8fJQ,70564
32
32
  mnspy/ecuaciones_diferenciales_parciales/mef/mef.py,sha256=SotSyqCblPRwcnzr1j0srKA60hKuPIzIWTjXSZu3nhw,43812
33
33
  mnspy/ecuaciones_diferenciales_parciales/mef/resorte.py,sha256=Jeq9bQjLfmIW0jkNA-ob6C27k5JGywZ1T9qLr4hMD0Q,13852
34
34
  mnspy/ecuaciones_diferenciales_parciales/mef/triangular_cst.py,sha256=nWK1uv9F9wpE_eelfhm1LyDiW7aMnckKf0mIcuhiY7U,12094
35
- mnspy/ecuaciones_diferenciales_parciales/mef/viga.py,sha256=-ys-041bJ0fSKrZ-cjyzfRzASMCCkTsSrw4145Mmo7c,41499
35
+ mnspy/ecuaciones_diferenciales_parciales/mef/viga.py,sha256=-YNv-_XJabSmvSKGUREWhjClNd9Ip0QSa8zYNASF05s,42505
36
36
  mnspy/ecuaciones_diferenciales_parciales/mvf/__init__.py,sha256=TDanegLPvu7-F5UYKEFdDXhXUeptbYDzPcD7N3Ozd8s,1369
37
37
  mnspy/ecuaciones_diferenciales_parciales/mvf/mvf.py,sha256=nthYy1DeRYHEi3E_yX4GeEbAhZAdJAkZJzPEWwjkpfg,30053
38
38
  mnspy/ecuaciones_diferenciales_parciales/mvf/volumen_finito.py,sha256=cjIenv-mMDhfPXj0uL24G0Sm9WexWAane3ni8GXvoPc,32334
@@ -53,18 +53,18 @@ mnspy/interpolación/inter_spline_cubica.py,sha256=1oBT-t5zVB5RrLx6BkUWweKdwVwI_
53
53
  mnspy/interpolación/inter_spline_lineal.py,sha256=-UZUBcTLKIZqZw2ZZd2qIyxJK2Q4dqlZxRBdz-0jvuY,5196
54
54
  mnspy/interpolación/interpolacion.py,sha256=gV7OoLzGbN-p1L3vr-cXhoYd13vysVpLXpg8JujwfAc,1695
55
55
  mnspy/raíces/__init__.py,sha256=8_8u3bPEoHjh804bNVZVbNM2UOv-RiC7TmzCrz6zHCc,1497
56
- mnspy/raíces/bisección.py,sha256=PHXWJfZ5CZ2jZLlpTdZWjsOI6U_W6MH-HfQwAWZJ5yA,5682
57
- mnspy/raíces/brent.py,sha256=OisCG3poUL5m3XOPip6nARu50UTTSWzOr2JN_Qj8srU,7090
58
- mnspy/raíces/falsa_posicion.py,sha256=XMHdOr_VD4avticGWxFBr2GzVL0y-Qb0hHf7OAI_hwQ,5419
59
- mnspy/raíces/muller.py,sha256=xA77ltemBu-m7HFumazqPFbSpEBmffzfsZKZqzjclC0,6313
60
- mnspy/raíces/newton_raphson.py,sha256=S7DTVCxSwMr1l9YScM7B3dlemN1NIdJM74AaGJApChw,6442
61
- mnspy/raíces/punto_fijo.py,sha256=yGlx3PZ19s2ENtb515ytH1Vxw0Van_6-hyC2XRWLi4g,4711
62
- mnspy/raíces/raices.py,sha256=lTjSOk84sg1VdlElmHaZSRen00zpt0jNrnFBx_SStnU,17510
63
- mnspy/raíces/secante.py,sha256=t8-NcN-Ki8BYrh3Cf3VUjaaRLxz6qV1v5i8johKBlZs,5220
56
+ mnspy/raíces/bisección.py,sha256=JHP8o48I58NWNAQwEDUfzotMTJsY4ZkyHaET_fd1AlE,5638
57
+ mnspy/raíces/brent.py,sha256=RwGSRcAeFp-Qy8XMmcEU6UqEcNb0RP1UYdmVMMiXngs,6689
58
+ mnspy/raíces/falsa_posicion.py,sha256=NAqgo9_U1XkWtUc9s9lcV4IpJ_-vxw_3b5p9pzDOQvs,5371
59
+ mnspy/raíces/muller.py,sha256=XkXLk99TrW_0hYam5CrzrmSJi6fJx-KhhaRL7_xLzcs,5886
60
+ mnspy/raíces/newton_raphson.py,sha256=HccOD0TZovQEzBi16Rcsg7gc7tvlrWPNplcpGDL6g04,6431
61
+ mnspy/raíces/punto_fijo.py,sha256=XCRl-rUsuMkYy2baptXT_wPXBLGht-r2_qegAKwv8xo,4635
62
+ mnspy/raíces/raices.py,sha256=GF6QTry--5piS5F2kw0gSnElNEBajdez-tZB8gQOkZM,17556
63
+ mnspy/raíces/secante.py,sha256=mLYNV4dwy2BLveAlehSVdqiAlY0-ORT-tEDlWbjvs3Y,5082
64
64
  mnspy/raíces/secante_modificada.py,sha256=0bLgcG8K_O6Ras3vKBIQpUdDlB69tWKHbx_fE8-47SE,5105
65
65
  mnspy/raíces/wegstein.py,sha256=23HQ6QuelMNo8S8W1fzha8ozbcy_NdsjK5XLMaH-m38,5397
66
- mnspy-0.9.15.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
67
- mnspy-0.9.15.dist-info/METADATA,sha256=PiLUJ3EW2mycuVYMxCmqOPok950hd2SUNq5KHnWota8,4641
68
- mnspy-0.9.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
69
- mnspy-0.9.15.dist-info/top_level.txt,sha256=fbooZdZwS41I8vFuAXnn5qL4_mfc1aPt_DM60ZpvtKE,6
70
- mnspy-0.9.15.dist-info/RECORD,,
66
+ mnspy-0.9.17.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
67
+ mnspy-0.9.17.dist-info/METADATA,sha256=twCh69elQkudvd9rk65dmONJMOyh3pPgVVJRFAjE0tY,4641
68
+ mnspy-0.9.17.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
69
+ mnspy-0.9.17.dist-info/top_level.txt,sha256=fbooZdZwS41I8vFuAXnn5qL4_mfc1aPt_DM60ZpvtKE,6
70
+ mnspy-0.9.17.dist-info/RECORD,,
File without changes