1 function [U,varargout]=mass_cons_flux(U0,X,method,check)
2 % mass consistent flux approximation
4 % U0 cell array, wind vectors u v w on staggered grids
5 % X cell array, nodal coordinatees
6 % method 'direct' or 'pcg' method for solving system
7 % check flag for optional timing and error checking
9 % U cell array, wind vectors u v w
10 % Lambda pressure field (optional)
14 % D = divergence of flux on cell sides
15 % M = transformation of wind to flux through cell sides with
16 % zero flux boundary condition at the bottom (the terrain)
17 % A = weights of the wind vector components, U'*A*U approx ||U||_L2^2
21 % min 1/2 (U - U0)'*A*(U - U0) s.t. D*M*U = 0
23 % <=> A*(U - U0) + M'*D'*Lambda = 0
27 % <=> U = U0 - inv(A)*M'*D'*Lambda
29 % D*M*inv(A)*M'*D'*Lambda = D*M*U0
31 if ~exist('check','var')
40 % Creates the weight vector... diagonal for now?
41 hvr = 1e4; % ratio of horizontal and vertical penalty: Sherman 1978 page 315
43 Avec = cell2vec({hvr*s.weight_u,hvr*s.weight_v,s.weight_w});
44 Ainv = diag(sparse(1./Avec));
49 DM = mat_gen_wind_flux_div(X); % divergence of u0
54 Uvec = U0vec - Ainv * DM' * Lambda;
55 U = vec2cell(Uvec,U0);
57 % uses pcg and implicit multiplication
58 DM = mat_gen_wind_flux_div(X); % divergence of u0
60 % rhs = Mmul_v(X, 'n', U0vec);
61 % rhs = Dmul_v(X, 'n', rhs);
64 % PC_L = ichol(PC,struct('michol','on'));
65 % lhs_mat = @(x) lhs_apply(X, Ainv, x);
66 % Lambda = pcg(lhs_mat, rhs, 1e-10, 100, PC_L, PC_L');
67 % Lambda = pcg(lhs_mat, rhs, 1e-8, 400);
68 % [Lambda,FLAG,RELRES,ITER,RESVEC] = pcg(lhs_mat, rhs, 1e-6, 400);
69 [Lambda,FLAG,RELRES,ITER,RESVEC] = pcg(L, rhs, 1e-6, 400);
72 title('Residuals using PCG')
73 xlabel('Iterations'),ylabel('Residuals')
74 Uvec = U0vec - Ainv * DM' * Lambda;
75 U = vec2cell(Uvec,U0);
77 error('only direct and iterative methods implemented')
81 % Check that the divergence of the computed U is 0
82 err_div = big(div3(wind2flux(U,X)))
83 varargout{2} = err_div;
84 fprintf('mass_cons_flux %g seconds\n',toc(tstart))
86 if length(varargout) > 0
87 varargout{1} = Lambda;
89 % check no correction in normal speed at the bottom
90 % if check, err_corr_w_bottom = big(u{3}(:,:,1)-U0{3}(:,:,1)), end