ensured that partials are not declared for type_key & expose approx method to user.
-
Major change
As I was building a nested problem I have noticed that due to global partial declaration in the class CostModelComponent() the compute was being called unnecessarily for an integer input.
So if the partials are approximated; for example the input variable 'type' would cause to call the compute n_wt times for no reason.
You can run a test with below changes to see what i mean. To avoid this the local variable input_keys is now filtering type_key before declaring partials. And then in the compute_partials type_key is omitted as it is not declared.
Not sure if we want to generalize this for user selected integer inputs. But for now it solves the main problem.
Minor change I exposed the method as user input coz some components are capable of running complex step instead of finite difference.
Sample to recreate the problem
I guess you can see this in different ways but I am writing the way I noticed it;
First make two changes in dummy.py in /topfarm/cost_models to make sure partials are approximated and compute is printed out
def __init__(self, optimal_state, inputs=[topfarm.x_key, topfarm.y_key]): """ Parameters ---------- optimal_state : array_like, dim=(#wt,#inputs) optimal state array inputs : array_like list of input names """ self.optimal_state = np.array(optimal_state) self.n_wt = self.optimal_state.shape[0] CostModelComponent.__init__(self, inputs, self.n_wt, self.cost) def cost(self, **kwargs): opt = self.optimal_state for i in self.input_keys: print(i, kwargs[i]) return np.sum([(kwargs[n] - opt[:, i])**2 for i, n in enumerate(self.input_keys)])
Copy this code taken from test anywhere in the computer and run. see the print on the screen for type-
from openmdao.drivers.doe_generators import FullFactorialGenerator,\ ListGenerator from openmdao.drivers.doe_driver import DOEDriver from topfarm.cost_models.dummy import DummyCost import numpy as np from topfarm.easy_drivers import EasyScipyOptimizeDriver from topfarm.tests import npt from topfarm import TopFarmProblem from topfarm.constraint_components.spacing import SpacingConstraint from topfarm.constraint_components.boundary import XYBoundaryConstraint optimal = np.array([(0, 2, 4, 1), (4, 2, 1, 0)]) design_vars = {k: v for k, v in zip('xy', optimal.T)} design_vars['z'] = (optimal[:, 2], 0, 4) xyz_problem = TopFarmProblem( design_vars, cost_comp=DummyCost(optimal, ['x', 'y', 'z', 'type']), constraints=[SpacingConstraint(2), XYBoundaryConstraint([(0, 0), (4, 4)], 'square')], driver=EasyScipyOptimizeDriver(disp=False)) tf = TopFarmProblem( {'type': ([0, 0], 0, 1)}, cost_comp=xyz_problem, driver=DOEDriver(FullFactorialGenerator(2))) cost = tf.optimize()[0] assert cost == 0
Edited by Emre Barlas