This page discusses the following topics:
// create a discrete space for a scalar field // with Lagrange order 1 basis functions. The vector type is not specified // so the default will be used. DiscreteSpace discSpace(mesh, new Lagrange(1));
// create a discrete space for a 3-component vector field where each component // is represented with Lagrange order 2 basis functions. The vector // type is specified through the vecType argument. DiscreteSpace discSpace(mesh, List(new Lagrange(2), new Lagrange(2), new Lagrange(2)), vecType);
An L2Projector is constructed by specifying a DiscreteSpace and an Expr to be projected onto that space:
// Set up projection on f onto the space of first-order Lagrange basis // functions on our mesh. DiscreteSpace discSpace(mesh, new Lagrange(1)); L2Projector projector(discSpace, f);
// Do the projections Expr discreteF = projector.project();
There is a certain amount of bookkeeping involved in projection; basically, the overhead required for the setup of the linear problem doing the projection. If you need to do many projections of the same expression (perhaps with changing values of a discrete field or parameter) onto the same space, it is recommended that you create a single L2Projector and reuse it for all of these projections.Initialization to a constant value and Initialization to a vector.
// Initialize a DiscreteFunction to a constant value 1.2345 DiscreteSpace discSpace(mesh, new Lagrange(1)); Expr f = new DiscreteFunction(discSpace, 1.2345);
Normally, insertion of a vector into a DiscreteFunction should be done using the vector access methods described in Access to DiscreteFunction vectorsVector<double>. In most user-level simulation code, you will never need to use this vector explicitly. However, when writing adapters to new kinds of solvers it is sometimes necessary to modify a discrete function's vector directly.
A DiscreteFunction will normally be wrapped in an Expr object, so the first step towards vector access is to extract a DiscreteFunction pointer from an Expr. This can be done with the static method
discFunc(), which has both const and non-const versions:
// Get a read-only pointer to the discrete function inside the Expr handle f0 const DiscreteFunction* discF0 = DiscreteFunction::discFunc(f0);
// Get a writable pointer to the discrete function inside the Expr handle f0 DiscreteFunction* discF0 = DiscreteFunction::discFunc(f0);
getVector()method. The discrete function can also be given a new vector by means of the
Note: Because Expr has shallow copy behavior, changing the vector of a discrete function will simultaneously change the vector of all copies of that expression. This is a deliberate design feature: it is thereby possible to update the value of a discrete function appearing multiple times inside a complicated expression simply by setting the vector of a single instance of that discrete function.