Skip to content

MDOF systems

Represent discrete structural dynamics with assembled masses, a shear-building parameterization, or validated mass, damping, and stiffness matrices.

Choose a construction method

Method Best for
ShearBuilding Story-based building models
MDOFSystem.attach_mass() Explicit spring-mass topologies
MDOFSystem(M, C, K) Imported or externally assembled matrices

All three implement the same StructuralSystem interface and can use the same loads, sensors, simulation engine, and dataset workflow.

Shear building

Provide one mass and one stiffness per story, ordered from the grounded story upward:

from dynaresp import systems

building = systems.ShearBuilding(
    masses=[1000.0, 900.0, 800.0],
    stiffnesses=[1.0e6, 8.0e5, 6.0e5],
    damping_ratio=0.02,
    labels=["floor_1", "floor_2", "floor_3"],
)

The first stiffness connects the first mass to ground. Each following stiffness connects adjacent masses. Damping is assembled in modal coordinates from the requested damping ratio.

mass, damping, stiffness = building.matrices()
modal = building.modal_analysis([0, 1, 2])

print(modal.frequencies_hz)
print(modal.mode_shapes.shape)  # (3 modes, 3 DOFs)

Attach masses explicitly

Use incremental assembly when the connection topology is more useful than raw matrix input:

system = systems.MDOFSystem()
system.attach_mass(
    name="m1",
    mass=1000.0,
    to="ground",
    stiffness=1.0e6,
    damping=1000.0,
)
system.attach_mass(
    name="m2",
    mass=900.0,
    to="m1",
    stiffness=8.0e5,
    damping=800.0,
)

to must name ground or a previously attached mass. Names are unique, and mass and stiffness must be positive. attach_mass() returns the same system, so calls may be chained.

For dataset generation, construct the complete attachment topology inside the system builder. No special parameter-registration interface is required.

Direct matrices

Use direct construction for matrices assembled by another solver or imported from a model:

import numpy as np

mass = np.diag([2.0, 1.0])
damping = np.diag([0.1, 0.2])
stiffness = np.array([[3.0, -1.0], [-1.0, 1.0]])

system = systems.MDOFSystem(
    M=mass,
    C=damping,
    K=stiffness,
    labels=["lower", "upper"],
)

Validation is performed at construction:

  • M, C, and K must be finite square matrices with equal shape;
  • M and K must be symmetric;
  • M must be positive definite;
  • K must be positive semidefinite;
  • labels must contain one non-empty value per DOF.

For a dataset, the system builder may assemble or import new M, C, and K arrays for every case.

Coordinates, loads, and sensors

MDOF coordinates are zero-based integer indices:

from dynaresp import loads, sensors

positions = np.arange(system.ndof)
load = loads.Harmonic(position=0, amplitude=10.0, frequency=2.0)
layout = [sensors.Accelerometer(position=index) for index in range(system.ndof)]

Fractional or out-of-range coordinates are rejected. Repeated load coordinates are summed during projection. Moving-load trajectories are intended for continuous-coordinate systems such as Beam; MDOF excitation should target fixed integer DOFs.

Matrix access

The following forms return copies and are equivalent:

mass, damping, stiffness = system.matrices()

system.mass_matrix
system.damping_matrix
system.stiffness_matrix

system.M
system.C
system.K

Returning copies protects the validated system definition from accidental in-place mutation.