Hi all,
I’m trying to solve a problem that is linear in displacement, u and non linear in plastic strain with magnitude p and direction N. What I’d like to do is step up a form of the linear elasticity problem to begin with and solve for u at fixed p and N, then minimise a functional over p and N to enforce the plasticity rules. Since solving the variational elasticity problem is identical to minimising the elastic strain energy, I expect is that the result of this process should minimise a functional F = E_{strain} + \phi_{ajdoint}.
For now I’m just trying to get the first part to work, but something to do with the calculation of elastic strain is making things not work.
from dolfin import *
from dolfin_adjoint import *
import numpy as np
# Create mesh and define function space
length =1
height = 1
mesh = RectangleMesh(Point(0, 0), Point(length, height), 5, 5)
V_element = VectorElement('CG',mesh.ufl_cell(), 1)
T_element = TensorElement('DG',mesh.ufl_cell(), 0)
S_element = FiniteElement('DG',mesh.ufl_cell(), 0)
u_space = FunctionSpace(mesh, V_element)
u = Function( FunctionSpace(mesh, V_element))
p = Function( FunctionSpace(mesh, S_element))
N = Function( FunctionSpace(mesh, T_element))
u_ = TestFunction( FunctionSpace(mesh, V_element))
# Define elastic parameters
E = Constant(1.0e2) # Young's modulus
nu = Constant(0.3) # Poisson's ratio
Sy = Constant(0.3) # Yield stress
# Define the stress-strain relation
lambda_ = E * nu / ((1 + nu) * (1 - nu))
mu = E / (2 * (1 + nu))
I = Identity(2)
def eps(u): # elastic strain
return sym(grad(u)) - N*p
def sigma(u): #stress from elastic strain
e = eps(u)
return lambda_ * tr(e) * I + 2 * mu * e
# Define the variational problem
F = (inner(sigma(u), eps(u_)))* dx - inner(Constant((0,0)), u_) *dx
# Define Dirichlet boundary conditions
def left_boundary(x, on_boundary):
return near(x[0], 0) and on_boundary
def right_boundary(x, on_boundary):
return near(x[0], length) and on_boundary
def bottom_boundary(x, on_boundary):
return near(x[1], 0) and on_boundary
bc_left = DirichletBC(u_space.sub(0), Constant(0.0), left_boundary) # Fix left boundary
bc_bottom = DirichletBC(u_space.sub(1), Constant(0.0), bottom_boundary) # Fix bottom boundary
bc_right = DirichletBC(u_space.sub(0), Constant(0.001), right_boundary) # Fix right boundary
bcs = [bc_left, bc_right,bc_bottom]
# Solve variational problem
solve(F == 0, u, bcs)
Gives the following error:
No Jacobian form specified for nonlinear variational problem.
Differentiating residual form F to obtain Jacobian J = F'.
Calling FFC just-in-time (JIT) compiler, this may take some time.
Traceback (most recent call last):
File "/root/Plasticity/SingleStep.py", line 67, in <module>
solve(F == 0, u, bcs)
File "/src/pyadjoint/fenics_adjoint/solving.py", line 51, in solve
output = backend.solve(*args, **kwargs)
File "/usr/lib/python3/dist-packages/dolfin/fem/solving.py", line 233, in solve
_solve_varproblem(*args, **kwargs)
File "/usr/lib/python3/dist-packages/dolfin/fem/solving.py", line 308, in _solve_varproblem
problem = NonlinearVariationalProblem(eq.lhs, u, bcs, J,
File "/usr/lib/python3/dist-packages/dolfin/fem/problem.py", line 157, in __init__
F = Form(F, form_compiler_parameters=form_compiler_parameters)
File "/usr/lib/python3/dist-packages/dolfin/fem/form.py", line 43, in __init__
ufc_form = ffc_jit(form, form_compiler_parameters=form_compiler_parameters,
File "/usr/lib/python3/dist-packages/dolfin/jit/jit.py", line 47, in mpi_jit
return local_jit(*args, **kwargs)
File "/usr/lib/python3/dist-packages/dolfin/jit/jit.py", line 97, in ffc_jit
return ffc.jit(ufl_form, parameters=p)
File "/usr/lib/python3/dist-packages/ffc/jitcompiler.py", line 217, in jit
module = jit_build(ufl_object, module_name, parameters)
File "/usr/lib/python3/dist-packages/ffc/jitcompiler.py", line 130, in jit_build
module, signature = dijitso.jit(jitable=ufl_object,
File "/usr/lib/python3/dist-packages/dijitso/jit.py", line 165, in jit
header, source, dependencies = generate(jitable, name, signature, params["generator"])
File "/usr/lib/python3/dist-packages/ffc/jitcompiler.py", line 65, in jit_generate
code_h, code_c, dependent_ufl_objects = compile_object(ufl_object,
File "/usr/lib/python3/dist-packages/ffc/compiler.py", line 142, in compile_form
return compile_ufl_objects(forms, "form", object_names,
File "/usr/lib/python3/dist-packages/ffc/compiler.py", line 185, in compile_ufl_objects
analysis = analyze_ufl_objects(ufl_objects, kind, parameters)
File "/usr/lib/python3/dist-packages/ffc/analysis.py", line 89, in analyze_ufl_objects
form_datas = tuple(_analyze_form(form, parameters)
File "/usr/lib/python3/dist-packages/ffc/analysis.py", line 89, in <genexpr>
form_datas = tuple(_analyze_form(form, parameters)
File "/usr/lib/python3/dist-packages/ffc/analysis.py", line 169, in _analyze_form
form_data = compute_form_data(form,
File "/usr/lib/python3/dist-packages/ufl/algorithms/compute_form_data.py", line 407, in compute_form_data
check_form_arity(preprocessed_form, self.original_form.arguments(), complex_mode) # Currently testing how fast this is
File "/usr/lib/python3/dist-packages/ufl/algorithms/check_arities.py", line 177, in check_form_arity
check_integrand_arity(itg.integrand(), arguments, complex_mode)
File "/usr/lib/python3/dist-packages/ufl/algorithms/check_arities.py", line 159, in check_integrand_arity
arg_tuples = map_expr_dag(rules, expr, compress=False)
File "/usr/lib/python3/dist-packages/ufl/corealg/map_dag.py", line 26, in map_expr_dag
result, = map_expr_dags(function, [expression], compress=compress)
File "/usr/lib/python3/dist-packages/ufl/corealg/map_dag.py", line 75, in map_expr_dags
r = handlers[v._ufl_typecode_](v, *[vcache[u] for u in v.ufl_operands])
File "/usr/lib/python3/dist-packages/ufl/algorithms/check_arities.py", line 48, in sum
raise ArityMismatch("Adding expressions with non-matching form arguments {0} vs {1}.".format(_afmt(a), _afmt(b)))
ufl.algorithms.check_arities.ArityMismatch: Adding expressions with non-matching form arguments () vs ('v_0',).
I’m fairly sure it has something to do with the multiplication of N*p
in the calculation of elastic strain, but I’m not sure why. All I’d like to do here is solve for u with fixed p and N, so that later on I can perform some other minimisation on p and N with a reduced functional. Is this possible or have I deeply misunderstood the dolfin-adjoint framework?
Kind regards,
Magnus