comparison +scheme/Beam.m @ 427:a613960a157b feature/quantumTriangles

merged with feature/beams
author Ylva Rydin <ylva.rydin@telia.com>
date Thu, 26 Jan 2017 15:59:25 +0100
parents 25ae8333ce2b
children dfb27a7e801f
comparison
equal deleted inserted replaced
426:29944ea7674b 427:a613960a157b
1 classdef Beam < scheme.Scheme
2 properties
3 order % Order accuracy for the approximation
4 grid
5
6 D % non-stabalized scheme operator
7 alpha
8
9 h
10 H % Discrete norm
11 Hi
12
13 e_l, e_r
14 d1_l, d1_r
15 d2_l, d2_r
16 d3_l, d3_r
17 gamm
18 delt
19 alphaII
20 alphaIII
21
22 opt
23 end
24
25 methods
26 function obj = Beam(grid, order, alpha, opsGen, opt)
27 default_arg('alpha', -1);
28
29 % default_arg('opsGen', @sbp.D4);
30 default_arg('opsGen', @sbp.D4Variable); % Supposed to be better
31
32 opt_default.interface_l.tuning = 1.1;
33 opt_default.interface_l.tau = [];
34 opt_default.interface_l.sig = [];
35 opt_default.interface_r.tuning = 1.1;
36 opt_default.interface_r.tau = [];
37 opt_default.interface_r.sig = [];
38 default_struct('opt', opt_default);
39
40 if ~isa(grid, 'grid.Cartesian') || grid.D() ~= 1
41 error('Grid must be 1d cartesian');
42 end
43
44 obj.grid = grid;
45 obj.order = order;
46 obj.alpha = alpha;
47
48 m = grid.m;
49 h = grid.scaling();
50
51 x_lim = {grid.x{1}(1), grid.x{1}(end)};
52 ops = opsGen(m, x_lim, order);
53
54 D4 = ops.D4;
55 obj.H = ops.H;
56 obj.Hi = ops.HI;
57 obj.e_l = ops.e_l;
58 obj.e_r = ops.e_r;
59 obj.d1_l = ops.d1_l;
60 obj.d1_r = ops.d1_r;
61 obj.d2_l = ops.d2_l;
62 obj.d2_r = ops.d2_r;
63 obj.d3_l = ops.d3_l;
64 obj.d3_r = ops.d3_r;
65
66 obj.D = alpha*D4;
67
68 alphaII = ops.borrowing.N.S2/2;
69 alphaIII = ops.borrowing.N.S3/2;
70
71 obj.gamm = h*alphaII;
72 obj.delt = h^3*alphaIII;
73 obj.alphaII = alphaII;
74 obj.alphaIII = alphaIII;
75 obj.h = h;
76 obj.opt = opt;
77 end
78
79
80 % Closure functions return the opertors applied to the own doamin to close the boundary
81 % Penalty functions return the opertors to force the solution. In the case of an interface it returns the operator applied to the other doamin.
82 % boundary is a string specifying the boundary e.g. 'l','r' or 'e','w','n','s'.
83 % type is a string specifying the type of boundary condition if there are several.
84 % neighbour_scheme is an instance of Scheme that should be interfaced to.
85 % neighbour_boundary is a string specifying which boundary to interface to.
86 function [closure, penalty] = boundary_condition(obj,boundary,type)
87 default_arg('type','dn');
88
89 [e, d1, d2, d3, s] = obj.get_boundary_ops(boundary);
90 gamm = obj.gamm;
91 delt = obj.delt;
92
93 switch type
94 case {'dn', 'clamped'} % Dirichlet-neumann boundary condition
95 alpha = obj.alpha;
96
97 % tau1 < -alpha^2/gamma
98 % tuning = 2;
99 tuning = 1.1;
100
101 tau1 = tuning * alpha/delt;
102 tau4 = s*alpha;
103
104 sig2 = tuning * alpha/gamm;
105 sig3 = -s*alpha;
106
107 tau = tau1*e+tau4*d3;
108 sig = sig2*d1+sig3*d2;
109
110 closure = obj.Hi*(tau*e' + sig*d1');
111
112 penalty{1} = -obj.Hi*tau;
113 penalty{2} = -obj.Hi*sig;
114
115
116 case {'free'}
117 a = obj.alpha;
118
119 tau = s*a*d1;
120 sig = -s*a*e;
121
122 closure = obj.Hi*(tau*d2' + sig*d3');
123 penalty{1} = -obj.Hi*tau;
124 penalty{1} = -obj.Hi*sig;
125
126
127 otherwise % Unknown, boundary condition
128 error('No such boundary condition: type = %s',type);
129 end
130 end
131
132 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary)
133 % u denotes the solution in the own domain
134 % v denotes the solution in the neighbour domain
135 [e_u,d1_u,d2_u,d3_u,s_u] = obj.get_boundary_ops(boundary);
136 [e_v,d1_v,d2_v,d3_v,s_v] = neighbour_scheme.get_boundary_ops(neighbour_boundary);
137
138
139 alpha_u = obj.alpha;
140 alpha_v = neighbour_scheme.alpha;
141
142
143 switch boundary
144 case 'l'
145 interface_opt = obj.opt.interface_l;
146 case 'r'
147 interface_opt = obj.opt.interface_r;
148 end
149
150
151 if isempty(interface_opt.tau) && isempty(interface_opt.sig)
152 gamm_u = obj.gamm;
153 delt_u = obj.delt;
154
155 gamm_v = neighbour_scheme.gamm;
156 delt_v = neighbour_scheme.delt;
157
158 tuning = interface_opt.tuning;
159
160 tau1 = ((alpha_u/2)/delt_u + (alpha_v/2)/delt_v)/2*tuning;
161 sig2 = ((alpha_u/2)/gamm_u + (alpha_v/2)/gamm_v)/2*tuning;
162 else
163 h_u = obj.h;
164 h_v = neighbour_scheme.h;
165
166 switch neighbour_boundary
167 case 'l'
168 neighbour_interface_opt = neighbour_scheme.opt.interface_l;
169 case 'r'
170 neighbour_interface_opt = neighbour_scheme.opt.interface_r;
171 end
172
173 tau_u = interface_opt.tau;
174 sig_u = interface_opt.sig;
175 tau_v = neighbour_interface_opt.tau;
176 sig_v = neighbour_interface_opt.sig;
177
178 tau1 = tau_u/h_u^3 + tau_v/h_v^3;
179 sig2 = sig_u/h_u + sig_v/h_v;
180 end
181
182 tau4 = s_u*alpha_u/2;
183 sig3 = -s_u*alpha_u/2;
184 phi2 = s_u*1/2;
185 psi1 = -s_u*1/2;
186
187 tau = tau1*e_u + tau4*d3_u;
188 sig = sig2*d1_u + sig3*d2_u ;
189 phi = phi2*d1_u ;
190 psi = psi1*e_u ;
191
192 closure = obj.Hi*(tau*e_u' + sig*d1_u' + phi*alpha_u*d2_u' + psi*alpha_u*d3_u');
193 penalty = -obj.Hi*(tau*e_v' + sig*d1_v' + phi*alpha_v*d2_v' + psi*alpha_v*d3_v');
194 end
195
196 % Returns the boundary ops and sign for the boundary specified by the string boundary.
197 % The right boundary is considered the positive boundary
198 function [e, d1, d2, d3, s] = get_boundary_ops(obj,boundary)
199 switch boundary
200 case 'l'
201 e = obj.e_l;
202 d1 = obj.d1_l;
203 d2 = obj.d2_l;
204 d3 = obj.d3_l;
205 s = -1;
206 case 'r'
207 e = obj.e_r;
208 d1 = obj.d1_r;
209 d2 = obj.d2_r;
210 d3 = obj.d3_r;
211 s = 1;
212 otherwise
213 error('No such boundary: boundary = %s',boundary);
214 end
215 end
216
217 function N = size(obj)
218 N = obj.grid.N;
219 end
220
221 end
222 end