|
9 | 9 | end |
10 | 10 | end |
11 | 11 |
|
12 | | - properties |
| 12 | + properties (SetAccess = private) |
13 | 13 | DistanceFunction |
14 | 14 | FlowVelocityMagnitude |
15 | 15 | JacobianFlowVelocityMagnitudeVectorProduct |
16 | | - RhsAD |
17 | 16 | end |
18 | 17 |
|
19 | 18 | methods (Static) |
@@ -110,72 +109,63 @@ function onSettingsChanged(obj) |
110 | 109 | Re = obj.Parameters.Re; |
111 | 110 | Ro = obj.Parameters.Ro; |
112 | 111 |
|
113 | | - lambda = obj.Parameters.les.lambda; |
114 | | - passes = obj.Parameters.les.passes; |
115 | | - %dfiltertype = obj.Parameters.les.filtertype; |
116 | | - |
117 | 112 | n = [nx, ny]; |
118 | 113 |
|
119 | | - h = 1/(nx + 1); |
| 114 | + hx = 1/(nx + 1); |
| 115 | + hy = 2/(ny + 1); |
120 | 116 |
|
121 | 117 | xdomain = [0, 1]; |
122 | 118 | ydomain = [0, 2]; |
123 | 119 |
|
124 | | - domain = [0, 1; 0, 2]; |
125 | | - diffc = [1, 1]; |
126 | 120 | bc = 'DD'; |
127 | 121 |
|
128 | | - % create laplacian |
129 | | - L = otp.utils.pde.laplacian(n, domain, diffc, bc); |
130 | | - Ddx = otp.utils.pde.Dd(n, xdomain, 1, 2, bc(1)); |
131 | | - Ddy = otp.utils.pde.Dd(n, ydomain, 2, 2, bc(2)); |
| 122 | + % create the spatial derivatives |
| 123 | + Dx = otp.utils.pde.Dd(nx, xdomain, 1, 1, bc(1)); |
| 124 | + DxT = Dx.'; |
| 125 | + |
| 126 | + Dy = otp.utils.pde.Dd(ny, ydomain, 1, 1, bc(2)); |
| 127 | + DyT = Dy.'; |
| 128 | + |
| 129 | + % create the x and y Laplacians |
| 130 | + Lx = otp.utils.pde.laplacian(nx, xdomain, 1, bc(1)); |
| 131 | + Ly = otp.utils.pde.laplacian(ny, ydomain, 1, bc(2)); |
132 | 132 |
|
133 | | - % do a Cholesky decomposition on the negative laplacian |
134 | | - [RdnL, ~, PdnL] = chol(-L); |
135 | | - RdnLT = RdnL.'; |
136 | | - PdnLT = PdnL.'; |
| 133 | + % Do decompositions for the eigenvalue sylvester method. See |
| 134 | + % |
| 135 | + % Kirsten, Gerhardus Petrus. Comparison of methods for solving Sylvester systems. Stellenbosch University, 2018. |
| 136 | + % |
| 137 | + % for a detailed method, the "Eigenvalue Method" which makes this particularly efficient. |
| 138 | + |
| 139 | + hx2 = hx^2; |
| 140 | + hy2 = hy^2; |
| 141 | + cx = (1:nx)/(nx + 1); |
| 142 | + cy = (1:ny)/(ny + 1); |
| 143 | + L12 = -(hx2*hy2./(2*(-hx2 - hy2 + hy2*cospi(cx).' + hx2*cospi(cy)))); |
| 144 | + P1 = sqrt(2/(nx + 1))*sinpi((1:nx).'*(1:nx)/(nx + 1)); |
| 145 | + P2 = sqrt(2/(ny + 1))*sinpi((1:ny).'*(1:ny)/(ny + 1)); |
137 | 146 |
|
138 | 147 | ys = linspace(ydomain(1), ydomain(end), ny + 2); |
139 | 148 | ys = ys(2:end-1); |
140 | 149 |
|
141 | 150 | ymat = repmat(ys.', 1, nx); |
142 | | - ymat = reshape(ymat.', prod(n), 1); |
143 | | - F = sin(pi*(ymat - 1)); |
| 151 | + F = sin(pi*(ymat.' - 1)); |
144 | 152 |
|
145 | 153 | obj.Rhs = otp.Rhs(@(t, psi) ... |
146 | | - otp.qg.f(psi, L, RdnL, RdnLT, PdnL, PdnLT, Ddx, Ddy, F, Re, Ro), ... |
| 154 | + otp.qg.f(psi, Lx, Ly, P1, P2, L12, Dx, DxT, Dy, DyT, F, Re, Ro), ... |
147 | 155 | ... |
148 | | - otp.Rhs.FieldNames.JacobianVectorProduct, @(t, psi, u) ... |
149 | | - otp.qg.jvp(psi, u, L, RdnL, PdnL, Ddx, Ddy, Re, Ro), ... |
| 156 | + otp.Rhs.FieldNames.JacobianVectorProduct, @(t, psi, v) ... |
| 157 | + otp.qg.jvp(psi, v, Lx, Ly, P1, P2, L12, Dx, DxT, Dy, DyT, F, Re, Ro), ... |
150 | 158 | ... |
151 | | - otp.Rhs.FieldNames.JacobianAdjointVectorProduct, @(t, psi, u) ... |
152 | | - otp.qg.javp(psi, u, L, RdnL, PdnL, Ddx, Ddy, Re, Ro)); |
| 159 | + otp.Rhs.FieldNames.JacobianAdjointVectorProduct, @(t, psi, v) ... |
| 160 | + otp.qg.javp(psi, v, Lx, Ly, P1, P2, L12, Dx, DxT, Dy, DyT, F, Re, Ro)); |
153 | 161 |
|
154 | 162 |
|
155 | | - % AD LES |
156 | | - fmat = speye(prod(n)) - ((lambda*h)^2)*L; |
157 | | - |
158 | | - [Rfmat, ~, Pfmat] = chol(fmat); |
159 | | - RfmatT = Rfmat.'; |
160 | | - PfmatT = Pfmat.'; |
161 | | - |
162 | | - if ~isfield(obj.Parameters, 'filter') || isempty(obj.Parameters.filter) |
163 | | - filter = @(u) Pfmat*(Rfmat\(RfmatT\(PfmatT*u))); |
164 | | - else |
165 | | - filter = obj.Parameters.filter; |
166 | | - end |
167 | | - |
168 | | - Fbar = filter(F); |
169 | | - obj.RhsAD = otp.Rhs(@(t, psi) ... |
170 | | - otp.qg.fAD(psi, L, RdnL, RdnLT, PdnL, PdnLT, Ddx, Ddy, Fbar, Re, Ro, filter, passes)); |
171 | | - |
172 | | - |
173 | 163 | %% Distance function, and flow velocity |
174 | 164 | obj.DistanceFunction = @(t, y, i, j) otp.qg.distfn(t, y, i, j, nx, ny); |
175 | 165 |
|
176 | | - obj.FlowVelocityMagnitude = @(psi) otp.qg.flowvelmag(psi, Ddx, Ddy); |
| 166 | + obj.FlowVelocityMagnitude = @(psi) otp.qg.flowvelmag(psi, Dx, Dy); |
177 | 167 |
|
178 | | - obj.JacobianFlowVelocityMagnitudeVectorProduct = @(psi, u) otp.qg.jacflowvelmagvp(psi, u, Ddx, Ddy); |
| 168 | + obj.JacobianFlowVelocityMagnitudeVectorProduct = @(psi, u) otp.qg.jacflowvelmagvp(psi, u, Dx, Dy); |
179 | 169 |
|
180 | 170 | end |
181 | 171 |
|
|
0 commit comments