Пример #1
0
void
prepare_surface3d(psurface3d gr)
{
  const     real(*x)[3] = (const real(*)[3]) gr->x;
  const     uint(*t)[3] = (const uint(*)[3]) gr->t;
  real(*n)[3] = gr->n;
  real     *g = gr->g;
  real      dx[3], dy[3], dz[3];
  real      norm, height, hmin, hmax, a, b, c;
  uint      triangles = gr->triangles;
  uint      i;

  hmin = 1e30;
  hmax = 0.0;

  for (i = 0; i < triangles; i++) {
    dx[0] = x[t[i][1]][0] - x[t[i][0]][0];
    dx[1] = x[t[i][1]][1] - x[t[i][0]][1];
    dx[2] = x[t[i][1]][2] - x[t[i][0]][2];

    dy[0] = x[t[i][2]][0] - x[t[i][0]][0];
    dy[1] = x[t[i][2]][1] - x[t[i][0]][1];
    dy[2] = x[t[i][2]][2] - x[t[i][0]][2];

    dz[0] = x[t[i][2]][0] - x[t[i][1]][0];
    dz[1] = x[t[i][2]][1] - x[t[i][1]][1];
    dz[2] = x[t[i][2]][2] - x[t[i][1]][2];

    n[i][0] = dx[1] * dy[2] - dx[2] * dy[1];
    n[i][1] = dx[2] * dy[0] - dx[0] * dy[2];
    n[i][2] = dx[0] * dy[1] - dx[1] * dy[0];
    norm =
      REAL_SQRT(REAL_SQR(n[i][0]) + REAL_SQR(n[i][1]) + REAL_SQR(n[i][2]));
    g[i] = norm;
    n[i][0] /= norm;
    n[i][1] /= norm;
    n[i][2] /= norm;

    a = REAL_SQRT(REAL_SQR(dx[0]) + REAL_SQR(dx[1]) + REAL_SQR(dx[2]));
    b = REAL_SQRT(REAL_SQR(dy[0]) + REAL_SQR(dy[1]) + REAL_SQR(dy[2]));
    c = REAL_SQRT(REAL_SQR(dz[0]) + REAL_SQR(dz[1]) + REAL_SQR(dz[2]));

    height = 2.0 * REAL_MIN3(a, b, c);

    a *= a;
    b *= b;
    c *= c;

    height =
      REAL_SQRT(2 * (a * b + b * c + a * c) -
		(a * a + b * b + c * c)) / height;

    hmin = REAL_MIN(hmin, height);
    hmax = REAL_MAX(hmax, height);
  }

  gr->hmin = hmin;
  gr->hmax = hmax;
}
Пример #2
0
field
rhs_dirichlet_point_helmholtzbem3d(const real * x, const real * n,
				   const void *data)
{

  helmholtz_data *hdata = (helmholtz_data *) data;
  field    *kvec = hdata->kvec;
  field     k =
    REAL_SQRT(ABSSQR(kvec[0]) + ABSSQR(kvec[1]) + ABSSQR(kvec[2]));
  real     *s = hdata->source;

  real      r =
    REAL_SQRT(REAL_SQR(x[0] - s[0]) + REAL_SQR(x[1] - s[1]) +
	      REAL_SQR(x[2] - s[2]));

  (void) n;

  return cexp(I * k * r) / r;
}
Пример #3
0
real
max_rel_inner_error(pcbem3d bem, helmholtz_data * hdata, pcavector x,
		    boundary_func3d rhs)
{
  uint      nx, nz, npoints;
  real(*xdata)[3];
  field    *ydata;
  uint      i, j;
  real      error, maxerror;
  real      eta_bw =
    REAL_SQRT(ABSSQR(bem->kvec[0]) + ABSSQR(bem->kvec[1]) +
	      ABSSQR(bem->kvec[2]));

  nx = 20;
  nz = 20;
  npoints = nx * nz;

  xdata = (real(*)[3]) allocreal(3 * npoints);
  npoints = 0;
  for (j = 0; j < nz; ++j) {
    for (i = 0; i < nx; ++i) {
      xdata[npoints][0] = -1.0 + (2.0 / (nx - 1)) * i;
      xdata[npoints][1] = 0.0;
      xdata[npoints][2] = -1.0 + (2.0 / (nz - 1)) * j;
      if (REAL_SQR(xdata[npoints][0]) + REAL_SQR(xdata[npoints][2]) < 1) {
	npoints++;
      }
    }
  }

  ydata = allocfield(npoints);

#pragma omp parallel for
  for (j = 0; j < npoints; ++j) {
    ydata[j] = eval_brakhage_werner_c(bem, x, eta_bw, xdata[j]);
  }

  j = 0;
  maxerror =
    ABS(ydata[j] -
	rhs(xdata[j], NULL, hdata)) / ABS(rhs(xdata[j], NULL, hdata));
  for (j = 1; j < npoints; ++j) {
    error =
      ABS(ydata[j] -
	  rhs(xdata[j], NULL, hdata)) / ABS(rhs(xdata[j], NULL, hdata));

    maxerror = error > maxerror ? error : maxerror;
  }

  freemem(ydata);
  freemem(xdata);

  return maxerror;
}
Пример #4
0
real
getdiam_2_cluster(pccluster t)
{
  real      diam2;
  uint      i;

  diam2 = 0.0;
  for (i = 0; i < t->dim; i++)
    diam2 += REAL_SQR(t->bmax[i] - t->bmin[i]);

  return REAL_SQRT(diam2);
}
Пример #5
0
bool
parabolic_admissibility(pdcluster rc, pdcluster cc, uint l,
			uint * rd, uint * cd, void *data)
{
  pcdiradmdata dad = (pcdiradmdata) data;
  real      eta2 = dad->eta2;
  real      wave_k = dad->wave_k;
  preal     xy = dad->xy;
  real      rdiam, cdiam, dist, dist2, invdist;
  uint      dim;
  uint      i, iota;

  dim = rc->dim;
  assert(cc->dim == dim);

  /* Compute cluster diameters */
  rdiam = diam_dcluster(rc);
  cdiam = diam_dcluster(cc);

  /* Compute distance */
  dist = dist_dcluster(rc, cc);

  /* Check parabolic admissibility condition */
  if (wave_k * rdiam * rdiam <= eta2 * dist &&
      wave_k * cdiam * cdiam <= eta2 * dist &&
      rdiam <= eta2 * dist && cdiam <= eta2 * dist) {

    /* Compute distance of midpoints */
    dist2 = 0.0;
    for (i = 0; i < dim; i++) {
      xy[i] = 0.5 * (rc->bmax[i] + rc->bmin[i]
		     - cc->bmax[i] - cc->bmin[i]);
      dist2 += REAL_SQR(xy[i]);
    }
    invdist = 1.0 / REAL_SQRT(dist2);

    /* Scale distance vector... */
    for (i = 0; i < dim; i++)
      xy[i] *= invdist;

    /* ... and choose a direction that is sufficiently close */
    iota = finddirection_leveldir(dad->ld, l, 1.0, xy);
    *rd = iota;
    *cd = iota;

    return true;
  }

  *rd = 0;
  *cd = 0;

  return false;
}
Пример #6
0
field
rhs_neumann_point_helmholtzbem3d(const real * x, const real * n,
				 const void *data)
{
  helmholtz_data *hdata = (helmholtz_data *) data;
  field    *kvec = hdata->kvec;
  field     k =
    REAL_SQRT(ABSSQR(kvec[0]) + ABSSQR(kvec[1]) + ABSSQR(kvec[2]));
  real     *s = hdata->source;

  real      r =
    REAL_SQRT(REAL_SQR(x[0] - s[0]) + REAL_SQR(x[1] - s[1]) +
	      REAL_SQR(x[2] - s[2]));

  field     res;

  res = cexp(I * k * r) / (r * r * r) * (I * k * r - 1.0);
  res = res
    * (n[0] * (x[0] - s[0]) + n[1] * (x[1] - s[1]) + n[2] * (x[2] - s[2]));

  return res;
}
Пример #7
0
void
smooth_unitcircle_tri2d(ptri2d t2)
{
  uint      i;
  real      normL2, normL1;

  /* Scaling vertices */
  for (i = 0; i < t2->vertices; i++) {
    normL1 = REAL_ABS(t2->x[i][0]) + REAL_ABS(t2->x[i][1]);
    normL2 = REAL_SQRT(t2->x[i][0] * t2->x[i][0] + t2->x[i][1] * t2->x[i][1]);
    if (normL1 != 0.0) {
      t2->x[i][0] = t2->x[i][0] * normL1 / normL2;
      t2->x[i][1] = t2->x[i][1] * normL1 / normL2;
    }
  }
}
Пример #8
0
real
getdist_2_cluster(pccluster t, pccluster s)
{
  real      dist2;
  uint      i;

  assert(t->dim == s->dim);

  dist2 = 0.0;
  for (i = 0; i < t->dim; i++)
    if (t->bmax[i] < s->bmin[i])	/* t to the "left" of s */
      dist2 += REAL_SQR(s->bmin[i] - t->bmax[i]);
    else if (s->bmax[i] < t->bmin[i])	/* t to the "right" of s */
      dist2 += REAL_SQR(t->bmin[i] - s->bmax[i]);

  return REAL_SQRT(dist2);
}
Пример #9
0
/* Compute the L_2-error for constant basis functions */
static real
L2gamma_c_diff_norm2(pbem2d bem, pavector x, boundary_func2d rhs)
{
  pccurve2d gr = bem->gr;
  const     real(*gr_x)[2] = (const real(*)[2]) gr->x;
  const     uint(*gr_e)[2] = (const uint(*)[2]) gr->e;
  const     real(*gr_n)[2] = (const real(*)[2]) gr->n;
  const preal gr_g = (const preal) gr->g;
  uint      n = x->dim;
  uint      nq = bem->sq->n_single;
  real     *xx = bem->sq->x_single;
  real     *ww = bem->sq->w_single;

  const real *A, *B, *N;
  uint      e, q;
  real      norm, sum, X[2], tx, Ax, Bx;

  assert(n == gr->edges);

  norm = 0.0;
  for (e = 0; e < n; ++e) {
    A = gr_x[gr_e[e][0]];
    B = gr_x[gr_e[e][1]];
    N = gr_n[e];

    sum = 0.0;

    for (q = 0; q < nq; ++q) {
      tx = xx[q];
      Ax = 1.0 - tx;
      Bx = tx;

      X[0] = A[0] * Ax + B[0] * Bx;
      X[1] = A[1] * Ax + B[1] * Bx;

      sum += ww[q] * ABSSQR(rhs(X, N) - x->v[e]);
    }

    norm += sum * gr_g[e];
  }

  norm = REAL_SQRT(norm);

  return norm;
}
Пример #10
0
void
prepare_curve2d(pcurve2d gr)
{
  const     real(*x)[2] = (const real(*)[2]) gr->x;
  const     uint(*e)[2] = (const uint(*)[2]) gr->e;
  real(*n)[2] = gr->n;
  real     *g = gr->g;
  real      norm;
  uint      edges = gr->edges;
  uint      i;

  for (i = 0; i < edges; i++) {
    n[i][0] = x[e[i][1]][1] - x[e[i][0]][1];
    n[i][1] = x[e[i][0]][0] - x[e[i][1]][0];
    norm = REAL_SQRT(REAL_SQR(n[i][0]) + REAL_SQR(n[i][1]));
    g[i] = norm;
    n[i][0] /= norm;
    n[i][1] /= norm;
  }
}
Пример #11
0
real
norm2chol_sparsematrix(pchmatrix LU, pcsparsematrix sp)
{
  avector   tmp1, tmp2;
  uint      rows = LU->rc->size;
  uint      cols = LU->cc->size;
  pavector  x, y;
  real      norm;
  uint      j;

  assert(sp->rows == rows);
  assert(sp->cols == cols);

  x = init_avector(&tmp1, cols);
  y = init_avector(&tmp2, rows);

  random_avector(x);
  norm = norm2_avector(x);
  scale_avector(1.0 / norm, x);

  for (j = 0; j < NORM_STEPS; j++) {
    // printf("norm = %g \n", sqrt( norm));
    clear_avector(y);
    mvm_sparsematrix_avector(1.0, false, sp, x, y);
    triangularsolve_hmatrix_avector(true, false, false, LU, y);
    triangularsolve_hmatrix_avector(true, false, true, LU, y);
    add_avector(-1.0, y, x);
    copy_avector(x, y);
    triangularsolve_hmatrix_avector(true, false, false, LU, y);
    triangularsolve_hmatrix_avector(true, false, true, LU, y);
    mvm_sparsematrix_avector(-1.0, true, sp, y, x);
    norm = norm2_avector(x);
    scale_avector(1.0 / norm, x);
  }

  uninit_avector(y);
  uninit_avector(x);

  return REAL_SQRT(norm);
}
Пример #12
0
void
statistics_tet3d(pctet3d t3, preal hmin, preal hmax, preal volmin,
		 preal volmax, preal relvolmin, preal relvolmax)
{
  const     real(*x)[3] = (const real(*)[3]) t3->x;
  uint      tetrahedra = t3->tetrahedra;
  real      xl[4][3];
  real      xd[6][3];
  real      h, norm, vol;
  uint      v[4];
  uint      i, j;

  for (i = 0; i < tetrahedra; i++) {
    getvertices_tet3d(t3, i, v);

    /* Get coordinates of vertices */
    for (j = 0; j < 4; j++) {
      xl[j][0] = x[v[j]][0];
      xl[j][1] = x[v[j]][1];
      xl[j][2] = x[v[j]][2];
    }

    /* Compute edge vectors */
    xd[0][0] = xl[1][0] - xl[0][0];
    xd[0][1] = xl[1][1] - xl[0][1];
    xd[0][2] = xl[1][2] - xl[0][2];

    xd[1][0] = xl[2][0] - xl[0][0];
    xd[1][1] = xl[2][1] - xl[0][1];
    xd[1][2] = xl[2][2] - xl[0][2];

    xd[2][0] = xl[3][0] - xl[0][0];
    xd[2][1] = xl[3][1] - xl[0][1];
    xd[2][2] = xl[3][2] - xl[0][2];

    xd[3][0] = xl[2][0] - xl[1][0];
    xd[3][1] = xl[2][1] - xl[1][1];
    xd[3][2] = xl[2][2] - xl[1][2];

    xd[4][0] = xl[3][0] - xl[1][0];
    xd[4][1] = xl[3][1] - xl[1][1];
    xd[4][2] = xl[3][2] - xl[1][2];

    xd[5][0] = xl[3][0] - xl[2][0];
    xd[5][1] = xl[3][1] - xl[2][1];
    xd[5][2] = xl[3][2] - xl[2][2];

    /* Update h, hmin and hmax */
    h = 0.0;
    for (j = 0; j < 6; j++) {
      norm =
	REAL_SQRT(REAL_SQR(xd[j][0]) + REAL_SQR(xd[j][1]) +
		  REAL_SQR(xd[j][2]));
      if (i == 0 || norm < *hmin)
	*hmin = norm;
      if (i == 0 || norm > *hmax)
	*hmax = norm;
      if (norm > h)
	h = norm;
    }

    /* Compute volume */
    vol = fabs(xd[0][0] * xd[1][1] * xd[2][2] + xd[1][0] * xd[2][1] * xd[0][2]
	       + xd[2][0] * xd[0][1] * xd[1][2]
	       - xd[0][0] * xd[2][1] * xd[1][2]
	       - xd[1][0] * xd[0][1] * xd[2][2]
	       - xd[2][0] * xd[1][1] * xd[0][2])
      / 6.0;
    if (i == 0 || vol < *volmin)
      *volmin = vol;
    if (i == 0 || vol > *volmax)
      *volmax = vol;

    /* Compute relative volume */
    vol /= h * h * h;
    if (i == 0 || vol < *relvolmin)
      *relvolmin = vol;
    if (i == 0 || vol > *relvolmax)
      *relvolmax = vol;
  }
}
Пример #13
0
ptet3d
new_regular_tet3d()
{
  ptet3d    t3;
  real      r, h, c, y;

  r = 1.0;
  h = REAL_SQRT(2.0) - 1.0;
  c = REAL_SQRT(0.75);
  y = 1.0 - REAL_SQRT(0.5);

  t3 = new_tet3d(4, 6, 4, 1);

  t3->x[0][0] = 0.0;
  t3->x[0][1] = -h - y;
  t3->x[0][2] = -r;
  t3->x[1][0] = -c * r;
  t3->x[1][1] = -h - y;
  t3->x[1][2] = 0.5 * r;
  t3->x[2][0] = c * r;
  t3->x[2][1] = -h - y;
  t3->x[2][2] = 0.5 * r;
  t3->x[3][0] = 0.0;
  t3->x[3][1] = 1.0 - y;
  t3->x[3][2] = 0.0;

  t3->e[0][0] = 1;
  t3->e[0][1] = 2;
  t3->e[1][0] = 2;
  t3->e[1][1] = 3;
  t3->e[2][0] = 3;
  t3->e[2][1] = 1;
  t3->e[3][0] = 0;
  t3->e[3][1] = 1;
  t3->e[4][0] = 0;
  t3->e[4][1] = 2;
  t3->e[5][0] = 0;
  t3->e[5][1] = 3;

  t3->f[0][0] = 1;
  t3->f[0][1] = 2;
  t3->f[0][2] = 0;
  t3->f[1][0] = 1;
  t3->f[1][1] = 4;
  t3->f[1][2] = 5;
  t3->f[2][0] = 2;
  t3->f[2][1] = 5;
  t3->f[2][2] = 3;
  t3->f[3][0] = 0;
  t3->f[3][1] = 3;
  t3->f[3][2] = 4;

  t3->t[0][0] = 0;
  t3->t[0][1] = 1;
  t3->t[0][2] = 2;
  t3->t[0][3] = 3;

  t3->xb[0] = t3->xb[1] = t3->xb[2] = t3->xb[3] = 1;
  t3->eb[0] = t3->eb[1] = t3->eb[2] = t3->eb[3] = t3->eb[4] = t3->eb[5] = 1;
  t3->fb[0] = t3->fb[1] = t3->fb[2] = t3->fb[3] = 1;

  t3->vertices = 4;
  t3->edges = 6;
  t3->faces = 4;
  t3->tetrahedra = 1;

  return t3;
}
Пример #14
0
int
main(int argc, char **argv)
{
  pmacrosurface3d mg;
  psurface3d gr;
  pamatrix  Vfull, KMfull;
  pbem3d    bem_slp, bem_dlp;
  pcluster  root;
  pblock block;
  phmatrix  V, KM;
  pclusterbasis Vrb, Vcb, KMrb, KMcb;
  ph2matrix V2, KM2;
  uint      n, q, clf, m, l;
  real      eta, delta, eps_aca;
  field     kvec[3];
  cl_device_id *devices;
  cl_uint   ndevices;
  uint     *idx;
  uint      i;

  init_h2lib(&argc, &argv);

  get_opencl_devices(&devices, &ndevices);
  ndevices = 1;
  set_opencl_devices(devices, ndevices, 2);

  kvec[0] = 2.0, kvec[1] = 0.0, kvec[2] = 0.0;
  n = 512;
  q = 2;
  clf = 16;
  eta = 1.0;

  mg = new_sphere_macrosurface3d();
  gr = build_from_macrosurface3d_surface3d(mg, REAL_SQRT(n * 0.125));
  n = gr->triangles;

  printf("Testing unit sphere with %d triangles\n", n);

  bem_slp = new_slp_helmholtz_ocl_bem3d(kvec, gr, q, q + 2,
					BASIS_CONSTANT_BEM3D);
  bem_dlp = new_dlp_helmholtz_ocl_bem3d(kvec, gr, q, q + 2,
					BASIS_CONSTANT_BEM3D,
					BASIS_CONSTANT_BEM3D, 0.5);
  root = build_bem3d_cluster(bem_slp, clf, BASIS_CONSTANT_BEM3D);
  block = build_nonstrict_block(root, root, &eta, admissible_max_cluster);

  max_pardepth = 0;

  Vfull = new_amatrix(n, n);
  KMfull = new_amatrix(n, n);
  idx = allocuint(n);
  for (i = 0; i < n; ++i) {
    idx[i] = i;
  }
  SCHEDULE_OPENCL(0, 1, bem_slp->nearfield, idx, idx, bem_slp, false, Vfull);
  SCHEDULE_OPENCL(0, 1, bem_dlp->nearfield, idx, idx, bem_dlp, false, KMfull);

  V = build_from_block_hmatrix(block, 0);
  KM = build_from_block_hmatrix(block, 0);

  printf("----------------------------------------\n");
  printf("Testing outer Boundary integral equations:\n");
  printf("----------------------------------------\n\n");

  /*
   * Test Interpolation
   */

  m = 4;

  setup_hmatrix_aprx_inter_row_bem3d(bem_slp, root, root, block, m);
  setup_hmatrix_aprx_inter_row_bem3d(bem_dlp, root, root, block, m);
  test_hmatrix_system("Interpolation row", Vfull, KMfull, block, bem_slp, V,
		      bem_dlp, KM, false, true, 1.0e-3, 2.0e-3);

  setup_hmatrix_aprx_inter_col_bem3d(bem_slp, root, root, block, m);
  setup_hmatrix_aprx_inter_col_bem3d(bem_dlp, root, root, block, m);
  test_hmatrix_system("Interpolation column", Vfull, KMfull, block, bem_slp,
		      V, bem_dlp, KM, false, true, 1.0e-3, 2.0e-3);

  setup_hmatrix_aprx_inter_mixed_bem3d(bem_slp, root, root, block, m);
  setup_hmatrix_aprx_inter_mixed_bem3d(bem_dlp, root, root, block, m);
  test_hmatrix_system("Interpolation mixed", Vfull, KMfull, block, bem_slp, V,
		      bem_dlp, KM, false, true, 1.0e-3, 2.0e-3);

  /*
   * Test Green
   */

  m = 5;
  l = 1;
  delta = 0.5;

  setup_hmatrix_aprx_green_row_bem3d(bem_slp, root, root, block, m, l, delta,
				     build_bem3d_cube_quadpoints);
  setup_hmatrix_aprx_green_row_bem3d(bem_dlp, root, root, block, m, l, delta,
				     build_bem3d_cube_quadpoints);
  test_hmatrix_system("Green row", Vfull, KMfull, block, bem_slp, V, bem_dlp,
		      KM, false, true, 1.0e-3, 2.0e-3);

  setup_hmatrix_aprx_green_col_bem3d(bem_slp, root, root, block, m, l, delta,
				     build_bem3d_cube_quadpoints);
  setup_hmatrix_aprx_green_col_bem3d(bem_dlp, root, root, block, m, l, delta,
				     build_bem3d_cube_quadpoints);
  test_hmatrix_system("Green column", Vfull, KMfull, block, bem_slp, V,
		      bem_dlp, KM, false, true, 1.0e-3, 2.0e-3);

  setup_hmatrix_aprx_green_mixed_bem3d(bem_slp, root, root, block, m, l,
				       delta, build_bem3d_cube_quadpoints);
  setup_hmatrix_aprx_green_mixed_bem3d(bem_dlp, root, root, block, m, l,
				       delta, build_bem3d_cube_quadpoints);
  test_hmatrix_system("Green mixed", Vfull, KMfull, block, bem_slp, V,
		      bem_dlp, KM, false, true, 1.0e-3, 2.0e-3);

  /*
   * Test Greenhybrid
   */

  m = 2;
  l = 1;
  delta = 1.0;
  eps_aca = 2.0e-2;

  setup_hmatrix_aprx_greenhybrid_row_bem3d(bem_slp, root, root, block, m, l,
					   delta, eps_aca,
					   build_bem3d_cube_quadpoints);
  setup_hmatrix_aprx_greenhybrid_row_bem3d(bem_dlp, root, root, block, m, l,
					   delta, eps_aca,
					   build_bem3d_cube_quadpoints);
  test_hmatrix_system("Greenhybrid row", Vfull, KMfull, block, bem_slp, V,
		      bem_dlp, KM, false, true, 1.0e-3, 2.0e-3);

  setup_hmatrix_aprx_greenhybrid_col_bem3d(bem_slp, root, root, block, m, l,
					   delta, eps_aca,
					   build_bem3d_cube_quadpoints);
  setup_hmatrix_aprx_greenhybrid_col_bem3d(bem_dlp, root, root, block, m, l,
					   delta, eps_aca,
					   build_bem3d_cube_quadpoints);
  test_hmatrix_system("Greenhybrid column", Vfull, KMfull, block, bem_slp, V,
		      bem_dlp, KM, false, true, 1.0e-3, 2.0e-3);

  setup_hmatrix_aprx_greenhybrid_mixed_bem3d(bem_slp, root, root, block, m, l,
					     delta, eps_aca,
					     build_bem3d_cube_quadpoints);
  setup_hmatrix_aprx_greenhybrid_mixed_bem3d(bem_dlp, root, root, block, m, l,
					     delta, eps_aca,
					     build_bem3d_cube_quadpoints);
  test_hmatrix_system("Greenhybrid mixed", Vfull, KMfull, block, bem_slp, V,
		      bem_dlp, KM, false, true, 1.0e-3, 2.0e-3);

  /*
   * Test ACA / PACA / HCA
   */

  m = 2;
  eps_aca = 1.0e-2;

  /* Nearfield computation on GPU not applicable here yet! */

//  setup_hmatrix_aprx_aca_bem3d(bem_slp, root, root, block, eps_aca);
//  setup_hmatrix_aprx_aca_bem3d(bem_dlp, root, root, block, eps_aca);
//  test_hmatrix_system("ACA full pivoting", Vfull, KMfull, block, bem_slp, V,
//      bem_dlp, KM, false, true, 1.0e-3, 2.0e-3);
//
//  setup_hmatrix_aprx_paca_bem3d(bem_slp, root, root, block, eps_aca);
//  setup_hmatrix_aprx_paca_bem3d(bem_slp, root, root, block, eps_aca);
//  test_hmatrix_system("ACA partial pivoting", Vfull, KMfull, block, bem_slp, V,
//      bem_dlp, KM, false, true, 1.0e-3, 2.0e-3);
  setup_hmatrix_aprx_hca_bem3d(bem_slp, root, root, block, m, eps_aca);
  setup_hmatrix_aprx_hca_bem3d(bem_slp, root, root, block, m, eps_aca);
  test_hmatrix_system("HCA2", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM,
		      false, true, 1.0e-3, 2.0e-3);

  del_hmatrix(V);
  del_hmatrix(KM);
  del_block(block);

  /*
   * H2-matrix
   */

  block = build_strict_block(root, root, &eta, admissible_max_cluster);

  Vrb = build_from_cluster_clusterbasis(root);
  Vcb = build_from_cluster_clusterbasis(root);
  KMrb = build_from_cluster_clusterbasis(root);
  KMcb = build_from_cluster_clusterbasis(root);

  V2 = build_from_block_h2matrix(block, Vrb, Vcb);
  KM2 = build_from_block_h2matrix(block, KMrb, KMcb);

  /*
   * Test Interpolation
   */

  m = 3;

  setup_h2matrix_aprx_inter_bem3d(bem_slp, Vrb, Vcb, block, m);
  setup_h2matrix_aprx_inter_bem3d(bem_dlp, KMrb, KMcb, block, m);
  test_h2matrix_system("Interpolation", Vfull, KMfull, block, bem_slp, V2,
		       bem_dlp, KM2, false, true, 1.0e-3, 2.0e-3);

  /*
   * Test Greenhybrid
   */

  m = 2;
  l = 1;
  delta = 1.0;
  eps_aca = 2.0e-2;

  setup_h2matrix_aprx_greenhybrid_bem3d(bem_slp, Vrb, Vcb, block, m, l, delta,
					eps_aca, build_bem3d_cube_quadpoints);
  setup_h2matrix_aprx_greenhybrid_bem3d(bem_dlp, KMrb, KMcb, block, m, l,
					delta, eps_aca,
					build_bem3d_cube_quadpoints);
  test_h2matrix_system("Greenhybrid", Vfull, KMfull, block, bem_slp, V2,
		       bem_dlp, KM2, false, true, 1.0e-3, 2.0e-3);

  /* Nearfield computation on GPU not applicable here yet! */

//  setup_h2matrix_aprx_greenhybrid_ortho_bem3d(bem_slp, Vrb, Vcb, block, m, l,
//      delta, eps_aca, build_bem3d_cube_quadpoints);
//  setup_h2matrix_aprx_greenhybrid_ortho_bem3d(bem_dlp, KMrb, KMcb, block, m, l,
//      delta, eps_aca, build_bem3d_cube_quadpoints);
//  test_h2matrix_system("Greenhybrid ortho", Vfull, KMfull, block, bem_slp, V2,
//      bem_dlp, KM2, false, true, 1.0e-3, 2.0e-3);
  del_h2matrix(V2);
  del_h2matrix(KM2);
  del_block(block);
  freemem(root->idx);
  del_cluster(root);
  del_helmholtz_ocl_bem3d(bem_slp);
  del_helmholtz_ocl_bem3d(bem_dlp);

  del_amatrix(Vfull);
  del_amatrix(KMfull);
  del_surface3d(gr);
  del_macrosurface3d(mg);
  freemem(idx);

  (void) printf("----------------------------------------\n"
		"  %u matrices and\n"
		"  %u vectors still active\n"
		"  %u errors found\n", getactives_amatrix(),
		getactives_avector(), problems);

  uninit_h2lib();

  return problems;
}
Пример #15
0
static void
test_h2matrix_system(const char *apprxtype, pcamatrix Vfull,
		     pcamatrix KMfull, pblock block, pbem3d bem_slp,
		     ph2matrix V, pbem3d bem_dlp, ph2matrix KM, bool linear,
		     bool exterior, real low, real high)
{
  struct _eval_A eval;
  helmholtz_data hdata;
  pavector  x, b;
  real      errorV, errorKM, error_solve, eps_solve;
  uint      steps;
  boundary_func3d rhs = (boundary_func3d) rhs_dirichlet_point_helmholtzbem3d;

  eps_solve = 1.0e-12;
  steps = 1000;

  printf("Testing: %s H2matrix %s\n"
	 "====================================\n\n",
	 (exterior == true ? "exterior" : "interior"), apprxtype);

  assemble_bem3d_h2matrix_row_clusterbasis(bem_slp, V->rb);
  assemble_bem3d_h2matrix_col_clusterbasis(bem_slp, V->cb);
  SCHEDULE_OPENCL(0, 1, assemble_bem3d_h2matrix, bem_slp, block, V);

  assemble_bem3d_h2matrix_row_clusterbasis(bem_dlp, KM->rb);
  assemble_bem3d_h2matrix_col_clusterbasis(bem_dlp, KM->cb);
  SCHEDULE_OPENCL(0, 1, assemble_bem3d_h2matrix, bem_dlp, block, KM);

  eval.V = V;
  eval.Vtype = H2MATRIX;
  eval.KM = KM;
  eval.KMtype = H2MATRIX;
  eval.eta =
    REAL_SQRT(ABSSQR(bem_slp->kvec[0]) + ABSSQR(bem_slp->kvec[1]) +
	      ABSSQR(bem_slp->kvec[2]));

  hdata.kvec = bem_slp->kvec;
  hdata.source = allocreal(3);
  if (exterior) {
    hdata.source[0] = 0.0, hdata.source[1] = 0.0, hdata.source[2] = 0.2;
  }
  else {
    hdata.source[0] = 0.0, hdata.source[1] = 0.0, hdata.source[2] = 5.0;
  }

  errorV = norm2diff_amatrix_h2matrix(V, Vfull) / norm2_amatrix(Vfull);
  printf("rel. error V       : %.5e\n", errorV);
  errorKM = norm2diff_amatrix_h2matrix(KM, KMfull) / norm2_amatrix(KMfull);
  printf("rel. error K%c0.5*M : %.5e\n", (exterior == true ? '-' : '+'),
	 errorKM);

  x = new_avector(Vfull->rows);
  b = new_avector(KMfull->cols);

  printf("Solving Dirichlet problem:\n");

  integrate_bem3d_const_avector(bem_dlp, rhs, b, (void *) &hdata);

  solve_gmres_bem3d(HMATRIX, &eval, b, x, eps_solve, steps);

  error_solve = max_rel_outer_error(bem_slp, &hdata, x, rhs);

  printf("max. rel. error : %.5e       %s\n", error_solve,
	 (IS_IN_RANGE(low, error_solve, high) ? "    okay" : "NOT okay"));

  if (!IS_IN_RANGE(low, error_solve, high))
    problems++;

  printf("\n");

  del_avector(x);
  del_avector(b);
  freemem(hdata.source);
}
Пример #16
0
void
draw_cairo_tri2d(pctri2d t2, const char *filename, bool mark_refedges,
		 int mark_triangle)
{
#ifdef USE_CAIRO
  cairo_surface_t *surface;
  cairo_t  *cr;
  const     real(*x)[2] = (const real(*)[2]) t2->x;
  const     uint(*e)[2] = (const uint(*)[2]) t2->e;
  const     uint(*t)[3] = (const uint(*)[3]) t2->t;
  uint      vertices = t2->vertices;
  uint      edges = t2->edges;
  uint      triangles = t2->triangles;
  double    xmin, xmax, ymin, ymax;
  double    hmin, hk, x0, y0, dx, dy, nx, ny;
  uint      k;

  xmin = xmax = x[0][0];
  ymin = ymax = x[0][1];
  for (k = 1; k < vertices; k++) {
    if (x[k][0] < xmin)
      xmin = x[k][0];
    else if (x[k][0] > xmax)
      xmax = x[k][0];
    if (x[k][1] < ymin)
      ymin = x[k][1];
    else if (x[k][1] > ymax)
      ymax = x[k][1];
  }

  surface = cairo_pdf_surface_create(filename, 100.0 * (xmax - xmin),
				     100.0 * (ymax - ymin));
  cr = cairo_create(surface);
  cairo_surface_destroy(surface);
  cairo_translate(cr, -100.0 * xmin, -100.0 * ymin);
  cairo_scale(cr, 95.0, 95.0);
  cairo_set_line_width(cr, cairo_get_line_width(cr) / 95.0);
  cairo_scale(cr, 1.0, -1.0);

  cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
  if (mark_triangle >= 0) {
    k = mark_triangle;
    cairo_move_to(cr, x[e[t[k][0]][0]][0], x[e[t[k][0]][0]][1]);
    cairo_line_to(cr, x[e[t[k][0]][1]][0], x[e[t[k][0]][1]][1]);
    if (e[t[k][1]][0] == e[t[k][0]][0] || e[t[k][1]][0] == e[t[k][0]][1])
      cairo_line_to(cr, x[e[t[k][1]][1]][0], x[e[t[k][1]][1]][1]);
    else
      cairo_line_to(cr, x[e[t[k][1]][0]][0], x[e[t[k][1]][0]][1]);
    cairo_close_path(cr);
    cairo_fill(cr);
  }

  if (mark_refedges) {
    hmin =
      REAL_SQRT(REAL_SQR(x[e[0][0]][0] - x[e[0][1]][0]) +
		REAL_SQR(x[e[0][0]][1] - x[e[0][1]][1]));
    for (k = 1; k < edges; k++) {
      hk =
	REAL_SQRT(REAL_SQR(x[e[k][0]][0] - x[e[k][1]][0]) +
		  REAL_SQR(x[e[k][0]][1] - x[e[k][1]][1]));
      if (hk < hmin)
	hmin = hk;
    }

    hk = xmax - xmin;
    if (ymax - ymin < hk)
      hk = ymax - ymin;
    if (hmin > 0.05 * hk)
      hmin = 0.05 * hk;

    cairo_set_source_rgb(cr, 0.0, 0.0, 1.0);
    for (k = 0; k < triangles; k++) {
      cairo_move_to(cr, x[e[t[k][0]][0]][0], x[e[t[k][0]][0]][1]);
      cairo_line_to(cr, x[e[t[k][0]][1]][0], x[e[t[k][0]][1]][1]);

      nx = x[e[t[k][0]][1]][1] - x[e[t[k][0]][0]][1];
      ny = x[e[t[k][0]][0]][0] - x[e[t[k][0]][1]][0];
      hk = REAL_SQRT(REAL_SQR(nx) + REAL_SQR(ny));
      nx /= hk;
      ny /= hk;

      if (e[t[k][1]][0] == e[t[k][2]][0] || e[t[k][1]][0] == e[t[k][2]][1]) {
	x0 = x[e[t[k][1]][0]][0];
	y0 = x[e[t[k][1]][0]][1];
      }
      else {
	assert(e[t[k][1]][1] == e[t[k][2]][0]
	       || e[t[k][1]][1] == e[t[k][2]][1]);
	x0 = x[e[t[k][1]][1]][0];
	y0 = x[e[t[k][1]][1]][1];
      }

      dx = x0 - x[e[t[k][0]][1]][0];
      dy = y0 - x[e[t[k][0]][1]][1];
      hk = REAL_ABS(dx * nx + dy * ny);
      dx /= hk;
      dy /= hk;
      cairo_line_to(cr, x[e[t[k][0]][1]][0] + hmin * 0.2 * dx,
		    x[e[t[k][0]][1]][1] + hmin * 0.2 * dy);

      dx = x0 - x[e[t[k][0]][0]][0];
      dy = y0 - x[e[t[k][0]][0]][1];
      hk = REAL_ABS(dx * nx + dy * ny);
      dx /= hk;
      dy /= hk;
      cairo_line_to(cr, x[e[t[k][0]][0]][0] + hmin * 0.2 * dx,
		    x[e[t[k][0]][0]][1] + hmin * 0.2 * dy);

      cairo_close_path(cr);
      cairo_fill(cr);
    }
  }

  cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
  for (k = 0; k < edges; k++) {
    cairo_move_to(cr, x[e[k][0]][0], x[e[k][0]][1]);
    cairo_line_to(cr, x[e[k][1]][0], x[e[k][1]][1]);
    cairo_stroke(cr);
  }

  cairo_destroy(cr);
#else
  fprintf(stderr, "CAIRO not supported.\n");
#endif
}
Пример #17
0
field
eval_brakhage_werner_c(pcbem3d bem, pcavector w, field eta, real * x)
{
  pcsurface3d gr = bem->gr;
  const     real(*gr_x)[3] = (const real(*)[3]) gr->x;
  const     uint(*gr_t)[3] = (const uint(*)[3]) gr->t;
  const     real(*gr_n)[3] = (const real(*)[3]) gr->n;
  const preal gr_g = (const preal) gr->g;
  const uint rows = gr->triangles;
  const field *kvec = bem->kvec;

  uint      nq = bem->sq->n_single;
  real     *xx = bem->sq->x_single;
  real     *yy = bem->sq->y_single;
  real     *ww = bem->sq->w_single + 3 * nq;

  const real *A, *B, *C, *ns;
  uint      s, ss, q;
  real      gs_fac, dx, dy, dz, tx, sx, Ax, Bx, Cx, norm, rnorm, norm2;
  field     k, sum;

  field     res;

  k = REAL_SQRT(ABSSQR(kvec[0]) + ABSSQR(kvec[1]) + ABSSQR(kvec[2]));

  /*
   *  integrate kernel function over first variable with constant basisfunctions
   */

  res = 0.0;

  for (s = 0; s < rows; ++s) {
    ss = s;
    gs_fac = gr_g[ss] * 0.0795774715459476679;
    ns = gr_n[ss];
    A = gr_x[gr_t[ss][0]];
    B = gr_x[gr_t[ss][1]];
    C = gr_x[gr_t[ss][2]];

    sum = 0.0;

    for (q = 0; q < nq; ++q) {
      tx = xx[q];
      sx = yy[q];
      Ax = 1.0 - tx;
      Bx = tx - sx;
      Cx = sx;

      dx = x[0] - (A[0] * Ax + B[0] * Bx + C[0] * Cx);
      dy = x[1] - (A[1] * Ax + B[1] * Bx + C[1] * Cx);
      dz = x[2] - (A[2] * Ax + B[2] * Bx + C[2] * Cx);

      norm2 = dx * dx + dy * dy + dz * dz;
      rnorm = REAL_RSQRT(norm2);
      norm = norm2 * rnorm;
      rnorm *= rnorm * rnorm;

      sum += ww[q]
	* cexp(I * k * norm)
	* rnorm
	* ((1.0 - I * k * norm) * (dx * ns[0] + dy * ns[1] + dz * ns[2]) - I
	   * eta * norm2);
    }

    res += sum * gs_fac * w->v[ss];
  }

  return res;
}
Пример #18
0
void
getproperties_surface3d(pcsurface3d gr, preal hmin, preal hmax,
			preal anglemin, preal angleedge)
{
  uint      edges = gr->edges;
  uint      triangles = gr->triangles;
  const     real(*x)[3] = (const real(*)[3]) gr->x;
  const     uint(*t)[3] = (const uint(*)[3]) gr->t;
  const     uint(*s)[3] = (const uint(*)[3]) gr->s;
  const     real(*n)[3] = (const real(*)[3]) gr->n;
  const real *g = (const real *) gr->g;
  uint     *neighbour;
  real      dt[3], ds[3], h[3], nn, angle;
  real      h_min, h_max, angle_min, angle_edge;
  uint      i, j;

  /* Just to avoid warnings */
  h_min = h_max = angle_min = 0.0;

  for (i = 0; i < triangles; i++) {
    dt[0] = x[t[i][1]][0] - x[t[i][0]][0];
    dt[1] = x[t[i][1]][1] - x[t[i][0]][1];
    dt[2] = x[t[i][1]][2] - x[t[i][0]][2];

    ds[0] = x[t[i][2]][0] - x[t[i][0]][0];
    ds[1] = x[t[i][2]][1] - x[t[i][0]][1];
    ds[2] = x[t[i][2]][2] - x[t[i][0]][2];

    h[0] = (REAL_SQR(dt[0]) + REAL_SQR(dt[1]) + REAL_SQR(dt[2]));
    h[1] = (REAL_SQR(ds[0]) + REAL_SQR(ds[1]) + REAL_SQR(ds[2]));
    h[2] = (REAL_SQR(dt[0] - ds[0]) + REAL_SQR(dt[1] - ds[1])
	    + REAL_SQR(dt[2] - ds[2]));

    if (i == 0 || h[0] < h_min)
      h_min = h[0];

    if (i == 0 || h[0] > h_max)
      h_max = h[0];

    if (h[1] < h_min)
      h_min = h[1];

    if (h[1] > h_max)
      h_max = h[1];

    if (h[2] < h_min)
      h_min = h[2];

    if (h[2] > h_max)
      h_max = h[2];

    angle = g[i] / REAL_SQRT(h[0] * h[1]);

    if (i == 0 || angle < angle_min)
      angle_min = angle;
  }

  if (hmin)
    *hmin = REAL_SQRT(h_min);

  if (hmax)
    *hmax = REAL_SQRT(h_max);

  if (anglemin)
    *anglemin = REAL_ASIN(angle_min);

  if (angleedge) {
    neighbour = (uint *) allocmem(sizeof(uint) * edges);

    for (i = 0; i < edges; i++)
      neighbour[i] = triangles;

    angle_edge = 1.0;

    for (i = 0; i < triangles; i++) {
      if (neighbour[s[i][0]] < triangles) {
	j = neighbour[s[i][0]];
	nn = (n[i][0] * n[j][0] + n[i][1] * n[j][1] + n[i][2] * n[j][2]);
	if (nn < angle_edge)
	  angle_edge = nn;
      }
      else
	neighbour[s[i][0]] = i;

      if (neighbour[s[i][1]] < triangles) {
	j = neighbour[s[i][1]];
	nn = (n[i][0] * n[j][0] + n[i][1] * n[j][1] + n[i][2] * n[j][2]);
	if (nn < angle_edge)
	  angle_edge = nn;
      }
      else
	neighbour[s[i][1]] = i;

      if (neighbour[s[i][2]] < triangles) {
	j = neighbour[s[i][2]];
	nn = (n[i][0] * n[j][0] + n[i][1] * n[j][1] + n[i][2] * n[j][2]);
	if (nn < angle_edge)
	  angle_edge = nn;
      }
      else
	neighbour[s[i][2]] = i;
    }

    *angleedge = REAL_ACOS(angle_edge);

    freemem(neighbour);
  }
}