## -*-octave-*- function [bonds,components,n_vector_bonds] = \ ibg2abg(name,bonds,infofile,errorfile) ## write useful quantity of data to log struct_levels_to_print = 4; ############################################### ## Extract data from bonds structure (ibg.m) ## ############################################### disp("--- Started extracting bonds data ---") ## unique number for each (sub-) bond bond_number = 0; ## extract data from each bond for [bond, bond_name] = bonds i = str2num(split(bond_name, "bond")(2,:)) ## extract type and name of component at each end head.name = deblank(split(bond.head.component, ":")(2,:)); head.type = deblank(split(bond.head.component, ":")(1,:)); tail.name = deblank(split(bond.tail.component, ":")(2,:)); tail.type = deblank(split(bond.tail.component, ":")(1,:)); ## capture directional info head.end = "head"; tail.end = "tail"; ## assign vector bond index head.index = i; tail.index = i; ## determine if internal port (and fix name) or subsystem if (strcmp(head.type, "SS") & (index(head.name, "[") == 1)) head.is_port = true; head.name = mtt_strip_name(head.name); else head.is_port = false; endif if (strcmp(tail.type, "SS") & (index(tail.name, "[") == 1)) tail.is_port = true; tail.name = mtt_strip_name(tail.name); else tail.is_port = false; endif ## determine if junction if (strcmp(head.type, "0") | (strcmp(head.type, "1"))) head.is_junction = true; else head.is_junction = false; endif if (strcmp(tail.type, "0") | (strcmp(tail.type, "1"))) tail.is_junction = true; else tail.is_junction = false; endif ## assign (vector) port names if (! head.is_junction) if (strcmp(bond.head.ports, "[]")) head.label = "in"; mtt_info(sprintf("Defaulting port name %s on component %s (%s)", head.label, head.name, head.type), infofile); else head.label = mtt_strip_name(bond.head.ports); endif endif if (! tail.is_junction) if (strcmp(bond.tail.ports, "[]")) tail.label = "out"; mtt_info(sprintf("Defaulting port name %s on component %s (%s)", tail.label, tail.name, tail.type), infofile); else tail.label = mtt_strip_name(bond.tail.ports); endif endif ## apply aliases if (! head.is_junction) head.alias = eval(sprintf("%s_alias", head.type)); if (is_struct(head.alias)) if (struct_contains(head.alias, head.label)) old_name = head.label; new_name = eval(sprintf("head.alias.%s", old_name)); head.label = new_name; mtt_info(sprintf("Aliasing [%s]\t on component %s (%s) to [%s]", old_name, head.name, head.type, new_name), \ infofile); endif endif endif if (!tail.is_junction) tail.alias = eval(sprintf("%s_alias", tail.type)); if (is_struct(tail.alias)) if (struct_contains(tail.alias, tail.label)) old_name = tail.label; new_name = eval(sprintf("tail.alias.%s", old_name)); tail.label = new_name; mtt_info(sprintf("Aliasing [%s]\t on component %s (%s) to [%s]", old_name, tail.name, tail.type, new_name), \ infofile); endif endif endif ## expand vector bonds disp("--- Expanding vector bonds ---"); if (! (head.is_junction | tail.is_junction)) ## junctions can't be expanded until all bonds are assigned ## as label might occur on only one bond [head.sub_bonds, head.n_sub_bonds] = split_port(head.label) [tail.sub_bonds, tail.n_sub_bonds] = split_port(tail.label) if (head.n_sub_bonds != tail.n_sub_bonds) mtt_error(sprintf("Vector ports %s and %s are not compatible", head.label, tail.label), errorfile); elseif (head.n_sub_bonds > 1) mtt_info(sprintf("Vector port %s matching %s", head.label, tail.label), infofile); endif endif ## assign unique number and causality to each sub-bond if (! (head.is_junction | tail.is_junction)) for sub_bond = 1:head.n_sub_bonds ++bond_number; eval(sprintf("head.bond%i.index = %i", sub_bond, +bond_number)); eval(sprintf("tail.bond%i.index = %i", sub_bond, -bond_number)); ## effort causality if (strcmp(bond.causality.effort, "head")) causality(bond_number, 1) = +1; head.causality = +1; elseif (strcmp(bond.causality.effort, "tail")) causality(bond_number, 1) = -1; head.causality = -1; else causality(bond_number, 1) = 0; head.causality = 0; endif ## flow causality if (strcmp(bond.causality.flow, "head")) causality(bond_number, 2) = -1; tail.causality = -1; elseif (strcmp(bond.causality.flow, "tail")) causality(bond_number, 2) = +1; tail.causality = +1; else causality(bond_number, 2) = 0; tail.causality = 0; endif eval(sprintf("head.bond%i.port = deblank(head.sub_bonds(%i,:))", sub_bond, sub_bond)); eval(sprintf("tail.port%i.port = deblank(tail.sub_bonds(%i,:))", sub_bond, sub_bond)); endfor else ## save bond causality data within junction for later use head.causality.effort = bond.causality.effort; tail.causality.effort = bond.causality.effort; head.causality.flow = bond.causality.flow; tail.causality.flow = bond.causality.flow; endif ## copy bond data to component structure (comp_s) if (head.is_port) S = sprintf("comp_s.port.%s", head.name); eval(sprintf("%s.vec_bond%i = head", S, i)); eval(sprintf("%s.name = '%s'", S, head.name)); else S = sprintf("comp_s.comp.%s", head.name); eval(sprintf("%s.vec_bond%i = head", S, i)); eval(sprintf("%s.name = '%s'", S, head.name)); eval(sprintf("%s.type = '%s'", S, head.type)); endif if (tail.is_port) S = sprintf("comp_s.port.%s", tail.name); eval(sprintf("%s.vec_bond%i = tail", S, i)); eval(sprintf("%s.name = '%s'", S, tail.name)); else S = sprintf("comp_s.comp.%s", tail.name); eval(sprintf("%s.vec_bond%i = tail", S, i)); eval(sprintf("%s.name = '%s'", S, tail.name)); eval(sprintf("%s.type = '%s'", S, tail.type)); endif endfor disp("--- Finished extracting bond data ---"); ############################# ## Expand vector junctions ## ############################# if (struct_contains(comp_s, "comp")) for [comp, comp_name] = comp_s.comp if (strcmp(comp.type, "0") | strcmp(comp.type, "1")) n_ports = size(struct_elements(comp), 1) - 2; ## subtracted 2 for name and type n_named_ports = 0; ## get labelled ports for [vec_bond, vec_bond_name] = comp if (! exist("vec_bond.label")) vec_bond.label = "[]"; endif if (index(vec_bond_name, "vec_bond") == 1) if (! strcmp(vec_bond.label, "[]")) n_named_ports += 1; port_name = vec_bond.label; endif endif eval(sprintf("comp.%s = vec_bond", vec_bond_name)); endfor ## attach labels to unlabelled ports if (n_named_ports == 0) for [vec_bond, vec_bond_name] = comp if (index(vec_bond_name, "vec_bond") == 1) vec_bond.label = "in"; endif eval(sprintf("comp.%s = vec_bond", vec_bond_name)); endfor elseif (n_named_ports == 1) mtt_info(sprintf("Defaulting all ports on junction %s to %s", comp_name, port_name), infofile); for [vec_bond, vec_bond_name] = comp if (index(vec_bond_name, "vec_bond") == 1) vec_bond.label = port_name; endif eval(sprintf("comp.%s = vec_bond", vec_bond_name)); endfor elseif ((n_named_ports != 0) && (n_named_ports != n_ports)) mtt_error(sprintf("Junction must have 0,1 or %i port labels", n_ports), errorfile); endif # eval(sprintf("comp.%s.%s = vec_bond", comp_name, vec_bond_name)) ## expand vector bonds for [vec_bond, vec_bond_name] = comp if (index(vec_bond_name, "vec_bond") == 1) [sub_bonds, n_sub_bonds] = split_port(vec_bond.label) for sub_bond = 1:n_sub_bonds ++bond_number; if (strcmp(vec_bond.end, "head")) direction = +1; else direction = -1; endif eval(sprintf("vec_bond.bond%i.index = %i", sub_bond, bond_number*direction)); ## causality if (strcmp(vec_bond.causality.effort, "head")) causality(bond_number, 1) = +1; elseif (strcmp(vec_bond.causality.effort, "tail")) causality(bond_number, 1) = -1; else causality(bond_number, 1) = 0; endif if (strcmp(vec_bond.causality.flow, "head")) causality(bond_number, 2) = -1; elseif (strcmp(vec_bond.causality.flow, "tail")) causality(bond_number, 2) = +1; else causality(bond_number, 2) = 0; endif endfor endif eval(sprintf("comp.%s = vec_bond", vec_bond_name)); endfor endif eval(sprintf("comp_s.comp.%s = comp", comp_name)); endfor endif ## FIXME: add sub_bonds to junctions bonds = causality; ################################# ## Map component data to cmp.m ## ################################# ## count number of components if (struct_contains(comp_s, "comp")) n_comps = size(struct_elements(comp_s.comp), 1) else n_comps = 0; endif ## count number of internal ports if (struct_contains(comp_s, "port")) n_ports = size(struct_elements(comp_s.port), 1) else n_ports = 0; endif ## read data from _cmp.m for cmp = 1:(n_comps + n_ports) [this_type, this_name] = eval(sprintf("%s_cmp(%i)", name, cmp)); ## determine if internal port (and fix name) or subsystem if (strcmp(this_type, "SS") & (index(this_name, "[") == 1)) comp_or_port = "port"; this_name = mtt_strip_name(this_name) else comp_or_port = "comp"; endif eval(sprintf("comp_s.%s.%s.index = cmp", comp_or_port, this_name)); endfor disp("--- Finished reading _cmp.m ---"); comp_s ########################## ## Write n_vector_bonds ## ########################## for [comp, comp_name] = comp_s.comp i = 0; for [val, key] = comp if (index(key, "vec_bond") == 1) ++i; endif endfor n_vector_bonds(comp.index) = i; endfor ########################################### ## Write connections matrix (components) ## ########################################### components = zeros(n_comps, max(n_vector_bonds)); if (struct_contains(comp_s, "comp")) for [comp, comp_name] = comp_s.comp counter = 0; bond_list = zeros(1, max(n_vector_bonds)); for [vbond, vbond_name] = comp if (index(vbond_name, "vec_bond") == 1) for [sbond, sbond_name] = vbond if (index(sbond_name, "bond") == 1) components(comp.index, ++counter) = sbond.index; endif endfor endif endfor endfor endif disp("--- Finished writing components ---") endfunction ## TODO: to fix 1-label vector junctions ## TODO: to put error checks back in ## TODO: port_bond_list error (abg2cbg) # ########################################## # ## Assign names to all component ports ## # ########################################## # disp("--- Assigning port names ---") # if (struct_contains(comp_S, "comp")) # for [comp, comp_name] = comp_S.comp # if (strcmp(comp.type, "0") || strcmp(comp.type, "1")) # disp("---- default junctions ----") # if (comp.named_ports == 1) # ## one named port, find it ... # for [port, bond_number] = comp.ports # if (! strcmp(port.name, "[]")) # the_name = port.name # endif # endfor # ## ... and name all remaining ports identically # mtt_info(sprintf("Defaulting all ports on junction %s to %s", # comp_name, the_name)); # for [port, bond_number] = comp.ports # eval(sprintf("comp.ports.%s.name = the_name", bond_number)); # endfor # elseif ((comp.named_ports != 0) # && (comp.named_ports != comp.n_vector_bonds)) # mtt_error(sprintf("Junction %s must have 0, 1 or %i port \ # labels", \ # comp_name, comp.n_vector_bonds)); # endif # else # ## Not a junction # unlabelled_ports = comp.n_vector_bonds - comp.named_ports; # if (unlabelled_ports == 1) # ## find the unlabelled port ... # for [port, bond_number] = comp.ports # if (strcmp(port.name, "[]")) # ## ... and name it [in] or [out] # if (port.sign == +1) # port_name = "[in]"; # elseif (port.sign == -1) # port_name = "[out]"; # endif # eval(sprintf("comp.ports.%s.name = '%s'", # bond_number, port_name)); # E = "Defaulting port name %s\t on component %s (%s)"; # mtt_info(sprintf(E, port_name, comp_name, comp.type), # infofile); # endif # endfor # elseif (unlabelled_ports == 2) # ## find the unlabelled ports ... # clear unlabelled_port1 # for [port, bond_number] = comp.ports # if (strcmp(port.name, "[]")) # if (exist("unlabelled_port1")) # unlabelled_port2 = port; # bond_number2 = bond_number; # else # unlabelled_port1 = port; # bond_number1 = bond_number; # endif # endif # endfor # ## ... and try to assign [in] and [out] # if ((unlabelled_port1.sign == +1) # && (unlabelled_port2.sign == +1)) # E = "More than one unlabelled INport on component %s (%s)"; # mtt_error(sprintf(E, comp_name, comp.type)); # elseif ((unlabelled_port1.sign == -1) # && (unlabelled_port2.sign == -1)) # E = "More than one unlabelled OUTport on component %s (%s)"; # mtt_error(sprintf(E, comp_name, comp.type)); # else # if (unlabelled_port1.sign == +1) # name1 = "[in]"; # name2 = "[out]"; # elseif (unlabelled_port1.sign == -1) # name1 = "[out]"; # name2 = "[in]"; # endif # eval(sprintf("comp.ports.%s.name = '%s'", # bond_number1, name1)); # eval(sprintf("comp.ports.%s.name = '%s'", # bond_number2, name2)); # S = "Defaulting port name %s\t on component %s (%s)" # mtt_info(sprintf(S, name1, comp_name, comp.type), infofile); # mtt_info(sprintf(S, name2, comp_name, comp.type), infofile); # endif # endif # endif # eval(sprintf("comp_S.comp.%s = comp", comp_name)); # endfor # endif # disp(" --- Finished assigning port names ---") # endfunction