def coefficient_gradient_trial(ct, cp): pitch_val = Constant(10.) tsr_val = Constant(6.) def get_coefficient(func, pitch, tsr): return func(pitch, tsr) backend_get_coefficient = get_coefficient from pyadjoint import Block class CoefficientBlock(Block): def __init__(self,func, pitch, tsr, **kwargs): super(CoefficientBlock, self).__init__() self.kwargs = kwargs self.func = func self.add_dependency(pitch) self.add_dependency(tsr) degree = func.function_space().ufl_element().degree() family = func.function_space().ufl_element().family() mesh = func.function_space().mesh() if np.isin(family, ["CG", "Lagrange"]): self.V = FunctionSpace(mesh, "DG", degree - 1) else: raise NotImplementedError( "Not implemented for other elements than Lagrange") def __str__(self): return "CoefficientBlock" def evaluate_adj_component(self, inputs, adj_inputs, block_variable, idx, prepared=None): # output = get_derivative(inputs[0], inputs[1], idx) * adj_inputs[0] grad_idx = project(self.func.dx(idx), self.V) output = grad_idx(inputs[0], inputs[1]) * adj_inputs[0] return output def recompute_component(self, inputs, block_variable, idx, prepared): return backend_get_coefficient(self.func, inputs[0], inputs[1]) from pyadjoint.overloaded_function import overload_function get_coefficient = overload_function(get_coefficient, CoefficientBlock) controls = [pitch_val, tsr_val] ctv = get_coefficient(ct, pitch_val, tsr_val) cpv = get_coefficient(cp, pitch_val, tsr_val) J = (ctv*cpv) **2 m = [Control(ctrl) for ctrl in controls] Jhat = ReducedFunctional(J, m) dJdm = Jhat.derivative() print("\nBeginning taylor test:\n") taylor_test(Jhat, controls, [Constant(0.01*np.random.rand()) for c in controls]) print("end")
def test_overload_function(): tape = Tape() set_working_tape(tape) sin = overload_function(ad_sin, SinBlock) z = AdjFloat(5) t = AdjFloat(3) r = sin(z) q = cos(r * t) Jhat = ReducedFunctional(q, Control(z)) assert (Jhat.derivative() == -np.sin(t * np.sin(z)) * t * np.cos(z))
def point_eval_taylor_test(ct, cp): pitch = Constant(5.) tsr = Constant(8.) # ctval = ct(pitch, tsr) backend_ct = ct def get_ct(pitch, tsr): return backend_ct(pitch, tsr) # http://www.dolfin-adjoint.org/en/latest/documentation/custom_functions.html from pyadjoint import Block class CtBlock(Block): def __init__(self, func, **kwargs): super(CtBlock, self).__init__() # self.func = func self.gradient = [project(backend_ct.dx(0), backend_ct.function_space()), project(backend_ct.dx(1), backend_ct.function_space())] self.kwargs = kwargs self.add_dependency(func) def __str__(self): return "CtBlock" def recompute_component(self, inputs, block_variable, idx, prepared): return backend_ct(inputs[0], inputs[1]) def evaluate_adj_component(self, inputs, adj_inputs, block_variable, idx, prepared=None): return self.gradient[idx](adj_inputs[0],adj_inputs[1]) from pyadjoint.overloaded_function import overload_function get_ct = overload_function(get_ct, CtBlock) # ct = overload_function(ct.__call__, CtBlock) J = assemble(ct(pitch, tsr)) m = Control(pitch) Jhat = ReducedFunctional(J, m) dJdm = Jhat.derivative() taylor_test(Jhat, m, m)
idx=idx) * adj_inputs[0] print(output) print([float(ix) for ix in inputs]) return output def recompute_component(self, inputs, block_variable, idx, prepared): return backend_get_coefficient(func=self.func, pitch=inputs[0], torque=inputs[1], rotor_speed=inputs[2], power_aero=inputs[3], disc_velocity=inputs[4]) # return backend_get_coefficient(self.func, inputs[0], inputs[1], inputs[2], self.power_aero, self.disc_velocity) get_coefficient = overload_function(get_coefficient, CoefficientBlock) pitch_grid, tsr_grid, ct_array, cp_array = read_rosco_curves() ct, cp = lookup_field(pitch_grid, tsr_grid, ct_array, cp_array) # float((1 / inertia) * (power_aero / rotor_speed - torque) + rotor_speed) w = Constant(5.) q = Constant(10.) pa = Constant(10.) # iner = Constant(5.) b = Constant(0.) ud = Constant(10.) # tsr = w # wn = (1 / iner) * (pa / q - q) + w w.assign(0.8)
coeff_array.append(inputs[self.dim+i]) return backend_add_linear_combination (self.dim, inputs[2*self.dim], basis_array, coeff_array) def evaluate_adj_component(self, inputs, adj_inputs, block_variable, idx, prepared=None): if (idx < self.dim): return inputs[idx+self.dim]*adj_inputs[0] elif (idx >= self.dim) and (idx < 2*self.dim): diff = Function (inputs[0].function_space()) #diff.assign (inputs[idx-self.dim], annotate=False) diff.assign (inputs[idx-self.dim]) return diff.vector().inner(adj_inputs[0]) elif (idx == 2*self.dim): return adj_inputs[0] else: raise RuntimeError ("add_linear_combination_block can only differentiate w.r.t. scalar.") add_linear_combination = overload_function(add_linear_combination, AddLinearCombinationBlock) def array_to_const_mat(G): return Constant(((G[0][0],G[0][1]),(G[1][0],G[1][1]))) def m_to_array(m,deg_r1,deg_r2,deg_t1,deg_t2): array = [] for i in range(0,10): array.append(float(m[i])) array_r1 = [] for i in range(0,deg_r1): array_r1.append(float(m[10+i])) array.append(array_r1)
adj_inputs, block_variable, idx, prepared=None): a = inputs[0] b = inputs[1] if idx == 2: diff = Function(a.function_space()) diff.assign(a - b, annotate=False) return diff.vector().inner(adj_inputs[0]) else: raise RuntimeError( "convex_combination can only differentiate w.r.t. scalar.") convex_combination = overload_function(convex_combination, ConvexCombinationBlock) def boundary_exp(i, j, n): return lambda x, on_boundary: on_boundary and i < x[ 0] * n < i + 1 and j < x[1] * n < j + 1 # this function computes the deformation psi and the displacement dpsi for a given vector of parameters alpha def get_deformation(alpha, n, U): # define the deformation on the boundaries boundary_psi = [] for i in range(0, n): for j in range(0, n): boundary_psi.append( DirichletBC(
class two_lengthBlock(Block): def __init__(self, turbine_locations, **kwargs): super(two_lengthBlock, self).__init__() self.kwargs = kwargs self.turbine_locations = turbine_locations for location in self.turbine_locations: self.add_dependency(location) def __str__(self): return "two_lengthBlock" def prepare_evaluate_adj(self, inputs, adj_inputs, relevant_dependencies): dldx = dlength_dx(inputs[:]) return dldx def evaluate_adj_component(self, inputs, adj_inputs, block_variable, idx, prepared): adj_input = adj_inputs[0] result_adj = adj_input * prepared[idx] return result_adj.item() def recompute_component(self, inputs, block_variable, idx, prepared): return backend_two_length(inputs[:]) two_length = overload_function(two_length, two_lengthBlock)
from normalise import normalise backend_normalise = normalise class NormaliseBlock(Block): def __init__(self, func, **kwargs): super(NormaliseBlock, self).__init__() self.kwargs = kwargs self.add_dependency(func) def __str__(self): return 'NormaliseBlock' def evaluate_adj_component(self, inputs, adj_inputs, block_variable, idx, prepared=None): adj_input = adj_inputs[0] x = inputs[idx].vector() inv_xnorm = 1.0 / x.norm('l2') return inv_xnorm * adj_input - inv_xnorm**3 * x.inner(adj_input) * x def recompute_component(self, inputs, block_variable, idx, prepared): return backend_normalise(inputs[0]) normalise = overload_function(normalise, NormaliseBlock)
t_location_float.append(float(i.values())) l_location_float = [ float(self.substation_location[0].values()), float(self.substation_location[1].values()) ] check_t_location = [] for i in t_location_float: if i not in check_t_location: check_t_location.append(i) if len(t_location_float) != len(check_t_location): relevant_outputs = self.order else: cableclass = prepare_cable.Hybrid_Code.CableCostGA( t_location_float, l_location_float) order_w = cableclass.compute_cable_cost_order() order_con = [i for j in order_w for i in j] # print(order_con) for i, order in enumerate(self.order): order.assign(order_con[i]) relevant_outputs = self.order return relevant_outputs def recompute_component(self, inputs, block_variable, idx, prepared): turbine_index = len(self.turbine_locations) return backend_cablelength(inputs[:], self.substation_location, prepared) cablelength = overload_function(cablelength, CablelengthBlock)
prepared=None): adj_input = adj_inputs[0] x = inputs[idx] derivative = 1.0 / x return derivative * adj_input def recompute_component(self, inputs, block_variable, idx, prepared): return backend_natlog(inputs[0]) def evaluate_tlm_component(self, inputs, tlm_inputs, block_variable, idx, prepared=None): # return derivative_example_function(inputs[0], tlm_inputs[0]) return tlm_inputs[0] / inputs[0] def evaluate_hessian_component(self, inputs, hessian_inputs, adj_inputs, block_variable, idx, relevant_dependencies, prepared=None): return -hessian_inputs[0] / inputs[0]**2 natlog = overload_function(natlog, NatLogBlock)