Forked from
gmsh / gmsh
13399 commits behind the upstream repository.
-
Christophe Geuzaine authored
- fixed MED node ordering - polished 64 bit Cocoa Mac OS X FLTK version - updated copyright
Christophe Geuzaine authored- fixed MED node ordering - polished 64 bit Cocoa Mac OS X FLTK version - updated copyright
Cell.h 7.30 KiB
// Gmsh - Copyright (C) 1997-2011 C. Geuzaine, J.-F. Remacle
//
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to <gmsh@geuz.org>.
//
// Contributed by Matti Pellikka <matti.pellikka@tut.fi>.
#ifndef _CELL_H_
#define _CELL_H_
#include "GmshConfig.h"
#if defined(HAVE_KBIPACK)
#include <stdio.h>
#include <string>
#include <algorithm>
#include <set>
#include <list>
#include <map>
#include "CellComplex.h"
#include "MElement.h"
#include "MVertex.h"
class Cell;
// Ordering of the cells
class Less_Cell{
public:
bool operator()(const Cell* c1, const Cell* c2) const;
};
// Class representing an elementary cell of a cell complex.
class Cell
{
protected:
// whether this cell belongs to a subdomain
// used in relative homology computation
bool _subdomain;
// whether this cell a combinded cell of elemetary cells
bool _combined;
// mutable index for each cell (used to create boundary operator matrices)
int _index;
// for some algorithms to omit this cell
bool _immune;
// mutable list of cells on the boundary and on the coboundary of this cell
std::map< Cell*, int, Less_Cell > _bd;
std::map< Cell*, int, Less_Cell > _cbd;
// immutable original boundary and coboundary before the reduction of the
// cell complex
std::map<Cell*, int, Less_Cell > _obd;
std::map<Cell*, int, Less_Cell > _ocbd;
private:
// sorted vertices of this cell (used for ordering of the cells)
std::vector<int> _vs;
// the mesh element that is the image of this cell
MElement* _image;
// whether to delete the mesh element when done
// (set to true if created for homology computation only)
bool _delimage;
// get vertex
MVertex* getVertex(int vertex) const { return _image->getVertex(vertex); }
// get the number of vertices this cell has
int getNumVertices() const { return _image->getNumPrimaryVertices(); }
// get the number of facets of this cell
int getNumFacets() const;
// get the vertices on a facet of this cell
void getFacetVertices(const int num, std::vector<MVertex*> &v) const;
public:
Cell() : _subdomain(false), _combined(false), _index(0), _immune(false), _image(NULL),
_delimage(false) {}
Cell(MElement* image);
~Cell();
// the mesh element this cell is represented by
MElement* getImageMElement() const {
if(_image == NULL || _combined){
printf("ERROR: No image mesh element for cell. \n"); }
return _image; }
// get the cell dimension
virtual int getDim() const { return _image->getDim(); };
// get/set whether the image mesh element should be deleted when
// this cell gets deleted
// (was the mesh element in the original mesh,
// is it needed after homology computation for visualization?)
void setDeleteImage(bool delimage) { if(!_combined) _delimage = delimage; }
bool getDeleteImage() const {
if(!_combined) return _delimage;
else return false; }
// find the cells on the boundary of this cell
bool findBoundaryElements(std::vector<MElement*>& bdElements);
// get boundary cell orientation
int findBoundaryCellOrientation(Cell* cell);
int getIndex() const { return _index; };
void setIndex(int index) { _index = index; };
void setImmune(bool immune) { _immune = immune; };
bool getImmune() const { return _immune; };
bool inSubdomain() const { return _subdomain; }
void setInSubdomain(bool subdomain) { _subdomain = subdomain; }
virtual int getNumSortedVertices() const { return _vs.size(); }
virtual int getSortedVertex(int vertex) const { return _vs.at(vertex); }
virtual int getNum() const { return 0; }
// restores the cell information to its original state before reduction
void restoreCell();
// true if this cell has given vertex
virtual bool hasVertex(int vertex) const;
// (co)boundary cell iterator
typedef std::map<Cell*, int, Less_Cell>::iterator biter;
// iterators to (first/last (co)boundary cells of this cell
// (orig: to original (co)boundary cells of this cell)
biter firstBoundary(bool orig=false){
return orig ? _obd.begin() : _bd.begin(); }
biter lastBoundary(bool orig=false){
return orig ? _obd.end() : _bd.end(); }
biter firstCoboundary(bool orig=false){
return orig ? _ocbd.begin() : _cbd.begin(); }
biter lastCoboundary(bool orig=false){
return orig ? _ocbd.end() : _cbd.end(); }
int getBoundarySize() { return _bd.size(); }
int getCoboundarySize() { return _cbd.size(); }
// get the (orig: original) cell boundary
void getBoundary(std::map<Cell*, int, Less_Cell >& boundary,
bool orig=false){
orig ? boundary = _obd : boundary = _bd; }
void getCoboundary(std::map<Cell*, int, Less_Cell >& coboundary,
bool orig=false){
orig ? coboundary = _ocbd : coboundary = _cbd; }
// add (co)boundary cell (orig: as original)
// (other: reciprocally also add this cell from the other cell's (co)boundary)
void addBoundaryCell(int orientation, Cell* cell,
bool orig, bool other);
void addCoboundaryCell(int orientation, Cell* cell,
bool orig, bool other);
// remove (co)boundary cell
// (other: reciprocally also revove this cell from the other cell's (co)boundary)
void removeBoundaryCell(Cell* cell, bool other);
void removeCoboundaryCell(Cell* cell, bool other);
// true if has given cell on (orig: original) (co)boundary
bool hasBoundary(Cell* cell, bool orig=false);
bool hasCoboundary(Cell* cell, bool orig=false);
void clearBoundary() { _bd.clear(); }
void clearCoboundary() { _cbd.clear(); }
// print cell debug info
virtual void printCell();
virtual void printBoundary(bool orig=false);
virtual void printCoboundary(bool orig=false);
// tools for combined cells
bool isCombined() const { return _combined; }
virtual void getCells( std::map< Cell*, int, Less_Cell >& cells) {
cells.clear();
cells[this] = 1;
return;
}
virtual int getNumCells() const {return 1;}
typedef std::map<Cell*, int, Less_Cell>::iterator citer;
// equivalence
virtual bool operator==(const Cell& c2) const {
if(this->isCombined() != c2.isCombined()) return false;
if(this->getNumSortedVertices() != c2.getNumSortedVertices()){
return false;
}
for(int i=0; i < this->getNumSortedVertices();i++){
if(this->getSortedVertex(i) != c2.getSortedVertex(i)){
return false;
}
}
return true;
}
};
// A cell that is a combination of cells of same dimension
class CombinedCell : public Cell{
private:
// list of cells this cell is a combination of
std::map< Cell*, int, Less_Cell > _cells;
// combined cell number, used for ordering
int _num;
static int _globalNum;
public:
CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co=false);
CombinedCell(std::vector<Cell*>& cells);
~CombinedCell() {}
int getDim() const { return _cells.begin()->first->getDim(); }
int getNumSortedVertices() const { return 0; }
int getSortedVertex(int vertex) const { return 0; }
void getCells(std::map< Cell*, int, Less_Cell >& cells) { cells = _cells; }
int getNumCells() const {return _cells.size();}
int getNum() const { return _num; }
bool hasVertex(int vertex) const;
bool operator==(const Cell& c2) const {
if(this->isCombined() != c2.isCombined()) return false;
if(this->getNum() != c2.getNum()) return false;
else return true;
}
};
#endif
#endif