59 bool read_binary =
fileExists(basename +
".bpts");
60 std::string pts_file = read_binary ? basename +
".bpts" : basename +
".pts";
62 FILE* pts_fd = fopen(pts_file.c_str(),
"r");
64 fprintf(stderr,
"Error: could not open file: %s. Aborting!\n", pts_file.c_str());
70 if(read_binary) fread(buffer,
sizeof(
char),
HDR_SIZE, pts_fd);
71 else fgets( buffer, 2048, pts_fd);
72 sscanf(buffer,
"%lu", &numpts);
90 inline void read_headers(FILE* ele_fd, FILE* fib_fd,
bool read_binary,
size_t & numelem,
int & nFib)
95 fread(buffer,
sizeof(
char),
HDR_SIZE, ele_fd);
100 sscanf(buffer,
"%lu", &numelem);
105 fread(buffer,
sizeof(
char),
HDR_SIZE, fib_fd);
106 sscanf(buffer,
"%d", &nFib);
112 short nread = sscanf(buffer,
"%f %f %f %f %f %f", fbuff, fbuff+1, fbuff+2, fbuff+3, fbuff+4, fbuff+5);
114 case 1: nFib = fbuff[0];
break;
115 case 3: nFib = 1;
break;
116 case 6: nFib = 2;
break;
118 fprintf(stderr,
"%s error: read %d values in line 1 of fiber file."
119 "This is unexpected! Setting number of fibers to 1.\n",
127 fseek(fib_fd, 0, SEEK_SET);
145 inline void write_elem_headers(FILE* & ele_fd, FILE* & fib_fd,
bool binary,
size_t numelem,
int nFib)
155 snprintf(header,
sizeof header,
"%lu %d %d", numelem,
MT_ENDIANNESS, checksum);
156 fwrite(header,
HDR_SIZE,
sizeof(
char), ele_fd);
159 fprintf(ele_fd,
"%lu\n", numelem);
165 snprintf(header,
sizeof header,
"%d %lu %d %d", nFib, (
unsigned long int)numelem,
MT_ENDIANNESS, checksum);
166 fwrite(header,
sizeof(
char),
HDR_SIZE, fib_fd);
169 fprintf(fib_fd,
"%d\n", nFib);
191 snprintf(header,
sizeof header,
"%lu %d %d", numpts,
MT_ENDIANNESS, checksum);
192 fwrite(header,
HDR_SIZE,
sizeof(
char), pts_fd);
195 fprintf(pts_fd,
"%lu\n", numpts);
208 template<
class T,
class S>
211 const int bufsize = 2048;
212 const int max_elem_size = 9;
214 char buffer[bufsize];
216 int n[max_elem_size];
221 mesh.
dsp.resize(bsize+1);
222 mesh.
tag.resize(bsize);
224 mesh.
con.resize(bsize*max_elem_size);
226 size_t ele_read = 0, con_size = 0;
228 T* elem = mesh.
con.data();
230 for(
size_t i=0; i<bsize; i++)
234 size_t r = fread(&etbuff,
sizeof(
int), 1, fd);
239 char* ptr = fgets( buffer, bufsize, fd);
240 if(ptr == NULL)
break;
241 sscanf(buffer,
"%s %d %d %d %d %d %d %d %d %d", etype_str, n, n+1, n+2, n+3, n+4, n+5, n+6, n+7, n+8);
277 fprintf(stderr,
"Error: Unsupported element type!\n");
280 mesh.
dsp[i+1] = mesh.
dsp[i] + nodes;
285 fread(n,
sizeof(
int), nodes+1, fd);
287 for(
int j=0; j<nodes; j++) elem[j] = n[j];
289 mesh.
tag[i] = n[nodes];
290 ref_eidx[i] = bstart + i;
295 mesh.
dsp.resize(ele_read+1);
296 mesh.
tag.resize(ele_read);
298 ref_eidx.
resize(ele_read);
299 mesh.
con.resize(con_size);
312 template<
class T,
class S>
315 const T* con = mesh.
con.data();
321 for(
size_t eidx=0; eidx < mesh.
l_numelem; eidx++)
323 fwrite(&mesh.
type[eidx], 1,
sizeof(
elem_t), fd);
324 T esize = mesh.
dsp[eidx+1] - mesh.
dsp[eidx];
326 wbuff[esize] = mesh.
tag[eidx];
328 fwrite(wbuff, esize+1,
sizeof(
int), fd);
334 for(
size_t eidx=0; eidx < mesh.
l_numelem; eidx++)
336 switch(mesh.
type[eidx])
339 fprintf(fd,
"Ln %d %d %d\n", con[0], con[1], mesh.
tag[eidx]);
344 fprintf(fd,
"Tr %d %d %d %d\n", con[0], con[1], con[2], mesh.
tag[eidx]);
349 fprintf(fd,
"Qd %d %d %d %d %d\n", con[0], con[1], con[2], con[3], mesh.
tag[eidx]);
354 fprintf(fd,
"Tt %d %d %d %d %d\n", con[0], con[1], con[2], con[3], mesh.
tag[eidx]);
359 fprintf(fd,
"Py %d %d %d %d %d %d\n", con[0], con[1], con[2], con[3],
360 con[4], mesh.
tag[eidx]);
365 fprintf(fd,
"Pr %d %d %d %d %d %d %d\n", con[0], con[1], con[2], con[3],
366 con[4], con[5], mesh.
tag[eidx]);
371 fprintf(fd,
"Hx %d %d %d %d %d %d %d %d %d\n", con[0], con[1], con[2], con[3],
372 con[4], con[5], con[6], con[7], mesh.
tag[eidx]);
377 fprintf(stderr,
"Error: Unsupported element type!\n");
394 template<
class T,
class S>
397 const int bufsize = 2048;
398 char buffer[bufsize];
407 for(
size_t i=0; i<bsize; i++) {
409 size_t r = fread(fib,
sizeof(
float), 6, fd);
413 char* ptr = fgets( buffer, bufsize, fd);
414 if(ptr == NULL)
break;
415 sscanf(buffer,
"%f %f %f %f %f %f", fib, fib+1, fib+2, fib+3, fib+4, fib+5);
417 mesh.
fib[nr*3+0] = fib[0];
418 mesh.
fib[nr*3+1] = fib[1];
419 mesh.
fib[nr*3+2] = fib[2];
420 mesh.
she[nr*3+0] = fib[3];
421 mesh.
she[nr*3+1] = fib[4];
422 mesh.
she[nr*3+2] = fib[5];
429 else if (nFib == 1) {
435 for(
size_t i=0; i<bsize; i++) {
437 size_t r = fread(fib,
sizeof(
float), 3, fd);
441 char* ptr = fgets( buffer, bufsize, fd);
442 if(ptr == NULL)
break;
443 sscanf(buffer,
"%f %f %f", fib, fib+1, fib+2);
446 mesh.
fib[nr*3+0] = fib[0];
447 mesh.
fib[nr*3+1] = fib[1];
448 mesh.
fib[nr*3+2] = fib[2];
464 template<
class T,
class S>
479 fib[0] = mesh.
fib[i*3+0];
480 fib[1] = mesh.
fib[i*3+1];
481 fib[2] = mesh.
fib[i*3+2];
482 fib[3] = mesh.
she[i*3+0];
483 fib[4] = mesh.
she[i*3+1];
484 fib[5] = mesh.
she[i*3+2];
487 fwrite(fib, 6,
sizeof(
float), fd);
489 fprintf(fd,
"%f %f %f %f %f %f\n", fib[0], fib[1], fib[2], fib[3], fib[4], fib[5]);
496 fib[0] = mesh.
fib[i*3+0];
497 fib[1] = mesh.
fib[i*3+1];
498 fib[2] = mesh.
fib[i*3+2];
501 fwrite(fib, 3,
sizeof(
float), fd);
503 fprintf(fd,
"%f %f %f\n", fib[0], fib[1], fib[2]);
517 template<
class T,
class S>
521 MPI_Comm comm = mesh.
comm;
524 MPI_Comm_size(comm, &size); MPI_Comm_rank(comm, &rank);
526 FILE* ele_fd = NULL, *fib_fd = NULL;
527 size_t gnumelems = 0;
529 bool read_binary =
false;
534 read_binary =
fileExists(basename +
".belem");
535 std::string ele_file = read_binary ? basename +
".belem" : basename +
".elem";
536 std::string fib_file = read_binary ? basename +
".blon" : basename +
".lon";
538 ele_fd = fopen(ele_file.c_str(),
"r");
540 fprintf(stderr,
"Error: could not open file: %s. Aborting!\n", ele_file.c_str());
544 fib_fd = fopen(fib_file.c_str(),
"r");
545 if((!fib_fd) && require_fibers) {
546 fprintf(stderr,
"Error: could not open file: %s. Aborting!\n", fib_file.c_str());
551 MPI_Allreduce(MPI_IN_PLACE, &err, 1, MPI_INT, MPI_SUM, comm);
557 read_headers(ele_fd, fib_fd, read_binary, gnumelems, nFib);
559 MPI_Bcast(&gnumelems,
sizeof(
size_t), MPI_BYTE, 0, comm);
560 MPI_Bcast(&nFib,
sizeof(
int), MPI_BYTE, 0, comm);
564 size_t blocksize = (gnumelems + size - 1) / size;
575 for(
int pid=1; pid<size; pid++) {
577 read_elem_block(ele_fd, read_binary, pid*blocksize, blocksize, meshbuff);
584 MPI_Send(meshbuff.
dsp.data(), meshbuff.
dsp.size()*
sizeof(T), MPI_BYTE, pid,
SF_MPITAG, comm);
585 MPI_Send(meshbuff.
tag.data(), meshbuff.
tag.size()*
sizeof(T), MPI_BYTE, pid,
SF_MPITAG, comm);
586 MPI_Send(ref_eidx.
data(), ref_eidx.
size()*
sizeof(T), MPI_BYTE, pid,
SF_MPITAG, comm);
593 size_t con_size = meshbuff.
con.size();
594 MPI_Send(&con_size,
sizeof(
size_t), MPI_BYTE, pid,
SF_MPITAG, comm);
595 MPI_Send(meshbuff.
con.data(), con_size*
sizeof(T), MPI_BYTE, pid,
SF_MPITAG, comm);
599 if(nFib>=1) fclose(fib_fd);
616 MPI_Recv(mesh.
dsp.data(), mesh.
dsp.size()*
sizeof(T), MPI_BYTE, 0,
SF_MPITAG, comm, &stat);
617 MPI_Recv(mesh.
tag.data(), mesh.
tag.size()*
sizeof(T), MPI_BYTE, 0,
SF_MPITAG, comm, &stat);
618 MPI_Recv(ref_eidx.
data(), ref_eidx.
size()*
sizeof(T), MPI_BYTE, 0,
SF_MPITAG, comm, &stat);
626 MPI_Recv(&con_size,
sizeof(
size_t), MPI_BYTE, 0,
SF_MPITAG, comm, &stat);
627 mesh.
con.resize(con_size);
628 MPI_Recv(mesh.
con.data(), con_size*
sizeof(T), MPI_BYTE, 0,
SF_MPITAG, comm, &stat);
645 template<
class T,
class S>
648 const MPI_Comm comm = mesh.
comm;
651 MPI_Comm_size(comm, &size); MPI_Comm_rank(comm, &rank);
653 FILE* ele_fd = NULL, *fib_fd = NULL;
660 std::string ele_file = binary ? basename +
".belem" : basename +
".elem";
661 std::string fib_file = binary ? basename +
".blon" : basename +
".lon";
665 ele_fd = fopen(ele_file.c_str(),
"w");
667 fprintf(stderr,
"Error: could not open file: %s. Aborting!\n", ele_file.c_str());
671 fib_fd = fopen(fib_file.c_str(),
"w");
673 fprintf(stderr,
"Error: could not open file: %s. Aborting!\n", fib_file.c_str());
680 if (nFib>=1) fclose(fib_fd);
684 for(
int pid=0; pid < size; pid++)
688 ele_fd = fopen(ele_file.c_str(),
"a");
690 fprintf(stderr,
"Error: could not open file: %s. Aborting!\n", ele_file.c_str());
694 fib_fd = fopen(fib_file.c_str(),
"a");
696 fprintf(stderr,
"Error: could not open file: %s. Aborting!\n", fib_file.c_str());
705 if(nFib>=1) fclose(fib_fd);
711 template<
class T,
class S>
714 const MPI_Comm comm = surfmesh.
comm;
715 const bool binary =
false;
718 MPI_Comm_size(comm, &size); MPI_Comm_rank(comm, &rank);
724 ele_fd = fopen(surffile.c_str(),
"w");
726 fprintf(stderr,
"Error: could not open file: %s. Aborting!\n", surffile.c_str());
729 fprintf(ele_fd,
"%lu\n", surfmesh.
g_numelem);
734 for(
int pid=0; pid < size; pid++)
737 ele_fd = fopen(surffile.c_str(),
"a");
739 fprintf(stderr,
"Error: could not open file: %s. Aborting!\n", surffile.c_str());
762 const int bufsize = 2048;
763 char buffer[bufsize];
769 for(
size_t i=0; i<bsize; i++) {
771 size_t r = fread(pts,
sizeof(
float), 3, fd);
775 char* ptr = fgets( buffer, bufsize, fd);
776 if(ptr == NULL)
break;
777 sscanf(buffer,
"%f %f %f", pts, pts+1, pts+2);
779 xyz[nr*3+0] = pts[0];
780 xyz[nr*3+1] = pts[1];
781 xyz[nr*3+2] = pts[2];
799 size_t nnodes = xyz.
size() / 3;
802 for(
size_t i=0; i<nnodes; i++)
809 fwrite(pt, 3,
sizeof(
float), fd);
811 fprintf(fd,
"%f %f %f\n", pt[0], pt[1], pt[2]);
823 template<
class T,
class S>
827 MPI_Comm_size(comm, &size); MPI_Comm_rank(comm, &rank);
831 bool read_binary =
false;
836 std::string pts_file = read_binary ? basename +
".bpts" : basename +
".pts";
838 pts_fd = fopen(pts_file.c_str(),
"r");
840 fprintf(stderr,
"Error: could not open file: %s. Aborting!\n", pts_file.c_str());
846 if(read_binary) fread(buffer,
sizeof(
char),
HDR_SIZE, pts_fd);
847 else fgets( buffer, 2048, pts_fd);
848 sscanf(buffer,
"%lu", &gnumpts);
850 MPI_Bcast(&gnumpts,
sizeof(
size_t), MPI_BYTE, 0, comm);
853 size_t blocksize = (gnumpts + size - 1) / size;
861 for(
int pid = 1; pid < size; pid++) {
863 long int numsend = buff.
size();
865 MPI_Send(&numsend, 1, MPI_LONG, pid,
SF_MPITAG, comm);
866 MPI_Send(buff.
data(), numsend*
sizeof(S), MPI_BYTE, pid,
SF_MPITAG, comm);
871 long int numrecv = 0;
872 MPI_Recv(&numrecv, 1, MPI_LONG, 0,
SF_MPITAG, comm, &stat);
875 MPI_Recv(pts.
data(), numrecv*
sizeof(S), MPI_BYTE, 0,
SF_MPITAG, comm, &stat);
878 long int mysize = pts.
size() / 3;
882 interval(ptsidx, layout[rank], layout[rank+1]);
884 if(rank == 0) fclose(pts_fd);
893 template<
class T,
class S>
898 assert(meshlist.size() > 0);
899 assert(pts.
size() == (ptsidx.
size() * 3));
903 MPI_Comm comm = (*meshlist.begin())->comm;
906 MPI_Comm_size(comm, &size); MPI_Comm_rank(comm, &rank);
911 for(
int pid = 0; pid < size; pid++) {
912 size_t numsend = pts.
size();
913 MPI_Bcast(&numsend,
sizeof(
size_t), MPI_BYTE, pid, comm);
921 idxbuff.
resize(numsend / 3);
924 MPI_Bcast(ptsbuff.
data(), ptsbuff.
size()*
sizeof(S), MPI_BYTE, pid, comm);
925 MPI_Bcast(idxbuff.
data(), idxbuff.
size()*
sizeof(T), MPI_BYTE, pid, comm);
929 for(
auto it = meshlist.begin(); it != meshlist.end(); ++it)
937 for(
size_t i=0; i<rnod.
size(); i++)
945 for(
size_t j=0; j<idxbuff.
size(); j++) {
946 if(g2l.
count(idxbuff[j])) {
953 for(
size_t j=0; j<ridx.
size(); j++) {
954 T w = widx[j], r = ridx[j];
955 mesh.
xyz[w*3+0] = ptsbuff[r*3+0];
956 mesh.
xyz[w*3+1] = ptsbuff[r*3+1];
957 mesh.
xyz[w*3+2] = ptsbuff[r*3+2];
969 template<
class T,
class S>
972 FILE* vtk_file = fopen(file.c_str(),
"w");
973 if(vtk_file == NULL)
return;
976 fprintf (vtk_file,
"# vtk DataFile Version 3.0\n");
977 fprintf (vtk_file,
"vtk output\n");
978 fprintf (vtk_file,
"binary\n");
979 fprintf (vtk_file,
"DATASET UNSTRUCTURED_GRID\n\n");
980 fprintf (vtk_file,
"POINTS %lu float\n", mesh.
l_numpts);
985 for (
unsigned long int i=0; i<mesh.
l_numpts; i++ ) {
986 pts[0] =
htobe(p[0]);
987 pts[1] =
htobe(p[1]);
988 pts[2] =
htobe(p[2]);
989 fwrite(pts,
sizeof(
float), 3, vtk_file);
992 fprintf(vtk_file,
"\n");
994 fprintf (vtk_file,
"CELL_TYPES %lu\n", mesh.
l_numelem);
995 unsigned long int valcount = 0;
997 for(
unsigned long int i=0; i< mesh.
l_numelem; i++) {
1024 vtk_type =
htobe(vtk_type);
1025 fwrite(&vtk_type,
sizeof(
int), 1, vtk_file);
1026 valcount += mesh.
dsp[i+1] - mesh.
dsp[i] + 1;
1028 fprintf(vtk_file,
"\n");
1030 fprintf(vtk_file,
"CELLS %lu %lu\n", mesh.
l_numelem, valcount);
1031 const T* elem = mesh.
con.data();
1032 for(
unsigned long int i=0; i<mesh.
l_numelem; i++)
1034 int nodes = mesh.
dsp[i+1] - mesh.
dsp[i], n;
1035 int be_nodes =
htobe(nodes);
1036 fwrite(&be_nodes,
sizeof(
int), 1, vtk_file);
1038 for(
int j=0; j<nodes; j++) {
1039 n = elem[j]; n =
htobe(n);
1040 fwrite(&n,
sizeof(
int), 1, vtk_file);
1044 fprintf(vtk_file,
"\n");
1046 fprintf (vtk_file,
"CELL_DATA %lu \n", mesh.
l_numelem);
1047 fprintf (vtk_file,
"SCALARS elemTag int 1\n");
1048 fprintf (vtk_file,
"LOOKUP_TABLE default\n");
1049 for (
unsigned long int i=0; i<mesh.
l_numelem; i++ ) {
1051 fwrite(&t,
sizeof(
int), 1, vtk_file);
1062 fprintf (vtk_file,
"VECTORS fiber float\n");
1063 for (
unsigned long int i=0; i<mesh.
l_numelem; i++ ) {
1064 pts[0] =
htobe(
float(mesh.
fib[i*3+0])),
1065 pts[1] =
htobe(
float(mesh.
fib[i*3+1])),
1066 pts[2] =
htobe(
float(mesh.
fib[i*3+2]));
1067 fwrite(pts,
sizeof(
float), 3, vtk_file);
1069 fprintf(vtk_file,
"\n");
1072 fprintf (vtk_file,
"VECTORS sheet float\n");
1073 for (
unsigned long int i=0; i<mesh.
l_numelem; i++ ) {
1074 pts[0] =
htobe(
float(mesh.
she[i*3+0])),
1075 pts[1] =
htobe(
float(mesh.
she[i*3+1])),
1076 pts[2] =
htobe(
float(mesh.
she[i*3+2]));
1077 fwrite(pts,
sizeof(
float), 3, vtk_file);
1079 fprintf(vtk_file,
"\n");
#define SF_MPITAG
the MPI tag when communicating
Functions related to network communication.
The vector class and related algorithms.
The mesh storage class. It contains both element and vertex data.
vector< T > dsp
connectivity starting index of each element
vector< S > she
sheet direction
vector< S > fib
fiber direction
size_t l_numelem
local number of elements
vector< elem_t > type
element type
vector< T > & register_numbering(SF_nbr nbr_type)
Register a new numbering to the mesh and return the associated index vector.
vector< S > xyz
node cooridnates
size_t l_numpts
local number of points
size_t g_numelem
global number of elements
void localize(SF_nbr nbr_type)
Localize the connectivity data w.r.t. a given numbering.
MPI_Comm comm
the parallel mesh is defined on a MPI world
vector< T > & get_numbering(SF_nbr nbr_type)
Get the vector defining a certain numbering.
vector< T > tag
element tag
A vector storing arbitrary data.
size_t size() const
The current size of the vector.
void resize(size_t n)
Resize a vector.
T * data()
Pointer to the vector's start.
hm_int count(const K &key) const
Check if key exists.
void read_pts_block(FILE *&fd, bool read_binary, size_t bsize, vector< S > &xyz)
Read a chunk of points from a file descriptor.
void read_headers(FILE *ele_fd, FILE *fib_fd, bool read_binary, size_t &numelem, int &nFib)
Read the header from the element and fiber files.
void read_points(const std::string basename, const MPI_Comm comm, vector< S > &pts, vector< T > &ptsidx)
Read the points and insert them into a list of meshes.
void read_fib_block(FILE *&fd, bool read_binary, int nFib, size_t bsize, meshdata< T, S > &mesh)
Read a chunk of fibers from a file descriptor.
void write_pts_block(FILE *&fd, bool write_binary, const vector< S > &xyz)
Write a chunk of points to a file.
void interval(vector< T > &vec, size_t start, size_t end)
Create an integer interval between start and end.
void write_surface(const meshdata< T, S > &surfmesh, std::string surffile)
void write_elements(const meshdata< T, S > &mesh, bool binary, std::string basename)
Read the element data (elements and fibers) of a CARP mesh.
void writeVTKmesh_binary(const meshdata< T, S > &mesh, std::string file)
Write a mesh in binary vtk format.
void insert_points(const vector< S > &pts, const vector< T > &ptsidx, std::list< meshdata< T, S > * > &meshlist)
Insert the points from the read-in buffers into a list of distributed meshes.
void write_pts_header(FILE *&pts_fd, bool binary, size_t numpts)
Write the header of the points file.
void read_elem_block(FILE *&fd, bool read_binary, size_t bstart, size_t bsize, meshdata< T, S > &mesh)
Read a block of size bsize from an CARP element file.
void write_elem_headers(FILE *&ele_fd, FILE *&fib_fd, bool binary, size_t numelem, int nFib)
Write the header of the element and fiber files.
void write_fib_block(FILE *&fd, bool write_binary, const meshdata< T, S > &mesh)
Write the local chunk of fibers to a file.
void vec_assign(S *lhs, const V *rhs, size_t size)
Assign the values in rhs to lhs. The data-type of rhs is cast to the type of lhs.
bool fileExists(std::string filename)
Function which checks if a given file exists.
elem_t getElemTypeID(char *eletype)
Generate element type enum from string.
void layout_from_count(const T count, vector< T > &layout, MPI_Comm comm)
size_t read_num_pts(std::string basename)
Function returns the number of points in a CARP points file.
void read_elements(meshdata< T, S > &mesh, std::string basename, bool require_fibers=true)
Read the element data (elements and fibers) of a CARP mesh.
@ NBR_ELEM_REF
The element numbering of the reference mesh (the one stored on HD).
@ NBR_REF
The nodal numbering of the reference mesh (the one stored on HD).
void write_elem_block(FILE *fd, bool write_binary, const meshdata< T, S > &mesh)
Write the local element block to a file.