swh:1:snp:f521c49ab17ef7db6ec70b2430e1ed203f50383f
Raw File
Tip revision: 1f4191c02ec16ac1f7ac5516516cc0706954d06e authored by Wenqing Wang on 24 June 2021, 09:48:45 UTC
[Test/postLIE] added a 3D test for post LIE
Tip revision: 1f4191c
MeshComponentMap.h
/**
 * \author Norihiro Watanabe
 * \date   2013-04-16
 *
 * \file
 * \copyright
 * Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org)
 *            Distributed under a Modified BSD License.
 *              See accompanying file LICENSE.txt or
 *              http://www.opengeosys.org/project/license
 */

#pragma once

#include "ComponentGlobalIndexDict.h"
#include "MeshLib/MeshSubset.h"
#include "numlib_export.h"

namespace NumLib
{
/// Ordering of components in global matrix/vector.
enum class ComponentOrder
{
    BY_COMPONENT,  ///< Ordering data by component type
    BY_LOCATION    ///< Ordering data by spatial location
};

/// Multidirectional mapping between mesh entities and degrees of freedom.
class MeshComponentMap final
{
public:
    using Location = MeshLib::Location;

public:
    /// \param components   a vector of components
    /// \param order        type of ordering values in a vector
    MeshComponentMap(std::vector<MeshLib::MeshSubset> const& components,
                     ComponentOrder order);

    /// Creates a multi-component subset of the current mesh component map.
    /// The order (BY_LOCATION/BY_COMPONENT) of components is the same as of the
    /// current map.
    ///
    /// \attention For each component the same new_mesh_subset will be used.
    ///
    /// \param bulk_mesh_subsets components that should remain in the created
    /// subset, one for each global component.
    /// \param new_mesh_subset The constraining mesh subset with a mapping of
    /// node ids to the bulk mesh nodes.
    /// \param new_global_component_ids The components for which the
    /// bulk_mesh_subsets should be intersected with the new_mesh_subset.
    MeshComponentMap getSubset(
        std::vector<MeshLib::MeshSubset> const& bulk_mesh_subsets,
        MeshLib::MeshSubset const& new_mesh_subset,
        std::vector<int> const& new_global_component_ids) const;

    /// The number of dofs including the those located in the ghost nodes.
    std::size_t dofSizeWithGhosts() const { return _dict.size(); }

    /// Component ids at given location \c l.
    ///
    /// | Location | ComponentID |
    /// | -------- | ----------- |
    /// | l        | comp_id_1   |
    /// | l        |  ...        |
    /// | l        | comp_id_n   |
    std::vector<int> getComponentIDs(const Location& l) const;

    /// Global index of the given component id at given location \c l.
    ///
    /// | Location | ComponentID | GlobalIndex |
    /// | -------- | ----------- | ----------- |
    /// | l        | comp_id     | gi          |
    GlobalIndexType getGlobalIndex(Location const& l, int const comp_id) const;

    /// Global indices for all components at the given location \c l.
    ///
    /// If there is more than one component at the given location, the
    /// function returns a vector containing global indices for each component.
    ///
    /// | Location | ComponentID | GlobalIndex |
    /// | -------- | ----------- | ----------- |
    /// | l        | comp_id_1   | gi23        |
    /// | ...      |  ...        | ...         |
    /// | l        | comp_id_k   | gi45        |
    std::vector<GlobalIndexType> getGlobalIndices(const Location& l) const;

    /// Global indices for all components at all given locations \c ls ordered
    /// by location. The return list is sorted first by location.
    ///
    /// | Location | ComponentID | GlobalIndex |
    /// | -------- | ----------- | ----------- |
    /// | l_1      | comp_id_1   | gi23        |
    /// | ...      |  ...        | ...         |
    /// | l_1      | comp_id_k   | gi45        |
    /// | l_2      | comp_id_1   | gi46        |
    /// | ...      |  ...        | ...         |
    /// | l_2      | comp_id_m   | gi67        |
    /// | ...      |  ...        | ...         |
    /// | l_n      | comp_id_n   | gi78        |
    std::vector<GlobalIndexType> getGlobalIndicesByLocation(
        const std::vector<Location>& ls) const;

    /// Global indices for all components at all given locations \c ls ordered
    /// by component ids. The return list is sorted first by component ids.
    /// | Location | ComponentID | GlobalIndex |
    /// | -------- | ----------- | ----------- |
    /// | l_1      | comp_id_1   | gi23        |
    /// | ...      |  ...        | ...         |
    /// | l_k      | comp_id_1   | gi45        |
    /// | l_1      | comp_id_2   | gi46        |
    /// | ...      |  ...        | ...         |
    /// | l_m      | comp_id_2   | gi78        |
    /// | ...      |  ...        | ...         |
    /// | l_n      | comp_id_n   | gi89        |
    std::vector<GlobalIndexType> getGlobalIndicesByComponent(
        const std::vector<Location>& ls) const;

    /// Get the number of local unknowns excluding those associated
    /// with ghost nodes (for DDC with node-wise mesh partitioning).
    std::size_t dofSizeWithoutGhosts() const { return _num_local_dof; }

    /// Get ghost indices (for DDC).
    std::vector<GlobalIndexType> const& getGhostIndices() const
    {
        return _ghosts_indices;
    }

    /// Computes the index in a local (for DDC) vector for a given location and
    /// component.
    /// When domain decomposition is not used, it is equal to getGlobalIndex().
    /// The range is needed to compute the offset for non-ghost locations and
    /// also to map ghost locations.
    GlobalIndexType getLocalIndex(Location const& l, int const comp_id,
                                  std::size_t const range_begin,
                                  std::size_t const range_end) const;

    /// A value returned if no global index was found for the requested
    /// location/component. The value is implementation dependent.
    static NUMLIB_EXPORT GlobalIndexType const nop;

#ifndef NDEBUG
    const detail::ComponentGlobalIndexDict& getDictionary() const
    {
        return _dict;
    }

    friend std::ostream& operator<<(std::ostream& os, MeshComponentMap const& m)
    {
        os << "Dictionary size: " << m._dict.size() << "\n";
        for (auto l : m._dict)
            os << l << "\n";
        return os;
    }
#endif  // NDEBUG

private:
    /// Private constructor used by internally created mesh component maps.
    explicit MeshComponentMap(detail::ComponentGlobalIndexDict& dict)
        : _dict(dict)
    {
    }

    /// Looks up if a line is already stored in the dictionary.
    /// \attention The line for the location l and component id must exist,
    /// the behaviour is undefined otherwise.
    /// \return a copy of the line.
    detail::Line getLine(Location const& l, int const comp_id) const;

    void renumberByLocation(GlobalIndexType offset = 0);

    detail::ComponentGlobalIndexDict _dict;

    /// Number of local unknowns excluding those associated
    /// with ghost nodes (for domain decomposition).
    std::size_t _num_local_dof = 0;

#ifdef USE_PETSC
    /// Number of global unknowns. Used internally only.
    std::size_t _num_global_dof = 0;
#endif

    /// Global ID for ghost entries
    std::vector<GlobalIndexType> _ghosts_indices;

    /// \param components   a vector of components
    /// \param order        type of ordering values in a vector
    void createSerialMeshComponentMap(
        std::vector<MeshLib::MeshSubset> const& components,
        ComponentOrder order);

#ifdef USE_PETSC
    /// \param components   a vector of components
    /// \param order        type of ordering values in a vector
    void createParallelMeshComponentMap(
        std::vector<MeshLib::MeshSubset> const& components,
        ComponentOrder order);
#endif
};

}  // namespace NumLib
back to top