FEMAP neutral file parser
Project description
FEMAP neutral file parser
Free software: MIT license
Features and limitations
Parse and render FEMAP neutral files. For now, three blocks are interpreted:
Block 100 “Neutral File Header”
Block 450 “Output Sets”
Block 451 “Output Data Vectors”
Usage
To use FEMAP neutral Parser in a project:
>>> from femap_neutral_parser import Parser
To instantiate a new parser, just pass a file path:
>>> neu = Parser("tests/data/mystran_00.NEU")
To have a list of available blocks:
>>> neu.available_blocks() {'header': 100, 'output_sets': 450, '_output_vectors': 451}
Or maybe in a more human-friendly way is to use info() method, which prints available results and outputs:
>>> neu.info() <BLANKLINE> Analysis ======== * subcase 1: Analyse. NASTRAN SPC 1 - lc1. test (MYSTRAN::Static) * subcase 2: Analyse. NASTRAN SPC 1 - lc2. test (MYSTRAN::Static) <BLANKLINE> Outputs ======= access to one of them using `._output_vectors[<title>][<SubcaseID>]['record'] <BLANKLINE> * displacements::t_total -> RSS translation * displacements::t1 -> T1 translation * displacements::t2 -> T2 translation * ... * cbar_stress::min_comb_a -> BAR EndA Min Stress * cbar_stress::min_comb_b -> BAR EndB Min Stress
Access available blocs by attribute:
>>> from pprint import pprint as pp >>> pp(neu.output_sets) {1: {'anal_type': 'Static', 'from_prog': 'Unknown', 'integer_format': None, 'notes': '', 'process_type': None, 'title': 'Analyse. NASTRAN SPC 1 - lc1. test', 'value': 0.0}, 2: {'anal_type': 'Static', 'from_prog': 'Unknown', 'integer_format': None, 'notes': '', 'process_type': None, 'title': 'Analyse. NASTRAN SPC 1 - lc2. test', 'value': 0.0}}
Low-level data access
Under the hood, output vectors (block451) are organized as nested dictionaries [<vector title>][<LCID>]:
>>> pp(neu._output_vectors["displacements::t_total"][2]) {'abs_max': 2.578386, 'calc_warn': True, 'cent_total': True, 'comp_dir': 1, 'component_vec': [10002.0, 10003.0, 10004.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 'id_max': 7, 'id_min': 1, 'max_val': 2.578386, 'min_val': 0.0, 'record': array([( 1, 0.000000e+00), ( 2, 2.045391e-01), ( 3, 0.000000e+00), ( 4, 1.468270e-02), ( 5, 9.231050e-05), ( 6, 6.276400e-01), ( 7, 2.578386e+00), ( 8, 1.025100e-01), ( 9, 2.578363e+00), (10, 1.916094e+00), (11, 1.100510e+00), (12, 2.389742e+00)], dtype=[('NodeID', '<i8'), ('displacements::t_total', '<f8')]), 'vecID': 10001}
Aggregated Outputs
Slightly highest level than _output_vectors access, aggregated output is available using Parser.vectors() method. For example, to get all outputs for translations vectors:
>>> arr = neu.vectors(("displacements::t1", "displacements::t2", "displacements::t3")) >>> arr rec.array([( 1, 0. , 0., 0.000000e+00, 1), ( 2, -0.1870816 , 0., 0.000000e+00, 1), ... (11, 0. , 0., -1.100510e+00, 2), (12, 0. , 0., -2.389742e+00, 2)], dtype=[('NodeID', '<i8'), ('displacements::t1', '<f8'), ('displacements::t2', '<f8'), ('displacements::t3', '<f8'), ('SubcaseID', '<i8')])
Returned value is a numpy structured array (https://numpy.org/doc/stable/user/basics.rec.html). If Pandas is available, you can request to have a DataFrame instead:
>>> neu.vectors(("displacements::t1", "displacements::t2", "displacements::t3"), asdf=True) displacements::t1 displacements::t2 displacements::t3 SubcaseID NodeID 1 1 0.000000 0.0 0.000000 2 -0.187082 0.0 0.000000 ... 11 0.000000 0.0 -0.956073 12 0.000000 0.0 -1.602912 2 1 0.000000 0.0 0.000000 2 -0.204539 0.0 0.000000 ... 11 0.000000 0.0 -1.100510 12 0.000000 0.0 -2.389742
You can also request sub-cases IDs, or request raw headers:
>>> neu.vectors(("displacements::t1", "displacements::t2", "displacements::t3"), asdf=True, raw=True, ... SubcaseIDs=2) T1 translation T2 translation T3 translation SubcaseID NodeID 2 1 0.000000 0.0 0.000000 2 -0.204539 0.0 0.000000 ... 11 0.000000 0.0 -1.100510 12 0.000000 0.0 -2.389742
High-Level access
At highest level, you can use the get method that already organize vectors for you:
>>> neu.get(what="displacements", asdf=True) t1 t2 t3 r1 r2 r3 SubcaseID NodeID 1 1 0.000000 0.0 0.000000 -0.000432 0.008923 4.699029e-03 2 -0.187082 0.0 0.000000 0.000432 0.008923 4.666047e-03 ... 2 1 0.000000 0.0 0.000000 -0.000007 0.009755 5.137517e-03 2 -0.204539 0.0 0.000000 0.000007 0.009755 5.101457e-03 ... 11 0.000000 0.0 -1.100510 0.000000 0.010988 1.006013e-06 12 0.000000 0.0 -2.389742 0.000000 0.004149 1.360364e-08
One can get the list of high-level shortcuts using Parser.get_vectors() which will return a set of available headers:
>>> neu.get_vectors() == { ... 'elem_gpf', ... 'force_vectors', ... 'displacements', ... 'summed_gpf', ... 'mpc_forces', ... 'constraint_gpf', ... 'cbar_force', ... 'cbar_stress', ... 'cbush_force', ... 'cbush_stress', ... 'cbar_ms', ... 'applied_gpf', ... 'spc_forces', ... 'cbeam_force' ... } True
Requirements
Beside Python>=3.8, only numpy is required. numpy arrays are released as https://numpy.org/doc/stable/user/basics.rec.html, which makes conversions to Pandas a breeze.
If Pandas is installed (which is advised), the asdf parameters are valid.
Testing
For testing, making docs or coding, all the dev requirements are provided in requirements_dev.txt.
From a blank virtual environment, clone this repo:
git clone https://framagit.org/numenic/femap_neutral_parser.git
Create a Python virtual environment, and activate it:
python -m venv fnp source fnp/bin/activate
Install requirements:
cd femap_neutral_parser pip install -r requirements.txt # install numpy pip install -r requirements_dev.txt pip install -e . # install femap-neutral-parser in new venv
Now testing:
make test # or make coverage
Building docs:
make docs
History
0.8.3 (2021-09-12)
Major internal refactoring
output_vectors becomes internal (_output_vectors). The recommended ways to access data is now Parser.vectors() or Parser.get() at a higher level.
no more autotranslate initialisation parameter. Everything is harmonized under the hood.
0.6.0 (2021-07-12)
add engineering shortcuts
harmonize NodeID and SubcaseID with pynastran
vectors are now case insensible
0.5.0 (2021-04-16)
improve parsing speed on large files
0.4.0 (2021-04-16)
add:
Parser.info()
Parser.vectors()
0.3.0 (2021-04-16)
add Parser.info() and Parser.vectors()
update documentation
add info() doprint option
0.2.0 - 0.3.0 (2021-04-16)
Update Documentation
0.1.0 (2021-03-24)
First release on PyPI.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file femap_neutral_parser-0.14.0.tar.gz
.
File metadata
- Download URL: femap_neutral_parser-0.14.0.tar.gz
- Upload date:
- Size: 46.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.8.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ca6ac11ef2ff8631826c74256243ec223ff51921f97b174106618b19cfa22877 |
|
MD5 | ad9f1711987a03c1d8bda3cb35f26811 |
|
BLAKE2b-256 | 5847cf59bd64d8a41acfdff9468cbc0e98c0e1b7e4fa68688a0e717edcea6dd8 |
File details
Details for the file femap_neutral_parser-0.14.0-py2.py3-none-any.whl
.
File metadata
- Download URL: femap_neutral_parser-0.14.0-py2.py3-none-any.whl
- Upload date:
- Size: 23.6 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.8.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | d1267761da9d84bf16afbd0fa7aee13c0059306a5441705d9f2a9246663a30ef |
|
MD5 | 1297fc042d1795fc7eead9a57ecd3b13 |
|
BLAKE2b-256 | 66f37ba082357c8f27581e934177cb9f545ad5f3d13f410766fd8dd87f13fe00 |