Forked from
Klaus Böhnlein / dune-microstructure
569 commits behind, 206 commits ahead of the upstream repository.
-
Klaus Böhnlein authoredKlaus Böhnlein authored
classifyMIN.m 7.98 KiB
function [A, angle, type, kappa] = classifyMIN (mu_1,rho_1,a,b,t,set_mu_gamma,print_output)
% returns
% A : Matrix of basis coefficients [a1,a2,a3]
%
% type :
% Type of minimizer 1 = (I) , 2 = (II) , 3 = (III) , 4 = (IV)
%
type = 0; % either 1,2,3,4
mu_h = @(b,t) mu_1.*(b./(t+(1-t).*b)); % harmonic mean
mu_bar = @(b,t) mu_1.*((1-t)+t.*b); % mu_bar
if (set_mu_gamma == 'q1')
mu_gamma = @(b,t) mu_h(b,t);
end
if (set_mu_gamma == 'q2')
mu_gamma = @(b,t) mu_bar(b,t);
end
if (set_mu_gamma == 'm')
mu_gamma = @(b,t) 0.5*(mu_h(b,t) + mu_bar(b,t));
end
% q1 q2 q3..
q1 = mu_h(b,t);
q2 = mu_bar(b,t);
q3 = mu_gamma(b,t);
% values for q1,q2,q3 should be positiv
% assert((q1 > 0 ) & (q2 > 0 ) & (q3 > 0), 'At least one of q1,q2 or q3 is not positive' )
% Compute components of B_eff (old)
% b1 = (mu_1*rho_1/4).*(b./(t+(1-t).*b)).*(1-t.*(1+a));
% b2 = mu_1.*(rho_1/8).*(1-t.*(1+b.*a));
%TEST (new)
b1 = (3*rho_1/2).*b.*(1-t.*(1+a));
b2 = (3*rho_1./(4.*((1-t)+t.*b))).*(1-t.*(1+b.*a));
% H = [q1 q3; q3 q2];
%check condition of H first
% fprintf('condition number of Matrix H: %d \n', cond(H));
CaseCount = 0; %check if more than one case ever happens
epsilon = eps;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% PARABOLIC CASE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% if abs(det(A)) < epsilon * min(abs(det(A)),0)
if abs(q1*q2-q3^2) < epsilon
fprintf('determinant equal zero (parabolic case)')
fprintf('SHOULD NOT HAPPEN')
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ELLIPTIC CASE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (q1*q2-q3^2 > epsilon)
% fprintf('determinant greater than zero (elliptic case)');
% a1_star = (q2(b,t).*q1(b,t).*b1(a,b,t) - q3(b,t).*q2(b,t).*b2(a,b,t))./(q1(b,t).*q2(b,t)-q3(b,t).^2);
% a2_star = (q1(b,t).*q2(b,t).*b2(a,b,t) - q3(b,t).*q1(b,t).*b1(a,b,t))./(q1(b,t).*q2(b,t)-q3(b,t).^2);
a1_star = (q2.*q1.*b1 - q3.*q2.*b2)./(q1.*q2-q3.^2);
a2_star = (q1.*q2.*b2 - q3.*q1.*b1)./(q1.*q2-q3.^2);
prod = a1_star*a2_star;
if(prod > epsilon) % (E1) inside Lamba %
% (a1_star,a2_star) is unique minimizer lies inside Lambda
% therefore Minimizer not aligned with axes
% fprintf('\n elliptic-case: (E1)');
a1 = a1_star;
a2 = a2_star;
type = 3;
CaseCount = CaseCount + 1;
end
% Make distinction between boundary & outside (prod < 0 )
if(abs(prod) < epsilon) % (E2) on boundary of Lambda
% fprintf('\n elliptic-case: (E2)');
% Uniqueness of gloal minimizer if lies on boundary if prod = 0
% ----- %
% global minimizer lies on the boundary of Lambda depending on
% condition:
if (q2*b2^2 < q1*b1^2) % global Minimizer given by (b1,0)
a1 = b1;
a2 = 0*b1;
type = 1; % Minimizer aligned with x1-axis
CaseCount = CaseCount + 1;
end
if (q2*b2^2 > q1*b1^2)% global Minimizer given by (0,b2)
a1 = 0*b1;
a2 = b2;
type = 2; % Minimizer aligned with x2-axis
CaseCount = CaseCount + 1;
end
if abs(q1*b1^2-q2*b2^2) < epsilon * min(q2*b2^2,q1*b1^2) % q1b1^2 = q2b2^2
% two Minimizers ..pick one
a1 = b1;
a2 = 0*b1;
type = 4;
CaseCount = CaseCount + 1;
end
end
if((prod) < -1*epsilon) %Outside of Lambda
if (q2*b2^2 < q1*b1^2) % global Minimizer given by (b1,0)
a1 = b1;
a2 = 0*b1;
type = 1; % Minimizer aligned with x1-axis
CaseCount = CaseCount + 1;
end
if (q2*b2^2 > q1*b1^2)% global Minimizer given by (0,b2)
a1 = 0*b1;
a2 = b2;
type = 2; % Minimizer aligned with x2-axis
CaseCount = CaseCount + 1;
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% HYPERBOLIC CASE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (q1*q2-q3^2 < -1*epsilon)
% fprintf('determinant less than zero (hyperbolic case)');
if (q2*b2^2 < q1*b1^2) % global Minimizer given by (b1,0)
a1 = b1;
a2 = 0*b1;
type = 1; % Minimizer aligned with x1-axis
CaseCount = CaseCount + 1;
end
if (q2*b2^2 > q1*b1^2)% global Minimizer given by (0,b2)
a1 = 0*b1;
a2 = b2;
type = 2; % Minimizer aligned with x2-axis
CaseCount = CaseCount + 1;
end
if abs(q1*b1^2-q2*b2^2) < epsilon * min(q2*b2^2,q1*b1^2) % q1b1^2 = q2b2^2
% two Minimizers ..pick one
a1 = b1;
a2 = 0*b1;
type = 4;
CaseCount = CaseCount + 1;
end
% CAN NOT BE TYPE 3!!
end
% Compute a3 from a1 % a2
a3 = sqrt(2*a1*a2); % WRONG ?
% compute angle between [sqrt(a1) , sqrt(a2)] and e1:
% angle = atan2(sqrt(a2),sqrt(a1));
v = [sqrt(a1), sqrt(a2)];
e1 = [1 0];
if (type == 3 )
% angle = atan2(a2,a1);
% angle = acos(v*e1/(sqrt(a1+a2)));
else
angle = 0;
end
% angle = atan2(norm(cross(a,b)), dot(a,b))
% Try to compute angle of Matrices
E1 = [1 0;0 0 ];
% V = [a1 sqrt(a1*a2)/sqrt(2); sqrt(a1*a2)/sqrt(2) a2]; % This ?? NO
V = [a1 sqrt(a1*a2); sqrt(a1*a2) a2]; % This!
% CHECK
% U = trace(V'*E1)/(sqrt(trace(V'*V))*sqrt(trace(E1'*E1)))
% if abs(U) > 1
% fprintf('value greater 1')
% end
% angle = atan2(sqrt(abs(a2)), sqrt(abs(a1))); % does this make sense?
% angle = acos(trace(V'*E1)/(sqrt(trace(V'*V))*sqrt(trace(E1'*E1)))); %angle in radians
% angle = acos(trace(V'*E1)/(sqrt(trace(V'*V))*sqrt(trace(E1'*E1))))/pi * 180; % angle in degrees
% CHECK does case (0,-b) ever happen? Yes
% if (q2*b2^2 > q1*b1^2 && b2 < 0)
% fprintf('point lies on negative half of y-axis');
% end
% CHECK if Minimizer ever lies inside lambda ... YES
% if (a1 ~= 0 && a2 ~= 0)
% fprintf('minimizer lies inside lambda');
% end
% Alternative atan2d(y,x): returns angle in degrees
% CHECK
e = [sqrt(a1), sqrt(a2)]; % Might be complex...
norm = sqrt(a1+a2); % Might be complex...
e = e./norm;
angle = atan2(e(2), e(1)); %TEST
if (imag(e(1))~= 0 || imag(e(2))~=0)
fprintf('complex vector e');
end
% if (imag(norm)~=0)
% fprintf('complex norm'); % happens a lot ..
% end
% do it this way to avoid complex numbers:
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));
if (imag(e(1))~= 0 || imag(e(2))~=0)
fprintf('complex vector e');
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% TEST -------------------
% the magnitude kappa of the vector does not matter for the angle ..
% In order to also get negative angles just use:
% atan2(a2,a1)
% angle = atan2(a2,a1); %% FEHLER : muss [sqrt(a1) sqrt(a2)] betrachten..
% angle = atan2(sqrt(a2),sqrt(a1)); % Inputs must be real...
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% angle2 = acos(e(1)/(sqrt(e(1)^2 + e(2)^2) ));
% if angle ~= angle2
% interesting = 1;
% end
% if (angle ~= 0 | angle ~= 3.1416)
% fprintf('angle not zero or pi.. plot type')
% type
% angle
% end
%compute Kappa?
% fprintf('Output Kappa:')
% k = sqrt(abs(a1) + abs(a2)); % ?
kappa = (a1 + a2);
% e = [sqrt(a1), sqrt(a2)];
% norm = sqrt((a1+a2));
% e = e./norm;
% K.*(e'*e);
if (CaseCount > 1)
fprintf('=============================== ERROR========================================= \n')
fprintf('Error: More than one Case happened!')
end
% Coefficients of minimizer
if(print_output)
fprintf(' \n ')
fprintf('=============================== OUTPUT ========================================= \n')
fprintf('Minimizer is of Type: %d \n' , type);
fprintf('Coefficients a1,a2,a3 given by : %d, %d, %d \n', a1, a2, a3);
fprintf('================================================================================ \n')
end
A = [a1, a2, a3];
end