25# include "levelSetMaskObject.hpp"
44 std::unordered_map<long,long> meshToEnvelope ;
46 std::unique_ptr<SurfUnstructured> segmentation = extractCellEnvelope(mask,mesh,meshToEnvelope) ;
48 long intrIndex = meshToEnvelope.begin()->first;
49 long enveIndex = meshToEnvelope.begin()->second;
51 bool sameOrientation = sameInterfaceEnvelopeOrientation(mesh, intrIndex, *segmentation, enveIndex);
53 auto const &
interface = mesh.getInterface(intrIndex);
54 long ownerId = interface.getOwner();
55 bool invert = (mask.count(ownerId)==0) ;
57 bool flip = (sameOrientation == invert);
59 bool orientable = segmentation->adjustCellOrientation( enveIndex, flip);
61 throw std::runtime_error (
"Error in LevelSetMaskObject");
78 std::unordered_map<long,long> meshToEnvelope ;
80 std::unique_ptr<SurfUnstructured> segmentation = extractFaceEnvelope(list,mesh,meshToEnvelope) ;
82 long enveIndex = meshToEnvelope.at(interfaceId);
83 bool sameOrientation = sameInterfaceEnvelopeOrientation(mesh, interfaceId, *segmentation, enveIndex);
85 bool flip = (sameOrientation == invert);
87 bool orientable = segmentation->adjustCellOrientation( enveIndex, flip);
89 throw std::runtime_error (
"Error in LevelSetMaskObject");
104std::unique_ptr<SurfUnstructured> LevelSetMaskObject::extractCellEnvelope(
const std::unordered_set<long> &mask,
const VolumeKernel &mesh, std::unordered_map<long,long> &meshToEnvelope){
106 std::vector<long> list;
108 for(
long cellIndex : mask){
109 const auto &cell = mesh.
getCell(cellIndex);
111 const long *interfaceIndex = cell.getInterfaces();
113 int interfaceCount= cell.getInterfaceCount() ;
115 for(
int i=0; i<interfaceCount; i++){
116 long neigh = adjacencies[i];
118 if(mask.count(neigh)==0){
119 list.push_back(interfaceIndex[i]);
124 return extractFaceEnvelope(list,mesh,meshToEnvelope);
135std::unique_ptr<SurfUnstructured> LevelSetMaskObject::extractFaceEnvelope(
const std::vector<long> &list,
const VolumeKernel &mesh, std::unordered_map<long,long> &meshToEnvelope){
137 std::unique_ptr<SurfUnstructured> envelope;
138#if BITPIT_ENABLE_MPI==1
139 envelope = std::unique_ptr<SurfUnstructured>(
new SurfUnstructured(mesh.getDimension()-1,mesh.getCommunicator()));
141 envelope = std::unique_ptr<SurfUnstructured>(
new SurfUnstructured(mesh.getDimension()-1));
148 long nCells(list.size());
150 for(
long faceIndex : list){
151 auto const &
interface = mesh.getInterface(faceIndex);
152 nVertices += interface.getVertexCount() ;
155 envelope->reserveVertices(nVertices);
156 envelope->reserveCells(nCells);
161 std::unordered_map<long,long> vertexMap;
163 for(
long faceIndex : list){
164 auto const &
interface = mesh.getInterface(faceIndex);
165 ConstProxyVector<long> faceVertexIds = interface.getVertexIds();
166 int nFaceVertices = faceVertexIds.size();
170 std::unique_ptr<long[]> faceEnvelopeConnect = std::unique_ptr<long[]>(
new long[nFaceVertices]);
171 for (
int j = 0; j < nFaceVertices; ++j) {
172 long vertexId = faceVertexIds[j];
176 if (vertexMap.count(vertexId) == 0) {
177 const Vertex &vertex = mesh.getVertex(vertexId);
178 auto envelopeVertex = envelope->addVertex(vertex);
179 vertexMap[vertexId] = envelopeVertex->getId();
183 faceEnvelopeConnect[j] = vertexMap.at(vertexId);
188 PatchKernel::CellIterator cellItr = envelope->addCell(faceType, std::move(faceEnvelopeConnect));
189 meshToEnvelope.insert({{faceIndex,cellItr.getId()}});
193 envelope->initializeAdjacencies();
194 envelope->initializeInterfaces();
196 envelope->getVTK().setName(
"geometry_002") ;
211bool LevelSetMaskObject::sameInterfaceEnvelopeOrientation(
const VolumeKernel &mesh,
long faceIndex, SurfUnstructured &envelope,
long enveIndex){
213 std::array<double,3> facetNormal = envelope.evalFacetNormal(enveIndex);
214 std::array<double,3> interfaceNormal = mesh.evalInterfaceNormal(faceIndex);
216 return (
dotProduct(facetNormal,interfaceNormal)>0) ;
const long * getAdjacencies() const
LevelSetMaskObject(int, const std::unordered_set< long > &, const VolumeKernel &)
Implements visitor pattern fo segmentated geometries.
void setSurface(std::unique_ptr< const SurfUnstructured > &&surface, bool force=false)
The VolumeKernel class provides an interface for defining volume patches.
T dotProduct(const std::array< T, d > &x, const std::array< T, d > &y)