From b57ac7c86ffe8775924cccf41b50fe45c057774f Mon Sep 17 00:00:00 2001 From: imcovangent <I.vanGent@tudelft.nl> Date: Tue, 23 Oct 2018 13:49:34 +0200 Subject: [PATCH] Improvement for Collaborative Optimization (CO) by scaling the consistency objective / constraint function J. Former-commit-id: 7b80c9727f86cc705b56e5c2b19136c85c28a887 --- kadmos/graph/graph_data.py | 24 ++++++++++++++++++------ kadmos/graph/graph_kadmos.py | 10 +++++++--- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/kadmos/graph/graph_data.py b/kadmos/graph/graph_data.py index f6b59e216..ed3016693 100644 --- a/kadmos/graph/graph_data.py +++ b/kadmos/graph/graph_data.py @@ -3731,7 +3731,7 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): mdao_arch = self.graph['problem_formulation']['mdao_architecture'] pre_functions = self.graph['problem_formulation']['function_ordering'][self.FUNCTION_ROLES[0]] - mg_function_ordering = dict(self.graph['problem_formulation']['function_ordering']) + mg_function_ordering = copy.deepcopy(self.graph['problem_formulation']['function_ordering']) # OPTIONS_ARCHITECTURE: IDF, MDF, unc-OPT, unc-DOE, con-DOE, CO, BLISS-2000 if mdao_arch in self.OPTIONS_ARCHITECTURES[2:9]: @@ -4821,7 +4821,9 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): local_des_vars_group+local_des_vars_copies_group, group_cof_obj_node, local_cnstrnt_vars_group, - label=sub_opts_labels[idx]) + label=sub_opts_labels[idx], + package='SciPy', maximum_iterations=100, + convergence_tolerance=1e-6, constraint_tolerance=1e-6) # Mark the final consistency objective value as a constraint and add it to the system level constraints group_cof_obj_node_final = mdg.find_all_nodes(attr_cond=['related_to_schema_node', '==', group_cof_obj_node]) @@ -4836,7 +4838,8 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): objective_node, list(sys_lev_cnstrnts), label=sys_opt_label, - package='pyOptSparse') + package='pyOptSparse', maximum_iterations=200, + convergence_tolerance=1e-3, constraint_tolerance=1e-3) # Temp fix: make post-coupling functions into post-desvars for node in sa['functions_lists'][0]: @@ -5660,7 +5663,7 @@ class MdaoDataGraph(DataGraph, MdaoMixin): def connect_consistency_objective_function(self, group_idx, ccv_mappings): """Method to add a consistency objective function. A consistency objective function between related values - y_1, y_1^c, y_2 and y_2^c would be: (y_1 - y_1^c)^2 + (y_2 - y_2^c)^2 + y_1, y_1^c, y_2 and y_2^c would be: (((y_1 - y_1^c)/y_1_scaler)^2 + ((y_2 - y_2^c)/y_2_scaler)^2)**0.5 :param group_idx: index of the subgroup :type group_idx: int @@ -5686,12 +5689,21 @@ class MdaoDataGraph(DataGraph, MdaoMixin): for idx, (var1, var2) in enumerate(ccv_mappings.iteritems()): eq_lab1 = 'x{}_0'.format(idx) eq_lab2 = 'x{}_1'.format(idx) + eq_lab3 = 'x{}_sc'.format(idx) self.add_edge(var1, new_function_node, equation_label=eq_lab1) self.add_edge(var2, new_function_node, equation_label=eq_lab2) + # Add the scaler variable and connect accordingly + new_scaler_node = '/{}/scalers/{}'.format(var1.split('/')[1], '/'.join(var1.split('/')[2:])) + if not self.has_node(new_scaler_node): + self.add_node(new_scaler_node, + category='variable', + label='{}Scaler'.format(var1.split('/')[-1]), + instance=1) + self.add_edge(new_scaler_node, new_function_node, equation_label=eq_lab3) if idx == 0: - math_expression = '({}-{})**2'.format(eq_lab2, eq_lab1) + math_expression = '(({}-{})/{})**2'.format(eq_lab2, eq_lab1, eq_lab3) else: - math_expression += '+({}-{})**2'.format(eq_lab2, eq_lab1) + math_expression += '+(({}-{})/{})**2'.format(eq_lab2, eq_lab1, eq_lab3) # Finally, add square root around expression math_expression = '(' + math_expression + ')**0.5' # Create the output objective node of the function and connect it diff --git a/kadmos/graph/graph_kadmos.py b/kadmos/graph/graph_kadmos.py index b85d1dc57..dbcbe5ef5 100644 --- a/kadmos/graph/graph_kadmos.py +++ b/kadmos/graph/graph_kadmos.py @@ -763,7 +763,7 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): # Now add the pseudo-Coordinator to the graph and connect the input and output parameters graph.add_node(pseudo_node, category='function', label='', problem_role=graph.FUNCTION_ROLES[0], - architecture_role=graph.ARCHITECTURE_ROLES_FUNS[0]) + architecture_role=graph.ARCHITECTURE_ROLES_FUNS[0], instance=1) graph_inputs = graph.find_all_nodes(subcategory='all inputs') graph_outputs = graph.find_all_nodes(subcategory='all outputs') for inp in graph_inputs: @@ -1264,7 +1264,8 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): self.add_node(input['xpath'], category='variable', shape='o', - label=input['xpath'].split('/')[-1]) # TODO: Extend this to pick up XML attributes for description, note, unit, data_type + label=input['xpath'].split('/')[-1], + instance=1) # TODO: Extend this to pick up XML attributes for description, note, unit, data_type self.add_edge(input['xpath'], input_el[1].get('uID')) for output_el in outputs_list: @@ -1275,7 +1276,8 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): self.add_node(output['xpath'], category='variable', shape='o', - label=output['xpath'].split('/')[-1]) # TODO: Extend this to pick up XML attributes for description, note, unit, data_type + label=output['xpath'].split('/')[-1], + instance=1) # TODO: Extend this to pick up XML attributes for description, note, unit, data_type self.add_edge(output_el[1].get('uID'), output['xpath']) return @@ -2083,6 +2085,8 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): self.nodes[n]['name'] = n if 'label' not in self.nodes[n]: self.nodes[n]['label'] = n + if 'instance' not in self.nodes[n]: + self.nodes[n]['instance'] = 1 def add_edge(self, u, v, attr_dict=None, **attr): """Add an edge between u and v. -- GitLab