50 std::vector<double> flux(B.dimension[0]->cells * B.dimension[1]->cells * B.dimension[2]->cells);
51 for (
unsigned int i = 0;
i < flux.size(); ++
i) {
55 bool eqPlane = B.dimension[1]->cells > 1;
56 int yCoord = eqPlane ? 1 : 2;
58 long double tmp_flux=0.;
59 long double bottom_flux=0.;
63 for (
int x = B.dimension[0]->cells - (outerBoundary+1); x >= outerBoundary; x--) {
64 int i = outerBoundary;
65 int y = eqPlane ?
i : 0;
66 int z = eqPlane ? 0 :
i;
67 if (
isInside(B, innerBoundary, x, y, z)) {
71 Vec3d bval = B.getCell(x,y,z);
73 bottom_flux -= bval[yCoord] * B.dx[0];
74 flux[B.dimension[0]->cells *
i + x] = bottom_flux;
76 tmp_flux = bottom_flux;
77 for(
i++;
i < B.dimension[yCoord]->cells - outerBoundary;
i++) {
80 if (
isInside(B, innerBoundary, x, y, z)) {
84 bval = B.getCell(x,y,z);
86 tmp_flux -= bval[0] * B.dx[yCoord];
87 flux[B.dimension[0]->cells *
i + x] = tmp_flux;
98 std::vector<double> flux(B.dimension[0]->cells * B.dimension[1]->cells * B.dimension[2]->cells);
99 for (
unsigned int i = 0;
i < flux.size(); ++
i) {
103 bool eqPlane = B.dimension[1]->cells > 1;
104 int yCoord = eqPlane ? 1 : 2;
106 long double tmp_flux=0.;
107 long double top_flux=0.;
111 for(
int i = outerBoundary;
i < B.dimension[yCoord]->cells - outerBoundary;
i++) {
112 int x = B.dimension[0]->cells - (outerBoundary + 1);
113 int y = eqPlane ?
i : 0;
114 int z = eqPlane ? 0 :
i;
115 if (
isInside(B, innerBoundary, x, y, z)) {
119 Vec3d bval = B.getCell(x, y, z);
121 top_flux -= bval[0]*B.dx[yCoord];
122 flux[B.dimension[0]->cells *
i + x] = top_flux;
127 for(
int x = B.dimension[0]->cells - (outerBoundary + 2); x >= outerBoundary; x--) {
128 int i = B.dimension[yCoord]->cells - (outerBoundary + 1);
129 int y = eqPlane ?
i : 0;
130 int z = eqPlane ? 0 :
i;
131 if (
isInside(B, innerBoundary, x, y, z)) {
135 Vec3d bval = B.getCell(x, y, z);
137 top_flux -= bval[yCoord] * B.dx[0];
138 flux[B.dimension[0]->cells *
i + x] = top_flux;
141 for (
i--;
i >= outerBoundary;
i--) {
144 if (
isInside(B, innerBoundary, x, y, z)) {
148 bval = B.getCell(x, y, z);
150 tmp_flux += bval[0] * B.dx[yCoord];
151 flux[B.dimension[0]->cells *
i + x] = tmp_flux;
161 std::vector<double> flux(B.dimension[0]->cells * B.dimension[1]->cells * B.dimension[2]->cells);
162 for (
unsigned int i = 0;
i < flux.size(); ++
i) {
166 bool eqPlane = B.dimension[1]->cells > 1;
167 int yCoord = eqPlane ? 1 : 2;
169 long double tmp_flux=0.;
170 long double right_flux=0.;
174 for(
int i = outerBoundary;
i < B.dimension[yCoord]->cells - outerBoundary;
i++) {
175 int x = B.dimension[0]->cells - (outerBoundary + 1);
176 int y = eqPlane ?
i : 0;
177 int z = eqPlane ? 0 :
i;
178 if (
isInside(B, innerBoundary, x, y, z)) {
182 Vec3d bval = B.getCell(x, y, z);
184 right_flux -= bval[0] * B.dx[yCoord];
185 flux[B.dimension[0]->cells *
i + x] = right_flux;
187 tmp_flux = right_flux;
188 for(x--; x >= outerBoundary; x--) {
189 if (
isInside(B, innerBoundary, x, y, z)) {
193 bval = B.getCell(x,y,z);
195 tmp_flux -= bval[yCoord] * B.dx[0];
196 flux[B.dimension[0]->cells *
i + x] = tmp_flux;
208 std::vector<double> flux(B.dimension[0]->cells * B.dimension[1]->cells * B.dimension[2]->cells);
209 for (
unsigned int i = 0;
i < flux.size(); ++
i) {
213 bool eqPlane = B.dimension[1]->cells > 1;
214 int yCoord = eqPlane ? 1 : 2;
216 long double tmp_flux=0.;
217 long double left_flux=0.;
220 for (
int x = B.dimension[0]->cells - (outerBoundary + 1); x >= outerBoundary; x--) {
221 int i = outerBoundary;
222 int y = eqPlane ?
i : 0;
223 int z = eqPlane ? 0 :
i;
224 if (
isInside(B, innerBoundary, x, y, z)) {
228 Vec3d bval = B.getCell(x,y,z);
230 left_flux -= bval[yCoord] * B.dx[0];
231 flux[B.dimension[0]->cells *
i + x] = left_flux;
236 for (
int i = outerBoundary;
i < B.dimension[yCoord]->cells - outerBoundary;
i++) {
237 int x = outerBoundary;
238 int y = eqPlane ?
i : 0;
239 int z = eqPlane ? 0 :
i;
240 if (
isInside(B, innerBoundary, x, y, z)) {
244 Vec3d bval = B.getCell(x, y, z);
246 left_flux -= bval[0] * B.dx[yCoord];
247 flux[B.dimension[0]->cells *
i + x] = left_flux;
249 tmp_flux = left_flux;
250 for(x++; x < B.dimension[0]->cells - outerBoundary; x++) {
251 if (
isInside(B, innerBoundary, x, y, z)) {
255 bval = B.getCell(x,y,z);
257 tmp_flux += bval[yCoord] * B.dx[0];
258 flux[B.dimension[0]->cells *
i + x] = tmp_flux;
270 std::vector<double> flux(B.dimension[0]->cells * B.dimension[1]->cells * B.dimension[2]->cells);
271 for (
unsigned int i = 0;
i < flux.size(); ++
i) {
275 bool eqPlane = B.dimension[1]->cells > 1;
276 int yCoord = eqPlane ? 1 : 2;
278 long double tmp_flux=0.;
279 long double left_flux=0.;
283 for(
int i = outerBoundary;
i < B.dimension[yCoord]->cells - outerBoundary;
i++) {
284 int x = B.dimension[0]->cells - (outerBoundary + 1);
285 int y = eqPlane ?
i : 0;
286 int z = eqPlane ? 0 :
i;
287 if (
isInside(B, innerBoundary, x, y, z)) {
291 Vec3d bval = B.getCell(x, y, z);
293 left_flux -= bval[0]*B.dx[yCoord];
294 flux[B.dimension[0]->cells *
i + x] = left_flux;
298 for(
int x = B.dimension[0]->cells - (outerBoundary + 2); x >= outerBoundary; x--) {
299 int i = B.dimension[yCoord]->cells - (outerBoundary + 1);
300 int y = eqPlane ?
i : 0;
301 int z = eqPlane ? 0 :
i;
302 if (
isInside(B, innerBoundary, x, y, z)) {
306 Vec3d bval = B.getCell(x, y, z);
308 left_flux -= bval[yCoord]*B.dx[0];
309 flux[B.dimension[0]->cells *
i + x] = left_flux;
314 for (
int i = B.dimension[yCoord]->cells - (outerBoundary + 2);
i >= outerBoundary;
i--) {
315 int x = outerBoundary;
316 int y = eqPlane ?
i : 0;
317 int z = eqPlane ? 0 :
i;
318 if (
isInside(B, innerBoundary, x, y, z)) {
322 Vec3d bval = B.getCell(x, y, z);
324 left_flux += bval[0] * B.dx[yCoord];
325 flux[B.dimension[0]->cells *
i + x] = left_flux;
327 tmp_flux = left_flux;
328 for(x++; x < B.dimension[0]->cells - outerBoundary; x++) {
329 if (
isInside(B, innerBoundary, x, y, z)) {
333 bval = B.getCell(x,y,z);
335 tmp_flux += bval[yCoord] * B.dx[0];
336 flux[B.dimension[0]->cells *
i + x] = tmp_flux;
345 v.erase(std::remove_if(v.begin(), v.end(), [](
const double& value) {return !isfinite(value);}), v.end());
350 std::nth_element(v.begin(), v.begin() + n/2, v.end());
353 std::nth_element(v.begin(), v.begin() + n/2 - 1, v.end());
354 std::nth_element(v.begin(), v.begin() + n/2, v.end());
355 return (v[n/2 - 1] + v[n/2])/2;
361 v.erase(std::remove_if(v.begin(), v.end(), [](
const double& value) {return !isfinite(value);}), v.end());
363 return n ? std::accumulate(v.begin(), v.end(), 0.0) / n :
NAN;
366int main(
int argc,
char** argv) {
371 cerr <<
"Syntax: fluxfunction input.vlsv output.bin" << endl;
372 cerr <<
"Output will be two files: output.bin and output.bin.bov." << endl;
373 cerr <<
"Point visit to the BOV file." << endl;
376 string inFile(argv[1]);
377 string outFile(argv[2]);
384 if(B.dimension[0]->cells > 1 && B.dimension[1]->cells > 1 && B.dimension[2]->cells > 1) {
385 cerr <<
"This is a 3D simulation output. Flux function calculation only makes sense for 2D data."
390 cerr <<
"File read, calculating flux function..." << endl;
394 std::vector<double> fluxUp, fluxDown, fluxLeft, fluxUR, fluxDR;
401 for(
unsigned int i=0;
i<fluxUp.size();
i++) {
402 std::vector<double> v {fluxUp[
i], fluxDown[
i], fluxLeft[
i], fluxUR[
i], fluxDR[
i]};
410 cerr <<
"Done. Writing output..." << endl;
419 int fd = open(outFile.c_str(), O_CREAT|O_TRUNC|O_WRONLY, 0644);
420 if(!fd || fd == -1) {
421 cerr <<
"Error: cannot open output file " << outFile <<
": " << strerror(errno) << endl;
424 size_t size=B.dimension[0]->cells*B.dimension[1]->cells*B.dimension[2]->cells*
sizeof(double);
427 for(ssize_t remain=size; remain > 0; ) {
428 remain -=
write(fd, ((
char*) &(fluxUp[0]))+remain-size, remain);
433 string outBov = outFile +
".bov";
434 FILE* f=fopen(outBov.c_str(),
"w");
436 cerr<<
"Error: unable to write BOV ascii file " << outBov <<
":" << strerror(errno) << endl;
439 fprintf(f,
"TIME: %lf\n", B.time);
440 fprintf(f,
"DATA_FILE: %s\n", outFile.c_str());
441 fprintf(f,
"DATA_SIZE: %i %i %i\n", B.dimension[0]->cells, B.dimension[1]->cells, B.dimension[2]->cells);
442 fprintf(f,
"DATA_FORMAT: DOUBLE\nVARIABLE: fluxfunction\nDATA_ENDIAN: LITTLE\nCENTERING: zonal\n");
443 fprintf(f,
"BRICK_ORIGIN: %lf %lf %lf\n", B.dimension[0]->min, B.dimension[1]->min, B.dimension[2]->min);
444 fprintf(f,
"BRICK_SIZE: %lf %lf %lf\n", B.dimension[0]->max - B.dimension[0]->min, B.dimension[1]->max - B.dimension[1]->min, B.dimension[2]->max - B.dimension[2]->min);
445 fprintf(f,
"DATA_COMPONENTS: 1\n");