FireDynamics / fdsreader

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

to_global() output 2 slices for a uniform domain defined with multi meshes #68

Closed 3dfirelab closed 9 months ago

3dfirelab commented 9 months ago

applying fdsreader to the simulation from the validation guide NIST_poolFire_acetone gives 2 slices.

configuration file is here

I added SLICES to the original configuration file

&SLCF XB=-0.3,0.3,-0.3,0.3,-0.05,1.15, QUANTITY='U-VELOCITY', /
&SLCF XB=-0.3,0.3,-0.3,0.3,-0.05,1.15, QUANTITY='V-VELOCITY', /
&SLCF XB=-0.3,0.3,-0.3,0.3,-0.05,1.15, QUANTITY='W-VELOCITY', /
&SLCF XB=-0.3,0.3,-0.3,0.3,-0.05,1.15, QUANTITY='TEMPERATURE', /

the meshes are defined with

&MESH XB=-0.3, 0.0,-0.3,0.0,-0.05, 0.35, IJK=30,30,40, MULT_ID='mesh' /
&MULT ID='mesh', DX=0.3, DY=0.3, DZ=0.4, I_UPPER=1, J_UPPER=1, K_UPPER=2 /

fdsreader gives 2 slices while using

sim = fdsreader.Simulation(path_to_the_simulation)
slc = sim.slices[3] 
output, grid = slc.to_global(return_coordinates=True, masked=True)

the vertical grid for the 2 slices are

print(grid[0]['z'])
  'z': array([-5.00000007e-02, -4.00000009e-02, -3.00000010e-02, -2.00000011e-02,
         -1.00000013e-02, -1.39698386e-09,  9.99999847e-03,  1.99999983e-02,
          2.99999982e-02,  3.99999981e-02,  4.99999980e-02,  5.99999978e-02,
          6.99999977e-02,  7.99999976e-02,  8.99999974e-02,  9.99999973e-02,
          1.09999997e-01,  1.19999997e-01,  1.29999997e-01,  1.39999997e-01,
          1.49999997e-01,  1.59999997e-01,  1.69999996e-01,  1.79999996e-01,
          1.89999996e-01,  1.99999996e-01,  2.09999996e-01,  2.19999996e-01,
          2.29999996e-01,  2.39999995e-01,  2.49999995e-01,  2.59999995e-01,
          2.69999995e-01,  2.79999995e-01,  2.89999995e-01,  2.99999995e-01,
          3.09999995e-01,  3.19999994e-01,  3.29999994e-01,  3.39999994e-01,
          3.49999994e-01])},

and

print(grid[1]['z'])
  'z': array([0.34999999, 0.35999999, 0.36999999, 0.37999999, 0.38999999,
         0.39999999, 0.40999999, 0.41999999, 0.42999999, 0.43999999,
         0.44999999, 0.45999999, 0.46999999, 0.47999999, 0.48999999,
         0.49999999, 0.50999999, 0.51999999, 0.52999999, 0.53999999,
         0.54999999, 0.55999999, 0.56999999, 0.57999999, 0.58999999,
         0.59999999, 0.60999999, 0.61999999, 0.62999999, 0.63999999,
         0.64999999, 0.65999999, 0.66999999, 0.67999999, 0.68999999,
         0.69999999, 0.70999999, 0.71999999, 0.72999999, 0.73999999,
         0.74999999, 0.75999998, 0.76999998, 0.77999998, 0.78999998,
         0.79999998, 0.80999998, 0.81999998, 0.82999998, 0.83999998,
         0.84999998, 0.85999998, 0.86999998, 0.87999998, 0.88999998,
         0.89999998, 0.90999998, 0.91999998, 0.92999998, 0.93999998,
         0.94999998, 0.95999998, 0.96999998, 0.97999998, 0.98999998,
         0.99999998, 1.00999998, 1.01999998, 1.02999998, 1.03999998,
         1.04999998, 1.05999998, 1.06999998, 1.07999998, 1.08999998,
         1.09999998, 1.10999998, 1.11999998, 1.12999998, 1.13999998,
         1.14999998])})

I was expecting only one slice as output.

JanVogelsang commented 9 months ago

Good catch, there is a bug for 3D-slices.

JanVogelsang commented 9 months ago

Alright, I fixed the bug and validated the results, which are indeed correct now. Try out version 1.9.13 please and tell me if everything works for you now.

3dfirelab commented 9 months ago

ok thanks I will test

any chance to have the to_global() function on smoke_3d quantities?

On Tuesday, November 28th, 2023 at 1:35 PM, Jan Vogelsang @.***> wrote:

Closed #68 as completed.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

JanVogelsang commented 9 months ago

Unfortunately, I won't have the capacities for that, but feel free to either create a PR for that or provide code snippets in case you combine the smoke_3d arrays manually. With some existing code at hand, it is less work to make a whole function out of that which also covers some edge cases.

Alternatively, if you could provide a minimal example for a case where you would need a smoke_3d to_global function, I might find some time to implement the to_global function and use that example for debugging. In theory, it should be very similar to the to_global implementation of 3D slices. It will even be simpler, as they always cover the whole extent of the mesh and not just parts of meshes.

JanVogelsang commented 9 months ago

@3dfirelab Alright, I actually implemented to_global for both Plot3D and Smoke3D data now. I tested it on a small test case and that worked, so feel free to upgrade to 1.10.0, test it with your cases as well and give me feedback if it works for you as well!

3dfirelab commented 9 months ago

This is working thanks

However for the same simulation as above, an acetone poolfire with 12 meshes split with

 I_UPPER=1, J_UPPER=1, K_UPPER=2

I can see the edges of the meshes in the smoke field image

the same simulation with to_global() apply to temperature saved in a 3d slices that span over the whole domain

&SLCF XB=-0.3,0.3,-0.3,0.3,-0.05,1.15, QUANTITY='TEMPERATURE', /

yields to image

JanVogelsang commented 9 months ago

Can you send me the python script you used for plotting, so that I can reproduce your results and debug the issue?

3dfirelab commented 9 months ago
import numpy as np 
import matplotlib.pyplot as plt
import fdsreader
from scipy.interpolate import RegularGridInterpolator, griddata
import sys
import pdb 

###########################
def load_slice(sim, id_var):
    slc = sim.slices[id_var] # to load temperature. see order of &SLCF in fds config file 
    data, grid = slc.to_global(return_coordinates=True, masked=True)  # need version 1.9.13

    times = slc.times

    return data, grid, times

###########################
def load_3dsmoke(sim, id_var):
    data = sim.smoke_3d[id_var] # to load temperature. see order of &SLCF in fds config file 
    mtx, grid = data.to_global(return_coordinates=True, masked=True)  # need version 1.9.13

    times = data.times

    return mtx, times

sim = fdsreader.Simulation('./NIST_PoolFire/') #load simulation
temp, grid, times_temp = load_slice(sim, 3)
smoke, times_smoke = load_3dsmoke(sim, 0)

#plot
ax = plt.subplot(131)
plt.imshow(temp[-1,:,30,:].T, origin='lower')
ax.set_title('temperature')
ax = plt.subplot(132)
plt.imshow(smoke[-1,:,int(smoke.shape[1]/2),:].T, origin='lower')
ax.set_title('3d smoke')
ax = plt.subplot(133)
plt.imshow(smoke[-1,:,int(smoke.shape[1]/2),:].T, origin='lower', vmax=5)
ax.set_title('3d smoke vmax=5')
plt.show()

attached in the input config file for the simulation NIST_PoolFire input_NIST_Acetone_Prescribed_1cm.txt

JanVogelsang commented 9 months ago

Fixed in 1.10.1. Please try that out and give me feedback if you encounter any issues with that.

3dfirelab commented 9 months ago

it works thanks

only the masked=True option gave an error

File ~/anaconda3/envs/geo/lib/python3.9/site-packages/fdsreader/smoke3d/smoke3d.py:216, in Smoke3D.to_global(self, masked, fill, return_coordinates)
    214         subsmoke_data = np.concatenate((subsmoke_data, temp_data[dim][tuple(temp_data_slices)]), axis=axis + 1)
    215         if masked:
--> 216             mask = np.concatenate((mask, temp_mask[dim]), axis=axis + 1)
    218 # If the slice should be masked, we set all cells at which an obstruction is in the
    219 # simulation space to the fill value set by the user
    220 if masked:

File <__array_function__ internals>:200, in concatenate(*args, **kwargs)

ValueError: all the input array dimensions except for the concatenation axis must match exactly, but along dimension 2, the array at index 0 has size 30 and the array at index 1 has size 31
JanVogelsang commented 8 months ago

Fixed in 1.10.2