123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- function model = mttPropagateCausality(model,branch)
- is_root_model = (nargin==1) ;
-
- objects = mttGetFieldNames(model,'obj') ;
-
- for i = 1:length(objects)
- object_name = objects{i} ;
- object = getfield(model,'obj',object_name) ;
-
- if is_root_model
- branch = mttDetachText(model.source,'/') ;
- end
- here = [branch,':',object_name] ;
-
- if isfield(object,'obj')
-
- for i = 1:mttGetFieldLength(object,'interface')
- port_name = object.interface(i).name ;
-
- inbond = object.interface(i).in ;
- outbond = object.interface(i).out ;
- inmap = object.interface(i).map.in ;
- outmap = object.interface(i).map.out ;
-
- [inbond_effort,inbond_flow,inbond_unicausal] = mttGetBondCausality(model,inbond) ;
- [outbond_effort,outbond_flow,outbond_unicausal] = mttGetBondCausality(model,outbond) ;
- [inmap_effort,inmap_flow,inmap_unicausal] = mttGetBondCausality(object,inmap) ;
- [outmap_effort,outmap_flow,outmap_unicausal] = mttGetBondCausality(object,outmap) ;
-
- [model,inbond_ok] = mttUpdateBondCausality(model,inbond,inmap_effort,inmap_flow,inmap_unicausal) ;
- [model,outbond_ok] = mttUpdateBondCausality(model,outbond,outmap_effort,outmap_flow,outmap_unicausal) ;
- [object,inmap_ok] = mttUpdateBondCausality(object,inmap,inbond_effort,inbond_flow,inbond_unicausal) ;
- [object,outmap_ok] = mttUpdateBondCausality(object,outmap,outbond_effort,outbond_flow,outbond_unicausal) ;
-
- ok = inbond_ok & outbond_ok & inmap_ok & outmap_ok ;
- mttAssert(ok,['Causal conflict at port "',port_name,'" in ',here]) ;
- end
-
- if is_root_model
- branch = object_name ;
- else
- branch = [branch,'/',object_name] ;
- end
-
- object = mttPropagateCausality(object,branch) ;
- model = setfield(model,'obj',object_name,object) ;
-
- else
- number_of_interfaces = mttGetFieldLength(object,'interface') ;
-
- switch object.class
- case {'Se','Sf','De','Df'}
- for i = 1:number_of_interfaces
- port_name = object.interface(i).name ;
-
- inbond = object.interface(i).in ;
- outbond = object.interface(i).out ;
-
- mttAssert(xor(isempty(inbond),isempty(outbond)),...
- ['"',object.class,'" objects must have exactly one attached bond in ',here]) ;
-
- switch object.class
- case {'Se','De'},
- [model,ok] = mttUpdateBondCausality(model,outbond,[],1,1) ; % Constraint
- [model] = mttUpdateBondCausality(model,outbond,1,[],1) ; % Preference
- case {'Sf','Df'},
- [model,ok] = mttUpdateBondCausality(model,outbond,0,[],1) ; % Constraint
- [model] = mttUpdateBondCausality(model,outbond,[],0,1) ; % Preference
- end
-
- mttAssert(ok,['Causal constraint violation at port "',port_name,'" in ',here])
- end
-
- case '0',
- mttAssert(number_of_interfaces>1,...
- ['Less than two interfaces at 0-junction ',here]) ;
-
- imposed_effort = [] ;
- resultant_flow = [] ;
-
- for j = 1:number_of_interfaces
- inbond = object.interface(j).in ;
- outbond = object.interface(j).out ;
-
- if isempty(inbond)
- bond(j) = outbond ;
- orientation(j) = 0 ;
- else
- bond(j) = inbond ;
- orientation(j) = 1 ;
- end
-
- [effort,flow,unicausal] = mttGetBondCausality(model,bond(j)) ;
-
- if ~isempty(effort)
- if effort==orientation(j)
- mttAssert(isempty(imposed_effort),...
- ['Over-determined effort at 0-junction ',here]) ;
- imposed_effort = bond(j) ;
- end
- end
-
- if ~isempty(flow)
- if flow==orientation(j)
- mttAssert(isempty(resultant_flow),...
- ['Over-determined flow at 0-junction ',here]) ;
- resultant_flow = bond(j) ;
- end
- end
- end
-
- for j = 1:number_of_interfaces
- if ~isempty(imposed_effort)
- if bond(j)~=imposed_effort
- model = mttUpdateBondCausality(model,bond(j),~orientation(j),[],[]) ;
- end
- end
-
- if ~isempty(resultant_flow)
- if bond(j)~=resultant_flow
- model = mttUpdateBondCausality(model,bond(j),[],~orientation(j),[]) ;
- end
- end
- end
-
- case '1',
- mttAssert(number_of_interfaces>1,...
- ['Less than two interfaces at 1-junction ',here]) ;
-
- imposed_flow = [] ;
- resultant_effort = [] ;
-
- for j = 1:number_of_interfaces
- inbond = object.interface(j).in ;
- outbond = object.interface(j).out ;
-
- if isempty(inbond)
- bond(j) = outbond ;
- orientation(j) = 0 ;
- else
- bond(j) = inbond ;
- orientation(j) = 1 ;
- end
- [effort,flow,unicausal] = mttGetBondCausality(model,bond(j)) ;
-
- if ~isempty(effort)
- if effort~=orientation(j)
- mttAssert(isempty(resultant_effort),...
- ['Over-determined effort at 1-junction ',here]) ;
- resultant_effort = bond(j) ;
- end
- end
-
- if ~isempty(flow)
- if flow~=orientation(j)
- mttAssert(isempty(imposed_flow),...
- ['Over-determined flow at 1-junction ',here]) ;
- imposed_flow = bond(j) ;
- end
- end
- end
-
- for j = 1:number_of_interfaces
- if ~isempty(resultant_effort)
- if bond(j)~=resultant_effort
- model = mttUpdateBondCausality(model,bond(j),orientation(j),[],[]) ;
- end
- end
-
- if ~isempty(imposed_flow)
- if bond(j)~=imposed_flow
- model = mttUpdateBondCausality(model,bond(j),[],orientation(j),[]) ;
- end
- end
- end
- end
- end
- end
-
|