Commit fa84b94e authored by GILLES Sebastien's avatar GILLES Sebastien
Browse files

#1526 Add a new function to compute the list of \a GeometricElt concerned by a boundary condition.

parent a2b4edf0
......@@ -1185,6 +1185,9 @@
BE8E6967248F77CC000FEFBA /* libModel.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BEA5FA82248F73B50032F3DB /* libModel.a */; };
BE8E6968248F77DF000FEFBA /* libModel.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BEA5FA82248F73B50032F3DB /* libModel.a */; };
BE8E6969248F77E5000FEFBA /* libModel.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BEA5FA82248F73B50032F3DB /* libModel.a */; };
BE8E696D249118AF000FEFBA /* ComputeGeometricEltList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE8E696A249118AF000FEFBA /* ComputeGeometricEltList.cpp */; };
BE8E696E249118AF000FEFBA /* ComputeGeometricEltList.hxx in Headers */ = {isa = PBXBuildFile; fileRef = BE8E696B249118AF000FEFBA /* ComputeGeometricEltList.hxx */; };
BE8E696F249118AF000FEFBA /* ComputeGeometricEltList.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BE8E696C249118AF000FEFBA /* ComputeGeometricEltList.hpp */; };
BE8F0E671A81260600D81C9F /* ___FILEBASENAME___.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BE8F0E631A81260600D81C9F /* ___FILEBASENAME___.hpp */; };
BE8F0E681A81260600D81C9F /* ___FILEBASENAME___.hxx in Headers */ = {isa = PBXBuildFile; fileRef = BE8F0E641A81260600D81C9F /* ___FILEBASENAME___.hxx */; };
BE90DECF1A24903700CCAFDE /* Enum.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BE5BC2F516C0133300232749 /* Enum.hpp */; };
......@@ -4211,6 +4214,9 @@
BE8E21CF207FA60000E24E6D /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
BE8E697024916B75000FEFBA /* unused-local-typedef.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = "unused-local-typedef.hpp"; sourceTree = "<group>"; };
BE8E697124916C2F000FEFBA /* reorder.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = reorder.hpp; sourceTree = "<group>"; };
BE8E696A249118AF000FEFBA /* ComputeGeometricEltList.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ComputeGeometricEltList.cpp; path = Internal/ComputeGeometricEltList.cpp; sourceTree = "<group>"; };
BE8E696B249118AF000FEFBA /* ComputeGeometricEltList.hxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = ComputeGeometricEltList.hxx; path = Internal/ComputeGeometricEltList.hxx; sourceTree = "<group>"; };
BE8E696C249118AF000FEFBA /* ComputeGeometricEltList.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = ComputeGeometricEltList.hpp; path = Internal/ComputeGeometricEltList.hpp; sourceTree = "<group>"; };
BE8F0E391A8110EE00D81C9F /* ___FILEBASENAME___.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = "___FILEBASENAME___.cpp"; sourceTree = "<group>"; };
BE8F0E3A1A8110EE00D81C9F /* ___FILEBASENAME___.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = "___FILEBASENAME___.hpp"; sourceTree = "<group>"; };
BE8F0E3B1A8110EE00D81C9F /* ___FILEBASENAME___.hxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = "___FILEBASENAME___.hxx"; sourceTree = "<group>"; };
......@@ -7755,6 +7761,9 @@
BE2ED6B91CB3E15600D00CBF /* DofStorage.cpp */,
BE2ED6BA1CB3E15600D00CBF /* DofStorage.hpp */,
BE2ED6BB1CB3E15600D00CBF /* DofStorage.hxx */,
BE8E696A249118AF000FEFBA /* ComputeGeometricEltList.cpp */,
BE8E696C249118AF000FEFBA /* ComputeGeometricEltList.hpp */,
BE8E696B249118AF000FEFBA /* ComputeGeometricEltList.hxx */,
BE510D711CB3D44900E953FE /* Component */,
);
name = Internal;
......@@ -11458,9 +11467,11 @@
BEDAC3C91AD7FBB500AA2156 /* NdofHolder.hxx in Headers */,
BE510D861CB3D44900E953FE /* Comp12.hpp in Headers */,
BE90E0741A2491AE00CCAFDE /* DofComputations.hxx in Headers */,
BE8E696E249118AF000FEFBA /* ComputeGeometricEltList.hxx in Headers */,
BE3221911B4686C100F27D6C /* FElt.hxx in Headers */,
BE4054051AC196480024D5F9 /* FEltSpace.hxx in Headers */,
BE2B66501A2778C700E80864 /* BasicRefFEltFactory.hpp in Headers */,
BE8E696F249118AF000FEFBA /* ComputeGeometricEltList.hpp in Headers */,
BE6341F1236A363B00028688 /* EnumInvertedElements.hpp in Headers */,
BE90E13A1A2491AE00CCAFDE /* DirichletBoundaryCondition.hxx in Headers */,
BE510D841CB3D44900E953FE /* Comp1.hpp in Headers */,
......@@ -12974,6 +12985,7 @@
BE90E0691A2491AE00CCAFDE /* FEltSpaceStorage.cpp in Sources */,
BEAB45AD24727EAB00B8C6F2 /* TwoStepsParallelism.cpp in Sources */,
BE4053FD1AC193FF0024D5F9 /* BreakCircularDependancy.cpp in Sources */,
BE8E696D249118AF000FEFBA /* ComputeGeometricEltList.cpp in Sources */,
BEB7B1031BB4168F005E5D18 /* DirichletBoundaryConditionManager.cpp in Sources */,
BE2B663B1A2778C700E80864 /* HexahedronQ2c.cpp in Sources */,
BE3E664D1ACEB94E00A3F7E2 /* Connectivity.cpp in Sources */,
......@@ -352,8 +352,6 @@ namespace MoReFEM
# endif // NDEBUG
/*!
* \brief Two internal possible methods methods to reduce to processor-wise.
*
......@@ -382,6 +380,7 @@ namespace MoReFEM
};
///@} // \addtogroup
......
//! \file
//
//
// ComputeGeometricEltList.cpp
// MoReFEM
//
// Created by sebastien on 10/06/2020.
//Copyright © 2020 Inria. All rights reserved.
//
#include "Geometry/Mesh/Mesh.hpp"
#include "Geometry/Domain/Domain.hpp"
#include "FiniteElement/BoundaryConditions/DirichletBoundaryCondition.hpp"
#include "FiniteElement/BoundaryConditions/Internal/ComputeGeometricEltList.hpp"
namespace MoReFEM::Internal::BoundaryConditionNS
{
GeometricElt::vector_shared_ptr ComputeGeometricEltList(const Mesh& mesh,
const DirichletBoundaryCondition& boundary_condition)
{
const auto& boundary_condition_domain = boundary_condition.GetDomain();
using iterator_geometric_element = Mesh::iterator_geometric_element;
iterator_geometric_element begin, end;
GeometricElt::vector_shared_ptr ret;
// We know that mathematically dimension lesser than dimension - 1 may not be properly defined, but it's
// still useful in some contexts, providing model writer knows what he's doing. See #1262 discussion
// for more details.
for (auto dimension = mesh.GetDimension() - 1u; dimension < 3u; --dimension)
{
const auto& bag_of_boundary_domain = mesh.BagOfEltType(dimension);
for (const auto& geometric_elt_type_ptr : bag_of_boundary_domain)
{
const auto& geom_elt_type = *geometric_elt_type_ptr;
if (!boundary_condition_domain.DoRefGeomEltMatchCriteria(geom_elt_type))
continue;
std::tie(begin, end) = mesh.GetSubsetGeometricEltList(geom_elt_type);
for (auto it = begin; it != end; ++it)
{
const auto& geometric_elt_ptr = *it;
assert(!(!geometric_elt_ptr));
const auto& geom_elt = *geometric_elt_ptr;
assert(geom_elt.GetIdentifier() == geom_elt_type.GetIdentifier()
&& "If not, GetSubsetGeometricEltList() above is buggy!");
if (!boundary_condition_domain.IsGeometricEltInside(geom_elt))
continue;
ret.push_back(geometric_elt_ptr);
}
}
}
return ret;
}
} // namespace MoReFEM::Internal::BoundaryConditionNS
//! \file
//
//
// ComputeGeometricEltList.hpp
// MoReFEM
//
// Created by sebastien on 10/06/2020.
//Copyright © 2020 Inria. All rights reserved.
//
#ifndef MOREFEM_x_FINITE_ELEMENT_x_BOUNDARY_CONDITIONS_x_INTERNAL_x_COMPUTE_GEOMETRIC_ELT_LIST_HPP_
# define MOREFEM_x_FINITE_ELEMENT_x_BOUNDARY_CONDITIONS_x_INTERNAL_x_COMPUTE_GEOMETRIC_ELT_LIST_HPP_
# include "Geometry/GeometricElt/GeometricElt.hpp"
namespace MoReFEM
{
// ============================
//! \cond IGNORE_BLOCK_IN_DOXYGEN
// Forward declarations.
// ============================
class Mesh;
class DirichletBoundaryCondition;
// ============================
// End of forward declarations.
//! \endcond IGNORE_BLOCK_IN_DOXYGEN
// ============================
namespace Internal::BoundaryConditionNS
{
/*!
* \brief Define all \a GeometricElt involved within the given \a boundary_condition.
*
* \param[in] mesh \a Mesh for which the involved \a GeometricElt are sought.
* \param[in] boundary_condition The \a DirichletBoundaryCondition which related \a GeometricElt we seek.
*
* \return List of all the relevant \a GeometricElt.
*
*/
GeometricElt::vector_shared_ptr ComputeGeometricEltList(const Mesh& mesh,
const DirichletBoundaryCondition& boundary_condition);
} // namespace Internal::BoundaryConditionNS
} // namespace MoReFEM
# include "FiniteElement/BoundaryConditions/Internal/ComputeGeometricEltList.hxx"
#endif // MOREFEM_x_FINITE_ELEMENT_x_BOUNDARY_CONDITIONS_x_INTERNAL_x_COMPUTE_GEOMETRIC_ELT_LIST_HPP_
//! \file
//
//
// ComputeGeometricEltList.hxx
// MoReFEM
//
// Created by sebastien on 10/06/2020.
//Copyright © 2020 Inria. All rights reserved.
//
#ifndef MOREFEM_x_FINITE_ELEMENT_x_BOUNDARY_CONDITIONS_x_INTERNAL_x_COMPUTE_GEOMETRIC_ELT_LIST_HXX_
# define MOREFEM_x_FINITE_ELEMENT_x_BOUNDARY_CONDITIONS_x_INTERNAL_x_COMPUTE_GEOMETRIC_ELT_LIST_HXX_
namespace MoReFEM::Internal::BoundaryConditionNS
{
} // namespace MoReFEM::Internal::BoundaryConditionNS
#endif // MOREFEM_x_FINITE_ELEMENT_x_BOUNDARY_CONDITIONS_x_INTERNAL_x_COMPUTE_GEOMETRIC_ELT_LIST_HXX_
......@@ -10,9 +10,12 @@
target_sources(${MOREFEM_FELT}
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/ComputeGeometricEltList.cpp"
"${CMAKE_CURRENT_LIST_DIR}/DofStorage.cpp"
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/ComputeGeometricEltList.hpp"
"${CMAKE_CURRENT_LIST_DIR}/ComputeGeometricEltList.hxx"
"${CMAKE_CURRENT_LIST_DIR}/DofStorage.hpp"
"${CMAKE_CURRENT_LIST_DIR}/DofStorage.hxx"
)
......
......@@ -22,6 +22,7 @@
#include "FiniteElement/FiniteElementSpace/Internal/CreateNodeListHelper.hpp"
#include "FiniteElement/BoundaryConditions/DirichletBoundaryCondition.hpp"
#include "FiniteElement/BoundaryConditions/Internal/ComputeGeometricEltList.hpp"
namespace MoReFEM
......@@ -155,63 +156,38 @@ namespace MoReFEM
::ComputeNodeBearerListOnBoundary(const Mesh& mesh,
const DirichletBoundaryCondition& boundary_condition) const
{
const auto& boundary_condition_domain = boundary_condition.GetDomain();
NodeBearer::vector_shared_ptr ret;
NodeBearer::vector_shared_ptr node_bearer_on_bc;
const auto geom_elt_list_for_bc =
Internal::BoundaryConditionNS::ComputeGeometricEltList(mesh,
boundary_condition);
using iterator_geometric_element = Mesh::iterator_geometric_element;
iterator_geometric_element begin, end;
// We know that mathematically dimension lesser than dimension - 1 may not be properly defined, but it's
// still useful in some contexts, providing model writer knows what he's doing. See #1262 discussion
// for more details.
for (auto dimension = mesh.GetDimension() - 1u; dimension < 3u; --dimension)
for (const auto& geom_elt_ptr : geom_elt_list_for_bc)
{
const auto& bag_of_boundary_domain = mesh.BagOfEltType(dimension);
for (const auto& geometric_elt_type_ptr : bag_of_boundary_domain)
{
const auto& geom_elt_type = *geometric_elt_type_ptr;
if (!boundary_condition_domain.DoRefGeomEltMatchCriteria(geom_elt_type))
continue;
std::tie(begin, end) = mesh.GetSubsetGeometricEltList(geom_elt_type);
assert(!(!geom_elt_ptr));
const auto& geom_elt = *geom_elt_ptr;
for (auto it = begin; it != end; ++it)
{
const auto& geometric_elt_ptr = *it;
assert(!(!geometric_elt_ptr));
const auto& geom_elt = *geometric_elt_ptr;
assert(geom_elt.GetIdentifier() == geom_elt_type.GetIdentifier()
&& "If not, GetSubsetGeometricEltList() above is buggy!");
AddNodeBearerOnBoundaryCondition(geom_elt.GetVertexList(),
vertex_node_bearer_list_,
ret);
if (!boundary_condition_domain.IsGeometricEltInside(geom_elt))
continue;
AddNodeBearerOnBoundaryCondition(geom_elt.GetVertexList(),
vertex_node_bearer_list_,
node_bearer_on_bc);
if (!edge_node_bearer_list_.empty())
{
AddNodeBearerOnBoundaryCondition(geom_elt.GetOrientedEdgeList(),
edge_node_bearer_list_,
node_bearer_on_bc);
}
if (!edge_node_bearer_list_.empty())
{
AddNodeBearerOnBoundaryCondition(geom_elt.GetOrientedEdgeList(),
edge_node_bearer_list_,
ret);
}
if (!face_node_bearer_list_.empty())
{
AddNodeBearerOnBoundaryCondition(geom_elt.GetOrientedFaceList(),
face_node_bearer_list_,
node_bearer_on_bc);
}
}
if (!face_node_bearer_list_.empty())
{
AddNodeBearerOnBoundaryCondition(geom_elt.GetOrientedFaceList(),
face_node_bearer_list_,
ret);
}
}
Utilities::EliminateDuplicate(node_bearer_on_bc);
return node_bearer_on_bc;
Utilities::EliminateDuplicate(ret);
return ret;
}
......
......@@ -660,7 +660,6 @@ namespace MoReFEM
/*!
* \brief For all processor-wise \a Coords, determine which is the lowest rank in which they appear (not counting ghosts).
*
* \internal This is an internal method that is meant to be called by SetReducedCoordsList() only.
*
* The point is to be able to count without duplicating the number of \a Coords inside a given \a Domain.
*
......@@ -668,6 +667,8 @@ namespace MoReFEM
* \param[in] Nprogram_wise_coords Number of program-wise coords. This is required for internal Mpi computations,
* \param[in,out] a_processor_wise_coords_list The processor-wise list of \a Coords. The list itself is not modified, but the point
* of the method is to set properly the internal field \a is_lowest_processor_, hence the 'out' status.
*
* \internal This is an internal method that is meant to be called by SetReducedCoordsList() only.
*/
void SetIsLowestProcessor(const Wrappers::Mpi& mpi,
unsigned int Nprogram_wise_coords,
......
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