pyMOTO 1.2.0__tar.gz → 1.2.1__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 (43) hide show
  1. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/PKG-INFO +1 -1
  2. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pyMOTO.egg-info/PKG-INFO +1 -1
  3. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pyMOTO.egg-info/SOURCES.txt +1 -0
  4. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/__init__.py +1 -1
  5. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/common/domain.py +3 -3
  6. pyMOTO-1.2.1/tests/test_assembly.py +91 -0
  7. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/LICENSE +0 -0
  8. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/README.md +0 -0
  9. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pyMOTO.egg-info/dependency_links.txt +0 -0
  10. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pyMOTO.egg-info/requires.txt +0 -0
  11. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pyMOTO.egg-info/top_level.txt +0 -0
  12. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pyMOTO.egg-info/zip-safe +0 -0
  13. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/common/dyadcarrier.py +0 -0
  14. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/common/mma.py +0 -0
  15. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/common/solvers.py +0 -0
  16. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/common/solvers_dense.py +0 -0
  17. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/common/solvers_sparse.py +0 -0
  18. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/core_objects.py +0 -0
  19. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/modules/assembly.py +0 -0
  20. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/modules/autodiff.py +0 -0
  21. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/modules/complex.py +0 -0
  22. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/modules/filter.py +0 -0
  23. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/modules/generic.py +0 -0
  24. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/modules/io.py +0 -0
  25. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/modules/linalg.py +0 -0
  26. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/modules/scaling.py +0 -0
  27. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/routines.py +0 -0
  28. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pymoto/utils.py +0 -0
  29. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/pyproject.toml +0 -0
  30. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/setup.cfg +0 -0
  31. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/tests/test_automod.py +0 -0
  32. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/tests/test_complex.py +0 -0
  33. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/tests/test_core.py +0 -0
  34. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/tests/test_dyadcarrier.py +0 -0
  35. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/tests/test_linsolve_sparse.py +0 -0
  36. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/tests/test_module_concatsignal.py +0 -0
  37. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/tests/test_module_eigensolve.py +0 -0
  38. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/tests/test_module_einsum.py +0 -0
  39. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/tests/test_module_mathgeneral.py +0 -0
  40. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/tests/test_scaling.py +0 -0
  41. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/tests/test_solvers_dense.py +0 -0
  42. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/tests/test_solvers_sparse.py +0 -0
  43. {pyMOTO-1.2.0 → pyMOTO-1.2.1}/tests/test_static_condenstation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyMOTO
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: A modular approach for topology optimization
5
5
  Home-page: https://github.com/aatmdelissen/pyMOTO
6
6
  Author: Arnoud Delissen
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyMOTO
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: A modular approach for topology optimization
5
5
  Home-page: https://github.com/aatmdelissen/pyMOTO
6
6
  Author: Arnoud Delissen
@@ -26,6 +26,7 @@ pymoto/modules/generic.py
26
26
  pymoto/modules/io.py
27
27
  pymoto/modules/linalg.py
28
28
  pymoto/modules/scaling.py
29
+ tests/test_assembly.py
29
30
  tests/test_automod.py
30
31
  tests/test_complex.py
31
32
  tests/test_core.py
@@ -1,4 +1,4 @@
1
- __version__ = '1.2.0'
1
+ __version__ = '1.2.1'
2
2
 
3
3
  from .common.domain import DomainDefinition
4
4
 
@@ -184,10 +184,10 @@ class DomainDefinition:
184
184
  """
185
185
  v = np.prod(self.element_size[:self.dim])
186
186
  assert v > 0.0, 'Element volume needs to be positive'
187
- ret = np.ones(self.nnodes)/v
187
+ shapefn = np.ones(self.elemnodes)/v
188
188
  for i in range(self.dim):
189
- ret *= np.array([self.element_size[i] + n[i]*pos[i] for n in self.node_numbering])
190
- return ret
189
+ shapefn *= np.array([self.element_size[i]/2 + n[i]*pos[i] for n in self.node_numbering])
190
+ return shapefn
191
191
 
192
192
  def eval_shape_fun_der(self, pos: np.ndarray):
193
193
  """ Evaluates the shape function derivatives in x, y, and optionally z-direction.
@@ -0,0 +1,91 @@
1
+ import unittest
2
+ import numpy as np
3
+ import pymoto as pym
4
+ import numpy.testing as npt
5
+
6
+
7
+ class TestAssembleStiffness(unittest.TestCase):
8
+ def test_FEA_pure_tensile_2d_one_element(self):
9
+ Lx, Ly, Lz = 0.1, 0.2, 0.3
10
+ domain = pym.DomainDefinition(1, 1, unitx=Lx, unity=Ly, unitz=Lz)
11
+ nodidx_left = domain.get_nodenumber(0, np.arange(domain.nely + 1))
12
+ # Fixed at bottom, roller at the top in y-direction
13
+ nodidx_right = domain.get_nodenumber(domain.nelx, np.arange(domain.nely + 1))
14
+ dofidx_left = np.concatenate([nodidx_left*2, np.array([nodidx_left[0]*2 + 1])])
15
+
16
+ E, nu = 210e+9, 0.3
17
+
18
+ s_x = pym.Signal('x', state=np.ones(domain.nel))
19
+
20
+ # Assemble stiffness matrix
21
+ m_K = pym.AssembleStiffness(s_x, domain=domain, bc=dofidx_left, e_modulus=E, poisson_ratio=nu, plane='stress')
22
+ s_K = m_K.sig_out[0]
23
+
24
+ m_K.response()
25
+ F = 1.5
26
+ f = np.zeros(domain.nnodes*2)
27
+ f[nodidx_right * 2] = F/nodidx_right.size
28
+ x = np.linalg.solve(s_K.state.toarray(), f)
29
+
30
+ # Bottom y displacement should be zero
31
+ npt.assert_allclose(x[nodidx_right[0]*2+1], 0, atol=1e-10)
32
+
33
+ # Analytical axial displacement using stiffness k = EA/L
34
+ ux_chk = F * Lx / (E * Ly * Lz)
35
+ npt.assert_allclose(x[nodidx_right*2], ux_chk, rtol=1e-10)
36
+
37
+ # Transverse displacement using Poisson's effect
38
+ e_xx = ux_chk / Lx # Strain in x-direction
39
+ e_yy = - nu * e_xx
40
+ uy_chk = e_yy * Ly
41
+ npt.assert_allclose(x[nodidx_right[1]*2+1], uy_chk, rtol=1e-10)
42
+
43
+ def test_FEA_pure_tensile_3d_one_element(self):
44
+ Lx, Ly, Lz = 0.1, 0.2, 0.3
45
+ domain = pym.DomainDefinition(1, 1, 1, unitx=Lx, unity=Ly, unitz=Lz)
46
+ nodidx_left = domain.get_nodenumber(*np.meshgrid(0, range(domain.nely + 1), range(domain.nelz + 1))).flatten()
47
+ # Fixed at (0,0,0), roller in z-direction at (0, 1, 0), roller in y-direction at (0, 0, 1)
48
+ nod_00 = domain.get_nodenumber(0, 0, 0)
49
+ nod_10 = domain.get_nodenumber(0, 1, 0)
50
+ nod_01 = domain.get_nodenumber(0, 0, 1)
51
+ dofidx_left = np.concatenate([nodidx_left * 3, np.array([nod_00, nod_01]) * 3 + 1, np.array([nod_00, nod_10]) * 3 + 2])
52
+ nodidx_right = domain.get_nodenumber(*np.meshgrid(1, range(domain.nely + 1), range(domain.nelz + 1))).flatten()
53
+
54
+ E, nu = 210e+9, 0.3
55
+
56
+ s_x = pym.Signal('x', state=np.ones(domain.nel))
57
+
58
+ # Assemble stiffness matrix
59
+ m_K = pym.AssembleStiffness(s_x, domain=domain, bc=dofidx_left, e_modulus=E, poisson_ratio=nu)
60
+ s_K = m_K.sig_out[0]
61
+
62
+ m_K.response()
63
+ F = 1.5e+3
64
+ f = np.zeros(domain.nnodes * 3)
65
+ f[nodidx_right * 3] = F / nodidx_right.size
66
+ x = np.linalg.solve(s_K.state.toarray(), f)
67
+
68
+ # y and z displacements at (1, 0, 0) should be zero
69
+ npt.assert_allclose(x[domain.get_nodenumber(1, 0, 0) * 3 + 1], 0, atol=1e-10)
70
+ npt.assert_allclose(x[domain.get_nodenumber(1, 0, 0) * 3 + 2], 0, atol=1e-10)
71
+
72
+ # Z displacement at (1, 1, 0) should be zero
73
+ npt.assert_allclose(x[domain.get_nodenumber(1, 1, 0) * 3 + 2], 0, atol=1e-10)
74
+
75
+ # Y displacement at (1, 0, 1) should be zero
76
+ npt.assert_allclose(x[domain.get_nodenumber(1, 0, 1) * 3 + 1], 0, atol=1e-10)
77
+
78
+ # Analytical axial displacement using stiffness k = EA/L
79
+ ux_chk = F * Lx / (E * Ly * Lz)
80
+ npt.assert_allclose(x[nodidx_right * 3], ux_chk, rtol=1e-10)
81
+
82
+ # Transverse displacement using Poisson's effect
83
+ e_xx = ux_chk / Lx # Strain in x-direction
84
+ e_trans = - nu * e_xx
85
+ uy_chk = e_trans * Ly
86
+ npt.assert_allclose(x[domain.get_nodenumber(1, 1, 0) * 3 + 1], uy_chk, rtol=1e-10)
87
+ npt.assert_allclose(x[domain.get_nodenumber(1, 1, 1) * 3 + 1], uy_chk, rtol=1e-10)
88
+
89
+ uz_chk = e_trans * Lz
90
+ npt.assert_allclose(x[domain.get_nodenumber(1, 0, 1) * 3 + 2], uz_chk, rtol=1e-10)
91
+ npt.assert_allclose(x[domain.get_nodenumber(1, 1, 1) * 3 + 2], uz_chk, rtol=1e-10)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes