def demo16(self, permeability, obs_case=1): """This demo program solves the mixed formulation of Poisson's equation: sigma + grad(u) = 0 in Omega div(sigma) = f in Omega du/dn = g on Gamma_N u = u_D on Gamma_D The corresponding weak (variational problem) <sigma, tau> + <grad(u), tau> = 0 for all tau - <sigma, grad(v)> = <f, v> + <g, v> for all v is solved using DRT (Discontinuous Raviart-Thomas) elements of degree k for (sigma, tau) and CG (Lagrange) elements of degree k + 1 for (u, v) for k >= 1. """ mesh = UnitSquareMesh(15, 15) ak_values = permeability flux_order = 1 s = scenarios.darcy_problem_1() DRT = fenics.FiniteElement("DRT", mesh.ufl_cell(), flux_order) # Lagrange CG = fenics.FiniteElement("CG", mesh.ufl_cell(), flux_order + 1) if s.integral_constraint: # From https://fenicsproject.org/qa/14184/how-to-solve-linear-system-with-constaint R = fenics.FiniteElement("R", mesh.ufl_cell(), 0) W = fenics.FunctionSpace(mesh, fenics.MixedElement([DRT, CG, R])) # Define trial and test functions (sigma, u, r) = fenics.TrialFunctions(W) (tau, v, r_) = fenics.TestFunctions(W) else: W = fenics.FunctionSpace(mesh, DRT * CG) # Define trial and test functions (sigma, u) = fenics.TrialFunctions(W) (tau, v) = fenics.TestFunctions(W) f = s.source_function g = s.g # Define property field function W_CG = fenics.FunctionSpace(mesh, "Lagrange", 1) if s.ak is None: ak = property_field.get_conductivity(W_CG, ak_values) else: ak = s.ak # Define variational form a = (fenics.dot(sigma, tau) + fenics.dot(ak * fenics.grad(u), tau) + fenics.dot(sigma, fenics.grad(v))) * fenics.dx L = -f * v * fenics.dx + g * v * fenics.ds # L = 0 if s.integral_constraint: # Lagrange multiplier? See above link. a += r_ * u * fenics.dx + v * r * fenics.dx # Define Dirichlet BC bc = fenics.DirichletBC(W.sub(1), s.dirichlet_bc, s.gamma_dirichlet) # Compute solution w = fenics.Function(W) fenics.solve(a == L, w, bc) # fenics.solve(a == L, w) if s.integral_constraint: (sigma, u, r) = w.split() else: (sigma, u) = w.split() x = u.compute_vertex_values(mesh) x2 = sigma.compute_vertex_values(mesh) p = x pre = p.reshape((16, 16)) if obs_case == 1: dd = np.zeros([8, 8]) pos = np.full((8 * 8, 2), 0) col = [1, 3, 5, 7, 9, 11, 13, 15] position = [1, 3, 5, 7, 9, 11, 13, 15] for i in range(8): for j in range(8): row = position pos[8 * i + j, :] = [col[i], row[j]] dd[i, j] = pre[col[i], row[j]] like = dd.reshape(8 * 8, ) return like, pre, ak_values, pos
def demo32(self, permeability, obs_case=1): mesh = UnitSquareMesh(31, 31) ak_values = permeability flux_order = 3 s = scenarios.darcy_problem_1() DRT = fenics.FiniteElement("DRT", mesh.ufl_cell(), flux_order) # Lagrange CG = fenics.FiniteElement("CG", mesh.ufl_cell(), flux_order + 1) if s.integral_constraint: # From https://fenicsproject.org/qa/14184/how-to-solve-linear-system-with-constaint R = fenics.FiniteElement("R", mesh.ufl_cell(), 0) W = fenics.FunctionSpace(mesh, fenics.MixedElement([DRT, CG, R])) # Define trial and test functions (sigma, u, r) = fenics.TrialFunctions(W) (tau, v, r_) = fenics.TestFunctions(W) else: W = fenics.FunctionSpace(mesh, DRT * CG) # Define trial and test functions (sigma, u) = fenics.TrialFunctions(W) (tau, v) = fenics.TestFunctions(W) f = s.source_function g = s.g # Define property field function W_CG = fenics.FunctionSpace(mesh, "Lagrange", 1) if s.ak is None: ak = property_field.get_conductivity(W_CG, ak_values) else: ak = s.ak # Define variational form a = (fenics.dot(sigma, tau) + fenics.dot(ak * fenics.grad(u), tau) + fenics.dot(sigma, fenics.grad(v))) * fenics.dx L = -f * v * fenics.dx + g * v * fenics.ds # L = 0 if s.integral_constraint: # Lagrange multiplier? See above link. a += r_ * u * fenics.dx + v * r * fenics.dx # Define Dirichlet BC bc = fenics.DirichletBC(W.sub(1), s.dirichlet_bc, s.gamma_dirichlet) # Compute solution w = fenics.Function(W) fenics.solve(a == L, w, bc) # fenics.solve(a == L, w) if s.integral_constraint: (sigma, u, r) = w.split() else: (sigma, u) = w.split() x = u.compute_vertex_values(mesh) x2 = sigma.compute_vertex_values(mesh) p = x pre = p.reshape((32, 32)) vx = x2[:1024].reshape((32, 32)) vy = x2[1024:].reshape((32, 32)) if obs_case == 1: dd = np.zeros([8, 8]) pos = np.full((8 * 8, 2), 0) col = [2, 6, 10, 14, 18, 22, 26, 30] position = [2, 6, 10, 14, 18, 22, 26, 30] for i in range(8): for j in range(8): row = position pos[8 * i + j, :] = [col[i], row[j]] dd[i, j] = pre[col[i], row[j]] like = dd.reshape(8 * 8, ) return like, pre, vx, vy, ak_values, pos
def navierStokes(projectId, mesh, faceSets, boundarySets, config): log("Navier Stokes Analysis has started") # this is the default directory, when user request for download all files in this directory is being compressed and sent to the user resultDir = "./Results/" if len(config["steps"]) > 1: return "more than 1 step is not supported yet" # config is a dictionary containing all the user inputs for solver configurations t_init = 0.0 t_final = float(config['steps'][0]["finalTime"]) t_num = int(config['steps'][0]["iterationNo"]) dt = ((t_final - t_init) / t_num) t = t_init # # Viscosity coefficient. # nu = float(config['materials'][0]["viscosity"]) rho = float(config['materials'][0]["density"]) # # Declare Finite Element Spaces # do not use triangle directly P2 = fn.VectorElement("P", mesh.ufl_cell(), 2) P1 = fn.FiniteElement("P", mesh.ufl_cell(), 1) TH = fn.MixedElement([P2, P1]) V = fn.VectorFunctionSpace(mesh, "P", 2) Q = fn.FunctionSpace(mesh, "P", 1) W = fn.FunctionSpace(mesh, TH) # # Declare Finite Element Functions # (u, p) = fn.TrialFunctions(W) (v, q) = fn.TestFunctions(W) w = fn.Function(W) u0 = fn.Function(V) p0 = fn.Function(Q) # # Macros needed for weak formulation. # def contract(u, v): return fn.inner(fn.nabla_grad(u), fn.nabla_grad(v)) def b(u, v, w): return 0.5 * (fn.inner(fn.dot(u, fn.nabla_grad(v)), w) - fn.inner(fn.dot(u, fn.nabla_grad(w)), v)) # Define boundaries bcs = [] for BC in config['BCs']: if BC["boundaryType"] == "wall": for edge in json.loads(BC["edges"]): bcs.append( fn.DirichletBC(W.sub(0), fn.Constant((0.0, 0.0, 0.0)), boundarySets, int(edge), method='topological')) if BC["boundaryType"] == "inlet": vel = json.loads(BC['value']) for edge in json.loads(BC["edges"]): bcs.append( fn.DirichletBC(W.sub(0), fn.Expression( (str(vel[0]), str(vel[1]), str(vel[2])), degree=2), boundarySets, int(edge), method='topological')) if BC["boundaryType"] == "outlet": for edge in json.loads(BC["edges"]): bcs.append( fn.DirichletBC(W.sub(1), fn.Constant(float(BC['value'])), boundarySets, int(edge), method='topological')) f = fn.Constant((0.0, 0.0, 0.0)) # weak form NSE NSE = (1.0/dt)*fn.inner(u, v)*fn.dx + b(u0, u, v)*fn.dx + nu * \ contract(u, v)*fn.dx - fn.div(v)*p*fn.dx + q*fn.div(u)*fn.dx LNSE = fn.inner(f, v) * fn.dx + (1. / dt) * fn.inner(u0, v) * fn.dx velocity_file = fn.XDMFFile(resultDir + "/vel.xdmf") pressure_file = fn.XDMFFile(resultDir + "/pressure.xdmf") velocity_file.parameters["flush_output"] = True velocity_file.parameters["functions_share_mesh"] = True pressure_file.parameters["flush_output"] = True pressure_file.parameters["functions_share_mesh"] = True # # code for projecting a boundary condition into a file for visualization # # for bc in bcs: # bc.apply(w.vector()) # fn.File("para_plotting/bc.pvd") << w.sub(0) for jj in range(0, t_num): t = t + dt # print('t = ' + str(t)) A, b = fn.assemble_system(NSE, LNSE, bcs) fn.solve(A, w.vector(), b) # fn.solve(NSE==LNSE,w,bcs) fn.assign(u0, w.sub(0)) fn.assign(p0, w.sub(1)) # Save Solutions to Paraview File if (jj % 20 == 0): velocity_file.write(u0, t) pressure_file.write(p0, t) sendFile(projectId, resultDir + "vel.xdmf") sendFile(projectId, resultDir + "vel.h5") sendFile(projectId, resultDir + "pressure.xdmf") sendFile(projectId, resultDir + "pressure.h5") statusUpdate(projectId, "STARTED", {"progress": jj / t_num * 100})
mesh = fn.RectangleMesh(fn.Point(-width / 2, 0.0), fn.Point(width / 2, height), 52, 39) # 52 * 0.75 = 39, elements are square nn = fn.FacetNormal(mesh) # Defintion of function spaces Vh = fn.VectorElement("CG", mesh.ufl_cell(), 2) Zh = fn.FiniteElement("CG", mesh.ufl_cell(), 1) Qh = fn.FiniteElement("CG", mesh.ufl_cell(), 2) # spaces for displacement and total pressure should be compatible # whereas the space for fluid pressure can be "anything". In particular the one for total pressure Hh = fn.FunctionSpace(mesh, fn.MixedElement([Vh, Zh, Qh])) (u, phi, p) = fn.TrialFunctions(Hh) (v, psi, q) = fn.TestFunctions(Hh) fileU = fn.File(mesh.mpi_comm(), "Output/2_5_1_Footing_wall_removed/u.pvd") filePHI = fn.File(mesh.mpi_comm(), "Output/2_5_1_Footing_wall_removed/phi.pvd") fileP = fn.File(mesh.mpi_comm(), "Output/2_5_1_Footing_wall_removed/p.pvd") # ******** Model constants ********** # E = 3.0e4 nu = 0.4995 lmbda = E * nu / ((1. + nu) * (1. - 2. * nu)) mu = E / (2. * (1. + nu)) c0 = 1.0e-3 kappa = 1.0e-6 alpha = 0.1
fileE = fn.File("Output/1_4_Karma/E.pvd") filen = fn.File("Output/1_4_Karma/n.pvd") t = 0.0; dt = 0.3; Tfinal = 600.0; frequency = 100; # mesh L = 6.72; nps = 64; mesh = fn.RectangleMesh(fn.Point(0, 0), fn.Point(L, L), nps, nps, "crossed") # element and function spaces Mhe = fn.FiniteElement("CG", mesh.ufl_cell(), 1) Mh = fn.FunctionSpace(mesh, Mhe) Nh = fn.FunctionSpace(mesh, fn.MixedElement([Mhe,Mhe])) # trial and test functions v, n = fn.TrialFunctions(Nh) w, m = fn.TestFunctions(Nh) # solution Ksol = fn.Function(Nh) # model constants diffScale = fn.Constant(1e-3) D0 = 1.1 * diffScale tauv = fn.Constant(2.5) taun = fn.Constant(250.0) Re = fn.Constant(1.0) M = fn.Constant(5.0) beta = fn.Constant(0.008) vstar = fn.Constant(1.5415) vh = fn.Constant(3.0)
Qh = fn.FiniteElement("CG", mesh.ufl_cell(), 2) Mh = fn.FiniteElement("CG", mesh.ufl_cell(), 1) Wh = fn.TensorElement("CG", mesh.ufl_cell(), 1) # function spaces Vhf = fn.FunctionSpace(mesh, Vh) Zhf = fn.FunctionSpace(mesh, Zh) Qhf = fn.FunctionSpace(mesh, Qh) Mhf = fn.FunctionSpace(mesh, Mh) Whf = fn.FunctionSpace(mesh, Wh) Hh = fn.FunctionSpace(mesh, fn.MixedElement([Vh,Zh,Qh])) Nh = fn.FunctionSpace(mesh, fn.MixedElement([Mh, Mh])) # functions and test functions u, phi, p = fn.TrialFunctions(Hh) v, psi, q = fn.TestFunctions(Hh) E, n = fn.TrialFunctions(Nh) F, m = fn.TestFunctions(Nh) # pvd files pvdU = fn.File(mesh.mpi_comm(), "Output/3_Combined_models/u.pvd") pvdPHI = fn.File(mesh.mpi_comm(), "Output/3_Combined_models/phi.pvd") pvdP = fn.File(mesh.mpi_comm(), "Output/3_Combined_models/p.pvd") pvdE = fn.File(mesh.mpi_comm(), "Output/3_Combined_models/E.pvd") pvdN = fn.File(mesh.mpi_comm(), "Output/3_Combined_models/n.pvd") # constants for poroelasticity model (taken from footing-scaled-BCs.py) EE = fn.Constant(3.0e4) nu = fn.Constant(0.4995)
fn.parameters["form_compiler"]["cpp_optimize"] = True # mesh setup nps = 64 # number of points mesh = fn.UnitSquareMesh(nps, nps) fileu = fn.File(mesh.mpi_comm(), "Output/1_3_Schnackenberg/u.pvd") filev = fn.File(mesh.mpi_comm(), "Output/1_3_Schnackenberg/v.pvd") # function spaces P1 = fn.FiniteElement("Lagrange", mesh.ufl_cell(), 1) Mh = fn.FunctionSpace(mesh, "Lagrange", 1) Nh = fn.FunctionSpace(mesh, fn.MixedElement([P1, P1])) Sol = fn.Function(Nh) # trial and test functions u, v = fn.TrialFunctions(Nh) uT, vT = fn.TestFunctions(Nh) # model constants a = fn.Constant(0.1305) b = fn.Constant(0.7695) c1 = fn.Constant(0.05) c2 = fn.Constant(1.0) d = fn.Constant(170.0) # initial value uinit = fn.Expression('a + b + 0.001 * exp(-100.0 * (pow(x[0] - 1.0/3, 2)' + ' + pow(x[1] - 0.5, 2)))', a=a, b=b, degree=3)
def monolithic_solve(self): self.U = fe.VectorElement('CG', self.mesh.ufl_cell(), 1) self.W = fe.FiniteElement("CG", self.mesh.ufl_cell(), 1) self.M = fe.FunctionSpace(self.mesh, self.U * self.W) self.WW = fe.FunctionSpace(self.mesh, 'DG', 0) m_test = fe.TestFunctions(self.M) m_delta = fe.TrialFunctions(self.M) m_new = fe.Function(self.M) self.eta, self.zeta = m_test self.x_new, self.d_new = fe.split(m_new) self.H_old = fe.Function(self.WW) vtkfile_u = fe.File('data/pvd/{}/u.pvd'.format(self.case_name)) vtkfile_d = fe.File('data/pvd/{}/d.pvd'.format(self.case_name)) self.build_weak_form_monolithic() dG = fe.derivative(self.G, m_new) self.set_bcs_monolithic() p = fe.NonlinearVariationalProblem(self.G, m_new, self.BC, dG) solver = fe.NonlinearVariationalSolver(p) for i, (disp, rp) in enumerate( zip(self.displacements, self.relaxation_parameters)): print('\n') print( '=================================================================================' ) print('>> Step {}, disp boundary condition = {} [mm]'.format( i, disp)) print( '=================================================================================' ) self.H_old.assign( fe.project( history(self.H_old, self.psi(strain(fe.grad(self.x_new))), self.psi_cr), self.WW)) self.presLoad.t = disp newton_prm = solver.parameters['newton_solver'] newton_prm['maximum_iterations'] = 100 newton_prm['absolute_tolerance'] = 1e-4 newton_prm['relaxation_parameter'] = rp solver.solve() self.x_plot, self.d_plot = m_new.split() self.x_plot.rename("u", "u") self.d_plot.rename("d", "d") vtkfile_u << self.x_plot vtkfile_d << self.d_plot force_upper = float(fe.assemble(self.sigma[1, 1] * self.ds(1))) print("Force upper {}".format(force_upper)) self.delta_u_recorded.append(disp) self.sigma_recorded.append(force_upper) print( '=================================================================================' )
# -- Spatial domain ne = 2**7 L = 15 mesh = fe.IntervalMesh(int(ne),0,L) degQ = 1 degA = 1 QE = fe.FiniteElement("Lagrange", cell=mesh.ufl_cell(), degree=degQ) AE = fe.FiniteElement("Lagrange", cell=mesh.ufl_cell(), degree=degA) ME = fe.MixedElement([AE,QE]) V = fe.FunctionSpace(mesh,ME) V_A = V.sub(0) V_Q = V.sub(1) (v1,v2) = fe.TestFunctions(V) dv1 = fe.grad(v1)[0] dv2 = fe.grad(v2)[0] (u1,u2) = fe.TrialFunctions(V) U0 = fe.Function(V) U0.assign( fe.Expression( ( 'A0', 'Q0' ) , A0=A0, Q0=Q0, degree=1 ) ) Un = fe.Function(V) Un.assign( fe.Expression( ( 'A0', 'Q0' ) , A0=A0, Q0=Q0, degree=1 ) ) (u01,u02) = fe.split(U0) (un1,un2) = fe.split(Un) du01 = fe.grad(u01)[0] ; du02 = fe.grad(u02)[0] dun1 = fe.grad(un1)[0] ; dun2 = fe.grad(un2)[0] B0 = getB(u01,u02) H0 = getH(u01,u02) HdUdz0 = matMult(H0,[du01, du02]) Bn = getB(un1,un2) Hn = getH(un1,un2)
def half_exp_dyn(w0, dt=1.e-5, t_end=1.e-4, show_plots=False): u0 = w0.u p0 = w0.p v0 = w0.v bcs_u, bcs_p, bcs_v = load_2d_muscle_bc(V_u, V_pv.sub(0), V_pv.sub(1), boundaries) F = deformation_grad(u0) I_1, I_2, J = invariants(F) F_iso = isochronic_deformation_grad(F, J) #I_1_iso, I_2_iso = invariants(F_iso)[0:2] W = material_mooney_rivlin(I_1, I_2, c_10, c_01) g = incompr_constr(J) # Lagrange function (without constraint) L = -W P = first_piola_stress(L, F) G = incompr_stress(g, F) # a_dyn_u = inner(u1 - u0, eta) * dx - dt * inner(v1, eta) * dx u1 = fe.TrialFunction(V_u) eta = fe.TestFunction(V_u) #u11 = fe.Function(V_u) #F1 = deformation_grad(u11) #g1 = incompr_constr(fe.det(F1)) #G1 = incompr_stress(g1, F1) (p1, v1) = fe.TrialFunctions(V_pv) (q, xi) = fe.TestFunctions(V_pv) a_dyn_u = inner(u1 - u0, eta) * dx - dt * inner(v0, eta) * dx a_dyn_p = fe.tr(G * grad(v1)) * q * dx #a_dyn_v = rho*inner(v1-v0, xi)*dx + dt*(inner(P + p0*G, grad(xi))*dx - inner(B, xi)*dx) a_dyn_v = rho * inner(v1 - v0, xi) * dx + dt * (inner( P, grad(xi)) * dx + inner(p1 * G, grad(xi)) * dx - inner(B, xi) * dx) a_u = fe.lhs(a_dyn_u) l_u = fe.rhs(a_dyn_u) a_pv = fe.lhs(a_dyn_p + a_dyn_v) l_pv = fe.rhs(a_dyn_p + a_dyn_v) u1 = fe.Function(V_u) pv1 = fe.Function(V_pv) sol = [] vol = fe.assemble(1. * dx) A_u = fe.assemble(a_u) A_pv = fe.assemble(a_pv) for bc in bcs_u: bc.apply(A_u) t = 0 while t < t_end: print("progress: %f" % (100. * t / t_end)) # update displacement u L_u = fe.assemble(l_u) fe.solve(A_u, u1.vector(), L_u) u0.assign(u1) L_pv = fe.assemble(l_pv) for bc in bcs_p + bcs_v: bc.apply(A_pv, L_pv) fe.solve(A_pv, pv1.vector(), L_pv) if fe.norm(pv1.vector()) > 1e8: print('ERROR: norm explosion') break # update initial values for next step w0.u = u1 w0.pv = pv1 p0.assign(w0.p) v0.assign(w0.v) t += dt if show_plots: # plot result fe.plot(w0.sub(0), mode='displacement') plt.show() # save solutions sol.append(Solution(t=t)) sol[-1].upv.assign(w0) return sol, W
def explicit_relax_dyn(w0, kappa=1e5, dt=1.e-5, t_end=1.e-4, show_plots=False): (u0, p0, v0) = fe.split(w0) bcs_u, bcs_p, bcs_v = load_2d_muscle_bc(V_upv.sub(0), V_upv.sub(1), V_upv.sub(2), boundaries) kappa = fe.Constant(kappa) F = deformation_grad(u0) I_1, I_2, J = invariants(F) F_iso = isochronic_deformation_grad(F, J) #I_1_iso, I_2_iso = invariants(F_iso)[0:2] W = material_mooney_rivlin(I_1, I_2, c_10, c_01) + incompr_relaxation( p0, kappa) g = incompr_constr(J) # Lagrange function (without constraint) L = -W P = first_piola_stress(L, F) G = incompr_stress(g, F) (u1, p1, v1) = fe.TrialFunctions(V_upv) (eta, q, xi) = fe.TestFunctions(V_upv) a_dyn_u = inner(u1 - u0, eta) * dx - dt * inner(v1, eta) * dx a_dyn_p = (p1 - p0) * q * dx - dt * kappa * div(v1) * J * q * dx #a_dyn_v = rho*inner(v1-v0, xi)*dx + dt*(inner(P + p0*G, grad(xi))*dx - inner(B, xi)*dx) a_dyn_v = rho * inner(v1 - v0, xi) * dx + dt * (inner( P, grad(xi)) * dx + inner(p0 * G, grad(xi)) * dx - inner(B, xi) * dx) a = fe.lhs(a_dyn_u + a_dyn_p + a_dyn_v) l = fe.rhs(a_dyn_u + a_dyn_p + a_dyn_v) w1 = fe.Function(V_upv) w2 = fe.Function(V_upv) sol = [] vol = fe.assemble(1. * dx) t = 0 while t < t_end: print("progress: %f" % (100. * t / t_end)) A = fe.assemble(a) L = fe.assemble(l) for bc in bcs_u + bcs_p + bcs_v: bc.apply(A, L) fe.solve(A, w1.vector(), L) if fe.norm(w1.vector()) > 1e7: print('ERROR: norm explosion') break # update initial values for next step w0.assign(w1) t += dt if show_plots: # plot result fe.plot(w0.sub(0), mode='displacement') plt.show() # save solutions sol.append(Solution(t=t)) sol[-1].upv.assign(w0) return sol, W, kappa