Skip to content

Commit

Permalink
Release v1.0.2: Extended the range of elements which are capable of t…
Browse files Browse the repository at this point in the history
…reating control constraints

These now include CG1, DG0, and R elements. Also added compatibility for (arbitrary) mixed controls.
Added tests to verify the expected behavior und test_optimal_control.py
  • Loading branch information
sblauth committed Sep 23, 2020
1 parent fc2bc8c commit 49f98fb
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 10 deletions.
9 changes: 4 additions & 5 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
Change Log
==========

1.0.1 (September 18, 2020)
--------------------------

- Updated the installation instructions, so that a correct version of meshio / h5py
is installed with the default instructions.
This is CASHOCS' change log. Note, that only major and minor releases are covered
here as they add new functionality or might change the API. For a documentation
of the maintenance releases, please take a look at
`<https://github.com/sblauth/cashocs/releases>`_.

1.0.0 (September 18, 2020)
--------------------------
Expand Down
22 changes: 19 additions & 3 deletions cashocs/_optimal_control/optimal_control_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,25 @@ def __init__(self, state_forms, bcs_list, cost_functional_form, states, controls
pass
else:
self.require_control_constraints[idx] = True
if not (self.controls[idx].ufl_element().family() == 'Lagrange' and self.controls[idx].ufl_element().degree() == 1):
raise InputError('cashocs._optimization.optimal_control_problem.OptimalControlProblem', 'controls',
'Control constraints are only implemented for linear Lagrange elements')

control_element = self.controls[idx].ufl_element()
if control_element.family() == 'Mixed':
for j in range(control_element.value_size()):
sub_elem = control_element.extract_component(j)[1]
if sub_elem.family() == 'Real' or (sub_elem.family() == 'Lagrange' and sub_elem.degree() == 1) \
or (sub_elem.family() == 'Discontinuous Lagrange' and sub_elem.degree() == 0):
pass
else:
raise InputError('cashocs._optimization.optimal_control_problem.OptimalControlProblem', 'controls',
'Control constraints are only implemented for linear Lagrange, constant Discontinuous Lagrange, and Real elements.')

else:
if control_element.family() == 'Real' or (control_element.family() == 'Lagrange' and control_element.degree() == 1) \
or (control_element.family() == 'Discontinuous Lagrange' and control_element.degree() == 0):
pass
else:
raise InputError('cashocs._optimization.optimal_control_problem.OptimalControlProblem', 'controls',
'Control constraints are only implemented for linear Lagrange, constant Discontinuous Lagrange, and Real elements.')

if not len(self.riesz_scalar_products) == self.control_dim:
raise InputError('cashocs._optimization.optimal_control_problem.OptimalControlProblem', 'riesz_scalar_products', 'Length of controls does not match')
Expand Down
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
author = 'Sebastian Blauth'

# The full version, including alpha/beta/rc tags
release = '1.0.1'
release = '1.0.2'


# -- General configuration ---------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="cashocs",
version="1.0.1",
version="1.0.2",
author="Sebastian Blauth",
author_email="[email protected]",
description="Computational Adjoint-Based Shape Optimization and Optimal Control Software",
Expand Down
40 changes: 40 additions & 0 deletions tests/test_optimal_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
"""

import pytest
import numpy as np
from fenics import *

import cashocs
from cashocs._exceptions import InputError



Expand All @@ -48,6 +50,42 @@
ocp_cc = cashocs.OptimalControlProblem(F, bcs, J, y, u, p, config, control_constraints=cc)


def test_control_constraints_handling():
cg1_elem = FiniteElement('CG', mesh.ufl_cell(), 1)
vcg1_elem = VectorElement('CG', mesh.ufl_cell(), 1)
vcg2_elem = VectorElement('CG', mesh.ufl_cell(), 2)
real_elem = FiniteElement('R', mesh.ufl_cell(), 0)
dg0_elem = FiniteElement('DG', mesh.ufl_cell(), 0)
vdg0_elem = VectorElement('DG', mesh.ufl_cell(), 0)
dg1_elem = FiniteElement('DG', mesh.ufl_cell(), 1)
rt_elem = FiniteElement('RT', mesh.ufl_cell(), 1)

mixed_elem = MixedElement([cg1_elem, dg0_elem, vdg0_elem])
pass_elem = MixedElement([cg1_elem, real_elem, dg0_elem, vcg1_elem, mixed_elem])
fail_elem1 = MixedElement([mixed_elem, cg1_elem, vdg0_elem, real_elem, rt_elem])
fail_elem2 = MixedElement([dg1_elem, mixed_elem, cg1_elem, vdg0_elem, real_elem])
fail_elem3 = MixedElement([mixed_elem, cg1_elem, vcg2_elem, vdg0_elem, real_elem])

pass_space = FunctionSpace(mesh, pass_elem)
pass_control = Function(pass_space)

fail_space1 = FunctionSpace(mesh, fail_elem1)
fail_space2 = FunctionSpace(mesh, fail_elem2)
fail_space3 = FunctionSpace(mesh, fail_elem3)
fail_control1 = Function(fail_space1)
fail_control2 = Function(fail_space2)
fail_control3 = Function(fail_space3)

ocp_cc_pass = cashocs.OptimalControlProblem(F, bcs, J, y, pass_control, p, config, control_constraints=cc)

with pytest.raises(InputError):
ocp_cc_fail1 = cashocs.OptimalControlProblem(F, bcs, J, y, fail_control1, p, config, control_constraints=cc)
with pytest.raises(InputError):
ocp_cc_fail2 = cashocs.OptimalControlProblem(F, bcs, J, y, fail_control2, p, config, control_constraints=cc)
with pytest.raises(InputError):
ocp_cc_fail3 = cashocs.OptimalControlProblem(F, bcs, J, y, fail_control3, p, config, control_constraints=cc)



def test_control_gradient():
assert cashocs.verification.control_gradient_test(ocp) > 1.9
Expand Down Expand Up @@ -321,3 +359,5 @@ def test_control_pdas_newton():
assert ocp_cc.solver.converged
assert np.alltrue(ocp_cc.controls[0].vector()[:] >= cc[0])
assert np.alltrue(ocp_cc.controls[0].vector()[:] <= cc[1])


0 comments on commit 49f98fb

Please sign in to comment.