function mttWriteSystemDefinitions(model)
def.structure = define_data_structures(model) ;
def.covar = define_bond_covariables(model) ;
def.var = define_interface_covariables(model) ;
def.sympar = define_symbolic_parameters(model) ;
def.numpar = define_numerical_parameters(model) ;
def.input = define_input_variables(model) ;
def.state = define_state_variables(model) ;
def.opvar = define_operator_variables(model) ;
write_definitions(def,model) ;
function code = define_data_structures(model)
mttNotify('...defining data structures') ;
mttWriteNewLine ;
code = [] ;
line = 0 ;
tab = char(32*ones(1,3)) ;
line = line + 1 ;
code{line} = ['typedef struct {'] ;
line = line + 1 ;
code{line} = [tab,'double state,derivative ;'] ;
line = line + 1 ;
code{line} = ['} mttState ;'] ;
line = line + 1 ;
code{line} = '' ;
line = line + 1 ;
code{line} = ['typedef struct {'] ;
line = line + 1 ;
code{line} = [tab,'double effort,flow ;'] ;
line = line + 1 ;
code{line} = ['} mttGenericDomain ;'] ;
line = line + 1 ;
code{line} = '' ;
domain_names = mttGetFieldNames(model.env,'domain') ;
for i = 1:length(domain_names)
domain_name = domain_names{i} ;
domain = getfield(model.env,'domain',domain_name) ;
public_domain = model.env.public_domain(domain.dom) ;
item_names = mttGetFieldNames(public_domain,'item') ;
if isempty(domain.item)
first = 1 ;
last = length(item_names) ;
else
first = strmatch(domain.item,item_names,'exact') ;
last = first ;
end
for j = first:last
item_name = item_names{j} ;
covariables = getfield(public_domain,'item',item_name) ;
line = line + 1 ;
code{line} = ['typedef struct {'] ;
for k = 1:length(covariables.effort)
line = line + 1 ;
effort_covariable = strrep(covariables.effort{k},'.','__') ;
flow_covariable = strrep(covariables.flow{k},'.','__') ;
code{line} = [tab,'double ',effort_covariable,',',flow_covariable,' ;'] ;
end
definition = ['} mttDomain__',domain_name] ;
if isempty(domain.item)
definition = [definition,'__',item_name] ;
end
definition = [definition,' ;'] ;
line = line + 1 ;
code{line} = definition ;
if j<last
line = line + 1 ;
code{line} = '' ;
end
end
line = line + 1 ;
code{line} = '' ;
end
struct_names = mttGetFieldNames(model.env,'struct') ;
for i = 1:length(struct_names)
struct_name = struct_names{i} ;
struct = getfield(model.env,'struct',struct_name) ;
public_struct = model.env.public_struct(struct.str) ;
item_names = mttGetFieldNames(public_struct,'item') ;
index = strmatch(struct.item,item_names,'exact') ;
item_name = item_names{index} ;
variables = getfield(public_struct,'item',item_name,'var') ;
line = line + 1 ;
code{line} = ['typedef struct {'] ;
for k = 1:length(variables)
line = line + 1 ;
variable = strrep(variables{k},'.','__') ;
code{line} = [tab,'double ',variable,' ;'] ;
end
definition = ['} ',struct_name,' ;'] ;
line = line + 1 ;
code{line} = definition ;
if i<length(struct_names)
line = line + 1 ;
code{line} = '' ;
end
end
function code = define_bond_covariables(model,root,branch)
is_root_model = nargin==1 ;
if is_root_model
mttNotify('...defining bond covariables') ;
mttWriteNewLine ;
root = model ;
current_branch = mttDetachText(model.source,'/') ;
else
current_branch = branch ;
end
width = 0 ;
domain_names = mttGetFieldNames(root.env,'domain') ;
for j = 1:length(domain_names)
domain_name = domain_names{j} ;
width = max(width,length(domain_name)) ;
end
code = [] ;
line = 0 ;
number_of_bonds = mttGetFieldLength(model,'bond') ;
for i = 1:number_of_bonds
current_bond = model.bond(i) ;
specified_domain = current_bond.domain ;
specified_domain_item = current_bond.domain_item ;
user_domain_identification = mttIdentifyUserDomain(root.env,specified_domain,specified_domain_item) ;
if isempty(user_domain_identification)
data_structure = ['mttGenericDomain'] ;
else
data_structure = ['mttDomain__',user_domain_identification] ;
end
nominal_width = 14 + width ;
actual_width = length(data_structure) ;
gap = nominal_width - actual_width ;
whitespace = char(32*ones(1,gap+3)) ;
line = line + 1 ;
code{line} = [data_structure,whitespace,current_branch,'__',num2str(i),' ;'] ;
end
objects = mttGetFieldNames(model,'obj') ;
for i = 1:length(objects)
object_name = objects{i} ;
object = getfield(model,'obj',object_name) ;
if ~isempty(object.abg)
next_branch = [current_branch,'__',object_name] ;
additional_code = define_bond_covariables(object,root,next_branch) ;
if isempty(code)
code = additional_code ;
else
code = [code,additional_code] ;
end
end
end
if line==0
code = [] ;
end
function code = define_interface_covariables(model)
mttNotify('...defining interface covariables') ;
mttWriteNewLine ;
width = 0 ;
domain_names = mttGetFieldNames(model.env,'domain') ;
for j = 1:length(domain_names)
domain_name = domain_names{j} ;
width = max(width,length(domain_name)) ;
end
code = [] ;
line = 0 ;
previous_name = model.namelist(1).var ;
number_of_variables = mttGetFieldLength(model,'namelist') ;
for i = 2:number_of_variables % .... first variable is reserved !
variable_name = model.namelist(i).var ;
[variable_name,extension] = mttCutText(variable_name,'.') ;
if ~strcmp(variable_name,previous_name)
previous_name = variable_name ;
specified_domain = model.namelist(i).domain ;
specified_domain_item = model.namelist(i).domain_item ;
user_domain_identification = mttIdentifyUserDomain(model.env,specified_domain,specified_domain_item) ;
if isempty(user_domain_identification)
data_structure = ['mttGenericDomain'] ;
else
data_structure = ['mttDomain__',user_domain_identification] ;
end
nominal_width = 14 + width ;
actual_width = length(data_structure) ;
gap = nominal_width - actual_width ;
whitespace = char(32*ones(1,gap+3)) ;
line = line + 1 ;
code{line} = [data_structure,whitespace,variable_name,' ;'] ;
end
end
function code = define_symbolic_parameters(model)
mttNotify('...defining symbolic parameters') ;
mttWriteNewLine ;
model_name = mttDetachText(model.source,'/') ;
code = [] ;
line = 0 ;
number_of_variables = mttGetFieldLength(model,'sympar') ;
for i = 1:number_of_variables
variable_name = model.sympar{i} ;
default_value = model.sympar_default{i} ;
whitespace = char(32*ones(1,3)) ;
if isempty(default_value)
line = line + 1 ;
code{line} = ['double',whitespace,model_name,'___',variable_name,' ;'] ;
end
end
function code = define_numerical_parameters(model,root,branch)
is_root_model = nargin==1 ;
if is_root_model
mttNotify('...defining numerical parameters') ;
mttWriteNewLine ;
root = model ;
current_branch = mttDetachText(model.source,'/') ;
else
current_branch = branch ;
end
code = [] ;
line = 0 ;
number_of_variables = mttGetFieldLength(model,'numpar') ;
for i = 1:number_of_variables
variable_name = model.numpar{i} ;
whitespace = char(32*ones(1,3)) ;
line = line + 1 ;
code{line} = ['double',whitespace,current_branch,'___',variable_name,' ;'] ;
end
objects = mttGetFieldNames(model,'obj') ;
for i = 1:length(objects)
object_name = objects{i} ;
object = getfield(model,'obj',object_name) ;
next_branch = [current_branch,'__',object_name] ;
additional_code = [] ;
if ~isempty(object.abg)
additional_code = define_numerical_parameters(object,root,next_branch) ;
elseif ~isempty(object.cr)
additional_code = define_numerical_parameters(object.cr,root,next_branch) ;
end
if isempty(code)
code = additional_code ;
else
line = length(code) ;
for j = 1:length(additional_code)
if ~ismember(additional_code{j},code)
line = line + 1 ;
code{line} = additional_code{j} ;
end
end
end
end
function code = define_input_variables(model,root,branch)
is_root_model = nargin==1 ;
if is_root_model
mttNotify('...defining input variables') ;
mttWriteNewLine ;
root = model ;
current_branch = mttDetachText(model.source,'/') ;
else
current_branch = branch ;
end
code = [] ;
line = 0 ;
number_of_variables = mttGetFieldLength(model,'input') ;
for i = 1:number_of_variables
variable_name = model.input{i} ;
whitespace = char(32*ones(1,3)) ;
line = line + 1 ;
code{line} = ['double',whitespace,current_branch,'___',variable_name,' ;'] ;
end
objects = mttGetFieldNames(model,'obj') ;
for i = 1:length(objects)
object_name = objects{i} ;
object = getfield(model,'obj',object_name) ;
next_branch = [current_branch,'__',object_name] ;
additional_code = [] ;
if ~isempty(object.abg)
additional_code = define_input_variables(object,root,next_branch) ;
elseif ~isempty(object.cr)
additional_code = define_input_variables(object.cr,root,next_branch) ;
end
if isempty(code)
code = additional_code ;
else
line = length(code) ;
for j = 1:length(additional_code)
if ~ismember(additional_code{j},code)
line = line + 1 ;
code{line} = additional_code{j} ;
end
end
end
end
function code = define_state_variables(model,root,branch,env)
is_root_model = nargin==1 ;
if is_root_model
mttNotify('...defining state variables') ;
mttWriteNewLine ;
root = model ;
current_branch = mttDetachText(model.source,'/') ;
env = model.env ;
else
current_branch = branch ;
end
whitespace = char(32*ones(1,3)) ;
code = [] ;
line = 0 ;
if isfield(model,'state')
assigned_states = [] ;
counter = 0 ;
port_names = mttGetFieldNames(model.interface,'port') ;
for j = 1:length(port_names)
port_name = port_names{j} ;
port = getfield(model,'interface','port',port_name) ;
if ~isempty(port.assign)
assignment = port.assign ;
if port.was_generic & ~isempty(port.domain)
covariables = mttGetCovariables(env,port.domain,port.domain_item) ;
if port.is_effort_state
covar = covariables.effort ;
else
covar = covariables.flow ;
end
block_size = length(covar) ;
for k = 1:length(assignment.state)
counter = counter + 1 ;
assigned_states{counter} = assignment.state{k} ;
for var = 1:block_size
line = line + 1 ;
code{line} = ['mttState',whitespace,current_branch,'___',assignment.state{k},'___',covar{var},' ;'] ;
end
end
end
end
end
number_of_variables = mttGetFieldLength(model,'state') ;
for i = 1:number_of_variables
variable_name = model.state{i} ;
if ~ismember(variable_name,assigned_states)
line = line + 1 ;
code{line} = ['mttState',whitespace,current_branch,'___',variable_name,' ;'] ;
end
end
end
objects = mttGetFieldNames(model,'obj') ;
for i = 1:length(objects)
object_name = objects{i} ;
object = getfield(model,'obj',object_name) ;
next_branch = [current_branch,'__',object_name] ;
additional_code = [] ;
if ~isempty(object.abg)
additional_code = define_state_variables(object,root,next_branch,env) ;
elseif ~isempty(object.cr)
additional_code = define_state_variables(object.cr,root,next_branch,env) ;
end
if isempty(code)
code = additional_code ;
else
line = length(code) ;
for j = 1:length(additional_code)
if ~ismember(additional_code{j},code)
line = line + 1 ;
code{line} = additional_code{j} ;
end
end
end
end
function code = define_operator_variables(model,root,branch)
is_root_model = nargin==1 ;
if is_root_model
mttNotify('...defining operator variables') ;
mttWriteNewLine ;
root = model ;
current_branch = mttDetachText(model.source,'/') ;
else
current_branch = branch ;
end
code = [] ;
objects = mttGetFieldNames(model,'obj') ;
for i = 1:length(objects)
object_name = objects{i} ;
object = getfield(model,'obj',object_name) ;
next_branch = [current_branch,'__',object_name] ;
if ~isempty(object.abg)
additional_code = define_operator_variables(object,root,next_branch) ;
elseif ~isempty(object.cr)
line = 0 ;
additional_code = [] ;
number_of_operators = mttGetFieldLength(object.cr,'operator') ;
for j = 1:number_of_operators
operator = object.cr.operator(j) ;
number_of_vars = mttGetFieldLength(operator,'var') ;
for k = 1:number_of_vars
variable_name = operator.var{k} ;
whitespace = char(32*ones(1,3)) ;
line = line + 1 ;
prefix = [next_branch,'___',operator.name] ;
additional_code{line} = ['double',whitespace,prefix,'___',variable_name,' = 0.0 ;'] ;
end
struct_names = mttGetFieldNames(operator,'struct') ;
number_of_structs = length(struct_names) ;
for k = 1:number_of_structs
struct_name = struct_names{k} ;
variables = getfield(operator,'struct',struct_name) ;
for kv = 1:length(variables)
variable_name = variables{kv} ;
whitespace = char(32*ones(1,3)) ;
line = line + 1 ;
prefix = [next_branch,'___',operator.name] ;
additional_code{line} = [struct_name,whitespace,prefix,'___',variable_name,' ;'] ;
end
end
end
end
if isempty(code)
code = additional_code ;
else
line = length(code) ;
for j = 1:length(additional_code)
if ~ismember(additional_code{j},code)
line = line + 1 ;
code{line} = additional_code{j} ;
end
end
end
end
function write_definitions(def,model)
filename = [model.source,'_include_def.h'] ;
fid = fopen(filename,'w') ;
mttNotify(['...creating ',filename]) ;
mttWriteNewLine ;
fprintf(fid,['// Definitions for Ordinary Differential Equations\n']) ;
fprintf(fid,'\n') ;
fprintf(fid,['// file: ',filename,'\n']) ;
fprintf(fid,['// written by MTT on ',datestr(now),'\n']) ;
write_definitive_list(fid,'data_structures',def.structure) ;
write_definitive_list(fid,'bond_covariables',def.covar) ;
write_definitive_list(fid,'interface_covariables',def.var) ;
write_definitive_list(fid,'symbolic_parameters',def.sympar) ;
write_definitive_list(fid,'numerical_parameters',def.numpar) ;
write_definitive_list(fid,'input_variables',def.input) ;
write_definitive_list(fid,'state_variables',def.state) ;
write_definitive_list(fid,'operator_variables',def.opvar) ;
fclose(fid) ;
function write_definitive_list(fid,var_type,var_list)
if ~isempty(var_list)
fprintf(fid,'\n\n') ;
fprintf(fid,['// ',var_type]) ;
fprintf(fid,'\n') ;
tab = char(32*ones(1,3)) ;
for i = 1:length(var_list)
formatted_declaration = [tab,var_list{i},'\n'] ;
fprintf(fid,formatted_declaration) ;
end
end