mttCreateAlternativeEquations.m 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. function ese = mttCreateAlternativeEquations(model)
  2. ese = write_equations(model) ;
  3. ese = ese' ;
  4. filename = [model.source,'_ese.txt'] ;
  5. fid = fopen(filename,'w') ;
  6. fprintf(fid,['// Elementary System Equations\n']) ;
  7. fprintf(fid,'\n') ;
  8. fprintf(fid,['// file: ',filename,'\n']) ;
  9. fprintf(fid,['// written by MTT on ',datestr(now),'\n']) ;
  10. fprintf(fid,'\n\n') ;
  11. fprintf(fid,['ese ',mttDetachText(model.source,'/'),' {']) ;
  12. fprintf(fid,'\n') ;
  13. tab = char(32*ones(1,3)) ;
  14. for i = 1:length(ese)
  15. fprintf(fid,[tab,ese{i},'\n']) ;
  16. end
  17. fprintf(fid,'}') ;
  18. fclose(fid) ;
  19. function ese = write_equations(model,branch)
  20. is_root_model = (nargin==1) ;
  21. if is_root_model
  22. branch = mttDetachText(model.source,'/') ;
  23. end
  24. % ese{1} = ' ' ;
  25. % ese{2} = ['// ESE representation for module: ',branch] ;
  26. % ese{3} = ' ' ;
  27. %
  28. % line = 3 ;
  29. line = 0 ;
  30. indent = char(32*ones(1,6)) ;
  31. objects = mttGetFieldNames(model,'obj') ;
  32. for i = 1:length(objects)
  33. object_name = objects{i} ;
  34. object = getfield(model,'obj',object_name) ;
  35. here = [branch,':',object_name] ;
  36. switch object.class
  37. case 'SS',
  38. for j = 1:mttGetFieldLength(object,'interface')
  39. flow_equation = [] ;
  40. effort_equation = [] ;
  41. port_name = object.interface(j).name ;
  42. inbond = object.interface(j).in ;
  43. outbond = object.interface(j).out ;
  44. if ~isempty(inbond)
  45. bond = model.bond(inbond) ;
  46. extern = [branch,'__',object_name,'___flow'] ;
  47. intern = [branch,'___f[',num2str(inbond),']'] ;
  48. if bond.flow
  49. flow_equation = [intern,' = ',extern,' ;'] ;
  50. else
  51. flow_equation = [extern,' = ',intern,' ;'] ;
  52. end
  53. extern = [branch,'__',object_name,'___effort'] ;
  54. intern = [branch,'___e[',num2str(inbond),']'] ;
  55. if bond.effort
  56. effort_equation = [extern,' = ',intern,' ;'] ;
  57. else
  58. effort_equation = [intern,' = ',extern,' ;'] ;
  59. end
  60. line = line + 1 ;
  61. ese{line} = flow_equation ;
  62. line = line + 1 ;
  63. ese{line} = effort_equation ;
  64. end
  65. if ~isempty(outbond)
  66. bond = model.bond(outbond) ;
  67. extern = [branch,'__',object_name,'___flow'] ;
  68. intern = [branch,'___f[',num2str(outbond),']'] ;
  69. if bond.flow
  70. flow_equation = [extern,' = ',intern,' ;'] ;
  71. else
  72. flow_equation = [intern,' = ',extern,' ;'] ;
  73. end
  74. extern = [branch,'__',object_name,'___effort'] ;
  75. intern = [branch,'___e[',num2str(outbond),']'] ;
  76. if bond.effort
  77. effort_equation = [intern,' = ',extern,' ;'] ;
  78. else
  79. effort_equation = [extern,' = ',intern,' ;'] ;
  80. end
  81. line = line + 1 ;
  82. ese{line} = flow_equation ;
  83. line = line + 1 ;
  84. ese{line} = effort_equation ;
  85. end
  86. end
  87. case '0',
  88. imposed_effort = [] ;
  89. resultant_flow = [] ;
  90. for i = 1:mttGetFieldLength(object,'interface')
  91. inbond = object.interface(i).in ;
  92. outbond = object.interface(i).out ;
  93. if isempty(inbond)
  94. bond_number(i) = outbond ;
  95. orientation(i) = 0 ;
  96. else
  97. bond_number(i) = inbond ;
  98. orientation(i) = 1 ;
  99. end
  100. [effort(i),flow(i)] = mttGetBondCausality(model,bond_number(i)) ;
  101. if effort(i)==orientation(i)
  102. imposed_effort_bond = bond_number(i) ;
  103. imposed_effort = [branch,'___e[',num2str(imposed_effort_bond),']'] ;
  104. end
  105. if flow(i)==orientation(i)
  106. resultant_flow_bond = bond_number(i) ;
  107. resultant_flow = [branch,'___f[',num2str(resultant_flow_bond),']'] ;
  108. end
  109. end
  110. for i = 1:mttGetFieldLength(object,'interface')
  111. if bond_number(i)~=imposed_effort_bond
  112. line = line + 1 ;
  113. derived_effort = [branch,'___e[',num2str(bond_number(i)),']'] ;
  114. ese{line} = [derived_effort,' = ',imposed_effort,' ;'] ;
  115. end
  116. end
  117. waiting = 1 ;
  118. offset = char(32*ones(1,length(resultant_flow)+1)) ;
  119. for i = 1:mttGetFieldLength(object,'interface')
  120. next_flow = [] ;
  121. if bond_number(i)~=resultant_flow_bond
  122. next_flow = [branch,'___f[',num2str(bond_number(i)),']'] ;
  123. line = line + 1 ;
  124. if waiting
  125. if orientation(i)
  126. ese{line} = [resultant_flow,' = ',next_flow] ;
  127. else
  128. ese{line} = [resultant_flow,' = -',next_flow] ;
  129. end
  130. waiting = 0 ;
  131. else
  132. if orientation(i)
  133. ese{line} = [offset,'+ ',next_flow] ;
  134. else
  135. ese{line} = [offset,'- ',next_flow] ;
  136. end
  137. end
  138. end
  139. end
  140. ese{line} = [ese{line},' ;'] ;
  141. case '1',
  142. imposed_flow = [] ;
  143. resultant_effort = [] ;
  144. for i = 1:mttGetFieldLength(object,'interface')
  145. inbond = object.interface(i).in ;
  146. outbond = object.interface(i).out ;
  147. if isempty(inbond)
  148. bond_number(i) = outbond ;
  149. orientation(i) = 0 ;
  150. else
  151. bond_number(i) = inbond ;
  152. orientation(i) = 1 ;
  153. end
  154. [effort(i),flow(i)] = mttGetBondCausality(model,bond_number(i)) ;
  155. if flow(i)~=orientation(i)
  156. imposed_flow_bond = bond_number(i) ;
  157. imposed_flow = [branch,'___f[',num2str(imposed_flow_bond),']'] ;
  158. end
  159. if effort(i)~=orientation(i)
  160. resultant_effort_bond = bond_number(i) ;
  161. resultant_effort = [branch,'___e[',num2str(resultant_effort_bond),']'] ;
  162. end
  163. end
  164. for i = 1:mttGetFieldLength(object,'interface')
  165. if bond_number(i)~=imposed_flow_bond
  166. line = line + 1 ;
  167. derived_flow = [branch,'___f[',num2str(bond_number(i)),']'] ;
  168. ese{line} = [derived_flow,' = ',imposed_flow,' ;'] ;
  169. end
  170. end
  171. waiting = 1 ;
  172. offset = char(32*ones(1,length(resultant_effort)+1)) ;
  173. for i = 1:mttGetFieldLength(object,'interface')
  174. next_effort = [] ;
  175. if bond_number(i)~=resultant_effort_bond
  176. next_effort = [branch,'___e[',num2str(bond_number(i)),']'] ;
  177. line = line + 1 ;
  178. if waiting
  179. if orientation(i)
  180. ese{line} = [resultant_effort,' = ',next_effort] ;
  181. else
  182. ese{line} = [resultant_effort,' = -',next_effort] ;
  183. end
  184. waiting = 0 ;
  185. else
  186. if orientation(i)
  187. ese{line} = [offset,'+ ',next_effort] ;
  188. else
  189. ese{line} = [offset,'- ',next_effort] ;
  190. end
  191. end
  192. end
  193. end
  194. ese{line} = [ese{line},' ;'] ;
  195. otherwise,
  196. if ~isempty(object.cr)
  197. operators = object.cr.operator ;
  198. interface = object.cr.interface ;
  199. port_names = mttGetFieldNames(interface,'port') ;
  200. link_counter = 0 ;
  201. for i = 1:length(port_names)
  202. port_name = port_names{i} ;
  203. port = getfield(interface,'port',port_name) ;
  204. terminal = [branch,'__',object_name,'___',port_name] ;
  205. inbond = port.in ;
  206. outbond = port.out ;
  207. if ~isempty(inbond)
  208. bond = model.bond(inbond) ;
  209. intern = [branch,'___f[',num2str(inbond),']'] ;
  210. if bond.flow
  211. link_counter = link_counter + 1 ;
  212. link(link_counter) = create_link(0,0,1,port_name,port.is_flow_state) ;
  213. if port.is_flow_state
  214. flow_equation = [intern,' = ',terminal,'___flow_state ;'] ;
  215. else
  216. flow_equation = [intern,' = ',terminal,'___flow ;'] ;
  217. end
  218. else
  219. link_counter = link_counter + 1 ;
  220. link(link_counter) = create_link(1,0,1,port_name,port.is_flow_state) ;
  221. if port.is_flow_state
  222. flow_equation = [terminal,'___flow_state = ',intern,' ;'] ;
  223. else
  224. flow_equation = [terminal,'___flow = ',intern,' ;'] ;
  225. end
  226. end
  227. intern = [branch,'___e[',num2str(inbond),']'] ;
  228. if bond.effort
  229. link_counter = link_counter + 1 ;
  230. link(link_counter) = create_link(1,1,0,port_name,port.is_effort_state) ;
  231. if port.is_effort_state
  232. effort_equation = [terminal,'___effort_state = ',intern,' ;'] ;
  233. else
  234. effort_equation = [terminal,'___effort = ',intern,' ;'] ;
  235. end
  236. else
  237. link_counter = link_counter + 1 ;
  238. link(link_counter) = create_link(0,1,0,port_name,port.is_effort_state) ;
  239. if port.is_effort_state
  240. effort_equation = [intern,' = ',terminal,'___effort_state ;'] ;
  241. else
  242. effort_equation = [intern,' = ',terminal,'___effort ;'] ;
  243. end
  244. end
  245. line = line + 1 ;
  246. ese{line} = flow_equation ;
  247. line = line + 1 ;
  248. ese{line} = effort_equation ;
  249. end
  250. if ~isempty(outbond)
  251. bond = model.bond(outbond) ;
  252. intern = [branch,'___f[',num2str(outbond),']'] ;
  253. if bond.flow
  254. link_counter = link_counter + 1 ;
  255. link(link_counter) = create_link(1,0,1,port_name,port.is_flow_state) ;
  256. if port.is_flow_state
  257. flow_equation = [terminal,'___flow_state = ',intern,' ;'] ;
  258. else
  259. flow_equation = [terminal,'___flow = ',intern,' ;'] ;
  260. end
  261. else
  262. link_counter = link_counter + 1 ;
  263. link(link_counter) = create_link(0,0,1,port_name,port.is_flow_state) ;
  264. if port.is_flow_state
  265. flow_equation = [intern,' = ',terminal,'___flow_state ;'] ;
  266. else
  267. flow_equation = [intern,' = ',terminal,'___flow ;'] ;
  268. end
  269. end
  270. intern = [branch,'___e[',num2str(outbond),']'] ;
  271. if bond.effort
  272. link_counter = link_counter + 1 ;
  273. link(link_counter) = create_link(0,1,0,port_name,port.is_effort_state) ;
  274. if port.is_effort_state
  275. effort_equation = [intern,' = ',terminal,'___effort_state ;'] ;
  276. else
  277. effort_equation = [intern,' = ',terminal,'___effort ;'] ;
  278. end
  279. else
  280. link_counter = link_counter + 1 ;
  281. link(link_counter) = create_link(1,1,0,port_name,port.is_effort_state) ;
  282. if port.is_effort_state
  283. effort_equation = [terminal,'___effort_state = ',intern,' ;'] ;
  284. else
  285. effort_equation = [terminal,'___effort = ',intern,' ;'] ;
  286. end
  287. end
  288. line = line + 1 ;
  289. ese{line} = flow_equation ;
  290. line = line + 1 ;
  291. ese{line} = effort_equation ;
  292. end
  293. end
  294. number_of_operators = length(operators) ;
  295. op_counter = 1 ;
  296. matching = 1 ;
  297. while matching
  298. operator = operators(op_counter) ;
  299. links = length(link) ;
  300. op_links = length(operator.link) ;
  301. op_linked = zeros(op_links,1) ;
  302. for j = 1:op_links
  303. for k = 1:links
  304. if compare_links(link(k),operator.link(j))
  305. op_linked(j) = k ;
  306. break ;
  307. end
  308. end
  309. end
  310. input_counter = 0 ;
  311. output_counter = 0 ;
  312. input = [] ;
  313. output = [] ;
  314. if all(op_linked)
  315. for j = 1:op_links
  316. current_link = link(op_linked(j)) ;
  317. port_name = current_link.name ;
  318. if current_link.is_effort
  319. if current_link.is_state
  320. link_name = [branch,'__',object_name,'___',port_name,'___effort_state'] ;
  321. else
  322. link_name = [branch,'__',object_name,'___',port_name,'___effort'] ;
  323. end
  324. end
  325. if current_link.is_flow
  326. if current_link.is_state
  327. link_name = [branch,'__',object_name,'___',port_name,'___flow_state'] ;
  328. else
  329. link_name = [branch,'__',object_name,'___',port_name,'___flow'] ;
  330. end
  331. end
  332. if current_link.is_input
  333. input_counter = input_counter + 1 ;
  334. input{input_counter} = link_name ;
  335. else
  336. output_counter = output_counter + 1 ;
  337. output{output_counter} = link_name ;
  338. end
  339. end
  340. if input_counter>0
  341. input_list = ['[',input{1}] ;
  342. for j = 2:input_counter
  343. input_list = [input_list,',',input{j}] ;
  344. end
  345. input_list = [input_list,']'] ;
  346. end
  347. if output_counter>0
  348. output_list = ['[',output{1}] ;
  349. for j = 2:output_counter
  350. output_list = [output_list,',',output{j}] ;
  351. end
  352. output_list = [output_list,']'] ;
  353. end
  354. if input_counter>0
  355. line = line + 1 ;
  356. ese{line} = [output_list,' = '] ;
  357. end
  358. line = line + 1 ;
  359. ese{line} = [indent,branch,'__',object_name,'___',operator.name] ;
  360. if output_counter>0
  361. line = line + 1 ;
  362. ese{line} = [indent,indent,input_list,' ;'] ;
  363. end
  364. link(op_linked) = [] ;
  365. end
  366. op_counter = op_counter + 1 ;
  367. matching = ~isempty(link) & (op_counter<=number_of_operators) ;
  368. end
  369. mttAssert(isempty(link),...
  370. ['Unattached ports in "cr" implementation in ',here]) ;
  371. end
  372. end
  373. end
  374. for i = 1:length(objects)
  375. object_name = objects{i} ;
  376. object = getfield(model,'obj',object_name) ;
  377. here = [branch,':',object_name] ;
  378. if ~isempty(object.abg)
  379. for j = 1:mttGetFieldLength(object,'interface')
  380. inbond = object.interface(j).in ;
  381. outbond = object.interface(j).out ;
  382. inmap = object.interface(j).map.in ;
  383. outmap = object.interface(j).map.out ;
  384. line = line + 1 ;
  385. ese{line} = ' ' ;
  386. if ~isempty(inbond)
  387. bond = model.bond(inbond) ;
  388. extern = [branch,'__',object_name,'___f[',num2str(inmap),']'] ;
  389. intern = [branch,'___f[',num2str(inbond),']'] ;
  390. if bond.flow
  391. flow_equation = [intern,' = ',extern,' ;'] ;
  392. else
  393. flow_equation = [extern,' = ',intern,' ;'] ;
  394. end
  395. extern = [branch,'__',object_name,'___e[',num2str(inmap),']'] ;
  396. intern = [branch,'___e[',num2str(inbond),']'] ;
  397. if bond.effort
  398. effort_equation = [extern,' = ',intern,' ;'] ;
  399. else
  400. effort_equation = [intern,' = ',extern,' ;'] ;
  401. end
  402. line = line + 1 ;
  403. ese{line} = flow_equation ;
  404. line = line + 1 ;
  405. ese{line} = effort_equation ;
  406. end
  407. if ~isempty(outbond)
  408. bond = model.bond(outbond) ;
  409. extern = [branch,'__',object_name,'___f[',num2str(outmap),']'] ;
  410. intern = [branch,'___f[',num2str(outbond),']'] ;
  411. if bond.flow
  412. flow_equation = [extern,' = ',intern,' ;'] ;
  413. else
  414. flow_equation = [intern,' = ',extern,' ;'] ;
  415. end
  416. extern = [branch,'__',object_name,'___e[',num2str(outmap),']'] ;
  417. intern = [branch,'___e[',num2str(outbond),']'] ;
  418. if bond.effort
  419. effort_equation = [intern,' = ',extern,' ;'] ;
  420. else
  421. effort_equation = [extern,' = ',intern,' ;'] ;
  422. end
  423. line = line + 1 ;
  424. ese{line} = flow_equation ;
  425. line = line + 1 ;
  426. ese{line} = effort_equation ;
  427. end
  428. end
  429. next_branch = [branch,'__',object_name] ;
  430. object_ese = write_equations(object,next_branch) ;
  431. ese = [ese, object_ese] ;
  432. line = length(ese) ;
  433. end
  434. end
  435. function link = create_link(is_input,is_effort,is_flow,name,is_state)
  436. link.is_input = is_input ;
  437. link.is_effort = is_effort ;
  438. link.is_flow = is_flow ;
  439. link.name = name ;
  440. link.is_state = is_state ;
  441. function boolean = compare_links(actual_link,op_link)
  442. input_is_same = actual_link.is_input==op_link.is_input ;
  443. effort_is_same = actual_link.is_effort==op_link.is_effort ;
  444. flow_is_same = actual_link.is_flow==op_link.is_flow ;
  445. name_is_same = strcmp(actual_link.name,op_link.name) ;
  446. boolean = input_is_same & effort_is_same & flow_is_same & name_is_same ;