https://gitlab.opengeosys.org/ogs/ogs.git
Raw File
Tip revision: 14334932eb85e75b88418f6cee3e6b753916ecf9 authored by Lars Bilke on 28 March 2024, 08:16:57 UTC
OpenGeoSys 6.5.1.
Tip revision: 1433493
ElementCoordinatesMappingLocal.cpp
/**
 * \file
 * \copyright
 * Copyright (c) 2012-2024, OpenGeoSys Community (http://www.opengeosys.org)
 *            Distributed under a Modified BSD License.
 *              See accompanying file LICENSE.txt or
 *              http://www.opengeosys.org/project/license
 */

#include "ElementCoordinatesMappingLocal.h"

#include <cassert>
#include <limits>

#include "GeoLib/AnalyticalGeometry.h"
#include "MathLib/MathTools.h"
#include "MathLib/Point3d.h"
#include "MeshLib/Elements/Element.h"
#include "MeshLib/Node.h"

namespace detail
{
/// rotate points to local coordinates
void rotateToLocal(const MeshLib::RotationMatrix& matR2local,
                   std::vector<MathLib::Point3d>& points)
{
    std::transform(points.begin(), points.end(), points.begin(),
                   [&matR2local](auto const& pnt) { return matR2local * pnt; });
}

/// get a rotation matrix to the global coordinates
/// it computes R in x=R*x' where x is original coordinates and x' is local
/// coordinates
MeshLib::RotationMatrix getRotationMatrixToGlobal(
    const unsigned element_dimension,
    const unsigned global_dim,
    const std::vector<MathLib::Point3d>& points)
{
    Eigen::Matrix3d matR;
    // compute R in x=R*x' where x are original coordinates and x' are local
    // coordinates
    if (element_dimension == 1)
    {
        Eigen::Vector3d const xx =
            (points[1].asEigenVector3d() - points[0].asEigenVector3d())
                .normalized();
        if (global_dim == 2)
        {
            matR = GeoLib::compute2DRotationMatrixToX(xx);
        }
        else
        {
            matR = GeoLib::compute3DRotationMatrixToX(xx);
        }
        matR.transposeInPlace();
    }
    else if (global_dim == 3 && element_dimension == 2)
    {
        // get plane normal
        auto const [plane_normal, d] = GeoLib::getNewellPlane(points);
        // compute a rotation matrix to XY
        matR = GeoLib::computeRotationMatrixToXY(plane_normal);
        // set a transposed matrix
        matR.transposeInPlace();
    }
    return matR;
}
}  // namespace detail

namespace MeshLib
{
ElementCoordinatesMappingLocal::ElementCoordinatesMappingLocal(
    const Element& e, const unsigned global_dim)
    : _global_dim(global_dim), _matR2global(Eigen::Matrix3d::Identity())
{
    unsigned const space_dim = std::max(e.space_dimension_, _global_dim);
    assert(e.getDimension() <= space_dim);
    _points.reserve(e.getNumberOfNodes());
    for (unsigned i = 0; i < e.getNumberOfNodes(); i++)
    {
        _points.emplace_back(*(e.getNode(i)));
    }

    auto const element_dim = e.getDimension();

    if (element_dim != space_dim)
    {
        _matR2global =
            detail::getRotationMatrixToGlobal(element_dim, space_dim, _points);
        detail::rotateToLocal(_matR2global.transpose(), _points);
    }
}

}  // namespace MeshLib
back to top