Parent Directory | Revision Log

Revision **1** -
(**show annotations**)
(**download**)
(**as text**)

*Fri Oct 29 20:54:12 2004 UTC*
(19 years, 10 months ago)
by *aw0a*

File MIME type: text/x-ascend

File size: 18810 byte(s)

File MIME type: text/x-ascend

File size: 18810 byte(s)

Setting up web subdirectory in repository

1 | PROVIDE "basemodel.a4l"; |

2 | |

3 | (* |

4 | * basemodel.a4l |

5 | * by Benjamin A. Allan |

6 | * Part of the ASCEND Library |

7 | * $Date: 1998/06/17 14:15:10 $ |

8 | * $Revision: 1.3 $ |

9 | * $Author: mthomas $ |

10 | * $Source: /afs/cs.cmu.edu/project/ascend/Repository/models/basemodel.a4l,v $ |

11 | * |

12 | * This file is part of the ASCEND Modeling Library. |

13 | * |

14 | * Copyright (C) 1998 Carnegie Mellon University |

15 | * |

16 | * The ASCEND Modeling Library is free software; you can redistribute |

17 | * it and/or modify it under the terms of the GNU General Public |

18 | * License as published by the Free Software Foundation; either |

19 | * version 2 of the License, or (at your option) any later version. |

20 | * |

21 | * The ASCEND Modeling Library is distributed in hope that it |

22 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied |

23 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |

24 | * See the GNU General Public License for more details. |

25 | * |

26 | * You should have received a copy of the GNU General Public License |

27 | * along with the program; if not, write to the Free Software |

28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check |

29 | * the file named COPYING. |

30 | *) |

31 | |

32 | (*============================================================================* |

33 | |

34 | B A S E M O D E L . A 4 L |

35 | ------------------------- |

36 | |

37 | AUTHOR: Benjamin A. Allan |

38 | |

39 | DATES: 03/98 - Original Code |

40 | |

41 | CONTENTS: Basic definitions cmu libraries and standard |

42 | methods. |

43 | This file is necessary for all |

44 | other CMU authored ASCEND models to work in ASCEND IV. |

45 | |

46 | *============================================================================*) |

47 | |

48 | MODEL catch_Word_model (* Bill Gates sacrificial goat *); |

49 | (* This MODEL does nothing. |

50 | * Normally catch_Word_model just gets parsed and ignored. |

51 | * |

52 | * If the user has tried to read a Microsoft Word binary file, Tcl file, |

53 | * or some other piece of junk as if it were an ASCEND MODEL |

54 | * source file, then catch_Word_model will die on an unknown |

55 | * syntax error. |

56 | * While catch_Word_model is dying the parser returns a good |

57 | * starting condition. |

58 | * |

59 | * Here is the message of recovery when this MODEL fails: |

60 | Asc-Error: Model definition "catch_Word_model" abandoned due to syntax errors. |

61 | Asc-Error: Rejected "catch_Word_model" at line basemodel.a4l:62. |

62 | *) |

63 | END catch_Word_model; |

64 | |

65 | (* First define the standard methods, or stand-ins which will tell |

66 | * us when a standard method has not been written. |

67 | *) |

68 | ADD METHODS IN DEFINITION MODEL; |

69 | |

70 | METHOD ClearAll; |

71 | |

72 | NOTES 'purpose' SELF { |

73 | This method finds anything that is a solver_var and changes |

74 | the .fixed flag on the var to FALSE. |

75 | |

76 | This method does not change .included flags on relations |

77 | or return boolean, integer, or symbol variables to a |

78 | default value. |

79 | } END NOTES; |

80 | |

81 | EXTERNAL asc_free_all_variables(SELF); |

82 | END ClearAll; |

83 | |

84 | (* |

85 | * Geniuses make more mistakes than anyone else -- because they |

86 | * try more things that anyone else. Part (perhaps a very large |

87 | * part) of what makes a genius different from the rest of |

88 | * humanity is that they quickly recognize their own mistakes |

89 | * and move on to try something else before anyone notices |

90 | * they screwed up! Solving a problem as far and as fast as you |

91 | * can, then going back to criticize every aspect of the solution |

92 | * with an eye to improving it is how you usually discover right answers. |

93 | * |

94 | * The authors of ASCEND (geniuses or not we'll |

95 | * leave to our users to decide) have found that it is |

96 | * best to do things such as writing mathematical MODELs and |

97 | * writing mathematical modeling software in ways which |

98 | * makes our mistakes (or your mistakes) very easy to detect. |

99 | * |

100 | * Below we describe a methodology (pun intended) which can |

101 | * help make anyone who can solve a quadratic equation |

102 | * a mathematical modeling expert. This methodology helps |

103 | * you to avoid screwing up and to find out about it when you have. |

104 | * |

105 | * The ASCEND system will not force you to write standard |

106 | * methods in your models. :-( METHODs of the sort we advocate |

107 | * here make your MODELs much easier to use and |

108 | * much more reliable. They pay off in the short run as well |

109 | * as the long run. These are _guidelines_, not _laws_: real |

110 | * genius requires knowing when to color outside the lines. :-) |

111 | * |

112 | * If you do not write the standard methods, your MODEL will |

113 | * inherit the ones given here. The "ClearAll" and "reset" |

114 | * methods here will work for you if you followed the guidelines. |

115 | * The other methods contain STOP statements which will warn you |

116 | * that you have skipped something important, should you accidentally |

117 | * end up calling one of them. |

118 | * |

119 | * The following methods should be redefined by each |

120 | * reusable library MODEL that REFINES this root MODEL. |

121 | * Models that do not supply proper versions of these |

122 | * (and possibly other) methods are very hard to reuse. |

123 | * |

124 | * The premise of this method design is that we can |

125 | * write the _self methods incrementally, building on the |

126 | * already tested methods of previous MODEL parts we are |

127 | * reusing. In this way we never have to write a single huge method |

128 | * that directly checks 100s of variables in a hierarchy. |

129 | * |

130 | * The _all methods are methods which simply "top off" the |

131 | * _self methods. With an _all method, you can treat |

132 | * just a part of a larger simulation already built |

133 | * as a self-contained simulation. |

134 | * |

135 | *) |

136 | |

137 | (* |

138 | * Usually discovery of the information you need to write the methods |

139 | * proceeds in the order that they appear below: |

140 | * check, default, specify, bound, scale. |

141 | *) |

142 | |

143 | METHOD check_self; |

144 | NOTES 'purpose' SELF { |

145 | This method should be written first, though it is run |

146 | last. Just like they taught you in elementary school, |

147 | always check your work. Start by defining criteria for a |

148 | successful solution that will not be included in the |

149 | equations solved and then computing those in this method. |

150 | As you develop your MODEL, you should expect to revise the |

151 | check method from time to time, if you are learning |

152 | anything about the MODEL. We frequently change our |

153 | definition of success. |

154 | |

155 | When a mathematical MODEL is solved, the assumptions that |

156 | went into writing (deriving) the equations should be |

157 | checked. Usually there are redundant equations available |

158 | (more than one way to state the physical MODEL |

159 | mathematically). These should be used to check the |

160 | particularly tricky bits of the MODEL. |

161 | |

162 | Check that the physical or intuitive (qualitative) |

163 | relationships among variables ch you expect to hold are |

164 | TRUE, especially if you have not written such relationships |

165 | in terms of inequalities in the MODEL equations. |

166 | |

167 | In some models, checking the variable values against |

168 | absolute physical limits (temperature > 0{K} and |

169 | temperature < Tcritical for example) may be all that is |

170 | necessary or possible. Do not check variable values against |

171 | their .lower_bound or .upper_bound, as any decent algebraic |

172 | solver or modeling system will do this for you. |

173 | |

174 | If a check fails, use a STOP or ERROR statement to notify |

175 | yourself (or you MODEL using customer) that the solution |

176 | may be bogus. |

177 | |

178 | Currently only STOP is implemented. |

179 | STOP raises an error signal and issues an error message; |

180 | STOP normally also stops further execution of the method |

181 | and returns control to a higher level, though there are |

182 | interactive tools to force method execution to continue. |

183 | STOP does not crash the ASCEND system. |

184 | |

185 | } END NOTES; |

186 | |

187 | STOP {Error! Standard method "check_self" called but not written in MODEL.}; |

188 | |

189 | END check_self; |

190 | |

191 | METHOD check_all; |

192 | |

193 | NOTES 'purpose' SELF { |

194 | When solving only a part of a simulation, it is necessary to check |

195 | the models and variables passed into the part as well as the |

196 | locally defined parts and variables. This method should check |

197 | all the received models and variables, then check the local |

198 | stuff. |

199 | } END NOTES; |

200 | |

201 | STOP {Error! Standard method "check_all" called but not written in MODEL.}; |

202 | RUN check_self; (* intentionally _second_ *) |

203 | |

204 | END check_all; |

205 | |

206 | METHOD defaults; |

207 | (* |

208 | * This is a kluge for interfaces that still think of |

209 | * 'defaults' as the standard method. |

210 | *) |

211 | RUN default_self; |

212 | STOP {GUI (or somebody) called non-standard method defaults. Call forwarded to default_self before stopping here.}; |

213 | END defaults; |

214 | |

215 | METHOD default_self; |

216 | NOTES 'purpose' SELF { |

217 | This method should set default values for any variables |

218 | declared locally (IS_A) to the MODEL. It should run |

219 | default_self on _all_ the models that are declared locally |

220 | (with IS_A) in the MODEL also. If the atoms you use to |

221 | define your variables have a suitable default already, then |

222 | you do not need to assign them a default in this method. |

223 | |

224 | This method should not run any methods on MODEL parts that |

225 | come via WILL_BE in the definition's parameter list. This |

226 | method also should not change the values of variables that |

227 | are passed in through the parameter list. |

228 | |

229 | Sometimes there will be nothing for this method to do. |

230 | Define it anyway, leaving it empty. |

231 | |

232 | When a top-level simulation is built by the compiler, this |

233 | method will be run at the end of compilation by the |

234 | compiler. |

235 | } END NOTES; |

236 | |

237 | STOP {Error! Standard method "default_self" called but not written in MODEL.}; |

238 | END default_self; |

239 | |

240 | METHOD default_all; |

241 | |

242 | NOTES 'purpose' SELF { |

243 | This method assumes that the arguments to the MODEL |

244 | instance have not been properly initialized, as is |

245 | frequently the case in one-off modeling efforts. This |

246 | method should run the default_self method on each of the |

247 | parts received through the parameter list and should give |

248 | appropriate default values to any variables received |

249 | through the parameter list. After these have been done, it |

250 | should then call default_self to take care of all locally |

251 | declared default needs. |

252 | } END NOTES; |

253 | |

254 | STOP {Error! Standard method "default_all" called but not written in MODEL.}; |

255 | RUN default_self; |

256 | END default_all; |

257 | |

258 | METHOD specify; |

259 | NOTES 'purpose' SELF { |

260 | * Assuming ClearAll has been run on the MODEL, this method |

261 | * should get the MODEL to a condition called 'square': |

262 | * the case where there are as many variables with .fixed == FALSE |

263 | * as there equations available to compute them. |

264 | * This is one of the hardest tasks ever invented by mathematicians |

265 | * if you go about it in the wrong way. We think we know the right way. |

266 | * |

267 | * Actually, 'square' is a bit trickier to achieve |

268 | * than simply counting equations and variables. |

269 | * Solver, such as QRSlv in ASCEND, may help greatly with the bookkeeping. |

270 | * |

271 | The general approach is to: |

272 | |

273 | (1) Run "specify" for all the parts (both passed in and locally defined) |

274 | that are not passed on into other parts. |

275 | |

276 | (2) Fix up (by tweaking .fixed flags on variables) any difficulties |

277 | that arise when parts compete to calculate the same variable. |

278 | |

279 | (3) Use the remaining new local variables to take care of any leftover |

280 | equations among the parts and any new equations written locally. |

281 | |

282 | At all steps 1-3 |

283 | Pay special attention to indexed variables used in |

284 | indexed equations; frequently you must fix or free N or |

285 | N-1 variables of a set sized N, if there are N matching equations. |

286 | In general, if you think you have specify correctly written, change |

287 | the sizes of all the sets in your MODEL by one and then by two |

288 | members. If your specify method still works, you are using sets |

289 | correctly. |

290 | |

291 | When writing models that combine parts which do not share |

292 | very well, or which both try to compute the same variable |

293 | in different ways, it may even be necessary to write a WHEN |

294 | statement to selectively TURN OFF the conflicting equations |

295 | or MODEL fragments. An object or equation USEd in a WHEN |

296 | statement is turned off by default and becomes a part of |

297 | the solved MODEL only when the conditions of some CASE |

298 | which refers to that object are matched. |

299 | |

300 | The setting of boolean, integer, and symbol variables which |

301 | are controlling conditions of WHEN and SWITCH statements |

302 | should be taken care of in the specify method. |

303 | |

304 | There is no 'one perfect "specify"' for all purposes. This |

305 | routine should merely define a reasonably useful base |

306 | configuration of the MODEL. |

307 | |

308 | Other specify_whatElseYouWant methods can (should) also be |

309 | written. |

310 | |

311 | The name of a method is a communication tool. Please use |

312 | meaningful names as long as necessary to tell what the |

313 | method does. Avoid cryptic abbreviations and hyper- |

314 | specialized jargon known only to you and your three friends |

315 | when you are naming methods; however, do not shy away from |

316 | technical terms common to the engineering domain in which |

317 | you are modeling. |

318 | |

319 | } END NOTES; |

320 | |

321 | STOP {Error! Standard method "specify" called but not written in MODEL.}; |

322 | |

323 | END specify; |

324 | |

325 | METHOD reset; |

326 | NOTES 'purpose' SELF { |

327 | This method gets the MODEL to some standard starting state, |

328 | though not necessarily the most useful starting state for a |

329 | particular application. In Chem. Eng. terms, this method |

330 | establishes a base case. |

331 | |

332 | There is no 'one perfect "reset"' for all purposes. This |

333 | routine should merely define a reasonably useful base |

334 | configuration of the MODEL. |

335 | |

336 | Other reset_whatElseYouWant methods can (should) also be |

337 | written. |

338 | |

339 | Normally you do not need to write this method: your models |

340 | will inherit this one unless you override it (redefine it) |

341 | in your MODEL. |

342 | } |

343 | END NOTES; |

344 | |

345 | RUN ClearAll; |

346 | RUN specify; |

347 | |

348 | END reset; |

349 | |

350 | METHOD bound_self; |

351 | NOTES 'purpose' SELF { |

352 | Much of the art of nonlinear physical modeling is in |

353 | bounding the solution. |

354 | |

355 | This method should update the bounds on _locally_ defined |

356 | (IS_A) variables and IS_A defined MODEL parts. Updating |

357 | bounds requires some care. For example, the bounds on |

358 | fractions frequently don't need updating. |

359 | |

360 | A common formula for updating bounds is to define a region |

361 | around the current value of the variable. A linear region |

362 | size formula, as an example, would be: |

363 | |

364 | v.upper_bound := v + boundwidth * v.nominal; |

365 | v.lower_bound := v - boundwidth * v.nominal; |

366 | |

367 | Care must be taken that such a formula does not move the |

368 | bounds (particularly lower bounds) out so far as to allow |

369 | non-physical solutions. Logarithmic bounding regions are |

370 | also simple to calculate. |

371 | |

372 | Here boundwidth IS_A bound_width; |

373 | boundwidth is a real variable (but not a solver_var) or a |

374 | value you can use to determine how much "wiggle-room" you |

375 | want to give a solver. Small powers of 4 and 10 are usually |

376 | good values of boundwidth. |

377 | |

378 | Too small a boundwidth can cut off the portion of number |

379 | space where the solution is found. Too large a bound width |

380 | can allow solvers to wander for great distances in |

381 | uninteresting regions of the number space. |

382 | |

383 | This method should not bound variables passed into the |

384 | MODEL definition or parts passed into the definition. |

385 | } END NOTES; |

386 | |

387 | STOP {Error! Standard method "bound_self" called but not written in MODEL.}; |

388 | END bound_self; |

389 | |

390 | METHOD bound_all; |

391 | NOTES 'purpose' SELF { |

392 | This method should be like bound_self except that it bounds the |

393 | passed in variables and calls bound_self on the passed in parts. |

394 | It should then call bound_self. |

395 | } END NOTES; |

396 | |

397 | STOP {Error! Standard method "bound_all" called but not written in MODEL.}; |

398 | RUN bound_self; |

399 | END bound_all; |

400 | |

401 | METHOD scale_self; |

402 | NOTES 'purpose' SELF { |

403 | Most nonlinear (and many linear) models cannot be solved without |

404 | proper scaling of the variables. |

405 | |

406 | This method should reset the .nominal value on every real |

407 | variable in need of scaling. It should then call the |

408 | scale_self method on all the locally defined (IS_A) parts |

409 | of the MODEL. 0.0 is the worst possible nominal value. A |

410 | proper nominal is one such that you expect at the solution |

411 | the quantity |

412 | |

413 | abs(variable/(variable.nominal)) |

414 | |

415 | to be around 1 (in the range of [0.1..10] or [0.01..100]). |

416 | |

417 | Variables (like fractions) bounded such that they cannot be |

418 | too far away from 1.0 in magnitude probably don't need scaling |

419 | most of the time if they are also bounded away from 0.0. |

420 | |

421 | Some solvers, but not all, will attempt to scale the |

422 | equations and variables by heuristic matrix-based methods. |

423 | This works, but inconsistently; user-defined scaling is |

424 | generaly much superior. |

425 | |

426 | ASCEND makes it easy to do. You scale the variables, which |

427 | can only be done well by knowing something about where the |

428 | solution is going to be found (by being an engineer, for |

429 | example.) Then ASCEND can calculate an appropriate |

430 | equation-scaling by efficient symbolic methods. |

431 | |

432 | This method should not change the scaling of models and |

433 | variables that are received through the parameter list of |

434 | the MODEL. |

435 | } END NOTES; |

436 | |

437 | STOP {Error! Standard method "scale_self" called but not written in MODEL.}; |

438 | END scale_self; |

439 | |

440 | METHOD scale_all; |

441 | NOTES 'purpose' SELF { |

442 | This method should be like scale_self above except that it also |

443 | should scale the variables and models received through the |

444 | parameter list. It should then call scale_self to take care of |

445 | the local variables and models. |

446 | } END NOTES; |

447 | |

448 | STOP {Error! Standard method "scale_all" called but not written in MODEL.}; |

449 | RUN scale_self; |

450 | END scale_all; |

451 | END METHODS; |

452 | |

453 | MODEL cmumodel(); |

454 | NOTES |

455 | 'purpose' SELF { |

456 | This MODEL does nothing except provide a root |

457 | for a collection of loosely related models. |

458 | If it happens to reveal a few bugs in the software, |

459 | and perhaps masks others, well, what me worry? |

460 | BAA, 8/97. |

461 | } |

462 | 'methods' SELF { |

463 | This MODEL also provides a hook to put in candidates for |

464 | becoming ascBuiltin global methods. Global methods may be |

465 | overridden by local definitions. |

466 | BAA, 3/98. |

467 | } |

468 | END NOTES; |

469 | |

470 | END cmumodel; |

471 | |

472 | MODEL testcmumodel(); |

473 | (* |

474 | * All CMU test models, of whatever sort should ultimately be |

475 | * rooted here or be a final refinement of a reusable MODEL. |

476 | *) |

477 | METHODS |

478 | METHOD values; |

479 | (* |

480 | * In a final application MODEL, you should record at least one set of |

481 | * input values (values of the fixed variables and guesses of key |

482 | * solved-for variables) that leads to a good solution. |

483 | * Do this so noone need reinvent that set the next time |

484 | * you use the MODEL or someone picks the MODEL up after you. |

485 | *) |

486 | STOP {Error! Standard method "values" called but not written in MODEL.}; |

487 | END values; |

488 | |

489 | METHOD specify; |

490 | STOP {Error! Standard method "specify" called but not written in test MODEL.}; |

491 | END specify; |

492 | (* |

493 | METHOD ClearAll; |

494 | EXTERNAL asc_free_all_variables(SELF); |

495 | END ClearAll; |

496 | |

497 | METHOD reset; |

498 | (* This method gets the MODEL to some standard starting state, |

499 | * though not necessarily the most useful starting state for |

500 | * a particular application. In Chem. Eng. terms, this method |

501 | * establishes a base case. |

502 | * There is no 'one perfect "reset"' for all purposes. This |

503 | * routine should merely define a reasonably useful base configuration |

504 | * of the MODEL. |

505 | * Other reset_whatElseYouWant methods can (should) also be |

506 | * written. |

507 | * |

508 | * Normally you do not need to write this method: your models |

509 | * will inherit this one unless you override it (redefine it) |

510 | * in your MODEL. |

511 | *) |

512 | RUN ClearAll; |

513 | RUN specify; |

514 | END reset; |

515 | *) |

516 | END testcmumodel; |

517 | |

518 | MODEL your_site_models(); |

519 | (* if you create a library to share with the net which is |

520 | * not just an end application of Carnegie Mellon models, |

521 | * please create an empy root MODEL such as this and use |

522 | * it as the origin of your library in the same way that |

523 | * we use cmumodel as the origin of our libraries. |

524 | * Thank you. |

525 | *) |

526 | END your_site_models; |

john.pye@anu.edu.au | ViewVC Help |

Powered by ViewVC 1.1.22 |