Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion references/RULES.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ As a rule of thumb, set `write_to_terminal_timestep` to a smaller value than `wr
Every one-shot event a script triggers (a mark, a final compress, any other state change meant to be captured) must run before the last `write_output_timestep` write it's meant to appear in.
Verifying the event actually took effect (see `strategies/STRATEGIES.md`'s "Verify a per-particle-state command actually worked" entry) is a separate concern from this ordering — a verified change that ran after the last capturing write still won't show up in the output.

### Output folders in a multi-phase case

Give each named script (`init`/`main`/`fill`/...) its own `output_settings folder`, and clear it (not just the restart file) before rerunning outside a full clean — see `commands/output_settings.md`.

## Timestep Criteria

Large timesteps may cause numerical instability.
Expand All @@ -96,11 +100,12 @@ Refer to the `check_timestep` command.

Shared parameters (e.g. `simulation_timestep`) across split scripts (`init.asx`, `main.asx`, ...) aren't enforced automatically — confirm they still match before running.

This includes a stop condition expressed as "N% of an earlier state" (e.g. a settled particle/mass count from a prior `fill`-style script) — Aspherix's variable system cannot snapshot a value from earlier in the *same* script for later comparison either, let alone across scripts (referencing one variable from inside another's formula either crashes at evaluation via `${name}`, or silently re-evaluates live every time via `v_name` — neither freezes a value; see `commands/variable.md`).
This includes a stop condition expressed as "N% of an earlier state" (e.g. a settled particle/mass count from a prior `fill`-style script) — Aspherix's variable system cannot snapshot a value from earlier in the *same* script for later comparison either, let alone across scripts (referencing one variable from inside another's *quoted* formula fails at evaluation via `${name}`, and `v_name` re-evaluates live every time — neither freezes a value; see `commands/variable.md`).
This kind of threshold has to be computed externally, from the prior script's *actual* achieved output, and hardcoded - never derived from the originally intended target.
Confirmed directly: a threshold sized for an intended count that insertion didn't fully reach (see `strategies/STRATEGIES.md`'s packing-generator entry) made `simulate mode until_condition_reached` satisfy on its very first check - no error, just a silent early exit that looks like the run did nothing.

A threshold on an *extensive* quantity — total `ke(...)`, total mass, a particle count — must likewise be rescaled whenever the particle count is, since it states a total over the system rather than a per-particle condition.
Derive it as `<per-particle value> * <this script's actual count>`, or avoid the problem with an intensive criterion — `simulate mode until_settled` breaks on a velocity threshold, which holds at any scale.

State handed between scripts needs the same care: `read_restart` reads whatever file is at the path, with no record of what wrote it (`read_restart.html`), so record provenance beside it — script, achieved count, timestamp — and check that before the phase that consumes it.
This includes physics settings, not just data: only declare one (e.g. heating) in the script phase that actually needs it, not earlier — a packing/prep phase split off via `write_restart`/`read_restart` can silently inherit one left over from an earlier script version.
9 changes: 8 additions & 1 deletion references/strategies/INSERTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@ Use `mode rate_in_region` with `insert_every_time` instead (self-limits correctl
In a non-physical prep phase (checkpointed via `write_restart`), point `enable_gravity`'s `direction` toward wherever the bed should end up — settling does the work for free instead of a slow pusher mesh.
Restore the real direction in the script that reads the restart.

## `mesh_module servo`'s `kp` often needs to be much larger than its default
## Compacting a bed with `mesh_module servo`

Once a bed is placed, `mesh_module servo` can compact it further by driving a wall against the bed toward a target force or torque.

### `kp` often needs to be much larger than its default

`kp`'s default (1e-2) is often orders of magnitude too small to reach `maximum_velocity` in a reasonable time — verify actual displacement rather than trusting the default.
`simulate mode until_settled` won't detect servo progress either, since it converges on kinetic energy, not on the servo's own target — use `fixed_time` instead (see the `until_filled`/`until_settled` entry above for the same convergence-check caveat in the insertion case).

### `center_of_mass` must track the pushed body, not the mesh's own STL position

When reusing the same piston geometry across scripts/restarts, point `center_of_mass` at the pushed body's actual current position, not the mesh's imported STL coordinates, which don't update when an earlier phase moves the body.
5 changes: 5 additions & 0 deletions references/strategies/STRATEGIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ Keep this separate from a final one-shot `write_restart` at a `simulate` block's
If a later phase's `read_restart` path should be swappable between the two, make it an `index`-style variable overridable via `-var` rather than a literal filename.
This mechanism is for a standalone Aspherix run only - a CFD-coupled case (`enable_cfd_coupling`) syncs restarts from the CFD side, not through this `restart` mechanism, so don't assume it applies there too (see `commands/enable_cfd_coupling.md`).

## Only regenerate a restart when the phase that produced it actually needs to change

Before re-running an earlier phase's script over a later phase's parameter change, check whether the earlier phase's own physics actually depends on it.
E.g. packing is independent of particle heat capacity, so `read_restart` can just pick up the new value instead of re-running the packing phase.

## Ramp prescribed mesh motion from rest, don't start it at full speed

See `mesh_module_motion.html`'s note on starting at full speed, and `variable.html`'s note on building a temporal ramp for a `simulate`-based script (not the `ramp(x,y)` math function, which isn't a fit there) - apply that general pattern to the motion command's velocity/period/omega argument.
Expand Down