Elaston 0.0.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.
- elaston-0.0.2/.gitignore +12 -0
- elaston-0.0.2/LICENSE +29 -0
- elaston-0.0.2/PKG-INFO +126 -0
- elaston-0.0.2/cached-miniforge/my-env/lib/python3.1/site-packages/elaston/__init__.py +13 -0
- elaston-0.0.2/cached-miniforge/my-env/lib/python3.1/site-packages/elaston/_version.py +24 -0
- elaston-0.0.2/cached-miniforge/my-env/lib/python3.1/site-packages/elaston/dislocation.py +292 -0
- elaston-0.0.2/cached-miniforge/my-env/lib/python3.1/site-packages/elaston/elastic_constants.py +389 -0
- elaston-0.0.2/cached-miniforge/my-env/lib/python3.1/site-packages/elaston/green.py +468 -0
- elaston-0.0.2/cached-miniforge/my-env/lib/python3.1/site-packages/elaston/inclusion.py +231 -0
- elaston-0.0.2/cached-miniforge/my-env/lib/python3.1/site-packages/elaston/linear_elasticity.py +521 -0
- elaston-0.0.2/cached-miniforge/my-env/lib/python3.1/site-packages/elaston/orientation.py +95 -0
- elaston-0.0.2/cached-miniforge/my-env/lib/python3.1/site-packages/elaston/tools.py +247 -0
- elaston-0.0.2/docs/README.md +73 -0
- elaston-0.0.2/elaston/__init__.py +13 -0
- elaston-0.0.2/elaston/_version.py +24 -0
- elaston-0.0.2/elaston/dislocation.py +292 -0
- elaston-0.0.2/elaston/elastic_constants.py +389 -0
- elaston-0.0.2/elaston/green.py +468 -0
- elaston-0.0.2/elaston/inclusion.py +231 -0
- elaston-0.0.2/elaston/linear_elasticity.py +521 -0
- elaston-0.0.2/elaston/orientation.py +95 -0
- elaston-0.0.2/elaston/tools.py +247 -0
- elaston-0.0.2/pyproject.toml +47 -0
elaston-0.0.2/.gitignore
ADDED
elaston-0.0.2/LICENSE
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024, Max-Planck-Institut für Nachhaltige Materialien GmbH - Computational Materials Design (CM) Department
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
* Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
elaston-0.0.2/PKG-INFO
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: Elaston
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: Elaston - linear elasticity toolbox
|
|
5
|
+
Project-URL: Homepage, https://pyiron.org/
|
|
6
|
+
Project-URL: Documentation, https://elaston.readthedocs.io
|
|
7
|
+
Project-URL: Repository, https://github.com/pyiron/elaston
|
|
8
|
+
Author-email: Sam Waseda <waseda@mpie.de>
|
|
9
|
+
License: BSD 3-Clause License
|
|
10
|
+
|
|
11
|
+
Copyright (c) 2024, Max-Planck-Institut für Nachhaltige Materialien GmbH - Computational Materials Design (CM) Department
|
|
12
|
+
All rights reserved.
|
|
13
|
+
|
|
14
|
+
Redistribution and use in source and binary forms, with or without
|
|
15
|
+
modification, are permitted provided that the following conditions are met:
|
|
16
|
+
|
|
17
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
18
|
+
list of conditions and the following disclaimer.
|
|
19
|
+
|
|
20
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
21
|
+
this list of conditions and the following disclaimer in the documentation
|
|
22
|
+
and/or other materials provided with the distribution.
|
|
23
|
+
|
|
24
|
+
* Neither the name of the copyright holder nor the names of its
|
|
25
|
+
contributors may be used to endorse or promote products derived from
|
|
26
|
+
this software without specific prior written permission.
|
|
27
|
+
|
|
28
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
29
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
30
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
31
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
32
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
33
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
34
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
35
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
36
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
37
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
38
|
+
License-File: LICENSE
|
|
39
|
+
Keywords: pyiron
|
|
40
|
+
Classifier: Development Status :: 3 - Alpha
|
|
41
|
+
Classifier: Intended Audience :: Science/Research
|
|
42
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
43
|
+
Classifier: Operating System :: OS Independent
|
|
44
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
45
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
46
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
47
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
48
|
+
Classifier: Topic :: Scientific/Engineering
|
|
49
|
+
Requires-Python: <3.15,>=3.11
|
|
50
|
+
Requires-Dist: numpy<2.5.0,>=2.4.6
|
|
51
|
+
Requires-Dist: semantikon<1.4.0,>=1.3.2
|
|
52
|
+
Description-Content-Type: text/markdown
|
|
53
|
+
|
|
54
|
+
[](https://mybinder.org/v2/gh/pyiron/elaston/HEAD)
|
|
55
|
+
[](https://opensource.org/licenses/BSD-3-Clause)
|
|
56
|
+
[](https://app.codacy.com/gh/pyiron/elaston/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
|
|
57
|
+
[](https://coveralls.io/github/pyiron/elaston?branch=main)
|
|
58
|
+
[](https://elaston.readthedocs.io/en/latest/?badge=latest)
|
|
59
|
+
|
|
60
|
+
# Elaston
|
|
61
|
+
|
|
62
|
+
Elaston is a simple and lightweight module for linear elasticity calculations.
|
|
63
|
+
|
|
64
|
+
## Installation
|
|
65
|
+
|
|
66
|
+
We will offer pip and conda at some point. For now, you can install the package by cloning the repository and running the following command in the root directory:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install .
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Features
|
|
73
|
+
|
|
74
|
+
- Calculation of elastic constants
|
|
75
|
+
- Stress, strain and displacement field around dislocations using anisotropic elasticity
|
|
76
|
+
- Stress, strain and displacement field around point defects
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
## Usage
|
|
80
|
+
|
|
81
|
+
Examples I: Get bulk modulus from the elastic tensor:
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from elaston import LinearElasticity
|
|
85
|
+
|
|
86
|
+
medium = LinearElasticity(C_11=211.0, C_12=130.0, C_44=82.0) # Fe
|
|
87
|
+
medium_voigt = medium.get_voigt_average()
|
|
88
|
+
parameters = medium_voigt.get_elastic_moduli()
|
|
89
|
+
print(parameters['bulk_modulus'])
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
Example II: Get strain field around a point defect:
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
import numpy as np
|
|
97
|
+
medium = LinearElasticity(C_11=211.0, C_12=130.0, C_44=82.0)
|
|
98
|
+
random_positions = np.random.random((10, 3)) - 0.5
|
|
99
|
+
dipole_tensor = np.eye(3)
|
|
100
|
+
print(medium.get_point_defect_strain(random_positions, dipole_tensor))
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
Example III: Get stress field around a dislocation:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
import numpy as np
|
|
108
|
+
medium = LinearElasticity(C_11=211.0, C_12=130.0, C_44=82.0)
|
|
109
|
+
random_positions = np.random.random((10, 3)) - 0.5
|
|
110
|
+
# Burgers vector of a screw dislocation in bcc Fe
|
|
111
|
+
burgers_vector = np.array([0, 0, 2.86 * np.sqrt(3) / 2])
|
|
112
|
+
print(medium.get_dislocation_stress(random_positions, burgers_vector))
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Example IV: Estimate the distance between partial dislocations:
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
medium = LinearElasticity(C_11=110.5, C_12=64.8, C_44=30.9) # Al
|
|
119
|
+
lattice_constant = 4.05
|
|
120
|
+
partial_one = np.array([-0.5, 0, np.sqrt(3) / 2]) * lattice_constant
|
|
121
|
+
partial_two = np.array([0.5, 0, np.sqrt(3) / 2]) * lattice_constant
|
|
122
|
+
distance = 100
|
|
123
|
+
stress_one = medium.get_dislocation_stress([0, distance, 0], partial_one)
|
|
124
|
+
print('Choose `distance` in the way that the value below corresponds to SFE')
|
|
125
|
+
medium.get_dislocation_force(stress_one, [0, 1, 0], partial_two)
|
|
126
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import importlib.metadata
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
# Installed package will find its version
|
|
5
|
+
__version__ = importlib.metadata.version(__name__)
|
|
6
|
+
except importlib.metadata.PackageNotFoundError:
|
|
7
|
+
# Repository clones will register an unknown version
|
|
8
|
+
__version__ = "0.0.0+unknown"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
from elaston.linear_elasticity import LinearElasticity
|
|
12
|
+
|
|
13
|
+
__all__ = ["LinearElasticity"]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# file generated by vcs-versioning
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"__version__",
|
|
7
|
+
"__version_tuple__",
|
|
8
|
+
"version",
|
|
9
|
+
"version_tuple",
|
|
10
|
+
"__commit_id__",
|
|
11
|
+
"commit_id",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
version: str
|
|
15
|
+
__version__: str
|
|
16
|
+
__version_tuple__: tuple[int | str, ...]
|
|
17
|
+
version_tuple: tuple[int | str, ...]
|
|
18
|
+
commit_id: str | None
|
|
19
|
+
__commit_id__: str | None
|
|
20
|
+
|
|
21
|
+
__version__ = version = '0.0.2'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 0, 2)
|
|
23
|
+
|
|
24
|
+
__commit_id__ = commit_id = None
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# Copyright (c) Max-Planck-Institut für Eisenforschung GmbH - Computational Materials Design (CM) Department
|
|
3
|
+
# Distributed under the terms of "New BSD License", see the LICENSE file.
|
|
4
|
+
|
|
5
|
+
from functools import cached_property
|
|
6
|
+
from typing import Annotated
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
from semantikon.converter import units
|
|
10
|
+
|
|
11
|
+
__author__ = "Sam Waseda"
|
|
12
|
+
__copyright__ = (
|
|
13
|
+
"Copyright 2021, Max-Planck-Institut für Eisenforschung GmbH "
|
|
14
|
+
"- Computational Materials Design (CM) Department"
|
|
15
|
+
)
|
|
16
|
+
__version__ = "1.0"
|
|
17
|
+
__maintainer__ = "Sam Waseda"
|
|
18
|
+
__email__ = "waseda@mpie.de"
|
|
19
|
+
__status__ = "development"
|
|
20
|
+
__date__ = "Aug 21, 2021"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Dislocation:
|
|
24
|
+
"""
|
|
25
|
+
Anisotropic elasticity theory for dislocations described by
|
|
26
|
+
[Eshelby](https://doi.org/10.1016/0001-6160(53)90099-6).
|
|
27
|
+
|
|
28
|
+
All notations follow the original paper.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self, elastic_tensor: np.ndarray, burgers_vector: np.ndarray) -> None:
|
|
32
|
+
"""
|
|
33
|
+
Args:
|
|
34
|
+
elastic_tensor ((3,3,3,3)-array): Elastic tensor
|
|
35
|
+
burgers_vector ((3,)-array): Burgers vector
|
|
36
|
+
"""
|
|
37
|
+
assert np.shape(elastic_tensor) == (3, 3, 3, 3)
|
|
38
|
+
assert np.shape(burgers_vector) == (3,)
|
|
39
|
+
self.elastic_tensor = elastic_tensor
|
|
40
|
+
self.burgers_vector = burgers_vector
|
|
41
|
+
self.fit_range = np.linspace(0, 1, 10)
|
|
42
|
+
|
|
43
|
+
def _get_pmat(self, x: np.ndarray) -> np.ndarray:
|
|
44
|
+
return (
|
|
45
|
+
self.elastic_tensor[:, 0, :, 0]
|
|
46
|
+
+ np.einsum(
|
|
47
|
+
"...,ij->...ij",
|
|
48
|
+
x,
|
|
49
|
+
self.elastic_tensor[:, 0, :, 1] + self.elastic_tensor[:, 1, :, 0],
|
|
50
|
+
)
|
|
51
|
+
+ np.einsum("...,ij->...ij", x**2, self.elastic_tensor[:, 1, :, 1])
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
@cached_property
|
|
55
|
+
def p(self) -> np.ndarray:
|
|
56
|
+
coeff = np.polyfit(
|
|
57
|
+
self.fit_range, np.linalg.det(self._get_pmat(self.fit_range)), 6
|
|
58
|
+
)
|
|
59
|
+
p = np.roots(coeff)
|
|
60
|
+
p = p[np.imag(p) > 0]
|
|
61
|
+
return p
|
|
62
|
+
|
|
63
|
+
@cached_property
|
|
64
|
+
def Ak(self) -> np.ndarray:
|
|
65
|
+
Ak = []
|
|
66
|
+
for mat in self._get_pmat(self.p):
|
|
67
|
+
values, vectors = np.linalg.eig(mat.T)
|
|
68
|
+
Ak.append(vectors.T[np.absolute(values).argmin()])
|
|
69
|
+
return np.array(Ak)
|
|
70
|
+
|
|
71
|
+
@cached_property
|
|
72
|
+
def D(self) -> np.ndarray:
|
|
73
|
+
F = np.einsum("n,ij->nij", self.p, self.elastic_tensor[:, 1, :, 1])
|
|
74
|
+
F += self.elastic_tensor[:, 1, :, 0]
|
|
75
|
+
F = np.einsum("nik,nk->ni", F, self.Ak)
|
|
76
|
+
F = np.concatenate((F.T, self.Ak.T), axis=0)
|
|
77
|
+
F = np.concatenate((np.real(F), -np.imag(F)), axis=-1)
|
|
78
|
+
D = np.linalg.solve(F, np.concatenate((np.zeros(3), self.burgers_vector)))
|
|
79
|
+
return D[:3] + 1j * D[3:]
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def dzdx(self) -> np.ndarray:
|
|
83
|
+
return np.stack((np.ones_like(self.p), self.p, np.zeros_like(self.p)), axis=-1)
|
|
84
|
+
|
|
85
|
+
def _get_z(self, positions: np.ndarray) -> np.ndarray:
|
|
86
|
+
z = np.stack((np.ones_like(self.p), self.p), axis=-1)
|
|
87
|
+
return np.einsum("nk,...k->...n", z, np.asarray(positions)[..., :2])
|
|
88
|
+
|
|
89
|
+
def get_displacement(self, positions: np.ndarray) -> np.ndarray:
|
|
90
|
+
"""
|
|
91
|
+
Displacement vectors
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
positions ((n,3)-array): Positions for which the displacements are
|
|
95
|
+
to be calculated
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
((n,3)-array): Displacement vectors
|
|
99
|
+
"""
|
|
100
|
+
return np.imag(
|
|
101
|
+
np.einsum(
|
|
102
|
+
"nk,n,...n->...k", self.Ak, self.D, np.log(self._get_z(positions))
|
|
103
|
+
)
|
|
104
|
+
) / (2 * np.pi)
|
|
105
|
+
|
|
106
|
+
def get_strain(self, positions: np.ndarray) -> np.ndarray:
|
|
107
|
+
"""
|
|
108
|
+
Strain tensors
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
positions ((n,3)-array): Positions for which the strains are to be
|
|
112
|
+
calculated
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
((n,3,3)-array): Strain tensors
|
|
116
|
+
"""
|
|
117
|
+
strain = np.imag(
|
|
118
|
+
np.einsum(
|
|
119
|
+
"ni,n,...n,nj->...ij",
|
|
120
|
+
self.Ak,
|
|
121
|
+
self.D,
|
|
122
|
+
1 / self._get_z(positions),
|
|
123
|
+
self.dzdx,
|
|
124
|
+
)
|
|
125
|
+
)
|
|
126
|
+
strain = strain + np.einsum("...ij->...ji", strain)
|
|
127
|
+
return strain / 4 / np.pi
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@units
|
|
131
|
+
def get_dislocation_displacement(
|
|
132
|
+
elastic_tensor: Annotated[np.ndarray, {"units": "=e"}],
|
|
133
|
+
positions: np.ndarray,
|
|
134
|
+
burgers_vector: Annotated[np.ndarray, {"units": "=b"}],
|
|
135
|
+
) -> Annotated[np.ndarray, {"units": "=b"}]:
|
|
136
|
+
"""
|
|
137
|
+
Displacement field around a dislocation according to anisotropic elasticity theory
|
|
138
|
+
described by [Eshelby](https://doi.org/10.1016/0001-6160(53)90099-6).
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
elastic_tensor ((3,3,3,3)-array): Elastic tensor
|
|
142
|
+
positions ((n,2) or (n,3)-array): Position around a dislocation. The third axis
|
|
143
|
+
coincides with the dislocation line.
|
|
144
|
+
burgers_vector ((3,)-array): Burgers vector
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
((n, 3)-array): Displacement field (z-axis coincides with the dislocation line)
|
|
148
|
+
"""
|
|
149
|
+
return Dislocation(elastic_tensor, burgers_vector).get_displacement(positions)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@units
|
|
153
|
+
def get_dislocation_strain(
|
|
154
|
+
elastic_tensor: Annotated[np.ndarray, {"units": "=e"}],
|
|
155
|
+
positions: Annotated[np.ndarray, {"units": "=p"}],
|
|
156
|
+
burgers_vector: Annotated[np.ndarray, {"units": "=b"}],
|
|
157
|
+
) -> Annotated[np.ndarray, {"units": "=b/p"}]:
|
|
158
|
+
"""
|
|
159
|
+
Strain field around a dislocation according to anisotropic elasticity theory
|
|
160
|
+
described by [Eshelby](https://doi.org/10.1016/0001-6160(53)90099-6).
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
elastic_tensor ((3,3,3,3)-array): Elastic tensor
|
|
164
|
+
positions ((n,2) or (n,3)-array): Position around a dislocation. The third axis
|
|
165
|
+
coincides with the dislocation line.
|
|
166
|
+
burgers_vector ((3,)-array): Burgers vector
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
((n, 3, 3)-array): Strain field (z-axis coincides with the dislocation line)
|
|
170
|
+
"""
|
|
171
|
+
return Dislocation(elastic_tensor, burgers_vector).get_strain(positions)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@units
|
|
175
|
+
def get_dislocation_stress(
|
|
176
|
+
elastic_tensor: Annotated[np.ndarray, {"units": "=e"}],
|
|
177
|
+
positions: Annotated[np.ndarray, {"units": "=p"}],
|
|
178
|
+
burgers_vector: Annotated[np.ndarray, {"units": "=b"}],
|
|
179
|
+
) -> Annotated[np.ndarray, {"units": "=e*b/p"}]:
|
|
180
|
+
"""
|
|
181
|
+
Stress field around a dislocation according to anisotropic elasticity theory
|
|
182
|
+
described by [Eshelby](https://doi.org/10.1016/0001-6160(53)90099-6).
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
elastic_tensor ((3,3,3,3)-array): Elastic tensor
|
|
186
|
+
positions ((n,2) or (n,3)-array): Position around a dislocation. The third axis
|
|
187
|
+
coincides with the dislocation line.
|
|
188
|
+
burgers_vector ((3,)-array): Burgers vector
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
((n, 3, 3)-array): Stress field (z-axis coincides with the dislocation line)
|
|
192
|
+
"""
|
|
193
|
+
strain = get_dislocation_strain(elastic_tensor, positions, burgers_vector)
|
|
194
|
+
return np.einsum("ijkl,...kl->...ij", elastic_tensor, strain)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
@units
|
|
198
|
+
def get_dislocation_energy_density(
|
|
199
|
+
elastic_tensor: Annotated[np.ndarray, {"units": "=e"}],
|
|
200
|
+
positions: Annotated[np.ndarray, {"units": "=p"}],
|
|
201
|
+
burgers_vector: Annotated[np.ndarray, {"units": "=b"}],
|
|
202
|
+
) -> Annotated[np.ndarray, {"units": "=e*b**2/p**2"}]:
|
|
203
|
+
"""
|
|
204
|
+
Energy density field around a dislocation (product of stress and strain, cf. corresponding
|
|
205
|
+
methods)
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
elastic_tensor ((3,3,3,3)-array): Elastic tensor
|
|
209
|
+
positions ((n,2) or (n,3)-array): Position around a dislocation. The third axis
|
|
210
|
+
coincides with the dislocation line.
|
|
211
|
+
burgers_vector ((3,)-array): Burgers vector
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
((n,)-array): Energy density field
|
|
215
|
+
"""
|
|
216
|
+
strain = get_dislocation_strain(elastic_tensor, positions, burgers_vector)
|
|
217
|
+
return np.einsum("ijkl,...kl,...ij->...", elastic_tensor, strain, strain)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
@units
|
|
221
|
+
def get_dislocation_energy(
|
|
222
|
+
elastic_tensor: Annotated[np.ndarray, {"units": "=e"}],
|
|
223
|
+
burgers_vector: Annotated[np.ndarray, {"units": "=b"}],
|
|
224
|
+
r_min: Annotated[float, {"units": "=r"}],
|
|
225
|
+
r_max: Annotated[float, {"units": "=r"}],
|
|
226
|
+
mesh: int = 100,
|
|
227
|
+
) -> Annotated[float, {"units": "=e*b**2"}]:
|
|
228
|
+
"""
|
|
229
|
+
Energy per unit length along the dislocation line.
|
|
230
|
+
|
|
231
|
+
Args:
|
|
232
|
+
elastic_tensor ((3,3,3,3)-array): Elastic tensor
|
|
233
|
+
burgers_vector ((3,)-array): Burgers vector
|
|
234
|
+
r_min (float): Minimum distance from the dislocation core
|
|
235
|
+
r_max (float): Maximum distance from the dislocation core
|
|
236
|
+
mesh (int): Number of grid points for the numerical integration along the angle
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
(float): Energy of dislocation per unit length
|
|
240
|
+
|
|
241
|
+
The energy is defined by the product of the stress and strain (i.e. energy density),
|
|
242
|
+
which is integrated over the plane vertical to the dislocation line. The energy density
|
|
243
|
+
:math:`w` according to the linear elasticity is given by:
|
|
244
|
+
|
|
245
|
+
.. math:
|
|
246
|
+
w(r, \\theta) = A(\\theta)/r^2
|
|
247
|
+
|
|
248
|
+
Therefore, the energy per unit length :math:`U` is given by:
|
|
249
|
+
|
|
250
|
+
.. math:
|
|
251
|
+
U = \\log(r_max/r_min)\\int A(\\theta)\\mathrm d\\theta
|
|
252
|
+
|
|
253
|
+
This implies :math:`r_min` cannot be 0 as well as :math:`r_max` cannot be infinity. This
|
|
254
|
+
is the consequence of the fact that the linear elasticity cannot describe the core
|
|
255
|
+
structure properly, and a real medium is not infinitely large. While :math:`r_max` can
|
|
256
|
+
be defined based on the real dislocation density, the choice of :math:`r_min` should be
|
|
257
|
+
done carefully.
|
|
258
|
+
"""
|
|
259
|
+
if r_min <= 0:
|
|
260
|
+
raise ValueError("r_min must be a positive float")
|
|
261
|
+
theta_range = np.linspace(0, 2 * np.pi, 100, endpoint=False)
|
|
262
|
+
r = np.stack((np.cos(theta_range), np.sin(theta_range)), axis=-1) * r_min
|
|
263
|
+
strain = get_dislocation_strain(elastic_tensor, r, burgers_vector=burgers_vector)
|
|
264
|
+
return (
|
|
265
|
+
np.einsum("ijkl,nkl,nij->", elastic_tensor, strain, strain)
|
|
266
|
+
* np.diff(theta_range)[0]
|
|
267
|
+
* r_min**2
|
|
268
|
+
* np.log(r_max / r_min)
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
@units
|
|
273
|
+
def get_dislocation_force(
|
|
274
|
+
stress: Annotated[np.ndarray, {"units": "=s"}],
|
|
275
|
+
glide_plane: np.ndarray,
|
|
276
|
+
burgers_vector: Annotated[np.ndarray, {"units": "=b"}],
|
|
277
|
+
) -> Annotated[np.ndarray, {"units": "=s*b"}]:
|
|
278
|
+
"""
|
|
279
|
+
Force per unit length along the dislocation line.
|
|
280
|
+
|
|
281
|
+
Args:
|
|
282
|
+
stress ((n, 3, 3)-array): External stress field at the dislocation line
|
|
283
|
+
glide_plane ((3,)-array): Glide plane
|
|
284
|
+
burgers_vector ((3,)-array): Burgers vector
|
|
285
|
+
|
|
286
|
+
Returns:
|
|
287
|
+
((3,)-array): Force per unit length acting on the dislocation.
|
|
288
|
+
"""
|
|
289
|
+
g = np.asarray(glide_plane) / np.linalg.norm(glide_plane)
|
|
290
|
+
return np.einsum(
|
|
291
|
+
"i,...ij,j,k->...k", g, stress, burgers_vector, np.cross(g, [0, 0, 1])
|
|
292
|
+
)
|