comparison +scheme/Schrodinger2d.m @ 719:b3f8fb9cefd2 feature/utux2D

Add interpolation to Schrödinger 2D scheme.
author Martin Almquist <malmquist@stanford.edu>
date Sun, 11 Mar 2018 21:39:49 -0700
parents 71aa5828cbbf
children f4595f14d696
comparison
equal deleted inserted replaced
718:71aa5828cbbf 719:b3f8fb9cefd2
26 D2 26 D2
27 27
28 H, Hi % Inner products 28 H, Hi % Inner products
29 e_l, e_r 29 e_l, e_r
30 d1_l, d1_r % Normal derivatives at the boundary 30 d1_l, d1_r % Normal derivatives at the boundary
31 e_w, e_e, e_s, e_n
32 d_w, d_e, d_s, d_n
31 33
32 H_boundary % Boundary inner products 34 H_boundary % Boundary inner products
33 35
36 interpolation_type % MC or AWW
37
34 end 38 end
35 39
36 methods 40 methods
37 41
38 function obj = Schrodinger2d(g ,order, a, opSet) 42 function obj = Schrodinger2d(g ,order, a, opSet, interpolation_type)
43 default_arg('interpolation_type','AWW');
39 default_arg('opSet',{@sbp.D2Variable, @sbp.D2Variable}); 44 default_arg('opSet',{@sbp.D2Variable, @sbp.D2Variable});
40 default_arg('a',1); 45 default_arg('a',1);
41 dim = 2; 46 dim = 2;
42 47
43 assert(isa(g, 'grid.Cartesian')) 48 assert(isa(g, 'grid.Cartesian'))
131 obj.h = h; 136 obj.h = h;
132 obj.order = order; 137 obj.order = order;
133 obj.grid = g; 138 obj.grid = g;
134 obj.dim = dim; 139 obj.dim = dim;
135 obj.a = a; 140 obj.a = a;
141 obj.e_w = obj.e_l{1};
142 obj.e_e = obj.e_r{1};
143 obj.e_s = obj.e_l{2};
144 obj.e_n = obj.e_r{2};
145 obj.d_w = obj.d1_l{1};
146 obj.d_e = obj.d1_r{1};
147 obj.d_s = obj.d1_l{2};
148 obj.d_n = obj.d1_r{2};
149 obj.interpolation_type = interpolation_type;
136 150
137 end 151 end
138 152
139 153
140 % Closure functions return the operators applied to the own domain to close the boundary 154 % Closure functions return the operators applied to the own domain to close the boundary
185 end 199 end
186 200
187 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) 201 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary)
188 % u denotes the solution in the own domain 202 % u denotes the solution in the own domain
189 % v denotes the solution in the neighbour domain 203 % v denotes the solution in the neighbour domain
190 error('Interface not implemented'); 204 % Get neighbour boundary operator
205
206 [coord_nei, n_nei] = get_boundary_number(obj, neighbour_boundary);
207 [coord, n] = get_boundary_number(obj, boundary);
208 switch n_nei
209 case 1
210 % North or east boundary
211 e_neighbour = neighbour_scheme.e_r;
212 d_neighbour = neighbour_scheme.d1_r;
213 case -1
214 % South or west boundary
215 e_neighbour = neighbour_scheme.e_l;
216 d_neighbour = neighbour_scheme.d1_l;
217 end
218
219 e_neighbour = e_neighbour{coord_nei};
220 d_neighbour = d_neighbour{coord_nei};
221 H_gamma = obj.H_boundary{coord};
222 Hi = obj.Hi;
223 a = obj.a;
224
225 switch coord_nei
226 case 1
227 m_neighbour = neighbour_scheme.m(2);
228 case 2
229 m_neighbour = neighbour_scheme.m(1);
230 end
231
232 switch coord
233 case 1
234 m = obj.m(2);
235 case 2
236 m = obj.m(1);
237 end
238
239 switch n
240 case 1
241 % North or east boundary
242 e = obj.e_r;
243 d = obj.d1_r;
244 case -1
245 % South or west boundary
246 e = obj.e_l;
247 d = obj.d1_l;
248 end
249 e = e{coord};
250 d = d{coord};
251
252 Hi = obj.Hi;
253 sigma = -n*1i*a/2;
254 tau = -n*(1i*a)'/2;
255
256 grid_ratio = m/m_neighbour;
257 if grid_ratio ~= 1
258
259 [ms, index] = sort([m, m_neighbour]);
260 orders = [obj.order, neighbour_scheme.order];
261 orders = orders(index);
262
263 switch obj.interpolation_type
264 case 'MC'
265 interpOpSet = sbp.InterpMC(ms(1),ms(2),orders(1),orders(2));
266 if grid_ratio < 1
267 I_neighbour2local_e = interpOpSet.IF2C;
268 I_neighbour2local_d = interpOpSet.IF2C;
269 I_local2neighbour_e = interpOpSet.IC2F;
270 I_local2neighbour_d = interpOpSet.IC2F;
271 elseif grid_ratio > 1
272 I_neighbour2local_e = interpOpSet.IC2F;
273 I_neighbour2local_d = interpOpSet.IC2F;
274 I_local2neighbour_e = interpOpSet.IF2C;
275 I_local2neighbour_d = interpOpSet.IF2C;
276 end
277 case 'AWW'
278 %String 'C2F' indicates that ICF2 is more accurate.
279 interpOpSetF2C = sbp.InterpAWW(ms(1),ms(2),orders(1),orders(2),'F2C');
280 interpOpSetC2F = sbp.InterpAWW(ms(1),ms(2),orders(1),orders(2),'C2F');
281 if grid_ratio < 1
282 % Local is coarser than neighbour
283 I_neighbour2local_e = interpOpSetF2C.IF2C;
284 I_neighbour2local_d = interpOpSetC2F.IF2C;
285 I_local2neighbour_e = interpOpSetC2F.IC2F;
286 I_local2neighbour_d = interpOpSetF2C.IC2F;
287 elseif grid_ratio > 1
288 % Local is finer than neighbour
289 I_neighbour2local_e = interpOpSetC2F.IC2F;
290 I_neighbour2local_d = interpOpSetF2C.IC2F;
291 I_local2neighbour_e = interpOpSetF2C.IF2C;
292 I_local2neighbour_d = interpOpSetC2F.IF2C;
293 end
294 otherwise
295 error(['Interpolation type ' obj.interpolation_type ...
296 ' is not available.' ]);
297 end
298
299 else
300 % No interpolation required
301 I_neighbour2local_e = speye(m,m);
302 I_neighbour2local_d = speye(m,m);
303 I_local2neighbour_e = speye(m,m);
304 I_local2neighbour_d = speye(m,m);
305 end
306
307 closure = tau*Hi*d*H_gamma*e' + sigma*Hi*e*H_gamma*d';
308 penalty = -tau*Hi*d*H_gamma*I_neighbour2local_e*e_neighbour' ...
309 -sigma*Hi*e*H_gamma*I_neighbour2local_d*d_neighbour';
310
191 end 311 end
192 312
193 % Returns the coordinate number and outward normal component for the boundary specified by the string boundary. 313 % Returns the coordinate number and outward normal component for the boundary specified by the string boundary.
194 function [j, nj] = get_boundary_number(obj, boundary) 314 function [j, nj] = get_boundary_number(obj, boundary)
195 315