static void write (PBF *bf, int n) { char str [512], *pstr = str; double d = (double)n; float f = (float)n; unsigned long ul = (unsigned long)n; long l = (long)n; unsigned int ui = (unsigned int)n; int i = n; unsigned short us = (unsigned short) (n % 32767); short s = (short) (n % 32767); unsigned char uc = (unsigned char) (n % 127); char c = (char) (n % 127); sprintf (str, "CURRENT NUMBER IS %d", n); /* output time */ PBF_Time (bf, &d); /* write unlabled data */ PBF_String (bf, &pstr); PBF_Double (bf, &d, 1); PBF_Float (bf, &f, 1); PBF_Ulong (bf, &ul, 1); PBF_Long (bf, &l, 1); PBF_Uint (bf, &ui, 1); PBF_Int (bf, &i, 1); PBF_Ushort (bf, &us, 1); PBF_Short (bf, &s, 1); PBF_Uchar (bf, &uc, 1); PBF_Char (bf, &c, 1); /* write labeled data */ PBF_Label (bf, "STRING"); PBF_String (bf, &pstr); PBF_Label (bf, "DOUBLE"); PBF_Double (bf, &d, 1); PBF_Label (bf, "FLOAT"); PBF_Float (bf, &f, 1); PBF_Label (bf, "ULONG"); PBF_Ulong (bf, &ul, 1); PBF_Label (bf, "LONG"); PBF_Long (bf, &l, 1); PBF_Label (bf, "UINT"); PBF_Uint (bf, &ui, 1); PBF_Label (bf, "INT"); PBF_Int (bf, &i, 1); PBF_Label (bf, "USHORT"); PBF_Ushort (bf, &us, 1); PBF_Label (bf, "SHORT"); PBF_Short (bf, &s, 1); PBF_Label (bf, "UCHAR"); PBF_Uchar (bf, &uc, 1); PBF_Label (bf, "CHAR"); PBF_Char (bf, &c, 1); }
/* 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 }
/* read fracture state */ FS* fracture_state_read (BODY *bod) { FS *out = NULL, *item, *instance; char path [1024]; unsigned int id; int i, n, dofs; double *disp; #if HDF5 PBF *f, *g; snprintf (path, 1024, "%s/fracture", bod->dom->solfec->outpath); g = PBF_Read (path); do { double time; PBF_Time (g, &time); /* unused, but could be useful at some point */ for (f = g; f; f = f->next) { int numbod; PBF_Int2 (f, "numbod", &numbod, 1); while (numbod > 0) { PBF_Uint (f, &id, 1); PBF_Int (f, &dofs, 1); ERRMEM (disp = malloc (dofs * sizeof (double))); PBF_Double (f, disp, dofs); PBF_Int (f, &n, 1); for (i = 0, instance = NULL; i < n; i ++) { ERRMEM (item = MEM_CALLOC (sizeof (FS))); PBF_Double (f, &item->radius, 1); PBF_Double (f, item->point, 3); PBF_Double (f, item->force, 3); if (id == bod->id) { item->inext = instance; instance = item; if (i == (n-1)) { item->disp = disp; /* put displacements into first element of instance list */ item->next = out; out = item; } } else free (item); } if (!out || out->disp != disp) free (disp); /* not used */ numbod --; } } } while (PBF_Forward (g, 1)); PBF_Close (g); #else FILE *f; XDR x; snprintf (path, 1024, "%s/fracture.dat", bod->dom->solfec->outpath); f = fopen (path, "r"); /* TODO: read MPI mode data in case f == NULL but fractureRANK.dat exit */ if (f) { xdrstdio_create (&x, f, XDR_DECODE); while (! feof (f)) { if (xdr_u_int (&x, &id) == 0) break; ASSERT (xdr_int (&x, &dofs), ERR_FILE_READ); ERRMEM (disp = malloc (dofs * sizeof (double))); ASSERT (xdr_vector (&x, (char*)disp, dofs, sizeof (double), (xdrproc_t)xdr_double), ERR_FILE_READ); ASSERT (xdr_int (&x, &n), ERR_FILE_READ); for (i = 0, instance = NULL; i < n; i ++) { ERRMEM (item = MEM_CALLOC (sizeof (FS))); ASSERT (xdr_double (&x, &item->radius), ERR_FILE_READ); ASSERT (xdr_vector (&x, (char*)item->point, 3, sizeof (double), (xdrproc_t)xdr_double), ERR_FILE_READ); ASSERT (xdr_vector (&x, (char*)item->force, 3, sizeof (double), (xdrproc_t)xdr_double), ERR_FILE_READ); if (id == bod->id) { item->inext = instance; instance = item; if (i == (n-1)) { item->disp = disp; /* put displacements into first element of instance list */ item->next = out; out = item; } } else free (item); } if (!out || out->disp != disp) free (disp); /* not used */ } xdr_destroy (&x); fclose (f); } #endif return out; }
/* read new bodies data */ static void read_new_bodies (DOM *dom, PBF *bf) { #if HDF5 double time, start, end; PBF_Time (bf, &time); /* back up time frame from outside of this function */ PBF_Limits (bf, &start, &end); PBF_Seek (bf, start); do { for (PBF *f = bf; f; f = f->next) { int ipos = 0, ints; int dpos = 0, doubles; double *d; int *i; int k, n; BODY *bod; if (PBF_Has_Group (f, "NEWBOD") == 0) continue; /* don't try to read if there are no new bodies stored */ PBF_Push (f, "NEWBOD"); PBF_Int2 (f, "count", &n, 1); PBF_Int2 (f, "ints", &ints, 1); ERRMEM (i = malloc (sizeof (int [ints]))); PBF_Int2 (f, "i", i, ints); PBF_Int2 (f, "doubles", &doubles, 1); ERRMEM (d = malloc (sizeof (double [doubles]))); PBF_Double2 (f, "d", d, doubles); for (k = 0; k < n; k ++) { bod = BODY_Unpack (dom->solfec, &dpos, d, doubles, &ipos, i, ints); if (!MAP_Find (dom->allbodies, (void*) (long) bod->id, NULL)) { MAP_Insert (&dom->mapmem, &dom->allbodies, (void*) (long) bod->id, bod, NULL); /* all bodies from all times */ } else BODY_Destroy (bod); /* FIXME: bodies created in input files at time > 0; FIXME: perhaps there is no need of moving GLV to the fist lng_RUN call, FIXME: but rather bodies created in Python should not be put into the 'dom->newb' set; FIXME: this way, as now, all Python created bodies will be anyway read at time 0 */ } free (d); free (i); PBF_Pop (f); } } while (PBF_Forward (bf, 1)); dom->allbodiesread = 1; /* mark as read */ PBF_Seek (bf, time); /* seek to the backed up time again */ #else char *path, *ext; FILE *file; int m, n; XDR xdr; if (dom->solfec->verbose) printf ("Reading all bodies ...\n"); dom->allbodiesread = 1; /* mark as read */ path = SOLFEC_Alloc_File_Name (dom->solfec, 16); ext = path + strlen (path); for (m = 0; bf; bf = bf->next) m ++; /* count input files */ for (n = 0; n < m; n ++) { if (n || m > 1) { sprintf (ext, ".bod.%d", n); if (!(file = fopen (path, "r"))) continue; /* no new bodies for this rank */ } else /* n == 0 && m == 1 */ { sprintf (ext, ".bod.%d", n); if (!(file = fopen (path, "r"))) /* either prallel with "mpirun -np 1" */ { sprintf (ext, ".bod"); if (!(file = fopen (path, "r"))) continue; /* or serial */ } } xdrstdio_create (&xdr, file, XDR_DECODE); int ipos, ints, *i, dpos, doubles; double *d; BODY *bod; for (;;) { if (xdr_int (&xdr, &doubles)) { ERRMEM (d = malloc (sizeof (double [doubles]))); if (xdr_vector (&xdr, (char*)d, doubles, sizeof (double), (xdrproc_t)xdr_double)) { if (xdr_int (&xdr, &ints)) { ERRMEM (i = malloc (sizeof (int [ints]))); if (xdr_vector (&xdr, (char*)i, ints, sizeof (int), (xdrproc_t)xdr_int)) { ipos = dpos = 0; bod = BODY_Unpack (dom->solfec, &dpos, d, doubles, &ipos, i, ints); if (!MAP_Find (dom->allbodies, (void*) (long) bod->id, NULL)) { MAP_Insert (&dom->mapmem, &dom->allbodies, (void*) (long) bod->id, bod, NULL); } else BODY_Destroy (bod); /* FIXME: bodies created in input files at time > 0; FIXME: perhaps there is no need of moving GLV to the fist lng_RUN call, FIXME: but rather bodies created in Python should not be put into the 'dom->newb' set; FIXME: this way, as now, all Python created bodies will be anyway read at time 0 */ free (d); free (i); } else { free (d); free (i); break; } } else { free (d); break; } } else { free (d); break; } } else break; } xdr_destroy (&xdr); fclose (file); } free (path); #endif }
static int read (PBF *bf, int n) { char *pstr = NULL; double d; float f; unsigned long ul; long l; unsigned int ui; int i; unsigned short us; short s; unsigned char uc; char c; char _str [512]; double _d = (double)n; float _f = (float)n; unsigned long _ul = (unsigned long)n; long _l = (long)n; unsigned int _ui = (unsigned int)n; int _i = n; unsigned short _us = (unsigned short) (n % 32767); short _s = (short) (n % 32767); unsigned char _uc = (unsigned char) (n % 127); char _c = (char) (n % 127); sprintf (_str, "CURRENT NUMBER IS %d", n); PBF_Time (bf, &d); if (d != (double)n) return 0; PBF_String (bf, &pstr); PBF_Double (bf, &d, 1); PBF_Float (bf, &f, 1); PBF_Ulong (bf, &ul, 1); PBF_Long (bf, &l, 1); PBF_Uint (bf, &ui, 1); PBF_Int (bf, &i, 1); PBF_Ushort (bf, &us, 1); PBF_Short (bf, &s, 1); PBF_Uchar (bf, &uc, 1); PBF_Char (bf, &c, 1); if (strcmp (pstr, _str) != 0 || d != _d || f != _f || ul != _ul || l != _l || ui != _ui || i != _i || us != _us || s != _s || uc != _uc || c != _c) return 0; free (pstr); pstr = NULL; d = 0.; f = 0.; ul = 0; l = 0; ui = 0; i = 0; us = 0; s = 0; uc = 0; c = 0; PBF_Label (bf, "STRING"); PBF_String (bf, &pstr); PBF_Label (bf, "DOUBLE"); PBF_Double (bf, &d, 1); PBF_Label (bf, "FLOAT"); PBF_Float (bf, &f, 1); PBF_Label (bf, "ULONG"); PBF_Ulong (bf, &ul, 1); PBF_Label (bf, "LONG"); PBF_Long (bf, &l, 1); PBF_Label (bf, "UINT"); PBF_Uint (bf, &ui, 1); PBF_Label (bf, "INT"); PBF_Int (bf, &i, 1); PBF_Label (bf, "USHORT"); PBF_Ushort (bf, &us, 1); PBF_Label (bf, "SHORT"); PBF_Short (bf, &s, 1); PBF_Label (bf, "UCHAR"); PBF_Uchar (bf, &uc, 1); PBF_Label (bf, "CHAR"); PBF_Char (bf, &c, 1); if (strcmp (pstr, _str) != 0 || d != _d || f != _f || ul != _ul || l != _l || ui != _ui || i != _i || us != _us || s != _s || uc != _uc || c != _c) return 0; free (pstr); return 1; }