-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathCalc_bh_From_sBS.m
147 lines (102 loc) · 3.26 KB
/
Calc_bh_From_sBS.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
function [b,h,GF]=Calc_bh_From_sBS(CtrlVar,MUA,s,B,S,rho,rhow)
narginchk(7,7)
nargoutchk(1,3)
%%
%
% *Calculates b and h from s, B, S and rho and rhow.*
%
%
% Sets
%
% $b=B$
%
% over grounded areas, and
%
% $b=(\rho s-\rho_w S)/(\rho-\rho_w)$
%
% over floating areas.
%
% On return $s=b+h$.
%
% Note: This will not conserve thickness.
%
% Because the floating mask depends on b through h, this is a non-linear
% problem.
%
% Solved using the NR method. Usually only one single NR iteration is
% required.
%
%
%
% MUA : also optional and not currently used.
%
% Example:
%
% b=Calc_bh_From_sBS(CtrlVar,[],s,B,S,rho,rhow)
%
%
%%
% get a rough and a reasonable initial estimate for b
% The lower surface b is
%
%
% b=max( B , (rhow S - rho s)/(rhow-rho) )
% where
%
% h_f = rhow (S-B) / rho
%
% b=s-h_f
hf=rhow*(S-B)./rho ;
b0 = max(B,(rho.*s-rhow.*S)./(rho-rhow)) ; % a rough initial estimate for b
b=b0;
h=s-b;
% iteration
ItMax=30 ; tol=1000*eps ; J=Inf ; I=0 ;
JVector=zeros(ItMax,1)+NaN ;
while I < ItMax && J > tol
I=I+1;
G = HeavisideApprox(CtrlVar.kH,h-hf,CtrlVar.Hh0); % 1
dGdb=-DiracDelta(CtrlVar.kH,h-hf,CtrlVar.Hh0) ;
F0= b - G.*B - (1-G).*(rho.*s-rhow.*S)./(rho-rhow) ;
dFdb = 1 - dGdb.* (B - (rho.*s-rhow.*S)./(rho-rhow)) ;
db= -F0./dFdb ;
b=b+db ;
h=s-b ;
F1 = b - G.*B - (1-G).*(rho.*s-rhow.*S)./(rho-rhow) ;
JLast=J ;
J=sum(F1.^2)/2 ;
if CtrlVar.MapOldToNew.Test
fprintf('\t %i : \t %g \t %g \t %g \n ',I,max(abs(db)),J,J/JLast)
end
JVector(I)=J ;
if J< tol
break
end
end
GF.node = HeavisideApprox(CtrlVar.kH,h-hf,CtrlVar.Hh0);
if CtrlVar.MapOldToNew.Test
FindOrCreateFigure("Testing Calc_bh_From_sBs") ;
semilogy(1:30,JVector,'-or')
xlabel("iterations",Interpreter="latex")
ylabel("Cost function, $J$",Interpreter="latex")
title("Calculating $b$ and $h$ from $s$, $S$, and $B$",Interpreter="latex")
title(sprintf("Calculating $b$ and $h$ from $s$, $S$, and $B$ by minimizing \n $J=\\int (b-\\mathcal{G}B - (1-\\mathcal{G}) (\\rho s -\\rho_o S/(\\rho-\\rho_o))\\, \\mathrm{d}x \\, \\mathrm{d}y$\n with respect to $b$ "),Interpreter="latex")
% f=gcf ; exportgraphics(f,'Calc_bh_from_sBS_Example.pdf')
end
if I==ItMax % if the NR iteration above, taking a blind NR step does not work, just
% hand this over the matlab opt.
% Why not do so right away? Because the above options is based on
% my experience always faster if it converges (fminunc is very reluctant to take
% large steps, and apparantly does not take a full NR step...?!)
warning("Calc_bh_From_SBS:NoConvergence","Calc_bh_from_sBS did not converge! \n")
options = optimoptions('fminunc','Algorithm','trust-region',...
'SpecifyObjectiveGradient',true,'HessianFcn','objective',...
'SubproblemAlgorithm','factorization','StepTolerance',1e-10,...
'Display','iter');
func=@(b) bFunc(b,CtrlVar,s,B,S,rho,rhow) ;
b = fminunc(func,b0,options) ;
h=s-b;
GF.node = HeavisideApprox(CtrlVar.kH,h-hf,CtrlVar.Hh0);
end
%%
end