Doubt in brittle fracture

Hello there,

I’m working with brittle fracture formulation, specifically I’m basing my studies from this papper: https://www.researchgate.net/publication/338897618_Phase_field_fracture_implementation_in_FEniCS. I changed a bit the code, my problem is basically, my problem is the following:

from __future__ import print_function
from dolfin import *
from mshr import *
from dolfin import File
import matplotlib.pyplot as plt
import numpy as np
from dolfin import plot


domain = Rectangle(Point(-0.5, -0.5), Point(0.5, 0.5)) - Rectangle(Point(-0.5, -0.0001), Point(0, 0.0001))
unitary_circle1 = Circle(Point(0.0, 0.0), 0.020)
unitary_circle2 = Circle(Point(0.5, 0.2), 0.09)
unitary_circle3 = Circle(Point(0.1, 0.4), 0.025)
unitary_circle4 = Circle(Point(0.26, 0.71), 0.05)

domain_with_hole = domain - unitary_circle1 - unitary_circle2 - unitary_circle3 - unitary_circle4
mesh = generate_mesh(domain_with_hole, 50)
mesh = refine(mesh)


plot(mesh)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Mesh Plot')
plt.show()


# Define Space
V = FunctionSpace(mesh, 'CG', 1)
W = VectorFunctionSpace(mesh, 'CG', 1)
WW = FunctionSpace(mesh, 'DG', 0)
p, q = TrialFunction(V), TestFunction(V)
u, v = TrialFunction(W), TestFunction(W)

# Introduce manually the material parameters
Gc =  2.7
l = 0.015
lmbda = 121.1538e3
mu = 80.7692e3

# Constituive functions
def epsilon(u):
    return sym(grad(u))
def sigma(u):
    return 2.0*mu*epsilon(u)+lmbda*tr(epsilon(u))*Identity(len(u))
def psi(u):
    return 0.5*(lmbda+mu)*(0.5*(tr(epsilon(u))+abs(tr(epsilon(u)))))**2+mu*inner(dev(epsilon(u)),dev(epsilon(u)))        
def H(uold,unew,Hold):
    return conditional(lt(psi(uold),psi(unew)),psi(unew),Hold)
        
# Boundary conditions
top = CompiledSubDomain("near(x[1], 0.5) && on_boundary")
bot = CompiledSubDomain("near(x[1], -0.5) && on_boundary")
def Crack(x):
    return abs(x[1]) < 1e-03 and x[0] <= 0.0
load = Expression("t", t = 0.0, degree=1)
bcbot= DirichletBC(W, Constant((0.0,0.0)), bot)
bctop = DirichletBC(W.sub(1), load, top)
bc_u = [bcbot, bctop]
bc_phi = [DirichletBC(V, Constant(1.0), Crack)]
boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
boundaries.set_all(0)
top.mark(boundaries,1)
ds = Measure("ds")(subdomain_data=boundaries)
n = FacetNormal(mesh)

And the output:

But what I tried to do is basically, in this unitary_circles be a “hole” on the plate and in these circles, be a region where the function doesn’t act on the material, and have zero boundary conditions near of these “holes”. Also, I thought that doing it would change the properties of crack propagation, but is really similar with the one without holes. What I did wrong? Thank by your attention.

You’ll need to clarify what is shown in the picture: I guess it is a solution field, but I can’t see the actual solve in your code.

Ok. The solver in the code is the following:

from __future__ import print_function
from dolfin import *
from mshr import *
from dolfin import File
import matplotlib.pyplot as plt
import numpy as np
from dolfin import plot


domain = Rectangle(Point(-0.5, -0.5), Point(0.5, 0.5)) - Rectangle(Point(-0.5, -0.0001), Point(0, 0.0001))
unitary_circle1 = Circle(Point(0.0, 0.0), 0.020)
unitary_circle2 = Circle(Point(0.5, 0.2), 0.09)
unitary_circle3 = Circle(Point(0.1, 0.4), 0.025)
unitary_circle4 = Circle(Point(0.26, 0.71), 0.05)

domain_with_hole = domain - unitary_circle1 - unitary_circle2 - unitary_circle3 - unitary_circle4
mesh = generate_mesh(domain_with_hole, 50)
mesh = refine(mesh)


plot(mesh)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Mesh Plot')
plt.show()


# Define Space
V = FunctionSpace(mesh, 'CG', 1)
W = VectorFunctionSpace(mesh, 'CG', 1)
WW = FunctionSpace(mesh, 'DG', 0)
p, q = TrialFunction(V), TestFunction(V)
u, v = TrialFunction(W), TestFunction(W)

# Introduce manually the material parameters
Gc =  2.7
l = 0.015
lmbda = 121.1538e3
mu = 80.7692e3

# Constituive functions
def epsilon(u):
    return sym(grad(u))
def sigma(u):
    return 2.0*mu*epsilon(u)+lmbda*tr(epsilon(u))*Identity(len(u))
def psi(u):
    return 0.5*(lmbda+mu)*(0.5*(tr(epsilon(u))+abs(tr(epsilon(u)))))**2+mu*inner(dev(epsilon(u)),dev(epsilon(u)))        
def H(uold,unew,Hold):
    return conditional(lt(psi(uold),psi(unew)),psi(unew),Hold)
        
# Boundary conditions
top = CompiledSubDomain("near(x[1], 0.5) && on_boundary")
bot = CompiledSubDomain("near(x[1], -0.5) && on_boundary")
def Crack(x):
    return abs(x[1]) < 1e-03 and x[0] <= 0.0
load = Expression("t", t = 0.0, degree=1)
bcbot= DirichletBC(W, Constant((0.0,0.0)), bot)
bctop = DirichletBC(W.sub(1), load, top)
bc_u = [bcbot, bctop]
bc_phi = [DirichletBC(V, Constant(1.0), Crack)]
boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
boundaries.set_all(0)
top.mark(boundaries,1)
ds = Measure("ds")(subdomain_data=boundaries)
n = FacetNormal(mesh)

# Variational form
unew, uold = Function(W), Function(W)
pnew, pold, Hold = Function(V), Function(V), Function(V)
E_du = ((1.0-pold)**2)*inner(grad(v),sigma(u))*dx
E_phi = (Gc*l*inner(grad(p),grad(q))+((Gc/l)+2.0*H(uold,unew,Hold))\
            *inner(p,q)-2.0*H(uold,unew,Hold)*q)*dx
p_disp = LinearVariationalProblem(lhs(E_du), rhs(E_du), unew, bc_u)
p_phi = LinearVariationalProblem(lhs(E_phi), rhs(E_phi), pnew, bc_phi)
solver_disp = LinearVariationalSolver(p_disp)
solver_phi = LinearVariationalSolver(p_phi)

# Initialization of the iterative procedure and output requests
t = 0
u_r = 0.007
deltaT  = 0.1
tol = 1e-3
conc_f = File ("./ResultsDir/phi.pvd")
fname = open('ForcevsDisp.txt', 'w')

# Staggered scheme
while t<=3.0:
    t += deltaT
    if t >=0.7:
        deltaT = 0.001
    load.t=t*u_r
    iter = 0
    err = 1
    while err > tol:
        iter += 1
        solver_disp.solve()
        solver_phi.solve()
        err_u = errornorm(unew,uold,norm_type = 'l2',mesh = None)
        err_phi = errornorm(pnew,pold,norm_type = 'l2',mesh = None)
        err = max(err_u,err_phi)
        uold.assign(unew)
        pold.assign(pnew)
        Hold.assign(project(psi(unew), WW))
        if err < tol:
            print ('Iterations:', iter, ', Total time', t)
            if round(t*1e4) % 10 == 0:
                conc_f << pnew
                Traction = dot(sigma(unew),n)
                fy = Traction[1]*ds(1)
                fname.write(str(t*u_r) + "\t")
                fname.write(str(assemble(fy)) + "\n")
                
fname.close()
print ('Simulation completed')

The picture is basically the the “plate” completely cracked. The problem is that this picture is identical (taking out the parts of the mesh that I remove it):

And it should have a different output, since the function doesn’t should act in the holes and near of its border (it changes also the density of the material, but my focus is more on see the crack propagating in the plate with holes).

Did you get the solution?

No, I didn’t, I’m trying to remove now a single circle from the mesh and apply zero Neumann and Dirichlet boundary conditions, but is not working. I’m trying the following:


def circle_boundary(x, on_boundary):
     return unitary_circle.inside(x, on_boundary)

def neumann_boundary(x, on_boundary):
    return on_boundary and not unitary_circle.inside(x, on_boundary)

# Boundary conditions

top = CompiledSubDomain("near(x[1], 0.5) && on_boundary")

bot = CompiledSubDomain("near(x[1], -0.5) && on_boundary")

boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1)

boundaries.set_all(0)

unitary_circle.mark(boundaries, 1)

def Crack(x):

return abs(x[1]) < 1e-03 and x[0] <= 0.0

load = Expression("t", t = 0.0, degree=1)

bcbot= DirichletBC(W, Constant((0.0,0.0)), bot)

bctop = DirichletBC(W.sub(1), load, top)

bc_r = DirichletBC(V, 0, circle_boundary)

bc_u = [bcbot, bctop,bcr]

bc_phi = [DirichletBC(V, Constant(1.0), Crack)]

top.mark(boundaries,1)

ds = Measure("ds")(subdomain_data=boundaries)

n = FacetNormal(mesh)

But for some reason, mark is not defined. I got the following error:

Traceback (most recent call last):
  File "/home/jandui/Documents/MATH code/First FEM approx/brittle_circle.py", line 58, in <module>
    unitary_circle.mark(boundaries, 1)
AttributeError: 'mshr.cpp.Circle' object has no attribute 'mark'

Does someone has any idea in what should I do to fix this?