Esempio n. 1
0
/* pick leaves overlapping the extents */
void KDT_Pick_Extents (KDT *kd, double *extents, SET **leaves)
{
  if (kd->d < 0) /* leaf */
  {
    SET_Insert (NULL, leaves, kd, NULL);
  }
  else if (extents [kd->d+3] <= kd->p [kd->d]) KDT_Pick_Extents (kd->l, extents, leaves);
  else if (extents [kd->d] > kd->p [kd->d]) KDT_Pick_Extents (kd->r, extents, leaves);
  else
  {
    KDT_Pick_Extents (kd->l, extents, leaves);
    KDT_Pick_Extents (kd->r, extents, leaves);
  }
}
Esempio n. 2
0
/* export data for fracture analysis in MoFEM (return number of exported analysis instances) */
int Fracture_Export_MoFEM (BODY *bod, double volume, double quality, FILE *output)
{
  double extents [6], *q, *u, (*p) [3];
  SOLFEC *sol = bod->dom->solfec;
  int n, elno, fano;
  FS *list, *it, *jt;
  ELEMENT *ele;
  FACE *fac;
  MESH *msh;
  KDT *kd;

  if (!(bod->flags & BODY_CHECK_FRACTURE) || sol->mode == SOLFEC_WRITE) return 0;

  list = fracture_state_read (bod);

  if (list)
  {
    MESH *copy = MESH_Copy (bod->shape->data);
    MESH_Update (copy, NULL, NULL, NULL); /* reference configuration */
    msh = tetrahedralize1 (copy, volume, quality, -INT_MAX, -INT_MAX, NULL); /* generate tet mesh in reference configuration */
    MESH_Destroy (copy);

    /* allocate displacements on the tet mesh */
    ERRMEM (q = malloc (6 * msh->nodes_count * sizeof (double)));
    u = q + 3 * msh->nodes_count;

    /* map faces to a kd-tree for quick point queries */
    kd = KDT_Create (msh->nodes_count, (double*)msh->ref_nodes, 0.0);
    for (ele = msh->surfeles; ele; ele = ele->next)
    { 
      ELEMENT_Ref_Extents (msh, ele, extents);
      for (fac = ele->faces; fac; fac = fac->next) KDT_Drop (kd, extents, fac);
    }

    //______________________________________________________
    // output file start
    for (fano = 0, fac = msh->faces; fac; fano ++, fac = fac->n) fac->index = fano; /* count and index faces */
    ERRMEM (p = malloc (fano * sizeof (double [3]))); /* allocate face pressures */

    elno = msh->surfeles_count + msh->bulkeles_count;

    fprintf (output, "mOFF %d %d %d\n", msh->nodes_count, fano, elno); // file header

    /* map displacements from the hex to the tet mesh */
    FEM_Map_State (bod->shape->data, bod->conf, bod->velo, msh, q, u); /* only bod->disp to q mapping is used */

    for (n = 0; n < msh->nodes_count; n ++)
    {
      fprintf (output, "%f %f %f %f %f %f\n", msh->ref_nodes [n][0], msh->ref_nodes [n][1], msh->ref_nodes [n][2], q[3*n], q[3*n+1], q[3*n+2]);
    }

    //______________________________________________________
    /* rewind the list to the end to find the last element,
       which corresponds to the earliest in time fracture instance */
    for (it = list; it->next; it = it->next) continue;

    /* for (it = list; it; it = it->next) */
    /* FIXME -- FIXME -- FIXME -- FIXME */
    {
      for (n = 0; n < fano; n ++)
      {
        SET (p [n], 0.0); /* zero face pressures */
      }

      for (jt = it; jt; jt = jt->inext) /* for each point force in this instance */
      {
        double (*ref) [3] = msh->ref_nodes;
        double a [3], b [3], c [3], area;
        SET *set = NULL, *item;
        double *qa, *qb, *qc;

        extents [0] = jt->point[0] - jt->radius - GEOMETRIC_EPSILON; /* set up search extents */
        extents [1] = jt->point[1] - jt->radius - GEOMETRIC_EPSILON;
        extents [2] = jt->point[2] - jt->radius - GEOMETRIC_EPSILON;
        extents [3] = jt->point[0] + jt->radius + GEOMETRIC_EPSILON;
        extents [4] = jt->point[1] + jt->radius + GEOMETRIC_EPSILON;
        extents [5] = jt->point[2] + jt->radius + GEOMETRIC_EPSILON;

        KDT_Pick_Extents (kd, extents, &set); /* pick kd-tree leaves within the extents */

	for (item = SET_First (set); item; item = SET_Next (item))
	{
	  KDT *leaf = item->data;
	  for (n = 0; n < leaf->n; n ++)
	  {
	    fac = leaf->data [n]; /* face dropped into this leaf */

	    qa = &q[3*fac->nodes[0]];
	    qb = &q[3*fac->nodes[1]];
	    qc = &q[3*fac->nodes[2]];

	    ADD (ref[fac->nodes[0]], qa, a); /* current face nodes */
	    ADD (ref[fac->nodes[1]], qb, b);
	    ADD (ref[fac->nodes[2]], qc, c);

	    TRIANGLE_AREA (a, b, c, area); /* current face area */

	    if (area > 0.0) /* XXX */
	    {
	      p [fac->index][0] += jt->force [0] / area; /* add up pressure */
	      p [fac->index][1] += jt->force [1] / area; /* FIXME: seems to be adding up to much pressure -> divided by area */
	      p [fac->index][2] += jt->force [2] / area;
	    }
	  }
	}

        SET_Free (NULL, &set);
      }

      for (fac = msh->faces, n=0; fac; fac = fac->n, n ++)
      {
        fprintf (output, "3 %d %d %d %g %g %g\n", fac->nodes[0], fac->nodes[1], fac->nodes[2], p[n][0], p[n][1], p[n][2]);
      }
    }

    //______________________________________________________
    for (ele = msh->surfeles; ele; ele = ele->next)
    {
      fprintf (output, "4 %d %d %d %d\n", ele->nodes[0], ele->nodes[1], ele->nodes[2], ele->nodes[3]);
    }

    for (ele = msh->bulkeles; ele; ele = ele->next)
    {
      fprintf (output, "4 %d %d %d %d\n", ele->nodes[0], ele->nodes[1], ele->nodes[2], ele->nodes[3]);
    }
    // output file complete
    //______________________________________________________

    fracture_state_free (list);
    free (q);
    free (p);
    MESH_Destroy (msh);
  }

  return 0;
}
Esempio n. 3
0
/* export data for fracture analysis in Yaffems (return number of exported analysis instances) */
int Fracture_Export_Yaffems (BODY *bod, double volume, double quality, FILE *output)
{
  double extents [6], *q, *u, (*p) [3];
  SOLFEC *sol = bod->dom->solfec;
  int n, m, elno, fano;
  FS *list, *it, *jt;
  ELEMENT *ele;
  FACE *fac;
  MESH *msh;
  KDT *kd;

  if (!(bod->flags & BODY_CHECK_FRACTURE) || sol->mode == SOLFEC_WRITE) return 0;

  list = fracture_state_read (bod);

  if (list)
  {
    MESH *copy = MESH_Copy (bod->shape->data);
    MESH_Update (copy, NULL, NULL, NULL); /* reference configuration */
    msh = tetrahedralize1 (copy, volume, quality, -INT_MAX, -INT_MAX, NULL); /* generate tet mesh in reference configuration */
    MESH_Destroy (copy);

    /* allocate displacements on the tet mesh */
    ERRMEM (q = malloc (6 * msh->nodes_count * sizeof (double)));
    u = q + 3 * msh->nodes_count;

    /* map faces to a kd-tree for quick point queries */
    kd = KDT_Create (msh->nodes_count, (double*)msh->ref_nodes, 0.0);
    for (ele = msh->surfeles; ele; ele = ele->next)
    { 
      ELEMENT_Ref_Extents (msh, ele, extents);
      for (fac = ele->faces; fac; fac = fac->next) KDT_Drop (kd, extents, fac);
    }

    fprintf (output, "%s\n", "# vtk DataFile Version 2.0");
    fprintf (output, "%s\n", "Test Title");
    fprintf (output, "ASCII\n");
    fprintf (output, "\n");
    fprintf (output, "DATASET UNSTRUCTURED_GRID\n");
    fprintf (output, "POINTS %d float\n", msh->nodes_count);

    for (n = 0; n < msh->nodes_count; n ++)
    {
      fprintf (output, "%f %f %f\n", msh->ref_nodes [n][0], msh->ref_nodes [n][1], msh->ref_nodes [n][2]);
    }

    for (fano = 0, fac = msh->faces; fac; fano ++, fac = fac->n) fac->index = fano; /* count and index faces */

    ERRMEM (p = malloc (fano * sizeof (double [3]))); /* allocate face pressures */

    elno = msh->surfeles_count + msh->bulkeles_count;

    fprintf (output, "\n");
    fprintf (output, "CELLS %d %d\n", elno + fano, elno*5 + fano*4);

    for (ele = msh->surfeles; ele; ele = ele->next)
    {
      fprintf (output, "4 %d %d %d %d\n", ele->nodes[0], ele->nodes[1], ele->nodes[2], ele->nodes[3]);
    }

    for (ele = msh->bulkeles; ele; ele = ele->next)
    {
      fprintf (output, "4 %d %d %d %d\n", ele->nodes[0], ele->nodes[1], ele->nodes[2], ele->nodes[3]);
    }

    for (fac = msh->faces; fac; fac = fac->n)
    {
      fprintf (output, "3 %d  %d  %d\n", fac->nodes[0], fac->nodes[1], fac->nodes[2]);
    }

    fprintf (output, "\n");
    fprintf (output, "CELL_TYPES %d\n", elno + fano);

    for (n = 0; n < elno; n++)
    {
      fprintf (output, "10\n");
    }
    
    for (n = 0; n < fano; n++)
    {
      fprintf (output, "5\n");
    }

    fprintf (output, "\n");
    fprintf (output, "POINT_DATA %d\n", msh->nodes_count);
    for (it = list, m = 0; it; it = it->next, m ++)
    {
      /* map displacements from the hex to the tet mesh */
      FEM_Map_State (bod->shape->data, it->disp, bod->velo, msh, q, u); /* only it->disp to q mapping is used */

      fprintf (output, "\n");
      fprintf (output, "VECTORS disp%d float\n", m+1);

      for (n = 0; n < msh->nodes_count; n ++)
      {
	fprintf (output, "%f %f %f\n", q[3*n], q[3*n+1], q[3*n+2]);
      }
    }

    fprintf (output, "\n");
    fprintf (output, "CELL_DATA %d\n", elno + fano);
    for (it = list, m = 0; it; it = it->next, m ++)
    {
      fprintf (output, "\n");
      fprintf (output, "VECTORS pres%d float\n", m);

      for (n = 0; n < elno; n ++) /* skip elements */
      {
        fprintf (output, "0 0 0\n");
      }

      for (n = 0; n < fano; n ++)
      {
        SET (p [n], 0.0); /* zero face pressures */
      }

      for (jt = it; jt; jt = jt->inext) /* for each point force in this instance */
      {
        double (*ref) [3] = msh->ref_nodes;
	double a [3], b [3], c [3], area;
        SET *set = NULL, *item;
	double *qa, *qb, *qc;

        extents [0] = jt->point[0] - jt->radius - GEOMETRIC_EPSILON; /* set up search extents */
        extents [1] = jt->point[1] - jt->radius - GEOMETRIC_EPSILON;
        extents [2] = jt->point[2] - jt->radius - GEOMETRIC_EPSILON;
        extents [3] = jt->point[0] + jt->radius + GEOMETRIC_EPSILON;
        extents [4] = jt->point[1] + jt->radius + GEOMETRIC_EPSILON;
        extents [5] = jt->point[2] + jt->radius + GEOMETRIC_EPSILON;

	KDT_Pick_Extents (kd, extents, &set); /* pick kd-tree leaves within the extents */

	for (item = SET_First (set); item; item = SET_Next (item))
	{
	  KDT *leaf = item->data;
	  for (n = 0; n < leaf->n; n ++)
	  {
	    fac = leaf->data [n]; /* face dropped into this leaf */
            qa = &q[3*fac->nodes[0]];
            qb = &q[3*fac->nodes[1]];
            qc = &q[3*fac->nodes[2]];
	    ADD (ref[fac->nodes[0]], qa, a); /* current face nodes */
	    ADD (ref[fac->nodes[1]], qb, b);
	    ADD (ref[fac->nodes[2]], qc, c);
	    TRIANGLE_AREA (a, b, c, area); /* current face area */

	    if (area > 0.0) /* XXX */
	    {
	      p [fac->index][0] += jt->force [0] / area; /* add up pressure */
	      p [fac->index][1] += jt->force [1] / area;
	      p [fac->index][2] += jt->force [2] / area;
	    }
	  }
	}

	SET_Free (NULL, &set);
      }

      for (n = 0; n < fano; n ++)
      {
        fprintf (output, "%g %g %g\n", p[n][0], p[n][1], p[n][2]);
      }
    }

    fracture_state_free (list);

    free (q);

    free (p);

    return m;
  }

  return 0;
}