sandbox/vheusinkveld/myfunctions/output/sliceOf3D.h
Intro
This function is an adaptation on the the standard basilisk output grid function that can be found here.
The differences
- The main addition is an coord argument of the function. This will let you choose a slice in 3D. If you would want the (x, y, L0/2) slice this is acieved by giving (1, 1, 0.5) as the coord argument. The coordinates that are set to 1 are varied, the one that is set to c < 1 will be kept constant at value c*L0.
- Another difference is the way in which the data is outputted. Since L0, X0, output cells etc. are known the x, y, z coordinates can be infered at the end and such storing those values is a waste of space. We opt for a matrix way of outputting the data. The first line is a header line, the second one will state the outputted field, and then a 2D array is written away. If multiple scalar fields are outputted the previous 2 steps will be repeated.
The function
The arguments and their default values are:
- list
- list of fields to output. Default is all.
- fp
- file pointer. Default is stdout.
- n
- number of points along each dimension. Default is N.
- linear
- use first-order (default) or bilinear interpolation.
- plane
- coord, define plane. Ex: {1, 1, 0.5} –> vary x and y, take z = 0.5L0 + Z0. note that the constant plane 1L0 is not possible, 1’s are assumed to be varied.
struct sOutputSlice {
scalar * list;
FILE * fp;
int n;
bool linear;
coord plane;
};
trace
void output_slice (struct sOutputSlice p)
{
if (!p.list) p.list = all;
if (p.n == 0) p.n = N;
if (!p.fp) p.fp = stdout;
if (!p.plane.x) p.plane.x = 1.;
if (!p.plane.y) p.plane.y = 1.;
if (!p.plane.z) p.plane.z = 0.;
p.n++;
int len = list_len(p.list);
double ** field = (double **) matrix_new (p.n, p.n, len*sizeof(double));
double Delta = 0.999999*L0/(p.n - 1);
for (int i = 0; i < p.n; i++) {
double varCoord1 = Delta*i; // some clever way of implementing general variation of coordinates instead of mapping them directly to x, y or z
bool varX = !(p.plane.x < 1.);
double x = (!varX ? p.plane.x*L0 : varCoord1) + X0;
for (int j = 0; j < p.n; j++) {
double varCoord2 = Delta*j;
double y = (varX ? (p.plane.y < 1. ? p.plane.y*L0 : varCoord2) : varCoord1) + Y0;
double z = (p.plane.z < 1. ? p.plane.z*L0 : varCoord2) + Z0;
if (p.linear) {
int k = 0;
for (scalar s in p.list)
field[i][len*j + k++] = interpolate (s, x, y, z);
}
else {
Point point = locate (x, y, z);
int k = 0;
for (scalar s in p.list)
field[i][len*j + k++] = point.level >= 0 ? s[] : nodata;
}
}
}
if (pid() == 0) { // master
@if _MPI
MPI_Reduce (MPI_IN_PLACE, field[0], len*p.n*p.n, MPI_DOUBLE, MPI_MIN, 0,
MPI_COMM_WORLD);
@endif
fprintf (p.fp, "x=%g\ty=%g\tz=%g\tn=%d\tlen=%d\n", p.plane.x*L0, p.plane.y*L0, p.plane.z*L0, p.n, len);
int k = 0;
for (scalar s in p.list) {
fprintf (p.fp, "%s\n", s.name);
for (int i = 0; i < p.n; i++) {
for (int j = 0; j < p.n; j++) {
fprintf (p.fp, "%g\t", (float) field[i][len*j + k]);
}
fputc ('\n', p.fp);
}
k++;
}
fflush (p.fp);
}
@if _MPI
else // slave
MPI_Reduce (field[0], NULL, len*p.n*p.n, MPI_DOUBLE, MPI_MIN, 0,
MPI_COMM_WORLD);
@endif
matrix_free (field);
}
*/