Пример #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
/* 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;
}
Пример #3
0
/* write fracture state */
static void fracture_state_write (DOM *dom)
{
  char path [1024];
  double R[3], r, (*disp) [3];
  int i, n, dofs;
  MESH *msh;
  SET *item;
  BODY *bod;
  CON *con;

#if HDF5
  int numbod;
  PBF *f;

  snprintf (path, 1024, "%s/fracture", dom->solfec->outpath);
  ASSERT (f = PBF_Write (path, PBF_ON, PBF_ON), ERR_FILE_OPEN);

  PBF_Time (f, &dom->time);

  for (numbod = 0, bod = dom->bod; bod; bod = bod->next)
  {
    if (bod->fracture)
    {
      msh = bod->shape->data;
      dofs = 3 * msh->nodes_count;
      ERRMEM (disp = malloc (msh->nodes_count * sizeof (double [3])));
      for (i = 0; i < msh->nodes_count; i ++)
      {
        SUB (msh->cur_nodes [i], msh->ref_nodes [i], disp [i]);
      }

      PBF_Uint (f, &bod->id, 1);
      PBF_Int (f, &dofs, 1);
      PBF_Double (f, (double*)disp, dofs);

      n = SET_Size (bod->con);
      PBF_Int (f, &n, 1);
      for (item = SET_First (bod->con); item; item = SET_Next (item))
      {
	con = item->data;
	r = sqrt (con->area/ALG_PI);
	PBF_Double (f, &r, 1);

	if (bod == con->master)
	{
	  PBF_Double (f, con->mpnt, 3);
	}
	else
	{
	  PBF_Double (f, con->spnt, 3);
	}

        NVMUL (con->base, con->R, R);
	PBF_Double (f, R, 3);
      }

      bod->fracture = 0;

      free (disp);
      numbod ++;
    }

    PBF_Int2 (f, "numbod", &numbod, 1);
  }

  PBF_Close (f);
#else
  FILE *f;
  XDR x;

#if MPI
  snprintf (path, 1024, "%s/fracture%d.dat", dom->solfec->outpath, dom->rank);
#else
  snprintf (path, 1024, "%s/fracture.dat", dom->solfec->outpath);
#endif
  ASSERT (f = fopen (path, "a"), ERR_FILE_OPEN);
  xdrstdio_create (&x, f, XDR_ENCODE);

  for (bod = dom->bod; bod; bod = bod->next)
  {
    if (bod->fracture)
    {
      msh = bod->shape->data;
      dofs = 3 * msh->nodes_count;
      ERRMEM (disp = malloc (msh->nodes_count * sizeof (double [3])));
      for (i = 0; i < msh->nodes_count; i ++)
      {
        SUB (msh->cur_nodes [i], msh->ref_nodes [i], disp [i]);
      }

      ASSERT (xdr_u_int (&x, &bod->id), ERR_FILE_WRITE);
      ASSERT (xdr_int (&x, &dofs), ERR_FILE_WRITE);
      ASSERT (xdr_vector (&x, (char*)disp, dofs, sizeof (double), (xdrproc_t)xdr_double), ERR_FILE_WRITE);
      n = SET_Size (bod->con);
      ASSERT (xdr_int (&x, &n), ERR_FILE_WRITE);
      for (item = SET_First (bod->con); item; item = SET_Next (item))
      {
	con = item->data;
	r = sqrt (con->area/ALG_PI);
	ASSERT (xdr_double (&x, &r), ERR_FILE_WRITE);

	if (bod == con->master)
	{
          ASSERT (xdr_vector (&x, (char*)con->mpnt, 3, sizeof (double), (xdrproc_t)xdr_double), ERR_FILE_WRITE);
	}
	else
	{
          ASSERT (xdr_vector (&x, (char*)con->spnt, 3, sizeof (double), (xdrproc_t)xdr_double), ERR_FILE_WRITE);
	}

        NVMUL (con->base, con->R, R);
        ASSERT (xdr_vector (&x, (char*)R, 3, sizeof (double), (xdrproc_t)xdr_double), ERR_FILE_WRITE);
      }

      bod->fracture = 0;

      free (disp);
    }
  }

  xdr_destroy (&x);
  fclose (f);
#endif
}
Пример #4
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;
}
Пример #5
0
/* map rigid onto FEM state */
int dom_rigid_to_fem (DOM *dom, PBF *bf, SET *subset)
{
  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);
      }

      ASSERT_TEXT (iover >= 3, "Output files are too old for RIGID_TO_FEM to work");

      /* read body states */

      if (subset)
      {
#if POSIX
	for (SET *item = SET_First (subset); item; item = SET_Next (item))
	{
	  regex_t xp;
	  char *pattern = item->data;
	  int error = regcomp (&xp, pattern, 0);

	  if (error != 0)
	  {
	    char *message = get_regerror (error, &xp);
	    fprintf (stderr, "-->\n");
	    fprintf (stderr, "Regular expression ERROR --> %s\n", message);
	    fprintf (stderr, "<--\n");
	    regfree (&xp);
	    free (message);
	    return 0;
	  }

	  for (BODY *bod = dom->bod; bod; bod = bod->next)
	  {
	    if (bod->label && regexec (&xp, bod->label, 0, NULL, 0) == 0)
	    {
	      if (PBF_Label (bf, bod->label))
	      {
	        double conf [12],
		       velo [6],
		       energy [4];

		int rkind;
		int rconf;
		int rdofs;

		PBF_Int (bf, &rkind, 1);
		PBF_Int (bf, &rconf, 1);
		PBF_Int (bf, &rdofs, 1);
       
		if (bod->kind == FEM && rkind == RIG)
		{

		  PBF_Double (bf, conf, 12);
		  PBF_Double (bf, velo, 6);
		  PBF_Double (bf, energy, 4);

		  BODY_From_Rigid (bod, conf, conf+9, velo, velo+3);
		}
		else
		{
		  ASSERT_TEXT (((bod->kind == RIG || bod->kind == OBS) &&
		    (rkind == RIG || rkind == OBS)) || bod->kind == (unsigned)rkind, "Body kind mismatch when reading state");
		  ASSERT_TEXT (BODY_Conf_Size (bod) == rconf, "Body configuration size mismatch when reading state");
		  ASSERT_TEXT (bod->dofs == rdofs, "Body dofs size mismatch when reading state");

		  BODY_Read_State (bod, bf, 0); /* use 0 state to skip reading of rkind, rnconf, rdofs */
		}
	      }
	    }
	  }

	  regfree (&xp);
	}
#else
	ASSERT_TEXT (0, "Regular expressions require POSIX support --> recompile Solfec with POSIX=yes");
	return 0;
#endif
      }
      else
      {
	ASSERT (PBF_Label (bf, "BODS"), ERR_FILE_FORMAT);

	int nbod;

	PBF_Int (bf, &nbod, 1);

	for (int n = 0; n < nbod; n ++)
	{
	  double conf [12], velo [6], energy [4];
	  unsigned int id;
	  BODY *bod;
	  int rank;

	  PBF_Uint (bf, &id, 1);

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

	  if (bod) /* update state of existing bodies only */
	  {
	    int rkind;
	    int rconf;
	    int rdofs;

	    PBF_Int (bf, &rkind, 1);
	    PBF_Int (bf, &rconf, 1);
	    PBF_Int (bf, &rdofs, 1);
   
	    if (bod->kind == FEM && rkind == RIG)
	    {

	      PBF_Double (bf, conf, 12);
	      PBF_Double (bf, velo, 6);
	      PBF_Double (bf, energy, 4);
	      if (bf->parallel == PBF_ON)
	      {
		PBF_Int (bf, &rank, 1);
	      }

	      BODY_From_Rigid (bod, conf, conf+9, velo, velo+3);
	    }
	    else
	    {
	      ASSERT_TEXT (((bod->kind == RIG || bod->kind == OBS) &&
		(rkind == RIG || rkind == OBS)) || bod->kind == (unsigned)rkind, "Body kind mismatch when reading state");
	      ASSERT_TEXT (BODY_Conf_Size (bod) == rconf, "Body configuration size mismatch when reading state");
	      ASSERT_TEXT (bod->dofs == rdofs, "Body dofs size mismatch when reading state");

	      BODY_Read_State (bod, bf, 0); /* use 0 state to skip reading of rkind, rnconf, rdofs */
	    }
	  }
	  else /* mock read */
	  {
	    int rkind;
	    int rconf;
	    int rdofs;

	    PBF_Int (bf, &rkind, 1);
	    PBF_Int (bf, &rconf, 1);
	    PBF_Int (bf, &rdofs, 1);

	    double *conf;
	    double *velo;
	    double energy[10];
	    int rank;

	    ERRMEM (conf = malloc (sizeof(double) * rconf));
	    ERRMEM (velo = malloc (sizeof(double) * rdofs));

	    PBF_Double (bf, conf, rconf);
	    PBF_Double (bf, velo, rdofs);
	    PBF_Double (bf, energy, BODY_ENERGY_SIZE(rkind));
	    if (bf->parallel == PBF_ON)
	    {
	      PBF_Int (bf, &rank, 1);
	    }

	    free (conf);
	    free (velo);
	  }
	}
      }
    }
  }

  return 1;
}
Пример #6
0
/* initialize domain state */
int dom_init_state (DOM *dom, PBF *bf, SET *subset)
{
  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);
      }
 
      ASSERT_TEXT (iover >= 3, "Output files are too old for INITIALISE_STATE to work");

      /* read body states */

      if (subset)
      {
#if POSIX
	for (SET *item = SET_First (subset); item; item = SET_Next (item))
	{
	  regex_t xp;
	  char *pattern = item->data;
	  int error = regcomp (&xp, pattern, 0);

	  if (error != 0)
	  {
	    char *message = get_regerror (error, &xp);
	    fprintf (stderr, "-->\n");
	    fprintf (stderr, "Regular expression ERROR --> %s\n", message);
	    fprintf (stderr, "<--\n");
	    regfree (&xp);
	    free (message);
	    return 0;
	  }

	  for (BODY *bod = dom->bod; bod; bod = bod->next)
	  {
	    if (bod->label && regexec (&xp, bod->label, 0, NULL, 0) == 0)
	    {
	      if (PBF_Label (bf, bod->label))
	      {
	        BODY_Read_State (bod, bf, iover);
	      }
	    }
	  }

	  regfree (&xp);
	}
#else
	ASSERT_TEXT (0, "Regular expressions require POSIX support --> recompile Solfec with POSIX=yes");
	return 0;
#endif
      }
      else
      {
	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;
	  BODY *bod;

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

	  if (bod) /* update state of existing bodies only */
	  {
	    BODY_Read_State (bod, bf, iover);
	  }
	  else /* mock read */
	  {
	    int rkind;
	    int rconf;
	    int rdofs;

	    PBF_Int (bf, &rkind, 1);
	    PBF_Int (bf, &rconf, 1);
	    PBF_Int (bf, &rdofs, 1);

	    double *conf;
	    double *velo;
	    double energy[10];
	    int rank;

	    ERRMEM (conf = malloc (sizeof(double) * rconf));
	    ERRMEM (velo = malloc (sizeof(double) * rdofs));

	    PBF_Double (bf, conf, rconf);
	    PBF_Double (bf, velo, rdofs);
	    PBF_Double (bf, energy, BODY_ENERGY_SIZE(rkind));
	    if (bf->parallel == PBF_ON)
	    {
	      PBF_Int (bf, &rank, 1);
	    }

	    free (conf);
	    free (velo);
	  }
	}
      }
    }
  }

  return 1;
}
Пример #7
0
/* write new bodies data */
static void write_new_bodies (DOM *dom)
{
  if (dom->newb == NULL) return; /* nothing to write */

#if HDF5
  PBF *bf = dom->solfec->bf;
  int isize = 0, ints = 0, *i = NULL;
  int dsize = 0, doubles = 0;
  double *d = NULL;
  SET *item;
  int n;

  PBF_Push (bf, "NEWBOD");

  n = SET_Size (dom->newb);
  PBF_Int2 (bf, "count", &n, 1);

  for (item = SET_First (dom->newb); item; item = SET_Next (item))
  {
    BODY_Pack (item->data, &dsize, &d, &doubles, &isize, &i, &ints);
  }

  PBF_Int2 (bf, "ints", &ints, 1);
  PBF_Int2 (bf, "i", i, ints);
  PBF_Int2 (bf, "doubles", &doubles, 1);
  PBF_Double2 (bf, "d", d, doubles);

  free (d);
  free (i);

  PBF_Pop (bf);
#else
  char *path, *ext;
  FILE *file;
  XDR xdr;

  path = SOLFEC_Alloc_File_Name (dom->solfec, 16);
  ext = path + strlen (path);

#if MPI
  sprintf (ext, ".bod.%d", dom->rank);
#else
  sprintf (ext, ".bod");
#endif

  ASSERT (file = fopen (path, "a"), ERR_FILE_OPEN);
  xdrstdio_create (&xdr, file, XDR_ENCODE);

  int isize = 0, ints, *i = NULL;
  int dsize = 0, doubles;
  double *d = NULL;
  SET *item;

  for (item = SET_First (dom->newb); item; item = SET_Next (item))
  {
    doubles = ints = 0;

    BODY_Pack (item->data, &dsize, &d, &doubles, &isize, &i, &ints);

    ASSERT (xdr_int (&xdr, &doubles), ERR_PBF_WRITE);
    ASSERT (xdr_vector (&xdr, (char*)d, doubles, sizeof (double), (xdrproc_t)xdr_double), ERR_PBF_WRITE);

    ASSERT (xdr_int (&xdr, &ints), ERR_PBF_WRITE);
    ASSERT (xdr_vector (&xdr, (char*)i, ints, sizeof (int), (xdrproc_t)xdr_int), ERR_PBF_WRITE);
  }

  free (d);
  free (i);

  xdr_destroy (&xdr);
  fclose (file);
  free (path);
#endif
}
Пример #8
0
/* create rank coloring using adjacency graph between processors derived from the W graph */
static int* processor_coloring (GAUSS_SEIDEL *gs, LOCDYN *ldy)
{
  int i, n, m, ncpu, rank, *color, *size, *disp, *adj;
  SET *adjcpu, *item;
  MEM setmem;
  DIAB *dia;
  OFFB *blk;
  CON *con;

  adjcpu = NULL;
  rank = ldy->dom->rank;
  ncpu = ldy->dom->ncpu;
  MEM_Init (&setmem, sizeof (SET), 128);
  ERRMEM (color = MEM_CALLOC (ncpu * sizeof (int)));
  ERRMEM (disp = malloc (sizeof (int [ncpu + 1])));
  ERRMEM (size = malloc (sizeof (int [ncpu])));

  /* collaps W adjacency into processor adjacency */
  for (dia = ldy->dia; dia; dia = dia->n)
  {
    for (blk = dia->adjext; blk; blk = blk->n)
    {
      con = (CON*) blk->dia;
      SET_Insert (&setmem, &adjcpu, (void*) (long) con->rank, NULL);
    }
  }

  n = SET_Size (adjcpu);
  MPI_Allgather (&n, 1, MPI_INT, size, 1, MPI_INT, MPI_COMM_WORLD);

  for (i = disp [0] = 0; i < ncpu - 1; i ++) disp [i+1] = disp [i] + size [i];
  for (i = 0, item = SET_First (adjcpu); item; i ++, item = SET_Next (item)) color [i] = (int) (long) item->data;

  m = disp [ncpu] = (disp [ncpu-1] + size [ncpu-1]);
  ERRMEM (adj = malloc (sizeof (int [m])));

  MPI_Allgatherv (color, n, MPI_INT, adj, size, disp, MPI_INT, MPI_COMM_WORLD); /* gather graph adjacency */

  for (i = 0; i < ncpu; i ++) color [i] = 0; /* zero colors */

  for (i = 0; i < ncpu; i ++) /* simple BFS coloring */
  {
    int *j, *k;

    do
    {
      color [i] ++; /* start from first color */

      for (j = &adj[disp[i]], k = &adj[disp[i+1]]; j < k; j ++) /* for each adjacent vertex */
      {
	if (color [*j] == color [i]) break; /* see whether the trial color exists in the adjacency */
      }
    }
    while (j < k); /* if so try next color */
  }

  for (m = i = 0; i < ncpu; i ++) m = MAX (m, color [i]); /* compute number of colors */
  gs->colors = m; /* record number of colors */

  if (rank == 0 && ldy->dom->verbose && gs->verbose)
  {
#if DEBUG
  for (i = 0; i < ncpu; i ++)
  {
    int *j, *k;

    printf ("GAUSS_SEIDEL: RANK %d [%d] ADJCPU:", i, color [i]);
    for (j = &adj[disp[i]], k = &adj[disp[i+1]]; j < k; j ++) printf (" %d [%d]", *j, color [*j]);
    printf ("\n");
  }
#endif
    printf ("GAUSS_SEIDEL: PROCESSOR COLORS = %d\n", m);
  }

  MEM_Release (&setmem);
  free (size);
  free (disp);
  free (adj);

  return color;
}