This is a description Pat Notz called his elevator speech on Phalanx:
The {NAME} package is a library to help decompose a complex problem into a set of simpler problems with managed dependencies. Two benefits of decomposing a problem using {NAME} are (1) increased flexibility because each simpler piece becomes an extension point that can be swapped out with different implementations and (2) easier to craft code because each piece is simpler, more focused and easier to test in isolation. The counter-benefits to these are (1) a potential performance loss due to fragmentation of the over-all algorithm (e.g., several small loops instead of one large loop) and (2) a potential loss of visibility of the original, composite problem (since the code is scattered into multiple places). Managing these trade-offs can result in application code that both performs well and supports rapid development and extensibility.
Simple concept for chunk-layout of heterogeneous members with proper data alignment.
A 'malloc'ed chunk of memory is always suitable to hold any data type, or array of data types (do a 'man malloc').
unsigned char * chunk = malloc( chunk_size );
If a 'double' is to occupy a portion of the chunk then is must be aligned such that:
double * d = (double *)( chunk + offset_d );
where:
0 == offset_d % sizeof(double);
The key point is for the offset of each member within the chunk to have the correct alignment, and of course not overlap any other member.
Email description of Phalanx (formerly known as the variable manager):
Phalanx is a tool for controlling the evaluation of data used in the assembly of a residual/Jacobian fill for PDE solvers. I implemented the one in Charon and one also exists in Aria (although it is used for a different purpose). The idea behind the VM is to allow for fast changes to dependency trees. The VM provides variable quantities. A variable consists of a name (string), a type (scalar, vector, tensor - all templated for ad), and the place that it lives (quadrature point, node, edge, face, element, etc...). A variable is evaluated using a provider. The provider contains lists of variables it provides (evlauates) and a list of variables it requires to perform the evaluation (its dependencies). The VM figures out the correct order to call the providers to get the dependency chain correct.
I developed this for Charon to address the following issues:
if (velocity is DOF) // get values from dof structure else if (velocity is auxiliary data) // go get from aux data structure else if (...)
There were hard coded loops in multiple places that had to be updated every time we added a new way to specify velocity. Now, when velocity is required, you just go to the VM and get it. No questions asked.
There are other benefits, but you get the idea. A primary goal of my current ASC funding is to generalize the variable manager in Charon (there are many things I can do better now to make it more efficient and easier to use) as a trilinos package to be used with Intrepid to aid in element assembly for nonlinear equation sets.