Newer
Older
/**
* \file AddLayerToMesh.cpp
Karsten Rink
committed
* \date 2016-01-18
* \brief Implementation of AddLayerToMesh class.
*
* \copyright
* Copyright (c) 2012-2016, 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 "AddLayerToMesh.h"
#include <vector>
#include <map>
#include <memory>
#include "logog/include/logog.hpp"
#include "MeshLib/Mesh.h"
#include "MeshLib/Node.h"
#include "MeshLib/Elements/Elements.h"
#include "MeshLib/MeshSurfaceExtraction.h"
Karsten Rink
committed
#include "MeshLib/MeshEditing/DuplicateMeshComponents.h"
namespace MeshLib
{
Karsten Rink
committed
MeshLib::Element* extrudeElement(std::vector<MeshLib::Node*> const& subsfc_nodes,
MeshLib::Element const& sfc_elem,
std::map<std::size_t, std::size_t> const& subsfc_sfc_id_map)
{
Karsten Rink
committed
if (sfc_elem.getDimension() > 2)
return nullptr;
const unsigned nElemNodes(sfc_elem.getNBaseNodes());
MeshLib::Node** new_nodes = new MeshLib::Node*[2*nElemNodes];
for (unsigned j=0; j<nElemNodes; ++j)
{
new_nodes[j] = subsfc_nodes[sfc_elem.getNode(j)->getID()];
std::size_t new_idx = (nElemNodes==2) ? (3-j) : (nElemNodes+j);
new_nodes[new_idx] =
subsfc_nodes[subsfc_sfc_id_map.at(sfc_elem.getNode(j)->getID())];
Karsten Rink
committed
}
if (sfc_elem.getGeomType() == MeshLib::MeshElemType::LINE)
return new MeshLib::Quad(new_nodes);
if (sfc_elem.getGeomType() == MeshLib::MeshElemType::TRIANGLE)
return new MeshLib::Prism(new_nodes);
if (sfc_elem.getGeomType() == MeshLib::MeshElemType::QUAD)
return new MeshLib::Hex(new_nodes);
return nullptr;
}
MeshLib::Mesh* addTopLayerToMesh(MeshLib::Mesh const& mesh,
double thickness,
std::string const& name)
MeshLib::Mesh* addBottomLayerToMesh(MeshLib::Mesh const& mesh,
double thickness,
std::string const& name)
MeshLib::Mesh* addLayerToMesh(MeshLib::Mesh const& mesh, double thickness,
std::string const& name,
bool on_top)
{
INFO("Extracting top surface of mesh \"%s\" ... ", mesh.getName().c_str());
int const flag = (on_top) ? -1 : 1;
const MathLib::Vector3 dir(0, 0, flag);
double const angle(90);
Karsten Rink
committed
std::unique_ptr<MeshLib::Mesh> sfc_mesh = (mesh.getDimension() == 3) ?
std::unique_ptr<MeshLib::Mesh>(
MeshLib::MeshSurfaceExtraction::getMeshSurface(mesh, dir, angle, true)) :
std::unique_ptr<MeshLib::Mesh>(new MeshLib::Mesh(mesh));
std::vector<MeshLib::Node*> subsfc_nodes =
MeshLib::copyNodeVector(mesh.getNodes());
Karsten Rink
committed
std::vector<MeshLib::Element*> subsfc_elements =
MeshLib::copyElementVector(mesh.getElements(), subsfc_nodes);
std::size_t const n_subsfc_nodes(subsfc_nodes.size());
std::vector<MeshLib::Node*> const& sfc_nodes(sfc_mesh->getNodes());
std::size_t const n_sfc_nodes(sfc_nodes.size());
// *** copy sfc nodes to subsfc mesh node
std::map<std::size_t, std::size_t> subsfc_sfc_id_map;
for (std::size_t k(0); k<n_sfc_nodes; ++k) {
std::size_t const subsfc_id(sfc_nodes[k]->getID());
std::size_t const sfc_id(k+n_subsfc_nodes);
subsfc_sfc_id_map.insert(std::make_pair(subsfc_id, sfc_id));
Karsten Rink
committed
MeshLib::Node const& node (*sfc_nodes[k]);
subsfc_nodes.push_back(new MeshLib::Node(
node[0], node[1], node[2] - (flag * thickness), sfc_id));
}
// *** insert new top layer elements into subsfc_mesh
std::vector<MeshLib::Element*> const& sfc_elements(sfc_mesh->getElements());
std::size_t const n_sfc_elements(sfc_elements.size());
Karsten Rink
committed
for (std::size_t k(0); k<n_sfc_elements; ++k)
subsfc_elements.push_back(
extrudeElement(subsfc_nodes, *sfc_elements[k], subsfc_sfc_id_map)
);
auto new_mesh = new MeshLib::Mesh(name, subsfc_nodes, subsfc_elements);
boost::optional<MeshLib::PropertyVector<int> const&> opt_materials(
mesh.getProperties().getPropertyVector<int>("MaterialIDs")
if (opt_materials) {
boost::optional<PropertyVector<int> &> new_opt_materials(
new_mesh->getProperties().createNewPropertyVector<int>("MaterialIDs",
MeshLib::MeshItemType::Cell, 1));
if (!new_opt_materials) {
ERR("Can not set material properties for new layer");
} else {
unsigned new_layer_id(*(std::max_element(
opt_materials->cbegin(), opt_materials->cend()))+1);
std::copy(opt_materials->cbegin(), opt_materials->cend(),
new_opt_materials->begin());
auto const n_new_props(subsfc_elements.size()-mesh.getNElements());
std::fill_n(new_opt_materials->end(), n_new_props, new_layer_id);
} else {
ERR(
"Could not copy the property \"MaterialIDs\" since the original "
"mesh does not contain such a property.");
}
} // namespace MeshLib