File mttroot/ntt/bin/trans/m/mttWriteSystemEquations.m artifact 6eecd251a9 part of check-in 0d3c58cce8


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) ;
    


MTT: Model Transformation Tools
GitHub | SourceHut | Sourceforge | Fossil RSS ]