Libraries have become a central part of all major programming efforts connected to scientific computing, as introduced in Section 4.4. As a consequence the possible library-centric software design can be regarded as a methodology for designing applications as an assembly of single components with a low degree of coherence and a high degree of orthogonality. However, the following basic principles are essential for writing successful generic components [16]:
An important step towards library design is the definition of interfaces based only on concept requirements [94,93] to avoid monolithic application development which always leads to redevelopment of parts or complete applications. Instead already existing concepts and modules which have already proven successful can be used. Essential requirements related to an optimal library development can be summarized as follows:
In the past the main drawback related to library-centric design was the absence of programming paradigms supporting this type of design. An example can be seen in one of the features most used in programming: loops. The imperative style of using loops offers a great degree of flexibility during the development process, with regard to maintainability and side-effects. Nevertheless, simple loops require local variables to maintain a state, and only the imperative style of quantity access is available. These issues result in codes that lack maintainability, scalability, and lead to unnecessarily error-prone implementation bodies. Another issue which also does not support the concept of component resuse by itself is the object-oriented programming paradigm (Section 4.2), which complicates the interoperability of its software modules. An advantage of imperative and object-oriented programming is that no sophisticated programming techniques have to be taught and learned for one to be able to understand or extend the code. But it also results in an additional drawback, which directly results from the missing expressiveness of the code. Highly optimized code sections can barely be extended by other developers.
Reusability, orthogonality, enhancement capabilities, and performance are all issues which can be eased by using paradigms other than imperative and object-oriented programming. One of the most important issues related to library-centric application design is the shift from these programming paradigms to generic programming and the efficient implementation in programming languages which then offer generality and specialization at the same time. The related work Section 4.4 shows that an important part of generic library design is focused on the selection of the most suitable programming paradigms.
The combination of different programming paradigms fits the scenario of scientific computing exceptionally well. The generic programming paradigm establishes homogeneous interfaces between algorithms and data structures without sub-typing polymorphism. Functional programming eases the specification of equations and offers extendable expressions while retaining the functional dependence of formulae by higher order functions. Also, this type of specification of access, algebraic manipulation, and traversal circumvents the problems of the imperative implementation. The features of meta-programming offer the embedding of domain-specific terms and mechanisms directly into the host language as well as compile-time algorithms to obtain optimal run-time. Developments toward an alternative compilation model and active library design are also an important step [47,131,49]. However, reusability of traditional libraries is often extremely limited due to the following issues:
To circumvent the stated issues, a set of requirements for library-centric application design in the field of scientific computing is given in the following to allow the transformation of the concepts for scientific computing into generically applicable and efficient software components. A transformation into applied concepts has to comply with these concepts.
The fiber bundle concept is used as an organizing tool for a first part of this set of requirements. It separates the application modules into base space and fiber space modules. Base space modules are used for traversal within the cell complex and other cell complex issues, e.g., derivation of cell and complex topology as well as an efficient data structure for storing the connection matrix. Fiber space modules deal with the evaluation of quantities with respect to their differential form or cochain representation with additional semantic information. This means that the appropriate combination and evaluation of cells and their corresponding quantity has to be determined accordingly.
An additional requirement is related to an efficient use of programming paradigms for each of the given tasks. A base layer is identified, which has to implement a formal topological interface for cell and complex properties as well as for traversal, thereby establishing a consistent interface for data structures and quantity storage. The object-oriented and generic programming paradigms are best suited to accomplish this. On top of this base layer, functional expression specification facilities are required, which can be modeled best by the functional programming paradigm. The concept of a DSEL in C++ requires the additional concept of meta-programming resulting in an active library concept to implement and guarantee an overall high performance.