https://github.com/H2Lib/H2Lib
Tip revision: fa39057fb97a0cb02d60c446644e2aaadec0db18 authored by schristophersen on 03 February 2017, 10:58:23 UTC
First working version for collocation BEM. Needs to be tidied up a bit.
First working version for collocation BEM. Needs to be tidied up a bit.
Tip revision: fa39057
test_tri2d.c
#include "tri2dp1.h"
#include "parameters.h"
#include "krylov.h"
#include "basic.h"
#include <stdio.h>
static uint problems = 0;
#define IS_IN_RANGE(a, b, c) (((a) <= (b)) && ((b) <= (c)))
static field
sin_solution(const real * x, void *data)
{
(void) data;
return sin(M_PI * x[0]) * sin(M_PI * x[1]);
}
static field
sin_rhs(const real * x, void *data)
{
(void) data;
return 2.0 * M_PI * M_PI * sin(M_PI * x[0]) * sin(M_PI * x[1]);
}
/* Simple convenience wrapper for conjugate gradient solver */
uint
solve_cg_sparsematrix(psparsematrix A, pavector b, pavector x,
real accuracy, uint steps)
{
addeval_t addevalA;
pavector r, p, a;
uint i, n;
real error, error2;
real norm;
n = b->dim;
assert(x->dim == n);
addevalA = (addeval_t) addeval_sparsematrix_avector;
r = new_avector(n);
p = new_avector(n);
a = new_avector(n);
random_avector(x);
norm = norm2_avector(b);
init_cg(addevalA, A, b, x, r, p, a);
error = norm2_avector(r);
for (i = 1; i < steps; i++) {
step_cg(addevalA, A, b, x, r, p, a);
error2 = norm2_avector(r);
(void) printf(" Residual (iterations %u): %.4e (%.3f) \r",
i, error2 / norm, error2 / error);
fflush(stdout);
error = error2;
if (error < accuracy * norm) {
break;
}
}
del_avector(r);
del_avector(p);
del_avector(a);
return i;
}
int
main(int argc, char **argv)
{
ptri2d *gr;
ptri2dp1 *dc;
ptri2dref *rf;
psparsematrix A, Af;
pavector xd, b, x;
uint L;
real error;
pstopwatch sw;
real runtime;
uint i;
real eps;
uint steps;
init_h2lib(&argc, &argv);
sw = new_stopwatch();
L = 8;
eps = 1e-12;
steps = 2500;
(void) printf("----------------------------------------\n"
"Creating mesh hierarchy\n");
gr = (ptri2d *) allocmem(sizeof(ptri2d) * (L + 1));
rf = (ptri2dref *) allocmem(sizeof(ptri2dref) * L);
gr[0] = new_unitsquare_tri2d();
(void) printf(" Level %2u: %u vertices, %u edges, %u triangles\n",
0, gr[0]->vertices, gr[0]->edges, gr[0]->triangles);
for (i = 0; i < L; i++) {
gr[i + 1] = refine_tri2d(gr[i], rf + i);
(void) printf(" Level %2u: %u vertices, %u edges, %u triangles\n",
i + 1, gr[i + 1]->vertices, gr[i + 1]->edges,
gr[i + 1]->triangles);
}
printf("Draw grid Level %u\n", 3);
draw_cairo_tri2d(gr[3], "mesh", 0, 0);
(void) printf("Creating discretizations\n");
dc = (ptri2dp1 *) allocmem(sizeof(ptri2dp1) * (L + 1));
for (i = 0; i <= L; i++) {
dc[i] = new_tri2dp1(gr[i]);
(void) printf(" Level %2u: %u degrees of freedom, %u fixed\n",
i, dc[i]->ndof, dc[i]->nfix);
}
for (i = 6; i <= L; i++) {
(void) printf("Testing level %u\n" " Setting up matrix\n", i);
start_stopwatch(sw);
A = build_tri2dp1_sparsematrix(dc[i]);
Af = build_tri2dp1_interaction_sparsematrix(dc[i]);
assemble_tri2dp1_laplace_sparsematrix(dc[i], A, Af);
runtime = stop_stopwatch(sw);
(void) printf(" %.1f seconds\n"
" %.1f MB (interaction %.1f MB)\n"
" %.1f KB/DoF (interaction %.1f KB/DoF)\n"
" %u non-zero entries (interaction %u)\n",
runtime,
getsize_sparsematrix(A) / 1048576.0,
getsize_sparsematrix(Af) / 1048576.0,
getsize_sparsematrix(A) / 1024.0 / dc[i]->ndof,
getsize_sparsematrix(Af) / 1024.0 / dc[i]->ndof,
A->nz, Af->nz);
(void) printf(" Setting up Dirichlet data\n");
xd = new_avector(dc[i]->nfix);
assemble_tri2dp1_dirichlet_avector(dc[i], sin_solution, 0, xd);
(void) printf(" Setting up right-hand side\n");
b = new_avector(dc[i]->ndof);
assemble_tri2dp1_functional_avector(dc[i], sin_rhs, 0, b);
(void) printf(" Starting iteration\n");
x = new_avector(dc[i]->ndof);
start_stopwatch(sw);
solve_cg_sparsematrix(A, b, x, eps, steps);
runtime = stop_stopwatch(sw);
(void) printf("\n"
" %.1f seconds\n"
" %.1f seconds per step\n", runtime, runtime / i);
error = norml2_tri2dp1(dc[i], sin_solution, 0, x, xd);
(void) printf(" rel. L^2 error %.4e %s\n", error,
(IS_IN_RANGE(1.0e-4, error, 4.0e-3) ? " okay" :
"NOT okay"));
if (!IS_IN_RANGE(1.0e-4, error, 4.0e-3))
problems++;
del_avector(x);
del_avector(b);
del_avector(xd);
del_sparsematrix(Af);
del_sparsematrix(A);
}
(void) printf("----------------------------------------\n" "Cleaning up\n");
for (i = 0; i <= L; i++)
del_tri2dp1(dc[i]);
freemem(dc);
for (i = 0; i < L; i++)
del_tri2dref(rf[i]);
freemem(rf);
for (i = 0; i <= L; i++)
del_tri2d(gr[i]);
freemem(gr);
del_stopwatch(sw);
uninit_h2lib();
return problems;
}