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

Annotation of /trunk/models/basemodel.a4l

Parent Directory Parent Directory | Revision Log Revision Log


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

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