Open airwarriorg91 opened 1 month ago
You got an error with the existing _NekDataStore
because of this method:
def meshgrid_to_dim(self, mesh):
"""Reverse of np.meshgrid. This method extracts one-dimensional
coordinates from a cubical array format for every direction
"""
I don't see a proper way of building 1D coordinate arrays for an unstructured arrays. We can add the DataStore later, but a working implementation is more important. Good that you chose to go for simpler functions.
You can get the connectivity data at least for the EXODUS mesh like this:
import xarray as xr
mesh = xr.open_dataset("naca(10x4).e")
print(mesh.data_vars)
mesh.connect1
This integer data array has the dimensions connect1 (num_el_in_blk1, num_nod_per_el1) int32 766kB ...
and looks like this:
array([[ 3, 2, 1, ..., 5, 8, 7],
[ 10, 9, 2, ..., 11, 6, 13],
[ 15, 14, 9, ..., 16, 12, 18],
...,
[72683, 72686, 32640, ..., 72732, 32642, 72731],
[72686, 72689, 32645, ..., 72733, 32647, 72732],
[72689, 72692, 32650, ..., 72734, 32652, 72733]], dtype=int32)
I am guessing it denotes one cell per row, and along the column denotes the 8 cells which surround it: 4 on each corner and 4 on each face (you need to double check it). Somebody wrote a short blog post looking at this using netCDF4, but above I used xarray (which also uses netCDF4 / h5netcdf behind the scenes).
https://johnfoster.pge.utexas.edu/blog/posts/extracting-exodus-information-with-netcdf-python/
One thing I was not able to get it working was opening the EXODUS mesh file directly from Uxarray, although they claim it to be supported:
https://uxarray.readthedocs.io/en/latest/user-guide/grid-formats.html#exodus
Yeah ! But I think extracting mesh or any mesh data from the exodus file will not provide us with the correct mesh data. The NEK5000 visualization file has the polynomial nodes data along with the nodes of the original mesh. Correct me, if I am wrong but I think this is the case only. So, in that case how to extract the connectivity data from the visualization file.
Thanks, I will try to implement a working function first then we can establish a class like for xarray.
What was your error ?
One thing I was not able to get it working was opening the EXODUS mesh file directly from Uxarray, although they claim it to be supported:
https://uxarray.readthedocs.io/en/latest/user-guide/grid-formats.html#exodus
import uxarray as ux
ux.open_grid("naca(10x4).e")
It assumes a 3D grid
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
~/Sources/foss/pymech/.venv/lib/python3.12/site-packages/xarray/core/dataset.py in ?(self, name)
1482 variable = self._variables[name]
1483 except KeyError:
-> 1484 _, name, variable = _get_virtual_variable(self._variables, name, self.sizes)
1485
KeyError: 'node_z'
During handling of the above exception, another exception occurred:
KeyError Traceback (most recent call last)
~/Sources/foss/pymech/.venv/lib/python3.12/site-packages/xarray/core/dataset.py in ?(self, key)
1585 if isinstance(key, tuple):
1586 message += f"\nHint: use a list to select multiple variables, for example `ds[{[d for d in key]}]`"
-> 1587 raise KeyError(message) from e
1588
~/Sources/foss/pymech/.venv/lib/python3.12/site-packages/xarray/core/dataset.py in ?(self, name)
1482 variable = self._variables[name]
1483 except KeyError:
-> 1484 _, name, variable = _get_virtual_variable(self._variables, name, self.sizes)
1485
~/Sources/foss/pymech/.venv/lib/python3.12/site-packages/xarray/core/dataset.py in ?(variables, key, dim_sizes)
216 split_key = key.split(".", 1)
217 if len(split_key) != 2:
--> 218 raise KeyError(key)
219
KeyError: 'node_z'
The above exception was the direct cause of the following exception:
KeyError Traceback (most recent call last)
<ipython-input-7-18c901787b96> in ?()
----> 1 ux.open_grid("naca(10x4).e")
~/Sources/foss/pymech/.venv/lib/python3.12/site-packages/uxarray/core/api.py in ?(grid_filename_or_obj, latlon, use_dual, **kwargs)
84 try:
85 grid_ds = xr.open_dataset(grid_filename_or_obj, **kwargs)
86
87 uxgrid = Grid.from_dataset(grid_ds, use_dual=use_dual)
---> 88 except ValueError:
89 raise ValueError("Inputted grid_filename_or_obj not supported.")
90
91 return uxgrid
~/Sources/foss/pymech/.venv/lib/python3.12/site-packages/uxarray/grid/grid.py in ?(cls, dataset, use_dual, **kwargs)
250 # parse to detect source grid spec
251
252 source_grid_spec = _parse_grid_type(dataset)
253 if source_grid_spec == "Exodus":
--> 254 grid_ds, source_dims_dict = _read_exodus(dataset)
255 elif source_grid_spec == "Scrip":
256 grid_ds, source_dims_dict = _read_scrip(dataset)
257 elif source_grid_spec == "UGRID":
~/Sources/foss/pymech/.venv/lib/python3.12/site-packages/uxarray/io/_exodus.py in ?(ext_ds)
101 )
102
103 # populate lon/lat coordinates
104 lon, lat = _xyz_to_lonlat_deg(
--> 105 ds["node_x"].values, ds["node_y"].values, ds["node_z"].values
106 )
107
108 # populate dataset
~/Sources/foss/pymech/.venv/lib/python3.12/site-packages/xarray/core/dataset.py in ?(self, key)
1583 message = f"No variable named {key!r}. Variables on the dataset include {shorten_list_repr(list(self.variables.keys()), max_items=10)}"
1584 # If someone attempts `ds['foo' , 'bar']` instead of `ds[['foo', 'bar']]`
1585 if isinstance(key, tuple):
1586 message += f"\nHint: use a list to select multiple variables, for example `ds[{[d for d in key]}]`"
-> 1587 raise KeyError(message) from e
1588
1589 if utils.iterable_of_hashable(key):
1590 return self._copy_listed(key)
KeyError: "No variable named 'node_z'. Variables on the dataset include ['node_x', 'node_y', 'face_node_connectivity']"
Yeah ! But I think extracting mesh or any mesh data from the exodus file will not provide us with the correct mesh data. The NEK5000 visualization file has the polynomial nodes data along with the nodes of the original mesh. Correct me, if I am wrong but I think this is the case only. So, in that case how to extract the connectivity data from the visualization file.
That is true. Nek5000's element numbering may be different. In that case we need its connectivity. Do you use gencon
command or the genmap
? If it is the latter, #40 implemented a reader for the .ma2
files. I didn't get a chance to explore it, but now is the time!
It could also be that .ma2
file does not contain this information. If getting the connectivity out of Nek5000 is too hard, we could tap into uxarray's methods to do that. The test suite TestConnectivity
suggest that it should be possible:
Yeah ! But I think extracting mesh or any mesh data from the exodus file will not provide us with the correct mesh data. The NEK5000 visualization file has the polynomial nodes data along with the nodes of the original mesh. Correct me, if I am wrong but I think this is the case only. So, in that case how to extract the connectivity data from the visualization file.
That is true. Nek5000's element numbering may be different. In that case we need its connectivity. Do you use
gencon
command or thegenmap
? If it is the latter, #40 implemented a reader for the.ma2
files. I didn't get a chance to explore it, but now is the time!
Yeah, it is essential for simulations, so we build the .ma2
. Although, I am also not sure whether it will contain the exact nodes numbering as that of the visualization file. As far as I know, it only depends on the input mesh and doesn't account for the polynomial nodes since it is generated prior to simulations.
We should work on extracting connectivity data from the .f00001
files itself. The uxarray
method _build_face_face_connectivity can be helpful but no mention about it in the documentation. I will look into this. Maybe ask in the discussion section of uxarray
.
@ashwinvis You probably missed my question, I am able to make an xarray dataset which can be used for most post-processing stuff like plotting, POD calculations, etc. It lacks the element connectivity data, so is it required ? If not, this method can be used to handle structured and unstructured arrays both.
It is a very simple approach.
I don't know. It depends on what you can do now. Without connectivity you may be able to plot, select a slice.
Sometimes you need to integrate or differentiate (by finite difference to roughly calculate a gradient) or interpolate along a direction. Without connectivity information that will be incredibly inconvenient.
You can get the connectivity data at least for the EXODUS mesh like this:
import xarray as xr mesh = xr.open_dataset("naca(10x4).e") print(mesh.data_vars) mesh.connect1
This integer data array has the dimensions
connect1 (num_el_in_blk1, num_nod_per_el1) int32 766kB ...
and looks like this:array([[ 3, 2, 1, ..., 5, 8, 7], [ 10, 9, 2, ..., 11, 6, 13], [ 15, 14, 9, ..., 16, 12, 18], ..., [72683, 72686, 32640, ..., 72732, 32642, 72731], [72686, 72689, 32645, ..., 72733, 32647, 72732], [72689, 72692, 32650, ..., 72734, 32652, 72733]], dtype=int32)
I am guessing it denotes one cell per row, and along the column denotes the 8 cells which surround it: 4 on each corner and 4 on each face (you need to double check it). Somebody wrote a short blog post looking at this using netCDF4, but above I used xarray (which also uses netCDF4 / h5netcdf behind the scenes).
https://johnfoster.pge.utexas.edu/blog/posts/extracting-exodus-information-with-netcdf-python/
I have an idea on how to build the connection data. The each face in the exodus file is further divided by polynomial nodes. So, each edge is a line with the polynomial as well as geometric nodes. We can get the slope of the edge and find which polynomial nodes lie on these edge and sort them based on the distance. This way we can find out how the nodes in each element object is form the face. This will work provided we can get connectivity of geometric nodes from exodus file.
Rough diagram of a 2D element (can be extended to 3D)
Red nodes are the polynomial nodes that we get from the .f00001
files and blue nodes are the geometric nodes.
@airwarriorg91 it has been a while. Did you work more on this?
I know it is a hard problem. It will be nice if we can try to complete this or at least document what the next steps are. Just so that we don't forget.
@airwarriorg91 it has been a while. Did you work more on this?
I know it is a hard problem. It will be nice if we can try to complete this or at least document what the next steps are. Just so that we don't forget.
Hey ! I was a little busy with the semester end. I need to try the above idea and check its feasibility. I will probably start working on it again after Dec 15 and let you know.
Thanks, Gaurav
Ok sounds good! It would make for a nice xmas project :christmas_tree:
Hey ! I am looked into
uxarray
and attempted two methods to include support for unstructured grids. The fundamental working of both the methods is same.Proposed Methodology
Method 1 Extend the current
xarray
method touxarray
asuxarray
also supports the creation of dataset throughload_store()
. But unfortunately, it doesn't work. I get the following error.Method 2 It is manual method to extract data from elements and store them as numpy arrays, use them to form a
xarray
dataset. I am able to make anxarray
dataset which can be used for most post-processing stuff like plotting, POD calculations, etc. It lacks the element connectivity data, so is it required ? If not, this method can be used to handle structured and unstructured arrays both.extract_elem_data
is the implementation of Method 2. We may not require the use ofuxarray
.A
uxarray
Grid can be constructed from the coordinates and connectivity data through uxarray.Grid.from_dataset and used with the available values to create a uxarray dataset using uxarray.UxDataset. Can someone help me in extracting the connectivity, so I can attempt creation of anuxarray
dataset.Thanks ! Gaurav