/[ascend]/trunk/models/basemodel.a4l
ViewVC logotype

Contents of /trunk/models/basemodel.a4l

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1290 - (show annotations) (download) (as text)
Mon Feb 26 04:54:45 2007 UTC (17 years, 5 months ago) by johnpye
File MIME type: text/x-ascend
File size: 19645 byte(s)
Added new 'default' functionality plus test case
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 on_load;
216 NOTES 'purpose' SELF {
217 This method adds improved ability to perform stuff when a model is first loaded.
218 By default, just 'default_self' will be run (this was the previous behaviour).
219 Any model that has an on_load method can override this behaviour however.
220 Note that this behaviour applies only in the C++/python interface at this stage.
221 } END NOTES;
222 RUN reset;
223 RUN default_all;
224 END on_load;
225
226 METHOD default;
227 NOTES 'purpose' SELF {
228 This method exists for the purpose ofOVERRIDING atom defaults in the local
229 MODEL. Hopefully this approach can replace the current practise of writing
230 'default_self' methods for most MODELs. It should be superiour, since using
231 'default' instead of 'default_self' will always result in ALL variables in a
232 model being reset to default values, rather than only those explicitly stated
233 by the modeller.
234 } END NOTES;
235 (* nothing here *)
236 END default;
237
238 METHOD default_self;
239 NOTES 'purpose' SELF {
240 This method should set default values for any variables
241 declared locally (IS_A) to the MODEL. It should run
242 default_self on _all_ the models that are declared locally
243 (with IS_A) in the MODEL also. If the atoms you use to
244 define your variables have a suitable default already, then
245 you do not need to assign them a default in this method.
246
247 This method should not run any methods on MODEL parts that
248 come via WILL_BE in the definition's parameter list. This
249 method also should not change the values of variables that
250 are passed in through the parameter list.
251
252 Sometimes there will be nothing for this method to do.
253 Define it anyway, leaving it empty.
254
255 When a top-level simulation is built by the compiler, this
256 method will be run at the end of compilation by the
257 compiler.
258 } END NOTES;
259 EXTERNAL asc_default_self(SELF);
260 RUN default;
261 END default_self;
262
263 METHOD default_all;
264
265 NOTES 'purpose' SELF {
266 This method assumes that the arguments to the MODEL
267 instance have not been properly initialized, as is
268 frequently the case in one-off modeling efforts. This
269 method should run the default_self method on each of the
270 parts received through the parameter list and should give
271 appropriate default values to any variables received
272 through the parameter list. After these have been done, it
273 should then call default_self to take care of all locally
274 declared default needs.
275 } END NOTES;
276 RUN default_self;
277 END default_all;
278
279 METHOD specify;
280 NOTES 'purpose' SELF {
281 * Assuming ClearAll has been run on the MODEL, this method
282 * should get the MODEL to a condition called 'square':
283 * the case where there are as many variables with .fixed == FALSE
284 * as there equations available to compute them.
285 * This is one of the hardest tasks ever invented by mathematicians
286 * if you go about it in the wrong way. We think we know the right way.
287 *
288 * Actually, 'square' is a bit trickier to achieve
289 * than simply counting equations and variables.
290 * Solver, such as QRSlv in ASCEND, may help greatly with the bookkeeping.
291 *
292 The general approach is to:
293
294 (1) Run "specify" for all the parts (both passed in and locally defined)
295 that are not passed on into other parts.
296
297 (2) Fix up (by tweaking .fixed flags on variables) any difficulties
298 that arise when parts compete to calculate the same variable.
299
300 (3) Use the remaining new local variables to take care of any leftover
301 equations among the parts and any new equations written locally.
302
303 At all steps 1-3
304 Pay special attention to indexed variables used in
305 indexed equations; frequently you must fix or free N or
306 N-1 variables of a set sized N, if there are N matching equations.
307 In general, if you think you have specify correctly written, change
308 the sizes of all the sets in your MODEL by one and then by two
309 members. If your specify method still works, you are using sets
310 correctly.
311
312 When writing models that combine parts which do not share
313 very well, or which both try to compute the same variable
314 in different ways, it may even be necessary to write a WHEN
315 statement to selectively TURN OFF the conflicting equations
316 or MODEL fragments. An object or equation USEd in a WHEN
317 statement is turned off by default and becomes a part of
318 the solved MODEL only when the conditions of some CASE
319 which refers to that object are matched.
320
321 The setting of boolean, integer, and symbol variables which
322 are controlling conditions of WHEN and SWITCH statements
323 should be taken care of in the specify method.
324
325 There is no 'one perfect "specify"' for all purposes. This
326 routine should merely define a reasonably useful base
327 configuration of the MODEL.
328
329 Other specify_whatElseYouWant methods can (should) also be
330 written.
331
332 The name of a method is a communication tool. Please use
333 meaningful names as long as necessary to tell what the
334 method does. Avoid cryptic abbreviations and hyper-
335 specialized jargon known only to you and your three friends
336 when you are naming methods; however, do not shy away from
337 technical terms common to the engineering domain in which
338 you are modeling.
339
340 } END NOTES;
341
342 (* STOP {Error! Standard method "specify" called but not written in MODEL.}; *)
343
344 END specify;
345
346 METHOD reset;
347 NOTES 'purpose' SELF {
348 This method gets the MODEL to some standard starting state,
349 though not necessarily the most useful starting state for a
350 particular application. In Chem. Eng. terms, this method
351 establishes a base case.
352
353 There is no 'one perfect "reset"' for all purposes. This
354 routine should merely define a reasonably useful base
355 configuration of the MODEL.
356
357 Other reset_whatElseYouWant methods can (should) also be
358 written.
359
360 Normally you do not need to write this method: your models
361 will inherit this one unless you override it (redefine it)
362 in your MODEL.
363 }
364 END NOTES;
365
366 RUN ClearAll;
367 RUN specify;
368
369 END reset;
370
371 METHOD bound_self;
372 NOTES 'purpose' SELF {
373 Much of the art of nonlinear physical modeling is in
374 bounding the solution.
375
376 This method should update the bounds on _locally_ defined
377 (IS_A) variables and IS_A defined MODEL parts. Updating
378 bounds requires some care. For example, the bounds on
379 fractions frequently don't need updating.
380
381 A common formula for updating bounds is to define a region
382 around the current value of the variable. A linear region
383 size formula, as an example, would be:
384
385 v.upper_bound := v + boundwidth * v.nominal;
386 v.lower_bound := v - boundwidth * v.nominal;
387
388 Care must be taken that such a formula does not move the
389 bounds (particularly lower bounds) out so far as to allow
390 non-physical solutions. Logarithmic bounding regions are
391 also simple to calculate.
392
393 Here boundwidth IS_A bound_width;
394 boundwidth is a real variable (but not a solver_var) or a
395 value you can use to determine how much "wiggle-room" you
396 want to give a solver. Small powers of 4 and 10 are usually
397 good values of boundwidth.
398
399 Too small a boundwidth can cut off the portion of number
400 space where the solution is found. Too large a bound width
401 can allow solvers to wander for great distances in
402 uninteresting regions of the number space.
403
404 This method should not bound variables passed into the
405 MODEL definition or parts passed into the definition.
406 } END NOTES;
407
408 (* STOP {Error! Standard method "bound_self" called but not written in MODEL.}; *)
409 END bound_self;
410
411 METHOD bound_all;
412 NOTES 'purpose' SELF {
413 This method should be like bound_self except that it bounds the
414 passed in variables and calls bound_self on the passed in parts.
415 It should then call bound_self.
416 } END NOTES;
417
418 (* STOP {Error! Standard method "bound_all" called but not written in MODEL.}; *)
419 RUN bound_self;
420 END bound_all;
421
422 METHOD scale_self;
423 NOTES 'purpose' SELF {
424 Most nonlinear (and many linear) models cannot be solved without
425 proper scaling of the variables.
426
427 This method should reset the .nominal value on every real
428 variable in need of scaling. It should then call the
429 scale_self method on all the locally defined (IS_A) parts
430 of the MODEL. 0.0 is the worst possible nominal value. A
431 proper nominal is one such that you expect at the solution
432 the quantity
433
434 abs(variable/(variable.nominal))
435
436 to be around 1 (in the range of [0.1..10] or [0.01..100]).
437
438 Variables (like fractions) bounded such that they cannot be
439 too far away from 1.0 in magnitude probably don't need scaling
440 most of the time if they are also bounded away from 0.0.
441
442 Some solvers, but not all, will attempt to scale the
443 equations and variables by heuristic matrix-based methods.
444 This works, but inconsistently; user-defined scaling is
445 generaly much superior.
446
447 ASCEND makes it easy to do. You scale the variables, which
448 can only be done well by knowing something about where the
449 solution is going to be found (by being an engineer, for
450 example.) Then ASCEND can calculate an appropriate
451 equation-scaling by efficient symbolic methods.
452
453 This method should not change the scaling of models and
454 variables that are received through the parameter list of
455 the MODEL.
456 } END NOTES;
457
458 (* STOP {Error! Standard method "scale_self" called but not written in MODEL.}; *)
459 END scale_self;
460
461 METHOD scale_all;
462 NOTES 'purpose' SELF {
463 This method should be like scale_self above except that it also
464 should scale the variables and models received through the
465 parameter list. It should then call scale_self to take care of
466 the local variables and models.
467 } END NOTES;
468
469 (* STOP {Error! Standard method "scale_all" called but not written in MODEL.}; *)
470 RUN scale_self;
471 END scale_all;
472 END METHODS;
473
474 MODEL cmumodel();
475 NOTES
476 'purpose' SELF {
477 This MODEL does nothing except provide a root
478 for a collection of loosely related models.
479 If it happens to reveal a few bugs in the software,
480 and perhaps masks others, well, what me worry?
481 BAA, 8/97.
482 }
483 'methods' SELF {
484 This MODEL also provides a hook to put in candidates for
485 becoming ascBuiltin global methods. Global methods may be
486 overridden by local definitions.
487 BAA, 3/98.
488 }
489 END NOTES;
490
491 END cmumodel;
492
493 MODEL testcmumodel();
494 (*
495 * All CMU test models, of whatever sort should ultimately be
496 * rooted here or be a final refinement of a reusable MODEL.
497 *)
498 METHODS
499 METHOD values;
500 (*
501 * In a final application MODEL, you should record at least one set of
502 * input values (values of the fixed variables and guesses of key
503 * solved-for variables) that leads to a good solution.
504 * Do this so noone need reinvent that set the next time
505 * you use the MODEL or someone picks the MODEL up after you.
506 *)
507 (* STOP {Error! Standard method "values" called but not written in MODEL.}; *)
508 END values;
509
510 METHOD specify;
511 (* STOP {Error! Standard method "specify" called but not written in test MODEL.}; *)
512 END specify;
513 (*
514 METHOD ClearAll;
515 EXTERNAL asc_free_all_variables(SELF);
516 END ClearAll;
517
518 METHOD reset;
519 (* This method gets the MODEL to some standard starting state,
520 * though not necessarily the most useful starting state for
521 * a particular application. In Chem. Eng. terms, this method
522 * establishes a base case.
523 * There is no 'one perfect "reset"' for all purposes. This
524 * routine should merely define a reasonably useful base configuration
525 * of the MODEL.
526 * Other reset_whatElseYouWant methods can (should) also be
527 * written.
528 *
529 * Normally you do not need to write this method: your models
530 * will inherit this one unless you override it (redefine it)
531 * in your MODEL.
532 *)
533 RUN ClearAll;
534 RUN specify;
535 END reset;
536 *)
537 END testcmumodel;
538
539 MODEL your_site_models();
540 (* if you create a library to share with the net which is
541 * not just an end application of Carnegie Mellon models,
542 * please create an empy root MODEL such as this and use
543 * it as the origin of your library in the same way that
544 * we use cmumodel as the origin of our libraries.
545 * Thank you.
546 *)
547 END your_site_models;

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22