From 670862b3502a13cbd553b4d6604a9ece046a9564 Mon Sep 17 00:00:00 2001 From: Anne-Liza <a.m.r.m.bruggeman@student.tudelft.nl> Date: Tue, 24 Jul 2018 16:40:14 +0200 Subject: [PATCH] Removed distributed-convergence as mdao architecture and added it as option for MDF, IDF and converged-MDA Former-commit-id: 2c1968166d28d3410ae3deeea6e9f62738b413c6 --- kadmos/graph/graph_data.py | 493 +++++++++++++++------------------- kadmos/graph/graph_kadmos.py | 21 +- kadmos/graph/graph_process.py | 17 +- kadmos/utilities/general.py | 11 +- 4 files changed, 239 insertions(+), 303 deletions(-) diff --git a/kadmos/graph/graph_data.py b/kadmos/graph/graph_data.py index f3e3121ac..7b2d2fad0 100644 --- a/kadmos/graph/graph_data.py +++ b/kadmos/graph/graph_data.py @@ -3044,8 +3044,7 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): if node_selection: nodes_to_partition = list(node_selection) # For IDF, all functions in the optimizer loop are partitioned except for the objective and constraint functions - elif 'system_architecture' in self.graph['problem_formulation'] and \ - self.graph['problem_formulation']['system_architecture'] == self.OPTIONS_ARCHITECTURES[2]: + elif self.graph['problem_formulation']['mdao_architecture'] == self.OPTIONS_ARCHITECTURES[2]: # Get post-design-variables, coupled and post-coupling functions mg_function_ordering = self.get_mg_function_ordering() @@ -3217,8 +3216,7 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): # Update the function order if node_selection: function_order = [node for partition in partitions for node in partition] - elif 'system_architecture' in self.graph['problem_formulation'] and \ - self.graph['problem_formulation']['system_architecture'] == self.OPTIONS_ARCHITECTURES[2]: + elif self.graph['problem_formulation']['mdao_architecture'] == self.OPTIONS_ARCHITECTURES[2]: # noinspection PyUnboundLocalVariable pre_desvars_order = self.sort_nodes_for_process(mg_function_ordering[self.FUNCTION_ROLES[3]]) partitioned_nodes_order = [node for partition in partitions for node in partition] @@ -3237,7 +3235,7 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): self.graph['problem_formulation']['coupled_functions_groups'] = best_partitions self.graph['problem_formulation']['local_convergers'] = convergers - self.graph['problem_formulation']['partition_convergence'] = [] + self.graph['problem_formulation']['jacobi_convergence'] = [] self.graph['problem_formulation']['sequence_partitions'] = [] if not node_selection: self.graph['problem_formulation']['function_order'] = function_order @@ -3411,7 +3409,7 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): 'partitions'] self.graph['problem_formulation']['local_convergers'] = partition_results[partition_range[idx]][ 'local_convergers'] - self.graph['problem_formulation']['partition_convergence'] = [] + self.graph['problem_formulation']['jacobi_convergence'] = [] self.graph['problem_formulation']['sequence_partitions'] = [] self.graph['problem_formulation']['function_order'] = partition_results[partition_range[idx]]['function_order'] @@ -3435,16 +3433,6 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): partitions = self.graph['problem_formulation']['coupled_functions_groups'] coupling_dict = self.get_coupling_dictionary() - # Select system architecture # todo: remove? System acrhictecture should be given before graph is partitioned - system_architectures = ['unconverged-MDA', 'converged-MDA', 'MDF', 'IDF', 'unconverged-OPT'] - options = [] - for idx, arch in enumerate(system_architectures): - options.append([idx, arch]) - printing.print_in_table(options, headers=['Option', 'System architecture']) - msg = 'Please select system architecture:' - system_architecture = str(prompting.user_prompt_select_options(*system_architectures, allow_empty=False, - allow_multi=False, message=msg)[0]) - # Select which partitions need a local converger msg = 'Please select which partitions need a local converger:' while True: @@ -3492,13 +3480,11 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): # todo: remove or improve print 'local converger:', local_convergers - print 'system architecture:', system_architecture print 'jacobi convergence:', jacobi_convergence print 'sequence partitions:', sequence_partitions - self.graph['problem_formulation']['system_architecture'] = system_architecture self.graph['problem_formulation']['local_convergers'] = local_convergers - self.graph['problem_formulation']['partition_convergence'] = jacobi_convergence + self.graph['problem_formulation']['jacobi_convergence'] = jacobi_convergence self.graph['problem_formulation']['sequence_partitions'] = sequence_partitions return @@ -3518,8 +3504,8 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): pre_functions = self.graph['problem_formulation']['function_ordering'][self.FUNCTION_ROLES[0]] mg_function_ordering = dict(self.graph['problem_formulation']['function_ordering']) - # OPTIONS_ARCHITECTURE: IDF, MDF, unc-OPT, unc-DOE, con-DOE, distr-conv, CO, BLISS-2000 - if mdao_arch in self.OPTIONS_ARCHITECTURES[2:10]: + # OPTIONS_ARCHITECTURE: IDF, MDF, unc-OPT, unc-DOE, con-DOE, CO, BLISS-2000 + if mdao_arch in self.OPTIONS_ARCHITECTURES[2:9]: del mg_function_ordering[self.FUNCTION_ROLES[0]] if pre_functions: target_set = set() @@ -3541,8 +3527,6 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): post_desvars_funcs = [] mg_function_ordering[self.FUNCTION_ROLES[3]] = pre_desvars_funcs mg_function_ordering[self.FUNCTION_ROLES[4]] = post_desvars_funcs - if mdao_arch == self.OPTIONS_ARCHITECTURES[2]: # IDF - mg_function_ordering[self.FUNCTION_ROLES[2]].append(self.CONSCONS_STRING) return mg_function_ordering @@ -3879,7 +3863,8 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): # TODO: Imco check docstring # Initiate dictionary - global_functions = [global_objective_function] + global_cnstrnt_functions + global_functions = [global_objective_function] if global_objective_function else [] + global_functions += global_cnstrnt_functions system_level_function_dict = dict() system_level_function_dict[self.FUNCTION_ROLES[1]] = [] system_level_function_dict[self.FUNCTION_ROLES[3]] = [] @@ -3889,8 +3874,12 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): # Get and check function groups if mg_function_ordering is None: mg_function_ordering = self.get_mg_function_ordering() - pre_desvars = mg_function_ordering[self.FUNCTION_ROLES[3]] - post_desvars = mg_function_ordering[self.FUNCTION_ROLES[4]] + if self.FUNCTION_ROLES[0] in mg_function_ordering: # TODO: This should be fixed when pre-coupling category is eliminated + pre_desvars = mg_function_ordering[self.FUNCTION_ROLES[0]] + post_desvars = [] + else: + pre_desvars = mg_function_ordering[self.FUNCTION_ROLES[3]] + post_desvars = mg_function_ordering[self.FUNCTION_ROLES[4]] post_couplings = mg_function_ordering[self.FUNCTION_ROLES[2]] # Add pre-design variables functions to the dictionary @@ -3974,7 +3963,10 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): # Get and check function groups if mg_function_ordering is None: mg_function_ordering = self.get_mg_function_ordering() - post_desvars = mg_function_ordering[self.FUNCTION_ROLES[4]] + if self.FUNCTION_ROLES[0] in mg_function_ordering: # TODO: This should be fixed when pre-coupling category is eliminated + post_desvars = [] + else: + post_desvars = mg_function_ordering[self.FUNCTION_ROLES[4]] post_couplings = mg_function_ordering[self.FUNCTION_ROLES[2]] additional_post_couplings = [] additional_post_desvars = [] @@ -4133,17 +4125,28 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): basic_group_couplings = list(group_couplings) # Determine objective function based on objective value - global_objective_function = self.get_sources(objective_node)[0] + if objective_node: + global_objective_function = self.get_sources(objective_node)[0] + else: + global_objective_function = None # TODO: Assert that objective function only has one output # Determine local and global design variables - global_des_vars, local_des_vars, des_vars_group_idxs = \ - self.determine_scope_design_variables(des_vars=des_var_nodes) + if des_var_nodes: + global_des_vars, local_des_vars, des_vars_group_idxs = \ + self.determine_scope_design_variables(des_vars=des_var_nodes) + else: + global_des_vars, local_des_vars, des_vars_group_idxs = [], [], dict() # TODO: assess that each discipline group is dependent on at least one design variable (?) # Get global and local constraints and their functions - global_cnstrnt_vars, global_cnstrnt_funcs, local_cnstrnt_vars, local_cnstrnt_funcs, cnstrnt_vars_group_idxs, \ - cnstrnt_funcs_group_idxs = self.determine_scope_constraint_functions(cnstrnt_vars=constraint_nodes) + if constraint_nodes: + global_cnstrnt_vars, global_cnstrnt_funcs, local_cnstrnt_vars, local_cnstrnt_funcs, \ + cnstrnt_vars_group_idxs, cnstrnt_funcs_group_idxs = \ + self.determine_scope_constraint_functions(cnstrnt_vars=constraint_nodes) + else: + global_cnstrnt_vars, global_cnstrnt_funcs, local_cnstrnt_vars, local_cnstrnt_funcs, \ + cnstrnt_vars_group_idxs, cnstrnt_funcs_group_idxs = [], [], [], [], [], dict() # Create dictionary of pre-desvar, post-desvar, and post-coupling functions for the system optimizer sys_functions_dict = self.get_system_level_functions(global_objective_function, global_cnstrnt_funcs, @@ -4244,6 +4247,19 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): # Set up MDAO data graph mdg = graph.create_mdg(mg_function_ordering, name=name) + # Check for partitions in monolithic architectures + if mdao_arch in graph.OPTIONS_ARCHITECTURES[1:4] and 'coupled_functions_groups' in \ + graph.graph['problem_formulation']: + partitions = graph.graph['problem_formulation']['coupled_functions_groups'] + system_analysis = self._analyze_distributed_system(des_var_nodes, objective_node, constraint_nodes, + mg_function_ordering, + add_system_functions_to_subsystems=False) + distr_function_ordering = system_analysis['functions_dicts'] + mdg.graph['distr_function_ordering'] = distr_function_ordering + sub_func_orderings = distr_function_ordering[1] + else: + partitions = None + # Manipulate data graph if mdao_arch == graph.OPTIONS_ARCHITECTURES[0]: # unconverged-MDA if allow_unconverged_couplings: @@ -4259,32 +4275,52 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): # Connect system inputs and outputs to the coordinator mdg.connect_coordinator() elif mdao_arch == graph.OPTIONS_ARCHITECTURES[1]: # converged-MDA - conv = graph.CONVERGER_STRING - # Connect converger - mdg.connect_converger(conv, conv_type, coup_functions, True) + if partitions: + # Connect partitions + # noinspection PyUnboundLocalVariable + mdg.connect_partitions(mdao_arch, sub_func_orderings, coup_functions) + else: + sys_conv, sys_conv_label = graph.CONVERGER_STRING, graph.CONVERGER_LABEL + # Connect system converger + mdg.connect_converger(sys_conv, conv_type, coup_functions, True, label=sys_conv_label) # Connect QOIs to the coordinator mdg.connect_qoi_nodes_as_input(qoi_nodes, graph.COORDINATOR_STRING, True) # Connect remaining system inputs and outputs to the coordinator mdg.connect_coordinator() elif mdao_arch == graph.OPTIONS_ARCHITECTURES[2]: # IDF - opt = graph.OPTIMIZER_STRING - # Connect optimizer as a converger using the consistency constraint function - mdg.connect_converger(opt, graph.OPTIONS_ARCHITECTURES[2], coup_functions, True) - # Connect optimizer w.r.t. design variables, objective, contraints + if partitions: + sys_opt = graph.SYS_PREFIX + graph.OPTIMIZER_STRING + sys_opt_label = graph.SYS_PREFIX + graph.OPTIMIZER_LABEL + # Connect partitions + # noinspection PyUnboundLocalVariable + mdg.connect_partitions(mdao_arch, sub_func_orderings, coup_functions) + else: + sys_opt, sys_opt_label = graph.OPTIMIZER_STRING, graph.OPTIMIZER_LABEL + # Connect optimizer as a converger using the consistency constraint function + mdg.connect_converger(sys_opt, graph.OPTIONS_ARCHITECTURES[2], coup_functions, True, + label=sys_opt_label, converger_is_optimizer=True) + # Connect optimizer w.r.t. design variables, objective, constraints # noinspection PyUnboundLocalVariable - mdg.connect_optimizer(opt, des_var_nodes, objective_node, constraint_nodes) + mdg.connect_optimizer(sys_opt, des_var_nodes, objective_node, constraint_nodes, label=sys_opt_label) # Connect QOIs to the coordinator mdg.connect_qoi_nodes_as_input(qoi_nodes, graph.COORDINATOR_STRING, True) # Connect remaining system inputs and outputs to the coordinator mdg.connect_coordinator() elif mdao_arch == graph.OPTIONS_ARCHITECTURES[3]: # MDF - opt = graph.OPTIMIZER_STRING - conv = graph.CONVERGER_STRING - # Connect converger - mdg.connect_converger(conv, conv_type, coup_functions, True) + if partitions: + sys_opt = graph.SYS_PREFIX + graph.OPTIMIZER_STRING + sys_opt_label = graph.SYS_PREFIX + graph.OPTIMIZER_LABEL + # Connect partitions + # noinspection PyUnboundLocalVariable + mdg.connect_partitions(mdao_arch, sub_func_orderings, coup_functions) + else: + sys_opt, sys_opt_label = graph.OPTIMIZER_STRING, graph.OPTIMIZER_LABEL + sys_conv, sys_conv_label = graph.CONVERGER_STRING, graph.CONVERGER_LABEL + # Connect system converger + mdg.connect_converger(sys_conv, conv_type, coup_functions, True, label=sys_conv_label) # Connect optimizer # noinspection PyUnboundLocalVariable - mdg.connect_optimizer(opt, des_var_nodes, objective_node, constraint_nodes) + mdg.connect_optimizer(sys_opt, des_var_nodes, objective_node, constraint_nodes, label=sys_opt_label) # Connect QOIs to the coordinator mdg.connect_qoi_nodes_as_input(qoi_nodes, graph.COORDINATOR_STRING, True) # Connect remaining system inputs and outputs to the coordinator @@ -4331,144 +4367,7 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): mdg.connect_doe_block(doe, des_var_nodes, qoi_nodes) # Connect remaining system inputs and outputs to the coordinator mdg.connect_coordinator() - elif mdao_arch == self.OPTIONS_ARCHITECTURES[7]: # distributed-convergence - - # Input checks - assert 'coupled_functions_groups' in graph.graph['problem_formulation'], 'Graph is not partitioned.' - assert 'system_architecture' in graph.graph['problem_formulation'], 'No architecture selected for ' \ - 'distributed convergence.' - - # Load extra variables from fpg - partitions = graph.graph['problem_formulation']['coupled_functions_groups'] - system_arch = graph.graph['problem_formulation']['system_architecture'] - local_convergers = graph.graph['problem_formulation']['local_convergers'] - parallel_conv = graph.graph['problem_formulation']['partition_convergence'] - - sys_opt, sys_conv, sub_convs = self.get_architecture_node_ids(self.OPTIONS_ARCHITECTURES[7], - number_of_groups=len(partitions)) - sys_opt_label, sys_conv_label, sub_convs_labels = self.get_architecture_node_labels( - self.OPTIONS_ARCHITECTURES[7], number_of_groups=len(partitions)) - system_analysis = self._analyze_distributed_system(des_var_nodes, objective_node, constraint_nodes, - mg_function_ordering, - add_system_functions_to_subsystems=False) - distr_function_ordering = system_analysis['functions_dicts'] - mdg.graph['distr_function_ordering'] = distr_function_ordering - sub_func_orderings = distr_function_ordering[1] - - if system_arch == 'converged-MDA' or system_arch == 'MDF': - # Connect partitions - for partition in range(len(partitions)): - # Get convergence type of partitions (default is Gauss-Seidel, unless indicated otherwise) - conv_type_partition = graph.OPTIONS_CONVERGERS[0] if partition in parallel_conv else \ - graph.OPTIONS_CONVERGERS[1] - # Connect disciplines to local converger if present, otherwise system converger - converger = sub_convs[partition] if partition in local_convergers else sys_conv - converger_label = sub_convs_labels[partition] if partition in local_convergers else sys_conv_label - nodes = [node for type in sub_func_orderings[partition] for node in - sub_func_orderings[partition][type]] if partition not in local_convergers and \ - conv_type_partition == graph.OPTIONS_CONVERGERS[0] else sub_func_orderings[partition]['coupled'] - mdg.connect_converger(converger, conv_type_partition, nodes, True, label=converger_label) - # Connect remaining couplings to system converger - mdg.connect_converger(sys_conv, graph.OPTIONS_CONVERGERS[0], coup_functions, True, - system_converger=True, label=sys_conv_label) - # Connect optimizer if present - if system_arch == 'MDF': - mdg.connect_optimizer(sys_opt, des_var_nodes, objective_node, constraint_nodes, label=sys_opt_label) - # Connect qoi - mdg.connect_qoi_nodes_as_input(qoi_nodes, graph.COORDINATOR_STRING, True) - # Connect coordinator - mdg.connect_coordinator() - elif system_arch == 'IDF': - # Connect partitions - # TODO: quick-fix to get IDF working - # Add concisitency constraint block - assert not self.has_node(self.CONSCONS_STRING), 'Consistency constraint name already in use in FPG.' - mdg.add_node(self.CONSCONS_STRING, - label=self.CONSCONS_LABEL, - category='function', - architecture_role=self.ARCHITECTURE_ROLES_FUNS[8], - function_type='consistency') - distr_function_ordering[0][self.FUNCTION_ROLES[2]].append('Gc') - mdg.graph['distr_function_ordering'] = distr_function_ordering - for partition in range(len(partitions)): - converger = sub_convs[partition] if partition in local_convergers else sys_opt - converger_label = sub_convs_labels[partition] if partition in local_convergers else sys_opt_label - # Get convergence type for the partition - if partition in parallel_conv: - if converger == sys_opt: - conv_type_partition = graph.OPTIONS_ARCHITECTURES[2] - else: - conv_type_partition = graph.OPTIONS_CONVERGERS[0] - else: - conv_type_partition = graph.OPTIONS_CONVERGERS[1] - converger_is_optimizer = True if converger_label == sys_opt_label else False - nodes = [node for type in sub_func_orderings[partition] for node in - sub_func_orderings[partition][type]] if partition not in local_convergers and \ - conv_type_partition in [graph.OPTIONS_CONVERGERS[0], graph.OPTIONS_ARCHITECTURES[2]] else \ - sub_func_orderings[partition]['coupled'] - mdg.connect_converger(converger, conv_type_partition, nodes, True, label=converger_label, - converger_is_optimizer=converger_is_optimizer) - # Connect remaining couplings to optimizer as system converger - mdg.connect_converger(sys_opt, graph.OPTIONS_ARCHITECTURES[2], coup_functions, True, - system_converger=True, label=sys_opt_label, converger_is_optimizer=True) - # Connect optimizer - mdg.connect_optimizer(sys_opt, des_var_nodes, objective_node, constraint_nodes, label=sys_opt_label) - # Connect qoi - mdg.connect_qoi_nodes_as_input(qoi_nodes, graph.COORDINATOR_STRING, True) - # Connect coordinator - mdg.connect_coordinator() - elif system_arch == 'unconverged-MDA' or system_arch == 'unconverged-OPT': - # Connect partitions - for partition in range(len(partitions)): - # Get convergence type of partitions (default is Gauss-Seidel, unless indicated otherwise) - conv_type_partition = graph.OPTIONS_CONVERGERS[0] if partition in parallel_conv else \ - graph.OPTIONS_CONVERGERS[1] - # Connect disciplines to local converger if present - if partition in local_convergers: - mdg.connect_converger(sub_convs[partition], conv_type_partition, - sub_func_orderings[partition]['coupled'], True, - label=sub_convs_labels[partition]) - else: - if conv_type_partition == graph.OPTIONS_CONVERGERS[1]: - mdg.manipulate_coupling_nodes(sub_func_orderings[partition]['coupled'], - remove_feedback=True, remove_feedforward=False, - converger=None, include_couplings_as_final_output=False) - else: - nodes = [node for type in sub_func_orderings[partition] for node in - sub_func_orderings[partition][type]] - mdg.manipulate_coupling_nodes(nodes, remove_feedback=True, remove_feedforward=True, - converger=None, include_couplings_as_final_output=False) - # Connect remaining couplings - mdg.manipulate_coupling_nodes(coup_functions, remove_feedback=True, remove_feedforward=True, - converger=None, include_couplings_as_final_output=False, - system_converger=True) - # Connect optimizer if present - if system_arch == 'unconverged-OPT': - mdg.connect_optimizer(sys_opt, des_var_nodes, objective_node, constraint_nodes, label=sys_opt_label) - # Connect qoi - mdg.connect_qoi_nodes_as_input(qoi_nodes, graph.COORDINATOR_STRING, True) - # Connect coordinator - mdg.connect_coordinator() - - # Resolve problematic variables # todo - prob_var = mdg.find_all_nodes(subcategory='all splittable variables') - for var in prob_var: - sources = mdg.get_sources(var) - targets = mdg.get_targets(var) - function_order = [] - for converger in local_convergers: - if sub_convs[converger] in sources: - function_order.extend([sub_convs[converger]]) - function_order.extend([target for target in targets if target in partitions[converger]]) - if sys_conv in sources: - function_order.extend([sys_conv]) - function_order.extend([target for target in targets if target not in function_order]) - if sys_opt in sources: - function_order.extend([sys_opt]) - function_order.extend([target for target in targets if target not in function_order]) - mdg.split_variables(var, function_order=function_order) - - elif mdao_arch == graph.OPTIONS_ARCHITECTURES[8]: # CO + elif mdao_arch == graph.OPTIONS_ARCHITECTURES[7]: # CO coupled_functions_groups = graph.graph['problem_formulation']['coupled_functions_groups'] n_groups = len(coupled_functions_groups) sys_opt, sub_opts = self.get_architecture_node_ids('CO', number_of_groups=n_groups) @@ -4543,7 +4442,7 @@ class FundamentalProblemGraph(DataGraph, KeChainMixin): # Write function_ordering to the graph mdg.graph['distr_function_ordering'] = sa['functions_dicts'] - elif mdao_arch == graph.OPTIONS_ARCHITECTURES[9]: # BLISS-2000 + elif mdao_arch == graph.OPTIONS_ARCHITECTURES[8]: # BLISS-2000 coupled_functions_groups = graph.graph['problem_formulation']['coupled_functions_groups'] n_groups = len(coupled_functions_groups) sys_opt, sys_conv, sys_sms, sub_smbds, sub_does, sub_opts, sub_smbs = \ @@ -5057,7 +4956,7 @@ class MdaoDataGraph(DataGraph, MdaoMixin): for func in functions: self.nodes[func]['architecture_role'] = 'pre-iterator analysis' # Add optimizer / DOE - if mdao_arch in self.OPTIONS_ARCHITECTURES[2:5]: # IDF, MDF, unc-OPT + if mdao_arch == self.OPTIONS_ARCHITECTURES[4]: # unc-OPT assert not self.has_node(self.OPTIMIZER_STRING), 'Optimizer name already in use in FPG.' self.add_node(self.OPTIMIZER_STRING, category='function', @@ -5084,8 +4983,7 @@ class MdaoDataGraph(DataGraph, MdaoMixin): self.nodes[func]['architecture_role'] = self.ARCHITECTURE_ROLES_FUNS[6] # Converger required - if mdao_arch in [self.OPTIONS_ARCHITECTURES[1]] + [self.OPTIONS_ARCHITECTURES[3]] + \ - [self.OPTIONS_ARCHITECTURES[6]]: # con-MDA, MDF, con-DOE + if mdao_arch == self.OPTIONS_ARCHITECTURES[6]: # con-DOE # Add converger assert not self.has_node(self.CONVERGER_STRING), 'Converger name already in use in FPG.' self.add_node(self.CONVERGER_STRING, @@ -5102,15 +5000,7 @@ class MdaoDataGraph(DataGraph, MdaoMixin): # Add post-coupling functions for func in mg_function_ordering[self.FUNCTION_ROLES[2]]: - if func != self.CONSCONS_STRING: - self.nodes[func]['architecture_role'] = self.ARCHITECTURE_ROLES_FUNS[8] - else: - assert not self.has_node(self.CONSCONS_STRING), 'Consistency constraint name already in use in FPG.' - self.add_node(self.CONSCONS_STRING, - label=self.CONSCONS_LABEL, - category='function', - architecture_role=self.ARCHITECTURE_ROLES_FUNS[8], - function_type='consistency') + self.nodes[func]['architecture_role'] = self.ARCHITECTURE_ROLES_FUNS[8] return @@ -5997,6 +5887,74 @@ class MdaoDataGraph(DataGraph, MdaoMixin): return + def connect_partitions(self, mdao_arch, sub_func_orderings, coup_functions): + """Method to connect partitions in a data graph of a monolithic architecture + """ + + partitions = self.graph['problem_formulation']['coupled_functions_groups'] + local_convergers = self.graph['problem_formulation']['local_convergers'] + jacobi_conv = self.graph['problem_formulation']['jacobi_convergence'] + + sys_opt, sys_conv, sub_convs = self.get_architecture_node_ids(mdao_arch, number_of_groups=len(partitions)) + sys_opt_label, sys_conv_label, sub_convs_labels = self.get_architecture_node_labels( + mdao_arch, number_of_groups=len(partitions)) + + # Connect partitions + for partition in range(len(partitions)): + # Connect nodes to local converger if present, otherwise system converger or optimizer + if partition in local_convergers: + conv, conv_label = sub_convs[partition], sub_convs_labels[partition] + elif mdao_arch == self.OPTIONS_ARCHITECTURES[2]: + conv, conv_label = sys_opt, sys_opt_label + else: + conv, conv_label = sys_conv, sys_conv_label + # Get convergence type + if partition in jacobi_conv: + conv_type = self.OPTIONS_ARCHITECTURES[2] if conv == sys_opt else self.OPTIONS_CONVERGERS[0] + else: + conv_type = self.OPTIONS_CONVERGERS[1] + # Check whether optimizer needs to be connected as converger + converger_is_optimizer = True if conv_label == sys_opt_label else False + # Get nodes in partition + if partition not in local_convergers and conv_type in [self.OPTIONS_CONVERGERS[0], + self.OPTIONS_ARCHITECTURES[2]]: + nodes = [node for func_role in sub_func_orderings[partition] for node in + sub_func_orderings[partition][func_role]] + else: + nodes = sub_func_orderings[partition]['coupled'] + # Connect nodes to (sub)system converger or system optimizer + self.connect_converger(conv, conv_type, nodes, True, label=conv_label, + converger_is_optimizer=converger_is_optimizer) + + # Connect remaining couplings to the system converger or optimizer + if mdao_arch == self.OPTIONS_ARCHITECTURES[2]: + conv, conv_label, conv_type = sys_opt, sys_opt_label, self.OPTIONS_ARCHITECTURES[2] + else: + conv, conv_label, conv_type = sys_conv, sys_conv_label, self.OPTIONS_CONVERGERS[0] + converger_is_optimizer = True if conv == sys_opt else False + self.connect_converger(conv, conv_type, coup_functions, True, system_converger=True, label=conv_label, + converger_is_optimizer=converger_is_optimizer) + + # Resolve problematic variables + prob_var = self.find_all_nodes(subcategory='all splittable variables') + for var in prob_var: + sources = self.get_sources(var) + targets = self.get_targets(var) + function_order = [] + for converger in local_convergers: + if sub_convs[converger] in sources: + function_order.extend([sub_convs[converger]]) + function_order.extend([target for target in targets if target in partitions[converger]]) + if sys_conv in sources: + function_order.extend([sys_conv]) + function_order.extend([target for target in targets if target not in function_order]) + if sys_opt in sources: + function_order.extend([sys_opt]) + function_order.extend([target for target in targets if target not in function_order]) + self.split_variables(var, function_order=function_order) + + return + def manipulate_coupling_nodes(self, func_order, remove_feedback, remove_feedforward, converger=None, include_couplings_as_final_output=False, system_converger=False): """Method to manipulate the coupling nodes in a data graph in order to remove unwanted feedback/feedforward. @@ -6076,6 +6034,17 @@ class MdaoDataGraph(DataGraph, MdaoMixin): self.copy_edge((coupling[2], coupling[1]), (coupling_copy_node, coupling[1])) # Create equation label equation_label = coupling[2].split('/')[-1] + # Add consistency constraint function to the graph (if it's not already there) + if not self.has_node(self.CONSCONS_STRING): + self.add_node(self.CONSCONS_STRING, + label=self.CONSCONS_LABEL, + category='function', + architecture_role=self.ARCHITECTURE_ROLES_FUNS[8], + function_type='consistency') + if 'distr_function_ordering' in self.graph: + self.graph['distr_function_ordering'][0][self.FUNCTION_ROLES[2]].append(self.CONSCONS_STRING) + if 'mg_function_ordering' in self.graph: + self.graph['mg_function_ordering'][self.FUNCTION_ROLES[2]].append(self.CONSCONS_STRING) # Connect original and copied coupling node to the consistency constraint function self.add_edge(coupling[2], self.CONSCONS_STRING, equation_label=equation_label) self.add_edge(coupling_copy_node, self.CONSCONS_STRING, equation_label=equation_label+'c') @@ -6160,6 +6129,17 @@ class MdaoDataGraph(DataGraph, MdaoMixin): coup_functions = mdg.sort_nodes_for_process(mg_function_ordering[mdg.FUNCTION_ROLES[1]]) post_functions = mg_function_ordering[mdg.FUNCTION_ROLES[2]] + # Check for partitions in monolithic architectures + if mdao_arch in mdg.OPTIONS_ARCHITECTURES[1:4] and 'coupled_functions_groups' in \ + mdg.graph['problem_formulation']: + partitions = mdg.graph['problem_formulation']['coupled_functions_groups'] + distr_function_ordering = mdg.graph['distr_function_ordering'] + pre_desvars_funcs = distr_function_ordering[0][mdg.FUNCTION_ROLES[3]] + post_desvars_funcs = distr_function_ordering[0][mdg.FUNCTION_ROLES[4]] + post_functions = distr_function_ordering[0][mdg.FUNCTION_ROLES[2]] + else: + partitions = None + # Set up MDAO process graph mpg = mdg.create_mpg(name=name) @@ -6171,35 +6151,53 @@ class MdaoDataGraph(DataGraph, MdaoMixin): sequence = [coor] + pre_functions + coup_functions + post_functions mpg.add_process(sequence, 0, mdg, end_in_iterative_node=coor) elif mdao_arch == mdg.OPTIONS_ARCHITECTURES[1]: # converged-MDA - conv = mdg.CONVERGER_STRING - sequence = [coor] + pre_functions + [conv] - mpg.add_process(sequence, 0, mdg) - sequence2 = [conv] + coup_functions - mpg.add_process(sequence2, mpg.nodes[sequence[-1]]['process_step'], mdg, end_in_iterative_node=conv) + _, sys_conv, _ = self.get_architecture_node_ids(mdao_arch, number_of_groups=len(partitions)) if \ + partitions else ([], mdg.CONVERGER_STRING, []) + sequence1 = [coor] + pre_functions + [sys_conv] + mpg.add_process(sequence1, 0, mdg) + if partitions: + mpg.add_process_partitions([sys_conv], partitions, [], mpg.nodes[sequence1[-1]]['process_step'], mdg, + end_in_iterative_node=sys_conv) + else: + sequence2 = [sys_conv] + coup_functions + mpg.add_process(sequence2, mpg.nodes[sequence1[-1]]['process_step'], mdg, + end_in_iterative_node=sys_conv) if post_functions: - sequence3 = [conv] + post_functions - mpg.add_process(sequence3, mpg.nodes[conv]['converger_step'], mdg, end_in_iterative_node=coor) + sequence3 = [sys_conv] + post_functions + mpg.add_process(sequence3, mpg.nodes[sys_conv]['converger_step'], mdg, end_in_iterative_node=coor) else: - mpg.connect_nested_iterators(coor, conv) + mpg.connect_nested_iterators(coor, sys_conv) elif mdao_arch == mdg.OPTIONS_ARCHITECTURES[2]: # IDF - opt = mdg.OPTIMIZER_STRING - sequence1 = [coor] + pre_desvars_funcs + [opt] + sys_opt, _, _ = self.get_architecture_node_ids(mdao_arch, number_of_groups=len(partitions)) if \ + partitions else (mdg.OPTIMIZER_STRING, [], []) + sequence1 = [coor] + pre_desvars_funcs + [sys_opt] mpg.add_process(sequence1, 0, mdg) - sequence2 = [opt] + post_desvars_funcs + coup_functions + post_functions - mpg.add_process(sequence2, mpg.nodes[sequence1[-1]]['process_step'], mdg, end_in_iterative_node=opt) - mpg.connect_nested_iterators(coor, opt) + if partitions: + sequence2 = [sys_opt] + post_desvars_funcs + sequence3 = post_functions + mpg.add_process_partitions(sequence2, partitions, sequence3, mpg.nodes[sequence1[-1]]['process_step'], + mdg, end_in_iterative_node=sys_opt) + else: + sequence2 = [sys_opt] + post_desvars_funcs + coup_functions + post_functions + mpg.add_process(sequence2, mpg.nodes[sequence1[-1]]['process_step'], mdg, end_in_iterative_node=sys_opt) + mpg.connect_nested_iterators(coor, sys_opt) elif mdao_arch == mdg.OPTIONS_ARCHITECTURES[3]: # MDF - opt = mdg.OPTIMIZER_STRING - conv = mdg.CONVERGER_STRING - sequence1 = [coor] + pre_desvars_funcs + [opt] + sys_opt, sys_conv, _ = self.get_architecture_node_ids(mdao_arch, number_of_groups=len(partitions)) if \ + partitions else (mdg.OPTIMIZER_STRING, mdg.CONVERGER_STRING, []) + sequence1 = [coor] + pre_desvars_funcs + [sys_opt] mpg.add_process(sequence1, 0, mdg) - sequence2 = [opt] + post_desvars_funcs + [conv] + sequence2 = [sys_opt] + post_desvars_funcs + [sys_conv] mpg.add_process(sequence2, mpg.nodes[sequence1[-1]]['process_step'], mdg) - sequence3 = [conv] + coup_functions - mpg.add_process(sequence3, mpg.nodes[sequence2[-1]]['process_step'], mdg, end_in_iterative_node=conv) - sequence4 = [conv] + post_functions - mpg.add_process(sequence4, mpg.nodes[conv]['converger_step'], mdg, end_in_iterative_node=opt) - mpg.connect_nested_iterators(coor, opt) + if partitions: + mpg.add_process_partitions([sys_conv], partitions, [], mpg.nodes[sequence2[-1]]['process_step'], mdg, + end_in_iterative_node=sys_conv) + else: + sequence3 = [sys_conv] + coup_functions + mpg.add_process(sequence3, mpg.nodes[sequence2[-1]]['process_step'], mdg, + end_in_iterative_node=sys_conv) + sequence4 = [sys_conv] + post_functions + mpg.add_process(sequence4, mpg.nodes[sys_conv]['converger_step'], mdg, end_in_iterative_node=sys_opt) + mpg.connect_nested_iterators(coor, sys_opt) elif mdao_arch == mdg.OPTIONS_ARCHITECTURES[4]: # unconverged-OPT opt = mdg.OPTIMIZER_STRING sequence1 = [coor] + pre_desvars_funcs + [opt] @@ -6229,62 +6227,7 @@ class MdaoDataGraph(DataGraph, MdaoMixin): else: mpg.connect_nested_iterators(doe, conv) mpg.connect_nested_iterators(coor, doe) - elif mdao_arch == mdg.OPTIONS_ARCHITECTURES[7]: # distributed-convergence - - # Input checks - assert 'coupled_functions_groups' in mdg.graph['problem_formulation'], 'Graph is not partitioned.' - assert 'system_architecture' in mdg.graph['problem_formulation'], 'No architecture selected for ' \ - 'distributed convergence.' - - # Load extra variables from fpg - partitions = mdg.graph['problem_formulation']['coupled_functions_groups'] - system_arch = mdg.graph['problem_formulation']['system_architecture'] - distr_function_ordering = mdg.graph['distr_function_ordering'] - system_pre_desvars_funcs = distr_function_ordering[0][mdg.FUNCTION_ROLES[3]] - system_post_desvars_funcs = distr_function_ordering[0][mdg.FUNCTION_ROLES[4]] - system_post_functions = distr_function_ordering[0][mdg.FUNCTION_ROLES[2]] - - sys_opt, sys_conv, _ = self.get_architecture_node_ids(self.OPTIONS_ARCHITECTURES[7], - number_of_groups=len(partitions)) - - if system_arch == 'unconverged-MDA': - sequence1 = [coor] + system_pre_desvars_funcs + system_post_desvars_funcs - sequence2 = system_post_functions - mpg.add_process_partitions(sequence1, partitions, sequence2, 0, mdg, end_in_iterative_node=coor) - elif system_arch == 'converged-MDA': - sequence1 = [coor] + system_pre_desvars_funcs + system_post_desvars_funcs + [sys_conv] - mpg.add_process(sequence1, 0, mdg) - mpg.add_process_partitions([sys_conv], partitions, [], mpg.nodes[sys_conv]['process_step'], mdg, - end_in_iterative_node=sys_conv) - sequence2 = [sys_conv] + system_post_functions - mpg.add_process(sequence2, mpg.nodes[sys_conv]['converger_step'], mdg, end_in_iterative_node=coor) - elif system_arch == 'IDF': - sequence1 = [coor] + system_pre_desvars_funcs + [sys_opt] - mpg.add_process(sequence1, 0, mdg) - sequence2 = [sys_opt] + system_post_desvars_funcs - sequence3 = system_post_functions - mpg.add_process_partitions(sequence2, partitions, sequence3, mpg.nodes[sys_opt]['process_step'], mdg, - end_in_iterative_node=sys_opt) - mpg.connect_nested_iterators(coor, sys_opt) - elif system_arch == 'MDF': - sequence1 = [coor] + system_pre_desvars_funcs + [sys_opt] - mpg.add_process(sequence1, 0, mdg) - sequence2 = [sys_opt] + system_post_desvars_funcs + [sys_conv] - mpg.add_process(sequence2, mpg.nodes[sys_opt]['process_step'], mdg) - mpg.add_process_partitions([sys_conv], partitions, [], mpg.nodes[sys_conv]['process_step'], mdg, - end_in_iterative_node=sys_conv) - sequence3 = [sys_conv] + system_post_functions - mpg.add_process(sequence3, mpg.nodes[sys_conv]['converger_step'], mdg, end_in_iterative_node=sys_opt) - mpg.connect_nested_iterators(coor, sys_opt) - elif system_arch == 'unconverged-OPT': - sequence1 = [coor] + system_pre_desvars_funcs + [sys_opt] - mpg.add_process(sequence1, 0, mdg) - sequence2 = [sys_opt] + system_post_desvars_funcs - sequence3 = system_post_functions - mpg.add_process_partitions(sequence2, partitions, sequence3, mpg.nodes[sys_opt]['process_step'], mdg, - end_in_iterative_node=sys_opt) - mpg.connect_nested_iterators(coor, sys_opt) - elif mdao_arch == mdg.OPTIONS_ARCHITECTURES[8]: # CO + elif mdao_arch == mdg.OPTIONS_ARCHITECTURES[7]: # CO distr_function_ordering = mdg.graph['distr_function_ordering'] n_groups = len(distr_function_ordering[1]) sys_opt, sub_opts = self.get_architecture_node_ids(mdao_arch, number_of_groups=n_groups) @@ -6301,7 +6244,7 @@ class MdaoDataGraph(DataGraph, MdaoMixin): end_in_iterative_node=sub_opts[idx]) mpg.connect_nested_iterators(sys_opt, sub_opts[idx]) mpg.connect_nested_iterators(coor, sys_opt) - elif mdao_arch == mdg.OPTIONS_ARCHITECTURES[9]: # BLISS-2000 + elif mdao_arch == mdg.OPTIONS_ARCHITECTURES[8]: # BLISS-2000 distr_function_ordering = mdg.graph['distr_function_ordering'] n_groups = len(distr_function_ordering[1]) sys_opt, sys_conv, _, sub_smbds, sub_does, sub_opts, sub_smbs = \ diff --git a/kadmos/graph/graph_kadmos.py b/kadmos/graph/graph_kadmos.py index 7461448f2..1b786868d 100644 --- a/kadmos/graph/graph_kadmos.py +++ b/kadmos/graph/graph_kadmos.py @@ -58,9 +58,8 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): 'unconverged-OPT', # 4 'unconverged-DOE', # 5 'converged-DOE', # 6 - 'distributed-convergence', # 7 - 'CO', # 8 - 'BLISS-2000'] # 9 + 'CO', # 7 + 'BLISS-2000'] # 8 OPTIONS_DOE_METHODS = ['Full factorial design', # 0 'Latin hypercube design', # 1 'Monte Carlo design', # 2 @@ -811,8 +810,8 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): # Add analysis blocks for idx in range(0, graph_mpg.number_of_nodes()): node_list = graph_mpg.find_all_nodes(attr_cond=['diagonal_position', '==', idx]) - assert len(node_list) == 1, 'Somehow, a unique diagonal position %d could not be found in the PSG' \ - ' data graph.' % idx + assert len(node_list) == 1, 'Somehow, a unique diagonal position {} could not be found in the MDG.'\ + .format(idx) node = node_list[0] try: role_index = self.ARCHITECTURE_ROLES_FUNS.index(graph_mpg.nodes[node]['architecture_role']) @@ -3103,7 +3102,7 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): :rtype: tuple """ - if mdao_architecture == self.OPTIONS_ARCHITECTURES[7]: # Distributed-convergence + if mdao_architecture in self.OPTIONS_ARCHITECTURES[1:4]: # Distributed convergence of monolithic architectures assert number_of_groups is not None, \ 'number_of_groups should be specified for this architecture ({}).'.format(mdao_architecture) assert number_of_groups > 0, 'number_of_groups should be larger than 0.' @@ -3112,7 +3111,7 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): sub_convs = ['{}{}{}{}'.format(self.SUBSYS_PREFIX, self.CONVERGER_STRING, self.SUBSYS_SUFFIX, item) for item in range(number_of_groups)] return sys_opt, sys_conv, sub_convs - elif mdao_architecture == self.OPTIONS_ARCHITECTURES[8]: # CO + elif mdao_architecture == self.OPTIONS_ARCHITECTURES[7]: # CO assert number_of_groups is not None, \ 'number_of_groups should be specified for this architecture ({}).'.format(mdao_architecture) assert number_of_groups > 0, 'number_of_groups should be larger than 0.' @@ -3120,7 +3119,7 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): sub_opts = ['{}{}{}{}'.format(self.SUBSYS_PREFIX, self.OPTIMIZER_STRING, self.SUBSYS_SUFFIX, item) for item in range(number_of_groups)] return sys_opt, sub_opts - elif mdao_architecture == self.OPTIONS_ARCHITECTURES[9]: # BLISS-2000 + elif mdao_architecture == self.OPTIONS_ARCHITECTURES[8]: # BLISS-2000 assert number_of_groups is not None, \ 'number_of_groups should be specified for this architecture ({}).'.format(mdao_architecture) assert number_of_groups > 0, 'number_of_groups should be larger than 0.' @@ -3149,7 +3148,7 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): :rtype: tuple """ - if mdao_architecture == self.OPTIONS_ARCHITECTURES[7]: # Distributed-convergence + if mdao_architecture in self.OPTIONS_ARCHITECTURES[1:4]: # Distributed convergence of monolithic architectures assert number_of_groups is not None, \ 'number_of_groups should be specified for this architecture ({}).'.format(mdao_architecture) assert number_of_groups > 0, 'number_of_groups should be larger than 0.' @@ -3158,7 +3157,7 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): sub_convs_labels = ['{}{}{}{}'.format(self.SUBSYS_PREFIX, self.CONVERGER_LABEL, self.SUBSYS_SUFFIX, item) for item in range(number_of_groups)] return sys_opt_label, sys_conv_label, sub_convs_labels - elif mdao_architecture == self.OPTIONS_ARCHITECTURES[8]: # CO + elif mdao_architecture == self.OPTIONS_ARCHITECTURES[7]: # CO assert number_of_groups is not None, \ 'number_of_groups should be specified for this architecture ({}).'.format(mdao_architecture) assert number_of_groups > 0, 'number_of_groups should be larger than 0.' @@ -3166,7 +3165,7 @@ class KadmosGraph(nx.DiGraph, EquationMixin, VistomsMixin): sub_opts_labels = ['{}{}{}{}'.format(self.SUBSYS_PREFIX, self.OPTIMIZER_LABEL, self.SUBSYS_SUFFIX, item) for item in range(number_of_groups)] return sys_opt_label, sub_opts_labels - elif mdao_architecture == self.OPTIONS_ARCHITECTURES[9]: # BLISS-2000 + elif mdao_architecture == self.OPTIONS_ARCHITECTURES[8]: # BLISS-2000 assert number_of_groups is not None, \ 'number_of_groups should be specified for this architecture ({}).'.format(mdao_architecture) assert number_of_groups > 0, 'number_of_groups should be larger than 0.' diff --git a/kadmos/graph/graph_process.py b/kadmos/graph/graph_process.py index 31d36a723..e892d984a 100644 --- a/kadmos/graph/graph_process.py +++ b/kadmos/graph/graph_process.py @@ -275,12 +275,10 @@ class MdaoProcessGraph(ProcessGraph): bliss2000 = False co = True distr_conv = False - elif mdao_architecture == 'distributed-convergence': + else: bliss2000 = False co = False distr_conv = True - else: - raise NotImplementedError('Invalid MDAO architecture {} found.'.format(mdao_architecture)) mg_function_ordering = self.graph['distr_function_ordering'] syslevel_ordering = mg_function_ordering[0] subsyslevel_orderings = mg_function_ordering[1] @@ -329,8 +327,8 @@ class MdaoProcessGraph(ProcessGraph): attr_cond=['architecture_role', '==', self.ARCHITECTURE_ROLES_FUNS[2]]) # converger if len(convs) >= 1: sys_conv = [item for item in convs if self.SYS_PREFIX in item] - if distr_conv and self.graph['problem_formulation']['system_architecture'] not in \ - self.OPTIONS_ARCHITECTURES[1] + self.OPTIONS_ARCHITECTURES[3]: + if distr_conv and mdao_architecture not in self.OPTIONS_ARCHITECTURES[1] + \ + self.OPTIONS_ARCHITECTURES[3]: assert len(sys_conv) == 0, '{} system convergers found, none expected'.format(len(sys_conv)) else: assert len(sys_conv) == 1, '{} system convergers found, one expected.'.format(len(sys_conv)) @@ -572,8 +570,8 @@ class MdaoProcessGraph(ProcessGraph): local_convergers = self.graph['problem_formulation']['local_convergers'] sequences_partitions = self.graph['problem_formulation']['sequence_partitions'] sublevel_function_orderings = mdg.graph['distr_function_ordering'][1] - _, _, sub_convs = self.get_architecture_node_ids(self.OPTIONS_ARCHITECTURES[7], - number_of_groups=len(partitions)) + mdao_arch = mdg.graph['problem_formulation']['mdao_architecture'] + _, _, sub_convs = self.get_architecture_node_ids(mdao_arch, number_of_groups=len(partitions)) # Add process first sequence self.add_process(previous_sequence, process_step, mdg) @@ -803,10 +801,11 @@ class MdaoProcessGraph(ProcessGraph): process_list = [] for step in range(max_step + 1): process_step_nodes = self.find_all_nodes(attr_cond=['process_step', '==', step]) + updated_process_step_nodes = copy.deepcopy(process_step_nodes) for process_step_node in process_step_nodes: if self.nodes[process_step_node]['architecture_role'] in self.ARCHITECTURE_ROLES_FUNS[:4]: - process_step_nodes.remove(process_step_node) - process_list.extend(process_step_nodes) + updated_process_step_nodes.remove(process_step_node) + process_list.extend(updated_process_step_nodes) return process_list def get_process_hierarchy(self): diff --git a/kadmos/utilities/general.py b/kadmos/utilities/general.py index 247550918..7c98f710d 100644 --- a/kadmos/utilities/general.py +++ b/kadmos/utilities/general.py @@ -157,9 +157,8 @@ def get_mdao_setup(mdao_setup): 'unconverged-DOE-J', # 13 'converged-DOE-GS', # 14 'converged-DOE-J', # 15 - 'distributed-convergence', # 16 - 'CO', # 17 - 'BLISS-2000'] # 18 + 'CO', # 16 + 'BLISS-2000'] # 17 if mdao_setup.endswith(('-FF', '-MC', '-LH', '-CT')): mdao_setup = mdao_setup[:-3] @@ -228,14 +227,10 @@ def get_mdao_setup(mdao_setup): mda_type = 'Jacobi' allow_unconverged_couplings = False elif mdao_setup == mdao_defintions[16]: - mdo_architecture = 'distributed-convergence' - mda_type = None - allow_unconverged_couplings = False - elif mdao_setup == mdao_defintions[17]: mdo_architecture = 'CO' mda_type = None allow_unconverged_couplings = False - elif mdao_setup == mdao_defintions[18]: + elif mdao_setup == mdao_defintions[17]: mdo_architecture = 'BLISS-2000' mda_type = None allow_unconverged_couplings = False -- GitLab