Source code for opentidalfarm.functionals.power_functionals

#"""
#.. module:: Power Functionals
#   :synopsis: This module contains the functional classes which compute the
#       power extracted by an array.
#"""

from dolfin import dot, Constant, dx, assemble
from ..helpers import smooth_uflmin
from prototype_functional import PrototypeFunctional


[docs]class PowerFunctional(PrototypeFunctional): r""" Implements a simple functional of the form: .. math:: J(u, m) = \int \rho c_t ||u||^3~ dx, where :math:`c_t` defines the friction field due to the turbines. :param problem: The problem for which the functional is being computed. :type problem: Instance of the problem class. """ def __init__(self, problem): self.farm = problem.parameters.tidal_farm self.rho = problem.parameters.rho self.farm.update() # Create a copy of the parameters so that future changes will not # affect the definition of this object. # self.params = dict(farm.params)
[docs] def Jt(self, state, turbine_field): """ Computes the power output of the farm. :param state: Current solution state :type state: UFL :param turbine_field: Turbine friction field :type turbine_field: UFL """ return self.power(state, turbine_field)*self.farm.site_dx
[docs] def power(self, state, turbine_field): """ Computes the power field over the domain. :param state: Current solution state. :type state: UFL :param turbine_field: Turbine friction field :type turbine_field: UFL """ return (self.rho * turbine_field * (dot(state[0], state[0]) + dot(state[1], state[1])) ** 1.5)
[docs] def Jt_individual(self, state, i): """ Computes the power output of the i'th turbine. :param state: Current solution state :type state: UFL :param i: refers to the i'th turbine :type i: Integer """ turbine_field_individual = \ self.farm.turbine_cache['turbine_field_individual'][i] return assemble(self.power(state, turbine_field_individual) * self.farm.site_dx)
[docs] def force(self, state, turbine_field): """ Computes the force field over turbine field :param state: Current solution state. :type state: UFL :param turbine_field: Turbine friction field :type turbine_field: UFL """ return self.rho * turbine_field * dot(state[0], state[0]) + dot(state[1], state[1])
[docs] def force_individual(self, state, i): """ Computes the total force on the i'th turbine :param state: Current solution state :type state: UFL :param i: refers to the i'th turbine :type i: Integer """ turbine_field_individual = \ self.farm.turbine_cache['turbine_field_individual'][i] return assemble(self.force(state, turbine_field_individual) * self.farm.site_dx(1))
[docs]class PowerCurveFunctional(PrototypeFunctional): # ''' Implements a functional for the power with a given power curve # :math:`J(u, m) = \int_\Omega P(u)` # where m controls the strength of each turbine. """ TODO: doesn't work yet... """ def __init__(self, farm): ''' Constructs a new DefaultFunctional. The turbine settings are derived from the settings params. ''' farm.update() self.farm = farm # Create a copy of the parameters so that future changes will not # affect the definition of this object. self.params = dict(farm.params) assert(self.params["turbine_thrust_parametrisation"] or \ self.params["implicit_turbine_thrust_parametrisation"]) def Jt(self, state, tf): up_u = state[3] # Extract the upstream velocity #ux = state[0] def power_function(u): # A simple power function implementation. # Could be replaced with a polynomial approximation. fac = Constant(1.5e6 / (3 ** 3)) return smooth_uflmin(1.5e6, fac * u ** 3) P = power_function(up_u)*tf/self.farm.turbine_specification.integral*dx return P