Source: k2dgrflow/topology.h
|
|
|
|
/***************************************************************************
topology.h - description
-------------------
begin : Mon May 28 2001
copyright : (C) 2001 by benny
email : bm@cage.rug.ac.be
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef TOPOLOGY_H
#define TOPOLOGY_H
//get general preprocessor switches to run library
#include "topodefs.h"
//QT includes only if variable is set
#ifdef LIB_WITH_QT
#include <qpainter.h>
#endif
//STL includes
#include <vector.h>
#include <iterator.h>
#include "vectorimp.h"
/**class with the topological objects found in an
optimazation Finite Element Method
*@author benny
*/
class TopoClass {
public:
/**a topology object can be an element, an edge or a node
*/
enum Topology{Element2d, Edge2d, Node2d};
TopoClass(){};
virtual ~TopoClass(){};
#ifdef LIB_WITH_QT
virtual void draw(QPainter *p)=0;
#endif
virtual Topology type()=0;
};
//forward declariation
class TopoEdge2d;
class TopoNode2d;
/** Class that represents an element of the net. Abstract, all real elements, eg triangle, polygon, ... inherit
from this class */
class TopoElement2d: public TopoClass {
public :
/** Construct a general element by telling how many nodes and edges it has
*/
TopoElement2d(int nrNodes, int nrEdges) : TopoClass(),
surf(0.0), fresh(true) {edges.reserve(nrEdges);nodes.reserve(nrNodes);neighbourEle.reserve(nrEdges);};
/**the element does not free space when destructed. An element will always be part of an net.
The net frees the space on destruction */
virtual ~TopoElement2d(){};
/** return the type if asked for, inherited from baseclass, performance issue : no bytes stored
*/
virtual Topology type(){return TopoClass::Element2d;};
/** an element has a surface
*/
virtual double surface()=0;
/** is the local matrix of the element already calculated or not. Execute this function befor accessing the local matrix
*/
bool freshLocMat(){return fresh;};
/** setting the fresh variable : is the local matrix up to date or not ?
*/
void setFresh(bool fr){fresh=fr ;};
/** setting a value I J of the local matrix
*/
virtual void setLocMat(uint localnodeI, uint localnodeJ, double value)=0;
/** return value I J of the local matrix
*/
virtual double locMat(uint localnodeI, uint localnodeJ) =0;
/** setting a value J of the force vector
*/
virtual void setLocForce(uint localnodeJ, double value)=0;
/** return value J of the force vector
*/
virtual double locForce( uint localnodeJ) =0;
/** return pointer to node index
*/
TopoNode2d* node(int index){return nodes[index];};
/** return pointer to node index
*/
TopoNode2d* node(unsigned int index){return nodes[index];};
/** return pointer to edge index
*/
TopoEdge2d* edge(int index){return edges[index];};
/** return pointer to neighbour index - no good method, you don't know how many neighbours there are
better to give an iterator to the users */
TopoElement2d* neighbour(int index){return neighbourEle[index];};
/** return an iterator over the vector of all neighbouring elements
*/
vector<TopoElement2d*>::iterator NeighbourIter(){ return neighbourEle.begin() ;};
/** add an element as neighbour of this element, el is added to the list of neighbours
*/
void addNeighbour(TopoElement2d* el){ neighbourEle.push_back (el);};
/** return the value of basisfunction associated to local node I in point (coor1, coor2)
*/
virtual double localBasisFunc(int nodeI, double coor1, double coor2)=0;
/** return the value of basisfunction associated to local node I, derived to first coord, in point (coor1, coor2)
*/
virtual double localBasisFuncD1(int nodeI, double coor1, double coor2)=0;
/** return the value of basisfunction associated to local node I, derived to second coord, in point (coor1, coor2)
*/
virtual double localBasisFuncD2(int nodeI, double coor1, double coor2)=0;
protected :
/** the surface of the element. 0.0 if not known
*/
double surf;
/** the edges of the element
*/
vector<TopoEdge2d*> edges;
/** the nodes of the element.
To the counterclock direction of node 0 is edge 0, of node 1 is edge 1, ...
Be sure you store edges and nodes in this fashion */
vector<TopoNode2d*> nodes;
/** the neighbouring elements.
Bording edge 0 is neighbour 0, bordering edge 1 is neighbour 1, ... */
vector <TopoElement2d*> neighbourEle;
private :
/** when fresh = true, the local matrices are not ok, so you should not use them until they are recalculated. When
fresh=false, the local matrices are up to date */
bool fresh;
};
/** Class that represents an edge of an element in the net. Abstract, all real edges (line, curve, ... ) inherit
from this class */
class TopoEdge2d: public TopoClass {
public :
/** construction of an abstract edge2d, as attribute the number of nodes on the edge is necessary
*/
TopoEdge2d(int nrNodes, bool noBoundary = true):TopoClass(),
len(0.0), inner(noBoundary) {nodes.reserve(nrNodes); neighbourEle.reserve(2);};
/** no special destruction, memory is left to controller object that manages the mesh
*/
virtual ~TopoEdge2d(){};
/** return the topology
*/
virtual Topology type(){return TopoClass::Edge2d;};
/** return node index, no validation if input is ok
*/
TopoNode2d* node(int index){return nodes[index];};
/** return neighbour index, no validation if input is ok
not so good method, since you don't know how many neighbours there are
remark : if inneredge : then 2 neighbours, else one neighbour */
TopoElement2d* neighbour(int index){return neighbourEle[index];};
/** return an iterator over the vector of all neighbouring elements
*/
vector<TopoElement2d*>::iterator NeighbourIter(){ return neighbourEle.begin() ;};
/** add an el as a neighbour
*/
void addNeighbour(TopoElement2d* el){ neighbourEle.push_back (el);};
/** return the length of the edge. Allow inheritace of this method
*/
virtual double length(){return len;};
/** an inneredge has a node in the inner part of the domain
Beware, the other node can be on the boundary */
virtual bool innerEdge(){return inner;};
/**type of boundary. is the one of the begin and end nodes
If those are on different boundary, then :
-> if one Neuman node and one Dir node, then a neuman edge, since if it was dirichlet, both nodes should be dirichlet (priority of dir to neu)
-> if one Neuman node and one Robin node, then Robin, since priority of neuman over robin
-> if one Robin and one Dir, then Robin, since priority of dirichlet over robin
*/
virtual bool robinEdge()=0;
virtual bool neuEdge()=0;
virtual bool dirEdge()=0;
protected :
/**length of the edge, 0.0 if not calculated yet
*/
double len;
/** is the edge an inner edge ?
*/
bool inner;
/** nodes of the edge
*/
vector<TopoNode2d*> nodes;
/** neighbour elements of the edge (always 1 or 2)
*/
vector<TopoElement2d*> neighbourEle;
};
/** Class that represents a node of the net. Abstract, all real nodes inherit
from this class */
class TopoNode2d: public TopoClass{
public :
/** enum of all the types of nodes
*/
enum Node{INNER, DIRICHLET, NEUMANN, ROBIN};
/** construct 2d node by giving coordinate 1 and 2
*/
TopoNode2d(double co1, double co2):TopoClass(), coord1(co1), coord2(co2){} ;
/** no special destruction, memory is left to controller object that manages the mesh
*/
virtual ~TopoNode2d(){};
/** return the topology
*/
virtual Topology type(){return TopoClass::Node2d;};
/** return coordinate 1
*/
double co1(){return coord1;};
/** return coordinate 2
*/
double co2(){return coord2;};
/**return the nodeType of the node
*/
virtual Node nodeType()=0;
/** is Node a node in de inner part of the total domain
*/
virtual bool innerNode()=0;
/** if no innernode, then a boundary node. But what type ?
keep this order on intersection of two bordertypes :
* first dirichlet
* second neuman
* tirth robin boundary
a node can not be two boundarytypes, so this class is implemented in 4 flavours
representing this. See the boundary nodes for extra functionality
*/
virtual bool robinNode()=0;
virtual bool neuNode()=0;
virtual bool dirNode()=0;
/**is the node a corner node, meaning is the intersection of 2 borders
*/
virtual bool cornerNode()=0;
/** everytime a node is added to an element, call this function, so that the node has a
list of all elements it is contained in */
void addInEle(TopoElement2d* el){ partOfEle.push_back(el);};
/** return an iterator over the vector of all elements the node is part of
*/
vector<TopoElement2d*>::iterator inElementsIter(){ return partOfEle.begin() ;};
/** return nr of elements the node is in.
*/
int inEleNr(){return partOfEle.size();};
/** return a pointer to a certain element index the node is in
*/
TopoElement2d* eleNodePartOf(int index){return partOfEle[index];} ;
/** is a node a part of a given element? return -1 if not, the local node number if true
*/
int inElement(TopoElement2d*);
protected :
/** a node is made out of 2 coordinates
*/
double coord1, coord2 ;
/** and a vector of all elements it is part of
*/
vector<TopoElement2d*> partOfEle ;
};
#endif
Generated by: benny@okidoki on Thu Jun 21 10:41:51 2001, using kdoc 2.0a53. |