Index: mttroot/mtt/bin/trans/m/cbg2ese.m ================================================================== --- mttroot/mtt/bin/trans/m/cbg2ese.m +++ mttroot/mtt/bin/trans/m/cbg2ese.m @@ -1,378 +1,372 @@ function structure = cbg2ese(system_name, system_type, system_cr, ... system_args, full_name, full_name_repetition, ... repetition,... structure, structure_file,infofilenum) -% Set up globals to count the component inputs and outputs. This relies on -% the named SS (the ports) being in the correct order. Using globals here -% avoids changing the common argument list for all _eqn files for something -% which is only used for named SS components. +# Set up globals to count the component inputs and outputs. This relies on +# the named SS (the ports) being in the correct order. Using globals here +# avoids changing the common argument list for all _eqn files for something +# which is only used for named SS components. global local_u_index global local_y_index global at_top_level -% -% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% %%%%% Model Transformation Tools %%%%% -% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% Matlab function cbg2ese.m -% Acausal bond graph to causal bond graph: mfile format -% Structure matrix [states,nonstates,inputs,outputs,zero_outputs] - -% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% %% Version control history -% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% %% $Id$ -% %% $Log$ -% %% Revision 1.24 1998/07/27 10:26:02 peterg -% %% No change - but fixed bug in alias_args -% %% -% %% Revision 1.23 1998/07/08 12:33:51 peterg -% %% Reinstated the infofilenum parameter. -% %% -% %% Revision 1.22 1998/07/04 07:10:27 peterg -% %% Don't evaluate alias if no constitutive relationship or args and write -% %% message. -% %% -% %% Revision 1.21 1998/07/03 18:58:58 peterg -% %% Put arg alias stuff within function alias_args -% %% Called recursively to handle arithmetic expressions -% %% -% %% Revision 1.20 1998/07/03 14:39:09 peterg -% %% Added info messages a bit busy now! -% %% -% %% Revision 1.19 1998/04/12 11:58:19 peterg -% %% Rename port components by changing name_r to [name_r -% %% -% %% Revision 1.18 1998/04/11 18:59:16 peterg -% %% at_top_level now global - passed to SS components -% %% -% %% Revision 1.17 1998/04/04 10:47:31 peterg -% %% Uses (coerced) components from _cbg file - _abg not now used here. -% %% -% %% Revision 1.16 1998/03/06 09:38:58 peterg -% %% Now writes correct structure file for multiport C & I -% %% -% %% Revision 1.15 1997/12/16 18:24:33 peterg -% %% Added unknown_input to structure list -% %% -% %% Revision 1.14 1997/08/26 07:51:10 peterg -% %% Now counts the local input and outputs by order of appearence rather -% %% than by port number - it therfore handles ports with bicausality correctely. -% %% -% %% Revision 1.13 1997/05/19 16:45:56 peterg -% %% Fixed ISW bug -- deleted spurious ISW_eqn.m file -% %% -% %% Revision 1.12 1997/04/15 09:17:26 peterg -% %% Added the structure file - contains details of states etc. -% %% -% %% Revision 1.11 1996/12/07 18:20:11 peterg -% %% Replaces null argument by a default and tells user. -% %% -% %% Revision 1.10 1996/12/07 17:37:07 peterg -% %% Now handles numbered SS ports appearing at top level. -% %% -% %% Revision 1.9 1996/12/04 21:49:47 peterg -% %% Compares full-name with empty string (instead of testing for zero -% %% length) -% %% -% %% Revision 1.8 1996/08/30 16:36:08 peter -% %% More info written to ese files. -% %% -% %% Revision 1.7 1996/08/30 11:23:13 peter -% %% Argument substitution implemented. -% %% -% %% Revision 1.6 1996/08/27 08:04:52 peterg -% %% Handles complex components and repetative components. -% %% -% %% Revision 1.5 1996/08/24 15:02:23 peter -% %% Writes `END;' to keep reduce happy. -% %% -% %% Revision 1.4 1996/08/19 09:03:41 peter -% %% Handles repeating components. -% %% -% %% Revision 1.3 1996/08/18 20:08:02 peter -% %% Included additional structure: structure(5) = zero_outputs. -% %% -% %% Revision 1.2 1996/08/08 18:08:11 peter -% %% Sorted out file naming sceme -% %% -% %% Revision 1.1 1996/08/08 15:53:23 peter -% %% Initial revision -% %% -% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -system_name, system_type, full_name, - -pc = "%"; - -% Set up the names corresponding to the structure matrix. -structure_name = [ - "state ", - "nonstate ", - "input ", - "output ", - "zero_output ", - "unknown_input"]; - - -% Are we at the top level of the heirarchy? -at_top_level = strcmp(full_name, ""); - -% Create the (full) system name -if at_top_level - full_name = system_name; - full_name_repetition = system_name; - system_type = system_name; -else - full_name = [full_name, "_", system_name]; - full_name_repetition = [full_name_repetition, ... - "_", system_name, "_", num2str(repetition)]; -end; - - -% $$$ full_name_type = [full_name, "_", system_type]; -% $$$ cbg_name = [full_name_type, "_cbg"]; -cbg_name = [full_name, "_cbg"]; -% Return if cbg file doesn't exist -if exist(cbg_name)~=2 - disp([cbg_name, " does not exist"]); - return -end; - -% Setup files -ese_name = [full_name_repetition, "_ese.r"]; -ese_file = fopen(ese_name, "w"); - -fprintf(ese_file, "\n%s%s Equation file for system %s (file %s)\n", ... - pc, pc, full_name_repetition, ese_name); -fprintf(ese_file, "%s%s Generated by MTT\n\n", pc, pc); - -% Evaluate the system function to get the bonds - eval(["[bonds,status,system_type,components] = ", cbg_name, ";"]); +# +# ###################################### +# ##### Model Transformation Tools ##### +# ###################################### +# +# Matlab function cbg2ese.m +# Acausal bond graph to causal bond graph: mfile format +# Structure matrix [states,nonstates,inputs,outputs,zero_outputs] + +# ############################################################### +# ## Version control history +# ############################################################### +# ## $Id$ +# ## $Log$ +# ## Revision 1.25 1998/07/28 19:05:12 peterg +# ## Sttill has vector SS port bug? +# ## +# ## Revision 1.24 1998/07/27 10:26:02 peterg +# ## No change - but fixed bug in alias_args +# ## +# ## Revision 1.23 1998/07/08 12:33:51 peterg +# ## Reinstated the infofilenum parameter. +# ## +# ## Revision 1.22 1998/07/04 07:10:27 peterg +# ## Don't evaluate alias if no constitutive relationship or args and write +# ## message. +# ## +# ## Revision 1.21 1998/07/03 18:58:58 peterg +# ## Put arg alias stuff within function alias_args +# ## Called recursively to handle arithmetic expressions +# ## +# ## Revision 1.20 1998/07/03 14:39:09 peterg +# ## Added info messages a bit busy now! +# ## +# ## Revision 1.19 1998/04/12 11:58:19 peterg +# ## Rename port components by changing name_r to [name_r +# ## +# ## Revision 1.18 1998/04/11 18:59:16 peterg +# ## at_top_level now global - passed to SS components +# ## +# ## Revision 1.17 1998/04/04 10:47:31 peterg +# ## Uses (coerced) components from _cbg file - _abg not now used here. +# ## +# ## Revision 1.16 1998/03/06 09:38:58 peterg +# ## Now writes correct structure file for multiport C & I +# ## +# ## Revision 1.15 1997/12/16 18:24:33 peterg +# ## Added unknown_input to structure list +# ## +# ## Revision 1.14 1997/08/26 07:51:10 peterg +# ## Now counts the local input and outputs by order of appearence rather +# ## than by port number - it therfore handles ports with bicausality correctely. +# ## +# ## Revision 1.13 1997/05/19 16:45:56 peterg +# ## Fixed ISW bug -- deleted spurious ISW_eqn.m file +# ## +# ## Revision 1.12 1997/04/15 09:17:26 peterg +# ## Added the structure file - contains details of states etc. +# ## +# ## Revision 1.11 1996/12/07 18:20:11 peterg +# ## Replaces null argument by a default and tells user. +# ## +# ## Revision 1.10 1996/12/07 17:37:07 peterg +# ## Now handles numbered SS ports appearing at top level. +# ## +# ## Revision 1.9 1996/12/04 21:49:47 peterg +# ## Compares full-name with empty string (instead of testing for zero +# ## length) +# ## +# ## Revision 1.8 1996/08/30 16:36:08 peter +# ## More info written to ese files. +# ## +# ## Revision 1.7 1996/08/30 11:23:13 peter +# ## Argument substitution implemented. +# ## +# ## Revision 1.6 1996/08/27 08:04:52 peterg +# ## Handles complex components and repetative components. +# ## +# ## Revision 1.5 1996/08/24 15:02:23 peter +# ## Writes `END;' to keep reduce happy. +# ## +# ## Revision 1.4 1996/08/19 09:03:41 peter +# ## Handles repeating components. +# ## +# ## Revision 1.3 1996/08/18 20:08:02 peter +# ## Included additional structure: structure(5) = zero_outputs. +# ## +# ## Revision 1.2 1996/08/08 18:08:11 peter +# ## Sorted out file naming sceme +# ## +# ## Revision 1.1 1996/08/08 15:53:23 peter +# ## Initial revision +# ## +# ############################################################# + + system_name, system_type, full_name, + + pc = "%"; + +# Set up the names corresponding to the structure matrix. + structure_name = [ + "state ", + "nonstate ", + "input ", + "output ", + "zero_output ", + "unknown_input"]; + + +# Are we at the top level of the heirarchy? + at_top_level = strcmp(full_name, ""); + +# Create the (full) system name + if at_top_level + full_name = system_name; + full_name_repetition = system_name; + system_type = system_name; + else + full_name = [full_name, "_", system_name]; + full_name_repetition = [full_name_repetition, ... + "_", system_name, "_", num2str(repetition)]; + end; + + + + cbg_name = [full_name, "_cbg"]; + if exist(cbg_name)~=2 # Return if cbg file doesn't exist + disp([cbg_name, " does not exist"]); + return + end; + +# Setup files + ese_name = [full_name_repetition, "_ese.r"]; + ese_file = fopen(ese_name, "w"); + + fprintf(ese_file, "\n%s%s Equation file for system %s (file %s)\n", ... + pc, pc, full_name_repetition, ese_name); + fprintf(ese_file, "%s%s Generated by MTT\n\n", pc, pc); + +# Evaluate the system function to get the bonds + eval(["CBG = ", cbg_name, ";"]); + #eval(["[bonds,status,system_type,components] = ", cbg_name, ";"]); abg_name = [system_type, "_abg"]; cmp_name = [system_type, "_cmp"]; alias_name = [system_type, "_alias"]; -% No longer needed - cbg now has components: -% eval(["[junk,components]=", abg_name, ";"]); +# No longer needed - cbg now has components: +# eval(["[junk,components]=", abg_name, ";"]); - % Find number of bonds - [n_bonds,columns] = size(bonds); + # Find number of bonds + [n_bonds,columns] = size(CBG.bonds); if (columns ~= 2)&(n_bonds>0) error("Incorrect bonds matrix: must have 2 columns"); - end; - - % Find number of components - [n_components,columns] = size(components); - n_components = n_components - - % Set up the first dummy bond number - needed for repetative components - next_bond = max(max(abs(components)))+1; - - % Set up the counters for the labelled SS. These are, by definition, - % encountered first and so the counters will not be messed up by subsystems. + endif; + +# # Find number of components +# [n_components,columns] = size(components); +# n_components = n_components + + # Set up the first dummy bond number - needed for repetative components +# next_bond = max(max(abs(components)))+1; + + # Set up the counters for the labelled SS. These are, by definition, + # encountered first and so the counters will not be messed up by subsystems. local_u_index = 0; local_y_index = 0; if (length(system_args)==0) mtt_info(sprintf("No arguments given so no argument aliasing done for system %s(%s)",\ - system_name,system_type), infofilenum); - else - eval([ "alias = ", alias_name ";"]); - end; + system_name,system_type), infofilenum); + endif; if (length(system_cr)==0) mtt_info(sprintf("No cr given so no cr aliasing done for system %s(%s)",\ - system_name,system_type), infofilenum); - else - eval([ "alias = ", alias_name ";"]); - end; - - for i = 1:n_components - comp = nozeros(components(i,:)); - bond_list = abs(comp); - direction = sign(comp)'*[1 1]; - % Convert from arrow orientated to component orientated causality - comp_bonds = bonds(bond_list,:).*direction; - -disp("---- Component ---"); - % Get the component details - eval([ "[comp_type,comp_name,cr,args,repetitions] = ", cmp_name, "(i)" ... - ]); - - % Alias the args list -- if not at top level - message = sprintf("\tfor component %s (%s) within %s",\ - comp_name,comp_type,full_name); - if (length(system_args)>0) - args = alias_args(args,alias,";",message,infofilenum) - end; - if (length(system_cr)>0) - cr = alias_args(cr,alias,";",message,infofilenum) - end; - - % Substitute positional ($1 etc) arguments - cr = subs_arg(cr,system_cr, ... - "lin",full_name,comp_type,comp_name,infofilenum); - args = subs_arg(args,system_args, ... - "1",full_name,comp_type,comp_name,infofilenum); - - % change name of 0 and 1 components -- matlab doesn't like numbers here - if strcmp(comp_type,"0") - comp_type = "zero"; - end; - if strcmp(comp_type,"1") - comp_type = "one"; - end; - - ports = length(bond_list); - - if repetitions>1 - port_pairs = ports/2; - if round(port_pairs)~=port_pairs; - mtt_info(["Repeated component ", comp_name, ... - " has an odd number of ports - ignoring repetitions"], infofilenum); - repetitions = 1; - end; - end; - - if repetitions>1 - odd_bonds = bond_list(1:2:ports-1); - even_bonds = bond_list(2:2:ports); - end; - - for k = 1:repetitions - - if repetitions>1 - - if k==1 - bond_list(1:2:ports-1) = odd_bonds; - else - bond_list(1:2:ports-1) = bond_list(2:2:ports); - end; - - if k==repetitions - bond_list(2:2:ports) = even_bonds; - else - new_bonds = [next_bond:next_bond+port_pairs-1]; - next_bond = next_bond+port_pairs; - bond_list(2:2:ports) = new_bonds; - end; - - end; - - % Invoke the appropriate equation-generating procedure - name_r = full_name_repetition; - eqn_name = [comp_type, "_eqn"] - - if exist(eqn_name)~=2 % Try a compound component - disp("---PUSH---"); bond_list, comp_name, comp_type - structure = cbg2ese(comp_name, comp_type, cr, args, ... - full_name, full_name_repetition, ... - k, structure, structure_file, infofilenum); - - % Link up the bonds - fprintf(ese_file, ... - "\n\t%s Equations linking up subsystem %s (%s)\n\n", ... - pc, comp_name, comp_type); - name_comp_name = sprintf("%s_%s_%d", ... - full_name_repetition, comp_name, k); - -printf("\n\t%s Equations linking up subsystem %s (%s)\n\n",\ - pc, comp_name, comp_type); -bond_list - - u_index = 0; y_index = 0; % Count the inputs and outputs - for port_number=1:length(bond_list) - % Effort - if comp_bonds(port_number,1)==1 % Source - u_index = u_index + 1; - fprintf(ese_file, "%s_MTTu%d := %s;\n", ... - name_comp_name, u_index, varname(name_r, ... - bond_list(port_number),1)); - else % Sensor - y_index = y_index + 1; - fprintf(ese_file, "%s := %s_MTTy%d;\n", ... - varname(name_r, ... - bond_list(port_number),1), name_comp_name, y_index); - end; - % Flow - if comp_bonds(port_number,2)==-1 % Source - u_index = u_index + 1; - fprintf(ese_file, "%s_MTTu%d := %s;\n", ... - name_comp_name, u_index, varname(name_r, ... - bond_list(port_number),-1)); - else % Sensor - y_index = y_index + 1; - fprintf(ese_file, "%s := %s_MTTy%d;\n", ... - varname(name_r, ... - bond_list(port_number),-1), name_comp_name, y_index); - end; - end; - - disp("---POP---"); - else % its a simple component - fprintf(ese_file, "\n\t%s Equations for component %s (%s), repetition %d\n\n", ... - pc, comp_name, comp_type,k); - - - % Is it a named port? (Name begins with [) - Named_Port = (comp_name(1)=="["); - - if Named_Port %Add [ to start of name - name_r = ["[" name_r]; - end; - -# % Take port SS to be ordinary SS at top level -# if at_top_level & strcmp(comp_type, "SS") -# effort_attribute = cr; -# flow_attribute = args; -# if strcmp(effort_attribute, "MTT_port") % Its a numbered port -# effort_attribute = "external"; -# flow_attribute = "external"; -# cr = effort_attribute; -# args = flow_attribute; -# end; -# end; - - % Save the current structure - old_structure = structure; - - % Generate the simple component equations - eval(["structure = ", ... - eqn_name, ... - "(name_r,bond_list,comp_bonds, ... - direction,cr,args,structure,ese_file);" ]); - - % If structure has changed, write info to structure file. - structure_change = structure-old_structure; - - % The following line is to avoid probs with multiport C or I - % it needs changing to handle multi ports correctly - structure_changes = sum(structure_change); - - structure_change = structure_change>zeros(size(structure_change)); - if structure_changes>0 - which_indices = getindex(structure_change,1); - which_indices = which_indices(:,2)'; - for which_index=which_indices - value = structure(which_index); - value_change=value-old_structure(which_index); - for k=1:value_change - fprintf(structure_file, ... - "%s\t%1.0f\t%s\t%s\t%1.0f\n", ... - structure_name(which_index,:), value-k+1, ... - comp_name, full_name, repetition); - end; - end; - end; - - end; - end; - end; - - % Close the files + system_name,system_type), infofilenum); + endif; + + + field=["ports";"subsystems"]; # Do for both ports and subsystems - + # ports first + for i=1:2 + if struct_contains(CBG,field(i,:)); + eval(["CBG_field = CBG.",field(i,:), ";"]); + for [subsystem,comp_name] = CBG_field + #comp = nozeros(components(i,:)); + comp = subsystem.connections; + bond_list = abs(comp); + direction = sign(comp)'*[1 1]; + # Convert from arrow orientated to component orientated causality + comp_bonds = CBG.bonds(bond_list,:).*direction; + + disp(["---- ", field(i,:), "Component ---"]); + # Get the component details + #eval([ "[comp_type,comp_name,cr,args,repetitions] = ", cmp_name, "(i)"]); + + # Alias the args list -- if not at top level + message = sprintf("\tfor component %s (%s) within %s",\ + comp_name,subsystem.type,full_name); + if (length(system_args)>0) + subsystem.arg = alias_args(subsystem.arg,subsystem.alias,";",message,infofilenum) + endif; + if (length(system_cr)>0) + subsystem.cr = alias_args(subsystem.cr,subsystem.alias,";",message,infofilenum) + endif; + + # Substitute positional ($1 etc) arguments + subsystem.cr = subs_arg(subsystem.cr,system_cr, ... + "lin",full_name,subsystem.type,comp_name,infofilenum); + subsystem.arg = subs_arg(subsystem.arg,system_args, ... + "1",full_name,subsystem.type,comp_name,infofilenum); + + # change name of 0 and 1 components -- matlab doesn't like numbers here + if strcmp(subsystem.type,"0") + subsystem.type = "zero"; + endif; + if strcmp(subsystem.type,"1") + subsystem.type = "one"; + endif; + + ports = length(bond_list); + + if subsystem.repetitions>1 + port_pairs = ports/2; + if round(port_pairs)~=port_pairs; + mtt_info(["Repeated component ", comp_name, ... + " has an odd number of ports - ignoring repetitions"], infofilenum); + subsystem.repetitions = 1; + endif; + endif; + + if subsystem.repetitions>1 + odd_bonds = bond_list(1:2:ports-1); + even_bonds = bond_list(2:2:ports); + endif; + + for k = 1:subsystem.repetitions + + if subsystem.repetitions>1 + + if k==1 + bond_list(1:2:ports-1) = odd_bonds; + else + bond_list(1:2:ports-1) = bond_list(2:2:ports); + endif; + + if k==subsystem.repetitions + bond_list(2:2:ports) = even_bonds; + else + new_bonds = [next_bond:next_bond+port_pairs-1]; + next_bond = next_bond+port_pairs; + bond_list(2:2:ports) = new_bonds; + endif; + + endif; + + # Invoke the appropriate equation-generating procedure + name_r = full_name_repetition; + eqn_name = [subsystem.type, "_eqn"] + + if exist(eqn_name)~=2 # Try a compound component + disp("---PUSH---"); bond_list, comp_name, subsystem.type + structure = cbg2ese(comp_name, subsystem.type, subsystem.cr, subsystem.arg, ... + full_name, full_name_repetition, ... + k, structure, structure_file, infofilenum); + + # Link up the bonds + fprintf(ese_file, ... + "\n\t%s Equations linking up subsystem %s (%s)\n\n", ... + pc, comp_name, subsystem.type); + name_comp_name = sprintf("%s_%s_%d", ... + full_name_repetition, comp_name, k); + + printf("\n\t%s Equations linking up subsystem %s (%s)\n\n",\ + pc, comp_name, subsystem.type); + bond_list + + u_index = 0; y_index = 0; # Count the inputs and outputs + for port_number=1:length(bond_list) + # Effort + if comp_bonds(port_number,1)==1 # Source + u_index = u_index + 1; + fprintf(ese_file, "%s_MTTu%d := %s;\n", ... + name_comp_name, u_index, varname(name_r, ... + bond_list(port_number),1)); + else # Sensor + y_index = y_index + 1; + fprintf(ese_file, "%s := %s_MTTy%d;\n", ... + varname(name_r, ... + bond_list(port_number),1), name_comp_name, y_index); + end; + # Flow + if comp_bonds(port_number,2)==-1 # Source + u_index = u_index + 1; + fprintf(ese_file, "%s_MTTu%d := %s;\n", ... + name_comp_name, u_index, varname(name_r, ... + bond_list(port_number),-1)); + else # Sensor + y_index = y_index + 1; + fprintf(ese_file, "%s := %s_MTTy%d;\n", ... + varname(name_r, ... + bond_list(port_number),-1), name_comp_name, y_index); + end; + end; + + disp("---POP---"); + else # its a simple component + fprintf(ese_file, "\n\t%s Equations for component %s (%s), repetition %d\n\n", ... + pc, comp_name, subsystem.type,k); + + + # Is it a named port? (Name begins with [) + Named_Port = (comp_name(1)=="["); + + if Named_Port #Add [ to start of name + name_r = ["[" name_r]; + endif; + + # Save the current structure + old_structure = structure; + + # Generate the simple component equations + eval(["structure = ", ... + eqn_name, ... + "(name_r,bond_list,comp_bonds, ... + direction,subsystem.cr,subsystem.arg,structure,ese_file);" ]); + + # If structure has changed, write info to structure file. + structure_change = structure-old_structure; + + # The following line is to avoid probs with multiport C or I + # it needs changing to handle multi ports correctly + structure_changes = sum(structure_change); + + structure_change = structure_change>zeros(size(structure_change)); + if structure_changes>0 + which_indices = getindex(structure_change,1); + which_indices = which_indices(:,2)'; + for which_index=which_indices + value = structure(which_index); + value_change=value-old_structure(which_index); + for k=1:value_change + fprintf(structure_file, ... + "%s\t%1.0f\t%s\t%s\t%1.0f\n", ... + structure_name(which_index,:), value-k+1, ... + comp_name, full_name, repetition); + endfor; + endfor; + endif; + + end; + end; + endfor # [subsystem,comp_name] = CBG_field + endif # struct_contains(CBG,field(i,:)) + endfor # i=1:2 + # Close the files fclose(ese_file); +endfunction