def test_spatial_convergence_is_two(self, sw_linear_problem_parameters,
            sin_ic):
        # Compute the errors
        errors = []
        levels = 3
        finish_time = 5.

        for l in range(levels):

            mesh_x = 4 * 2**l
            mesh_y = 2
            time_step = 0.25

            model = setup_model(sw_linear_problem_parameters, sin_ic, time_step, 
                                finish_time, mesh_x, mesh_y)
            error = compute_error(*model)
            errors.append(error)

        # Compute the orders of convergence
        conv = []
        for i in range(len(errors)-1):
            convergence_order = -math.log(errors[i+1]/errors[i], 2)
            conv.append(convergence_order)

        # Check the minimum convergence order and exit
        log(INFO, "Spatial order of convergence (expecting 2.0): %s." % conv)

        assert min(conv) > 1.9
    def test_derivative(self):

        turbine = BumpTurbine(diameter=10.0, friction=1.0)
        domain = RectangularDomain(0, 0, 3000, 1000, 20, 3)
        farm = Farm(domain, turbine)
        farm.add_turbine((1500, 500))

        ieq = farm.minimum_distance_constraints()

        # Only test the correctness of the first inequality constraint for simplicity
        ieqcons_J = lambda m: ieq.function(m)[0]
        ieqcons_dJ = lambda m, forget=False: ieq.jacobian(m)[0]

        x = numpy.array([1., 2., 3., 4., 7., 1., 6., 9.])
        minconv = helpers.test_gradient_array(ieqcons_J, ieqcons_dJ, x)

        assert minconv > 1.99

        ieq = ConvexPolygonSiteConstraint(farm, [[0, 0], [10, 0], [10, 10]])

        # Only test the correctness of the first inequality constraint for
        # simplicity.
        ieqcons_J = lambda m: ieq.function(m)[0]
        ieqcons_dJ = lambda m, forget=False: ieq.jacobian(m)[0]

        # This will raise a RunetimeWarning, which is fine because we expect
        # division by zero
        x = numpy.array([0, 0, 10, 4, 20, 8])
        minconv = helpers.test_gradient_array(ieqcons_J, ieqcons_dJ, x=x,
                                              seed=0.1)

        # These constraints are linear so we expect no convergence at all.
        # Let's check that the tolerance is not above a threshold
        log(INFO, "Expecting a Nan convergence order")
        assert math.isnan(minconv)
    def test_spatial_convergence_is_two(self, sw_linear_problem_parameters,
                                        sin_ic):
        # Compute the errors
        errors = []
        levels = 3
        finish_time = 5.

        for l in range(levels):

            mesh_x = 4 * 2**l
            mesh_y = 2
            time_step = 0.25

            model = setup_model(sw_linear_problem_parameters, sin_ic,
                                time_step, finish_time, mesh_x, mesh_y)
            error = compute_error(*model)
            errors.append(error)

        # Compute the orders of convergence
        conv = []
        for i in range(len(errors) - 1):
            convergence_order = -math.log(errors[i + 1] / errors[i], 2)
            conv.append(convergence_order)

        # Check the minimum convergence order and exit
        log(INFO, "Spatial order of convergence (expecting 2.0): %s." % conv)

        assert min(conv) > 1.9
Beispiel #4
0
 def load_checkpoint(self, filename):
     try:
         self.memo = pickle.load(open(filename, "rb"))
     except IOError:
         log(WARNING, "Warning: Checkpoint file '%s' not found." % filename)
     except ValueError:
         log(WARNING, "Error: Checkpoint file '%s' is invalid." % filename)
Beispiel #5
0
    def function(self, m):
        """Return an object which must be zero for the point to be feasible.

        :param m: The serialized paramaterisation of the turbines.
        :tpye m: numpy.ndarray.
        :returns: numpy.ndarray -- each entry must be zero for a poinst to be
            feasible.

        """
        dolfin.log(dolfin.PROGRESS, "Calculating minimum distance constraints.")
        inequality_constraints = []
        for i in range(len(m)/2):
            for j in range(len(m)/2):
                if i <= j:
                    continue
                inequality_constraints.append(self._sl2norm([m[2*i]-m[2*j],
                                                             m[2*i+1]-m[2*j+1]])
                                              - self._minimum_distance**2)

        inequality_constraints = numpy.array(inequality_constraints)
        if any(inequality_constraints <= 0):
            dolfin.log(dolfin.WARNING,
                       "Minimum distance inequality constraints (should all "
                       "be > 0): %s" % inequality_constraints)
        return inequality_constraints
Beispiel #6
0
def get_distance_function(config, domains):
    V = dolfin.FunctionSpace(config.domain.mesh, "CG", 1)
    v = dolfin.TestFunction(V)
    d = dolfin.TrialFunction(V)
    sol = dolfin.Function(V)
    s = dolfin.interpolate(Constant(1.0), V)
    domains_func = dolfin.Function(dolfin.FunctionSpace(config.domain.mesh, "DG", 0))
    domains_func.vector().set_local(domains.array().astype(numpy.float))

    def boundary(x):
        eps_x = config.params["turbine_x"]
        eps_y = config.params["turbine_y"]

        min_val = 1
        for e_x, e_y in [(-eps_x, 0), (eps_x, 0), (0, -eps_y), (0, eps_y)]:
            try:
                min_val = min(min_val, domains_func((x[0] + e_x, x[1] + e_y)))
            except RuntimeError:
                pass

        return min_val == 1.0

    bc = dolfin.DirichletBC(V, 0.0, boundary)

    # Solve the diffusion problem with a constant source term
    log(INFO, "Solving diffusion problem to identify feasible area ...")
    a = dolfin.inner(dolfin.grad(d), dolfin.grad(v)) * dolfin.dx
    L = dolfin.inner(s, v) * dolfin.dx
    dolfin.solve(a == L, sol, bc)

    return sol
Beispiel #7
0
 def load_checkpoint(self, filename):
     try:
         self.memo = cPickle.load(open(filename, "rb"))
     except IOError:
         log(WARNING, "Warning: Checkpoint file '%s' not found." % filename)
     except ValueError:
         log(WARNING, "Error: Checkpoint file '%s' is invalid." % filename)
Beispiel #8
0
    def function(self, m):
        """Return an object which must be >0 for the point to be feasible.

        :param m: The serialized paramaterisation of the turbines.
        :tpye m: numpy.ndarray.
        :returns: numpy.ndarray -- each entry must be zero for a poinst to be
            feasible.

        """
        dolfin.log(dolfin.PROGRESS, "Calculating minimum distance constraints.")

        if self._controls.position and self._controls.friction:
            friction_length = len(m)/3
            m = m[friction_length:]

        value = 0
        for i in range(len(m)/2):
            for j in range(len(m)/2):
                if i <= j:
                    continue
                dist_sq = self._sl2norm([m[2*i]-m[2*j],
                                         m[2*i+1]-m[2*j+1]])
                value += self._penalty(dist_sq)

        if value <= 0:
            dolfin.log(dolfin.WARNING,
                       "Minimum distance inequality constraints (should all "
                       "be => 0): %s" % value)
        return numpy.array([value])
Beispiel #9
0
    def __init__(self, config, feasible_area, attraction_center):
        '''
           Generates the inequality constraints to enforce the turbines in the feasible area.
           If the turbine is outside the domain, the constraints is equal to the distance between the turbine and the attraction center.
        '''
        self.config = config
        self.feasible_area = feasible_area

        # Compute the gradient of the feasible area
        fs = dolfin.FunctionSpace(feasible_area.function_space().mesh(),
                                  "DG",
                                  feasible_area.function_space().ufl_element().degree() - 1)

        feasible_area_grad = (dolfin.Function(fs),
                              dolfin.Function(fs))
        t = dolfin.TestFunction(fs)
        log(INFO, "Solving for gradient of feasible area")
        for i in range(2):
            form = dolfin.inner(feasible_area_grad[i], t) * dolfin.dx - dolfin.inner(feasible_area.dx(i), t) * dolfin.dx
            if dolfin.NonlinearVariationalSolver.default_parameters().has_parameter("linear_solver"):
                dolfin.solve(form == 0, feasible_area_grad[i], solver_parameters={"linear_solver": "cg", "preconditioner": "amg"})
            else:
                dolfin.solve(form == 0, feasible_area_grad[i], solver_parameters={"newton_solver": {"linear_solver": "cg", "preconditioner": "amg"}})
        self.feasible_area_grad = feasible_area_grad

        self.attraction_center = attraction_center
    def test_optimisation_recovers_optimal_position(self):
        problem = self.default_problem()
        farm = problem.parameters.tidal_farm

        solver = DummySolver(problem)
        functional = PowerFunctional(problem)
        control = TurbineFarmControl(farm)
        rf_params = ReducedFunctionalParameters()
        rf_params.automatic_scaling = 5.
        rf = ReducedFunctional(functional, control, solver, rf_params)
        m0 = farm.control_array

        p = numpy.random.rand(len(m0))
        minconv = helpers.test_gradient_array(rf.__call__, rf.derivative, m0, seed=0.005,
                                              perturbation_direction=p)
        assert minconv > 1.9

        bounds = [[Constant(0), Constant(0)], [Constant(3000), Constant(1000)]]
        maximize(rf, bounds=bounds, method="SLSQP")

        m = farm._parameters["position"][0]
        log(INFO, "Solution of the primal variables: m=" + repr(m) + "\n")

        assert abs(m[0]-1500) < 40
        assert abs(m[1]-500) < 0.4
    def function(self, m):
        ieqcons = []
        if len(self.config.params['controls']) == 2:
            # If the controls consists of the the friction and the positions, then we need to first extract the position part
            assert (len(m) % 3 == 0)
            m_pos = m[len(m) / 3:]
        else:
            m_pos = m

        for i in range(len(m_pos) / 2):
            x = m_pos[2 * i]
            y = m_pos[2 * i + 1]
            try:
                ieqcons.append(function_eval(self.feasible_area, (x, y)))
            except RuntimeError:
                print "Warning: a turbine is outside the domain"
                ieqcons.append((x - self.attraction_center[0])**2 +
                               (y - self.attraction_center[1])**
                               2)  # Point is outside domain

        arr = -numpy.array(ieqcons)
        if any(arr <= 0):
            log(
                INFO,
                "Domain restriction inequality constraints (should be >= 0): %s"
                % arr)
        return arr
Beispiel #12
0
    def test_optimisation_recovers_optimal_position(self):
        problem = self.default_problem()
        farm = problem.parameters.tidal_farm

        solver = DummySolver(problem)
        functional = PowerFunctional(problem)
        control = TurbineFarmControl(farm)
        rf_params = ReducedFunctionalParameters()
        rf_params.automatic_scaling = 5.
        rf = ReducedFunctional(functional, control, solver, rf_params)
        m0 = farm.control_array

        p = numpy.random.rand(len(m0))
        minconv = helpers.test_gradient_array(rf.__call__,
                                              rf.derivative,
                                              m0,
                                              seed=0.005,
                                              perturbation_direction=p)
        assert minconv > 1.9

        bounds = [[Constant(0), Constant(0)], [Constant(3000), Constant(1000)]]
        maximize(rf, bounds=bounds, method="SLSQP")

        m = farm._parameters["position"][0]
        log(INFO, "Solution of the primal variables: m=" + repr(m) + "\n")

        assert abs(m[0] - 1500) < 40
        assert abs(m[1] - 500) < 0.4
Beispiel #13
0
    def __call__(self, *args, **kwds):
        h = self.get_key(args, kwds)

        if h not in self.memo:
            self.memo[h] = self.fn(*args, **kwds)
        else:
            log(INFO, "Use checkpoint value.")
        return self.memo[h]
Beispiel #14
0
    def __call__(self, *args, **kwds):
        h = self.get_key(args, kwds)

        if h not in self.memo:
            self.memo[h] = self.fn(*args, **kwds)
        else:
            log(INFO, "Use checkpoint value.")
        return self.memo[h]
Beispiel #15
0
    def derivative(self, forget=False, **kwargs):
        """ Computes the first derivative of the functional with respect to its
        controls by solving the adjoint equations. """

        log(INFO, 'Start evaluation of dj')
        timer = Timer("dj evaluation")

        self.functional = self.time_integrator.dolfin_adjoint_functional(self.solver.state)
        dj = compute_gradient(self.functional, self.controls, forget=forget, **kwargs)
        parameters["adjoint"]["stop_annotating"] = False

        log(INFO, "Runtime: " + str(timer.stop()) + " s")

        return enlisting.enlist(dj)
    def test_temporal_convergence_is_two(self, sw_linear_problem_parameters, sin_ic):
        errors = []
        tests = 4
        for refinement_level in range(tests):
            error = self.compute_temporal_error(sw_linear_problem_parameters, refinement_level, sin_ic)
            errors.append(error)
        # Compute the order of convergence
        conv = []
        for i in range(len(errors) - 1):
            conv.append(-math.log(errors[i + 1] / errors[i], 2))

        log(INFO, "Temporal Taylor remainders: %s" % errors)
        log(INFO, "Temporal order of convergence (expecting 2.0): %s" % conv)
        assert min(conv) > 1.8
Beispiel #17
0
    def read(self, filename="muflon-parameters.xml"):
        """
        Read parameters from XML file.

        :param filename: name of the input XML file (can be relative or
                         absolute path)
        :type filename: str
        """
        filename += ".xml" if filename[-4:] != ".xml" else ""
        if os.path.isfile(filename) and os.access(filename, os.R_OK):
            log(DEBUG, "Reading default values from '%s'" % filename)
            with File(filename) as xmlfile:
                xmlfile >> self
        else:
            log(DEBUG, "File '%s' is missing or not readable." % filename)
Beispiel #18
0
    def test_spatial_convergence_is_two(self, sw_linear_problem_parameters,
            sin_ic):
        errors = []
        tests = 4
        for refinement_level in range(tests):
            errors.append(self.compute_spatial_error(sw_linear_problem_parameters,
                                                     refinement_level, sin_ic))
        # Compute the order of convergence
        conv = []
        for i in range(len(errors)-1):
            conv.append(-math.log(errors[i+1]/errors[i], 2))

        log(INFO, "Errors: %s" % errors)
        log(INFO, "Spatial order of convergence (expecting 2.0): %s" % conv)
        assert min(conv) > 1.8
    def test_spatial_convergence_is_first_order(self, sw_nonlinear_problem_parameters):
        errors = []
        tests = 4
        for refinement_level in range(tests):
            error = self.compute_spatial_error(sw_nonlinear_problem_parameters,
                                               refinement_level)
            errors.append(error)
        # Compute the order of convergence
        conv = []
        for i in range(len(errors)-1):
            conv.append(-math.log(errors[i+1] / errors[i], 2))

        log(INFO, "Spatial Taylor remainders are : %s" % str(errors))
        log(INFO, "Spatial order of convergence (expecting 1.0): %s" % str(conv))
        assert min(conv) > 1.0
Beispiel #20
0
    def matvec(self, b):
        from time import time
        from block.block_vec import block_vec
        from dolfin import log, info, Progress
        TRACE = 13 # dolfin.TRACE

        T = time()

        # If x and initial_guess are block_vecs, some of the blocks may be
        # scalars (although they are normally converted to vectors by bc
        # application). To be sure, call allocate() on them.

        if isinstance(b, block_vec):
            # Create a shallow copy to call allocate() on, to avoid changing the caller's copy of b
            b = block_vec(len(b), b.blocks)
            b.allocate(self.A, dim=0)

        if self.initial_guess:
            # Most (all?) solvers modify x, so make a copy to avoid changing
            # the caller's copy of x
            from block.block_util import copy
            x = copy(self.initial_guess)
            if isinstance(x, block_vec):
                x.allocate(self.A, dim=1)
        else:
            x = self.A.create_vec(dim=1)
            x.zero()

        try:
            log(TRACE, self.__class__.__name__+' solve of '+str(self.A))
            if self.B != 1.0:
                log(TRACE, 'Using preconditioner: '+str(self.B))
            progress = Progress(self.name, self.maxiter)
            if self.tolerance < 0:
                tolerance = -self.tolerance
                relative = True
            else:
                tolerance = self.tolerance
                relative = False
            x = self.method(self.B, self.AR, x, b, tolerance=tolerance,
                            relativeconv=self.relativeconv, maxiter=self.maxiter,
                            progress=progress, callback=self.callback,
                            **self.kwargs)
            del progress # trigger final printout
        except Exception, e:
            from dolfin import warning
            warning("Error solving " + self.name)
            raise
Beispiel #21
0
    def test_temporal_convergence_is_two(self, sw_linear_problem_parameters):
        errors = []
        tests = 4
        for refinement_level in range(tests):
            error = self.compute_temporal_error(sw_linear_problem_parameters,
                                                refinement_level)
            errors.append(error)
        # Compute the order of convergence
        conv = []
        for i in range(len(errors) - 1):
            conv.append(-math.log(errors[i + 1] / errors[i], 2))

        log(INFO, "Temporal Taylor remainders are : %s" % str(errors))
        log(INFO,
            "Temporal order of convergence (expecting 2.0): %s" % str(conv))
        assert min(conv) > 1.8
    def jacobian(self, m):
        """Returns the gradient of the constraint function.

        Return a list of vector-like objects representing the gradient of the
        constraint function with respect to the parameter m.

        :param m: The serialized paramaterisation of the turbines.
        :tpye m: numpy.ndarray.
        :returns: numpy.ndarray -- the gradient of the constraint function with
            respect to each input parameter m.

        """
        dolfin.log(
            dolfin.PROGRESS, "Calculating the jacobian of minimum "
            "distance constraints function.")
        inequality_constraints = []

        if self._controls.position and self._controls.friction:
            friction_length = len(m) / 3
            m = m[friction_length:]
        else:
            friction_length = 0

        p_ineq_c = numpy.zeros(friction_length + len(m))

        for i in range(len(m) / 2):
            for j in range(len(m) / 2):
                if i <= j:
                    continue

                dist_sq = self._sl2norm(
                    [m[2 * i] - m[2 * j], m[2 * i + 1] - m[2 * j + 1]])
                dvalue = self._dpenalty(dist_sq)

                # The control vector contains the friction coefficients first,
                # so we need to shift here
                p_ineq_c[friction_length +
                         2 * i] += dvalue * 2 * (m[2 * i] - m[2 * j])
                p_ineq_c[friction_length +
                         2 * j] += dvalue * (-2 * (m[2 * i] - m[2 * j]))
                p_ineq_c[friction_length + 2 * i +
                         1] += dvalue * 2 * (m[2 * i + 1] - m[2 * j + 1])
                p_ineq_c[friction_length + 2 * j +
                         1] += dvalue * (-2 * (m[2 * i + 1] - m[2 * j + 1]))

        return numpy.array([p_ineq_c])
    def jacobian(self, m):
        """Returns the gradient of the constraint function.

        Return a list of vector-like objects representing the gradient of the
        constraint function with respect to the parameter m.

        :param m: The serialized paramaterisation of the turbines.
        :tpye m: numpy.ndarray.
        :returns: numpy.ndarray -- the gradient of the constraint function with
            respect to each input parameter m.

        """
        dolfin.log(
            dolfin.PROGRESS, "Calculating the jacobian of minimum "
            "distance constraints function.")
        inequality_constraints = []

        for i in range(len(m) / 2):
            for j in range(len(m) / 2):
                if i <= j:
                    continue

                # Need to add space for zeros for the friction
                if self._controls.position and self._controls.friction:
                    prime_inequality_constraints = numpy.zeros(len(m) * 3 / 2)
                    friction_length = len(m) / 2
                else:
                    prime_inequality_constraints = numpy.zeros(len(m))
                    friction_length = 0

                # Provide a shorter handle
                p_ineq_c = prime_inequality_constraints

                # The control vector contains the friction coefficients first,
                # so we need to shift here
                p_ineq_c[friction_length + 2 * i] = 2 * (m[2 * i] - m[2 * j])
                p_ineq_c[friction_length + 2 * j] = -2 * (m[2 * i] - m[2 * j])
                p_ineq_c[friction_length + 2 * i +
                         1] = 2 * (m[2 * i + 1] - m[2 * j + 1])
                p_ineq_c[friction_length + 2 * j +
                         1] = -2 * (m[2 * i + 1] - m[2 * j + 1])
                inequality_constraints.append(p_ineq_c)

        return numpy.array(inequality_constraints)
Beispiel #24
0
    def function(self, m):
        ieqcons = []
        controlled_by = self.farm.turbine_specification.controls
        if (controlled_by.position and
            (controlled_by.friction or controlled_by.dynamic_friction)):
        # If the controls consists of the the friction and the positions, then we need to first extract the position part
            assert(len(m) % 3 == 0)
            m_pos = m[len(m) / 3:]
        else:
            m_pos = m

        for i in range(len(m_pos) / 2):
            pos = numpy.array([m_pos[2 * i], m_pos[2 * i + 1]])
            c = self.b - numpy.dot(self.A, pos)
            ieqcons = ieqcons + list(c)

        arr = numpy.array(ieqcons)
        if any(arr < 0):
          log(INFO, "Convex site position constraints (should be >= 0): %s" % arr)
        return arr
    def derivative(self, forget=False, **kwargs):
        """ Computes the first derivative of the functional with respect to its
        controls by solving the adjoint equations. """

        log(INFO, 'Start evaluation of dj')
        timer = Timer("dj evaluation")

        if not hasattr(self, "time_integrator"):
            self.evaluate()
        self.functional = self.time_integrator.dolfin_adjoint_functional(
            self.solver.state)
        dj = compute_gradient(self.functional,
                              self.controls,
                              forget=forget,
                              **kwargs)
        parameters["adjoint"]["stop_annotating"] = False

        log(INFO, "Runtime: " + str(timer.stop()) + " s")

        return enlisting.enlist(dj)
    def jacobian(self, m):
        """Returns the gradient of the constraint function.

        Return a list of vector-like objects representing the gradient of the
        constraint function with respect to the parameter m.

        :param m: The serialized paramaterisation of the turbines.
        :tpye m: numpy.ndarray.
        :returns: numpy.ndarray -- the gradient of the constraint function with
            respect to each input parameter m.

        """
        dolfin.log(dolfin.PROGRESS, "Calculating the jacobian of minimum "
                   "distance constraints function.")
        inequality_constraints = []

        if self._controls.position and self._controls.friction:
            friction_length = len(m)/3
            m = m[friction_length:]
        else:
            friction_length = 0

        p_ineq_c = numpy.zeros(friction_length + len(m))

        for i in range(len(m)/2):
            for j in range(len(m)/2):
                if i <= j:
                    continue

                dist_sq = self._sl2norm([m[2*i]-m[2*j],
                                         m[2*i+1]-m[2*j+1]])
                dvalue = self._dpenalty(dist_sq)

                # The control vector contains the friction coefficients first,
                # so we need to shift here
                p_ineq_c[friction_length+2*i] += dvalue * 2*(m[2*i] - m[2*j])
                p_ineq_c[friction_length+2*j] += dvalue * (-2*(m[2*i] - m[2*j]))
                p_ineq_c[friction_length+2*i+1] += dvalue * 2*(m[2*i+1] - m[2*j+1])
                p_ineq_c[friction_length+2*j+1] += dvalue * (-2*(m[2*i+1] - m[2*j+1]))

        return numpy.array([p_ineq_c])
    def jacobian(self, m):
        """Returns the gradient of the constraint function.

        Return a list of vector-like objects representing the gradient of the
        constraint function with respect to the parameter m.

        :param m: The serialized paramaterisation of the turbines.
        :tpye m: numpy.ndarray.
        :returns: numpy.ndarray -- the gradient of the constraint function with
            respect to each input parameter m.

        """
        dolfin.log(dolfin.PROGRESS, "Calculating the jacobian of minimum "
                   "distance constraints function.")
        inequality_constraints = []

        for i in range(len(m)/2):
            for j in range(len(m)/2):
                if i <= j:
                    continue

                # Need to add space for zeros for the friction
                if self._controls.position and self._controls.friction:
                    prime_inequality_constraints = numpy.zeros(len(m)*3/2)
                    friction_length = len(m)/2
                else:
                    prime_inequality_constraints = numpy.zeros(len(m))
                    friction_length = 0

                # Provide a shorter handle
                p_ineq_c = prime_inequality_constraints

                # The control vector contains the friction coefficients first,
                # so we need to shift here
                p_ineq_c[friction_length+2*i] = 2*(m[2*i] - m[2*j])
                p_ineq_c[friction_length+2*j] = -2*(m[2*i] - m[2*j])
                p_ineq_c[friction_length+2*i+1] = 2*(m[2*i+1] - m[2*j+1])
                p_ineq_c[friction_length+2*j+1] = -2*(m[2*i+1] - m[2*j+1])
                inequality_constraints.append(p_ineq_c)

        return numpy.array(inequality_constraints)
    def test_site_constraint(self):

        farm = self.get_farm()

        ieq = ConvexPolygonSiteConstraint(farm, [[0, 0], [10, 0], [10, 10]])

        # Only test the correctness of the first inequality constraint for
        # simplicity.
        ieqcons_J = lambda m: ieq.function(m)[0]
        ieqcons_dJ = lambda m, forget=False: ieq.jacobian(m)[0]

        # This will raise a RunetimeWarning, which is fine because we expect
        # division by zero
        x = numpy.array([0, 0, 10, 4, 20, 8])
        minconv = helpers.test_gradient_array(ieqcons_J, ieqcons_dJ, x=x,
                                              seed=0.1)

        # These constraints are linear so we expect no convergence at all.
        # Let's check that the tolerance is not above a threshold
        log(INFO, "Expecting a Nan convergence order")
        assert math.isnan(minconv)
Beispiel #29
0
    def write(self, comm, filename="muflon-parameters.xml"):
        """
        Write parameters to XML file.

        :param comm: MPI communicator
        :type comm: :py:class:`dolfin.MPI_Comm`
        :param filename: name of the output XML file (can be relative or
                         absolute path)
        :type filename: str
        """
        filename += ".xml" if filename[-4:] != ".xml" else ""
        log(DEBUG, "Writing current parameter values into '%s'." % filename)
        from dolfin import DOLFIN_VERSION_MAJOR, DOLFIN_VERSION_MINOR
        if DOLFIN_VERSION_MAJOR >= 2017 and DOLFIN_VERSION_MINOR >= 2:
            with File(filename) as xmlfile:
                xmlfile << self
        elif MPI.rank(comm) == 0: # FIXME: remove this backporting
            with File(filename) as xmlfile:
                xmlfile << self
        else:
            return
Beispiel #30
0
    def evaluate(self, annotate=True):
        """ Computes the functional value by running the forward model. """

        log(INFO, 'Start evaluation of j')
        timer = Timer("j evaluation")

        farm = self.solver.problem.parameters.tidal_farm

        # Configure dolfin-adjoint
        adj_reset()
        parameters["adjoint"]["record_all"] = True

        # Solve the shallow water system and integrate the functional of
        # interest.
        final_only = (not self.solver.problem._is_transient or
                      self._problem_params.functional_final_time_only)
        self.time_integrator = TimeIntegrator(self.solver.problem,
                                              self._functional, final_only)

        for sol in self.solver.solve(annotate=annotate):
            self.time_integrator.add(sol["time"], sol["state"], sol["tf"],
                                     sol["is_final"])

        j = self.time_integrator.integrate()

        timer.stop()

        log(INFO, 'Runtime: %f s.' % timer.elapsed()[0])
        log(INFO, 'j = %e.' % float(j))

        return j
    def evaluate(self, annotate=True):
        """ Computes the functional value by running the forward model. """

        log(INFO, 'Start evaluation of j')
        timer = Timer("j evaluation")

        farm = self.solver.problem.parameters.tidal_farm

        # Configure dolfin-adjoint
        adj_reset()
        parameters["adjoint"]["record_all"] = True

        # Solve the shallow water system and integrate the functional of
        # interest.
        final_only = (not self.solver.problem._is_transient
                      or self._problem_params.functional_final_time_only)
        self.time_integrator = TimeIntegrator(self.solver.problem,
                                              self._functional, final_only)

        for sol in self.solver.solve(annotate=annotate):
            self.time_integrator.add(sol["time"], sol["state"], sol["tf"],
                                     sol["is_final"])

        j = self.time_integrator.integrate()

        timer.stop()

        log(INFO, 'Runtime: %f s.' % timer.elapsed()[0])
        log(INFO, 'j = %e.' % float(j))

        return j
    def function(self, m):
        ieqcons = []
        if len(self.config.params['controls']) == 2:
        # If the controls consists of the the friction and the positions, then we need to first extract the position part
            assert(len(m) % 3 == 0)
            m_pos = m[len(m) / 3:]
        else:
            m_pos = m

        for i in range(len(m_pos) / 2):
            x = m_pos[2 * i]
            y = m_pos[2 * i + 1]
            try:
                ieqcons.append(function_eval(self.feasible_area, (x, y)))
            except RuntimeError:
                print("Warning: a turbine is outside the domain")
                ieqcons.append((x - self.attraction_center[0]) ** 2 + (y - self.attraction_center[1]) ** 2)  # Point is outside domain

        arr = -numpy.array(ieqcons)
        if any(arr <= 0):
          log(INFO, "Domain restriction inequality constraints (should be >= 0): %s" % arr)
        return arr
    def test_site_constraint(self):

        farm = self.get_farm()

        ieq = ConvexPolygonSiteConstraint(farm, [[0, 0], [10, 0], [10, 10]])

        # Only test the correctness of the first inequality constraint for
        # simplicity.
        ieqcons_J = lambda m: ieq.function(m)[0]
        ieqcons_dJ = lambda m, forget=False: ieq.jacobian(m)[0]

        # This will raise a RunetimeWarning, which is fine because we expect
        # division by zero
        x = numpy.array([0, 0, 10, 4, 20, 8])
        minconv = helpers.test_gradient_array(ieqcons_J,
                                              ieqcons_dJ,
                                              x=x,
                                              seed=0.1)

        # These constraints are linear so we expect no convergence at all.
        # Let's check that the tolerance is not above a threshold
        log(INFO, "Expecting a Nan convergence order")
        assert math.isnan(minconv)
Beispiel #34
0
def cbc_log(level, msg):
    "Log on master process."
    if on_master_process():
        log(level, msg)