This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

Error: Unable to access vector of degrees of freedom.

0 votes

I have defined a function Continuum_relaxation (code attached) which solved a linear elasticity problem with some periodic and Dirichlet BCs. However the solver machinery is more general Non-linear one. It has Periodic BCs on the x and y directions. One of the z-boundary is fixed to zero displacement. Whereas on the other z-boundary every node has a Dirichlet BC.

When I run this code, I get the following error:

File "AC_coupling.py", line 456, in Continuum_relaxation
solver.solve()
RuntimeError:

*** -------------------------------------------------------------------------
*** DOLFIN encountered an error. If you are not able to resolve this issue
*** using the information listed below, you can ask for help at


*** fenics@fenicsproject.org


*** Remember to include the error message listed below and, if possible,
*** include a minimal running example to reproduce the error.


*** -------------------------------------------------------------------------
*** Error: Unable to access vector of degrees of freedom.
*** Reason: Cannot access a non-const vector from a subfunction.
*** Where: This error was encountered inside Function.cpp.
*** Process: 0


*** DOLFIN version: 1.6.0
*** Git changeset: unknown

I am learning fenics and have no idea how to solve this issue. I will very grateful if anyone can help me out.

Thank you very much.

Hope to hear from some of you soon.

Sincerely,
Shankha

def Continuum_relaxation(interface_atom_disp, n_pad_atoms, nodes, orient, xlo, xhi, ylo, yhi, z_end_continuum, mu, lmbda, alpha):

  """ Create mesh and define function space """
  # Importing the mesh
  mesh = Mesh("mesh.xml")

  mesh.init(2) # Compute faces
  mesh.init(0, 0) # Compute vertex neighbors for each vertex
  mesh.init(1, 1) # Compute edge neighbors for each edge

  """ Defining Sub Domains for Boundary Conditions"""

  """Sub domain for Periodic boundary condition"""
  class PeriodicDomain(SubDomain):

     #Defining the "target domain" G
     def inside(self, x, on_boundary):
        return bool((near(x[0], xhi) or near(x[1], yhi)) and (not ((near(x[0], xlo) and near(x[1], yhi)) or (near(x[0], xhi) and near(x[1], ylo)))) and on_boundary)

     #Mapping domain H to "target domain" G
     def map(self, x, y):
        if near(x[0], xlo) and near(x[1], ylo):
           y[0] = x[0] + (xhi - xlo)
           y[1] = x[1] + (yhi - ylo)
           y[2] = x[2]
        elif near(x[0], xlo):
           y[0] = x[0] + (xhi - xlo)
           y[1] = x[1]
           y[2] = x[2]
        elif near(x[1], ylo):
           y[0] = x[0]
           y[1] = x[1] + (yhi - ylo)
           y[2] = x[2]
        else:
           y[0] = -1000
           y[1] = -1000
           y[2] = -1000

  """Sub domains for every interface node"""
  interface = [CompiledSubDomain("x[0] == xi && x[1] == yi && x[2] == zi", xi = pos[0], yi = pos[1], zi = pos[2]) for pos in nodes[np.array([list(nodes[:,0]).index(i) for i in interface_atom_disp[:,0]]), 1:]]

  """Sub domain for free surface boundary opposite to the interface"""
  def free_surface(x, on_boundary):
     return bool(near(x[2], z_end_continuum) and (not ((near(x[2], z_end_continuum) and near(x[0], xhi)) or (near(x[2], z_end_continuum) and near(x[1], yhi)))) and on_boundary)


  """ Function space with linear functions(deg=1) """
  V = VectorFunctionSpace(mesh, "Lagrange", 1, constrained_domain=PeriodicDomain())


  """ Assigning Dirichlet Boundary Conditions """
  u0_interface = [Constant(disp) for disp in interface_atom_disp[:,1:]]
  u0_free_surface  = Constant((0.0, 0.0, 0.0))

  bc_interface = [DirichletBC(V, u0_interface[count] , interface[count]) for count in range(0, np.shape(interface_atom_disp)[0])]
  bc_free_surface = [DirichletBC(V, u0_free_surface, free_surface)]

  bcs = bc_interface + bc_free_surface

  """ Define variational problem """
  du = TrialFunction(V)        # Incremental displacement
  v  = TestFunction(V)         # Test function
  u  = Function(V)             # Displacement from previous iteration

  # Define material model 
  def material_model(u):

     # Kinematics
     epsilon = sym(grad(u))
     Id = Identity(u.geometric_dimension())
     nu1 = np.array([np.dot(orient['x'], np.array([1, 0, 0])) / np.linalg.norm(orient['x']), np.dot(orient['y'], np.array([1, 0, 0]))  / np.linalg.norm(orient['y']), np.dot(orient['z'], np.array([1, 0, 0])) / np.linalg.norm(orient['z'])])
     nu2 = np.array([np.dot(orient['x'], np.array([0, 1, 0])) / np.linalg.norm(orient['x']), np.dot(orient['y'], np.array([0, 1, 0]))  / np.linalg.norm(orient['y']), np.dot(orient['z'], np.array([0, 1, 0])) / np.linalg.norm(orient['z'])])
     nu3 = np.array([np.dot(orient['x'], np.array([0, 0, 1])) / np.linalg.norm(orient['x']), np.dot(orient['y'], np.array([0, 0, 1]))  / np.linalg.norm(orient['y']), np.dot(orient['z'], np.array([0, 0, 1])) / np.linalg.norm(orient['z'])])

     # Material law
     i,j = indices(2)
     O1 = as_tensor(Constant(nu1)[i] * Constant(nu1)[j], (i,j))
     O2 = as_tensor(Constant(nu2)[i] * Constant(nu2)[j], (i,j))
     O3 = as_tensor(Constant(nu3)[i] * Constant(nu3)[j], (i,j))
     sigma = (2.0*mu*epsilon) + (lmbda * tr(epsilon) * Id) + (alpha*((inner(epsilon,O1)*O1) + (inner(epsilon,O2)*O2) + (inner(epsilon,O3)*O3)))
     jacobian = 0

     return (sigma,jacobian)



  # Bilinear form definitions
  Sigma , J  = material_model(u) 

  L  = inner(Sigma, nabla_grad(v))*dx 
  traction = Constant((0.0, 0.0, 0.0))   # Traction force on the boundary
  F  = dot(traction, v)*ds  
  B  = L - F

  J  = derivative(B, u, du)  


  """ Compute solution """
  # Set up the problem and solver
  problem = NonlinearVariationalProblem(B, u, bcs, J)
  solver  = NonlinearVariationalSolver(problem)

  # Set up solver parameters
  prm = solver.parameters
  prm['newton_solver']['absolute_tolerance'] = 1E-8
  prm['newton_solver']['relative_tolerance'] = 1E-7
  prm['newton_solver']['maximum_iterations'] = 10
  prm['newton_solver']['relaxation_parameter'] = 1.0

  # Solve the problem
  solver.solve()


  """ Output """

  disp = np.vstack(np.split(u.vector().array()[vertex_to_dof_map()], mesh.num_vertices()))
  pad_atom_disp = np.column_stack((np.array(range(0, n_pad_atoms)), disp[0:n_pad_atoms,:]))
  id_coor_disp = np.column_stack((np.array(range(0, mesh.num_vertices())), mesh.coordinates(), disp))

  return pad_atom_disp, id_coor_disp'
closed with the note: I found the answer myself
asked Jun 13, 2016 by shankha FEniCS Novice (220 points)
closed Jun 15, 2016 by shankha
...