4. Validate INCLUDE Path Resolution for Rel
Why INCLUDE path resolution breaks when the working directory changes
LS-DYNA resolves every *INCLUDE card at run time, not when the deck is authored. A relative filename such as mesh/body.k is interpreted against the process working directory (or against a directory established by *INCLUDE_PATH), so a deck that runs cleanly from /home/analyst/project will fail immediately when launched from /scratch/run04. Absolute references such as /home/analyst/project/mesh/body.k survive a directory change but break the moment the model is copied to another machine or handed to a colleague. The practical goal of this case is a deck that mixes both styles, plus a corrected set of path definitions, so that the same input runs from at least two different working directories without editing.
Two keyword behaviours drive everything below. First, *INCLUDE_PATH registers one or more search directories; when a subsequent *INCLUDE gives a relative filename, LS-DYNA searches the registered paths in order and uses the first match. Second, the *INCLUDE_PATH entries themselves may be relative or absolute, and relative entries are resolved against the working directory at the moment the card is read. That second point is the usual source of "it worked yesterday" failures: the path list is fine, but the base it is anchored to has moved.
Reference deck used in this case
The example below is a small but complete deck that deliberately mixes reference styles. It is a teaching model, not a production model; the mesh and material files are minimal placeholders whose only job is to make resolution observable.
$ main.k -- run this from any directory
*KEYWORD
*INCLUDE_PATH_RELATIVE
$ anchored to the directory containing this main deck
./library
./library/materials
*INCLUDE_PATH
$ absolute fallback for shared corporate data
/opt/lsdyna/shared/contacts
*INCLUDE
mesh/body.k
*INCLUDE
library/materials/steel.k
*INCLUDE
/opt/lsdyna/shared/contacts/general_contact.k
*CONTROL_TERMINATION
$# endtim endcyc dtmin endeng endmas
0.010 0 0.0 0.0 0.0
*END
Note the deliberate mixture: mesh/body.k is relative with no registered prefix, library/materials/steel.k is relative but also reachable through the registered ./library entry, and general_contact.k is absolute. The deck also uses *INCLUDE_PATH_RELATIVE, which anchors its entries to the location of the file that contains the card rather than to the process working directory. That single choice is what makes the deck portable; the absolute contact path is kept only to demonstrate the mixed case and to show how to audit it.
Resolution order and the failure it produces
When LS-DYNA encounters *INCLUDE mesh/body.k, it tries the literal relative path first, then each registered search directory in the order listed. If nothing matches, the run terminates during input processing with a message in d3hsp and messag naming the unresolved file. The diagram below shows the search chain for the three includes in the reference deck, including the branch that fails when the deck is launched from a directory that does not contain mesh/.
Correcting the path definitions
The fix is not to convert everything to absolute paths. That would make Case B pass while making the deck unusable on any other machine. The durable correction is to anchor the relative entries to the deck itself and to keep absolute references only for genuinely shared, machine-independent resources. Three concrete edits achieve this:
- Replace
*INCLUDE_PATHwith*INCLUDE_PATH_RELATIVEfor any directory that lives inside the model tree. Entries are then resolved against the directory of the file containing the card, so the deck can be launched from anywhere. - Register the directory that contains
mesh/explicitly, or change the include to./mesh/body.kso it is unambiguous. A baremesh/body.kwith no matching search path only works when the working directory happens to be the project root. - Audit every absolute path. Keep it only if the target is a shared installation such as
/opt/lsdyna/shared/contacts; otherwise convert it to a relative reference under the model tree.
The corrected header for the reference deck is shown below. The only remaining absolute entry is the shared contact library, which is intentional and documented in a comment.
*KEYWORD
*INCLUDE_PATH_RELATIVE
$ anchored to the directory of this file, not the cwd
.
./library
./library/materials
*INCLUDE_PATH
$ shared corporate data, intentionally absolute
/opt/lsdyna/shared/contacts
*INCLUDE
./mesh/body.k
*INCLUDE
./library/materials/steel.k
*INCLUDE
/opt/lsdyna/shared/contacts/general_contact.k
*CONTROL_TERMINATION
$# endtim endcyc dtmin endeng endmas
0.010 0 0.0 0.0 0.0
*END
Verification from two working directories
Verification is a two-run check, not a single successful launch. Run the deck once from the project root and once from an unrelated directory, and compare the input-processing section of d3hsp in both runs. The expected observable is that both runs list the same three include files with the same resolved paths, and that neither run reports an unresolved include. A practical procedure:
- From the project root, launch the solver with the deck as the input file and let it reach at least the first cycle, then stop it. Confirm
d3hspcontains no "Error reading include file" lines. - Create an empty scratch directory, change into it, and launch the same deck by absolute path to
main.k. This is the case that previously failed. - Diff the include-resolution lines of the two
d3hspfiles. They should match; any difference points to a path that is still anchored to the working directory. - Optionally, copy the model tree to a second location and repeat step 2 to confirm the deck is portable, not merely runnable from two directories on one machine.
d3hsp for the literal filename from the failing *INCLUDE card. LS-DYNA reports the string as written, not the resolved path, so a match tells you which card to inspect and a mismatch tells you the failure is elsewhere.Path audit checklist
The following checklist is the deliverable for this case. Apply it to any deck that mixes reference styles before handing the model to another analyst or moving it to a compute node.
| Check | Pass condition | Typical failure symptom |
|---|---|---|
| Every relative include has a matching search path | Each relative filename resolves through a registered *INCLUDE_PATH or *INCLUDE_PATH_RELATIVE entry |
Unresolved include reported in d3hsp when cwd differs from the authoring directory |
Model-tree directories use *INCLUDE_PATH_RELATIVE |
Entries are anchored to the deck location, not the process cwd | Deck runs from project root but fails from a scratch directory |
| Absolute paths are justified | Each absolute reference points to a shared, machine-independent resource | Deck fails after being copied to another machine or user account |
| Search order is intentional | No two registered directories contain files with the same name | Wrong material or mesh silently picked up from an earlier search path |
| Two-directory run test passes | Include-resolution lines in d3hsp match across both runs |
One run completes input processing, the other aborts |
Once the checklist passes, the deck is independent of the launch directory for everything inside the model tree, and the only remaining absolute reference is the shared contact library, which is deliberate and documented. That is the correct end state for a mixed-reference deck: portability where it matters, and a small, auditable set of absolute paths where sharing genuinely requires them.