Browse Source

Add exercise 4

master
nssc_kuen 3 months ago
parent
commit
392cc3fead
20 changed files with 61430 additions and 36 deletions
  1. +12
    -0
      Exercise_04/Parameters.jl
  2. +5
    -0
      Exercise_04/README
  3. +104
    -0
      Exercise_04/fem.jl
  4. +0
    -0
      Exercise_04/plots/.keep
  5. BIN
      Exercise_04/plots/baseline.png
  6. BIN
      Exercise_04/plots/variation1.png
  7. BIN
      Exercise_04/plots/variation2.png
  8. BIN
      Exercise_04/plots/variation3.png
  9. BIN
      Exercise_04/plots/variation4_div.png
  10. BIN
      Exercise_04/plots/variation4_mul.png
  11. +39
    -0
      Exercise_04/print_HTP.jl
  12. +0
    -36
      Exercise_04/print_HTP.py
  13. +94
    -0
      Exercise_04/run.jl
  14. +0
    -0
      Exercise_04/txt/.keep
  15. +10193
    -0
      Exercise_04/txt/htp_baseline.txt
  16. +10193
    -0
      Exercise_04/txt/htp_variation1.txt
  17. +10193
    -0
      Exercise_04/txt/htp_variation2.txt
  18. +10193
    -0
      Exercise_04/txt/htp_variation3.txt
  19. +10193
    -0
      Exercise_04/txt/htp_variation4_div.txt
  20. +10193
    -0
      Exercise_04/txt/htp_variation4_mul.txt

+ 12
- 0
Exercise_04/Parameters.jl View File

@@ -0,0 +1,12 @@
module Parameters
export k, hz, L, q, T, e, elₘ

k = 429.
hz = 0.0005
L = 0.01

q = 2000000.
T = 293.
c = 10.
elₘ = [41,42,43,44,45,46,47,59,60,61,62,63,77,78,79,95]
end

+ 5
- 0
Exercise_04/README View File

@@ -0,0 +1,5 @@
FEM solver

- programmed in julia
- run using `julia run.jl`
- this generates output txt files in ./txt/ and plots in ./plots/ for all 5 variants

+ 104
- 0
Exercise_04/fem.jl View File

@@ -0,0 +1,104 @@
module FEM
export Node, Element, stiffness, tri_tiles, gradient, center, normalize, p

include("./Parameters.jl")

using GeometryBasics
using GeometryBasics.LinearAlgebra

struct Node
x::Float64
y::Float64
index::UInt
end

p(n::Node) = Point2f(n.x, n.y)

struct Element
nodes::Vector{Node}
a::Vector{Float64}
b::Vector{Float64}
c::Vector{Float64}
Δ::Float64

function Element(n::Vector{Node})
xs = map(nd->nd.x,n)
ys = map(nd->nd.y,n)
a = cross(xs, ys)
b = cross(ys, ones(3))
c = cross(ones(3), xs)
Δ = dot(xs,b) / 2

new(n,a,b,c,Δ)
end
end

function stiffness(e::Element)::Matrix{Float64}
# tensor product
Hₑ = e.b .* e.b'
Hₑ += e.c .* e.c'
Hₑ *= Parameters.hz*Parameters.k/4e.Δ

return Hₑ
end

function tri_tiles(L::Float64, divisions::Int, trapezoidal::Bool=false, biased::Bool=false, ring::Bool=false)::Tuple{Vector{Node}, Vector{Element}}
nodes = Matrix{Node}(undef, divisions+1, divisions+1)
i = 1
for y in 0:divisions
for x in 0:divisions
xₑ = L*x/divisions
yₑ = L*y/divisions

if biased
B = yₑ/2Parameters.L
xₑ = xₑ*(xₑ*B/Parameters.L - B + 1)
end

if trapezoidal
xₑ *= 1 - 0.5*(y/divisions)
end

if ring
r = Parameters.L*(1 + x/divisions)
θ = (π/4)*(y/divisions)

xₑ = r*cos(θ)
yₑ = r*sin(θ)
xₑ -= Parameters.L
end

nodes[x+1,y+1] = Node(xₑ,yₑ,i)
i += 1
end
end

elements = []

for y in 1:divisions
for x in 1:divisions
# lower/upper triangle
push!(elements, Element([nodes[x,y], nodes[x+1,y], nodes[x,y+1]]))
push!(elements, Element([nodes[x+1,y+1], nodes[x,y+1], nodes[x+1,y]]))
end
end

return vec(nodes), elements
end

function gradient(e::Element, T::Vector{Float64})::Vec2f
return Vec2f([
e.b[1] e.b[2] e.b[3] ;
e.c[1] e.c[2] e.c[3]
] * [
T[e.nodes[1].index]
T[e.nodes[2].index]
T[e.nodes[3].index]
] / 2e.Δ)
end

center(e::Element)::Point2f = Point2f(sum([n.x for n in e.nodes])/3.0, sum([n.y for n in e.nodes])/3.0)
normalize(v::Vec2f)::Vec2f = v / sqrt(v[1]^2 + v[2]^2)

end

+ 0
- 0
Exercise_04/plots/.keep View File


BIN
Exercise_04/plots/baseline.png (Stored with Git LFS) View File

oid sha256:ebb1dfb91e09d7fe15f8d810287b854866a3cb6f6f093a1601e7424e983a2d2e
size 211782

BIN
Exercise_04/plots/variation1.png (Stored with Git LFS) View File

oid sha256:08e02d96b6ac9dfdb896701456074c3761edd5f8b5f6905d8b32c9ee543f9c70
size 274954

BIN
Exercise_04/plots/variation2.png (Stored with Git LFS) View File

oid sha256:5305a388953b71ef266fac0467bf6371c2fbc2f6616b3c16bf7ea57a7f28e154
size 241470

BIN
Exercise_04/plots/variation3.png (Stored with Git LFS) View File

oid sha256:43f0fd5f57de731aa3a3c060ba9600a20f9d5ce31fde627575e09442af9a52ce
size 280970

BIN
Exercise_04/plots/variation4_div.png (Stored with Git LFS) View File

oid sha256:2cc8c53423e1d539d0ff072e3d4e6aa9b1494d753191f2bba7ec6b02878eeeb2
size 326217

BIN
Exercise_04/plots/variation4_mul.png (Stored with Git LFS) View File

oid sha256:5d18fa50df65e05f7fcd8c1ff7b94d2cdc85921bbd6a055fa140382728ec27b9
size 337070

+ 39
- 0
Exercise_04/print_HTP.jl View File

@@ -0,0 +1,39 @@
using Fmt

function print_HTP(H::Matrix{Float64}, T::Vector{Float64}, P::Vector{Float64}, filename="output.txt")
# Print matrices to .txt-file (name of file = filename).
# H... overall assembled stiffness matrix
# T... nodal temperature vector
# P... nodal force vector

# Make sure, that your system of equations is sorted by
# ascending node numbers, i.e., N1 N2 ... N100.

open(filename, "w") do io
write(io, "Stiffness matrix H: \n")
for row in H
for col in row
outline = f"{$col:+8.4e},"
write(io, f"{$outline:11s}")
end
write(io, "\n")
end

write(io, "Temperature T: \n")
for row in T
for col in row
outline = f"{$col:+8.4e},"
write(io, f"{$outline:11s} \n")
end
end

write(io, "Force vector P: \n")
for row in P
for col in row
outline = f"{$col:+8.4e},"
write(io, f"{$outline:11s} \n")
end
end
end
end

+ 0
- 36
Exercise_04/print_HTP.py View File

@@ -1,36 +0,0 @@
def print_HTP(H, T, P, filename="output.txt"):
"""
Print matrices to .txt-file (name of file = filename).
H... overall assembled stiffness matrix
T... nodal temperature vector
P... nodal force vector

Make sure, that your system of equations is sorted by
ascending node numbers, i.e., N1 N2 ... N100.
"""

F = open(filename, 'w')

F.write("Stiffness matrix H: \n")
for row in H:
for col in row:
outline = "{0:+8.4e},".format(col)
F.write("{0:11s}".format(str(outline)))
F.write("\n")

F.write("Temperature T: \n")
for row in T:
for col in row:
outline = "{0:+8.4e},".format(col)
F.write("{0:11s} \n".format(str(outline)))


F.write("Force vector P: \n")
for row in P:
for col in row:
outline = "{0:+8.4e},".format(col)
F.write("{0:11s} \n".format(str(outline)))

F.close()

return None

+ 94
- 0
Exercise_04/run.jl View File

@@ -0,0 +1,94 @@
include("./fem.jl")
include("./Parameters.jl")
include("./print_HTP.jl")

using .FEM
using GLMakie
using Makie.GeometryBasics

@enum Variation BASIC V1 V2 V3 V4_div V4_mul

function solve(name::String, variation::Variation)
div = 9
H = zeros(Float64,(div+1)^2, (div+1)^2)

(nodes, elements) = tri_tiles(Parameters.L, div, variation==V1, variation==V2, variation==V3)
for (index, el) in enumerate(elements)
Hₑ = stiffness(el)

if variation == V4_div && index in Parameters.elₘ
Hₑ /= Parameters.c
elseif variation == V4_mul && index in Parameters.elₘ
Hₑ *= Parameters.c
end

for i in 1:3
for j in 1:3
H[el.nodes[i].index, el.nodes[j].index] += Hₑ[i,j]
end
end
end
P = zeros(Float64, 90)
# impose neumann conditions on top edge
# adapted from https://mathoverflow.net/questions/5085/how-to-apply-neuman-boundary-condition-to-finite-element-method-problems
# maybe check if this actually makes sense
nᵧ = -Parameters.q / Parameters.k
# skip=2 since only every second element has a edge along the bottom: ◺◹
for ∂_el in elements[1:2:18]
n1 = ∂_el.nodes[1]
n2 = ∂_el.nodes[2]
l = abs(n2.x - n1.x)
P[n1.index] += nᵧ*l/2
P[n2.index] += nᵧ*l/2
end
rhs = P - H[1:90,91:100]*fill(Parameters.T, 10,1)
T = vec(H[1:90,1:90]\rhs)
append!(T, fill(Parameters.T, 10))
reaction_forces = H[91:100,:]*T
centers = center.(elements)

gradients = map(el -> gradient(el, T), elements)
flux = gradients .* -1

norm = maximum(map(g-> sqrt(g[1]^2 + g[2]^2), gradients))/(Parameters.L/div)*2.5
gradients ./= norm
flux ./= norm
set_theme!(theme_black())
f = Figure(resolution = (1536, 1024))
tris = map(e->Polygon([p(e.nodes[1]), p(e.nodes[2]), p(e.nodes[3])]), elements)
poly(f[1, 1], tris, color=:transparent, linestyle=:solid, strokewidth=0.8, strokecolor=:white, transparency=true)

xs = map(n->n.x, nodes)
ys = map(n->n.y, nodes)

xs = reshape(xs, (div+1, div+1))
ys = reshape(ys, (div+1, div+1))
Ts = reshape(T, (div+1, div+1))

surface(f[2, 1], xs, ys, Ts, colormap=:matter, axis=(type=Axis3,))

contour(f[1:2,2:3], map(n->n.x,nodes), map(n->n.y,nodes), T, levels=16, colormap=:matter)
arrows!(f[1:2,2:3], centers, gradients, arrowcolor=:red, linecolor=:red)
arrows!(f[1:2,2:3], centers, flux, arrowcolor=:blue, linecolor=:blue)
save("plots/$name.png", current_figure())

print_HTP(H, T, P, "txt/htp_$name.txt")
end

solve("baseline", BASIC)
solve("variation1", V1)
solve("variation2", V2)
solve("variation3", V3)
solve("variation4_div", V4_div)
solve("variation4_mul", V4_mul)

+ 0
- 0
Exercise_04/txt/.keep View File


+ 10193
- 0
Exercise_04/txt/htp_baseline.txt
File diff suppressed because it is too large
View File


+ 10193
- 0
Exercise_04/txt/htp_variation1.txt
File diff suppressed because it is too large
View File


+ 10193
- 0
Exercise_04/txt/htp_variation2.txt
File diff suppressed because it is too large
View File


+ 10193
- 0
Exercise_04/txt/htp_variation3.txt
File diff suppressed because it is too large
View File


+ 10193
- 0
Exercise_04/txt/htp_variation4_div.txt
File diff suppressed because it is too large
View File


+ 10193
- 0
Exercise_04/txt/htp_variation4_mul.txt
File diff suppressed because it is too large
View File


Loading…
Cancel
Save