Skip to content

Quickstart

DynaResp uses caller-defined numerical axes. Put the complete inputs for one run in a SimulationSpec; this keeps the main simulation path explicit and independent of process-wide state.

import numpy as np

import dynaresp as dr

time = np.arange(1000, dtype=float) / 100.0
positions = np.arange(3, dtype=float)

system = dr.systems.ShearBuilding(
    masses=[1000.0, 900.0, 800.0],
    stiffnesses=[1.0e6, 8.0e5, 6.0e5],
    damping_ratio=0.02,
)

spec = dr.SimulationSpec(
    system=system,
    load=dr.loads.WhiteNoise(position=0, rms=10.0),
    sensors=tuple(dr.sensors.Accelerometer(position=i) for i in positions),
    time=time,
    positions=positions,
)
result = dr.run_simulation(spec, seed=42)

result.time and result.positions are copies of the supplied axes. result.load_values has shape (positions, time), while result.force is the projected generalized force with shape (DOF, time).

The same axes are passed to dataset generation:

def build_case(rng):
    return {"masses": rng.uniform(800.0, 1200.0, size=3)}


def build_system(case):
    return dr.ShearBuilding(
        masses=np.asarray(case["masses"], dtype=float),
        stiffnesses=[1.0e6, 8.0e5, 6.0e5],
    )


def build_load(_case):
    return dr.loads.WhiteNoise(position=0, rms=10.0)


dataset = dr.generate_dataset(
    n_samples=100,
    case_builder=build_case,
    system_builder=build_system,
    load_builder=build_load,
    sensors=[dr.sensors.Accelerometer(position=i) for i in positions],
    time=time,
    positions=positions,
    record=[
        dr.Record.signal,
        dr.Record.case_parameter,
        dr.Record.time,
        dr.Record.positions,
    ],
    seed=42,
)

Loads and simulations require explicit axes. Dataset generation also requires the axes as simulation inputs, but stores them only when Record.time and Record.positions are selected. This keeps every run self-contained without silently retaining unwanted arrays.

Continue with loads, the finite-element beam, or dataset generation.