In this section we discus geometric properties that can be derived from grain boundaries. Lets start by importing some EBSD data and computing grain boundaries.
% load some example data
plottingConvention.default('y↑→x');
mtexdata twins silent
ebsd.prop = rmfield(ebsd.prop,{'error','bands'});
% detect grains
[grains,ebsd] = calcGrains(ebsd,'angle',10*degree,'minPixel',3);
% smooth them - this page reads ebsdId per segment, which only means something
% as long as every segment still runs between one pair of pixels, so the
% coarsening and resampling steps are switched off
grains = grains.smoothBoundary(5,'noSimplify','noRefine');
% visualize the grains
plot(grains,grains.meanOrientation)
% extract all grain boundaries
gB = grains.boundary;
hold on
plot(gB,'LineWidth',2)
hold off
Property overview
A variable of type grainBoundary contains the following properties
|
ebsdId |
neighboring pixel ids |
phaseId |
neighboring phase ids |
|
grainId |
neighboring grain ids |
F |
vertices ids of the segments |
|
length of each segment |
direction |
direction of each segment |
|
|
midPoint |
mid point of the segment |
curvature of each segment |
|
|
misorientation |
between ebsdId(:,1) and ebsdId(:,2) |
triplePoints |
list of all triple points |
|
componentId |
connected component id |
componentSize |
connected component size |
The first three properties refer to \(N \times 2\) matrices where \(N\) is the number of boundary segments. Each row of these matrices contains the information about the EBSD data, and grain data on both sides of the grain boundary. To illustrate this consider the grain boundary of one specific grain
gB4 = grains(4).boundarygB4 = grainBoundary (y↑→x)
Segments length mineral 1 mineral 2
8 1.3 µm Magnesium MagnesiumThis boundary consists of 8 segments and hence ebsdId forms a 8x2 matrix
gB4.ebsdIdans =
1103 1104
966 967
966 829
965 828
965 964
965 1102
1103 1102
1103 1240It is important to understand that the id is not necessarily the same as the index in the list. In order to index an variable of type EBSD by id and not by index the following syntax has to be used
ebsd('id',gB4.ebsdId)ans = EBSDsquare (y↑→x, row←col↑)
Phase Orientations Mineral Color Symmetry Crystal reference frame
1 16 (100%) Magnesium LightSkyBlue 6/mmm X||a*, Y||b, Z||c
Id Phase orientation bc bs mad oldId grainId
1103 1 (114.7°,15.7°,218.5°) 182 174 0.5 1011 4
966 1 (113.7°,15.5°,219.3°) 164 158 0.5 1010 4
966 1 (113.7°,15.5°,219.3°) 164 158 0.5 1010 4
965 1 (115.3°,15.6°,218.2°) 170 176 0.7 843 4
965 1 (115.3°,15.6°,218.2°) 170 176 0.7 843 4
965 1 (115.3°,15.6°,218.2°) 170 176 0.7 843 4
1103 1 (114.7°,15.7°,218.5°) 182 174 0.5 1011 4
1103 1 (114.7°,15.7°,218.5°) 182 174 0.5 1011 4
1104 1 (4.7°,80.8°,195.4°) 174 181 0.5 1178 42
967 1 (4.5°,80.7°,195.2°) 168 171 0.3 1177 42
829 1 (4.6°,80.7°,195.4°) 156 160 0.4 1009 42
828 1 (4.9°,80.4°,195.2°) 167 170 0.5 842 42
964 1 (4.9°,80.4°,195.2°) 176 196 0.5 676 42
1102 1 (4.4°,80.5°,195.1°) 174 197 0.3 844 42
1102 1 (4.4°,80.5°,195.1°) 174 197 0.3 844 42
1240 1 (4.4°,80.5°,195.2°) 176 168 0.4 1012 42
Scan unit : um
X x Y x Z : [1.8 → 2.7] x [1.2 → 2.1] x [0 → 0]
Normal vector: (0,0,1)
Square grid :8 x 2Similarly
gB4.grainIdans =
4 42
4 42
4 42
4 42
4 42
4 42
4 42
4 42results in 8x2 matrix indicating that grain 4 is a tiny inclusion of grain 42.
plot(grains(4),'FaceColor','DarkBlue','micronbar','off')
hold on
plot(grains(42),'FaceColor','LightCoral')
hold off
Grain boundary misorientations
The grain boundary misorientation defined as the misorientation between the orientations corresponding to ids in first and second column of ebsdId, i.e. following two commands should give the same result
gB4(1).misorientation
inv(ebsd('id',gB4.ebsdId(1,2)).orientations) .* ebsd('id',gB4.ebsdId(1,1)).orientationsans = misorientation (Magnesium → Magnesium)
antipodal: true
Bunge Euler angles in degree
phi1 Phi phi2
329.875 86.401 150.169
ans = misorientation (Magnesium → Magnesium)
Bunge Euler angles in degree
phi1 Phi phi2
329.875 86.401 150.169Note that in the first result the antipodal flag is true while it is false in the second result.
Obviously, misorientations of a list of grain boundaries can only be extracted if all of them have the same type of phase transition. Let us consider only Magnesium to Magnesium grain boundaries, i.e., omit all grain boundaries to an not indexed region.
gB_Mg = gB('Magnesium','Magnesium')gB_Mg = grainBoundary (y↑→x)
Segments length mineral 1 mineral 2
3161 722 µm Magnesium MagnesiumThen the misorientation angles can be plotted by
plot(gB_Mg,gB_Mg.misorientation.angle./degree,'linewidth',4,'micronbar','off')
mtexColorbar('title','misorientation angle (°)')
Geometric properties
The direction property of the boundary segments is useful when checking for tilt and twist boundaries, i.e., when we want to compare the misorientation axis with the interface between the grains
% compute misorientation axes in specimen coordinates
ori = ebsd('id',gB_Mg.ebsdId).orientations;
axes = axis(ori(:,1),ori(:,2),'antipodal')
% plot the angle between the misorientation axis and the boundary direction
plot(gB_Mg,angle(gB_Mg.direction,axes),'linewidth',4,'micronbar','off')axes = vector3d (y↑→x)
size: 3161 x 1
antipodal: true
We observe that the angle is quite oscillatory. This is because of the stair casing effect when reconstructing grains from gridded EBSD data. The weaken this effect we may average the segment directions using the command calcMeanDirection
% plot the angle between the misorientation axis and the boundary direction
plot(gB_Mg,angle(gB_Mg.calcMeanDirection(4),axes),'linewidth',4,'micronbar','off')
The midPoint property gives the position of each segment as a vector3d. It is what one needs whenever something has to be drawn at, or selected by, the location of a segment - the misorientation axes above, for instance, are best shown as arrows sitting on their segments
plot(grains,grains.meanOrientation,'faceAlpha',0.3,'micronbar','off')
hold on
quiver(gB_Mg(1:3:end),axes(1:3:end),'color','black','autoScaleFactor',0.6)
hold off
and it is equally the natural handle for a spatial selection
pos = gB_Mg.midPoint;
isTop = pos.y > 30;
plot(grains,'faceAlpha',0.3,'micronbar','off')
hold on
plot(gB_Mg(isTop),'linewidth',3,'lineColor','red')
plot(gB_Mg(~isTop),'linewidth',3,'lineColor','blue')
hold off
While the command length(gB_Mg) gives the total number of all Magnesium to Magnesium grain boundary segments the command segLength(gB_Mg) gives the length of each segment in µm. The total length of all Magnesium to Magnesium grain boundary segments is hence
sum(gB_Mg.segLength)ans =
722.2508Connected components
When analyzing the topology of boundary networks connected components of certain subsets of boundaries are of interest. Using the commands|gB.componentId| and gB.componentSize we are able to separate the boundary network into groups of connected components and analyze them separately. We do so below at the example of twin boundaries which we first colorize according to length.
CS = ebsd.CS;
twinning = orientation.map(Miller(1,-1,0,1,CS),Miller(1,0,-1,-1,CS),...
Miller(0,1,-1,1,CS,'uvw'),Miller(1,-1,0,1,CS,'uvw'))
gBTwin = gB(gB.isTwinning(twinning));
plot(grains,grains.meanOrientation,'faceAlpha',0.25,'micronbar','off')
hold on
plot(gBTwin,gBTwin.componentSize,'lineWidth',4)
hold off
mtexColorbartwinning = misorientation (Magnesium → Magnesium)
(101̅1̅) || (011̅1) [011̅1] || [11̅01]
Next we compute how curvy each twin boundary component is, by dividing it spatial extension by its total length. This measure has proven to be useful to tell apart misindexing due to pseudosymmetries and true twin boundaries.
numComponents = max(gBTwin.componentId);
xmax = accumarray(gBTwin.componentId,gBTwin.midPoint.x,[numComponents,1],@max);
ymax = accumarray(gBTwin.componentId,gBTwin.midPoint.y,[numComponents,1],@max);
xmin = accumarray(gBTwin.componentId,gBTwin.midPoint.x,[numComponents,1],@min);
ymin = accumarray(gBTwin.componentId,gBTwin.midPoint.y,[numComponents,1],@min);
ext = sqrt((xmax-xmin).^2+(ymax-ymin).^2);
len = accumarray(gBTwin.componentId,gBTwin.segLength,[numComponents,1],@sum);
value = ext ./ len;
plot(grains,grains.meanOrientation,'faceAlpha',0.25)
hold on
plot(gBTwin,value(gBTwin.componentId),'lineWidth',4)
hold off
mtexColorbar
mtexColorMap blue2red
Citing this page.
This page is part of the documentation of
MTEX, a free and open
source MATLAB toolbox for analyzing and modeling crystallographic textures.
It was written by The MTEX Developers and is published at
https://mtex-toolbox.github.io/BoundaryProperties.html.
If you use MTEX, or reuse text or figures from this page, in your research,
please cite
F. Bachmann, R. Hielscher, H. Schaeben: Texture Analysis with MTEX - Free and Open Source Software Toolbox, Solid State Phenomena 160 (2010), 63-68. 10.4028/www.scientific.net/SSP.160.63
BibTeX
@article{bachmann2010mtex,
author = {F. Bachmann and R. Hielscher and H. Schaeben},
title = {Texture Analysis with MTEX - Free and Open Source Software Toolbox},
journal = {Solid State Phenomena},
volume = {160},
pages = {63-68},
year = {2010},
doi = {10.4028/www.scientific.net/SSP.160.63},
url = {https://doi.org/10.4028/www.scientific.net/SSP.160.63}
}
Other papers describing specific MTEX methods are listed under Publications — please cite the one that best fits your application. The MTEX source code is licensed under the GNU General Public License v2.0; the text and figures of this documentation are licensed under CC BY 4.0, which permits reuse — including by automated systems — provided The MTEX Developers and this page are credited.