LifeV
|
Flags are needed in order to save computation. Indeed, when the LifeV::ETCurrentFE structure has to be updated for a given element, it is possible that all the informations (e.g. second derivatives of the basis functions) are not needed. The flag carry the information of the values to be computed because they are required.
At first sight, we might think that a flag is a complicated class implemented to do exactly what we want, with overloaded operators... Actually, it is much simpler: a LifeV::flag_Type is just an unsigned integer.
The flags use the binary representation of the integers to work. This enables a very fast definition and use of the flags. To understand it, let us make a simple example. Suppose that we can update three quantities A,B and C.
The first step is to define a "primitive" flag for each of these quantities. These flags are defined as powers of 2. Here, we will define
We need here powers of 2 because this makes the binary representation of the "primitive" flags simple: UPDATE_A is 001, UPDATE_B is 010 and UPDATE_C is 100 (if the integers are coded on 3 bits, otherwise there are many zeros before). The fact that we want A to be update is then represented by a 1 in the third position, for B it is the second position and for C the first position.
So now, if we want to build a flag that updates A and C, we want it to be in binary 101, that is 5. So, the flag UPDATE_AC will be defined as:
With the last example, one could think that is it just a matter of addition, but it is not. Suppose that we want to combine the flags UPDATE_A and UPDATE_AC. If we add the corresponding values, we will get 1+5=6 that is represented in binary by 110. This would mean update B and C, what is not what we want!
To combine flags, we use the binary operator | (bitwise "OR" operation) that do exactly the job that we want: 1|5=5.
Now that we can build every flag that we want, we want to detect quickly the different flags. This is achievied by using the binary operator & (bitwise "AND" operation) and the "primitive" flags.
Suppose that we want to know if A has to be updated. Then, we perform the operation "& UPDATE_A" on the incoming flag. If the result is zero, then we do not need to update it: for example, UPDATE_B & UPDATE_A = 0 . Otherwise, we have to update it: for example, UPDATE_AC & UPDATE_A = 1.
There are several flags defined for you. Here is a list of the possible flags that are usually used:
Flag name | Effect |
---|---|
ET_UPDATE_QUAD_NODES | Update everything needed to know the position of the quadrature nodes in the current cell |
ET_UPDATE_DPHI | Update everything needed to know the values of the derivatives of the basis functions in the quadrature nodes (in the current cell) |
ET_UPDATE_D2PHI | Update everything needed to know the values of the second derivatives of the basis functions in the quadrature nodes (in the current cell) |
ET_UPDATE_WDET | Update everything needed to know the determinant of the transformation multiplied by the weights of the quadrature. |
Note: in the old versions there was also the flag UPDATE_PHI. This flag has been removed, since the values of the basis functions in the quadrature nodes are always the same, so they do not need to be updated. Besides this usual flags, there are a couple of "primitive" flags, that update only a particular element in the currentFE structure. Be sure to know what you are doing before using them.