Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
D
dune-microstructure
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Klaus Böhnlein
dune-microstructure
Commits
cf95fe39
Commit
cf95fe39
authored
3 years ago
by
Klaus Böhnlein
Browse files
Options
Downloads
Patches
Plain Diff
Add symMinimization.m to run symbolic Minimization via Python
parent
62cc070c
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
Matlab-Programs/symMinimization.m
+367
-0
367 additions, 0 deletions
Matlab-Programs/symMinimization.m
with
367 additions
and
0 deletions
Matlab-Programs/symMinimization.m
0 → 100644
+
367
−
0
View file @
cf95fe39
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
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 ???
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-10
fprintf
(
'Qmat (close to) symmetric \n'
)
else
fprintf
(
'Qmat not symmetric \n'
)
end
% Check if B_eff is diagonal this is equivalent to b3 == 0
if
abs
(
Bmat
(
3
))
<
1e-10
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.. 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'
)
<
eps
%check is this sufficient here?
% both StationaryPoints correspond to the same
% (Matrix-)Minimizer
else
% 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-9
||
abs
(
angle
)
<
1e-9
)
% 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-9
||
abs
(
angle
)
<
1e-9
)
% 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-9
||
abs
(
angle
)
<
1e-9
)
% 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);
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment