I know we have discussed this a while ago, but given the new code in the branch fe_tools I think it's worth to reconsider the return type of the following two methods (both belong to ScalarReferenceFiniteElement):
I see three problems with the current return types:
Computing the local element matrices is unnecessary complex and inefficient: At the moment, both methods are exclusively called by LocCompLagrFEPreprocessor which transforms the returned data into a more suitable form.
Given a FE solution vector, it is rather complicated and inefficient to evaluate the solution function at a given point on the mesh. (for loop over local shape functions is necessary).
We solved a similar problem, namely the return type of Geometry::Jacobians() differently. This is not very consistent.
I suggest that the return types of both methods become Èigen::MatrixXd matrices of size NumRefShapeFunctions() x NumQuadPoints(), respectively NumRefShapeFunctions() x (DimLocal*NumQuadPoints). This solves all three problems mentioned above:
Computing e.g. the stiffness matrix is rather simple: GradientsScalarReferenceShapeFunctions()*W*GradientsScalarReferenceShapeFunctions().transpose() where w is a diagonal (assuming diffusion tensor is the identity) square matrix of size (DimLocal*NumQuadPoints) that has every quadrature weight DimLocal times on the diagonal. The mass matrix or boundary integrals can be computed very similarly.
If we have a local solution vector v of length NumRefShapeFunctions(), we can compute the value of the fe-solution at quadrature points qp by evaluating v.transpose()*EvalScalarReferenceShapeFunctions(qp).
Is clear.
I know that the my proposed change makes the code at first a little bit less readable, but as soon as someone has to deal with assembly of local element matrices, it's much easier this way... And I think in 90% of the use cases, these methods are called to compute local element matrices...
Since, a similar scheme is in use already for returning Jacobians, adopting the same convention for ScalarReferenceFiniteElement should not be too confusing. I endorse the proposed changes.
I know we have discussed this a while ago, but given the new code in the branch fe_tools I think it's worth to reconsider the return type of the following two methods (both belong to
ScalarReferenceFiniteElement
):I see three problems with the current return types:
LocCompLagrFEPreprocessor
which transforms the returned data into a more suitable form.Geometry::Jacobians()
differently. This is not very consistent.I suggest that the return types of both methods become
Èigen::MatrixXd
matrices of sizeNumRefShapeFunctions() x NumQuadPoints()
, respectivelyNumRefShapeFunctions() x (DimLocal*NumQuadPoints)
. This solves all three problems mentioned above:GradientsScalarReferenceShapeFunctions()*W*GradientsScalarReferenceShapeFunctions().transpose()
where w is a diagonal (assuming diffusion tensor is the identity) square matrix of size(DimLocal*NumQuadPoints)
that has every quadrature weightDimLocal
times on the diagonal. The mass matrix or boundary integrals can be computed very similarly.v
of lengthNumRefShapeFunctions()
, we can compute the value of the fe-solution at quadrature pointsqp
by evaluatingv.transpose()*EvalScalarReferenceShapeFunctions(qp)
.I know that the my proposed change makes the code at first a little bit less readable, but as soon as someone has to deal with assembly of local element matrices, it's much easier this way... And I think in 90% of the use cases, these methods are called to compute local element matrices...