-
Notifications
You must be signed in to change notification settings - Fork 24
/
SiStER_flow_solve.m
118 lines (90 loc) · 3.74 KB
/
SiStER_flow_solve.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
%==========================================================================
% SiStER_flow_solve
% Performs inner solve of linear LS=R system as well as outer, iterative
% solution for non-linear dependence of L (viscosity) on S (vx,vy,P)
% Used to be named "run_Picard_iterations" but name changed by G.Ito 6/21/16
%==========================================================================
if PARAMS.BalanceStickyLayer==1
% BALANCE FLUXES %%% JAO July 16, 2015
% RE-ADJUST BCs SO FLUX OF ROCK AND STICKY AIR MATERIAL ARE CONSERVED
% locate height of sticky layer - rock contact on the sides
bL=interp1(topo_x,topo_y,0);
bR=interp1(topo_x,topo_y,xsize);
utop=BC.right(3)*(bL+bR)/xsize;
ubot=BC.right(3)*(2*ysize-bL-bR)/xsize;
BC.top(3)=utop;
BC.bot(3)=-ubot;
end
ResL2=1;
for pit=1:PARAMS.Npicard_max
if pit==1
ResL2init=ResL2;
end
%% ---------------------------------------------------------------------------------
% Compute visco-elasto-plastic viscosities
%---------------------------------------------------------------------------------
SiStER_VEP_rheology
%---------------------------------------------------------------------------------
% Assemble L and R matrices
%---------------------------------------------------------------------------------
[L, R, Kc, Kb]=SiStER_assemble_L_R(dx,dy,Zs.*etas,Zn.*etan,rho,BC,PARAMS,srhs_xx,srhs_xy); %G.Ito
%---------------------------------------------------------------------------------
% Residual: L and R are from current solution S
%---------------------------------------------------------------------------------
if (exist('S','var'));
Res=L*S-R;
ResL2=norm(Res,2)/norm(R,2);
else
S=L\R; disp('First solve is linearized');
Res=L*S-R;
ResL2=norm(Res,2)/norm(R,2);
end
%---------------------------------------------------------------------------------
% Solve for new solution S using Picard or approximate Newton or a
% combination of the two
%---------------------------------------------------------------------------------
if (pit >= PARAMS.pitswitch);
if pit==PARAMS.pitswitch; disp('switching from Picard to approx. Newton'); end;
beta=1;
S=S-beta.*(L\Res); % approximate Newton update, with L as approximation to Jacobian
it_type='Newton: ';
else
S=L\R; % Picard update
it_type='Picard: ';
end
[p, vx, vy]=SiStER_reshape_solver_output(S,Kc,Nx,Ny);
%% ASSESS CONVERGENCE
if(ResL2<PARAMS.conv_crit_ResL2 && pit >= PARAMS.Npicard_min)
disp(['Final residual = ' num2str(ResL2)])
disp([num2str(pit) ' iterations converged: L2 norm of residual dropped below ' num2str( PARAMS.conv_crit_ResL2)]);
break;
elseif (pit==PARAMS.Npicard_max);
disp(['Final residual = ' num2str(ResL2)])
disp(['WARNING! ' num2str(pit) ' Picard / approx. Newton iterations failed to converge within tolerance of ' num2str( PARAMS.conv_crit_ResL2)]);
end
%end
%% get strain rate on nodes current solution
[EXX,EXY]=SiStER_get_strain_rate(vx,vy,dx,dy,BC);
EXY_n=SiStER_interp_shear_to_normal_nodes(EXY);
EXX_s=SiStER_interp_normal_to_shear_nodes(EXX,dx,dy);
epsII_n=sqrt(EXX.^2+EXY_n.^2);
epsII_s=sqrt(EXX_s.^2+EXY.^2);
% helpful to visualize convergence
% figure(1)
% pcolor(X,Y,log10(etas))
% set(gca,'ydir','reverse')
% axis equal
% caxis([18 25])
% colorbar
% title(num2str(pit))
% pause(.001)
% RESIDUAL FOR INDIVIDUAL VARIABLES
% [pres, vxres, vyres]=SiStER_reshape_solver_output(Res,Kc,Nx,Ny);
% figure(1)
% pcolor(X,Y,vxres)
% set(gca,'ydir','reverse')
% axis equal
% colorbar
% title(num2str(pit))
% pause(.001)
end