Commit 0c3ae125 authored by GILLES Sebastien's avatar GILLES Sebastien
Browse files

#734 Change the internal storage of local finite element space, to speed up...

#734 Change the internal storage of local finite element space, to speed up the method FEltSpace::GetLocalFEltSpace(const GeometricElt& geometric_elt).
parent 484e996c
......@@ -96,6 +96,9 @@ namespace HappyHeart
//! Friendship to the only class entitled to add finite elements to the local felt space.
friend class Private::CreateNodeListHelper;
//! Convenient storage: key is the index of the geometric element, value the actual pointer to the LocalFEltSpace.
using per_geom_elt_index = std::unordered_map<unsigned int,
private:
......
......@@ -89,8 +89,9 @@ namespace HappyHeart
{
const auto& local_felt_space_list = pair.second;
for (auto& local_felt_space_ptr : local_felt_space_list)
for (auto& local_felt_space_pair : local_felt_space_list)
{
auto& local_felt_space_ptr = local_felt_space_pair.second;
assert(!(!local_felt_space_ptr));
local_felt_space_ptr->InitLocal2Global(numbering_subset_list,
......@@ -152,8 +153,9 @@ namespace HappyHeart
{
const auto& local_felt_space_list = pair.second;
for (auto& local_felt_space_ptr : local_felt_space_list)
for (auto& local_felt_space_pair : local_felt_space_list)
{
auto& local_felt_space_ptr = local_felt_space_pair.second;
assert(!(!local_felt_space_ptr));
local_felt_space_ptr->ComputeLocal2Global(extended_unknown_list_for_numbering_subset,
......@@ -190,7 +192,9 @@ namespace HappyHeart
auto geometric_elt_range = mesh.GetSubsetGeometricEltList(*geometric_type_ptr);
LocalFEltSpace::vector_shared_ptr local_felt_space_list;
std::unordered_map<unsigned int, LocalFEltSpace::shared_ptr> local_felt_space_list;
local_felt_space_list.max_load_factor(Utilities::DefaultMaxLoadFactor());
assert(geometric_elt_range.second > geometric_elt_range.first);
const std::size_t Ngeometric_elt_in_range =
......@@ -208,7 +212,7 @@ namespace HappyHeart
if (domain.IsGeometricEltInside(geometric_elt))
{
auto&& ptr = new LocalFEltSpace(*ref_felt_space_ptr, geometric_elt_ptr);
local_felt_space_list.push_back(LocalFEltSpace::shared_ptr(ptr));
local_felt_space_list.insert({ geometric_elt.GetIndex(), LocalFEltSpace::shared_ptr(ptr)});
}
}
......@@ -217,7 +221,7 @@ namespace HappyHeart
if (local_felt_space_list.empty()) // might happen if for instance RefGeomElt not considered in the domain.
continue;
local_felt_space_list.shrink_to_fit();
// local_felt_space_list.shrink_to_fit();
felt_list_per_type.push_back(std::make_pair(std::move(ref_felt_space_ptr), local_felt_space_list));
}
......@@ -265,8 +269,9 @@ namespace HappyHeart
{
const auto& local_felt_space_list = pair.second;
for (const auto& local_felt_space_ptr : local_felt_space_list)
for (const auto& local_felt_space_pair : local_felt_space_list)
{
auto& local_felt_space_ptr = local_felt_space_pair.second;
assert(!(!local_felt_space_ptr));
local_felt_space_ptr->ClearTemporaryData();
}
......@@ -305,7 +310,7 @@ namespace HappyHeart
} // namespace anonymous
const LocalFEltSpace::vector_shared_ptr& FEltSpace
const std::unordered_map<unsigned int, LocalFEltSpace::shared_ptr>& FEltSpace
::GetLocalFEltSpaceList(const RefFEltNS::Private::RefFEltSpace& ref_felt_space) const
{
auto it = IteratorLocalFEltSpacePair(*this, ref_felt_space.GetRefGeomElt());
......@@ -400,18 +405,14 @@ namespace HappyHeart
const auto end = local_felt_list.cend();
// \todo #60 It would be nice here to try a logarithmic search if we can ensure local felt spaces are ordered the same way as geometric elements.
const auto it = std::find_if(local_felt_list.cbegin(),
end,
[&geometric_elt](const auto& local_felt_space_ptr)
{
return local_felt_space_ptr->GetGeometricElt() == geometric_elt;
});
const auto it = local_felt_list.find(geometric_elt.GetIndex());
assert(it != end);
assert(!(!*it));
return *(*it);
const auto& local_felt_space_ptr = it->second;
assert(!(!local_felt_space_ptr));
return *local_felt_space_ptr;
}
......
......@@ -260,7 +260,7 @@ namespace HappyHeart
/*!
* \brief Get the list of local finite element spaces sort for a given RefFEltSpace.
*/
const LocalFEltSpace::vector_shared_ptr&
const std::unordered_map<unsigned int, LocalFEltSpace::shared_ptr>&
GetLocalFEltSpaceList(const RefFEltNS::Private::RefFEltSpace& ref_felt_space) const;
/*!
......@@ -272,7 +272,7 @@ namespace HappyHeart
/*!
* \brief Get the list of local finite element spaces sort for a given \a ref_geom_elt.
*/
const LocalFEltSpace::vector_shared_ptr&
const std::unordered_map<unsigned int, LocalFEltSpace::shared_ptr>&
GetLocalFEltSpaceList(const RefGeomElt& ref_geom_elt) const;
/*!
......
......@@ -98,7 +98,7 @@ namespace HappyHeart
}
inline const LocalFEltSpace::vector_shared_ptr&
inline const std::unordered_map<unsigned int, LocalFEltSpace::shared_ptr>&
FEltSpace::GetLocalFEltSpaceList(const RefGeomElt& ref_geom_elt) const
{
const auto& ref_local_felt_space = GetRefFEltSpace(ref_geom_elt);
......
......@@ -243,8 +243,9 @@ namespace HappyHeart
const auto& local_felt_space_list = pair.second;
for (const auto& local_felt_space_ptr : local_felt_space_list)
for (const auto& local_felt_space_pair : local_felt_space_list)
{
const auto& local_felt_space_ptr = local_felt_space_pair.second;
assert(!(!local_felt_space_ptr));
auto& local_felt_space = *local_felt_space_ptr;
......@@ -923,8 +924,9 @@ namespace HappyHeart
{
const auto& local_felt_space_list = pair.second;
for (const auto& local_felt_space_ptr : local_felt_space_list)
for (const auto& local_felt_space_pair : local_felt_space_list)
{
const auto& local_felt_space_ptr = local_felt_space_pair.second;
assert((!(!local_felt_space_ptr)));
const auto& node_bearer_list = local_felt_space_ptr->GetNodeBearerList();
......
......@@ -96,8 +96,9 @@ namespace HappyHeart
{
const auto& local_felt_space_list = pair.second;
for (const auto& local_felt_space_ptr : local_felt_space_list)
for (const auto& local_felt_space_pair : local_felt_space_list)
{
const auto& local_felt_space_ptr = local_felt_space_pair.second;
assert(!(!local_felt_space_ptr));
const NodeBearer::vector_shared_ptr& node_bearers_in_current_finite_element =
local_felt_space_ptr->GetNodeBearerList();
......
......@@ -141,16 +141,18 @@ namespace HappyHeart
auto& ref_felt_space_ptr = pair.first;
const auto& complete_local_felt_space_list = pair.second;
LocalFEltSpace::vector_shared_ptr local_felt_space_list;
std::unordered_map<unsigned int, LocalFEltSpace::shared_ptr> local_felt_space_list;
local_felt_space_list.max_load_factor(Utilities::DefaultMaxLoadFactor());
for (const auto& local_felt_space_ptr : complete_local_felt_space_list)
for (const auto& local_felt_space_pair : complete_local_felt_space_list)
{
const auto& local_felt_space_ptr = local_felt_space_pair.second;
assert(!(!local_felt_space_ptr));
const auto& local_felt_space = *local_felt_space_ptr;
if (IsLocalFEltSpaceInDomain(local_felt_space, domain))
local_felt_space_list.push_back(local_felt_space_ptr);
local_felt_space_list.insert({local_felt_space.GetGeometricElt().GetIndex(), local_felt_space_ptr});
}
if (!local_felt_space_list.empty())
......
......@@ -24,8 +24,9 @@
namespace HappyHeart
{
using LocalFEltSpacePerRefFEltSpace =
std::vector<std::pair<RefFEltNS::Private::RefFEltSpace::const_unique_ptr, LocalFEltSpace::vector_shared_ptr>>;
std::vector<std::pair<RefFEltNS::Private::RefFEltSpace::const_unique_ptr, std::unordered_map<unsigned int, LocalFEltSpace::shared_ptr>>>;
// ============================
......
......@@ -136,10 +136,12 @@ namespace HappyHeart
const auto& ref_felt_space_ptr = pair.first;
const auto& local_felt_space_list = pair.second;
LocalFEltSpace::vector_shared_ptr buf;
std::unordered_map<unsigned int, LocalFEltSpace::shared_ptr> buf;
buf.max_load_factor(Utilities::DefaultMaxLoadFactor());
for (const auto& local_felt_space_ptr : local_felt_space_list)
for (const auto& local_felt_space_pair : local_felt_space_list)
{
const auto& local_felt_space_ptr = local_felt_space_pair.second;
assert(!(!local_felt_space_ptr));
const auto& local_felt_space = *local_felt_space_ptr;
......@@ -148,7 +150,7 @@ namespace HappyHeart
attribute_processor_helper.ProcessorForCurrentLocalFEltSpace(local_felt_space);
if (chosen_processor_for_local_felt_space == mpi_rank)
buf.push_back(local_felt_space_ptr);
buf.insert({ local_felt_space.GetGeometricElt().GetIndex(), local_felt_space_ptr });
// IF NOT BUT IF THERE ARE SOME NODE BEARERS DOF SHOULD BE ADDED TO THE DOF LIST OF THE
// FINITE ELEMENT SPACE (WHERE IT COULD IN FACT BE GHOST OR NOT!)
......@@ -183,8 +185,10 @@ namespace HappyHeart
{
const auto& local_felt_space_list = pair.second;
for (const auto& local_felt_space_ptr : local_felt_space_list)
for (const auto& local_felt_space_pair : local_felt_space_list)
{
const auto& local_felt_space_ptr = local_felt_space_pair.second;
assert(!(!local_felt_space_ptr));
const auto& node_bearer_list_in_geometric_element = local_felt_space_ptr->GetNodeBearerList();
......@@ -218,8 +222,9 @@ namespace HappyHeart
{
const auto& local_felt_space_list = pair.second;
for (const auto& local_felt_space_ptr : local_felt_space_list)
for (const auto& local_felt_space_pair : local_felt_space_list)
{
const auto& local_felt_space_ptr = local_felt_space_pair.second;
assert(!(!local_felt_space_ptr));
processor_wise_geo_element.push_back(local_felt_space_ptr->GetGeometricEltPtr());
}
......
......@@ -443,8 +443,9 @@ namespace HappyHeart
const auto& ref_node_list =
ref_felt_space_list_ptr->GetRefFElt(extended_unknown).GetBasicRefFElt().GetLocalNodeList();
for (const auto& local_felt_space_ptr : local_felt_space_list)
for (const auto& local_felt_space_pair : local_felt_space_list)
{
const auto& local_felt_space_ptr = local_felt_space_pair.second;
assert(!(!local_felt_space_ptr));
auto& local_felt_space = *local_felt_space_ptr;
......
......@@ -181,11 +181,11 @@ namespace HappyHeart
const auto& local_projection_matrix = GetLocalOperator(ref_geom_elt).GetProjectionMatrix();
ConformInterpolatorNS::Private::ComputePatternFromRefGeomElt(ref_felt_space,
pair.second,
local_projection_matrix,
interpolation_data,
map_pattern,
map_values);
pair.second,
local_projection_matrix,
interpolation_data,
map_pattern,
map_values);
}
const auto god_of_dof_ptr = target_felt_space.GetGodOfDofPtr();
......
......@@ -116,7 +116,7 @@ namespace HappyHeart
void ComputePatternFromRefGeomElt(const RefFEltNS::Private::RefFEltSpace& ref_felt_space,
const LocalFEltSpace::vector_shared_ptr& source_local_felt_space_list,
const std::unordered_map<unsigned int, LocalFEltSpace::shared_ptr>& source_local_felt_space_list,
const LocalMatrix& local_projection_matrix,
const Private::InterpolationData& interpolation_data,
std::map<std::size_t, std::vector<PetscInt>>& map_pattern,
......@@ -143,31 +143,24 @@ namespace HappyHeart
const auto god_of_dof_ptr = target_felt_space.GetGodOfDofPtr();
const auto Nglobal_row = god_of_dof_ptr->NprocessorWiseDof(target_data.GetNumberingSubset());
const auto begin_source_local_felt_space_list = source_local_felt_space_list.cbegin();
const auto end_source_local_felt_space_list = source_local_felt_space_list.cend();
for (const auto& target_local_felt_space_ptr : target_local_felt_space_list)
for (const auto& target_local_felt_space_pair : target_local_felt_space_list)
{
const auto& target_local_felt_space_ptr = target_local_felt_space_pair.second;
assert(!(!target_local_felt_space_ptr));
const auto& target_local_felt_space = *target_local_felt_space_ptr;
const auto& geometric_elt = target_local_felt_space.GetGeometricElt();
// Look if local finite element space is present in source local felt space.
auto it_source_local_felt_space_list
= std::find_if(begin_source_local_felt_space_list,
end_source_local_felt_space_list,
[&geometric_elt](const auto& local_felt_space_ptr)
{
assert(!(!local_felt_space_ptr));
return local_felt_space_ptr->GetGeometricElt() == geometric_elt;
});
// If none foundm skip it: these rows will be filled with zeros.
const auto it_source_local_felt_space_list = source_local_felt_space_list.find(geometric_elt.GetIndex());
// If none found skip it: these rows will be filled with zeros.
if (it_source_local_felt_space_list == end_source_local_felt_space_list)
continue;
const auto& source_local_felt_space_ptr = *it_source_local_felt_space_list;
const auto& source_local_felt_space_ptr = it_source_local_felt_space_list->second;
assert(!(!source_local_felt_space_ptr));
const auto& source_local_felt_space = *source_local_felt_space_ptr;
assert(source_local_felt_space.GetGeometricElt() == geometric_elt);
......
......@@ -80,7 +80,7 @@ namespace HappyHeart
* \brief Free function called by LagrangianInterpolator::ComputePattern().
*/
void ComputePatternFromRefGeomElt(const RefFEltNS::Private::RefFEltSpace& ref_felt_space,
const LocalFEltSpace::vector_shared_ptr& source_local_felt_space_list,
const std::unordered_map<unsigned int, LocalFEltSpace::shared_ptr>& source_local_felt_space_list,
const LocalMatrix& local_projection_matrix,
const InterpolationData& interpolation_data,
std::map<std::size_t, std::vector<PetscInt>>& map_pattern,
......
......@@ -177,8 +177,9 @@ namespace HappyHeart
const auto& local_felt_space_list = pair.second;
for (const auto& local_felt_space_ptr : local_felt_space_list)
for (const auto& local_felt_space_pair : local_felt_space_list)
{
const auto& local_felt_space_ptr = local_felt_space_pair.second;
assert(!(!local_felt_space_ptr));
auto& local_felt_space = *local_felt_space_ptr;
......
Supports Markdown
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