Lhs = A.form AttributeError: 'Equation' object has no attribute 'form'

Hi, in the code below I am having the error:

File “/home/user/.local/lib/python3.10/site-packages/fenics_adjoint/blocks/solving.py”, line 6, in init
lhs = A.form
AttributeError: ‘Equation’ object has no attribute ‘form’

from dolfin import *
from dolfin_adjoint import *
import matplotlib.pyplot as plt
import numpy as np

# Optimization options for the form compiler
parameters["form_compiler"]["cpp_optimize"] = True
ffc_options = {"optimize": True,
               "eliminate_zeros": True,
               "precompute_basis_const": True,
               "precompute_ip_const": True}

# Stored strain energy density (compressible neo-Hookean model)
def psi(mu, Ic, J_, lmbda):
    return (mu / 2) * (Ic - 3) - mu * ln(J_) + (lmbda / 2) * (ln(J_)) ** 2

def kinematics(u):
	v = TestFunction(V_vector)  # Test function
	d = u.geometric_dimension()
	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)
	return Ic, J_, v, F

def optimization(chi):
    max_error = 0
    count = 0
    for i in max_disp:
        u0 = Function(V_vector)
        u = Function(V_vector)
        step_size = np.linspace(0, i, 100, endpoint=True)
        for j in step_size:
            disp = Constant([0.0, j])
            bcs, dss = bcs_(disp)
            Ic, J_, v, F = kinematics(u)
            # Stored strain energy density (compressible neo-Hookean model)
            Psi = H((chi - 0.5), l2) * psi(mu1, Ic, J_, lmbda1) + (1 - H((chi - 0.5), l2)) * psi(mu2, Ic, J_, lmbda2)
            # Total potential energy
            Pi = Psi * dx
            # Compute first variation of Pi (directional derivative about u in the direction of v)
            dPi = derivative(Pi, u, v)
            file2 = File("./Results" + "/stress-opt.pvd");
            u.assign(u0)
            solve(dPi == 0, u, bcs,
                  form_compiler_parameters=ffc_options)
            u0.assign(u)
            # Piola-Kirchhoff Stress
            stress = diff(Psi, F)
            stress_calculation = (project(stress,  W_tensor))
            file2 << stress_calculation
            t = dot(stress, normal)
            t = assemble(t[1] * dss(1))
        count += 1
   
    controls = File("./Results" + "/control_iterations_guess.pvd")
...
    solver = IPOPTSolver(problem, parameters=parameters_ipopt)  # , parameters=parameters_ipopt
    f_opt = solver.solve()

    return f_opt

opt_chi = optimization(chi)

I could not find the reason, I would be happy if you can help me, thanks!

You have truncated the code, which makes it impossible to reproduce the error.

First of all, i would try without both the loops:

to see if you can solve a single pde optimization problem.

Here is the full version of the code, I am still having the same error:

from dolfin import *
from dolfin_adjoint import *
import moola
import matplotlib.pyplot as plt
import numpy as np
from png_to_mesh import convert
from boundaries import bcs_
import os

# Set log level
set_log_level(LogLevel.WARNING)

# Optimization options for the form compiler
parameters["form_compiler"]["cpp_optimize"] = True
ffc_options = {"optimize": True,
               "eliminate_zeros": True,
               "precompute_basis_const": True,
               "precompute_ip_const": True}
try:
	import cyipopt
except ImportError:
	print("""This example depends on IPOPT and pyipopt. \
  When compiling IPOPT, make sure to link against HSL, as it \
  is a necessity for practical problems.""")
	raise


iteration = 21
tol = 1.0e-60
l1 = 1e-1
l2 = 1e-6
normal = Constant((0, 1))
chi0 = 0.9
delta_t = 1e-1
Traclist = []
E1, nu1 = 26.0, 0.4  # base material
E2, nu2 = 1e-9, 0.0  # void
# E2, nu2 = 1e-30, 0.0  # void
mu1, lmbda1 = Constant(E1 / (2 * (1 + nu1))), Constant(E1 * nu1 / ((1 + nu1) * (1 - 2 * nu1)))
mu2, lmbda2 = Constant(E2 / (2 * (1 + nu2))), Constant(E2 * nu2 / ((1 + nu2) * (1 - 2 * nu2)))
max_disp = [-0.02, -0.06]
f_desired =  [-0.09, -0.12]

p = 2
sum_f = 0
for i in f_desired:
    sum_f += i
store_u = np.linspace(0, 1.0 * min(max_disp), 100)
displacement_by_step = store_u
img = plt.imread("bertoldi_clear2.png")
(Nx, Ny, Nz) = img.shape
c1, c2 = 0.5 * 1e+1 , 1e+2

# Create mesh and define function space
n = 32
mesh = UnitSquareMesh(n, n)
W = FunctionSpace(mesh, "DG", 0)
V_vector = VectorFunctionSpace(mesh, "CG", 2)
W_tensor = TensorFunctionSpace(mesh, "CG", 2)
force_FS = VectorFunctionSpace(mesh, "Real", 0)
df = TestFunction(force_FS)

def H(a, l):
    return 0.5 * (1 + a / (l + abs(a)))

# initial chi expression
chi = convert(img, Nx, Ny, Nz, mesh, l1, W)

# Stored strain energy density (compressible neo-Hookean model)
def psi(mu, Ic, J_, lmbda):
    return (mu / 2) * (Ic - 3) - mu * ln(J_) + (lmbda / 2) * (ln(J_)) ** 2


def kinematics(u):
    v = TestFunction(V_vector)  # Test function
    d = u.geometric_dimension()
    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)
    return Ic, J_, v, F


def optimization(chi):
    max_error = 0
    count = 0
    for i in max_disp:
        print("i:", i)
        u0 = Function(V_vector)
        u = Function(V_vector, name='Response')  # it should be a vector disp.normal
        step_size = np.linspace(0, i, 100, endpoint=True)
        for j in step_size:
            disp = Constant([0.0, j])
            bcs, dss = bcs_(mesh, V_vector, disp)
            Ic, J_, v, F = kinematics(u)
            # Stored strain energy density (compressible neo-Hookean model)
            Psi = ((H((chi - 0.5), l2))) * psi(mu1, Ic, J_, lmbda1) + (1 - ((H((chi - 0.5), l2) )) ) * psi(mu2, Ic, J_, lmbda2)
            # Total potential energy
            Pi = Psi * dx
            # Compute first variation of Pi (directional derivative about u in the direction of v)
            dPi = derivative(Pi, u, v)
            FF = dPi
            u.assign(u0)
            solve(FF == 0, u, bcs,
                  form_compiler_parameters=ffc_options)
            u0.assign(u)
            # Piola-Kirchhoff Stress
            stress = diff(Psi, F)
            stress_calculation = (project(stress, W_tensor))
            t = dot(stress, normal)
            t = assemble(t[1] * dss(1))
        max_error += ((t - f_desired[count]) ** 20) ** (1/20)
        print("desired f", f_desired[count])
        print("calculated f", t)
        count += 1
    J = c1 * max_error 


    control = Control(chi)
    rf = ReducedFunctional(J, control)
    # const = UFLInequalityConstraint(dJdx - 1e-5, control)
    lb = 0.0
    ub = 1.0
    problem = MinimizationProblem(rf, bounds=[lb, ub])  # , constraints=const
    parameters_ipopt = {"acceptable_tol": tol, "maximum_iterations": iteration}
    solver = IPOPTSolver(problem, parameters=parameters_ipopt)  # , parameters=parameters_ipopt
    f_opt = solver.solve()

    print(f"Initial J: {rf(chi)}")
    print(f"min opt {min(f_opt.vector().get_local())}, max opt {max(f_opt.vector().get_local())}")
    print(f"Optimal J {rf(f_opt)}")

    return f_opt

opt_chi = optimization(chi)

all error is like below:

Traceback (most recent call last):
  File "/home/gokcen/PycharmProjects/optimization/opt-main-code.py", line 196, in <module>
    opt_chi = optimization(chi)
  File "/home/gokcen/PycharmProjects/optimization/opt-main-code.py", line 153, in optimization
    solve(FF == 0, u, bcs,
  File "/home/gokcen/.local/lib/python3.10/site-packages/fenics_adjoint/solving.py", line 47, in solve
    block = solve_block_type(*args, ad_block_tag=ad_block_tag, **sb_kwargs)
  File "/home/gokcen/.local/lib/python3.10/site-packages/fenics_adjoint/blocks/solving.py", line 6, in __init__
    lhs = A.form
AttributeError: 'Equation' object has no attribute 'form'

@dokken I downloaded fenics again and still having the same error

I’m running into the same error - did you end up finding a solution @HaticeGokcenGuner ?

Hello @Mike_Norton, no I created a new conda environment and downloaded fenics again.

Ah okay, thanks! @HaticeGokcenGuner would you be willing to post a list of the packages you’ve installed in your conda environment? I’m wondering if there is some version mismatch between fenics and dolfin_adjoint on my end.

Hello Mike, when I had the error before I created a new User and downloaded everything again. However, I got the same problem again now. I could not solve it @Mike_Norton

Hi Mike, running <pip install git+https://bitbucket.org/dolfin-adjoint/pyadjoint.git@master> solved my problem

Please note that dolfin-adjoint from bitbucket is no longer maintained, please see:

for a compatible up to date release

Thanks @dokken, it solved my error but do you have any other suggestions?

I don’t understand what you imply by “other suggestions”. Please clarify your question.