elasticipy 5.0.0__py3-none-any.whl → 6.0.0__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.
Files changed (33) hide show
  1. {Elasticipy → elasticipy}/FourthOrderTensor.py +4 -4
  2. elasticipy/StressStrainTensors.py +16 -0
  3. {Elasticipy → elasticipy}/ThermalExpansion.py +3 -3
  4. elasticipy/gui/__init__.py +3 -0
  5. elasticipy/gui/about.py +49 -0
  6. {Elasticipy → elasticipy/gui}/gui.py +138 -61
  7. elasticipy/gui/rotate_window.py +79 -0
  8. {Elasticipy → elasticipy}/interfaces/FEPX.py +2 -2
  9. {Elasticipy → elasticipy}/interfaces/PRISMS.py +2 -2
  10. {Elasticipy → elasticipy}/plasticity.py +6 -6
  11. elasticipy/resources/favicon.png +0 -0
  12. elasticipy/resources/logo_text.svg +126 -0
  13. {Elasticipy → elasticipy}/spherical_function.py +3 -3
  14. elasticipy/tensors/__init__.py +0 -0
  15. {Elasticipy → elasticipy}/tensors/elasticity.py +22 -22
  16. {Elasticipy → elasticipy}/tensors/fourth_order.py +20 -20
  17. {Elasticipy → elasticipy}/tensors/second_order.py +8 -8
  18. {Elasticipy → elasticipy}/tensors/stress_strain.py +10 -10
  19. {Elasticipy → elasticipy}/tensors/thermal_expansion.py +3 -3
  20. {elasticipy-5.0.0.dist-info → elasticipy-6.0.0.dist-info}/METADATA +11 -11
  21. elasticipy-6.0.0.dist-info/RECORD +30 -0
  22. {elasticipy-5.0.0.dist-info → elasticipy-6.0.0.dist-info}/entry_points.txt +1 -1
  23. elasticipy-6.0.0.dist-info/top_level.txt +1 -0
  24. Elasticipy/StressStrainTensors.py +0 -16
  25. elasticipy-5.0.0.dist-info/RECORD +0 -24
  26. elasticipy-5.0.0.dist-info/top_level.txt +0 -1
  27. {Elasticipy → elasticipy}/__init__.py +0 -0
  28. {Elasticipy → elasticipy}/crystal_symmetries.py +0 -0
  29. {Elasticipy/tensors → elasticipy/interfaces}/__init__.py +0 -0
  30. {Elasticipy → elasticipy}/polefigure.py +0 -0
  31. {Elasticipy → elasticipy}/tensors/mapping.py +0 -0
  32. {elasticipy-5.0.0.dist-info → elasticipy-6.0.0.dist-info}/WHEEL +0 -0
  33. {elasticipy-5.0.0.dist-info → elasticipy-6.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,10 +1,10 @@
1
1
  import warnings
2
- from Elasticipy.tensors.elasticity import StiffnessTensor as NewStiffnessTensor
3
- from Elasticipy.tensors.elasticity import ComplianceTensor as NewComplianceTensor
2
+ from elasticipy.tensors.elasticity import StiffnessTensor as NewStiffnessTensor
3
+ from elasticipy.tensors.elasticity import ComplianceTensor as NewComplianceTensor
4
4
 
5
5
  warnings.warn(
6
- "The module 'Elasticipy.FourthOrderTensor' is deprecated and will be removed in a future release. "
7
- "Please use 'Elasticipy.tensors.elasticity' instead.",
6
+ "The module 'elasticipy.FourthOrderTensor' is deprecated and will be removed in a future release. "
7
+ "Please use 'elasticipy.tensors.elasticity' instead.",
8
8
  DeprecationWarning,
9
9
  stacklevel=2
10
10
  )
@@ -0,0 +1,16 @@
1
+ import warnings
2
+ from elasticipy.tensors.stress_strain import StressTensor as NewStressTensor
3
+ from elasticipy.tensors.stress_strain import StrainTensor as NewStrainTensor
4
+
5
+ warnings.warn(
6
+ "The module 'elasticipy.StressStrainTensors' is deprecated and will be removed in a future release. "
7
+ "Please use 'elasticipy.tensors.stress_strain' instead.",
8
+ DeprecationWarning,
9
+ stacklevel=2
10
+ )
11
+
12
+ class StressTensor(NewStressTensor):
13
+ pass
14
+
15
+ class StrainTensor(NewStrainTensor):
16
+ pass
@@ -1,9 +1,9 @@
1
1
  import warnings
2
- from Elasticipy.tensors.thermal_expansion import ThermalExpansionTensor as NewThermalExpansionTensor
2
+ from elasticipy.tensors.thermal_expansion import ThermalExpansionTensor as NewThermalExpansionTensor
3
3
 
4
4
  warnings.warn(
5
- "The module 'Elasticipy.ThermalExpansion' is deprecated and will be removed in a future release. "
6
- "Please use 'Elasticipy.tensors.thermal_expansion' instead.",
5
+ "The module 'elasticipy.ThermalExpansion' is deprecated and will be removed in a future release. "
6
+ "Please use 'elasticipy.tensors.thermal_expansion' instead.",
7
7
  DeprecationWarning,
8
8
  stacklevel=2
9
9
  )
@@ -0,0 +1,3 @@
1
+ from .gui import crystal_elastic_plotter
2
+
3
+ __all__ = ["crystal_elastic_plotter"]
@@ -0,0 +1,49 @@
1
+ from qtpy.QtWidgets import QVBoxLayout, QLabel, QPushButton
2
+ from qtpy.QtGui import QPixmap
3
+ from qtpy.QtCore import Qt
4
+
5
+ def about(dialog, logo_path):
6
+ dialog.setWindowTitle("About elasticipy")
7
+ dialog.setFixedWidth(400)
8
+
9
+ layout = QVBoxLayout(dialog)
10
+
11
+ if logo_path.exists():
12
+ logo = QLabel()
13
+ pixmap = QPixmap(str(logo_path))
14
+ pixmap = pixmap.scaledToWidth(250, Qt.SmoothTransformation)
15
+ logo.setPixmap(pixmap)
16
+ logo.setAlignment(Qt.AlignCenter)
17
+ layout.addWidget(logo)
18
+
19
+ # --- Text ---
20
+ text = QLabel(
21
+ "A Python library for elasticity tensors computations<br><br>"
22
+ "© 2024–2025 Dorian Depriester, MIT Licence"
23
+ )
24
+ text.setAlignment(Qt.AlignCenter)
25
+ layout.addWidget(text)
26
+
27
+ # --- Link ---
28
+ link = QLabel(
29
+ '<a href="https://elasticipy.readthedocs.io/">'
30
+ 'https://elasticipy.readthedocs.io/</a>'
31
+ )
32
+ link.setAlignment(Qt.AlignCenter)
33
+ link.setOpenExternalLinks(True)
34
+ layout.addWidget(link)
35
+
36
+ # --- Bug report ---
37
+ link = QLabel(
38
+ '<a href="https://github.com/DorianDepriester/Elasticipy/issues">'
39
+ 'Report a bug</a>'
40
+ )
41
+ link.setAlignment(Qt.AlignCenter)
42
+ link.setOpenExternalLinks(True)
43
+ layout.addWidget(link)
44
+
45
+ # --- Close button ---
46
+ close_btn = QPushButton("Close")
47
+ close_btn.clicked.connect(dialog.close)
48
+ layout.addWidget(close_btn)
49
+ return dialog
@@ -1,24 +1,35 @@
1
1
  import sys
2
-
3
2
  import numpy as np
4
3
  from qtpy.QtWidgets import (
5
- QApplication, QMainWindow, QComboBox, QGridLayout, QLabel,
6
- QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout, QWidget, QFrame, QMessageBox
4
+ QApplication, QMainWindow, QComboBox, QGridLayout, QLineEdit, QWidget, QFrame, QMessageBox
7
5
  )
6
+ from qtpy.QtGui import QIcon
8
7
  from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
9
8
  from matplotlib.figure import Figure
10
9
 
11
- from Elasticipy.crystal_symmetries import SYMMETRIES
12
- from Elasticipy.tensors.elasticity import StiffnessTensor
10
+ from elasticipy.crystal_symmetries import SYMMETRIES
11
+ from elasticipy.gui.rotate_window import EulerBungeDialog
12
+ from elasticipy.gui.about import about
13
+ from elasticipy.tensors.elasticity import StiffnessTensor
14
+ from pathlib import Path
15
+
16
+ from scipy.spatial.transform import Rotation
13
17
 
14
18
  WHICH_OPTIONS = {'Mean': 'mean', 'Max': 'max', 'Min': 'min', 'Std. dev.': 'std'}
15
19
 
20
+ # --- Logo ---
21
+ here = Path(__file__).resolve().parent
22
+ LOGO_PATH = here / ".." / "resources" / "logo_text.svg"
23
+ ICON_PATH = here / ".." / "resources" / "favicon.png"
24
+
16
25
  class ElasticityGUI(QMainWindow):
17
26
  def __init__(self):
18
27
  super().__init__()
28
+ self.C_stiff = None
19
29
  self.coefficient_fields = {}
20
- self.setWindowTitle("Elasticipy - GUI")
30
+ self.setWindowTitle("elasticipy - GUI")
21
31
  self.initUI()
32
+ self.C_invar= np.zeros(7)
22
33
 
23
34
  def selected_symmetry(self):
24
35
  symmetry_name = self.symmetry_selector.currentText()
@@ -53,6 +64,7 @@ class ElasticityGUI(QMainWindow):
53
64
 
54
65
  # Space Group selection
55
66
  self.point_group_selector = QComboBox()
67
+ self.point_group_selector.setMinimumWidth(140)
56
68
  self.point_group_selector.addItems(['', ''])
57
69
  self.point_group_selector.currentIndexChanged.connect(self.update_fields)
58
70
  selectors_layout.addWidget(QLabel("Point group:"))
@@ -65,6 +77,14 @@ class ElasticityGUI(QMainWindow):
65
77
  selectors_layout.addWidget(QLabel("Diad convention:"))
66
78
  selectors_layout.addWidget(self.diag_selector)
67
79
 
80
+ # About button
81
+ self.about_button = QPushButton("About")
82
+ self.about_button.setFixedHeight(24)
83
+ self.about_button.setMaximumWidth(60)
84
+ self.about_button.clicked.connect(self.show_about)
85
+ selectors_layout.addStretch()
86
+ selectors_layout.addWidget(self.about_button)
87
+
68
88
  # Add horizontal separator
69
89
  separator = QFrame()
70
90
  separator.setFrameShape(QFrame.HLine)
@@ -125,9 +145,16 @@ class ElasticityGUI(QMainWindow):
125
145
 
126
146
  # Plot button
127
147
  self.calculate_button = QPushButton("Plot")
148
+ self.calculate_button.setEnabled(False)
128
149
  self.calculate_button.clicked.connect(self.calculate_and_plot)
129
150
  left_panel_layout.addWidget(self.calculate_button)
130
151
 
152
+ self.euler_button = QPushButton("Apply rotation")
153
+ self.euler_button.setEnabled(False)
154
+ self.euler_button.setToolTip("Rotate stiffness tensor (Bunge ZXZ)")
155
+ self.euler_button.clicked.connect(self.open_euler_dialog)
156
+ left_panel_layout.addWidget(self.euler_button)
157
+
131
158
  # Add horizontal separator
132
159
  separator = QFrame()
133
160
  separator.setFrameShape(QFrame.HLine)
@@ -157,7 +184,7 @@ class ElasticityGUI(QMainWindow):
157
184
  ("nu_reuss", "Reuss"),
158
185
  ("nu_hill", "Hill"),
159
186
  ],
160
- "Linear compressibility": [
187
+ "Linear compressibility (x1000)": [
161
188
  ("Beta_mean", "Mean"),
162
189
  ("Beta_voigt", "Voigt"),
163
190
  ("Beta_reuss", "Reuss"),
@@ -205,6 +232,8 @@ class ElasticityGUI(QMainWindow):
205
232
 
206
233
  # Fill space
207
234
  left_panel_layout.addStretch()
235
+
236
+
208
237
  bottom_layout.addLayout(left_panel_layout,1)
209
238
 
210
239
  ############################################
@@ -235,7 +264,6 @@ class ElasticityGUI(QMainWindow):
235
264
  self.plotting_selector.setCurrentText('Young modulus')
236
265
  self.which_selector.setEnabled(False)
237
266
 
238
- self.C_matrix = np.zeros((6, 6))
239
267
 
240
268
  def update_fields(self):
241
269
  # Deactivate unused fields
@@ -270,61 +298,48 @@ class ElasticityGUI(QMainWindow):
270
298
  self.which_selector.setEnabled(True)
271
299
 
272
300
  def calculate_and_plot(self):
273
- """Collect entries and compute the stiffness tensor"""
274
- coefficients = np.zeros((6, 6))
275
- for (i, j), field in self.coefficient_fields.items():
301
+ stiff = self.C_stiff
302
+ self.figure.clear()
303
+ requested_value = self.plotting_selector.currentText()
304
+ if requested_value == "Young modulus":
305
+ value = stiff.Young_modulus
306
+ plot_kwargs = {}
307
+ elif requested_value == 'Linear compressibility':
308
+ value = stiff.linear_compressibility
309
+ plot_kwargs = {}
310
+ else:
311
+ if requested_value == 'Shear modulus':
312
+ value = stiff.shear_modulus
313
+ else:
314
+ value = stiff.Poisson_ratio
315
+ plot_kwargs = {'which': WHICH_OPTIONS[self.which_selector.currentText()]}
316
+ if self.plot_style_selector.currentIndex() == 0:
317
+ value.plot3D(fig=self.figure, **plot_kwargs)
318
+ elif self.plot_style_selector.currentIndex() == 1:
319
+ value.plot_xyz_sections(fig=self.figure)
320
+ else:
321
+ value.plot_as_pole_figure(fig=self.figure, **plot_kwargs)
322
+ self.canvas.draw()
323
+ invariants = np.array(stiff.linear_invariants() + stiff.quadratic_invariants())
324
+ if not np.all(np.isclose(invariants, self.C_invar)):
325
+ self.C_invar = invariants
326
+ self.result_labels["E_mean"].setText(f"{stiff.Young_modulus.mean():.3f}")
327
+ self.result_labels["G_mean"].setText(f"{stiff.shear_modulus.mean():.3f}")
328
+ self.result_labels["nu_mean"].setText(f"{stiff.Poisson_ratio.mean():.3f}")
329
+ self.result_labels["Beta_mean"].setText(f"{stiff.linear_compressibility.mean()*1000:.3f}")
330
+ for method in ['voigt', 'reuss', 'hill']:
331
+ C = stiff.average(method=method)
332
+ self.result_labels[f"E_{method}"].setText(f"{C.Young_modulus.eval([1,0,0]):.3f}")
333
+ self.result_labels[f"G_{method}"].setText(f"{C.shear_modulus.eval([1, 0, 0],[0,1,0]):.3f}")
334
+ self.result_labels[f"nu_{method}"].setText(f"{C.Poisson_ratio.eval([1, 0, 0], [0, 1, 0]):.3f}")
335
+ self.result_labels[f"Beta_{method}"].setText(f"{C.linear_compressibility.eval([1, 0, 0])*1000:.3f}")
336
+ self.result_labels["K"].setText(f"{stiff.bulk_modulus:.3f}")
276
337
  try:
277
- coefficients[i, j] = float(field.text())
338
+ Z = stiff.Zener_ratio()
339
+ self.result_labels["Z"].setText(f"{stiff.Zener_ratio():.3f}")
278
340
  except ValueError:
279
- coefficients[i, j] = 0
280
- C = np.array(coefficients)
281
- Csym = C + np.tril(C.T, -1) # Rebuild the lower triangular part
282
-
283
- try:
284
- stiff = StiffnessTensor(Csym)
285
- self.figure.clear()
286
- requested_value = self.plotting_selector.currentText()
287
- if requested_value == "Young modulus":
288
- value = stiff.Young_modulus
289
- plot_kwargs = {}
290
- elif requested_value == 'Linear compressibility':
291
- value = stiff.linear_compressibility
292
- plot_kwargs = {}
293
- else:
294
- if requested_value == 'Shear modulus':
295
- value = stiff.shear_modulus
296
- else:
297
- value = stiff.Poisson_ratio
298
- plot_kwargs = {'which': WHICH_OPTIONS[self.which_selector.currentText()]}
299
- if self.plot_style_selector.currentIndex() == 0:
300
- value.plot3D(fig=self.figure, **plot_kwargs)
301
- elif self.plot_style_selector.currentIndex() == 1:
302
- value.plot_xyz_sections(fig=self.figure)
303
- else:
304
- value.plot_as_pole_figure(fig=self.figure, **plot_kwargs)
305
- self.canvas.draw()
306
- if not np.all(self.C_matrix == Csym):
307
- self.result_labels["E_mean"].setText(f"{stiff.Young_modulus.mean():.3f}")
308
- self.result_labels["G_mean"].setText(f"{stiff.shear_modulus.mean():.3f}")
309
- self.result_labels["nu_mean"].setText(f"{stiff.Poisson_ratio.mean():.3f}")
310
- self.result_labels["Beta_mean"].setText(f"{stiff.linear_compressibility.mean():.3f}")
311
- for method in ['voigt', 'reuss', 'hill']:
312
- C = stiff.average(method=method)
313
- self.result_labels[f"E_{method}"].setText(f"{C.Young_modulus.eval([1,0,0]):.3f}")
314
- self.result_labels[f"G_{method}"].setText(f"{C.shear_modulus.eval([1, 0, 0],[0,1,0]):.3f}")
315
- self.result_labels[f"nu_{method}"].setText(f"{C.Poisson_ratio.eval([1, 0, 0], [0, 1, 0]):.3f}")
316
- self.result_labels[f"Beta_{method}"].setText(f"{C.linear_compressibility.eval([1, 0, 0]):.3f}")
317
- self.result_labels["K"].setText(f"{stiff.bulk_modulus:.3f}")
318
- try:
319
- Z = stiff.Zener_ratio()
320
- self.result_labels["Z"].setText(f"{stiff.Zener_ratio():.3f}")
321
- except ValueError:
322
- self.result_labels["Z"].setText("—")
323
- self.result_labels["A"].setText(f"{stiff.universal_anisotropy:.3f}")
324
- self.C_matrix = Csym
325
-
326
- except ValueError as inst:
327
- QMessageBox.critical(self, "Singular stiffness", inst.__str__(), QMessageBox.Ok)
341
+ self.result_labels["Z"].setText("—")
342
+ self.result_labels["A"].setText(f"{stiff.universal_anisotropy:.3f}")
328
343
 
329
344
 
330
345
  def update_dependent_fields(self):
@@ -351,12 +366,74 @@ class ElasticityGUI(QMainWindow):
351
366
  self.coefficient_fields[index].setText(f"{0.5*(C11-C12)}")
352
367
  except ValueError:
353
368
  pass
369
+ coefficients = np.zeros((6, 6))
370
+ for (i, j), field in self.coefficient_fields.items():
371
+ try:
372
+ coefficients[i, j] = float(field.text())
373
+ except ValueError:
374
+ coefficients[i, j] = 0
375
+ Csym = coefficients + np.tril(coefficients.T, -1) # Rebuild the lower triangular part
376
+ try:
377
+ self.C_stiff = StiffnessTensor(Csym)
378
+ self.calculate_button.setEnabled(True)
379
+ self.euler_button.setToolTip("Plot directional dependence")
380
+ self.euler_button.setEnabled(True)
381
+ self.euler_button.setToolTip("Rotate stiffness tensor (Bunge ZXZ)")
382
+ except ValueError:
383
+ self.calculate_button.setEnabled(False)
384
+ error_msg = "The stiffness tensor is not definite positive!"
385
+ self.calculate_button.setToolTip(error_msg)
386
+ self.euler_button.setEnabled(False)
387
+ self.euler_button.setToolTip(error_msg)
388
+
389
+ def show_about(self):
390
+ dialog = QDialog(self)
391
+ dialog = about(dialog, LOGO_PATH)
392
+ dialog.exec_()
393
+
394
+ def open_euler_dialog(self):
395
+ if not hasattr(self, "euler_dialog"):
396
+ self.current_config = {'sym': self.symmetry_selector.currentText(),
397
+ 'pg': self.point_group_selector.currentText(),
398
+ 'diag': self.diag_selector.currentText()}
399
+ self.euler_dialog = EulerBungeDialog(self, C=self.C_stiff.matrix())
400
+ self.euler_dialog.anglesChanged.connect(self.update_from_euler)
401
+ self.euler_dialog.show()
402
+
403
+ def update_from_euler(self, phi1, Phi, phi2):
404
+ C0 = StiffnessTensor(self.euler_dialog.C)
405
+ rot = Rotation.from_euler(seq='ZXZ', angles=[phi1, Phi, phi2], degrees=True)
406
+ if np.any(np.array([phi1, Phi, phi2])) != 0.:
407
+ self.symmetry_selector.setCurrentText('Triclinic')
408
+ C_new = C0.rotate(rot).matrix()
409
+ for (i, j), field in self.coefficient_fields.items():
410
+ self.coefficient_fields[(i,j)].setText(f"{C_new[i,j]}")
411
+ else:
412
+ for (i, j), field in self.coefficient_fields.items():
413
+ self.coefficient_fields[(i,j)].setText(f"{self.euler_dialog.C[i,j]}")
414
+ self.symmetry_selector.setCurrentText(self.current_config['sym'])
415
+ self.point_group_selector.setCurrentText(self.current_config['pg'])
416
+ self.diag_selector.setCurrentText(self.current_config['diag'])
417
+ if self.euler_dialog.live_button.isChecked():
418
+ self.calculate_and_plot()
354
419
 
355
420
  def crystal_elastic_plotter():
356
421
  app = QApplication(sys.argv)
422
+ try:
423
+ icon = QIcon(str(ICON_PATH))
424
+ except Exception:
425
+ icon = QIcon()
426
+ app.setWindowIcon(icon)
357
427
  window = ElasticityGUI()
428
+ window.setWindowIcon(icon)
358
429
  window.show()
359
430
  sys.exit(app.exec_())
360
431
 
432
+
433
+ from qtpy.QtWidgets import (
434
+ QDialog, QVBoxLayout, QHBoxLayout,
435
+ QLabel, QPushButton
436
+ )
437
+
361
438
  if __name__ == "__main__":
362
439
  crystal_elastic_plotter()
@@ -0,0 +1,79 @@
1
+ import numpy as np
2
+ from PyQt5.QtCore import Qt
3
+ from PyQt5.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QLabel, QSlider, QDoubleSpinBox, QPushButton, QCheckBox
4
+ from qtpy.QtCore import Qt, Signal
5
+
6
+
7
+ class EulerBungeDialog(QDialog):
8
+ anglesChanged = Signal(float, float, float)
9
+
10
+ def __init__(self, parent=None, C=np.zeros((6, 6))):
11
+ super().__init__(parent)
12
+ self.setWindowTitle("Euler angles (Bunge ZXZ)")
13
+ self._build_ui()
14
+ self.reset()
15
+ self.C = C
16
+
17
+ def _build_ui(self):
18
+ self.layout = QVBoxLayout(self)
19
+
20
+ self.sliders = []
21
+ self.spins = []
22
+
23
+ labels = ["φ₁ (deg)", "Φ (deg)", "φ₂ (deg)"]
24
+ ranges = [(0, 360), (0, 180), (0, 360)]
25
+
26
+ for label, (vmin, vmax) in zip(labels, ranges):
27
+ row = QHBoxLayout()
28
+
29
+ row.addWidget(QLabel(label))
30
+
31
+ slider = QSlider(Qt.Horizontal)
32
+ slider.setRange(vmin * 10, vmax * 10)
33
+ slider.setSingleStep(1)
34
+
35
+ spin = QDoubleSpinBox()
36
+ spin.setRange(vmin, vmax)
37
+ spin.setDecimals(1)
38
+ spin.setSingleStep(0.1)
39
+
40
+ slider.valueChanged.connect(
41
+ lambda v, s=spin: s.setValue(v / 10)
42
+ )
43
+ spin.valueChanged.connect(
44
+ lambda v, s=slider: s.setValue(int(v * 10))
45
+ )
46
+ spin.valueChanged.connect(self._emit_angles)
47
+
48
+ row.addWidget(slider, stretch=1)
49
+ row.addWidget(spin)
50
+
51
+ self.sliders.append(slider)
52
+ self.spins.append(spin)
53
+
54
+ self.layout.addLayout(row)
55
+
56
+ # Live update
57
+ self.live_button = QCheckBox("Live-update plotting")
58
+ self.layout.addWidget(self.live_button)
59
+
60
+ # Reset button
61
+ reset_button = QPushButton("Reset orientation")
62
+ reset_button.clicked.connect(self.reset)
63
+ self.layout.addWidget(reset_button)
64
+
65
+ def reset(self):
66
+ self._set_angles(0.0, 0.0, 0.0)
67
+ for slider in self.sliders:
68
+ slider.setValue(0)
69
+
70
+ def _set_angles(self, phi1, Phi, phi2):
71
+ for spin, val in zip(self.spins, (phi1, Phi, phi2)):
72
+ spin.blockSignals(True)
73
+ spin.setValue(val)
74
+ spin.blockSignals(False)
75
+ self._emit_angles()
76
+
77
+ def _emit_angles(self):
78
+ angles = [spin.value() for spin in self.spins]
79
+ self.anglesChanged.emit(*angles)
@@ -1,6 +1,6 @@
1
- from Elasticipy.tensors.second_order import SymmetricSecondOrderTensor, SecondOrderTensor, \
1
+ from elasticipy.tensors.second_order import SymmetricSecondOrderTensor, SecondOrderTensor, \
2
2
  SkewSymmetricSecondOrderTensor
3
- from Elasticipy.tensors.stress_strain import StressTensor, StrainTensor
3
+ from elasticipy.tensors.stress_strain import StressTensor, StrainTensor
4
4
  import pandas as pd
5
5
  import numpy as np
6
6
  import os
@@ -1,5 +1,5 @@
1
- from Elasticipy.tensors.second_order import SecondOrderTensor, SymmetricSecondOrderTensor
2
- from Elasticipy.tensors.stress_strain import StressTensor
1
+ from elasticipy.tensors.second_order import SecondOrderTensor, SymmetricSecondOrderTensor
2
+ from elasticipy.tensors.stress_strain import StressTensor
3
3
  import pandas as pd
4
4
  import numpy as np
5
5
 
@@ -1,5 +1,5 @@
1
1
  import numpy as np
2
- from Elasticipy.tensors.stress_strain import StrainTensor, StressTensor
2
+ from elasticipy.tensors.stress_strain import StrainTensor, StressTensor
3
3
 
4
4
 
5
5
  class IsotropicHardening:
@@ -55,7 +55,7 @@ class IsotropicHardening:
55
55
  --------
56
56
  As an example, we consider a Jonhson-Cook model:
57
57
 
58
- >>> from Elasticipy.plasticity import JohnsonCook
58
+ >>> from elasticipy.plasticity import JohnsonCook
59
59
  >>> JC = JohnsonCook(A=792, B=510, n=0.26)
60
60
  >>> print(JC)
61
61
  Johnson-Cook plasticity model
@@ -100,7 +100,7 @@ class IsotropicHardening:
100
100
  --------
101
101
  As an example, we consider the Johnson-Cook plasticity model:
102
102
 
103
- >>> from Elasticipy.plasticity import JohnsonCook
103
+ >>> from elasticipy.plasticity import JohnsonCook
104
104
  >>> JC = JohnsonCook(A=792, B=510, n=0.26)
105
105
  >>> print(JC)
106
106
  Johnson-Cook plasticity model
@@ -167,12 +167,12 @@ class IsotropicHardening:
167
167
  --------
168
168
  As an example, we consider the Johnson-Cook plasticity model:
169
169
 
170
- >>> from Elasticipy.plasticity import JohnsonCook
170
+ >>> from elasticipy.plasticity import JohnsonCook
171
171
  >>> JC = JohnsonCook(A=792, B=510, n=0.26)
172
172
 
173
173
  The yield stress is equal to A here. So consider a tensile stress whose magnitude below A:
174
174
 
175
- >>> from Elasticipy.tensors.stress_strain import StressTensor
175
+ >>> from elasticipy.tensors.stress_strain import StressTensor
176
176
  >>> sigma = StressTensor.tensile([1,0,0], 700)
177
177
  >>> strain_inc = JC.compute_strain_increment(sigma)
178
178
  >>> print(strain_inc)
@@ -221,7 +221,7 @@ class IsotropicHardening:
221
221
  --------
222
222
  As an example, we consider the Johnson-Cook plasticity model:
223
223
 
224
- >>> from Elasticipy.plasticity import JohnsonCook
224
+ >>> from elasticipy.plasticity import JohnsonCook
225
225
  >>> JC = JohnsonCook(A=792, B=510, n=0.26)
226
226
 
227
227
  First apply a strain increment:
Binary file
@@ -0,0 +1,126 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+
4
+ <svg
5
+ width="78.908997mm"
6
+ height="36.786999mm"
7
+ viewBox="0 0 78.908996 36.786998"
8
+ version="1.1"
9
+ id="svg1"
10
+ sodipodi:docname="logo_text.svg"
11
+ inkscape:export-filename="logo_text_whitebg.png"
12
+ inkscape:export-xdpi="422.73401"
13
+ inkscape:export-ydpi="422.73401"
14
+ inkscape:version="1.4 (86a8ad7, 2024-10-11)"
15
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
16
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
17
+ xmlns:xlink="http://www.w3.org/1999/xlink"
18
+ xmlns="http://www.w3.org/2000/svg"
19
+ xmlns:svg="http://www.w3.org/2000/svg">
20
+ <sodipodi:namedview
21
+ id="namedview1"
22
+ pagecolor="#ffffff"
23
+ bordercolor="#000000"
24
+ borderopacity="0.25"
25
+ inkscape:showpageshadow="2"
26
+ inkscape:pageopacity="0.0"
27
+ inkscape:pagecheckerboard="0"
28
+ inkscape:deskcolor="#d1d1d1"
29
+ inkscape:document-units="mm"
30
+ inkscape:zoom="1.4520904"
31
+ inkscape:cx="120.51591"
32
+ inkscape:cy="48.550696"
33
+ inkscape:window-width="1920"
34
+ inkscape:window-height="1017"
35
+ inkscape:window-x="1912"
36
+ inkscape:window-y="-8"
37
+ inkscape:window-maximized="1"
38
+ inkscape:current-layer="layer1"
39
+ inkscape:export-bgcolor="#ffffffff"
40
+ showgrid="false" />
41
+ <defs
42
+ id="defs1">
43
+ <linearGradient
44
+ inkscape:collect="always"
45
+ xlink:href="#linearGradient4671"
46
+ id="linearGradient11"
47
+ gradientUnits="userSpaceOnUse"
48
+ gradientTransform="matrix(0.26458333,0,0,-0.26458333,62.63747,141.42565)"
49
+ x1="333.83426"
50
+ y1="-25.560944"
51
+ x2="333.83426"
52
+ y2="-79.333092"
53
+ spreadMethod="pad" />
54
+ <linearGradient
55
+ id="linearGradient4671">
56
+ <stop
57
+ style="stop-color:#ffd43b;stop-opacity:1"
58
+ offset="0"
59
+ id="stop4673" />
60
+ <stop
61
+ style="stop-color:#ffe873;stop-opacity:1"
62
+ offset="1"
63
+ id="stop4675" />
64
+ </linearGradient>
65
+ <linearGradient
66
+ inkscape:collect="always"
67
+ xlink:href="#linearGradient4689"
68
+ id="linearGradient9"
69
+ gradientUnits="userSpaceOnUse"
70
+ gradientTransform="matrix(0.26458333,0,0,0.26458333,79.98938,139.19081)"
71
+ x1="181.30275"
72
+ y1="-17.131027"
73
+ x2="256.79184"
74
+ y2="52.408573" />
75
+ <linearGradient
76
+ id="linearGradient4689">
77
+ <stop
78
+ style="stop-color:#5a9fd4;stop-opacity:1"
79
+ offset="0"
80
+ id="stop4691" />
81
+ <stop
82
+ style="stop-color:#306998;stop-opacity:1"
83
+ offset="1"
84
+ id="stop4693" />
85
+ </linearGradient>
86
+ <linearGradient
87
+ inkscape:collect="always"
88
+ xlink:href="#linearGradient4671"
89
+ id="linearGradient2"
90
+ x1="171.01212"
91
+ y1="149.74876"
92
+ x2="171.01212"
93
+ y2="161.5468"
94
+ gradientUnits="userSpaceOnUse" />
95
+ </defs>
96
+ <g
97
+ inkscape:label="Layer 1"
98
+ inkscape:groupmode="layer"
99
+ id="layer1"
100
+ transform="translate(-126.73542,-133.35)">
101
+ <path
102
+ id="text1-4-5-2-54-3"
103
+ style="font-size:192px;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;fill:url(#linearGradient11);fill-opacity:1;stroke-width:0.264583"
104
+ d="m 150.16462,142.15596 c -0.96996,0 -1.83852,0.007 -2.66237,0.0186 0.52425,0.50605 0.97673,1.07142 1.28261,1.74873 0.50892,1.12689 0.82992,2.28417 0.82992,3.53829 v 1.39991 c 2.66736,0.0162 5.07681,0.0196 8.15455,0.0196 0,-0.87942 0.0155,-1.76812 0.0155,-2.4474 0,-2.51527 -0.32529,-4.27777 -7.62021,-4.27777 z m -11.61583,2.07016 c -0.74411,1.15235 -0.76426,2.93071 -0.76946,5.67458 v 0.0248 c 0,1.14102 0.14056,2.1084 0.42168,2.90215 0.11054,0.30092 0.24218,0.57875 0.39378,0.83406 1.45247,-0.19775 2.71407,-2.31732 2.71404,-4.72736 3e-5,-2.43536 -1.28837,-4.55112 -2.76004,-4.70824 z m 16.1029,0.14314 a 1.3449186,1.3449186 0 0 1 1.34513,1.34514 1.3449186,1.3449186 0 0 1 -1.34513,1.34513 1.3449186,1.3449186 0 0 1 -1.34462,-1.34513 1.3449186,1.3449186 0 0 1 1.34462,-1.34514 z m -5.05448,5.9893 c -0.0858,2.29191 -0.60955,4.25462 -1.45572,5.93038 -0.90878,1.81756 -2.28539,2.88556 -4.03025,3.84887 -1.74485,0.96331 -3.67874,1.21646 -6.13244,1.21646 -0.067,0 -0.12977,-0.004 -0.19585,-0.005 -3.2e-4,0.0383 -0.004,0.0729 -0.004,0.11162 v 0.0248 c 0.0134,7.04478 0.0291,7.74475 12.38529,7.74475 7.29492,0 7.62021,-1.7625 7.62021,-4.27777 0,-0.67928 -0.0155,-1.56798 -0.0155,-2.4474 -4.40154,0 -7.05527,-0.01 -11.76001,0.046 -0.74191,0.01 -0.77069,-0.8692 -0.01,-0.8692 4.27995,0 5.96966,-1.55757 5.96966,-6.01823 0,-2.77849 -0.67428,-4.46657 -2.37195,-5.30562 z"
105
+ inkscape:label="epsilon" />
106
+ <path
107
+ id="text1-1-5-1"
108
+ style="font-weight:bold;font-size:192px;font-family:Bahnschrift;-inkscape-font-specification:'Bahnschrift Bold';display:inline;fill:url(#linearGradient9);stroke-width:0.705556"
109
+ d="m 143.34747,134.44325 c -2.87272,0 -8.44558,0.27355 -10.72338,1.48363 -1.5875,0.84336 -2.80293,2.06706 -3.64629,3.6711 -0.82682,1.60402 -1.24023,3.53053 -1.24023,5.77949 v 4.19199 c 0,2.36472 0.41341,4.39043 1.24023,6.07715 0.84336,1.67018 2.05879,2.94349 3.64629,3.81992 1.5875,0.87644 3.49746,1.31465 5.72988,1.31465 2.23242,0 4.14239,-0.43821 5.72989,-1.31465 1.5875,-0.87643 2.79466,-2.14147 3.62148,-3.79511 0.84336,-1.67019 1.26504,-3.67937 1.26504,-6.02754 v -2.03399 c 0,-1.14101 -0.23151,-2.22415 -0.69453,-3.24941 -0.46302,-1.02526 -1.14102,-1.87689 -2.03399,-2.55488 -0.29302,-0.22791 -0.60567,-0.42439 -0.93431,-0.59532 0,0 6.299,0.0465 8.87181,0 0.001,-0.72917 0.0207,-1.55216 0.0207,-2.13475 0,-3.69368 -0.73316,-4.63228 -10.85257,-4.63228 z m 7.72666,2.2779 a 1.3383084,1.3383084 0 0 1 1.33841,1.33842 1.3383084,1.3383084 0 0 1 -1.33841,1.3379 1.3383084,1.3383084 0 0 1 -1.33791,-1.3379 1.3383084,1.3383084 0 0 1 1.33791,-1.33842 z m -12.67365,6.68641 c 1.97408,3e-4 3.57433,2.43687 3.57446,5.44257 6e-5,3.00589 -1.60025,5.44278 -3.57446,5.44308 -1.97441,1.4e-4 -3.57503,-2.43688 -3.57497,-5.44308 1.3e-4,-3.00601 1.60069,-5.44271 3.57497,-5.44257 z"
110
+ inkscape:label="sigma" />
111
+ <path
112
+ style="font-weight:500;font-size:16.9333px;font-family:Flux;-inkscape-font-specification:'Flux Medium';fill:url(#linearGradient2);stroke-width:0.0352778;fill-opacity:1"
113
+ d="m 155.92935,161.50243 v -0.64346 c -0.8636,-0.0339 -1.38853,-0.27094 -1.38853,-1.25307 v -10.02451 l -1.20227,0.38947 v 9.66891 c 0,1.27 0.94827,2.01506 2.5908,1.86266 z m 6.62093,-1.25306 v -4.28413 c 0,-1.37159 -1.2192,-2.18439 -2.45533,-2.18439 -1.016,0 -1.69333,0.16933 -2.57386,0.64346 l 0.3048,0.7112 c 0.66039,-0.33866 1.20226,-0.52493 1.94732,-0.52493 0.82974,0 1.60867,0.57573 1.60867,1.4224 v 0.72813 h -2.01506 c -1.4224,-0.0169 -2.54,0.8636 -2.55693,2.30293 -0.0339,1.35466 1.0668,2.42146 2.40453,2.45533 1.47319,0.0169 2.62466,-0.5588 3.33586,-1.27 z m -1.20227,-0.16933 c -0.22013,0.23706 -0.88053,0.62653 -1.59173,0.60959 -0.98213,0 -1.69333,-0.81279 -1.69333,-1.65946 0,-0.93133 0.7112,-1.4732 1.65947,-1.4732 0.60959,-0.0169 1.23613,-0.0169 1.62559,-0.0169 z m 5.04613,1.50706 c 1.4224,0 2.92947,-0.74507 2.9464,-2.3368 0,-0.67733 -0.3048,-1.11759 -0.7112,-1.43933 -0.38947,-0.3048 -0.8636,-0.47413 -1.3208,-0.6604 -0.47413,-0.18626 -0.98213,-0.38946 -1.35466,-0.55879 -0.38947,-0.16934 -0.64347,-0.4064 -0.64347,-0.82974 0.0169,-0.79586 0.79587,-1.16839 1.50707,-1.16839 0.54186,0.0169 1.0668,0.16933 1.62559,0.49106 l 0.4572,-0.72813 c -0.67733,-0.37253 -1.38853,-0.62653 -2.15053,-0.62653 -1.32079,0 -2.59079,0.77893 -2.59079,2.20133 0,0.69426 0.3048,1.11759 0.7112,1.40546 0.38946,0.3048 0.8636,0.47413 1.3208,0.64347 0.23706,0.0677 0.47413,0.16933 0.69426,0.254 0.5588,0.22013 1.2192,0.44026 1.23613,1.16839 0.0339,0.93133 -0.93133,1.30387 -1.74413,1.30387 -0.6604,-0.0169 -1.40546,-0.27094 -1.91346,-0.6604 l -0.44027,0.7112 c 0.64347,0.49106 1.50707,0.82973 2.37066,0.82973 z m 4.77519,-6.82412 v 4.85986 c 0,1.26999 0.98213,2.01506 2.62466,1.86266 v -0.64347 c -0.8636,-0.0339 -1.38853,-0.27093 -1.38853,-1.25306 v -4.82599 h 1.38853 v -0.79587 h -1.38853 v -2.50612 l -1.23613,0.44026 v 2.06586 h -0.84667 v 0.79587 z m 4.72438,6.62092 h 1.2192 v -7.60305 l -1.2192,0.4064 z m -0.2032,-9.99065 c 0,0.44027 0.3556,0.79587 0.79587,0.79587 0.4572,0 0.8128,-0.3556 0.8128,-0.79587 0,-0.4572 -0.3556,-0.8128 -0.79587,-0.8128 -0.4572,0 -0.8128,0.3556 -0.8128,0.79587 z m 6.33305,10.14305 c 1.08373,0 1.99813,-0.3048 2.72626,-0.77893 l -0.32173,-0.64347 c -0.67733,0.32173 -1.25306,0.6096 -2.04893,0.59267 -1.40546,-0.0169 -2.11666,-1.60867 -2.11666,-2.9464 0,-1.40546 0.6604,-3.08186 1.99813,-3.14959 0.57573,-0.0339 1.27,0.16933 1.77799,0.4064 l 0.3556,-0.6604 c -1.16839,-0.72813 -2.74319,-0.77893 -3.77612,-0.0677 -1.03293,0.7112 -1.60867,2.08279 -1.60867,3.47132 0,1.86267 1.1176,3.7592 3.01413,3.77613 z m 4.45347,-0.1524 h 1.21919 v -7.60305 l -1.21919,0.4064 z m -0.2032,-9.99065 c 0,0.44027 0.3556,0.79587 0.79586,0.79587 0.4572,0 0.8128,-0.3556 0.8128,-0.79587 0,-0.4572 -0.3556,-0.8128 -0.79586,-0.8128 -0.4572,0 -0.8128,0.3556 -0.8128,0.79587 z"
114
+ id="text1"
115
+ aria-label="lasticipy"
116
+ sodipodi:nodetypes="ccsccsccssccsscccccccscccsccccccccsscccccccscsccscccccccccccccccssssssccccsccccscccccccssssss"
117
+ inkscape:label="lastici" />
118
+ <path
119
+ style="font-weight:500;font-size:16.9333px;font-family:Flux;-inkscape-font-specification:'Flux Medium';fill:#646464;stroke-width:0.0352778"
120
+ d="m 193.45354,153.79778 c 2.01506,-0.0339 2.92946,1.86266 2.94639,4.01319 0,1.89653 -0.94826,3.67453 -2.98026,3.74226 -0.82973,0 -1.54093,-0.254 -2.23519,-0.67733 v 4.38573 l -1.2192,-0.44027 0.0169,-9.73665 c -0.0169,0 0.94827,-1.27 3.4544,-1.30386 z m -0.3048,6.87492 c 1.6256,-0.1016 1.8288,-1.69333 1.8288,-2.94639 0,-1.2192 -0.2032,-3.048 -1.74413,-3.11573 -1.04987,-0.0677 -1.89653,0.42333 -2.06587,0.59266 v 4.826 c 0.4064,0.25399 1.2192,0.69426 1.9812,0.64346 z m 6.53626,-1.69333 v -5.19852 l -1.25307,0.42333 v 5.14772 c 0,1.3716 1.27,2.16747 2.3876,2.16747 1.45626,0 2.28599,-0.4064 2.65853,-0.57574 0.0169,0.18627 0,0.13547 0,0.32174 0,0.54186 -0.0169,1.47319 -0.27094,1.94733 -0.508,0.96519 -1.86266,1.10066 -2.81093,1.23613 l 0.2032,0.77893 c 1.25307,-0.0339 3.01413,-0.508 3.64066,-1.69333 0.3556,-0.67733 0.4064,-1.9812 0.4064,-2.8448 v -6.72252 h -1.23613 v 6.04519 c -0.4064,0.27093 -1.15146,0.64347 -1.81186,0.6604 -1.10067,0.0169 -1.91346,-0.57573 -1.91346,-1.71026 z"
121
+ id="text1-2"
122
+ aria-label="lasticipy"
123
+ sodipodi:nodetypes="ccccccccccscccccccsscsccccscccccc"
124
+ inkscape:label="py" />
125
+ </g>
126
+ </svg>