Mercurial > repos > public > sbplib
comparison +scheme/Heat2dVariable.m @ 1197:433c89bf19e0 feature/rv
Merge with default
author | Vidar Stiernström <vidar.stiernstrom@it.uu.se> |
---|---|
date | Wed, 07 Aug 2019 15:23:42 +0200 |
parents | 8d73fcdb07a5 |
children |
comparison
equal
deleted
inserted
replaced
1196:f6c571d8f22f | 1197:433c89bf19e0 |
---|---|
1 classdef Heat2dVariable < scheme.Scheme | 1 classdef Heat2dVariable < scheme.Scheme |
2 | 2 |
3 % Discretizes the Laplacian with variable coefficent, | 3 % Discretizes the Laplacian with variable coefficent, |
4 % In the Heat equation way (i.e., the discretization matrix is not necessarily | 4 % In the Heat equation way (i.e., the discretization matrix is not necessarily |
5 % symmetric) | 5 % symmetric) |
6 % u_t = div * (kappa * grad u ) | 6 % u_t = div * (kappa * grad u ) |
7 % opSet should be cell array of opSets, one per dimension. This | 7 % opSet should be cell array of opSets, one per dimension. This |
8 % is useful if we have periodic BC in one direction. | 8 % is useful if we have periodic BC in one direction. |
9 | 9 |
10 properties | 10 properties |
11 m % Number of points in each direction, possibly a vector | 11 m % Number of points in each direction, possibly a vector |
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 alpha % Vector of borrowing constants | 31 alpha % Vector of borrowing constants |
32 | 32 |
33 H_boundary % Boundary inner products | 33 H_boundary % Boundary inner products |
34 | 34 |
35 end | 35 end |
36 | 36 |
37 methods | 37 methods |
160 function [closure, penalty] = boundary_condition(obj, boundary, type, symmetric, tuning) | 160 function [closure, penalty] = boundary_condition(obj, boundary, type, symmetric, tuning) |
161 default_arg('type','Neumann'); | 161 default_arg('type','Neumann'); |
162 default_arg('symmetric', false); | 162 default_arg('symmetric', false); |
163 default_arg('tuning',1.2); | 163 default_arg('tuning',1.2); |
164 | 164 |
165 % j is the coordinate direction of the boundary | 165 % nj: outward unit normal component. |
166 % nj: outward unit normal component. | |
167 % nj = -1 for west, south, bottom boundaries | 166 % nj = -1 for west, south, bottom boundaries |
168 % nj = 1 for east, north, top boundaries | 167 % nj = 1 for east, north, top boundaries |
169 [j, nj] = obj.get_boundary_number(boundary); | 168 nj = obj.getBoundarySign(boundary); |
170 switch nj | |
171 case 1 | |
172 e = obj.e_r; | |
173 d = obj.d1_r; | |
174 case -1 | |
175 e = obj.e_l; | |
176 d = obj.d1_l; | |
177 end | |
178 | 169 |
179 Hi = obj.Hi; | 170 Hi = obj.Hi; |
180 H_gamma = obj.H_boundary{j}; | 171 [e, d] = obj.getBoundaryOperator({'e', 'd'}, boundary); |
172 H_gamma = obj.getBoundaryQuadrature(boundary); | |
173 alpha = obj.getBoundaryBorrowing(boundary); | |
174 | |
181 KAPPA = obj.KAPPA; | 175 KAPPA = obj.KAPPA; |
182 kappa_gamma = e{j}'*KAPPA*e{j}; | 176 kappa_gamma = e'*KAPPA*e; |
183 h = obj.h(j); | |
184 alpha = h*obj.alpha(j); | |
185 | 177 |
186 switch type | 178 switch type |
187 | 179 |
188 % Dirichlet boundary condition | 180 % Dirichlet boundary condition |
189 case {'D','d','dirichlet','Dirichlet'} | 181 case {'D','d','dirichlet','Dirichlet'} |
190 | 182 |
191 if ~symmetric | 183 if ~symmetric |
192 closure = -nj*Hi*d{j}*kappa_gamma*H_gamma*(e{j}' ); | 184 closure = -nj*Hi*d*kappa_gamma*H_gamma*(e' ); |
193 penalty = nj*Hi*d{j}*kappa_gamma*H_gamma; | 185 penalty = nj*Hi*d*kappa_gamma*H_gamma; |
194 else | 186 else |
195 closure = nj*Hi*d{j}*kappa_gamma*H_gamma*(e{j}' )... | 187 closure = nj*Hi*d*kappa_gamma*H_gamma*(e' )... |
196 -tuning*2/alpha*Hi*e{j}*kappa_gamma*H_gamma*(e{j}' ) ; | 188 -tuning*2/alpha*Hi*e*kappa_gamma*H_gamma*(e' ) ; |
197 penalty = -nj*Hi*d{j}*kappa_gamma*H_gamma ... | 189 penalty = -nj*Hi*d*kappa_gamma*H_gamma ... |
198 +tuning*2/alpha*Hi*e{j}*kappa_gamma*H_gamma; | 190 +tuning*2/alpha*Hi*e*kappa_gamma*H_gamma; |
199 end | 191 end |
200 | 192 |
201 % Free boundary condition | 193 % Free boundary condition |
202 case {'N','n','neumann','Neumann'} | 194 case {'N','n','neumann','Neumann'} |
203 closure = -nj*Hi*e{j}*kappa_gamma*H_gamma*(d{j}' ); | 195 closure = -nj*Hi*e*kappa_gamma*H_gamma*(d' ); |
204 penalty = Hi*e{j}*kappa_gamma*H_gamma; | 196 penalty = Hi*e*kappa_gamma*H_gamma; |
205 % penalty is for normal derivative and not for derivative, hence the sign. | 197 % penalty is for normal derivative and not for derivative, hence the sign. |
206 | 198 |
207 % Unknown boundary condition | 199 % Unknown boundary condition |
208 otherwise | 200 otherwise |
209 error('No such boundary condition: type = %s',type); | 201 error('No such boundary condition: type = %s',type); |
214 % u denotes the solution in the own domain | 206 % u denotes the solution in the own domain |
215 % v denotes the solution in the neighbour domain | 207 % v denotes the solution in the neighbour domain |
216 error('Interface not implemented'); | 208 error('Interface not implemented'); |
217 end | 209 end |
218 | 210 |
219 % Returns the coordinate number and outward normal component for the boundary specified by the string boundary. | 211 % Returns the boundary operator op for the boundary specified by the string boundary. |
220 function [j, nj] = get_boundary_number(obj, boundary) | 212 % op -- string or a cell array of strings |
221 | 213 % boundary -- string |
222 switch boundary | 214 function varargout = getBoundaryOperator(obj, op, boundary) |
223 case {'w','W','west','West', 'e', 'E', 'east', 'East'} | 215 assertIsMember(boundary, {'w', 'e', 's', 'n'}) |
224 j = 1; | 216 |
225 case {'s','S','south','South', 'n', 'N', 'north', 'North'} | 217 if ~iscell(op) |
226 j = 2; | 218 op = {op}; |
227 otherwise | 219 end |
228 error('No such boundary: boundary = %s',boundary); | 220 |
229 end | 221 for i = 1:numel(op) |
230 | 222 switch op{i} |
231 switch boundary | |
232 case {'w','W','west','West','s','S','south','South'} | |
233 nj = -1; | |
234 case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} | |
235 nj = 1; | |
236 end | |
237 end | |
238 | |
239 % Returns the coordinate number and outward normal component for the boundary specified by the string boundary. | |
240 function [return_op] = get_boundary_operator(obj, op, boundary) | |
241 | |
242 switch boundary | |
243 case {'w','W','west','West', 'e', 'E', 'east', 'East'} | |
244 j = 1; | |
245 case {'s','S','south','South', 'n', 'N', 'north', 'North'} | |
246 j = 2; | |
247 otherwise | |
248 error('No such boundary: boundary = %s',boundary); | |
249 end | |
250 | |
251 switch op | |
252 case 'e' | 223 case 'e' |
253 switch boundary | 224 switch boundary |
254 case {'w','W','west','West','s','S','south','South'} | 225 case 'w' |
255 return_op = obj.e_l{j}; | 226 e = obj.e_l{1}; |
256 case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} | 227 case 'e' |
257 return_op = obj.e_r{j}; | 228 e = obj.e_r{1}; |
229 case 's' | |
230 e = obj.e_l{2}; | |
231 case 'n' | |
232 e = obj.e_r{2}; | |
258 end | 233 end |
234 varargout{i} = e; | |
235 | |
259 case 'd' | 236 case 'd' |
260 switch boundary | 237 switch boundary |
261 case {'w','W','west','West','s','S','south','South'} | 238 case 'w' |
262 return_op = obj.d1_l{j}; | 239 d = obj.d1_l{1}; |
263 case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} | 240 case 'e' |
264 return_op = obj.d1_r{j}; | 241 d = obj.d1_r{1}; |
242 case 's' | |
243 d = obj.d1_l{2}; | |
244 case 'n' | |
245 d = obj.d1_r{2}; | |
265 end | 246 end |
266 otherwise | 247 varargout{i} = d; |
267 error(['No such operator: operatr = ' op]); | 248 end |
268 end | 249 end |
269 | 250 end |
251 | |
252 % Returns square boundary quadrature matrix, of dimension | |
253 % corresponding to the number of boundary points | |
254 % | |
255 % boundary -- string | |
256 function H_b = getBoundaryQuadrature(obj, boundary) | |
257 assertIsMember(boundary, {'w', 'e', 's', 'n'}) | |
258 | |
259 switch boundary | |
260 case 'w' | |
261 H_b = obj.H_boundary{1}; | |
262 case 'e' | |
263 H_b = obj.H_boundary{1}; | |
264 case 's' | |
265 H_b = obj.H_boundary{2}; | |
266 case 'n' | |
267 H_b = obj.H_boundary{2}; | |
268 end | |
269 end | |
270 | |
271 % Returns the boundary sign. The right boundary is considered the positive boundary | |
272 % boundary -- string | |
273 function s = getBoundarySign(obj, boundary) | |
274 assertIsMember(boundary, {'w', 'e', 's', 'n'}) | |
275 | |
276 switch boundary | |
277 case {'e','n'} | |
278 s = 1; | |
279 case {'w','s'} | |
280 s = -1; | |
281 end | |
282 end | |
283 | |
284 % Returns borrowing constant gamma*h | |
285 % boundary -- string | |
286 function gamm = getBoundaryBorrowing(obj, boundary) | |
287 assertIsMember(boundary, {'w', 'e', 's', 'n'}) | |
288 | |
289 switch boundary | |
290 case {'w','e'} | |
291 gamm = obj.h(1)*obj.alpha(1); | |
292 case {'s','n'} | |
293 gamm = obj.h(2)*obj.alpha(2); | |
294 end | |
270 end | 295 end |
271 | 296 |
272 function N = size(obj) | 297 function N = size(obj) |
273 N = prod(obj.m); | 298 N = prod(obj.m); |
274 end | 299 end |