*** Wartungsfenster jeden ersten Mittwoch vormittag im Monat ***

Skip to content
Snippets Groups Projects
Commit 83cfc1af authored by Dadic, Aleksandar's avatar Dadic, Aleksandar
Browse files

Added oscillation term

parent e8206158
No related branches found
No related tags found
No related merge requests found
......@@ -10,7 +10,7 @@ pmax = 4;
lamalg = 0.1;
%% initialization for every polynomial degree
[nElem, nDofs, errEst, iterations, time, directSolveTime] = deal(zeros(pmax, 1000));
[nElem, nDofs, errEst, recovery, oscillation, iterations, time, directSolveTime] = deal(zeros(pmax, 1000));
for p = 1:pmax
%% setup geometry & spaces
printLogMessage('*** p = %d (of %d) ***', p, pmax)
......@@ -66,7 +66,7 @@ for p = 1:pmax
while ~solverIsConverged
solver.step();
u.setFreeData(solver.x)
mu2 = estimateZZ(blf, lf, u);
[mu2, recoveryTerm, oscillationTerm] = estimateZZ(blf, lf, u);
estimator = sqrt(sum(mu2));
solver.tol = lamalg*estimator;
solverIsConverged = solver.isConverged;
......@@ -76,6 +76,8 @@ for p = 1:pmax
%% estimate error and store data
nDofs(p,ell) = getDofs(fes).nDofs;
errEst(p,ell) = estimator;
recovery(p,ell) = sqrt(sum(recoveryTerm));
oscillation(p,ell) = sqrt(sum(oscillationTerm));
iterations(p, ell) = solver.iterationCount();
nElem(p,ell) = mesh.nElements;
printLogMessage('number of dofs: %d, estimator: %.2e after %d iterations', ...
......@@ -94,12 +96,21 @@ for p = 1:pmax
end
end
%% plot
figure()
colors = [[0 0.4470 0.7410];
[0.8500 0.3250 0.0980];
[0.9290 0.6940 0.1250];
[0.4940 0.1840 0.5560];
[0.4660 0.6740 0.1880];
[0.3010 0.7450 0.9330];
[0.6350 0.0780 0.1840]];
for p = 1:pmax
idx = find(nDofs(p,:) > 0);
complexity = [cumsum(nDofs(p, idx) .* iterations(p, idx))];
loglog(complexity, errEst(p,idx), '-o', 'LineWidth', 2, 'DisplayName', ['p=',num2str(p)]);
loglog(complexity, errEst(p,idx), '-o', 'LineWidth', 2, 'DisplayName', ['\mu for p=',num2str(p)], 'Color', colors(p,:));
hold on
loglog(complexity, recovery(p,idx), '-x', 'LineWidth', 2, 'DisplayName', ['recovery for p=',num2str(p)], 'Color', colors(p,:));
end
for p = unique([1,pmax])
x = complexity / complexity(1);
......@@ -113,9 +124,11 @@ title('error estimator over number of total computational cost')
%% local function for recovery based a posteriori error estimation
function indicators = estimateZZ(~, ~, u)
function [indicators, recoveryTerm, oscillationTerm] = estimateZZ(~, lf, u)
p = u.fes.finiteElement.order;
mesh = u.fes.mesh;
trafo = getAffineTransformation(mesh);
qr = QuadratureRule.ofOrder(2*p);
% Remark: Scott-Zhang operator for piecewise polynomials of degree p corresponds to nodal interpolation
......@@ -130,7 +143,55 @@ gGradU2.setData(nodalInterpolation(CompositeFunction(@(grad) grad(2,:,:), Gradie
% compute recovery term
recoveryTermHandle = @(g1, g2, grad) (g1 - grad(1,:,:)).^2 + (g2 - grad(2,:,:)).^2;
recoveryTerm = CompositeFunction(recoveryTermHandle, gGradU1, gGradU2, Gradient(u));
indicators = integrateElement(recoveryTerm, qr);
recoveryTermFunction = CompositeFunction(recoveryTermHandle, gGradU1, gGradU2, Gradient(u));
recoveryTerm = integrateElement(recoveryTermFunction, qr);
% element-wise integrals of residual and residual squared
R = CompositeFunction(@(u,f) u(1,:,:) + u(4,:,:) + f, Hessian(u), lf.f);
rIntegrals = integrateElement(R, qr);
rSquaredIntegrals = integrateElement(CompositeFunction(@(R) R.^2, R), qr);
% compute patches
patches = computePatches(mesh.elements);
patchAreas = mesh.computePatchAreas;
% compute oscillation term (projection only for p=0, i.e., integral mean)
oscillationTerm = zeros(1, mesh.nElements);
boundaryVertices = mesh.edges(:,mesh.getCombinedBndEdges);
interiorVertices = true(1, mesh.nCoordinates);
interiorVertices(boundaryVertices) = false;
interiorVertices = find(interiorVertices);
for i = 1:length(interiorVertices)
z = interiorVertices(i);
rPatchIntegral = sum(rIntegrals(patches{z}));
rSquaredPatchIntegral = sum(rSquaredIntegrals(patches{z}));
diff_integral = rSquaredPatchIntegral - (rPatchIntegral)^2 / patchAreas(z);
oscillationTerm(patches{z}) = oscillationTerm(patches{z}) + diff_integral;
end
% combine terms suitably
hT = sqrt(trafo.area);
oscillationTerm = hT.^2 .* oscillationTerm;
indicators = recoveryTerm + oscillationTerm;
end
%% local function for computing patches for each vertex
function patches = computePatches(elements)
n = size(elements, 1);
N = size(elements, 2);
patchCounts = accumarray(elements(:), 1);
ptr = cumsum([1; patchCounts]);
patchElements = zeros(n*N, 1);
for i = 1:N
for k = 1:n
idx = elements(k,i);
patchElements(ptr(idx)) = i;
ptr(idx) = ptr(idx) + 1;
end
end
patches = mat2cell(patchElements, patchCounts);
end
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment