def binary_constraints(self, lower_bounds, upper_bounds):
		if upper_bounds is None:
			raise ValueError("Please supply upper bounds for the binary control variables.")

		n_turbines = len(self._parameters['binary'])

		lower_bounds = n_turbines*[dolfin_adjoint.Constant(lower_bounds)]
		upper_bounds = n_turbines*[dolfin_adjoint.Constant(upper_bounds)]
		return lower_bounds, upper_bounds
예제 #2
0
    def _build_function_space(self):
        class Exterior(fa.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and (fa.near(x[1], 1) or fa.near(x[0], 1) or
                                        fa.near(x[0], 0) or fa.near(x[1], 0))

        class Left(fa.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and fa.near(x[0], 0)

        class Right(fa.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and fa.near(x[0], 1)

        class Bottom(fa.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and fa.near(x[1], 0)

        class Top(fa.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and fa.near(x[1], 1)

        class Interior(fa.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and (x[0] > 0.1 and x[0] < 0.9
                                        and x[1] > 0.1 and x[1] < 0.9)

        self.exteriors_dic = {
            'left': Left(),
            'right': Right(),
            'bottom': Bottom(),
            'top': Top()
        }
        self.exterior = Exterior()
        self.interior = Interior()

        self.V = fa.FunctionSpace(self.mesh, 'P', 1)

        self.source = da.Expression(("100*sin(2*pi*x[0])"), degree=3)
        # self.source = da.Expression("k*100*exp( (-(x[0]-x0)*(x[0]-x0) -(x[1]-x1)*(x[1]-x1)) / (2*0.01*l) )",
        #                        k=1, l=1, x0=0.9, x1=0.1, degree=3)
        # self.source = da.Constant(10)
        self.source = da.interpolate(self.source, self.V)

        boundary_fn_ext = da.Constant(1.)
        boundary_fn_int = da.Constant(1.)
        boundary_bc_ext = da.DirichletBC(self.V, boundary_fn_ext,
                                         self.exterior)
        boundary_bc_int = da.DirichletBC(self.V, boundary_fn_int,
                                         self.interior)
        self.bcs = [boundary_bc_ext, boundary_bc_int]
def test_strain(isochoric=True):

    mesh = dolfin_adjoint.UnitCubeMesh(3, 3, 3)
    x_dir = dolfin_adjoint.Constant([1.0, 0.0, 0.0])
    y_dir = dolfin_adjoint.Constant([0.0, 1.0, 0.0])
    V = dolfin.VectorFunctionSpace(mesh, "CG", 2)
    # u = dolfin_adjoint.Function(V)

    # Make an incompressible deformation (with J = 1)
    x_strain = -0.1
    y_strain = 1 / (1 + x_strain) - 1
    u = dolfin_adjoint.interpolate(
        dolfin.Expression(
            ("x_strain * x[0]", "y_strain * x[1]", "0.0"),
            x_strain=x_strain,
            y_strain=y_strain,
            degree=2,
        ),
        V,
    )
    x_strain_obs = StrainObservation(mesh=mesh,
                                     field=x_dir,
                                     isochoric=isochoric,
                                     strain_tensor="gradu")

    assert abs(x_strain_obs(u).vector().get_local()[0] - x_strain) < 1e-12

    x_strain_obs = StrainObservation(mesh=mesh,
                                     field=x_dir,
                                     isochoric=isochoric,
                                     strain_tensor="E")

    assert (abs(
        x_strain_obs(u).vector().get_local()[0] - 0.5 *
        ((1 + x_strain)**2 - 1)) < 1e-12)

    y_strain_obs = StrainObservation(mesh=mesh,
                                     field=y_dir,
                                     isochoric=isochoric,
                                     strain_tensor="gradu")

    assert abs(y_strain_obs(u).vector().get_local()[0] - y_strain) < 1e-12

    y_strain_obs = StrainObservation(mesh=mesh,
                                     field=y_dir,
                                     isochoric=isochoric,
                                     strain_tensor="E")

    assert (abs(
        y_strain_obs(u).vector().get_local()[0] - 0.5 *
        ((1 + y_strain)**2 - 1)) < 1e-12)
예제 #4
0
    def friction_constraints(self, lower_bounds=0., upper_bounds=None):
        if (upper_bounds == None):
            upper_bounds = upper_bounds = self._turbine_specification.friction
        n_turbines = len(self.turbine_positions)
        if (self.n_time_steps == None):
            self.n_time_steps = 0
        elif (not self._turbine_specification.controls.dynamic_friction):
            self.n_time_steps = 0
        lower_bounds = (self.n_time_steps+1)*n_turbines*\
                       [dolfin_adjoint.Constant(lower_bounds)]
        upper_bounds = (self.n_time_steps+1)*n_turbines*\
                       [dolfin_adjoint.Constant(upper_bounds)]

        return lower_bounds, upper_bounds
예제 #5
0
    def __init__(self, bcs, solver_parameters, pressure):

        self._init_pressures(bcs["pressure"], pressure["p_lv"], "lv")
        self.p_lv.assign(dolfin_adjoint.Constant(float(self.lv_pressure[0])))

        if "p_rv" in pressure:
            self.has_rv = True
            self._init_pressures(bcs["rv_pressure"], pressure["p_rv"], "rv")
            self.p_rv.assign(
                dolfin_adjoint.Constant(float(self.rv_pressure[0])))
        else:
            self.has_rv = False

        # Mechanical solver Active strain Holzapfel and Ogden
        self.solver = create_mechanics_problem(solver_parameters)
예제 #6
0
    def __init__(
        self,
        mesh,
        field,
        strain_tensor="E",
        dmu=None,
        approx="original",
        F_ref=None,
        isochoric=True,
        displacement_space="CG_2",
        interpolation_space="CG_1",
        description="",
    ):

        ModelObservation.__init__(self,
                                  mesh,
                                  target_space="R_0",
                                  description=description)

        # Check that the given field is a vector of the same dim as the mesh
        dim = mesh.geometry().dim()
        # assert isinstance(field, (dolfin.Function, dolfin.Constant)
        assert field.ufl_shape[0] == dim
        approxs = ["project", "interpolate", "original"]
        msg = 'Expected "approx" for be one of {}, got {}'.format(
            approxs, approx)
        self.field = field

        assert approx in approxs, msg
        self._approx = approx

        self._F_ref = F_ref if F_ref is not None else dolfin.Identity(dim)

        self._isochoric = isochoric

        tensors = ["gradu", "E", "almansi"]
        msg = "Expected strain tensor to be one of {}, got {}".format(
            tensors, strain_tensor)
        assert strain_tensor in tensors, msg
        self._tensor = strain_tensor

        if dmu is None:
            dmu = dolfin.dx(domain=mesh)
        assert isinstance(dmu, dolfin.Measure)
        self._dmu = dmu

        self._vol = dolfin_adjoint.Constant(
            dolfin.assemble(dolfin.Constant(1.0) * dmu))

        # These spaces are only used if you want to project
        # or interpolate the displacement before assigning it
        # Space for interpolating the displacement if needed
        family, degree = interpolation_space.split("_")
        self._interpolation_space = dolfin.VectorFunctionSpace(
            mesh, family, int(degree))

        # Displacement space
        family, degree = displacement_space.split("_")
        self._displacement_space = dolfin.VectorFunctionSpace(
            mesh, family, int(degree))
예제 #7
0
def default_parameters(**values):
    """
    Parameter values
    """
    # Imports
    import dolfin
    import dolfin_adjoint

    # Param values
    # a=0.13, b=0.013, c_1=0.26, c_2=0.1, c_3=1.0, v_peak=40.0, v_rest=-85.0
    param_values = [0.13, 0.013, 0.26, 0.1, 1.0, 40.0, -85.0]
    param_names = ["a", "b", "c", "c_1", "c_2", "c_3", "v_peak", "v_rest"]

    # Parameter indices and limit checker
    param_ind = dict(a=(0, Range()), b=(1, Range()), c_1=(2, Range()),\
        c_2=(3, Range()), c_3=(4, Range()), v_peak=(5, Range()), v_rest=(6,\
        Range()))

    for param_name, value in list(values.items()):
        if param_name not in param_ind:
            raise ValueError("{{0}} is not a param".format(param_name))
        ind, range = param_ind[param_name]
        if value not in range:
            raise ValueError("While setting '{0}' {1}".format(param_name,\
                range.format_not_in(value)))

        # Assign value
        param_values[ind] = value

    params = []
    for (val, name) in zip(param_values, param_names):
        params.append(dolfin_adjoint.Constant(val, name=name))

    return params
예제 #8
0
    def validate(self):

        data_points = len(self.bcs[0].data)
        ref = self.bcs[0].bc
        for i in self.bcs:
            msg = (
                "Number of data points for BC {} is {} which does not "
                "match with {} which has {} data points"
                ""
            ).format(i.bc, len(i.data), ref, data_points)
            if len(i.data) != data_points:
                raise ValueError(msg)

        for i in self.targets:
            msg = (
                "Number of data points for target {} is {} which does not "
                "match with {} which has {} data point"
                ""
            ).format(i.model, len(i.observations), ref, data_points)
            if len(i.observations) != data_points:
                raise ValueError(msg)
        self.data_points = data_points

        try:
            meshvol = self.problem.geometry.meshvol
        except AttributeError:
            meshvol = compute_meshvolume(self.problem.geometry.mesh)
        self._meshvol = dolfin_adjoint.Constant(meshvol)
def test_boundary_observation():

    bc = pulse.NeumannBC(traction=dolfin_adjoint.Constant(0.0),
                         marker=0,
                         name="test bc")
    pressures = (0.0, 0.1, 0.2)
    bcs = BoundaryObservation(bc=bc, data=pressures)

    for i, b in enumerate(bcs):
        b.assign_bc()
        assert abs(float(b.bc.traction) - pressures[i]) < 1e-12
예제 #10
0
    def site_boundary_constraints(self):
        """Returns the site boundary constraints for a rectangular site.

        These constraints ensure that the turbine positions remain within the
        turbine site during optimisation.

        :raises: ValueError
        :returns: Tuple of lists of length equal to the twice the number of
            turbines. Each list contains dolfin_adjoint.Constant objects of the
            upper and lower bound coordinates.

        """
        # Check we have deployed some turbines in the farm.
        n_turbines = len(self.turbine_positions)
        if (n_turbines < 1):
            raise ValueError("You must deploy turbines before computing "
                             "position constraints.")

        radius = self._turbine_specification.radius
        # Get the lower and upper bounds.
        lower_x = self.site_x_start + radius
        lower_y = self.site_y_start + radius
        upper_x = self.site_x_end - radius
        upper_y = self.site_y_end - radius

        # Check the site is large enough.
        if upper_x < lower_x or upper_y < lower_y:
            raise ValueError("Lower bound is larger than upper bound. Is your "
                             "domain large enough?")

        # The control variable is ordered as [t1_x, t1_y, t2_x, t2_y, t3_x, ...]
        lower_bounds = n_turbines * [
            dolfin_adjoint.Constant(lower_x),
            dolfin_adjoint.Constant(lower_y)
        ]
        upper_bounds = n_turbines * [
            dolfin_adjoint.Constant(upper_x),
            dolfin_adjoint.Constant(upper_y)
        ]

        return lower_bounds, upper_bounds
예제 #11
0
파일: matlab.py 프로젝트: tianjuxue/crack
    def set_bcs_staggered(self):
        self.upper.mark(self.boundaries, 1)

        self.presLoad = da.Expression((0, "t"), t=0.0, degree=1)
        BC_u_lower = da.DirichletBC(self.U, da.Constant((0., 0.)), self.lower)
        BC_u_upper = da.DirichletBC(self.U, self.presLoad, self.upper)

        BC_d_middle = fe.DirichletBC(self.W,
                                     fe.Constant(1.),
                                     self.middle,
                                     method='pointwise')

        self.BC_u = [BC_u_lower, BC_u_upper]
        self.BC_d = [BC_d_middle]
예제 #12
0
 def form(self):
     if self.reg_type == "":
         return dolfin_adjoint.Constant(0.0)
     elif self.reg_type == "L2":
         return L2(self.f)
     elif self.reg_type == "H0":
         return H0(self.f)
     elif self.reg_type == "H1":
         return H1(self.f)
     elif self.reg_type == "regional":
         return regional(self.f)
     else:
         raise ValueError("Unknown regularization type {}".format(
             self.reg_type))
예제 #13
0
    def __init__(self,
                 observations,
                 model_observation,
                 weight=1.0,
                 collect=True):

        assert isinstance(model_observation, ModelObservation)
        self.model = model_observation

        if np.isscalar(observations):
            self.observations = (observations, )
        elif isinstance(observations, tuple):
            self.observations = observations
        else:
            self.observations = tuple(observations)

        self._V = dolfin.FunctionSpace(model_observation.mesh, "R", 0)
        # self._functional = dolfin_adjoint.Function(
        #     self._V, name="functional {}".format(self.model)
        # )
        #
        # self.model_function = dolfin_adjoint.Function(
        #     self.model._V, name="model function {}".format(self.model)
        # )
        # self.data_function = dolfin_adjoint.Function(
        #     self.model._V, name="data function {}".format(self.model)
        # )

        # Test and trial functions for the target space
        self._trial = dolfin.TrialFunction(self._V)
        self._test = dolfin.TestFunction(self._V)

        self.weight = dolfin_adjoint.Constant(weight,
                                              name="Weight {}".format(
                                                  self.model))

        self.__len__ = len(self.observations)
        self._load_observations()

        self.collector = dict(model=[], data=[], functional=[])
        self.collect = collect

        self.reset()
예제 #14
0
    def __init__(
        self,
        mesh,
        dmu,
        approx="project",
        displacement_space="CG_2",
        interpolation_space="CG_1",
        description="",
    ):
        ModelObservation.__init__(self,
                                  mesh,
                                  target_space="R_0",
                                  description=description)

        approxs = ["project", "interpolate", "original"]
        msg = 'Expected "approx" for be one of {}, got {}'.format(
            approxs, approx)
        assert approx in approxs, msg
        self._approx = approx

        # These spaces are only used if you want to project
        # or interpolate the displacement before assigning it
        # Space for interpolating the displacement if needed
        family, degree = interpolation_space.split("_")
        self._interpolation_space = dolfin.VectorFunctionSpace(
            mesh, family, int(degree))

        # Displacement space
        family, degree = displacement_space.split("_")
        self._displacement_space = dolfin.VectorFunctionSpace(
            mesh, family, int(degree))

        self._X = dolfin.SpatialCoordinate(mesh)
        self._N = dolfin.FacetNormal(mesh)
        assert isinstance(dmu, dolfin.Measure)
        self._dmu = dmu

        name = "EndoArea {}".format(self)
        self._endoarea = dolfin_adjoint.Constant(dolfin.assemble(
            dolfin.Constant(1.0) * dmu),
                                                 name=name)
def test_strain(strains):

    mesh = dolfin_adjoint.UnitCubeMesh(3, 3, 3)
    x_dir = dolfin_adjoint.Constant([1.0, 0.0, 0.0])
    V = dolfin.VectorFunctionSpace(mesh, "CG", 2)

    # Make an incompressible deformation (with J = 1)
    x_strain = -0.1
    y_strain = 1 / (1 + x_strain) - 1
    u = dolfin_adjoint.interpolate(
        dolfin.Expression(
            ("x_strain * x[0]", "y_strain * x[1]", "0.0"),
            x_strain=x_strain,
            y_strain=y_strain,
            degree=2,
        ),
        V,
    )
    strain_obs = StrainObservation(mesh=mesh, field=x_dir)

    model_strain = strain_obs(u).vector().get_local()[0]
    weight = 0.1
    target = OptimizationTarget(strains,
                                strain_obs,
                                weight=weight,
                                collect=False)
    if np.isscalar(strains):
        strains = (strains, )

    for t, s in zip(target, strains):
        fun = dolfin.project(t.assign(u), t._V)
        f = fun.vector().get_local()[0]
        g = (model_strain - s)**2
        assert abs(f - weight * g) < 1e-12

    # Nothing is collected
    for k, v in target.collector.items():
        assert len(v) == 0
예제 #16
0
import fenics as fa
import dolfin_adjoint as da
import numpy as np
import moola

n = 64
alpha = da.Constant(0)
mesh = da.UnitSquareMesh(n, n)

# case_flag = 0 runs the default case by
# http://www.dolfin-adjoint.org/en/latest/documentation/poisson-mother/poisson-mother.html
# change to any other value runs the other case
case_flag = 1

x = fa.SpatialCoordinate(mesh)
w = da.Expression("sin(pi*x[0])*sin(pi*x[1])", degree=3)

V = fa.FunctionSpace(mesh, "CG", 1)
W = fa.FunctionSpace(mesh, "DG", 0)

# g is the ground truth for source term
# f is the control variable
if case_flag == 0:
    g = da.interpolate(
        da.Expression("1/(1+alpha*4*pow(pi, 4))*w", w=w, alpha=alpha,
                      degree=3), W)
    f = da.interpolate(
        da.Expression("1/(1+alpha*4*pow(pi, 4))*w", w=w, alpha=alpha,
                      degree=3), W)
else:
    g = da.interpolate(da.Expression(("sin(2*pi*x[0])"), degree=3), W)
예제 #17
0
def test_constant_regularization(value, reg_type, weight,
                                 expected_functional_value):
    f = da.Constant(value, cell="tetrahedron")
    reg = Regularization(f, weight=weight, reg_type=reg_type)
    assert abs(float(reg.functional) - expected_functional_value) < 1e-12
예제 #18
0
 def reset(self) -> None:
     self._count = -1
     name = "Start value Boundary {}".format(self.bc)
     self.bc.traction.assign(dolfin_adjoint.Constant(self._start_value, name=name))
예제 #19
0
def create_problem():

    geometry = pulse.HeartGeometry.from_file(
        pulse.mesh_paths["simple_ellipsoid"])

    activation = dolfin_adjoint.Function(dolfin.FunctionSpace(
        geometry.mesh, "R", 0),
                                         name="activation")
    activation.assign(dolfin_adjoint.Constant(0.0))
    matparams = pulse.HolzapfelOgden.default_parameters()

    V = dolfin.FunctionSpace(geometry.mesh, "R", 0)
    control = dolfin_adjoint.Function(V)
    control.assign(dolfin_adjoint.Constant(1.0))
    # control = dolfin_adjoint.Constant(1.0, name="matparam control (a)")
    matparams["a"] = control

    f0 = dolfin_adjoint.Function(geometry.f0.function_space())
    f0.assign(geometry.f0)
    s0 = dolfin_adjoint.Function(geometry.s0.function_space())
    s0.assign(geometry.s0)
    n0 = dolfin_adjoint.Function(geometry.n0.function_space())
    n0.assign(geometry.n0)

    material = pulse.HolzapfelOgden(activation=activation,
                                    parameters=matparams,
                                    f0=f0,
                                    s0=s0,
                                    n0=n0)

    # LV Pressure
    lvp = dolfin_adjoint.Constant(0.0, name="lvp")
    lv_marker = geometry.markers["ENDO"][0]
    lv_pressure = pulse.NeumannBC(traction=lvp, marker=lv_marker, name="lv")
    neumann_bc = [lv_pressure]

    # Add spring term at the base with stiffness 1.0 kPa/cm^2
    base_spring = 1.0
    robin_bc = [
        pulse.RobinBC(
            value=dolfin_adjoint.Constant(base_spring, name="base_spring"),
            marker=geometry.markers["BASE"][0],
        )
    ]

    # Fix the basal plane in the longitudinal direction
    # 0 in V.sub(0) refers to x-direction, which is the longitudinal direction
    def fix_basal_plane(W):
        V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0)
        bc = dolfin_adjoint.DirichletBC(
            V.sub(0),
            dolfin.Constant(0.0, name="fix_base"),
            geometry.ffun,
            geometry.markers["BASE"][0],
        )
        return bc

    dirichlet_bc = [fix_basal_plane]

    # Collect boundary conditions
    bcs = pulse.BoundaryConditions(dirichlet=dirichlet_bc,
                                   neumann=neumann_bc,
                                   robin=robin_bc)

    # Create the problem
    problem = pulse.MechanicsProblem(geometry, material, bcs)

    return problem, control
예제 #20
0
 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)
예제 #21
0
 def __init__(self, f, weight=1.0, reg_type="L2"):
     self.f = f
     self.weight = dolfin_adjoint.Constant(weight,
                                           name="Regularization weight")
     self.reg_type = reg_type
예제 #22
0
 def assign_bc(self):
     data = self.data[self.count]
     name = "Data ({}) Boundary {}".format(self.count, self.bc)
     dolfin_data = dolfin_adjoint.Constant(data, name=name)
     self.bc.traction.assign(dolfin_data)
예제 #23
0
    def friction_constraints(self):
        n_turbines = len(self.turbine_positions)
        lower_bounds = n_turbines*[dolfin_adjoint.Constant(0)]
        upper_bounds = n_turbines*[dolfin_adjoint.Constant(self._turbine_specification.friction)]

        return lower_bounds, upper_bounds