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_element(self): """ Implement the mixed element per @cite{danaila2014newton}. """ pressure_element = fenics.FiniteElement( "P", self.mesh.ufl_cell(), self.temperature_element_degree) velocity_element = fenics.VectorElement( "P", self.mesh.ufl_cell(), self.temperature_element_degree + 1) temperature_element = fenics.FiniteElement( "P", self.mesh.ufl_cell(), self.temperature_element_degree) self.element = fenics.MixedElement( [pressure_element, velocity_element, temperature_element])
def MeshDefinition(Dimensions, NumberElements, Type='Lagrange', PolynomDegree=1): # Mesh Mesh = fe.BoxMesh(fe.Point(-Dimensions[0]/2, -Dimensions[1]/2, -Dimensions[2]/2), fe.Point(Dimensions[0]/2, Dimensions[1]/2, Dimensions[2]/2), NumberElements, NumberElements, NumberElements) # Functions spaces V_ele = fe.VectorElement(Type, Mesh.ufl_cell(), PolynomDegree) V = fe.VectorFunctionSpace(Mesh, Type, PolynomDegree) # Finite element functions du = fe.TrialFunction(V) v = fe.TestFunction(V) u = fe.Function(V) return [Mesh, V, u, du, v]
def make_mixed_fe(cell): """ Define the mixed finite element. MixedFunctionSpace used to be available but is now deprecated. To create the mixed space, I'm using the approach from https://fenicsproject.org/qa/11983/mixedfunctionspace-in-2016-2-0 """ velocity_degree = pressure_degree + 1 velocity_element = fenics.VectorElement("P", cell, velocity_degree) pressure_element = fenics.FiniteElement("P", cell, pressure_degree) temperature_element = fenics.FiniteElement("P", cell, temperature_degree) mixed_element = fenics.MixedElement( [velocity_element, pressure_element, temperature_element]) return mixed_element
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)
from fenics import div, grad, curl, inner, dot, inv, tr import numpy as np #import matplotlib.pyplot as plt # some fenics settings fe.parameters['form_compiler']['cpp_optimize'] = True fe.parameters['form_compiler']['optimize'] = True #fe.parameters["form_compiler"]["quadrature_degree"] = 5 # Create mesh and define function space n = 20 mesh = fe.UnitCubeMesh(n, n, n) # Init function spaces element_3 = fe.VectorElement("P", mesh.ufl_cell(), 1) element = fe.FiniteElement("P", mesh.ufl_cell(), 2) # Mixed function space TH = element_3 * element V = fe.FunctionSpace(mesh, TH) # Define Boundaries 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.)
EPSILON = 1.0e-14 DEG = 2 mesh = fe.Mesh('step.xml') # Control pannel MODEL = False # flag to use SA model b = fe.Expression(('0', '0'), degree=DEG) # forcing nu = fe.Constant(2e-6) rho = fe.Constant(1) RE = 0.01 lmx = 1 # mixing length 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])
"""Inverse permeability as a function of rho""" return alphabar + (alphaunderbar - alphabar) * rho * (1 + q) / (rho + q) N = 20 delta = 1.5 # The aspect ratio of the domain, 1 high and \delta wide V = ( fenics_adjoint.Constant(1.0 / 3) * delta ) # want the fluid to occupy 1/3 of the domain mesh = fenics_adjoint.Mesh( fenics.RectangleMesh(fenics.Point(0.0, 0.0), fenics.Point(delta, 1.0), N, N) ) A = fenics.FunctionSpace(mesh, "CG", 1) # control function space U_h = fenics.VectorElement("CG", mesh.ufl_cell(), 2) P_h = fenics.FiniteElement("CG", mesh.ufl_cell(), 1) W = fenics.FunctionSpace(mesh, U_h * P_h) # mixed Taylor-Hood function space # Define the boundary condition on velocity (x, y) = ufl.SpatialCoordinate(mesh) l = 1.0 / 6.0 # noqa: E741 gbar = 1.0 cond1 = ufl.And(ufl.gt(y, (1.0 / 4 - l / 2)), ufl.lt(y, (1.0 / 4 + l / 2))) val1 = gbar * (1 - (2 * (y - 0.25) / l) ** 2) cond2 = ufl.And(ufl.gt(y, (3.0 / 4 - l / 2)), ufl.lt(y, (3.0 / 4 + l / 2))) val2 = gbar * (1 - (2 * (y - 0.75) / l) ** 2) inflow_outflow = ufl.conditional(cond1, val1, ufl.conditional(cond2, val2, 0)) inflow_outflow_bc = fenics_adjoint.project(inflow_outflow, W.sub(0).sub(0).collapse()) solve_templates = (fenics_adjoint.Function(A),)
import fenics as fn fn.parameters["form_compiler"]["representation"] = "uflacs" fn.parameters["form_compiler"]["cpp_optimize"] = True # Create mesh and define function space size = width, height = 1.0, 0.75 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
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})
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 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( '=================================================================================' )
import time from load_meshes import load_2d_muscle_geo, load_2d_muscle_bc from plotting_tools import * mesh, dx, ds, boundaries = load_2d_muscle_geo() cell = mesh.ufl_cell() dim = 2 # Notation # u: displacement field # p: lagrange multiplier, pressure # v: velocity field element_u = fe.VectorElement('CG', cell, 2) element_p = fe.FiniteElement('CG', cell, 1) element_v = fe.VectorElement('CG', cell, 2) # define mixed elements mix_up = fe.MixedElement([element_u, element_p]) mix_uv = fe.MixedElement([element_u, element_v]) mix_pv = fe.MixedElement([element_p, element_v]) mix_upv = fe.MixedElement([element_u, element_p, element_v]) # define function spaces V_u = fe.FunctionSpace(mesh, element_u) V_p = fe.FunctionSpace(mesh, element_p) V_v = fe.FunctionSpace(mesh, element_v) V_up = fe.FunctionSpace(mesh, mix_up) V_uv = fe.FunctionSpace(mesh, mix_uv)
def xest_implement_2d_myosin(self): #Parameters total_time = 1.0 number_of_time_steps = 100 delta_t = total_time / number_of_time_steps nx = ny = 100 domain_size = 1.0 lambda_ = 5.0 mu = 2.0 gamma = 1.0 eta_b = 0.0 eta_s = 1.0 k_b = 1.0 k_u = 1.0 # zeta_1 = -0.5 zeta_1 = 0.0 zeta_2 = 1.0 mu_a = 1.0 K_0 = 1.0 K_1 = 0.0 K_2 = 0.0 K_3 = 0.0 D = 0.25 alpha = 3 c = 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 True if on left or bottom boundary AND NOT on one of the two corners (0, 1) and (1, 0) return bool( (fenics.near(x[0], 0) or fenics.near(x[1], 0)) and (not ((fenics.near(x[0], 0) and fenics.near(x[1], 1)) or (fenics.near(x[0], 1) and fenics.near(x[1], 0)))) and on_boundary) def map(self, x, y): if fenics.near(x[0], 1) and fenics.near(x[1], 1): y[0] = x[0] - 1. y[1] = x[1] - 1. elif fenics.near(x[0], 1): y[0] = x[0] - 1. y[1] = x[1] else: # near(x[1], 1) y[0] = x[0] y[1] = x[1] - 1. periodic_boundary_condition = PeriodicBoundary() #Set up finite elements mesh = fenics.RectangleMesh(fenics.Point(0, 0), fenics.Point(domain_size, domain_size), nx, ny) vector_element = fenics.VectorElement('P', fenics.triangle, 2, dim=2) single_element = fenics.FiniteElement('P', fenics.triangle, 2) mixed_element = fenics.MixedElement(vector_element, single_element) V = fenics.FunctionSpace( mesh, mixed_element, constrained_domain=periodic_boundary_condition) 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) #Define non-linear weak formulation def epsilon(u): return 0.5 * (fenics.nabla_grad(u) + fenics.nabla_grad(u).T ) #return sym(nabla_grad(u)) def sigma_e(u): return lambda_ * ufl.nabla_div(u) * fenics.Identity( 2) + 2 * mu * epsilon(u) def sigma_d(u): return eta_b * ufl.nabla_div(u) * fenics.Identity( 2) + 2 * eta_s * epsilon(u) # def sigma_a(u,rho): # return ( -zeta_1*rho/(1+zeta_2*rho)*mu_a*fenics.Identity(2)*(K_0+K_1*ufl.nabla_div(u)+ # K_2*ufl.nabla_div(u)*ufl.nabla_div(u)+K_3*ufl.nabla_div(u)*ufl.nabla_div(u)*ufl.nabla_div(u))) def sigma_a(u, rho): return -zeta_1 * rho / ( 1 + zeta_2 * rho) * mu_a * fenics.Identity(2) * (K_0) F = (gamma * fenics.dot(u, v) * fenics.dx - gamma * fenics.dot(u_n, v) * fenics.dx + fenics.inner(sigma_d(u), fenics.nabla_grad(v)) * fenics.dx - fenics.inner(sigma_d(u_n), fenics.nabla_grad(v)) * fenics.dx - delta_t * fenics.inner(sigma_e(u) + sigma_a(u, rho), fenics.nabla_grad(v)) * fenics.dx + rho * r * fenics.dx - rho_n * r * fenics.dx + ufl.nabla_div(rho * u) * r * fenics.dx - ufl.nabla_div(rho * u_n) * r * fenics.dx - D * delta_t * fenics.dot(fenics.nabla_grad(rho), fenics.nabla_grad(r)) * fenics.dx + delta_t * (-k_u * rho * fenics.exp(alpha * ufl.nabla_div(u)) + k_b * (1 - c * ufl.nabla_div(u))) * r * fenics.dx) # F = ( gamma*fenics.dot(u,v)*fenics.dx - gamma*fenics.dot(u_n,v)*fenics.dx + fenics.inner(sigma_d(u),fenics.nabla_grad(v))*fenics.dx - # fenics.inner(sigma_d(u_n),fenics.nabla_grad(v))*fenics.dx - delta_t*fenics.inner(sigma_e(u)+sigma_a(u,rho),fenics.nabla_grad(v))*fenics.dx # +rho*r*fenics.dx-rho_n*r*fenics.dx + ufl.nabla_div(rho*u)*r*fenics.dx - ufl.nabla_div(rho*u_n)*r*fenics.dx - # D*delta_t*fenics.dot(fenics.nabla_grad(rho),fenics.nabla_grad(r))*fenics.dx +delta_t*(-k_u*rho*fenics.exp(alpha*ufl.nabla_div(u))+k_b*(1-c*ufl.nabla_div(u)))) 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) time = 0.0 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() vtkfile_rho << (vis_rho, time) vtkfile_u << (vis_u, time) full_trial_function_n.assign(full_trial_function)