Optimal controls
Optimal controlsΒΆ
To run this you need to install dolfin-adjoint and cyipopt
import dolfin as df
import dolfin_adjoint as da
import matplotlib.pyplot as plt
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Input In [1], in <cell line: 2>()
1 import dolfin as df
----> 2 import dolfin_adjoint as da
3 import matplotlib.pyplot as plt
ModuleNotFoundError: No module named 'dolfin_adjoint'
import pulse
def cost_function(u_model, u_data):
norm = lambda f: da.assemble(df.inner(f, f) * df.dx)
return norm(u_model - u_data)
def create_forward_problem(
mesh,
activation,
active_value=0.0,
active_model="active_stain",
T_ref=1.0,
):
ffun = df.MeshFunction("size_t", mesh, 2)
ffun.set_all(0)
left = df.CompiledSubDomain("on_boundary && near(x[0], 0)")
left_marker = 1
left.mark(ffun, left_marker)
# Collect the functions containing the markers
marker_functions = pulse.MarkerFunctions(ffun=ffun)
def dirichlet_bc(W):
V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0)
return da.DirichletBC(V, da.Constant((0.0, 0.0, 0.0)), left)
bcs = pulse.BoundaryConditions(
dirichlet=(dirichlet_bc,),
)
f0 = df.as_vector([1, 0, 0])
microstructure = pulse.Microstructure(f0=f0)
geometry = pulse.Geometry(
mesh=mesh,
marker_functions=marker_functions,
microstructure=microstructure,
)
material_parameters = dict(
a=2.28,
a_f=1.686,
b=9.726,
b_f=15.779,
a_s=0.0,
b_s=0.0,
a_fs=0.0,
b_fs=0.0,
)
material = pulse.HolzapfelOgden(
active_model=active_model,
parameters=material_parameters,
activation=activation,
T_ref=T_ref,
)
problem = pulse.MechanicsProblem(geometry, material, bcs)
problem.solve()
if active_value > 0.0:
pulse.iterate.iterate(problem, activation, active_value)
return problem
def main():
N = 5
mesh = da.UnitCubeMesh(N, N, N)
W = df.FunctionSpace(mesh, "CG", 1)
active = da.Function(W)
problem = create_forward_problem(mesh, active, active_value=0.1)
u, _ = problem.state.split()
V = df.VectorFunctionSpace(mesh, "CG", 2)
u_synthetic = da.project(u, V)
active_ctrl = da.Function(W)
problem = create_forward_problem(mesh, active_ctrl, active_value=0.0)
u_model, _ = problem.state.split()
J = cost_function(
u_model,
u_synthetic,
)
cost_func_values = []
control_values = []
def eval_cb(j, m):
"""Callback function"""
cost_func_values.append(j)
control_values.append(m)
reduced_functional = da.ReducedFunctional(
J,
da.Control(active_ctrl),
eval_cb_post=eval_cb,
)
problem = da.MinimizationProblem(reduced_functional, bounds=[(0, 0.4)])
parameters = {
"limited_memory_initialization": "scalar2",
"maximum_iterations": 10,
}
solver = da.IPOPTSolver(problem, parameters=parameters)
optimal_control = solver.solve()
control_error = [df.assemble((c - active) ** 2 * df.dx) for c in control_values]
fig, ax = plt.subplots(2, 1, sharex=True)
ax[0].semilogy(cost_func_values)
ax[0].set_xlabel("#iterations")
ax[0].set_ylabel("cost function")
ax[1].semilogy(control_error)
ax[1].set_xlabel("#iterations")
ax[1].set_ylabel(r"$\int (\gamma - \gamma^*) \mathrm{d}x$")
fig.tight_layout()
fig.savefig("results")
mean = optimal_control.vector().get_local().mean()
std = optimal_control.vector().get_local().std()
print(f"Optimal control is {mean} +/- {std}")
if __name__ == "__main__":
main()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Input In [6], in <cell line: 1>()
1 if __name__ == "__main__":
----> 2 main()
Input In [5], in main()
1 def main():
2 N = 5
----> 3 mesh = da.UnitCubeMesh(N, N, N)
5 W = df.FunctionSpace(mesh, "CG", 1)
7 active = da.Function(W)
NameError: name 'da' is not defined