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/.

Resolution chain: main.k launched from two working directories Case A: cwd = project root /home/analyst/project mesh/ and library/ present Case B: cwd = /scratch/run04 /scratch/run04 no mesh/ or library/ here main.k *INCLUDE_PATH_RELATIVE ./library, ./library/materials *INCLUDE mesh/body.k relative, no prefix *INCLUDE library/materials/steel.k relative, matches ./library *INCLUDE /opt/lsdyna/shared/contacts/general_contact.k absolute, cwd-independent Outcome per case Case A: all three includes resolve; input processing completes. Case B: mesh/body.k unresolved; run aborts before the first cycle. Case B: absolute contact path still resolves; only relative entries fail. Failure signature in d3hsp *** Error reading include file mesh/body.k Reported path is the literal string from the card, not the resolved one. Reading the diagram Relative include resolved through a registered search path Absolute include, independent of working directory Unresolved include, aborts input processing Search order: literal path, then each *INCLUDE_PATH entry in listed order.

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:

  1. Replace *INCLUDE_PATH with *INCLUDE_PATH_RELATIVE for 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.
  2. Register the directory that contains mesh/ explicitly, or change the include to ./mesh/body.k so it is unambiguous. A bare mesh/body.k with no matching search path only works when the working directory happens to be the project root.
  3. 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:

  1. 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 d3hsp contains no "Error reading include file" lines.
  2. 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.
  3. Diff the include-resolution lines of the two d3hsp files. They should match; any difference points to a path that is still anchored to the working directory.
  4. 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.
If a run fails only in the scratch directory, the fastest diagnostic is to search 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.
Do not "fix" a resolution failure by copying files into the working directory. That hides the defect, breaks the next run from a different directory, and defeats the purpose of a modular deck. Correct the path definition instead.

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.