This page’ purpose is twofold:
The crystal structure must be defined through the @CrystalStructure
keyword. This keyword is followed by one of the following value:
Cubic
: cubic structure.BCC
: body centered cubic structure.FCC
: face centered cubic structure.HCP
: hexagonal closed-packed structures.@CrystalStructure FCC;
A single slip systems family can be defined by one of the following keywords: @SlidingSystem
, @GlidingSystem
or @SlipSystem
. Those keywords are followed by the definition of one family of slip systems.
Several slip systems families can be defined by one of the following keywords: @SlidingSystems
, @GlidingSystems
or @SlipSystems
. Those keywords are followed by an array giving the definition of the families of slip systems.
A slip system is defined by its Burgers’vector and its plane. In the case of a cubic system, the syntax is as follows:
1,-1,0>{1,1,1} <
Hexagonal systems For an hexagonal system, a fourth indices notation is used.
Thus, an example of the usage of the @SlidingSystem
keyword is:
@SlidingSystem <1,-1,0>{1,1,1};
For a given slip systems family, a set of slip systems are generated by symmetry using code extracted from the NUMODIS
code (see [1]). The previous example defines \(12\) slip systems.
The list of the generated slip systems can be retrieved using mfront-query
.
Consider the following example:
@DSL ImplicitFiniteStrain;
@Behaviour SlipSystemGenerationTest;
@Brick FiniteStrainSingleCrystal;
@CrystalStructure FCC;
@SlidingSystem <1,-1,0>{1,1,1};
If the previous code is saved a file called SlipSystemGenerationTest.mfront
, one may use mfront-query
as follows:
$ mfront-query --slip-systems SlipSystemGenerationTest.mfront
- <1,-1,0>{1,1,1}: [0,1,-1](1,1,1) [1,0,-1](1,1,1) [1,-1,0](1,1,1) [0,1,1](1,1,-1) [1,0,1](1,1,-1) [1,-1,0](1,1,-1) [0,1,-1](1,-1,-1) [1,0,1](1,-1,-1) [1,1,0](1,-1,-1) [0,1,1](1,-1,1) [1,0,-1](1,-1,1) [1,1,0](1,-1,1)
The output shows that \(12\) slip systems were generated. All those systems are equivalent by symmetry.
Concerning slip systems, the following queries are available:
$ mfront-query --help-behaviour-queries-list |grep slip
--slip-systems : list all the slip systems, sorted by family
--slip-systems-by-index : list all the slip systems
The --slip-systems-by-index
query gives the index associated to a given slip system, which is helpfull for postprocessing purposes. For this example:
$ mfront-query --slip-systems-by-index SlipSystemGenerationTest.mfront
- 0: [0,1,-1](1,1,1)
- 1: [1,0,-1](1,1,1)
- 2: [1,-1,0](1,1,1)
- 3: [0,1,1](1,1,-1)
- 4: [1,0,1](1,1,-1)
- 5: [1,-1,0](1,1,-1)
- 6: [0,1,-1](1,-1,-1)
- 7: [1,0,1](1,-1,-1)
- 8: [1,1,0](1,-1,-1)
- 9: [0,1,1](1,-1,1)
- 10: [1,0,-1](1,-1,1)
- 11: [1,1,0](1,-1,1)
Concerning the orientation tensors, the following queries are available:
--orientation-tensors
: list all the orientation tensors, sorted by family".--orientation-tensors-by-index
: list all the orientation tensors.--orientation-tensors-by-slip-system
: list all the orientation tensors sorted by slip systems.Concerning the climb tensors, the following queries are available:
--climb-tensors
: list all the climb tensors, sorted by family".--climb-tensors-by-index
: list all the climb tensors.--climb-tensors-by-slip-system
: list all the climb tensors sorted by slip systems.Concerning the Schmid factors, the following queries are available:
--schmid-factors
: list all the Schmid factors, sorted by family".--schmid-factors-by-index
: list all the Schmid factors.$ mfront-query --schmid-factors-by-index='<1,1,1>' SlipSystemGenerationTest.mfront
Note In this example, the direction must be surrounded by simple quote to avoid interpretation by the shell.
Since many interactions between slip systems are equivalent, the interaction matrix only contains a few independent coefficients.
Using mfront-query
, one may have access to the whole matrix using the --interaction-matrix
query:
$ mfront-query --interaction-matrix SlipSystemGenerationTest.mfront
| 0 1 2 2 3 4 5 6 5 6 4 3 |
| 1 0 2 2 6 5 4 3 4 3 5 6 |
| 2 2 0 1 5 6 3 4 6 5 3 4 |
| 2 2 1 0 4 3 6 5 3 4 6 5 |
| 3 4 5 6 0 1 2 2 6 5 4 3 |
| 6 5 4 3 1 0 2 2 3 4 5 6 |
| 5 6 3 4 2 2 0 1 5 6 3 4 |
| 4 3 6 5 2 2 1 0 4 3 6 5 |
| 5 6 4 3 4 3 5 6 0 1 2 2 |
| 4 3 5 6 5 6 4 3 1 0 2 2 |
| 6 5 3 4 6 5 3 4 2 2 0 1 |
| 3 4 6 5 3 4 6 5 2 2 1 0 |
Here only \(7\) coefficients are needed. The number corresponding to a pair of slip systems defines the rank of the interaction.
The mfront-query
also provides the --interaction-matrix-structure
query which displays the number of independent coefficients and sorts the pair of slip systems by rank:
$ mfront-query --interaction-matrix-structure SlipSystemGenerationTest.mfront
- number of independent coefficients: 7
- rank 0: ([0,1,-1](1,1,1):[0,1,-1](1,1,1)) ([1,0,-1](1,1,1):[1,0,-1](1,1,1)) ([1,-1,0](1,1,1):[1,-1,0](1,1,1)) ([0,1,1](1,1,-1):[0,1,1](1,1,-1)) ([1,0,1](1,1,-1):[1,0,1](1,1,-1)) ([1,-1,0](1,1,-1):[1,-1,0](1,1,-1)) ([0,1,-1](1,-1,-1):[0,1,-1](1,-1,-1)) ([1,0,1](1,-1,-1):[1,0,1](1,-1,-1)) ([1,1,0](1,-1,-1):[1,1,0](1,-1,-1)) ([0,1,1](1,-1,1):[0,1,1](1,-1,1)) ([1,0,-1](1,-1,1):[1,0,-1](1,-1,1)) ([1,1,0](1,-1,1):[1,1,0](1,-1,1))
- rank 1: ([0,1,-1](1,1,1):[1,0,-1](1,1,1)) ([0,1,-1](1,1,1):[1,-1,0](1,1,1)) ([1,0,-1](1,1,1):[0,1,-1](1,1,1)) ([1,0,-1](1,1,1):[1,-1,0](1,1,1)) ([1,-1,0](1,1,1):[0,1,-1](1,1,1)) ([1,-1,0](1,1,1):[1,0,-1](1,1,1)) ([0,1,1](1,1,-1):[1,0,1](1,1,-1)) ([0,1,1](1,1,-1):[1,-1,0](1,1,-1)) ([1,0,1](1,1,-1):[0,1,1](1,1,-1)) ([1,0,1](1,1,-1):[1,-1,0](1,1,-1)) ([1,-1,0](1,1,-1):[0,1,1](1,1,-1)) ([1,-1,0](1,1,-1):[1,0,1](1,1,-1)) ([0,1,-1](1,-1,-1):[1,0,1](1,-1,-1)) ([0,1,-1](1,-1,-1):[1,1,0](1,-1,-1)) ([1,0,1](1,-1,-1):[0,1,-1](1,-1,-1)) ([1,0,1](1,-1,-1):[1,1,0](1,-1,-1)) ([1,1,0](1,-1,-1):[0,1,-1](1,-1,-1)) ([1,1,0](1,-1,-1):[1,0,1](1,-1,-1)) ([0,1,1](1,-1,1):[1,0,-1](1,-1,1)) ([0,1,1](1,-1,1):[1,1,0](1,-1,1)) ([1,0,-1](1,-1,1):[0,1,1](1,-1,1)) ([1,0,-1](1,-1,1):[1,1,0](1,-1,1)) ([1,1,0](1,-1,1):[0,1,1](1,-1,1)) ([1,1,0](1,-1,1):[1,0,-1](1,-1,1))
.....
In this example, the rank \(0\) contains all the interactions of a slip system with itself.
FCC
caseIn the case of FCC
, the interaction matrix has \(7\) independent coefficients and the matrix is non symmetric (see [2]).
The interaction matrix is defined through the @InteractionMatrix
keyword. This keyword is followed by an array of values, ordered by growing rank.
A special keyword has been introduced for the user to have access to a second interaction matrix. By convention this matrix is meant to be used to evaluate the effect of all the dislocation on the mean free path of dislocations of a specific system.
This interaction has the same structure than the interaction matrix used to describe hardening effects. Please refer to the previous paragraph for details.
This second matrix can be defined using the @DislocationsMeanFreePathInteractionMatrix
keywords.
Once the sliding system families has been defined, a static integer variable called Nss
is available which contains the total number of slip systems defined. In the previous example, Nss
value is \(12\).
This value can be used to define additional state variables:
//! equivalent plastic strain on each slip system
@AuxiliaryStateVariable real p[Nss];
Also, note that for the \(i^{\text{th}}\) slip systems family, a static integer variable beginning by Nss
and followed by the value of \(i\) is defined. In the previous example, a unique slip systems family is defined and a variable Nss0
is made available. Of course, in this case Nss0
is equal to Nss
. Those variables may be useful to define variables specific to a slip system family.
For performances reasons, it would be too costly to build the information about slip systems and interaction matrices every time the behaviour is integrated.
For this reason, an auxiliary data structure is generated. The name of the data structure is the name of the behaviour, followed by SlipSystems
. For example, if the behaviour name is FCCSingleCrystal
, the name of this auxiliary data structure is FCCSingleCrystalSlipSystems
.
This data structure is build once for the whole duration of the execution following a technique called singleton
.
When using the FiniteStrainSingleCrystal
brick, this uniq instance is available in @Integrator
block through a (reference) variable called ss
.
If this brick is not used or if this variable is needed in other blocks of the code, one may declare the ss
variable as follows:
const auto& ss = FCCSingleCrystalSlipSystems<real>::getSlipSystems();
Of course, the name ss
(for slips systems) can be changed by the user to match his/her own conventions.
The previous data structure has the following public members:
np
: an array containing all the normals to the slip planesns
: an array containing all the slip directions (unit vector based on the Burger’s vector)mu
: an array containing all the orientation tensorsmus
: an array containing all the symmetric part of the orientation tensorsclimb_tensors
: an array containing all the climb tensors (as symmetric tensors) defined as the tensorial product of the normals by themselves.For every slip system family, specific arrays are also provided. For example, np0
contains all the normals to the slip planes of the first family.
@InteractionMatrix
The interaction matrix is accessible through the him
(hardening interaction matrix) member.
//! access to the interaction matrix
const auto& m = ss.him;
For backward compatibility and ease the transition from previous implementations, this matrix is also accessible through the mh
member.
@DislocationsMeanFreePathInteractionMatrix
If defined, the interaction matrix meant to evaluate the effect of all the dislocation on the mean free path of dislocations of a specific system can be accessed through the dim
(dislocation interaction matrix) member.
//! access to the interaction matrix
const auto& m = ss.dim;
The member function buildInteractionMatrix
can be used to compute manually the interaction matrix.
It allows to define the coefficients of the interaction matrix as parameters or as material properties:
@Parameters real im_coefficients[7];
"InteractionMatrixCoefficients");
im_coefficients.setEntryName(
....
@Integrator{
const auto& ss = FCCSingleCrystalSlipSystems<real>::getSlipSystems();
const auto m = ss.buildInteractionMatrix(im_coefficients);
.... }
To know if two systems are coplanar, the data structure described in the previous paragraph provides the areCoplanar
method. For example:
for(unsigned short i=0;i!=Nss;++i){
....for(unsigned short j=0;j!=Nss;++j){
if (ss.areCoplanar(i,j)){
hcopla[i]+=sqrt(ss.him(i,j)*ppomega[j]);else {
}
hforest[i]+=sqrt(ss.him(i,j))*ppomega[j];
} ...
The FiniteStrainSingleCrystal
brick creates a huge vector of internal state variable describing the plastic slips along the slips systems. It is sometimes useful to be able to distinguish each slip systems’ family: for example to prescribe different constitutive equations for each family.
The slips systems are sorted by family. So the Nss0
first plastic slips correspond to the first family. One can thus use the Nss.+
variables to compute the offset of each family. For example, the plastic slip of the second system of the third family can be accessed as follows (remember that C++
indices starts at 0
, so the index of the second system is 1
):
const auto g2_3 = this->g[Nss0+Nss1+1];
To define constitutive equations for the third family, one may use a loop, as follows:
for(const unsigned short i=0;i!=Nss2;++i){
fg[Nss0+Nss1+i]=... }
However, this approach is error-prone, the data structure describing the slip systems provides methods to compute the offset of each family. There is one general method called offset
and one methods per family called offset
plus the number of the family (e.g. offset1
for the second family).
Hence, the previous loop can be written with the offset
method as follows:
for(const unsigned short i=0;i!=Nss2;++i){
2,i)]=...
fg[ss.offset( }
This loop can also be written using the offset2
method:
for(const unsigned short i=0;i!=Nss2;++i){
fg[ss.offset2(i)]=... }
This latter way can be more efficient than using the global offset
method depending on the compiler (and the compiler options used).