function mttWriteSystemEquations(model) [eqn,ini] = format_equations(model) ; write_equations(eqn,ini,model) ; function [eqn,ini] = format_equations(model) mttNotify('...formating ordinary differential equations') ; mttWriteNewLine ; sse = model.equation ; namelist = model.namelist ; tab = char(32*ones(1,3)) ; eqn_counter = 0 ; ini_counter = 0 ; eqn = [] ; ini = [] ; for i = 1:length(sse) content = [] ; indent = 0 ; if isempty(sse(i).operator) Lvar = sse(i).var.LHS ; Rvar = sse(i).var.RHS ; if isnumeric(Lvar) | isnumeric(Rvar) if isnumeric(Lvar) name = sse(i).branch.LHS ; if mod(Lvar,2) bond_number = (Lvar+1)/2 ; else bond_number = Lvar/2 ; end else name = sse(i).branch.RHS ; if mod(Rvar,2) bond_number = (Rvar+1)/2 ; else bond_number = Rvar/2 ; end end [hierarchy,interface] = mttCutText(name,'___') ; level = length(findstr(hierarchy,'__')) ; [root,hierarchy] = mttCutText(hierarchy,'__') ; for j = 1:level [obj{j},hierarchy] = mttCutText(hierarchy,'__') ; end if level==0 local_object = model ; else local_object = getfield(model,'obj',obj{1}) ; for j = 2:level local_object = getfield(local_object,'obj',obj{j}) ; end end [specified_domain,specified_domain_item] = mttGetBondDomain(local_object,bond_number) ; else [name,covar] = mttCutText(namelist(Lvar{1}).var,'.') ; [hierarchy,interface] = mttCutText(name,'___') ; level = length(findstr(hierarchy,'__')) ; [root,hierarchy] = mttCutText(hierarchy,'__') ; for j = 1:level [obj{j},hierarchy] = mttCutText(hierarchy,'__') ; end parent_object = model ; object = getfield(model,'obj',obj{1}) ; for j = 2:level parent_object = object ; object = getfield(object,'obj',obj{j}) ; end index = strmatch(interface,{object.interface.name},'exact') ; interface_definition = object.interface(index) ; if isempty(interface_definition.in) bond_number = interface_definition.out ; else bond_number = interface_definition.in ; end [specified_domain,specified_domain_item] = mttGetBondDomain(parent_object,bond_number) ; end covariables = mttGetCovariables(model.env,specified_domain,specified_domain_item) ; dimension = length(covariables.effort) ; var = sse(i).var.LHS ; branch = sse(i).branch.LHS ; LHS.name = [] ; LHS.is_effort = [] ; switch class(var) case 'double', if mod(var,2) % LHS.name = [branch,'[',num2str((var+1)/2),']'] ; LHS.name = [branch,'__',num2str((var+1)/2)] ; LHS.is_effort = 1 ; else % LHS.name = [branch,'[',num2str(var/2),']'] ; LHS.name = [branch,'__',num2str(var/2)] ; LHS.is_effort = 0 ; end case 'cell', [name,covar] = mttCutText(namelist(var{1}).var,'.') ; LHS.name = name ; if strcmp(covar,'effort') LHS.is_effort = 1 ; else LHS.is_effort = 0 ; end end var = sse(i).var.RHS ; branch = sse(i).branch.RHS ; RHS.name = [] ; RHS.is_effort = [] ; switch class(var) case 'double', if mod(abs(var(1)),2) % RHS.name{1} = [branch,'[',num2str((abs(var(1))+1)/2),']'] ; RHS.name{1} = [branch,'__',num2str((abs(var(1))+1)/2)] ; RHS.is_effort(1) = 1 ; else % RHS.name{1} = [branch,'[',num2str(abs(var(1))/2),']'] ; RHS.name{1} = [branch,'__',num2str(abs(var(1))/2)] ; RHS.is_effort(1) = 0 ; end if var(1)<0 RHS.name{1} = ['-',RHS.name{1}] ; end for j = 2:length(var) if mod(abs(var(j)),2) % RHS.name{j} = [branch,'[',num2str((abs(var(j))+1)/2),']'] ; RHS.name{j} = [branch,'__',num2str((abs(var(j))+1)/2)] ; RHS.is_effort(j) = 1 ; else % RHS.name{j} = [branch,'[',num2str(abs(var(j))/2),']'] ; RHS.name{j} = [branch,'__',num2str(abs(var(j))/2)] ; RHS.is_effort(j) = 0 ; end if var(j)>0 RHS.name{j} = [' + ',RHS.name{j}] ; else RHS.name{j} = [' - ',RHS.name{j}] ; end end case 'cell', [name,covar] = mttCutText(namelist(var{1}).var,'.') ; RHS.name{1} = name ; if strcmp(covar,'effort') | strcmp(covar,'effort_state') RHS.is_effort = 1 ; else RHS.is_effort = 0 ; end end for k = 1:dimension if LHS.is_effort covar = covariables.effort{k} ; else covar = covariables.flow{k} ; end content = [LHS.name,'.',strrep(covar,'.','__')] ; indent = char(32*ones(1,length(content)+3)) ; for j = 1:length(RHS.name) if RHS.is_effort(j) covar = covariables.effort{k} ; else covar = covariables.flow{k} ; end if j==1 if strcmp(RHS.name{1},'0') content = [content,' = ',RHS.name{1}] ; else content = [content,' = ',RHS.name{1},'.',strrep(covar,'.','__')] ; end else content = [content,'\n',indent,RHS.name{j},'.',strrep(covar,'.','__')] ; end end content = [content,' ;'] ; if ~isempty(content) eqn_counter = eqn_counter + 1 ; eqn{eqn_counter} = content ; end end else op = [sse(i).operator] ; [cr,operator] = mttCutText(op,'___') ; if ~strcmp(eqn{eqn_counter},'') eqn_counter = eqn_counter + 1 ; eqn{eqn_counter} = [''] ; end eqn_counter = eqn_counter + 1 ; eqn{eqn_counter} = ['// ',op] ; [root,hierarchy] = mttCutText(cr,'__') ; level = length(findstr(cr,'__')) ; for j = 1:level [obj{j},hierarchy] = mttCutText(hierarchy,'__') ; end object = getfield(model,'obj',obj{1}) ; for j = 2:level object = getfield(object,'obj',obj{j}) ; end index = strmatch(operator,{object.cr.operator.name},'exact') ; cr_definition = object.cr ; operator_definition = cr_definition.operator(index) ; structlist = [] ; if ~isempty(operator_definition.struct) struct_names = mttGetFieldNames(operator_definition,'struct') ; number_of_structs = length(struct_names) ; for i = 1:number_of_structs struct_name = struct_names{i} ; variables = getfield(operator_definition,'struct',struct_name) ; if i==1 structlist = variables ; else structlist = [structlist,variables] ; end end end reassigned_state_list = [] ; counter = 0 ; port_names = mttGetFieldNames(cr_definition.interface,'port') ; for j = 1:length(port_names) port_name = port_names{j} ; port = getfield(cr_definition,'interface','port',port_name) ; if ~isempty(port.assign) assignment = port.assign ; if port.was_generic & ~isempty(port.domain) covar = mttGetCovariables(model.env,port.domain,port.domain_item) ; if port.is_effort_state covar = covariables.effort ; else covar = covariables.flow ; end for k = 1:length(assignment.state) counter = counter + 1 ; reassigned_state_list.name{counter} = assignment.state{k} ; reassigned_state_list.covar{counter} = covar ; end block_size = length(covar) ; for var = 1:block_size segment = [] ; for k = 1:length(assignment.state) segment{1} = [cr,'___',port_name,'.',strrep(covar{var},'.','__')] ; segment{2} = [' = '] ; segment{3} = [cr,'___',assignment.state{k},'___',strrep(covar{var},'.','__'),'.state ;'] ; ini_counter = ini_counter + 1 ; ini{ini_counter} = [segment{1},segment{2},segment{3}] ; end end else for k = 1:length(assignment.state) segment{1} = [cr,'___',port_name,'.',strrep(assignment.covar{k},'.','__')] ; segment{2} = [' = '] ; segment{3} = [cr,'___',assignment.state{k},'.state ;'] ; ini_counter = ini_counter + 1 ; ini{ini_counter} = [segment{1},segment{2},segment{3}] ; end end end end equations = operator_definition.equation ; for j = 1:length(equations) equation = equations(j) ; number_of_chunks = mttGetFieldLength(equation,'chunk') ; equation.domain = [] ; equation.domain_item = [] ; for k = 1:number_of_chunks chunk = equation.chunk{k} ; switch class(chunk) case 'cell' type = chunk{1} ; index = chunk{2} ; switch type case 'link' port_name = operator_definition.link(index).name ; port = getfield(cr_definition,'interface','port',port_name) ; if port.was_generic & ~isempty(port.domain) if isempty(equation.domain) equation.domain = port.domain ; equation.domain_item = port.domain_item ; else same_domain = equation.domain==port.domain ; same_domain_item = strcmp(equation.domain_item,port.domain_item) ; mttAssert(same_domain&same_domain_item,... ['Attempt to overwrite implicit variables with conflicting domains in "',... operator_definition.content{j},'"']) ; end end end end end covariables = mttGetCovariables(model.env,equation.domain,equation.domain_item) ; % if equation.is_effort % covar = covariables.effort ; % else % covar = covariables.flow ; % end block_size = length(covariables.effort) ; for line = 1:block_size segment = [] ; content = [] ; for k = 1:number_of_chunks chunk = equation.chunk{k} ; switch class(chunk) case 'cell' type = chunk{1} ; index = chunk{2} ; switch type case 'link' port_variable = [cr,'___',operator_definition.link(index).name] ; if strcmp(chunk{3},'generic___effort') segment{k} = [port_variable,'.',strrep(covariables.effort{line},'.','__')] ; elseif strcmp(chunk{3},'generic___flow') segment{k} = [port_variable,'.',strrep(covariables.flow{line},'.','__')] ; else segment{k} = [port_variable,'.',strrep(chunk{3},'.','__')] ; end % if length(chunk)>2 % segment{k} = [port_variable,'.',strrep(chunk{3},'.','__')] ; % else % segment{k} = [port_variable,'.',strrep(covar{line},'.','__')] ; % end case 'numpar' segment{k} = [cr,'___',cr_definition.numpar{index}] ; case 'sympar' parameter = [cr_definition.parameter{index}] ; if isnumeric(parameter) segment{k} = num2str(parameter) ; else segment{k} = [cr_definition.parameter{index}] ; end case 'var' segment{k} = [op,'___',operator_definition.var{index}] ; case 'struct' segment{k} = [op,'___',structlist{index}] ; case 'input' segment{k} = [cr,'___',cr_definition.input{index}] ; case 'state' state = cr_definition.state{index} ; if isempty(reassigned_state_list) state_reassignment = [] ; else state_reassignment = strmatch(state,reassigned_state_list.name,'exact') ; end if isempty(state_reassignment) segment{k} = [cr,'___',state,'.state'] ; else state_covar = reassigned_state_list.covar{line} ; segment{k} = [cr,'___',state,'___',state_covar{1},'.state'] ; end % segment{k} = [cr,'___',cr_definition.state{index},'.state'] ; case 'derivative' state = cr_definition.state{index} ; if isempty(reassigned_state_list) state_reassignment = [] ; else state_reassignment = strmatch(state,reassigned_state_list.name,'exact') ; end if isempty(state_reassignment) segment{k} = [cr,'___',state,'.derivative'] ; else state_covar = reassigned_state_list.covar{line} ; segment{k} = [cr,'___',state,'___',state_covar{1},'.derivative'] ; end % segment{k} = [cr,'___',cr_definition.state{index},'.derivative'] ; end otherwise chunk = strrep(chunk,':=','=') ; segment{k} = chunk ; end end content = [tab,segment{1}] ; for k = 2:length(segment) content = [content,segment{k}] ; end content = [content,' ;'] ; eqn_counter = eqn_counter + 1 ; eqn{eqn_counter} = content ; end end eqn_counter = eqn_counter + 1 ; eqn{eqn_counter} = ['// End of ',op] ; eqn_counter = eqn_counter + 1 ; eqn{eqn_counter} = [''] ; end end eqn = eqn' ; ini = ini' ; function write_equations(eqn,ini,model) filename = [model.source,'_include_ode.h'] ; fid = fopen(filename,'w') ; mttNotify(['...creating ',filename]) ; mttWriteNewLine ; fprintf(fid,['// Ordinary Differential Equations\n']) ; fprintf(fid,'\n') ; fprintf(fid,['// file: ',filename,'\n']) ; fprintf(fid,['// written by MTT on ',datestr(now),'\n']) ; fprintf(fid,'\n\n') ; tab = char(32*ones(1,3)) ; for i = 1:length(ini) formatted_equation = [tab,ini{i},'\n'] ; fprintf(fid,formatted_equation) ; end fprintf(fid,'\n') ; for i = 1:length(eqn) formatted_equation = [tab,eqn{i},'\n'] ; fprintf(fid,formatted_equation) ; end fclose(fid) ;