Mercurial > repos > public > sbplib
comparison +grid/Schrodinger2dCurve.m @ 490:b13d44271ead feature/quantumTriangles
Schrodinger2dCurve Added
author | Ylva Rydin <ylva.rydin@telia.com> |
---|---|
date | Thu, 09 Feb 2017 11:41:21 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
432:eca4ca84cf0a | 490:b13d44271ead |
---|---|
1 classdef Schrodinger2dCurve < scheme.Scheme | |
2 properties | |
3 m % Number of points in each direction, possibly a vector | |
4 h % Grid spacing | |
5 | |
6 grid | |
7 | |
8 order % Order accuracy for the approximation | |
9 | |
10 D % non-stabalized scheme operator | |
11 M % Derivative norm | |
12 H % Discrete norm | |
13 Hi | |
14 H_u, H_v % Norms in the x and y directions | |
15 Hu,Hv % Kroneckerd norms. 1'*Hx*v corresponds to integration in the x dir. | |
16 Hi_u, Hi_v | |
17 Hiu, Hiv | |
18 D1_v D1_u | |
19 D2_v D2_u | |
20 Du Dv | |
21 | |
22 | |
23 e_w, e_e, e_s, e_n | |
24 du_w, dv_w | |
25 du_e, dv_e | |
26 du_s, dv_s | |
27 du_n, dv_n | |
28 g_1 | |
29 g_2 | |
30 | |
31 p,p_tau | |
32 end | |
33 | |
34 methods | |
35 function obj = Schrodinger2dCurve(g ,order, opSet, p,p_tau) | |
36 default_arg('opSet',@sbp.D2Variable); | |
37 default_arg('c', 1); | |
38 | |
39 assert(isa(g, 'grid.Curvilinear')) | |
40 | |
41 obj.p=p; | |
42 obj.p_tau=p_tau; | |
43 obj.c=1; | |
44 | |
45 m = g.size(); | |
46 m_u = m(1); | |
47 m_v = m(2); | |
48 m_tot = g.N(); | |
49 | |
50 h = g.scaling(); | |
51 h_u = h(1); | |
52 h_v = h(2); | |
53 | |
54 % Operators | |
55 ops_u = opSet(m_u, {0, 1}, order); | |
56 ops_v = opSet(m_v, {0, 1}, order); | |
57 | |
58 I_u = speye(m_u); | |
59 I_v = speye(m_v); | |
60 | |
61 D1_u = ops_u.D1; | |
62 | |
63 H_u = ops_u.H; | |
64 Hi_u = ops_u.HI; | |
65 e_l_u = ops_u.e_l; | |
66 e_r_u = ops_u.e_r; | |
67 d1_l_u = ops_u.d1_l; | |
68 d1_r_u = ops_u.d1_r; | |
69 | |
70 obj.D1_v = ops_v.D1; | |
71 obj.D2_v = ops_v.D2; | |
72 H_v = ops_v.H; | |
73 Hi_v = ops_v.HI; | |
74 e_l_v = ops_v.e_l; | |
75 e_r_v = ops_v.e_r; | |
76 d1_l_v = ops_v.d1_l; | |
77 d1_r_v = ops_v.d1_r; | |
78 | |
79 obj.Du = kr(D1_u,I_v); | |
80 obj.Dv = kr(I_u,D1_v); | |
81 | |
82 obj.H = kr(H_u,H_v); | |
83 obj.Hi = kr(Hi_u,Hi_v); | |
84 obj.Hu = kr(H_u,I_v); | |
85 obj.Hv = kr(I_u,H_v); | |
86 obj.Hiu = kr(Hi_u,I_v); | |
87 obj.Hiv = kr(I_u,Hi_v); | |
88 | |
89 obj.e_w = kr(e_l_u,I_v); | |
90 obj.e_e = kr(e_r_u,I_v); | |
91 obj.e_s = kr(I_u,e_l_v); | |
92 obj.e_n = kr(I_u,e_r_v); | |
93 obj.du_w = kr(d1_l_u,I_v); | |
94 obj.dv_w = (obj.e_w'*Dv)'; | |
95 obj.du_e = kr(d1_r_u,I_v); | |
96 obj.dv_e = (obj.e_e'*Dv)'; | |
97 obj.du_s = (obj.e_s'*Du)'; | |
98 obj.dv_s = kr(I_u,d1_l_v); | |
99 obj.du_n = (obj.e_n'*Du)'; | |
100 obj.dv_n = kr(I_u,d1_r_v); | |
101 | |
102 % obj.x_u = x_u; | |
103 % obj.x_v = x_v; | |
104 % obj.y_u = y_u; | |
105 % obj.y_v = y_v; | |
106 | |
107 obj.m = m; | |
108 obj.h = [h_u h_v]; | |
109 obj.order = order; | |
110 obj.grid = g; | |
111 | |
112 | |
113 end | |
114 | |
115 | |
116 function [D ]= d_fun(obj,t) | |
117 % Metric derivatives | |
118 ti = parametrization.Ti.points(obj.p.p1(t),obj.p.p2(t),obj.p.p3,obj.p.p4); | |
119 ti_tau = parametrization.Ti.points(obj.p_tau.p1(t),obj.p_tau.p2(t),obj.p_tau.p3,obj.p_tau.p4); | |
120 | |
121 coords = parametrization.ti.map(); | |
122 coords_tau = parametrization.ti_tau.map(); | |
123 x = coords(:,1); | |
124 y = coords(:,2); | |
125 | |
126 x_tau = coords_tau(:,1); | |
127 y_tau = coords_tau(:,2); | |
128 | |
129 x_u = obj.Du*x; | |
130 x_v = obj.Dv*x; | |
131 y_u = obj.Du*y; | |
132 y_v = obj.Dv*y; | |
133 | |
134 J = x_u.*y_v - x_v.*y_u; | |
135 a11 = 1./J.* (x_v.^2 + y_v.^2); | |
136 a12 = -1./J .* (x_u.*x_v + y_u.*y_v); | |
137 a22 = 1./J .* (x_u.^2 + y_u.^2); | |
138 lambda = 1/2 * (a11 + a22 - sqrt((a11-a22).^2 + 4*a12.^2)); | |
139 | |
140 % Assemble full operators | |
141 L_12 = spdiags(a12, 0, m_tot, m_tot); | |
142 Duv = obj.Du*L_12*obj.Dv; | |
143 Dvu = obj.Dv*L_12*obj.Du; | |
144 | |
145 Duu = sparse(m_tot); | |
146 Dvv = sparse(m_tot); | |
147 ind = grid.funcToMatrix(g, 1:m_tot); | |
148 | |
149 for i = 1:m_v | |
150 D = D2_u(a11(ind(:,i))); | |
151 p = ind(:,i); | |
152 Duu(p,p) = D; | |
153 end | |
154 | |
155 for i = 1:m_u | |
156 D = D2_v(a22(ind(i,:))); | |
157 p = ind(i,:); | |
158 Dvv(p,p) = D; | |
159 end | |
160 | |
161 | |
162 J = spdiags(J, 0, m_tot, m_tot); | |
163 Ji = spdiags(1./J, 0, m_tot, m_tot); | |
164 obj.g_1 = x_tau.*y_v-y_tau.*x_v; | |
165 obj.g_2 = -x_tau.*y_u + y_tau.*x_u; | |
166 | |
167 %Add the flux splitting | |
168 D = Ji*(obj.g_1*obj.Du + obj.g_2*obj.Dv + 1i*obj.c^2*(Duu + Duv + Dvu + Dvv)); | |
169 | |
170 % obj.gamm_u = h_u*ops_u.borrowing.M.d1; | |
171 % obj.gamm_v = h_v*ops_v.borrowing.M.d1; | |
172 | |
173 end | |
174 | |
175 % Closure functions return the opertors applied to the own doamin to close the boundary | |
176 % Penalty functions return the opertors to force the solution. In the case of an interface it returns the operator applied to the other doamin. | |
177 % boundary is a string specifying the boundary e.g. 'l','r' or 'e','w','n','s'. | |
178 % type is a string specifying the type of boundary condition if there are several. | |
179 % data is a function returning the data that should be applied at the boundary. | |
180 % neighbour_scheme is an instance of Scheme that should be interfaced to. | |
181 % neighbour_boundary is a string specifying which boundary to interface to. | |
182 function [closure, penalty] = boundary_condition(obj, boundary, parameter) | |
183 default_arg('type','neumann'); | |
184 default_arg('parameter', []); | |
185 | |
186 % v denotes the solution in the neighbour domain | |
187 tuning = 1.2; | |
188 % tuning = 20.2; | |
189 [e, d_n, d_t, coeff_n, coeff_t, s, gamm, halfnorm_inv_n, halfnorm_inv_t, halfnorm_t,g] = obj.get_boundary_ops(boundary); | |
190 | |
191 a_n = spdiag(coeff_n); | |
192 a_t = spdiag(coeff_t); | |
193 | |
194 F = (s * a_n * d_n' + s * a_t*d_t')'; | |
195 | |
196 u = obj; | |
197 | |
198 b1 = gamm*u.lambda./u.a11.^2; | |
199 b2 = gamm*u.lambda./u.a22.^2; | |
200 | |
201 tau1 = -1./b1 - 1./b2; | |
202 tau1 = tuning * spdiag(tau1); | |
203 sig1 = 1; | |
204 | |
205 a = e'*g; | |
206 tau2 = (-1*s*a - abs(a))/4; | |
207 | |
208 penalty_parameter_1 = halfnorm_inv_n*(tau1 + sig1*halfnorm_inv_t*F*e'*halfnorm_t)*e; | |
209 penalty_parameter_2 = halfnorm_inv_n(tau2)*e; | |
210 | |
211 closure = obj.Ji*obj.c^2 * penalty_parameter_1*e' +obj.Ji* penalty_parameter_2*e'; | |
212 penalty = -obj.Ji*obj.c^2 * penalty_parameter_1; | |
213 | |
214 end | |
215 | |
216 function [e, d_n, d_t, coeff_n, coeff_t, s, gamm, halfnorm_inv_n, halfnorm_inv_t, halfnorm_t, I, scale_factor,g] = get_boundary_ops(obj, boundary) | |
217 | |
218 % gridMatrix = zeros(obj.m(2),obj.m(1)); | |
219 % gridMatrix(:) = 1:numel(gridMatrix); | |
220 | |
221 ind = grid.funcToMatrix(obj.grid, 1:prod(obj.m)); | |
222 | |
223 switch boundary | |
224 case 'w' | |
225 e = obj.e_w; | |
226 d_n = obj.du_w; | |
227 d_t = obj.dv_w; | |
228 s = -1; | |
229 | |
230 I = ind(1,:); | |
231 coeff_n = obj.a11(I); | |
232 coeff_t = obj.a12(I); | |
233 scale_factor = sqrt(obj.x_v(I).^2 + obj.y_v(I).^2); | |
234 case 'e' | |
235 e = obj.e_e; | |
236 d_n = obj.du_e; | |
237 d_t = obj.dv_e; | |
238 s = 1; | |
239 | |
240 I = ind(end,:); | |
241 coeff_n = obj.a11(I); | |
242 coeff_t = obj.a12(I); | |
243 scale_factor = sqrt(obj.x_v(I).^2 + obj.y_v(I).^2); | |
244 case 's' | |
245 e = obj.e_s; | |
246 d_n = obj.dv_s; | |
247 d_t = obj.du_s; | |
248 s = -1; | |
249 | |
250 I = ind(:,1)'; | |
251 coeff_n = obj.a22(I); | |
252 coeff_t = obj.a12(I); | |
253 scale_factor = sqrt(obj.x_u(I).^2 + obj.y_u(I).^2); | |
254 case 'n' | |
255 e = obj.e_n; | |
256 d_n = obj.dv_n; | |
257 d_t = obj.du_n; | |
258 s = 1; | |
259 | |
260 I = ind(:,end)'; | |
261 coeff_n = obj.a22(I); | |
262 coeff_t = obj.a12(I); | |
263 scale_factor = sqrt(obj.x_u(I).^2 + obj.y_u(I).^2); | |
264 otherwise | |
265 error('No such boundary: boundary = %s',boundary); | |
266 end | |
267 | |
268 switch boundary | |
269 case {'w','e'} | |
270 halfnorm_inv_n = obj.Hiu; | |
271 halfnorm_inv_t = obj.Hiv; | |
272 halfnorm_t = obj.Hv; | |
273 gamm = obj.gamm_u; | |
274 g=obj.g_1; | |
275 case {'s','n'} | |
276 halfnorm_inv_n = obj.Hiv; | |
277 halfnorm_inv_t = obj.Hiu; | |
278 halfnorm_t = obj.Hu; | |
279 gamm = obj.gamm_v; | |
280 g=obj.g_2; | |
281 end | |
282 end | |
283 | |
284 function N = size(obj) | |
285 N = prod(obj.m); | |
286 end | |
287 | |
288 | |
289 end | |
290 end |