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.
Metadata
Release files for femap-neutral-parser 0.14.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| femap_neutral_parser-0.14.0.tar.gz | 46.4 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| femap_neutral_parser-0.14.0-py2.py3-none-any.whl | Python 2, Python 3 | none | any | Details |
Total release size: 70.0 kB
Release files / femap_neutral_parser-0.14.0.tar.gz
| Download URL | femap_neutral_parser-0.14.0.tar.gz |
|---|---|
| Size | 46.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ca6ac11ef2ff8631826c74256243ec223ff51921f97b174106618b19cfa22877
|
|
BLAKE2b-256 checksum How to use checksums |
5847cf59bd64d8a41acfdff9468cbc0e98c0e1b7e4fa68688a0e717edcea6dd8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.8.13
|
Release files / femap_neutral_parser-0.14.0-py2.py3-none-any.whl
| Download URL | femap_neutral_parser-0.14.0-py2.py3-none-any.whl |
|---|---|
| Size | 23.6 kB |
| Tags | Python 2 Python 3 |
|
SHA-256 checksum How to use checksums |
d1267761da9d84bf16afbd0fa7aee13c0059306a5441705d9f2a9246663a30ef
|
|
BLAKE2b-256 checksum How to use checksums |
66f37ba082357c8f27581e934177cb9f545ad5f3d13f410766fd8dd87f13fe00
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.8.13
|
Security for femap-neutral-parser 0.14.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.