Revise the Mapping::fill_fe_*_values() interfaces.
These functions previously got a whole lot of arguments for the output arrays.
Consolidate them by simply passing the structure in which they actually lie.
While there, also do:
- Sort these arguments in such a way that they make a bit more sense.
- Provide a thorough documentation of these functions.
Make the internal data object of the mapping classes const.
Logically, they are input arguments to the fill_fe_values() functions, they are only
initialized in get_data() etc. Thus, make them const in the fill_fe_values functions.
There are places where mapping classes want to move data across from fill_fe_values
in terms of temporary arrays to the transform() function that may be called right
afterwards from FiniteElement::fill_fe_values(). In those cases, make these members
mutable.
Let second_derivative() return a const reference, rather than a value.
This function is used in places where we want to get pointers into an array. Make sure that
is possible for both the const and the non-const version of the function. (The latter
already did this; the former didn't and that wasn't needed, but I need it for a
follow-up patch.)
There are a couple of places where we call a get_data() function
that returns a pointer to a base class when we know that the actual
data type is a pointer to derived class. We need to cast right back
to the derived class.
This can be avoided by using covariant return types where the get_data()
function returns a pointer to derived right away.
Make sure that compute refinement thresholds are no larger than the max indicator.
This could happen because we search the threshold in an interval larger than the
actual indicators. If we end up with a threshold that is larger than the largest
indicator, we need to cut things back.
In the process of debugging, I also found a few oddities that have to do
with the fact that we do a lot of arithmetic in double precision, but often
pass in criteria as vectors of float. Fix some of those as well.
Make the CellSimilarity argument const also in Mapping.
Logically, these arguments are intended to be input arguments, so make them
const. Also, don't make them a reference as they are simply integral values.
That said, the original intention of having a reference was so that
mappings can indicate situations where cell similarity has to be
disregarded. Consequently, let the fill_fe_values() functions return a
cell similarity value that will then simply be assigned to the same
variable again.
Specifically, don't modify an input argument of the function but instead use the
old value and just modify the conditions in which it is used. This makes it clearer
when certain actions have to be performed.
Rewrite the FE_DGPNonparametric::fill_fe_*_values() functions.
Specifically, make sure that the FiniteElement::InternalDataBase object they receive is
really used specifically only for read-only purposes. This requires that we allocate some
memory in the fill_fe_*_values() functions for scratch arrays, but on the upside, we can
get rid of the FE_DGPNonparametric::InternalData class.
In the constructor of FESystem, we clone the base elements, which requires
constructing new finite element objects -- an expensive task. This patch
does this in parallel for the base elements.
Timo Heister [Sat, 18 Jul 2015 16:24:04 +0000 (12:24 -0400)]
Avoid Intel 15 bug in SymmetricTensor
This should fix broken behavior in deal.II/fe_values_view_{23|24|25} with
Intel 15.0.3, where the compiler sometimes forgets to initialize the static
fields.
Workaround: fix compilation with icc and linear_operator
Disables the sfinae lookup in the has_vmult_add helper class for faulty
icc. Intel's compiler up version 15.0.3 run into an sfinae bug otherwise.
For affected compiler versions, has_vmult_add will always report "false"
for icc which will result in a slight performance penalty due to
unnecessary temporary storage.
My understanding is that when FEValues calls the mapping, the mapping puts
its results into the FEValuesData base class of the FEValues object. Then,
FEValues calls FiniteElement::fill_fe_values which uses the mapping data
and its InternalData object to compute shape function information and again
put it into the FEValuesData base class of the FEValues object.
In the case of FESystem, this is a bit more complicated: Here, we don't want
the base elements to put their stuff into the FEValuesData base object
because the results of *all* base elements will go there (and because,
consequently, array sizes don't match, etc). Thus, FESystem::fill_fe_values
creates an array of scratch FEValuesData objects, passes these to the
base elements that fill them, and the copies back the data from the scratch
objects to its own base element. To make this work, FESystem has to also first
copy everything that's in its own FEValuesData base object to each of the scratch
objects.
This is where the bug lies: Currently, only one of the elements that the mapping
has computed is copied; we need to be consistent and do this with all
mapping related arrays in FEValuesData.