FireDynamics / fdsreader

Python reader for FDS data
GNU General Public License v3.0
44 stars 18 forks source link

to_global has Problem with different cell-sizes #49

Open r-wrobel opened 1 year ago

r-wrobel commented 1 year ago

I have multiple meshes in different sizes and cell sizes.

The xy-plane (z-axis) works as desired. But slcf/slices.py:to_global returns a tuple for axis x and y instand of numpy.ndarray. The first element contains the numpy.ndarray of the finder mesh, while the second element contains the numpy.ndarray of the coarser mesh. It would be nice, if all axis behave same and create only one result.

Problem illustrated: z|x y|-

Plots of different slices with a hole where the higher cell size is

JanVogelsang commented 1 year ago

Hi Robert, the to_global method returning two is the expected behavior in some cases. The documentation states: Will create two global slices in cases where cell-centered slices cut right through one or more mesh borders.

This problem is the following: If there is a cell-centered slice that cuts right through the border of two meshes (mesh1 and mesh2), there will actually be two slices that could be equally relevant for the user. The one will cells on mesh1 and the one wiht cells on mesh2. As there are no cells in between (i.e. where the slice "should" be) and cell-centered slices output values at the centers of each cell (as the name suggests obviously), FDS simply outputs two slices, one on each side of the mesh borders. As the fdsreader will never discard any data, both slices that are output by FDS are sent to the user for him to decide which one to use.
Receiving two slices in some cases is therefore the expected behavior. If you have any suggestion on how to improve the method or make it clearer what the method returns, please let me know. If you think you are actually getting the wrong data, please send me your FDS case so I can verify the correctness of the method.

r-wrobel commented 1 year ago

Hi Jan, thank you for the explanation. I found the problem. After further consideration, the output is (and should be) the expected behavior. I tried to get a global slice from a slice which looks like this: -- to_global returned two slices | | and |--|. SMV ignores the different levels and shows all data (which was the behavior I expected from to_global). But unlike the 3D-space in SMV, the different levels aren't visible. This might cause misinterpretation. Therefore it is important to return a slice for each level by default. With this knowledge, an optional boolean argument would be helpful, which merges all slices to one (just filling the holes - not regarding cell-centered double data). And an information in the documentation like: If slices are at different heights (e.g. different resolution of Meshes), a separate slice is output for each height.

Further Information for example (wouldn't read): x and y: 0.05 is ok, 0.0 is splitted 0.05 lies on the grid of the coarser mesh and of the finer mesh 0.0 only lies on the finer mesh grid

z: 0.8 is ok, 0.81 is splitted 08 lies on the grid of the coarser mesh and of the finer mesh 0.81 only lies on the finer mesh grid

[0.05,0.05,0.8] -> x,y,z ok [0.0,0.0,0.8] ->z ok; x,y splitted [0.0,0.0,0.81] -> x,y,z splitted LaborModell_min.fds.txt

JanVogelsang commented 1 year ago

We could add a boolean to the function to either return just a single slice which averages the data of both slices (and also "fills holes") or return both "raw" slices. @lu-kas Is there anything you would add here or should I just implement that additional parameter?

lu-kas commented 1 year ago

Sorry, I was ill. I will have to think about a reasonable strategy here and propose something asap.

lu-kas commented 1 year ago

@JanVogelsang @r-wrobel Before something gets implemented, here are my thoughts regarding non-unique choice of slices:

Regarding the different resolutions:

What do you think?

r-wrobel commented 1 year ago

I don't have enough knowledge about cell-centered data to be able to survey all of the consequences of changing the data.

Global data is intuitiv and convenient. But I don't think we need global data. When I use meshes for computational optimization, the bounds have no special meaning. An evaluation of individual sub-slices therefore makes no sense. Therefore, the handling of the data as one global slice correspondes to the way i think about it. But it is necessary only for spatially resolved operations, e.g. local maxima (but then i would use the 3D space). Even for maxima or average i can work on the level of subslices. Having no global slice would result in every user to calculate a kind of global slice by themself.

There is a reason for the finer meshes, so the "finest" option should be default. I would use the "coarsest" option only for preview (faster calculation and maybe i can look at the whole array printed). Out of laziness or because the amount of data is too large to handle in a practical way, I could imagine using the "coarsest" option on final calculation (e.g. u-vel slice when refinement is used to for concentration).

Interpolation changes the data, therfore i would avoid it. Especially for boundaries (e.g. layers of different densities or a strong gas flow) an interpolation could even produce wrong data. For the "finest" option, I would just use the original value for all refined values. For "coarsest" data, the result should be the mean average of the finer data. I assume this corrspondes most to the result you would get from FDS by calculating with the required resolution.

JanVogelsang commented 1 year ago

I have to admit, I don't really see why we would need the "coarstest"/"finest" option, as the user could simply downsample/pool the fine global array (e.g. using numpy) to get a coarser version of the array. I think the reader should simply output the data that is provided by FDS without changing any raw data (e.g. by averaging).

@lu-kas Regarding the "random" option, this alone would not solve the problem. The issue comes when the two arrays, produced by FDS when cutting through two mesh borders, can carry different information. It might be possible that one array cuts through 3 meshes, while the other one only cuts through 2 ones. Example:
⬛ ⬛
⬛⬛⬛
Imagine each box represents one mesh. The cell-centered slice cuts through these meshes horizontally. FDS would then output slice data for 5 meshes, while those could be combined to two arrays with data of 3 and 2 meshes respectively.
Just taking any of the two meshes randomly would not work either: ⬛ ⬛
⬛⬛⬛
Which data would you take here? It gets quite complicated in this case. One could probably still pick data randomly here, but randomly picking whole subslice-arrays would not work. While this could be implemented in theory, it would be a nightmare. We could still do that of course.