sandbox/Cyprien_Lemarechal/output_vtu_foreach.h
Changes
This function is borrowed from acastillo’s sandbox : output_vtu_foreach.h
The addition is a function “time_output_test()” that can be called during the run to write a time-series collection of files, either in squential or MPI. The output file is a *.pvd file that can be read right away in Paraview to diplay each timestep saved with “output_vtu()”.
The header / footer will be missing in restart / brut stop.
An example here.
#include <stdint.h>
/*
This function writes one XML VTK file per PID process of type unstructured grid
(*.vtu) which can be read using Paraview. File stores scalar and vector fields
defined at the center points. Results are recorded on binary format. If one writes
one *.vtu file per PID process this function may be combined with
output_pvtu() above to read in parallel. Tested in (quad- and oct-)trees
using MPI. Also works with solids (when not using MPI).
*/
void output_vtu_pid (scalar * list, vector * vlist, char * subname)
{
char name[80];
sprintf(name, "%s.vtu", subname);
FILE * fp = fopen(name, "w");
#if defined(_OPENMP)
int num_omp = omp_get_max_threads();
(1);
omp_set_num_threads#endif
// This is to match the number of points and vertices when using periodic conditions
scalar per_mask[];
foreach(){
[] = 1.;
per_maskif (((Period.x) & (x + Delta > X0 + L0)))
[] = 0.;
per_mask#if dimension > 1
if (((Period.y) & (y + Delta > Y0 + L0)))
[] = 0.;
per_mask#endif
#if dimension > 2
if (((Period.z) & (z + Delta > Z0 + L0)))
[] = 0.;
per_mask#endif
}
vertex scalar marker[];
uint64_t no_points = 0, no_cells=0 ;
foreach_vertex(){
[] = _k;
markerif is_vertex(cell)
+= 1;
no_points }
foreach()
if (per_mask[])
+= 1;
no_cells
("<?xml version=\"1.0\"?>\n"
fputs "<VTKFile type=\"UnstructuredGrid\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">\n", fp);
("\t <UnstructuredGrid>\n", fp);
fputs fprintf (fp,"\t\t <Piece NumberOfPoints=\"%ld\" NumberOfCells=\"%ld\">\n", no_points, no_cells);
("\t\t\t <CellData Scalars=\"scalars\">\n", fp);
fputs
uint64_t count = 0;
for (scalar s in list) {
fprintf (fp,"\t\t\t\t <DataArray type=\"Float64\" Name=\"%s\" format=\"appended\" offset=\"%ld\"/>\n", s.name, count);
+= (no_cells * sizeof (double)) + sizeof (uint64_t);
count }
for (vector v in vlist) {
fprintf (fp,"\t\t\t\t <DataArray type=\"Float64\" Name=\"%s\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%ld\"/>\n", v.x.name, count);
+= (3 * no_cells * sizeof (double)) + sizeof (uint64_t);
count }
("\t\t\t </CellData>\n", fp);
fputs ("\t\t\t <Points>\n", fp);
fputs fprintf (fp,"\t\t\t\t <DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%ld\"/>\n",count);
("\t\t\t </Points>\n", fp);
fputs ("\t\t\t <Cells>\n", fp);
fputs += (3 * no_points * sizeof (double)) + sizeof (uint64_t);
count
#if dimension == 2
uint8_t type=9, noffset=4;
#elif dimension == 3
uint8_t type=12, noffset=8;
#endif
uint64_t offset, connectivity[noffset];
fprintf (fp,"\t\t\t\t <DataArray type=\"UInt64\" Name=\"offsets\" format=\"appended\" offset=\"%ld\"/>\n", count);
+= (no_cells * sizeof (uint64_t)) + sizeof (uint64_t);
count
fprintf (fp,"\t\t\t\t <DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\"%ld\"/>\n", count);
+= (no_cells * sizeof (uint8_t)) + sizeof (uint64_t);
count
fprintf (fp,"\t\t\t\t <DataArray type=\"UInt64\" Name=\"connectivity\" format=\"appended\" offset=\"%ld\"/>\n", count);
+= (no_cells * noffset * sizeof (uint64_t)) + sizeof (uint64_t);
count
("\t\t\t </Cells>\n", fp);
fputs ("\t\t </Piece>\n", fp);
fputs ("\t </UnstructuredGrid>\n", fp);
fputs ("\t <AppendedData encoding=\"raw\">\n", fp);
fputs ("_", fp);
fputs
uint64_t block_len=no_cells*sizeof (double);
#if dimension == 2
double vz=0;
#endif
for (scalar s in list) {
(&block_len, sizeof (uint64_t), 1, fp);
fwrite foreach()
if (per_mask[])
(&val(s), sizeof (double), 1, fp);
fwrite }
=no_cells*3*sizeof (double);
block_lenfor (vector v in vlist) {
(&block_len, sizeof (uint64_t), 1, fp);
fwrite foreach(){
if (per_mask[]){
(&val(v.x), sizeof (double), 1, fp);
fwrite (&val(v.y), sizeof (double), 1, fp);
fwrite #if dimension == 2
(&vz, sizeof (double), 1, fp);
fwrite #elif dimension == 3
(&val(v.z), sizeof (double), 1, fp);
fwrite #endif
}
}
}
=no_points*3*sizeof (double);
block_len(&block_len, sizeof (uint64_t), 1, fp);
fwrite foreach_vertex(){
(&x, sizeof (double), 1, fp);
fwrite (&y, sizeof (double), 1, fp);
fwrite (&z, sizeof (double), 1, fp);
fwrite }
=no_cells*1*sizeof(uint64_t);
block_len(&block_len, sizeof (uint64_t), 1, fp);
fwrite for (int i = 0; i < no_cells; i++){
= (i+1)*noffset;
offset (&offset, sizeof (int64_t), 1, fp);
fwrite }
=no_cells*1*sizeof(uint8_t);
block_len(&block_len, sizeof (uint64_t), 1, fp);
fwrite for (int i = 0; i < no_cells; i++)
(&type, sizeof (int8_t), 1, fp);
fwrite
=no_cells*noffset*sizeof(uint64_t);
block_len(&block_len, sizeof (uint64_t), 1, fp);
fwrite foreach(){
if (per_mask[]){
[0] = (uint64_t)marker[];
connectivity[1] = (uint64_t)marker[1];
connectivity[2] = (uint64_t)marker[1,1];
connectivity[3] = (uint64_t)marker[0,1];
connectivity#if dimension == 3
[4] = (uint64_t)marker[0,0,1];
connectivity[5] = (uint64_t)marker[1,0,1];
connectivity[6] = (uint64_t)marker[1,1,1];
connectivity[7] = (uint64_t)marker[0,1,1];
connectivity#endif
(&connectivity, sizeof (uint64_t), noffset, fp);
fwrite }
}
("\t\n", fp);
fputs ("\t </AppendedData>\n", fp);
fputs ("</VTKFile>\n", fp);
fputs fflush (fp);
#if defined(_OPENMP)
(num_omp);
omp_set_num_threads#endif
fclose (fp);
}
/*
This function writes one XML file which allows to read the *.vtu files generated
by output_vtu() when used in MPI. Tested in (quad- and oct-)trees
using MPI.
*/
@if _MPIvoid output_pvtu (scalar * list, vector * vlist, char * subname)
{
char name[80];
FILE * fp;
if (pid() == 0) {
sprintf(name, "%s.pvtu", subname);
= fopen(name, "w");
fp
("<?xml version=\"1.0\"?>\n"
fputs "<VTKFile type=\"PUnstructuredGrid\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">\n", fp);
("\t <PUnstructuredGrid GhostLevel=\"0\">\n", fp);
fputs ("\t\t\t <PCellData Scalars=\"scalars\">\n", fp);
fputs for (scalar s in list) {
fprintf (fp,"\t\t\t\t <PDataArray type=\"Float64\" Name=\"%s\" format=\"appended\">\n", s.name);
("\t\t\t\t </PDataArray>\n", fp);
fputs }
for (vector v in vlist) {
fprintf (fp,"\t\t\t\t <PDataArray type=\"Float64\" NumberOfComponents=\"3\" Name=\"%s\" format=\"appended\">\n", v.x.name);
("\t\t\t\t </PDataArray>\n", fp);
fputs }
("\t\t\t </PCellData>\n", fp);
fputs ("\t\t\t <PPoints>\n", fp);
fputs ("\t\t\t\t <PDataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"appended\">\n", fp);
fputs ("\t\t\t\t </PDataArray>\n", fp);
fputs ("\t\t\t </PPoints>\n", fp);
fputs
for (int i = 0; i < npe(); i++)
fprintf (fp, "<Piece Source=\"%s_n%3.3d.vtu\"/> \n", subname, i);
("\t </PUnstructuredGrid>\n", fp);
fputs ("</VTKFile>\n", fp);
fputs fflush (fp);
fclose (fp);
}
(MPI_COMM_WORLD);
MPI_Barrier
sprintf(name, "%s_n%3.3d", subname, pid());
output_vtu_pid (list, vlist, name);
}
@endif
trace
void output_vtu (scalar * list, vector * vlist, char * subname)
{
@if _MPIoutput_pvtu (list, vlist, subname);
@elseoutput_vtu_pid (list, vlist, subname);
@endif}
This function writes a slice defined by n={n_x, n_y, n_z} and \alpha using a similar approach to
view.h
into one XML VTK file per PID process of type
unstructured grid (*.vtu) in binary format which can be read using
Paraview. Only works for x, y, and/or z planes. Here, _alpha is assumed
to intersect a cell face and must be a multiple of L0/1<<MINLEVEL.
This also means that scalar and vector fields are written at the
corresponding face values.
#if dimension > 2
void output_vtu_plane_pid (scalar * list, vector * vlist, char * subname, coord n, double _alpha)
{
char name[80];
sprintf(name, "%s.vtu", subname);
FILE * fp = fopen(name, "w");
#if defined(_OPENMP)
int num_omp = omp_get_max_threads();
(1);
omp_set_num_threads#endif
scalar per_mask[];
foreach(){
[] = 0.;
per_maskdouble alpha = (_alpha - n.x*x - n.y*y - n.z*z)/Delta;
if (fabs(alpha) > 0.87)
continue;
if (alpha > 0.)
[] = 1.;
per_mask
if ((((Period.x) & (x + Delta > X0 + L0)) || ((Period.y) & (y + Delta > Y0 + L0))) || ((Period.z) & (z + Delta > Z0 + L0)))
[] = 0.;
per_mask}
vertex scalar marker[];
uint64_t no_points = 0, no_cells=0 ;
foreach_vertex(){
[] = 0.;
markerdouble alpha = (_alpha - n.x*x - n.y*y - n.z*z)/Delta;
if (fabs(alpha) > 0.87)
continue;
[] = no_points;
marker+= 1;
no_points }
foreach()
if (per_mask[])
+= 1;
no_cells
("<?xml version=\"1.0\"?>\n"
fputs "<VTKFile type=\"UnstructuredGrid\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">\n", fp);
("\t <UnstructuredGrid>\n", fp);
fputs fprintf (fp,"\t\t <Piece NumberOfPoints=\"%ld\" NumberOfCells=\"%ld\">\n", no_points, no_cells);
("\t\t\t <CellData Scalars=\"scalars\">\n", fp);
fputs
uint64_t count = 0;
for (scalar s in list) {
fprintf (fp,"\t\t\t\t <DataArray type=\"Float64\" Name=\"%s\" format=\"appended\" offset=\"%ld\"/>\n", s.name, count);
+= (no_cells * sizeof (double)) + sizeof (uint64_t);
count }
for (vector v in vlist) {
fprintf (fp,"\t\t\t\t <DataArray type=\"Float64\" Name=\"%s\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%ld\"/>\n", v.x.name, count);
+= (3 * no_cells * sizeof (double)) + sizeof (uint64_t);
count }
("\t\t\t </CellData>\n", fp);
fputs ("\t\t\t <Points>\n", fp);
fputs fprintf (fp,"\t\t\t\t <DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%ld\"/>\n", count);
("\t\t\t </Points>\n", fp);
fputs ("\t\t\t <Cells>\n", fp);
fputs += (3 * no_points * sizeof (double)) + sizeof (uint64_t);
count
uint8_t type=9, noffset=4;
uint64_t offset, connectivity[noffset];
fprintf (fp,"\t\t\t\t <DataArray type=\"UInt64\" Name=\"offsets\" format=\"appended\" offset=\"%ld\"/>\n", count);
+= (no_cells * sizeof (uint64_t)) + sizeof (uint64_t);
count
fprintf (fp,"\t\t\t\t <DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\"%ld\"/>\n", count);
+= (no_cells * sizeof (uint8_t)) + sizeof (uint64_t);
count
fprintf (fp,"\t\t\t\t <DataArray type=\"UInt64\" Name=\"connectivity\" format=\"appended\" offset=\"%ld\"/>\n", count);
+= (no_cells * noffset * sizeof (uint64_t)) + sizeof (uint64_t);
count
("\t\t\t </Cells>\n", fp);
fputs ("\t\t </Piece>\n", fp);
fputs ("\t </UnstructuredGrid>\n", fp);
fputs ("\t <AppendedData encoding=\"raw\">\n", fp);
fputs ("_", fp);
fputs
uint64_t block_len=no_cells*sizeof (double);
for (scalar s in list) {
(&block_len, sizeof (uint64_t), 1, fp);
fwrite foreach(){
if (per_mask[]){
double sval;
if (n.x == 1)
= 0.5*(val(s) + val(s,1,0,0));
sval else if (n.y == 1)
= 0.5*(val(s) + val(s,0,1,0));
sval
else= 0.5*(val(s) + val(s,0,0,1));
sval (&sval, sizeof (double), 1, fp);
fwrite }
}
}
=no_cells*3*sizeof (double);
block_lenfor (vector v in vlist) {
(&block_len, sizeof (uint64_t), 1, fp);
fwrite foreach(){
if (per_mask[]){
double xval, yval, zval;
if (n.x == 1) {
= 0.5*(val(v.x) + val(v.x,1,0,0));
xval = 0.5*(val(v.y) + val(v.y,1,0,0));
yval = 0.5*(val(v.z) + val(v.z,1,0,0));
zval }
else if (n.y == 1) {
= 0.5*(val(v.x) + val(v.x,0,1,0));
xval = 0.5*(val(v.y) + val(v.y,0,1,0));
yval = 0.5*(val(v.z) + val(v.z,0,1,0));
zval }
else {
= 0.5*(val(v.x) + val(v.x,0,0,1));
xval = 0.5*(val(v.y) + val(v.y,0,0,1));
yval = 0.5*(val(v.z) + val(v.z,0,0,1));
zval }
(&xval, sizeof (double), 1, fp);
fwrite (&yval, sizeof (double), 1, fp);
fwrite (&zval, sizeof (double), 1, fp);
fwrite }
}
}
=no_points*3*sizeof (double);
block_len(&block_len, sizeof (uint64_t), 1, fp);
fwrite foreach_vertex(){
double alpha = (_alpha - n.x*x - n.y*y - n.z*z)/Delta;
if (fabs(alpha) > 0.87)
continue;
(&x, sizeof (double), 1, fp);
fwrite (&y, sizeof (double), 1, fp);
fwrite (&z, sizeof (double), 1, fp);
fwrite }
=no_cells*1*sizeof(uint64_t);
block_len(&block_len, sizeof (uint64_t), 1, fp);
fwrite for (int i = 0; i < no_cells; i++){
= (i+1)*noffset;
offset (&offset, sizeof (int64_t), 1, fp);
fwrite }
=no_cells*1*sizeof(uint8_t);
block_len(&block_len, sizeof (uint64_t), 1, fp);
fwrite for (int i = 0; i < no_cells; i++)
(&type, sizeof (int8_t), 1, fp);
fwrite
=no_cells*noffset*sizeof(uint64_t);
block_len(&block_len, sizeof (uint64_t), 1, fp);
fwrite foreach(){
if (per_mask[]){
if (n.x == 1) {
[0] = (uint64_t)marker[1,0,0];
connectivity[1] = (uint64_t)marker[1,1,0];
connectivity[2] = (uint64_t)marker[1,1,1];
connectivity[3] = (uint64_t)marker[1,0,1];
connectivity}
else if (n.y == 1) {
[0] = (uint64_t)marker[0,1,0];
connectivity[1] = (uint64_t)marker[1,1,0];
connectivity[2] = (uint64_t)marker[1,1,1];
connectivity[3] = (uint64_t)marker[0,1,1];
connectivity}
else {
[0] = (uint64_t)marker[0,0,1];
connectivity[1] = (uint64_t)marker[1,0,1];
connectivity[2] = (uint64_t)marker[1,1,1];
connectivity[3] = (uint64_t)marker[0,1,1];
connectivity}
(&connectivity, sizeof (uint64_t), noffset, fp);
fwrite }
}
("\t\n", fp);
fputs ("\t </AppendedData>\n", fp);
fputs ("</VTKFile>\n", fp);
fputs fflush (fp);
#if defined(_OPENMP)
(num_omp);
omp_set_num_threads#endif
}
@if _MPIvoid output_pvtu_plane (scalar * list, vector * vlist, char * subname, coord n, double _alpha)
{
char name[80];
FILE * fp;
if (pid() == 0) {
sprintf(name, "%s.pvtu", subname);
= fopen(name, "w");
fp
("<?xml version=\"1.0\"?>\n"
fputs "<VTKFile type=\"PUnstructuredGrid\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">\n", fp);
("\t <PUnstructuredGrid GhostLevel=\"0\">\n", fp);
fputs ("\t\t\t <PCellData Scalars=\"scalars\">\n", fp);
fputs for (scalar s in list) {
fprintf (fp,"\t\t\t\t <PDataArray type=\"Float64\" Name=\"%s\" format=\"appended\">\n", s.name);
("\t\t\t\t </PDataArray>\n", fp);
fputs }
for (vector v in vlist) {
fprintf (fp,"\t\t\t\t <PDataArray type=\"Float64\" NumberOfComponents=\"3\" Name=\"%s\" format=\"appended\">\n", v.x.name);
("\t\t\t\t </PDataArray>\n", fp);
fputs }
("\t\t\t </PCellData>\n", fp);
fputs ("\t\t\t <PPoints>\n", fp);
fputs ("\t\t\t\t <PDataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"appended\">\n", fp);
fputs ("\t\t\t\t </PDataArray>\n", fp);
fputs ("\t\t\t </PPoints>\n", fp);
fputs
for (int i = 0; i < npe(); i++)
fprintf (fp, "<Piece Source=\"%s_n%3.3d.vtu\"/> \n", subname, i);
("\t </PUnstructuredGrid>\n", fp);
fputs ("</VTKFile>\n", fp);
fputs fflush (fp);
fclose (fp);
}
(MPI_COMM_WORLD);
MPI_Barrier
sprintf(name, "%s_n%3.3d", subname, pid());
output_vtu_plane_pid (list, vlist, name, n, _alpha);
}
@endif
trace
void output_vtu_plane (scalar * list, vector * vlist, char * subname, coord n, double _alpha)
{
@if _MPIoutput_pvtu_plane (list, vlist, subname, n, _alpha);
@elseoutput_vtu_plane_pid (list, vlist, subname, n, _alpha);
@endif}
#endif
Here are the additions
void time_output (char * subname, char * newline, double timestep, int nb_file, int file_number)
{
char name[200], name2[200];
FILE * fp;
sprintf (name, "%s.pvd", subname);
sprintf (name2, "%s.vtu", newline);
if (file_number == 0) {
= fopen (name, "w");
fp ("<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">\n", fp);
fputs ("\t<Collection>\n", fp);
fputs fprintf (fp, "\t\t <DataSet timestep=\"%g\" file=\"%s\"/>\n", timestep, name2);
fflush (fp);
fclose (fp);
}
if (file_number < nb_file - 1 && file_number != 0) {
= fopen (name, "a");
fp fprintf (fp, "\t\t <DataSet timestep=\"%g\" file=\"%s\"/>\n", timestep, name2);
fflush (fp);
fclose (fp);
}
if (file_number == nb_file-1 ) {
= fopen(name, "a");
fp fprintf (fp,"\t\t <DataSet timestep=\"%g\" file=\"%s\"/>\n", timestep,name2);
("\t</Collection>\n", fp);
fputs ("</VTKFile>\n", fp);
fputs fflush (fp);
fclose (fp);
}
}
void time_output_test (char * subname, char * newline, double timestep, int nb_file, int file_number)
{
char name[200], name2[200];
FILE * fp;
sprintf (name, "%s.pvd", subname);
@if _MPIif (pid() == 0) {
sprintf(name2, "%s.pvtu", newline);
if (file_number == 0) {
= fopen(name, "w");
fp ("<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">\n", fp);
fputs ("\t<Collection>\n", fp);
fputs fprintf (fp, "\t\t <DataSet timestep=\"%g\" file=\"%s\"/>\n", timestep, name2);
fflush (fp);
fclose (fp);
}
if (file_number < nb_file - 1 && file_number != 0) {
= fopen (name, "a");
fp fprintf (fp, "\t\t <DataSet timestep=\"%g\" file=\"%s\"/>\n", timestep, name2);
fflush (fp);
fclose (fp);
}
if (file_number == nb_file - 1) {
= fopen(name, "a");
fp fprintf (fp, "\t\t <DataSet timestep=\"%g\" file=\"%s\"/>\n", timestep, name2);
("\t</Collection>\n", fp);
fputs ("</VTKFile>\n", fp);
fputs fflush (fp);
fclose (fp);
}
}
(MPI_COMM_WORLD);
MPI_Barrier
@elsetime_output (subname, newline, timestep, nb_file, file_number);
@endif}