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

Annotation of /trunk/models/basemodel.a4l

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2651 - (hide annotations) (download) (as text)
Thu Dec 13 07:29:48 2012 UTC (11 years, 6 months ago) by jpye
File MIME type: text/x-ascend
File size: 19334 byte(s)
Fixing GPL header, removing postal address (rpmlint incorrect-fsf-address)
1 johnpye 1293 (* ASCEND modelling environment
2     Copyright (C) 1998, 2007 Carnegie Mellon University
3    
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2, or (at your option)
7     any later version.
8    
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12     GNU General Public License for more details.
13    
14     You should have received a copy of the GNU General Public License
15 jpye 2651 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 johnpye 1293 *)
17 aw0a 1 PROVIDE "basemodel.a4l";
18     (*
19 johnpye 1293 basemodel.a4l, by Benjamin A. Allan 03/98 - Original Code
20 aw0a 1
21 johnpye 1293 Basic definitions cmu libraries and standard methods.
22     This file is necessary for all other CMU authored ASCEND models to work
23     in ASCEND IV.
24     *)
25 aw0a 1
26     MODEL catch_Word_model (* Bill Gates sacrificial goat *);
27     (* This MODEL does nothing.
28     * Normally catch_Word_model just gets parsed and ignored.
29     *
30     * If the user has tried to read a Microsoft Word binary file, Tcl file,
31     * or some other piece of junk as if it were an ASCEND MODEL
32     * source file, then catch_Word_model will die on an unknown
33     * syntax error.
34     * While catch_Word_model is dying the parser returns a good
35     * starting condition.
36     *
37     * Here is the message of recovery when this MODEL fails:
38     Asc-Error: Model definition "catch_Word_model" abandoned due to syntax errors.
39     Asc-Error: Rejected "catch_Word_model" at line basemodel.a4l:62.
40 johnpye 1293
41     @TODO document how this works
42 aw0a 1 *)
43     END catch_Word_model;
44    
45     (* First define the standard methods, or stand-ins which will tell
46     * us when a standard method has not been written.
47     *)
48     ADD METHODS IN DEFINITION MODEL;
49    
50     METHOD ClearAll;
51    
52     NOTES 'purpose' SELF {
53     This method finds anything that is a solver_var and changes
54     the .fixed flag on the var to FALSE.
55    
56     This method does not change .included flags on relations
57     or return boolean, integer, or symbol variables to a
58     default value.
59     } END NOTES;
60    
61     EXTERNAL asc_free_all_variables(SELF);
62     END ClearAll;
63    
64     (*
65     * Geniuses make more mistakes than anyone else -- because they
66     * try more things that anyone else. Part (perhaps a very large
67     * part) of what makes a genius different from the rest of
68     * humanity is that they quickly recognize their own mistakes
69     * and move on to try something else before anyone notices
70     * they screwed up! Solving a problem as far and as fast as you
71     * can, then going back to criticize every aspect of the solution
72     * with an eye to improving it is how you usually discover right answers.
73     *
74     * The authors of ASCEND (geniuses or not we'll
75     * leave to our users to decide) have found that it is
76     * best to do things such as writing mathematical MODELs and
77     * writing mathematical modeling software in ways which
78     * makes our mistakes (or your mistakes) very easy to detect.
79     *
80     * Below we describe a methodology (pun intended) which can
81     * help make anyone who can solve a quadratic equation
82     * a mathematical modeling expert. This methodology helps
83     * you to avoid screwing up and to find out about it when you have.
84     *
85     * The ASCEND system will not force you to write standard
86     * methods in your models. :-( METHODs of the sort we advocate
87     * here make your MODELs much easier to use and
88     * much more reliable. They pay off in the short run as well
89     * as the long run. These are _guidelines_, not _laws_: real
90     * genius requires knowing when to color outside the lines. :-)
91     *
92     * If you do not write the standard methods, your MODEL will
93     * inherit the ones given here. The "ClearAll" and "reset"
94     * methods here will work for you if you followed the guidelines.
95     * The other methods contain STOP statements which will warn you
96     * that you have skipped something important, should you accidentally
97     * end up calling one of them.
98     *
99     * The following methods should be redefined by each
100     * reusable library MODEL that REFINES this root MODEL.
101     * Models that do not supply proper versions of these
102     * (and possibly other) methods are very hard to reuse.
103     *
104     * The premise of this method design is that we can
105     * write the _self methods incrementally, building on the
106     * already tested methods of previous MODEL parts we are
107     * reusing. In this way we never have to write a single huge method
108     * that directly checks 100s of variables in a hierarchy.
109     *
110     * The _all methods are methods which simply "top off" the
111     * _self methods. With an _all method, you can treat
112     * just a part of a larger simulation already built
113     * as a self-contained simulation.
114     *
115     *)
116    
117     (*
118     * Usually discovery of the information you need to write the methods
119     * proceeds in the order that they appear below:
120     * check, default, specify, bound, scale.
121     *)
122    
123     METHOD check_self;
124     NOTES 'purpose' SELF {
125     This method should be written first, though it is run
126     last. Just like they taught you in elementary school,
127     always check your work. Start by defining criteria for a
128     successful solution that will not be included in the
129     equations solved and then computing those in this method.
130     As you develop your MODEL, you should expect to revise the
131     check method from time to time, if you are learning
132     anything about the MODEL. We frequently change our
133     definition of success.
134    
135     When a mathematical MODEL is solved, the assumptions that
136     went into writing (deriving) the equations should be
137     checked. Usually there are redundant equations available
138     (more than one way to state the physical MODEL
139     mathematically). These should be used to check the
140     particularly tricky bits of the MODEL.
141    
142     Check that the physical or intuitive (qualitative)
143     relationships among variables ch you expect to hold are
144     TRUE, especially if you have not written such relationships
145     in terms of inequalities in the MODEL equations.
146    
147     In some models, checking the variable values against
148     absolute physical limits (temperature > 0{K} and
149     temperature < Tcritical for example) may be all that is
150     necessary or possible. Do not check variable values against
151     their .lower_bound or .upper_bound, as any decent algebraic
152     solver or modeling system will do this for you.
153    
154     If a check fails, use a STOP or ERROR statement to notify
155     yourself (or you MODEL using customer) that the solution
156     may be bogus.
157    
158     Currently only STOP is implemented.
159     STOP raises an error signal and issues an error message;
160     STOP normally also stops further execution of the method
161     and returns control to a higher level, though there are
162     interactive tools to force method execution to continue.
163     STOP does not crash the ASCEND system.
164    
165     } END NOTES;
166    
167 johnpye 1290 (* STOP {Error! Standard method "check_self" called but not written in MODEL.}; *)
168 aw0a 1
169     END check_self;
170    
171     METHOD check_all;
172    
173     NOTES 'purpose' SELF {
174     When solving only a part of a simulation, it is necessary to check
175     the models and variables passed into the part as well as the
176     locally defined parts and variables. This method should check
177     all the received models and variables, then check the local
178     stuff.
179     } END NOTES;
180    
181 johnpye 1290 (* STOP {Error! Standard method "check_all" called but not written in MODEL.}; *)
182 aw0a 1 RUN check_self; (* intentionally _second_ *)
183    
184     END check_all;
185    
186     METHOD defaults;
187     (*
188     * This is a kluge for interfaces that still think of
189     * 'defaults' as the standard method.
190     *)
191     RUN default_self;
192     STOP {GUI (or somebody) called non-standard method defaults. Call forwarded to default_self before stopping here.};
193     END defaults;
194    
195 johnpye 669 METHOD on_load;
196     NOTES 'purpose' SELF {
197     This method adds improved ability to perform stuff when a model is first loaded.
198     By default, just 'default_self' will be run (this was the previous behaviour).
199     Any model that has an on_load method can override this behaviour however.
200     Note that this behaviour applies only in the C++/python interface at this stage.
201     } END NOTES;
202 johnpye 1290 RUN default_all;
203 johnpye 669 END on_load;
204    
205 johnpye 1290 METHOD default;
206     NOTES 'purpose' SELF {
207     This method exists for the purpose ofOVERRIDING atom defaults in the local
208     MODEL. Hopefully this approach can replace the current practise of writing
209 johnpye 1293 'default_self' methods for most MODELs. It should be superior, since using
210 johnpye 1290 'default' instead of 'default_self' will always result in ALL variables in a
211     model being reset to default values, rather than only those explicitly stated
212     by the modeller.
213     } END NOTES;
214 jpye 2244 (*STOP {it works!};*)
215 johnpye 1290 (* nothing here *)
216     END default;
217    
218 aw0a 1 METHOD default_self;
219     NOTES 'purpose' SELF {
220     This method should set default values for any variables
221     declared locally (IS_A) to the MODEL. It should run
222     default_self on _all_ the models that are declared locally
223     (with IS_A) in the MODEL also. If the atoms you use to
224     define your variables have a suitable default already, then
225     you do not need to assign them a default in this method.
226    
227     This method should not run any methods on MODEL parts that
228     come via WILL_BE in the definition's parameter list. This
229     method also should not change the values of variables that
230     are passed in through the parameter list.
231    
232     Sometimes there will be nothing for this method to do.
233     Define it anyway, leaving it empty.
234    
235     When a top-level simulation is built by the compiler, this
236     method will be run at the end of compilation by the
237 johnpye 1293 compiler. See notes in on_load method for new behaviour in
238     the PyGTK GUI.
239 aw0a 1 } END NOTES;
240 jpye 1372 EXTERNAL defaultself_visit_childatoms(SELF);
241     EXTERNAL defaultself_visit_submodels(SELF); (* overwrite ATOM defaults explicit nested code if needed *)
242 jpye 2244 RUN default; (* local overrides *)
243 aw0a 1 END default_self;
244    
245     METHOD default_all;
246     NOTES 'purpose' SELF {
247     This method assumes that the arguments to the MODEL
248     instance have not been properly initialized, as is
249     frequently the case in one-off modeling efforts. This
250     method should run the default_self method on each of the
251     parts received through the parameter list and should give
252     appropriate default values to any variables received
253     through the parameter list. After these have been done, it
254     should then call default_self to take care of all locally
255     declared default needs.
256     } END NOTES;
257 jpye 1372 (* INITIALISATION OF PARAMETERS IS NOT IMPLEMENTED YET *)
258 aw0a 1 RUN default_self;
259     END default_all;
260    
261     METHOD specify;
262     NOTES 'purpose' SELF {
263     * Assuming ClearAll has been run on the MODEL, this method
264     * should get the MODEL to a condition called 'square':
265     * the case where there are as many variables with .fixed == FALSE
266     * as there equations available to compute them.
267     * This is one of the hardest tasks ever invented by mathematicians
268     * if you go about it in the wrong way. We think we know the right way.
269     *
270     * Actually, 'square' is a bit trickier to achieve
271     * than simply counting equations and variables.
272     * Solver, such as QRSlv in ASCEND, may help greatly with the bookkeeping.
273     *
274     The general approach is to:
275    
276     (1) Run "specify" for all the parts (both passed in and locally defined)
277     that are not passed on into other parts.
278    
279     (2) Fix up (by tweaking .fixed flags on variables) any difficulties
280     that arise when parts compete to calculate the same variable.
281    
282     (3) Use the remaining new local variables to take care of any leftover
283     equations among the parts and any new equations written locally.
284    
285     At all steps 1-3
286     Pay special attention to indexed variables used in
287     indexed equations; frequently you must fix or free N or
288     N-1 variables of a set sized N, if there are N matching equations.
289     In general, if you think you have specify correctly written, change
290     the sizes of all the sets in your MODEL by one and then by two
291     members. If your specify method still works, you are using sets
292     correctly.
293    
294     When writing models that combine parts which do not share
295     very well, or which both try to compute the same variable
296     in different ways, it may even be necessary to write a WHEN
297     statement to selectively TURN OFF the conflicting equations
298     or MODEL fragments. An object or equation USEd in a WHEN
299     statement is turned off by default and becomes a part of
300     the solved MODEL only when the conditions of some CASE
301     which refers to that object are matched.
302    
303     The setting of boolean, integer, and symbol variables which
304     are controlling conditions of WHEN and SWITCH statements
305     should be taken care of in the specify method.
306    
307     There is no 'one perfect "specify"' for all purposes. This
308     routine should merely define a reasonably useful base
309     configuration of the MODEL.
310    
311     Other specify_whatElseYouWant methods can (should) also be
312     written.
313    
314     The name of a method is a communication tool. Please use
315     meaningful names as long as necessary to tell what the
316     method does. Avoid cryptic abbreviations and hyper-
317     specialized jargon known only to you and your three friends
318     when you are naming methods; however, do not shy away from
319     technical terms common to the engineering domain in which
320     you are modeling.
321    
322     } END NOTES;
323    
324 johnpye 1290 (* STOP {Error! Standard method "specify" called but not written in MODEL.}; *)
325 aw0a 1
326     END specify;
327    
328     METHOD reset;
329     NOTES 'purpose' SELF {
330     This method gets the MODEL to some standard starting state,
331     though not necessarily the most useful starting state for a
332     particular application. In Chem. Eng. terms, this method
333     establishes a base case.
334    
335     There is no 'one perfect "reset"' for all purposes. This
336     routine should merely define a reasonably useful base
337     configuration of the MODEL.
338    
339     Other reset_whatElseYouWant methods can (should) also be
340     written.
341    
342     Normally you do not need to write this method: your models
343     will inherit this one unless you override it (redefine it)
344     in your MODEL.
345     }
346     END NOTES;
347    
348     RUN ClearAll;
349     RUN specify;
350    
351     END reset;
352    
353 jpye 1373 METHOD values;
354     END values;
355    
356 aw0a 1 METHOD bound_self;
357     NOTES 'purpose' SELF {
358     Much of the art of nonlinear physical modeling is in
359     bounding the solution.
360    
361     This method should update the bounds on _locally_ defined
362     (IS_A) variables and IS_A defined MODEL parts. Updating
363     bounds requires some care. For example, the bounds on
364     fractions frequently don't need updating.
365    
366     A common formula for updating bounds is to define a region
367     around the current value of the variable. A linear region
368     size formula, as an example, would be:
369    
370     v.upper_bound := v + boundwidth * v.nominal;
371     v.lower_bound := v - boundwidth * v.nominal;
372    
373     Care must be taken that such a formula does not move the
374     bounds (particularly lower bounds) out so far as to allow
375     non-physical solutions. Logarithmic bounding regions are
376     also simple to calculate.
377    
378     Here boundwidth IS_A bound_width;
379     boundwidth is a real variable (but not a solver_var) or a
380     value you can use to determine how much "wiggle-room" you
381     want to give a solver. Small powers of 4 and 10 are usually
382     good values of boundwidth.
383    
384     Too small a boundwidth can cut off the portion of number
385     space where the solution is found. Too large a bound width
386     can allow solvers to wander for great distances in
387     uninteresting regions of the number space.
388    
389     This method should not bound variables passed into the
390     MODEL definition or parts passed into the definition.
391     } END NOTES;
392    
393 johnpye 1290 (* STOP {Error! Standard method "bound_self" called but not written in MODEL.}; *)
394 aw0a 1 END bound_self;
395    
396     METHOD bound_all;
397     NOTES 'purpose' SELF {
398     This method should be like bound_self except that it bounds the
399     passed in variables and calls bound_self on the passed in parts.
400     It should then call bound_self.
401     } END NOTES;
402    
403 johnpye 1290 (* STOP {Error! Standard method "bound_all" called but not written in MODEL.}; *)
404 aw0a 1 RUN bound_self;
405     END bound_all;
406    
407     METHOD scale_self;
408     NOTES 'purpose' SELF {
409     Most nonlinear (and many linear) models cannot be solved without
410     proper scaling of the variables.
411    
412     This method should reset the .nominal value on every real
413     variable in need of scaling. It should then call the
414     scale_self method on all the locally defined (IS_A) parts
415     of the MODEL. 0.0 is the worst possible nominal value. A
416     proper nominal is one such that you expect at the solution
417     the quantity
418    
419     abs(variable/(variable.nominal))
420    
421     to be around 1 (in the range of [0.1..10] or [0.01..100]).
422    
423     Variables (like fractions) bounded such that they cannot be
424     too far away from 1.0 in magnitude probably don't need scaling
425     most of the time if they are also bounded away from 0.0.
426    
427     Some solvers, but not all, will attempt to scale the
428     equations and variables by heuristic matrix-based methods.
429     This works, but inconsistently; user-defined scaling is
430     generaly much superior.
431    
432     ASCEND makes it easy to do. You scale the variables, which
433     can only be done well by knowing something about where the
434     solution is going to be found (by being an engineer, for
435     example.) Then ASCEND can calculate an appropriate
436     equation-scaling by efficient symbolic methods.
437    
438     This method should not change the scaling of models and
439     variables that are received through the parameter list of
440     the MODEL.
441     } END NOTES;
442    
443 johnpye 1290 (* STOP {Error! Standard method "scale_self" called but not written in MODEL.}; *)
444 aw0a 1 END scale_self;
445    
446     METHOD scale_all;
447     NOTES 'purpose' SELF {
448     This method should be like scale_self above except that it also
449     should scale the variables and models received through the
450     parameter list. It should then call scale_self to take care of
451     the local variables and models.
452     } END NOTES;
453    
454 johnpye 1290 (* STOP {Error! Standard method "scale_all" called but not written in MODEL.}; *)
455 aw0a 1 RUN scale_self;
456     END scale_all;
457     END METHODS;
458    
459     MODEL cmumodel();
460     NOTES
461     'purpose' SELF {
462     This MODEL does nothing except provide a root
463     for a collection of loosely related models.
464     If it happens to reveal a few bugs in the software,
465     and perhaps masks others, well, what me worry?
466     BAA, 8/97.
467     }
468     'methods' SELF {
469     This MODEL also provides a hook to put in candidates for
470     becoming ascBuiltin global methods. Global methods may be
471     overridden by local definitions.
472     BAA, 3/98.
473     }
474     END NOTES;
475    
476     END cmumodel;
477    
478     MODEL testcmumodel();
479     (*
480     * All CMU test models, of whatever sort should ultimately be
481     * rooted here or be a final refinement of a reusable MODEL.
482     *)
483     METHODS
484 jpye 1372 METHOD values;
485     (*
486     * In a final application MODEL, you should record at least one set of
487     * input values (values of the fixed variables and guesses of key
488     * solved-for variables) that leads to a good solution.
489     * Do this so noone need reinvent that set the next time
490     * you use the MODEL or someone picks the MODEL up after you.
491     *)
492     (* STOP {Error! Standard method "values" called but not written in MODEL.}; *)
493     END values;
494 aw0a 1
495 jpye 1372 METHOD specify;
496     (* STOP {Error! Standard method "specify" called but not written in test MODEL.}; *)
497     END specify;
498 aw0a 1
499 jpye 1372 METHOD ClearAll;
500     EXTERNAL asc_free_all_variables(SELF);
501     END ClearAll;
502    
503     METHOD reset;
504     (* This method gets the MODEL to some standard starting state,
505     * though not necessarily the most useful starting state for
506     * a particular application. In Chem. Eng. terms, this method
507     * establishes a base case.
508     * There is no 'one perfect "reset"' for all purposes. This
509     * routine should merely define a reasonably useful base configuration
510     * of the MODEL.
511     * Other reset_whatElseYouWant methods can (should) also be
512     * written.
513     *
514     * Normally you do not need to write this method: your models
515     * will inherit this one unless you override it (redefine it)
516     * in your MODEL.
517     *)
518     RUN ClearAll;
519     RUN specify;
520     END reset;
521 aw0a 1 END testcmumodel;
522    
523     MODEL your_site_models();
524     (* if you create a library to share with the net which is
525     * not just an end application of Carnegie Mellon models,
526     * please create an empy root MODEL such as this and use
527     * it as the origin of your library in the same way that
528     * we use cmumodel as the origin of our libraries.
529     * Thank you.
530     *)
531     END your_site_models;

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