-
Notifications
You must be signed in to change notification settings - Fork 7
/
ORTools_example07.m
208 lines (178 loc) · 8.57 KB
/
ORTools_example07.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
% *********************************************************************
% ORTools - Example 7
% *********************************************************************
% Reconstructing the prior austenite microstructure from lath martensite
% with the variant graph approach and analyzing variant pairing and block
% width
% The MTEX description for reconstruction is given here:
% https://mtex-toolbox.github.io/MaParentGrainReconstruction.html
% https://www.youtube.com/watch?v=E9IFyFUQNl4&t=166s
% *********************************************************************
% Dr. Azdiar Gazder, 2022, azdiaratuowdotedudotau
% Dr. Frank Niessen, 2022, contactatfniessendotcom
% (Remove "dot" and "at" to make this email address valid)
% *********************************************************************
home; close all; clear variables;
currentFolder;
set(0,'DefaultFigureWindowStyle','normal');
screenPrint('StartUp','ORTools - Example 7 - Variant Graph Approach');
%% Initialize MTEX
% Startup and set some settings
startup_mtex;
setMTEXpref('xAxisDirection','east');
setMTEXpref('zAxisDirection','outOfPlane');
setMTEXpref('FontSize',14);
setInterp2Tex;
% Default directories - Do not modify
Ini.dataPath = [strrep(pwd,'\','/'),'/data/'];
Ini.cifPath = [Ini.dataPath,'input/cif/'];
Ini.ebsdPath = [Ini.dataPath,'input/ebsd/'];
Ini.texturePath = [Ini.dataPath,'output/texture/'];
Ini.imagePath = [Ini.dataPath,'output/images/'];
%% Load data
% Load an MTEX dataset into 'ebsd'
mtexDataset = 'martensite';
screenPrint('SegmentStart',sprintf('Loading MTEX example data ''%s''',mtexDataset));
ebsd = mtexdata(mtexDataset);
%% Compute, filter and smooth grains
screenPrint('SegmentStart','Computing, filtering and smoothing grains');
% Grains are calculated with a 3° threshold
[grains,ebsd.grainId] = calcGrains(ebsd('indexed'),'angle',3*degree);
% EBSD data in small grains are removed
ebsd(grains(grains.grainSize < 3)) = [];
% Recalculate the grains from the remaining data ...
[grains,ebsd.grainId] = calcGrains(ebsd('indexed'),'angle',3*degree);
% ... and smooth the grain boundaries
grains = smooth(grains,5);
%% Rename and recolor phases
screenPrint('SegmentStart','Renaming and recoloring phases');
phaseNames = {'Gamma','AlphaP'};
% Rename 'Iron bcc (old)'to 'AlphaP' and 'Iron fcc' to 'Gamma'
ebsd = renamePhases(ebsd,phaseNames);
% Choose your favourite colors
ebsd = recolorPhases(ebsd);
%% Define and refine parent-to-child orientation relationship
screenPrint('SegmentStart','Define and refine parent-to-child OR');
% Define 'Gamma" as the parent and 'AlphaP' as the child phase
job = setParentGrainReconstructor(ebsd,grains,Ini.cifPath);
% Give an initial guess for the OR: Kurdjumov-Sachs ...
KS = orientation.KurdjumovSachs(job.csParent,job.csChild);
job.p2c = KS;
% ... and refine it based on the fit with boundary misorientations
job.calcParent2Child;
% Let us check the disorientation and compare it with K-S and N-W
% (The disorientation is the misfit between the grain misorientations
% and the misorientation of the OR)
NW = orientation.NishiyamaWassermann(job.csParent,job.csChild);
plotHist_OR_misfit(job,[KS,NW],'legend',{'K-S OR','N-W OR'});
% Display information about the OR
ORinfo(job.p2c);
% - There are 24 martensitic variants
% - And a ~2.1° disorientation exists from the Nishiyama-Wassermann OR
%% Plotting (with ORTools functions)
screenPrint('SegmentStart','Plotting some ORTools maps');
% Use some of the ORTools functions to visualize the determined OR
% and its relation to the microstructure
% Phase map
plotMap_phases(job,'linewidth',2);
% - There is no retained austenite (gamma)
% Parent and child IPF maps
plotMap_IPF_p2c(job,vector3d.Z,'linewidth',2);
% - It is clear that martensite has formed from multiple prior
% - austenite grains and that some surface scratches led to bad indexing
% Child-child grain boundary misorientation map
plotMap_gB_c2c(job,'linewidth',2);
% - Misorientation angles of ~15-50° are not present within prior
% austenite grains and thus delinitate prior austenite grain
% boundaries
% Plot a map of the OR boundary disorientation, or misfit
plotMap_gB_misfit(job,'linewidth',2, 'maxColor',5);
% - By setting a threshold at 5 degrees, the prior austenite grain
% boundaries are identified by their large misfit with the OR
% Plot a map of the OR boundary probability
plotMap_gB_prob(job,'linewidth',2);
% - the same can be visualized by calculating the probability that a
% boundary belongs to the OR
%% Reconstruct parent microstructure
% - Reconstruct the microstructure with the variant graph based approach
job.calcVariantGraph('threshold',4*degree,'tolerance',3.5*degree);
%job.calcVariantGraph('threshold',2.5*degree,'tolerance',2.5*degree,'mergeSimilar')
job.clusterVariantGraph;
% ... plot the votes (high values show high certainty)
figure; plot(job.grains,job.votes.prob(:,1))
mtexColorbar
% ... and calculate the parent orientations
job.calcParentFromVote('minProb',0.5)
% Plot the reconstructed parent microstructure
plotMap_IPF_p2c(job,vector3d.Z,'linewidth',1,'parent');
%% Remove badly reconstructed clusters
% In order to reconstruct the remaining parent grains, we can calculate the
% votes for surrounding parent grains by the already reconstructed parent
% grains
% compute the votes
job.calcGBVotes('p2c','reconsiderAll')
% assign parent orientations according to the votes
job.calcParentFromVote
% plot the result
plot(job.parentGrains,job.parentGrains.meanOrientation)
%% Clean reconstructed grains
% Now clean the grains by:
% - merging grains with similar orientation
job.mergeSimilar('threshold',7.5*degree);
% - merging small inclusions
job.mergeInclusions('maxSize',150);
% This is the cleaned reconstructed parent microstructure
plotMap_IPF_p2c(job,vector3d.Z,'linewidth',2,'parent');
%% Variant analysis
% Now that both the alpha and the associated prior gamma orientations are
% available, variant analysis can be conducted.
% Plot the possible variants in a pole figure
plotPDF_variants(job);
% Then calculate the variant IDs of all alpha grains ...
job.calcVariants;
% ... and plot them
plotMap_variants(job,'grains','linewidth',2); %Grain data
plotMap_variants(job,'linewidth',2); %EBSD data
plotMap_variants(job,'grains','bc','linewidth',2); %Plot as overlay on BC data
% We see that each child grain contains several variants on EBSD level
% For analyzing variant pairing, we need the variants on the EBSD level
% to be reconstructed as grains
%% Variant pairing (block boundary) analysis
[~,maxGrainId] = max(job.grains.area);
[newGrains,newEBSD] = computeVariantGrains(job);
% Compare variant indexing for old and new grains
figure; % Old child grains
plot(grains(job.csChild),grains(job.csChild).meanOrientation);
figure; % New child grains
plot(newGrains(job.csChild),newGrains(job.csChild).meanOrientation);
% We see that all the variant detail of the variantIds in the EBSD map are
% absent at the grain level. This allows us to analyze the boundaries
% between variants.
variantBoundaries_map = plotMap_KSvariantPairs(job,'linewidth',1.5);
% We can also analyze and plot the same for individual prior austenite grains.
% We also return the grain object as "PAG" with the variant data stored in
% PAG.prop
[variantBoundaries_PAG, PAG] = plotMap_KSvariantPairs(job,'parentGrainId',maxGrainId,'linewidth',2);
% In theory, one could use the reindexed grains to redo the parent grain
% reconstruction based on these grains. This does however not lead to a
% significantly better reconstruction in the present dataset.
%% Calculate martensite block widths
% ... for a PAG by specifying a gamma grain id
plotMap_blockWidths(job,'parentGrainId',maxGrainId,'linewidth',1.5);
% ... for the entire map (more statistics, but can be slow for large maps)
plotMap_blockWidths(job,'linewidth',1);
%% Display variant information for a PAG by specifying a gamma grain id
plotStack(job,'parentGrainId',maxGrainId,'linewidth',1.5);
plotStack(job,'grains','noFrame','parentGrainId',maxGrainId,'linewidth',1.5);
%% Save images
saveImage(Ini.imagePath);
%% Display variant information for a PAG by interactively clicking on a gamma grain
grainClick(job,'noScalebar','noFrame'); %Based on EBSD data
%% Do the same at the grain level
grainClick(job,'grains','noFrame'); %Based on grain data
%% Display variant pairing (block boundary) analysis for a PAG by interactively clicking on a gamma grain
grainClick(job,'variantPairs','noFrame','linewidth',2);
%% Calculate martensite block widths for a PAG by interactively clicking on a gamma grain
grainClick(job,'blockWidth','noFrame','linewidth',2);
%% Refine gamma twins for a PAG by interactively clicking on a gamma grain
grainClick(job,'parentTwins');