TGeometricElt.hxx 13.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
///
////// \file
///
///
/// Created by Sebastien Gilles <sebastien.gilles@inria.fr> on the Mon, 21 Jan 2013 14:21:56 +0100
/// Copyright (c) Inria. All rights reserved.
///
/// \ingroup GeometryGroup
/// \addtogroup GeometryGroup
/// \{
11

12 13
#ifndef MOREFEM_x_GEOMETRY_x_GEOMETRIC_ELT_x_ADVANCED_x_T_GEOMETRIC_ELT_HXX_
# define MOREFEM_x_GEOMETRY_x_GEOMETRIC_ELT_x_ADVANCED_x_T_GEOMETRIC_ELT_HXX_
14 15


16
namespace MoReFEM
17
{
18 19


20
    namespace Internal
21
    {
22 23 24 25


        namespace GeomEltNS
        {
26

27 28

/// Deactivate noreturn here: it would trigger false positives. )
29 30 31
PRAGMA_DIAGNOSTIC(push)
PRAGMA_DIAGNOSTIC(ignored "-Wmissing-noreturn")

32 33 34 35 36 37
            template<class TraitsRefGeomEltT>
            TGeometricElt<TraitsRefGeomEltT>::TGeometricElt(unsigned int mesh_unique_id)
            : GeometricElt(mesh_unique_id)
            {
                StaticAssertBuiltInConsistency();
            }
38 39


40 41
            template<class TraitsRefGeomEltT>
            TGeometricElt<TraitsRefGeomEltT>::TGeometricElt(unsigned int mesh_unique_id,
42
                                                            const Coords::vector_unique_ptr& mesh_coords_list,
43 44 45
                                                            unsigned int index,
                                                            std::vector<unsigned int>&& coords)
            : GeometricElt(mesh_unique_id, mesh_coords_list, index, std::move(coords))
46
            {
47
                StaticAssertBuiltInConsistency();
48
            }
49 50


51 52
            template<class TraitsRefGeomEltT>
            TGeometricElt<TraitsRefGeomEltT>::TGeometricElt(unsigned int mesh_unique_id,
53
                                                            const Coords::vector_unique_ptr& mesh_coords_list,
54 55 56 57 58
                                                            std::vector<unsigned int>&& coords)
            : GeometricElt(mesh_unique_id, mesh_coords_list, std::move(coords))
            {
                StaticAssertBuiltInConsistency();
            }
59 60


61 62
            template<class TraitsRefGeomEltT>
            TGeometricElt<TraitsRefGeomEltT>::TGeometricElt(unsigned int mesh_unique_id,
63
                                                            const Coords::vector_unique_ptr& mesh_coords_list,
64 65
                                                            std::istream& stream)
            : GeometricElt(mesh_unique_id)
66
            {
67
                StaticAssertBuiltInConsistency();
68

69
                std::vector<unsigned int> coords_list(TraitsRefGeomEltT::Ncoords);
70

71 72
                for (unsigned int i = 0u; i < TraitsRefGeomEltT::Ncoords; ++i)
                    stream >> coords_list[i];
73

74 75 76 77 78
                if (stream)
                {
                    // Modify geometric element only if failbit not set.
                    SetCoordsList(mesh_coords_list, std::move(coords_list));
                }
79
            }
80 81


82 83
            template<class TraitsRefGeomEltT>
            TGeometricElt<TraitsRefGeomEltT>::~TGeometricElt() = default;
84 85


86 87
            template<class TraitsRefGeomEltT>
            Advanced::GeometricEltEnum TGeometricElt<TraitsRefGeomEltT>::GetIdentifier() const
88
            {
89 90
                return TraitsRefGeomEltT::Identifier();
            }
91 92


93 94 95 96 97
            template<class TraitsRefGeomEltT>
            const std::string TGeometricElt<TraitsRefGeomEltT>::GetName() const
            {
                return TraitsRefGeomEltT::ClassName();
            }
98 99


100 101 102 103
            template<class TraitsRefGeomEltT>
            unsigned int TGeometricElt<TraitsRefGeomEltT>::Ncoords() const
            {
                return static_cast<unsigned int>(TraitsRefGeomEltT::Ncoords);
104
            }
105 106


107 108 109
            template<class TraitsRefGeomEltT>
            unsigned int TGeometricElt<TraitsRefGeomEltT>::Nvertex() const
            {
110
                return TraitsRefGeomEltT::topology::Nvertex;
111
            }
112 113


114 115 116
            template<class TraitsRefGeomEltT>
            unsigned int TGeometricElt<TraitsRefGeomEltT>::Nedge() const
            {
117
                return TraitsRefGeomEltT::topology::Nedge;
118
            }
119 120


121 122 123
            template<class TraitsRefGeomEltT>
            unsigned int TGeometricElt<TraitsRefGeomEltT>::Nface() const
            {
124
                return TraitsRefGeomEltT::topology::Nface;
125
            }
126 127


128 129 130
            template<class TraitsRefGeomEltT>
            unsigned int TGeometricElt<TraitsRefGeomEltT>::GetDimension() const
            {
131
                return TraitsRefGeomEltT::topology::dimension;
132
            }
133 134


135 136 137 138 139 140
            template<class TraitsRefGeomEltT>
            inline const std::string& TGeometricElt<TraitsRefGeomEltT>::GetEnsightName() const
            {
                static auto ret = Internal::MeshNS::FormatNS::Ensight::Dispatch::GetName<TraitsRefGeomEltT>(EnsightSupport());
                return ret;
            }
141 142


143 144 145 146 147
            template<class TraitsRefGeomEltT>
            inline GmfKwdCod TGeometricElt<TraitsRefGeomEltT>::GetMeditIdentifier() const
            {
                return Internal::MeshNS::FormatNS::Medit::Dispatch::GetIdentifier<TraitsRefGeomEltT>(MeditSupport());
            }
148 149


150 151 152 153 154 155 156 157 158 159 160 161 162
            template<class TraitsRefGeomEltT>
            inline void TGeometricElt<TraitsRefGeomEltT>::WriteEnsightFormat(std::ostream& stream, bool do_print_index) const
            {
                Internal::MeshNS::FormatNS::Ensight::Dispatch::WriteFormat
                <
                    TraitsRefGeomEltT,
                    TraitsRefGeomEltT::Ncoords
                >(EnsightSupport(),
                  stream,
                  do_print_index,
                  GetIndex(),
                  GetCoordsList());
            }
163

164

165 166 167 168 169 170 171
            template<class TraitsRefGeomEltT>
            void TGeometricElt<TraitsRefGeomEltT>
            ::WriteMeditFormat(const int mesh_index,
                               const std::unordered_map<unsigned int, int>& processor_wise_reindexing) const
            {
                auto label_ptr = GetMeshLabelPtr();
                int label_index = (label_ptr ? static_cast<int>(label_ptr->GetIndex()) : 0);
172

173
                const auto& coords_list = GetCoordsList();
174

175
                // Medit assumes indexes between 1 and Ncoord, whereas MoReFEM starts at 0.
176 177
                std::vector<int> coord_index_list;
                coord_index_list.reserve(coords_list.size());
178

179 180 181 182
                for (const auto& coord_ptr : coords_list)
                {
                    assert(!(!coord_ptr));
                    auto it = processor_wise_reindexing.find(coord_ptr->GetIndex());
183

184
                    assert(it != processor_wise_reindexing.cend() && "Otherwise processor_wise_reindexing is poorly built.");
185

186 187
                    coord_index_list.push_back(it->second);
                }
188

189 190 191 192 193 194 195 196 197 198
                Internal::MeshNS::FormatNS::Medit::Dispatch::WriteFormat
                <
                    TraitsRefGeomEltT,
                    TraitsRefGeomEltT::Ncoords
                >(MeditSupport(),
                  mesh_index,
                  GetMeditIdentifier(),
                  coord_index_list,
                  label_index);
            }
199 200


201
            template<class TraitsRefGeomEltT>
202
            void TGeometricElt<TraitsRefGeomEltT>::ReadMeditFormat(const Coords::vector_unique_ptr& mesh_coords_list,
203 204 205 206 207
                                                                   int libmesh_mesh_index,
                                                                   unsigned int Ncoord_in_mesh,
                                                                   int& label_index)
            {
                std::vector<unsigned int> coords(TraitsRefGeomEltT::Ncoords);
208

209 210 211 212 213 214 215 216 217
                Internal::MeshNS::FormatNS::Medit::Dispatch::ReadFormat
                <
                    TraitsRefGeomEltT,
                    TraitsRefGeomEltT::Ncoords
                >(MeditSupport(),
                  libmesh_mesh_index,
                  GetMeditIdentifier(),
                  coords,
                  label_index);
218

219 220 221 222
                // Check here the indexes of the coords are between 1 and Ncoord:
                for (auto coord_index : coords)
                {
                    if (coord_index == 0 || coord_index > Ncoord_in_mesh)
223
                        throw MoReFEM::ExceptionNS::Format::Medit::InvalidCoordIndex(TraitsRefGeomEltT::ClassName(),
224 225 226 227 228
                                                                                        coord_index,
                                                                                        Ncoord_in_mesh,
                                                                                        __FILE__,
                                                                                        __LINE__);
                }
229

230 231
                SetCoordsList(mesh_coords_list, std::move(coords));
            }
232 233 234



235 236
            template<class TraitsRefGeomEltT>
            inline double TGeometricElt<TraitsRefGeomEltT>::ShapeFunction(unsigned int i,
237
                                                                             const LocalCoords& local_coords) const
238 239 240
            {
                return TraitsRefGeomEltT::ShapeFunction(i, local_coords);
            }
241 242


243 244 245
            template<class TraitsRefGeomEltT>
            inline double TGeometricElt<TraitsRefGeomEltT>
            ::FirstDerivateShapeFunction(unsigned int i, unsigned int icoor,
246
                                         const LocalCoords& local_coords) const
247 248 249
            {
                return TraitsRefGeomEltT::FirstDerivateShapeFunction(i, icoor, local_coords);
            }
250 251


252 253 254 255 256
            template<class TraitsRefGeomEltT>
            inline double TGeometricElt<TraitsRefGeomEltT>
            ::SecondDerivateShapeFunction(unsigned int i,
                                          unsigned int icoor,
                                          unsigned int jcoor,
257
                                          const LocalCoords& local_coords) const
258 259 260
            {
                return TraitsRefGeomEltT::SecondDerivateShapeFunction(i, icoor, jcoor, local_coords);
            }
261

262 263 264 265 266

            template<class TraitsRefGeomEltT>
            void TGeometricElt<TraitsRefGeomEltT>::
            BuildVertexList(const GeometricElt* geom_elt_ptr,
                            Vertex::InterfaceMap& existing_list)
267
            {
268
                const auto& coords_list = GetCoordsList();
269

270
                using Topology = typename TraitsRefGeomEltT::topology;
271

272 273
                auto&& vertex_list =
                    Internal::InterfaceNS::Build<Vertex, Topology>::Perform(geom_elt_ptr, coords_list, existing_list);
274

275
                SetVertexList(std::move(vertex_list));
276
            }
277

278 279


280 281 282 283 284
            template<class TraitsRefGeomEltT>
            void TGeometricElt<TraitsRefGeomEltT>::
            BuildEdgeList(const GeometricElt* geom_elt_ptr,
                          Edge::InterfaceMap& existing_list)
            {
285
                using Topology = typename TraitsRefGeomEltT::topology;
286

287
                constexpr bool is_edge = (Topology::Nedge > 0u);
288

289 290 291 292
                auto&& oriented_edge_list =
                    Internal::InterfaceNS::BuildEdgeListHelper<Topology, is_edge>::Perform(geom_elt_ptr,
                                                                                          GetCoordsList(),
                                                                                          existing_list);
293

294 295
                SetOrientedEdgeList(std::move(oriented_edge_list));
            }
296 297


298 299 300 301 302
            template<class TraitsRefGeomEltT>
            void TGeometricElt<TraitsRefGeomEltT>::
            BuildFaceList(const GeometricElt* geom_elt_ptr,
                          Face::InterfaceMap& existing_list)
            {
303
                using Topology = typename TraitsRefGeomEltT::topology;
304

305
                constexpr bool is_face = (Topology::Nface > 0u);
306

307 308 309 310
                auto&& oriented_face_list =
                    Internal::InterfaceNS::BuildFaceListHelper<Topology, is_face>::Perform(geom_elt_ptr,
                                                                                          GetCoordsList(),
                                                                                          existing_list);
311

312 313
                SetOrientedFaceList(std::move(oriented_face_list));
            }
314 315


316 317 318 319 320 321
            template<class TraitsRefGeomEltT>
            void TGeometricElt<TraitsRefGeomEltT>::
            BuildVolumeList(const GeometricElt* geom_elt,
                            Volume::InterfaceMap& existing_list)
            {
                Volume::shared_ptr volume_ptr =
322
                (TraitsRefGeomEltT::topology::Nvolume > 0u ? std::make_shared<Volume>(shared_from_this()) : nullptr);
323
                SetVolume(volume_ptr);
324

325 326 327 328
                if (!(!volume_ptr))
                {
                    assert("One Volume shoudn't be entered twice in the list: it is proper to each GeometricElt."
                           && existing_list.find(volume_ptr) == existing_list.cend());
329

330 331
                    std::vector<const GeometricElt*> vector_raw;
                    vector_raw.push_back(geom_elt);
332

333 334
                    existing_list.insert({volume_ptr, vector_raw});
                }
335

336
            }
337 338


339 340 341
            template<class TraitsRefGeomEltT>
            void TGeometricElt<TraitsRefGeomEltT>::StaticAssertBuiltInConsistency()
            {
342
                static_assert(static_cast<unsigned int>(TraitsRefGeomEltT::Nderivate_component_) ==
343
                              static_cast<unsigned int>(TraitsRefGeomEltT::topology::dimension),
344 345
                              "Shape function should be consistent with geometric element!");
            }
346

347 348 349 350

// Reactivate the warning disabled at the beginning of this file.
PRAGMA_DIAGNOSTIC(pop)

351 352 353 354 355

        } // namespace GeomEltNS


    } // namespace Internal
356 357


358
} // namespace MoReFEM
359 360


361 362 363
/// @} // addtogroup GeometryGroup


364 365


366
#endif // MOREFEM_x_GEOMETRY_x_GEOMETRIC_ELT_x_ADVANCED_x_T_GEOMETRIC_ELT_HXX_