diff --git a/kadmos/graph/graph_data.py b/kadmos/graph/graph_data.py
index f3e3121acf95941e4bd97a7dc7e720610bda5904..7b2d2fad0f0a4b21571d93311c7df85e3a4cfd2a 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 7461448f24712a5c54e2d40a7078f1d76e627e50..1b786868d2a885aaa8af9fd8c77062762eca5b5b 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 31d36a7237def1fd83d868912f7a70cb6cc7f33e..e892d984a29a81f7b9a8e3848d0c7792cfe46a65 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 2475509188e8ad6a3a927cfefd9755467ad57342..7c98f710d6caaabc21df8c35536dbaf447155332 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