MESA++ logo

Level 1 MESA++

This page describes Level 1 MESA++, which extends the Level 0 interface with exceptions and more C++-friendly argument lists.

What is Level 1 MESA++?
Some wrinkles
Namespaces


What is Level 1 MESA++?

Level 1 MESA++ is a straightforward extension of Level 0 MESA++ that makes use of exceptions and of more C++-friendly argument lists while retaining a procedural interface.

Let's take those points in reverse order. C++ support object-oriented programming, but it is not a pure object-oriented language, like Eiffel or Java, where all data is in the form of objects and all procedures are methods of object classes. You can write the kinds of procedure-oriented programs you are familiar with from Fortran in C++ and you can even achieve near-Fortran efficiency if you write them carefully. C++ is, after all, based on C, which in turn was designed to closely match the assembly instruction set of a typical computer of its day. Level 1 MESA++ supports procedural programming by providing a library of procedures that make little use of class objects.

Note that we said "little use", not "no use." The C++ standard library provides a number of container types, such as string and vector, which are classes but at a fairly low level. We make use of these simple standard classes in Mesa++ Level 1 wherever they make sense. However, there are some limitations on where they can sensibly be used, as described in the next section.

Finally, MESA makes extensive use of an error flag argument (typically spelled ierr) in its argument lists. C++ provides a somewhat more elegant method of handling errors, namely, exceptions. An exception is "thrown" when an error condition is detected, and "caught" at some higher level of the code that is prepared to deal with the exception. Intermediate layers of code simply propagate the exception upwards, automatically perfoming some cleanup along the way. This model avoids the need to check the error flag at every level of the code to see if that level should stop and return the error flag to the next higher level of code.

The C++ library provides a number of standard exception types, but we have chosen to provide our own Mesa_Exception class to represent MESA++ exceptions. This class stores the location of the exception (as a string) and the ierr value (as an int).


Some wrinkles

We intend for Level 1 MESA++ to retain as much of the computational efficiency of the underlying Fotran as possible. This puts some restrictions on how we write this level of MESA++.

Exceptions are supposed to be "pay to play." In other words, the use of exceptions in a program is not supposed to incur significant memory or runtime cost until an exception is actually thrown. This ideal is nearly realized on modern C++ compilers, and we use exceptions freely.

Standard library classes are another matter. We use string fairly freely, because of the enormous convenience of having the string contents and length readily available in a single package and because of the extensive string manipulation functionality provided by the methods of the string class. We reason that character strings are not often used at the lowest levels of a calculation (this certainly seems true of MESA and MESA++) so their overhead is almost always acceptable.

vector is a beautiful class in many ways. It provides automatic memory management and, like string, it wraps data and size information in one place. We can even extract the data pointer from a vector and wrap it in a Shape to be passed into a Fortran routine that expects a deferred array argument.

The fly in the ointment is that we cannot do the reverse. When a Fortran procedure does the allocating of a Shape, we have no way to move it into a vector short of copying all the data. That's an expensive operation we'd like to avoid anywhere it could create a computational bottleneck. Hence, there is presently (and likely always will be) a lot of procedures at Level 1 that use Shape in preference to vector.

Of course, we could write our own class that combines Shape and vector and has the machinery to decide which is wanted in various contexts. We might even be able to make this reasonably efficient. However, it's something that is only experimental at the moment, and not yet part of MESA++ Level 1. It may  make more sense to more fully flesh out Shape instead and use it in preference to vector.


Name spaces


Many functions in MESA++ Level 0 do not return an ierr flag and already have perfectly serviceable argument lists. We incorporate these into MESA++ Level 1 via a using declaration, so that they appear in the Level 1 name spaces as if they were defined in those name spaces. This should be completely transparent to the average developer, who should rarely if ever have occasion to explicitly use the Level 0 name spaces.

All Level 1 and Level 2 MESA++ functions and objects based on a module in MESA will be found in a corresponding namespace Mesa_module. The Level 0 functions and objects are found in Mesa_module_L0. The reason for separating out the Level 0 functions is that they are usually implemented as direct references to the underlying MESA Fortran functions, and references (unlike actual functions) cannot be overloaded. To provide a function in Level 1 that has an improved interface (perhaps with a potential thrown exception) to a MESA function accessed via reference in level 0, it is necessary to place that function in a separate namespace so the names don't collide.


web traffic statsSourceForge.net Logowebsite design by
Andreas Viklund