EasyFEA 1.2.0__tar.gz → 1.2.2__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 (55) hide show
  1. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/Geoms.py +54 -49
  2. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/Materials.py +2 -2
  3. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/fem/_boundary_conditions.py +33 -32
  4. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/fem/_gauss.py +4 -5
  5. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/fem/_gmsh_interface.py +272 -207
  6. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/fem/_group_elems.py +221 -201
  7. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/fem/_mesh.py +109 -106
  8. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/fem/_utils.py +8 -8
  9. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/materials/_beam.py +39 -35
  10. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/materials/_elastic.py +89 -81
  11. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/materials/_phasefield.py +309 -233
  12. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/materials/_thermal.py +3 -2
  13. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/materials/_utils.py +63 -55
  14. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/simulations/Solvers.py +19 -18
  15. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/simulations/_beam.py +18 -19
  16. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/simulations/_dic.py +86 -85
  17. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/simulations/_elastic.py +38 -41
  18. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/simulations/_phasefield.py +131 -120
  19. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/simulations/_simu.py +121 -128
  20. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/simulations/_thermal.py +10 -11
  21. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/simulations/_utils.py +1 -1
  22. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/utilities/Display.py +76 -73
  23. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/utilities/Folder.py +14 -6
  24. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/utilities/Paraview_Interface.py +11 -10
  25. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/utilities/PyVista_Interface.py +20 -26
  26. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/utilities/_tic.py +6 -5
  27. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA.egg-info/PKG-INFO +5 -2
  28. {EasyFEA-1.2.0 → easyfea-1.2.2}/PKG-INFO +5 -2
  29. {EasyFEA-1.2.0 → easyfea-1.2.2}/README.md +4 -1
  30. {EasyFEA-1.2.0 → easyfea-1.2.2}/pyproject.toml +1 -1
  31. {EasyFEA-1.2.0 → easyfea-1.2.2}/AUTHORS.md +0 -0
  32. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/Simulations.py +0 -0
  33. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/__about__.py +0 -0
  34. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/__init__.py +0 -0
  35. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/fem/__init__.py +0 -0
  36. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/fem/elems/__init__.py +0 -0
  37. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/fem/elems/_hexa.py +0 -0
  38. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/fem/elems/_point.py +0 -0
  39. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/fem/elems/_prism.py +0 -0
  40. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/fem/elems/_quad.py +0 -0
  41. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/fem/elems/_seg.py +0 -0
  42. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/fem/elems/_tetra.py +0 -0
  43. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/fem/elems/_tri.py +0 -0
  44. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/materials/__init__.py +0 -0
  45. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/simulations/__init__.py +0 -0
  46. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/utilities/Numba_Interface.py +0 -0
  47. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/utilities/__init__.py +0 -0
  48. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA/utilities/_observers.py +0 -0
  49. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA.egg-info/SOURCES.txt +0 -0
  50. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA.egg-info/dependency_links.txt +0 -0
  51. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA.egg-info/requires.txt +0 -0
  52. {EasyFEA-1.2.0 → easyfea-1.2.2}/EasyFEA.egg-info/top_level.txt +0 -0
  53. {EasyFEA-1.2.0 → easyfea-1.2.2}/LICENSE.txt +0 -0
  54. {EasyFEA-1.2.0 → easyfea-1.2.2}/setup.cfg +0 -0
  55. {EasyFEA-1.2.0 → easyfea-1.2.2}/setup.py +0 -0
@@ -19,7 +19,7 @@ from abc import ABC, abstractmethod
19
19
  class Point:
20
20
 
21
21
  def __init__(self, x=0.0, y=0.0, z=0.0, isOpen=False, r=0.0):
22
- """Build a point.
22
+ """Creates a point.
23
23
 
24
24
  Parameters
25
25
  ----------
@@ -83,7 +83,7 @@ class Point:
83
83
  self.__isOpen = value
84
84
 
85
85
  def Check(self, coord) -> bool:
86
- """Check if coordinates are identical"""
86
+ """Checks if coordinates are identical"""
87
87
  coord = As_Coordinates(coord)
88
88
  n = np.linalg.norm(self.coord)
89
89
  n = 1 if n == 0 else n
@@ -91,11 +91,11 @@ class Point:
91
91
  return diff <= 1e-12
92
92
 
93
93
  def Translate(self, dx: float=0.0, dy: float=0.0, dz: float=0.0) -> None:
94
- """Translate the point."""
94
+ """Translates the point."""
95
95
  self.__coord = Translate_coord(self.__coord, dx, dy, dz).ravel()
96
96
 
97
97
  def Rotate(self, theta: float, center: tuple=(0,0,0), direction: tuple=(0,0,1)) -> None:
98
- """Rotate the point with around an axis.
98
+ """Rotates the point with around an axis.
99
99
 
100
100
  Parameters
101
101
  ----------
@@ -109,7 +109,7 @@ class Point:
109
109
  self.__coord = Rotate_coord(self.__coord, theta, center, direction).ravel()
110
110
 
111
111
  def Symmetry(self, point=(0,0,0), n=(1,0,0)) -> None:
112
- """Symmetrise the point coordinates with a plane.
112
+ """Symmetrizes the point coordinates with a plane.
113
113
 
114
114
  Parameters
115
115
  ----------
@@ -166,7 +166,7 @@ class Point:
166
166
  class _Geom(ABC):
167
167
 
168
168
  def __init__(self, points: list[Point], meshSize: float, name: str, isHollow: bool, isOpen: bool):
169
- """Builds a geometric object.
169
+ """Creates a geometric object.
170
170
 
171
171
  Parameters
172
172
  ----------
@@ -193,7 +193,7 @@ class _Geom(ABC):
193
193
 
194
194
  @property
195
195
  def meshSize(self) -> float:
196
- """Element size used for meshing"""
196
+ """element size used for meshing"""
197
197
  return self.__meshSize
198
198
 
199
199
  @meshSize.setter
@@ -235,7 +235,7 @@ class _Geom(ABC):
235
235
 
236
236
  @property
237
237
  def isHollow(self) -> bool:
238
- """Indicates whether the the formed domain is hollow/empty."""
238
+ """Indicates whether the the formed domain is hollow/filled."""
239
239
  return self.__isHollow
240
240
 
241
241
  @isHollow.setter
@@ -254,12 +254,12 @@ class _Geom(ABC):
254
254
  self.__isOpen = value
255
255
 
256
256
  def Translate(self, dx: float=0.0, dy: float=0.0, dz: float=0.0) -> None:
257
- """Translate the object."""
257
+ """Translates the object."""
258
258
  # to translate an object, all you have to do is move these points
259
259
  [p.Translate(dx,dy,dz) for p in self.__points]
260
260
 
261
261
  def Rotate(self, theta: float, center: tuple=(0,0,0), direction: tuple=(0,0,1)) -> None:
262
- """Rotate the object coordinates around an axis.
262
+ """Rotates the object coordinates around an axis.
263
263
 
264
264
  Parameters
265
265
  ----------
@@ -277,7 +277,7 @@ class _Geom(ABC):
277
277
  [point.Translate(*dec[p]) for p, point in enumerate(self.points)]
278
278
 
279
279
  def Symmetry(self, point=(0,0,0), n=(1,0,0)) -> None:
280
- """Symmetrise the object coordinates with a plane.
280
+ """Symmetrizes the object coordinates with a plane.
281
281
 
282
282
  Parameters
283
283
  ----------
@@ -295,18 +295,20 @@ class _Geom(ABC):
295
295
 
296
296
  def Plot(self, ax: plt.Axes=None, color:str="", name:str="", lw=None, ls=None, plotPoints=True) -> plt.Axes:
297
297
 
298
- from EasyFEA import Display
298
+ from .utilities import Display
299
299
 
300
300
  if ax is None:
301
301
  ax = Display.Init_Axes(3)
302
302
 
303
303
  inDim = 3 if ax.name == '3d' else 2
304
304
 
305
+ name = self.name if name == "" else name
306
+
305
307
  lines, points = self.Get_coord_for_plot()
306
308
  if color != "":
307
- ax.plot(*lines[:,:inDim].T, color=color, label=self.name, lw=lw, ls=ls)
309
+ ax.plot(*lines[:,:inDim].T, color=color, label=name, lw=lw, ls=ls)
308
310
  else:
309
- ax.plot(*lines[:,:inDim].T, label=self.name, lw=lw, ls=ls)
311
+ ax.plot(*lines[:,:inDim].T, label=name, lw=lw, ls=ls)
310
312
  if plotPoints:
311
313
  ax.plot(*points[:,:inDim].T, ls='', marker='.',c='black')
312
314
 
@@ -341,7 +343,8 @@ class Points(_Geom):
341
343
  __nbPoints = 0
342
344
 
343
345
  def __init__(self, points: list[Point], meshSize=0.0, isHollow=True, isOpen=False):
344
- """Builds a point list. Can be used to construct a closed surface or a spline.
346
+ """Creates points (list of point).\n
347
+ Can be used to construct a closed surface or a spline.
345
348
 
346
349
  Parameters
347
350
  ----------
@@ -367,21 +370,21 @@ class Points(_Geom):
367
370
  super().__init__(points, meshSize, name, isHollow, isOpen)
368
371
 
369
372
  def Get_Contour(self):
370
- """Builds a contour from the point list.\n
371
- Pass a fillet if a point has a radius which is not 0."""
373
+ """Creates a contour from the points.\n
374
+ Creates a fillet if a point has a radius which is not 0."""
372
375
 
373
376
  coordinates = self.coord
374
377
  N = coordinates.shape[0]
375
378
  mS = self.meshSize
376
379
 
377
- # TODO Permettre d'ajouter des congés ?
380
+ # TODO Allows the addition of chamfers?
378
381
 
379
382
  # Get corners
380
383
  corners: list[_Geom] = []
381
384
  geoms: list[_Geom] = []
382
385
 
383
386
  def Link(idx1: int, idx2: int):
384
- # this function make the link between corners[idx1] and corners[idx2]
387
+ # this function makes the link between corners[idx1] and corners[idx2]
385
388
 
386
389
  # get the last point associated with idx1
387
390
  if isinstance(corners[idx1], Point):
@@ -453,19 +456,19 @@ class Line(_Geom):
453
456
 
454
457
  @staticmethod
455
458
  def distance(pt1: Point, pt2: Point) -> float:
456
- """Calculate the distance between two points."""
459
+ """Computes the distance between two points."""
457
460
  length = np.sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2 + (pt1.z-pt2.z)**2)
458
461
  return np.abs(length)
459
462
 
460
463
  @staticmethod
461
464
  def get_unitVector(pt1: Point, pt2: Point) -> np.ndarray:
462
- """Construct the unit vector between two points."""
465
+ """Creates the unit vector between two points."""
463
466
  length = Line.distance(pt1, pt2)
464
467
  v = np.array([pt2.x-pt1.x, pt2.y-pt1.y, pt2.z-pt1.z])/length
465
468
  return v
466
469
 
467
470
  def __init__(self, pt1: Point, pt2: Point, meshSize=0.0, isOpen=False):
468
- """Builds a line.
471
+ """Creates a line.
469
472
 
470
473
  Parameters
471
474
  ----------
@@ -495,7 +498,7 @@ class Line(_Geom):
495
498
 
496
499
  @property
497
500
  def length(self) -> float:
498
- """Calculate the distance between the two points on the line"""
501
+ """distance between the two points of the line"""
499
502
  return Line.distance(self.pt1, self.pt2)
500
503
 
501
504
  def Get_coord_for_plot(self) -> tuple[np.ndarray,np.ndarray]:
@@ -506,7 +509,7 @@ class Domain(_Geom):
506
509
  __nbDomain = 0
507
510
 
508
511
  def __init__(self, pt1: Point, pt2: Point, meshSize=0.0, isHollow=True):
509
- """Builds a domain
512
+ """Creates a 2d or 3d domain.
510
513
 
511
514
  Parameters
512
515
  ----------
@@ -555,7 +558,7 @@ class Circle(_Geom):
555
558
  __nbCircle = 0
556
559
 
557
560
  def __init__(self, center: Point, diam: float, meshSize=0.0, isHollow=True, isOpen=False, n=(0,0,1)):
558
- """Constructing a circle according to its center, diameter and the normal vector
561
+ """Creates a circle according to its center, diameter and the normal vector.
559
562
 
560
563
  Parameters
561
564
  ----------
@@ -589,7 +592,7 @@ class Circle(_Geom):
589
592
  circleArc2 = CircleArc(self.pt2, self.pt3, center=center, meshSize=meshSize, isOpen=isOpen)
590
593
  circleArc3 = CircleArc(self.pt3, self.pt4, center=center, meshSize=meshSize, isOpen=isOpen)
591
594
  circleArc4 = CircleArc(self.pt4, self.pt1, center=center, meshSize=meshSize, isOpen=isOpen)
592
- # create the contour object associated with the circle
595
+ # creates the contour object associated with the circle
593
596
  self.contour = Contour([circleArc1, circleArc2, circleArc3, circleArc4], isHollow, isOpen)
594
597
 
595
598
  Circle.__nbCircle += 1
@@ -618,7 +621,7 @@ class Circle(_Geom):
618
621
 
619
622
  @property
620
623
  def diam(self) -> float:
621
- """circle diameter"""
624
+ """circle's diameter"""
622
625
  p1 = self.pt1.coord
623
626
  pC = self.center.coord
624
627
  return np.linalg.norm(p1-pC) * 2
@@ -664,11 +667,12 @@ class CircleArc(_Geom):
664
667
  __nbCircleArc = 0
665
668
 
666
669
  def __init__(self, pt1: Point, pt2: Point, center:Point=None, R:float=None, P:Point=None, meshSize=0.0, n=(0,0,1), isOpen=False, coef=1):
667
- """Construct a circular arc using several methods:
668
- 1: with 2 points, a radius R and a normal vector n.
669
- 2: with 2 points and a center
670
- 3: with 2 points and a point P belonging to the circle\n
671
- The methods are chosen in the following order 3 2 1. This means that if you enter P, the other methods will not be used.
670
+ """Creates a circular arc using several methods:\n
671
+ - 1: with 2 points, a radius R and a normal vector.\n
672
+ - 2: with 2 points and a center.\n
673
+ - 3: with 2 points and a point P belonging to the circle.\n
674
+ The methods are chosen in the following order 3 2 1.\n
675
+ This means that if you enter P, the other methods will not be used.
672
676
 
673
677
  Parameters
674
678
  ----------
@@ -695,7 +699,7 @@ class CircleArc(_Geom):
695
699
  assert isinstance(pt1, Point), "must be a point"
696
700
  assert isinstance(pt2, Point), "must be a point"
697
701
 
698
- # first check that pt1 and pt2 dont share the same coordinates
702
+ # checks that pt1 and pt2 dont share the same coordinates
699
703
  assert not pt1.Check(pt2), 'pt1 and pt2 are on the same coordinates'
700
704
 
701
705
  if P != None:
@@ -723,7 +727,7 @@ class CircleArc(_Geom):
723
727
  self.pt2 = pt2
724
728
  """Ending point of the arc."""
725
729
 
726
- # Here we'll create an intermediate point, because in gmsh, circular arcs are limited to an angle pi.
730
+ # Here we'll create an intermediate point, because in gmsh, circular arcs are limited to an pi angle.
727
731
 
728
732
  i1 = (pt1-center).coord
729
733
  i2 = (pt2-center).coord
@@ -810,7 +814,7 @@ class Contour(_Geom):
810
814
  __nbContour = 0
811
815
 
812
816
  def __init__(self, geoms: list[Union[Line,CircleArc,Points]], isHollow=True, isOpen=False):
813
- """Create a contour from a list of lines or arcs.
817
+ """Creates a contour from a list of line circleArc and points.
814
818
 
815
819
  Parameters
816
820
  ----------
@@ -910,7 +914,7 @@ def Normalize_vect(vect: np.ndarray) -> np.ndarray:
910
914
 
911
915
  def Rotation_matrix(vect: np.ndarray, theta: float) -> np.ndarray:
912
916
  """Gets the rotation matrix for turning along an axis with theta angle (rad).\n
913
- p(x,y) = matrice • p(i,j)\n
917
+ p(x,y) = mat • p(i,j)\n
914
918
  https://en.wikipedia.org/wiki/Rotation_matrix#Axis_and_angle"""
915
919
 
916
920
  x, y, z = Normalize_vect(vect)
@@ -925,7 +929,7 @@ def Rotation_matrix(vect: np.ndarray, theta: float) -> np.ndarray:
925
929
  return mat
926
930
 
927
931
  def AngleBetween_a_b(a: np.ndarray, b: np.ndarray) -> float:
928
- """Calculates the angle between vector a and vector b in radian.
932
+ """Computes the angle between vectors a and b (rad).
929
933
  https://math.stackexchange.com/questions/878785/how-to-find-an-angle-in-range0-360-between-2-vectors"""
930
934
 
931
935
  a = As_Coordinates(a)
@@ -950,7 +954,7 @@ def AngleBetween_a_b(a: np.ndarray, b: np.ndarray) -> float:
950
954
  return angle
951
955
 
952
956
  def Translate_coord(coord: np.ndarray, dx: float=0.0, dy: float=0.0, dz: float=0.0) -> np.ndarray:
953
- """Translate the coordinates."""
957
+ """Translates the coordinates."""
954
958
 
955
959
  oldCoord = np.reshape(coord, (-1, 3))
956
960
 
@@ -961,7 +965,7 @@ def Translate_coord(coord: np.ndarray, dx: float=0.0, dy: float=0.0, dz: float=0
961
965
  return newCoord
962
966
 
963
967
  def Rotate_coord(coord: np.ndarray, theta: float, center: tuple=(0,0,0), direction: tuple=(0,0,1)) -> np.ndarray:
964
- """Rotate the coordinates arround a specified center and axis.
968
+ """Rotates the coordinates arround a specified center and axis.
965
969
 
966
970
  Parameters
967
971
  ----------
@@ -995,7 +999,7 @@ def Rotate_coord(coord: np.ndarray, theta: float, center: tuple=(0,0,0), directi
995
999
  return newCoord
996
1000
 
997
1001
  def Symmetry_coord(coord: np.ndarray, point=(0,0,0), n=(1,0,0)) -> np.ndarray:
998
- """Symmetrise coordinates with a plane.
1002
+ """Symmetrizes coordinates with a plane.
999
1003
 
1000
1004
  Parameters
1001
1005
  ----------
@@ -1024,8 +1028,9 @@ def Symmetry_coord(coord: np.ndarray, point=(0,0,0), n=(1,0,0)) -> np.ndarray:
1024
1028
  return newCoord
1025
1029
 
1026
1030
  def Jacobian_Matrix(i: np.ndarray, k: np.ndarray) -> np.ndarray:
1027
- """Compute the Jacobian matrix to transform local coordinates (i,j,k) to global (x,y,z) coordinates.\n
1031
+ """Computes the Jacobian matrix to transform local coordinates (i,j,k) to global (x,y,z) coordinates.\n
1028
1032
  p(x,y,z) = J • p(i,j,k) and p(i,j,k) = inv(J) • p(x,y,z)\n\n
1033
+
1029
1034
  ix jx kx\n
1030
1035
  iy jy ky\n
1031
1036
  iz jz kz
@@ -1053,8 +1058,8 @@ def Jacobian_Matrix(i: np.ndarray, k: np.ndarray) -> np.ndarray:
1053
1058
  return F
1054
1059
 
1055
1060
  def Points_Rayon(P0: np.ndarray, P1: np.ndarray, P2: np.ndarray, r: float) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
1056
- """Calculation of point coordinates to create a radius in a corner P0.\n
1057
- return A, B, C
1061
+ """Computes fillet in a corner P0.\n
1062
+ returns A, B, C
1058
1063
 
1059
1064
  Parameters
1060
1065
  ----------
@@ -1065,7 +1070,7 @@ def Points_Rayon(P0: np.ndarray, P1: np.ndarray, P2: np.ndarray, r: float) -> tu
1065
1070
  P2 : np.ndarray
1066
1071
  coordinates after P0 coordinates
1067
1072
  r : float
1068
- radius at point P0
1073
+ radius (or fillet) at point P0
1069
1074
 
1070
1075
  Returns
1071
1076
  -------
@@ -1099,8 +1104,8 @@ def Points_Rayon(P0: np.ndarray, P1: np.ndarray, P2: np.ndarray, r: float) -> tu
1099
1104
  return A, B, C
1100
1105
 
1101
1106
  def Circle_Triangle(p1, p2, p3) -> np.ndarray:
1102
- """Return center and radius for the circumcicular arc formed by 3 points.\n
1103
- return center, R
1107
+ """Returns triangle's center for the circumcicular arc formed by 3 points.\n
1108
+ returns center
1104
1109
  """
1105
1110
 
1106
1111
  # https://math.stackexchange.com/questions/1076177/3d-coordinates-of-circle-center-given-three-point-on-the-circle
@@ -1125,7 +1130,7 @@ def Circle_Triangle(p1, p2, p3) -> np.ndarray:
1125
1130
  return center
1126
1131
 
1127
1132
  def Circle_Coord(coord: np.ndarray, R: float, n: np.ndarray) -> np.ndarray:
1128
- """Return center from coordinates a radius and and a vector normal to the circle.\n
1133
+ """Returns center from coordinates a radius and and a vector normal to the circle.\n
1129
1134
  return center
1130
1135
  """
1131
1136
 
@@ -1156,7 +1161,8 @@ def Circle_Coord(coord: np.ndarray, R: float, n: np.ndarray) -> np.ndarray:
1156
1161
  return center
1157
1162
 
1158
1163
  def Points_Intersect_Circles(circle1: Circle, circle2: Circle) -> np.ndarray:
1159
- """Calculates the coordinates at the intersection of the two circles (i,3). This only works if they're on the same plane.
1164
+ """Computes the coordinates at the intersection of the two circles (i,3).\n
1165
+ This only works if they're on the same plane.
1160
1166
 
1161
1167
  Parameters
1162
1168
  ----------
@@ -1192,7 +1198,6 @@ def Points_Intersect_Circles(circle1: Circle, circle2: Circle) -> np.ndarray:
1192
1198
  if d == r1 + r2:
1193
1199
  return p3.reshape(1, 3)
1194
1200
  else:
1195
-
1196
1201
  i = Normalize_vect(p2-p1)
1197
1202
  k = np.array([0,0,1])
1198
1203
  j = np.cross(k, i)
@@ -2,7 +2,7 @@
2
2
  # This file is part of the EasyFEA project.
3
3
  # EasyFEA is distributed under the terms of the GNU General Public License v3 or later, see LICENSE.txt and CREDITS.md for more information.
4
4
 
5
- """Module containing material behavior. Such as elastic, damage, thermal and beam materials."""
5
+ """Module containing constitutive laws for materials, including elastic, damage, thermal, and beam materials."""
6
6
 
7
7
  from .materials import Reshape_variable
8
8
 
@@ -22,7 +22,7 @@ from .materials._phasefield import PhaseField
22
22
  # Beam
23
23
  # ----------------------------------------------
24
24
 
25
- from .materials._beam import _Beam, Beam_Structure, Beam_Elas_Isot
25
+ from .materials._beam import _Beam, BeamStructure, Beam_Elas_Isot
26
26
 
27
27
  # ----------------------------------------------
28
28
  # Thermal
@@ -14,15 +14,15 @@ class BoundaryCondition:
14
14
  Parameters
15
15
  ----------
16
16
  problemType : str
17
- Type of the problem.
17
+ Problem type.
18
18
  nodes : np.ndarray
19
19
  Nodes on which the condition is applied.
20
20
  dofs : np.ndarray
21
- Degrees of freedom associated with nodes and directions.
21
+ Degrees of freedom (associated with nodes and directions).
22
22
  directions : np.ndarray
23
- Directions.
23
+ Dofs directions (e.g. [“x”, “y”], [“rz”]).
24
24
  dofsValues : np.ndarray
25
- Values applied to degrees of freedom.
25
+ Dofs values.
26
26
  description : str
27
27
  Description of the boundary condition.
28
28
  """
@@ -32,68 +32,69 @@ class BoundaryCondition:
32
32
  self.__dofs = np.asarray(dofs, dtype=int)
33
33
  assert self.dofs.size % self.nodes.size == 0, f"dofs.size must be a multiple of {self.nodes.size}"
34
34
  self.__dofsValues = np.asarray(dofsValues, dtype=float)
35
+ # assert dofs.size == dofsValues.size, "must be the same size." don't uncomment !
36
+ # This assertion is commented out to illustrate that using Lagrange conditions might bypass this size check.
35
37
  self.description = description
36
38
 
37
39
  @property
38
40
  def problemType(self) -> str:
39
- """Type of the problem."""
41
+ """type of problem"""
40
42
  return self.__problemType
41
43
 
42
44
  @property
43
45
  def nodes(self) -> np.ndarray:
44
- """Nodes on which the condition is applied."""
46
+ """nodes on which the condition is applied"""
45
47
  return self.__nodes.copy()
46
48
 
47
49
  @property
48
50
  def dofs(self) -> np.ndarray:
49
- """Degrees of freedom associated with nodes and directions."""
51
+ """degrees of freedom associated with the nodes and directions"""
50
52
  return self.__dofs.copy()
51
53
 
52
54
  @property
53
55
  def dofsValues(self) -> np.ndarray:
54
- """Values applied to degrees of freedom."""
56
+ """values applied"""
55
57
  return self.__dofsValues.copy()
56
58
 
57
59
  @property
58
60
  def directions(self) -> np.ndarray:
59
- """Associated directions."""
61
+ """dofs directions"""
60
62
  return self.__directions.copy()
61
63
 
62
64
  @staticmethod
63
65
  def Get_nBc(problemType: str, list_Bc_Condition: list) -> int:
64
- """Recovers the number of conditions applied to the problem.
66
+ """Returns the number of conditions for the problem type.
65
67
 
66
68
  Parameters
67
69
  ----------
68
70
  problemType : str
69
- Type of the problem.
71
+ Problem type.
70
72
  list_Bc_Condition : list[BoundaryCondition]
71
73
  List of boundary conditions.
72
74
 
73
75
  Returns
74
76
  -------
75
77
  int
76
- nBc
78
+ Number of boundary conditions (nBc).
77
79
  """
78
80
  list_Bc_Condition: list[BoundaryCondition] = list_Bc_Condition
79
81
  return len([1 for bc in list_Bc_Condition if bc.problemType == problemType])
80
82
 
81
-
82
83
  @staticmethod
83
84
  def Get_dofs(problemType: str, list_Bc_Condition: list) -> list[int]:
84
- """Get the degrees of freedom of the given problem and condition list.
85
+ """Returns the degrees of freedom for the problem type.
85
86
 
86
87
  Parameters
87
88
  ----------
88
89
  problemType : str
89
- Type of the problem.
90
+ Problem type.
90
91
  list_Bc_Condition : list[BoundaryCondition]
91
92
  List of boundary conditions.
92
93
 
93
94
  Returns
94
95
  -------
95
96
  list
96
- Degrees of freedom.
97
+ List of degrees of freedom.
97
98
  """
98
99
  list_Bc_Condition: list[BoundaryCondition] = list_Bc_Condition
99
100
  dofs: list[int] = []
@@ -102,19 +103,19 @@ class BoundaryCondition:
102
103
 
103
104
  @staticmethod
104
105
  def Get_values(problemType: str, list_Bc_Condition: list) -> list[float]:
105
- """Get the values of degrees of freedom for the given problem and condition list.
106
+ """Returns the dofs values for problem type.
106
107
 
107
108
  Parameters
108
109
  ----------
109
110
  problemType : str
110
- Type of the problem.
111
+ Problem type.
111
112
  list_Bc_Condition : list[BoundaryCondition]
112
- List of boundary conditions.
113
+ List of boundary condition.
113
114
 
114
115
  Returns
115
116
  -------
116
- list
117
- Values of degrees of freedom.
117
+ list[float]
118
+ dofs values.
118
119
  """
119
120
  list_Bc_Condition: list[BoundaryCondition] = list_Bc_Condition
120
121
  values: list[float] = []
@@ -123,21 +124,21 @@ class BoundaryCondition:
123
124
 
124
125
  @staticmethod
125
126
  def Get_dofs_nodes(availableDirections: list[str], nodes: np.ndarray, directions: list[str]) -> np.ndarray:
126
- """Get degrees of freedom (dofs) associated with the nodes.
127
+ """Retrieves degrees of freedom (dofs) associated with the nodes.
127
128
 
128
129
  Parameters
129
130
  ----------
130
131
  availableDirections : list[str]
131
- Directions available in the form of a string list. Must be a unique string list.
132
+ Available directions as a list of strings. Must be a unique string list.
132
133
  nodes : np.ndarray
133
- Nodes.
134
+ Nodes for which dofs are calculated.
134
135
  directions : list[str]
135
- Directions.
136
+ Directions corresponding to the nodes.
136
137
 
137
138
  Returns
138
139
  -------
139
140
  np.ndarray
140
- Degrees of freedom.
141
+ degrees of freedom.
141
142
  """
142
143
 
143
144
  nodes = np.asarray(nodes, dtype=int).ravel()
@@ -163,20 +164,20 @@ class BoundaryCondition:
163
164
  class LagrangeCondition(BoundaryCondition):
164
165
 
165
166
  def __init__(self, problemType: str, nodes: np.ndarray, dofs: np.ndarray, directions: np.ndarray, dofsValues: np.ndarray, lagrangeCoefs: np.ndarray, description=""):
166
- """Construct a Lagrange condition based on a boundary condition.
167
+ """Creates a Lagrange condition (based on a boundary condition).
167
168
 
168
169
  Parameters
169
170
  ----------
170
171
  problemType : str
171
- Type of the problem.
172
+ Problem type.
172
173
  nodes : np.ndarray
173
174
  Nodes on which the condition is applied.
174
175
  dofs : np.ndarray
175
- Degrees of freedom associated with nodes and directions.
176
+ Degrees of freedom (associated with nodes and directions).
176
177
  directions : np.ndarray
177
- Directions.
178
+ Dofs directions.
178
179
  dofsValues : np.ndarray
179
- Values applied to degrees of freedom.
180
+ Dofs values.
180
181
  lagrangeCoefs : np.ndarray
181
182
  Lagrange coefficients.
182
183
  description : str, optional
@@ -188,4 +189,4 @@ class LagrangeCondition(BoundaryCondition):
188
189
  @property
189
190
  def lagrangeCoefs(self) -> np.ndarray:
190
191
  """Lagrange coefficients."""
191
- return self.__lagrangeCoefs.copy()
192
+ return self.__lagrangeCoefs.copy()
@@ -12,14 +12,14 @@ from ._utils import ElemType, MatrixType
12
12
  class Gauss:
13
13
 
14
14
  def __init__(self, elemType: str, matrixType: str):
15
- """Integration point construction
15
+ """Creates integration points.
16
16
 
17
17
  Parameters
18
18
  ----------
19
19
  elemType : str
20
- element type
20
+ element type.
21
21
  matrixType : str
22
- [MatrixType.rigi, MatrixType.mass, MatrixType.beam]
22
+ matrix type (e.g [MatrixType.rigi, MatrixType.mass, MatrixType.beam])
23
23
  """
24
24
 
25
25
  coord, weights = Gauss._Gauss_factory(elemType, matrixType)
@@ -212,7 +212,6 @@ class Gauss:
212
212
  """available [6, 8]\n
213
213
  orderX = [3, 3]\n
214
214
  orderYZ = [2, 3]"""
215
-
216
215
 
217
216
  # X, Y, Z -> base code aster
218
217
  # z, x, y -> gmsh
@@ -374,7 +373,7 @@ class Gauss:
374
373
  x, y, z, weights = Gauss._Prism(nPg)
375
374
 
376
375
  else:
377
- raise Exception("Element not implemented")
376
+ raise Exception("Element not implemented.")
378
377
 
379
378
  if dim == 1:
380
379
  coord = np.asarray([x]).T.reshape((nPg,1))