GithubHelp home page GithubHelp logo

ex-mech / pymech Goto Github PK

View Code? Open in Web Editor NEW
23.0 6.0 22.0 12.71 MB

A Python software suite for Nek5000 and SIMSON

Home Page: https://pymech.readthedocs.io/en/stable

License: GNU General Public License v3.0

Python 100.00%
io nek5000 simson numpy xarray closember

pymech's People

Contributors

akhoubani avatar ashwinvis avatar dependabot[bot] avatar guillaumechauvat avatar jcanton avatar nfabbiane avatar paugier avatar pre-commit-ci[bot] avatar shiyu-sandy-du avatar simkern avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

pymech's Issues

Improve open_dataset performance

  • Investigate upstream use of FrozenDict and __slots__ in store class.
  • Main bottleneck: Improve / find alternative to combine_by_coords function to combine elements

Output messed up on visit

In some cases, loading a nek file with readnek() and writing it back with writenek() gives an output that looks messed up on visit. Slicing through it only displays some elements. Some points are projected far from where they should be. I have reproduced this with both single and double precision files, writing back in both single and double precision. The files look fine when read with readnek(). I don't know if it's a pymech bug or a visit bug. I haven't tested whether Nek reads the file properly yet.

I wonder if this is related to the element map found in the beginning of files? I have never seen this documented or mentioned on the Nek mailing list. After the header and endianness check, the files start with what appears to be a permutation table for the elements. Why is it there? Why is it not identity when it comes from Nek? readnek() reorders the elements when reading, is there a reason for this?

Reword unclear docstrings

  • clever enough
docs/simsonsuite.rst
19:readdns() is clever enough to figure out the rest.
32:readplane() is clever enough to figure out the rest.

docs/neksuite.rst
19:readnek() is clever enough to figure out the rest.
48:readrea() is clever enough to figure out the rest.

Quickly get the time corresponding to a file

To get the time corresponding to a file, I know that one can use pymech.readnek(path).time. However, if I understand correctly, it reads the whole file just to get the time. There should be an API (pymech.readtime ?) to get the time without reading the other data in the file.

Meshtools

Not sure what exactly that is for, but merge the branches if it is ready :)

Slow script with new pymech version

Hi,
some time ago I wrote some very basic Python scripts to post-process the fields from my simulations in Nek5000, and some of them rely on the package pymech. One of these scripts is used to extract slices at each GLL point in the streamwise direction (cross-sections basically). I noticed that when I use the new version of pymech the script takes a huge amount of time to be executed, whereas with the older version it took few minutes. Is someone aware of some tasks that are performed in the new versions and are much heavier than before?

I attach the script as a .md since .py are not supported here
extract_slices.md

open_dataset error "conflicting sizes" with gmsh extruded mesh

Hello,

I have experienced an error when loading a Nek5000 output file with a mesh created from GMSH. A similar case with a mesh from genbox works flowlessly.

when running the following command :
open_dataset('channel3D_0.f00001')
I get the following error :
conflicting sizes for dimension 'y': length 8 on 'xmesh' and length 9 on 'y'

Could you help me resolve this issue ?

(Visualizing it with paraview works fine in both cases, as a check)

Missing functions in meshtools

There aren't many functionalities implemented in meshtools right now. A few easy functions would be potentially useful:

  • Generating a box. This is trivial and hasn't been done before because the native Nek5000 tool genbox does it, but having it in pymech would allow using it as a building blocks for more complex meshes.
  • A function to map geometries, for example to map a [0, 1]ร—[0, 1] box to an arbitrary shape with four corners. This is also trivial and would allow for generating more complex meshes.
  • Coons patches? (trivial using the two functions above)
  • A function to generate the outside of a circle.
  • Functions to add, delete or change boundary conditions for velocity, temperature and passive scalars.

More complicated and speculative:

  • A function to generate a cylinder-box junction.
  • Integrating my airfoils script in some way. Perhaps by generating a boundary-layer mesh and returning some kind of analytic representation of the outer boudary. Then, combined with the functions above it might be possible to write a tutorial for generating a complete airfoil mesh with a boundary layer and a few free-stream blocks.
  • Getting inspired by Vitor's extrude_refine function to perform some kind of mesh refinement.

Feel free to add anything to this list!

Optimize writenek

I managed to bring down readnek time from 4.35 seconds to 0.2 seconds with the changes: ed6ec2d...215c3c4. Notable changes are the use of np.frombuffer and .reshape functions. I think writenek could be cleaned up similarly.

Function writevtk errors because Path object is used

In vtksuite.py, we have a function called writevtk(). keep getting thrown an error which corresponds to line 195 of writevtk() - that we cannot add a Posix path with a string. Given that writevtk is still experimental, do we correct the code before line 195 converting 'fname' from PosixPath to str() ? Would this be a bug fix?

Sent by A. Vinodh

Add to Zenodo

  • Archive in Zenodo Sandbox as test
  • Check with @eX-Mech developers for corrections
  • Archive in Zenodo

Explicit errors and fail quickly

This is not a good pattern to have. @guillaumechauvat had mentioned this before.

logger.error(...)
return 1

Rather than use C / Fortran style integer return, we should raise an error to avoid confusing error messages. This however might break some compatibility in user code, because someone might be not catching the errors as they should.

We can also have a PymechError custom exception if it helps.

Single precision readnek

I use the neksuite.readnek routine to read some nek fields which are in single precision, but once I read it, in python I have arrays of float64 (looking at pos, pres, vel attributes of each element). For memory issues, I need to store my data in single precision, is there a way to directly set it in pymech?

- Originally asked by @danielemassaro

ValueError: conflicting sizes for dimension 'y'

I encountered another error for simulations done on 20 cores related to the dataset when using pymech.dataset.open_dataset("cbox0.f00030").

File ~/useful/project/20CONVECTION/miniconda3/lib/python3.9/site-packages/pymech/dataset.py:36, in open_dataset(path, **kwargs)
     33 else:
     34     raise NotImplementedError(f"Filetype: {path.suffix} is not supported.")
---> 36 return _open(path, **kwargs)

File ~/useful/project/20CONVECTION/miniconda3/lib/python3.9/site-packages/pymech/dataset.py:152, in _open_nek_dataset(path)
    150 elements = field.elem
    151 elem_stores = [_NekDataStore(elem) for elem in elements]
--> 152 elem_dsets = [
    153     xr.Dataset.load_store(store).set_coords(store.axes) for store in elem_stores
    154 ]
    156 # See: https://github.com/MITgcm/xmitgcm/pull/200
    157 if xr.__version__ < "0.15.2":

File ~/useful/project/20CONVECTION/miniconda3/lib/python3.9/site-packages/pymech/dataset.py:153, in <listcomp>(.0)
    150 elements = field.elem
    151 elem_stores = [_NekDataStore(elem) for elem in elements]
    152 elem_dsets = [
--> 153     xr.Dataset.load_store(store).set_coords(store.axes) for store in elem_stores
    154 ]
    156 # See: https://github.com/MITgcm/xmitgcm/pull/200
    157 if xr.__version__ < "0.15.2":

File ~/useful/project/20CONVECTION/miniconda3/lib/python3.9/site-packages/xarray/core/dataset.py:770, in Dataset.load_store(cls, store, decoder)
    768 if decoder:
    769     variables, attributes = decoder(variables, attributes)
--> 770 obj = cls(variables, attrs=attributes)
    771 obj.set_close(store.close)
    772 return obj

File ~/useful/project/20CONVECTION/miniconda3/lib/python3.9/site-packages/xarray/core/dataset.py:750, in Dataset.__init__(self, data_vars, coords, attrs)
    747 if isinstance(coords, Dataset):
    748     coords = coords.variables
--> 750 variables, coord_names, dims, indexes, _ = merge_data_and_coords(
    751     data_vars, coords, compat="broadcast_equals"
    752 )
    754 self._attrs = dict(attrs) if attrs is not None else None
    755 self._close = None

File ~/useful/project/20CONVECTION/miniconda3/lib/python3.9/site-packages/xarray/core/merge.py:483, in merge_data_and_coords(data, coords, compat, join)
    481 explicit_coords = coords.keys()
    482 indexes = dict(_extract_indexes_from_coords(coords))
--> 483 return merge_core(
    484     objects, compat, join, explicit_coords=explicit_coords, indexes=indexes
    485 )

File ~/useful/project/20CONVECTION/miniconda3/lib/python3.9/site-packages/xarray/core/merge.py:640, in merge_core(objects, compat, join, combine_attrs, priority_arg, explicit_coords, indexes, fill_value)
    635 variables, out_indexes = merge_collected(
    636     collected, prioritized, compat=compat, combine_attrs=combine_attrs
    637 )
    638 assert_unique_multiindex_level_names(variables)
--> 640 dims = calculate_dimensions(variables)
    642 coord_names, noncoord_names = determine_coords(coerced)
    643 if explicit_coords is not None:

File ~/useful/project/20CONVECTION/miniconda3/lib/python3.9/site-packages/xarray/core/dataset.py:204, in calculate_dimensions(variables)
    202             last_used[dim] = k
    203         elif dims[dim] != size:
--> 204             raise ValueError(
    205                 f"conflicting sizes for dimension {dim!r}: "
    206                 f"length {size} on {k!r} and length {dims[dim]} on {last_used!r}"
    207             )
    208 return dims

ValueError: conflicting sizes for dimension 'y': length 10 on 'xmesh' and length 1 on {'x': 'x', 'y': 'y', 'z': 'z'}

Originally posted by @akhoubani in #48 (comment)

Implement postprocessing I/O functions

The "PSTAT" module of the KTH framework requires some specialized output, specifically positionsof the interpolated mesh. These are now some scripts adapted from pymech functions. Those can be generalized and added to pymech:

There are also 2D functions in phill_PSTAT2D/pp_Python/modules

Reading coordinates in double precision by open_dataset

Hi,

I have already setup the PR #106 for a dangerous section in the code. Here the coordinates could then be read as double precision floating numbers (which is originally rounded off by 8 digits). Please have a check. Thank you very much!

open_dataset raises ValueError with non-box meshes

Hey guys,

(probably this is not the best to post this)

I have a 3d field and I need to plot the evolution of the boundary layer thickness along x.
All examples refer to .mean. I can't even obtain a slice of an instantaneous quantity.

Is there a reference to functions like mean or slice? any chance to add some more usage examples?

Thanks for your time,
R

Read connectivity of elements and index them

Options

In the order of increasing complexity...

  • Reader for ma2 files?
  • Third party library networkx / trimesh, ... ?
  • Native genmap reader / cffi interface?

ma2 files structure

See subroutine dmp_mapfile (pmap,nel,depth,cell,nv,nrnk,npts,noutflow) in Nek5000/tools/genmap/genmap.f and the header of the ma2 file corresponding to:

$ strings abl.ma2
#v001         392         490           8         256        3136         490           0       
                                    
$ xxd -b abl.ma2 | less
00000000: 00100011 01110110 00110000 00110000 00110001 00100000  #v001 
00000006: 00100000 00100000 00100000 00100000 00100000 00100000        
0000000c: 00100000 00100000 00110011 00111001 00110010 00100000    392 
00000012: 00100000 00100000 00100000 00100000 00100000 00100000        
00000018: 00100000 00100000 00110100 00111001 00110000 00100000    490 
0000001e: 00100000 00100000 00100000 00100000 00100000 00100000        
00000024: 00100000 00100000 00100000 00100000 00111000 00100000      8 
0000002a: 00100000 00100000 00100000 00100000 00100000 00100000        
00000030: 00100000 00100000 00110010 00110101 00110110 00100000    256 
00000036: 00100000 00100000 00100000 00100000 00100000 00100000        
0000003c: 00100000 00110011 00110001 00110011 00110110 00100000   3136 
00000042: 00100000 00100000 00100000 00100000 00100000 00100000        
00000048: 00100000 00100000 00110100 00111001 00110000 00100000    490 
0000004e: 00100000 00100000 00100000 00100000 00100000 00100000        
00000054: 00100000 00100000 00100000 00100000 00110000 00100000      0 
0000005a: 00100000 00100000 00100000 00100000 00100000 00100000        
00000060: 00100000 00100000 00100000 00100000 00100000 00100000        
00000066: 00100000 00100000 00100000 00100000 00100000 00100000        
0000006c: 00100000 00100000 00100000 00100000 00100000 00100000        
00000072: 00100000 00100000 00100000 00100000 00100000 00100000        
00000078: 00100000 00100000 00100000 00100000 00100000 00100000        
0000007e: 00100000 00100000 00100000 00100000 00100000 00100000        
00000084: 11111010 01100001 11010001 01000000 11000101 00000000  .a.@..
0000008a: 00000000 00000000 10001000 00000001 00000000 00000000  ......
00000090: 00110101 00000001 00000000 00000000 10000111 00000001  5.....
00000096: 00000000 00000000 00110100 00000001 00000000 00000000  ..4...
0000009c: 10000110 00000001 00000000 00000000 00110011 00000001  ....3.
000000a2: 00000000 00000000 10000101 00000001 00000000 00000000  ......
000000a8: 00110001 00000001 00000000 00000000 11010111 00000000  1.....
000000ae: 00000000 00000000 00110101 00000001 00000000 00000000  ..5...
000000b4: 00100101 00000001 00000000 00000000 00110100 00000001  %...4.
000000ba: 00000000 00000000 00100100 00000001 00000000 00000000  ..$...
000000c0: 00110011 00000001 00000000 00000000 00110010 00000001  3...2.
000000c6: 00000000 00000000 00110001 00000001 00000000 00000000  ..1...
000000cc: 00110000 00000001 00000000 00000000 11010111 00000000  0.....
000000d2: 00000000 00000000 00100101 00000001 00000000 00000000  ..%...
000000d8: 01101100 00000001 00000000 00000000 00100100 00000001  l...$.
000000de: 00000000 00000000 01101010 00000001 00000000 00000000  ..j...
000000e4: 00110010 00000001 00000000 00000000 01101000 00000001  2...h.
000000ea: 00000000 00000000 00110000 00000001 00000000 00000000  ..0...
000000f0: 01100110 00000001 00000000 00000000 11111011 00000000  f.....
000000f6: 00000000 00000000 01101100 00000001 00000000 00000000  ..l...
000000fc: 01101011 00000001 00000000 00000000 01101010 00000001  k...j.
00000102: 00000000 00000000 01101001 00000001 00000000 00000000  ..i...
00000108: 01101000 00000001 00000000 00000000 01100111 00000001  h...g.
0000010e: 00000000 00000000 01100110 00000001 00000000 00000000  ..f...
00000114: 01100101 00000001 00000000 00000000 11110011 00000000  e.....
0000011a: 00000000 00000000 01101011 00000001 00000000 00000000  ..k...
00000120: 00111110 00000001 00000000 00000000 01101001 00000001  >...i.
00000126: 00000000 00000000 01000110 00000001 00000000 00000000  ..F...
0000012c: 01100111 00000001 00000000 00000000 01000100 00000001  g...D.
00000132: 00000000 00000000 01100101 00000001 00000000 00000000  ..e...

IndexError: list index out of range in geometry reading

We encountered an IndexError: list index out of range in geometry reading for loading nek5000 field files. readnek works fine for some dumped field files, while fails for some other files with the same geometry. I share two field files, one working and one broken.

This field file works fine.
cbox0.f00298.txt

While the following gives the error.
cbox0.f00299.txt

home/Dev/miniconda3/lib/python3.8/site-packages/pymech/neksuite.py in readnek(fname)
    139     # read geometry
    140     for iel in elmap:
--> 141         el = data.elem[iel - 1]
    142         for idim in range(var[0]):  # if var[0] == 0, geometry is not read
    143             read_file_into_data(el.pos, idim)

IndexError: list index out of range

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.