Applying the same Euler rotation to individual grains of different symmetries
2 ビュー (過去 30 日間)
古いコメントを表示
One of the master’s students in my group approached me with a coding problem, which I've subsequently got stuck on! Their overall objective is to explore parent-daughter relationships within metamorphic rocks. They wanted a generalised script which would rotate all grains of the 'parent' phase, aka 'Phase A', into a single orientation, and then rotate the neighbouring daughter grains, aka "Phase B" by the same rotation. In this way they could look at a pole figure of Phase A and of Phase B and compare to see if any topotaxy exists.
I’ve got into an issue when it comes to the rotation of the daughter phase. In the below script I have isolated unique parent-daughter grain pairs, worked out a Euler to rotate each grain of PhaseA into the most common orientation of A and then tried to apply this Euler rotation to PhaseB. However, at this point I realised that a major flaw in my plan was the different crystal symmetries of the two systems. Any suggestions about how to apply a Euler rotation to a different phase would be much appreciated, otherwise its back to the drawing board.
% Script below
% Note there are TWO USER INPUT sections, scroll down for second
close all; clear all
% USER INPUTS
PhaseA = 'Staurolite'; % Parent Phase
PhaseB = 'Chloritoid 2M'; % Daughter Phase
halfwidth = 7.5; % Degree
gB = 10; % Grain boundary misorientation (degree)
%% Import Data
% Specify Crystal and Specimen Symmetries
CS = {...
'notIndexed',...
crystalSymmetry('12/m1', [5.2 9.1 14], [90,97.03,90]*degree, 'X||a*', 'Y||b*', 'Z||c', 'mineral', 'Chlorite', 'color', [0.53 0.81 0.98]),...
crystalSymmetry('12/m1', [9.5 5.5 18], [90,101.738,90]*degree, 'X||a*', 'Y||b*', 'Z||c', 'mineral', 'Chloritoid 2M', 'color', [0.56 0.74 0.56]),...
crystalSymmetry('-3m1', [4.9 4.9 5.5], 'X||a*', 'Y||b', 'Z||c*', 'mineral', 'Quartz-new', 'color', [0.85 0.65 0.13]),...
crystalSymmetry('12/m1', [7.9 17 5.7], [90,90.39,90]*degree, 'X||a*', 'Y||b*', 'Z||c', 'mineral', 'Staurolite', 'color', [0.94 0.5 0.5]),...
crystalSymmetry('4/m', [12 12 12], 'mineral', 'Garnet', 'color', [0 0 0.55]),...
crystalSymmetry('12/m1', [5.2 9 20], [90,95.73,90]*degree, 'X||a*', 'Y||b*', 'Z||c', 'mineral', 'Muscovite - 2M1', 'color', [0 0.39 0]),...
crystalSymmetry('-3', [5.1 5.1 14], 'X||a*', 'Y||b', 'Z||c*', 'mineral', 'Ilmenite', 'color', [0.55 0 0]),...
crystalSymmetry('-1', [8.2 13 14], [93.134,115.885,91.236]*degree, 'X||a*', 'Z||c', 'mineral', 'Anorthite', 'color', [0.58 0 0.83])};
% plotting convention
setMTEXpref('xAxisDirection','east');
setMTEXpref('zAxisDirection','intoPlane');
%% Specify File Names
% path to files
pname = 'C:\Users\relli\Dropbox\_HelpingFriends\Finn Vanderkam';
% which files to be imported
fname = [pname '\ISUA_2_Specimen1_Area1_Montaged3.ctf'];
%% Import the Data
% create an EBSD variable containing the data
ebsd = EBSD.load(fname,CS,'interface','ctf',...
'convertEuler2SpatialReferenceFrame');
%% clean the data
BAD_MAD = ebsd.mad > 1;
ebsd(BAD_MAD) = [];
[grains,ebsd.grainId,ebsd.mis2mean] = calcGrains(ebsd,'angle',gB*degree, 'boundary', 'tight');
ebsd(grains(grains.grainSize<=3)) = [];
ebsd = fill(ebsd);
[grains,ebsd.grainId,ebsd.mis2mean] = calcGrains(ebsd,'angle',gB*degree, 'boundary', 'tight');
%% USER INPUTS
% Directions and planes of interest
h_ADir = Miller({1,0,0},{0,1,0},{0,0,1},ebsd(PhaseA).CS,'direction'); % Directions of interest, Phase A
h_APlan = Miller({1,0,0},{0,1,0},{0,0,1},ebsd(PhaseA).CS,'plane'); % Planes of interest, Phase A
h_BDir = Miller({1,0,0},{0,1,0},{0,0,1},ebsd(PhaseB).CS,'direction'); % Direction of interest, Phase B
h_BPlan = Miller({1,0,0},{0,1,0},{0,0,1},ebsd(PhaseB).CS,'plane'); % Planes of interest, Phase B
%% Find a reference orientation for the Parent mineral
% A potnentially better way of doing this would be to create an
% idealise orientation with axis aligned at least in part with the
% reference framework - not sure how
ori_PA = grains(PhaseA).meanOrientation;
PAODF = calcDensity(ori_PA, 'halfwidth', halfwidth*degree); % Calculate an orientation density function.
[modes, values] = calcModes(PAODF,'numLocal', 1); % Find the most common orienation in the parent grain
%% Identify all grains that have the desired phase boundary
grain_id = grains.boundary(PhaseA, PhaseB).grainId;
% Plot grain boundaries - potentially remove this as could be too messy
figure
plot(grains(grain_id))
% Find unique boundary pairs
grain_id_unique = unique(grain_id, 'rows');
%% Look at the orientation of parent/daughters
sub = grains(grain_id_unique);
Ori_sub_PA_pre = sub(PhaseA).meanOrientation;
Ori_sub_PB_pre = sub(PhaseB).meanOrientation;
% Plotting the figures
figure,
plotPDF(Ori_sub_PA_pre, h_ADir, 'anitpodal', 'lower')
hold on;
figure,
plotPDF(Ori_sub_PA_pre, h_APlan, 'anitpodal', 'lower')
hold on;
figure,
plotPDF(Ori_sub_PB_pre, h_BDir, 'anitpodal', 'lower')
hold on;
figure,
plotPDF(Ori_sub_PB_pre, h_BPlan, 'anitpodal', 'lower')
hold on;
%% For each grain calulate the rotation between the 'mode' orientation in
% Phase A. Apply this rotation to both Phase A (as a check) and Phase B.
for a = 1:1:length(grain_id_unique)
if grains(grain_id_unique(a,1)).mineral == PhaseA
temp = inv(grains(grain_id_unique(a,1)).meanOrientation) * modes(1);
% Rotate Phase A grain by Temp to check a single orientation
grains(grain_id_unique(a,1)).meanOrientation = grains(grain_id_unique(a,1)).meanOrientation * temp;
% Apply same rotation to Phase B
%grains(grain_id_unique(a,2)).meanOrientation = grains(grain_id_unique(a,2)).meanOrientation * temp; % <-- where the problem occurs
elseif grains(grain_id_unique(a,2)).mineral == PhaseA
temp = inv(grains(grain_id_unique(a,2)).meanOrientation) * modes(1);
% Rotate Phase A grain by Temp to check a single orientation
grains(grain_id_unique(a,2)).meanOrientation = grains(grain_id_unique(a,2)).meanOrientation * temp;
% Apply same rotation to Phase B
%grains(grain_id_unique(a,1)).meanOrientation = grains(grain_id_unique(a,1)).meanOrientation * temp; <-- % <-- where the problem occurs
end
end
%%
sub_post = grains(grain_id_unique);
Ori_sub_PA_post = sub_post(PhaseA).meanOrientation;
%Ori_sub_PB_post = sub_post(PhaseB).meanOrientation;
Sub_PA_ODF = calcDensity(Ori_sub_PA_post, 'halfwidth', halfwidth*degree); % Calculate an orientation density function.
%Sub_PB_ODF = calcDensity(Ori_sub_PB_post, 'halfwidth', halfwidth*degree);
%% Plotting the figures
% Plotting the figures
figure,
plotPDF(Ori_sub_PA_post, h_ADir, 'anitpodal', 'lower')
hold on;
figure,
plotPDF(Ori_sub_PA_post, h_APlan, 'anitpodal', 'lower')
hold on;
% figure,
% plotPDF(Ori_sub_PB_post, h_BDir, 'anitpodal', 'lower')
% hold on;
%
%
% figure,
% plotPDF(Ori_sub_PB_post, h_BPlan, 'anitpodal', 'lower')
% hold on;
0 件のコメント
回答 (1 件)
UDAYA PEDDIRAJU
2024 年 3 月 14 日
Hi Rellie,
To address the challenge of applying the same Euler rotation to grains of different symmetries (Phase A and Phase B), it's essential to consider the crystallographic symmetries of both phases. The core issue arises because the same geometric rotation can result in different crystal orientations depending on the underlying symmetry of the crystal structure. Here's a concise strategy to tackle this problem:
1. Calculate the Rotation for Phase A: You've correctly calculated the rotation (`temp`) needed to align a grain of Phase A to a common orientation. This is done by finding the inverse of the grain's mean orientation and multiplying it by the mode orientation.
2. Apply Rotation to Phase A for Verification: Applying the rotation to Phase A as a check is a good practice and helps ensure that the rotation calculation is correct.
3. Adjust Rotation Application for Phase B: The challenge comes when applying the same rotation to Phase B, which has a different crystal symmetry. Directly applying the rotation calculated for Phase A to Phase B without considering the symmetry differences can lead to incorrect orientations.
4. Solution - Symmetry Consideration: To correctly apply the rotation to Phase B, you need to:
- Convert the Rotation to a Universal Frame: Convert the rotation calculated for Phase A into a representation that doesn't depend on the crystal symmetry (e.g., a rotation matrix or a quaternion in the sample reference frame).
- Apply the Rotation to Phase B: Apply this rotation to Phase B's grains. Since the rotation is now in a universal frame, it should correctly rotate the grains of Phase B despite the difference in crystal symmetry.
- Consider Symmetry Equivalents: After applying the rotation, consider the symmetry equivalents for Phase B to ensure that the rotated orientation is correctly interpreted within Phase B's crystal symmetry.
5. Re-evaluate Orientations: After applying the rotations, re-evaluate the orientations of both Phase A and Phase B to verify that the operation has been successful and the orientations are now comparable in the context of their respective symmetries.
6. Code Adjustment: The critical adjustment in your script involves converting the rotation to a universal frame and carefully applying it to Phase B, considering its symmetry. This might require additional functions or steps depending on the software you're using (e.g., MTEX in MATLAB).
By following this strategy, you should be able to apply the same conceptual rotation to grains of different symmetries and compare their orientations meaningfully.
参考
カテゴリ
Help Center および File Exchange で Coordinate Transformations and Trajectories についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!