Commit 45be234e authored by GILLES Sebastien's avatar GILLES Sebastien
Browse files

#531 Doxygen comments in Private::Impl::Recursivity.

parent fbd53506
......@@ -816,8 +816,6 @@
BEA263B71A28D0FB001802B6 /* libOps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BE2393141A23977700E24C84 /* libOps.a */; };
BEA263B81A28D0FB001802B6 /* libSeldon.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BE2393191A23978400E24C84 /* libSeldon.a */; };
BEA263B91A28D0FB001802B6 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEC37E0617DDC0210021BFB7 /* Accelerate.framework */; };
BEA3FA7F1AF10AA000D3F871 /* Recursivity.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BEA3FA7C1AF10AA000D3F871 /* Recursivity.hpp */; };
BEA3FA801AF10AA000D3F871 /* Recursivity.hxx in Headers */ = {isa = PBXBuildFile; fileRef = BEA3FA7D1AF10AA000D3F871 /* Recursivity.hxx */; };
BEA3FA8C1AF10CFB00D3F871 /* Recursivity.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BEA3FA891AF10CFB00D3F871 /* Recursivity.hpp */; };
BEA3FA8D1AF10CFB00D3F871 /* Recursivity.hxx in Headers */ = {isa = PBXBuildFile; fileRef = BEA3FA8A1AF10CFB00D3F871 /* Recursivity.hxx */; };
BEA9CB9F1A1E26A8003A6276 /* libCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BE05B52916D238FE000E248D /* libCore.a */; };
......@@ -2149,8 +2147,6 @@
BEA3248717A7E5BA00ADEB73 /* Exception.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Exception.hpp; sourceTree = "<group>"; };
BEA355D617D0971500FB643B /* OpsFunction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OpsFunction.hpp; sourceTree = "<group>"; };
BEA355D717D0971500FB643B /* OpsFunction.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OpsFunction.hxx; sourceTree = "<group>"; };
BEA3FA7C1AF10AA000D3F871 /* Recursivity.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Recursivity.hpp; sourceTree = "<group>"; };
BEA3FA7D1AF10AA000D3F871 /* Recursivity.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Recursivity.hxx; sourceTree = "<group>"; };
BEA3FA891AF10CFB00D3F871 /* Recursivity.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Recursivity.hpp; sourceTree = "<group>"; };
BEA3FA8A1AF10CFB00D3F871 /* Recursivity.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Recursivity.hxx; sourceTree = "<group>"; };
BEA4FC2A18214B6A002B2EA1 /* TransientParameters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TransientParameters.cpp; sourceTree = "<group>"; };
......@@ -3306,8 +3302,6 @@
BE4DDE8C1AE1332900D60CCC /* GlobalVariationalOperator.cpp */,
BE4DDE8D1AE1332900D60CCC /* GlobalVariationalOperator.hpp */,
BE4DDE8E1AE1332900D60CCC /* GlobalVariationalOperator.hxx */,
BEA3FA7C1AF10AA000D3F871 /* Recursivity.hpp */,
BEA3FA7D1AF10AA000D3F871 /* Recursivity.hxx */,
BEA3FA811AF10CD000D3F871 /* Impl */,
BE4DDE861AE1332900D60CCC /* Crtp */,
);
......@@ -5215,7 +5209,6 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
BEA3FA801AF10AA000D3F871 /* Recursivity.hxx in Headers */,
BE90E1041A2491AE00CCAFDE /* EnumGaussQuadratureFormula.hpp in Headers */,
BE2B66481A2778C700E80864 /* TetrahedronP1.hpp in Headers */,
BEB03EB61A36056B00E99AAC /* Force.hpp in Headers */,
......@@ -5406,7 +5399,6 @@
BE2B66601A2778C700E80864 /* RefFEltInLocalNumbering.hpp in Headers */,
BE90E0B41A2491AE00CCAFDE /* Component.hpp in Headers */,
BE90E1551A2491AE00CCAFDE /* CompNA.hpp in Headers */,
BEA3FA7F1AF10AA000D3F871 /* Recursivity.hpp in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -28,7 +28,6 @@
# include "FiniteElement/FiniteElement/EnumFiniteElt.hpp"
# include "FiniteElement/FiniteElement/LocalFEltSpace.hpp"
# include "FiniteElement/Operators/GlobalVariationalOperator/Private/GlobalVariationalOperator.hpp"
# include "FiniteElement/Operators/GlobalVariationalOperator/Private/Recursivity.hpp"
# include "FiniteElement/Operators/Crtp/UnknownAndNumberingSubsetList.hpp"
......
......@@ -9,9 +9,13 @@
#ifndef _HAPPY_HEART__FINITE_ELEMENT__OPERATORS__GLOBAL_VARIATIONAL_OPERATOR__PRIVATE__GLOBAL_VARIATIONAL_OPERATOR_HPP_
# define _HAPPY_HEART__FINITE_ELEMENT__OPERATORS__GLOBAL_VARIATIONAL_OPERATOR__PRIVATE__GLOBAL_VARIATIONAL_OPERATOR_HPP_
# include <tuple>
# include "Utilities/MatrixOrVector.hpp"
# include "FiniteElement/RefFiniteElement/ElementaryData.hpp"
# include "FiniteElement/Operators/GlobalVariationalOperator/Private/Impl/Recursivity.hpp"
namespace HappyHeart
......@@ -25,6 +29,43 @@ namespace HappyHeart
namespace Private
{
/*!
* \brief Call Petsc's Assembly() function for each item of \a linear_algebra_tuple.
*
* \tparam LinearAlgebraTupleT A tuple that may include either \a GlobalMatrixAndCoefficient (for bilinear
* operators) or \a GlobalVectorAndCoefficient (for linear operators) objects. Some non linear operators
* may include both types of objects; the ordering doesn't matter.
*
* \param[in] linear_algebra_tuple List of global matrices and/or vectors into which the operator is
* assembled. These objects are assumed to be already properly allocated.
*
*/
template<class LinearAlgebraTupleT>
void Assembly(const LinearAlgebraTupleT& linear_algebra_tuple);
/*!
* \brief Perform the actual assembling for each item of \a linear_algebra_tuple.
*
* \tparam LinearAlgebraTupleT A tuple that may include either \a GlobalMatrixAndCoefficient (for bilinear
* operators) or \a GlobalVectorAndCoefficient (for linear operators) objects. Some non linear operators
* may include both types of objects; the ordering doesn't matter.
*
* \param[in] linear_algebra_tuple List of global matrices and/or vectors into which the operator is
* assembled. These objects are assumed to be already properly allocated.
* \param[in] local_felt_space Local finite element space being assembled. Remind a local finite element
* space is the object linked to a geometric element that hold finite elements information.
* \param[in,out] local_operator Local variational operator in charge of the computation of the local
* linear algebra. It also holds the results of these computations, hence its presence here.
*
*/
template<class LinearAlgebraTupleT, class LocalVariationalOperatorT>
void InjectInGlobalLinearAlgebra(const LinearAlgebraTupleT& linear_algebra_tuple,
const LocalFEltSpace& local_felt_space,
LocalVariationalOperatorT& local_operator);
......
......@@ -18,10 +18,29 @@ namespace HappyHeart
{
template<class LinearAlgebraTupleT>
void Assembly(const LinearAlgebraTupleT& linear_algebra_tuple)
{
static_assert(Utilities::IsSpecializationOf<std::tuple, LinearAlgebraTupleT>::value,
"Compilation error if LinearAlgebraTupleT is not a std::tuple.");
Impl::Recursivity<LinearAlgebraTupleT, 0, std::tuple_size<LinearAlgebraTupleT>::value>
::Assembly(linear_algebra_tuple);
}
template<class LinearAlgebraTupleT, class LocalVariationalOperatorT>
void InjectInGlobalLinearAlgebra(const LinearAlgebraTupleT& linear_algebra_tuple,
const LocalFEltSpace& local_felt_space,
LocalVariationalOperatorT& local_variational_operator)
{
Impl::Recursivity<LinearAlgebraTupleT, 0, std::tuple_size<LinearAlgebraTupleT>::value>
::InjectInGlobalLinearAlgebra(linear_algebra_tuple, local_felt_space, local_variational_operator);
}
} // namespace Private
......
......@@ -29,35 +29,103 @@ namespace HappyHeart
{
/*!
* \brief Helper class used for metaprogramming iterations.
*
* The main purpose here is to apply the same operation to each item of \a LinearAlgebraTupleT.
*
* \tparam LinearAlgebraTupleT A tuple that may include either \a GlobalMatrixAndCoefficient (for bilinear
* operators) or \a GlobalVectorAndCoefficient (for linear operators) objects. Some non linear operators
* may include both types of objects; the ordering doesn't matter.
* \tparam I Current element of the tuple.
* \tparam TupleSizeT The result of std::tuple_size<LinearAlgebraTupleT>::value.
*/
template<class LinearAlgebraTupleT, std::size_t I, std::size_t TupleSizeT>
struct Recursivity
{
//! Type of the current element; might be either GlobalMatrixWithCoefficient or GlobalVectorWithCoefficient.
using current_type = typename std::tuple_element<I, LinearAlgebraTupleT>::type;
// Check here the type of current item is one of those expected.
static_assert(std::is_same<current_type, GlobalMatrixWithCoefficient>::value
|| std::is_same<current_type, GlobalVectorWithCoefficient>::value
, "Tuple is expected to include only one of those types.");
/*!
* \brief Call Assembly() on current element and then apply recursion.
*/
static void Assembly(const LinearAlgebraTupleT& linear_algebra_tuple);
/*!
* \brief Report the result of elementary computation into the matrix pointed by current item and
* then apply recursion.
*
* \param[in] local_felt_space Local finite element space being assembled. Remind a local finite element
* space is the object linked to a geometric element that hold finite elements information.
* \param[in,out] local_operator Local variational operator in charge of the computation of the local
* linear algebra. It also holds the results of these computations, hence its presence here.
*/
template<class LocalVariationalOperatorT>
static void InjectInGlobalLinearAlgebra(const LinearAlgebraTupleT& linear_algebra_tuple,
const LocalFEltSpace& local_felt_space,
LocalVariationalOperatorT& local_variational_operator);
const LocalFEltSpace& local_felt_space,
LocalVariationalOperatorT& local_variational_operator);
private:
/*!
* \brief Private function called by \a InjectInGlobalLinearAlgebra when current element refers to a
* matrix.
*
* \param[in] previous_coefficient The elementary matrix has been computed once but during each assembling
* the coefficient applied is not the same. Unfortunately Petsc doesn't provide a function that
* set the values multiplied by a factor, so I have to multiply the local matrix by a factor.
*
* Let's say for instance the operator is assembled in two matrices (this is pseudo code, not actual
* HappyHeart call):
*
* \code
* operator.Assemble({ Matrix1, factor1 }, {Matrix2, factor2});
* \endcode
*
* One way to do injection is (still pseudo code):
* \code
* local_matrix *= factor1;
* Inject local_matrix into Matrix1;
* local_matrix /= factor1; // of course with check no 0 here...
* local_matrix *= factor2;
* Inject local_matrix into Matrix2;
* local_matrix /= factor2; // of course with check no 0 here...
* \endcode
*
* However we see here that on one hand the last division isn't useful, on the other hand two of the
* operations could be done in one step.
*
* The latter case is exactly the point of \a previous_coefficient: when assembling into Matrix2
* the program looks the previous matrix being assembled to determine the correct factor. So in
* pseudo-code what is done is:
*
* \code
* local_matrix *= factor1;
* Inject local_matrix into Matrix1;
* local_matrix *= factor2 / factor1; of course with check no 0 here...
* Inject local_matrix into Matrix2;
* \endcode
*
* If there are both matrices and vectors in \a LinearAlgebraTupleT, it still works whatever the
* ordering: when computing a matrix vectors objects are skipped in the determination of the
* previous factor.
*
*/
template<class LocalVariationalOperatorT>
static void InjectInGlobalLinearAlgebraImpl(const LocalFEltSpace& local_felt_space,
LocalVariationalOperatorT& local_variational_operator,
const GlobalMatrixWithCoefficient& global_matrix,
double previous_coefficient);
//! Same as previously for vectors.
template<class LocalVariationalOperatorT>
static void InjectInGlobalLinearAlgebraImpl(const LocalFEltSpace& local_felt_space,
LocalVariationalOperatorT& local_variational_operator,
......@@ -66,6 +134,16 @@ namespace HappyHeart
// \todo #531 Improve efficiency (copy is stupid here...)
/*!
* \brief Reduce the elementary matrix to the subset that must be reported in the global matrix.
*
* Let's consider for instance a Stokes operator in a nonmonolithic way: same elementary matrix
* must be reported in two blocks of different sizes (said size is deduced from numbering subset
* arguments).
* Role of current function is to generate a smaller matrix that includes only the elements to report
* into the bigger one. Reason for this is the prototype of Petsc function: it expects the elements
* to be set to be contiguous in memory.
*/
template<class LocalVariationalOperatorT>
static LocalMatrix ComputeLocalMatrix(const LocalVariationalOperatorT& local_variational_operator,
const NumberingSubset& row_numbering_subset,
......@@ -74,6 +152,46 @@ namespace HappyHeart
};
/*!
* \brief Another struct for recursion that works in the opposite direction: the stopping condition
* is when index is 0.
*
*
* \tparam LinearAlgebraTupleT A tuple that may include either \a GlobalMatrixAndCoefficient (for bilinear
* operators) or \a GlobalVectorAndCoefficient (for linear operators) objects. Some non linear operators
* may include both types of objects; the ordering doesn't matter.
* \tparam I Current element of the tuple.
*/
template<class LinearAlgebraTupleT, std::size_t I>
struct ZeroSpecialCase
{
//! Type of the current element; might be either GlobalMatrixWithCoefficient or GlobalVectorWithCoefficient.
using current_type = typename std::tuple_element<I, LinearAlgebraTupleT>::type;
/*!
* \brief This static method computes the coefficient required by
* \a Recursivity::InjectInGlobalLinearAlgebraImpl.
*
* See this function for a detailed explanation.
*/
template<class CurrentTypeT>
static double FetchPreviousCoefficient(const LinearAlgebraTupleT& linear_algebra_tuple);
};
// ============================
// Stop points of recursive loops.
// ============================
//! \cond IGNORE_BLOCK_IN_DOXYGEN
template<class LinearAlgebraTupleT, std::size_t TupleSizeT>
struct Recursivity<LinearAlgebraTupleT, TupleSizeT, TupleSizeT>
......@@ -84,41 +202,29 @@ namespace HappyHeart
template<class LocalVariationalOperatorT>
static void InjectInGlobalLinearAlgebra(const LinearAlgebraTupleT& linear_algebra_tuple,
const LocalFEltSpace& local_felt_space,
LocalVariationalOperatorT& local_variational_operator);
const LocalFEltSpace& local_felt_space,
LocalVariationalOperatorT& local_variational_operator);
};
template<class LinearAlgebraTupleT, std::size_t I>
struct ZeroSpecialCase
template<class LinearAlgebraTupleT>
struct ZeroSpecialCase<LinearAlgebraTupleT, 0>
{
using current_type = typename std::tuple_element<I, LinearAlgebraTupleT>::type;
// What we really seek is the previous coefficient FOR THE SAME TYPE of linear algebra.
// However, nothing prevent a user to ask for:
// non_linear_operator.Assemble(*matrix1*, *vector1*, *matrix2*);
// In this case, the expected previous coefficient are respectively: 1., 1., coeff(matrix1).
template<class CurrentTypeT>
static double FetchPreviousCoefficient(const LinearAlgebraTupleT& linear_algebra_tuple);
};
//! \endcond IGNORE_BLOCK_IN_DOXYGEN
// ============================
// End of stop points of recursive loops.
// ============================
template<class LinearAlgebraTupleT>
struct ZeroSpecialCase<LinearAlgebraTupleT, 0>
{
template<class CurrentTypeT>
static double FetchPreviousCoefficient(const LinearAlgebraTupleT& linear_algebra_tuple);
};
......
//
// Recursivity.hpp
// HappyHeart
//
// Created by Sebastien Gilles on 29/04/15.
// Copyright (c) 2015 Inria. All rights reserved.
//
#ifndef _HAPPY_HEART__FINITE_ELEMENT__OPERATORS__GLOBAL_VARIATIONAL_OPERATOR__PRIVATE__RECURSIVITY_HPP_
# define _HAPPY_HEART__FINITE_ELEMENT__OPERATORS__GLOBAL_VARIATIONAL_OPERATOR__PRIVATE__RECURSIVITY_HPP_
# include <tuple>
# include "FiniteElement/Operators/GlobalVariationalOperator/Private/Impl/Recursivity.hpp"
namespace HappyHeart
{
namespace Private
{
/*!
* \brief Call Petsc's Assembly() function for each item of \a linear_algebra_tuple.
*
* \tparam LinearAlgebraTupleT A tuple that may include either \a GlobalMatrixAndCoefficient (for bilinear
* operators) or \a GlobalVectorAndCoefficient (for linear operators) objects. Some non linear operators
* may include both types of objects; the ordering doesn't matter.
*
* \param[in] linear_algebra_tuple List of global matrices and/or vectors into which the operator is
* assembled. These objects are assumed to be already properly allocated.
*
*/
template<class LinearAlgebraTupleT>
void Assembly(const LinearAlgebraTupleT& linear_algebra_tuple);
/*!
* \brief Perform the actual assembling for each item of \a linear_algebra_tuple.
*
* \tparam LinearAlgebraTupleT A tuple that may include either \a GlobalMatrixAndCoefficient (for bilinear
* operators) or \a GlobalVectorAndCoefficient (for linear operators) objects. Some non linear operators
* may include both types of objects; the ordering doesn't matter.
*
* \param[in] linear_algebra_tuple List of global matrices and/or vectors into which the operator is
* assembled. These objects are assumed to be already properly allocated.
* \param[in] local_felt_space Local finite element space being assembled. Remind a local finite element
* space is the object linked to a geometric element that hold finite elements information.
* \param[in,out] local_operator Local variational operator in charge of the computation of the local
* linear algebra. It also holds the results of these computations, hence its presence here.
*
*/
template<class LinearAlgebraTupleT, class LocalVariationalOperatorT>
void InjectInGlobalLinearAlgebra(const LinearAlgebraTupleT& linear_algebra_tuple,
const LocalFEltSpace& local_felt_space,
LocalVariationalOperatorT& local_operator);
} //namespace Private
} // namespace HappyHeart
# include "FiniteElement/Operators/GlobalVariationalOperator/Private/Recursivity.hxx"
#endif // _HAPPY_HEART__FINITE_ELEMENT__OPERATORS__GLOBAL_VARIATIONAL_OPERATOR__PRIVATE__RECURSIVITY_HPP_
//
// Recursivity.hxx
// HappyHeart
//
// Created by Sebastien Gilles on 29/04/15.
// Copyright (c) 2015 Inria. All rights reserved.
//
#ifndef _HAPPY_HEART__FINITE_ELEMENT__OPERATORS__GLOBAL_VARIATIONAL_OPERATOR__PRIVATE__RECURSIVITY_HXX_
# define _HAPPY_HEART__FINITE_ELEMENT__OPERATORS__GLOBAL_VARIATIONAL_OPERATOR__PRIVATE__RECURSIVITY_HXX_
namespace HappyHeart
{
namespace Private
{
template<class LinearAlgebraTupleT>
void Assembly(const LinearAlgebraTupleT& linear_algebra_tuple)
{
static_assert(Utilities::IsSpecializationOf<std::tuple, LinearAlgebraTupleT>::value,
"Compilation error if LinearAlgebraTupleT is not a std::tuple.");
Impl::Recursivity<LinearAlgebraTupleT, 0, std::tuple_size<LinearAlgebraTupleT>::value>
::Assembly(linear_algebra_tuple);
}
template<class LinearAlgebraTupleT, class LocalVariationalOperatorT>
void InjectInGlobalLinearAlgebra(const LinearAlgebraTupleT& linear_algebra_tuple,
const LocalFEltSpace& local_felt_space,
LocalVariationalOperatorT& local_variational_operator)
{
Impl::Recursivity<LinearAlgebraTupleT, 0, std::tuple_size<LinearAlgebraTupleT>::value>
::InjectInGlobalLinearAlgebra(linear_algebra_tuple, local_felt_space, local_variational_operator);
}
} //namespace Private
} // namespace HappyHeart
#endif // _HAPPY_HEART__FINITE_ELEMENT__OPERATORS__GLOBAL_VARIATIONAL_OPERATOR__PRIVATE__RECURSIVITY_HXX_
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment