def run(self): domain = self._create_domain() mesh = generate_mesh(domain, MESH_PTS) # fe.plot(mesh) # plt.show() self._create_boundary_expression() Omega = fe.FiniteElement("Lagrange", mesh.ufl_cell(), 1) R = fe.FiniteElement("Real", mesh.ufl_cell(), 0) W = fe.FunctionSpace(mesh, Omega*R) Theta, c = fe.TrialFunction(W) v, d = fe.TestFunctions(W) sigma = self.conductivity LHS = (sigma * fe.inner(fe.grad(Theta), fe.grad(v)) + c*v + Theta*d) * fe.dx RHS = self.boundary_exp * v * fe.ds w = fe.Function(W) fe.solve(LHS == RHS, w) Theta, c = w.split() print(c(0, 0)) # fe.plot(Theta, "solution", mode='color', vmin=-3, vmax=3) # plt.show() plot(fe.interpolate(Theta, fe.FunctionSpace(mesh, Omega)), mode='color') plt.show()
def initWeakFormulation(): """Define function spaces etc. to initialize weak formulation.""" P = fe.FiniteElement('P', mesh.ufl_cell(), 1) V = fe.FunctionSpace(mesh, 'P', 1) auxP = [] for k in range(nEvenMoments): auxP.append(P) VVec = fe.FunctionSpace(mesh, fe.MixedElement(auxP)) auxV = [] for k in range(nEvenMoments): auxV.append(V) assigner = fe.FunctionAssigner(auxV, VVec) v = fe.TestFunctions(VVec) u = fe.TrialFunctions(VVec) uSol = fe.Function(VVec) uSolComponents = [] for k in range(nEvenMoments): uSolComponents.append(fe.Function(V)) # FEniCS work-around if N_PN == 1: solAssignMod = lambda uSolComponents, uSol: [ assigner.assign(uSolComponents[0], uSol) ] else: solAssignMod = lambda uSolComponents, uSol: assigner.assign( uSolComponents, uSol) return u, v, V, uSol, uSolComponents, solAssignMod
def __init__(self, mesh: fe.Mesh, density: fe.Expression, constitutive_model: ConstitutiveModelBase, bf: fe.Expression = fe.Expression('0', degree=0)): self._mesh = mesh self._density = density self._constitutive_model = constitutive_model self.bf = bf element_v = fe.VectorElement("P", mesh.ufl_cell(), 1) element_s = fe.FiniteElement("P", mesh.ufl_cell(), 1) mixed_element = fe.MixedElement([element_v, element_v, element_s]) W = fe.FunctionSpace(mesh, mixed_element) # Unknowns, values at previous step and test functions w = fe.Function(W) self.u, self.v, self.p = fe.split(w) w0 = fe.Function(W) self.u0, self.v0, self.p0 = fe.split(w0) self.a0 = fe.Function(fe.FunctionSpace(mesh, element_v)) self.ut, self.vt, self.pt = fe.TestFunctions(W) self.F = kin.def_grad(self.u) self.F0 = kin.def_grad(self.u0)
def setup_governing_form(self): """ Implement the variational form per @cite{zimmerman2018monolithic}. """ Pr = fenics.Constant(self.prandtl_number) Ste = fenics.Constant(self.stefan_number) f_B = self.make_buoyancy_function() phi = self.make_semi_phasefield_function() mu = self.make_phase_dependent_material_property_function( P_L=fenics.Constant(self.liquid_viscosity), P_S=fenics.Constant(self.solid_viscosity)) gamma = fenics.Constant(self.penalty_parameter) p, u, T = fenics.split(self.state.solution) u_t, T_t, phi_t = self.make_time_discrete_terms() psi_p, psi_u, psi_T = fenics.TestFunctions(self.function_space) dx = self.integration_metric inner, dot, grad, div, sym = fenics.inner, fenics.dot, fenics.grad, fenics.div, fenics.sym self.governing_form = ( -psi_p * (div(u) + gamma * p) + dot(psi_u, u_t + f_B(T) + dot(grad(u), u)) - div(psi_u) * p + 2. * mu(phi(T)) * inner(sym(grad(psi_u)), sym(grad(u))) + psi_T * (T_t - 1. / Ste * phi_t) + dot(grad(psi_T), 1. / Pr * grad(T) - T * u)) * dx
def impl_dyn(w0, 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) # Lagrange function (without constraint) (u1, p1, v1) = fe.TrialFunctions(V_upv) (eta, q, xi) = fe.TestFunctions(V_upv) F = deformation_grad(u1) 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) 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 a_dyn_p = inner(g, q) * 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 = a_dyn_u + a_dyn_p + a_dyn_v w1 = fe.Function(V_upv) sol = [] t = 0 while t < t_end: print("progress: %f" % (100. * t / t_end)) fe.solve(a == 0, w1, bcs_u + bcs_p + bcs_v) 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
def solve_steady_state_heiser_weissinger(kappa): w = fe.Function(V_up) (u, p) = fe.split(w) p = fe.variable(p) (eta, q) = fe.TestFunctions(V_up) dw = fe.TrialFunction(V_up) kappa = fe.Constant(kappa) bcs_u, bcs_p, bcs_v = load_2d_muscle_bc(V_up.sub(0), V_up.sub(1), None, boundaries) F = deformation_grad(u) I_1, I_2, J = invariants(F) F_iso = isochronic_deformation_grad(F, J) I_1_iso, I_2_iso = invariants(F)[0:2] W = material_mooney_rivlin(I_1_iso, I_2_iso, c_10, c_01) #+ incompr_relaxation(p, kappa) g = incompr_constr(J) # Lagrange function (without constraint) L = -W # Modified Lagrange function (with constraints) L_mod = L - p * g P = first_piola_stress(L, F) G = incompr_stress(g, F) # = J*fe.inv(F.T) Lp = const_eq(L_mod, p) a_static = weak_div_term(P + p * G, eta) + inner(B, eta) * dx + inner(Lp, q) * dx J_static = fe.derivative(a_static, w, dw) ffc_options = {"optimize": True} problem = fe.NonlinearVariationalProblem( a_static, w, bcs_u + bcs_p, J=J_static, form_compiler_parameters=ffc_options) solver = fe.NonlinearVariationalSolver(problem) solver.solve() return w
def __init__(self, mesh: fe.Mesh, constitutive_model: ConstitutiveModelBase, u_order=1, p_order=0): # TODO a lot here... element_v = fe.VectorElement("P", mesh.ufl_cell(), u_order) element_s = fe.FiniteElement("DG", mesh.ufl_cell(), p_order) # mixed_element = fe.MixedElement([element_v, element_v, element_s]) mixed_element = fe.MixedElement([element_v, element_s]) self.W = fe.FunctionSpace(mesh, mixed_element) self.V, self.Q = self.W.split() self.w = fe.Function(self.W) self.u, self.p = fe.split(self.w) w0 = fe.Function(self.W) self.u0, self.p0 = fe.split(w0) self.ut, self.pt = fe.TestFunctions(self.W) self.F = kin.def_grad(self.u) self.F0 = kin.def_grad(self.u0) S_iso = constitutive_model.iso_stress(self.u) mod_p = constitutive_model.p(self.u) J = fe.det(self.F) F_inv = fe.inv(self.F) if mod_p is None: mod_p = J**2 - 1. else: mod_p -= self.p S = S_iso + J * self.p * F_inv * F_inv.T self.d_LHS = fe.inner(fe.grad(self.ut), self.F * S) * fe.dx \ + fe.inner(mod_p, self.pt) * fe.dx # + fe.inner(mod_p, fe.tr(fe.nabla_grad(self.ut)*fe.inv(self.F))) * fe.dx self.d_RHS = (fe.inner(fe.Constant((0., 0., 0.)), self.ut) * fe.dx)
def forward(rho): """Solve the forward problem for a given fluid distribution rho(x).""" w = fenics_adjoint.Function(W) (u, p) = fenics.split(w) (v, q) = fenics.TestFunctions(W) inner, grad, dx, div = ufl.inner, ufl.grad, ufl.dx, ufl.div F = ( alpha(rho) * inner(u, v) * dx + inner(grad(u), grad(v)) * dx + inner(grad(p), v) * dx + inner(div(u), q) * dx ) bcs = [ fenics_adjoint.DirichletBC(W.sub(0).sub(1), 0, "on_boundary"), fenics_adjoint.DirichletBC(W.sub(0).sub(0), inflow_outflow_bc, "on_boundary"), ] fenics_adjoint.solve(F == 0, w, bcs=bcs) return w
def run(self): e_domain = self._create_e_domain() mesh = generate_mesh(e_domain, MESH_PTS) self._create_boundary_expression() Omega_e = fe.FiniteElement("Lagrange", mesh.ufl_cell(), 1) Omega_i = fe.FiniteElement("Lagrange", self.passive_seg.mesh.ufl_cell(), 1) Omega = fe.FunctionSpace(mesh, Omega_e * Omega_i) Theta_e, Theta_i = fe.TrialFunction(Omega) v_e, v_i = fe.TestFunctions(Omega) sigma_e, sigma_i = 0.3, 0.4 LHS = sigma_e * fe.inner(fe.grad(Theta_e), fe.grad(v_e)) * fe.dx # poisson LHS += sigma_i * fe.inner(fe.grad(Theta_i), fe.grad(v_i)) * fe.dx # poisson LHS -= sigma_e * fe.grad(Theta_e) * v_e * fe.ds # current LHS += sigma_i * fe.grad(Theta_i) * v_i * fe.ds # current RHS = self.boundary_exp * v_e * fe.ds # source term # TODO: solve Poisson in extracellular space w = fe.Function(Omega) fe.solve(LHS == RHS, w) Theta_e, Theta_i = w.split() plot(fe.interpolate(Theta, fe.FunctionSpace(mesh, Omega)), mode='color') plt.show() # Set the potential just inside the membrane to Ve (just computed) # minus V_m (from prev timestep) self.passive_seg.set_v(Theta, self.passive_seg_vm) # Solve for the potential and current inside the passive cell self.passive_seg.run() # Use Im to compute a new Vm for the next timestep, eq (8) self.passive_seg_vm = self.passive_seg_vm + self.dt / self.cm * ( self.passive_seg_im - self.passive_seg_vm / self.rm)
def _create_variational_problem(m0, u0, W, dt): """We set up the variational problem.""" p, q = fc.TestFunctions(W) w = fc.Function(W) # Function to solve for m, u = fc.split(w) # Relabel i.e. initialise m_prev, u_prev as m0, u0. m_prev, u_prev = m0, u0 m_mid = 0.5 * (m + m_prev) u_mid = 0.5 * (u + u_prev) F = ( (q * u + q.dx(0) * u.dx(0) - q * m) * fc.dx + # q part (p * (m - m_prev) + dt * (p * m_mid * u_mid.dx(0) - p.dx(0) * m_mid * u_mid)) * fc.dx # p part ) J = fc.derivative(F, w) problem = fc.NonlinearVariationalProblem(F, w, J=J) solver = fc.NonlinearVariationalSolver(problem) solver.parameters["newton_solver"]["maximum_iterations"] = 100 # Default is 50 solver.parameters["newton_solver"]["error_on_nonconvergence"] = False return solver, w, m_prev, u_prev
dt = 0.1 # Re = 10 / 1e-4 = 1e5 V = fe.VectorElement("Lagrange", mesh.ufl_cell(), 2) P = fe.FiniteElement("Lagrange", mesh.ufl_cell(), 1) NU = fe.FiniteElement("Lagrange", mesh.ufl_cell(), 1) if MODEL: M = fe.MixedElement([V, P, NU]) else: M = fe.MixedElement([V, P]) W = fe.FunctionSpace(mesh, M) W0 = fe.Function(W) We = fe.Function(W) u0, p0 = fe.split(We) #u0 = fe.Function((W0[0], W0[1]), 'Velocity000023.vtu') #p0 = fe.Function(W0[2]) v, q = fe.TestFunctions(W) #u, p = fe.split(W0) u, p = (fe.as_vector((W0[0], W0[1])), W0[2]) #------------------------------------------------------- # Defining essential/Dirichlet boundary conditions # Step 1: Identify all boundary segments forming Gamma_d #------------------------------------------------------- # (-3., 2.5) # | # | # |_______(0, 1.) # bc1 | # bc2|__________(3., ,0.) # (0,0) bc3
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 sigma0 = 1.5e4
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
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
rho = fe.Constant(1) RE = 50 lmx = 1 # mixing length :) # Re = 10 / 1e-4 = 1e5 V = fe.VectorElement("Lagrange", mesh.ufl_cell(), 2) P = fe.FiniteElement("Lagrange", mesh.ufl_cell(), 1) NU = fe.FiniteElement("Lagrange", mesh.ufl_cell(), 1) if MODEL: M = fe.MixedElement([V, P, NU]) else: M = fe.MixedElement([V, P]) W = fe.FunctionSpace(mesh, M) W0 = fe.Function(W) if MODEL: (v, q, nu_test) = fe.TestFunctions(W) (u, p, nu_trial) = fe.split(W0) else: ( v, q, ) = fe.TestFunctions(W) ( u, p, ) = fe.split(W0) nu_trial = fe.Constant(5) # artificial viscosity!!! fv1 = fe.Constant(1) #------------------------------------------------------- # Defining essential/Dirichlet boundary conditions
# define potentials and concentrations u_GND = fn.Expression('0', degree=2) #Ground u_DD = fn.Expression('0.5', degree=2) #pontential c_avg = fn.Expression('0.0001', degree=2) #average concentration # set boundary conditions bcs = [] bcs += [fn.DirichletBC(V.sub(0), u_DD, mf, 3)] bcs += [fn.DirichletBC(V.sub(0), u_GND, mf, 1)] # define problem UC = fn.Function(V) uc = fn.split(UC) # trial function potential concentration lagrange multi u, c, lam = uc[0], uc[1:M + 1], uc[M + 1:] VW = fn.TestFunctions( V) # test function potential concentration lagrange multi v, w, mu = VW[0], VW[1:M + 1], VW[M + 1:] #lets try rot r = fn.Expression('x[0]', degree=0) # changing concentrations charges Rho = 0 for i in range(M): if i % 2: Rho += -c[i] else: Rho += c[i] PoissonLeft = (fn.dot(fn.grad(u), fn.grad(v))) * fn.dx # weak solution Poisson left
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( '=================================================================================' )
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) lmbda = EE*nu/((1.+nu)*(1.-2.*nu))
Ain = (Pin*A0/beta+np.sqrt(A0))**2; # -- 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)
def xest_implement_1d_myosin(self): #Parameters total_time = 10.0 number_of_time_steps = 1000 # delta_t = fenics.Constant(total_time/number_of_time_steps) delta_t = total_time / number_of_time_steps nx = 1000 domain_size = 1.0 b = fenics.Constant(6.0) k = fenics.Constant(0.5) z_1 = fenics.Constant(-10.5) #always negative # z_1 = fenics.Constant(0.0) #always negative z_2 = 0.1 # always positive xi_0 = fenics.Constant(1.0) #always positive xi_1 = fenics.Constant(1.0) #always positive xi_2 = 0.001 #always positive xi_3 = 0.0001 #always negative d = fenics.Constant(0.15) alpha = fenics.Constant(1.0) c = fenics.Constant(0.1) # Sub domain for Periodic boundary condition class PeriodicBoundary(fenics.SubDomain): # Left boundary is "target domain" G def inside(self, x, on_boundary): return bool(-fenics.DOLFIN_EPS < x[0] < fenics.DOLFIN_EPS and on_boundary) def map(self, x, y): y[0] = x[0] - 1 periodic_boundary_condition = PeriodicBoundary() #Set up finite elements mesh = fenics.IntervalMesh(nx, 0.0, 1.0) vector_element = fenics.FiniteElement('P', fenics.interval, 1) single_element = fenics.FiniteElement('P', fenics.interval, 1) mixed_element = fenics.MixedElement(vector_element, single_element) V = fenics.FunctionSpace( mesh, mixed_element, constrained_domain=periodic_boundary_condition) # V = fenics.FunctionSpace(mesh, mixed_element) v, r = fenics.TestFunctions(V) full_trial_function = fenics.Function(V) u, rho = fenics.split(full_trial_function) full_trial_function_n = fenics.Function(V) u_n, rho_n = fenics.split(full_trial_function_n) u_initial = fenics.Constant(0.0) # rho_initial = fenics.Expression('1.0*sin(pi*x[0])*sin(pi*x[0])+1.0/k0', degree=2,k0 = k) rho_initial = fenics.Expression('1/k0', degree=2, k0=k) u_n = fenics.interpolate(u_initial, V.sub(0).collapse()) rho_n = fenics.interpolate(rho_initial, V.sub(1).collapse()) # perturbation = np.zeros(rho_n.vector().size()) # perturbation[:int(perturbation.shape[0]/2)] = 1.0 rho_n.vector().set_local( np.array(rho_n.vector()) + 1.0 * (0.5 - np.random.random(rho_n.vector().size()))) # u_n.vector().set_local(np.array(u_n.vector())+4.0*(0.5-np.random.random(u_n.vector().size()))) fenics.assign(full_trial_function_n, [u_n, rho_n]) u_n, rho_n = fenics.split(full_trial_function_n) F = (u * v * fenics.dx - u_n * v * fenics.dx + delta_t * (b + (z_1 * rho) / (1 + z_2 * rho) * c * xi_1) * u.dx(0) * v.dx(0) * fenics.dx - delta_t * (z_1 * rho) / (1 + z_2 * rho) * c * c * xi_2 / 2.0 * u.dx(0) * u.dx(0) * v.dx(0) * fenics.dx + delta_t * (z_1 * rho) / (1 + z_2 * rho) * c * c * c * xi_3 / 6.0 * u.dx(0) * u.dx(0) * u.dx(0) * v.dx(0) * fenics.dx - delta_t * z_1 * rho / (1 + z_2 * rho) * xi_0 * v.dx(0) * fenics.dx + u.dx(0) * v.dx(0) * fenics.dx - u_n.dx(0) * v.dx(0) * fenics.dx + rho * r * fenics.dx - rho_n * r * fenics.dx - rho * u * r.dx(0) * fenics.dx + rho * u_n * r.dx(0) * fenics.dx + delta_t * d * rho.dx(0) * r.dx(0) * fenics.dx + delta_t * k * fenics.exp(alpha * u.dx(0)) * rho * r * fenics.dx - delta_t * r * fenics.dx + delta_t * c * u.dx(0) * r * fenics.dx) vtkfile_rho = fenics.File( os.path.join(os.path.dirname(__file__), 'output', 'myosin_2d', 'solution_rho.pvd')) vtkfile_u = fenics.File( os.path.join(os.path.dirname(__file__), 'output', 'myosin_2d', 'solution_u.pvd')) # rho_0 = fenics.Expression(((('0.0'),('0.0'),('0.0')),('sin(x[0])')), degree=1 ) # full_trial_function_n = fenics.project(rho_0, V) # print('initial u and rho') # print(u_n.vector()) # print(rho_n.vector()) time = 0.0 not_initialised = True plt.figure() for time_index in range(number_of_time_steps): # Update current time time += delta_t # Compute solution fenics.solve(F == 0, full_trial_function) # Save to file and plot solution vis_u, vis_rho = full_trial_function.split() plt.subplot(311) fenics.plot(vis_u, color='blue') plt.ylim(-0.5, 0.5) plt.subplot(312) fenics.plot(-vis_u.dx(0), color='blue') plt.ylim(-2, 2) plt.title('actin density change') plt.subplot(313) fenics.plot(vis_rho, color='blue') plt.title('myosin density') plt.ylim(0, 7) plt.tight_layout() if not_initialised: animation_camera = celluloid.Camera(plt.gcf()) not_initialised = False animation_camera.snap() print('time is') print(time) # plt.savefig(os.path.join(os.path.dirname(__file__),'output','this_output_at_time_' + '{:04d}'.format(time_index) + '.png')) # print('this u and rho') # print(np.array(vis_u.vector())) # print(np.array(vis_rho.vector())) # vtkfile_rho << (vis_rho, time) # vtkfile_u << (vis_u, time) full_trial_function_n.assign(full_trial_function) animation = animation_camera.animate() animation.save( os.path.join(os.path.dirname(__file__), 'output', 'myosin_1D.mp4'))
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) vn = fn.Constant(1.0)
import fenics import matplotlib N = 4 mesh = fenics.UnitSquareMesh(N, N) P2 = fenics.VectorElement('P', mesh.ufl_cell(), 2) P1 = fenics.FiniteElement('P', mesh.ufl_cell(), 1) P2P1 = fenics.MixedElement([P2, P1]) W = fenics.FunctionSpace(mesh, P2P1) psi_u, psi_p = fenics.TestFunctions(W) w = fenics.Function(W) u, p = fenics.split(w) dynamic_viscosity = 0.01 mu = fenics.Constant(dynamic_viscosity) inner, dot, grad, div, sym = fenics.inner, fenics.dot, fenics.grad, fenics.div, fenics.sym momentum = dot(psi_u, dot(grad(u), u)) - div(psi_u) * p + 2. * mu * inner( sym(grad(psi_u)), sym(grad(u))) mass = -psi_p * div(u)
def discretize(self): """Builds function space, call again after introducing constraints""" # FEniCS interface self.mesh = fn.IntervalMesh(self.N, self.x0_scaled, self.x1_scaled) # http://www.femtable.org/ # Argyris* ARG # Arnold-Winther* AW # Brezzi-Douglas-Fortin-Marini* BDFM # Brezzi-Douglas-Marini BDM # Bubble B # Crouzeix-Raviart CR # Discontinuous Lagrange DG # Discontinuous Raviart-Thomas DRT # Hermite* HER # Lagrange CG # Mardal-Tai-Winther* MTW # Morley* MOR # Nedelec 1st kind H(curl) N1curl # Nedelec 2nd kind H(curl) N2curl # Quadrature Q # Raviart-Thomas RT # Real R # construct test and trial function space from elements # spanned by Lagrange polynomials for the pyhsical variables of # potential and concentration and global elements with a single degree # of freedom ('Real') for constraints. # For an example of this approach, refer to # https://fenicsproject.org/docs/dolfin/latest/python/demos/neumann-poisson/demo_neumann-poisson.py.html # For another example on how to construct and split function spaces # for solving coupled equations, refer to # https://fenicsproject.org/docs/dolfin/latest/python/demos/mixed-poisson/demo_mixed-poisson.py.html P = fn.FiniteElement('Lagrange', fn.interval, 3) R = fn.FiniteElement('Real', fn.interval, 0) elements = [P] * (1 + self.M) + [R] * self.K H = fn.MixedElement(elements) self.W = fn.FunctionSpace(self.mesh, H) # solution functions self.w = fn.Function(self.W) # set initial values if available P = fn.FunctionSpace(self.mesh, 'P', 1) dof2vtx = fn.vertex_to_dof_map(P) if self.ui0 is not None: x = np.linspace(self.x0_scaled, self.x1_scaled, self.ui0.shape[0]) ui0 = scipy.interpolate.interp1d(x, self.ui0) # use linear interpolation on mesh self.u0_func = fn.Function(P) self.u0_func.vector()[:] = ui0(self.X)[dof2vtx] fn.assign(self.w.sub(0), fn.interpolate(self.u0_func, self.W.sub(0).collapse())) if self.ni0 is not None: x = np.linspace(self.x0_scaled, self.x1_scaled, self.ni0.shape[1]) ni0 = scipy.interpolate.interp1d(x, self.ni0) self.p0_func = [fn.Function(P)] * self.ni0.shape[0] for k in range(self.ni0.shape[0]): self.p0_func[k].vector()[:] = ni0(self.X)[k, :][dof2vtx] fn.assign( self.w.sub(1 + k), fn.interpolate(self.p0_func[k], self.W.sub(k + 1).collapse())) # u represents voltage , p concentrations uplam = fn.split(self.w) self.u, self.p, self.lam = (uplam[0], [*uplam[1:(self.M + 1)]], [*uplam[(self.M + 1):]]) # v, q and mu represent respective test functions vqmu = fn.TestFunctions(self.W) self.v, self.q, self.mu = (vqmu[0], [*vqmu[1:(self.M + 1)]], [*vqmu[(self.M + 1):]])
def __init__(self, L, ne, r0, Q0, E, h0, theta, dt, degA=1, degQ=1): # -- Setup domain self.L = L self.ne = ne self.dt = dt self.mesh = fe.IntervalMesh(ne, 0, L) QE = fe.FiniteElement("Lagrange", cell=self.mesh.ufl_cell(), degree=degQ) AE = fe.FiniteElement("Lagrange", cell=self.mesh.ufl_cell(), degree=degA) ME = fe.MixedElement([AE, QE]) # -- Setup functionspaces self.V = fe.FunctionSpace(self.mesh, ME) self.V_A = self.V.sub(0) self.V_Q = self.V.sub(1) (self.v1, self.v2) = fe.TestFunctions(self.V) self.dv1 = fe.grad(self.v1)[0] self.dv2 = fe.grad(self.v2)[0] self.E = E self.h0 = h0 self.beta = E * h0 * np.sqrt(np.pi) self.A0 = np.pi * r0**2 self.Q0 = Q0 self.U0 = fe.Function(self.V) self.Un = fe.Function(self.V) # -- Setup initial conditions self.U0.assign(fe.Expression(('A0', 'Q0'), A0=self.A0, Q0=Q0, degree=1)) self.Un.assign(fe.Expression(('A0', 'Q0'), A0=self.A0, Q0=Q0, degree=1)) (self.u01, self.u02) = fe.split(self.U0) (self.un1, self.un2) = fe.split(self.Un) self.du01 = fe.grad(self.u01)[0] self.du02 = fe.grad(self.u02)[0] self.dun1 = fe.grad(self.un1)[0] self.dun2 = fe.grad(self.un2)[0] (self.W1_initial, self.W2_initial) = self.getCharacteristics(self.A0, self.Q0) # -- Setup weakform terms B0 = self.getB(self.u01, self.u02) Bn = self.getB(self.un1, self.un2) H0 = self.getH(self.u01, self.u02) Hn = self.getH(self.un1, self.un2) HdUdz0 = matMult(H0, [self.du01, self.du02]) HdUdzn = matMult(Hn, [self.dun1, self.dun2]) # -- Setup weakform wf = -self.un1 * self.v1 - self.un2 * self.v2 wf += self.u01 * self.v1 + self.u02 * self.v2 wf += -dt * theta * (HdUdzn[0] + Bn[0]) * self.v1 - dt * theta * ( HdUdzn[1] + Bn[1]) * self.v2 wf += -dt * (1 - theta) * (HdUdz0[0] + B0[0]) * self.v1 - dt * ( 1 - theta) * (HdUdz0[1] + B0[1]) * self.v2 wf = wf * fe.dx self.wf = wf self.J = fe.derivative(wf, self.Un, fe.TrialFunction(self.V))
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 = 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((16, 16)) vx = x2[:256].reshape((16, 16)) vy = x2[256:].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, 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})
def demo64(self, permeability, obs_case=1): mesh = UnitSquareMesh(63, 63) 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((64, 64)) vx = x2[:4096].reshape((64, 64)) vy = x2[4096:].reshape((64, 64)) if obs_case == 1: dd = np.zeros([8, 8]) pos = np.full((8 * 8, 2), 0) col = [4, 12, 20, 28, 36, 44, 52, 60] position = [4, 12, 20, 28, 36, 44, 52, 60] 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
# set boundary conditions GammaGND = fn.DirichletBC(V.sub(0), u_GND, boundaryGND) # ground potential at straight electrode GammaHigh = fn.DirichletBC(V.sub(0), u_DD, boundaryHigh) # high potential at shaped electrode #GammaC_GND0 = fn.DirichletBC(V.sub(0) , c_INIT, boundaryGND) #GammaC_GND1 = fn.DirichletBC(V.sub(1) , c_INIT, boundaryGND) #GammaC_GND2 = fn.DirichletBC(V.sub(2) , c_INIT, boundaryGND) bcs=[GammaGND,GammaHigh] #bcs=[GammaGND,GammaHigh,GammaC_GND0,GammaC_GND1,GammaC_GND2] # %% # define problem UC = fn.Function(V) uc = fn.split(UC) u, c1, c2, lam1, lam2 = uc[0], uc[1], uc[2], uc[3], uc[4] VW = fn.TestFunctions(V) v, w1, w2, mu1, mu2 = VW[0], VW[1], VW[2], VW[3], VW[4] #create rotation #r = fn.Expression('x[0]', degree=1) # changing concentrations charges PoissonLeft = (fn.dot(fn.grad(u), fn.grad(v)))*fn.dx PoissonRight = c1*v*fn.dx - c2*v*fn.dx NernstPlanck1 = fn.dot((-fn.grad(c1) - (c1)*fn.grad(u)),fn.grad(w1))*fn.dx NernstPlanck2 = fn.dot((-fn.grad(c2) + (c2)*fn.grad(u)),fn.grad(w2))*fn.dx Constraint1 = lam1 * w1 * fn.dx + ((c1) - c_AVG) * mu1 * fn.dx Constraint2 = lam2 * w2 * fn.dx + ((c2) - c_AVG) * mu2 * fn.dx PNP_xy = PoissonLeft - PoissonRight + NernstPlanck1 + NernstPlanck2 + Constraint1 + Constraint2
left = fe.CompiledSubDomain("near(x[0], side) && on_boundary", side=0.0) right = fe.CompiledSubDomain("near(x[0], side) && on_boundary", side=1.0) # Define Dirichlet boundary (x = 0 or x = 1) u_left = fe.Expression(("0.0", "0.0", "0.0"), element=element_3) u_right = fe.Expression(("0.0", "0.0", "0.0"), element=element_3) p_left = fe.Constant(0.) # Define acting force b = fe.Constant((0.0, 0.0, 0.0)) # Body force per unit volume t_bar = fe.Constant((0.0, 0.0, 0.0)) # Traction force on the boundary # Define test and trial functions w = fe.Function(V) # most recently computed solution (u, p) = fe.split(w) (v, q) = fe.TestFunctions(V) dw = fe.TrialFunction(V) # Kinematics d = u.geometric_dimension() I = fe.Identity(d) # Identity tensor F = fe.variable(I + grad(u)) # Deformation gradient C = fe.variable(F.T * F) # Right Cauchy-Green tensor J = fe.det(C) DE = lambda v: 0.5 * (F.T * grad(v) + grad(v).T * F) a_0 = fe.as_vector([[1.0], [0.], [0.]]) # Invariants
# 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)