Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • s7603593/dune-microstructure
  • s7603593/dune-microstructure-backup
2 results
Show changes
Showing
with 404 additions and 0 deletions
Matlab-Programs/resources/previewImage.png

18.8 KiB

File added
Matlab-Programs/resources/screenshot.png

17 KiB

function [G, angle, Type, kappa] = symMinimization(print_Input,print_statPoint,print_Output,make_FunctionPlot, InputPath) %(Q_hom,B_eff)
syms v1 v2 q1 q2 q3 q12 b1 b2 b3
% -------- Options ----------
% % print_Input = false; %effective quantities
% print_Input = true;
% % print_statPoint = false;
% print_statPoint = true;
% print_Minimizer = true;
% % make_FunctionPlot = false;
% make_FunctionPlot = true;
print_Uniqueness = false;
check_StationaryPoints = false; % could be added to Input-Parameters..
compare_with_Classification = false; %maybe added later ---
%fprintf('Functions to be minimized:')
f_plus(v1,v2,q1,q2,q3,q12,b1,b2,b3) = q1*v1^4 + q2*v2^4+2*q3*v1^2*v2^2-2*(q1*b1*v1^2+ q2*b2*v2^2+sqrt(2)*q3*b3*v1*v2)...
+ q12*(v1^2*v2^2-b2*v1^2-b1*v2^2+b1*b2);
f_minus(v1,v2,q1,q2,q3,q12,b1,b2,b3) = q1*v1^4 + q2*v2^4+2*q3*v1^2*v2^2+2*(q1*b1*v1^2+ q2*b2*v2^2+sqrt(2)*q3*b3*v1*v2)...
+ q12*(v1^2*v2^2+b2*v1^2+b1*v2^2+b1*b2);
% ---- Fix parameters
% Epsilon used:
epsilon = 1e-8;
if ~exist('InputPath','var')
% third parameter does not exist, so default it to something
absPath = "/home/klaus/Desktop/DUNE/dune-microstructure/outputs";
end
% 1. Import effective quantities from CellSolver-Code:
%read as sparse Matrix...
try %absolutePath
Qmat = spconvert(load(absPath + '' + "/QMatrix.txt"));
Bmat = spconvert(load(absPath + '' + "/BMatrix.txt"));
% fprintf('Use absolute Path')
catch ME % use relativePath
Qmat = spconvert(load('../outputs/QMatrix.txt'));
Bmat = spconvert(load('../outputs/BMatrix.txt'));
% fprintf('Use relative Path')
end
%convert to full matrix...
Qmat = full(Qmat);
Bmat = full(Bmat);
% --- TODO CHECK: assert if Q is orthotropic ??? check ifq13=q31=q23=q32= 0 ?
if print_Input
fprintf('effective quadratic form:')
Qmat
fprintf('effective prestrain')
Bmat
% check if Q is (close to..) symmetric
% könnte Anti-symmetric part berechnen und schauen dass dieser klein?
% Test: issymmetric(Qmat) does not work for float matrices?
% symmetric part 0.5*(Qmat+Qmat')
% anti-symmetric part 0.5*(Qmat-Qmat')
if norm(0.5*(Qmat-Qmat'),'fro') < 1e-8
fprintf('Qmat (close to) symmetric \n')
norm(0.5*(Qmat-Qmat'),'fro') % TEST
else
fprintf('Qmat not symmetric \n')
end
% Check if B_eff is diagonal this is equivalent to b3 == 0
if abs(Bmat(3)) < 1e-8
fprintf('B_eff is diagonal (b3 == 0) \n')
else
fprintf('B_eff is NOT diagonal (b3 != 0) \n')
end
end
% CAST VALUES TO SYM FIRST? This is done anyway..
% % Substitute effective quantitites
f_plus = subs(f_plus,{q1, q2, q3, q12, b1, b2, b3}, {Qmat(1,1), Qmat(2,2), Qmat(3,3), Qmat(1,2), ...
Bmat(1), Bmat(2), Bmat(3)});
f_minus = subs(f_minus,{q1, q2, q3, q12, b1, b2, b3}, {Qmat(1,1), Qmat(2,2), Qmat(3,3), Qmat(1,2), ...
Bmat(1), Bmat(2), Bmat(3)});
% Compute the Gradients
df_plusx = diff(f_plus,v1);
df_plusy = diff(f_plus,v2);
df_minusx = diff(f_minus,v1);
df_minusy = diff(f_minus,v2);
% Setup Equations Grad(f) = 0
eq1 = df_plusx == 0;
eq2 = df_plusy == 0;
eqns_plus = [eq1, eq2];
eq3 = df_minusx == 0;
eq4 = df_minusy == 0;
eqns_minus = [eq3, eq4];
% ------- Symbolically Solve Equations:
% More robust (works even for values b_3 ~ 1e-08 ):
S_plus = solve(eqns_plus,v1,v2,'MaxDegree' , 5);
S_minus = solve(eqns_minus,v1,v2,'MaxDegree' , 5);
A_plus = S_plus.v1;
B_plus = S_plus.v2;
A_minus = S_minus.v1;
B_minus = S_minus.v2;
if check_StationaryPoints
%---------- TEST if Grad(f) = 0 ---------------------
fprintf('Testing equation grad(f) = 0 with stationary points')
for i = 1:size(A_plus,1)
fprintf('Testing %d.point (f_plus): ',i )
[ double(subs(subs(df_plusx,v1,A_plus(i)),v2,B_plus(i))), double(subs(subs(df_plusy,v1,A_plus(i)),v2,B_plus(i))) ]
end
for i = 1:size(A_minus,1)
fprintf('Testing %d.point (f_minus): ',i )
[double(subs(subs(df_minusx,v1,A_minus(i)),v2,B_minus(i))), double(subs(subs(df_minusy,v1,A_minus(i)),v2,B_minus(i)))]
end
% ------------------------------------
end
% --- Extract only Real-Solutions
% fprintf('real stationary points of f_plus:')
tmp1 = A_plus(imag(double(A_plus))==0 & imag(double(B_plus)) == 0);
tmp2 = B_plus(imag(double(A_plus))==0 & imag(double(B_plus)) == 0);
A_plus = tmp1;
B_plus = tmp2;
SP_plus = [A_plus,B_plus];
% fprintf('real stationary points of f_minus:')
tmp1 = A_minus(imag(double(A_minus))==0 & imag(double(B_minus)) == 0);
tmp2 = B_minus(imag(double(A_minus))==0 & imag(double(B_minus)) == 0);
A_minus = tmp1;
B_minus = tmp2;
SP_minus = [A_minus,B_minus];
% TODO one should use f_plus.subs(A_plus..) to compute function value symbolically?
% in the end only the stationaryPoints are used.. should be ok to compare function values numerically
% Determine global Minimizer from stationary points:
% fprintf('function values at stationary points (f_plus):')
T_plus = arrayfun(@(v1,v2) double(f_plus(v1,v2,q1,q2,q3,q12,b1,b2,b3)),A_plus,B_plus,'UniformOutput', false);
T_plus = cell2mat(T_plus);
%Test: use Substitution
% subs(f_plus,{v1, v2}, {A_plus,B_plus})
% fprintf('function values at stationary points (f_minus):')
T_minus = arrayfun(@(v1,v2) double(f_minus(v1,v2,q1,q2,q3,q12,b1,b2,b3)),A_minus,B_minus,'UniformOutput', false);
T_minus = cell2mat(T_minus);
%Test: use Substitution
% T_minus = subs(f_minus,{v1, v2}, {A_minus,B_minus})
% double(T_minus)
if print_statPoint
fprintf('real stationary points of f_plus: ')
% SP_Plus %alternative: output as symbolic (can be unwieldy)
double(SP_plus)
fprintf('real stationary points of f_minus:')
% SP_Minus %alternative: output as symbolic (can be unwieldy)
double(SP_minus)
fprintf('function values at stationary points (f_plus):')
T_plus
fprintf('function values at stationary points (f_minus):')
T_minus
end
% --- Find Stationary Point(s) with minimum Value
[Min_plus,MinIdx_plus] = min(T_plus, [], 'all', 'linear'); %find one min...
[Min_minus,MinIdx_minus] = min(T_minus, [], 'all', 'linear');
% [Min_minus,MinIdx_minus] = min(T_minus) % works with symbolic too
% Compare Minimizers of f_plus & f_minus
[globalMinimizerValue,GlobalIdx] = min([Min_plus,Min_minus]);
if GlobalIdx == 1 %Min_plus % i.e. Global Minimizer is given by f_plus
GlobalMinimizer = SP_plus(MinIdx_plus,:);
sign = 1.0;
elseif GlobalIdx == 2 %Min_minus % i.e. Global Minimizer is given by f_minus
GlobalMinimizer = SP_minus(MinIdx_minus,:);
sign = -1.0;
end
% ------ Check if there are more SP with the same value...
MinIndices_minus = find(T_minus(:) == globalMinimizerValue); % Find indices of All Minima
MinIndices_plus = find(T_plus(:) == globalMinimizerValue); % Find indices of All Minima
numMinSP_minus = size(MinIndices_minus,1); % One of these is always >= 2 due to the structure of the roots..
numMinSP_plus = size(MinIndices_plus,1);
% AllMinSP_minus = SP_minus(MinIndices_minus,:)
% AllMinSP_minus = double(SP_minus(MinIndices_minus,:))
% AllMin = T_minus(MinIndices) %bereits klar dass diese selben funktionswert haben..
Minimizer = sign*(GlobalMinimizer'*GlobalMinimizer); % global minimizing Matrix G*
MinimizerCount = 1;
% different Stationary Points might correspond to the same minimizing
% Matrix G*... check this:
% Compare only with other StationaryPoints/Minimizers
% remove Index of Minimizer
if GlobalIdx == 1
MinIndices_plus = MinIndices_plus(MinIndices_plus~=MinIdx_plus);
elseif GlobalIdx == 2
MinIndices_minus = MinIndices_minus(MinIndices_minus~=MinIdx_minus);
end
MinIndices = cat(1,MinIndices_plus,MinIndices_minus); %[Minimizers-Indices f_plus, Minimizer-Indices f_minus]
for i = 1:(numMinSP_minus+numMinSP_plus-1) % -1: dont count Minimizer itself..
idx = MinIndices(i);
if i > numMinSP_plus
SP = SP_minus(idx,:);
else
SP = SP_plus(idx,:);
end
% SP_value = T_minus(idx) % not needed?
Matrix = sign*(SP'*SP);
if norm(double(Matrix-Minimizer),'fro') < 1e-8 %check is this sufficient here?
% fprintf('both StationaryPoints correspond to the same(Matrix-)Minimizer')
else
% fprintf('StationaryPoint corresponds to a different (Matrix-)Minimizer')
MinimizerCount = MinimizerCount + 1;
end
end
% ----------------------------------------------------------------------------------------------------------------
% Output Uniqueness of Minimizers:
if print_Uniqueness
if MinimizerCount == 1
fprintf('Unique Minimzier')
elseif MinimizerCount == 2
fprintf('Two Minimziers')
else
fprintf('1-Parameter family of Minimziers')
end
end
% --- determine the angle of the Minimizer
% a1 = Minimizer(1,1)
% a2 = Minimizer(2,2)
a1 = double(Minimizer(1,1));
a2 = double(Minimizer(2,2));
% compute the angle <(e,e_1) where Minimizer = kappa* (e (x) e)
e = [sqrt((a1/(a1+a2))), sqrt((a2/(a1+a2)))]; % always positive under sqrt here .. basically takes absolute value here
angle = atan2(e(2), e(1));
% compute curvature kappa
kappa = (a1 + a2);
% % CHeck off diagonal entries:
% sqrt(a1*a2);
% double(Minimizer);
G = double(Minimizer);
% --- "Classification" / Determine the TYPE of Minimizer by using
% the number of solutions (Uniqueness?)
% the angle (axial- or non-axial Minimizer)
% (Alternative compute det[GlobalMinimizer' e1'] where e1 = [1 0] ?)
% Check Uniqueness -- Options: unique/twoMinimizers/1-ParameterFamily
if MinimizerCount == 1
% fprintf('Unique Minimzier')
% Check if Minimizer is axial or non-axial:
if (abs(angle-pi/2) < 1e-8 || abs(angle) < 1e-8) % axial Minimizer
Type = 3;
else % non-axial Minimizer
Type = 1;
end
elseif MinimizerCount == 2
% fprintf('Two Minimziers')
% Check if Minimizer is axial or non-axial:
if (abs(angle-pi/2) < 1e-8 || abs(angle) < 1e-8) % axial Minimizer
Type = 3;
else % non-axial Minimizer
fprintf('ERROR: Two non-axial Minimizers cannot happen!')
end
else
% fprintf('1-Parameter family of Minimziers')
% Check if Minimizer is axial or non-axial:
if (abs(angle-pi/2) < 1e-8 || abs(angle) < 1e-8) % axial Minimizer
% fprintf('ERROR: axial Minimizers cannot happen for 1-Parameter Family!')
else % non-axial Minimizer
Type = 2;
end
end
% ------------------------------------------------------------------------------------------------------
if print_Output
fprintf(' --------- Output symMinimization --------')
fprintf('Global Minimizer v: (%d,%d) \n', GlobalMinimizer(1),GlobalMinimizer(2) )
fprintf('Global Minimizer Value f(v): %d \n', sym(globalMinimizerValue) ) %cast to symbolic
% fprintf('Global Minimizer Value : %d', globalMinimizerValue )
fprintf('Global Minimizer G: \n' )
G
fprintf("Angle = %d \n", angle)
fprintf("Curvature = %d \n", kappa)
fprintf("Type = %i \n", Type)
fprintf(' --------- -------------------- --------')
end
if make_FunctionPlot
fsurf(@(x,y) f_plus(x,y,q1,q2,q3,q12,b1,b2,b3)) % Plot functions
hold on
plot3(double(A_plus),double(B_plus),T_plus,'g*')
%Plot GlobalMinimizer:
hold on
plot3(double(GlobalMinimizer(1)),double(GlobalMinimizer(2)),globalMinimizerValue, 'o', 'Color','c')
% view(90,0)
% view(2)
figure
fsurf(@(x,y) f_minus(x,y,q1,q2,q3,q12,b1,b2,b3))
hold on
plot3(double(A_minus),double(B_minus),T_minus,'g*')
hold on
plot3(double(GlobalMinimizer(1)), double(GlobalMinimizer(2)),globalMinimizerValue, 'o', 'Color','c')
end
return
% Write symbolic solution to txt-File in Latex format
% fileID = fopen('txt.txt','w');
% fprintf(fileID,'%s' , latex(S_plus.v1));
% fclose(fileID);
syms q1 q2 q3 q12 b1 b2 a1 a2
% eqn1 = q1 * a1 + (q3 + (q12/2)) *a2 == -2*q1*b1 - q12*b2
%
% eqn2 = (q3 + (q12/2)) * a1 + q2 *a2 == -2*q2*b2 - q12*b1
eqn1 = q1 * a1 + (q3 + (q12/2)) *a2 == q1*b1 + (q12*b2/2)
eqn2 = (q3 + (q12/2)) * a1 + q2 *a2 == q2*b2 + (q12*b1/2)
[A,B] = equationsToMatrix([eqn1, eqn2], [a1,a2])
X = linsolve(A,B)
% check special case
fprintf('special case q12 = 0 ')
subs(X,q12,0)
\ No newline at end of file
Colormap: Cool-to-Warm
Representation: Point-Gaussian
Opacity: 0.01
PointSize: 2
Gaussian-radius: 0.0075
Shader-Preset: Plain-Circle
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.