コード例 #1
0
def D_map(A):
    """Unit stiffness tensor mapping strain -> stress."""
    return lambda_ * ufl.tr(A) * ufl.Identity(3) + 2 * mu * A
コード例 #2
0
def sigma_u(u):
    """Consitutive relation for stress-strain. Assuming plane-stress in XY"""
    eps = 0.5 * (ufl.grad(u) + ufl.grad(u).T)
    sigma = E / (1. - nu**2) * (
        (1. - nu) * eps + nu * ufl.Identity(2) * ufl.tr(eps))
    return sigma
コード例 #3
0
# Define state and rate as (ordered) list of functions
m, mt, mtt, δm = [u], [ut], [utt], [δu]

# Time integrator
odeint = dolfiny.odeint.ODEInt2(t=time, dt=dt, x=m, xt=mt, xtt=mtt, rho=0.95)

# Configuration gradient
I = ufl.Identity(u.geometric_dimension())  # noqa: E741
F = I + ufl.grad(u)  # deformation gradient as function of displacement

# Strain measures
# E = E(u) total strain
E = 1 / 2 * (F.T * F - I)
# S = S(E) stress
S = 2 * mu * E + la * ufl.tr(E) * I

# Variation of rate of Green-Lagrange strain
δE = dolfiny.expression.derivative(E, m, δm)

# Weak form (as one-form)
f = ufl.inner(δu, rho * utt) * dx + ufl.inner(δu, eta * ut) * dx \
    + ufl.inner(δE, S) * dx \
    - ufl.inner(δu, rho * b) * dx

# Optional: linearise weak form
# f = dolfiny.expression.linearise(f, m)  # linearise around zero state

# Overall form (as one-form)
F = odeint.discretise_in_time(f)
# Overall form (as list of forms)
コード例 #4
0
 def sigma(self, u):
     n = u.geometric_dimension()
     lmbda = self.lmbda3D(0)
     mu = self.mu3D(0)
     return lmbda * tr(self.eps(u)) * Identity(n) + 2 * mu * self.eps(u)
コード例 #5
0
def test_diff_then_integrate():

    # Define 1D geometry
    n = 21
    mesh = UnitIntervalMesh(MPI.COMM_WORLD, n)

    # Shift and scale mesh
    x0, x1 = 1.5, 3.14
    mesh.coordinates()[:] *= (x1 - x0)
    mesh.coordinates()[:] += x0

    x = SpatialCoordinate(mesh)[0]
    xs = 0.1 + 0.8 * x / x1  # scaled to be within [0.1,0.9]

    # Define list of expressions to test, and configure
    # accuracies these expressions are known to pass with.
    # The reason some functions are less accurately integrated is
    # likely that the default choice of quadrature rule is not perfect
    F_list = []

    def reg(exprs, acc=10):
        for expr in exprs:
            F_list.append((expr, acc))

    # FIXME: 0*dx and 1*dx fails in the ufl-ffcx-jit framework somewhere
    # reg([Constant(0.0, cell=cell)])
    # reg([Constant(1.0, cell=cell)])
    monomial_list = [x**q for q in range(2, 6)]
    reg(monomial_list)
    reg([2.3 * p + 4.5 * q for p in monomial_list for q in monomial_list])
    reg([x**x])
    reg([x**(x**2)], 8)
    reg([x**(x**3)], 6)
    reg([x**(x**4)], 2)
    # Special functions:
    reg([atan(xs)], 8)
    reg([sin(x), cos(x), exp(x)], 5)
    reg([ln(xs), pow(x, 2.7), pow(2.7, x)], 3)
    reg([asin(xs), acos(xs)], 1)
    reg([tan(xs)], 7)

    try:
        import scipy
    except ImportError:
        scipy = None

    if hasattr(math, 'erf') or scipy is not None:
        reg([erf(xs)])
    else:
        print(
            "Warning: skipping test of erf, old python version and no scipy.")

    # if 0:
    #     print("Warning: skipping tests of bessel functions, doesn't build on all platforms.")
    # elif scipy is None:
    #     print("Warning: skipping tests of bessel functions, missing scipy.")
    # else:
    #     for nu in (0, 1, 2):
    #         # Many of these are possibly more accurately integrated,
    #         # but 4 covers all and is sufficient for this test
    #         reg([bessel_J(nu, xs), bessel_Y(nu, xs), bessel_I(nu, xs), bessel_K(nu, xs)], 4)

    # To handle tensor algebra, make an x dependent input tensor
    # xx and square all expressions
    def reg2(exprs, acc=10):
        for expr in exprs:
            F_list.append((inner(expr, expr), acc))

    xx = as_matrix([[2 * x**2, 3 * x**3], [11 * x**5, 7 * x**4]])
    x3v = as_vector([3 * x**2, 5 * x**3, 7 * x**4])
    cc = as_matrix([[2, 3], [4, 5]])
    reg2([xx])
    reg2([x3v])
    reg2([cross(3 * x3v, as_vector([-x3v[1], x3v[0], x3v[2]]))])
    reg2([xx.T])
    reg2([tr(xx)])
    reg2([det(xx)])
    reg2([dot(xx, 0.1 * xx)])
    reg2([outer(xx, xx.T)])
    reg2([dev(xx)])
    reg2([sym(xx)])
    reg2([skew(xx)])
    reg2([elem_mult(7 * xx, cc)])
    reg2([elem_div(7 * xx, xx + cc)])
    reg2([elem_pow(1e-3 * xx, 1e-3 * cc)])
    reg2([elem_pow(1e-3 * cc, 1e-3 * xx)])
    reg2([elem_op(lambda z: sin(z) + 2, 0.03 * xx)], 2)  # pretty inaccurate...

    # FIXME: Add tests for all UFL operators:
    # These cause discontinuities and may be harder to test in the
    # above fashion:
    # 'inv', 'cofac',
    # 'eq', 'ne', 'le', 'ge', 'lt', 'gt', 'And', 'Or', 'Not',
    # 'conditional', 'sign',
    # 'jump', 'avg',
    # 'LiftingFunction', 'LiftingOperator',

    # FIXME: Test other derivatives: (but algorithms for operator
    # derivatives are the same!):
    # 'variable', 'diff',
    # 'Dx', 'grad', 'div', 'curl', 'rot', 'Dn', 'exterior_derivative',

    # Run through all operators defined above and compare integrals
    debug = 0
    for F, acc in F_list:
        # Apply UFL differentiation
        f = diff(F, SpatialCoordinate(mesh))[..., 0]
        if debug:
            print(F)
            print(x)
            print(f)

        # Apply integration with DOLFINx
        # (also passes through form compilation and jit)
        M = f * dx
        f_integral = assemble_scalar(M)  # noqa
        f_integral = mesh.mpi_comm().allreduce(f_integral, op=MPI.SUM)

        # Compute integral of f manually from anti-derivative F
        # (passes through pybind11 interface and uses UFL evaluation)
        F_diff = F((x1, )) - F((x0, ))

        # Compare results. Using custom relative delta instead
        # of decimal digits here because some numbers are >> 1.
        delta = min(abs(f_integral), abs(F_diff)) * 10**-acc
        assert f_integral - F_diff <= delta
コード例 #6
0
 def sigma0(self):
     n = self.dim
     lmbda = self.lmbda3D(0)
     mu = self.mu3D(0)
     return lmbda * tr(self.eps0()) * Identity(n) + 2 * mu * self.eps0()
コード例 #7
0
 def elastic_energy_density(self, eps):
     lmbda = self.E0 * self.nu / ((1.0 + self.nu) * (1.0 - 2.0 * self.nu))
     mu = self.E0 / (2.0 * (1.0 + self.nu))
     return 1.0 / 2.0 * lmbda * tr(eps)**2 + mu * inner(eps, eps)
コード例 #8
0
def test_neohooke():
    mesh = dolfinx.mesh.create_unit_cube(MPI.COMM_WORLD, 7, 7, 7)
    V = dolfinx.fem.VectorFunctionSpace(mesh, ("P", 1))
    P = dolfinx.fem.FunctionSpace(mesh, ("P", 1))

    L = dolfinx.fem.FunctionSpace(mesh, ("DG", 0))

    u = dolfinx.fem.Function(V, name="u")
    v = ufl.TestFunction(V)

    p = dolfinx.fem.Function(P, name="p")
    q = ufl.TestFunction(P)

    lmbda0 = dolfinx.fem.Function(L)

    d = mesh.topology.dim
    Id = ufl.Identity(d)
    F = Id + ufl.grad(u)
    C = F.T * F
    J = ufl.det(F)

    E_, nu_ = 10.0, 0.3
    mu, lmbda = E_ / (2 * (1 + nu_)), E_ * nu_ / ((1 + nu_) * (1 - 2 * nu_))
    psi = (mu / 2) * (ufl.tr(C) -
                      3) - mu * ufl.ln(J) + lmbda / 2 * ufl.ln(J)**2 + (p -
                                                                        1.0)**2
    pi = psi * ufl.dx

    F0 = ufl.derivative(pi, u, v)
    F1 = ufl.derivative(pi, p, q)

    # Number of eigenvalues to find
    nev = 8

    opts = PETSc.Options("neohooke")
    opts["eps_smallest_magnitude"] = True
    opts["eps_nev"] = nev
    opts["eps_ncv"] = 50 * nev
    opts["eps_conv_abs"] = True

    # opts["eps_non_hermitian"] = True
    opts["eps_tol"] = 1.0e-14
    opts["eps_max_it"] = 1000
    opts["eps_error_relative"] = "ascii::ascii_info_detail"
    opts["eps_monitor"] = "ascii"

    slepcp = dolfiny.slepcblockproblem.SLEPcBlockProblem([F0, F1], [u, p],
                                                         lmbda0,
                                                         prefix="neohooke")
    slepcp.solve()

    # mat = dolfiny.la.petsc_to_scipy(slepcp.eps.getOperators()[0])
    # eigvals, eigvecs = linalg.eigsh(mat, which="SM", k=nev)

    with dolfinx.io.XDMFFile(MPI.COMM_WORLD, "eigvec.xdmf", "w") as ofile:
        ofile.write_mesh(mesh)
        for i in range(nev):
            eigval, ur, ui = slepcp.getEigenpair(i)

            # Expect first 6 eignevalues 0, i.e. rigid body modes
            if i < 6:
                assert np.isclose(eigval, 0.0)

            for func in ur:
                name = func.name
                func.name = f"{name}_eigvec_{i}_real"
                ofile.write_function(func)

                func.name = name
コード例 #9
0
 def sigma(v):
     return (2.0 * mu * epsilon(v) + lmbda * tr(epsilon(v)) * Identity(len(v)))
コード例 #10
0

def skw(tau):
    """Define vectorized skew operator"""
    sk = 2 * skew(tau)
    return as_vector((sk[0, 1], sk[0, 2], sk[1, 2]))


cell = tetrahedron
n = 3

# Finite element exterior calculus syntax
r = 1
S = VectorElement("P Lambda", cell, r, form_degree=n - 1)
V = VectorElement("P Lambda", cell, r - 1, form_degree=n)
Q = VectorElement("P Lambda", cell, r - 1, form_degree=n)

# Alternative syntax:
# S = VectorElement("BDM", cell, r)
# V = VectorElement("Discontinuous Lagrange", cell, r-1)
# Q = VectorElement("Discontinuous Lagrange", cell, r-1)

W = MixedElement(S, V, Q)

(sigma, u, gamma) = TrialFunctions(W)
(tau, v, eta) = TestFunctions(W)

a = (inner(sigma, tau) - tr(sigma) * tr(tau) +
     dot(div(tau), u) - dot(div(sigma), v) +
     inner(skw(tau), gamma) + inner(skw(sigma), eta)) * dx
コード例 #11
0
# Define state and rate as (ordered) list of functions
m, mt, mtt, δm = [u, S], [ut, St], [utt, Stt], [δu, δS]

# Time integrator
odeint = dolfiny.odeint.ODEInt2(t=time, dt=dt, x=m, xt=mt, xtt=mtt, rho=0.95)

# Configuration gradient
I = ufl.Identity(u.geometric_dimension())  # noqa: E741
F = I + ufl.grad(u)  # deformation gradient as function of displacement

# Strain measures
# E = E(u) total strain
E = 1 / 2 * (F.T * F - I)
# E = E(S) elastic strain
Es = 1 / (2 * mu) * S - la / (2 * mu * (3 * la + 2 * mu)) * ufl.tr(S) * I

# Variation of rate of Green-Lagrange strain
δE = dolfiny.expression.derivative(E, m, δm)

# Weak form (as one-form)
f = ufl.inner(δu, rho * utt) * dx + ufl.inner(δu, eta * ut) * dx \
    + ufl.inner(δE, S) * dx + ufl.inner(δS, Es - E) * dx \
    - ufl.inner(δu, rho * b) * dx

# Optional: linearise weak form
# f = dolfiny.expression.linearise(f, m)  # linearise around zero state

# Overall form (as one-form)
F = odeint.discretise_in_time(f)
# Overall form (as list of forms)
コード例 #12
0
top_facets = dolfinx.mesh.locate_entities_boundary(mesh, 1, top)
top_dofs = dolfinx.fem.locate_dofs_topological(V_u, mesh.topology.dim - 1,
                                                top_facets)

bottom_facets = dolfinx.mesh.locate_entities_boundary(mesh, 1, bottom)
bottom_dofs = dolfinx.fem.locate_dofs_topological(V_u, mesh.topology.dim - 1,
                                                bottom_facets)

# energy
mu = parameters["model"]["mu"]
lmbda = parameters["model"]["lmbda"]

def _e(u):
  return ufl.sym(ufl.grad(u))

en_density = 1/2 * (2*mu* ufl.inner(_e(u),_e(u))) + lmbda*ufl.tr(_e(u))**2
energy = en_density * dx - ufl.inner(u, g)*dS(4)

#bcs = [dirichletbc(zero, bottom_dofs), dirichletbc(one, top_dofs)]
bcs = [dirichletbc(zero, bottom_dofs)]

# solving
from solvers import SNESSolver
D_energy_u = ufl.derivative(energy, u, ufl.TestFunction(V_u))

problem = SNESSolver(
    D_energy_u,
    u,
    bcs,
    bounds=None,
    petsc_options=parameters.get("solvers").get("snes"),
コード例 #13
0
def D_rebar_map(A):
    """Unit stiffness tensor (rebars) mapping strain -> stress."""
    return lambda_rebar_ * ufl.tr(A) * ufl.Identity(3) + 2 * mu_rebar * A
コード例 #14
0
def C_map(A):
    """unit compliance tensor mapping stress -> strain."""
    return -lambda_ / (2.0 * mu * (3.0 * lambda_ + 2.0 * mu)
                       ) * ufl.tr(A) * ufl.Identity(3) + 1.0 / (2 * mu) * A
コード例 #15
0
def sigma(v):
    return (1/(1+Nu))*strain(v) + ((1*Nu)/((1+Nu)*(1-2*Nu)))*ufl.tr(strain(v))*ufl.Identity(v.geometric_dimension()) #v.cell().d
コード例 #16
0
    """Square root of J2 invariant of tensor A"""
    J2 = 1 / 2 * ufl.inner(A, A)
    rJ2 = ufl.sqrt(J2)
    return ufl.conditional(rJ2 < 1.0e-12, 0.0, rJ2)


# Configuration gradient
I = ufl.Identity(u.geometric_dimension())  # noqa: E741
F = I + ufl.grad(u)  # deformation gradient as function of displacement

# Strain measures
E = 1 / 2 * (F.T * F - I)  # E = E(F), total Green-Lagrange strain
E_el = E - P  # E_el = E(F) - P, elastic strain

# Stress
S = 2 * mu * E_el + la * ufl.tr(
    E_el) * I  # S = S(E_el), PK2, St.Venant-Kirchhoff

# Wrap variable around expression (for diff)
S, B, h = ufl.variable(S), ufl.variable(B), ufl.variable(h)

# Yield function
f = ufl.sqrt(3) * rJ2(ufl.dev(S) - ufl.dev(B)) - (Sy + h)

# Plastic potential
g = f

# Total differential of yield function
df = + ufl.inner(ufl.diff(f, S), S - S0) \
     + ufl.inner(ufl.diff(f, h), h - h0) \
     + ufl.inner(ufl.diff(f, B), B - B0)
コード例 #17
0
 def sigma(w, gdim):
     return 2.0 * mu * ufl.sym(grad(w)) + lmbda * ufl.tr(
         grad(w)) * ufl.Identity(gdim)
コード例 #18
0
 def sigma(v):
     return (2.0 * mu * ufl.sym(ufl.grad(v))
             + lmbda * ufl.tr(ufl.sym(ufl.grad(v))) * ufl.Identity(len(v)))
コード例 #19
0
 def elastic_energy_density(self, eps, alpha):
     # lmbda = self.lmbda3D(alpha)
     lmbda = self.lmbda2D(alpha)
     mu = self.mu3D(alpha)
     return 1.0 / 2.0 * lmbda * tr(eps - self.eps0())**2 + mu * inner(
         eps - self.eps0(), eps - self.eps0())
コード例 #20
0
def compliance(sigma):
  ' Returns the strain tensor as a function of sigma '
  return sigma/(2*mu) - lmbda/(4*mu*(lmbda + mu))*tr(sigma)*Identity(u.geometric_dimension())
コード例 #21
0
 def elastic_energy_density(self, eps, alpha):
     lmbda = self.lmbda3D(alpha)
     mu = self.mu3D(alpha)
     return 1.0 / 2.0 * lmbda * tr(eps)**2 + mu * inner(eps, eps)
コード例 #22
0
    def write_output(self, pb, writemesh=False, N=1, t=0):
        
        if writemesh:
            
            if self.write_results_every > 0:
            
                self.resultsfiles = {}
                for res in self.results_to_write:
                    outfile = XDMFFile(self.comm, self.output_path+'/results_'+pb.simname+'_'+res+'.xdmf', 'w')
                    outfile.write_mesh(self.mesh)
                    self.resultsfiles[res] = outfile
                
            return
        
        
        else:

            # write results every write_results_every steps
            if self.write_results_every > 0 and N % self.write_results_every == 0:
                
                # save solution to XDMF format
                for res in self.results_to_write:
                    
                    if res=='displacement':
                        self.resultsfiles[res].write_function(pb.u, t)
                    elif res=='velocity': # passed in v is not a function but form, so we have to project
                        v_proj = project(pb.vel, pb.V_u, pb.dx_, nm="Velocity")
                        self.resultsfiles[res].write_function(v_proj, t)
                    elif res=='acceleration': # passed in a is not a function but form, so we have to project
                        a_proj = project(pb.acc, pb.V_u, pb.dx_, nm="Acceleration")
                        self.resultsfiles[res].write_function(a_proj, t)
                    elif res=='pressure':
                        self.resultsfiles[res].write_function(pb.p, t)
                    elif res=='cauchystress':
                        stressfuncs=[]
                        for n in range(pb.num_domains):
                            stressfuncs.append(pb.ma[n].sigma(pb.u,pb.p,ivar=pb.internalvars))
                        cauchystress = project(stressfuncs, pb.Vd_tensor, pb.dx_, nm="CauchyStress")
                        self.resultsfiles[res].write_function(cauchystress, t)
                    elif res=='trmandelstress':
                        stressfuncs=[]
                        for n in range(pb.num_domains):
                            stressfuncs.append(tr(pb.ma[n].M(pb.u,pb.p,ivar=pb.internalvars)))
                        trmandelstress = project(stressfuncs, pb.Vd_scalar, pb.dx_, nm="trMandelStress")
                        self.resultsfiles[res].write_function(trmandelstress, t)
                    elif res=='trmandelstress_e':
                        stressfuncs=[]
                        for n in range(pb.num_domains):
                            if pb.mat_growth[n]: stressfuncs.append(tr(pb.ma[n].M_e(pb.u,pb.p,pb.ki.C(pb.u),ivar=pb.internalvars)))
                            else: stressfuncs.append(as_ufl(0))
                        trmandelstress_e = project(stressfuncs, pb.Vd_scalar, pb.dx_, nm="trMandelStress_e")
                        self.resultsfiles[res].write_function(trmandelstress_e, t)
                    elif res=='vonmises_cauchystress':
                        stressfuncs=[]
                        for n in range(pb.num_domains):
                            stressfuncs.append(pb.ma[n].sigma_vonmises(pb.u,pb.p,ivar=pb.internalvars))
                        vonmises_cauchystress = project(stressfuncs, pb.Vd_scalar, pb.dx_, nm="vonMises_CauchyStress")
                        self.resultsfiles[res].write_function(vonmises_cauchystress, t)
                    elif res=='pk1stress':
                        stressfuncs=[]
                        for n in range(pb.num_domains):
                            stressfuncs.append(pb.ma[n].P(pb.u,pb.p,ivar=pb.internalvars))
                        pk1stress = project(stressfuncs, pb.Vd_tensor, pb.dx_, nm="PK1Stress")
                        self.resultsfiles[res].write_function(pk1stress, t)
                    elif res=='pk2stress':
                        stressfuncs=[]
                        for n in range(pb.num_domains):
                            stressfuncs.append(pb.ma[n].S(pb.u,pb.p,ivar=pb.internalvars))
                        pk2stress = project(stressfuncs, pb.Vd_tensor, pb.dx_, nm="PK2Stress")
                        self.resultsfiles[res].write_function(pk2stress, t)
                    elif res=='jacobian':
                        jacobian = project(pb.ki.J(pb.u), pb.Vd_scalar, pb.dx_, nm="Jacobian")
                        self.resultsfiles[res].write_function(jacobian, t)
                    elif res=='glstrain':
                        glstrain = project(pb.ki.E(pb.u), pb.Vd_tensor, pb.dx_, nm="GreenLagrangeStrain")
                        self.resultsfiles[res].write_function(glstrain, t)
                    elif res=='eastrain':
                        eastrain = project(pb.ki.e(pb.u), pb.Vd_tensor, pb.dx_, nm="EulerAlmansiStrain")
                        self.resultsfiles[res].write_function(eastrain, t)
                    elif res=='fiberstretch':
                        fiberstretch = project(pb.ki.fibstretch(pb.u,pb.fib_func[0]), pb.Vd_scalar, pb.dx_, nm="FiberStretch")
                        self.resultsfiles[res].write_function(fiberstretch, t)
                    elif res=='fiberstretch_e':
                        stretchfuncs=[]
                        for n in range(pb.num_domains):
                            if pb.mat_growth[n]: stretchfuncs.append(pb.ma[n].fibstretch_e(pb.ki.C(pb.u),pb.theta,pb.fib_func[0]))
                            else: stretchfuncs.append(as_ufl(0))
                        fiberstretch_e = project(stretchfuncs, pb.Vd_scalar, pb.dx_, nm="FiberStretch_e")
                        self.resultsfiles[res].write_function(fiberstretch_e, t)
                    elif res=='theta':
                        self.resultsfiles[res].write_function(pb.theta, t)
                    elif res=='phi_remod':
                        phifuncs=[]
                        for n in range(pb.num_domains):
                            if pb.mat_remodel[n]: phifuncs.append(pb.ma[n].phi_remod(pb.theta))
                            else: phifuncs.append(as_ufl(0))
                        phiremod = project(phifuncs, pb.Vd_scalar, pb.dx_, nm="phiRemodel")
                        self.resultsfiles[res].write_function(phiremod, t)
                    elif res=='tau_a':
                        self.resultsfiles[res].write_function(pb.tau_a, t)
                    elif res=='fiber1':
                        fiber1 = project(pb.fib_func[0], pb.Vd_vector, pb.dx_, nm="Fiber1")
                        self.resultsfiles[res].write_function(fiber1, t)
                    elif res=='fiber2':
                        fiber2 = project(pb.fib_func[1], pb.Vd_vector, pb.dx_, nm="Fiber2")
                        self.resultsfiles[res].write_function(fiber2, t)
                    else:
                        raise NameError("Unknown output to write for solid mechanics!")


            if self.write_restart_every > 0 and N % self.write_restart_every == 0:

                self.writecheckpoint(pb, N)
コード例 #23
0
def test_div_grad_then_integrate_over_cells_and_boundary():

    # Define 2D geometry
    n = 10
    mesh = RectangleMesh(
        [numpy.array([0.0, 0.0, 0.0]),
         numpy.array([2.0, 3.0, 0.0])], 2 * n, 3 * n)

    x, y = SpatialCoordinate(mesh)
    xs = 0.1 + 0.8 * x / 2  # scaled to be within [0.1,0.9]
    #    ys = 0.1 + 0.8 * y / 3  # scaled to be within [0.1,0.9]
    n = FacetNormal(mesh)

    # Define list of expressions to test, and configure accuracies
    # these expressions are known to pass with.  The reason some
    # functions are less accurately integrated is likely that the
    # default choice of quadrature rule is not perfect
    F_list = []

    def reg(exprs, acc=10):
        for expr in exprs:
            F_list.append((expr, acc))

    # FIXME: 0*dx and 1*dx fails in the ufl-ffcx-jit framework somewhere
    # reg([Constant(0.0, cell=cell)])
    # reg([Constant(1.0, cell=cell)])
    monomial_list = [x**q for q in range(2, 6)]
    reg(monomial_list)
    reg([2.3 * p + 4.5 * q for p in monomial_list for q in monomial_list])
    reg([xs**xs])
    reg(
        [xs**(xs**2)], 8
    )  # Note: Accuracies here are from 1D case, not checked against 2D results.
    reg([xs**(xs**3)], 6)
    reg([xs**(xs**4)], 2)
    # Special functions:
    reg([atan(xs)], 8)
    reg([sin(x), cos(x), exp(x)], 5)
    reg([ln(xs), pow(x, 2.7), pow(2.7, x)], 3)
    reg([asin(xs), acos(xs)], 1)
    reg([tan(xs)], 7)

    # To handle tensor algebra, make an x dependent input tensor
    # xx and square all expressions
    def reg2(exprs, acc=10):
        for expr in exprs:
            F_list.append((inner(expr, expr), acc))

    xx = as_matrix([[2 * x**2, 3 * x**3], [11 * x**5, 7 * x**4]])
    xxs = as_matrix([[2 * xs**2, 3 * xs**3], [11 * xs**5, 7 * xs**4]])
    x3v = as_vector([3 * x**2, 5 * x**3, 7 * x**4])
    cc = as_matrix([[2, 3], [4, 5]])
    reg2(
        [xx]
    )  # TODO: Make unit test for UFL from this, results in listtensor with free indices
    reg2([x3v])
    reg2([cross(3 * x3v, as_vector([-x3v[1], x3v[0], x3v[2]]))])
    reg2([xx.T])
    reg2([tr(xx)])
    reg2([det(xx)])
    reg2([dot(xx, 0.1 * xx)])
    reg2([outer(xx, xx.T)])
    reg2([dev(xx)])
    reg2([sym(xx)])
    reg2([skew(xx)])
    reg2([elem_mult(7 * xx, cc)])
    reg2([elem_div(7 * xx, xx + cc)])
    reg2([elem_pow(1e-3 * xxs, 1e-3 * cc)])
    reg2([elem_pow(1e-3 * cc, 1e-3 * xx)])
    reg2([elem_op(lambda z: sin(z) + 2, 0.03 * xx)], 2)  # pretty inaccurate...

    # FIXME: Add tests for all UFL operators:
    # These cause discontinuities and may be harder to test in the
    # above fashion:
    # 'inv', 'cofac',
    # 'eq', 'ne', 'le', 'ge', 'lt', 'gt', 'And', 'Or', 'Not',
    # 'conditional', 'sign',
    # 'jump', 'avg',
    # 'LiftingFunction', 'LiftingOperator',

    # FIXME: Test other derivatives: (but algorithms for operator
    # derivatives are the same!):
    # 'variable', 'diff',
    # 'Dx', 'grad', 'div', 'curl', 'rot', 'Dn', 'exterior_derivative',

    # Run through all operators defined above and compare integrals
    debug = 0
    if debug:
        F_list = F_list[1:]

    for F, acc in F_list:
        if debug:
            print('\n', "F:", str(F))

        # Integrate over domain and its boundary
        int_dx = assemble(div(grad(F)) * dx(mesh))  # noqa
        int_ds = assemble(dot(grad(F), n) * ds(mesh))  # noqa

        if debug:
            print(int_dx, int_ds)

        # Compare results. Using custom relative delta instead of
        # decimal digits here because some numbers are >> 1.
        delta = min(abs(int_dx), abs(int_ds)) * 10**-acc
        assert int_dx - int_ds <= delta
コード例 #24
0
# Functions
u = Coefficient(element)        # Displacement from previous iteration
# B = Coefficient(element)        # Body force per unit volume
# T = Coefficient(element)        # Traction force on the boundary

# Now, we can define the kinematic quantities involved in the model::

# Kinematics
d = len(u)
I = Identity(d)         # Identity tensor
F = variable(I + grad(u))         # Deformation gradient
C = F.T*F               # Right Cauchy-Green tensor

# Invariants of deformation tensors
Ic = tr(C)
J = det(F)

# Before defining the energy density and thus the total potential
# energy, it only remains to specify constants for the elasticity
# parameters::

# Elasticity parameters
E = 10.0
nu = 0.3
mu = E/(2*(1 + nu))
lmbda = E*nu/((1 + nu)*(1 - 2*nu))

# Both the first variation of the potential energy, and the Jacobian of
# the variation, can be automatically computed by a call to
# ``derivative``::
コード例 #25
0
def sigma(v):
    return 2.0 * mu * sym(grad(v)) + lmbda * tr(sym(grad(v))) * Identity(
        len(v))
コード例 #26
0
 def S(tau):
     return tau - ufl.Identity(2) * ufl.tr(tau)
コード例 #27
0
def sigma(v):
    return 2.0*mu*epsilon(v) + lmbda*ufl.tr(epsilon(v)) \
        * ufl.Identity(v.geometric_dimension())
コード例 #28
0
odeint = dolfiny.odeint.ODEInt(t=time, dt=dt, x=m, xt=mt, rho=0.95)

# Expression for time-integrated quantities
u_expr = u + odeint.integral_dt(v)

# Configuration gradient
I = ufl.Identity(v.geometric_dimension())  # noqa: E741
F = I + ufl.grad(
    u_expr)  # deformation gradient as function of time-integrated velocity
dotF = ufl.grad(v)  # rate of deformation gradient as function of velocity

# Strain measures
# dot E = dot E(u,v) total strain rate
dotE = 1 / 2 * (dotF.T * F + F.T * dotF)
# dot E = dot E(S) elastic strain rate
dotEs = 1 / (2 * mu) * St - la / (2 * mu * (3 * la + 2 * mu)) * ufl.tr(St) * I

# Variation of rate of Green-Lagrange strain
δdotE = dolfiny.expression.derivative(dotE, m, δm)

# Weak form (as one-form)
f = ufl.inner(δv, rho * vt) * dx + ufl.inner(δv, eta * v) * dx \
    + ufl.inner(δdotE, S) * dx + ufl.inner(δS, dotEs - dotE) * dx \
    - ufl.inner(δv, rho * b) * dx

# Optional: linearise weak form
# f = dolfiny.expression.linearise(dolfiny.expression.evaluate(f, u_expr, u), m, [v, S, u])  # linearise

# Overall form (as one-form)
F = odeint.discretise_in_time(f)
# Overall form (as list of forms)
コード例 #29
0
def inv(A):
    """Matrix invariants"""
    return ufl.tr(A), 1. / 2 * A[_i, _j] * A[_i, _j], ufl.det(A)
コード例 #30
0
rho = Constant(cell)
K = Constant(cell)
c00 = Constant(cell)
c11 = Constant(cell)
c22 = Constant(cell)

# Deformation gradient
I = Identity(d)
F = I + grad(u)
F = variable(F)
Finv = inv(F)
J = det(F)

# Left Cauchy-Green deformation tensor
B = F * F.T
I1_B = tr(B)
I2_B = (I1_B**2 - tr(B * B)) / 2
I3_B = J**2

# Right Cauchy-Green deformation tensor
C = F.T * F
I1_C = tr(C)
I2_C = (I1_C**2 - tr(C * C)) / 2
I3_C = J**2

# Green strain tensor
E = (C - I) / 2

# Mapping of strain in fiber directions
Ef = A * E * A.T