Update inp2rad.py to add dload pressure#104
Update inp2rad.py to add dload pressure#104PaulAltair wants to merge 1 commit intoOpenRadioss:mainfrom
Conversation
includes a number of wip updates for dload/dsload pressure also incorporates wip change to dcoup3d support skipgrav section commented out (may revert later)
There was a problem hiding this comment.
Pull request overview
This PR updates the Abaqus .inp → Radioss .rad converter to support additional load and formatting cases, primarily adding pressure (*DLOAD/*DSLOAD) conversion to Radioss /PLOAD/ and improving compatibility with newer export/format variants.
Changes:
- Add conversion of *DLOAD/*DSLOAD pressure definitions (with optional amplitude) into Radioss
/PLOAD/blocks, generating/SURF/SEG/when needed. - Adjust shell property output formatting for Radioss 2025 output and broaden segment generation to run even without explicit *SURFACE definitions.
- Improve preprocessing/robustness for DCOUP3D / distributing coupling and related placeholder ELSET handling.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| nset_counter += 1 | ||
| pload_counter = nset_counter | ||
|
|
||
| if new_surf_id: | ||
| pload_block = "#---1----|----2----|----3----|----4----|----5----|----6----|----7----|----8----|----9----|---10----|\n" |
There was a problem hiding this comment.
new_surf_id is not reset for each *DLOAD/*DSLOAD entry. If a previous pressure load created a new surface, subsequent loads that reference an existing surface can still take the if new_surf_id: branch and incorrectly re-emit /SURF/SEG using stale surf_segs/IDs. Reset new_surf_id (and ideally surf_segs) at the start of each pressure-load line, and base the branch on whether a surface was created for the current line only.
| if not existing_surf_id: | ||
| surf_id += 1 | ||
| new_surf_id = surf_id | ||
| surf_name_key = f"{elset_name}_{load_type}_pload" |
There was a problem hiding this comment.
The newly created pressure surface is stored in surf_name_to_id under surf_name_key = f"{elset_name}_{load_type}_pload", but later lookups use surf_name_to_id.get(elset_name, 0). This prevents reuse of generated surfaces and will create duplicate /SURF/SEG blocks for repeated pressure loads on the same region. Use a consistent key for both storing and lookup (either store under elset_name when the input region is an ELSET, or look up using the same constructed key).
| surf_name_key = f"{elset_name}_{load_type}_pload" | |
| surf_name_key = elset_name |
| for line in input_lines: | ||
| # Regular expression to find '*SURFACE' of type 'Element' | ||
| stype_pattern = r'^\*SURFACE\s*,\s*(?:NAME\s*=\s*[^\s,]+|TYPE\s*=\s*[^\s,]+)\s*(?!.*TYPE\s*=\s*NODE)' | ||
| matchelement = re.search(stype_pattern, line, re.IGNORECASE) | ||
|
|
||
| if matchelement and not segments_converted_already: | ||
| #if matchelement and not segments_converted_already: | ||
| if not segments_converted_already: |
There was a problem hiding this comment.
convert_segments() now returns on the first iteration regardless of whether a *SURFACE section exists, but it still loops over input_lines and computes stype_pattern/matchelement which are no longer used. Consider removing the loop/regex entirely and just build segment_dictionary from element_dicts once; this will simplify the control flow and avoid unnecessary per-line regex work.
| elset_values = [] | ||
| if dload_name.isdigit(): | ||
| skipgrav = True | ||
| skipgrav = False # modified 31st March 2026, to (temp) prevent skip for digit, don't recall why this was added? | ||
| continue |
There was a problem hiding this comment.
This branch is contradictory: the comment says it was modified to prevent skipping digit-named regions, but the continue still skips processing numeric dload_name entries entirely. Either implement numeric-region handling here (e.g., treat it as an element/part identifier) or remove the misleading skipgrav assignment/comment to avoid silently ignoring valid inputs.
|
|
||
|
|
||
| #################################################################################################### | ||
| # Function to convert *DLOAD or *DSlOAD pressure loads to Radioss /PLOAD/ cards # |
There was a problem hiding this comment.
Typo in the header comment: *DSlOAD should be *DSLOAD (uppercase S).
| # Function to convert *DLOAD or *DSlOAD pressure loads to Radioss /PLOAD/ cards # | |
| # Function to convert *DLOAD or *DSLOAD pressure loads to Radioss /PLOAD/ cards # |
| print(f"found a coupling on line {line}") | ||
| refnode_match = refnode_pattern.search(line) | ||
| surface_match = surface_pattern.search(line) | ||
| j = 0 | ||
| if refnode_match and surface_match: | ||
| current_refnode = refnode_match.group(1) | ||
| current_surface = surface_match.group(1) |
There was a problem hiding this comment.
j is initialized to 0 here but (in the current control flow) it isn’t incremented in the *COUPLING branch. Since j is later used as the initial coupling_data[...]['count'], this can leave a 0 count if the corresponding *SURFACE, TYPE=NODE block isn’t found/parsed. Consider deferring count assignment until nodes are actually collected (or compute it from len(nodes) when emitting) to avoid writing an invalid 0 count.
Draft:
includes a number of updates to add support for dload/dsload pressure definition, with amplitude, for set or surf reference
also incorporates change to dcoup3d support, allowing for newer HM export standard (set separated from dcoup3d element definition) improves robustness this slows down read/conversion if dcoup3ds present, could be specifically recoded for HM in future to speed back up
shell property output corrected in the 2025 output format, to move ipos field (was on new line in Radioss 2025 documentation, moved to end of previous line in 2025.1)
segments are generated for all elsets instead of only when surfs are present (since mapping may be needed for dload/dsload pressure definition, relatively low overhead)
skipgrav section in dload grav deactivated/commented out (may revert later)