Ejemplo n.º 1
0
static void psc_write_shape (SHAPE *shp, FILE *f)
{
  SHAPE *ptr;
  int n;

  for (ptr = shp, n = 0; ptr; ptr = ptr->next) n ++;

  ASSERT_TEXT (n == 1, "Compund shapes are not supported in PSC mode");
  ASSERT_TEXT (shp->kind == SHAPE_MESH, "Only MESH shapes are supported in PSC mode");
  /* TODO: support all shapes */

  psc_write_mesh (shp->data, f);
}
Ejemplo n.º 2
0
/* after the body has been imported via MPI calls,
 * read body data from file and compare */
void PSC_Test_Body (BODY *bod)
{
  char txt [1024];
  FILE *f;
  BODY a;
  int i;

  snprintf (txt, 1024, "%s/body%d.data", bod->dom->solfec->outpath, bod->id);
  ASSERT (f = fopen (txt, "r"), ERR_FILE_OPEN);

  fread (&a.kind, sizeof (a.kind), 1, f);

  if (a.kind != bod->kind)
  {
    ASSERT_TEXT (0, "PSC ERROR: kind");
  }

#if 0
  fread (&i, sizeof (int), 1, f);
  fread (txt, sizeof (char), i, f);
  txt[i] = '\0';

  if (strcmp (txt, bod->mat->label) != 0)
  {
    ASSERT_TEXT (0, "PSC ERROR: material");
  }
#endif

  fread (&a.ref_mass, sizeof (double), 1, f);

  if (a.ref_mass != bod->ref_mass)
  {
    ASSERT_TEXT (0, "PSC ERROR: ref_mass");
  }

  fread (&a.ref_volume, sizeof (double), 1, f);

  if (a.ref_volume != bod->ref_volume)
  {
    ASSERT_TEXT (0, "PSC ERROR: ref_volume");
  }

  fread (&a.ref_center, sizeof (double), 3, f);

  for (i = 0; i < 3; i ++)
  {
    if (a.ref_center [i]!= bod->ref_center [i])
    {
      ASSERT_TEXT (0, "PSC ERROR: ref_center");
    }
  }

  fread (&a.ref_tensor, sizeof (double), 9, f);

  for (i = 0; i < 9; i ++)
  {
    if (a.ref_tensor [i]!= bod->ref_tensor [i])
    {
      ASSERT_TEXT (0, "PSC ERROR: ref_tensor");
    }
  }

  fread (&a.dofs, sizeof (int), 1, f);

  if (a.dofs != bod->dofs)
  {
    ASSERT_TEXT (0, "PSC ERROR: dofs");
  }

  fread (&a.form, sizeof (a.form), 1, f);

  if (a.form != bod->form)
  {
    ASSERT_TEXT (0, "PSC ERROR: form");
  }

  int confsize = bod->kind != FEM ? 12 : bod->form == REDUCED_ORDER ? bod->dofs + 9 : bod->dofs;

  ERRMEM (a.conf = malloc (sizeof (double [confsize])));

  fread (a.conf, sizeof (double), confsize, f);

  for (i = 0; i < confsize; i ++)
  {
    if (a.conf [i] != bod->conf [i])
    {
      ASSERT_TEXT (0, "PSC ERROR: conf");
    }
  }

  free (a.conf);

  ERRMEM (a.velo = malloc (sizeof (double [a.dofs])));

  fread (a.velo, sizeof (double), a.dofs, f);

  for (i = 0; i < bod->dofs; i ++)
  {
    if (!DEQ(a.velo[i], bod->velo[i])) /* XXX: differs after 15th decimal place => why is ONLY velocity giving this kind of trouble? */
    {
      double x = fabs (a.velo[i]-bod->velo[i]), y = DBL_EPSILON;
      printf ("%.17f > %.17f\n", x, y);
      ASSERT_TEXT (0, "PSC ERROR: velo => %d => %.17f != %.17f", i, a.velo[i], bod->velo[i]);
    }
  }

  free (a.velo);

  /* TODO => bod->forces */

  /* TODO => bod->cra */

  a.shape = psc_read_shape (f);

  if (psc_compare_shapes (a.shape, bod->shape) == 0)
  {
    ASSERT_TEXT (0, "PSC ERROR: shape");
  }

  SHAPE_Destroy (a.shape);

  fread (&a.scheme, sizeof (a.scheme), 1, f);

  if (a.scheme != bod->scheme)
  {
    ASSERT_TEXT (0, "PSC ERROR: scheme");
  }

  a.inverse = psc_read_matrix (f);

  if (psc_compare_matrices (a.inverse, bod->inverse) == 0)
  {
    ASSERT_TEXT (0, "PSC ERROR: inverse");
  }

  psc_matrix_free (a.inverse);

  a.M = psc_read_matrix (f);

  if (psc_compare_matrices (a.M, bod->M) == 0)
  {
    ASSERT_TEXT (0, "PSC ERROR: M");
  }

  psc_matrix_free (a.M);

  a.K = psc_read_matrix (f);

  if (psc_compare_matrices (a.K, bod->K) == 0)
  {
    ASSERT_TEXT (0, "PSC ERROR: K");
  }

  psc_matrix_free (a.K);

  fread (&a.damping, sizeof (double), 1, f);

  if (a.damping != bod->damping)
  {
    ASSERT_TEXT (0, "PSC ERROR: damping");
  }

  fread (&i, sizeof (int), 1, f);

  if (i && bod->evec == NULL)
  {
    ASSERT_TEXT (0, "PSC ERROR: evec existence");
  }

  if (i)
  {
    a.evec = psc_read_matrix (f);

    if (psc_compare_matrices (a.evec, bod->evec) == 0)
    {
      ASSERT_TEXT (0, "PSC ERROR: evec");
    }

    ERRMEM (a.eval = malloc (sizeof (double [a.evec->n])));

    fread (a.eval, sizeof (double), a.evec->n, f);

    for (i = 0; i < a.evec->n; i ++)
    {
      if (a.eval [i]!= bod->eval [i])
      {
	ASSERT_TEXT (0, "PSC ERROR: eval");
      }
    }

    psc_matrix_free (a.evec);

    free (a.eval);
  }

  /* XXX: skip bod->label as non-essential */

  /* XXX: skip bod->mesh for the moment */

  /* XXX: skip bod->energy as non-essential */

  /* XXX: skip bod->fracture as non-essential */

  fclose (f);
}
Ejemplo n.º 3
0
/* write body data to file before sending the body via MPI calles;
 * the file is SOLFEC->outpath/bodyID.data; */
void PSC_Write_Body (BODY *bod)
{
  char txt [1024];
  FILE *f;
  int i;

  ASSERT_TEXT (bod->kind == FEM, "Only FEM bodies are supported in PSC mode");

  snprintf (txt, 1024, "%s/body%d.data", bod->dom->solfec->outpath, bod->id);
  ASSERT (f = fopen (txt, "w"), ERR_FILE_OPEN);

  fwrite (&bod->kind, sizeof (bod->kind), 1, f);

#if 0
  i = strlen(bod->mat->label);
  ASSERT_TEXT (i < 1024, "Material label is too long!");
  fwrite (&i, sizeof (int), i, f);
  fwrite (bod->mat->label, sizeof (char), i, f);
#endif

  fwrite (&bod->ref_mass, sizeof (double), 1, f);
  fwrite (&bod->ref_volume, sizeof (double), 1, f);
  fwrite (bod->ref_center, sizeof (double), 3, f);
  fwrite (bod->ref_tensor, sizeof (double), 9, f);

  fwrite (&bod->dofs, sizeof (int), 1, f);

  fwrite (&bod->form, sizeof (bod->form), 1, f);

  int confsize = bod->kind != FEM ? 12 : bod->form == REDUCED_ORDER ? bod->dofs + 9 : bod->dofs;

  fwrite (bod->conf, sizeof (double), confsize, f);
  fwrite (bod->velo, sizeof (double), bod->dofs, f);

  /* TODO => bod->forces */

  /* TODO => bod->cra */

  psc_write_shape (bod->shape, f);

  /* XXX => skip bod->extents (updated independently) */

  fwrite (&bod->scheme, sizeof (bod->scheme), 1, f);

  psc_write_matrix (bod->inverse, f);

  psc_write_matrix (bod->M, f);

  psc_write_matrix (bod->K, f);

  fwrite (&bod->damping, sizeof (double), 1, f);

  if (bod->evec)
  {
    i = 1;

    fwrite (&i, sizeof (int), 1, f);

    psc_write_matrix (bod->evec, f);

    fwrite (bod->eval, sizeof (double), bod->evec->n, f);
  }
  else
  {
    i = 0;

    fwrite (&i, sizeof (int), 1, f);
  }

  /* XXX: skip bod->label as non-essential */

  /* XXX: skip bod->mesh for the moment */

  /* XXX: skip bod->energy as non-essential */

  /* XXX: skip bod->fracture as non-essential */

  fclose (f);
}
Ejemplo n.º 4
0
static MESH* psc_read_mesh (FILE *f)
{
  ELEMENT *ele, **tab, *tail;
  MESH *msh;
  int i, j;

  ERRMEM (msh = MEM_CALLOC (sizeof (MESH)));
  MEM_Init (&msh->elemem, sizeof (ELEMENT), 128);
  MEM_Init (&msh->facmem, sizeof (FACE), 128);
  MEM_Init (&msh->mapmem, sizeof (MAP), 128);

  fread (&msh->nodes_count, sizeof (int), 1, f);

  ERRMEM (msh->ref_nodes = malloc (2 * msh->nodes_count * sizeof (double [3])));
  msh->cur_nodes = msh->ref_nodes + msh->nodes_count;

  fread (msh->ref_nodes, sizeof (double [3]), msh->nodes_count, f);
  fread (msh->cur_nodes, sizeof (double [3]), msh->nodes_count, f);

  fread (&msh->surfeles_count, sizeof (int), 1, f);
  fread (&msh->bulkeles_count, sizeof (int), 1, f);

  ERRMEM (tab = malloc ((msh->surfeles_count + msh->bulkeles_count) * sizeof (ELEMENT*)));

  for (i = 0, tail = NULL; i < msh->surfeles_count; i ++)
  {
    ele = psc_read_element (&msh->elemem, &msh->facmem, f);
    ele->flag = i;

    if (tail) ele->prev = tail, tail->next = ele;
    else msh->surfeles = ele;
    tail = ele;
    tab [i] = ele;
  }

  for (tail = NULL; i < msh->surfeles_count + msh->bulkeles_count; i ++)
  {
    ele = psc_read_element (&msh->elemem, &msh->facmem, f);
    ele->flag = i;

    if (tail) ele->prev = tail, tail->next = ele;
    else msh->bulkeles = ele;
    tail = ele;
    tab [i] = ele;
  }

  for (i = 0; i < msh->surfeles_count + msh->bulkeles_count; i ++)
  {
    ele = tab [i];

    for (j = 0; j < ele->neighs; j ++)
    {
      int idx = (long) (void*) ele->adj[j];
      ASSERT_TEXT (idx >= 0 && idx < msh->surfeles_count + msh->bulkeles_count, "INCONSITENT ELEMENT INDEXING");
      ele->adj[j] = tab [idx];
    }
  }

  free (tab);

  return msh;
}
Ejemplo n.º 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;
}
Ejemplo n.º 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;
}
Ejemplo n.º 7
0
/* update ellipsoid according to the given motion */
void ELLIP_Update (ELLIP *eli, void *body, void *shp, MOTION motion)
{
  SGP sgp = {shp, eli, GOBJ_ELLIP, NULL};
  double *ref = eli->ref_center,
	 (*ref_pnt) [3] = eli->ref_point,
	 *cur = eli->cur_center,
	 (*cur_pnt) [3] = eli->cur_point;

  if (motion)
  { 
    motion (body, &sgp, ref, cur);
    motion (body, &sgp, ref_pnt [0], cur_pnt [0]);
    motion (body, &sgp, ref_pnt [1], cur_pnt [1]);
    motion (body, &sgp, ref_pnt [2], cur_pnt [2]);

    BODY *bod = body;

    switch (bod->kind)
    {
    case OBS:
    case RIG:
    {
      double *R1 = bod->conf, *R0 = eli->ref_rot, *rot = eli->cur_rot;

      NNMUL (R1, R0, rot);
    }
    break;
    case PRB:
    {
      double *F = bod->conf, *sca0 = eli->ref_sca, *rot0 = eli->ref_rot, *sca1 = eli->cur_sca, *rot1 = eli->cur_rot;
      double U[9] = {1.0/(sca0[0]*sca0[0]), 0.0, 0.0, 0.0, 1.0/(sca0[1]*sca0[1]), 0.0, 0.0, 0.0, 1.0/(sca0[2]*sca0[2])};
      double A0[9], iF[9], det, X[3], Y[9], A[9];

      NTMUL (U, rot0, Y);
      NNMUL (rot0, Y, A0);

      TNCOPY (F, Y); /* T --> since deformation gradient is stored row-wise */

      INVERT (Y, iF, det);
      ASSERT_TEXT (det > 0.0, "det(F) <= 0.0 during ellipsoid update");

      NNMUL (A0, iF, Y);
      TNMUL (iF, Y, A);

      ASSERT_TEXT (lapack_dsyev ('V', 'U', 3, A, 3, X, Y, 9) == 0, "Eigen decomposition failed during ellipsoid update");

      if (DET(A) < 0.0) /* det(A) is 1.0 or -1.0 */
      {
	SCALE9 (A, -1.0); /* keep positive space orientation */
      }

      NNCOPY (A, rot1);

      sca1[0] = 1.0/sqrt(X[0]);
      sca1[1] = 1.0/sqrt(X[1]);
      sca1[2] = 1.0/sqrt(X[2]);
    }
    break;
    default:
    {
      ASSERT_TEXT (0, "Invalid body kind during ellipsoid update");
    }
    break;
    }
  }
  else
  {
    COPY (ref, cur);
    COPY (ref_pnt [0], cur_pnt [0]);
    COPY (ref_pnt [1], cur_pnt [1]);
    COPY (ref_pnt [2], cur_pnt [2]);

    sca_rot (eli->ref_center, eli->ref_point, eli->ref_sca, eli->ref_rot);

    COPY (eli->ref_sca, eli->cur_sca);
    NNCOPY (eli->ref_rot, eli->cur_rot);
  }
}