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);
onto a discrete space
is to do an
projection, in other words, to find the discrete function
that is closest to
in the
norm. This minimization problem can be set up easily in user-level Sundance using a LinearProblem, but because of its frequent occurrance we have encapsulated this capability into a specialized object called an L2Projector.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);
project() method, // 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.
// 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 vectors
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 setVector() method.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.