comparison +scheme/Beam.m @ 175:8f22829b69d0 feature/beams

Added and upgraded schemes for the beam equation in 1d and 2d.
author Jonatan Werpers <jonatan@werpers.com>
date Fri, 26 Feb 2016 16:21:47 +0100
parents
children d095b5396103
comparison
equal deleted inserted replaced
174:513019e3d855 175:8f22829b69d0
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 % Discrete norm
10 Hi
11
12 e_l, e_r
13 d1_l, d1_r
14 d2_l, d2_r
15 d3_l, d3_r
16 gamm
17 delt
18 end
19
20 methods
21 function obj = Beam(grid, order, alpha, opsGen)
22 default_arg('alpha', 1);
23 default_arg('opsGen', @sbp.Higher);
24
25 if ~isa(grid, 'Cartesian') || grid.D() ~= 1
26 error('Grid must be 1d cartesian');
27 end
28
29 obj.grid = grid;
30 obj.order = order;
31 obj.alpha = alpha;
32
33 m = grid.m;
34 h = grid.spacing();
35
36 ops = opsGen(m, h, order);
37
38 I = speye(m);
39
40 D4 = sparse(ops.derivatives.D4);
41 obj.H = sparse(ops.norms.H);
42 obj.Hi = sparse(ops.norms.HI);
43 obj.e_l = sparse(ops.boundary.e_1);
44 obj.e_r = sparse(ops.boundary.e_m);
45 obj.d1_l = sparse(ops.boundary.S_1);
46 obj.d1_r = sparse(ops.boundary.S_m);
47 obj.d2_l = sparse(ops.boundary.S2_1);
48 obj.d2_r = sparse(ops.boundary.S2_m);
49 obj.d3_l = sparse(ops.boundary.S3_1);
50 obj.d3_r = sparse(ops.boundary.S3_m);
51
52 obj.D = alpha*D4;
53
54 obj.gamm = h*ops.borrowing.N.S2/2;
55 obj.delt = h^3*ops.borrowing.N.S3/2;
56 end
57
58
59 % Closure functions return the opertors applied to the own doamin to close the boundary
60 % Penalty functions return the opertors to force the solution. In the case of an interface it returns the operator applied to the other doamin.
61 % boundary is a string specifying the boundary e.g. 'l','r' or 'e','w','n','s'.
62 % type is a string specifying the type of boundary condition if there are several.
63 % neighbour_scheme is an instance of Scheme that should be interfaced to.
64 % neighbour_boundary is a string specifying which boundary to interface to.
65 function [closure, penalty_e, penalty_d] = boundary_condition(obj,boundary,type)
66 default_arg('type','dn');
67
68 [e, d1, d2, d3, s] = obj.get_boundary_ops(boundary);
69 gamm = obj.gamm;
70 delt = obj.delt;
71
72 switch type
73 case {'dn'} % Dirichlet-neumann boundary condition
74 alpha = obj.alpha;
75
76 % tau1 < -alpha^2/gamma
77 tuning = 1.1;
78
79 tau1 = tuning * alpha/delt;
80 tau4 = s*alpha;
81
82 sig2 = tuning * alpha/gamm;
83 sig3 = -s*alpha;
84
85 tau = tau1*e+tau4*d3;
86 sig = sig2*d1+sig3*d2;
87
88 closure = obj.Hi*(tau*e' + sig*d1');
89
90 penalty_e = obj.Hi*tau;
91 penalty_d = obj.Hi*sig;
92 otherwise % Unknown, boundary condition
93 error('No such boundary condition: type = %s',type);
94 end
95 end
96
97 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary)
98 % u denotes the solution in the own domain
99 % v denotes the solution in the neighbour domain
100 [e_u,d1_u,d2_u,d3_u,s_u] = obj.get_boundary_ops(boundary);
101 [e_v,d1_v,d2_v,d3_v,s_v] = neighbour_scheme.get_boundary_ops(neighbour_boundary);
102
103 gamm_u = obj.gamm;
104 delt_u = obj.delt;
105
106 gamm_v = neighbour_scheme.gamm;
107 delt_v = neighbour_scheme.delt;
108
109 tuning = 2;
110
111 alpha_u = obj.alpha;
112 alpha_v = neighbour_scheme.alpha;
113
114 tau1 = ((alpha_u/2)/delt_u + (alpha_v/2)/delt_v)/2*tuning;
115 % tau1 = (alpha_u/2 + alpha_v/2)/(2*delt_u)*tuning;
116 tau4 = s_u*alpha_u/2;
117
118 sig2 = ((alpha_u/2)/gamm_u + (alpha_v/2)/gamm_v)/2*tuning;
119 sig3 = -s_u*alpha_u/2;
120
121 phi2 = s_u*1/2;
122
123 psi1 = -s_u*1/2;
124
125 tau = tau1*e_u + tau4*d3_u;
126 sig = sig2*d1_u + sig3*d2_u ;
127 phi = phi2*d1_u ;
128 psi = psi1*e_u ;
129
130 closure = obj.Hi*(tau*e_u' + sig*d1_u' + phi*alpha_u*d2_u' + psi*alpha_u*d3_u');
131 penalty = -obj.Hi*(tau*e_v' + sig*d1_v' + phi*alpha_v*d2_v' + psi*alpha_v*d3_v');
132 end
133
134 % Returns the boundary ops and sign for the boundary specified by the string boundary.
135 % The right boundary is considered the positive boundary
136 function [e, d1, d2, d3, s] = get_boundary_ops(obj,boundary)
137 switch boundary
138 case 'l'
139 e = obj.e_l;
140 d1 = obj.d1_l;
141 d2 = obj.d2_l;
142 d3 = obj.d3_l;
143 s = -1;
144 case 'r'
145 e = obj.e_e;
146 d1 = obj.d1_e;
147 d2 = obj.d2_e;
148 d3 = obj.d3_e;
149 s = 1;
150 otherwise
151 error('No such boundary: boundary = %s',boundary);
152 end
153 end
154
155 function N = size(obj)
156 N = prod(obj.m);
157 end
158
159 end
160 end