Skip to content

Instantly share code, notes, and snippets.

@alex-fu27
Last active March 4, 2025 08:08
Show Gist options
  • Save alex-fu27/f5b046e83bdb8d8f8e889c3d533b2923 to your computer and use it in GitHub Desktop.
Save alex-fu27/f5b046e83bdb8d8f8e889c3d533b2923 to your computer and use it in GitHub Desktop.
Periodic boundary conditions cant be applied because assembly changes sparsity pattern?
using Ferrite
function assemble_element!(Me :: Matrix, Ke::Matrix, cellvalues::CellValues, q :: Ferrite.Vec{2})
n_basefuncs = getnbasefunctions(cellvalues)
# Reset to 0
fill!(Me, 0)
fill!(Ke, 0)
# Loop over quadrature points
for q_point in 1:getnquadpoints(cellvalues)
# Get the quadrature weight
dΩ = getdetJdV(cellvalues, q_point)
# Loop over test shape functions
for i in 1:n_basefuncs
v = shape_value(cellvalues, q_point, i)
∇v = shape_gradient(cellvalues, q_point, i)
# Loop over trial shape functions
for j in 1:n_basefuncs
u = shape_value(cellvalues, q_point, j)
∇u = shape_gradient(cellvalues, q_point, j)
# Add contribution to Ke
Me[i, j] += u * v * dΩ
Ke[i, j] += (q ⋅ ∇u) * v * dΩ
end
end
end
return Me, Ke
end
function assemble_global!(cellvalues, dh, q::Ferrite.Vec{2})
n_basefns = getnbasefunctions(cellvalues)
M = allocate_matrix(dh)
K = allocate_matrix(dh)
Me = zeros(n_basefns, n_basefns)
Ke = zeros(n_basefns, n_basefns)
M_ass = start_assemble(M)
K_ass = start_assemble(K)
for cell in CellIterator(dh)
reinit!(cellvalues, cell)
assemble_element!(Me, Ke, cellvalues, q)
assemble!(M_ass, celldofs(cell), Me)
assemble!(K_ass, celldofs(cell), Ke)
end
return M, K
end
grid = generate_grid(Quadrilateral, (100, 1)) # 1d mesh didn't work
ip = Lagrange{RefQuadrilateral, 1}()
dh = DofHandler(grid)
add!(dh, :c, ip)
close!(dh)
cellvalues = CellValues(QuadratureRule{RefQuadrilateral}(2), ip)
ch = ConstraintHandler(dh)
mapping = collect_periodic_facets(grid, "left", "right", (x) -> x - Ferrite.Vec{2}((2.0, 0.0)))
pdbc = PeriodicDirichlet(:c, mapping, [1,])
add!(ch, pdbc)
close!(ch)
# this works
B = allocate_matrix(dh)
_ = get_rhs_data(ch, B)
apply!(B, ch)
# this doesnt
M, K = assemble_global!(cellvalues, dh, +Ferrite.Vec{2}((1.0, 0)))
Δt = 0.01
A = M .+ (Δt .* K)
rhs_data = get_rhs_data(ch, A)
apply!(A, ch)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment