示例#1
0
/* filter out epsilon margin separated points */
static int separate (int n, double **q, double epsilon)
{
  if (epsilon <= 0.0) return n;

  double epshalf = .5 * epsilon,
	 epsq = epsilon * epsilon,
	 d [3], r;
  BOX *b, *g, **pb;
  SET *item;
  int i, m;

  ERRMEM (b = malloc (n * sizeof (BOX)));
  ERRMEM (pb = malloc (n * sizeof (BOX*)));

  for (i = 0, g = b; i < n; i ++, g ++)
  {
    double *e = g->extents,
	   *p = q [i];
    e [0] = p [0] - epshalf;
    e [1] = p [1] - epshalf;
    e [2] = p [2] - epshalf;
    e [3] = p [0] + epshalf;
    e [4] = p [1] + epshalf;
    e [5] = p [2] + epshalf;
    g->sgp = (void*) p;
    g->body = NULL;
    g->mark = NULL;
    pb [i] = g;
  }

  hybrid (pb, n, NULL, overlap);

  for (i = m = 0, g = b; i < n; i ++, g ++)
  {
    if (!g->mark)
    {
      double *a =  (double*) g->sgp;
      q [m ++] = a;

      for (item = SET_First ((SET*)g->body); item; item = SET_Next (item))
      {
	BOX *adj = item->data;
	double *b = (double*) adj->sgp;
	SUB (a, b, d);
	r = DOT (d, d);
	if (r < epsq) adj->mark = (void*) 1; /* epsilon separation */
      }
    }

    SET_Free (NULL, (SET**) &g->body);
  }

  free (pb);
  free (b);

  return m;
}
示例#2
0
文件: dio.c 项目: tkoziara/solfec
/* attach constraints to bodies after reading */
static void dom_attach_constraints (DOM *dom)
{
  BODY *bod;
  CON *con;

  for (bod = dom->bod; bod; bod = bod->next) SET_Free (&dom->setmem, &bod->con);

  for (con = dom->con; con; con = con->next)
  {
    if (con->master)
    {
      ASSERT_DEBUG (MAP_Find_Node (dom->idb, (void*) (long) con->master->id, NULL), "Invalid master id");
      SET_Insert (&dom->setmem, &con->master->con, con, NULL);
    }

    if (con->slave)
    {
      ASSERT_DEBUG (MAP_Find_Node (dom->idb, (void*) (long) con->slave->id, NULL), "Invalid slave id");
      SET_Insert (&dom->setmem, &con->slave->con, con, NULL);
    }
  }
}
示例#3
0
文件: fra.c 项目: tkoziara/solfec
/* 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;
}
示例#4
0
文件: fra.c 项目: tkoziara/solfec
/* 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;
}
示例#5
0
文件: dio.c 项目: tkoziara/solfec
/* read domain state */
void dom_read_state (DOM *dom, PBF *bf)
{
  BODY *bod, *next;
  int ncon;

  /* clear contacts */
  MAP_Free (&dom->mapmem, &dom->idc);
  MEM_Release (&dom->conmem);
  dom->con = NULL;
  dom->ncon = 0;

  /* read all bodies if needed */
  if (!dom->allbodiesread) read_new_bodies (dom, bf);

  /* mark all bodies as absent */
  for (bod = dom->bod; bod; bod = bod->next) bod->flags |= BODY_ABSENT;

  SET *usedlabel = NULL;

  for (; bf; bf = bf->next)
  {
    if (PBF_Label (bf, "DOM"))
    {
      /* read iover */

      int iover = 2;

      if (PBF_Label (bf, "IOVER"))
      {
	PBF_Int (bf, &iover, 1);
      }

      /* read time step */

      ASSERT (PBF_Label (bf, "STEP"), ERR_FILE_FORMAT);

      PBF_Double (bf, &dom->step, 1);

      /* read constraints merit */

      ASSERT (PBF_Label (bf, "MERIT"), ERR_FILE_FORMAT);

      PBF_Double (bf, &dom->merit, 1);

      /* read body states */

      ASSERT (PBF_Label (bf, "BODS"), ERR_FILE_FORMAT);

      int nbod;

      PBF_Int (bf, &nbod, 1);

      for (int n = 0; n < nbod; n ++)
      {
	unsigned int id;

	PBF_Uint (bf, &id, 1);
	bod = MAP_Find (dom->idb, (void*) (long) id, NULL);

	if (bod == NULL) /* pick from all bodies set */
	{
	  ASSERT_DEBUG_EXT (bod = MAP_Find (dom->allbodies, (void*) (long) id, NULL), "Body id invalid");

	  if (bod->label)
	  {
	    MAP *node = MAP_Find_Node (dom->lab, bod->label, (MAP_Compare)strcmp);
	    if (node)
	    {
	      node->data = bod; /* body fregments can inherit labels */
	      SET_Insert (NULL, &usedlabel, bod->label, (SET_Compare)strcmp);
	    }
	    else MAP_Insert (&dom->mapmem, &dom->lab, bod->label, bod, (MAP_Compare) strcmp);
	  }
	  MAP_Insert (&dom->mapmem, &dom->idb, (void*) (long) bod->id, bod, NULL);
	  bod->next = dom->bod;
	  if (dom->bod) dom->bod->prev = bod;
	  dom->bod = bod;
	  bod->dom = dom;
	  dom->nbod ++;
	}

	BODY_Read_State (bod, bf, iover);
	bod->flags &= ~BODY_ABSENT;
      }

      /* read constraints */

      ASSERT (PBF_Label (bf, "CONS"), ERR_FILE_FORMAT);
    
      PBF_Int (bf, &ncon, 1);

      for (int n = 0; n < ncon; n ++)
      {
	CON *con;
	
	con = read_constraint (dom, iover, bf);
	MAP_Insert (&dom->mapmem, &dom->idc, (void*) (long) con->id, con, NULL);
	con->next = dom->con;
	if (dom->con) dom->con->prev = con;
	dom->con = con;
      }

      dom->ncon += ncon;
    }
  }

  /* remove absent bodies */
  for (bod = dom->bod; bod; bod = next)
  {
    next = bod->next;

    if (bod->flags & BODY_ABSENT)
    {
      if (bod->label && !SET_Contains (usedlabel, bod->label, (SET_Compare)strcmp))
	MAP_Delete (&dom->mapmem, &dom->lab, bod->label, (MAP_Compare) strcmp);
      MAP_Delete (&dom->mapmem, &dom->idb, (void*) (long) bod->id, NULL);
      if (bod->next) bod->next->prev = bod->prev;
      if (bod->prev) bod->prev->next = bod->next;
      else dom->bod = bod->next;
      dom->nbod --;
    }
  }

  SET_Free (NULL, &usedlabel);

  /* attach constraints to bodies */
  dom_attach_constraints (dom);
}
示例#6
0
文件: dio.c 项目: tkoziara/solfec
/* write domain state */
void dom_write_state (DOM *dom, PBF *bf, SET *subset)
{
  /* mark domain output */

  PBF_Label (bf, "DOM");

#if IOVER >= 3
  /* write iover */

  PBF_Label (bf, "IOVER");

  int iover  = ABS (dom->solfec->iover);

  PBF_Int (bf, &iover, 1);
#endif

  /* write time step */

  PBF_Label (bf, "STEP");

  PBF_Double (bf, &dom->step, 1);

  /* write constraints merit */

  PBF_Label (bf, "MERIT");

  PBF_Double (bf, &dom->merit, 1);

  /* write complete data of newly created bodies and empty the newly created bodies set */

  write_new_bodies (dom); /* writing is done to a separate file */

  SET_Free (&dom->setmem, &dom->newb);

  /* write regular bodies (this also includes states of newly created ones) */

  PBF_Label (bf, "BODS");

  if (subset)
  {
    int nbod = SET_Size (subset);

    PBF_Int (bf, &nbod, 1);
  }
  else PBF_Int (bf, &dom->nbod, 1);

  for (BODY *bod = dom->bod; bod; bod = bod->next)
  {
    if (subset && !SET_Find (subset, (void*) (long) bod->id, NULL)) continue;

    PBF_Uint (bf, &bod->id, 1);

    if (bod->label) PBF_Label (bf, bod->label); /* label body record for fast access */

    BODY_Write_State (bod, bf);
  }

  /* write constraints */

  PBF_Label (bf, "CONS");

  if (subset)
  {
    int ncon = 0;

    for (CON *con = dom->con; con; con = con->next)
    {
      if (subset)
      {
	if (!SET_Find (subset, (void*) (long) con->master->id, NULL)) continue;
	if (con->slave && !SET_Find (subset, (void*) (long) con->slave->id, NULL)) continue;
      }

      ncon ++;
    }

    PBF_Int (bf, &ncon, 1);
  }
  else PBF_Int (bf, &dom->ncon, 1);

  for (CON *con = dom->con; con; con = con->next)
  {
    if (subset)
    {
      if (!SET_Find (subset, (void*) (long) con->master->id, NULL)) continue;
      if (con->slave && !SET_Find (subset, (void*) (long) con->slave->id, NULL)) continue;
    }

    write_constraint (con, bf);
  }
}