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

Annotation of /trunk/models/basemodel.a4l

Parent Directory Parent Directory | Revision Log Revision Log


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

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