Using the vDEC library: Using DEC: Differential forms ======================================================================== Template parameters ------------------- Assuming you know what a differential form is (if you don't, why are you reading this?), then the paradigm taken in this library is that a form is an entity that depends on its manifold, and must know certain things about it. What this boils down to is that forms can only exist with its corresponding mesh (discrete manifold) since they hold a reference to it. Also, for certain "pretty" overloaded operators to work, forms must also know the dimensionality of its manifold. The form class has 4 template parameters when you instantiate it: Form<3, 1, PRIMAL_FORM, double> CopyOfMy1Form(My1Form); Getting down to business, the mesh classes inherit from abstract base class SimplicialComplex, whose single template parameter is its dimensionality (2 for Mesh2D, 3 for Mesh3D). This corresponds to the first template parameter for a form. This is required to define the Hodge star operator. The second template parameter is the k in k-form (the "rank" of the form). The third parameter indicates whether the form is primal or dual. For certain applications, this parameter may not be necessary (and so you can specify primal always), although it is good to use it as a bookkeeping tool. The last parameter is the data type stored in the form. This will almost always be float or double, but you may wish to store an arrayed type, or something wacky. Since 4 template parameters is a lot of baggage to carry around, it is suggested you use typedefs to name the types to your liking: typedef Form<3, 1, PRIMAL_FORM, double> Primal1FormType; Sidenote: Implementation ------------------------------------------------ Discrete differential forms of dimension k are simply vectors of length Nk, where Nk is the number of k-dimensional simplices in the discrete manifold. So a 1-form is a vector with one value for each edge in a mesh. In this way, discrete differential forms "live" on a certain type of mesh element. Instantiation ------------- Since forms depend on the mesh they are defined on, the mesh must be given as a parameter when instantiating a form: Primal1FormType My1Form(MyTetMesh); Operations ---------- The common simple operations on forms are supported with overloaded operators: Form3 = 2.5 * (Form1 - Form2); where the template parameters must agree (the explicit checking is still spotty at the moment). These operations include addition, subtraction, scalar multiplication and division, and assignment. Hodge star (with the Euclidean metric) is implemented intuitively: MyDual2Form = *MyPrimal1Form; Taking the exterior derivative is also simple (at the cost of namespace pollution): MyPrimal2Form = d(MyPrimal1Form); And the co-derivative is similarly defined: MyDual1Form = dT(MyDual2Form); The wedge product will be implemented using the caret operator (^) as soon as the nuances of C++ are worked out, but don't count on it. Each of these operators will have finalized verbose function names as well for those who despise operator overloading. Finally, the most important operation is indexing into the array of values, for which the [] operator is overloaded: double MyParticularValue = MyDual1Form[SavedEdgeIndex]; Much of the syntax, and perhaps the templating may be altered in the future, but this is just to give a taste of what is possible in this area, and so that these ideas may be put to some use first.