# \[ANN\] StructuralVibration.jl

**URL:** <https://discourse.julialang.org/t/ann-structuralvibration-jl/127978>\
**Category:** Package Announcements\
**Tags:** physics\
**Created:** [April 11, 2025, 12:38pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978 "2025-04-11T12:38:44Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![Maucejo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maucejo/32/39090_2.png) [@Maucejo](https://discourse.julialang.org/u/Maucejo)\
**Post date:** [April 11, 2025, 12:38pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/1 "2025-04-11T12:38:44Z")

</div>

Hi all,

I am pleased to announce my first real contribution to the Julia environment. StructuralVibration.jl is intended to provide a set of tools for generating vibration data either to validate new numerical methods or to serve as input data for solving inverse problems such as input state estimation via Bayesian filtering, Bayesian regularization, machine learning, etc.

This package is developed as part of my research activities on source identification in structural dynamics and acoustics. It has been tested with DispatchDoctor.jl and Aqua.jl.

I tried to developed a comprehensive documentation that you can read [here](https://maucejo.github.io/StructuralVibration.jl/).

The package provides the following features:

### Mechanical models

- **Discrete models**
  - Spring-mass-damper of SDOF and MDOF systems
  - FE models of bar, rod, strings and beams

- **Continuous models**
  - Longitudinal bars, Torsional bars, Strings
  - Beams
  - Rectangular plates, Rectangular membranes

- **State space model**
  - Continuous state-space representation
  - Discrete state-space representation
    - Zero-order hold (ZOH)
    - First-order hold (FOH)
    - Band-limited hold (BLH)
    - RK4

### Vibration data generation

- **Excitation signals**

- **Solution for SDOF systems**

- **Time-domain integration schemes for linear second order systems**

- **Frequency-domain calculations for linear systems**

- **State-space solvers**

- **Measurement noise**

- **Signal processing**

### Visualization

- Bode plot
- 2D and 3D Nyquist plot
- Waterfall plot
- General 2D plot

PR are welcome !

---

<div class="post-metadata">

**Author:** ![Jake](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jake/32/46007_2.png) [@Jake](https://discourse.julialang.org/u/Jake)\
**Post date:** [May 12, 2025, 12:54pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/2 "2025-05-12T12:54:05Z")

</div>

Thanks to @Krastanov for mentioning your package, otheriwise I would have missed it.

I tried loading it and received the error

```julia
(@v1.11) pkg> dev StructuralVibration
ERROR: The following package names could not be resolved:
 * StructuralVibration (not found in project, manifest or registry)
   Suggestions: StructuredOptimization StructuralEquationModels StructuralUnits StructureFunctions StructuralInheritance

(@v1.11) pkg> add StructuralVibration
ERROR: The following package names could not be resolved:
 * StructuralVibration (not found in project, manifest or registry)
   Suggestions: StructuredOptimization StructuralEquationModels StructuralUnits StructureFunctions StructuralInheritance

(@v1.11) pkg> 

```

This however works:

`https://github.com/maucejo/StructuralVibration.jl)`

The documentation should be updated.

---

<div class="post-metadata">

**Author:** ![Maucejo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maucejo/32/39090_2.png) [@Maucejo](https://discourse.julialang.org/u/Maucejo)\
**Post date:** [May 12, 2025, 5:00pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/3 "2025-05-12T17:00:40Z")

</div>

You are right. I will update. However, you can just type `add StructuralVibration` to install the package.

---

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [December 13, 2025, 7:17pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/4 "2025-12-13T19:17:41Z")

</div>

I’m trying to simulate s string, but I’m hitting an error. What do I do wrong?

```julia-auto
using StructuralVibration

# Defining String
L = 1.
d = 3e-2
S = π*d^2/4
T = 5000.
ρ = 7800.
strings = Strings(L, S, T, ρ)

# Mesh definition
oned_mesh = OneDMesh(strings, 0., 20, :CC)

# Construction of K and M
Kfe, Mfe = assembly(strings, oned_mesh)

# Application of the BCs
Kbc = apply_bc(Kfe, oned_mesh)
Mbc = apply_bc(Mfe, oned_mesh)

# Calculation of the damping matrix
Cray = rayleigh_damping_matrix(Kbc, Mbc, 1., 1.)

t = 0.:1e-2:30.

# pull middle node
x0 = [zeros(10); .1; zeros(10)]  
v0 = zeros(21) # length(oned_mesh.Nodes)
u0 = (x0, v0)

# No force
F_free = zeros(length(oned_mesh.Nodes), length(t))

# Direct time problem
prob = DirectTimeProblem(Kfe, Mfe, Cray, F_free, u0, t)

x_free = solve(prob)

ERROR: DimensionMismatch: incompatible dimensions for matrix multiplication: tried to multiply a matrix of size (19, 19) with a vector of length 21. The second dimension of the matrix: 19, does not match the length of the vector: 21.

```

The mismatch is probably between the stiffness / mass matrix of size (21,21) with the dampening matrix of size (19,19).

What am I missing?

---

<div class="post-metadata">

**Author:** ![Maucejo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maucejo/32/39090_2.png) [@Maucejo](https://discourse.julialang.org/u/Maucejo)\
**Post date:** [December 13, 2025, 7:55pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/5 "2025-12-13T19:55:55Z")

</div>

Hi @tp2750, there are several places in the code where you have a problem with dimensions:

- You apply the BCs to obtain Kbc and Mbc but you don’t use it in the definition of `DirectTimeproblem`
- The initial conditions have improper dimensions it should be 19 instead of 21. Same for `F_free.`

---

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [December 14, 2025, 9:34am UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/6 "2025-12-14T09:34:26Z")

</div>

Thank you for the quick reply @Maucejo .That makes sense.

But I still don’t understand the solution: the string seems to be accelerating:

```julia-auto
using StructuralVibration

# Defining String
L = 1.
d = 3e-2
S = π*d^2/4
T = 5000.
ρ = 7800.
strings = Strings(L, S, T, ρ)

# Mesh definition
oned_mesh = OneDMesh(strings, 0., 20, :CC)

# Construction of K and M
Kfe, Mfe = assembly(strings, oned_mesh)

# Application of the BCs
Kbc = apply_bc(Kfe, oned_mesh)
Mbc = apply_bc(Mfe, oned_mesh)

# Calculation of the damping matrix
Cray = rayleigh_damping_matrix(Kbc, Mbc, 1., 1.)

t = 0.:1e-2:30.

# pull middle node
x0 = [zeros(9); .1; zeros(9)]  
v0 = zeros(19) 
u0 = (x0, v0)

# No force
F_free = zeros(19, length(t))

# Direct time problem
prob = DirectTimeProblem(Kbc, Mbc, Cray, F_free, u0, t)

res = solve(prob, RK4())

res.u[10,1:10]
# 10-element Vector{Float64}:
# 0.1
# -1.8784032029609778e9
# -8.401071302860451e25
# -1.1089726996095221e43
# -2.134285418196705e60
# -4.314418943294794e77
# -8.76890712758781e94
# -1.7835251743719702e112
# -3.6279960099309237e129
# -7.380157835402002e146

```

I would expect the amplitude of the middle element to decrease over time, not increase.

How am I holding it wrong?

---

<div class="post-metadata">

**Author:** ![Maucejo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maucejo/32/39090_2.png) [@Maucejo](https://discourse.julialang.org/u/Maucejo)\
**Post date:** [December 14, 2025, 12:09pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/7 "2025-12-14T12:09:15Z")

</div>

@tp2750 I will check that tomorrow but I noticed that you only check the solution over the first 0.1 s. Did you plot the solution over the whole duration ?

---

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [December 14, 2025, 12:23pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/8 "2025-12-14T12:23:07Z")

</div>

Thanks @Maucejo . Yes, I plotted the full time trajectory and it is all NaN after about 0.5 sec or so.

---

<div class="post-metadata">

**Author:** ![Maucejo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maucejo/32/39090_2.png) [@Maucejo](https://discourse.julialang.org/u/Maucejo)\
**Post date:** [December 14, 2025, 12:49pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/9 "2025-12-14T12:49:09Z")

</div>

I quickly checked. It seems that there are some instabilities. I have to admit that I don’t know why at the moment…

---

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [December 14, 2025, 12:52pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/10 "2025-12-14T12:52:53Z")

</div>

Thanks for checking @Maucejo . I wanted to try and generate sound from the models to hear if the string sounds like a string. It’s not urgent, but I’ll be happy to learn how to do it correctly. I would love to try to do some “physical modeling” sound synthesis based on this.

I also tried the other models (rod, bar, beam) and the state space solvers. I got instabilities like this in all cases. But the examples in the documentation work (of course).

---

<div class="post-metadata">

**Author:** ![Maucejo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maucejo/32/39090_2.png) [@Maucejo](https://discourse.julialang.org/u/Maucejo)\
**Post date:** [December 14, 2025, 1:51pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/11 "2025-12-14T13:51:12Z")

</div>

The problem is probably related to the choice of the timestep. When you have a fixed time step, the choice is related to the critical time step which depends on the numerical scheme considered. When using finite element modeling it is related to the eigenvalues of the smallest element in the mesh.

As an alternative, you can use a modal solver, e.g. `FreeModalTimeProblem`, which is based on analytical formula or try to construct the state space matrices from the FE matrices and use it `DifferentialEquations.jl` which use adaptive time stepping.

That being said, I will check the construction of the FE matrices and make an example in the documentation using FE matrices.

---

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [December 14, 2025, 2:32pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/12 "2025-12-14T14:32:46Z")

</div>

Thanks for you help @Maucejo . An example in the documentation would be great!

---

<div class="post-metadata">

**Author:** ![Maucejo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maucejo/32/39090_2.png) [@Maucejo](https://discourse.julialang.org/u/Maucejo)\
**Post date:** [December 16, 2025, 3:00pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/13 "2025-12-16T15:00:13Z")

</div>

I have updated the documentation to include an example using DifferentialEquations.jl. I also fixed a bug in the `solve` function for the Newmark family. You can update the package to v1.4.

---

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [December 16, 2025, 4:06pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/14 "2025-12-16T16:06:17Z")

</div>

Thanks a lot @Maucejo .  
Looking forward to [reading](https://maucejo.github.io/StructuralVibration.jl/solvers/direct_time_solvers.html#differentialequations.jl-solvers) and [testing](https://github.com/maucejo/StructuralVibration.jl/blob/main/test/solvers/test_solver_fe.jl) 😄

And thank you for a great package with excellent documentation!

---

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [December 20, 2025, 5:19pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/15 "2025-12-20T17:19:32Z")

</div>

Now I can simulate my sting 😄  
However, I get a lot more damping than I would expect 🤔

I found parameters for a guitar string in [https://www.eurecom.fr/publication/8193/download/sec-publi-8193.pdf](https://www.eurecom.fr/publication/8193/download/sec-publi-8193.pdf)

Parameters for a nylon string B3 (247 Hz)

- L = 0.65 m
- µ = 0.000582 kg m−1
- T = 60 N
- Diameter: d = 0.69 mm = 6.9 × 10−4m

`modefreq` agrees:

```julia-auto
using StructuralVibration

L = .65
d = 6.9E-4
# Section features
S = π*d^2/4
# Tension for string
T = 60.
# Material
ρ = 0.000582/S

modefreq(Strings(L, S, T, ρ), 1000.)[1]/2pi
# 4-element Vector{Float64}:
# 246.98511502612902
# 493.97023005225805
# 740.9553450783872
# 987.9404601045161

```

It can also be solved now (takes about a sec):

```julia-auto
"""
   Pick a structure. Solve using generalized alpha method
"""
function pick_ga(m; d = 1E-3, bc = :CC, elements = 20)
    oned_mesh = OneDMesh(m, 0., elements, bc)
    
    # Construction of K and M
    Kfe, Mfe = assembly(m, oned_mesh)
    
    # Application of the BCs
    Kbc = apply_bc(Kfe, oned_mesh)
    Mbc = apply_bc(Mfe, oned_mesh)
    nddl = size(Kbc, 1)
    
    # Calculation of the damping matrix
    Cbc = rayleigh_damping_matrix(Kbc, Mbc, 1e-4, 5e-4)
    
    # 4.2 Problem solution
    # Time vector
    t = 0.:1e-5:1.
        nt = length(t)
    
    # Initial conditions
    x0 = d*ones(nddl)
    # x0 = zeros(nddl) ## 1e-3ones(nddl)
    # x0[div(nddl,2)] = d # pick middle element
    v0 = zeros(nddl)
    u0 = (x0, v0)
    
    # Direct time problem - Generalized-alpha method
    prob = DirectTimeProblem(Kbc, Mbc, Cbc, u0, t)
    (; t, res=solve(prob)) 
end

t,s1 = pick_ga(Strings(L, S, T, ρ); d=1E-2) 

# (t = 0.0:1.0e-5:1.0, res = StructuralVibration.DirectTimeSolution{Float64}
# u: 19×100001 Matrix{Float64} [0.01, 0.01, 0.01, 0.01, 0.01]...
# du: 19×100001 Matrix{Float64} [0.0, 0.0, 0.0, 0.0, 0.0]...
# ddu: 19×100001 Matrix{Float64} [-1.5691528380771137e6, 420453.2360393165, -112660.10608015256, 30187.18828129456, -8088.647045024554]...
# )

```

However, the “sound” dies very quickly (in about 20 ms):

```julia-auto
using Plots
plot(
    plot(t, s1.u[10,:], label="y(t) Element 10"),
    plot(t[100:5000], s1.u[19,100:5000], label="y(t) e 10 @ (0.01-0.05s)"),
    plot([s1.u[:,400] s1.u[:,600]], label=["0.004s" "0.006s"]),
    layout=(3,1)
)

```

 ![s247](https://global.discourse-cdn.com/julialang/original/3X/2/5/254940276cbae39fb3d2921779861aeaac9b8eda.png)

I thought it might be a discretization problem, but I get exactly the same using 100 elements (takes 20 sec to run)

```julia-auto
t,s100 = pick_ga(Strings(L, S, T, ρ); d=1E-2, bc = :CC, elements = 100)
plot(
    plot(t, s100.u[50,:], label="y(t) Element 50"),
    plot(t[100:5000], s100.u[50,100:5000], label="y(t) e 50 @ (0.01-0.05s)"),
    plot([s100.u[:,400] s100.u[:,600]], label=["0.004s" "0.006s"]),
    layout=(3,1)
)

```

 ![s247-100](https://global.discourse-cdn.com/julialang/original/3X/f/1/f125416474e885cd49f84016f439ad294be9bc05.png)

Is this as expected?

---

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [December 20, 2025, 5:44pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/16 "2025-12-20T17:44:14Z")

</div>

Oh, It’s the damping of course.

> [@tp2750](#):
>
> `Cbc = rayleigh_damping_matrix(Kbc, Mbc, 1e-4, 5e-4)`

Any idea what that should be for a guitar string?

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [December 20, 2025, 6:52pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/17 "2025-12-20T18:52:47Z")

</div>

Any guitar string will be damped. Just mess with the constants till you get something you like.

---

<div class="post-metadata">

**Author:** ![Maucejo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maucejo/32/39090_2.png) [@Maucejo](https://discourse.julialang.org/u/Maucejo)\
**Post date:** [December 20, 2025, 7:35pm UTC](https://discourse.julialang.org/t/ann-structuralvibration-jl/127978/18 "2025-12-20T19:35:26Z")

</div>

The parameters I used for Rayleigh damping are completely random. The package allows to compute the coefficient alpha and beta given two resonance frequencies and the corresponding modal damping. Another possible approach is to use modal damping matrix using a low damping ratio.

It should however be mentioned that the string model is purely linear. In practice, I think that a nonlinear model will give you a more realistic result from a perceptual perspective.
