diff --git a/Project NGSolve/NETGEN_cooling_of_coffee_trimmed.mp4 b/Project NGSolve/NETGEN_cooling_of_coffee_trimmed.mp4 new file mode 100644 index 0000000..8cecd8f Binary files /dev/null and b/Project NGSolve/NETGEN_cooling_of_coffee_trimmed.mp4 differ diff --git a/Project NGSolve/q2_end_temp.png b/Project NGSolve/q2_end_temp.png new file mode 100644 index 0000000..9f68201 Binary files /dev/null and b/Project NGSolve/q2_end_temp.png differ diff --git a/Project NGSolve/q2_init_temp.png b/Project NGSolve/q2_init_temp.png new file mode 100644 index 0000000..f1aed65 Binary files /dev/null and b/Project NGSolve/q2_init_temp.png differ diff --git a/Project NGSolve/q2_time_temp.txt b/Project NGSolve/q2_time_temp.txt new file mode 100644 index 0000000..bee611a --- /dev/null +++ b/Project NGSolve/q2_time_temp.txt @@ -0,0 +1,39 @@ +Q2 with tau=2.5; theta = 0.5 +average temperature of the liquid (=coffee) for specific times + +time: 100.0; temperature: 81.388 +time: 200.0; temperature: 79.947 +time: 300.0; temperature: 78.664 +time: 400.0; temperature: 77.451 +time: 500.0; temperature: 76.282 +time: 600.0; temperature: 75.148 +time: 700.0; temperature: 74.042 +time: 800.0; temperature: 72.962 +time: 900.0; temperature: 71.905 +time: 1000.0; temperature: 70.870 +time: 1100.0; temperature: 69.855 +time: 1200.0; temperature: 68.861 +time: 1300.0; temperature: 67.886 +time: 1400.0; temperature: 66.930 +time: 1500.0; temperature: 65.993 +time: 1600.0; temperature: 65.074 +time: 1700.0; temperature: 64.172 +time: 1800.0; temperature: 63.288 +time: 1900.0; temperature: 62.421 +time: 2000.0; temperature: 61.570 +time: 2100.0; temperature: 60.736 +time: 2200.0; temperature: 59.918 +time: 2300.0; temperature: 59.115 +time: 2400.0; temperature: 58.328 +time: 2500.0; temperature: 57.555 +time: 2600.0; temperature: 56.798 +time: 2700.0; temperature: 56.055 +time: 2800.0; temperature: 55.326 +time: 2900.0; temperature: 54.611 +time: 3000.0; temperature: 53.910 +time: 3100.0; temperature: 53.223 +time: 3200.0; temperature: 52.548 +time: 3300.0; temperature: 51.887 +time: 3400.0; temperature: 51.238 +time: 3500.0; temperature: 50.601 +end-time: 3597.5; temperature: 49.993 diff --git a/Project NGSolve/scicomp_project.py b/Project NGSolve/scicomp_project.py new file mode 100644 index 0000000..b8586ca --- /dev/null +++ b/Project NGSolve/scicomp_project.py @@ -0,0 +1,311 @@ +# Scientific Computing and FEM +# Project C: mug simulation with ngsolve + + +from ngsolve import * +# from netgen.csg import * +from netgen.geom2d import SplineGeometry +import matplotlib.pyplot as plt +import time + +""" It's not possible to generate a 3D model of the mug. I tried several ways. +One can build the geometry and have a look on it. However, the computer is not able to generate a +mesh from it. It got stuck. Using the jupyterhub from university does not change the situation. +So we will continue solving this example in 2D instead of 3D. """ + +# # generating the mesh 3D +# geo = CSGeometry() + +# # parameter +# h = 105 # height +# r_bottom = 55 # radius bottom +# r_top = 83 # radius top +# thickness = 5 # thickness of cup +# fill_height = 66 + +# # outer cone (mug outside) +# outer = Cone(Pnt(0,0,0), Pnt(0,0,h), r_bottom, r_top) + +# # inner cone +# inner = Cone(Pnt(0,0,thickness), Pnt(0,0,h), r_bottom - thickness, r_top - thickness) + +# # ceramic (=difference) +# #cup = outer - inner + +# # cutting liquid / air +# cyl_liquid = Cylinder(Pnt(0,0,0), Pnt(0,0,fill_height), r_top+10) +# cyl_air = Cylinder(Pnt(0,0,fill_height), Pnt(0,0,h), r_top+10) + +# inside = inner +# # liquid (lower part) +# liquid = inside * cyl_liquid + +# # air (upper part) +# air = inside * cyl_air + +# cup = outer - (liquid + air) + +# # whole geometry + material +# geo.Add(cup.mat("ceramic")) +# geo.Add(liquid.mat("liquid")) +# geo.Add(air.mat("air")) + +# mesh = Mesh(geo.GenerateMesh(maxh=40.5)) +# print("Elements:", mesh.ne) + +# Draw(mesh, mesh.Materials()) +# geo.Draw() + +# ----------------------------------- + +# generating the 2D model and the corresponding mesh +geo = SplineGeometry() + +midpoint = 22+66/99*(83/2-25) +points_mm = [(25,0), (83/2,105), (-83/2,105), (-25,0), # outer points of ceramic + (22,6), (midpoint,72), (-midpoint,72), (-22,6), # points of liquid + (83/2-3,105), (-83/2+3,105)] # upper points of air +factor = 10**-3 # transformation from mm to m +points = [[x * factor, y * factor] for x, y in points_mm] + +p0,p1,p2,p3,p4,p5,p6,p7,p8,p9 = [geo.AppendPoint(*pnt) for pnt in points] + +curves = [[["line",p0,p1],"right",1,0], + [["line",p1,p8],"top_mug",1,0], + [["line",p8,p5],"rest",1,3], + [["line",p5,p4],"rest",1,2], + [["line",p4,p7],"rest",1,2], + [["line",p7,p6],"rest",1,2], + [["line",p6,p9],"rest",1,3], + [["line",p9,p2],"top_mug",1,0], + [["line",p2,p3],"left",1,0], + [["line",p3,p0],"bottom",1,0], + [["line",p5,p6],"rest",2,3], + [["line",p8,p9],"top_air",3,0]] + +for geom_part, name, left, right in curves: + if name != "rest": # only on the boundary we need a name for bc + geo.Append(geom_part, leftdomain=left, rightdomain=right, bc=name) + else: + geo.Append(geom_part, leftdomain=left, rightdomain=right) + +geo.SetMaterial (1, "ceramic") +geo.SetMaterial (2, "liquid") +geo.SetMaterial (3, "air") + +mesh = Mesh(geo.GenerateMesh(maxh=0.0007)) +#print (f"segments of the boundary: {mesh.GetBoundaries()}") +#print (f"name of the materials: {mesh.GetMaterials()}") + +#Draw(mesh) # plotting the mesh + +# printing the domains of the mug +print_domains = False +if print_domains == True: + cf = CoefficientFunction([ + 1 if mat=="ceramic" else + 2 if mat=="liquid" else + 3 if mat=="air" else 0 + for mat in mesh.GetMaterials() + ]) + + Draw(cf, mesh, "domains") + +# -------------------------------------- + +# defining the parameters +# heat storage capacity (J/(m^3*K)) +c_domain_values = {'ceramic': 1240*2.3*10**3, 'liquid': 4.138*10**6, 'air': 1.21*10**3} +c = mesh.MaterialCF(c_domain_values) +# thermal conductivity (W/(m*K)) +lam_domain_values = {'ceramic': 5, 'liquid': 0.6, 'air': 0.026} +lam = mesh.MaterialCF(lam_domain_values) +# heat transfer coefficient (W/(m^2*K)) +alpha = 8 +# outside temperature +u_out = 18 + +# ----------------------------------- + +# setting up the FEM +# H1-conforming finite element space +fes = H1(mesh, order=1, autoupdate=True) + +# define trial- and test-functions +u = fes.TrialFunction() +v = fes.TestFunction() + +# define the bilinear form (stiffness + Robin part) +a = BilinearForm(fes, symmetric=True) +a += (lam*grad(u)*grad(v))*dx +a += (alpha*u*v)*ds + +# define the bilinear form (mass) +m = BilinearForm(fes, symmetric=True) +m += c*u*v*dx + +# define the right-hand side (Robin part) +f = LinearForm(fes) +f += (alpha*u_out*v)*ds + +# assemble the system of linear equation +a.Assemble() +m.Assemble() +f.Assemble() +minv = m.mat.Inverse(fes.FreeDofs(), inverse="pardiso") + +# solution field +gfu = GridFunction(fes) + +# ------------------------------------ + +# stationary problem (no time aspect) +# gfu.vec.data = a.mat.Inverse(fes.FreeDofs(), inverse="pardiso")*f.vec.data +# Draw(gfu) + +# ----------------------------------- + +# functions that will be helpful + +# calculatin the average temperatur in a given subdomain +def mean_temp(gfu,mesh,domain): + temp_int = Integrate(gfu, mesh, definedon=mesh.Materials(domain)) + vol = Integrate(1, mesh, definedon=mesh.Materials(domain)) + + return temp_int/vol + +# ----------------------------------- + +# Q1 +run_Q1 = False + +if run_Q1 == True: + + # initial data for Q1 + init_u_liquid = 80 + init_u_domain_values = {'ceramic': u_out, 'liquid': init_u_liquid, 'air': u_out} + init_u = mesh.MaterialCF(init_u_domain_values) + gfu.Set(init_u) + Draw(gfu) + + time.sleep(7) + #Redraw(blocking=True) + + # setting up the FEM environment + time_max = 10*60 # breaking condition for simulation + tau = 0.5 # duration of 1 timestep + temp_opt = 67 + + theta = 0.5 # paramater for time discretization + # 0 (explicit Euler), 0.5 (Crank Nicolson scheme), 1 (implicit Euler) + + mstar = m.mat.CreateMatrix() + mstar.AsVector().data = m.mat.AsVector() + theta*tau*a.mat.AsVector() + mstarinv = mstar.Inverse(fes.FreeDofs(), inverse="pardiso") + r = gfu.vec.CreateVector() + + time_act = 0 # starting time =0 for loop condition + temp = 0 # here just for starting condition in while loop + data_q1 = [[time_act,u_out]] + + # calculating T_warm, temperature when ceramic has optimal temperature temp_opt + while temptemp_opt and time_act