4. Time intelligence in CAE
CAE programs rarely produce a single simulation result that stands alone. A crashworthiness team may run dozens of load cases per vehicle program, each repeated across design iterations, solver versions, and mesh revisions. The value of a KPI such as peak occupant acceleration, intrusion, or HIC is only meaningful when it can be placed on a timeline: how does this run compare with the previous iteration, with the baseline, or with the same load case one program phase earlier? DAX time intelligence provides the machinery to answer those questions, but only if the underlying model exposes a clean, contiguous date dimension and a well-defined notion of what a "run" represents in time.
Establishing a Simulation Date Dimension
Time intelligence functions in DAX — TOTALYTD, SAMEPERIODLASTYEAR, DATEADD, DATESBETWEEN, PARALLELPERIOD — all depend on a marked date table with one row per day and no gaps. In a CAE context the natural date is not the calendar day a report is viewed but the run completion date recorded in the simulation management system (for example, a CAE results database or PLM export). Build a dedicated DimDate table covering the full program window, mark it as a date table, and relate it one-to-many to the fact table FactSimulationRun on RunCompletedDate.
DimDate =
ADDCOLUMNS (
CALENDAR ( DATE ( 2023, 1, 1 ), DATE ( 2025, 12, 31 ) ),
"Year", YEAR ( [Date] ),
"Quarter", "Q" & QUARTER ( [Date] ),
"Month", FORMAT ( [Date], "YYYY-MM" ),
"ProgramPhase",
SWITCH ( TRUE (),
[Date] < DATE ( 2024, 1, 1 ), "Phase A - Concept",
[Date] < DATE ( 2024, 7, 1 ), "Phase B - Design",
[Date] < DATE ( 2025, 1, 1 ), "Phase C - Validation",
"Phase D - Release" )
)
The ProgramPhase column is the key adaptation for CAE. Calendar months are a poor proxy for engineering progress; a program phase column lets you write period comparisons that align with design gates rather than fiscal periods. Keep the date table at day granularity even if runs complete weekly — the functions require it, and the extra rows cost almost nothing.
Defining the Run Grain and the Comparison Baseline
Before writing any time intelligence measure, decide what a single row in the fact table means. A defensible grain is one row per run: a unique combination of load case, design iteration, solver version, and completion timestamp. Store the KPI value (for example, PeakAcceleration_g) alongside identifiers such as LoadCaseID, IterationID, and IsBaseline. The baseline flag is what makes period-over-period analysis tractable: rather than relying on dates alone, you can compare the current iteration against the flagged baseline run for the same load case.
A common mistake is to aggregate runs by summing KPI values. Peak acceleration does not sum across runs; it is a per-run observation. Time intelligence measures should therefore use AVERAGE, MIN, MAX, or a LASTNONBLANK pattern, never SUM, unless the KPI is genuinely additive (for example, total simulated CPU hours).
Comparing the Current Run Against the Previous Iteration
The most frequent CAE question is: did this iteration improve on the last one? The following measure returns the KPI for the most recent prior run of the same load case, using LASTNONBLANK over the date dimension to avoid empty dates between runs.
PeakAccel Previous Run =
VAR CurrentLoadCase = SELECTEDVALUE ( FactSimulationRun[LoadCaseID] )
VAR CurrentDate = MAX ( FactSimulationRun[RunCompletedDate] )
RETURN
CALCULATE (
AVERAGE ( FactSimulationRun[PeakAcceleration_g] ),
FILTER (
ALL ( FactSimulationRun ),
FactSimulationRun[LoadCaseID] = CurrentLoadCase
&& FactSimulationRun[RunCompletedDate] < CurrentDate
),
TOPN ( 1, VALUES ( FactSimulationRun[RunCompletedDate] ),
CALCULATE ( MAX ( FactSimulationRun[RunCompletedDate] ) ), DESC )
)
Pair this with a delta measure and a directional indicator. Because lower peak acceleration is better, the sign convention must be stated explicitly and applied consistently: define improvement as a negative delta in g, and surface it as a positive percentage improvement in the report.
PeakAccel Delta % =
VAR Prev = [PeakAccel Previous Run]
RETURN
IF ( NOT ISBLANK ( Prev ) && Prev <> 0,
DIVIDE ( [PeakAccel Current] - Prev, Prev ) )
Tracking KPI Trends Across Program Phases
Trend tracking answers a different question: is the KPI moving in the right direction over the life of the program? Use DATESBETWEEN or PARALLELPERIOD to build rolling windows, and plot the result against the phase boundaries defined in DimDate. A rolling 90-day average smooths the noise introduced by irregular run cadence, while a phase-level average gives a cleaner gate-to-gate comparison.
PeakAccel Rolling 90D =
CALCULATE (
AVERAGE ( FactSimulationRun[PeakAcceleration_g] ),
DATESINPERIOD ( DimDate[Date], MAX ( DimDate[Date] ), -90, DAY )
)
PeakAccel Phase Avg =
CALCULATE (
AVERAGE ( FactSimulationRun[PeakAcceleration_g] ),
ALLEXCEPT ( DimDate, DimDate[ProgramPhase] )
)
When plotting trends, always filter to a single load case and a single occupant position. Mixing load cases in one trend line produces a sawtooth pattern that reflects run scheduling, not engineering progress. Use small multiples or a slicer on LoadCaseID to keep each series interpretable.
Period-over-Period Analysis with SAMEPERIODLASTYEAR and DATEADD
For programs that span multiple years, SAMEPERIODLASTYEAR and DATEADD provide the standard period-over-period comparison. These functions shift the filter context on DimDate, so they work correctly only when the relationship between DimDate and the fact table is active and single-directional.
PeakAccel YoY Delta =
VAR Current = [PeakAccel Current]
VAR Prior = CALCULATE ( [PeakAccel Current], SAMEPERIODLASTYEAR ( DimDate[Date] ) )
RETURN IF ( NOT ISBLANK ( Prior ), Current - Prior )
PeakAccel vs Prior Quarter =
VAR Prior = CALCULATE ( [PeakAccel Current], DATEADD ( DimDate[Date], -1, QUARTER ) )
RETURN IF ( NOT ISBLANK ( Prior ), [PeakAccel Current] - Prior )
In CAE, calendar-based YoY comparisons are often less useful than phase-based ones, because a program may not have runs in the same calendar quarter across years. Use DATEADD with a custom offset when the comparison should be "same phase, previous program," and fall back to the baseline-flag approach when the timeline is irregular. The table below summarises when each pattern is appropriate.
| Comparison pattern | DAX construct | Best suited to | Watch out for |
|---|---|---|---|
| Previous run, same load case | TOPN + FILTER | Iteration-to-iteration improvement | Irregular run cadence; ties on date |
| Rolling window trend | DATESINPERIOD | Smoothing noisy KPI series | Window shorter than run interval yields blanks |
| Phase-to-phase | ALLEXCEPT on phase | Design gate reviews | Phase boundaries must be defined in DimDate |
| Year-over-year | SAMEPERIODLASTYEAR | Multi-year programs with regular cadence | Missing prior-year runs return blank |
| Quarter-over-quarter | DATEADD ( …, -1, QUARTER ) | Program management reporting | Calendar quarters may not align with gates |
IF ( NOT ISBLANK ( … ) ). A blank prior period is a data-availability fact, not a zero delta, and displaying it as 0% misleads reviewers into thinking no change occurred.Reading the Result: A Worked Example
Consider a frontal impact load case with three runs in Phase C. Run 1 (baseline, 2024-08-12) records 42.5 g peak chest acceleration; Run 2 (2024-09-03) records 39.8 g; Run 3 (2024-09-27) records 40.6 g. The previous-run measure for Run 3 returns 39.8 g, giving a delta of +0.8 g (+2.0%), which flags a regression against the prior iteration even though the phase average (40.97 g) is below the baseline. This is exactly the kind of nuance time intelligence exposes: phase-level trends can look healthy while the most recent iteration has drifted. Reviewers should inspect both the phase average and the latest-run delta before signing off a gate.
The SVG below maps the comparison logic: how a single run's KPI flows into previous-run, rolling-window, phase, and year-over-year contexts, and which DAX construct drives each path.
Practical Guardrails
- Mark the date table and keep it contiguous. A single missing day breaks
DATESINPERIODandSAMEPERIODLASTYEARsilently, returning blanks rather than errors. - Never sum non-additive KPIs. Peak acceleration, HIC, and intrusion are per-run observations; use averages or last-non-blank patterns.
- State the sign convention once. Define improvement as a reduction in the KPI and apply it in every measure, tooltip, and conditional-format rule.
- Separate run cadence from calendar periods. If runs complete irregularly, prefer previous-run and phase-based comparisons over calendar YoY.
- Validate against a known run. Pick one load case with three or four runs, compute the previous-run delta by hand, and confirm the measure matches before publishing the report.
With a marked date table, a clearly defined run grain, and measures that respect the non-additive nature of CAE KPIs, time intelligence turns a flat list of simulation results into a defensible narrative of engineering progress — one that reviewers can trace from a single run back through its iteration history and forward to the next design gate.