sandbox/acastillo/output_fields/vtu/output_vtu_helpers.h
Helper functions for output_vtu.h
#include "geometry.h"
#include "fractions.h"
#if dimension == 1
mycs(Point point, scalar c)
coord {
= {1.};
coord n return n;
}
#elif dimension == 2
#include "myc2d.h"
#define mfacets int m = facets(n, alpha, v);
#else // dimension == 3
#include "myc.h"
#define mfacets int m = facets(n, alpha, v, 1.);
#endif
Macro to simplify facets calculation
#define shortcut_facets \
; \
coord n= mycs(point, c); \
n double alpha = plane_alpha(c[], n); \
[12]; \
coord v; mfacets
Macro to simplify dealing with slices
#define shortcut_slice(n, _alpha) \
double alpha = (_alpha - n.x * x - n.y * y - n.z * z) / Delta; \
if (fabs(alpha) > 0.87) \
continue;
Functions to write light data
Write the VTU file header
void write_vtu_header(FILE *fp, long no_points, long no_cells) {
("<?xml version=\"1.0\"?>\n", fp);
fputs("<VTKFile type=\"UnstructuredGrid\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">\n", fp);
fputs("\t<UnstructuredGrid>\n", fp);
fputsfprintf(fp, "\t\t<Piece NumberOfPoints=\"%ld\" NumberOfCells=\"%ld\">\n", no_points, no_cells);
}
void write_pvtu_header(FILE *fp) {
("<?xml version=\"1.0\"?>\n", fp);
fputs("<VTKFile type=\"PUnstructuredGrid\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">\n", fp);
fputs("\t<PUnstructuredGrid GhostLevel=\"0\">\n", fp);
fputs}
Write scalar data arrays
void write_scalar_light_data(FILE *fp, scalar *list, vector *vlist, long *count, long no_cells) {
("\t\t\t<CellData Scalars=\"scalars\">\n", fp);
fputsfor (scalar s in list){
fprintf(fp, "\t\t\t\t<DataArray type=\"Float64\" Name=\"%s\" format=\"appended\" offset=\"%ld\"/>\n", s.name, *count);
*count += (no_cells * sizeof(double)) + sizeof(long);
}
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);
*count += (3 * no_cells * sizeof(double)) + sizeof(long);
}
("\t\t\t</CellData>\n", fp);
fputs}
void write_scalar_light_pdata(FILE *fp, scalar *list, vector *vlist) {
("\t\t<PCellData Scalars=\"scalars\">\n", fp);
fputs
for (scalar s in list){
fprintf(fp, "\t\t\t<PDataArray type=\"Float64\" Name=\"%s\" format=\"appended\"/>\n", s.name);
}
for (vector v in vlist){
fprintf(fp, "\t\t\t<PDataArray type=\"Float64\" NumberOfComponents=\"3\" Name=\"%s\" format=\"appended\"/>\n", v.x.name);
}
("\t\t</PCellData>\n", fp);
fputs}
Write points data array
void write_points_light_data(FILE *fp, long *count, long no_points) {
("\t\t\t<Points>\n", fp);
fputsfprintf(fp, "\t\t\t\t<DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%ld\"/>\n", *count);
("\t\t\t</Points>\n", fp);
fputs
*count += (3 * no_points * sizeof(double)) + sizeof(long);
}
void write_points_light_pdata(FILE *fp) {
("\t\t<PPoints>\n", fp);
fputs("\t\t\t<PDataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"appended\"/>\n", fp);
fputs("\t\t</PPoints>\n", fp);
fputs}
Write cells data arrays
void write_cells_light_data(FILE *fp, long *count, long no_cells, long no_cells_offset) {
("\t\t\t<Cells>\n", fp);
fputs
fprintf(fp, "\t\t\t\t<DataArray type=\"Int64\" Name=\"offsets\" format=\"appended\" offset=\"%ld\"/>\n", *count);
*count += (no_cells * sizeof(long)) + sizeof(long);
fprintf(fp, "\t\t\t\t<DataArray type=\"Int8\" Name=\"types\" format=\"appended\" offset=\"%ld\"/>\n", *count);
*count += (no_cells * sizeof(char)) + sizeof(long);
fprintf(fp, "\t\t\t\t<DataArray type=\"Int64\" Name=\"connectivity\" format=\"appended\" offset=\"%ld\"/>\n", *count);
*count += (no_cells_offset * sizeof(long)) + sizeof(long);
("\t\t\t</Cells>\n", fp);
fputs}
Write appended data section
void write_vtu_appended(FILE *fp) {
("\t\t</Piece>\n", fp);
fputs("\t</UnstructuredGrid>\n", fp);
fputs("\t<AppendedData encoding=\"raw\">\n", fp);
fputs("_", fp);
fputs}
Write piece references for each process
void write_pieces_light_pdata(FILE *fp, char *subname) {
for (int i = 0; i < npe(); i++){
fprintf(fp, "\t\t<Piece Source=\"%s_n%3.3d.vtu\"/>\n", subname, i);
}
("\t</PUnstructuredGrid>\n", fp);
fputs("</VTKFile>\n", fp);
fputs}
Functions to write heavy data
Write scalar field data
void write_scalar_heavy_data(FILE *fp, scalar *list, scalar per_mask, long no_cells){
long block_len = no_cells * sizeof(double);
for (scalar s in list){
(&block_len, sizeof(long), 1, fp);
fwriteforeach (){
if (per_mask[]){
(&val(s), sizeof(double), 1, fp);
fwrite}
}
}
}
void write_scalar_heavy_data_slice(FILE *fp, scalar *list, scalar per_mask, long no_cells, coord n = {0, 0, 1}, double _alpha = 0){
long block_len = no_cells * sizeof(double);
for (scalar s in list){
(&block_len, sizeof(long), 1, fp);
fwriteforeach (){
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}
}
}
}
void write_scalar_heavy_data_array(FILE *fp, long no_cells, double *pt_array_s){
long block_len = no_cells * sizeof(double);
(&block_len, sizeof(long), 1, fp);
fwritefor (int i = 0; i < no_cells; i++){
(&pt_array_s[i], sizeof(double), 1, fp);
fwrite}
}
Write vector field data
void write_vector_heavy_data(FILE *fp, vector *vlist, scalar per_mask, long no_cells){
long block_len = no_cells * 3 * sizeof(double);
for (vector v in vlist){
(&block_len, sizeof(long), 1, fp);
fwriteforeach (){
if (per_mask[]){
(&val(v.x), sizeof(double), 1, fp);
fwrite(&val(v.y), sizeof(double), 1, fp);
fwrite#if dimension == 2
double vz = 0;
(&vz, sizeof(double), 1, fp);
fwrite#elif dimension == 3
(&val(v.z), sizeof(double), 1, fp);
fwrite#endif
}
}
}
}
void write_vector_heavy_data_slice(FILE *fp, vector *vlist, scalar per_mask, long no_cells, coord n = {0, 0, 1}, double _alpha = 0){
long block_len = no_cells * 3 * sizeof(double);
for (vector v in vlist){
(&block_len, sizeof(long), 1, fp);
fwriteforeach (){
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 #if dimension == 3
= 0.5 * (val(v.z) + val(v.z, 1, 0, 0));
zval #else
= 0;
zval #endif
}
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 #if dimension == 3
= 0.5 * (val(v.z) + val(v.z, 0, 1, 0));
zval #else
= 0;
zval #endif
}
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 #if dimension == 3
= 0.5 * (val(v.z) + val(v.z, 0, 0, 1));
zval #else
= 0;
zval #endif
}
(&xval, sizeof(double), 1, fp);
fwrite(&yval, sizeof(double), 1, fp);
fwrite(&zval, sizeof(double), 1, fp);
fwrite}
}
}
}
Write points data
void write_points_heavy_data(FILE *fp, long no_points) {
long block_len = no_points * 3 * sizeof(double);
(&block_len, sizeof(long), 1, fp);
fwriteforeach_vertex(){
(&x, sizeof(double), 1, fp);
fwrite(&y, sizeof(double), 1, fp);
fwrite(&z, sizeof(double), 1, fp);
fwrite}
}
void write_points_heavy_data_masked(FILE *fp, long no_points, vertex scalar mask) {
long block_len = no_points * 3 * sizeof(double);
(&block_len, sizeof(long), 1, fp);
fwriteforeach_vertex(){
if (mask[] >= 0.5){
(&x, sizeof(double), 1, fp);
fwrite(&y, sizeof(double), 1, fp);
fwrite(&z, sizeof(double), 1, fp);
fwrite}
}
}
void write_points_heavy_data_slice(FILE *fp, long no_points, coord n = {0,0,1}, double _alpha = 0) {
long block_len = no_points * 3 * sizeof(double);
(&block_len, sizeof(long), 1, fp);
fwriteforeach_vertex(){
(n, _alpha);
shortcut_slice(&x, sizeof(double), 1, fp);
fwrite(&y, sizeof(double), 1, fp);
fwrite(&z, sizeof(double), 1, fp);
fwrite}
}
void write_points_heavy_data_array(FILE *fp, long no_points, double *pt_array_x, double *pt_array_y, double *pt_array_z) {
long block_len = no_points * 3 * sizeof(double);
(&block_len, sizeof(long), 1, fp);
fwritefor (int i = 0; i < no_points; i++){
(&pt_array_x[i], sizeof(double), 1, fp);
fwrite(&pt_array_y[i], sizeof(double), 1, fp);
fwrite#if dimension == 2
double vz = 0;
(&vz, sizeof(double), 1, fp);
fwrite#elif dimension == 3
(&pt_array_z[i], sizeof(double), 1, fp);
fwrite#endif
}
}
Write cell offsets
void write_cell_offsets(FILE *fp, long no_cells, char noffset) {
long block_len = no_cells * sizeof(long);
(&block_len, sizeof(long), 1, fp);
fwritefor (int i = 0; i < no_cells; i++){
long offset = (i + 1) * noffset;
(&offset, sizeof(int64_t), 1, fp);
fwrite}
}
void write_cell_offsets2(FILE *fp, long nfacets, long *offsets) {
long block_len = nfacets * sizeof(long);
(&block_len, sizeof(long), 1, fp);
fwritefor (int ii = 0; ii < nfacets; ii++)
(&offsets[ii], sizeof(long), 1, fp);
fwrite}
void write_cell_offsets3(FILE *fp, long no_cells) {
long block_len = no_cells * sizeof(long);
(&block_len, sizeof(long), 1, fp);
fwritefor (long i = 0; i < no_cells; i++){
(&i, sizeof(int64_t), 1, fp);
fwrite}
}
Write cell types
void write_cell_types(FILE *fp, long no_cells, char type) {
long block_len = no_cells * sizeof(char);
(&block_len, sizeof(long), 1, fp);
fwritefor (int i = 0; i < no_cells; i++){
(&type, sizeof(char), 1, fp);
fwrite}
}
Write cell connectivity
void write_cell_connectivity(FILE *fp, vertex scalar marker, scalar per_mask, long no_cells, char noffset) {
long block_len = no_cells * noffset * sizeof(long);
(&block_len, sizeof(long), 1, fp);
fwriteforeach (serial, noauto){
if (per_mask[]){
long connectivity[noffset];
[0] = (long)marker[];
connectivity[1] = (long)marker[1];
connectivity[2] = (long)marker[1, 1];
connectivity[3] = (long)marker[0, 1];
connectivity#if dimension == 3
[4] = (long)marker[0, 0, 1];
connectivity[5] = (long)marker[1, 0, 1];
connectivity[6] = (long)marker[1, 1, 1];
connectivity[7] = (long)marker[0, 1, 1];
connectivity#endif
(connectivity, sizeof(long), noffset, fp);
fwrite}
}
}
void write_cell_connectivity_slice(FILE *fp, vertex scalar marker, scalar per_mask, long no_cells, char noffset, coord n = {0,0,1} ) {
long block_len = no_cells * noffset * sizeof(long);
(&block_len, sizeof(long), 1, fp);
fwriteforeach (serial, noauto){
if (per_mask[]){
long connectivity[noffset];
if (n.x == 1){
[0] = (long)marker[1, 0, 0];
connectivity[1] = (long)marker[1, 1, 0];
connectivity[2] = (long)marker[1, 1, 1];
connectivity[3] = (long)marker[1, 0, 1];
connectivity}
else if (n.y == 1){
[0] = (long)marker[0, 1, 0];
connectivity[1] = (long)marker[1, 1, 0];
connectivity[2] = (long)marker[1, 1, 1];
connectivity[3] = (long)marker[0, 1, 1];
connectivity}
else{
[0] = (long)marker[0, 0, 1];
connectivity[1] = (long)marker[1, 0, 1];
connectivity[2] = (long)marker[1, 1, 1];
connectivity[3] = (long)marker[0, 1, 1];
connectivity}
(connectivity, sizeof(long), noffset, fp);
fwrite}
}
}
Other functions
Count the number of vertices and facets
void count_vertices_and_facets(scalar c, long *nverts, long *nfacets) {
foreach (serial, noauto){
#if EMBED
if ((c[] > 1e-6 && c[] < 1. - 1e-6) && cs[] == 1)
#else
if (c[] > 1e-6 && c[] < 1. - 1e-6)
#endif
{
shortcut_facetsfor (int i = 0; i < m; i++)(*nverts)++;
if (m > 0)
(*nfacets)++;
}
}
}
Populate vertex coordinates and facet offsets
void populate_vertex_and_offset_arrays(scalar c, long nverts, long nfacets, double *pt_array_x, double *pt_array_y, double *pt_array_z, long *offsets) {
long iverts = 0, ifacet = 0, offset = 0;
foreach (serial, noauto){
#if EMBED
if ((c[] > 1e-6 && c[] < 1. - 1e-6) && cs[] == 1)
#else
if (c[] > 1e-6 && c[] < 1. - 1e-6)
#endif
{
// we cycle if cell is not at the interface
shortcut_facets
// Calculate and store vertex coordinates
= {x, y, z};
coord _p for (int i = 0; i < m; i++){
[iverts] = _p.x + v[i].x * Delta;
pt_array_x[iverts] = _p.y + v[i].y * Delta;
pt_array_y#if dimension == 3
[iverts] = _p.z + v[i].z * Delta;
pt_array_z#endif
++;
iverts}
// Store facet offset if there are vertices in the facet
if (m > 0){
+= m;
offset [ifacet] = offset;
offsets++;
ifacet}
}
}
}
Populate arrays with values at the facets
void populate_facet_arrays(scalar c, scalar s, long nverts, long nfacets, double *val_array_s) {
long ifacet = 0;
foreach (serial, noauto){
#if EMBED
if ((c[] > 1e-6 && c[] < 1. - 1e-6) && cs[] == 1)
#else
if (c[] > 1e-6 && c[] < 1. - 1e-6)
#endif
{
// we cycle if cell is not at the interface
shortcut_facets
if (m > 0){
[ifacet] = s[];
val_array_s++;
ifacet}
}
}
}