Subject: OOP in Comp. Chem. and other ideas

From: [email-masked] (Terry R. Coley)
Date: 13 Feb 1994 21:55:28 GMT

For the past two years various members of the Goddard research group
at Caltech have been using advanced software techniques for
computational chemistry.  We will be talking about some of the results
at the ACS meeting in San Diego this March.
	
There are several areas of discussion when software approaches are
considered:

1)  how to make programs flexible and accessible to users
2)  what language to use
3)  what design techniques to use (OOD, etc.)
4)  how to make code reusable

In short, our approach has been to use whatever works.  This somewhat
lengthy post presents some of the approaches that have been working
for us in each of these areas:

1)  Accessibility/Flexibility.

This is perhaps the most important point of all and is related to previous
CCL discussions of "tools" for computational chemistry.  Much code falls
into two categories:

a) monolithic programs
b) simple, single purpose programs
	
Type a) becomes difficult/impossible to maintain/extend without an
in-depth knowledge of the entire program.  Data structures tend to be
so inextricably mixed with each other that there is essentially no way
to fully test a new change for correctness and lack of side-effects.
	
Type b) result in the chemist spending lots of time trying to make
input and output file formats compatible.  This is the case because
research naturally tends to want new results combined in ways not
previously considered.

Our programs are all run using a Tcl (Tool Command Language, see
comp.lang.tcl) embedded interpreter.  Traditional programs read input,
setup and perform a calculation, and output results.  In contrast, we
try to *enforce as little overall structure on the flow* of events as
possible.  Our objects, even the ones that perform calculations, are
*interpreter-driven*, and are written as generally as possible.

Major algorithms are implemented by simple Tcl commands with operate
on internally defined objects.  The course of a calculation is
dictated by the Tcl script written by the user.  This allows usrs to
then easily recombine objects to perform different calculations as
necessary.

Most major data structures (e.g., Matrices, Molecules, Atoms) and
their corresponding member functions are available to the Tcl script.
What does this mean in a practical sense to the user?  Suppose you
have one of our programs and you need to output a final basis set
overlap matrix in a particular form to be analyzed by another program.
Without changing the executable, it is possible to write and test a
simple Tcl script to output data from the program in whatever form is
needed.  All this can be done interactively... if there is an error in
the script, just edit it and try again - no need to rerun the
calculation that generated the result.

Example:
Suppose you wish to run a calculation using a specially generated set
of one electron integrals.  Without modifying the program, all that is
necessary is to write an interpreted script to input the desired
matrix (or perform a transformation on the current one).  No change
to the program is needed.

It is hard to overstate the usefulness of this concept.  A program
designed in this way may be reconfigured to perform calculations not
forseen by the author.  Furthermore, all our Tcl-based programs can
communicate with each other via TCP/IP.  A single Tcl script can
coordinate the flow of input and results from several different 
programs at once.
	
2)  Language.

Our code is primarily based on C++, but we make use of Fortran where
it is the most appropriate tool.  C++ can represent complex data
structures more naturally; some numerical operations are done in
Fortran or using reliable libraries.
	
Example:
Our C++ matrix classes are implemented with member functions that use
the Fortran LAPACK routines for fast, parallel matrix operations.

3) Object oriented design.

We have made use of object oriented design where it is most natural.
In our current focus on quantum code, the data representing things
like atoms, molecules, and basis sets are collected together with the
code that implements operations on them in C++ objects.  Essentially,
what we are designing are libraries, but ones where the code/data
structure closely reflects the organization of the ideas represented.
Encapsulation of the data with code affecting our objects is very
important for generating software that does not have arbitrary (and
difficult to debug) interdependencies on other code.

Features of the language, such as operator overloading, make the
code easier to read, and assist in usability and reusability.

We realize some of this is a bit philosophical, but we do think that
it is pragmatically important.  When software does not clearly
parallel the way we conceptualize things and algorithms, confusion
often results, especially when multiple programmers are involved.  In
our experience C++ (and probably other modern languages) leads
naturally to data structures that mirror chemical ideas.

4)  Reusability

By reusability, we really mean two things:

  o Generality of coding
  o Maintainability of coding

To a large extent good general code can be incorporated without change
into new code.  Maintainable code also leads to reuse by being
approachable and extensible by a programmer other than the author.

What are things that don't lead to reusability?  Odd subroutine
interfaces, confusion about what a routine actually does, silly output
(or weird formats), overzealous speed optimization.  Our use of C++
allows us to design so that the input and output are much more
intuitive; the code is hopefully easy to read, so that it is more
easily understood what a routine does.

Unnecessary speed optimization is a frequent culprit in the production
of unreadable, unmaintainable code.  Our approach is to write code in
the most straightforward (some might say verbose) way first.  After
correctness is verified, profiling is done.  Only code that requires
significant CPU-time need be rewritten.

We have also been putting C++ templates to use by making certain
container classes as general and reusable as possible.

We hope to have this code ready for free public consumption via ftp
around the time of the March ACS meeting.  Although we have found the
ideas useful in our work, the code is still young.  We would like
others to experiment using Tcl and TCP/IP for creating programs which
can communicate with each other.

  Terry R. Coley, Ph.D                    Erik P. Bierwagen
  Goddard Research Group, Caltech         Goddard Research Group, Caltech
  [email-masked]                   [email-masked]