diff --git a/src/serial/alloca.h b/src/serial/alloca.h new file mode 100644 index 0000000000000000000000000000000000000000..c0d7985b7eddcfd47fe943ed6a24412191b1531b --- /dev/null +++ b/src/serial/alloca.h @@ -0,0 +1 @@ +#include <malloc.h> diff --git a/src/serial/gitter_geo.cc b/src/serial/gitter_geo.cc new file mode 100644 index 0000000000000000000000000000000000000000..fa7b3f530ebb7fd0698ba49c33e73ddb13d79071 --- /dev/null +++ b/src/serial/gitter_geo.cc @@ -0,0 +1,629 @@ +// Version f"ur DUNE +// + // (c) bernhard schupp, 1997 - 1998 + + // $Source$ + // $Revision$ + // $Name$ + // $State$ + +/* $Id$ + * $Log$ + * Revision 1.1 2005/03/23 14:57:53 robertk + * all files for serial version of ALU3dGrid. + * + * Revision 1.7 2005/03/23 11:36:06 robertk + * removed BSGridVecType, which is double * now. + * + * Revision 1.6 2004/12/21 17:36:45 robertk + * removed some warnings. + * + * Revision 1.5 2004/12/20 21:37:56 robertk + * reference tetra added. + * + * Revision 1.4 2004/11/16 19:32:24 robertk + * oppositeFace for Hexa. + * + * Revision 1.3 2004/10/25 16:38:09 robertk + * All header end with .h now. Like the original. + * + * In the .cc this changes are done. + * + * Revision 1.2 2004/10/19 13:19:51 robertk + * neighOuterNormal added. this method calculates the normal from neighbour + * point of view but pointing outside of actual element. + * + * Revision 1.1 2004/10/15 09:48:37 robertk + * Inititial version. Some extenxions for Dune made. Schould be compatible + * with all other applications done so far. + * + * Revision 1.10 2002/05/24 09:05:31 dedner + * Vorl"aufig syntaktisch korrekte, d.h. kompilierbare Version + * + * Revision 1.9 2002/05/23 16:37:41 dedner + * Test nach Einbau der Periodischen 4-Raender + * + * Revision 1.8 2002/04/19 15:36:07 wesenber + * modifications required for IBM VisualAge C++ Version 5.0 + * + * Revision 1.7 2001/12/12 09:49:05 wesenber + * resetRefinementRequest() added + * + * Revision 1.6 2001/12/10 13:35:39 wesenber + * parameter ``filePath'' for backup() and backupCMode() added + * + ***/ + +#ifdef IBM_XLC + #define _ANSI_HEADER +#endif + +#include <stdlib.h> +#include <assert.h> + +#ifdef _ANSI_HEADER + using namespace std; + #include <iostream> + #include <fstream> + #include <vector> + #include <map> +#else + #include <iostream.h> + #include <fstream.h> + #include <vector.h> + #include <map.h> +#endif + +#include "mapp_cube_3d.h" +#include "mapp_tetra_3d.h" +#include "gitter_sti.h" +#include "walk.h" + +static volatile char RCSId_gitter_geo_cc [] = "$Id$" ; + +extern "C" { double drand48 (void) ; } + +const pair < Gitter :: Geometric :: hasFace3 *, int > Gitter :: Geometric :: hface3 :: face3Neighbour :: null + = pair < Gitter :: Geometric :: hasFace3 *, int > (Gitter :: Geometric :: InternalHasFace3 ()(0), -1) ; + +const pair < Gitter :: Geometric :: hasFace4 *, int > Gitter :: Geometric :: hface4 :: face4Neighbour :: null + = pair < Gitter :: Geometric :: hasFace4 *, int > (Gitter :: Geometric :: InternalHasFace4 ()(0), -1) ; + + +const int Gitter :: Geometric :: Tetra :: prototype [4][3] = {{1,3,2},{0,2,3},{0,3,1},{0,1,2}} ; + +const int Gitter :: Geometric :: Periodic3 :: prototype [2][3] = {{0,1,2},{3,5,4}} ; + +// Anfang - Neu am 23.5.02 (BS) +const int Gitter :: Geometric :: Periodic4 :: prototype [2][4] = {{0,3,2,1},{4,5,6,7}} ; +// Ende - Neu am 23.5.02 (BS) + + +// # # +// # # ###### # # ## +// # # # # # # # +// ####### ##### ## # # +// # # # ## ###### +// # # # # # # # +// # # ###### # # # # + + // Prototyp des Hexaeders wie er im Programm verwendet wird. + // Eckpunkte und Seitenflaechen: + // + // + // 7---------6 + // /. /| + // / . 1 / | + // / . / | + // 4---------5 | <-- 4 (hinten) + // 5 --> | . | 3 | + // | 3.....|...2 + // | . | / + // | . 2 | / <-- 0 (unten) + // |. |/ + // 0---------1 + // + +const int Gitter :: Geometric :: Hexa :: prototype [6][4] = {{0,3,2,1},{4,5,6,7},{0,1,5,4},{1,2,6,5},{2,3,7,6},{0,4,7,3}} ; +const int Gitter :: Geometric :: Hexa :: oppositeFace [6] = { 1 , 0 , 4 , 5 , 2 , 3 }; // opposite face of face + +int Gitter :: Geometric :: Hexa :: test () const { + static const int v0[8][2] = {{0,0},{0,1},{0,2},{0,3},{1,0},{1,1},{1,2},{1,3}} ; + static const int v1[8][2] = {{2,0},{4,1},{3,1},{2,1},{2,3},{2,2},{3,2},{4,2}} ; + static const int v2[8][2] = {{5,0},{5,3},{4,0},{3,0},{5,1},{3,3},{4,3},{5,2}} ; + int nfaults = 0 ; + { + for(int i = 0 ; i < 8 ; i ++ ) { + int i0 = v0[i][0], j0 = v0[i][1] ; + int i1 = v1[i][0], j1 = v1[i][1] ; + int i2 = v2[i][0], j2 = v2[i][1] ; + if(myvertex (i0, j0) != myvertex (i1, j1)) { + cerr << "**FEHLER auf level: " << level () << " " ; + cerr << "vertex (" << i0 << "," << j0 << ") != vertex (" << i1 << "," << j1 << ")"; + cerr << "\t(" << i0 << "," << j0 << ") =" << myvertex(i0,j0) << " " << twist (i0) ; + cerr << "\t(" << i1 << "," << j1 << ") =" << myvertex(i1,j1) << " " << twist (i1) ; + cerr << endl ; + nfaults ++ ; + } + if(myvertex (i0, j0) != myvertex (i2, j2)) { + cerr << "**FEHLER auf level: " << level () << " " ; + cerr << "vertex (" << i0 << "," << j0 << ") != vertex (" << i2 << "," << j2 << ")" ; + cerr << "\t(" << i0 << "," << j0 << ") =" << myvertex(i0,j0) << " " << twist (i0) ; + cerr << "\t(" << i2 << "," << j2 << ") =" << myvertex(i2,j2) << " " << twist (i1) ; + cerr << endl; + nfaults ++ ; + } + } + } + return nfaults ; +} + +int Gitter :: Geometric :: Hexa :: tagForGlobalRefinement () { + return (request (myrule_t :: iso8), 1) ; +} + +int Gitter :: Geometric :: Hexa :: resetRefinementRequest () { + return (request (myrule_t :: crs), 1) ; +} + +static inline bool insideBall (const double (&p)[3], const double (&c)[3], double r) { + bool inside=false; + double q[3]; + int x,y,z; + for (x=0 , q[0]=p[0]-c[0]-2.0 ; !inside && x<3 ; x++) { + for (y=0 , q[1]=p[1]-c[1]-2.0 ; !inside && y<3 ; y++) { + for (z=0 , q[2]=p[2]-c[2]-2.0 ; !inside && z<3 ; z++) { + inside = ( q[0]*q[0]+q[1]*q[1]+q[2]*q[2] < r*r ) ; + q[2]+=2.0; + } + q[1]+=2.0; + } + q[0]+=2.0; + } + return inside; + //return + // (((p [0] - c [0]) * (p [0] - c [0]) + (p [1] - c [1]) * (p [1] - c [1]) + // + (p [2] - c [2]) * (p [2] - c [2])) < (r * r)) ? true : false ; +} + +int Gitter :: Geometric :: Hexa :: tagForBallRefinement (const double (¢er)[3], double radius, int limit) { + bool hit = false ; + for (int i = 0 ; i < 8 ; i ++) { + const double (&p)[3] = myvertex (i)->Point () ; + if (insideBall (p,center,radius)) { hit = true ; break ; } + } + if (!hit) { + const int resolution = 50 ; + TrilinearMapping map (myvertex(0)->Point(), myvertex(1)->Point(), + myvertex(2)->Point(), myvertex(3)->Point(), myvertex(4)->Point(), + myvertex(5)->Point(), myvertex(6)->Point(), myvertex(7)->Point()) ; + double p [3] ; + for (int i = 0 ; i < resolution ; i ++ ) { + map.map2world (2.0 * drand48 () - 1.0, 2.0 * drand48 () - 1.0, 2.0 * drand48 () - 1.0, p) ; + if (insideBall (p,center,radius)) { hit = true ; break ; } + } + } + return hit ? (level () < limit ? (request (myrule_t :: iso8), 1) + : (request (myrule_t :: nosplit), 0)) : (request (myrule_t :: crs), 1) ; +} + +// ####### +// # ###### ##### ##### ## +// # # # # # # # +// # ##### # # # # # +// # # # ##### ###### +// # # # # # # # +// # ###### # # # # # + +#if 0 +/* +// z y +// 3 |-------- 2 +// |. /\ faces opposite to vertices +// | . / \ +// | ./ \ +// | / . \ +// | / . \ +// | / . \ +// | / . \ +// |/ .\ 1 +// 0 ----------------------- x +// +// face 0 = {1,3,2} +// face 1 = {0,2,3} +// face 2 = {0,3,1} +// face 3 = {0,1,2} +// +// +// +// +// +// +// +*/ +#endif + +int Gitter :: Geometric :: Tetra :: test () const { +// cerr << "**WARNUNG (IGNORIERT) Tetra :: test () nicht implementiert, in " << __FILE__ << " " << __LINE__ << endl; + return 0 ; +} + +int Gitter :: Geometric :: Tetra :: tagForGlobalRefinement () { + return (request (myrule_t :: iso8), 1) ; +} + +int Gitter :: Geometric :: Tetra :: resetRefinementRequest () { + return (request (myrule_t :: crs), 1) ; +} + +int Gitter :: Geometric :: Tetra :: tagForBallRefinement (const double (¢er)[3], double radius, int limit) { + bool hit = false ; + for (int i = 0 ; i < 4 ; i ++) { + const double (&p)[3] = myvertex (i)->Point () ; + if (insideBall (p,center,radius)) { hit = true ; break ; } + } + if (!hit) { + const int resolution = 50 ; + LinearMapping map (myvertex(0)->Point(), myvertex(1)->Point(), + myvertex(2)->Point(), myvertex(3)->Point()) ; + double p [3] ; + for (int i = 0 ; i < resolution ; i ++ ) { + double b1 = drand48 () ; + double b2 = (1.0 - b1) * drand48 () ; + double b3 = (1.0 - b1 - b2) * drand48 () ; + double b4 = 1.0 - b1 - b2 - b3 ; + + // Sind das "uberhaupt Zufallspunkte ? Nein. Leider nicht. + + map.map2world (b1, b2, b3, b4, p) ; + if (insideBall (p,center,radius)) { hit = true ; break ; } + } + } + return hit ? (level () < limit ? (request (myrule_t :: iso8), 1) + : (request (myrule_t :: nosplit), 0)) : (request (myrule_t :: crs), 1) ; +} + +void Gitter :: Geometric :: Tetra :: outerNormal (int face , double * normal ) +{ + BSGridLinearSurfaceMapping + LSM(this->myvertex(face,0)->Point(), + this->myvertex(face,1)->Point(), + this->myvertex(face,2)->Point() + ); + LSM.normal(normal); + return; +} + +void Gitter :: Geometric :: Tetra :: neighOuterNormal (int face , double * normal ) +{ + // just use with other twist to minus normal + BSGridLinearSurfaceMapping + LSM(this->myvertex(face,2)->Point(), + this->myvertex(face,1)->Point(), + this->myvertex(face,0)->Point() + ); + LSM.normal(normal); + return; +} + +// ###### ##### +// # # ###### ##### # #### ##### # #### # # +// # # # # # # # # # # # # # # +// ###### ##### # # # # # # # # # ##### +// # # ##### # # # # # # # # +// # # # # # # # # # # # # # # +// # ###### # # # #### ##### # #### ##### + +// #include <iomanip.h> + +int Gitter :: Geometric :: Periodic3 :: test () const { + cerr << "**WARNUNG (IGNORIERT) Periodic3 :: test () nicht implementiert, in " << __FILE__ << " " << __LINE__ << endl; +// const int digits = 3 ; +// cout << "Fl\"ache: 0, Twist: " << twist (0) << "\t" ; +// const VertexGeo * vx = myvertex (0,0) ; +// cout << "(" << setw (digits) << vx->Point ()[0] << "," << setw (digits) << vx->Point ()[1] << "," << setw (digits) << vx->Point ()[2] << ") " ; +// vx = myvertex (0,1) ; +// cout << "(" << setw (digits) << vx->Point ()[0] << "," << setw (digits) << vx->Point ()[1] << "," << setw (digits) << vx->Point ()[2] << ") " ; +// vx = myvertex (0,2) ; +// cout << "(" << setw (digits) << vx->Point ()[0] << "," << setw (digits) << vx->Point ()[1] << "," << setw (digits) << vx->Point ()[2] << ") \n" ; +// cout << "Fl\"ache: 1, Twist: " << twist (1) << "\t" ; +// vx = myvertex (1,0) ; +// cout << "(" << setw (digits) << vx->Point ()[0] << "," << setw (digits) << vx->Point ()[1] << "," << setw (digits) << vx->Point ()[2] << ") " ; +// vx = myvertex (1,2) ; +// cout << "(" << setw (digits) << vx->Point ()[0] << "," << setw (digits) << vx->Point ()[1] << "," << setw (digits) << vx->Point ()[2] << ") " ; +// vx = myvertex (1,1) ; +// cout << "(" << setw (digits) << vx->Point ()[0] << "," << setw (digits) << vx->Point ()[1] << "," << setw (digits) << vx->Point ()[2] << ") \n" << endl ; + return 0 ; +} + +int Gitter :: Geometric :: Periodic3 :: tagForGlobalRefinement () { + return 0 ; +} + +int Gitter :: Geometric :: Periodic3 :: resetRefinementRequest () { + return 0 ; +} + +int Gitter :: Geometric :: Periodic3 :: tagForBallRefinement (const double (¢er)[3], double radius, int limit) { + return 0 ; +} + +// Anfang - Neu am 23.5.02 (BS) + +// ###### # +// # # ###### ##### # #### ##### # #### # # +// # # # # # # # # # # # # # # # +// ###### ##### # # # # # # # # # # # +// # # ##### # # # # # # # ####### +// # # # # # # # # # # # # # +// # ###### # # # #### ##### # #### # + +int Gitter :: Geometric :: Periodic4 :: test () const { + cerr << "**WARNUNG (IGNORIERT) Periodic4 :: test () nicht implementiert, in " << __FILE__ << " " << __LINE__ << endl; + return 0 ; +} + +int Gitter :: Geometric :: Periodic4 :: tagForGlobalRefinement () { + return 0 ; +} + +int Gitter :: Geometric :: Periodic4 :: resetRefinementRequest () { + return 0 ; +} + +int Gitter :: Geometric :: Periodic4 :: tagForBallRefinement (const double (¢er)[3], double radius, int limit) { + return 0 ; +} + +// Ende - Neu am 23.5.02 (BS) + +Gitter :: Geometric :: BuilderIF :: ~BuilderIF () { + if (iterators_attached ()) + cerr << "**WARNUNG (IGNORIERT) beim L\"oschen von BuilderIF: Iterator-Z\"ahler [" << iterators_attached () << "]" << endl ; + {for (list < hexa_GEO * > :: iterator i = _hexaList.begin () ; i != _hexaList.end () ; delete (*i++)) ; } + {for (list < tetra_GEO * > :: iterator i = _tetraList.begin () ; i != _tetraList.end () ; delete (*i++)) ; } + {for (list < periodic3_GEO * > :: iterator i = _periodic3List.begin () ; i != _periodic3List.end () ; delete (*i++)) ; } + {for (list < periodic4_GEO * > :: iterator i = _periodic4List.begin () ; i != _periodic4List.end () ; delete (*i++)) ; } + {for (list < hbndseg4_GEO * > :: iterator i = _hbndseg4List.begin () ; i != _hbndseg4List.end () ; delete (*i++)) ; } + {for (list < hbndseg3_GEO * > :: iterator i = _hbndseg3List.begin () ; i != _hbndseg3List.end () ; delete (*i++)) ; } + {for (list < hface4_GEO * > :: iterator i = _hface4List.begin () ; i != _hface4List.end () ; delete (*i++)) ; } + {for (list < hface3_GEO * > :: iterator i = _hface3List.begin () ; i != _hface3List.end () ; delete (*i++)) ; } + {for (list < hedge1_GEO * > :: iterator i = _hedge1List.begin () ; i != _hedge1List.end () ; delete (*i++)) ; } + {for (list < VertexGeo * > :: iterator i = _vertexList.begin () ; i != _vertexList.end () ; delete (*i++)) ; } +} + +IteratorSTI < Gitter :: vertex_STI > * Gitter :: Geometric :: BuilderIF :: iterator (const vertex_STI *) const { + ListIterator < VertexGeo > w (_vertexList) ; + return new Wrapper < ListIterator < VertexGeo >, InternalVertex > (w) ; +} + +IteratorSTI < Gitter :: vertex_STI > * Gitter :: Geometric :: BuilderIF :: iterator (const IteratorSTI < vertex_STI > * w) const { + return new Wrapper < ListIterator < VertexGeo >, InternalVertex > (*(const Wrapper < ListIterator < VertexGeo >, InternalVertex > *) w) ; +} + +IteratorSTI < Gitter :: hedge_STI > * Gitter :: Geometric :: BuilderIF :: iterator (const hedge_STI *) const { + ListIterator < hedge1_GEO > w (_hedge1List) ; + return new Wrapper < ListIterator < hedge1_GEO >, InternalEdge > (w) ; +} + +IteratorSTI < Gitter :: hedge_STI > * Gitter :: Geometric :: BuilderIF :: iterator (const IteratorSTI < hedge_STI > * w) const { + return new Wrapper < ListIterator < hedge1_GEO >, InternalEdge > (*(const Wrapper < ListIterator < hedge1_GEO >, InternalEdge > *)w) ; +} + +IteratorSTI < Gitter :: hface_STI > * Gitter :: Geometric :: BuilderIF :: iterator (const hface_STI *) const { + ListIterator < hface4_GEO > w1 (_hface4List) ; + ListIterator < hface3_GEO > w2 (_hface3List) ; + return new AlignIterator < ListIterator < hface4_GEO >, ListIterator < hface3_GEO >, hface_STI > (w1,w2) ; +} + +IteratorSTI < Gitter :: hface_STI > * Gitter :: Geometric :: BuilderIF :: iterator (const IteratorSTI < hface_STI > * w) const { + return new AlignIterator < ListIterator < hface4_GEO >, ListIterator < hface3_GEO >, hface_STI > + (*(const AlignIterator < ListIterator < hface4_GEO >, ListIterator < hface3_GEO >, hface_STI > *)w) ; +} + +IteratorSTI < Gitter :: hbndseg_STI > * Gitter :: Geometric :: BuilderIF :: iterator (const hbndseg_STI *) const { + ListIterator < hbndseg4_GEO > w1 (_hbndseg4List) ; + ListIterator < hbndseg3_GEO > w2 (_hbndseg3List) ; + return new AlignIterator < ListIterator < hbndseg4_GEO >, ListIterator < hbndseg3_GEO >, hbndseg_STI > (w1,w2) ; +} + +IteratorSTI < Gitter :: hbndseg_STI > * Gitter :: Geometric :: BuilderIF :: iterator (const IteratorSTI < hbndseg_STI > * w) const { + return new AlignIterator < ListIterator < hbndseg4_GEO >, ListIterator < hbndseg3_GEO >, hbndseg_STI > + (*(const AlignIterator < ListIterator < hbndseg4_GEO >, ListIterator < hbndseg3_GEO >, hbndseg_STI > *)w) ;; +} + +IteratorSTI < Gitter :: helement_STI > * Gitter :: Geometric :: BuilderIF :: iterator (const helement_STI *) const { + + // Vorsicht ! Falls diese Methode ver"andert wird, muss die selbe "Anderung + // in der Kopiermethode (nachfolgend) vorgenommen werden. Sonst f"uhrt die + // statische Typkonversion zu einem schwer nachvollziehbaren Fehler. +// Anfang - Neu am 23.5.02 (BS) + + ListIterator < hexa_GEO > w1 (_hexaList) ; + ListIterator < tetra_GEO > w2 (_tetraList) ; + ListIterator < periodic3_GEO > w3 (_periodic3List) ; + ListIterator < periodic4_GEO > w4 (_periodic4List) ; + + AlignIterator < ListIterator < hexa_GEO >, ListIterator < tetra_GEO >, helement_STI > aw12 (w1,w2) ; + AlignIterator < ListIterator < periodic3_GEO >, ListIterator < periodic4_GEO >, helement_STI > aw34 (w3,w4) ; + + return new AlignIterator < AlignIterator < ListIterator < hexa_GEO >, ListIterator < tetra_GEO >, helement_STI >, + AlignIterator < ListIterator < periodic3_GEO >, ListIterator < periodic4_GEO >, helement_STI >, helement_STI > (aw12,aw34) ; +// Ende - Neu am 23.5.02 (BS) +} + +IteratorSTI < Gitter :: helement_STI > * Gitter :: Geometric :: BuilderIF :: iterator (const IteratorSTI < helement_STI > * w) const { + return new AlignIterator < AlignIterator < ListIterator < hexa_GEO >, ListIterator < tetra_GEO >, helement_STI >, + AlignIterator < ListIterator < periodic3_GEO >, ListIterator < periodic4_GEO >, helement_STI >, helement_STI > + (*(const AlignIterator < AlignIterator < ListIterator < hexa_GEO >, ListIterator < tetra_GEO >, helement_STI >, + AlignIterator < ListIterator < periodic3_GEO >, ListIterator < periodic4_GEO >, helement_STI >, helement_STI > *) w) ; +} + // *** Neu: Iterator der nur die "echten" Elemente (ohne period. R"ander) + // iteriert. + +IteratorSTI < Gitter :: helement_STI > * Gitter :: Geometric :: BuilderIF :: pureElementIterator (const helement_STI *) const { + + // Vorsicht ! Falls diese Methode ver"andert wird, muss die selbe "Anderung + // in der Kopiermethode (nachfolgend) vorgenommen werden. Sonst f"uhrt die + // statische Typkonversion zu einem schwer nachvollziehbaren Fehler. + + ListIterator < hexa_GEO > w1 (_hexaList) ; + ListIterator < tetra_GEO > w2 (_tetraList) ; + + return new AlignIterator < ListIterator < hexa_GEO >, ListIterator < tetra_GEO >, helement_STI > (w1,w2) ; +} + +IteratorSTI < Gitter :: helement_STI > * Gitter :: Geometric :: BuilderIF :: pureElementIterator (const IteratorSTI < helement_STI > * w) const { + return new AlignIterator < ListIterator < hexa_GEO >, ListIterator < tetra_GEO >, helement_STI > + (*(const AlignIterator < ListIterator < hexa_GEO >, ListIterator < tetra_GEO >, helement_STI > *)w) ; +} + // *** + +void Gitter :: Geometric :: BuilderIF :: backupCMode (ostream & os) const { + + // Das Compatibility Mode Backup sichert das Makrogitter genau + // dann, wenn es zwischenzeitlich ge"andert wurde, was beim + // Neuanlegen und bei der Lastverteilung der Fall ist. + + map < VertexGeo *, int, less < VertexGeo * > > vm ; + os.setf (ios::fixed, ios::floatfield) ; + os.precision (16) ; + + // Bisher enth"alt die erste Zeile der Datei entweder "!Tetraeder" + // oder "!Hexaeder" je nachdem, ob ein reines Tetraeder- oder + // Hexaedernetz vorliegt. Gemischte Netze sind bez"uglich ihres + // Dateiformats noch nicht spezifiziert. + + if (_tetraList.size () == 0) { + os << "!Hexaeder" << endl ; + } else if (_hexaList.size () == 0 && _tetraList.size () != 0) { + os << "!Tetraeder" << endl ; + } else { + cerr << "**WARNUNG (IGNORIERT) Gitter :: Geometric :: BuilderIF :: backupCMode (ostream &)" ; + cerr << " schreibt nur entweder reine Hexaedernetze oder reine Tetraedernetze." ; + cerr << " In " << __FILE__ << " " << __LINE__ << endl ; + } + + // In jedem Fall die Vertexkoordinaten rausschreiben. + + os << _vertexList.size () << endl ; + { + int index (0) ; + for (list < VertexGeo * > :: const_iterator i = _vertexList.begin () ; i != _vertexList.end () ; i ++) { + os << (*i)->Point ()[0] << " " << (*i)->Point ()[1] << " " << (*i)->Point ()[2] << endl ; + vm [*i] = index ++ ; + } + } + if (_tetraList.size () == 0) { + assert (_hbndseg3List.size () == 0) ; + os << _hexaList.size () << endl ; + { + for (list < hexa_GEO * > :: const_iterator i = _hexaList.begin () ; i != _hexaList.end () ; i ++ ) { + for (int j = 0 ; j < 8 ; os << vm [(*i)->myvertex (j ++)] << " ") ; + os << endl ; + } + } +// Anfang - Neu am 23.5.02 (BS) + os << _hbndseg4List.size () + _periodic4List.size () << endl ; +// Ende - Neu am 23.5.02 (BS) + { + for (list < hbndseg4_GEO * > :: const_iterator i = _hbndseg4List.begin () ; i != _hbndseg4List.end () ; i ++) { + os << -(int)(*i)->bndtype () << " " << 4 << " " ; + for (int j = 0 ; j < 4 ; os << vm [(*i)->myvertex (0,j ++)] << " ") ; + os << endl ; + } + } +// Anfang - Neu am 23.5.02 (BS) + { + for (list < periodic4_GEO * > :: const_iterator i = _periodic4List.begin () ; i != _periodic4List.end () ; i ++) { + os << -(int)(hbndseg :: periodic) << " " << 8 << " " ; + for (int j = 0 ; j < 8 ; os << vm [(*i)->myvertex (j ++)] << " ") ; + os << endl ; + } + } +// Ende - Neu am 23.5.02 (BS) + } else if (_hexaList.size () == 0 && _tetraList.size () != 0) { + os << _tetraList.size () << endl ; + { + for (list < tetra_GEO * > :: const_iterator i = _tetraList.begin () ; i != _tetraList.end () ; i ++ ) { + for (int j = 0 ; j < 4 ; os << vm [(*i)->myvertex (j ++)] << " ") ; + os << endl ; + } + } + os << _hbndseg3List.size () + _periodic3List.size () << endl ; + { + for (list < hbndseg3_GEO * > :: const_iterator i = _hbndseg3List.begin () ; i != _hbndseg3List.end () ; i ++) { + os << -(int)(*i)->bndtype () << " " << 3 << " " ; + for (int j = 0 ; j < 3 ; os << vm [(*i)->myvertex (0,j ++)] << " ") ; + os << endl ; + } + } + { + for (list < periodic3_GEO * > :: const_iterator i = _periodic3List.begin () ; i != _periodic3List.end () ; i ++) { + os << -(int)(hbndseg :: periodic) << " " << 6 << " " ; + for (int j = 0 ; j < 6 ; os << vm [(*i)->myvertex (j ++)] << " ") ; + os << endl ; + } + } + } + { + // Die Vertexidentifierliste hinten anh"angen, damit ein verteiltes + // Grobgitter wieder zusammengefunden wird. + + for (list < VertexGeo * > :: const_iterator i = _vertexList.begin () ; i != _vertexList.end () ; i ++) + os << (*i)->ident () << " " << -1 << endl ; + } + // Die Modified - Markierung zur"ucksetzen. + // Bisher leider noch mit 'cast around const' feature. + +// ((BuilderIF *)this)->_modified = false ; + return ; +} + + +void Gitter :: Geometric :: BuilderIF :: backupCMode (const char * filePath, const char * fileName) const { + if (_modified) { + char * name = new char [strlen (filePath) + strlen (fileName) + 20] ; + sprintf (name, "%smacro.%s", filePath, fileName) ; + ofstream out (name) ; + if (out) { + backupCMode (out) ; + } else { + cerr << "**WARNUNG (IGNORIERT) in Gitter :: Geometric :: BuilderIF :: backupCMode (const char *, const char *)" ; + cerr << " beim Anlegen der Datei < " << name << " > in " << __FILE__ << " " << __LINE__ << endl ; + } + delete [] name ; + } + return ; +} + +void Gitter :: Geometric :: BuilderIF :: backup (ostream & os) const { + + // Man sollte sich erstmal darauf einigen, wie ein allgemeines Gitterdateiformat + // auszusehen hat f"ur Hexaeder, Tetraeder und alle m"oglichen Pyramiden. + // Solange leiten wir die Methodenaufrufe auf backupCMode (..) um. + + cerr << "**WARNUNG (IGNORIERT) Gitter :: Geometric :: BuilderIF :: backup (ostream &) " ; + cerr << " nach Gitter :: Geometric :: BuilderIF :: backupCMode (ostream &) umgeleitet " << endl ; + + backupCMode (os) ; + return ; +} + +void Gitter :: Geometric :: BuilderIF :: backup (const char * filePath, const char * fileName) const +{ + cerr << "**WARNUNG (IGNORIERT) Gitter :: Geometric :: BuilderIF :: backup (const char *) " ; + cerr << " nach Gitter :: Geometric :: BuilderIF :: backupCMode (const char *, const char *) umgeleitet " << endl ; + + backupCMode (filePath, fileName) ; + return ; +} + + + + + + + + + diff --git a/src/serial/gitter_hexa_top.h b/src/serial/gitter_hexa_top.h new file mode 100644 index 0000000000000000000000000000000000000000..0a4d30234538951f9ff8c9f527f80dac40d4449f --- /dev/null +++ b/src/serial/gitter_hexa_top.h @@ -0,0 +1,1637 @@ +// (c) bernhard schupp 1997 - 1998 +// modifications for Dune Interface +// (c) Robert Kloefkorn 2004 - 2005 + +#ifndef GITTER_HEXA_TOP_H_INCLUDED +#define GITTER_HEXA_TOP_H_INCLUDED + +#include "mapp_cube_3d.h" + +template < class A > class Hedge1Top : public A { + protected : + typedef Hedge1Top < A > inneredge_t ; + typedef typename A :: innervertex_t innervertex_t ; + typedef typename A :: myvertex_t myvertex_t ; + typedef typename A :: myrule_t myrule_t ; + private : + int _lvl ; + inneredge_t * _dwn, * _bbb ; + innervertex_t * _cv ; + myrule_t _rule ; + + IndexManagerType & _indexManager; + public : + // need for refinement + IndexManagerType & getIndexManager() { return _indexManager; } + + inline Hedge1Top (int,myvertex_t *,myvertex_t *, IndexManagerType & im) ; + virtual ~Hedge1Top () ; + inneredge_t * subedge1 (int) ; + const inneredge_t * subedge1 (int) const ; + inneredge_t * down () ; + const inneredge_t * down () const ; + inneredge_t * next () ; + const inneredge_t * next () const ; + int level () const ; + inline void append (inneredge_t *) ; + innervertex_t * innerVertex () ; + const innervertex_t * innerVertex () const ; + innervertex_t * subvertex (int) ; + const innervertex_t * subvertex (int) const ; + public : + virtual void backup (ostream &) const ; + virtual void restore (istream &) ; + + // new xdr methods + virtual void backup (XDRstream_out &) const ; + virtual void restore (XDRstream_in &) ; + public : + virtual myrule_t getrule () const ; + virtual void refineImmediate (myrule_t) ; + virtual bool coarse () ; +} ; + +template < class A > class Hface4Top : public A { + protected : + typedef Hface4Top < A > innerface_t ; + typedef typename A :: inneredge_t inneredge_t ; + typedef typename A :: innervertex_t innervertex_t ; + typedef typename A :: myhedge1_t myhedge1_t ; + typedef typename A :: myvertex_t myvertex_t ; + typedef typename A :: myrule_t myrule_t ; + private : + innerface_t * _dwn, * _bbb ; + innervertex_t * _cv ; + inneredge_t * _ed ; + int _lvl ; + myrule_t _rule ; + IndexManagerType & _indexManager; + + inline myhedge1_t * subedge1 (int,int) ; + inline const myhedge1_t * subedge1 (int,int) const ; + void splitISO4 () ; + IndexManagerType & getEdgeIndexManager () ; + public: + // for HexaTop, when refinement is done + IndexManagerType & getIndexManager() { return _indexManager; } + + inline Hface4Top (int,myhedge1_t *,int,myhedge1_t *,int,myhedge1_t *,int,myhedge1_t *,int, IndexManagerType & im) ; + virtual ~Hface4Top () ; + innervertex_t * subvertex (int) ; + const innervertex_t * subvertex (int) const ; + inneredge_t * subedge1 (int) ; + const inneredge_t * subedge1 (int) const ; + innerface_t * subface4 (int) ; + const innerface_t * subface4 (int) const ; + int level () const ; + innervertex_t * innerVertex () ; + const innervertex_t * innerVertex () const ; + inneredge_t * innerHedge () ; + const inneredge_t * innerHedge () const ; + innerface_t * down () ; + const innerface_t * down () const ; + innerface_t * next () ; + const innerface_t * next () const ; + void append (innerface_t * f) ; + public : + virtual myrule_t getrule () const ; + virtual bool refine (myrule_t,int) ; + virtual void refineImmediate (myrule_t) ; + virtual bool coarse () ; + public : + virtual void backup (ostream &) const ; + virtual void restore (istream &) ; +} ; + +template < class A > class Hbnd4Top : public A { + protected : + typedef Hbnd4Top < A > innerbndseg_t ; + typedef typename A :: myhface4_t myhface4_t ; + typedef typename A :: myrule_t myrule_t ; + typedef typename A :: balrule_t balrule_t ; + typedef typename A :: bnd_t bnd_t; + + void splitISO4 () ; + bool refineLikeElement (balrule_t) ; + private : + innerbndseg_t * _bbb, * _dwn, * _up ; + int _lvl ; + const bnd_t _bt; // type of boundary + IndexManagerType & _indexManager; + + inline bool coarse () ; + inline void append (innerbndseg_t *) ; + public : + // constructor for refinement + inline Hbnd4Top (int,myhface4_t *,int,ProjectVertex *, innerbndseg_t *) ; + + // constructor for macro element + inline Hbnd4Top (int,myhface4_t *,int,ProjectVertex *, const bnd_t bt , IndexManagerType & im) ; + virtual ~Hbnd4Top () ; + bool refineBalance (balrule_t,int) ; + bool bndNotifyCoarsen () ; + void restoreFollowFace () ; + int level () const ; + innerbndseg_t * next () ; + innerbndseg_t * down () ; + const innerbndseg_t * next () const ; + const innerbndseg_t * down () const ; + + // for dune + innerbndseg_t * up () ; + const innerbndseg_t * up () const ; + inline bnd_t bndtype () const { return _bt; } +} ; + +template < class A > class HexaTop : public A { + protected : + typedef HexaTop < A > innerhexa_t ; + typedef typename A :: innerface_t innerface_t ; + typedef typename A :: inneredge_t inneredge_t ; + typedef typename A :: innervertex_t innervertex_t ; + typedef typename A :: myhface4_t myhface4_t ; + typedef typename A :: myhedge1_t myhedge1_t ; + typedef typename A :: myvertex_t myvertex_t ; + typedef typename A :: myrule_t myrule_t ; + typedef typename A :: balrule_t balrule_t ; + inline void refineImmediate (myrule_t) ; + inline void append (innerhexa_t * h) ; + private : + innerhexa_t * _bbb, * _dwn, * _up ; + innerface_t * _fc ; + inneredge_t * _ed ; + innervertex_t * _cv ; + int _lvl ; + myrule_t _rule, _req ; + IndexManagerType & _indexManager; + + void splitISO8 () ; + inline myhedge1_t * subedge1 (int,int) ; + inline const myhedge1_t * subedge1 (int,int) const ; + inline myhface4_t * subface4 (int,int) ; + inline const myhface4_t * subface4 (int,int) const ; + + IndexManagerType & getEdgeIndexManager () ; + IndexManagerType & getFaceIndexManager () ; + + public: + // Constructor for macro elements + inline HexaTop (int,myhface4_t *,int,myhface4_t *,int,myhface4_t *,int, + myhface4_t *,int,myhface4_t *,int,myhface4_t *,int, IndexManagerType & im) ; + + // constructor for refinement + inline HexaTop (int,myhface4_t *,int,myhface4_t *,int,myhface4_t *,int, + myhface4_t *,int,myhface4_t *,int,myhface4_t *,int, innerhexa_t * up ) ; + + virtual ~HexaTop () ; + inline innerhexa_t * up () ; + inline const innerhexa_t * up () const; + inline innerhexa_t * down () ; + inline const innerhexa_t * down () const ; + inline innerhexa_t * next () ; + inline const innerhexa_t * next () const ; + inline innervertex_t * innerVertex () ; + inline const innervertex_t * innerVertex () const ; + inline inneredge_t * innerHedge () ; + inline const inneredge_t * innerHedge () const ; + inline innerface_t * innerHface () ; + inline const innerface_t * innerHface () const ; + int level () const ; + public : + myrule_t getrule () const ; + bool refine () ; + void request (myrule_t) ; + bool refineBalance (balrule_t,int) ; + bool coarse () ; + bool bndNotifyCoarsen () ; + void backupCMode (ostream &) const ; + void backup (ostream &) const ; + void restore (istream &) ; +} ; + +template < class A > class Periodic4Top : public A { + protected : + typedef Periodic4Top < A > innerperiodic4_t ; + typedef typename A :: innervertex_t innervertex_t ; + typedef typename A :: inneredge_t inneredge_t ; + typedef typename A :: innerface_t innerface_t ; + typedef typename A :: myhedge1_t myhedge1_t ; + typedef typename A :: myhface4_t myhface4_t ; + typedef typename A :: myrule_t myrule_t ; + typedef typename A :: balrule_t balrule_t ; + inline void refineImmediate (myrule_t) ; + inline void append (innerperiodic4_t * h) ; + private : + innerperiodic4_t * _dwn, * _bbb, * _up ; + int _lvl ; + myrule_t _rule ; + private : + void splitISO4 () ; + protected : + myhedge1_t * subedge1 (int,int) ; + const myhedge1_t * subedge1 (int,int) const ; + myhface4_t * subface4 (int,int) ; + const myhface4_t * subface4 (int i, int j) const ; + public: + inline Periodic4Top (int,myhface4_t *,int,myhface4_t *,int) ; + virtual inline ~Periodic4Top () ; + + inline innerperiodic4_t * up () ; + inline const innerperiodic4_t * up () const; + + inline innerperiodic4_t * down () ; + inline const innerperiodic4_t * down () const ; + inline innerperiodic4_t * next () ; + inline const innerperiodic4_t * next () const ; + inline innervertex_t * innerVertex () ; + inline const innervertex_t * innerVertex () const ; + inline inneredge_t * innerHedge () ; + inline const inneredge_t * innerHedge () const ; + inline innerface_t * innerHface () ; + inline const innerface_t * innerHface () const ; + inline int level () const ; + public : + myrule_t getrule () const ; + bool refine () ; + void request (myrule_t) ; + bool refineBalance (balrule_t,int) ; + bool coarse () ; + bool bndNotifyCoarsen () ; + void backupCMode (ostream &) const ; + void backup (ostream &) const ; + void restore (istream &) ; +}; + + // + // # # # # # # # ###### + // # ## # # # ## # # + // # # # # # # # # # ##### + // # # # # # # # # # # + // # # ## # # # ## # + // # # # ###### # # # ###### + // + +// # # # ####### +// # # ###### ##### #### ###### ## # #### ##### +// # # # # # # # # # # # # # # # +// ####### ##### # # # ##### # # # # # # +// # # # # # # ### # # # # # ##### +// # # # # # # # # # # # # # +// # # ###### ##### #### ###### ##### # #### # + + +template < class A > inline Hedge1Top < A > :: Hedge1Top (int l, myvertex_t * a, myvertex_t * b, IndexManagerType & im ) + : A (a,b), _lvl (l), _dwn (0), _bbb (0), _cv (0), _rule (myrule_t :: nosplit) , _indexManager (im) { + this->setIndex( _indexManager.getIndex() ); + return ; +} + +template < class A > Hedge1Top < A > :: ~Hedge1Top () { + _indexManager.freeIndex( this->getIndex() ); + if(_bbb) delete _bbb; + if(_dwn) delete _dwn; + if(_cv) delete _cv; + return ; +} + +template < class A > int Hedge1Top < A > :: level () const { + return _lvl ; +} + +template < class A > Hedge1Top < A > * Hedge1Top < A > :: down () { + return _dwn ; +} + +template < class A > const Hedge1Top < A > * Hedge1Top < A > :: down () const { + return _dwn ; +} + +template < class A > Hedge1Top < A > * Hedge1Top < A > :: next () { + return _bbb ; +} + +template < class A > const Hedge1Top < A > * Hedge1Top < A > :: next () const { + return _bbb ; +} + +template < class A > void Hedge1Top < A > :: backup (ostream & os) const { + os.put ((char) getrule ()) ; + {for (const inneredge_t * d = down () ; d ; d = d->next ()) d->backup (os) ; } + return ; +} + +template < class A > void Hedge1Top < A > :: restore (istream & is) { + char r = (char) is.get () ; + refineImmediate (myrule_t (r)) ; + {for (inneredge_t * d = down () ; d ; d = d->next ()) d->restore (is) ; } + return ; +} +template < class A > void Hedge1Top < A > :: backup (XDRstream_out & os) const { + os.put ((char) getrule ()) ; + {for (const inneredge_t * d = down () ; d ; d = d->next ()) d->backup (os) ; } + return ; +} + +template < class A > void Hedge1Top < A > :: restore (XDRstream_in & is) { + char r = (char) is.get () ; + refineImmediate (myrule_t (r)) ; + {for (inneredge_t * d = down () ; d ; d = d->next ()) d->restore (is) ; } + return ; +} + +template < class A > inline void Hedge1Top < A > :: append (inneredge_t * e) { + assert (!_bbb && e) ; + _bbb = e ; + return ; +} + +template < class A > typename Hedge1Top < A > :: myrule_t +Hedge1Top < A > :: getrule () const { + return myrule_t (_rule) ; +} + +template < class A > void Hedge1Top < A > :: refineImmediate (myrule_t r) { + if (r != getrule ()) { + assert (getrule () == myrule_t :: nosplit) ; + switch (r) { + case myrule_t :: iso2 : + { + int l = 1 + level () ; + assert (_cv == 0 && _dwn == 0) ; + // the last myvertex(0) is submitted for the indexmanager reference, rk + _cv = new innervertex_t (l, .5 * (this->myvertex(0)->Point()[0] + this->myvertex(1)->Point()[0]), + .5 * (this->myvertex(0)->Point()[1] + this->myvertex(1)->Point()[1]), + .5 * (this->myvertex(0)->Point()[2] + this->myvertex(1)->Point()[2]) , *(this->myvertex(0)) ) ; + assert (_cv) ; + inneredge_t * e0 = new inneredge_t (l, this->myvertex(0), _cv, _indexManager ) ; + inneredge_t * e1 = new inneredge_t (l, _cv, this->myvertex(1), _indexManager ) ; + assert (e0 && e1) ; + (_dwn = e0)->append (e1) ; + _rule = myrule_t :: iso2 ; + break ; + } + default : + cerr << "**FEHLER (FATAL) falsche Verfeinerungsregel [" << r ; + cerr << "] in " << __FILE__ << " " << __LINE__ << endl ; + abort () ; + break ; + } + this->postRefinement () ; + } + return ; +} + +template < class A > bool Hedge1Top < A > :: coarse () { + if (this->leaf ()) return false ; + bool x = true ; + + // Der Wert von x bleibt 'true' falls alle Kinder der Kante + // Bl"atter sind und zudem keine Referenzen auf diese Kanten + // gesetzt sind. Andernfalls liegt kein vergr"oberungsf"ahiger + // Knoten vor. + // Vorsicht: Im parallelen Gitter bleiben auch Kanten ohne + // Refcount stehen, um konsistente "Uberg"ange zu erhalten. + + for (inneredge_t * f = this->down () ; f ; f = f->next ()) { + if (f->leaf ()) { + x &= ! f->ref ; + } else { + x = false ; + f->coarse () ; + } + } + if (x) { + + // Falls lockedAgainstCoarsening () aufgerufen 'true' liefert + // soll die Operation des Vergr"oberns nicht sofort ausgef"uhrt + // sondern (pending) zur"uckgestellt werden. + + if (!this->lockedAgainstCoarsening ()) { + delete _dwn ; + _dwn = 0 ; + delete _cv ; + _cv = 0 ; + _rule = myrule_t :: nosplit ; + } + } + return x ; +} + +template < class A > Hedge1Top < A > * Hedge1Top < A > :: subedge1 (int n) { + assert (n == 0 || n == 1) ; + assert (n ? this->down ()->next () : this->down ()) ; + return n ? this->down ()->next () : this->down () ; +} + +template < class A > const Hedge1Top < A > * Hedge1Top < A > :: subedge1 (int n) const { + assert (n == 0 || n == 1) ; + assert (n ? this->down ()->next () : this->down ()) ; + return n ? this->down ()->next () : this->down () ; +} + +template < class A > inline typename Hedge1Top < A > :: innervertex_t * +Hedge1Top < A > :: innerVertex () { + return _cv ; +} + +template < class A > inline const typename Hedge1Top < A > :: innervertex_t * Hedge1Top < A > :: innerVertex () const { + return _cv ; +} + +template < class A > inline typename Hedge1Top < A > :: innervertex_t * Hedge1Top < A > :: subvertex (int) { + return _cv ; +} + +template < class A > inline const typename Hedge1Top < A > :: innervertex_t * Hedge1Top < A > :: subvertex (int) const { + return _cv ; +} + +// # # # ####### +// # # ###### ## #### ###### # # # #### ##### +// # # # # # # # # # # # # # # # +// ####### ##### # # # ##### # # # # # # # +// # # # ###### # # ####### # # # ##### +// # # # # # # # # # # # # # +// # # # # # #### ###### # # #### # + + +template < class A > typename Hface4Top < A > :: innerface_t * Hface4Top < A > :: down () { + return _dwn ; +} + +template < class A > const typename Hface4Top < A > :: innerface_t * Hface4Top < A > :: down () const { + return _dwn ; +} + +template < class A > typename Hface4Top < A > :: innerface_t * Hface4Top < A > :: next () { + return _bbb ; +} + +template < class A > const typename Hface4Top < A > :: innerface_t * Hface4Top < A > :: next () const { + return _bbb ; +} + +template < class A > int Hface4Top < A > :: level () const { + return _lvl ; +} + +template < class A > typename Hface4Top < A > :: myhedge1_t * +Hface4Top < A > :: subedge1 (int i,int j) { + assert(j == 0 || j == 1) ; + return this->myhedge1 (i)->subedge1 (j ? 1 - this->twist(i) : this->twist(i)) ; +} + +template < class A > const typename Hface4Top < A > :: myhedge1_t * +Hface4Top < A > :: subedge1 (int i,int j) const { + assert(j == 0 || j == 1) ; + return this->myhedge1 (i)->subedge1 (j ? 1 - this->twist(i) : this->twist(i)) ; +} + +template < class A > typename Hface4Top < A > :: innervertex_t * +Hface4Top < A > :: subvertex (int) { + assert (getrule() == myrule_t :: iso4) ; + return _cv ; +} + +template < class A > const typename Hface4Top < A > :: innervertex_t * +Hface4Top < A > :: subvertex (int) const { + assert (getrule() == myrule_t :: iso4) ; + return _cv ; +} + +template < class A > typename Hface4Top < A > :: inneredge_t * +Hface4Top < A > :: subedge1 (int n) { + inneredge_t * e = _ed ; + for (int i = 0 ; i < n ; i ++ ) e = e ? e->next () : 0 ; + assert (e) ; + return e ; +} + +template < class A > const typename Hface4Top < A > :: inneredge_t * +Hface4Top < A > :: subedge1 (int n) const { + const inneredge_t * e = _ed ; + for (int i = 0 ; i < n ; i ++ ) e = e ? e->next () : 0 ; + assert (e) ; + return e ; +} + +template < class A > typename Hface4Top < A > :: innerface_t * +Hface4Top < A > :: subface4 (int n) { + innerface_t * f = this->down () ; + for (int i = 0 ; i < n ; i++ ) f = f ? f->next () : 0 ; + assert (f) ; + return f ; +} + +template < class A > const typename Hface4Top < A > :: innerface_t * +Hface4Top < A > :: subface4 (int n) const { + const innerface_t * f = this->down () ; + for (int i = 0 ; i < n ; i++ ) f = f ? f->next () : 0 ; + assert (f) ; + return f ; +} + +template < class A > inline Hface4Top < A > :: Hface4Top (int l, myhedge1_t * e0, int t0, myhedge1_t * e1, int t1, + myhedge1_t * e2, int t2, myhedge1_t * e3, int t3, IndexManagerType & im) + : A (e0, t0, e1, t1, e2, t2, e3, t3), + _dwn (0), _bbb (0), _cv (0), _ed (0), _lvl (l), + _rule (myrule_t :: nosplit) , _indexManager(im) { + this->setIndex( _indexManager.getIndex() ); + return ; +} + +template < class A > Hface4Top < A > :: ~Hface4Top () { + _indexManager.freeIndex( this->getIndex() ); + if (_bbb) delete _bbb ; + if (_dwn) delete _dwn ; + if (_ed) delete _ed ; + if (_cv) delete _cv ; + return ; +} + +template < class A > typename Hface4Top < A > :: innervertex_t * +Hface4Top < A > :: innerVertex () { + return _cv ; +} + +template < class A > const typename Hface4Top < A > :: innervertex_t * +Hface4Top < A > :: innerVertex () const { + return _cv ; +} + +template < class A > typename Hface4Top < A > :: inneredge_t * +Hface4Top < A > :: innerHedge () { + return _ed ; +} + +template < class A > const typename Hface4Top < A > :: inneredge_t * +Hface4Top < A > :: innerHedge () const { + return _ed ; +} + +template < class A > inline void Hface4Top < A > :: append (innerface_t * f) { + assert (_bbb == 0) ; + _bbb = f ; + return ; +} + +template < class A > typename Hface4Top < A > :: myrule_t +Hface4Top < A > :: getrule () const { + return myrule_t (_rule) ; +} + +template < class A > inline IndexManagerType & Hface4Top < A > :: getEdgeIndexManager () { + return static_cast<inneredge_t &> (*(this->subedge1(0))).getIndexManager(); +} + +template < class A > void Hface4Top < A > :: splitISO4 () { + int l = 1 + level () ; + assert (_cv == 0 && _ed == 0 && _dwn == 0) ; + { + BilinearSurfaceMapping + map(this->myvertex (0)->Point(), + this->myvertex (1)->Point(), + this->myvertex (2)->Point(), + this->myvertex (3)->Point()) ; + double p [3] ; + map.map2world( .0, .0, p) ; + // myvertex(0) is submitted for the indexmanager reference + _cv = new innervertex_t (l, p[0], p[1], p[2], *(this->myvertex(0))) ; + assert (_cv) ; + } + myvertex_t * ev0 = this->myhedge1(0)->subvertex (0) ; + myvertex_t * ev1 = this->myhedge1(1)->subvertex (0) ; + myvertex_t * ev2 = this->myhedge1(2)->subvertex (0) ; + myvertex_t * ev3 = this->myhedge1(3)->subvertex (0) ; + assert(ev0 && ev1 && ev2 && ev3) ; + + IndexManagerType & im = getEdgeIndexManager(); + inneredge_t * e0 = new inneredge_t (l, ev0, _cv, im) ; + inneredge_t * e1 = new inneredge_t (l, ev1, _cv, im) ; + inneredge_t * e2 = new inneredge_t (l, ev2, _cv, im) ; + inneredge_t * e3 = new inneredge_t (l, ev3, _cv, im) ; + assert( e0 && e1 && e2 && e3) ; + e0->append(e1) ; + e1->append(e2) ; + e2->append(e3) ; + innerface_t * f0 = new innerface_t (l, this->subedge1(0,0), this->twist(0), e0, 0, e3, 1, this->subedge1(3,1), this->twist(3), _indexManager ) ; + innerface_t * f1 = new innerface_t (l, this->subedge1(0,1), this->twist(0), this->subedge1(1,0), this->twist(1), e1, 0, e0, 1, _indexManager ) ; + innerface_t * f2 = new innerface_t (l, e1, 1, this->subedge1(1,1), this->twist(1), this->subedge1(2,0), this->twist(2), e2, 0, _indexManager ) ; + innerface_t * f3 = new innerface_t (l, e3, 0, e2, 1, this->subedge1(2,1), this->twist(2), this->subedge1(3,0), this->twist(3), _indexManager ) ; + assert (f0 && f1 && f2 && f3) ; + f0->append(f1) ; + f1->append(f2) ; + f2->append(f3) ; + _ed = e0 ; + _dwn = f0 ; + _rule = myrule_t :: iso4 ; + return ; +} + +template < class A > void Hface4Top < A > :: refineImmediate (myrule_t r) { + if (r != getrule ()) { + assert (getrule () == myrule_t :: nosplit) ; + switch(r) { + typedef typename myhedge1_t :: myrule_t myhedge1rule_t; + case myrule_t :: iso4 : + this->myhedge1 (0)->refineImmediate (myhedge1rule_t (myhedge1_t :: myrule_t :: iso2).rotate (this->twist (0))) ; + this->myhedge1 (1)->refineImmediate (myhedge1rule_t (myhedge1_t :: myrule_t :: iso2).rotate (this->twist (1))) ; + this->myhedge1 (2)->refineImmediate (myhedge1rule_t (myhedge1_t :: myrule_t :: iso2).rotate (this->twist (2))) ; + this->myhedge1 (3)->refineImmediate (myhedge1rule_t (myhedge1_t :: myrule_t :: iso2).rotate (this->twist (3))) ; + splitISO4 () ; + break ; + default : + cerr << "**FEHLER (FATAL) falsche Verfeinerungsregel [" << r ; + cerr << "] in " << __FILE__ << " " << __LINE__ << endl ; + abort () ; + break ; + } +// ?? // Die nichtkonforme Nachbarschaft noch erg"anzen und auf der +// ?? // Fl"ache die Situation nach der Verfeinerung vervollst"andigen. +// ?? +// ?? {for (innerface_t * f = down () ; f ; f = f->next ()) f->nb = nb ; } + this->postRefinement () ; + } + return ; +} + +template < class A > bool Hface4Top < A > :: refine (myrule_t r, int twist) { + if (r != getrule ()) { + assert (getrule () == myrule_t :: nosplit ? 1 : + (cerr << "**FEHLER beim Verfeinern mit Regel " << r << " auf " << getrule () << endl, 0)) ; + switch(r) { + case myrule_t :: iso4 : + { + + bool a = twist < 0 ? this->nb.front ().first->refineBalance (r,this->nb.front ().second) + : this->nb.rear ().first->refineBalance (r,this->nb.rear ().second) ; + + if (a) { + if (getrule () == myrule_t :: nosplit) { + refineImmediate (r) ; + {for (innerface_t * f = down () ; f ; f = f->next ()) f->nb = this->nb ; } + } else { + assert (getrule () == myrule_t :: iso4) ; + } + return true ; + } else { + return false ; + } + } + default : + cerr << "**WARNUNG (IGNORIERT) falsche Verfeinerungsregel gefunden: " ; + cerr << "[" << r << "] in " << __FILE__ << " " << __LINE__ << endl ; + return false ; + } + } + return true ; +} + +template < class A > bool Hface4Top < A > :: coarse () { + innerface_t * f = down() ; + if (!f) return false ; + bool x = true ; + do { + + // Falls eine Kind-Fl"ache noch referenziert wird, kann + // nicht auf diesem Level vergr"obert werden. + // Daher wird nur die nichtkonforme Nachbarschaft ver- + // vollst"andigt, die eventuell durch Elementvergr"oberung + // durcheinander gekommen war. Die Vergr"oberung geht dann + // auf das n"achste Level "uber. + + if (f->ref) { + if (f->ref == 1) f->nb.complete (this->nb) ; + f->coarse () ; + x = false ; + } + } while (f = f->next()) ; + if (x) { + + // Hier wird tats"achlich vergr"obert, d.h. alle Kinder + // werden beseitigt, und das Bezugsobjekt wird zum neuen + // Blatt im Baum. + + delete _dwn ; + _dwn = 0 ; + delete _ed ; + _ed = 0 ; + delete _cv ; + _cv = 0 ; + _rule = myrule_t :: nosplit ; + {for (int i = 0 ; i < 4 ; i ++ ) this->myhedge1 (i)->coarse () ; } + } + return x ; +} + +template < class A > void Hface4Top < A > :: backup (ostream & os) const { + os.put ((char) getrule ()) ; + {for (const inneredge_t * e = innerHedge () ; e ; e = e->next ()) e->backup (os) ; } + {for (const innerface_t * c = down () ; c ; c = c->next ()) c->backup (os) ; } + return ; +} + +template < class A > void Hface4Top < A > :: restore (istream & is) { + refineImmediate (myrule_t ((char) is.get ())) ; + {for (inneredge_t * e = innerHedge () ; e ; e = e->next ()) e->restore (is) ; } + {for (innerface_t * c = down () ; c ; c = c->next ()) c->restore (is) ; } + return ; +} + +// # # # ####### +// # # ##### # # ##### # # # #### ##### +// # # # # ## # # # # # # # # # # +// ####### ##### # # # # # # # # # # # # +// # # # # # # # # # ####### # # # ##### +// # # # # # ## # # # # # # # +// # # ##### # # ##### # # #### # + +template < class A > inline Hbnd4Top < A > :: Hbnd4Top (int l, myhface4_t * f, int i, ProjectVertex *ppv, innerbndseg_t * up) + : A (f, i,ppv), _bbb (0), _dwn (0), _up(up) , _lvl (l), _bt(_up->_bt) , _indexManager(_up->_indexManager) { + this->setIndex( _indexManager.getIndex() ); + return ; +} + +template < class A > inline Hbnd4Top < A > :: Hbnd4Top (int l, myhface4_t * f, int i, ProjectVertex *ppv, bnd_t bt , IndexManagerType & im ) + : A (f, i,ppv), _bbb (0), _dwn (0), _up(0) , _lvl (l) , _bt(bt) , _indexManager(im) { + this->setIndex( _indexManager.getIndex() ); + return ; +} + +template < class A > Hbnd4Top < A > :: ~Hbnd4Top () { + _indexManager.freeIndex( this->getIndex() ); + if (_bbb) delete _bbb ; + if (_dwn) delete _dwn ; + return ; +} + +template < class A > int Hbnd4Top < A > :: level () const { + return _lvl ; +} + +template < class A > typename Hbnd4Top < A > :: innerbndseg_t * Hbnd4Top < A > :: next () { + return _bbb ; +} + +template < class A > const typename Hbnd4Top < A > :: innerbndseg_t * Hbnd4Top < A > :: next () const { + return _bbb ; +} + +template < class A > typename Hbnd4Top < A > :: innerbndseg_t * Hbnd4Top < A > :: down () { + return _dwn ; +} + +template < class A > const typename Hbnd4Top < A > :: innerbndseg_t * Hbnd4Top < A > :: down () const { + return _dwn ; +} + +template < class A > typename Hbnd4Top < A > :: innerbndseg_t * Hbnd4Top < A > :: up () { + return _up ; +} + +template < class A > const typename Hbnd4Top < A > :: innerbndseg_t * Hbnd4Top < A > ::up () const { + return _up ; +} + +template < class A > inline void Hbnd4Top < A > :: append (innerbndseg_t * b) { + assert (_bbb == 0) ; + _bbb = b ; + return ; +} + +template < class A > bool Hbnd4Top < A > :: coarse () { + innerbndseg_t * b = down () ; + if (!b) return false ; + bool x = true ; + do { + if(b->myhface4(0)->ref > 1) (b->coarse (), x = false) ; + } while (b = b->next()) ; + if (x) { + if (! this->lockedAgainstCoarsening ()) { + this->preCoarsening () ; + delete _dwn ; + _dwn = 0 ; + this->myhface4 (0)->coarse () ; + } + } + return x ; +} + +template < class A > inline bool Hbnd4Top < A > :: bndNotifyCoarsen () { + return coarse () ; +} + +template < class A > inline void Hbnd4Top < A > :: splitISO4 () { + int l = 1 + level () ; + assert (_dwn == 0) ; + innerbndseg_t * b0 = new innerbndseg_t (l, this->subface4 (0,0), this->twist (0), this->projection, this) ; + innerbndseg_t * b1 = new innerbndseg_t (l, this->subface4 (0,1), this->twist (0), this->projection, this) ; + innerbndseg_t * b2 = new innerbndseg_t (l, this->subface4 (0,2), this->twist (0), this->projection, this) ; + innerbndseg_t * b3 = new innerbndseg_t (l, this->subface4 (0,3), this->twist (0), this->projection, this) ; + assert (b0 && b1 && b2 && b3) ; + b0->append(b1) ; + b1->append(b2) ; + b2->append(b3) ; + _dwn = b0 ; + return ; +} + +template < class A > inline bool Hbnd4Top < A > :: refineBalance (balrule_t r, int b) { + + // Die Methode refineBalance () f"uhrt auf dem Randabschluss entweder + // unbedingt die Verfeinerung durch, da im Verlauf der Verfeinerung keine + // weiteren Anforerungen mehr an den Randabschluss gerichtet werden + // ODER gibt die Verfeinerung als nicht erf"ullt zur"uck: Dann liegt + // es am Aufrufer die Verfeinerung nochmals anzuforern. + + assert (b == 0) ; + assert (this->leaf ()) ; + if (! bndNotifyBalance (r,b)) { + + // Hier kann der innere Rand [parallel] die Verfeinerung + // verhindern, damit z.B. das Durchverfeinern im anisotropen + // Fall erstmal nicht stattfindet, wenn nicht klar ist, wie die + // weitere Rekursion aussieht. Dazu muss auf dem Niveau der Klasse + // des Template-Arguments die Methode bndNotifyBalance () "uber- + // schrieben werden. Die Defaultmethode liefert immer 'true'. + + return false ; + } else { + if(r == myrule_t :: iso4) { + + // Der Rand verfeinert unbedingt die anliegende Fl"ache und dann + // sich selbst, weil die Anforderung durch die Fl"ache kam, und + // dahinter keine Balancierung stattfinden muss. + + this->myhface4 (0)->refineImmediate (r) ; + splitISO4 () ; + } else { + cerr << "**FEHLER (FATAL, weil nicht vorgesehen) beim Verfeinern am " ; + cerr << "Randst\"uck mit der Regel [" << r << "] in " ; + cerr << __FILE__ << " " << __LINE__ << endl ; + abort () ; + } + + // postRefinement () gibt die M"oglichkeit auf dem Niveau des + // Template-Arguments eine Methode aufzurufen, um eventuelle + // Operationen auf dem verfeinerten Randst"uck aufzurufen. + + this->postRefinement () ; + return true ; + } +} + +template < class A > inline bool Hbnd4Top < A > :: refineLikeElement (balrule_t r) { + + // Mit der Methode refineLikeElement () verh"alt sich ein Randabschluss + // in der Verfeinerung wie ein Element: Es wird zuerst gepr"uft ob eine + // Balancierung der Vererfeinerung durch die Fl"ache hindurch erfolgreich + // ist und nur genau dann die Verfeinerung durchgef"uhrt mit R"uckgabewert + // 'true'. Diese Methode bedient eigentlich nur die parallele Verfeinerung + // kann aber auch auf jedem beliebigen Randelement im seriellen Fall auf- + // gerufen werden ohne Schaden anzurichten: Eine 1-Level Verfeinerung am + // Rand ist jedoch wirkungslos, da sie beim n"achsten Vergr"obern wieder + // aufgel"ost ist. Erst die mehrfache Anwendung f"uhrt durch die + // Balancierung zu einer "Anderung am Elementgitter. + + if (r == myrule_t :: nosplit) { + cerr << "**WARNUNG (IGNORIERT) beim Versuch mit nosplit zu Verfeinern" ; + cerr << " in " << __FILE__ << " " << __LINE__ << endl ; + + // Eine Anforderung mit nosplit zu Verfeinern nur erf"ullt, + // falls die zugeh"orige Fl"achenregel auch nosplit ist, sonst + // wird die Anforderung als nicht erf"ullt zur"uckgegeben. + + return this->getrule () == balrule_t :: nosplit ? true : false ; + } else { + if (this->getrule () == r) { + + // Alles schon wie es sein soll -> true. + + return true ; + } else { + + // Der nachfolgende Test bezieht sich auf die Verfeinerungssituation + // der Fl"ache, da getrule () auf myhface4 (0)->getrule () umgeleitet + // ist. + + assert (this->getrule () == myrule_t :: nosplit) ; + switch (r) { + case balrule_t :: iso4 : + if (! this->myhface4 (0)->refine(balrule_t (balrule_t :: iso4).rotate (this->twist (0)), this->twist (0))) return false ; + splitISO4 () ; + return true ; + default : + cerr << "**WARNUNG (FEHLER IGNORIERT) falsche Verfeinerungsregel [" << this->getrule () ; + cerr << "] (ignoriert) in " << __FILE__ << " " << __LINE__ << endl ; + return false ; + } + } + } +} + +template < class A > void Hbnd4Top < A > :: restoreFollowFace () { + + // retoreFollowFace () veranlasst das Randelement sich am + // bestehenden Fl"achenbaum wiederherzustellen durch die + // entsprechende Verfeinerung. + + myhface4_t & f (*(this->myhface4 (0))) ; + if (!f.leaf ()) { + balrule_t r = f.getrule () ; + switch (r) { + case myrule_t :: iso4 : + splitISO4 () ; + break ; + default : + cerr << "**FEHLER (FATAL, weil nicht vorgesehen) beim Verfeinern am " ; + cerr << "Randst\"uck mit der Regel [" << r << "] in " ; + cerr << __FILE__ << " " << __LINE__ << endl ; + abort () ; + break ; + } + this->postRefinement () ; + {for (innerbndseg_t * b = down () ; b ; b = b->next ()) b->restoreFollowFace () ; } + } + return ; +} + +// # # ####### +// # # ###### # # ## # #### ##### +// # # # # # # # # # # # # +// ####### ##### ## # # # # # # # +// # # # ## ###### # # # ##### +// # # # # # # # # # # # +// # # ###### # # # # # #### # + +template < class A > inline typename HexaTop < A > :: myhedge1_t * HexaTop < A > :: subedge1 (int i, int j) { + return (j < 4) ? ((this->twist (i) < 0) ? this->myhface4 (i)->myhedge1 ((8 - j + this->twist (i)) % 4) : + this->myhface4 (i)->myhedge1 ((j + this->twist (i)) % 4)) : + ((this->twist (i) < 0) ? this->myhface4 (i)->subedge1 ((12 - j + this->twist (i)) % 4) : + this->myhface4 (i)->subedge1 ((j + this->twist (i)) % 4)) ; +} + +template < class A > inline const typename HexaTop < A > :: myhedge1_t * HexaTop < A > :: subedge1 (int i, int j) const { + return (j < 4) ? ((this->twist (i) < 0) ? this->myhface4 (i)->myhedge1 ((8 - j + this->twist (i)) % 4) : + this->myhface4 (i)->myhedge1 ((j + this->twist (i)) % 4)) : + ((this->twist (i) < 0) ? this->myhface4 (i)->subedge1 ((12 - j + this->twist (i)) % 4) : + this->myhface4 (i)->subedge1 ((j + this->twist (i)) % 4)) ; +} + +template < class A > inline typename HexaTop < A > :: myhface4_t * HexaTop < A > :: subface4 (int i, int j) { + return (this->myhface4(i)->getrule() == myhface4_t :: myrule_t :: iso4) ? + this->myhface4(i)->subface4(this->twist(i) < 0 ? (9 - j + this->twist(i)) % 4 : (j + this->twist(i)) % 4) : + (abort (), (myhface4_t *)0) ; +} + +template < class A > inline const typename HexaTop < A > :: myhface4_t * HexaTop < A > :: subface4 (int i, int j) const { + return (this->myhface4(i)->getrule() == myhface4_t :: myrule_t :: iso4) ? + this->myhface4(i)->subface4(this->twist(i) < 0 ? (9 - j + this->twist(i)) % 4 : (j + this->twist(i)) % 4) : + (abort (), (const myhface4_t *)0) ; +} + +template < class A > inline HexaTop < A > :: HexaTop (int l, myhface4_t * f0, int t0, myhface4_t * f1, int t1, + myhface4_t * f2, int t2, myhface4_t * f3, int t3, myhface4_t * f4, int t4, myhface4_t * f5, int t5, IndexManagerType & im ) + : A (f0, t0, f1, t1, f2, t2, f3, t3, f4, t4, f5, t5) + , _bbb (0), _dwn (0), _up(0), _fc (0), _ed (0), _cv (0), _lvl (l), + _rule (myrule_t :: nosplit), _req (myrule_t :: nosplit), _indexManager(im) { + this->setIndex( _indexManager.getIndex() ); + return ; +} + +template < class A > inline HexaTop < A > :: HexaTop (int l, myhface4_t * f0, int t0, myhface4_t * f1, int t1, + myhface4_t * f2, int t2, myhface4_t * f3, int t3, myhface4_t * f4, int t4, myhface4_t * f5, int t5, innerhexa_t * up ) + : A (f0, t0, f1, t1, f2, t2, f3, t3, f4, t4, f5, t5) + , _bbb (0), _dwn (0), _up(up), _fc (0), _ed (0), _cv (0), _lvl (l), + _rule (myrule_t :: nosplit), _req (myrule_t :: nosplit), _indexManager(_up->_indexManager) { + this->setIndex( _indexManager.getIndex() ); + return ; +} + +template < class A > HexaTop < A > :: ~HexaTop () { + _indexManager.freeIndex( this->getIndex() ); + if (_bbb) delete _bbb ; + if (_dwn) delete _dwn ; + if (_fc) delete _fc ; + if (_ed) delete _ed ; + if (_cv) delete _cv ; + return ; +} + +template < class A > inline typename HexaTop < A > :: innerhexa_t * HexaTop < A > :: up () { + return _up ; +} + +template < class A > inline const typename HexaTop < A > :: innerhexa_t * HexaTop < A > :: up () const { + return _up ; +} + +template < class A > inline typename HexaTop < A > :: innerhexa_t * HexaTop < A > :: down () { + return _dwn ; +} + +template < class A > inline const typename HexaTop < A > :: innerhexa_t * HexaTop < A > :: down () const { + return _dwn ; +} + +template < class A > inline typename HexaTop < A > :: innerhexa_t * HexaTop < A > :: next () { + return _bbb ; +} + +template < class A > inline const typename HexaTop < A > :: innerhexa_t * HexaTop < A > :: next () const { + return _bbb ; +} + +template < class A > inline typename HexaTop < A > :: innervertex_t * HexaTop < A > :: innerVertex () { + return _cv ; +} + +template < class A > inline const typename HexaTop < A > :: innervertex_t * HexaTop < A > :: innerVertex () const { + return _cv ; +} + +template < class A > inline typename HexaTop < A > :: inneredge_t * HexaTop < A > :: innerHedge () { + return _ed ; +} + +template < class A > inline const typename HexaTop < A > :: inneredge_t * HexaTop < A > :: innerHedge () const { + return _ed ; +} + +template < class A > inline typename HexaTop < A > :: innerface_t * HexaTop < A > :: innerHface () { + return _fc ; +} + +template < class A > inline const typename HexaTop < A > :: innerface_t * HexaTop < A > :: innerHface () const { + return _fc ; +} + +template < class A > inline void HexaTop < A > :: append (HexaTop < A > * h) { + assert (_bbb == 0) ; + _bbb = h ; + return ; +} + +template < class A > int HexaTop < A > :: level () const { + return _lvl ; +} + +template < class A > inline IndexManagerType & HexaTop < A > :: getEdgeIndexManager () { + return static_cast<inneredge_t &> (*(this->subedge1(0,0))).getIndexManager(); +} + +template < class A > inline IndexManagerType & HexaTop < A > :: getFaceIndexManager () { + return static_cast<innerface_t &> (*(this->subface4(0,0))).getIndexManager(); +} + +template < class A > void HexaTop < A > :: splitISO8 () { + int l = 1 + level () ; + assert (_dwn == 0 && _fc == 0 && _ed == 0 && _cv == 0) ; + { + TrilinearMapping map( + this->myvertex(0)->Point(), this->myvertex(1)->Point(), + this->myvertex(2)->Point(), this->myvertex(3)->Point(), this->myvertex(4)->Point(), + this->myvertex(5)->Point(), this->myvertex(6)->Point(), this->myvertex(7)->Point()) ; + double p[3] ; + map.map2world(.0, .0, .0, p) ; + _cv = new innervertex_t (l, p[0], p[1], p[2], *(this->myvertex(0)) ) ; + assert (_cv) ; + } + myvertex_t * fv0 = this->myhface4 (0)->subvertex (0) ; + myvertex_t * fv1 = this->myhface4 (1)->subvertex (0) ; + myvertex_t * fv2 = this->myhface4 (2)->subvertex (0) ; + myvertex_t * fv3 = this->myhface4 (3)->subvertex (0) ; + myvertex_t * fv4 = this->myhface4 (4)->subvertex (0) ; + myvertex_t * fv5 = this->myhface4 (5)->subvertex (0) ; + assert(fv0 && fv1 && fv2 && fv3 && fv4 && fv5) ; + + IndexManagerType & im = getEdgeIndexManager(); + inneredge_t * e0 = new inneredge_t (l, fv0, _cv, im) ; + inneredge_t * e1 = new inneredge_t (l, fv1, _cv, im) ; + inneredge_t * e2 = new inneredge_t (l, fv2, _cv, im) ; + inneredge_t * e3 = new inneredge_t (l, fv3, _cv, im) ; + inneredge_t * e4 = new inneredge_t (l, fv4, _cv, im) ; + inneredge_t * e5 = new inneredge_t (l, fv5, _cv, im) ; + assert(e0 && e1 && e2 && e3 && e4 && e5) ; + e0->append(e1) ; + e1->append(e2) ; + e2->append(e3) ; + e3->append(e4) ; + e4->append(e5) ; + IndexManagerType & faceIm = getFaceIndexManager(); + innerface_t * f0 = new innerface_t (l, this->subedge1 (2, 7), 0, e2, 0, e5, 1, this->subedge1 (5, 4), 1, faceIm ) ; + innerface_t * f1 = new innerface_t (l, this->subedge1(2, 5), 1, this->subedge1 (3, 7), 0, e3, 0, e2, 1, faceIm ) ; + innerface_t * f2 = new innerface_t (l, e3, 1, this->subedge1 (3, 5), 1, this->subedge1 (4, 7), 0, e4, 0, faceIm ) ; + innerface_t * f3 = new innerface_t (l, e5, 0, e4, 1, this->subedge1 (4, 5), 1, this->subedge1 (5, 6), 0, faceIm ) ; + innerface_t * f4 = new innerface_t (l, this->subedge1 (0, 7), 0, e0, 0, e2, 1, this->subedge1 (2, 4), 1, faceIm ) ; + innerface_t * f5 = new innerface_t (l, this->subedge1 (0, 5), 1, this->subedge1 (4, 4), 0, e4, 0, e0, 1, faceIm ) ; + innerface_t * f6 = new innerface_t (l, e4, 1, this->subedge1 (4, 6), 1, this->subedge1 (1, 6), 0, e1, 0, faceIm ) ; + innerface_t * f7 = new innerface_t (l, e2, 0, e1, 1, this->subedge1 (1, 4), 1, this->subedge1 (2, 6), 0, faceIm ) ; + innerface_t * f8 = new innerface_t (l, this->subedge1 (0, 4), 0, e0, 0, e5, 1, this->subedge1 (5, 7), 1, faceIm ) ; + innerface_t * f9 = new innerface_t (l, this->subedge1 (0, 6), 1, this->subedge1 (3, 4), 0, e3, 0, e0, 1, faceIm ) ; + innerface_t * f10 = new innerface_t (l, e3, 1, this->subedge1 (3, 6), 1, this->subedge1 (1, 5), 0, e1, 0, faceIm ) ; + innerface_t * f11 = new innerface_t (l, e5, 0, e1, 1, this->subedge1 (1, 7), 1, this->subedge1 (5, 5), 0, faceIm ) ; + assert(f0 && f1 && f2 && f3 && f4 && f5 && f6 && f7 && f8 && f9 && f10 && f11) ; + f0->append(f1) ; + f1->append(f2) ; + f2->append(f3) ; + f3->append(f4) ; + f4->append(f5) ; + f5->append(f6) ; + f6->append(f7) ; + f7->append(f8) ; + f8->append(f9) ; + f9->append(f10) ; + f10->append(f11) ; + innerhexa_t * h0 = new innerhexa_t (l, this->subface4 (0, 0), this->twist (0), f0, 0, this->subface4 (2, 0), this->twist (2), f4, 0, f8, -4, this->subface4 (5, 0), this->twist (5) , this) ; + innerhexa_t * h1 = new innerhexa_t (l, this->subface4 (0, 3), this->twist (0), f1, 0, this->subface4 (2, 1), this->twist (2), this->subface4 (3, 0), this->twist (3), f9, -4, f4, -1, this) ; + innerhexa_t * h2 = new innerhexa_t (l, this->subface4 (0, 2), this->twist (0), f2, 0,f9, 0, subface4 (3, 1), this->twist (3), this->subface4 (4, 0), this->twist (4), f5, -1 , this) ; + innerhexa_t * h3 = new innerhexa_t (l, this->subface4 (0, 1), this->twist (0), f3, 0, f8, 0, f5, 0, this->subface4(4, 1), this->twist (4), this->subface4(5, 3), this->twist (5) , this) ; + innerhexa_t * h4 = new innerhexa_t (l, f0, -1, this->subface4(1, 0), this->twist (1), this->subface4(2, 3), this->twist (2), f7, 0, f11, -4, this->subface4(5, 1), this->twist (5) , this) ; + innerhexa_t * h5 = new innerhexa_t (l, f1, -1, this->subface4(1, 1), this->twist (1), this->subface4(2, 2), this->twist (2), this->subface4(3, 3), this->twist (3), f10, -4, f7, -1 , this) ; + innerhexa_t * h6 = new innerhexa_t (l, f2, -1, this->subface4(1, 2), this->twist (1), f10, 0, this->subface4(3, 2), this->twist (3), this->subface4(4, 3), this->twist (4), f6, -1 , this) ; + innerhexa_t * h7 = new innerhexa_t (l, f3, -1, this->subface4(1, 3), this->twist (1), f11, 0, f6, 0, this->subface4(4, 2), this->twist (4), this->subface4(5, 2), this->twist (5) , this) ; + assert(h0 && h1 && h2 && h3 && h4 && h5 && h6 && h7) ; + h0->append(h1) ; + h1->append(h2) ; + h2->append(h3) ; + h3->append(h4) ; + h4->append(h5) ; + h5->append(h6) ; + h6->append(h7) ; + _ed = e0 ; + _fc = f0 ; + _dwn = h0 ; + _rule = myrule_t :: iso8 ; + return ; +} + +template < class A > typename HexaTop < A > :: myrule_t HexaTop < A > :: getrule () const { + return myrule_t (_rule) ; +} + +template < class A > void HexaTop < A > :: request (myrule_t r) { + assert (r.isValid ()) ; + _req = r ; + return ; +} + +template < class A > void HexaTop < A > :: refineImmediate (myrule_t r) { + assert (getrule () == myrule_t :: nosplit) ; + switch(r) { + case myrule_t :: iso8 : + + // Das refineImmediate (..) auf allen Fl"achen wird vom Hexa :: refine (..) + // zwar nicht ben"otigt, da schliesslich alle Fl"achen sauber sind wenn + // "uberall hface4 :: refine (..) true geliefert hat, wohl aber z.B. von + // restore () oder abgeleiteten Funktionen die eine direkte Verfeinerung + // erzwingen m"ussen und d"urfen. + + { + typedef typename myhface4_t :: myrule_t myhface4rule_t; + for (int i = 0 ; i < 6 ; i ++) + this->myhface4 (i)->refineImmediate (myhface4rule_t (myhface4_t :: myrule_t :: iso4).rotate (this->twist (i))) ; } + splitISO8 () ; + break ; + default : + cerr << "**FEHLER (FATAL) beim unbedingten Verfeinern mit unbekannter Regel: " ; + cerr << "[" << r << "]. In " << __FILE__ << __LINE__ << endl ; + abort () ; + break ; + } + this->postRefinement () ; + return ; +} + +template < class A > bool HexaTop < A > :: refine () { + myrule_t r = _req ; + if (r != myrule_t :: crs && r != myrule_t :: nosplit) { + if (r != getrule ()) { + assert (getrule () == myrule_t :: nosplit) ; + _req = myrule_t :: nosplit ; + switch (r) { + case myrule_t :: crs : + case myrule_t :: nosplit : + return true ; + case myrule_t :: iso8 : + { + typedef typename myhface4_t :: myrule_t myhface4rule_t; + for (int i = 0 ; i < 6 ; i ++ ) + if (!this->myhface4 (i)->refine (myhface4rule_t (myhface4_t :: myrule_t :: iso4) + .rotate (this->twist (i)), this->twist (i))) return false ; + } + refineImmediate (r) ; + return true ; + default : + cerr << "**WARNUNG (FEHLER IGNORIERT) falsche Verfeinerungsregel [" << getrule () ; + cerr << "] (ignoriert) in " << __FILE__ << " " << __LINE__ << endl ; + return false ; + } + } + } + return true ; +} + +template < class A > bool HexaTop < A > :: refineBalance (balrule_t r, int fce) { + assert (r == balrule_t :: iso4) ; + if (getrule () == myrule_t :: nosplit) { + if (! this->myhface4 (fce)->leaf ()) { + for (int i = 0 ; i < 6 ; i ++) + if (i != fce) + if (!this->myhface4 (i)->refine (balrule_t (balrule_t :: iso4).rotate (this->twist (i)), this->twist (i))) + return false ; + _req = myrule_t :: nosplit ; + refineImmediate (myrule_t :: iso8) ; + } + } + return true ; +} + +template < class A > bool HexaTop < A > :: coarse () { + if (this->leaf ()) { + assert (_req == myrule_t :: nosplit || _req == myrule_t :: crs) ; + myrule_t w = _req ; + _req = myrule_t :: nosplit ; + if (w != myrule_t :: crs) return false ; + for (int i = 0 ; i < 6 ; i ++) if (!this->myhface4 (i)->leaf ()) return false ; + return true ; + } else { + assert (_req == myrule_t :: nosplit) ; + bool x = true ; + {for (innerhexa_t * h = down () ; h ; h = h->next ()) x &= h->coarse () ; } + if (x) { + this->preCoarsening () ; + delete _dwn ; + _dwn = 0 ; + delete _fc ; + _fc = 0 ; + delete _ed ; + _ed = 0 ; + delete _cv ; + _cv = 0 ; + _rule = myrule_t :: nosplit ; + { + for (int i = 0 ; i < 6 ; i ++ ) { + this->myneighbour (i).first->bndNotifyCoarsen () ; + this->myhface4 (i)->coarse () ; + } + } + return false ; + } + } + return false ; +} + +template < class A > bool HexaTop < A > :: bndNotifyCoarsen () { + return true ; +} + +template < class A > void HexaTop < A > :: backupCMode (ostream & os) const { + + // Das backup im alten Stil, d.h. levelweise die Verfeinerungsregeln + // vom Gitter runterschreiben. Diese Technik wird nur f"ur das backup + // noch unterst"utzt, um die Daten mit "alteren Konstruktionen visual. + // zu k"onnen. + + os << getrule () << " " ; + return ; +} + +template < class A > void HexaTop < A > :: backup (ostream & os) const { + os.put ((char) getrule ()) ; + {for (const inneredge_t * e = innerHedge () ; e ; e = e->next ()) e->backup (os) ; } + {for (const innerface_t * f = innerHface () ; f ; f = f->next ()) f->backup (os) ; } + {for (const innerhexa_t * c = down () ; c ; c = c->next ()) c->backup (os) ; } + return ; +} + +template < class A > void HexaTop < A > :: restore (istream & is) { + + // restore () stellt den Elmentbaum aus der Verfeinerungs + // geschichte wieder her. Es ruft refine () auf und testet + // auf den korrekten Vollzug der Verfeinerung. Danach werden + // die inneren Gitterteile restore'd. + + myrule_t r ((char) is.get ()) ; + assert(getrule() == myrule_t :: nosplit) ; + if (r == myrule_t :: nosplit) { + + // Vorsicht: beim restore m"ussen sich sowohl Element als auch + // Randelement um die Korrektheit der Nachbarschaft k"ummern, + // und zwar dann wenn sie "on the top" sind (= die gelesene + // Verfeinerungsregel ist nosplit). (s.a. beim Randelement) + + for (int i = 0 ; i < 6 ; i ++) { + myhface4_t & f (*(this->myhface4 (i))) ; + if (!f.leaf ()) { + for (int j = 0 ; j < 4 ; j ++) f.subface4 (j)->nb.complete (f.nb) ; + } + } + } else { + request (r) ; + refine () ; + assert (getrule() == r) ; + {for (inneredge_t * e = innerHedge () ; e ; e = e->next ()) e->restore (is) ; } + {for (innerface_t * f = innerHface () ; f ; f = f->next ()) f->restore (is) ; } + {for (innerhexa_t * c = down () ; c ; c = c->next ()) c->restore (is) ; } + } + return ; +} + +// Anfang - Neu am 23.5.02 (BS) + +// ###### # ####### +// # # ###### ##### # #### ##### # #### # # # +// # # # # # # # # # # # # # # # # +// ###### ##### # # # # # # # # # # # # +// # # ##### # # # # # # # ####### # +// # # # # # # # # # # # # # # +// # ###### # # # #### ##### # #### # # + + +template < class A > inline Periodic4Top < A > :: Periodic4Top (int l, myhface4_t * f0, int t0, + myhface4_t * f1, int t1) : A (f0, t0, f1, t1), _dwn (0), _bbb (0), _up(0), _lvl (l), + _rule (myrule_t :: nosplit) { // ok + return ; +} + +template < class A > inline Periodic4Top < A > :: ~Periodic4Top () { // ok + if (_bbb) delete _bbb ; + if (_dwn) delete _dwn ; + return ; +} + +template < class A > inline int Periodic4Top < A > :: level () const { // ok + return _lvl ; +} + +//us eingefuegt +template < class A > inline typename Periodic4Top < A > :: innerperiodic4_t * Periodic4Top < A > :: up () { + return _up ; +} + +template < class A > inline const typename Periodic4Top < A > :: innerperiodic4_t * Periodic4Top < A > :: up () const { + return _up ; +} +//ende us + +template < class A > inline typename Periodic4Top < A > :: innerperiodic4_t * Periodic4Top < A > :: down () { // ok + return _dwn ; +} + +template < class A > inline const typename Periodic4Top < A > :: innerperiodic4_t * Periodic4Top < A > :: down () const { // ok + return _dwn ; +} + +template < class A > inline typename Periodic4Top < A > :: innerperiodic4_t * Periodic4Top < A > :: next () { // ok + return _bbb ; +} + +template < class A > inline const typename Periodic4Top < A > :: innerperiodic4_t * Periodic4Top < A > :: next () const { // ok + return _bbb ; +} + +template < class A > inline typename Periodic4Top < A > :: innervertex_t * Periodic4Top < A > :: innerVertex () { // ok + return 0 ; +} + +template < class A > inline const typename Periodic4Top < A > :: innervertex_t * Periodic4Top < A > :: innerVertex () const { // ok + return 0 ; +} + +template < class A > inline typename Periodic4Top < A > :: inneredge_t * Periodic4Top < A > :: innerHedge () { // ok + return 0 ; +} + +template < class A > inline const typename Periodic4Top < A > :: inneredge_t * Periodic4Top < A > :: innerHedge () const { // ok + return 0 ; +} + +template < class A > inline typename Periodic4Top < A > :: innerface_t * Periodic4Top < A > :: innerHface () { // ok + return 0 ; +} + +template < class A > inline const typename Periodic4Top < A > :: innerface_t * Periodic4Top < A > :: innerHface () const { // ok + return 0 ; +} + +template < class A > inline void Periodic4Top < A > :: append (Periodic4Top < A > * h) { // ok + assert (_bbb == 0) ; + _bbb = h ; + return ; +} + +template < class A > typename Periodic4Top < A > :: myhedge1_t * Periodic4Top < A > :: subedge1 (int i, int j) { // ?? + assert (getrule () == myrule_t :: iso4) ; + return (j < 4) ? ((this->twist (i) < 0) ? this->myhface4 (i)->myhedge1 ((8 - j + this->twist (i)) % 4) : // aus dem Hexaeder + this->myhface4 (i)->myhedge1 ((j + this->twist (i)) % 4)) : + ((this->twist (i) < 0) ? this->myhface4 (i)->subedge1 ((12 - j + this->twist (i)) % 4) : + this->myhface4 (i)->subedge1 ((j + this->twist (i)) % 4)) ; +} + +template < class A > const typename Periodic4Top < A > :: myhedge1_t * Periodic4Top < A > :: subedge1 (int i, int j) const { // ok + return ((Periodic4Top < A > *)this)->subedge1 (i,j) ; +} + +template < class A > typename Periodic4Top < A > :: myhface4_t * Periodic4Top < A > :: subface4 (int i, int j) { // ok + return (this->myhface4(i)->getrule() == myhface4_t :: myrule_t :: iso4) ? + this->myhface4(i)->subface4(this->twist(i) < 0 ? (9 - j + this->twist(i)) % 4 : (j + this->twist(i)) % 4) : // Zeile aus dem Hexaeder + (abort (), (myhface4_t *)0) ; +} + +template < class A > const typename Periodic4Top < A > :: myhface4_t * Periodic4Top < A > :: subface4 (int i, int j) const { + return ((Periodic4Top < A > *)this)->subface4 (i,j) ; +} + +template < class A > typename Periodic4Top < A > :: myrule_t Periodic4Top < A > :: getrule () const { + return myrule_t (_rule) ; +} + +template < class A > void Periodic4Top < A > :: request (myrule_t) { + + // Einen Request zur Verfeinerung zu setzen, ist vorl"aufig inhaltlich nicht + // vorgesehen und wird deshalb ignoriert (leise). + + return ; +} + +template < class A > void Periodic4Top < A > :: splitISO4 () { // ok + int l = 1 + level () ; + innerperiodic4_t * p0 = new innerperiodic4_t (l, this->subface4 (0,0), this->twist (0), this->subface4 (1,0), this->twist (1)) ; + innerperiodic4_t * p1 = new innerperiodic4_t (l, this->subface4 (0,1), this->twist (0), this->subface4 (1,3), this->twist (1)) ; + innerperiodic4_t * p2 = new innerperiodic4_t (l, this->subface4 (0,2), this->twist (0), this->subface4 (1,2), this->twist (1)) ; + innerperiodic4_t * p3 = new innerperiodic4_t (l, this->subface4 (0,3), this->twist (0), this->subface4 (1,1), this->twist (1)) ; + assert (p0 && p1 && p2 && p3) ; + p0->append(p1) ; + p1->append(p2) ; + p2->append(p3) ; + _dwn = p0 ; + _rule = myrule_t :: iso4 ; + return ; +} + +template < class A > void Periodic4Top < A > :: refineImmediate (myrule_t r) { + + // Die Methode wird nur vom restore () und vom refineBalance () auf- + // gerufen und geht davon aus, dass das betroffene Element noch nicht + // verfeinert ist -> ist ein Blatt der Hierarchie. + + assert (this->leaf()) ; + switch (r) { + case myrule_t :: iso4 : + + // Das refineImmediate (..) auf allen Fl"achen wird vom periodic4 :: refine (..) + // zwar nicht ben"otigt, da schliesslich alle Fl"achen sauber sind, wenn + // "uberall hface4 :: refine (..) true geliefert hat, wohl aber z.B. von + // restore () oder abgeleiteten Funktionen, die eine direkte Verfeinerung + // erzwingen m"ussen und d"urfen. + + typedef typename myhface4_t :: myrule_t myhface4rule_t; + this->myhface4 (0)->refineImmediate (myhface4rule_t (r).rotate (this->twist (0))) ; + this->myhface4 (1)->refineImmediate (myhface4rule_t (r).rotate (this->twist (1))) ; + splitISO4 () ; + break ; + default : + cerr << "**FEHLER (FATAL) beim unbedingten Verfeinern mit unbekannter Regel: " ; + cerr << "[" << r << "]. In " << __FILE__ << __LINE__ << endl ; + abort () ; + break ; + } + this->postRefinement () ; + return ; +} + +template < class A > bool Periodic4Top < A > :: refine () { // ok + + // Das refine () reagiert nicht auf die Elementaktivierung zur Verfeinerung + // in der globalen Schleife, weil das perioodische Randelement sich nur auf + // Anforderung zur Balancierung aus einem anliegenden Element direkt verfeinert. + + return true ; +} + +template < class A > bool Periodic4Top < A > :: refineBalance (balrule_t r, int fce) { // ok + if (r != balrule_t :: iso4) { + cerr << "**WARNUNG (IGNORIERT) in Periodic4Top < A > :: refineBalance (..) nachschauen, Datei " + << __FILE__ << " Zeile " << __LINE__ << endl ; + + // Bisher kann die Balancierung nur die isotrope Achtelung handhaben, + // falls mehr gew"unscht wird, muss es hier eingebaut werden. Im Moment wird + // die Balancierung einfach verweigert, d.h. die Verfeinerung des anfordernden + // Elements f"allt flach. + + return false ; + } else { + + // Der nachfolgende Aufruf nutzt aus, dass die Regel der periodischen R"ander + // sich direkt auf die Balancierungsregel des entsprechenden Polygonverbinders + // projezieren l"asst (n"amlich 1:1). Deshalb unterscheidet der Aufruf nicht nach + // der angeforderten Regel in einer 'case' Anweisung. + + typedef typename myhface4_t :: myrule_t myhface4rule_t; + int opp = fce == 0 ? 1 : 0 ; + if (this->myhface4 (opp)->refine (myhface4rule_t (r).rotate (this->twist (opp)), this->twist (opp))) { + refineImmediate (r) ; + return true ; + } else { + return false ; + } + } +} + +template < class A > bool Periodic4Top < A > :: coarse () { // ok + + // Das Vergr"obern geschieht auch passiv, sobald ein anliegendes Element + // vergr"obert wird durch den Aufruf von "bndNotifyCoarsen ()" s.u. + + bndNotifyCoarsen () ; + return false ; +} + +template < class A > bool Periodic4Top < A > :: bndNotifyCoarsen () { + + // Wie beim Randelement auch: Die Vergr"oberung eines anliegenden Elements + // l"ost einen Vorgang aus, der feststellt ob das periodische RE ebenfalls + // vergr"obert werden soll. + + innerperiodic4_t * p = down () ; + if (!p) return false ; + bool x = true ; + do { + + // Falls p kein Blatt der Hierarchie ist, + // die Vergr"oberungsm"oglichkeit weitergeben. + + if (!p->leaf ()) p->coarse () ; + + // F"ur die hintere und vordere Fl"ache feststellen, ob + // der Referenzenz"ahler mehr als einen Eintrag ergibt. + + if (p->myhface4 (0)->ref > 1) (x = false) ; + if (p->myhface4 (1)->ref > 1) (x = false) ; + + } while (p = p->next ()) ; + if (x) { + + // Falls keine Fl"achen anliegen, die auf Kinder oder Kindes- + // mit mehr als einer Referenz f"uhren, ist sicher, dass das + // Bezugsrandelement zwischen zwei 'relativ groben' Elementen + // liegt. Somit kann es vergr"obert werden. + + this->preCoarsening () ; + delete _dwn ; + _dwn = 0 ; + _rule = myrule_t :: nosplit ; + this->myhface4 (0)->coarse () ; + this->myhface4 (1)->coarse () ; + } + return x ; +} + +template < class A > void Periodic4Top < A > :: backupCMode (ostream & os) const { + + // Das backup im alten Stil, d.h. levelweise die Verfeinerungsregeln + // vom Gitter runterschreiben. Diese Technik wird nur f"ur das backup + // noch unterst"utzt, um die Daten mit "alteren Konstruktionen visual. + // zu k"onnen. + + os << getrule () << " " ; + return ; +} + +template < class A > void Periodic4Top < A > :: backup (ostream & os) const { + os.put ((char) getrule ()) ; + {for (const innerperiodic4_t * c = down () ; c ; c = c->next ()) c->backup (os) ; } + return ; +} + +template < class A > void Periodic4Top < A > :: restore (istream & is) { + myrule_t r ((char) is.get ()) ; + assert(getrule () == myrule_t :: nosplit) ; // Testen auf unverfeinerten Zustand + if (r == myrule_t :: nosplit) { + for (int i = 0 ; i < 2 ; i ++) { + myhface4_t & f (*(this->myhface4 (i))) ; + if (!f.leaf ()) { + switch (f.getrule ()) { + case balrule_t :: iso4 : + {for (int j = 0 ; j < 4 ; j ++) f.subface4 (j)->nb.complete (f.nb) ;} + break ; + default : + cerr << "**FEHLER (FATAL) beim restore mit unbekannter Balancierungsregel: " + << "[" << r << "]. In " << __FILE__ << __LINE__ << endl ; + abort () ; + break ; + } + } + } + } else { + refineImmediate (r) ; + assert (getrule() == r) ; + {for (innerperiodic4_t * c = down () ; c ; c = c->next ()) c->restore (is) ; } + } + return ; +} + +// Ende - Neu am 23.5.02 (BS) + +#endif // GITTER_HEXA_TOP_H_INCLUDED diff --git a/src/serial/gitter_impl.h b/src/serial/gitter_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..83acf3ea01893849723eca594c26e20a9e0eeac6 --- /dev/null +++ b/src/serial/gitter_impl.h @@ -0,0 +1,543 @@ +// (c) bernhard schupp 1997 - 1998 + +#ifndef GITTER_IMPL_H_INCLUDED +#define GITTER_IMPL_H_INCLUDED + +#ifdef IBM_XLC + #define _ANSI_HEADER +#endif + +#ifdef _ANSI_HEADER + using namespace std; + #include <fstream> + #include <vector> + #include <utility> +#else + #include <fstream.h> + #include <vector.h> + #include <pair.h> +#endif + +#include "gitter_sti.h" + +#include "mapp_tetra_3d.h" + +#include "gitter_hexa_top.h" +#include "gitter_tetra_top.h" + +//static ofstream logFile ("logfile"); + +class GitterBasis : public virtual Gitter, public Gitter :: Geometric { + public : + class Objects { + public : + class VertexEmpty : public VertexGeo { + public : + inline VertexEmpty (int, double, double, double, + IndexManagerType &im) ; + inline VertexEmpty (int, double, double, double, + VertexGeo & ) ; + ~VertexEmpty () {} + virtual inline int ident () const ; + } ; + + class VertexEmptyMacro : public VertexEmpty { + public : + inline VertexEmptyMacro (double, double, double, int, + IndexManagerType &im) ; + ~VertexEmptyMacro () {} + virtual inline int ident () const ; + private : + int _idn ; + } ; + + // organizes the indices for boundary faces and the opposite vertices for + // ghost cells + template <int pdimvx> + class Dune_hbndDefault + { + protected: + enum { dimvx = pdimvx }; + int _index; + double _oppVx[dimvx][3]; + + public: + inline Dune_hbndDefault (); + inline void setOppPoint (int i, const double (&p)[3]); + inline const double (& oppositeVertex (int i) const) [3]; + + inline int getIndex () const; + inline void setIndex ( int idx ); + inline int dimVx () const; + + protected: + inline void splitGhost () {} + inline void setGhost (Gitter::helement_STI *) {} + }; + + class Hbnd3Default : public hbndseg3_GEO +#ifdef _DUNE_USES_BSGRID_ + , public Dune_hbndDefault<1> +#endif + { + protected : + inline Hbnd3Default (myhface3_t *, int, ProjectVertex * ) ; + virtual ~Hbnd3Default () {} + public : + typedef hbndseg3_GEO :: bnd_t bnd_t; + virtual inline bnd_t bndtype () const ; + virtual int ghostLevel () const ; + + // default implementation is doing nothing for these 3 methods + // these methods are overloades just on HbndPll + virtual helement_STI * getGhost () { return 0; } + + // points inside ghosts + void faceNormal( double * normal) const; + }; + typedef Hbnd3Top < Hbnd3Default > hbndseg3_IMPL ; + + class Hbnd4Default : public hbndseg4_GEO +#ifdef _DUNE_USES_BSGRID_ + , public Dune_hbndDefault<4> +#endif + { + protected : + inline Hbnd4Default (myhface4_t *, int, ProjectVertex *) ; + virtual ~Hbnd4Default () {} + public : + typedef hbndseg4_GEO :: bnd_t bnd_t; + virtual inline bnd_t bndtype () const ; + virtual int ghostLevel () const ; + + // default implementation is doing nothing for these 3 methods + // these methods are overloades just on HbndPll + virtual helement_STI * getGhost () { return 0; } + + // points inside ghosts + void faceNormal( double * normal) const; + }; + typedef Hbnd4Top < Hbnd4Default > hbndseg4_IMPL ; + + class Hedge1Empty : public hedge1_GEO { + protected : + typedef VertexEmpty innervertex_t ; + inline Hedge1Empty (myvertex_t *,myvertex_t *) ; + ~Hedge1Empty () {} + // Methode um einen Vertex zu verschieben; f"ur die Randanpassung + virtual inline void projectInnerVertex(const ProjectVertex &pv) ; + } ; + + typedef Hedge1Top < Hedge1Empty > hedge1_IMPL ; + + class Hface3Empty : public hface3_GEO { + protected : + typedef VertexEmpty innervertex_t ; + typedef hedge1_IMPL inneredge_t ; + inline Hface3Empty (myhedge1_t *,int, myhedge1_t *,int, myhedge1_t *,int) ; + ~Hface3Empty () {} + // Methode um einen Vertex zu verschieben; f"ur die Randanpassung + virtual inline void projectVertex(const ProjectVertex &pv) ; + } ; + typedef Hface3Top < Hface3Empty > hface3_IMPL ; + + class Hface4Empty : public hface4_GEO { + protected : + typedef VertexEmpty innervertex_t ; + typedef hedge1_IMPL inneredge_t ; + inline Hface4Empty (myhedge1_t *,int, myhedge1_t *,int, myhedge1_t *,int,myhedge1_t *,int) ; + ~Hface4Empty () {} + // Methode um einen Vertex zu verschieben; f"ur die Randanpassung + virtual inline void projectVertex(const ProjectVertex &pv) ; + } ; + typedef Hface4Top < Hface4Empty > hface4_IMPL ; + + class TetraEmpty : public tetra_GEO { + protected : + typedef hface3_IMPL innerface_t ; + typedef hedge1_IMPL inneredge_t ; + typedef VertexEmpty innervertex_t ; + inline TetraEmpty (myhface3_t *,int,myhface3_t *,int,myhface3_t *,int,myhface3_t *,int) ; + ~TetraEmpty () {} + public : + } ; + typedef TetraTop < TetraEmpty > tetra_IMPL ; + + class Periodic3Empty : public periodic3_GEO { + protected : + typedef hface3_IMPL innerface_t ; + typedef hedge1_IMPL inneredge_t ; + typedef VertexEmpty innervertex_t ; + inline Periodic3Empty (myhface3_t *,int,myhface3_t *,int) ; + ~Periodic3Empty () {} + public: + } ; + typedef Periodic3Top < Periodic3Empty > periodic3_IMPL ; + +// Anfang - Neu am 23.5.02 (BS) + class Periodic4Empty : public periodic4_GEO { + protected : + typedef hface4_IMPL innerface_t ; + typedef hedge1_IMPL inneredge_t ; + typedef VertexEmpty innervertex_t ; + inline Periodic4Empty (myhface4_t *,int,myhface4_t *,int) ; + ~Periodic4Empty () {} + public: + } ; + typedef Periodic4Top < Periodic4Empty > periodic4_IMPL ; +// Ende - Neu am 23.5.02 (BS) + + class HexaEmpty : public hexa_GEO { + protected : + typedef hface4_IMPL innerface_t ; + typedef hedge1_IMPL inneredge_t ; + typedef VertexEmpty innervertex_t ; + inline HexaEmpty (myhface4_t *,int,myhface4_t *,int,myhface4_t *,int,myhface4_t *,int,myhface4_t *,int,myhface4_t *,int) ; + ~HexaEmpty () {} + } ; + typedef HexaTop < HexaEmpty > hexa_IMPL ; + } ; + public : + class MacroGitterBasis : public virtual BuilderIF { + protected : + virtual inline VertexGeo * insert_vertex (double, double, double, int,int = 0) ; + virtual inline hedge1_GEO * insert_hedge1 (VertexGeo *, VertexGeo *) ; + virtual inline hface3_GEO * insert_hface3 (hedge1_GEO *(&)[3], int (&)[3]) ; + virtual inline hface4_GEO * insert_hface4 (hedge1_GEO *(&)[4], int (&)[4]) ; + virtual inline hbndseg3_GEO * insert_hbnd3 (hface3_GEO *, int, Gitter :: hbndseg_STI :: bnd_t) ; + // version with point , returns insert_hbnd3 here + virtual inline hbndseg3_GEO * insert_hbnd3 (hface3_GEO *, int, Gitter :: hbndseg_STI :: bnd_t, const double (&p)[3]) ; + virtual inline hbndseg4_GEO * insert_hbnd4 (hface4_GEO *, int, Gitter :: hbndseg_STI :: bnd_t) ; + virtual inline tetra_GEO * insert_tetra (hface3_GEO *(&)[4], int (&)[4]) ; + virtual inline periodic3_GEO * insert_periodic3 (hface3_GEO *(&)[2], int (&)[2]) ; +// Anfang - Neu am 23.5.02 (BS) + virtual inline periodic4_GEO * insert_periodic4 (hface4_GEO *(&)[2], int (&)[2]) ; +// Ende - Neu am 23.5.02 (BS) + virtual inline hexa_GEO * insert_hexa (hface4_GEO *(&)[6], int (&)[6]) ; + public : + inline MacroGitterBasis (istream &) ; + inline MacroGitterBasis () ; + virtual ~MacroGitterBasis () {} + + // return index manager mostly for restore and backup + inline IndexManagerType & indexManager(int codim); + + protected: + // index provider, for every codim one , 4 is for boundary + IndexManagerType _indexmanager[ numOfIndexManager ]; + } ; +} ; + +class GitterBasisImpl : public GitterBasis { + MacroGitterBasis * _macrogitter ; + public: + //us fuer Globalmethode levelwalk + inline Makrogitter & container () ; + inline const Makrogitter & container () const ; + public : + inline IndexManagerType & indexManager(int codim); + + inline GitterBasisImpl () ; + inline GitterBasisImpl (istream &) ; + inline GitterBasisImpl (const char *) ; + inline ~GitterBasisImpl () ; +} ; + + + // + // # # # # # # # ###### + // # ## # # # ## # # + // # # # # # # # # # ##### + // # # # # # # # # # # + // # # ## # # # ## # + // # # # ###### # # # ###### + // + +inline GitterBasis :: Objects :: VertexEmpty :: VertexEmpty (int l, double x, double y, double z, IndexManagerType & im) + : GitterBasis :: VertexGeo (l,x,y,z,im) { + return ; +} + +inline GitterBasis :: Objects :: VertexEmpty :: VertexEmpty (int l, double x, double y, double z, VertexGeo & vx ) + : GitterBasis :: VertexGeo (l,x,y,z,vx) { + return ; +} + +inline int GitterBasis :: Objects :: VertexEmpty :: ident () const { + cerr << "**FEHLER (FATAL) vertex :: ident () nur f\"ur level-0 Vertices zul\"assig " << endl ; + return (abort (), -1) ; +} + +inline GitterBasis :: Objects :: VertexEmptyMacro :: VertexEmptyMacro (double x,double y,double z,int i, IndexManagerType &im) + : GitterBasis :: Objects :: VertexEmpty (0,x,y,z,im), _idn (i) { + return ; +} + +inline int GitterBasis :: Objects :: VertexEmptyMacro :: ident () const { + return _idn ; +} + +inline GitterBasis :: Objects :: Hedge1Empty :: Hedge1Empty (myvertex_t * a, myvertex_t * b) + : Gitter :: Geometric :: hedge1_GEO (a,b) { + return ; +} + +inline void GitterBasis :: Objects :: Hedge1Empty :: projectInnerVertex(const ProjectVertex &pv) { + if (innerVertex()) { + assert(!leaf()); + innerVertex()->project(pv); + } +} + +inline GitterBasis :: Objects :: Hface3Empty :: Hface3Empty (myhedge1_t *e0, int s0, + myhedge1_t *e1, int s1, myhedge1_t *e2, int s2) : Gitter :: Geometric :: hface3_GEO (e0, s0, e1, s1, e2, s2) { + return ; +} + +inline void GitterBasis :: Objects :: Hface3Empty :: projectVertex(const ProjectVertex &pv) { + assert(!leaf()); + for (int e = 0; e < polygonlength; e++) + myhedge1(e)->projectInnerVertex(pv); + if (innerVertex()) + innerVertex()->project(pv); +} + +inline GitterBasis :: Objects :: Hface4Empty :: Hface4Empty (myhedge1_t *e0, int s0, + myhedge1_t *e1, int s1, myhedge1_t *e2, int s2, myhedge1_t *e3, int s3) + : Gitter :: Geometric :: hface4_GEO (e0, s0, e1, s1, e2, s2, e3, s3) { + return ; +} + +inline void GitterBasis :: Objects :: Hface4Empty :: projectVertex(const ProjectVertex &pv) { + for (int e = 0; e < polygonlength; e++) + myhedge1(e)->projectInnerVertex(pv); + if (innerVertex()) + innerVertex()->project(pv); +} + + +// Dune_hbndDefault +template <int pdimvx> +inline GitterBasis :: Objects :: Dune_hbndDefault<pdimvx> :: Dune_hbndDefault () : _index (-1) +{ + for(int i=0; i<dimvx; i++) + for(int j=0; j<3; j++) + _oppVx[i][j] = 0.0; +} + + +template <int pdimvx> +inline void GitterBasis :: Objects :: Dune_hbndDefault<pdimvx> :: setOppPoint (int i, const double (&p)[3]) +{ + assert((i >= 0) && (i < dimvx)); + _oppVx[i][0] = p[0]; + _oppVx[i][1] = p[1]; + _oppVx[i][2] = p[2]; + return; +} + +template <int pdimvx> +inline const double (& GitterBasis :: Objects :: Dune_hbndDefault<pdimvx> ::oppositeVertex (int i) const) [3] +{ + assert((i >= 0) && (i < dimvx)); + return _oppVx[i]; +} + +template <int pdimvx> inline int +GitterBasis :: Objects :: Dune_hbndDefault<pdimvx> :: getIndex () const +{ + assert( _index >= 0 ); + return _index; +} + +template <int pdimvx> inline void +GitterBasis :: Objects :: Dune_hbndDefault<pdimvx> :: setIndex ( int idx ) +{ + _index = idx; + return ; +} + +template <int pdimvx> inline int +GitterBasis :: Objects :: Dune_hbndDefault<pdimvx> :: dimVx () const { return dimvx; } + +// end of Dune_hbndDefault + + +inline GitterBasis :: Objects :: Hbnd3Default :: Hbnd3Default (myhface3_t * f, int i, ProjectVertex *ppv) : Gitter :: Geometric :: hbndseg3_GEO (f, i, ppv) +{ + return ; +} + +inline GitterBasis :: Objects ::Hbnd3Default :: bnd_t GitterBasis :: Objects :: Hbnd3Default :: bndtype () const { + return undefined ; +} + +inline int GitterBasis :: Objects :: Hbnd3Default :: ghostLevel () const { + assert(false); + return level() ; +} + +inline void GitterBasis :: Objects :: Hbnd3Default :: faceNormal( double * normal) const { + + hface3_GEO * face = this->myhface3(0); + int tw = this->twist(0); + BSGridLinearSurfaceMapping + LSM(face->myvertex( (tw < 0) ? 0 : 2 )->Point(), + face->myvertex( 1 )->Point(), + face->myvertex( (tw < 0) ? 2 : 0 )->Point() + ); + LSM.normal(normal); + return ; +} + +inline GitterBasis :: Objects :: Hbnd4Default :: Hbnd4Default (myhface4_t * f, int i, ProjectVertex *ppv) : Gitter :: Geometric :: hbndseg4_GEO (f, i,ppv) +{ + return ; +} + +inline GitterBasis :: Objects ::Hbnd4Default :: bnd_t GitterBasis :: Objects :: Hbnd4Default :: bndtype () const { + return undefined ; +} + +inline int GitterBasis :: Objects :: Hbnd4Default :: ghostLevel () const { + return level() ; +} + +inline void GitterBasis :: Objects :: Hbnd4Default :: faceNormal( double * normal) const { + cerr << "ERORR: Hbnd4Default :: faceNormal not implemented! " << __FILE__ << __LINE__ << endl; + return ; +} + +inline GitterBasis :: Objects :: TetraEmpty :: TetraEmpty (myhface3_t * f0, int t0, myhface3_t * f1, int t1, + myhface3_t * f2, int t2, myhface3_t * f3, int t3) : Gitter :: Geometric :: Tetra (f0, t0, f1, t1, f2, t2, f3, t3) { + return ; +} + +inline GitterBasis :: Objects :: Periodic3Empty :: Periodic3Empty (myhface3_t * f0, int t0, myhface3_t * f1, int t1) + : Gitter :: Geometric :: Periodic3 (f0, t0, f1, t1) { + return ; +} + +// Anfang - Neu am 23.5.02 (BS) +inline GitterBasis :: Objects :: Periodic4Empty :: Periodic4Empty (myhface4_t * f0, int t0, myhface4_t * f1, int t1) + : Gitter :: Geometric :: Periodic4 (f0, t0, f1, t1) { + return ; +} +// Ende - Neu am 23.5.02 (BS) + +inline GitterBasis :: Objects :: HexaEmpty :: HexaEmpty (myhface4_t * f0, int t0, myhface4_t * f1, int t1, + myhface4_t * f2, int t2, myhface4_t * f3, int t3, myhface4_t * f4, int t4, myhface4_t * f5, int t5) + : Gitter :: Geometric :: hexa_GEO (f0, t0, f1, t1, f2, t2, f3, t3, f4, t4, f5, t5) { + return ; +} + +inline GitterBasisImpl :: GitterBasisImpl () : _macrogitter (0) { + _macrogitter = new MacroGitterBasis () ; + assert (_macrogitter) ; + notifyMacroGridChanges () ; + return ; +} + +inline GitterBasisImpl :: GitterBasisImpl (istream & in) : _macrogitter (0) { + _macrogitter = new MacroGitterBasis (in) ; + assert (_macrogitter) ; + notifyMacroGridChanges () ; + return ; +} + +inline GitterBasisImpl :: GitterBasisImpl (const char * file) : _macrogitter (0) { + ifstream in (file) ; + if (!in) { + cerr << " GitterBasisImpl :: GitterBasisImpl (const char *) FEHLER (IGNORIERT) " ; + cerr << "beim \"Offnen der Datei " << (file ? file : "\"null\"" ) << endl ; + _macrogitter = new MacroGitterBasis () ; + } else { + _macrogitter = new MacroGitterBasis (in) ; + } + assert (_macrogitter) ; + notifyMacroGridChanges () ; + return ; +} + +inline GitterBasisImpl :: ~GitterBasisImpl () { + delete _macrogitter ; + return ; +} + +inline Gitter :: Makrogitter & GitterBasisImpl :: container () { + return * _macrogitter ; +} + +inline const Gitter :: Makrogitter & GitterBasisImpl :: container () const { + return * _macrogitter ; +} + +inline IndexManagerType & GitterBasisImpl :: indexManager (int codim) +{ + return _macrogitter->indexManager(codim); +} + +inline GitterBasis :: MacroGitterBasis :: MacroGitterBasis (istream & in) { + macrogridBuilder (in) ; + return ; +} + +inline GitterBasis :: MacroGitterBasis :: MacroGitterBasis () { + return ; +} + +inline GitterBasis :: VertexGeo * GitterBasis :: MacroGitterBasis :: insert_vertex (double x, double y, double z, int id,int) { + return new Objects :: VertexEmptyMacro (x, y, z, id, indexManager(3)) ; +} + +inline GitterBasis :: hedge1_GEO * GitterBasis :: MacroGitterBasis :: insert_hedge1 (VertexGeo * a, GitterBasis :: VertexGeo * b) { + return new Objects :: hedge1_IMPL (0, a, b, indexManager(2) ) ; +} + +inline GitterBasis :: hface3_GEO * GitterBasis :: MacroGitterBasis :: insert_hface3 (hedge1_GEO *(&e)[3], int (&s)[3]) { + return new Objects :: hface3_IMPL (0,e[0],s[0],e[1],s[1],e[2],s[2], indexManager(1) ) ; +} + +inline GitterBasis :: hface4_GEO * GitterBasis :: MacroGitterBasis :: insert_hface4 (hedge1_GEO *(&e)[4], int (&s)[4]) { + return new Objects :: hface4_IMPL (0, e[0],s[0],e[1],s[1],e[2],s[2],e[3],s[3], indexManager(1) ) ; +} + +inline GitterBasis :: tetra_GEO * GitterBasis :: MacroGitterBasis :: insert_tetra (hface3_GEO *(&f)[4], int (&t)[4]) { + return new Objects :: tetra_IMPL (0,f[0],t[0],f[1],t[1],f[2],t[2],f[3],t[3], indexManager(0) ) ; +} + +inline GitterBasis :: periodic3_GEO * GitterBasis :: MacroGitterBasis :: insert_periodic3 (hface3_GEO *(&f)[2], int (&t)[2]) { + return new Objects :: periodic3_IMPL (0,f[0],t[0],f[1],t[1]) ; +} + +// Anfang - Neu am 23.5.02 (BS) +inline GitterBasis :: periodic4_GEO * GitterBasis :: MacroGitterBasis :: insert_periodic4 (hface4_GEO *(&f)[2], int (&t)[2]) { + return new Objects :: periodic4_IMPL (0,f[0],t[0],f[1],t[1]) ; +} +// Ende - Neu am 23.5.02 (BS) + +inline GitterBasis :: hexa_GEO * GitterBasis :: MacroGitterBasis :: insert_hexa (hface4_GEO *(&f)[6], int (&t)[6]) { + return new Objects :: hexa_IMPL (0,f[0],t[0],f[1],t[1],f[2],t[2],f[3],t[3],f[4],t[4],f[5],t[5], indexManager(0) ) ; +} + +inline GitterBasis :: hbndseg3_GEO * GitterBasis :: MacroGitterBasis :: +insert_hbnd3 (hface3_GEO * f, int i, Gitter :: hbndseg_STI :: bnd_t b) { + return new Objects :: hbndseg3_IMPL (0,f,i,NULL,NULL ,b, indexManager(4) , 0 ) ; +} + +inline GitterBasis :: hbndseg3_GEO * GitterBasis :: MacroGitterBasis :: +insert_hbnd3 (hface3_GEO * f, int i, Gitter :: hbndseg_STI :: bnd_t b, const double (&p)[3]) { + return insert_hbnd3(f,i,b); +} + +inline GitterBasis :: hbndseg4_GEO * GitterBasis :: MacroGitterBasis :: insert_hbnd4 (hface4_GEO * f, int i, Gitter :: hbndseg_STI :: bnd_t b) { + return new Objects :: hbndseg4_IMPL (0,f,i,NULL, b,indexManager(4)); +} + +inline IndexManagerType & GitterBasis :: MacroGitterBasis :: indexManager (int codim ) +{ + assert((codim >= 0) && (codim < numOfIndexManager )); + return _indexmanager[codim]; +} + +#endif // GITTER_IMPL_H_INCLUDED diff --git a/src/serial/gitter_mgb.cc b/src/serial/gitter_mgb.cc new file mode 100644 index 0000000000000000000000000000000000000000..f9d759a89dad8d59a2cead32e7aa56ef33057cb1 --- /dev/null +++ b/src/serial/gitter_mgb.cc @@ -0,0 +1,924 @@ +// (c) bernhard schupp 1997 - 1998 +// modifications for Dune Interface +// (c) Robert Kloefkorn 2004 - 2005 +#ifdef IBM_XLC + #define _ANSI_HEADER +#endif + +#include <assert.h> +#include <time.h> + +#ifdef _ANSI_HEADER + using namespace std; + #include <strstream> + #include <iterator> + #include <vector> + #include <utility> + #include <set> + #include <map> + #include <algorithm> +#else + #include <strstream.h> + #include <iterator.h> + #include <vector.h> + #include <pair.h> + #include <set.h> + #include <map.h> + #include <algo.h> +#endif + +#include "gitter_sti.h" +#include "gitter_mgb.h" + +pair < Gitter :: Geometric :: VertexGeo *, bool > MacroGridBuilder :: +InsertUniqueVertex (double x, double y, double z, int i) { + vertexMap_t :: const_iterator hit = _vertexMap.find (i) ; + if (hit == _vertexMap.end ()) { + VertexGeo * v = myBuilder ().insert_vertex (x,y,z,i) ; + _vertexMap [i] = v ; + return pair < VertexGeo *, bool > (v,true) ; + } else { + return pair < VertexGeo *, bool > ((*hit).second, false) ; + } +} + +pair < Gitter :: Geometric :: hedge1_GEO *, bool > MacroGridBuilder :: InsertUniqueHedge1 (int l, int r) { + if (l > r) { + int i = l ; l = r ; r = i ; + } + edgeKey_t key (l,r) ; + edgeMap_t :: const_iterator hit = _edgeMap.find (key) ; + if (hit == _edgeMap.end ()) { + vertexMap_t :: const_iterator a = _vertexMap.find (l), b = _vertexMap.find (r), end = _vertexMap.end () ; + if (a == end || b == end) abort () ; + hedge1_GEO * h = myBuilder ().insert_hedge1 ((*a).second,(*b).second) ; + _edgeMap [key] = h ; + return pair < hedge1_GEO *, bool > (h,true) ; + } else { + return pair < hedge1_GEO *, bool > ((*hit).second,false) ; + } +} + +pair < Gitter :: Geometric :: hface3_GEO *, bool > MacroGridBuilder :: InsertUniqueHface3 (int (&v)[3]) { + cyclicReorder (v,v+3) ; + faceKey_t key (v[0],v[1],v[2]) ; + faceMap_t :: const_iterator hit = _face3Map.find (key) ; + if (hit == _face3Map.end ()) { + hedge1_GEO * edge [3] ; + int dire [3] = { 0, 0, 1 } ; + edge [0] = InsertUniqueHedge1 (v[0],v[1]).first ; + edge [1] = InsertUniqueHedge1 (v[1],v[2]).first ; + edge [2] = InsertUniqueHedge1 (v[2],v[0]).first ; + hface3_GEO * f3 = myBuilder ().insert_hface3 (edge,dire) ; + _face3Map [key] = f3 ; + return pair < hface3_GEO *, bool > (f3,true) ; + } else { + return pair < hface3_GEO *, bool > ((hface3_GEO *)(*hit).second,false) ; + } +} + +pair < Gitter :: Geometric :: hface4_GEO *, bool > MacroGridBuilder :: InsertUniqueHface4 (int (&v)[4]) { + cyclicReorder (v,v+4) ; + faceKey_t key (v[0],v[1],v[2]) ; + faceMap_t :: const_iterator hit = _face4Map.find (key) ; + if (hit == _face4Map.end ()) { + hedge1_GEO * edge [4] ; + int dire [4]; + edge [0] = InsertUniqueHedge1 (v[0],v[1]).first ; + edge [1] = InsertUniqueHedge1 (v[1],v[2]).first ; + edge [2] = InsertUniqueHedge1 (v[2],v[3]).first ; + edge [3] = InsertUniqueHedge1 (v[3],v[0]).first ; + dire [0] = v[0] < v[1] ? 0 : 1 ; + dire [1] = v[1] < v[2] ? 0 : 1 ; + dire [2] = v[2] < v[3] ? 0 : 1 ; + dire [3] = v[3] < v[0] ? 0 : 1 ; + hface4_GEO * f4 = myBuilder ().insert_hface4 (edge,dire) ; + _face4Map [key] = f4 ; + return pair < hface4_GEO *, bool > (f4,true) ; + } else { + return pair < hface4_GEO *, bool > ((hface4_GEO *)(*hit).second,false) ; + } +} + +pair < Gitter :: Geometric :: tetra_GEO *, bool > MacroGridBuilder :: InsertUniqueTetra (int (&v)[4]) { + elementKey_t key (v [0], v [1], v [2], v [3]) ; + elementMap_t :: const_iterator hit = _tetraMap.find (key) ; + if (hit == _tetraMap.end ()) { + hface3_GEO * face [4] ; + int twst [4] ; + for (int fce = 0 ; fce < 4 ; fce ++ ) { + int x [3] ; + x [0] = v [Tetra :: prototype [fce][0]] ; + x [1] = v [Tetra :: prototype [fce][1]] ; + x [2] = v [Tetra :: prototype [fce][2]] ; + twst [fce] = cyclicReorder (x,x+3) ; + face [fce] = InsertUniqueHface3 (x).first ; + } + tetra_GEO * t = myBuilder ().insert_tetra (face,twst) ; + assert (t) ; + _tetraMap [key] = t ; + return pair < tetra_GEO *, bool > (t,true) ; + } else { + return pair < tetra_GEO *, bool > ((tetra_GEO *)(*hit).second,false) ; + } +} + +pair < Gitter :: Geometric :: hexa_GEO *, bool > MacroGridBuilder :: InsertUniqueHexa (int (&v)[8]) { + elementKey_t key (v [0], v [1], v [3], v[4]) ; + elementMap_t :: const_iterator hit = _hexaMap.find (key) ; + if (hit == _hexaMap.end ()) { + hface4_GEO * face [6] ; + int twst [6] ; + for (int fce = 0 ; fce < 6 ; fce ++) { + int x [4] ; + x [0] = v [Hexa :: prototype [fce][0]] ; + x [1] = v [Hexa :: prototype [fce][1]] ; + x [2] = v [Hexa :: prototype [fce][2]] ; + x [3] = v [Hexa :: prototype [fce][3]] ; + twst [fce] = cyclicReorder (x,x+4) ; + face [fce] = InsertUniqueHface4 (x).first ; + } + hexa_GEO * hx = myBuilder ().insert_hexa (face,twst) ; + _hexaMap [key] = hx ; + return pair < hexa_GEO *, bool > (hx,true) ; + } else { + return pair < hexa_GEO *, bool > ((hexa_GEO *)(*hit).second,false) ; + } +} + +bool MacroGridBuilder :: InsertUniqueHbnd3 (int (&v)[3],Gitter :: hbndseg_STI ::bnd_t bt) +{ + int twst = cyclicReorder (v,v+3) ; + faceKey_t key (v [0], v [1], v [2]) ; + if (bt == Gitter :: hbndseg_STI :: closure) { + if (_hbnd3Int.find (key) == _hbnd3Int.end ()) { + hface3_GEO * face = InsertUniqueHface3 (v).first ; + _hbnd3Int [key] = new Hbnd3IntStorage (face,twst) ; + return true ; + } + } else { + if (_hbnd3Map.find (key) == _hbnd3Map.end ()) { + hface3_GEO * face = InsertUniqueHface3 (v).first ; + hbndseg3_GEO * hb3 = myBuilder ().insert_hbnd3 (face,twst,bt) ; + _hbnd3Map [key] = hb3 ; + return true ; + } + } + return false ; +} + +bool MacroGridBuilder :: InsertUniqueHbnd4 (int (&v)[4], Gitter :: hbndseg_STI ::bnd_t bt) { + int twst = cyclicReorder (v,v+4) ; + faceKey_t key (v [0], v [1], v [2]) ; + if (bt == Gitter :: hbndseg_STI :: closure) { + if (_hbnd4Int.find (key) == _hbnd4Int.end ()) { + hface4_GEO * face = InsertUniqueHface4 (v).first ; + _hbnd4Int [key] = (void *) new pair < hface4_GEO *, int > (face,twst) ; + return true ; + } + } else { + if (_hbnd4Map.find (key) == _hbnd4Map.end ()) { + hface4_GEO * face = InsertUniqueHface4 (v).first ; + hbndseg4_GEO * hb4 = myBuilder ().insert_hbnd4 (face,twst,bt) ; + _hbnd4Map [key] = hb4 ; + return true ; + } + } + return false ; +} + +pair < Gitter :: Geometric :: periodic3_GEO *, bool > MacroGridBuilder :: InsertUniquePeriodic3 (int (&v)[6]) { + + // Vorsicht: Der Schl"ussel f"ur das periodische Randelement wird + // dummerweise mit dem eines Hexaeders verwechselt, falls nicht + // der letzte Knoten negativ (mit umgekehrtem Vorzeichen) in die + // Schl"ussel eingef"ugt wird. + + elementKey_t key (v [0], v [1], v [2], -(v [3])-1) ; + elementMap_t :: const_iterator hit = _periodic3Map.find (key) ; + if (hit == _periodic3Map.end ()) { + hface3_GEO * face [2] ; + int twst [2] ; + for (int fce = 0 ; fce < 2 ; fce ++ ) { + int x [3] ; + x [0] = v [Periodic3 :: prototype [fce][0]] ; + x [1] = v [Periodic3 :: prototype [fce][1]] ; + x [2] = v [Periodic3 :: prototype [fce][2]] ; + twst [fce] = cyclicReorder (x,x+3) ; + face [fce] = InsertUniqueHface3 (x).first ; + } + periodic3_GEO * t = myBuilder ().insert_periodic3 (face,twst) ; + assert (t) ; + _periodic3Map [key] = t ; + return pair < periodic3_GEO *, bool > (t,true) ; + } else { + return pair < periodic3_GEO *, bool > ((periodic3_GEO *)(*hit).second,false) ; + } +} + +// Anfang - Neu am 23.5.02 (BS) +pair < Gitter :: Geometric :: periodic4_GEO *, bool > MacroGridBuilder :: InsertUniquePeriodic4 (int (&v)[8]) { + + // Vorsicht: Der Schl"ussel f"ur das periodische Randelement wird + // dummerweise mit dem eines Hexaeders verwechselt, falls nicht + // der letzte Knoten negativ (mit umgekehrtem Vorzeichen) in die + // Schl"ussel eingef"ugt wird. + + elementKey_t key (v [0], v [1], v [3], -(v [4])-1) ; + elementMap_t :: const_iterator hit = _periodic4Map.find (key) ; + if (hit == _periodic4Map.end ()) { + hface4_GEO * face [2] ; + int twst [2] ; + for (int fce = 0 ; fce < 2 ; fce ++ ) { + int x [4] ; + x [0] = v [Periodic4 :: prototype [fce][0]] ; + x [1] = v [Periodic4 :: prototype [fce][1]] ; + x [2] = v [Periodic4 :: prototype [fce][2]] ; + x [3] = v [Periodic4 :: prototype [fce][3]] ; + twst [fce] = cyclicReorder (x,x+4) ; + face [fce] = InsertUniqueHface4 (x).first ; + } + periodic4_GEO * t = myBuilder ().insert_periodic4 (face,twst) ; + assert (t) ; + _periodic4Map [key] = t ; + return pair < periodic4_GEO *, bool > (t,true) ; + } else { + return pair < periodic4_GEO *, bool > ((periodic4_GEO *)(*hit).second,false) ; + } +} +// Ende - Neu am 23.5.02 (BS) + +void MacroGridBuilder :: removeElement (const elementKey_t & k) { + + // Der Schl"ussel sollte nur in genau einer Map vorliegen. + +// Anfang - Neu am 23.5.02 (BS) + assert ((_hexaMap.find (k) == _hexaMap.end () ? 0 : 1) + + (_tetraMap.find(k) == _tetraMap.end () ? 0 : 1) + + (_periodic3Map.find (k) == _periodic3Map.end () ? 0 : 1) + + (_periodic4Map.find (k) == _periodic4Map.end () ? 0 : 1) == 1) ; +// Ende - Neu am 23.5.02 (BS) + + elementMap_t :: iterator hit = _tetraMap.find (k) ; + if (hit != _tetraMap.end ()) { + tetra_GEO * tr = (tetra_GEO *)(*hit).second ; + for (int i = 0 ; i < 4 ; i ++) + { + _hbnd3Int [faceKey_t (tr->myhface3 (i)->myvertex (0)->ident (), tr->myhface3 (i)->myvertex (1)->ident (), + tr->myhface3 (i)->myvertex (2)->ident ())] = new Hbnd3IntStorage (tr->myhface3 (i), tr->twist (i), tr->myvertex(i)->Point()) ; + } + delete tr ; + _tetraMap.erase (hit) ; + return ; + } + hit = _hexaMap.find (k) ; + if (hit != _hexaMap.end ()) { + hexa_GEO * hx = (hexa_GEO *)(*hit).second ; + for (int i = 0 ; i < 6 ; i ++) { + _hbnd4Int [faceKey_t (hx->myhface4 (i)->myvertex (0)->ident (), hx->myhface4 (i)->myvertex (1)->ident (), + hx->myhface4 (i)->myvertex (2)->ident ())] = new pair < hface4_GEO *, int > (hx->myhface4 (i), hx->twist (i)) ; + } + delete hx ; + _hexaMap.erase (hit) ; + return ; + } + hit = _periodic3Map.find (k) ; + if (hit != _periodic3Map.end ()) { + periodic3_GEO * p3 = (periodic3_GEO *)(*hit).second ; + for (int i = 0 ; i < 2 ; i ++) { + _hbnd3Int [faceKey_t (p3->myhface3 (i)->myvertex (0)->ident (), p3->myhface3 (i)->myvertex (1)->ident (), + p3->myhface3 (i)->myvertex (2)->ident ())] = new Hbnd3IntStorage (p3->myhface3 (i), p3->twist (i)) ; + } + delete p3 ; + _periodic3Map.erase (hit) ; + return ; + } +// Anfang - Neu am 23.5.02 (BS) + hit = _periodic4Map.find (k) ; + if (hit != _periodic4Map.end ()) { + periodic4_GEO * p4 = (periodic4_GEO *)(*hit).second ; + for (int i = 0 ; i < 2 ; i ++) { + _hbnd4Int [faceKey_t (p4->myhface4 (i)->myvertex (0)->ident (), p4->myhface4 (i)->myvertex (1)->ident (), + p4->myhface4 (i)->myvertex (2)->ident ())] = new pair < hface4_GEO *, int > (p4->myhface4 (i), p4->twist (i)) ; + } + delete p4 ; + _periodic4Map.erase (hit) ; + return ; + } +// Ende - Neu am 23.5.02 (BS) + abort () ; + return ; +} + +void MacroGridBuilder :: cubeHexaGrid (int n, ostream & out) { + + // cubeHexaGrid () ist eine statische Methode, die einen ASCII Strom + // mit einem gleichm"assigen Hexaedernetz auf dem Einheitsw"urfel + // [0,1]^3 beschreibt, wobei <n> die Aufl"osung der Raumrichtungen + // vorgibt: Es entstehen n^3 Hexaederelemente, und (n+1)^3 Knoten. + // Es ist als Servicemethode f"ur die 'ball' und 'ball_pll' Test- + // programme n"otig und deshalb in der MacrogridBuilder Klasse + // beheimatet. + + const int bndtype = -1 ; + out.setf(ios::fixed, ios::floatfield) ; + out.precision (14) ; + n = n < 0 ? 0 : n ; + int npe = n + 1 ; + out << (npe * npe * npe) << endl ; + double delta = 1.0 / (double)(n) ; + { + for(int i = 0 ; i < npe ; i ++) { + for(int j = 0 ; j < npe ; j ++) { + for(int k = 0 ; k < npe ; k ++) { + out << double(k * delta) << " " << double(j * delta) << " " << double(i * delta) << "\n" ; + } + } + } + } + out << n * n * n << "\n" ; + { + for(int i = 0 ; i < n ; i ++) { + int ipea = (i + 1) * npe * npe, ia = i * npe * npe ; + for(int j = 0 ; j < n ; j ++) { + int jpea = (j + 1) * npe, ja = j * npe ; + for(int k = 0 ; k < n ; k ++) { + int kpe = k + 1 ; + out << k + ia + ja << " " << kpe + ia + ja << " " << kpe + ia + jpea << " " << k + ia + jpea << " " + << k + ja + ipea << " " << kpe + ja + ipea << " " << kpe + ipea + jpea << " " << k + ipea + jpea << "\n" ; + } + } + } + out << endl ; + } + out << 6 * n * n << endl ; + { // unten und oben + int l = n * npe * npe ; + for(int j = 0 ; j < n ; j ++) { + int jpea = (j + 1) * npe, ja = j * npe ; + for(int k = 0 ; k < n ; k ++) { + int kpe = k + 1 ; + out << bndtype << " " << 4 << " " << (kpe + ja) << " " << (kpe + jpea) << " " + << (k + jpea) << " " << (k + ja) << "\n" << bndtype << " " << 4 << " " + << (k + jpea + l) << " " << (kpe + jpea + l) << " " << (kpe + ja + l) << " " << (k + ja + l) << "\n" ; + } + } + out << endl ; + } + { // links und rechts + int l = n * npe ; + for(int j = 0 ; j < n ; j ++) { + int jpea = (j + 1) * npe * npe, ja = j * npe * npe ; + for(int ka = 0 ; ka < n ; ka ++) { + int kpea = (ka + 1) ; + out << bndtype << " " << 4 << " " << ka + jpea << " " << kpea + jpea << " " + << kpea + ja << " " << ka + ja << "\n" << bndtype << " " << 4 << " " + << kpea + ja + l << " " << kpea + jpea + l << " " << ka + jpea + l << " " << ka + ja + l << "\n" ; + } + } + out << endl ; + } + { // hinten und vorne + int l = n ; + for(int j = 0 ; j < n ; j ++) { + int jpea = (j + 1) * npe * npe, ja = j * npe * npe ; + for(int k = 0 ; k < n ; k ++) { + int kpea = (k + 1) * npe, ka = k * npe ; + out << bndtype << " " << 4 << " " << kpea + ja << " " << kpea + jpea << " " + << ka + jpea << " " << ka + ja << "\n" << bndtype << " " << 4 << " " + << ka + jpea + l << " " << kpea + jpea + l << " " << kpea + ja + l << " " << ka + ja + l << "\n" ; + } + } + out << endl ; + } + return ; +} + +void MacroGridBuilder :: generateRawHexaImage (istream & in, ostream & os) { + + // generateRawHexaImage () ist im nur ein Adapter, der aus den + // bisherigen Hexaederdateiformaten ein entsprechendes 'rohes' + // Dateiformat f"ur den Macrogridinflator erzeugt. Damit bleibt + // die Option erhalten das Format der rohen Dateien auf weitere + // Elemente auszudehnen und zu modifizieren, ohne die + // Kompatibilit"at zu den alten Hexaederdateien zu verlieren. + // Das alte Format sieht im wesentlichen so aus: + // + // <Anzahl der Knoten : int > /* 1.Zeile der Datei + // <x-Koordinate : float> <y-Koo. : float> <z-Koo. : float> + // ... /* f"ur den letzten Knoten + // <Anzahl der Elemente : int> + // <KnotenNr. 0: int> ... <KnotenNr. 7: int> /* f"ur das erste Hexaederelement + // ... /* f"ur das letzte Hexaederelement + // <Anzahl der Randfl"achen : int> + // <Randtyp> 4 <KnotenNr. 0> ... <KnotenNr. 3>/* erste Randfl"ache + // ... /* letzte Randfl"ache + // <Identifier f"ur den 0. Knoten : int> /* Identifierliste ist im seriellen + // ... /* Verfahren oder beim Aufsetzen aus + // <Identifier f"ur den letzten Knoten : int> /* einem Gitter optional, sonst muss + // /* jeder Vertex eine eigene Nummer haben + + const int start = clock () ; + int nv = 0, ne = 0, nb = 0, nper = 0 ; + int (* vnum)[8] = 0, (* bvec)[5] = 0, (* pervec)[8] = 0, * pident = 0 ; + double (* coord)[3] = 0 ; + { + in >> nv ; + coord = new double [nv][3] ; + assert (coord) ; + for (int i = 0 ; i < nv ; i ++) in >> coord [i][0] >> coord [i][1] >> coord [i][2] ; + } + { + in >> ne ; + vnum = new int [ne][8] ; + assert (vnum) ; + for (int i = 0 ; i < ne ; i ++ ) + in >> vnum [i][0] >> vnum [i][1] >> vnum [i][2] >> vnum [i][3] >> vnum [i][4] >> vnum [i][5] >> vnum [i][6] >> vnum [i][7] ; + } +// Anfang - Neu am 23.5.02 (BS) + { + int temp_nb; + in >> temp_nb ; + bvec = new int [temp_nb][5] ; + pervec = new int [temp_nb][8] ; + assert (bvec); + assert (pervec); + for (int i = 0 ; i < temp_nb ; i ++) { + int n ; + int identification ; + in >> identification >> n; + if (n == 4) { + in >> bvec [nb][0] >> bvec [nb][1] >> bvec [nb][2] >> bvec [nb][3] ; + bvec [nb][4] = identification ; + nb++; + } + else if (n == 8 && identification == -20) { + in >> pervec [nper][0] >> pervec [nper][1] >> pervec [nper][2] >> pervec [nper][3] + >> pervec [nper][4] >> pervec [nper][5] >> pervec [nper][6] >> pervec [nper][7] ; + nper++; + } + else { + cerr << "**FEHLER (FATAL): "__FILE__ << " " << __LINE__ << " ... Exiting." << endl ; + abort(); + } + } + } +// Ende - Neu am 23.5.02 (BS) + if (! in.good ()) { + cerr << "**FEHLER (FATAL): Dateiende zu fr\"uh erreicht (inkonsistente Datei). " ; + cerr << __FILE__ << " " << __LINE__ << " ... Exiting." << endl ; + exit (1) ; + } + pident = new int [nv] ; + { + int dummy ; + for (int i = 0 ; i < nv ; i ++ ) in >> pident [i] >> dummy ; + } + if (!in.good()) { + cerr << "**WARNUNG (IGNORIERT) MacroGridBuilder :: generateRawHexaImage () " ; + cerr << "Identifierliste unvollst\"andig oder nicht vorhanden. Daher keine parallele " ; + cerr << "Identifikation falls aus mehreren Gittern geladen wurde." << endl ; + for (int i = 0 ; i < nv ; i ++ ) pident [i] = i ; + } + { + os << nv << endl ; + for (int i = 0 ; i < nv ; i ++ ) + os << pident [i] << " " << coord [i][0] << " " << coord [i][1] << " " << coord [i][2] << endl ; + } + { + os << (ne + nper) << endl ; + for (int i = 0 ; i < ne ; i ++) + os << HEXA_RAW << " " << pident [vnum [i][0]] << " " << pident [vnum [i][1]] << " " + << pident [vnum [i][2]] << " " << pident [vnum [i][3]] << " " << pident [vnum [i][4]] << " " + << pident [vnum [i][5]] << " " << pident [vnum [i][6]] << " " << pident [vnum [i][7]] << endl ; + } + { +// Anfang - Neu am 23.5.02 (BS) + for (int i = 0 ; i < nper ; i ++) + os << PERIODIC4_RAW << " " << pident [pervec [i][0]] << " " << pident [pervec [i][1]] << " " + << pident [pervec [i][2]] << " " << pident [pervec [i][3]] << " " + << pident [pervec [i][4]] << " " << pident [pervec [i][5]] << " " + << pident [pervec [i][6]] << " " << pident [pervec [i][7]] << endl ; +// Ende - Neu am 23.5.02 (BS) + } + { + os << nb << endl ; + for (int i = 0 ; i < nb ; i ++) + os << 4 << " " << pident [bvec [i][0]] << " " << pident [bvec [i][1]] << " " + << pident [bvec [i][2]] << " " << pident [bvec [i][3]] << " " << bvec [i][4] << endl ; + } + delete [] vnum ; + delete [] coord ; + delete [] bvec ; + delete [] pident ; + if (debugOption (4)) + cout << "**INFO MacroGridBuilder :: generateRawHexaImage () used: " + << (float)(clock () - start)/(float)(CLOCKS_PER_SEC) << " sec." << endl ; + return ; +} + +void MacroGridBuilder :: generateRawTetraImage (istream & in, ostream & os) { + const int start = clock () ; + int nv = 0, ne = 0, nb = 0, nper = 0; + int (* vnum)[4] = 0, (* bvec)[4] = 0, (* pervec)[6] = 0 , + * pident = 0 ; + double (* coord)[3] = 0 ; + { + in >> nv ; + coord = new double [nv][3] ; + assert (coord) ; + for (int i = 0 ; i < nv ; i ++) in >> coord [i][0] >> coord [i][1] >> coord [i][2] ; + } + { + in >> ne ; + vnum = new int [ne][4] ; + assert (vnum) ; + for (int i = 0 ; i < ne ; i ++ ) + in >> vnum [i][0] >> vnum [i][1] >> vnum [i][2] >> vnum [i][3] ; + } + { + int temp_nb; + in >> temp_nb ; + bvec = new int [temp_nb][4] ; + pervec = new int [temp_nb][6] ; + assert (bvec); + assert (pervec); + for (int i = 0 ; i < temp_nb ; i ++) { + int n ; + int identification ; + in >> identification >> n; + if (n==3) { + in >> bvec [nb][0] >> bvec [nb][1] >> bvec [nb][2] ; + bvec [nb][3] = identification ; + nb++; + } + else if (n == 6 && identification == -20) { + in >> pervec [nper][0] >> pervec [nper][1] >> pervec [nper][2] >> + pervec [nper][3] >> pervec [nper][4] >> pervec [nper][5]; + nper++; + } + else + abort(); + } + } + if (! in.good ()) { + cerr << "**FEHLER (FATAL): Dateiende zu fr\"uh erreicht (inkonsistente Datei). " + << __FILE__ << " " << __LINE__ << " ... Exiting." << endl ; + exit (1) ; + } + pident = new int [nv] ; + assert(pident); + { + int dummy ; + for (int i = 0 ; i < nv ; i ++ ) in >> pident [i] >> dummy ; + } + if (!in.good()) { + cerr << "**WARNUNG (IGNORIERT) MacroGridBuilder :: generateRawTetraImage () " ; + cerr << "Identifierliste unvollst\"andig oder nicht vorhanden. Daher keine parallele " ; + cerr << "Identifikation falls aus mehreren Gittern geladen wurde." << endl ; + for (int i = 0 ; i < nv ; i ++ ) pident [i] = i ; + } + { + os << nv << endl ; + for (int i = 0 ; i < nv ; i ++ ) + os << pident [i] << " " << coord [i][0] << " " << coord [i][1] << " " << coord [i][2] << endl ; + } + { + int i; + os << ne+nper << endl ; + for (i = 0 ; i < ne ; i ++) + os << TETRA_RAW << " " << pident [vnum [i][0]] << " " << pident [vnum [i][1]] << " " + << pident [vnum [i][2]] << " " << pident [vnum [i][3]] << endl ; + for (i = 0 ; i < nper ; i ++) + os << PERIODIC3_RAW << " " << pident [pervec [i][0]] << " " << pident [pervec [i][1]] << " " + << pident [pervec [i][2]] << " " << pident [pervec [i][3]] << " " + << pident [pervec [i][4]] << " " << pident [pervec [i][5]] << endl ; + } + { + os << nb << endl ; + for (int i = 0 ; i < nb ; i ++) + os << 3 << " " << pident [bvec [i][0]] << " " << pident [bvec [i][1]] << " " + << pident [bvec [i][2]] << " " << " " << bvec [i][3] << endl ; + } + delete [] vnum ; + delete [] coord ; + delete [] bvec ; + delete [] pervec ; + delete [] pident ; + if (debugOption (4)) + cout << "**INFO MacroGridBuilder :: generateRawTetraImage () used: " << (float)(clock () - start)/(float)(CLOCKS_PER_SEC) << " sec." << endl ; + return ; +} + +// default of init == true +MacroGridBuilder :: MacroGridBuilder (BuilderIF & b, bool init) + : _initialized(false) , _finalized(false) , _mgb (b) +{ + if(init) initialize(); +} + +void MacroGridBuilder :: initialize () +{ + { + for (list < VertexGeo * > :: iterator i = myBuilder ()._vertexList.begin () ; + i != myBuilder ()._vertexList.end () ; myBuilder ()._vertexList.erase (i ++)) + _vertexMap [(*i)->ident ()] = (*i) ; + } + { + for (list < hedge1_GEO * > :: iterator i = myBuilder ()._hedge1List.begin () ; + i != myBuilder ()._hedge1List.end () ; myBuilder ()._hedge1List.erase (i ++)) { + long k = (*i)->myvertex (0)->ident (), l = (*i)->myvertex (1)->ident () ; + _edgeMap [edgeKey_t (k < l ? k : l, k < l ? l : k)] = (*i) ; + } + } + {for (list < hface3_GEO * > :: iterator i = myBuilder ()._hface3List.begin () ; i != myBuilder ()._hface3List.end () ; + myBuilder ()._hface3List.erase (i ++)) { + _face3Map [faceKey_t ((*i)->myvertex (0)->ident (),(*i)->myvertex (1)->ident (), (*i)->myvertex (2)->ident ())] = (*i) ; + }} + { + for (list < hface4_GEO * > :: iterator i = myBuilder ()._hface4List.begin () ; i != myBuilder ()._hface4List.end () ; + myBuilder ()._hface4List.erase (i ++)) _face4Map [faceKey_t ((*i)->myvertex (0)->ident (),(*i)->myvertex (1)->ident (), + (*i)->myvertex (2)->ident ())] = (*i) ; + } + {for (list < hbndseg4_GEO * > :: iterator i = myBuilder ()._hbndseg4List.begin () ; i != myBuilder ()._hbndseg4List.end () ; myBuilder ()._hbndseg4List.erase (i++)) { + faceKey_t key ((*i)->myhface4 (0)->myvertex (0)->ident (), (*i)->myhface4 (0)->myvertex (1)->ident (), (*i)->myhface4 (0)->myvertex (2)->ident ()) ; + if ((*i)->bndtype () == Gitter :: hbndseg_STI :: closure) { + _hbnd4Int [key] = (void *) new pair < hface4_GEO *, int > ((*i)->myhface4 (0), (*i)->twist (0)) ; + delete (*i) ; + } else { + _hbnd4Map [key] = (*i) ; + } + }} + {for (list < hbndseg3_GEO * > :: iterator i = myBuilder ()._hbndseg3List.begin () ; i != myBuilder ()._hbndseg3List.end () ; + myBuilder ()._hbndseg3List.erase (i++)) { + faceKey_t key ((*i)->myhface3 (0)->myvertex (0)->ident (), (*i)->myhface3 (0)->myvertex (1)->ident (), (*i)->myhface3 (0)->myvertex (2)->ident ()) ; + if ((*i)->bndtype () == Gitter :: hbndseg_STI :: closure) + { + _hbnd3Int [key] = new Hbnd3IntStorage ((*i)->myhface3 (0), (*i)->twist (0)) ; + delete (*i) ; + } else { + _hbnd3Map [key] = (*i) ; + } + }} + {for (list < tetra_GEO * > :: iterator i = myBuilder ()._tetraList.begin () ; i != myBuilder ()._tetraList.end () ; + myBuilder ()._tetraList.erase (i++)) { + _tetraMap [elementKey_t ((*i)->myvertex (0)->ident (), (*i)->myvertex (1)->ident (), + (*i)->myvertex (2)->ident (), (*i)->myvertex (3)->ident ())] = (*i) ; + }} + {for (list < periodic3_GEO * > :: iterator i = myBuilder ()._periodic3List.begin () ; i != myBuilder ()._periodic3List.end () ; + myBuilder ()._periodic3List.erase (i++)) { + _periodic3Map [elementKey_t ((*i)->myvertex (0)->ident (), (*i)->myvertex (1)->ident (), + (*i)->myvertex (2)->ident (), -((*i)->myvertex (3)->ident ())-1)] = (*i) ; + }} +// Anfang - Neu am 23.5.02 (BS) + {for (list < periodic4_GEO * > :: iterator i = myBuilder ()._periodic4List.begin () ; i != myBuilder ()._periodic4List.end () ; + myBuilder ()._periodic4List.erase (i++)) { + _periodic4Map [elementKey_t ((*i)->myvertex (0)->ident (), (*i)->myvertex (1)->ident (), + (*i)->myvertex (3)->ident (), -((*i)->myvertex (4)->ident ())-1)] = (*i) ; + }} +// Ende - Neu am 23.5.02 (BS) + { + for (list < hexa_GEO * > :: iterator i = myBuilder ()._hexaList.begin () ; i != myBuilder ()._hexaList.end () ; + myBuilder ()._hexaList.erase (i++)) _hexaMap [elementKey_t ((*i)->myvertex (0)->ident (), (*i)->myvertex (1)->ident (), + (*i)->myvertex (3)->ident (), (*i)->myvertex (4)->ident ())] = (*i) ; + } + + _initialized = true; + return ; +} + +MacroGridBuilder :: ~MacroGridBuilder () +{ + // _finalized is true if the method was called in inherited classes + if(!_finalized) finalize(); +} + +// clean the map tables +void MacroGridBuilder :: finalize () +{ + assert(_initialized); + + {for (elementMap_t :: iterator i = _hexaMap.begin () ; i != _hexaMap.end () ; _hexaMap.erase (i++)) + myBuilder ()._hexaList.push_back ((hexa_GEO *)(*i).second) ; + } + {for (elementMap_t :: iterator i = _tetraMap.begin () ; i != _tetraMap.end () ; _tetraMap.erase (i++)) + myBuilder ()._tetraList.push_back ((tetra_GEO *)(*i).second) ; + } + {for (elementMap_t :: iterator i = _periodic3Map.begin () ; i != _periodic3Map.end () ; _periodic3Map.erase (i++)) + myBuilder ()._periodic3List.push_back ((periodic3_GEO *)(*i).second) ; + } + + {for (elementMap_t :: iterator i = _periodic4Map.begin () ; i != _periodic4Map.end () ; _periodic4Map.erase (i++)) + myBuilder ()._periodic4List.push_back ((periodic4_GEO *)(*i).second) ; + } + + {for (faceMap_t :: iterator i = _hbnd4Map.begin () ; i != _hbnd4Map.end () ; ) + if (((hbndseg4_GEO *)(*i).second)->myhface4 (0)->ref == 1) { + delete (hbndseg4_GEO *)(*i).second ; + _hbnd4Map.erase (i++) ; + } else { + myBuilder ()._hbndseg4List.push_back ((hbndseg4_GEO *)(*i ++).second) ; + } + } + {for (faceMap_t :: iterator i = _hbnd3Map.begin () ; i != _hbnd3Map.end () ; ) + if (((hbndseg3_GEO *)(*i).second)->myhface3 (0)->ref == 1) { + delete (hbndseg3_GEO *)(*i).second ; + _hbnd3Map.erase (i++) ; + } else { + myBuilder ()._hbndseg3List.push_back ((hbndseg3_GEO *)(*i ++).second) ; + } + } + {for (faceMap_t :: iterator i = _hbnd4Int.begin () ; i != _hbnd4Int.end () ; i ++) { + const pair < hface4_GEO *, int > & p = * (pair < hface4_GEO *, int > *)(*i).second ; + if (p.first->ref == 1) { + hbndseg4_GEO * hb4 = myBuilder ().insert_hbnd4 (p.first,p.second,Gitter :: hbndseg_STI :: closure) ; + myBuilder ()._hbndseg4List.push_back (hb4) ; + } + delete (pair < hface4_GEO *, int > *)(*i).second ; + }} + + // here the internal boundary elements are created + {for (hbndintMap_t :: iterator i = _hbnd3Int.begin () ; i != _hbnd3Int.end () ; i ++) { + const Hbnd3IntStorage & p = * (Hbnd3IntStorage *) (*i).second ; + if (p.first()->ref == 1) { + hbndseg3_GEO * hb3 = myBuilder ().insert_hbnd3 (p.first(),p.second(),Gitter :: hbndseg_STI :: closure) ; + myBuilder ()._hbndseg3List.push_back (hb3) ; + } + delete (pair < hface3_GEO *, int > *)(*i).second ; + }} + {for (faceMap_t :: iterator i = _face4Map.begin () ; i != _face4Map.end () ; ) + if (!((hface4_GEO *)(*i).second)->ref) { + delete (hface4_GEO *)(*i).second ; + _face4Map.erase (i++) ; + } else { + assert (((hface4_GEO *)(*i).second)->ref == 2) ; + myBuilder ()._hface4List.push_back ((hface4_GEO *)(*i ++).second ) ; + } + } + {for (faceMap_t :: iterator i = _face3Map.begin () ; i != _face3Map.end () ; ) { + if (!((hface3_GEO *)(*i).second)->ref) { + delete (hface3_GEO *)(*i).second ; + _face3Map.erase (i++) ; + } else { + assert (((hface3_GEO *)(*i).second)->ref == 2) ; + myBuilder ()._hface3List.push_back ((hface3_GEO *)(*i ++).second ) ; + } + }} + {for (edgeMap_t :: iterator i = _edgeMap.begin () ; i != _edgeMap.end () ; ) + if (!(*i).second->ref) { + delete (*i).second ; + _edgeMap.erase (i++) ; + } else { + assert ((*i).second->ref >= 1) ; + myBuilder ()._hedge1List.push_back ((*i ++).second) ; + } + } + {for (vertexMap_t :: iterator i = _vertexMap.begin () ; i != _vertexMap.end () ; ) + if (!(*i).second->ref) { + delete (*i).second ; + _vertexMap.erase (i++) ; + } else { + assert ((*i).second->ref >= 2) ; + myBuilder ()._vertexList.push_back ((*i ++).second) ; + } + } + myBuilder ()._modified = true ; // wichtig ! + _finalized = true; + return ; +} + +void MacroGridBuilder :: inflateMacroGrid (istream & rawInput) { + const int start = clock () ; + { + int nv = 0 ; + rawInput >> nv ; + for (int i = 0 ; i < nv ; i ++ ) { + int id ; + double x, y, z ; + rawInput >> id >> x >> y >> z ; + InsertUniqueVertex (x,y,z,id) ; + } + } + { + int ne = 0 ; + rawInput >> ne ; + for (int i = 0 ; i < ne ; i ++ ) { + int elementType ; + rawInput >> elementType ; + switch (elementType) { + case HEXA_RAW : + { + int v [8] ; + rawInput >> v [0] >> v [1] >> v [2] >> v [3] >> v [4] >> v [5] >> v [6] >> v [7] ; + InsertUniqueHexa (v) ; + } + break ; + case TETRA_RAW : + { + int v [4] ; + rawInput >> v [0] >> v [1] >> v [2] >> v [3] ; + InsertUniqueTetra (v) ; + } + break ; + case PERIODIC3_RAW : + { + int v [6] ; + rawInput >> v [0] >> v [1] >> v [2] >> v [3] >> v [4] >> v [5] ; + InsertUniquePeriodic3 (v) ; + } + break ; + case PERIODIC4_RAW : + { + int v [8] ; + rawInput >> v [0] >> v [1] >> v [2] >> v [3] >> v [4] >> v [5] >> v [6] >> v [7] ; + InsertUniquePeriodic4 (v) ; + } + break ; + default : + cerr << "**FEHLER (FATAL): Unbekannte ElementID im Rawformat File [" + << elementType << "] in "__FILE__ << " " << __LINE__ << " ... Exiting. " << endl ; + exit (1) ; + break ; + } + } + } + { + int nb = 0 ; + rawInput >> nb ; + for (int i = 0 ; i < nb ; i ++) { + int polygonLen ; + rawInput >> polygonLen ; + if (polygonLen == 4) { + int bt, v [4] ; + rawInput >> v [0] >> v [1] >> v [2] >> v [3] >> bt ; + InsertUniqueHbnd4 (v,(Gitter :: hbndseg :: bnd_t)(-bt)) ; + } else if (polygonLen == 3) { + int bt, v [3] ; + rawInput >> v [0] >> v [1] >> v [2] >> bt ; + InsertUniqueHbnd3 (v,(Gitter :: hbndseg :: bnd_t)(-bt)) ; + } else { + cerr << " MacroGridBuilder :: inflateMacroGrid (istream &) FEHLER (fatal): kann" ; + cerr << " Randelement mit Polygonl\"ange " << polygonLen << " NICHT erzeugen " << endl ; + abort () ; + } + } + } + if (debugOption (3)) { + cout << "**INFO MacroGridBuilder :: inflateMacroGrid () used: " ; + cout << (float)(clock () - start)/(float)(CLOCKS_PER_SEC) << " sec." << endl ; + } + return ; +} + +void Gitter :: Geometric :: BuilderIF :: macrogridBuilder (istream & in) { + strstream raw ; + MacroGridBuilder mm (*this) ; + int c = in.get () ; + assert (!in.eof ()) ; + in.putback (c) ; + assert (in.good ()) ; + if (c == int ('!')) { + + // Kommentar gefunden: Die erste Zeile in den strstreambuf buf lesen + // und auf 'Tetraeder' oder 'Hexaeder' untersuchen. + + strstreambuf buf ; + in.get () ; // Das Kommentarzeichen wird entfernt. + in.get (buf) ; + int len = in.gcount () ; + in.get () ; // Der folgende Zeilenumbruchwird auch entfernt. + istream is (& buf) ; + char * str = new char [len + 1] ; + assert (str) ; + is >> str ; // Das erste Wort nach dem Kommentar steht jetzt in str. + // Alle weiteren k"onnen noch aus is gelesen werden, das + // array str ist so lang, wie die gesamte Zeile in 'buf'. + + if (0 == strcmp (str, "Tetraeder")) { + + // Versuchen wir's mal mit Tetraedern + + MacroGridBuilder :: generateRawTetraImage (in,raw) ; + } else if (0 == strcmp (str, "Hexaeder")) { + + // oder andernfalls mit Hexaedern. + + MacroGridBuilder :: generateRawHexaImage (in,raw) ; + } else { + cerr << "**WARNUNG (IGNORIERT) Unbekannter Kommentar zum Gitterformat: " << str ; + cerr << " In : " << __FILE__ << " " << __LINE__ << endl ; + delete [] str ; + return ; + } + delete [] str ; + } else { + cerr << "**WARNUNG (IGNORIERT) Kein Bezeichner f\"ur das Dateiformat vorhanden.\n" ; + cerr << " -> Versuche es als Hexaedernetz zu lesen." << endl ; + MacroGridBuilder :: generateRawHexaImage (in,raw) ; + } + mm.inflateMacroGrid (raw) ; + return ; +} + + + diff --git a/src/serial/gitter_mgb.h b/src/serial/gitter_mgb.h new file mode 100644 index 0000000000000000000000000000000000000000..d8e7d60bf496a441eb78e4f89b7e89cdf93386b8 --- /dev/null +++ b/src/serial/gitter_mgb.h @@ -0,0 +1,167 @@ +// (c) bernhard schupp 1997 - 1998 + +#ifndef GITTER_MGB_H_INCLUDED +#define GITTER_MGB_H_INCLUDED + +#ifdef IBM_XLC + #define _ANSI_HEADER +#endif + +#include <assert.h> + +#ifdef _ANSI_HEADER + using namespace std; + #include <vector> + #include <functional> + #include <utility> + #include <map> + #include <algorithm> +#else + #include <vector.h> + #include <function.h> + #include <pair.h> + #include <map.h> + #include <algo.h> +#endif + +#include "key.h" +#include "gitter_sti.h" + +static volatile char RCSId_gitter_mgb_h [] = "$Id$" ; + +template < class RandomAccessIterator > inline int cyclicReorder (RandomAccessIterator begin, RandomAccessIterator end) { + RandomAccessIterator middle = min_element (begin,end) ; + int pos = middle == begin ? 0 : (rotate (begin,middle,end), (end - middle)) ; + if (*(begin + 1) < *(end - 1)) return pos ; + else { + reverse (begin,end) ; + rotate (begin,end - 1,end) ; + return - pos - 1 ; + } +} + +class MacroGridBuilder : protected Gitter :: Geometric { + protected : + class Hbnd3IntStorage + { + double _p[3]; + hface3_GEO * _first; + int _second; + bool _pInit; // true if p was initialized with a value + public: + // store point and face and twist + Hbnd3IntStorage( hface3_GEO * f, int tw, const double (&p) [3] ); + + // store face and twist and set point to default + Hbnd3IntStorage( hface3_GEO * f, int tw ); + + // return reference to _p + const double (& getPoint () const )[3]; + + hface3_GEO * first () const { return _first; } + int second () const { return _second; } + }; + + protected : + enum ElementRawID {TETRA_RAW=4, HEXA_RAW=8, PERIODIC3_RAW=33, PERIODIC4_RAW=44} ; + protected : + typedef long vertexKey_t ; + typedef pair < int, int > edgeKey_t ; + typedef Key3 < int > faceKey_t ; + typedef Key4 < int > elementKey_t ; + + typedef map < vertexKey_t , VertexGeo *, less < vertexKey_t > > vertexMap_t ; + typedef map < edgeKey_t, hedge1_GEO *, less < edgeKey_t > > edgeMap_t ; + typedef map < faceKey_t, void *, less < faceKey_t > > faceMap_t ; + typedef map < faceKey_t, Hbnd3IntStorage *, less < faceKey_t > > hbndintMap_t ; + typedef map < elementKey_t, void *, less < elementKey_t > > elementMap_t ; + + vertexMap_t _vertexMap ; + edgeMap_t _edgeMap ; + + faceMap_t _face4Map, _face3Map, _hbnd3Map, _hbnd4Map, _hbnd4Int ; + hbndintMap_t _hbnd3Int; // new type here, so we dont have to cast to void * + // todo here: same thing for hbnd4int + + elementMap_t _hexaMap, _tetraMap, _periodic3Map, _periodic4Map ; + + inline BuilderIF & myBuilder () ; + inline const BuilderIF & myBuilder () const ; + void removeElement (const elementKey_t &) ; + public : + virtual pair < VertexGeo *, bool > InsertUniqueVertex (double, double, double, int) ; + virtual pair < hedge1_GEO *, bool > InsertUniqueHedge1 (int,int) ; + virtual pair < hface3_GEO *, bool > InsertUniqueHface3 (int (&)[3]) ; + virtual pair < hface4_GEO *, bool > InsertUniqueHface4 (int (&)[4]) ; + virtual pair < tetra_GEO *, bool > InsertUniqueTetra (int (&)[4]) ; + virtual pair < periodic3_GEO *, bool > InsertUniquePeriodic3 (int (&)[6]) ; + + virtual pair < periodic4_GEO *, bool > InsertUniquePeriodic4 (int (&)[8]) ; + virtual pair < hexa_GEO *, bool > InsertUniqueHexa (int (&)[8]) ; + + virtual bool InsertUniqueHbnd3 (int (&)[3], Gitter :: hbndseg :: bnd_t) ; + virtual bool InsertUniqueHbnd4 (int (&)[4], Gitter :: hbndseg :: bnd_t) ; + + public : + static bool debugOption (int) ; + static void generateRawHexaImage (istream &, ostream &) ; + static void generateRawTetraImage (istream &, ostream &) ; + static void cubeHexaGrid (int, ostream &) ; + MacroGridBuilder (BuilderIF &, bool init = true) ; + virtual ~MacroGridBuilder () ; + void inflateMacroGrid (istream &) ; + void backupMacroGrid (ostream &) ; + + // former constructor + void initialize (); + // former destructor + void finalize (); + protected: + bool _initialized; + bool _finalized; + private : + BuilderIF & _mgb ; +} ; + + +// +// # # # # # # # ###### +// # ## # # # ## # # +// # # # # # # # # # ##### +// # # # # # # # # # # +// # # ## # # # ## # +// # # # ###### # # # ###### +// +inline Gitter :: Geometric :: BuilderIF & MacroGridBuilder :: myBuilder () { + return _mgb ; +} + +inline const Gitter :: Geometric :: BuilderIF & MacroGridBuilder :: myBuilder () const { + return _mgb ; +} + +inline bool MacroGridBuilder :: debugOption (int level) { + return (getenv ("VERBOSE_MGB") ? ( atoi (getenv ("VERBOSE_MGB")) > level ? true : (level == 0)) : false) ; +} + +inline MacroGridBuilder :: Hbnd3IntStorage :: +Hbnd3IntStorage( hface3_GEO * f, int tw, const double (&p) [3] ) + : _first(f) , _second(tw) , _pInit(true) +{ + for(int i=0; i<3; i++) _p[i] = p[i]; +} + +inline MacroGridBuilder :: Hbnd3IntStorage :: +Hbnd3IntStorage( hface3_GEO * f, int tw ) + : _first(f) , _second(tw) , _pInit(false) +{ + for(int i=0; i<3; i++) _p[i] = -666.0; +} + +inline const double (& MacroGridBuilder :: Hbnd3IntStorage :: getPoint () const )[3] +{ + assert(_pInit); + return _p; +} + +#endif diff --git a/src/serial/gitter_sti.cc b/src/serial/gitter_sti.cc new file mode 100644 index 0000000000000000000000000000000000000000..08fa45a514637d5f302a9cc64051f19ba6841826 --- /dev/null +++ b/src/serial/gitter_sti.cc @@ -0,0 +1,524 @@ +// (c) bernhard schupp 1997 - 1998 +// modifications for Dune Interface +// (c) Robert Kloefkorn 2004 - 2005 +#ifndef GITTER_STI_CC_INCLUDED +#define GITTER_STI_CC_INCLUDED + + +#ifdef IBM_XLC + #define _ANSI_HEADER +#endif + +#include <stdlib.h> +#include <assert.h> +#include <time.h> +#include <math.h> + +#ifdef _ANSI_HEADER + using namespace std; + #include <iostream> + #include <fstream> +#else + #include <iostream.h> + #include <fstream.h> +#endif + +#include "lock.h" +#include "gitter_sti.h" +#include "walk.h" + +#include "xdrclass.h" + +extern "C" { double drand48 (void) ; } + +#ifndef NDEBUG +Refcount :: Globalcount Refcount :: _g ; + +Refcount :: Globalcount :: ~Globalcount () { + assert (_c ? (cerr << "**WARNUNG Refcount :: Globalcount :: ~Globalcount() " << _c + << " objekte sind stehen geblieben" << endl, 1) : 1) ; + return ; +} +#endif + +typedef Wrapper < AccessIterator < Gitter :: vertex_STI > :: Handle, + Gitter :: InternalVertex > leaf_vertex__macro_vertex__iterator ; + +typedef Insert < AccessIterator < Gitter :: hedge_STI > :: Handle, + TreeIterator < Gitter :: hedge_STI, is_leaf < Gitter :: hedge_STI > > > leaf_edge__macro_edge__iterator ; + +typedef Insert < AccessIterator < Gitter :: hface_STI > :: Handle, + TreeIterator < Gitter :: hface_STI, is_leaf < Gitter :: hface_STI > > > leaf_face__macro_face__iterator ; + +typedef Insert < AccessIterator < Gitter :: hbndseg_STI > :: Handle, + TreeIterator < Gitter :: hbndseg_STI, is_leaf < Gitter :: hbndseg_STI> > > leaf_bnd__macro_bnd__iterator ; + +typedef Insert < AccessIterator < Gitter :: helement_STI > :: Handle, + TreeIterator < Gitter :: helement_STI, is_leaf < Gitter :: helement_STI> > > leaf_element__macro_element__iterator ; + +IteratorSTI < Gitter :: vertex_STI > * Gitter :: iterator (const Gitter :: vertex_STI *) { + vector < IteratorSTI < vertex_STI > * > _iterators ; + { + _iterators.push_back ( new AccessIterator < vertex_STI > :: Handle (container ())) ; + } + Insert < AccessIterator < hedge_STI > :: Handle, + TreeIterator < hedge_STI, has_int_vertex < hedge_STI > > > dw (container ()) ; + _iterators.push_back ( new Wrapper < Insert < AccessIterator < hedge_STI > :: Handle, + TreeIterator < hedge_STI, has_int_vertex < hedge_STI > > >, InternalVertex > (dw)) ; + { + Insert < AccessIterator < hface_STI > :: Handle, + TreeIterator < hface_STI, has_int_vertex < hface_STI > > > fw (container ()) ; + _iterators.push_back ( new Wrapper < Insert < AccessIterator < hface_STI > :: Handle, + TreeIterator < hface_STI, has_int_vertex < hface_STI > > >, InternalVertex > (fw)) ; + } + { + Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_vertex < helement_STI > > > ew (container ()) ; + _iterators.push_back ( new Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_vertex < helement_STI > > >, InternalVertex > (ew)) ; + } + { + Insert < AccessIterator < hface_STI > :: Handle, + TreeIterator < hface_STI, has_int_edge < hface_STI > > > fw (container ()) ; + Wrapper < Insert < AccessIterator < hface_STI > :: Handle, + TreeIterator < hface_STI, has_int_edge < hface_STI > > >, InternalEdge > df (fw) ; + Insert < Wrapper < Insert < AccessIterator < hface_STI > :: Handle, + TreeIterator < hface_STI, has_int_edge < hface_STI > > >, InternalEdge >, + TreeIterator < hedge_STI, unary_not < is_leaf < hedge_STI > > > > dif (df) ; + _iterators.push_back ( new Wrapper < Insert < Wrapper < Insert < AccessIterator < hface_STI > :: Handle, + TreeIterator < hface_STI, has_int_edge < hface_STI > > >, InternalEdge >, + TreeIterator < hedge_STI, unary_not < is_leaf < hedge_STI > > > >, InternalVertex > (dif)) ; + } + { + Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_edge < helement_STI > > > ew (container ()) ; + Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_edge < helement_STI > > >, InternalEdge > de (ew) ; + Insert < Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_edge < helement_STI > > >, InternalEdge >, + TreeIterator < hedge_STI, unary_not < is_leaf < hedge_STI > > > > die (de) ; + _iterators.push_back ( new Wrapper < Insert < Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_edge < helement_STI > > >, InternalEdge >, + TreeIterator < hedge_STI, unary_not < is_leaf < hedge_STI > > > >, InternalVertex > (die)) ; + } + { + Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > > ew (container ()) ; + Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > >, InternalFace > fe (ew) ; + Insert < Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > >, InternalFace >, + TreeIterator < hface_STI, has_int_vertex < hface_STI > > > fie (fe) ; + _iterators.push_back ( new Wrapper < Insert < Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > >, InternalFace >, + TreeIterator < hface_STI, has_int_vertex < hface_STI > > >, InternalVertex > (fie)) ; + } + { + Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > > ew (container ()) ; + Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > >, InternalFace > fe (ew) ; + Insert < Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > >, InternalFace >, + TreeIterator < hface_STI, has_int_edge < hface_STI > > > fie (fe) ; + Wrapper < Insert < Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > >, InternalFace >, + TreeIterator < hface_STI, has_int_edge < hface_STI > > >, InternalEdge > dfie (fie) ; + Insert < Wrapper < Insert < Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > >, InternalFace >, + TreeIterator < hface_STI, has_int_edge < hface_STI > > >, InternalEdge >, + TreeIterator < hedge_STI, has_int_vertex < hedge_STI > > > difie (dfie) ; + _iterators.push_back (new Wrapper < Insert < Wrapper < Insert < Wrapper < + Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > >, InternalFace >, + TreeIterator < hface_STI, has_int_edge < hface_STI > > >, InternalEdge >, + TreeIterator < hedge_STI, has_int_vertex < hedge_STI > > >, InternalVertex > (difie)) ; + } + return new VectorAlign < vertex_STI > (_iterators) ; +} + +IteratorSTI < Gitter :: hedge_STI > * Gitter :: iterator (const hedge_STI *) { + vector < IteratorSTI < hedge_STI > * > _iterators ; + _iterators.push_back ( new leaf_edge__macro_edge__iterator (container ())) ; + Insert < AccessIterator < hface_STI > :: Handle, + TreeIterator < hface_STI, has_int_edge < hface_STI > > > nf (container ()) ; + Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_edge < helement_STI > > > ne (container ()) ; + Wrapper < Insert < AccessIterator < hface_STI > :: Handle, + TreeIterator < hface_STI, has_int_edge < hface_STI > > >, InternalEdge > ef (nf) ; + Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_edge < helement_STI > > >, InternalEdge > ee (ne) ; + _iterators.push_back ( new Insert < Wrapper < Insert < AccessIterator < hface_STI > :: Handle, + TreeIterator < hface_STI, has_int_edge < hface_STI > > >, InternalEdge >, + TreeIterator < hedge_STI, is_leaf < hedge_STI > > > (ef)) ; + _iterators.push_back ( new Insert < Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_edge < helement_STI > > >, InternalEdge >, + TreeIterator < hedge_STI, is_leaf < hedge_STI > > > (ee)) ; + Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > > nef (container ()) ; + Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > >, InternalFace > fnef (nef) ; + Insert < Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > >, InternalFace >, + TreeIterator < hface_STI, has_int_edge < hface_STI > > > fie (fnef) ; + Wrapper < Insert < Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > >, InternalFace >, + TreeIterator < hface_STI, has_int_edge < hface_STI > > >, InternalEdge > efie (fie) ; + _iterators.push_back (new Insert < Wrapper < Insert < Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > >, InternalFace >, + TreeIterator < hface_STI, has_int_edge < hface_STI > > >, InternalEdge >, + TreeIterator < hedge_STI, is_leaf < hedge_STI > > > (efie)) ; + return new VectorAlign < hedge_STI > (_iterators) ; +} + +IteratorSTI < Gitter :: hface_STI > * Gitter :: iterator (const hface_STI *) { + leaf_face__macro_face__iterator w1 (container ()) ; + Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > > nw (container ()) ; + Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > >, InternalFace > ww (nw) ; + Insert < Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > >, InternalFace >, + TreeIterator < hface_STI, is_leaf < hface_STI > > > www (nw) ; + return new AlignIterator < leaf_face__macro_face__iterator, + Insert < Wrapper < Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, has_int_face < helement_STI > > >, InternalFace >, + TreeIterator < hface_STI, is_leaf < hface_STI > > >, hface_STI > (w1, www) ; +} + +IteratorSTI < Gitter :: hbndseg_STI > * Gitter :: iterator (const hbndseg_STI *) { + return new leaf_bnd__macro_bnd__iterator (container ()) ; +} + +IteratorSTI < Gitter :: helement_STI > * Gitter :: iterator (const helement_STI *) { + return new leaf_element__macro_element__iterator (container ()) ; +} + +// --vertex iterator +IteratorSTI < Gitter :: vertex_STI > * Gitter :: iterator (const IteratorSTI < vertex_STI > * w) { + cerr << "ERROR: method not implemented! " << __FILE__ << " " << __LINE__ << "\n"; + abort(); + return 0; +} + +IteratorSTI < Gitter :: hedge_STI > * Gitter :: iterator (const IteratorSTI < hedge_STI > * w) { + cerr << "ERROR: method not implemented! " << __FILE__ << " " << __LINE__ << "\n"; + abort(); + return 0; +} + +IteratorSTI < Gitter :: hface_STI > * Gitter :: iterator (const IteratorSTI < hface_STI > * w) { + cerr << "ERROR: method not implemented! " << __FILE__ << " " << __LINE__ << "\n"; + abort(); + return 0; +} + +IteratorSTI < Gitter :: helement_STI > * Gitter :: iterator (const IteratorSTI < helement_STI > * w) { + return new leaf_element__macro_element__iterator (*(const leaf_element__macro_element__iterator *) w) ; +} + +void Gitter :: fullIntegrityCheck () { + const int start = clock() ; + int count = 0 ; + leaf_element__macro_element__iterator w (container ()) ; + for(w.first () ; !w.done () ; w.next ()) + w.item ().test () ? (cerr << "-> fehler gefunden am element : " << count << "\n" << endl, count++) : (count ++) ; + if (debugOption (3)) { + float used = (float)(clock () - start)/(float)(CLOCKS_PER_SEC) ; + cout << "**INFO Gitter :: fullIntegrityCheck () used : " << used << " sec." << endl ; + } + return ; +} + +void Gitter :: printsize () { + cout << "\n Gitter :: printSize () : \n\n" ; + if (debugOption (10)) { + { cout << " - Makroelemente .... " << AccessIterator < helement_STI > :: Handle (container ()).size() << "\n" ; } + { cout << " - Makror\"ander ..... " << AccessIterator < hbndseg_STI > :: Handle (container ()).size() << "\n" ; } + { cout << " - Makrofl\"achen .... " << AccessIterator < hface_STI > :: Handle (container ()).size() << "\n" ; } + { cout << " - Makrokanten ...... " << AccessIterator < hedge_STI > :: Handle (container ()).size() << "\n" ; } + { cout << " - Makrovertices .... " << AccessIterator < vertex_STI > :: Handle (container ()).size() << "\n" ; } + cout << "\n" ; + } + { cout << " - Elemente ......... " << LeafIterator < helement_STI > (*this)->size() << "\n" ;} + { cout << " - R\"ander .......... " << LeafIterator < hbndseg_STI > (*this)->size() << "\n" ;} + { cout << " - Fl\"achen ......... " << LeafIterator < hface_STI > (*this)->size() << "\n" ;} + { cout << " - Kanten ........... " << LeafIterator < hedge_STI > (*this)->size() << "\n" ;} + { cout << " - Vertices ......... " << LeafIterator < vertex_STI > (*this)->size() << "\n" ;} + cout << endl ; + return ; +} + +bool Gitter :: refine () { + assert (debugOption (20) ? (cout << "**INFO Gitter :: refine ()" << endl, 1) : 1) ; + bool x = true ; + { + leaf_element__macro_element__iterator i (container ()) ; + for( i.first(); ! i.done() ; i.next()) x &= i.item ().refine () ; + } + return x ; +} + +void Gitter :: coarse() { + assert (debugOption (20) ? (cout << "**INFO Gitter :: coarse ()" << endl, 1) : 1) ; + {AccessIterator < helement_STI > :: Handle i (container ()) ; + for( i.first(); ! i.done() ; i.next()) i.item ().coarse () ; } + return ; +} + +bool Gitter :: adapt () { + assert (debugOption (20) ? (cout << "**INFO Gitter :: adapt ()" << endl, 1) : 1) ; + assert (! iterators_attached ()) ; + const int start = clock () ; + + bool refined = refine (); + if (!refined) { + cerr << "**WARNUNG (IGNORIERT) Verfeinerung nicht vollst\"andig (warum auch immer)\n" ; + cerr << " diese Option ist eigentlich dem parallelen Verfeinerer vorbehalten.\n" ; + cerr << " Der Fehler trat auf in " << __FILE__ << " " << __LINE__ << endl ; + } + int lap = clock () ; + coarse () ; + int end = clock () ; + if (debugOption (1)) { + float u1 = (float)(lap - start)/(float)(CLOCKS_PER_SEC) ; + float u2 = (float)(end - lap)/(float)(CLOCKS_PER_SEC) ; + float u3 = (float)(end - start)/(float)(CLOCKS_PER_SEC) ; + cout << "**INFO Gitter :: adapt () [ref|cse|all] " << u1 << " " << u2 << " " << u3 << endl ; + } + return refined; +} + +void Gitter :: backupCMode (ostream & out) { + + // das Kompatibilit"ats - Backup f"ur backups im alten Modus. + + int i = 0 ; + while(1) { + Insert < AccessIterator < helement_STI > :: Handle, + TreeIterator < helement_STI, any_has_level < helement_STI > > > w (container (),i ++) ; + if (! w.size()) break ; + for(w.first() ; ! w.done() ; w.next()) w.item ().backupCMode (out) ; + out << endl ; + } + return ; +} + +void Gitter :: backup (ostream & out) { + assert (debugOption (20) ? (cout << "**INFO Gitter :: backup (ostream & = " << out << ") " << endl, 1) : 1) ; + {AccessIterator <hedge_STI> :: Handle fw (container ()) ; + for (fw.first(); !fw.done(); fw.next()) fw.item ().backup (out) ; } + {AccessIterator <hface_STI>::Handle fw (container ()) ; + for (fw.first () ; ! fw.done () ; fw.next ()) fw.item().backup(out) ; } + {AccessIterator <helement_STI> :: Handle ew (container ()) ; + for (ew.first () ; ! ew.done () ; ew.next ()) ew.item ().backup (out) ; } + + return ; +} + +void Gitter :: backup (XDRstream_out & out) { +/* + //assert (debugOption (20) ? (cout << "**INFO Gitter :: backup (ostream & = " << out << ") " << endl, 1) : 1) ; + {AccessIterator <hedge_STI> :: Handle fw (container ()) ; + for (fw.first(); !fw.done(); fw.next()) fw.item ().backup (out) ; } + {AccessIterator <hface_STI>::Handle fw (container ()) ; + for (fw.first () ; ! fw.done () ; fw.next ()) fw.item().backup(out) ; } + {AccessIterator <helement_STI> :: Handle ew (container ()) ; + for (ew.first () ; ! ew.done () ; ew.next ()) ew.item ().backup (out) ; } +*/ + return ; +} + +void Gitter ::restore (istream & in) { + assert (debugOption (20) ? (cout << "**INFO Gitter :: restore (istream & = " << in << ") " << endl, 1) : 1) ; + {AccessIterator < hedge_STI > :: Handle ew (container ()); + for (ew.first () ; !ew.done () ; ew.next ()) ew.item ().restore (in) ; } + {AccessIterator < hface_STI >:: Handle fw(container()); + for ( fw.first(); !fw.done (); fw.next()) fw.item().restore (in); } + {AccessIterator < helement_STI >:: Handle ew(container()); + for ( ew.first(); !ew.done(); ew.next()) ew.item().restore (in); } + {AccessIterator < hbndseg_STI > :: Handle bw (container ()) ; + for (bw.first () ; ! bw.done () ; bw.next ()) bw.item ().restoreFollowFace () ; } + notifyGridChanges () ; + return ; +} + +void Gitter ::restore (XDRstream_in & in) { + //assert (debugOption (20) ? (cout << "**INFO Gitter :: restore (istream & = " << in << ") " << endl, 1) : 1) ; +/* + {AccessIterator < hedge_STI > :: Handle ew (container ()); + for (ew.first () ; !ew.done () ; ew.next ()) ew.item ().restore (in) ; } + {AccessIterator < hface_STI >:: Handle fw(container()); + for ( fw.first(); !fw.done (); fw.next()) fw.item().restore (in); } + {AccessIterator < helement_STI >:: Handle ew(container()); + for ( ew.first(); !ew.done(); ew.next()) ew.item().restore (in); } + {AccessIterator < hbndseg_STI > :: Handle bw (container ()) ; + for (bw.first () ; ! bw.done () ; bw.next ()) bw.item ().restoreFollowFace () ; } + notifyGridChanges () ; +*/ + return ; +} + +void Gitter :: backup (const char * filePath, const char * fileName) { + + // Die Konstruktion des Backup und Restore ist folgendermassen gedacht: + // Jede "uberschreibende Methode mit Signatur (const char *) modifiziert + // lediglich den Dateinamen und delegiert dann an Gitter :: backup / restore. + // Gitter :: backup erzeugt dann event. Lockfiles usw. und in jedem Fall die + // Datenstr"ome, mit denen dann die Methoden mit der Signatur (.stream &) + // aufgerufen werden. Diese wiederum sollen polymorph reimplementiert + // werden, falls ein erweitertes backup / restore erforderlich ist. Dabei + // mu"s immer als erstes die backup / restore Methode der direkten Basisklasse + // aufgerufen werden. Auf diese Art kommt es zu einem strukturierten Konzept + // f"ur die Sicherung und Wiederherstellung, bei dem auch die objektorientierte + // Struktur der Gitterklassen ber"ucksichtigt wird. + + + assert (debugOption (20) ? (cout << "**INFO Gitter :: backup (const char * = \"" + << filePath << ", const char * =\"" + << fileName << "\") " << endl, 1) : 1) ; + + char *fullName = new char[strlen(filePath)+strlen(fileName)+1]; + sprintf(fullName,"%s%s",filePath,fileName); + + ofstream out (fullName) ; + if (!out) { + cerr << "**WARNUNG (IGNORIERT) Gitter :: backup (const char *, const char *) Fehler beim Anlegen von < " + << (fullName ? fullName : "null") << " >" << endl ; + } else { + FSLock lock (fullName) ; + backup (out) ; + container ().backup (filePath, fileName) ; + } + + delete [] fullName; + + return ; +} + + +void Gitter :: backupCMode (const char * filePath, const char * fileName) { + assert (debugOption (20) ? (cout << "**INFO Gitter :: backupCMode (const char * = \"" + << filePath << ", const char * = \"" + << fileName << "\") " << endl, 1) : 1) ; + + char *fullName = new char[strlen(filePath)+strlen(fileName)+1]; + sprintf(fullName,"%s%s",filePath,fileName); + + ofstream out (fullName) ; + if (!out) { + cerr << "**WARNUNG (IGNORIERT) Gitter :: backupCMode (const char *) Fehler beim Anlegen von < " + << (fullName ? fullName : "null") << " >" << endl ; + } else { + backupCMode (out) ; + container ().backupCMode (filePath, fileName) ; + } + + delete [] fullName; + + return ; +} + +void Gitter :: restore (const char * filePath, const char * fileName) { + + // Erkl"arung siehe Gitter :: backup (const char *, const char *) in gitter_sti.cc ; + + assert (debugOption (20) ? (cout << "**INFO Gitter :: restore (const char * = \"" + << filePath << ", const char * = \"" + << fileName << "\") " << endl, 1) : 1) ; + + char *fullName = new char[strlen(filePath)+strlen(fileName)+1]; + sprintf(fullName,"%s%s",filePath,fileName); + + ifstream in (fullName) ; + if (!in) { + cerr << "**WARNUNG (IGNORIERT) Gitter :: restore (const char *, const char*) Fehler beim \"Offnen von < " + << (fullName ? fullName : "null") << " > " << endl ; + } else { + restore (in) ; + } + + delete [] fullName; + + return ; +} + +void Gitter :: refineGlobal () { + assert (debugOption (20) ? (cout << "**INFO Gitter :: refineGlobal () " << endl, 1) : 1) ; + const int start = clock () ; + {leaf_element__macro_element__iterator w (container ()) ; + for (w.first () ; ! w.done () ; w.next ()) w.item (). tagForGlobalRefinement () ; } + adapt () ; + if (debugOption (2)) + cout << " Gitter :: refineGlobal () used " + << (double)(clock () - start)/(double)(CLOCKS_PER_SEC) << " sec." << endl ; + return ; +} + +void Gitter :: refineRandom (double p) { + assert (debugOption (20) ? (cout << "**INFO Gitter :: refineRandom (double = " << p << ") " << endl, 1) : 1) ; + const int start = clock () ; + if (p < .0 || p > 1.) { + cerr << "**WARNUNG (IGNORIERT) Gitter :: refineRandom (double = " << p << ") Argument muss zwischen 0 und 1 liegen" << endl ; + } else { + { + leaf_element__macro_element__iterator w (container ()) ; + for (w.first () ; ! w.done () ; w.next ()) + if( drand48 () < p ) w.item ().tagForGlobalRefinement (); + } + adapt () ; + if (debugOption (2)) + cout << "**INFO Gitter :: refineRandom () used " + << (double)(clock () - start)/(double)(CLOCKS_PER_SEC) << " sec." << endl ; + } + return ; +} + +void Gitter :: refineBall (const double (¢er)[3], double radius, int limit) { + if (radius < .0) { + cerr << "**WARNUNG (IGNORIERT) Gitter :: refineBall (center = ?, radius = " + << radius << ") Radius darf nicht negativ sein" << endl ; + } else { + const int start = clock () ; + { + leaf_element__macro_element__iterator w (container ()) ; + for (w.first () ; ! w.done () ; w.next ()) + w.item (). tagForBallRefinement (center,radius,limit) ; + } + adapt () ; + if (debugOption (2)) + cout << "**INFO Gitter :: refineBall () used " + << (double)(clock () - start)/(double)(CLOCKS_PER_SEC) << " sec." << endl ; + } + return ; +} + +void Gitter :: notifyGridChanges () { + assert (debugOption (20) ? (cout << "**INFO Gitter :: notifyGridChanges () " << endl, 1) : 1) ; + return ; +} + +void Gitter :: notifyMacroGridChanges () { + assert (debugOption (20) ? (cout << "**INFO Gitter :: notifyMacroGridChanges () " << endl, 1) : 1) ; + return ; +} + +Gitter :: ~Gitter () { + if (ref) + cerr << "**WARNUNG (IGNORIERT) Gitter-Referenzz\"ahler beim L\"oschen [" << ref << "]" << endl ; + return ; +} + +int Gitter :: Makrogitter :: iterators_attached () const { + return AccessIterator < vertex_STI > :: ref + AccessIterator < hedge_STI > :: ref + + AccessIterator < hface_STI > :: ref + AccessIterator < helement_STI > :: ref + + AccessIterator < hbndseg_STI > :: ref ; +} + +Gitter :: Makrogitter :: ~Makrogitter () { + if (iterators_attached()) + cerr << "**WARNUNG (IGNORIERT) in " << __FILE__ << " " << __LINE__ << endl ; + return ; +} + +#endif diff --git a/src/serial/gitter_sti.h b/src/serial/gitter_sti.h new file mode 100644 index 0000000000000000000000000000000000000000..f1d54806824a5b414d093bfcf86e10f56b64f80e --- /dev/null +++ b/src/serial/gitter_sti.h @@ -0,0 +1,2540 @@ +// (c) Bernhard Schupp 1997 - 1998 +// modifications for Dune Interface +// (c) Robert Kloefkorn 2004 - 2005 +#ifndef GITTER_STI_H_INCLUDED +#define GITTER_STI_H_INCLUDED + +#ifdef IBM_XLC + #define _ANSI_HEADER +#endif + +#include <assert.h> + +#ifdef _ANSI_HEADER + using namespace std; + #include <utility> + #include <iostream> + #include <list> +#else + #include <pair.h> + #include <iostream.h> + #include <list.h> +#endif + +#include "myalloc.h" +#include "parallel.h" + +#include "xdrclass.h" + +// if DUNE uses this grid the _DUNE_USES_BSGRID_ variable should be defined +// otherwise some dummy are set +#include "indexstack.h" +#ifdef _DUNE_USES_BSGRID_ +enum { lengthOfFiniteStack = 10000 }; +typedef IndexStack<int,lengthOfFiniteStack> IndexManagerType; +#else +typedef DummyIndexStack<int> IndexManagerType; +typedef BSGridVec double; +#endif + +// number of different index manager that exists +enum { numOfIndexManager = 6 }; +// 0 == elements +// 1 == faces +// 2 == edges +// 3 == vertices +// 4 == boundary elements +// 5 == dummy index for unused internal bnd + + +class ProjectVertex { + public: + virtual int operator()(const double (&p)[3],double (&ret)[3]) const = 0; +}; + + + // Einfacher Referenzenz"ahler mit cast-around-const + // feature, der zum Z"ahlen der Referenzen auf Fl"achen + // Kanten und Knoten verwendet wird. Vorteil: Objekte, + // die einen Z"ahler dieser Klasse enthalten, werden + // durch Inkrementierung bzw. Dekrementierung des Z"ahlers + // nicht ver"andert (k"onnen also auch 'const' sein). + +class Refcount { +#ifndef NDEBUG + + // Der Globale Z"ahler soll helfen, nicht gel"oschte + // Gitterobjekte oder Iteratorobjekte zu erkennen. + // (Wird aber nur in den DEBUG-Versionen angelegt.) + + class Globalcount { + int _c ; + public : + inline Globalcount() ; + ~Globalcount() ; + inline void operator ++ (int) const ; + inline void operator -- (int) const ; + } ; + static Globalcount _g ; +#endif + int _c ; + public : + inline Refcount () ; + inline ~Refcount () ; + inline int operator ++ (int) const ; + inline int operator ++ () const ; + inline int operator -- (int) const ; + inline int operator -- () const ; + inline bool operator ! () const ; + inline operator int () const ; +} ; + + // Schnittstelle des Iterationsobjekts vgl. Gamma, Helm, Johnson & + // Vlissides: Design Patterns; Addison Wesley + // Die Schnittstellenbeschreibung wird sowohl polymorph als auch + // in den verschiedenen Schablonen f"ur einfache Iterationsobjekte + // s.a. Datei 'walk.h' verwendet. + +template < class A > class IteratorSTI { + const IteratorSTI < A > & operator = (const IteratorSTI < A > &) ; + IteratorSTI (const IteratorSTI < A > &) {} + public : + typedef A val_t ; + IteratorSTI () {} + virtual ~IteratorSTI () {} + virtual void first () ; + virtual void next () ; + virtual int done () const ; + virtual int size () ; + virtual val_t & item () const ; +} ; + + // sobald die const-correctness verbessert wird ... + +template < class A > class ConstIteratorSTI { + const ConstIteratorSTI < A > & operator = (const ConstIteratorSTI < A > &) ; + ConstIteratorSTI (const ConstIteratorSTI < A > &) {} + public : + typedef A val_t ; + ConstIteratorSTI () {} + virtual ~ConstIteratorSTI () {} + virtual void first () ; + virtual void next () ; + virtual int done () const ; + virtual int size () ; + virtual const val_t & item () const ; +} ; + + // AccessIterator < . > ist eine Schnittstellenschablone, die + // ausgepr"agt mit vertex, hedge, hface, helement und hbndseg + // die Schnittstellen des Grobgittercontainers zur Erstellung + // und Kopie von Iterationsobjekten erzeugt. + +template < class A > class AccessIterator { + public : + Refcount ref ; + virtual IteratorSTI < A > * iterator (const A *) const = 0 ; + virtual IteratorSTI < A > * iterator (const IteratorSTI < A > *) const = 0 ; + public : + + // Handle ist ein einfaches Iteratorproxy, das ein abstraktes + // Iterationsobjekt verwendet, um nach aussen die entsprechenden + // Schnittstellenmethoden zu implementieren. Dabei ist dem Proxy + // nur bekannt, wie ein Iterator von der entsprechenden Schnittstelle + // zu bekommen ist, bzw. wie ein bestehender mit einer Schnittstellen- + // methode kopiert werden kann. + + class Handle : public IteratorSTI < A > { + AccessIterator < A > * _fac ; + A * _a ; + IteratorSTI < A > * _w ; + public : + inline Handle (AccessIterator < A > &) ; + inline Handle (const AccessIterator < A > :: Handle &) ; + inline Handle () ; + inline ~Handle () ; + inline const Handle & operator = (const AccessIterator < A > :: Handle &) ; + inline bool operator == (const AccessIterator < A > :: Handle &) const ; + inline bool operator < (const AccessIterator < A > :: Handle &) const ; + inline void first () ; + inline void next () ; + inline int done () const ; + inline int size () ; + inline A & item () const ; + } ; + protected : + AccessIterator () {} + virtual ~AccessIterator () { assert (!ref) ; } +} ; + +template < class A > class LeafIterator ; +template < class A > class ConstLeafIterator ; + +class Gitter { + Refcount ref ; + public : + static inline bool debugOption (int = 0) ; + + typedef Parallel stiExtender_t ; // parallel.h + + // Nachfolgend sind die Iterationsschnittstellen der Knoten, + // Kanten, Fl"achen, Elemente und Randelemente definiert. + class Dune_vertex + { +#ifdef _DUNE_USES_BSGRID_ + protected: + int _idx; + Dune_vertex () : _idx(-1) {} +#endif + public: + // backup and restore index of vertices + virtual void backupIndex (ostream & os ) const {}; + virtual void restoreIndex (istream & is ) {}; + +#ifdef _DUNE_USES_BSGRID_ + inline int getIndex () const { return _idx; } + void setIndex ( const int index ) { _idx = index; } +#else + inline int getIndex () const { return -1; } + void setIndex ( const int index ) {} +#endif + }; + + + public : + class vertex : public stiExtender_t :: VertexIF +#ifdef _DUNE_USES_BSGRID_ + , public Dune_vertex +#endif + { + protected : + vertex () {} + virtual ~vertex () {} + public : + virtual int ident () const = 0 ; + virtual int level () const = 0 ; + virtual const double (& Point () const )[3] = 0 ; + + // Methode um einen Vertex zu verschieben; f"ur die Randanpassung + virtual void project(const ProjectVertex &pv) = 0; + + // Extrainteger, damit die Element zu Vertex Zuordnug klappt, + // wenn die Daten zur Visualisierung mit GRAPE rausgeschrieben + // werden sollen: + + } ; + + // numbering for hedge and hface + class Dune_hface_or_hedge + { +#ifdef _DUNE_USES_BSGRID_ + protected: + int _index; // global_index, unique per level but not per processor + Dune_hface_or_hedge () : _index (-1) {} +#endif + public: + // use only this methods to get and set the _index + inline int getIndex () const; + inline void setIndex (const int index) ; + + virtual void backupIndex (ostream &) const ; // backup _index + + // method is virual, because former index set by constructor has to + // be freeed , means method has to be overloaded for correct work + virtual void restoreIndex (istream &) ;// retore _index + }; + + class hedge : public stiExtender_t :: EdgeIF, public Dune_hface_or_hedge { + protected : + hedge () {} + virtual ~hedge () {} + public : + virtual hedge * down () = 0 ; + virtual const hedge * down () const = 0 ; + virtual hedge * next () = 0 ; + virtual const hedge * next () const = 0 ; + virtual vertex * innerVertex () = 0 ; + virtual const vertex * innerVertex () const = 0 ; + virtual int level () const = 0 ; + inline int leaf () const ; + public : + virtual bool coarse () = 0 ; + virtual void backup (ostream &) const = 0 ; + virtual void restore (istream &) = 0 ; + + // new xdr methods + //virtual void backup (XDRstream_out &) const {}; + //virtual void restore (XDRstream_in &) {}; + // Methode um einen Vertex zu verschieben; f"ur die Randanpassung + virtual void projectInnerVertex(const ProjectVertex &pv) = 0; + } ; + + class hface : public stiExtender_t :: FaceIF , public Dune_hface_or_hedge { + protected : + hface () {} + virtual ~hface () {} + public : + virtual hface * down () = 0 ; + virtual const hface * down () const = 0 ; + virtual hface * next () = 0 ; + virtual const hface * next () const = 0 ; + virtual vertex * innerVertex () = 0 ; + virtual const vertex * innerVertex () const = 0 ; + virtual hedge * innerHedge () = 0 ; + virtual const hedge * innerHedge () const = 0 ; + virtual int level () const = 0 ; + inline int leaf () const ; + public : + virtual bool coarse () = 0 ; + virtual void backup (ostream &) const = 0 ; + virtual void restore (istream &) = 0 ; + + //virtual void backup (XDRstream_out &) const {}; + //virtual void restore (XDRstream_in &) {}; + + // Methode um einen Vertex zu verschieben; f"ur die Randanpassung + virtual void projectVertex(const ProjectVertex &pv) = 0; + } ; + + // class with all extensions for helement + class Dune_helement + { + +#ifdef _DUNE_USES_BSGRID_ + protected: + int _index; // global_index, unique per level but not per processor + bool _refinedTag; // true if element was refined + Dune_helement () : _index (-1) , _refinedTag (true) {} +#endif + public: + // reset the _refinedTag to false + void resetRefinedTag(); + // true if element was refined this adaptation step + bool hasBeenRefined () const; + + // use only this methods to get and set the _index + inline int getIndex () const; + inline void setIndex (const int index) ; + + virtual void backupIndex (ostream &) const ; // backup _index + + // method is virual, because former index set by constructor has to + // be freeed , means method has to be overloaded for correct work + virtual void restoreIndex (istream &) ;// retore _index + + // the Dune extentions + + // calculate outer normal of face face + virtual void outerNormal(int face, double * normal) + { + cerr << "helement :: outerNormal(..) : in " << __FILE__ << " " << __LINE__ << " not overloaded! \n"; + abort(); + } + + // calculate outer normal of face face + virtual void neighOuterNormal(int faceInNeigh, double * normal) + { + cerr << "helement :: neighOuterNormal(..) : in " << __FILE__ << " " << __LINE__ << " not overloaded! \n"; + abort(); + } + }; + + class helement : public virtual stiExtender_t :: ElementIF + , public Dune_helement + { + protected : + helement () {} + virtual ~helement () {} + public : + //testweise us + virtual helement * up () = 0; + virtual const helement * up () const = 0; + //us + virtual helement * down () = 0 ; + virtual const helement * down () const = 0 ; + virtual helement * next () = 0 ; + virtual const helement * next () const = 0 ; + virtual vertex * innerVertex () = 0 ; + virtual const vertex * innerVertex () const = 0 ; + virtual hedge * innerHedge () = 0 ; + virtual const hedge * innerHedge () const = 0 ; + virtual hface * innerHface () = 0 ; + virtual const hface * innerHface () const = 0 ; + virtual int level () const = 0 ; + + virtual int tagForGlobalRefinement () = 0 ; + virtual int resetRefinementRequest () = 0 ; + virtual int tagForBallRefinement (const double (&)[3],double,int) = 0 ; + virtual int test () const = 0 ; + inline int leaf () const ; + public : + virtual bool refine () = 0 ; + virtual bool coarse () = 0 ; + virtual void backupCMode (ostream &) const = 0 ; + virtual void backup (ostream &) const = 0 ; + virtual void restore (istream &) = 0 ; + + // xdr methods + //virtual void backup (XDRstream_out &) const {}; + //virtual void restore (XDRstream_in &) {}; + public: + virtual grid_t type() = 0; + } ; + + + class hbndseg + { + protected : + hbndseg () {} + virtual ~hbndseg () {} + public : + typedef enum { none = 0, inflow = 1, outflow = 2, noslip = 3, slip = 4, sym_xy = 5, + sym_xz = 6, sym_yz = 7, reflect = 8, fluxtube3d = 9, periodic = 20, + closure = 111, ghost_closure = 222 , undefined = 333 } bnd_t ; + virtual bnd_t bndtype () const = 0 ; + + // for dune + virtual hbndseg * up () = 0 ; + virtual const hbndseg * up () const = 0 ; + + virtual hbndseg * down () = 0 ; + virtual const hbndseg * down () const = 0 ; + virtual hbndseg * next () = 0 ; + virtual const hbndseg * next () const = 0 ; + virtual int level () const = 0 ; + inline int leaf () const ; + // for dune + virtual int ghostLevel () const = 0 ; + // default return 0 means we have no ghost element on this boundary + // segment, because we only have ghost on interior boundary + virtual helement * getGhost () = 0; // should return 0 for not interior boundaries + virtual void faceNormal (double * normal) const = 0 ; + public : + virtual void restoreFollowFace () = 0 ; + } ; + public : + typedef hbndseg hbndseg_STI ; + typedef helement helement_STI ; + typedef hface hface_STI ; + typedef hedge hedge_STI ; + typedef vertex vertex_STI ; + + // Die Klassen Internal-*- sind nur daf"ur da, aus einem Element, einer + // Fl"ache oder einer Kante die inneren geometrischen Objekte, die von + // dort verwaltet werden 'ans Licht zu f"ordern'. Sie werden ben"otigt, + // um z.B. von einem Iterator mit Element-Item auf einen Teilbaumiterator + // der inneren Fl"achen "uberzugehen. + + class InternalVertex { + public : + typedef vertex_STI val_t ; + val_t & operator () (helement_STI & e) const { return * e.innerVertex () ; } + val_t & operator () (hface_STI & f) const { return * f.innerVertex () ; } + val_t & operator () (hedge_STI & d) const { return * d.innerVertex () ; } + val_t & operator () (vertex_STI & v) const { return v ; } + } ; + class InternalEdge { + public : + typedef hedge_STI val_t ; + val_t & operator () (helement_STI & e) const { return * e.innerHedge () ; } + val_t & operator () (hface_STI & f) const { return * f.innerHedge () ; } + val_t & operator () (hedge_STI & e) const { return e ; } + } ; + class InternalFace { + public : + typedef hface_STI val_t ; + val_t & operator () (helement_STI & e) const { return * e.innerHface () ; } + val_t & operator () (hface_STI & f) const { return f ; } + } ; + class InternalBndseg { + public : + typedef hbndseg_STI val_t ; + val_t & operator () (hbndseg_STI & b) const { return b ; } + } ; + class InternalElement { + public : + typedef helement_STI val_t ; + val_t & operator () (helement_STI & e) const { return e ; } + } ; + + public : + + // Die allgemeinste Schnittstelle zum Grobgittercontainer enth"alt Methoden zum + // Anfordern und Kopieren von Iterationsobjekten, die aber nur im Sinne ihres + // abstrakten Interfaces bekannt sind. + // Das Makrogitterinterface beerbt erst mal die verschiedenen Auspr"agungen f"ur + // Schnittstellen zu Anforderung von Iterationsobjekten. Alles ganz abstrakt bis hier. + + class Makrogitter : public AccessIterator < vertex_STI >, public AccessIterator < hedge_STI >, + public AccessIterator < hface_STI >, public AccessIterator < hbndseg_STI >, + public AccessIterator < helement_STI > { + protected : + Makrogitter () {} + virtual ~Makrogitter () ; + public : + virtual int iterators_attached () const ; + virtual void backup (ostream &) const = 0 ; + virtual void backup (const char*,const char *) const = 0 ; + virtual void backupCMode (ostream &) const = 0 ; + virtual void backupCMode (const char *,const char *) const = 0 ; + + // Methoden f"ur den Strahlungstransportl"oser + virtual void sortmacrogrid () {abort();} + } ; + public : + class Geometric { + + // Innerhalb des Namensraums Geometric sind zuerst die Klassen mit den + // Verfeinerungsregeln und dann die Geometriesockelklassen VertexGeo, + // Hedge1, Hface3, Hface4, Tetra, Hexa, Hbndseg3/4 + // sowie die Polygonverbinder (Schnittstellen) hasFace3/4 definiert. + + public : + class VertexGeo ; + class hedge1 ; + class hface4 ; + class hface3 ; + class hasFace3 ; + class hasFace4 ; + class Tetra ; + class Hexa ; + class hbndseg3 ; + class hbndseg4 ; + public : + + // Die Verfeinerungsregeln sind nur enumerierte Typen, mit Zuweisung + // Vergleich und Typkonversion, im Falle der Regeln f"ur die Dreiecks- + // bzw Vierecksfl"ache sind aber auch Methoden n"otig, die eine Regel + // mit dem Twist der Fl"ache mitdrehen, damit der "Ubergang der + // Verfeinerung stimmt. + + class Hedge1Rule { + public : + typedef enum { invalid=0, nosplit=1, iso2 } rule_t ; + private : + rule_t _r ; + public : + inline Hedge1Rule (int) ; + inline Hedge1Rule (rule_t = nosplit) ; + inline bool operator == (rule_t) const ; + inline operator int () const ; + inline bool isValid () const ; + inline Hedge1Rule rotate (int) const ; + } ; + + class Hface3Rule { + public : + typedef enum { nosplit=1, e01, e12, e20, iso4 } rule_t ; + public : + inline Hface3Rule (int) ; + inline Hface3Rule (rule_t = nosplit) ; + inline operator int () const ; + inline bool operator == (rule_t) const ; + inline bool isValid () const ; + inline Hface3Rule rotate (int) const ; + private : + rule_t _r ; + } ; + + class Hface4Rule { + public : + typedef enum { nosplit=1, iso4, ni02, ni13 } rule_t ; + public : + inline Hface4Rule (int) ; + inline Hface4Rule (rule_t = nosplit) ; + inline operator int () const ; + inline bool operator == (rule_t) const ; + inline bool isValid () const ; + inline Hface4Rule rotate (int) const ; + private : + rule_t _r ; + } ; + + class TetraRule { + public : + typedef enum { crs = -1, nosplit = 1, e01, e12, e20, e23, e30, e31, iso8 } rule_t ; + public : + inline TetraRule (int) ; + inline TetraRule (rule_t = nosplit) ; + inline operator int () const ; + inline bool operator == (rule_t) const ; + inline bool isValid () const ; + private : + rule_t _r ; + } ; + + class HexaRule { + public : + typedef enum { crs = -1, nosplit = 1, iso8 } rule_t ; + public : + inline HexaRule (int) ; + inline HexaRule (rule_t = nosplit) ; + inline operator int () const ; + inline bool operator == (rule_t) const ; + inline bool isValid () const ; + private : + rule_t _r ; + } ; + + public : + + // Die Geometriesockelklassen sind die Grundlage zur Implementierung + // numerischer Verfahren auf den bestimmten Elementtypen, und erlauben + // alle Man"over, die "uber die geometrische Information verf"ugen + // m"ussen, wie z.B. Navigation zur Fl"ache, zu den Kanten und Knoten, + // aber auch Anforderungen an den Nachbarn. + + class hasFace3 : public virtual stiExtender_t :: ElementIF { + public : + typedef Hface3Rule balrule_t ; + virtual bool refineBalance (balrule_t,int) = 0 ; + virtual bool bndNotifyCoarsen () = 0 ; + protected : + hasFace3 () {} + virtual ~hasFace3 () {} + inline bool bndNotifyBalance (balrule_t,int) ; + +// Schwerpunkt des anliegenden Elements beschaffen: + public: + virtual const double (& barycenter () const)[3] { + static double p [3] = {.0,.0,.0} ; + return p ; + } +// Ende + public: + virtual int calcSortnr (int,int) {return (abort(),0);} + virtual bool isboundary() = 0; + + virtual helement_STI * mySelf() { return ((helement_STI *) this); } + } ; + + class hasFace4 : public virtual stiExtender_t :: ElementIF { + public : + typedef Hface4Rule balrule_t ; + virtual bool refineBalance (balrule_t,int) = 0 ; + virtual bool bndNotifyCoarsen () = 0 ; + protected : + hasFace4 () {} + virtual ~hasFace4 () {} + inline bool bndNotifyBalance (balrule_t,int) ; + +// Schwerpunkt des anliegenden Elements beschaffen: + public: + virtual const double (& barycenter () const)[3] { + static double p [3] = {.0,.0,.0} ; + return p ; + } +// Ende + } ; + + class VertexGeo : public vertex_STI, public MyAlloc + { + protected: + IndexManagerType & _indexmanager; + public : + Refcount ref ; + // VertexGeo is provided for the vertices on lower levels + inline VertexGeo (int,double,double,double, VertexGeo & ) ; + inline VertexGeo (int,double,double,double, IndexManagerType & im ) ; + inline virtual ~VertexGeo () ; + inline const double (& Point () const) [3] ; + inline int level () const ; + // Methode um einen Vertex zu verschieben; f"ur die Randanpassung + virtual inline void project(const ProjectVertex &pv) ; + + inline void backup (ostream & os ) const; + inline void restore (istream & is ) ; + + // Extramethode zum Rausschreiben der Elementdaten in einfachem + // Format f"ur die Visualisierung mit GRAPE: + + //inline int & vertexIndex () ; + //inline int vertexIndex () const ; + private : + double _c [3] ; + int _lvl ; +#ifndef _DUNE_USES_BSGRID_ + int _idx ; // Vertexindex zum Datenrausschreiben +#endif // wird nur verwendet, wenn nicht fuer Dune ubersetzt + } ; + + typedef class hedge1 : public hedge_STI, public MyAlloc { + protected : + typedef VertexGeo myvertex_t ; + inline hedge1 (myvertex_t *,myvertex_t *) ; + inline int postRefinement () ; + inline int preCoarsening () ; + inline bool lockedAgainstCoarsening () const ; + public : + typedef Hedge1Rule myrule_t ; + inline virtual ~hedge1 () ; + Refcount ref ; + inline myvertex_t * myvertex (int) ; + inline const myvertex_t * myvertex (int) const ; + virtual myvertex_t * subvertex (int) = 0 ; + virtual const myvertex_t * subvertex (int) const = 0 ; + virtual hedge1 * subedge1 (int) = 0 ; + virtual const hedge1 * subedge1 (int) const = 0 ; + public : + virtual myrule_t getrule () const = 0 ; + virtual void refineImmediate (myrule_t) = 0 ; + private : + myvertex_t * v0, * v1 ; + } hedge1_GEO ; + + typedef class hface3 : public hface_STI, public MyAlloc { + public : + typedef hasFace3 myconnect_t ; + enum { polygonlength = 3 } ; + class face3Neighbour { + pair < hasFace3 *, int > _v, _h ; + public : + static const pair < myconnect_t *, int > null ; + inline face3Neighbour () ; + inline void operator = (const face3Neighbour &) ; + inline int complete (const face3Neighbour &) ; + inline pair < myconnect_t *, int > front () ; + inline pair < const myconnect_t *, int > front () const ; + inline pair < myconnect_t *, int > rear () ; + inline pair < const myconnect_t *, int > rear () const ; + friend class hface3 ; + } nb ; + protected : + typedef VertexGeo myvertex_t ; + typedef hedge1_GEO myhedge1_t ; + public : + typedef Hface3Rule myrule_t ; + protected : + inline hface3 (myhedge1_t *,int,myhedge1_t *,int,myhedge1_t *,int) ; + inline int postRefinement () ; + inline int preCoarsening () ; + public : + inline virtual ~hface3 () ; + Refcount ref ; + inline void attachElement (const pair < hasFace3 *, int > &,int) ; + inline void detachElement (int) ; + public : + inline int twist (int) const ; + inline myvertex_t * myvertex (int) ; + inline const myvertex_t * myvertex (int) const ; + inline myhedge1_t * myhedge1 (int) ; + inline const myhedge1_t * myhedge1 (int) const ; + virtual hface3 * down () = 0 ; + virtual const hface3 * down () const = 0 ; + virtual hface3 * next () = 0 ; + virtual const hface3 * next () const = 0 ; + virtual myvertex_t * subvertex (int) = 0 ; + virtual const myvertex_t * subvertex (int) const = 0 ; + virtual myhedge1_t * subedge1 (int) = 0 ; + virtual const myhedge1_t * subedge1 (int) const = 0 ; + virtual hface3 * subface3 (int) = 0 ; + virtual const hface3 * subface3 (int) const = 0 ; + public : + virtual myrule_t getrule () const = 0 ; + virtual bool refine (myrule_t,int) = 0 ; + virtual void refineImmediate (myrule_t) = 0 ; + + protected : + myhedge1_t * e [polygonlength] ; + signed char s [polygonlength] ; + +// H"ohere Ordnung: 1. Regel des Elternelements, 2. Nummer in der Reihe der Kinder +// 3. Nichtkonforme Situation vorne, 4. Ninchtkonforme Situation hinten +// bei 3. + 4. ja=1, nein=0 + signed char _parRule, _nChild, _nonv, _nonh ; +// Ende: H"ohere Ordnung + + } hface3_GEO ; + + typedef class hface4 : public hface_STI, public MyAlloc { + public : + typedef hasFace4 myconnect_t ; + enum { polygonlength = 4 } ; + class face4Neighbour { + pair < myconnect_t *, int > _v, _h ; + public : + static const pair < myconnect_t *, int > null ; + inline face4Neighbour () ; + inline void operator = (const face4Neighbour &) ; + inline int complete (const face4Neighbour &) ; + inline pair < myconnect_t *, int > front () ; + inline pair < const myconnect_t *, int > front () const ; + inline pair < myconnect_t *, int > rear () ; + inline pair < const myconnect_t *, int > rear () const ; + friend class hface4 ; + } nb ; + protected : + typedef VertexGeo myvertex_t ; + typedef hedge1_GEO myhedge1_t ; + public : + typedef Hface4Rule myrule_t ; + protected : + inline hface4 (myhedge1_t *,int,myhedge1_t *,int,myhedge1_t *,int,myhedge1_t *,int) ; + inline int postRefinement () ; + inline int preCoarsening () ; + public : + inline virtual ~hface4 () ; + Refcount ref ; + inline void attachElement (const pair < hasFace4 *, int > &,int) ; + inline void detachElement (int) ; + public : + inline int twist (int) const ; + inline myvertex_t * myvertex (int) ; + inline const myvertex_t * myvertex (int) const ; + inline myhedge1_t * myhedge1 (int) ; + inline const myhedge1_t * myhedge1 (int) const ; + virtual hface4 * down () = 0 ; + virtual const hface4 * down () const = 0 ; + virtual hface4 * next () = 0 ; + virtual const hface4 * next () const = 0 ; + virtual myvertex_t * subvertex (int) = 0 ; + virtual const myvertex_t * subvertex (int) const = 0 ; + virtual myhedge1_t * subedge1 (int) = 0 ; + virtual const myhedge1_t * subedge1 (int) const = 0 ; + virtual hface4 * subface4 (int) = 0 ; + virtual const hface4 * subface4 (int) const = 0 ; + public : + virtual myrule_t getrule () const = 0 ; + virtual bool refine (myrule_t,int) = 0 ; + virtual void refineImmediate (myrule_t) = 0 ; + + private : + myhedge1_t * e [polygonlength] ; + signed char s [polygonlength] ; + } hface4_GEO ; + + // Geometriesockelklasse des Tetraeders: Vorsicht der Prototyp der dem + // Tetraeder zugrunde liegt, hat eine nach links (gegen Uhrzeigersinn) + // umlaufende Numerierung der Knoten auf den Randfl"achen, wenn aus + // dem Element herausgeblickt wird. Die Konvention f"ur den Hexaeder + // ist leider genau umgekehrt. Dies sollte beim Aufbau von Pyramiden + // und Prismen sorgf"altig bedacht werden. + // Der Prototyp steht in 'gitter_geo.cc'. + + typedef class Tetra : public helement_STI, public hasFace3, public MyAlloc { + protected : + typedef VertexGeo myvertex_t ; + typedef hedge1_GEO myhedge1_t ; + typedef hface3_GEO myhface3_t ; + typedef TetraRule myrule_t ; + inline Tetra (myhface3_t *, int, myhface3_t *, int, myhface3_t *, int, myhface3_t *, int) ; + inline int postRefinement () ; + inline int preCoarsening () ; + public : + static const int prototype [4][3] ; + inline virtual ~Tetra () ; + inline hface3_GEO * myhface3 (int) ; + inline const hface3_GEO * myhface3 (int) const ; + inline VertexGeo * myvertex (int) ; + inline const VertexGeo * myvertex (int) const ; + inline VertexGeo * myvertex (int,int) ; + inline const VertexGeo * myvertex (int,int) const ; + inline pair < hasFace3 *, int > myneighbour (int) ; + inline pair < const hasFace3 *, int > myneighbour (int) const ; + + // Dune extension + // return pair, first = pointer to face, second = twist of face + inline pair < hface3_GEO *, int > myintersection (int) ; + inline pair < const hface3_GEO *, int > myintersection (int) const; + + inline int twist (int) const ; + int test () const ; + public : + virtual myrule_t getrule () const = 0 ; + + // return rule which was set by request + virtual myrule_t requestrule () const = 0 ; + + virtual void request (myrule_t) = 0 ; + int tagForGlobalRefinement () ; + int resetRefinementRequest () ; + int tagForBallRefinement (const double (&)[3],double,int) ; + virtual bool isboundary() {return false;} + virtual grid_t type() {return tetra;} + + // Dune extentions + + // calculate outer normal of face face + virtual void outerNormal (int face , double * normal ); + virtual void neighOuterNormal (int faceInNeigh , double * normal ); + + private : + myhface3_t * f [4] ; + signed char s [4] ; + } tetra_GEO ; + + // Geometriesockelklasse des periodischen Randelements mit zwei + // 3-Punkt-Fl"achen. + + typedef class Periodic3 : public helement_STI, public hasFace3, public MyAlloc { + protected : + typedef VertexGeo myvertex_t ; + typedef hedge1_GEO myhedge1_t ; + typedef hface3_GEO myhface3_t ; + typedef Hface3Rule myrule_t ; + inline Periodic3 (myhface3_t *, int, myhface3_t *, int) ; + inline int postRefinement () ; + inline int preCoarsening () ; + public : + static const int prototype [2][3] ; + inline virtual ~Periodic3 () ; + inline hface3_GEO * myhface3 (int) ; + inline const hface3_GEO * myhface3 (int) const ; + inline VertexGeo * myvertex (int) ; + inline const VertexGeo * myvertex (int) const ; + inline VertexGeo * myvertex (int,int) ; + inline const VertexGeo * myvertex (int,int) const ; + inline pair < hasFace3 *, int > myneighbour (int) ; + inline pair < const hasFace3 *, int > myneighbour (int) const ; + inline int twist (int) const ; + int test () const ; + public : + virtual myrule_t getrule () const = 0 ; + virtual void request (myrule_t) = 0 ; + int tagForGlobalRefinement () ; + int resetRefinementRequest () ; + int tagForBallRefinement (const double (&)[3],double,int) ; + virtual bool isboundary() {return true;} + virtual grid_t type() {return tetra;} + private : + myhface3_t * f [2] ; + signed char s [2] ; + } periodic3_GEO ; + +// Anfang - Neu am 23.5.02 (BS) + + // Geometriesockelklasse des periodischen Randelements mit zwei + // 4-Punkt-Fl"achen. + + typedef class Periodic4 : public helement_STI, public hasFace4, public MyAlloc { + protected : + typedef VertexGeo myvertex_t ; + typedef hedge1_GEO myhedge1_t ; + typedef hface4_GEO myhface4_t ; + typedef Hface4Rule myrule_t ; + inline Periodic4 (myhface4_t *, int, myhface4_t *, int) ; + inline int postRefinement () ; + inline int preCoarsening () ; + public : + static const int prototype [2][4] ; + inline virtual ~Periodic4 () ; + inline hface4_GEO * myhface4 (int) ; + inline const hface4_GEO * myhface4 (int) const ; + inline VertexGeo * myvertex (int) ; + inline const VertexGeo * myvertex (int) const ; + inline VertexGeo * myvertex (int,int) ; + inline const VertexGeo * myvertex (int,int) const ; + inline pair < hasFace4 *, int > myneighbour (int) ; + inline pair < const hasFace4 *, int > myneighbour (int) const ; + inline int twist (int) const ; + int test () const ; + virtual bool isboundary() {return true;} + virtual grid_t type() {return hexa;} + public : + virtual myrule_t getrule () const = 0 ; + virtual void request (myrule_t) = 0 ; + int tagForGlobalRefinement () ; + int resetRefinementRequest () ; + int tagForBallRefinement (const double (&)[3],double,int) ; + private : + myhface4_t * f [2] ; + signed char s [2] ; + } periodic4_GEO ; + +// Ende - Neu am 23.5.02 (BS) + + // Der Prototyp f"ur das Hexaederelement bedingt eine im Uhrzeigersinn + // umlaufende Numerierung der lokalen Knoten einer Aussenfl"ache, falls + // aus dem Element herausgeschaut wird. Gegensatz zum Tetraeder. + // Der Prototyp steht in 'gitter_geo.cc' + + typedef class Hexa : public helement_STI, public hasFace4, public MyAlloc { + protected : + typedef VertexGeo myvertex_t ; + typedef hedge1_GEO myhedge1_t ; + typedef hface4_GEO myhface4_t ; + typedef HexaRule myrule_t ; + inline Hexa (myhface4_t *, int, myhface4_t *, int, myhface4_t *, int, + myhface4_t *, int, myhface4_t *, int, myhface4_t *, int) ; + inline int postRefinement () ; + inline int preCoarsening () ; + public : + static const int prototype [6][4] ; + static const int oppositeFace [6] ; + inline virtual ~Hexa () ; + inline hface4_GEO * myhface4 (int) ; + inline const hface4_GEO * myhface4 (int) const ; + inline VertexGeo * myvertex (int) ; + inline const VertexGeo * myvertex (int) const ; + inline VertexGeo * myvertex (int,int) ; + inline const VertexGeo * myvertex (int,int) const ; + inline pair < hasFace4 *, int > myneighbour (int) ; + inline pair < const hasFace4 *, int > myneighbour (int) const ; + inline int twist (int) const ; + int test () const ; + public : + virtual myrule_t getrule () const = 0 ; + virtual void request (myrule_t) = 0 ; + int tagForGlobalRefinement () ; + int resetRefinementRequest () ; + int tagForBallRefinement (const double (&)[3],double,int) ; + virtual bool isboundary() {return false;} + virtual grid_t type() {return hexa;} + private : + myhface4_t * f [6] ; + signed char s [6] ; + } hexa_GEO ; + + // Auch hier ist Vorsicht geboten: Der Protoyp des Dreiecksrandelement + // numeriert seine Knoten gegen den Uhrzeigersinn, wenn aus dem Randelement + // auf die Randfl"ache geschaut wird. Das Vierecksrandelement hat die + // entgegengesetzte Konvention. + + typedef class hbndseg3 : public hbndseg_STI, public hasFace3, public MyAlloc { + public : + typedef VertexGeo myvertex_t ; + typedef hedge1_GEO myhedge1_t ; + typedef hface3_GEO myhface3_t ; + typedef hface3_GEO myhface_t ; + typedef Hface3Rule myrule_t ; + + typedef hbndseg_STI :: bnd_t bnd_t; + protected : + inline hbndseg3 (myhface3_t *,int,ProjectVertex *) ; + inline int postRefinement () ; + inline int preCoarsening () ; + inline bool lockedAgainstCoarsening () const { return false ; } + public : + inline virtual ~hbndseg3 () ; + inline myrule_t getrule () const ; + virtual bool refineLikeElement (balrule_t) = 0 ; + inline myvertex_t * myvertex (int,int) const ; + inline myhface3_t * myhface3 (int) const ; + inline int twist (int) const ; + inline hface3_GEO * subface3 (int,int) const ; + virtual bool isboundary() {return true;} + private : + myhface3_t * _face ; + int _twist ; + protected : + ProjectVertex *projection; + public: + } hbndseg3_GEO ; + + typedef class hbndseg4 : public hbndseg_STI, public hasFace4, public MyAlloc { + public : + typedef VertexGeo myvertex_t ; + typedef hedge1_GEO myhedge1_t ; + typedef hface4_GEO myhface4_t ; + typedef hface4_GEO myhface_t ; + typedef Hface4Rule myrule_t ; + + typedef hbndseg_STI :: bnd_t bnd_t; + protected : + inline hbndseg4 (myhface4_t *,int,ProjectVertex *) ; + inline int postRefinement () ; + inline int preCoarsening () ; + inline bool lockedAgainstCoarsening () const { return false ; } + public : + inline virtual ~hbndseg4 () ; + inline myrule_t getrule () const ; + virtual bool refineLikeElement (balrule_t) = 0 ; + inline myvertex_t * myvertex (int,int) const ; + inline myhface4_t * myhface4 (int) const ; + inline int twist (int) const ; + inline hface4_GEO * subface4 (int,int) const ; + private : + myhface4_t * _face ; + int _twist ; + protected : + ProjectVertex *projection; + + public: + } hbndseg4_GEO ; + + class InternalHasFace3 { + public : + typedef hasFace3 val_t ; + val_t * operator () (hasFace3 * x) const { return x ; } + val_t & operator () (hasFace3 & x) const { return x ; } + } ; + + class InternalHasFace4 { + public : + typedef hasFace4 val_t ; + val_t * operator () (hasFace4 * x) const { return x ; } + val_t & operator () (hasFace4 & x) const { return x ; } + } ; + public : + class BuilderIF : public Makrogitter { + + // BuilderIF ist die Stelle des Makrogitters an der der Builder angreift, wenn das + // Gitter erbaut werden soll. Der Builder geht direkt mit den Listen um und + // wendet sich an die Factorymethoden insert_--*-- (), um neue Objekte zu erhalten. + + list < VertexGeo * > _vertexList ; + list < hedge1_GEO * > _hedge1List ; + list < hface4_GEO * > _hface4List ; + list < hface3_GEO * > _hface3List ; + list < tetra_GEO * > _tetraList ; + list < periodic3_GEO * > _periodic3List ; +// Anfang - Neu am 23.5.02 (BS) + list < periodic4_GEO * > _periodic4List ; +// Ende - Neu am 23.5.02 (BS) + list < hexa_GEO * > _hexaList ; + list < hbndseg3_GEO * > _hbndseg3List ; + list < hbndseg4_GEO * > _hbndseg4List ; + bool _modified ; + protected : + BuilderIF () : _modified (true) {} + virtual ~BuilderIF () ; + void generateRawHexaImage (istream &, ostream &) ; + virtual void macrogridBuilder (istream &) ; + virtual VertexGeo * insert_vertex (double, double, double, int,int = 0) = 0 ; + virtual hedge1_GEO * insert_hedge1 (VertexGeo *, VertexGeo *) = 0 ; + virtual hface3_GEO * insert_hface3 (hedge1_GEO *(&)[3], int (&)[3]) = 0 ; + virtual hface4_GEO * insert_hface4 (hedge1_GEO *(&)[4], int (&)[4]) = 0 ; + virtual tetra_GEO * insert_tetra (hface3_GEO *(&)[4], int (&)[4]) = 0 ; + virtual periodic3_GEO * insert_periodic3 (hface3_GEO *(&)[2], int (&)[2]) = 0 ; +// Anfang - Neu am 23.5.02 (BS) + virtual periodic4_GEO * insert_periodic4 (hface4_GEO *(&)[2], int (&)[2]) = 0 ; +// Ende - Neu am 23.5.02 (BS) + virtual hexa_GEO * insert_hexa (hface4_GEO *(&)[6], int (&)[6]) = 0 ; + virtual hbndseg3_GEO * insert_hbnd3 (hface3_GEO *, int, hbndseg_STI :: bnd_t) = 0 ; + virtual hbndseg3_GEO * insert_hbnd3 (hface3_GEO *, int, hbndseg_STI :: bnd_t,const double(&p)[3]) = 0 ; + virtual hbndseg4_GEO * insert_hbnd4 (hface4_GEO *, int, hbndseg_STI :: bnd_t) = 0 ; + IteratorSTI < vertex_STI > * iterator (const vertex_STI *) const ; + IteratorSTI < vertex_STI > * iterator (const IteratorSTI < vertex_STI > *) const ; + IteratorSTI < hedge_STI > * iterator (const hedge_STI *) const ; + IteratorSTI < hedge_STI > * iterator (const IteratorSTI < hedge_STI > *) const ; + IteratorSTI < hface_STI > * iterator (const hface_STI *) const ; + IteratorSTI < hface_STI > * iterator (const IteratorSTI < hface_STI > *) const ; + IteratorSTI < helement_STI > * iterator (const helement_STI *) const ; + IteratorSTI < helement_STI > * iterator (const IteratorSTI < helement_STI > *) const ; + IteratorSTI < hbndseg_STI > * iterator (const hbndseg_STI *) const ; + IteratorSTI < hbndseg_STI > * iterator (const IteratorSTI < hbndseg_STI > *) const ; + protected : + IteratorSTI < helement_STI > * pureElementIterator (const helement_STI *) const ; + IteratorSTI < helement_STI > * pureElementIterator (const IteratorSTI < helement_STI > *) const ; + public : + virtual void backup (ostream &) const ; + virtual void backup (const char*,const char *) const ; + virtual void backupCMode (ostream &) const ; + virtual void backupCMode (const char*,const char *) const ; + friend class MacroGridBuilder ; +#ifdef _DUNE_USES_BSGRID_ + friend class DuneParallelGridMover; +#endif + } ; + } ; + private : + IteratorSTI < vertex_STI > * iterator (const vertex_STI *) ; + IteratorSTI < vertex_STI > * iterator (const IteratorSTI < vertex_STI > *) ; + IteratorSTI < hedge_STI > * iterator (const hedge_STI *) ; + IteratorSTI < hedge_STI > * iterator (const IteratorSTI < hedge_STI > *) ; + IteratorSTI < hface_STI > * iterator (const hface_STI *) ; + IteratorSTI < hface_STI > * iterator (const IteratorSTI < hface_STI > *) ; + IteratorSTI < hbndseg_STI > * iterator (const hbndseg_STI *) ; + IteratorSTI < hbndseg_STI > * iterator (const IteratorSTI < hbndseg_STI > *) ; + IteratorSTI < helement_STI > * iterator (const helement_STI *) ; + IteratorSTI < helement_STI > * iterator (const IteratorSTI < helement_STI > *) ; + protected : + virtual bool refine () ; + virtual void coarse () ; + virtual Makrogitter & container () = 0 ; + virtual const Makrogitter & container () const = 0 ; + virtual inline int iterators_attached () const ; + virtual void notifyGridChanges () ; + virtual void notifyMacroGridChanges () ; + protected : + Gitter () {} + virtual ~Gitter () ; + public : + virtual void fullIntegrityCheck () ; + virtual void printsize () ; + virtual bool adapt () ; + virtual void refineGlobal () ; + virtual void refineBall (const double (&)[3],double,int) ; + virtual void refineRandom (double) ; + virtual void backupCMode (ostream &) ; + virtual void backupCMode (const char*,const char *) ; + virtual void backup (ostream &) ; + + + virtual void backup (const char*,const char *) ; + virtual void restore (istream &) ; + virtual void restore (const char*,const char *) ; + + // new xdr backup and restore method + virtual void backup (XDRstream_out &) ; + virtual void restore (XDRstream_in &) ; + + protected: + // return index manager of macro grid + virtual IndexManagerType & indexManager (int codim ) = 0; + + friend class LeafIterator < helement_STI > ; + friend class LeafIterator < vertex_STI > ; + friend class LeafIterator < hbndseg_STI > ; + friend class LeafIterator < hedge_STI > ; + friend class LeafIterator < hface_STI > ; +} ; + + // "Ausseres Iteratorproxy oder auch einfach ein Smartpointer + // um von aussen vom Gitter Iterationsobjekte zu bekommen und + // zu verwalten. + +template < class A > class LeafIterator : public MyAlloc { + Gitter * _grd ; + IteratorSTI < A > * _w ; + const A * _a ; + void * operator new (size_t) { return 0 ; } + void operator delete (void *) { } + inline LeafIterator () ; + public : + typedef A val_t; + inline LeafIterator (Gitter &) ; + inline LeafIterator (const LeafIterator < A > & ) ; + inline ~LeafIterator () ; + inline IteratorSTI < A > * operator -> () const ; + inline IteratorSTI < A > & operator * () const ; +} ; + + // Die const-correctness ist leider noch nicht soweit, dass + // zwischen const und non-const Gitterreferenzen vern"unftig + // schon an dieser Stelle unterschieden wird. + +#if 0 +template < class A > class ConstLeafIterator : public MyAlloc { + const Gitter * _grd ; + ConstIteratorSTI < A > * _w ; + const A * _a ; + void * operator new (size_t) ; + void operator delete (void *) ; + inline ConstLeafIterator () ; + public : + inline ConstLeafIterator (const Gitter &) ; + inline ConstLeafIterator (const ConstLeafIterator < A > & ) ; + inline ~ConstLeafIterator () ; + inline ConstIteratorSTI < A > * operator -> () const ; + inline ConstIteratorSTI < A > & operator * () const ; +} ; +#endif + + // + // # # # # # # # ###### + // # ## # # # ## # # + // # # # # # # # # # ##### + // # # # # # # # # # # + // # # ## # # # ## # + // # # # ###### # # # ###### + // + +inline pair < int, int > operator += (pair < int, int> & a, const pair < int, int > & b) { + return pair < int, int > (a.first += b.first, a.second += b.second) ; +} + +/* +inline ostream & operator << (ostream & out, const pair < const int, int > & p) { + return (out << p.first << " " << p.second << " ") ; +} + +inline ostream & operator << (ostream & out, const pair < int, int > & p) { + return (out << p.first << " " << p.second << " ") ; +} + +inline istream & operator >> (istream & in, pair < int, int > & p) { + return (in >> p.first >> p.second) ; +} +*/ +#ifndef NDEBUG +inline Refcount :: Globalcount :: Globalcount () : _c (0) { + return ; +} + +inline void Refcount :: Globalcount :: operator ++ (int) const { + // ! cast around const + ++ (int &) _c ; + return ; +} + +inline void Refcount :: Globalcount :: operator -- (int) const { + -- (int &) _c ; + return ; +} + +inline Refcount :: Refcount () : _c (0) { + _g ++ ; + return ; +} + +inline Refcount :: ~Refcount () { + _g -- ; + return ; +} +#else +inline Refcount :: Refcount () : _c (0) { + return ; +} + +inline Refcount :: ~Refcount () { + return ; +} +#endif +inline int Refcount :: operator ++ (int) const { + return ((int &)_c) ++ ; +} + +inline int Refcount ::operator ++ () const { + return ++ (int &) _c ; +} + +inline int Refcount :: operator -- (int) const { + return ((int &)_c) -- ; +} + +inline int Refcount :: operator -- () const { + return -- (int &) _c ; +} + +inline bool Refcount :: operator ! () const { + return _c ? false : true ; +} + +inline Refcount :: operator int () const { + return _c ; +} + +template < class A > void ConstIteratorSTI < A > :: first () { + return ; +} + +template < class A > void ConstIteratorSTI < A > :: next () { + return ; +} + +template < class A > int ConstIteratorSTI < A > :: done () const { + return 1 ; +} + +template < class A > int ConstIteratorSTI < A > :: size () { + return 0 ; +} + +template < class A > const A & ConstIteratorSTI < A > :: item () const { + void * p = (void *)(0) ; + abort () ; + return * (const val_t *)p ; +} + +template < class A > void IteratorSTI < A > :: first () { + return ; +} + +template < class A > void IteratorSTI < A > :: next () { + return ; +} + +template < class A > int IteratorSTI < A > :: done () const { + return 1 ; +} + +template < class A > int IteratorSTI < A > :: size () { + return 0 ; +} + +template < class A > A & IteratorSTI < A > :: item () const { + void * p = (void *)(0) ; + abort() ; + return *(val_t *)(p) ; +} + +template < class A > inline AccessIterator < A > :: Handle :: Handle (AccessIterator < A > & f) : _fac (&f), _a (0), _w (0) { + _fac->ref ++ ; + _w = _fac->iterator (_a) ; + return ; +} + +template < class A > inline AccessIterator < A > :: Handle :: Handle (const AccessIterator < A > :: Handle & p) : _fac (p._fac), _a (0) { + _fac ? (_fac->ref ++, _w = _fac->iterator (p._w), 0) : (_w = new IteratorSTI < A > (), 0) ; + return ; +} + +template < class A > inline AccessIterator < A > :: Handle :: Handle () : _fac (0), _w (0), _a (0) { + _w = new IteratorSTI < A > () ; + return ; +} + +template < class A > inline AccessIterator < A > :: Handle :: ~Handle () { + //_fac ? (_fac->ref --, 0) : 0 ; + if(_fac) _fac->ref-- ; + delete _w ; + return ; +} + +template < class A > inline const typename AccessIterator < A > :: Handle & AccessIterator < A > :: Handle :: operator = (const AccessIterator < A > :: Handle & x) { + delete _w, _w = 0 ; + x._fac ? ((_fac ? _fac->ref -- : 0), _w = (_fac = x._fac)->iterator (x._w), _fac->ref ++) + : ((_fac ? _fac->ref -- : 0), _fac = 0, _w = new IteratorSTI < A > (), 0) ; + return x ; +} + +template < class A > inline bool AccessIterator < A > :: Handle :: operator == (const AccessIterator < A > :: Handle & x) const { + return (x._fac == _fac) ? ((& x._w->item ()) == (& _w->item ()) ? 1 : 0) : 0 ; +} + +template < class A > inline bool AccessIterator < A > :: Handle :: operator < (const AccessIterator < A > :: Handle & x) const { + return (abort (), false ) ; +} + +template < class A > inline void AccessIterator < A > :: Handle :: first () { + _w->first () ; + return ; +} + +template < class A > inline void AccessIterator < A > :: Handle :: next () { + _w->next () ; + return ; +} + +template < class A > inline int AccessIterator < A > :: Handle :: done () const { + return _w->done () ; +} + +template < class A > inline int AccessIterator < A > :: Handle :: size () { + return _w->size () ; +} + +template < class A > inline A & AccessIterator < A > :: Handle :: item () const { + return _w->item () ; +} + +inline bool Gitter :: debugOption (int level) { + return (getenv ("VERBOSE") ? ( atoi (getenv ("VERBOSE")) > level ? true : (level == 0)) : false) ; +} + +inline int Gitter :: iterators_attached () const { + return ref ; +} + +inline int Gitter :: hedge :: leaf () const { + return ! down () ; +} + +inline int Gitter :: hface :: leaf () const { + return ! down () ; +} + +inline int Gitter :: helement :: leaf () const { + return ! down () ; +} + +inline int Gitter :: Dune_hface_or_hedge :: getIndex () const { +#ifdef _DUNE_USES_BSGRID_ + assert( _index >= 0); + return _index; +#else + std::cerr << "Dune_hface_or_hedge::getIndex () -- ERROR: '_DUNE_USES_BSGRID_' is not defined, so index cannot be used! " << __FILE__ << __LINE__ << "\n"; + abort(); + return -1; +#endif +} + +inline void Gitter :: Dune_hface_or_hedge :: setIndex (const int index) { +#ifdef _DUNE_USES_BSGRID_ + _index = index; +#endif +} + +inline void Gitter :: Dune_hface_or_hedge :: backupIndex (ostream & os ) const { +#ifdef _DUNE_USES_BSGRID_ + cerr << "Dune_hface_or_hedge :: backupIndex : Implemenation should be in inherited class " << __FILE__ << __LINE__ << "\n"; + abort(); +#endif +} + +inline void Gitter :: Dune_hface_or_hedge :: restoreIndex (istream & is ) { +#ifdef _DUNE_USES_BSGRID_ + cerr << "Dune_hface_or_hedge :: restoreIndex : Implemenation should be in inherited class " << __FILE__ << __LINE__ << "\n"; + abort(); +#endif +} + + +// Dune extensions +inline void Gitter :: Dune_helement :: resetRefinedTag () { +#ifdef _DUNE_USES_BSGRID_ + _refinedTag = false; +#endif +} + +inline bool Gitter :: Dune_helement :: hasBeenRefined () const { +#ifdef _DUNE_USES_BSGRID_ + return _refinedTag; +#else + return false; +#endif +} + +inline int Gitter :: Dune_helement :: getIndex () const { +#ifdef _DUNE_USES_BSGRID_ + assert( _index >= 0); + return _index; +#else + std::cerr << "helement::getIndex () -- ERROR: '_DUNE_USES_BSGRID_' is not defined, so index cannot be used! " << __FILE__ << __LINE__ << "\n"; + abort(); + return -1; +#endif +} + +inline void Gitter :: Dune_helement :: setIndex (const int index) { +#ifdef _DUNE_USES_BSGRID_ + _index = index; +#endif +} + +inline void Gitter :: Dune_helement :: backupIndex (ostream & os ) const { +#ifdef _DUNE_USES_BSGRID_ + cerr << "Dune_helement :: backupIndex : Implemenation should be in inherited class " << __FILE__ << __LINE__ << "\n"; + abort(); +#endif +} + +inline void Gitter :: Dune_helement :: restoreIndex (istream & is ) { +#ifdef _DUNE_USES_BSGRID_ + cerr << "Dune_helement :: restoreIndex : Implemenation should be in inherited class " << __FILE__ << __LINE__ << "\n"; + abort(); +#endif +} + +inline int Gitter :: hbndseg :: leaf () const { + return ! down () ; +} + +inline bool Gitter :: Geometric :: hasFace3 :: bndNotifyBalance (balrule_t,int) { + return true ; +} + +inline bool Gitter :: Geometric :: hasFace4 :: bndNotifyBalance (balrule_t,int) { + return true ; +} + + + + +// # # ##### +// # # ###### ##### ##### ###### # # # # ###### #### +// # # # # # # # # # # # # # +// # # ##### # # # ##### ## # #### ##### # # +// # # # ##### # # ## # # # # # +// # # # # # # # # # # # # # # +// # ###### # # # ###### # # ##### ###### #### + +inline Gitter :: Geometric :: VertexGeo :: VertexGeo (int l, double x, double y, double z, IndexManagerType & im) + : _indexmanager (im) + , _lvl (l) +{ + _c [0] = x ; _c [1] = y ; _c [2] = z ; + this->setIndex( _indexmanager.getIndex() ); + return ; +} + +inline Gitter :: Geometric :: VertexGeo :: VertexGeo (int l, double x, double y, double z, VertexGeo & vx) + : _indexmanager ( vx._indexmanager ) + , _lvl (l) +{ + _c [0] = x ; _c [1] = y ; _c [2] = z ; + this->setIndex( _indexmanager.getIndex() ); + return ; +} + +inline Gitter :: Geometric :: VertexGeo :: ~VertexGeo () { + _indexmanager.freeIndex( this->getIndex() ); + assert (ref ? (cerr << "**WARNUNG Vertex-Refcount war " << ref << endl, 1) : 1) ; + return ; +} + +inline const double (& Gitter :: Geometric :: VertexGeo :: Point () const) [3] { + return _c ; +} + +inline int Gitter :: Geometric :: VertexGeo :: level () const { + return _lvl ; +} + +inline void Gitter :: Geometric :: VertexGeo :: project(const ProjectVertex &pv) { + double p[3] = {_c[0],_c[1],_c[2]}; + if (!pv(p,_c)) { + cerr << "FEHLER in Gitter :: Geometric :: VertexGeo :: project(const ProjectVertex &pv) " + << "keine Randanpassung m\"oglich!" << endl; + _c[0] = p[0]; _c[1] = p[1]; _c[2] = p[2]; + } +} + +inline void Gitter :: Geometric :: VertexGeo :: backup ( ostream & os ) const { +#ifdef _DUNE_USES_BSGRID_ + os.write( ((const char *) &_idx ), sizeof(int) ) ; +#endif +} + +inline void Gitter :: Geometric :: VertexGeo :: restore ( istream & is ) { +#ifdef _DUNE_USES_BSGRID_ + //_indexmanager.freeIndex( _idx ); + is.read ( ((char *) &_idx), sizeof(int) ); +#endif +} + +// # # # ###### +// # # ###### ##### #### ###### ## # # # # # ###### +// # # # # # # # # # # # # # # # # +// ####### ##### # # # ##### # ###### # # # ##### +// # # # # # # ### # # # # # # # # +// # # # # # # # # # # # # # # # +// # # ###### ##### #### ###### ##### # # #### ###### ###### + + +inline Gitter :: Geometric :: Hedge1Rule :: Hedge1Rule (int i) : _r ( (rule_t) i ) { + return ; +} + +inline Gitter :: Geometric :: Hedge1Rule :: Hedge1Rule (rule_t r) : _r (r) { + return ; +} + +inline bool Gitter :: Geometric :: Hedge1Rule :: operator == (rule_t r) const { + return _r == r ; +} + +inline Gitter :: Geometric :: Hedge1Rule :: operator int () const { + return (int) _r ; +} + +inline bool Gitter :: Geometric :: Hedge1Rule :: isValid () const { + return _r == nosplit || _r == iso2 ; +} + +inline Gitter :: Geometric :: Hedge1Rule Gitter :: Geometric :: Hedge1Rule :: rotate (int i) const { + assert (i == 0 || i == 1) ; + switch (_r) { + case nosplit : + return Hedge1Rule (nosplit) ; + case iso2 : + return Hedge1Rule (iso2) ; + default : + cerr << __FILE__ << " " << __LINE__ << endl ; + abort () ; + return Hedge1Rule (nosplit) ; + } +} + +// # # # +// # # ###### ##### #### ###### ## +// # # # # # # # # # # +// ####### ##### # # # ##### # +// # # # # # # ### # # +// # # # # # # # # # +// # # ###### ##### #### ###### ##### + +inline Gitter :: Geometric :: hedge1 :: hedge1 (myvertex_t * a, myvertex_t * b) : v0 (a), v1 (b) { + v0->ref ++ ; + v1->ref ++ ; + return ; +} + +inline Gitter :: Geometric :: hedge1 :: ~hedge1 () { + assert (ref ? (cerr << "**WARNUNG Kante-Refcount war " << ref << endl, 1) : 1) ; + v0->ref -- ; + v1->ref -- ; + return ; +} + +inline int Gitter :: Geometric :: hedge1 :: postRefinement () { + return 0 ; +} + +inline int Gitter :: Geometric :: hedge1 :: preCoarsening () { + return 0 ; +} + +inline bool Gitter :: Geometric :: hedge1 :: lockedAgainstCoarsening () const { + return false ; +} + +inline Gitter :: Geometric :: VertexGeo * Gitter :: Geometric :: hedge1 :: myvertex (int i) { + assert (i == 0 || i == 1) ; + return i == 1 ? v1 : v0 ; +} + +inline const Gitter :: Geometric :: hedge1 :: myvertex_t * Gitter :: Geometric :: hedge1 :: myvertex (int i) const { + assert (i == 0 || i == 1) ; + return i == 1 ? v1 : v0 ; +} + +// # # ##### ###### +// # # ###### ## #### ###### # # # # # # # ###### +// # # # # # # # # # # # # # # # +// ####### ##### # # # ##### ##### ###### # # # ##### +// # # # ###### # # # # # # # # # +// # # # # # # # # # # # # # # # # +// # # # # # #### ###### ##### # # #### ###### ###### + +inline Gitter :: Geometric :: Hface3Rule :: Hface3Rule (int x) : _r ((rule_t)x) { + return ; +} + +inline Gitter :: Geometric :: Hface3Rule :: Hface3Rule (rule_t r) : _r (r) { + return ; +} + +inline Gitter :: Geometric :: Hface3Rule :: operator int () const { + return (int) _r ; +} + +inline bool Gitter :: Geometric :: Hface3Rule :: operator == (rule_t r) const { + return r == _r ; +} + +inline bool Gitter :: Geometric :: Hface3Rule :: isValid () const { + return _r == nosplit || _r == iso4 || _r == e01 || _r == e12 || _r == e20 ; +} + +inline Gitter :: Geometric :: Hface3Rule Gitter :: Geometric :: Hface3Rule :: rotate (int t) const { + assert ((-4 < t) && (t < 3)) ; + switch (_r) { + case nosplit : + return Hface3Rule (nosplit) ; + case e01 : + case e12 : + case e20 : + if (t == 0 || t == -3) { // twist 0 bzw. -2 : e01 bleibt und e12 <-> e20 event. swappen + return Hface3Rule (_r == e01 ? e01 : (_r == e12 ? (t == 0 ? e12 : e20) : (t == 0 ? e20 : e12))) ; + } else if (t == 1 || t == -1) { // twist 1 bzw. -1 : e20 -> e01 (beidesmal) + return Hface3Rule (_r == e20 ? e01 : (_r == e12 ? (t == 1 ? e20 : e12) : (t == 1 ? e12 : e20))) ; + } else if (t == 2 || t == -2) { // twist 2 bzw. -3 : e12 -> e01 (beidesmal) + return Hface3Rule (_r == e12 ? e01 : (_r == e01 ? (t == 2 ? e20 : e12) : (t == 2 ? e12 : e20))) ; + } else { + abort () ; + } + case iso4 : + return Hface3Rule (iso4) ; + default : + cerr << __FILE__ << " " << __LINE__ << endl ; + abort () ; + return Hface3Rule (nosplit) ; + } +} + +// # # # ###### +// # # ###### ## #### ###### # # # # # # # ###### +// # # # # # # # # # # # # # # # # +// ####### ##### # # # ##### # # ###### # # # ##### +// # # # ###### # # ####### # # # # # # +// # # # # # # # # # # # # # # # +// # # # # # #### ###### # # # #### ###### ###### + +inline Gitter :: Geometric :: Hface4Rule :: Hface4Rule (int x) : _r ((rule_t)x) { + return ; +} + +inline Gitter :: Geometric :: Hface4Rule :: Hface4Rule (rule_t r) : _r (r) { + return ; +} + +inline Gitter :: Geometric :: Hface4Rule :: operator int () const { + return (int) _r ; +} + +inline bool Gitter :: Geometric :: Hface4Rule :: operator == (rule_t r) const { + return r == _r ; +} + +inline bool Gitter :: Geometric :: Hface4Rule :: isValid () const { + return _r == nosplit || _r == iso4 /* || _r == ni02 || _r == ni13 */ ; +} + +inline Gitter :: Geometric :: Hface4Rule Gitter :: Geometric :: Hface4Rule :: rotate (int t) const { + switch (_r) { + case nosplit : + return Hface4Rule (nosplit) ; + case iso4 : + return Hface4Rule (iso4) ; + default : + cerr << __FILE__ << " " << __LINE__ << endl ; + abort () ; + return Hface4Rule (nosplit) ; + } +} + + // ##### + // # # ###### ## #### ###### # # + // # # # # # # # # # + // ###### ##### # # # ##### ##### + // # # # ###### # # # + // # # # # # # # # # # + // # # # # # #### ###### ##### + // + +inline Gitter :: Geometric :: hface3 :: face3Neighbour :: face3Neighbour () : _v (null), _h (null) { + return ; +} + +inline void Gitter :: Geometric :: hface3 :: face3Neighbour :: operator = (const face3Neighbour & n) { + _v = n._v ; + _h = n._h ; + return ; +} + +inline int Gitter :: Geometric :: hface3 :: face3Neighbour :: complete (const face3Neighbour & n) { + return (_v == null ? (_v = n._v, 1) : 0 ) + (_h == null ? (_h = n._h, 1) : 0 ) ; +} + +inline pair < Gitter :: Geometric :: hface3 :: myconnect_t *, int > Gitter :: Geometric :: hface3 :: face3Neighbour :: front () { + //assert (!(_v == null)) ; + return _v ; +} + +inline pair < const Gitter :: Geometric :: hface3 :: myconnect_t *, int > Gitter :: Geometric :: hface3 :: face3Neighbour :: front () const { + //assert (!(_v == null)) ; + return pair < const hasFace3 *, int > (_v.first,_v.second) ; +} + +inline pair < Gitter :: Geometric :: hface3 :: myconnect_t *, int > Gitter :: Geometric :: hface3 :: face3Neighbour :: rear () { + //assert (!(_h == null)) ; + return _h ; +} + +inline pair < const Gitter :: Geometric :: hface3 :: myconnect_t *, int > Gitter :: Geometric :: hface3 :: face3Neighbour :: rear () const { + //assert (!(_h == null)) ; + return pair < const hasFace3 *, int > (_h.first,_h.second) ; ; +} + +inline Gitter :: Geometric :: hface3 :: hface3 (myhedge1_t * e0, int s0, myhedge1_t * e1, int s1, myhedge1_t * e2, int s2) { + assert(e0 && e1 && e2) ; + (e [0] = e0)->ref ++ ; s [0] = s0 ; + (e [1] = e1)->ref ++ ; s [1] = s1 ; + (e [2] = e2)->ref ++ ; s [2] = s2 ; +// H"ohere Ordnung: + _parRule = _nChild = (signed char) -1 ; // Test. + _nonv = _nonh = (signed char) 1 ; +// Ende: H"ohere Ordnung + return ; +} + +inline Gitter :: Geometric :: hface3 :: ~hface3 () { + assert (ref ? (cerr << "**WARNUNG Dreiecksfl\"ache :: Refcount war " << ref << endl, 1) : 1) ; + e [0] -> ref -- ; + e [1] -> ref -- ; + e [2] -> ref -- ; + return ; +} + +inline void Gitter :: Geometric :: hface3 :: attachElement (const pair < myconnect_t *, int > & p, int t) { +// H"ohere Ordnung, bisher: " t < 0 ? nb._h = p : nb._v = p ;" + t < 0 ? (_nonh = 0, nb._h = p) : (_nonv = 0, nb._v = p) ; + ref ++ ; + return ; +} + +inline void Gitter :: Geometric :: hface3 :: detachElement (int t) { +// H"ohere Ordnung, bisher: "t < 0 ? nb._h = nb.null : nb._v = nb.null ;" + t < 0 ? (_nonh = 1, nb._h = nb.null) : (_nonv = 1, nb._v = nb.null) ; + ref -- ; + return ; +} + +inline int Gitter :: Geometric :: hface3 :: postRefinement () { + return 0 ; +} + +inline int Gitter :: Geometric :: hface3 :: preCoarsening () { + return 0 ; +} + +inline int Gitter :: Geometric :: hface3 :: twist (int i) const { + assert (i < 3) ; + return s [i] ; +} + +inline Gitter :: Geometric :: hface3 :: myhedge1_t * Gitter :: Geometric :: hface3 :: myhedge1 (int i) { + assert (i < 3) ; + return e [i] ; +} + +inline const Gitter :: Geometric :: hface3 :: myhedge1_t * Gitter :: Geometric :: hface3 :: myhedge1 (int i) const { + assert (i < 3) ; + return e [i] ; +} + +inline Gitter :: Geometric :: hface3 :: myvertex_t * Gitter :: Geometric :: hface3 :: myvertex (int i) { + assert(0<=i && i < 3) ; + return myhedge1 (i)->myvertex (s[i]) ; +} + +inline const Gitter :: Geometric :: hface3 :: myvertex_t * Gitter :: Geometric :: hface3 :: myvertex (int i) const { + assert(0<=i && i < 3) ; + return myhedge1 (i)->myvertex (s[i]) ; +} + +// # +// # # ###### ## #### ###### # # +// # # # # # # # # # # +// ###### ##### # # # ##### # # +// # # # ###### # # ####### +// # # # # # # # # # +// # # # # # #### ###### # + +inline Gitter :: Geometric :: hface4 :: face4Neighbour :: face4Neighbour () : _v (null), _h (null) { + return ; +} + +inline void Gitter :: Geometric :: hface4 :: face4Neighbour :: operator = (const face4Neighbour & n) { + _v = n._v ; + _h = n._h ; + return ; +} + +inline int Gitter :: Geometric :: hface4 :: face4Neighbour :: complete (const face4Neighbour & n) { + return (_v == null ? (_v = n._v, 1) : 0 ) + (_h == null ? (_h = n._h, 1) : 0 ) ; +} + +inline pair < Gitter :: Geometric :: hface4 :: myconnect_t *, int > Gitter :: Geometric :: hface4 :: face4Neighbour :: front () { + //assert (!(_v == null)) ; + return _v ; +} + +inline pair < const Gitter :: Geometric :: hface4 :: myconnect_t *, int > Gitter :: Geometric :: hface4 :: face4Neighbour :: front () const { + //assert (!(_v == null)) ; + return pair < const myconnect_t *, int > (_v.first,_v.second) ; +} + +inline pair < Gitter :: Geometric :: hface4 :: myconnect_t *, int > Gitter :: Geometric :: hface4 :: face4Neighbour :: rear () { + //assert (!(_h == null)) ; + return _h ; +} + +inline pair < const Gitter :: Geometric :: hface4 :: myconnect_t *, int > Gitter :: Geometric :: hface4 :: face4Neighbour :: rear () const { + //assert (!(_h == null)) ; + return pair < const myconnect_t *, int > (_h.first,_h.second) ; ; +} + +inline Gitter :: Geometric :: hface4 :: hface4 (myhedge1_t * e0, int s0, myhedge1_t * e1, int s1, myhedge1_t * e2, int s2, myhedge1_t * e3, int s3) { + assert(e0 && e1 && e2 && e3) ; + (e [0] = e0)->ref ++ ; s [0] = s0 ; + (e [1] = e1)->ref ++ ; s [1] = s1 ; + (e [2] = e2)->ref ++ ; s [2] = s2 ; + (e [3] = e3)->ref ++ ; s [3] = s3 ; + return ; +} + +inline Gitter :: Geometric :: hface4 :: ~hface4 () { + assert (ref ? (cerr << "**WARNUNG Fl\"ache-Refcount war " << ref << endl, 1) : 1) ; + e [0] -> ref -- ; + e [1] -> ref -- ; + e [2] -> ref -- ; + e [3] -> ref -- ; + return ; +} + +inline void Gitter :: Geometric :: hface4 :: attachElement (const pair < myconnect_t *, int > & p, int t) { + t < 0 ? nb._h = p : nb._v = p ; + ref ++ ; + return ; +} + +inline void Gitter :: Geometric :: hface4 :: detachElement (int t) { + t < 0 ? nb._h = nb.null : nb._v = nb.null ; + ref -- ; + return ; +} + +inline int Gitter :: Geometric :: hface4 :: postRefinement () { + return 0 ; +} + +inline int Gitter :: Geometric :: hface4 :: preCoarsening () { + return 0 ; +} + +inline int Gitter :: Geometric :: hface4 :: twist (int i) const { + assert (i < 4) ; + return s [i] ; +} + +inline Gitter :: Geometric :: hface4 :: myhedge1_t * Gitter :: Geometric :: hface4 :: myhedge1 (int i) { + assert (i < 4) ; + return e [i] ; +} + +inline const Gitter :: Geometric :: hface4 :: myhedge1_t * Gitter :: Geometric :: hface4 :: myhedge1 (int i) const { + assert (i < 4) ; + return e [i] ; +} + +inline Gitter :: Geometric :: hface4 :: myvertex_t * Gitter :: Geometric :: hface4 :: myvertex (int i) { + assert(0<=i && i < 4) ; + return myhedge1 (i)->myvertex (s[i]) ; +} + +inline const Gitter :: Geometric :: hface4 :: myvertex_t * Gitter :: Geometric :: hface4 :: myvertex (int i) const { + assert(0<=i && i < 4) ; + return myhedge1 (i)->myvertex (s[i]) ; +} + +// ####### ###### +// # ###### ##### ##### ## # # # # # ###### +// # # # # # # # # # # # # # +// # ##### # # # # # ###### # # # ##### +// # # # ##### ###### # # # # # # +// # # # # # # # # # # # # # +// # ###### # # # # # # # #### ###### ###### + +inline Gitter :: Geometric :: TetraRule :: TetraRule (int x) : _r ((rule_t)x) { + return ; +} + +inline Gitter :: Geometric :: TetraRule :: TetraRule (rule_t r) : _r (r) { + return ; +} + +inline Gitter :: Geometric :: TetraRule :: operator int () const { + return (int) _r ; +} + +inline bool Gitter :: Geometric :: TetraRule :: operator == (rule_t r) const { + return r == _r ; +} + +inline bool Gitter :: Geometric :: TetraRule :: isValid () const { + return _r == crs || _r == nosplit || _r == iso8 || _r == e01 + || _r == e12 || _r == e20 || _r == e23 || _r == e30 || _r == e31; +} + + +// ####### +// # ###### ##### ##### ## +// # # # # # # # +// # ##### # # # # # +// # # # ##### ###### +// # # # # # # # +// # ###### # # # # # + +inline Gitter :: Geometric :: Tetra :: Tetra (myhface3_t * f0, int t0, myhface3_t * f1, + int t1, myhface3_t * f2, int t2, myhface3_t * f3, int t3) { + (f [0] = f0)->attachElement (pair < hasFace3 *, int > (InternalHasFace3 ()(this), 0),(s [0] = t0)) ; + (f [1] = f1)->attachElement (pair < hasFace3 *, int > (InternalHasFace3 ()(this), 1),(s [1] = t1)) ; + (f [2] = f2)->attachElement (pair < hasFace3 *, int > (InternalHasFace3 ()(this), 2),(s [2] = t2)) ; + (f [3] = f3)->attachElement (pair < hasFace3 *, int > (InternalHasFace3 ()(this), 3),(s [3] = t3)) ; + return ; +} + +inline Gitter :: Geometric :: Tetra :: ~Tetra () { + f [0] ->detachElement (s [0]) ; + f [1] ->detachElement (s [1]) ; + f [2] ->detachElement (s [2]) ; + f [3] ->detachElement (s [3]) ; + return ; +} + +inline int Gitter :: Geometric :: Tetra :: twist (int i) const { + assert (i < 4) ; + return s [i] ; +} + +inline Gitter :: Geometric :: Tetra :: myhface3_t * Gitter :: Geometric :: Tetra :: myhface3 (int i) { + assert (i < 4) ; + return f [i] ; +} + +inline const Gitter :: Geometric :: Tetra :: myhface3_t * Gitter :: Geometric :: Tetra :: myhface3 (int i) const { + assert (i < 4) ; + return f [i] ; +} + +inline Gitter :: Geometric :: Tetra :: myvertex_t * Gitter :: Geometric :: Tetra :: myvertex (int i, int j) { + return (twist(i) < 0) ? myhface3(i)->myvertex((7 - j + twist(i)) % 3) : myhface3(i)->myvertex((j + twist(i)) % 3) ; +} + +inline const Gitter :: Geometric :: Tetra :: myvertex_t * Gitter :: Geometric :: Tetra :: myvertex (int i, int j) const { + return (twist(i) < 0) ? myhface3(i)->myvertex((7 - j + twist(i)) % 3) : myhface3(i)->myvertex((j + twist(i)) % 3) ; +} + +inline Gitter :: Geometric :: Tetra :: myvertex_t * Gitter :: Geometric :: Tetra :: myvertex (int i) { + assert (0 <= i && i < 4) ; + return (i < 3) ? myvertex (3,i) : myvertex (2,1) ; +} + +inline const Gitter :: Geometric :: Tetra :: myvertex_t * Gitter :: Geometric :: Tetra :: myvertex (int i) const { + assert (0 <= i && i < 4) ; + return (i < 3) ? myvertex (3,i) : myvertex (2,1) ; +} + +inline pair < Gitter :: Geometric :: hasFace3 *, int > Gitter :: Geometric :: Tetra :: myneighbour (int i) +{ + return twist (i) < 0 ? myhface3 (i)->nb.front () : myhface3 (i)->nb.rear (); +} + +inline pair < const Gitter :: Geometric :: hasFace3 *, int > Gitter :: Geometric :: Tetra :: myneighbour (int i) const { + return twist (i) < 0 ? pair < const hasFace3 *, int > (myhface3 (i)->nb.front ().first, myhface3 (i)->nb.front ().second) + : pair < const hasFace3 *, int > (myhface3 (i)->nb.rear ().first, myhface3 (i)->nb.rear ().second) ; +} + +inline pair < Gitter :: Geometric :: hface3_GEO *, int > Gitter :: Geometric :: Tetra :: myintersection (int i) +{ + // return pair, first = pointer to face, second = twist of face + return pair< Gitter::Geometric::hface3_GEO *,int> (myhface3 (i) ,twist (i)); +} + +inline pair < const Gitter :: Geometric :: hface3_GEO *, int > Gitter :: Geometric :: Tetra :: myintersection (int i) const +{ + // return pair, first = pointer to face, second = twist of face + return pair< const Gitter::Geometric::hface3_GEO * , int > (myhface3 (i) , twist (i) ); +} + +inline int Gitter :: Geometric :: Tetra :: postRefinement () { + return 0 ; +} + +inline int Gitter :: Geometric :: Tetra :: preCoarsening () { + return 0 ; +} + +// ###### ##### +// # # ###### ##### # #### ##### # #### # # +// # # # # # # # # # # # # # # +// ###### ##### # # # # # # # # # ##### +// # # ##### # # # # # # # # +// # # # # # # # # # # # # # # +// # ###### # # # #### ##### # #### ##### + +inline Gitter :: Geometric :: Periodic3 :: Periodic3 (myhface3_t * f0, int t0, myhface3_t * f1, int t1) { + (f [0] = f0)->attachElement (pair < hasFace3 *, int > (InternalHasFace3 ()(this), 0),(s [0] = t0)) ; + (f [1] = f1)->attachElement (pair < hasFace3 *, int > (InternalHasFace3 ()(this), 1),(s [1] = t1)) ; + return ; +} + +inline Gitter :: Geometric :: Periodic3 :: ~Periodic3 () { + f [0] ->detachElement (s [0]) ; + f [1] ->detachElement (s [1]) ; + return ; +} + +inline int Gitter :: Geometric :: Periodic3 :: twist (int i) const { + assert (0 <= i && i < 2) ; + return s [i] ; +} + +inline Gitter :: Geometric :: Periodic3 :: myhface3_t * Gitter :: Geometric :: Periodic3 :: myhface3 (int i) { + assert (0 <= i && i < 2) ; + return f [i] ; +} + +inline const Gitter :: Geometric :: Periodic3 :: myhface3_t * Gitter :: Geometric :: Periodic3 :: myhface3 (int i) const { + assert (0 <= i && i < 2) ; + return f [i] ; +} + +inline Gitter :: Geometric :: Periodic3 :: myvertex_t * Gitter :: Geometric :: Periodic3 :: myvertex (int i, int j) { + assert (0 <= i && i < 2) ; + return (twist(i) < 0) ? myhface3(i)->myvertex((7 - j + twist(i)) % 3) : myhface3(i)->myvertex((j + twist(i)) % 3) ; +} + +inline const Gitter :: Geometric :: Periodic3 :: myvertex_t * Gitter :: Geometric :: Periodic3 :: myvertex (int i, int j) const { + return (twist(i) < 0) ? myhface3(i)->myvertex((7 - j + twist(i)) % 3) : myhface3(i)->myvertex((j + twist(i)) % 3) ; +} + +inline Gitter :: Geometric :: Periodic3 :: myvertex_t * Gitter :: Geometric :: Periodic3 :: myvertex (int i) { + assert (0 <= i && i < 6) ; + + // Der Ausdruck liefert 0-> (0,0) + // 1-> (0,1) + // 2-> (0,2) + // 3-> (1,0) + // 4-> (1,2) + // 5-> (1,1) + return (i < 3) ? myvertex (0,i) : myvertex (1,(6-i)%3) ; +} + +inline const Gitter :: Geometric :: Periodic3 :: myvertex_t * Gitter :: Geometric :: Periodic3 :: myvertex (int i) const { + assert (0 <= i && i < 6) ; + return (i < 3) ? myvertex (0,i) : myvertex (1,(6-i)%3) ; +} + +inline pair < Gitter :: Geometric :: hasFace3 *, int > Gitter :: Geometric :: Periodic3 :: myneighbour (int i) { + assert (0 <= i && i < 2) ; + return twist (i) < 0 ? myhface3 (i)->nb.front () : myhface3 (i)->nb.rear () ; +} + +inline pair < const Gitter :: Geometric :: hasFace3 *, int > Gitter :: Geometric :: Periodic3 :: myneighbour (int i) const { + assert (0 <= i && i < 2) ; + return twist (i) < 0 ? pair < const hasFace3 *, int > (myhface3 (i)->nb.front ().first, myhface3 (i)->nb.front ().second) + : pair < const hasFace3 *, int > (myhface3 (i)->nb.rear ().first, myhface3 (i)->nb.rear ().second) ; +} + +inline int Gitter :: Geometric :: Periodic3 :: postRefinement () { + return 0 ; +} + +inline int Gitter :: Geometric :: Periodic3 :: preCoarsening () { + return 0 ; +} + +// Anfang - Neu am 23.5.02 (BS) + +// ###### # +// # # ###### ##### # #### ##### # #### # # +// # # # # # # # # # # # # # # # +// ###### ##### # # # # # # # # # # # +// # # ##### # # # # # # # ####### +// # # # # # # # # # # # # # +// # ###### # # # #### ##### # #### # + +inline Gitter :: Geometric :: Periodic4 :: Periodic4 (myhface4_t * f0, int t0, myhface4_t * f1, int t1) { + (f [0] = f0)->attachElement (pair < hasFace4 *, int > (InternalHasFace4 ()(this), 0),(s [0] = t0)) ; + (f [1] = f1)->attachElement (pair < hasFace4 *, int > (InternalHasFace4 ()(this), 1),(s [1] = t1)) ; + return ; +} + +inline Gitter :: Geometric :: Periodic4 :: ~Periodic4 () { + f [0] ->detachElement (s [0]) ; + f [1] ->detachElement (s [1]) ; + return ; +} + +inline int Gitter :: Geometric :: Periodic4 :: twist (int i) const { + assert (0 <= i && i < 2) ; + return s [i] ; +} + +inline Gitter :: Geometric :: Periodic4 :: myhface4_t * Gitter :: Geometric :: Periodic4 :: myhface4 (int i) { + assert (0 <= i && i < 2) ; + return f [i] ; +} + +inline const Gitter :: Geometric :: Periodic4 :: myhface4_t * Gitter :: Geometric :: Periodic4 :: myhface4 (int i) const { + assert (0 <= i && i < 2) ; + return f [i] ; +} + +inline Gitter :: Geometric :: Periodic4 :: myvertex_t * Gitter :: Geometric :: Periodic4 :: myvertex (int i, int j) { + assert (0 <= i && i < 2) ; + return (twist(i) < 0) ? myhface4(i)->myvertex((9 - j + twist(i)) % 4) : myhface4(i)->myvertex((j + twist(i)) % 4) ; +} + +inline const Gitter :: Geometric :: Periodic4 :: myvertex_t * Gitter :: Geometric :: Periodic4 :: myvertex (int i, int j) const { + assert (0 <= i && i < 2) ; + return (twist(i) < 0) ? myhface4(i)->myvertex((9 - j + twist(i)) % 4) : myhface4(i)->myvertex((j + twist(i)) % 4) ; +} + +inline Gitter :: Geometric :: Periodic4 :: myvertex_t * Gitter :: Geometric :: Periodic4 :: myvertex (int i) { // ok + assert (0 <= i && i < 8) ; + return (i < 4) ? myvertex (0, (4 - i) % 4) : myvertex (1, i - 4) ; +} + +inline const Gitter :: Geometric :: Periodic4 :: myvertex_t * Gitter :: Geometric :: Periodic4 :: myvertex (int i) const { // ok + assert (0 <= i && i < 8) ; + return (i < 4) ? myvertex (0,i) : myvertex (1,(8-i)%4) ; +} + +inline pair < Gitter :: Geometric :: hasFace4 *, int > Gitter :: Geometric :: Periodic4 :: myneighbour (int i) { + assert (0 <= i && i < 2) ; + return twist (i) < 0 ? myhface4 (i)->nb.front () : myhface4 (i)->nb.rear () ; +} + +inline pair < const Gitter :: Geometric :: hasFace4 *, int > Gitter :: Geometric :: Periodic4 :: myneighbour (int i) const { + assert (0 <= i && i < 2) ; + return twist (i) < 0 ? pair < const hasFace4 *, int > (myhface4 (i)->nb.front ().first, myhface4 (i)->nb.front ().second) + : pair < const hasFace4 *, int > (myhface4 (i)->nb.rear ().first, myhface4 (i)->nb.rear ().second) ; +} + +inline int Gitter :: Geometric :: Periodic4 :: postRefinement () { + return 0 ; +} + +inline int Gitter :: Geometric :: Periodic4 :: preCoarsening () { + return 0 ; +} + +// Ende - Neu am 23.5.02 (BS) + +// # # ###### +// # # ###### # # ## # # # # # ###### +// # # # # # # # # # # # # # +// ####### ##### ## # # ###### # # # ##### +// # # # ## ###### # # # # # # +// # # # # # # # # # # # # # +// # # ###### # # # # # # #### ###### ###### + + +inline Gitter :: Geometric :: HexaRule :: HexaRule (int x) : _r ((rule_t)x) { + return ; +} + +inline Gitter :: Geometric :: HexaRule :: HexaRule (rule_t r) : _r (r) { + return ; +} + +inline Gitter :: Geometric :: HexaRule :: operator int () const { + return (int) _r ; +} + +inline bool Gitter :: Geometric :: HexaRule :: operator == (rule_t r) const { + return r == _r ; +} + +inline bool Gitter :: Geometric :: HexaRule :: isValid () const { + return _r == crs || _r == nosplit || _r == iso8 ; +} + +// # # +// # # ###### # # ## +// # # # # # # # +// ####### ##### ## # # +// # # # ## ###### +// # # # # # # # +// # # ###### # # # # + +inline Gitter :: Geometric :: Hexa :: Hexa (myhface4_t * f0, int t0, myhface4_t * f1, int t1, myhface4_t * f2, int t2, + myhface4_t * f3, int t3, myhface4_t * f4, int t4, myhface4_t * f5, int t5) { + (f [0] = f0)->attachElement (pair < hasFace4 *, int > (InternalHasFace4 ()(this), 0),(s [0] = t0)) ; + (f [1] = f1)->attachElement (pair < hasFace4 *, int > (InternalHasFace4 ()(this), 1),(s [1] = t1)) ; + (f [2] = f2)->attachElement (pair < hasFace4 *, int > (InternalHasFace4 ()(this), 2),(s [2] = t2)) ; + (f [3] = f3)->attachElement (pair < hasFace4 *, int > (InternalHasFace4 ()(this), 3),(s [3] = t3)) ; + (f [4] = f4)->attachElement (pair < hasFace4 *, int > (InternalHasFace4 ()(this), 4),(s [4] = t4)) ; + (f [5] = f5)->attachElement (pair < hasFace4 *, int > (InternalHasFace4 ()(this), 5),(s [5] = t5)) ; + return ; +} + +inline Gitter :: Geometric :: Hexa :: ~Hexa () { + f [0] ->detachElement (s [0]) ; + f [1] ->detachElement (s [1]) ; + f [2] ->detachElement (s [2]) ; + f [3] ->detachElement (s [3]) ; + f [4] ->detachElement (s [4]) ; + f [5] ->detachElement (s [5]) ; + return ; +} + +inline int Gitter :: Geometric :: Hexa :: twist (int i) const { + assert (i < 6) ; + return s [i] ; +} + +inline Gitter :: Geometric :: Hexa :: myhface4_t * Gitter :: Geometric :: Hexa :: myhface4 (int i) { + assert (i < 6) ; + return f [i] ; +} + +inline const Gitter :: Geometric :: Hexa :: myhface4_t * Gitter :: Geometric :: Hexa :: myhface4 (int i) const { + assert (i < 6) ; + return f [i] ; +} + +inline Gitter :: Geometric :: Hexa :: myvertex_t * Gitter :: Geometric :: Hexa :: myvertex (int i, int j) { + return (twist(i) < 0) ? myhface4(i)->myvertex((9 - j + twist(i)) % 4) : myhface4(i)->myvertex((j + twist(i)) % 4) ; +} + +inline const Gitter :: Geometric :: Hexa :: myvertex_t * Gitter :: Geometric :: Hexa :: myvertex (int i, int j) const { + return (twist(i) < 0) ? myhface4(i)->myvertex((9 - j + twist(i)) % 4) : myhface4(i)->myvertex((j + twist(i)) % 4) ; +} + +inline Gitter :: Geometric :: Hexa :: myvertex_t * Gitter :: Geometric :: Hexa :: myvertex (int i) { + assert (0 <= i && i < 8) ; + return (i < 4) ? myvertex (0, (4 - i) % 4) : myvertex (1, i - 4) ; +} + +inline const Gitter :: Geometric :: Hexa :: myvertex_t * Gitter :: Geometric :: Hexa :: myvertex (int i) const { + assert (0 <= i && i < 8) ; + return (i < 4) ? myvertex (0, (4 - i) % 4) : myvertex (1, i - 4) ; +} + +inline pair < Gitter :: Geometric :: hasFace4 *, int > Gitter :: Geometric :: Hexa :: myneighbour (int i) { + return twist (i) < 0 ? myhface4 (i)->nb.front () : myhface4 (i)->nb.rear () ; +} + +inline pair < const Gitter :: Geometric :: hasFace4 *, int > Gitter :: Geometric :: Hexa :: myneighbour (int i) const { + return twist (i) < 0 ? pair < const hasFace4 *, int > (myhface4 (i)->nb.front ().first, myhface4 (i)->nb.front ().second) + : pair < const hasFace4 *, int > (myhface4 (i)->nb.rear ().first, myhface4 (i)->nb.rear ().second) ; +} + +inline int Gitter :: Geometric :: Hexa :: postRefinement () { + return 0 ; +} + +inline int Gitter :: Geometric :: Hexa :: preCoarsening () { + return 0 ; +} + +// # # ##### +// # # ##### # # ##### #### ###### #### # # +// # # # # ## # # # # # # # # +// ####### ##### # # # # # #### ##### # ##### +// # # # # # # # # # # # # ### # +// # # # # # ## # # # # # # # # # +// # # ##### # # ##### #### ###### #### ##### + +inline Gitter :: Geometric :: hbndseg3 :: hbndseg3 (myhface3_t * a, int b, ProjectVertex *ppv) : _face (a), _twist (b), projection(ppv) { + _face->attachElement (pair < hasFace3 *, int > (InternalHasFace3 ()(this),0), _twist) ; + return ; +} + +inline Gitter :: Geometric :: hbndseg3 :: ~hbndseg3 () { + _face->detachElement (_twist) ; + return ; +} + +inline int Gitter :: Geometric :: hbndseg3 :: postRefinement () { + if (projection) { + myhface3(0)->projectVertex(*projection); + } + return 0 ; +} + +inline int Gitter :: Geometric :: hbndseg3 :: preCoarsening () { + return 0 ; +} + +inline int Gitter :: Geometric :: hbndseg3 :: twist (int i) const { + assert (i == 0) ; + return _twist ; +} + +inline Gitter :: Geometric :: hbndseg3 :: myhface3_t * Gitter :: Geometric :: hbndseg3 :: myhface3 (int i) const { + assert (i == 0) ; + return _face ; +} + +inline Gitter :: Geometric :: hbndseg3 :: myvertex_t * Gitter :: Geometric :: hbndseg3 :: myvertex (int,int j) const { + return (twist (0) < 0) ? myhface3 (0)->myvertex ((7 - j + twist (0)) % 3) : myhface3 (0)->myvertex ((j + twist (0)) % 3) ; +} + +inline Gitter :: Geometric :: hbndseg3 :: myhface3_t * Gitter :: Geometric :: hbndseg3 :: subface3 (int,int i) const { + return myhface3 (0)->subface3 (i) ; +} + +inline Gitter :: Geometric :: hbndseg3 :: myrule_t Gitter :: Geometric :: hbndseg3 :: getrule () const { + return myhface3 (0)->getrule () ; +} + +// # # # +// # # ##### # # ##### #### ###### #### # # +// # # # # ## # # # # # # # # # +// ####### ##### # # # # # #### ##### # # # +// # # # # # # # # # # # # ### ####### +// # # # # # ## # # # # # # # # +// # # ##### # # ##### #### ###### #### # + +inline Gitter :: Geometric :: hbndseg4 :: hbndseg4 (myhface4_t * a, int b, ProjectVertex *ppv) : _face (a), _twist (b), projection(ppv) { + _face->attachElement (pair < hasFace4 *, int > (InternalHasFace4 ()(this),0), _twist) ; + return ; +} + +inline Gitter :: Geometric :: hbndseg4 :: ~hbndseg4 () { + _face->detachElement (_twist) ; + return ; +} + +inline int Gitter :: Geometric :: hbndseg4 :: postRefinement () { + if (projection) { + myhface4(0)->projectVertex(*projection); + } + return 0 ; +} + +inline int Gitter :: Geometric :: hbndseg4 :: preCoarsening () { + return 0 ; +} + +inline int Gitter :: Geometric :: hbndseg4 :: twist (int i) const { + assert (i == 0) ; + return _twist ; +} + +inline Gitter :: Geometric :: hbndseg4 :: myhface4_t * Gitter :: Geometric :: hbndseg4 :: myhface4 (int i) const { + assert (i == 0) ; + return _face ; +} + +inline Gitter :: Geometric :: hbndseg4 :: myvertex_t * Gitter :: Geometric :: hbndseg4 :: myvertex (int,int j) const { + return (twist (0) < 0) ? myhface4 (0)->myvertex ((9 - j + twist (0)) % 4) : myhface4 (0)->myvertex ((j + twist (0)) % 4) ; +} + +inline Gitter :: Geometric :: hbndseg4 :: myhface4_t * Gitter :: Geometric :: hbndseg4 :: subface4 (int,int i) const { + return myhface4 (0)->subface4 (i) ; +} + +inline Gitter :: Geometric :: hbndseg4 :: myrule_t Gitter :: Geometric :: hbndseg4 :: getrule () const { + return myhface4 (0)->getrule () ; +} + +#if 0 +template < class A > ConstLeafIterator < A > :: ConstLeafIterator () : _grd (0), _w (0) { + return ; +} + +template < class A > ConstLeafIterator < A > :: ConstLeafIterator (const Gitter & g) : _grd (&g), _w (0) { + _grd->ref ++ ; + _w = _grd->iterator (_a) ; + return ; +} + +template < class A > ConstLeafIterator < A > :: ConstLeafIterator (const ConstLeafIterator < A > & x) : _grd (x._grd), _w (0) { + _grd->ref ++ ; + _w = _grd->iterator (x._w) ; + return ; +} + +template < class A > ConstLeafIterator < A > :: ~ConstLeafIterator () { + if (_grd) _grd->ref -- ; + if(_w) delete _w ; + return ; +} + +template < class A > IteratorSTI < A > * ConstLeafIterator < A > :: operator -> () const { + return _w ; +} + +template < class A > IteratorSTI < A > & ConstLeafIterator < A > :: operator * () const { + return * _w ; +} +#endif + + +// # ### +// # ###### ## ###### # ##### ###### ##### ## ##### #### ##### +// # # # # # # # # # # # # # # # # # +// # ##### # # ##### # # ##### # # # # # # # # # +// # # ###### # # # # ##### ###### # # # ##### +// # # # # # # # # # # # # # # # # # +// ####### ###### # # # ### # ###### # # # # # #### # # + +template < class A > LeafIterator < A > :: LeafIterator () : _grd (0), _w (0) { + return ; +} + +template < class A > LeafIterator < A > :: LeafIterator (Gitter & g) : _grd (&g), _w (0) { + _grd->ref ++ ; + _w = _grd->iterator (_a) ; + return ; +} + +template < class A > LeafIterator < A > :: LeafIterator (const LeafIterator < A > & x) : _grd (x._grd), _w (0) { + _grd->ref ++ ; + _w = _grd->iterator (x._w) ; + return ; +} + +template < class A > LeafIterator < A > :: ~LeafIterator () { + if (_grd) _grd->ref -- ; + if(_w) delete _w ; + return ; +} + +template < class A > IteratorSTI < A > * LeafIterator < A > :: operator -> () const { + return _w ; +} + +template < class A > IteratorSTI < A > & LeafIterator < A > :: operator * () const { + return * _w ; +} + +#endif // GITTER_STI_H_INCLUDED diff --git a/src/serial/gitter_tetra_top.h b/src/serial/gitter_tetra_top.h new file mode 100644 index 0000000000000000000000000000000000000000..94f0cf2cba480de7030d73416138d97c696e80f0 --- /dev/null +++ b/src/serial/gitter_tetra_top.h @@ -0,0 +1,1949 @@ +// (c) mario ohlberger, 1998 +// modifications for dune interface +// (c) Robert Kloefkorn 2004 - 2005 +#ifndef GITTER_TETRATOP_H_INCLUDED +#define GITTER_TETRATOP_H_INCLUDED + +#include <limits.h> + +#include "gitter_sti.h" +#include "gitter_hexa_top.h" + + +static volatile char RCSId_gitter_tetra_top_h [] = "$Id$" ; + +template < class A > class Hface3Top : public A { + protected : + typedef Hface3Top < A > innerface_t ; + typedef typename A :: inneredge_t inneredge_t; + typedef typename A :: innervertex_t innervertex_t; + typedef typename A :: myhedge1_t myhedge1_t ; + typedef typename A :: myvertex_t myvertex_t ; + typedef typename A :: myrule_t myrule_t ; + private : + innerface_t * _dwn, * _bbb ; + inneredge_t * _ed ; + int _lvl ; + myrule_t _rule ; + + IndexManagerType & _indexManager; + + private: + inline myhedge1_t * subedge1 (int,int) ; + inline const myhedge1_t * subedge1 (int,int) const ; + void split_e01 () ; + void split_e12 () ; + void split_e20 () ; + void split_iso4 () ; + public : + inline Hface3Top (int,myhedge1_t *,int,myhedge1_t *,int,myhedge1_t *,int , IndexManagerType & im ) ; + virtual inline ~Hface3Top () ; + innervertex_t * subvertex (int) ; + const innervertex_t * subvertex (int) const ; + inneredge_t * subedge1 (int) ; + const inneredge_t * subedge1 (int) const ; + innerface_t * subface3 (int) ; + const innerface_t * subface3 (int) const ; + int level () const ; + innervertex_t * innerVertex () ; + const innervertex_t * innerVertex () const ; + inneredge_t * innerHedge () ; + const inneredge_t * innerHedge () const ; + innerface_t * down () ; + const innerface_t * down () const ; + innerface_t * next () ; + const innerface_t * next () const ; + void append (innerface_t * f) ; + public: + virtual myrule_t getrule () const ; + virtual bool refine (myrule_t,int) ; + virtual void refineImmediate (myrule_t) ; + virtual bool coarse () ; + public : + // we need this because TetraTop needs access to this indexManager + inline IndexManagerType & getIndexManager () { return _indexManager; } + + inline IndexManagerType & getEdgeIndexManager () ; + + virtual void backup (ostream &) const ; + virtual void restore (istream &) ; + + // new xdr methods + virtual void backup (XDRstream_out &) const ; + virtual void restore (XDRstream_in &) ; +} ; + + +template < class A > class Hbnd3Top : public A { + protected : + typedef Hbnd3Top < A > innerbndseg_t ; + typedef typename A :: myhface3_t myhface3_t ; + typedef typename A :: balrule_t balrule_t ; + typedef typename A :: myrule_t myrule_t ; + typedef typename A :: bnd_t bnd_t; + bool refineLikeElement (balrule_t) ; + inline void append (innerbndseg_t *) ; + private : + innerbndseg_t * _bbb, * _dwn , * _up ; + int _lvl ; + void split_e01 () ; + void split_e12 () ; + void split_e20 () ; + void split_iso4 () ; + inline bool coarse () ; + const bnd_t _bt; // type of boundary + + IndexManagerType & _indexManager; + public: + inline Hbnd3Top (int,myhface3_t *,int,ProjectVertex *, + innerbndseg_t * up, const bnd_t b, + IndexManagerType & im, typename Gitter::helement_STI * gh) ; + inline virtual ~Hbnd3Top () ; + bool refineBalance (balrule_t,int) ; + bool bndNotifyCoarsen () ; + void restoreFollowFace () ; + inline int level () const ; + inline innerbndseg_t * next () ; + inline innerbndseg_t * down () ; + inline const innerbndseg_t * next () const ; + inline const innerbndseg_t * down () const ; + + // for dune + inline innerbndseg_t * up () ; + inline const innerbndseg_t * up () const ; + + inline bnd_t bndtype () const { return _bt; } +} ; + +template < class A > class TetraTop : public A { + protected : + typedef TetraTop < A > innertetra_t ; + typedef typename A :: innervertex_t innervertex_t ; + typedef typename A :: inneredge_t inneredge_t ; + typedef typename A :: innerface_t innerface_t ; + typedef typename A :: myhedge1_t myhedge1_t ; + typedef typename A :: myhface3_t myhface3_t ; + typedef typename A :: myrule_t myrule_t ; + typedef typename A :: balrule_t balrule_t ; + inline void refineImmediate (myrule_t) ; + inline void append (innertetra_t * h) ; + private : + innertetra_t * _dwn, * _bbb, * _up ; //us + innerface_t * _fc ; + inneredge_t * _ed ; + int _lvl ; + myrule_t _req, _rule ; + IndexManagerType & _indexManager; + + private : + inline IndexManagerType & getFaceIndexManager (); + inline IndexManagerType & getEdgeIndexManager (); + + void split_e01 () ; + void split_e12 () ; + void split_e20 () ; + void split_e23 () ; + void split_e30 () ; + void split_e31 () ; + void split_iso8 () ; + protected : + myhedge1_t * subedge1 (int,int) ; + const myhedge1_t * subedge1 (int,int) const ; + myhface3_t * subface3 (int,int) ; + const myhface3_t * subface3 (int i, int j) const ; + public: + inline TetraTop (int,myhface3_t *,int,myhface3_t *,int,myhface3_t *,int, + myhface3_t *,int,innertetra_t *up) ; + inline TetraTop (int,myhface3_t *,int,myhface3_t *,int,myhface3_t *,int, + myhface3_t *,int,IndexManagerType & im) ; + virtual inline ~TetraTop () ; + //testweise us + inline innertetra_t * up () ; + inline const innertetra_t * up () const; + //testweise us + inline innertetra_t * down () ; + inline const innertetra_t * down () const ; + inline innertetra_t * next () ; + inline const innertetra_t * next () const ; + inline innervertex_t * innerVertex () ; + inline const innervertex_t * innerVertex () const ; + inline inneredge_t * innerHedge () ; + inline const inneredge_t * innerHedge () const ; + inline innerface_t * innerHface () ; + inline const innerface_t * innerHface () const ; + inline int level () const ; + public : + myrule_t getrule () const ; + myrule_t requestrule () const ; + bool refine () ; + void request (myrule_t) ; + bool refineBalance (balrule_t,int) ; + bool coarse () ; + bool bndNotifyCoarsen () ; + void backupCMode (ostream &) const ; + + void backup (ostream &) const ; + void restore (istream &) ; + + void backup (XDRstream_out &) const ; + void restore (XDRstream_in &) ; + + // backup and restore index + void backupIndex (ostream &) const ; + void restoreIndex (istream &) ; +}; + +template < class A > class Periodic3Top : public A { + protected : + typedef Periodic3Top < A > innerperiodic3_t ; + typedef typename A :: innervertex_t innervertex_t ; + typedef typename A :: inneredge_t inneredge_t ; + typedef typename A :: innerface_t innerface_t ; + typedef typename A :: myhedge1_t myhedge1_t ; + typedef typename A :: myhface3_t myhface3_t ; + typedef typename A :: myrule_t myrule_t ; + typedef typename A :: balrule_t balrule_t ; + inline void refineImmediate (myrule_t) ; + inline void append (innerperiodic3_t * h) ; + private : + innerperiodic3_t * _dwn, * _bbb, * _up ; //us eingefuegt + int _lvl ; + myrule_t _rule ; + private : + void split_e01 () ; + void split_e12 () ; + void split_e20 () ; + void split_iso4 () ; + protected : + myhedge1_t * subedge1 (int,int) ; + const myhedge1_t * subedge1 (int,int) const ; + myhface3_t * subface3 (int,int) ; + const myhface3_t * subface3 (int i, int j) const ; + public: + inline Periodic3Top (int,myhface3_t *,int,myhface3_t *,int) ; + virtual inline ~Periodic3Top () ; + //testweise us + inline innerperiodic3_t * up () ; + inline const innerperiodic3_t * up () const; + //testweise us + inline innerperiodic3_t * down () ; + inline const innerperiodic3_t * down () const ; + inline innerperiodic3_t * next () ; + inline const innerperiodic3_t * next () const ; + inline innervertex_t * innerVertex () ; + inline const innervertex_t * innerVertex () const ; + inline inneredge_t * innerHedge () ; + inline const inneredge_t * innerHedge () const ; + inline innerface_t * innerHface () ; + inline const innerface_t * innerHface () const ; + inline int level () const ; + public : + myrule_t getrule () const ; + bool refine () ; + void request (myrule_t) ; + bool refineBalance (balrule_t,int) ; + bool coarse () ; + bool bndNotifyCoarsen () ; + void backupCMode (ostream &) const ; + void backup (ostream &) const ; + void restore (istream &) ; +}; + // + // # # # # # # # ###### + // # ## # # # ## # # + // # # # # # # # # # ##### + // # # # # # # # # # # + // # # ## # # # ## # + // # # # ###### # # # ###### + // + + +// # # ##### ####### +// # # ###### ## #### ###### # # # #### ##### +// # # # # # # # # # # # # # # +// ####### ##### # # # ##### ##### # # # # # +// # # # ###### # # # # # # ##### +// # # # # # # # # # # # # # # +// # # # # # #### ###### ##### # #### # + + +template < class A > typename Hface3Top < A > :: innerface_t * Hface3Top < A > :: down () { + return _dwn ; +} + +template < class A > const typename Hface3Top < A > :: innerface_t * Hface3Top < A > :: down () const { + return _dwn ; +} + +template < class A > typename Hface3Top < A > :: innerface_t * Hface3Top < A > :: next () { + return _bbb ; +} + +template < class A > const typename Hface3Top < A > :: innerface_t * Hface3Top < A > :: next () const { + return _bbb ; +} + +template < class A > int Hface3Top < A > :: level () const { + return _lvl ; +} + +template < class A > typename Hface3Top < A > :: innervertex_t * Hface3Top < A > :: innerVertex () { + return 0 ; +} + +template < class A > const typename Hface3Top < A > :: innervertex_t * Hface3Top < A > :: innerVertex () const { + return 0 ; +} + +template < class A > typename Hface3Top < A > :: inneredge_t * Hface3Top < A > :: innerHedge () { + return _ed ; +} + +template < class A > const typename Hface3Top < A > :: inneredge_t * Hface3Top < A > :: innerHedge () const { + return _ed ; +} + +template < class A > typename Hface3Top < A > :: innervertex_t * Hface3Top < A > :: subvertex (int) { + assert (getrule() == myrule_t :: iso4) ; + return 0 ; +} + +template < class A > const typename Hface3Top < A > :: innervertex_t * Hface3Top < A > :: subvertex (int) const { + assert (getrule() == myrule_t :: iso4) ; + return 0 ; +} + +template < class A > typename Hface3Top < A > :: myhedge1_t * Hface3Top < A > :: subedge1 (int i,int j) { + assert(j == 0 || j == 1) ; + return this->myhedge1 (i)->subedge1 (j ? 1 - this->twist(i) : this->twist(i)) ; +} + +template < class A > const typename Hface3Top < A > :: myhedge1_t * Hface3Top < A > :: subedge1 (int i,int j) const { + assert(j == 0 || j == 1) ; + return this->myhedge1 (i)->subedge1 (j ? 1 - this->twist(i) : this->twist(i)) ; +} + +template < class A > typename Hface3Top < A > :: inneredge_t * Hface3Top < A > :: subedge1 (int n) { + inneredge_t * e = _ed ; + for (int i = 0 ; i < n ; i ++ ) e = e ? e->next () : 0 ; + assert (e) ; + return e ; +} + +template < class A > const typename Hface3Top < A > :: inneredge_t * Hface3Top < A > :: subedge1 (int n) const { + inneredge_t * e = _ed ; + for (int i = 0 ; i < n ; i ++ ) e = e ? e->next () : 0 ; + assert (e) ; + return e ; +} + +template < class A > typename Hface3Top < A > :: innerface_t * Hface3Top < A > :: subface3 (int n) { + innerface_t * f = down() ; + for (int i = 0 ; i < n ; i++ ) f = f ? f->next () : 0 ; + assert (f) ; + return f ; +} + +template < class A > const typename Hface3Top < A > :: innerface_t * Hface3Top < A > :: subface3 (int n) const { + const innerface_t * f = down () ; + for (int i = 0 ; i < n ; i++ ) f = f ? f->next () : 0 ; + assert (f) ; + return f ; +} + +template < class A > void Hface3Top < A > :: append (innerface_t * f) { + assert (!_bbb) ; + _bbb = f ; + return ; +} + +template < class A > typename Hface3Top < A > :: myrule_t Hface3Top < A > :: getrule () const { + return myrule_t (_rule) ; +} + +template < class A > inline IndexManagerType & Hface3Top < A > :: getEdgeIndexManager () { + return static_cast<inneredge_t &> (*(this->myhedge1(0))).getIndexManager(); +} + +template < class A > void Hface3Top < A > :: split_e01 () { + int l = 1 + level () ; + myvertex_t * ev0 = this->myhedge1(1)->subvertex (2) ; + assert(ev0) ; + inneredge_t * e0 = new inneredge_t (l, ev0, this->myvertex (2), getEdgeIndexManager() ) ; + assert( e0 ) ; + innerface_t * f0 = new innerface_t (l, this->myhedge1(2), this->twist(2), this->subedge1(0,0), this->twist(0) , e0, 0, _indexManager ) ; + innerface_t * f1 = new innerface_t (l, e0, 1, this->subedge1(0,1), this->twist(0), this->myhedge1(1), this->twist(1), _indexManager ) ; + assert (f0 && f1 ) ; + f0->append(f1) ; + _ed = e0 ; + _dwn = f0 ; + _rule = myrule_t :: e01 ; + return ; +} + +template < class A > void Hface3Top < A > :: split_e12 () { + int l = 1 + level () ; + myvertex_t * ev0 = this->myhedge1(1)->subvertex (0) ; + assert(ev0) ; + inneredge_t * e0 = new inneredge_t (l, ev0, this->myvertex (0), getEdgeIndexManager()) ; + assert( e0 ) ; + innerface_t * f0 = new innerface_t (l, this->myhedge1(0), this->twist(0), this->subedge1(1,0), this->twist(1) , e0, 0, _indexManager ) ; + innerface_t * f1 = new innerface_t (l, e0, 1, this->subedge1(1,1), this->twist(1), this->myhedge1(2), this->twist(2), _indexManager ) ; + assert (f0 && f1 ) ; + f0->append(f1) ; + _ed = e0 ; + _dwn = f0 ; + _rule = myrule_t :: e12 ; + return ; +} + +template < class A > void Hface3Top < A > :: split_e20 () { + int l = 1 + level () ; + myvertex_t * ev0 = this->myhedge1(1)->subvertex (1) ; + assert(ev0) ; + inneredge_t * e0 = new inneredge_t (l, ev0, this->myvertex(1), getEdgeIndexManager()) ; + assert( e0 ) ; + innerface_t * f0 = new innerface_t (l, this->myhedge1(1), this->twist(1), this->subedge1(2,0), this->twist(2) , e0, 0, _indexManager ) ; + innerface_t * f1 = new innerface_t (l, e0, 1, this->subedge1(2,1), this->twist(2), this->myhedge1(0), this->twist(0), _indexManager ) ; + assert (f0 && f1 ) ; + f0->append(f1) ; + _ed = e0 ; + _dwn = f0 ; + _rule = myrule_t :: e20 ; + return ; +} + +template < class A > void Hface3Top < A > :: split_iso4 () { + int l = 1 + level () ; + myvertex_t * ev0 = this->myhedge1(0)->subvertex (0) ; + myvertex_t * ev1 = this->myhedge1(1)->subvertex (0) ; + myvertex_t * ev2 = this->myhedge1(2)->subvertex (0) ; + assert(ev0 && ev1 && ev2 ) ; + IndexManagerType & im = getEdgeIndexManager(); + inneredge_t * e0 = new inneredge_t (l, ev0, ev1, im) ; + inneredge_t * e1 = new inneredge_t (l, ev1, ev2, im) ; + inneredge_t * e2 = new inneredge_t (l, ev2, ev0, im) ; + assert( e0 && e1 && e2 ) ; + e0->append(e1) ; + e1->append(e2) ; + innerface_t * f0 = new innerface_t (l, this->subedge1(0,0), this->twist(0), e2, 1, this->subedge1(2,1), this->twist(2), _indexManager ) ; + innerface_t * f1 = new innerface_t (l, this->subedge1(0,1), this->twist(0), this->subedge1(1,0), this->twist(1), e0, 1, _indexManager ) ; + innerface_t * f2 = new innerface_t (l, e1, 1, this->subedge1(1,1), this->twist(1), this->subedge1(2,0), this->twist(2), _indexManager ) ; + innerface_t * f3 = new innerface_t (l, e0, 0, e1, 0, e2, 0, _indexManager ) ; + assert (f0 && f1 && f2 && f3) ; + f0->append(f1) ; + f1->append(f2) ; + f2->append(f3) ; + _ed = e0 ; + _dwn = f0 ; + _rule = myrule_t :: iso4 ; + return ; +} + +template < class A > inline Hface3Top < A > :: Hface3Top (int l, myhedge1_t * e0, + int t0, myhedge1_t * e1, int t1, myhedge1_t * e2, int t2, + IndexManagerType & im ) : + A (e0, t0, e1, t1, e2, t2), + _dwn (0), _bbb (0), _ed (0), _lvl (l), _rule (myrule_t :: nosplit) , + _indexManager (im) +{ + this->setIndex( _indexManager.getIndex() ); + return ; +} + +template < class A > inline Hface3Top < A > :: ~Hface3Top () { + _indexManager.freeIndex( this->getIndex() ); + if (_bbb) delete _bbb ; + if (_dwn) delete _dwn ; + if (_ed) delete _ed ; + return ; +} + +template < class A > void Hface3Top < A > :: refineImmediate (myrule_t r) { + if (r != getrule ()) { + assert (getrule () == myrule_t :: nosplit) ; + switch(r) { + typedef typename myhedge1_t :: myrule_t myhedge1rule_t; + case myrule_t :: e01 : + this->myhedge1 (0)->refineImmediate (myhedge1rule_t (myhedge1_t :: myrule_t :: iso2).rotate (this->twist (0))) ; + split_e01 () ; + break ; + case myrule_t :: e12 : + this->myhedge1 (1)->refineImmediate (myhedge1rule_t (myhedge1_t :: myrule_t :: iso2).rotate (this->twist (0))) ; + split_e12 () ; + break ; + case myrule_t :: e20 : + this->myhedge1 (2)->refineImmediate (myhedge1rule_t (myhedge1_t :: myrule_t :: iso2).rotate (this->twist (0))) ; + split_e20 () ; + break ; + case myrule_t :: iso4 : + this->myhedge1 (0)->refineImmediate (myhedge1rule_t (myhedge1_t :: myrule_t :: iso2).rotate (this->twist (0))) ; + this->myhedge1 (1)->refineImmediate (myhedge1rule_t (myhedge1_t :: myrule_t :: iso2).rotate (this->twist (1))) ; + this->myhedge1 (2)->refineImmediate (myhedge1rule_t (myhedge1_t :: myrule_t :: iso2).rotate (this->twist (2))) ; + split_iso4 () ; + break ; + default : + cerr << "**FEHLER (FATAL) falsche Verfeinerungsregel [" << r << "] in " << __FILE__ << " " << __LINE__ << endl ; + abort () ; + break ; + } +// H"ohere Ordnung: + { + assert (getrule () < SCHAR_MAX) ; + int i = 0 ; + for (innerface_t * f = down () ; f ; f = f->next ()) { + f->_parRule = (signed char) getrule () ; + f->_nChild = (signed char) i++ ; + f->_nonv = f->_nonh = (signed char) 1 ; + } + assert (i < SCHAR_MAX) ; + } +// Ende: H"ohere Ordnung + this->postRefinement () ; + } + return ; +} + +template < class A > bool Hface3Top < A > :: refine (myrule_t r, int twist) { + if (r != getrule ()) { + assert (getrule () == myrule_t :: nosplit ? 1 : + (cerr << "**FEHLER beim Verfeinern mit Regel " << r << " auf " << getrule () << endl, 0)) ; + switch(r) { + case myrule_t :: e01 : + case myrule_t :: e12 : + case myrule_t :: e20 : + case myrule_t :: iso4 : + { + + // --thetwist + bool a = false; + if( this->nb.rear().first && this->nb.front().first ) + { + a = twist < 0 ? this->nb.front ().first->refineBalance (r,this->nb.front ().second) + : this->nb.rear ().first->refineBalance (r,this->nb.rear ().second) ; + } + else + { + if(this->nb.rear().first) + a = this->nb.rear ().first->refineBalance (r,this->nb.rear ().second); + if(this->nb.front().first) + a = this->nb.front ().first->refineBalance (r,this->nb.front().second); + } + + //bool a = twist < 0 ? nb.front ().first->refineBalance (r,nb.front ().second) + // : nb.rear ().first->refineBalance (r,nb.rear ().second) ; + + if (a) { + if (getrule () == myrule_t :: nosplit) { + refineImmediate (r) ; + {for (innerface_t * f = down () ; f ; f = f->next ()) f->nb = this->nb ; } + } else { + + // Als Test absichern, da"s die Verfeinerung durchgekommen ist. Im + // anisotropen Fall darf das so nicht mehr gemacht werden. + + assert (getrule () == r) ; + } + this->postRefinement () ; + return true ; + } else { + return false ; + } + } + default : + cerr << "**WARNUNG (IGNORIERT) falsche Verfeinerungsregel gefunden: " ; + cerr << "[" << r << "] in " << __FILE__ << " " << __LINE__ << endl ; + return false ; + } + } + return true ; +} + +template < class A > bool Hface3Top < A > :: coarse () { + innerface_t * f = down () ; + if (!f) return false ; + bool x = true ; + do { + + // Falls eine Kind-Fl"ache noch referenziert wird, kann + // nicht auf diesem Level vergr"obert werden. + // Daher wird nur die nichtkonforme Nachbarschaft ver- + // vollst"andigt, die eventuell durch Elementvergr"oberung + // durcheinander gekommen war. Die Vergr"oberung geht dann + // auf das n"achste Level "uber. + + if (f->ref) { + if (f->ref == 1) f->nb.complete (this->nb) ; + f->coarse () ; + x = false ; + } + } while (f = f->next()) ; + if (x) { + + // Hier wird tats"achlich vergr"obert, d.h. alle Kinder + // werden beseitigt, und das Bezugsobjekt wird zum neuen + // Blatt im Baum. + + delete _dwn ; + _dwn = 0 ; + delete _ed ; + _ed = 0 ; + _rule = myrule_t :: nosplit ; + {for (int i = 0 ; i < 3 ; i ++ ) this->myhedge1 (i)->coarse () ; } + } + return x ; +} + +template < class A > void Hface3Top < A > :: backup (ostream & os) const { + os.put ((char) getrule ()) ; + {for (const inneredge_t * e = innerHedge () ; e ; e = e->next ()) e->backup (os) ; } + {for (const innerface_t * c = down () ; c ; c = c->next ()) c->backup (os) ; } + return ; +} + +template < class A > void Hface3Top < A > :: restore (istream & is) { + refineImmediate (myrule_t ((char) is.get ())) ; + {for (inneredge_t * e = innerHedge () ; e ; e = e->next ()) e->restore (is) ; } + {for (innerface_t * c = down () ; c ; c = c->next ()) c->restore (is) ; } + return ; +} + +template < class A > void Hface3Top < A > :: backup (XDRstream_out & os) const { + os.put ((char) getrule ()) ; + {for (const inneredge_t * e = innerHedge () ; e ; e = e->next ()) e->backup (os) ; } + {for (const innerface_t * c = down () ; c ; c = c->next ()) c->backup (os) ; } + return ; +} + +template < class A > void Hface3Top < A > :: restore (XDRstream_in & is) { + refineImmediate (myrule_t ((char) is.get ())) ; + {for (inneredge_t * e = innerHedge () ; e ; e = e->next ()) e->restore (is) ; } + {for (innerface_t * c = down () ; c ; c = c->next ()) c->restore (is) ; } + return ; +} + +// # # ##### ####### +// # # ##### # # ##### # # # #### ##### +// # # # # ## # # # # # # # # # +// ####### ##### # # # # # ##### # # # # # +// # # # # # # # # # # # # # ##### +// # # # # # ## # # # # # # # # +// # # ##### # # ##### ##### # #### # + +template < class A > inline Hbnd3Top < A > :: Hbnd3Top (int l, myhface3_t * f, int i, + ProjectVertex *ppv, innerbndseg_t * up, bnd_t bt, + IndexManagerType & im , Gitter::helement_STI * gh) + : A (f, i, ppv ), _bbb (0), _dwn (0), _up (up) , _lvl (l), _bt (bt) , _indexManager(im) { + this->setGhost ( gh ); + //if(gh) printTetra(cout,gh); + this->setIndex( _indexManager.getIndex() ); + return ; +} + +template < class A > inline Hbnd3Top < A > :: ~Hbnd3Top () { + _indexManager.freeIndex( this->getIndex() ); + if (_bbb) delete _bbb ; + if (_dwn) delete _dwn ; + return ; +} + +template < class A > inline int Hbnd3Top < A > :: level () const { + return _lvl ; +} + +template < class A > typename Hbnd3Top < A > :: innerbndseg_t * Hbnd3Top < A > :: next () { + return _bbb ; +} + +template < class A > const typename Hbnd3Top < A > :: innerbndseg_t * Hbnd3Top < A > :: next () const { + return _bbb ; +} + +template < class A > typename Hbnd3Top < A > :: innerbndseg_t * Hbnd3Top < A > :: down () { + return _dwn ; +} + +template < class A > const typename Hbnd3Top < A > :: innerbndseg_t * Hbnd3Top < A > :: down () const { + return _dwn ; +} + +template < class A > typename Hbnd3Top < A > :: innerbndseg_t * Hbnd3Top < A > :: up () { + return _up ; +} + +template < class A > const typename Hbnd3Top < A > :: innerbndseg_t * Hbnd3Top < A > :: up () const { + return _up ; +} + +template < class A > inline void Hbnd3Top < A > :: append (innerbndseg_t * b) { + assert (_bbb == 0) ; + _bbb = b ; + return ; +} + +template < class A > void Hbnd3Top < A > :: split_e01 () { + int l = 1 + level () ; + innerbndseg_t * b0 = new innerbndseg_t (l, this->subface3 (0,0), this->twist (0), this->projection, this , _bt, _indexManager, 0 ) ; + innerbndseg_t * b1 = new innerbndseg_t (l, this->subface3 (0,1), this->twist (0), this->projection, this , _bt, _indexManager, 0 ) ; + assert (b0 && b1) ; + b0->append(b1) ; + _dwn = b0 ; + return ; +} + +template < class A > void Hbnd3Top < A > :: split_e12 () { + int l = 1 + level () ; + innerbndseg_t * b0 = new innerbndseg_t (l, this->subface3 (0,0), this->twist (0), this->projection, this , _bt, _indexManager, 0 ) ; + innerbndseg_t * b1 = new innerbndseg_t (l, this->subface3 (0,1), this->twist (0), this->projection, this , _bt, _indexManager, 0 ) ; + assert (b0 && b1) ; + b0->append(b1) ; + _dwn = b0 ; + return ; +} + +template < class A > void Hbnd3Top < A > :: split_e20 () { + int l = 1 + level () ; + innerbndseg_t * b0 = new innerbndseg_t (l, this->subface3 (0,0), this->twist (0), this->projection, this , _bt, _indexManager, 0) ; + innerbndseg_t * b1 = new innerbndseg_t (l, this->subface3 (0,1), this->twist (0), this->projection, this , _bt, _indexManager, 0) ; + assert (b0 && b1) ; + b0->append(b1) ; + _dwn = b0 ; + return ; +} + +template < class A > void Hbnd3Top < A > :: split_iso4 () { + int l = 1 + level () ; + + this->splitGhost(); + + // get the childs + typedef typename Gitter :: Geometric :: tetra_GEO tetra_GEO; + typedef typename Gitter :: Geometric :: hface3_GEO hface3_GEO; + tetra_GEO * gh = static_cast<tetra_GEO *> (this->getGhost()); + + tetra_GEO *(ghchild)[4] = {0,0,0,0}; + if(gh) + { + hface3_GEO * face = gh->myhface3(3); + face = face->down(); + for(int i=0; i<4; i++) + { + assert(face); + tetra_GEO * ghch = static_cast<tetra_GEO *> (face->nb.front().first); + if(ghch){ if(ghch->up() != gh) ghch = static_cast<tetra_GEO *> (face->nb.rear().first);} + else { ghch = static_cast<tetra_GEO *> (face->nb.rear().first); } + + assert(ghch); + assert(ghch->up() == gh); + ghchild[i] = ghch; + face = face->next(); + } + } + + innerbndseg_t * b0 = new innerbndseg_t (l, this->subface3 (0,0), this->twist (0), this->projection, this , _bt, _indexManager, ghchild[0] ) ; + innerbndseg_t * b1 = new innerbndseg_t (l, this->subface3 (0,1), this->twist (0), this->projection, this , _bt, _indexManager, ghchild[1] ) ; + innerbndseg_t * b2 = new innerbndseg_t (l, this->subface3 (0,2), this->twist (0), this->projection, this , _bt, _indexManager, ghchild[2] ) ; + innerbndseg_t * b3 = new innerbndseg_t (l, this->subface3 (0,3), this->twist (0), this->projection, this , _bt, _indexManager, ghchild[3] ) ; + assert (b0 && b1 && b2 && b3) ; + b0->append(b1) ; + b1->append(b2) ; + b2->append(b3) ; + _dwn = b0 ; + + return ; +} + +template < class A > bool Hbnd3Top < A > :: coarse () { + innerbndseg_t * b = down () ; + if (!b) return false ; + bool x = true ; + do { + if(b->myhface3(0)->ref > 1) (b->coarse (), x = false) ; + } while (b = b->next()) ; + if (x) { + if (!this->lockedAgainstCoarsening ()) { + this->preCoarsening () ; + delete _dwn ; + _dwn = 0 ; + this->myhface3 (0)->coarse () ; + } + } + return x ; +} + +template < class A > inline bool Hbnd3Top < A > :: bndNotifyCoarsen () { + return coarse () ; +} + +template < class A > inline bool Hbnd3Top < A > :: refineBalance (balrule_t r, int b) { + + // Die Methode refineBalance () f"uhrt auf dem Randabschluss entweder + // unbedingt die Verfeinerung durch, da im Verlauf der Verfeinerung keine + // weiteren Anforerungen mehr an den Randabschluss gerichtet werden + // ODER gibt die Verfeinerung als nicht erf"ullt zur"uck: Dann liegt + // es am Aufrufer die Verfeinerung nochmals anzuforern. + + assert (b == 0) ; + assert (this->leaf ()) ; + if (!bndNotifyBalance (r,b)) { + + // Hier kann der innere Rand [parallel] die Verfeinerung + // verhindern, damit z.B. das Durchverfeinern im anisotropen + // Fall erstmal nicht stattfindet, wenn nicht klar ist, wie die + // weitere Rekursion aussieht. Dazu muss auf dem Niveau der Klasse + // des Template-Arguments die Methode bndNotifyBalance () "uber- + // schrieben werden. Die Defaultmethode liefert immer 'true'. + + return false ; + } else { + if(r == myrule_t :: iso4) { + + // Der Rand verfeinert unbedingt die anliegende Fl"ache und dann + // sich selbst, weil die Anforderung durch die Fl"ache kam, und + // dahinter keine Balancierung stattfinden muss. + + this->myhface3 (0)->refineImmediate (r) ; + split_iso4 () ; + } else if (r == myrule_t :: e01) { + this->myhface3 (0)->refineImmediate (r) ; + split_e01 () ; + } else if (r == myrule_t :: e12) { + this->myhface3 (0)->refineImmediate (r) ; + split_e12 () ; + } else if (r == myrule_t :: e20) { + this->myhface3 (0)->refineImmediate (r) ; + split_e20 () ; + } else { + cerr << "**FEHLER (FATAL, weil nicht vorgesehen) beim Verfeinern am " ; + cerr << "Randst\"uck mit der Regel [" << r << "] in " ; + cerr << __FILE__ << " " << __LINE__ << endl ; + abort () ; + } + + // postRefinement () gibt die M"oglichkeit auf dem Niveau des + // Template-Arguments eine Methode aufzurufen, um eventuelle + // Operationen auf dem verfeinerten Randst"uck durchzuf"uhren. + + this->postRefinement () ; + return true ; + } +} + +template < class A > inline bool Hbnd3Top < A > :: refineLikeElement (balrule_t r) { + + // Mit der Methode refineLikeElement () verh"alt sich ein Randabschluss + // in der Verfeinerung wie ein Element: Es wird zuerst gepr"uft ob eine + // Balancierung der Vererfeinerung durch die Fl"ache hindurch erfolgreich + // ist und nur genau dann die Verfeinerung durchgef"uhrt mit R"uckgabewert + // 'true'. Diese Methode bedient eigentlich nur die parallele Verfeinerung + // kann aber auch auf jedem beliebigen Randelement im seriellen Fall auf- + // gerufen werden ohne Schaden anzurichten: Eine 1-Level Verfeinerung am + // Rand ist jedoch wirkungslos, da sie beim n"achsten Vergr"obern wieder + // aufgel"ost ist. Erst die mehrfache Anwendung f"uhrt durch die + // Balancierung zu einer "Anderung am Elementgitter. + + if (r == myrule_t :: nosplit) { + + cerr << "**WARNUNG (IGNORIERT) beim Versuch mit nosplit zu Verfeinern" ; + cerr << " in " << __FILE__ << " " << __LINE__ << endl ; + + // Eine Anforderung mit nosplit zu Verfeinern nur erf"ullt, + // falls die zugeh"orige Fl"achenregel auch nosplit ist, sonst + // wird die Anforderung als nicht erf"ullt zur"uckgegeben. + + return this->getrule () == balrule_t :: nosplit ? true : false ; + + } else { + if (this->getrule () == r) { + + // Alles schon wie es sein soll -> true. + + return true ; + } else { + + // Der nachfolgende Test bezieht sich auf die Verfeinerungssituation + // der Fl"ache, da getrule () auf myhface3 (0)->getrule () umgeleitet + // ist. + + assert (this->getrule () == myrule_t :: nosplit) ; + switch (r) { + case balrule_t :: e01 : + if (!this->myhface3 (0)->refine (balrule_t (balrule_t :: e01).rotate (this->twist (0)), this->twist (0))) return false ; + split_e01 () ; + break; + case balrule_t :: e12 : + if (!this->myhface3 (0)->refine (balrule_t (balrule_t :: e12).rotate (this->twist (0)), this->twist (0))) return false ; + split_e12 () ; + break; + case balrule_t :: e20 : + if (!this->myhface3 (0)->refine (balrule_t (balrule_t :: e20).rotate (this->twist (0)), this->twist (0))) return false ; + split_e20 () ; + break; + case balrule_t :: iso4 : + if (!this->myhface3 (0)->refine (balrule_t (balrule_t :: iso4).rotate (this->twist (0)), this->twist (0))) return false ; + split_iso4 () ; + break; + default : + cerr << "**WARNUNG (FEHLER IGNORIERT) falsche Verfeinerungsregel [" << this->getrule () ; + cerr << "] (ignoriert) in " << __FILE__ << " " << __LINE__ << endl ; + return false ; + } + + // postRefinement () gibt die M"oglichkeit auf dem Niveau des + // Template-Arguments eine Methode aufzurufen, um eventuelle + // Operationen auf dem verfeinerten Randst"uck durchzuf"uhren. + this->postRefinement () ; + return true ; + } + } +} + +template < class A > void Hbnd3Top < A > :: restoreFollowFace () { + + // retoreFollowFace () veranlasst das Randelement sich am + // bestehenden Fl"achenbaum wiederherzustellen durch die + // entsprechende Verfeinerung. + + myhface3_t & f (*(this->myhface3 (0))) ; + if (!f.leaf ()) { + balrule_t r = f.getrule () ; + switch (r) { + case myrule_t :: e01 : + split_e01 () ; + break ; + case myrule_t :: e12 : + split_e12 () ; + break ; + case myrule_t :: e20 : + split_e20 () ; + break ; + case myrule_t :: iso4 : + split_iso4 () ; + break ; + default : + cerr << "**FEHLER (FATAL) beim Verfeinern am Randst\"uck mit der Regel [" << r << "] in " << __FILE__ << " " << __LINE__ << endl ; + abort () ; + break ; + } + this->postRefinement () ; + {for (innerbndseg_t * b = down () ; b ; b = b->next ()) b->restoreFollowFace () ; } + } + return ; +} + +// ####### ####### +// # ###### ##### ##### ## # #### ##### +// # # # # # # # # # # # # +// # ##### # # # # # # # # # # +// # # # ##### ###### # # # ##### +// # # # # # # # # # # # +// # ###### # # # # # # #### # + +template < class A > inline TetraTop < A > :: TetraTop (int l, myhface3_t * f0, int t0, + myhface3_t * f1, int t1, myhface3_t * f2, int t2, myhface3_t * f3, int t3, innertetra_t *up) + : A (f0, t0, f1, t1, f2, t2, f3, t3), _dwn (0), _bbb (0), _up(up), _fc (0), _ed (0), _lvl (l), + _rule (myrule_t :: nosplit) + , _indexManager(up->_indexManager) +{ // _up wird im Constructor uebergeben + this->setIndex( _indexManager.getIndex() ); + return ; +} + +// constrcutor mit IndexManager uebergabe +template < class A > inline TetraTop < A > :: TetraTop (int l, myhface3_t * f0, int t0, + myhface3_t * f1, int t1, myhface3_t * f2, int t2, myhface3_t * f3, int t3, IndexManagerType & im) + : A (f0, t0, f1, t1, f2, t2, f3, t3), _dwn (0), _bbb (0), _up(0), _fc (0),_ed (0), _lvl (l), + _rule (myrule_t :: nosplit) , _indexManager(im) +{ // _up wird im Constructor uebergeben + this->setIndex( _indexManager.getIndex() ); + return ; +} + +template < class A > inline TetraTop < A > :: ~TetraTop () +{ + _indexManager.freeIndex( this->getIndex() ); + if (_bbb) delete _bbb ; + if (_dwn) delete _dwn ; + if (_fc) delete _fc ; + if (_ed) delete _ed ; + return ; +} + + +template < class A > inline int TetraTop < A > :: level () const { + return _lvl ; +} + +//testweise us +template < class A > inline typename TetraTop < A > :: innertetra_t * TetraTop < A > :: up () { + return _up ; +} +template < class A > inline const typename TetraTop < A > :: innertetra_t * TetraTop < A> :: up () const { + return _up ; +} +//us ende + +template < class A > inline typename TetraTop < A > :: innertetra_t * TetraTop < A > :: down () { + return _dwn ; +} + +template < class A > inline const typename TetraTop < A > :: innertetra_t * TetraTop < A > :: down () const { + return _dwn ; +} + +template < class A > inline typename TetraTop < A > :: innertetra_t * TetraTop < A > :: next () { + return _bbb ; +} + +template < class A > inline const typename TetraTop < A > :: innertetra_t * TetraTop < A > :: next () const { + return _bbb ; +} + +template < class A > inline typename TetraTop < A > :: innervertex_t * TetraTop < A > :: innerVertex () { + return 0 ; +} + +template < class A > inline const typename TetraTop < A > :: innervertex_t * TetraTop < A > :: innerVertex () const { + return 0 ; +} + +template < class A > inline typename TetraTop < A > :: inneredge_t * TetraTop < A > :: innerHedge () { + return _ed ; +} + +template < class A > inline const typename TetraTop < A > :: inneredge_t * TetraTop < A > :: innerHedge () const { + return _ed ; +} + +template < class A > inline typename TetraTop < A > :: innerface_t * TetraTop < A > :: innerHface () { + return _fc ; +} + +template < class A > inline const typename TetraTop < A > :: innerface_t * TetraTop < A > :: innerHface () const { + return _fc ; +} + +template < class A > inline void TetraTop < A > :: append (TetraTop < A > * h) { + assert (_bbb == 0) ; + _bbb = h ; + return ; +} + +template < class A > typename TetraTop < A > :: myhedge1_t * TetraTop < A > :: subedge1 (int i, int j) { + switch (this->myhface3(i)->getrule()) { + case myhface3_t :: myrule_t :: e01 : + assert( j == 0 ); + return this->myhface3 (i)->subedge1 (0) ; + case myhface3_t :: myrule_t :: e12 : + assert( j == 0 ); + return this->myhface3 (i)->subedge1 (0) ; + case myhface3_t :: myrule_t :: e20 : + assert( j == 0 ); + return this->myhface3 (i)->subedge1 (0) ; + case myhface3_t :: myrule_t :: iso4 : + assert( j < 3 ); + return ((this->twist (i) < 0) ? this->myhface3 (i)->subedge1 ((8 - j + this->twist (i)) % 3) : this->myhface3 (i)->subedge1 ((j + this->twist (i)) % 3)) ; + case myhface3_t :: myrule_t :: nosplit : + cerr << "**FEHLER (FATAL): subedge1 () auf nicht in verfeinerter Fl\"ache aufgerufen. In " << __FILE__ << " " << __LINE__ << endl ; + abort () ; + return 0 ; + } + return 0 ; +} + +template < class A > const typename TetraTop < A > :: myhedge1_t * TetraTop < A > :: subedge1 (int i, int j) const { + return ((TetraTop < A > *)this)->subedge1 (i,j) ; +} + + +template < class A > typename TetraTop < A > :: myhface3_t * TetraTop < A > :: subface3 (int i, int j) { + switch (this->myhface3(i)->getrule()) { + case myhface3_t :: myrule_t :: e01 : + assert( j < 2 ); + if ( this->twist(i) == 0 || this->twist(i) == 1 || this->twist(i) == -1 ) + return this->myhface3(i)->subface3(j) ; + if ( this->twist(i) == 2 || this->twist(i) == -2 || this->twist(i) == -3 ) + return this->myhface3(i)->subface3(!j) ; + cerr << __FILE__ << " " << __LINE__ << "myhface3(i)->subface3()" << endl; + return 0; + case myhface3_t :: myrule_t :: e12 : + assert( j < 2 ); + if ( this->twist(i) == 0 || this->twist(i) == 2 || this->twist(i) == -3 ) + return this->myhface3(i)->subface3(j) ; + if ( this->twist(i) == -1 || this->twist(i) == 1 || this->twist(i) == -2 ) + return this->myhface3(i)->subface3(!j) ; + cerr << __FILE__ << " " << __LINE__ << "myhface3(i)->subface3()" << endl; + return 0; + case myhface3_t :: myrule_t :: e20 : + assert( j < 2 ); + if ( this->twist(i) == 1 || this->twist(i) == 2 || this->twist(i) == -2 ) + return this->myhface3(i)->subface3(j) ; + if ( this->twist(i) == 0 || this->twist(i) == -1 || this->twist(i) == -3 ) + return this->myhface3(i)->subface3(!j) ; + cerr << __FILE__ << " " << __LINE__ << "myhface3(i)->subface3()" << endl; + return 0; + case myhface3_t :: myrule_t :: iso4 : + assert( j < 4 ); + if ( j == 3 ) + return this->myhface3(i)->subface3(3); + if ( j < 3 ) + return this->myhface3(i)->subface3(this->twist(i) < 0 ? (7 - j + this->twist(i)) % 3 : (j + this->twist(i)) % 3) ; + case myhface3_t :: myrule_t :: nosplit : + cerr << "**FEHLER (FATAL): subface3 () auf nicht verfeinerter Fl\"ache aufgerufen. In " << __FILE__ << " " << __LINE__ << endl ; + abort () ; + return 0 ; + default: + cerr << "**FEHLER (FATAL): Falsche Verfeinerungsregel [" << this->myhface3(i)->getrule() << "] in "__FILE__ << " " << __LINE__ << endl ; + abort() ; + } + return 0 ; +} + +template < class A > const typename TetraTop < A > :: myhface3_t * TetraTop < A > :: subface3 (int i, int j) const { + return ((TetraTop < A > *)this)->subface3 (i,j) ; +} + +template < class A > inline IndexManagerType & TetraTop < A > :: getFaceIndexManager () { + return static_cast<innerface_t &> (*(static_cast<TetraTop < A > *> (this)->subface3(0,0))).getIndexManager(); +} + +template < class A > inline IndexManagerType & TetraTop < A > :: getEdgeIndexManager () { + return static_cast<inneredge_t &> (*(static_cast<TetraTop < A > *> (this)->subedge1(0,0))).getIndexManager(); +} + +template < class A > void TetraTop < A > :: split_e01 () { + int l = 1 + level () ; + innerface_t * f0 = new innerface_t (l, this->subedge1 (3, 3), 1, this->subedge1 (0, 3), 0, this->subedge1 (2, 2), 0, getFaceIndexManager() ) ; + assert(f0) ; + innertetra_t * h0 = new innertetra_t (l, this->subface3(0, 0), this->twist (0), f0, 0, this->myhface3(2), this->twist (2), this->subface3(3, 0), this->twist (3), this) ; + innertetra_t * h1 = new innertetra_t (l, this->subface3(0, 1), this->twist (0), this->myhface3(1), this->twist (1), f0, 1, this->subface3(3, 1), this->twist (3), this) ; + assert(h0 && h1) ; + h0->append(h1) ; + _fc = f0 ; + _dwn = h0 ; + h0->_up = h1->_up = this; //us + return ; +} + +template < class A > void TetraTop < A > :: split_e12 () { + int l = 1 + level () ; + innerface_t * f0 = new innerface_t (l, this->subedge1 (3, 3), 1, this->subedge1 (0, 3), 0, this->subedge1 (2, 2), 0, getFaceIndexManager() ) ; + assert(f0 ) ; + innertetra_t * h0 = new innertetra_t (l, this->subface3(0, 0), this->twist (0), f0, 0, this->myhface3(2), this->twist (2), this->subface3(3, 0), this->twist (3), this) ; + innertetra_t * h1 = new innertetra_t (l, this->subface3(0, 1), this->twist (0), this->myhface3(1), this->twist (1), f0, 1, this->subface3(3, 1), this->twist (3), this) ; + assert(h0 && h1) ; + h0->append(h1) ; + _fc = f0 ; + _dwn = h0 ; + _rule = myrule_t :: e12 ; + return ; +} + +template < class A > void TetraTop < A > :: split_e20 () { + int l = 1 + level () ; + innerface_t * f0 = new innerface_t (l, this->subedge1 (3, 3), 1, this->subedge1 (0, 3), 0, this->subedge1 (2, 2), 0, getFaceIndexManager() ) ; + assert(f0) ; + innertetra_t * h0 = new innertetra_t (l, this->subface3(0, 0), this->twist (0), f0, 0, this->myhface3(2), this->twist (2), this->subface3(3, 0), this->twist (3), this) ; + innertetra_t * h1 = new innertetra_t (l, this->subface3(0, 1), this->twist (0), this->myhface3(1), this->twist (1), f0, 1, this->subface3(3, 1), this->twist (3), this) ; + assert(h0 && h1) ; + h0->append(h1) ; + _fc = f0 ; + _dwn = h0 ; + _rule = myrule_t :: e20 ; + return ; +} + +template < class A > void TetraTop < A > :: split_e23 () { + int l = 1 + level () ; + innerface_t * f0 = new innerface_t (l, this->subedge1 (3, 3), 1, this->subedge1 (0, 3), 0, this->subedge1 (2, 2), 0, getFaceIndexManager() ) ; + assert(f0) ; + innertetra_t * h0 = new innertetra_t (l, this->subface3(0, 0), this->twist (0), f0, 0, this->myhface3(2), this->twist (2), this->subface3(3, 0), this->twist (3), this) ; + innertetra_t * h1 = new innertetra_t (l, this->subface3(0, 1), this->twist (0), this->myhface3(1), this->twist (1), f0, 1, this->subface3(3, 1), this->twist (3), this) ; + assert(h0 && h1) ; + h0->append(h1) ; + _fc = f0 ; + _dwn = h0 ; + _rule = myrule_t :: e23 ; + return ; +} + +template < class A > void TetraTop < A > :: split_e30 () { + int l = 1 + level () ; + innerface_t * f0 = new innerface_t (l, this->subedge1 (3, 3), 1, this->subedge1 (0, 3), 0, this->subedge1 (2, 2), 0, getFaceIndexManager() ) ; + assert(f0) ; + innertetra_t * h0 = new innertetra_t (l, this->subface3(0, 0), this->twist (0), f0, 0, this->myhface3(2), this->twist (2), this->subface3(3, 0), this->twist (3), this) ; + innertetra_t * h1 = new innertetra_t (l, this->subface3(0, 1), this->twist (0), this->myhface3(1), this->twist (1), f0, 1, this->subface3(3, 1), this->twist (3), this) ; + assert(h0 && h1) ; + h0->append(h1) ; + _fc = f0 ; + _dwn = h0 ; + _rule = myrule_t :: e30 ; + return ; +} + +template < class A > void TetraTop < A > :: split_e31 () { + int l = 1 + level () ; + innerface_t * f0 = new innerface_t (l, this->subedge1 (3, 3), 1, this->subedge1 (0, 3), 0, this->subedge1 (2, 2), 0, getFaceIndexManager()) ; + assert(f0) ; + innertetra_t * h0 = new innertetra_t (l, this->subface3(0, 0), this->twist (0), f0, 0, this->myhface3(2), this->twist (2), this->subface3(3, 0), this->twist (3), this) ; + innertetra_t * h1 = new innertetra_t (l, this->subface3(0, 1), this->twist (0), this->myhface3(1), this->twist (1), f0, 1, this->subface3(3, 1), this->twist (3), this) ; + assert(h0 && h1) ; + h0->append(h1) ; + _fc = f0 ; + _dwn = h0 ; + _rule = myrule_t :: e31 ; + return ; +} + +template < class A > void TetraTop < A > :: split_iso8 () { + typedef typename A :: myvertex_t myvertex_t; + typedef typename A :: inneredge_t inneredge_t; + int l = 1 + level () ; + myvertex_t * e31 = this->myhface3 (0)->myhedge1 ((this->twist(0) < 0) ? ((9+this->twist(0))%3) : (this->twist(0)%3))->subvertex (0) ; + myvertex_t * e20 = this->myhface3 (1)->myhedge1 ((this->twist(1) < 0) ? ((9+this->twist(1))%3) : (this->twist(1)%3))->subvertex (0) ; + assert(e31 && e20); + inneredge_t * e0 = new inneredge_t (l, e31, e20, getEdgeIndexManager() ) ; + assert(e0) ; + IndexManagerType & faceIdxMan = getFaceIndexManager(); + innerface_t * f0 = new innerface_t (l, this->subedge1 (3, 2), ((this->twist(3)>=0)?1:0), this->subedge1 (1, 2), ((this->twist(1)>=0)?1:0), this->subedge1 (2, 2), ((this->twist(2)>=0)?1:0), faceIdxMan ) ; + innerface_t * f1 = new innerface_t (l, this->subedge1 (3, 0), ((this->twist(3)>=0)?1:0), this->subedge1 (2, 1), ((this->twist(2)>=0)?1:0), this->subedge1 (0, 2), ((this->twist(0)>=0)?1:0), faceIdxMan ) ; + innerface_t * f2 = new innerface_t (l, this->subedge1 (3, 1), ((this->twist(3)>=0)?1:0), this->subedge1 (0, 1), ((this->twist(0)>=0)?1:0), this->subedge1 (1, 0), ((this->twist(1)>=0)?1:0), faceIdxMan ) ; + innerface_t * f3 = new innerface_t (l, this->subedge1 (2, 0), ((this->twist(2)>=0)?0:1), this->subedge1 (0, 0), ((this->twist(0)>=0)?0:1), this->subedge1 (1, 1), ((this->twist(1)>=0)?0:1), faceIdxMan ) ; + innerface_t * f4 = new innerface_t (l, e0, 0, this->subedge1 (3, 2), ((this->twist(3)>=0)?0:1), this->subedge1 (2, 1), ((this->twist(2)>=0)?1:0), faceIdxMan ) ; + innerface_t * f5 = new innerface_t (l, e0, 0, this->subedge1 (3, 1), ((this->twist(3)>=0)?1:0), this->subedge1 (0, 2), ((this->twist(0)>=0)?0:1), faceIdxMan ) ; + innerface_t * f6 = new innerface_t (l, e0, 0, this->subedge1 (1, 0), ((this->twist(1)>=0)?0:1), this->subedge1 (0, 0), ((this->twist(0)>=0)?1:0), faceIdxMan ) ; + innerface_t * f7 = new innerface_t (l, e0, 0, this->subedge1 (1, 2), ((this->twist(1)>=0)?1:0), this->subedge1 (2, 0), ((this->twist(2)>=0)?0:1), faceIdxMan ) ; + assert(f0 && f1 && f2 && f3 && f4 && f5 && f6 && f7) ; + f0->append(f1) ; + f1->append(f2) ; + f2->append(f3) ; + f3->append(f4) ; + f4->append(f5) ; + f5->append(f6) ; + f6->append(f7) ; + // this is the pointer to the father element + innertetra_t * h0 = new innertetra_t (l, f0, -1, this->subface3(1, 0), this->twist(1), this->subface3(2, 0), this->twist(2), this->subface3(3, 0), this->twist(3), this) ; + innertetra_t * h1 = new innertetra_t (l, this->subface3(0, 0), this->twist(0), f1, -3, this->subface3(2, 2), this->twist(2), this->subface3(3, 1), this->twist(3), this) ; + innertetra_t * h2 = new innertetra_t (l, this->subface3(0, 2), this->twist(0), this->subface3(1, 1), this->twist(1), f2, -1, this->subface3(3, 2), this->twist(3), this) ; + innertetra_t * h3 = new innertetra_t (l, this->subface3(0, 1), this->twist(0), this->subface3(1, 2), this->twist(1), this->subface3(2, 1), this->twist(2), f3, 0, this) ; + innertetra_t * h4 = new innertetra_t (l, f7, -3, this->subface3(2, 3), ((this->twist(2)>=0) ? ((this->twist(2)+2)%3) : this->twist(2)) , f4, 2, f0, 0, this) ; + innertetra_t * h5 = new innertetra_t (l, f4, -3, f1, 0, f5, 2, this->subface3(3, 3), ((this->twist(3)>=0) ? (this->twist(3)+1)%3 : (this->twist(3)-1)%3-1), this) ; + innertetra_t * h6 = new innertetra_t (l, f3, -1, f6, -3, this->subface3(1, 3), ((this->twist(1)>=0) ? this->twist(1) : this->twist(1)%3-1), f7, 1, this) ; + innertetra_t * h7 = new innertetra_t (l, this->subface3(0, 3), ((this->twist(0)>=0) ? (this->twist(0)+1)%3 : (this->twist(0)-1)%3-1), f5, -3, f2, 0, f6, 1, this) ; + assert(h0 && h1 && h2 && h3 && h4 && h5 && h6 && h7) ; + h0->append(h1) ; + h1->append(h2) ; + h2->append(h3) ; + h3->append(h4) ; + h4->append(h5) ; + h5->append(h6) ; + h6->append(h7) ; + _ed = e0 ; + _fc = f0 ; + _dwn = h0 ; + _rule = myrule_t :: iso8 ; + + return ; +} + +template < class A > typename TetraTop < A > :: myrule_t TetraTop < A > :: getrule () const { + return myrule_t (_rule) ; +} + +template < class A > typename TetraTop < A > :: myrule_t TetraTop < A > :: requestrule () const { + return myrule_t (_req) ; +} + +template < class A > void TetraTop < A > :: request (myrule_t r) +{ + assert (r.isValid ()) ; + _req = r ; + return ; +} + +template < class A > void TetraTop < A > :: refineImmediate (myrule_t r) { + assert (getrule () == myrule_t :: nosplit) ; + typedef typename myhface3_t :: myrule_t myhface3rule_t; + switch(r) { + case myrule_t :: e01 : + this->myhface3 (2)->refineImmediate (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (2))) ; + this->myhface3 (3)->refineImmediate (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (3))) ; + split_e01 () ; + break ; + case myrule_t :: e12 : + this->myhface3 (0)->refineImmediate (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (0))) ; + this->myhface3 (3)->refineImmediate (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (3))) ; + split_e12 () ; + break ; + case myrule_t :: e20 : + this->myhface3 (1)->refineImmediate (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (1))) ; + this->myhface3 (3)->refineImmediate (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (3))) ; + split_e20 () ; + break ; + case myrule_t :: e23 : + this->myhface3 (0)->refineImmediate (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (0))) ; + this->myhface3 (1)->refineImmediate (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (1))) ; + split_e23 () ; + break ; + case myrule_t :: e30 : + this->myhface3 (1)->refineImmediate (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (1))) ; + this->myhface3 (2)->refineImmediate (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (2))) ; + split_e30 () ; + break ; + case myrule_t :: e31 : + this->myhface3 (0)->refineImmediate (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (0))) ; + this->myhface3 (2)->refineImmediate (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (2))) ; + split_e31 () ; + break ; + case myrule_t :: iso8 : + + // Das refineImmediate (..) auf allen Fl"achen wird vom tetra :: refine (..) + // zwar nicht ben"otigt, da schliesslich alle Fl"achen sauber sind, wenn + // "uberall hface3 :: refine (..) true geliefert hat, wohl aber z.B. von + // restore () oder abgeleiteten Funktionen die eine direkte Verfeinerung + // erzwingen m"ussen und d"urfen. + + {for (int i = 0 ; i < 4 ; i ++) + this->myhface3 (i)->refineImmediate (myhface3rule_t (myhface3_t :: myrule_t :: iso4).rotate (this->twist (i))) ; } + split_iso8 () ; + break ; + default : + cerr << "**FEHLER (FATAL) beim unbedingten Verfeinern mit unbekannter Regel: " ; + cerr << "[" << r << "]. In " << __FILE__ << __LINE__ << endl ; + abort () ; + break ; + } + this->postRefinement () ; + return ; +} + +template < class A > bool TetraTop < A > :: refine () { + + myrule_t r = _req ; + if (r != myrule_t :: crs && r != myrule_t :: nosplit) { + if (r != getrule ()) { + assert (getrule () == myrule_t :: nosplit) ; + _req = myrule_t :: nosplit ; + switch (r) { + typedef typename myhface3_t :: myrule_t myhface3rule_t; + case myrule_t :: crs : + case myrule_t :: nosplit : + return true ; + case myrule_t :: e01 : + if (!this->myhface3 (2)->refine (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (2)), this->twist (2))) return false ; + if (!this->myhface3 (3)->refine (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (3)), this->twist (3))) return false ; + break ; + case myrule_t :: e12 : + if (!this->myhface3 (0)->refine (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (0)), this->twist (0))) return false ; + if (!this->myhface3 (3)->refine (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (3)), this->twist (3))) return false ; + break ; + case myrule_t :: e20 : + if (!this->myhface3 (1)->refine (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (1)), this->twist (1))) return false ; + if (!this->myhface3 (3)->refine (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (3)), this->twist (3))) return false ; + break ; + case myrule_t :: e23 : + if (!this->myhface3 (0)->refine (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (0)), this->twist (0))) return false ; + if (!this->myhface3 (1)->refine (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (1)), this->twist (1))) return false ; + break ; + case myrule_t :: e30 : + if (!this->myhface3 (1)->refine (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (1)), this->twist (1))) return false ; + if (!this->myhface3 (2)->refine (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (2)), this->twist (2))) return false ; + break ; + case myrule_t :: e31 : + if (!this->myhface3 (0)->refine (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (0)), this->twist (0))) return false ; + if (!this->myhface3 (2)->refine (myhface3rule_t (myhface3_t :: myrule_t :: e01).rotate (this->twist (2)), this->twist (2))) return false ; + break ; + case myrule_t :: iso8 : + {for (int i = 0 ; i < 4 ; i ++ ) + if (!this->myhface3 (i)->refine (myhface3rule_t (myhface3_t :: myrule_t :: iso4).rotate (this->twist (i)), this->twist (i))) return false ; } + break ; + default : + cerr << "**WARNUNG (FEHLER IGNORIERT) falsche Verfeinerungsregel [" << getrule () ; + cerr << "] (ignoriert) in " << __FILE__ << " " << __LINE__ << endl ; + return false ; + } + + // Vorsicht: Im Fall eines konformen Verfeinerers mu"s hier die entstandene Verfeinerung + // untersucht werden und dann erst das Element danach verfeinert werden. + + refineImmediate (r) ; + return true ; + } + } + return true ; +} + +template < class A > bool TetraTop < A > :: refineBalance (balrule_t r, int fce) { + if (r != balrule_t :: iso4) { + cerr << "**WARNUNG (IGNORIERT) in TetraTop < A > :: refineBalance (..) nachschauen, Datei " + << __FILE__ << " Zeile " << __LINE__ << endl ; + + // Bisher kann die Balancierung nur die isotrope Achtelung handhaben, + // falls mehr gew"unscht wird muss es hier eingebaut werden. Im Moment wird + // die Balancierung einfach verweigert, d.h. die Verfeinerung des anfordernden + // Elements f"allt flach. + + return false ; + } + if (getrule () == myrule_t :: nosplit) { + if (! this->myhface3 (fce)->leaf ()) { + for (int i = 0 ; i < 4 ; i ++) + if (i != fce) + if (!this->myhface3 (i)->refine (balrule_t (balrule_t :: iso4).rotate (this->twist (i)), this->twist (i))) + return false ; + _req = myrule_t :: nosplit ; + refineImmediate (myrule_t :: iso8) ; + } + } + return true ; +} + +template < class A > bool TetraTop < A > :: coarse () { + if (this->leaf ()) { + assert (_req == myrule_t :: nosplit || _req == myrule_t :: crs) ; + myrule_t w = _req ; + _req = myrule_t :: nosplit ; + if (w != myrule_t :: crs) return false ; + for (int i = 0 ; i < 4 ; i ++) if (!this->myhface3 (i)->leaf ()) return false ; + return true ; + } else { + assert (_req == myrule_t :: nosplit) ; + bool x = true ; + {for (innertetra_t * h = down () ; h ; h = h->next ()) x &= h->coarse () ; } + if (x) { + this->preCoarsening () ; + delete _dwn ; + _dwn = 0 ; + delete _fc ; + _fc = 0 ; + delete _ed ; + _ed = 0 ; + _rule = myrule_t :: nosplit ; + { + for (int i = 0 ; i < 4 ; i ++ ) { + this->myneighbour (i).first->bndNotifyCoarsen () ; + this->myhface3 (i)->coarse () ; + } + } + return false ; + } + } + return false ; +} + +template < class A > bool TetraTop < A > :: bndNotifyCoarsen () { + return true ; +} + +template < class A > void TetraTop < A > :: backupCMode (ostream & os) const { + + // Das backup im alten Stil, d.h. levelweise die Verfeinerungsregeln + // vom Gitter runterschreiben. Diese Technik wird nur f"ur das backup + // noch unterst"utzt, um die Daten mit "alteren Konstruktionen visual. + // zu k"onnen. + + os << getrule () << " " ; + return ; +} + +// buckupTetra +template < class A > void TetraTop < A > :: backupIndex (ostream & os) const +{ +#ifdef _DUNE_USES_BSGRID_ + os.write( ((const char *) & this->_index ), sizeof(int) ) ; + {for (const innertetra_t * c = down () ; c ; c = c->next ()) c->backupIndex (os) ; } +#endif + return; +} + +// buckupTetra +template < class A > void TetraTop < A > :: backup (ostream & os) const +{ + os.put ((char) getrule ()) ; + {for (const inneredge_t * e = innerHedge () ; e ; e = e->next ()) e->backup (os) ; } + {for (const innerface_t * f = innerHface () ; f ; f = f->next ()) f->backup (os) ; } + {for (const innertetra_t * c = down () ; c ; c = c->next ()) c->backup (os) ; } + + return ; +} + +template < class A > void TetraTop < A > :: backup (XDRstream_out & os) const +{ + os.put ((char) getrule ()) ; + {for (const inneredge_t * e = innerHedge () ; e ; e = e->next ()) e->backup (os) ; } + {for (const innerface_t * f = innerHface () ; f ; f = f->next ()) f->backup (os) ; } + {for (const innertetra_t * c = down () ; c ; c = c->next ()) c->backup (os) ; } + + return ; +} + +// overloaded restoreIndex Method +template < class A > inline void TetraTop < A > :: restoreIndex (istream & is) +{ +#ifdef _DUNE_USES_BSGRID_ + // free index from constructor + //_indexManager.freeIndex( this->getIndex() ); + is.read ( ((char *) &(this->_index) ), sizeof(int) ); + {for (innertetra_t * c = down () ; c ; c = c->next ()) c->restoreIndex (is) ; } +#endif + return; +} + +// restoreTetra +template < class A > void TetraTop < A > :: restore (istream & is) { + + // restore () stellt den Elementbaum aus der Verfeinerungs- + // geschichte wieder her. Es ruft refine () auf und testet + // auf den korrekten Vollzug der Verfeinerung. Danach werden + // die inneren Gitterteile restore'd. + + myrule_t r ((char) is.get ()) ; + assert(getrule() == myrule_t :: nosplit) ; + if (r == myrule_t :: nosplit) { + + // Vorsicht: beim restore m"ussen sich sowohl Element als auch + // Randelement um die Korrektheit der Nachbarschaft k"ummern, + // und zwar dann wenn sie "on the top" sind (= die gelesene + // Verfeinerungsregel ist nosplit). (s.a. beim Randelement) + // Die nachfolgende L"osung ist weit davon entfernt, sch"on + // zu sein - leider. Eventuell wird mit der Verbesserung der + // Behandlung der nichtkonf. Situationen mal eine "Anderung + // n"otig. + + for (int i = 0 ; i < 4 ; i ++) { + myhface3_t & f (*(this->myhface3 (i))) ; + if (!f.leaf ()) { + switch (f.getrule ()) { + case balrule_t :: e01 : + case balrule_t :: e12 : + case balrule_t :: e20 : + {for (int j = 0 ; j < 2 ; j ++) f.subface3 (j)->nb.complete (f.nb) ;} + break ; + case balrule_t :: iso4 : + {for (int j = 0 ; j < 4 ; j ++) f.subface3 (j)->nb.complete (f.nb) ;} + break ; + default : + abort () ; + break ; + } + } + } + } else { + + // Auf dem Element gibt es kein refine (myrule_t) deshalb mu"s erst + // request (myrule_t) und dann refine () durchgef"uhrt werden. + + request (r) ; + refine () ; + assert (getrule() == r) ; + {for (inneredge_t * e = innerHedge () ; e ; e = e->next ()) e->restore (is) ; } + {for (innerface_t * f = innerHface () ; f ; f = f->next ()) f->restore (is) ; } + {for (innertetra_t * c = down () ; c ; c = c->next ()) c->restore (is) ; } + } + + return ; +} +template < class A > void TetraTop < A > :: restore (XDRstream_in & is) { + + // restore () stellt den Elementbaum aus der Verfeinerungs- + // geschichte wieder her. Es ruft refine () auf und testet + // auf den korrekten Vollzug der Verfeinerung. Danach werden + // die inneren Gitterteile restore'd. + + myrule_t r ((char) is.get ()) ; + assert(getrule() == myrule_t :: nosplit) ; + if (r == myrule_t :: nosplit) { + + // Vorsicht: beim restore m"ussen sich sowohl Element als auch + // Randelement um die Korrektheit der Nachbarschaft k"ummern, + // und zwar dann wenn sie "on the top" sind (= die gelesene + // Verfeinerungsregel ist nosplit). (s.a. beim Randelement) + // Die nachfolgende L"osung ist weit davon entfernt, sch"on + // zu sein - leider. Eventuell wird mit der Verbesserung der + // Behandlung der nichtkonf. Situationen mal eine "Anderung + // n"otig. + + for (int i = 0 ; i < 4 ; i ++) { + myhface3_t & f (*(this->myhface3 (i))) ; + if (!f.leaf ()) { + switch (f.getrule ()) { + case balrule_t :: e01 : + case balrule_t :: e12 : + case balrule_t :: e20 : + {for (int j = 0 ; j < 2 ; j ++) f.subface3 (j)->nb.complete (f.nb) ;} + break ; + case balrule_t :: iso4 : + {for (int j = 0 ; j < 4 ; j ++) f.subface3 (j)->nb.complete (f.nb) ;} + break ; + default : + abort () ; + break ; + } + } + } + } else { + + // Auf dem Element gibt es kein refine (myrule_t) deshalb mu"s erst + // request (myrule_t) und dann refine () durchgef"uhrt werden. + + request (r) ; + refine () ; + assert (getrule() == r) ; + {for (inneredge_t * e = innerHedge () ; e ; e = e->next ()) e->restore (is) ; } + {for (innerface_t * f = innerHface () ; f ; f = f->next ()) f->restore (is) ; } + {for (innertetra_t * c = down () ; c ; c = c->next ()) c->restore (is) ; } + } + + return ; +} + +// ###### ##### ####### +// # # ###### ##### # #### ##### # #### # # # #### ##### +// # # # # # # # # # # # # # # # # # # # +// ###### ##### # # # # # # # # # ##### # # # # # +// # # ##### # # # # # # # # # # # ##### +// # # # # # # # # # # # # # # # # # # +// # ###### # # # #### ##### # #### ##### # #### # + +template < class A > inline Periodic3Top < A > :: Periodic3Top (int l, myhface3_t * f0, int t0, + myhface3_t * f1, int t1) : A (f0, t0, f1, t1), _dwn (0), _bbb (0), _up(0), _lvl (l), + _rule (myrule_t :: nosplit) { //_up eing. us + return ; +} + +template < class A > inline Periodic3Top < A > :: ~Periodic3Top () { + if (_bbb) delete _bbb ; + if (_dwn) delete _dwn ; + return ; +} + +template < class A > inline int Periodic3Top < A > :: level () const { + return _lvl ; +} + +//testweise us +template < class A > inline typename Periodic3Top < A > :: innerperiodic3_t * Periodic3Top < A > :: up () { + return _up ; +} +template < class A > inline const typename Periodic3Top < A > :: innerperiodic3_t * Periodic3Top < A> :: up () const { + return _up ; +} +//us ende + +template < class A > inline typename Periodic3Top < A > :: innerperiodic3_t * Periodic3Top < A > :: down () { + return _dwn ; +} + +template < class A > inline const typename Periodic3Top < A > :: innerperiodic3_t * Periodic3Top < A > :: down () const { + return _dwn ; +} + +template < class A > inline typename Periodic3Top < A > :: innerperiodic3_t * Periodic3Top < A > :: next () { + return _bbb ; +} + +template < class A > inline const typename Periodic3Top < A > :: innerperiodic3_t * Periodic3Top < A > :: next () const { + return _bbb ; +} + +template < class A > inline typename Periodic3Top < A > :: innervertex_t * Periodic3Top < A > :: innerVertex () { + return 0 ; +} + +template < class A > inline const typename Periodic3Top < A > :: innervertex_t * Periodic3Top < A > :: innerVertex () const { + return 0 ; +} + +template < class A > inline typename Periodic3Top < A > :: inneredge_t * Periodic3Top < A > :: innerHedge () { + return 0 ; +} + +template < class A > inline const typename Periodic3Top < A > :: inneredge_t * Periodic3Top < A > :: innerHedge () const { + return 0 ; +} + +template < class A > inline typename Periodic3Top < A > :: innerface_t * Periodic3Top < A > :: innerHface () { + return 0 ; +} + +template < class A > inline const typename Periodic3Top < A > :: innerface_t * Periodic3Top < A > :: innerHface () const { + return 0 ; +} + +template < class A > inline void Periodic3Top < A > :: append (Periodic3Top < A > * h) { + assert (_bbb == 0) ; + _bbb = h ; + return ; +} + +template < class A > typename Periodic3Top < A > :: myhedge1_t * Periodic3Top < A > :: subedge1 (int i, int j) { + switch (this->myhface3(i)->getrule()) { + case myhface3_t :: myrule_t :: e01 : + case myhface3_t :: myrule_t :: e12 : + case myhface3_t :: myrule_t :: e20 : + assert( j == 0 ); + return this->myhface3 (i)->subedge1 (0) ; + case myhface3_t :: myrule_t :: iso4 : + assert( j < 3 ); + return ((this->twist (i) < 0) ? this->myhface3 (i)->subedge1 ((8 - j + this->twist (i)) % 3) : this->myhface3 (i)->subedge1 ((j + this->twist (i)) % 3)) ; + case myhface3_t :: myrule_t :: nosplit : + cerr << "**FEHLER (FATAL): subedge1 () auf nicht in verfeinerter Fl\"ache aufgerufen. In " << __FILE__ << " " << __LINE__ << endl ; + abort () ; + return 0 ; + } + return 0 ; +} + +template < class A > const typename Periodic3Top < A > :: myhedge1_t * Periodic3Top < A > :: subedge1 (int i, int j) const { + return ((Periodic3Top < A > *)this)->subedge1 (i,j) ; +} + +template < class A > typename Periodic3Top < A > :: myhface3_t * Periodic3Top < A > :: subface3 (int i, int j) { + switch (this->myhface3 (i)->getrule ()) { + case myhface3_t :: myrule_t :: e01 : + assert( j < 2 ); + if ( this->twist(i) == 0 || this->twist(i) == 1 || this->twist(i) == -1 ) + return this->myhface3(i)->subface3(j) ; + if ( this->twist(i) == 2 || this->twist(i) == -2 || this->twist(i) == -3 ) + return this->myhface3(i)->subface3(!j) ; + cerr << __FILE__ << " " << __LINE__ << "myhface3(i)->subface3()" << endl; + return 0; + case myhface3_t :: myrule_t :: e12 : + assert( j < 2 ); + if ( this->twist(i) == 0 || this->twist(i) == 2 || this->twist(i) == -3 ) + return this->myhface3(i)->subface3(j) ; + if ( this->twist(i) == -1 || this->twist(i) == 1 || this->twist(i) == -2 ) + return this->myhface3(i)->subface3(!j) ; + cerr << __FILE__ << " " << __LINE__ << "myhface3(i)->subface3()" << endl; + return 0; + case myhface3_t :: myrule_t :: e20 : + assert( j < 2 ); + if ( this->twist(i) == 1 || this->twist(i) == 2 || this->twist(i) == -2 ) + return this->myhface3(i)->subface3(j) ; + if ( this->twist(i) == 0 || this->twist(i) == -1 || this->twist(i) == -3 ) + return this->myhface3(i)->subface3(!j) ; + cerr << __FILE__ << " " << __LINE__ << "myhface3(i)->subface3()" << endl; + return 0; + case myhface3_t :: myrule_t :: iso4 : + assert( j < 4 ); + if ( j == 3 ) + return this->myhface3(i)->subface3 (3) ; + if ( j < 3 ) + return this->myhface3 (i)->subface3 (this->twist(i) < 0 ? (7 - j + this->twist(i)) % 3 : (j + this->twist(i)) % 3) ; + case myhface3_t :: myrule_t :: nosplit : + cerr << "**FEHLER (FATAL): subface3 () auf nicht verfeinerter Fl\"ache aufgerufen. In " << __FILE__ << " " << __LINE__ << endl ; + abort () ; + return 0 ; + default: + cerr << "**FEHLER (FATAL): Falsche Verfeinerungsregel [" << this->myhface3(i)->getrule() << "] in "__FILE__ << " " << __LINE__ << endl ; + abort() ; + } + return 0 ; +} + +template < class A > const typename Periodic3Top < A > :: myhface3_t * Periodic3Top < A > :: subface3 (int i, int j) const { + return ((Periodic3Top < A > *)this)->subface3 (i,j) ; +} + +template < class A > typename Periodic3Top < A > :: myrule_t Periodic3Top < A > :: getrule () const { + return myrule_t (_rule) ; +} + +template < class A > void Periodic3Top < A > :: request (myrule_t) { + + // Einen Request zur Verfeinerung zu setzen, ist vorl"aufig inhaltlich nicht + // vorgesehen und wird deshalb ignoriert (leise). + + return ; +} + +template < class A > void Periodic3Top < A > :: split_iso4 () { + int l = 1 + level () ; + innerperiodic3_t * p0 = new innerperiodic3_t (l, this->subface3 (0,0), this->twist (0), this->subface3 (1,0), this->twist (1)) ; + innerperiodic3_t * p1 = new innerperiodic3_t (l, this->subface3 (0,1), this->twist (0), this->subface3 (1,2), this->twist (1)) ; + innerperiodic3_t * p2 = new innerperiodic3_t (l, this->subface3 (0,2), this->twist (0), this->subface3 (1,1), this->twist (1)) ; + + // Mir ist nicht ganz klar, warum der Twist auf diese seltsame Art umzurechnen ist, + // die Zeile (bzw. die Formel) habe ich aus Mario's Tetradeder Split Iso-8 "uber- + // nommen, ohne im einzelnen nachzupr"ufen, ob die Regel richtig ist. (BS) + + innerperiodic3_t * p3 = new innerperiodic3_t (l, this->subface3 (0,3), (this->twist(0) >= 0 ? (this->twist(0)+1)%3 : (this->twist(0)-1)%3-1), this->subface3 (1,3), (this->twist(1)>=0 ? (this->twist(1)+1)%3 : (this->twist(1)-1)%3-1)) ; + assert (p0 && p1 && p2 && p3) ; + p0->append(p1) ; + p1->append(p2) ; + p2->append(p3) ; + _dwn = p0 ; + _rule = myrule_t :: iso4 ; + p0->_up = p1->_up = p2->_up = p3->_up = this; //us + return ; +} + +template < class A > void Periodic3Top < A > :: refineImmediate (myrule_t r) { + + // Die Methode wird nur vom restore () und vom refineBalance () auf- + // gerufen und geht davon aus, dass das betroffene Element noch nicht + // verfeinert ist -> ist ein Blatt der Hierarchie. + + assert (this->leaf()) ; + switch(r) { + case myrule_t :: e01 : + case myrule_t :: e12 : + case myrule_t :: e20 : + + // Mit den drei anisotropen Regeln k"onnen wir leider noch nichts anfangen. + + abort () ; + case myrule_t :: iso4 : + + // Das refineImmediate (..) auf allen Fl"achen wird vom periodic3 :: refine (..) + // zwar nicht ben"otigt, da schliesslich alle Fl"achen sauber sind, wenn + // "uberall hface3 :: refine (..) true geliefert hat, wohl aber z.B. von + // restore () oder abgeleiteten Funktionen die eine direkte Verfeinerung + // erzwingen m"ussen und d"urfen. + + typedef typename myhface3_t :: myrule_t myhface3rule_t; + this->myhface3 (0)->refineImmediate (myhface3rule_t (r).rotate (this->twist (0))) ; + this->myhface3 (1)->refineImmediate (myhface3rule_t (r).rotate (this->twist (1))) ; + split_iso4 () ; + break ; + default : + cerr << "**FEHLER (FATAL) beim unbedingten Verfeinern mit unbekannter Regel: " ; + cerr << "[" << r << "]. In " << __FILE__ << __LINE__ << endl ; + abort () ; + break ; + } + this->postRefinement () ; + return ; +} + +template < class A > bool Periodic3Top < A > :: refine () { + + // Das refine () reagiert nicht auf die Elementaktivierung zur Verfeinerung + // in der globalen Schleife, weil das perioodische Randelement sich nur auf + // Anforderung zur Balancierung aus einem anliegenden Element direkt verfeinert. + + return true ; +} + +template < class A > bool Periodic3Top < A > :: refineBalance (balrule_t r, int fce) { + if (r != balrule_t :: iso4) { + cerr << "**WARNUNG (IGNORIERT) in Periodic3Top < A > :: refineBalance (..) nachschauen, Datei " + << __FILE__ << " Zeile " << __LINE__ << endl ; + + // Bisher kann die Balancierung nur die isotrope Achtelung handhaben, + // falls mehr gew"unscht wird, muss es hier eingebaut werden. Im Moment wird + // die Balancierung einfach verweigert, d.h. die Verfeinerung des anfordernden + // Elements f"allt flach. + + return false ; + } else { + + // Der nachfolgende Aufruf nutzt aus, dass die Regel der periodischen R"ander + // sich direkt auf die Balancierungsregel des entsprechenden Polygonverbinders + // projezieren l"asst (n"amlich 1:1). Deshalb unterscheidet der Aufruf nicht nach + // der angeforderten Regel in einer 'case' Anweisung. + + int opp = fce == 0 ? 1 : 0 ; + if (this->myhface3 (opp)->refine (typename myhface3_t :: myrule_t (r).rotate (this->twist (opp)), this->twist (opp))) { + refineImmediate (r) ; + return true ; + } else { + return false ; + } + } +} + +template < class A > bool Periodic3Top < A > :: coarse () { + + // Das Vergr"obern geschieht auch passiv, sobald ein anliegendes Element + // vergr"obert wird durch den Aufruf von "bndNotifyCoarsen ()" s.u. + + bndNotifyCoarsen () ; + return false ; +} + +template < class A > bool Periodic3Top < A > :: bndNotifyCoarsen () { + + // Wie beim Randelement auch: Die Vergr"oberung eines anliegenden Elements + // l"ost einen Vorgang aus, der feststellt ob das periodische RE ebenfalls + // vergr"obert werden soll. + + innerperiodic3_t * p = down () ; + if (!p) return false ; + bool x = true ; + do { + + // Falls p kein Blatt der Hierarchie ist, + // die Vergr"oberungsm"oglichkeit weitergeben. + + if (!p->leaf ()) p->coarse () ; + + // F"ur die hintere und vordere Fl"ache feststellen, ob + // der Referenzenz"ahler mehr als einen Eintrag ergibt. + + if (p->myhface3 (0)->ref > 1) (x = false) ; + if (p->myhface3 (1)->ref > 1) (x = false) ; + + } while (p = p->next ()) ; + if (x) { + + // Falls keine Fl"achen anliegen, die auf Kinder oder Kindes- + // mit mehr als einer Referenz f"uhren, ist sicher, dass das + // Bezugsrandelement zwischen zwei 'relativ groben' Elementen + // liegt. Somit kann es vergr"obert werden. + + this->preCoarsening () ; + delete _dwn ; + _dwn = 0 ; + _rule = myrule_t :: nosplit ; + this->myhface3 (0)->coarse () ; + this->myhface3 (1)->coarse () ; + } + return x ; +} + +template < class A > void Periodic3Top < A > :: backupCMode (ostream & os) const { + + // Das backup im alten Stil, d.h. levelweise die Verfeinerungsregeln + // vom Gitter runterschreiben. Diese Technik wird nur f"ur das backup + // noch unterst"utzt, um die Daten mit "alteren Konstruktionen visual. + // zu k"onnen. + + os << getrule () << " " ; + return ; +} + +template < class A > void Periodic3Top < A > :: backup (ostream & os) const { + os.put ((char) getrule ()) ; + {for (const innerperiodic3_t * c = down () ; c ; c = c->next ()) c->backup (os) ; } + return ; +} + +template < class A > void Periodic3Top < A > :: restore (istream & is) { + myrule_t r ((char) is.get ()) ; + assert(getrule () == myrule_t :: nosplit) ; // Testen auf unverfeinerten Zustand + if (r == myrule_t :: nosplit) { + for (int i = 0 ; i < 2 ; i ++) { + myhface3_t & f (*(this->myhface3 (i))) ; + if (!f.leaf ()) { + switch (f.getrule ()) { + case balrule_t :: iso4 : + {for (int j = 0 ; j < 4 ; j ++) f.subface3 (j)->nb.complete (f.nb) ;} + break ; + default : + cerr << "**FEHLER (FATAL) beim restore mit unbekannter Balancierungsregel: " + << "[" << r << "]. In " << __FILE__ << __LINE__ << endl ; + abort () ; + break ; + } + } + } + } else { + refineImmediate (r) ; + assert (getrule() == r) ; + {for (innerperiodic3_t * c = down () ; c ; c = c->next ()) c->restore (is) ; } + } + return ; +} + +#endif // GITTER_TetraTop_H_INCLUDED diff --git a/src/serial/headers.h b/src/serial/headers.h new file mode 100644 index 0000000000000000000000000000000000000000..7726d78f09b7c944d12feaa645b2229cbb2a6cd3 --- /dev/null +++ b/src/serial/headers.h @@ -0,0 +1,9 @@ +#ifndef __FAKE_HEADERS_INCLUDED__ +#define __FAKE_HEADERS_INCLUDED__ + +#include "key.h" +#include "serialize.h" +#include "lock.h" +#include "gitter_sti.h" + +#endif diff --git a/src/serial/indexstack.h b/src/serial/indexstack.h new file mode 100644 index 0000000000000000000000000000000000000000..8a95d2a8f3a7fb0be637ca9af4023169156de417 --- /dev/null +++ b/src/serial/indexstack.h @@ -0,0 +1,279 @@ +// (c) Robert Kloefkorn 2004 - 2005 +#ifndef INDEXSTACK_H_INCLUDED +#define INDEXSTACK_H_INCLUDED + +#ifdef IBM_XLC + #define _ANSI_HEADER +#endif + +#include <assert.h> + +#ifdef _ANSI_HEADER + using namespace std; + #include <stack> +#else + #include <stack.h> +#endif + +#ifdef _DUNE_USES_BSGRID_ + +template<class T, int length> +class FiniteStack { +public : + // Makes empty stack + FiniteStack () : _f(0) {} + + // Returns true if the stack is empty + bool empty () const { return _f==0; } + + // Returns true if the stack is full + bool full () const { return (_f >= length); } + + // Puts a new object onto the stack + void push (const T& t) { _s[_f++] = t; } + + // Removes and returns the uppermost object from the stack + T pop () { return _s[--_f]; } + + // Returns the uppermost object on the stack + T top () const { return _s[_f-1]; } + + // stacksize + int size () const { return _f; } + +private: + T _s[length]; // the stack + int _f; // actual position in stack +}; + + +//****************************************************** +// +// IndexStack providing indices via getIndex and freeIndex +// indices that are freed, are put on a stack and get +// +//****************************************************** +template <class T, int length> +class IndexStack +{ + typedef FiniteStack<T,length> StackType; + typedef stack < StackType * > StackListType; + + StackListType fullStackList_; + StackListType emptyStackList_; + + //typedef typename StackListType::Iterator DListIteratorType; + StackType * stack_; + + // current maxIndex + int maxIndex_; +public: + //! Constructor, create new IndexStack + IndexStack(); + + //! Destructor, deleting all stacks + inline ~IndexStack (); + + //! set index as maxIndex if index is bigger than maxIndex + void checkAndSetMax(T index) { if(index > maxIndex_) maxIndex_ = index; } + + //! set index as maxIndex + void setMaxIndex(T index) { maxIndex_ = index; } + + //! set index as maxIndex + int getMaxIndex() const { return maxIndex_; } + + //! restore index from stack or create new index + T getIndex (); + + //! store index on stack + void freeIndex(T index); + + //! test stack funtcionality + void test (); + + // backup set to out stream + void backupIndexSet ( ostream & os ); + + // restore from in stream + void restoreIndexSet ( istream & is ); +private: + // no copy constructor allowed + IndexStack( const IndexStack<T,length> & s) : maxIndex_ (0) , stack_(0) {} + + // no assignment operator allowed + IndexStack<T,length> & operator = ( const IndexStack<T,length> & s) + { + cout << "IndexStack::operator = () not allowed! in: " __FILE__ << " line:" << __LINE__ << "\n"; + abort(); + return *this; + } + + // clear all stored indices + void clearStack (); +}; // end class IndexStack + +//**************************************************************** +// Inline implementation +// *************************************************************** +template <class T, int length> +inline IndexStack<T,length>::IndexStack() + : stack_ ( new StackType () ) , maxIndex_ (0) {} + +template <class T, int length> +inline IndexStack<T,length>::~IndexStack () +{ + if(stack_) + { + delete stack_; + stack_ = new StackType(); + assert(stack_); + } + + while( !fullStackList_.empty() ) + { + StackType * st = fullStackList_.top(); + if(st) delete st; + fullStackList_.pop(); + } + while( !emptyStackList_.empty() ) + { + StackType * st = emptyStackList_.top(); + if(st) delete st; + emptyStackList_.pop(); + } +} + +template <class T, int length> +inline T IndexStack<T,length>::getIndex () +{ + if((*stack_).empty()) + { + if( fullStackList_.size() <= 0) + { + return maxIndex_++; + } + else + { + emptyStackList_.push( stack_ ); + stack_ = fullStackList_.top(); + fullStackList_.pop(); + } + } + return (*stack_).pop(); +} + +template <class T, int length> +inline void IndexStack<T,length>::freeIndex ( T index ) +{ + if((*stack_).full()) + { + fullStackList_.push( stack_ ); + if(emptyStackList_.size() <= 0) + { + stack_ = new StackType (); + } + else + { + stack_ = emptyStackList_.top(); + emptyStackList_.pop(); + } + } + (*stack_).push(index); +} + +template <class T, int length> +inline void IndexStack<T,length>::test () +{ + T vec[2*length]; + + for(int i=0; i<2*length; i++) + vec[i] = getIndex(); + + for(int i=0; i<2*length; i++) + freeIndex(vec[i]); + + for(int i=0; i<2*length; i++) + vec[i] = getIndex(); + + for(int i=0; i<2*length; i++) + printf(" index [%d] = %d \n",i,vec[i]); +} + +template <class T, int length> +inline void IndexStack<T,length>::backupIndexSet ( ostream & os ) +{ + // holes are not stored at the moment + os.write( ((const char *) &maxIndex_ ), sizeof(int) ) ; + return ; +} + +template <class T, int length> +inline void IndexStack<T,length>::restoreIndexSet ( istream & is ) +{ + is.read ( ((char *) &maxIndex_), sizeof(int) ); + clearStack (); + + return ; +} + +template <class T, int length> +inline void IndexStack<T,length>::clearStack () +{ + if(stack_) + { + delete stack_; + stack_ = new StackType(); + assert(stack_); + } + + while( !fullStackList_.empty() ) + { + StackType * st = fullStackList_.top(); + if(st) delete st; + fullStackList_.pop(); + } + return; +} + + +#else + +//********************************************************************* +// +// Dummy implementation for the index stack, if index is not used +// +//********************************************************************* +template <class T> +struct DummyIndexStack +{ + //! set index as maxIndex if index is bigger than maxIndex + inline void checkAndSetMax(T index) + { + } + + //! set index as maxIndex + inline void setMaxIndex(T index) + { + } + + //! restore index from stack or create new index + T getIndex () + { + return -1; + } + + //! store index on stack + inline void freeIndex(T index) + { + } + + //! test stack funtcionality + inline void test () + { + } +}; // end class DummyIndexStack + +#endif + +#endif diff --git a/src/serial/key.h b/src/serial/key.h new file mode 100644 index 0000000000000000000000000000000000000000..de5cfcc113785a90202dafc7f0d9f178cf83c7d7 --- /dev/null +++ b/src/serial/key.h @@ -0,0 +1,75 @@ +// (c) bernhard schupp 1997 - 1998 +#ifndef KEY_H_INCLUDED +#define KEY_H_INCLUDED + +template < class A > class Key3 { + protected : + A _a, _b, _c ; + public : + inline Key3 () ; + inline Key3 (const A &,const A &,const A &) ; + inline Key3 (const Key3 < A > &) ; + inline const Key3 < A > & operator = (const Key3 < A > &) ; + inline bool operator < (const Key3 < A > &) const ; +} ; + +template < class A > class Key4 { + protected : + A _a, _b, _c, _d ; + public : + inline Key4 () ; + inline Key4 (const A &, const A &, const A &, const A &) ; + inline Key4 (const Key4 < A > &) ; + inline const Key4 < A > & operator = (const Key4 < A > &) ; + inline bool operator < (const Key4 < A > &) const ; +} ; + +template < class A > inline Key3 < A > :: Key3 () : _a (-1), _b (-1), _c (-1) { + return ; +} + +template < class A > inline Key3 < A > :: Key3 (const A & a, const A & b, const A & c) : _a (a), _b (b), _c (c) { + return ; +} + +template < class A > inline Key3 < A > :: Key3 (const Key3 < A > & k) : _a (k._a), _b (k._b), _c (k._c) { + return ; +} + +template < class A > inline const Key3 < A > & Key3 < A > :: operator = (const Key3 < A > & k) { + _a = k._a ; + _b = k._b ; + _c = k._c ; + return * this ; +} + +template < class A > inline bool Key3 < A > :: operator < (const Key3 < A > & k) const { + return _a < k._a ? true : (_a == k._a ? (_b < k._b ? true : (_b == k._b ? (_c < k._c ? true : false) : false)) : false) ; +} + +template < class A > inline Key4 < A > :: Key4 () : _a (), _b (), _c (), _d () { + return ; +} + +template < class A > inline Key4 < A > :: Key4 (const A & a, const A & b, const A & c, const A & d) : _a(a), _b (b), _c (c), _d (d) { + return ; +} + +template < class A > inline Key4 < A > :: Key4 (const Key4 < A > & k) : _a (k._a), _b (k._b), _c(k._c), _d (k._d) { + return ; +} + +template < class A > inline const Key4 < A > & Key4 < A > :: operator = (const Key4 < A > & k) { + _a = k._a ; + _b = k._b ; + _c = k._c ; + _d = k._d ; + return * this ; +} + +template < class A > inline bool Key4 < A > :: operator < (const Key4 < A > & k) const { + return _a < k._a ? true : (_a == k._a ? (_b < k._b ? true : (_b == k._b ? (_c < k._c ? true : + (_c == k._c ? (_d < k._d ? true : false) : false)) : false)) : false) ; +} + +#endif diff --git a/src/serial/lock.h b/src/serial/lock.h new file mode 100644 index 0000000000000000000000000000000000000000..4e27a2d9c6e6fd8f5b24d5df20863b9f299d0cfc --- /dev/null +++ b/src/serial/lock.h @@ -0,0 +1,58 @@ +// (c) bernhard schupp, 1997 - 1998 +#ifndef LOCK_H_INCLUDED +#define LOCK_H_INCLUDED + +#ifdef IBM_XLC + #define _ANSI_HEADER +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + +#ifdef _ANSI_HEADER + using namespace std; + #include <iostream> +#else + #include <iostream.h> +#endif + + // Einfache Klasse, die w"ahrend ihrer Lebnsdauer ein + // Lockfile mit einem vorgegebenen Namen (Pfad) h"alt. + +class FSLock { + char * _fname ; + public : + FSLock (const char * = "") ; + ~FSLock () ; +} ; + +inline FSLock :: FSLock (const char * name) : _fname (0) { + _fname = new char [strlen(name) + 100] ; + assert (_fname) ; + sprintf (_fname, "%s.lock", name) ; + FILE * fp = fopen (_fname, "w") ; + if (fp == NULL) { + delete [] _fname ; + _fname = 0 ; + cerr << "**WARNUNG (IGNORIERT) Lockfile konnte nicht erzeugt werden" << endl ; + } else { + int test = fclose (fp) ; + assert (test == 0) ; + } + return ; +} + +inline FSLock :: ~FSLock () { + if (_fname) { + int test = remove (_fname) ; + if (test != 0) { + cerr << "**WARNUNG (IGNORIERT) Lockfile konnte nicht gel\"oscht werden." << endl ; + } + delete [] _fname ; + _fname = 0 ; + } + return ; +} + +#endif // LOCK_H_INCLUDED diff --git a/src/serial/mapp_cube_3d.cc b/src/serial/mapp_cube_3d.cc new file mode 100644 index 0000000000000000000000000000000000000000..5e9446cf7bb25bdee9de09fc405477c09e871d37 --- /dev/null +++ b/src/serial/mapp_cube_3d.cc @@ -0,0 +1,123 @@ + // (c) bernhard schupp 1997 - 1998 + + // $Source$ + // $Revision$ + // $Name$ + // $State$ + +/* $Id$ + * $Log$ + * Revision 1.1 2005/03/23 14:57:55 robertk + * all files for serial version of ALU3dGrid. + * + * Revision 1.2 2004/10/25 16:38:11 robertk + * All header end with .h now. Like the original. + * + * In the .cc this changes are done. + * + * Revision 1.1 2004/10/15 09:48:37 robertk + * Inititial version. Some extenxions for Dune made. Schould be compatible + * with all other applications done so far. + * + * Revision 1.2 2001/12/10 13:57:23 wesenber + * RCS Log history and/or RCSId-variable added + * + ***/ + +#include <math.h> +#include <assert.h> +#include <stdlib.h> + +#include "mapp_cube_3d.h" + +static volatile char RCSId_mapp_cube_3d_cc [] = "$Id$" ; + +const double TrilinearMapping :: _epsilon = 1.0e-8 ; +const double QuadraturCube3Dbasis :: _p2 [4][3] = { { .816496580927726, .0, .5773502691896258}, + { .0, .816496580927726, -.5773502691896258}, + { -.816496580927726, .0, .5773502691896258}, + { .0, -.816496580927726, -.5773502691896258} } ; +const double QuadraturCube3Dbasis :: _p3 [8][3] = { { .5773502691896258, .5773502691896258, .5773502691896258}, + { -.5773502691896258, .5773502691896258, .5773502691896258}, + { .5773502691896258, -.5773502691896258, .5773502691896258}, + { -.5773502691896258, -.5773502691896258, .5773502691896258}, + { .5773502691896258, .5773502691896258, -.5773502691896258}, + { -.5773502691896258, .5773502691896258, -.5773502691896258}, + { .5773502691896258, -.5773502691896258, -.5773502691896258}, + { -.5773502691896258, -.5773502691896258, -.5773502691896258} } ; + +const double QuadraturCube2Dbasis :: _p1 [2] = { .0, .0 } ; +const double QuadraturCube2Dbasis :: _p3 [4][2] = { { .5773502691896258, .5773502691896258 }, + {-.5773502691896258, .5773502691896258 }, + { .5773502691896258, -.5773502691896258 }, + {-.5773502691896258, -.5773502691896258 } } ; + + +void TrilinearMapping :: linear(const double (&p)[3]) { + double x = .5 * (p[0] + 1.) ; + double y = .5 * (p[1] + 1.) ; + double z = .5 * (p[2] + 1.) ; + double t0 = .5 ; + double t3 = y * z ; + double t8 = x * z ; + double t13 = x * y ; + Df[2][0] = t0 * ( a[1][2] + y * a[4][2] + z * a[6][2] + t3 * a[7][2] ) ; + Df[2][1] = t0 * ( a[2][2] + x * a[4][2] + z * a[5][2] + t8 * a[7][2] ) ; + Df[1][2] = t0 * ( a[3][1] + y * a[5][1] + x * a[6][1] + t13 * a[7][1] ) ; + Df[2][2] = t0 * ( a[3][2] + y * a[5][2] + x * a[6][2] + t13 * a[7][2] ) ; + Df[0][0] = t0 * ( a[1][0] + y * a[4][0] + z * a[6][0] + t3 * a[7][0] ) ; + Df[0][2] = t0 * ( a[3][0] + y * a[5][0] + x * a[6][0] + t13 * a[7][0] ) ; + Df[1][0] = t0 * ( a[1][1] + y * a[4][1] + z * a[6][1] + t3 * a[7][1] ) ; + Df[0][1] = t0 * ( a[2][0] + x * a[4][0] + z * a[5][0] + t8 * a[7][0] ) ; + Df[1][1] = t0 * ( a[2][1] + x * a[4][1] + z * a[5][1] + t8 * a[7][1] ) ; + +} + +double TrilinearMapping :: det(const double (&point)[3]) { + // Determinante der Abbildung f:[-1,1]^3 -> Hexaeder im Punkt point. + linear (point) ; + return (DetDf = Df[0][0] * Df[1][1] * Df[2][2] - Df[0][0] * Df[1][2] * Df[2][1] - + Df[1][0] * Df[0][1] * Df[2][2] + Df[1][0] * Df[0][2] * Df[2][1] + + Df[2][0] * Df[0][1] * Df[1][2] - Df[2][0] * Df[0][2] * Df[1][1]) ; +} + +void TrilinearMapping :: inverse(const double (&p)[3]) { + // Kramer - Regel, det() rechnet Df und DetDf neu aus. + double val = 1.0 / det(p) ; + Dfi[0][0] = ( Df[1][1] * Df[2][2] - Df[1][2] * Df[2][1] ) * val ; + Dfi[0][1] = ( Df[0][2] * Df[2][1] - Df[0][1] * Df[2][2] ) * val ; + Dfi[0][2] = ( Df[0][1] * Df[1][2] - Df[0][2] * Df[1][1] ) * val ; + Dfi[1][0] = ( Df[1][2] * Df[2][0] - Df[1][0] * Df[2][2] ) * val ; + Dfi[1][1] = ( Df[0][0] * Df[2][2] - Df[0][2] * Df[2][0] ) * val ; + Dfi[1][2] = ( Df[0][2] * Df[1][0] - Df[0][0] * Df[1][2] ) * val ; + Dfi[2][0] = ( Df[1][0] * Df[2][1] - Df[1][1] * Df[2][0] ) * val ; + Dfi[2][1] = ( Df[0][1] * Df[2][0] - Df[0][0] * Df[2][1] ) * val ; + Dfi[2][2] = ( Df[0][0] * Df[1][1] - Df[0][1] * Df[1][0] ) * val ; + return ; +} + +void TrilinearMapping :: world2map (const double (&wld)[3], double (&map)[3]) { + // Newton - Iteration zum Invertieren der Abbildung f. + double err = 10.0 * _epsilon ; +#ifndef NDEBUG + int count = 0 ; +#endif + map [0] = map [1] = map [2] = .0 ; + do { + double upd [3] ; + map2world (map, upd) ; + inverse (map) ; + double u0 = upd [0] - wld [0] ; + double u1 = upd [1] - wld [1] ; + double u2 = upd [2] - wld [2] ; + double c0 = Dfi [0][0] * u0 + Dfi [0][1] * u1 + Dfi [0][2] * u2 ; + double c1 = Dfi [1][0] * u0 + Dfi [1][1] * u1 + Dfi [1][2] * u2 ; + double c2 = Dfi [2][0] * u0 + Dfi [2][1] * u1 + Dfi [2][2] * u2 ; + map [0] -= c0 ; + map [1] -= c1 ; + map [2] -= c2 ; + err = fabs (c0) + fabs (c1) + fabs (c2) ; + assert (count ++ < 1000) ; + } while (err > _epsilon) ; + return ; +} diff --git a/src/serial/mapp_cube_3d.h b/src/serial/mapp_cube_3d.h new file mode 100644 index 0000000000000000000000000000000000000000..4c08b09ea41d1e8c37ff550fe0aa5db2bb26a92b --- /dev/null +++ b/src/serial/mapp_cube_3d.h @@ -0,0 +1,385 @@ +// (c) bernhard schupp 1997 - 1998 + +#ifndef MAPP_CUBE_3D_H_INCLUDED +#define MAPP_CUBE_3D_H_INCLUDED + +#include <math.h> + +class LinearMapping ; // in mapp_tetra_3d.h + +class TrilinearMapping { + static const double _epsilon ; + const double (&p0)[3], (&p1)[3], (&p2)[3], (&p3)[3] ; + const double (&p4)[3], (&p5)[3], (&p6)[3], (&p7)[3] ; + double a [8][3] ; + double Df [3][3] ; + double Dfi [3][3] ; + double DetDf ; + void linear (const double (&)[3]) ; + void inverse (const double (&)[3]) ; + public : + inline TrilinearMapping (const double (&)[3], const double (&)[3], const double (&)[3], const double (&)[3], + const double (&)[3], const double (&)[3], const double (&)[3], const double (&)[3]) ; + inline TrilinearMapping (const TrilinearMapping &) ; + ~TrilinearMapping () {} + double det (const double (&)[3]) ; + inline void map2world (const double (&)[3], double (&)[3]) const ; + inline void map2world (const double , const double , const double , double (&)[3]) const ; + void world2map (const double (&)[3], double (&)[3]) ; +} ; + +class QuadraturCube3Dbasis { + protected : + static const double _p2 [4][3] ; + static const double _p3 [8][3] ; +} ; + +class VolumeCalc { + public : + typedef double val_t ; + typedef int arg_t ; + inline val_t operator () (const double (&)[3], const arg_t & ) ; + inline val_t operator () (const double (&)[4], const LinearMapping &, const arg_t &) ; +} ; + +class SurfaceCalc { + public : + typedef double val_t ; + typedef int arg_t ; + inline val_t operator () (const double (&)[2], const double (&)[3], const arg_t &) ; + inline val_t operator () (const double (&)[3], const double (&)[3], const arg_t &) ; +} ; + +template < class A > class QuadraturCube3D : private QuadraturCube3Dbasis { + private : + TrilinearMapping _map ; + public : + QuadraturCube3D (const TrilinearMapping & m) : _map (m) {} + ~QuadraturCube3D () {} + typedef typename A :: val_t val_t ; + typedef typename A :: arg_t arg_t ; + inline val_t integrate2 (val_t, const arg_t & = arg_t ()) ; + inline val_t integrate3 (val_t, const arg_t & = arg_t ()) ; +} ; + +template < class A > class QuadraturCube3D_1 : private QuadraturCube3Dbasis { + private : + TrilinearMapping _map ; + public : + QuadraturCube3D_1 (const TrilinearMapping & m) : _map (m) {} + ~QuadraturCube3D_1 () {} + typedef typename A :: val_t val_t ; + typedef typename A :: arg_t arg_t ; + inline val_t integrate2 (val_t, const arg_t & = arg_t ()) ; + inline val_t integrate3 (val_t, const arg_t & = arg_t ()) ; +} ; + +class BilinearSurfaceMapping { + const double (&_p0)[3], (&_p1)[3], (&_p2)[3], (&_p3)[3] ; + double _b [4][3] ; + double _n [3][3] ; + public : + inline BilinearSurfaceMapping (const double (&)[3], const double (&)[3], const double (&)[3], const double (&)[3]) ; + inline BilinearSurfaceMapping (const BilinearSurfaceMapping &) ; + ~BilinearSurfaceMapping () {} + inline void map2world(const double (&)[2], double (&)[3]) const ; + inline void map2world(double x, double y, double (&w)[3]) const ; + inline void normal(const double (&)[2], double (&)[3]) const ; +} ; + +class QuadraturCube2Dbasis { + protected : + static const double _p1 [2] ; + static const double _p3 [4][2] ; +} ; + +template < class A > class QuadraturCube2D : private QuadraturCube2Dbasis { + BilinearSurfaceMapping _map ; + public: + QuadraturCube2D(const BilinearSurfaceMapping & m) : _map (m) {} + ~QuadraturCube2D() {} + typedef typename A :: val_t val_t ; + typedef typename A :: arg_t arg_t ; + inline val_t integrate1 (val_t, const arg_t & = arg_t()) ; + inline val_t integrate3 (val_t, const arg_t & = arg_t()) ; + inline val_t integrate (val_t, const arg_t & = arg_t(), int = 1) ; +} ; + +template < class A > class QuadraturCube2D_1 : private QuadraturCube2Dbasis { + BilinearSurfaceMapping _map ; + public: + QuadraturCube2D_1(const BilinearSurfaceMapping & m) : _map (m) {} + ~QuadraturCube2D_1() {} + typedef typename A :: val_t val_t ; + typedef typename A :: arg_t arg_t ; + inline val_t integrate1 (val_t, const arg_t & = arg_t()) ; + inline val_t integrate3 (val_t, const arg_t & = arg_t()) ; + inline val_t integrate (val_t, const arg_t & = arg_t(), int = 1) ; +} ; + + // + // # # # # # # # ###### + // # ## # # # ## # # + // # # # # # # # # # ##### + // # # # # # # # # # # + // # # ## # # # ## # + // # # # ###### # # # ###### + // + + +inline TrilinearMapping :: TrilinearMapping (const double (&x0)[3], const double (&x1)[3], + const double (&x2)[3], const double (&x3)[3], const double (&x4)[3], + const double (&x5)[3], const double (&x6)[3], const double (&x7)[3]) + : p0(x0), p1(x1), p2(x2), p3(x3), p4(x4), p5(x5), p6(x6), p7(x7) { + a [0][0] = p3 [0] ; + a [0][1] = p3 [1] ; + a [0][2] = p3 [2] ; + a [1][0] = p0 [0] - p3 [0] ; + a [1][1] = p0 [1] - p3 [1] ; + a [1][2] = p0 [2] - p3 [2] ; + a [2][0] = p2 [0] - p3 [0] ; + a [2][1] = p2 [1] - p3 [1] ; + a [2][2] = p2 [2] - p3 [2] ; + a [3][0] = p7 [0] - p3 [0] ; + a [3][1] = p7 [1] - p3 [1] ; + a [3][2] = p7 [2] - p3 [2] ; + a [4][0] = p1 [0] - p2 [0] - a [1][0] ; + a [4][1] = p1 [1] - p2 [1] - a [1][1] ; + a [4][2] = p1 [2] - p2 [2] - a [1][2] ; + a [5][0] = p6 [0] - p7 [0] - a [2][0] ; + a [5][1] = p6 [1] - p7 [1] - a [2][1] ; + a [5][2] = p6 [2] - p7 [2] - a [2][2] ; + a [6][0] = p4 [0] - p0 [0] - a [3][0] ; + a [6][1] = p4 [1] - p0 [1] - a [3][1] ; + a [6][2] = p4 [2] - p0 [2] - a [3][2] ; + a [7][0] = p5 [0] - p4 [0] + p7 [0] - p6 [0] - p1 [0] + p0 [0] + a [2][0] ; + a [7][1] = p5 [1] - p4 [1] + p7 [1] - p6 [1] - p1 [1] + p0 [1] + a [2][1] ; + a [7][2] = p5 [2] - p4 [2] + p7 [2] - p6 [2] - p1 [2] + p0 [2] + a [2][2] ; + return ; +} + +inline TrilinearMapping :: TrilinearMapping (const TrilinearMapping & map) + : p0(map.p0), p1(map.p1), p2(map.p2), p3(map.p3), p4(map.p4), p5(map.p5), p6(map.p6), p7(map.p7) { + for (int i = 0 ; i < 8 ; i ++) + for (int j = 0 ; j < 3 ; j ++) + a [i][j] = map.a [i][j] ; + return ; +} + +inline void TrilinearMapping :: map2world(const double (&p)[3], double (&world)[3]) const { + double x = .5 * (p [0] + 1.) ; + double y = .5 * (p [1] + 1.) ; + double z = .5 * (p [2] + 1.) ; + double t3 = y * z ; + double t8 = x * z ; + double t13 = x * y ; + double t123 = x * t3 ; + world [0] = a [0][0] + a [1][0] * x + a [2][0] * y + a [3][0] * z + a [4][0] * t13 + a [5][0] * t3 + a [6][0] * t8 + a [7][0] * t123 ; + world [1] = a [0][1] + a [1][1] * x + a [2][1] * y + a [3][1] * z + a [4][1] * t13 + a [5][1] * t3 + a [6][1] * t8 + a [7][1] * t123 ; + world [2] = a [0][2] + a [1][2] * x + a [2][2] * y + a [3][2] * z + a [4][2] * t13 + a [5][2] * t3 + a [6][2] * t8 + a [7][2] * t123 ; + return ; +} + +inline void TrilinearMapping :: map2world(const double x1, const double x2, const double x3, double (&world)[3]) const { + double map [3] ; + map [0] = x1 ; + map [1] = x2 ; + map [2] = x3 ; + map2world (map, world) ; + return ; +} + +template < class A > inline typename QuadraturCube3D < A > :: val_t QuadraturCube3D < A > :: integrate2 (val_t base, const arg_t & x) { + + // Exakt f"ur Polynome vom Grad <= 2 + // auf dem W"urfel [-1,1]x[-1,1]x[-1,1], V([-1,1]^3) = 8.0 + + for(int i = 0 ; i < 4 ; i ++) { + val_t t = A()( _p2 [i], x) ; + base += (t *= ( _map.det ( _p2 [i]) * 2.0)) ; + } + return base ; +} + +template < class A > inline typename QuadraturCube3D < A > :: val_t QuadraturCube3D < A > :: integrate3 (val_t base, const arg_t & x) { + + // exakt f"ur Polynome vom Grad <= 3 + + for(int i = 0 ; i < 8 ; i ++ ) { + val_t t = A()( _p3 [i], x) ; + base += (t *= _map.det ( _p3 [i])) ; + } + return base ; +} + +template < class A > inline typename QuadraturCube3D_1 < A > :: val_t QuadraturCube3D_1 < A > :: integrate2 (val_t base, const arg_t & x) { + + // Exakt f"ur Polynome vom Grad <= 2 + // auf dem W"urfel [-1,1]x[-1,1]x[-1,1], V([-1,1]^3) = 8.0 + + for(int i = 0 ; i < 4 ; i ++) { + val_t t = A()( _p2 [i], _map, x) ; + base += (t *= ( _map.det ( _p2 [i]) * 2.0)) ; + } + return base ; +} + +template < class A > inline typename QuadraturCube3D_1 < A > :: val_t QuadraturCube3D_1 < A > :: integrate3 (val_t base, const arg_t & x) { + + // exakt f"ur Polynome vom Grad <= 3 + + for(int i = 0 ; i < 8 ; i ++ ) { + val_t t = A()( _p3 [i], _map, x) ; + base += (t *= _map.det ( _p3 [i])) ; + } + return base ; +} + +inline VolumeCalc :: val_t VolumeCalc :: operator () (const double (&)[3], const arg_t &) { + return 1.0 ; +} + +inline VolumeCalc :: val_t VolumeCalc :: operator () (const double (&)[4], const LinearMapping &, const arg_t &) { + return 1.0 ; +} + +inline BilinearSurfaceMapping :: BilinearSurfaceMapping (const double (&x0)[3], const double (&x1)[3], const double (&x2)[3], const double (&x3)[3]) + : _p0 (x0), _p1 (x1), _p2 (x2), _p3 (x3) { + _b [0][0] = _p0 [0] ; + _b [0][1] = _p0 [1] ; + _b [0][2] = _p0 [2] ; + _b [1][0] = _p3 [0] - _p0 [0] ; + _b [1][1] = _p3 [1] - _p0 [1] ; + _b [1][2] = _p3 [2] - _p0 [2] ; + _b [2][0] = _p1 [0] - _p0 [0] ; + _b [2][1] = _p1 [1] - _p0 [1] ; + _b [2][2] = _p1 [2] - _p0 [2] ; + _b [3][0] = _p2 [0] - _p1 [0] - _b [1][0] ; + _b [3][1] = _p2 [1] - _p1 [1] - _b [1][1] ; + _b [3][2] = _p2 [2] - _p1 [2] - _b [1][2] ; + _n [0][0] = _b [1][1] * _b [2][2] - _b [1][2] * _b [2][1] ; + _n [0][1] = _b [1][2] * _b [2][0] - _b [1][0] * _b [2][2] ; + _n [0][2] = _b [1][0] * _b [2][1] - _b [1][1] * _b [2][0] ; + _n [1][0] = _b [1][1] * _b [3][2] - _b [1][2] * _b [3][1] ; + _n [1][1] = _b [1][2] * _b [3][0] - _b [1][0] * _b [3][2] ; + _n [1][2] = _b [1][0] * _b [3][1] - _b [1][1] * _b [3][0] ; + _n [2][0] = _b [3][1] * _b [2][2] - _b [3][2] * _b [2][1] ; + _n [2][1] = _b [3][2] * _b [2][0] - _b [3][0] * _b [2][2] ; + _n [2][2] = _b [3][0] * _b [2][1] - _b [3][1] * _b [2][0] ; + return ; +} + +inline BilinearSurfaceMapping :: BilinearSurfaceMapping (const BilinearSurfaceMapping & m) + : _p0(m._p0), _p1(m._p1), _p2(m._p2), _p3(m._p3) { + {for (int i = 0 ; i < 4 ; i ++) + for (int j = 0 ; j < 3 ; j ++ ) + _b [i][j] = m._b [i][j] ; + } + {for (int i = 0 ; i < 3 ; i ++) + for (int j = 0 ; j < 3 ; j ++ ) + _n [i][j] = m._n [i][j] ; + } + return ; +} + +inline void BilinearSurfaceMapping :: map2world (const double (&map)[2], double (&wld)[3]) const { + double x = .5 * (map [0] + 1.0) ; + double y = .5 * (map [1] + 1.0) ; + double xy = x * y ; + wld[0] = _b [0][0] + x * _b [1][0] + y * _b [2][0] + xy * _b [3][0] ; + wld[1] = _b [0][1] + x * _b [1][1] + y * _b [2][1] + xy * _b [3][1] ; + wld[2] = _b [0][2] + x * _b [1][2] + y * _b [2][2] + xy * _b [3][2] ; + return ; +} + +inline void BilinearSurfaceMapping :: map2world (double x, double y, double (&w)[3]) const { + double p [2] ; + p [0] = x ; + p [1] = y ; + map2world (p,w) ; + return ; +} + +inline void BilinearSurfaceMapping :: normal (const double (&map)[2], double (&normal)[3]) const { + double x = .5 * (map [0] + 1.0) ; + double y = .5 * (map [1] + 1.0) ; + normal [0] = -( _n [0][0] + _n [1][0] * x + _n [2][0] * y) ; + normal [1] = -( _n [0][1] + _n [1][1] * x + _n [2][1] * y) ; + normal [2] = -( _n [0][2] + _n [1][2] * x + _n [2][2] * y) ; + return ; +} + +template < class A > typename QuadraturCube2D < A > :: val_t QuadraturCube2D < A > :: integrate1 (val_t base, const arg_t & x) { + double n [3] ; + _map.normal (_p1,n) ; + return base + A () (_p1,n,x) ; +} + +template < class A > typename QuadraturCube2D < A > :: val_t QuadraturCube2D < A > :: integrate3 (val_t base, const arg_t & x) { + const double quarter = 1.0/4.0 ; + val_t res ; + for(int i = 0 ; i < 4 ; i ++) { + double n [3] ; + _map.normal (_p3 [i],n) ; + val_t tmp = A () ( _p3 [i],n,x) ; + base += (tmp *= quarter) ; + } + return base ; +} + +template < class A > typename QuadraturCube2D < A > :: val_t QuadraturCube2D < A > :: integrate(val_t base, const arg_t & x, int resolution) { + double w = 1.0/double (resolution * resolution) ; + double delta = 2.0/double (resolution) ; + for(int i = 0; i < resolution; i ++) { + double p [2] ; + p [0] = delta * (double (i) + .5) - 1.0 ; + for(int j = 0; j < resolution ; j ++) { + double n [3] ; + p [1] = delta * (double (j) + .5) - 1.0 ; + _map.normal (p,n) ; + val_t tmp = A () (p,n,x) ; + tmp *= w ; + base += tmp ; + } + } + return base ; +} + +template < class A > typename QuadraturCube2D_1 < A > :: val_t QuadraturCube2D_1 < A > :: integrate1 (val_t base, const arg_t & x) { + return base + A () (_p1,_map,x) ; +} + +template < class A > typename QuadraturCube2D_1 < A > :: val_t QuadraturCube2D_1 < A > :: integrate3 (val_t base, const arg_t & x) { + const double quarter = 1.0/4.0 ; + val_t res ; + for(int i = 0 ; i < 4 ; i ++) { + val_t tmp = A () ( _p3 [i],_map,x) ; + base += (tmp *= quarter) ; + } + return base ; +} + +template < class A > typename QuadraturCube2D_1 < A > :: val_t QuadraturCube2D_1 < A > :: integrate(val_t base, const arg_t & x, int resolution) { + double w = 1.0/double (resolution * resolution) ; + double delta = 2.0/double (resolution) ; + for(int i = 0; i < resolution; i ++) { + double p [2] ; + p [0] = delta * (double (i) + .5) - 1.0 ; + for(int j = 0; j < resolution ; j ++) { + p [1] = delta * (double (j) + .5) - 1.0 ; + val_t tmp = A () (p,_map,x) ; + tmp *= w ; + base += tmp ; + } + } + return base ; +} + +inline SurfaceCalc :: val_t SurfaceCalc :: operator()(const double (&)[2], const double (&n)[3], const arg_t &) { + return sqrt (n [0] * n [0] + n [1] * n [1] + n [2] * n [2]) ; +} +inline SurfaceCalc :: val_t SurfaceCalc :: operator()(const double (&)[3], const double (&n)[3], const arg_t &) { + return sqrt (n [0] * n [0] + n [1] * n [1] + n [2] * n [2]) ; +} + +#endif // MAPP_CUBE_3D_H_INCLUDED diff --git a/src/serial/mapp_tetra_3d.cc b/src/serial/mapp_tetra_3d.cc new file mode 100644 index 0000000000000000000000000000000000000000..f0670941b57a8788ded0f2a959ec5afa3d95cbc5 --- /dev/null +++ b/src/serial/mapp_tetra_3d.cc @@ -0,0 +1,285 @@ +// (c) mario ohlberger 1998 + +// $Source$ +// $Revision$ +// $Name$ +// $State$ + +/* $Id$ + * $Log$ + * Revision 1.1 2005/03/23 14:57:55 robertk + * all files for serial version of ALU3dGrid. + * + * Revision 1.3 2004/10/25 16:38:11 robertk + * All header end with .h now. Like the original. + * + * In the .cc this changes are done. + * + * Revision 1.2 2004/10/19 13:16:04 robertk + * minor changes. + * + * Revision 1.1 2004/10/15 09:48:37 robertk + * Inititial version. Some extenxions for Dune made. Schould be compatible + * with all other applications done so far. + * + * Revision 1.2 2001/12/10 13:57:23 wesenber + * RCS Log history and/or RCSId-variable added + * + ***/ + +#include <math.h> +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <stdlib.h> + +#include "mapp_tetra_3d.h" + + +static volatile char RCSId_mapp_tetra_3d_cc [] = "$Id$" ; + +const double quadraturTetra3Dbasis :: _p1 [4] = {0.25, 0.25, 0.25, 0.25} ; + +const double quadraturTetra3Dbasis :: _w2 [4] = {.0416666666, + .0416666666, + .0416666666, + .0416666666} ; + +const double quadraturTetra3Dbasis :: _p2 [4][4] = {{.1381966, .1381966, .1381966, .5854102}, + {.1381966, .1381966, .5854102, .1381966}, + {.1381966, .5854102, .1381966, .1381966}, + {.5854102, .1381966, .1381966, .1381966}}; + +const double quadraturTetra3Dbasis :: _w7 [64] = {0.0026134590, + 0.0048996145, + 0.0048996145, + 0.0026134590, + 0.0039241268, + 0.0073568050, + 0.0073568050, + 0.0039241268, + 0.0025043094, + 0.0046949850, + 0.0046949850, + 0.0025043094, + 0.0006013729, + 0.0011274313, + 0.0011274313, + 0.0006013729, + 0.0033810896, + 0.0063387393, + 0.0063387393, + 0.0033810896, + 0.0050767294, + 0.0095176610, + 0.0095176610, + 0.0050767294, + 0.0032398804, + 0.0060740056, + 0.0060740056, + 0.0032398804, + 0.0007780094, + 0.0014585828, + 0.0014585828, + 0.0007780094, + 0.0016175887, + 0.0030325944, + 0.0030325944, + 0.0016175887, + 0.0024288207, + 0.0045534614, + 0.0045534614, + 0.0024288207, + 0.0015500311, + 0.0029059399, + 0.0029059399, + 0.0015500311, + 0.0003722171, + 0.0006978185, + 0.0006978185, + 0.0003722171, + 0.0002439854, + 0.0004574147, + 0.0004574147, + 0.0002439854, + 0.0003663458, + 0.0006868113, + 0.0006868113, + 0.0003663458, + 0.0002337955, + 0.0004383110, + 0.0004383110, + 0.0002337955, + 0.0000561425, + 0.0001052539, + 0.0001052539, + 0.0000561425} ; + +const double quadraturTetra3Dbasis :: _p7 [64][4] = {{0.0485005494,0.0543346112,0.0622918076,0.8348730318}, + {0.0485005494,0.0543346112,0.2960729005,0.6010919389}, + {0.0485005494,0.0543346112,0.6010919389,0.2960729005}, + {0.0485005494,0.0543346112,0.8348730300,0.0622918093}, + {0.0485005494,0.2634159753,0.0477749033,0.6403085720}, + {0.0485005494,0.2634159753,0.2270740686,0.4610094066}, + {0.0485005494,0.2634159753,0.4610094066,0.2270740686}, + {0.0485005494,0.2634159753,0.6403085706,0.0477749047}, + {0.0485005494,0.5552859758,0.0275098315,0.3687036433}, + {0.0485005494,0.5552859758,0.1307542021,0.2654592727}, + {0.0485005494,0.5552859758,0.2654592727,0.1307542021}, + {0.0485005494,0.5552859758,0.3687036425,0.0275098323}, + {0.0485005494,0.8185180165,0.0092331459,0.1237482881}, + {0.0485005494,0.8185180165,0.0438851337,0.0890963004}, + {0.0485005494,0.8185180165,0.0890963004,0.0438851337}, + {0.0485005494,0.8185180165,0.1237482879,0.0092331462}, + {0.2386007376,0.0434790928,0.0498465199,0.6680736497}, + {0.2386007376,0.0434790928,0.2369204606,0.4809997090}, + {0.2386007376,0.0434790928,0.4809997090,0.2369204606}, + {0.2386007376,0.0434790928,0.6680736482,0.0498465214}, + {0.2386007376,0.2107880664,0.0382299497,0.5123812464}, + {0.2386007376,0.2107880664,0.1817069135,0.3689042825}, + {0.2386007376,0.2107880664,0.3689042825,0.1817069135}, + {0.2386007376,0.2107880664,0.5123812453,0.0382299508}, + {0.2386007376,0.4443453248,0.0220136390,0.2950402987}, + {0.2386007376,0.4443453248,0.1046308045,0.2124231331}, + {0.2386007376,0.4443453248,0.2124231331,0.1046308045}, + {0.2386007376,0.4443453248,0.2950402980,0.0220136396}, + {0.2386007376,0.6549862048,0.0073884546,0.0990246030}, + {0.2386007376,0.6549862048,0.0351173176,0.0712957400}, + {0.2386007376,0.6549862048,0.0712957400,0.0351173176}, + {0.2386007376,0.6549862048,0.0990246028,0.0073884548}, + {0.5170472951,0.0275786260,0.0316174612,0.4237566177}, + {0.5170472951,0.0275786260,0.1502777622,0.3050963168}, + {0.5170472951,0.0275786260,0.3050963168,0.1502777622}, + {0.5170472951,0.0275786260,0.4237566168,0.0316174621}, + {0.5170472951,0.1337020823,0.0242491141,0.3250015085}, + {0.5170472951,0.1337020823,0.1152560157,0.2339946069}, + {0.5170472951,0.1337020823,0.2339946069,0.1152560157}, + {0.5170472951,0.1337020823,0.3250015078,0.0242491148}, + {0.5170472951,0.2818465779,0.0139631689,0.1871429581}, + {0.5170472951,0.2818465779,0.0663669280,0.1347391990}, + {0.5170472951,0.2818465779,0.1347391990,0.0663669280}, + {0.5170472951,0.2818465779,0.1871429577,0.0139631693}, + {0.5170472951,0.4154553004,0.0046864691,0.0628109354}, + {0.5170472951,0.4154553004,0.0222747832,0.0452226213}, + {0.5170472951,0.4154553004,0.0452226213,0.0222747832}, + {0.5170472951,0.4154553004,0.0628109352,0.0046864693}, + {0.7958514179,0.0116577407,0.0133649937,0.1791258477}, + {0.7958514179,0.0116577407,0.0635238021,0.1289670393}, + {0.7958514179,0.0116577407,0.1289670393,0.0635238021}, + {0.7958514179,0.0116577407,0.1791258473,0.0133649941}, + {0.7958514179,0.0565171087,0.0102503252,0.1373811482}, + {0.7958514179,0.0565171087,0.0487197855,0.0989116879}, + {0.7958514179,0.0565171087,0.0989116879,0.0487197855}, + {0.7958514179,0.0565171087,0.1373811479,0.0102503255}, + {0.7958514179,0.1191391593,0.0059023608,0.0791070620}, + {0.7958514179,0.1191391593,0.0280539153,0.0569555075}, + {0.7958514179,0.1191391593,0.0569555075,0.0280539153}, + {0.7958514179,0.1191391593,0.0791070618,0.0059023610}, + {0.7958514179,0.1756168040,0.0019810139,0.0265507642}, + {0.7958514179,0.1756168040,0.0094157572,0.0191160209}, + {0.7958514179,0.1756168040,0.0191160209,0.0094157572}, + {0.7958514179,0.1756168040,0.0265507642,0.0019810140}}; + +const double quadraturTriang2Dbasis :: _p1 [3] = { 1.0/3.0, 1.0/3.0, 1.0/3.0 } ; + +const double quadraturTriang2Dbasis :: _w3 [7] = {0.025, + 0.025, + 0.025, + 0.066666666, + 0.066666666, + 0.066666666, + 0.225} ; + +const double quadraturTriang2Dbasis :: _p3 [7][3] = {{ .0, .0, 1.}, + { .0, 1., .0}, + { 1., .0, .0}, + {.0, .5, .5 }, + { .5, .0, .5}, + { .5, .5, .0}, + {.333333333, .333333333, .333333333}} ; + +const double quadraturTriang2Dbasis :: _w5 [7] = {.11250000, + .06296959, + .06296959, + .06296959, + .06619708, + .06619708, + .06619708} ; + +const double quadraturTriang2Dbasis :: _p5 [7][3] = {{.333333333, .333333333, .333333333}, + {.101286507, .101286507, .797426985}, + {.101286507, .797426985, .101286507}, + {.797426985, .101286507, .101286507}, + {.470142064, .470142064, .059715871}, + {.470142064, .059715871, .470142064}, + {.059715871, .470142064, .470142064}} ; + +const double quadraturTriang2Dbasis :: _w7 [16] = {.023568368192, + .044185088508, + .044185088508, + .023568368192, + .035388067903, + .066344216097, + .066344216097, + .035388067903, + .022584049285, + .042339724515, + .042339724515, + .022584049285, + .005423225903, + .010167259547, + .010167259547, + .005423225903} ; + +const double quadraturTriang2Dbasis :: _p7 [16][3] = {{.057104196, .065466992, .877428812}, + {.057104196, .311164552, .631731251}, + {.057104196, .631731250, .311164553}, + {.057104196, .877428808, .065466995}, + {.276843013, .050210121, .672946865}, + {.276843013, .238648659, .484508327}, + {.276843013, .484508326, .238648660}, + {.276843013, .672946863, .050210123}, + {.583590432, .028912083, .387497484}, + {.583590432, .137419104, .278990463}, + {.583590432, .278990463, .137419105}, + {.583590432, .387497483, .028912084}, + {.860240136, .009703785, .130056079}, + {.860240136, .046122079, .093637784}, + {.860240136, .093637784, .046122079}, + {.860240136, .130056078, .009703785}} ; + + +void LinearMapping :: inverse() { + // Kramer - Regel + double val = 1.0 / det () ; + Dfi[0][0] = ( Df[1][1] * Df[2][2] - Df[1][2] * Df[2][1] ) * val ; + Dfi[0][1] = ( Df[0][2] * Df[2][1] - Df[0][1] * Df[2][2] ) * val ; + Dfi[0][2] = ( Df[0][1] * Df[1][2] - Df[0][2] * Df[1][1] ) * val ; + Dfi[1][0] = ( Df[1][2] * Df[2][0] - Df[1][0] * Df[2][2] ) * val ; + Dfi[1][1] = ( Df[0][0] * Df[2][2] - Df[0][2] * Df[2][0] ) * val ; + Dfi[1][2] = ( Df[0][2] * Df[1][0] - Df[0][0] * Df[1][2] ) * val ; + Dfi[2][0] = ( Df[1][0] * Df[2][1] - Df[1][1] * Df[2][0] ) * val ; + Dfi[2][1] = ( Df[0][1] * Df[2][0] - Df[0][0] * Df[2][1] ) * val ; + Dfi[2][2] = ( Df[0][0] * Df[1][1] - Df[0][1] * Df[1][0] ) * val ; + return ; +} + +void LinearMapping :: world2map (const double (&wld)[3], double (&map)[4]) { + map [0] = map [1] = map [2] = map [3] = .0 ; + double upd [3] ; + map2world (map, upd) ; + inverse () ; + double u0 = wld [0] - upd [0] ; + double u1 = wld [1] - upd [1] ; + double u2 = wld [2] - upd [2] ; + double c0 = Dfi [0][0] * u0 + Dfi [0][1] * u1 + Dfi [0][2] * u2 ; + double c1 = Dfi [1][0] * u0 + Dfi [1][1] * u1 + Dfi [1][2] * u2 ; + double c2 = Dfi [2][0] * u0 + Dfi [2][1] * u1 + Dfi [2][2] * u2 ; + map [0] = c0 ; + map [1] = c1 ; + map [2] = c2 ; + return ; +} + + + diff --git a/src/serial/mapp_tetra_3d.h b/src/serial/mapp_tetra_3d.h new file mode 100644 index 0000000000000000000000000000000000000000..b22d115e55f84583c0fafb961ec2fec0fa1f33ef --- /dev/null +++ b/src/serial/mapp_tetra_3d.h @@ -0,0 +1,321 @@ +// (c) mario ohlberger, 1998 +#ifndef MAPP_TETRA_3D_H_INCLUDED +#define MAPP_TETRA_3D_H_INCLUDED + +#include <math.h> +#include <stdlib.h> + +#include "gitter_sti.h" + +class LinearMapping { + private : + const double (&p0)[3], (&p1)[3], (&p2)[3], (&p3)[3]; + double a[4][3] ; + double Df[3][3] ; + double Dfi[3][3] ; + double DetDf ; + void inverse () ; + public : + LinearMapping (const double (&)[3], const double (&)[3], const double (&)[3], const double (&)[3]) ; + LinearMapping (const LinearMapping &) ; + ~LinearMapping () {} + double det () const { return DetDf ; } + void map2world (const double (&)[4], double (&)[3]) const ; + void map2world (const double , const double , const double, const double, double (&)[3]) const ; + void world2map (const double (&)[3], double (&)[4]) ; +} ; + +class quadraturTetra3Dbasis { + protected : + static const double _p1 [4] ; + static const double _w2 [4] ; + static const double _p2 [4][4] ; + static const double _w7 [64] ; + static const double _p7 [64][4] ; +} ; + +template < class A > class quadraturTetra3D : private quadraturTetra3Dbasis { + private : + LinearMapping _map ; + public : + typedef typename A :: val_t val_t; + typedef typename A :: arg_t arg_t; + quadraturTetra3D (const LinearMapping & m) : _map (m) {} + ~quadraturTetra3D () {} + inline val_t integrate1 (val_t, const arg_t & = arg_t ()) ; + inline val_t integrate2 (val_t, const arg_t & = arg_t ()) ; + inline val_t integrate7 (val_t, const arg_t & = arg_t ()) ; +} ; + +class FunctionWrapper { + public : + struct arg { + double (*f)(const double (&)[4], LinearMapping &, void *) ; + void *user ; + arg () { abort() ; } ; + arg ( double (*p)(const double (&)[4], LinearMapping &, void * ), void *a ) : f(p), user(a) {} ; + }; + typedef double val_t ; + typedef arg arg_t ; + public : + inline val_t operator () (const double (&)[4], LinearMapping &, const arg_t & ) ; +} ; + + +class LinearSurfaceMapping { + const double (&_p0)[3], (&_p1)[3], (&_p2)[3] ; + double _b [3][3] ; +protected: + double _n [3] ; +public : + inline LinearSurfaceMapping (const double (&)[3], const double (&)[3], const double (&)[3]) ; + inline LinearSurfaceMapping (const LinearSurfaceMapping &) ; + ~LinearSurfaceMapping() { } + inline void map2world(const double (&)[3], double (&)[3]) const ; + inline void map2world(double x, double y, double z, double (&w)[3]) const ; + inline void normal(double (&)[3]) const; +} ; + +class quadraturTriang2Dbasis { + protected : + static const double _p1 [3] ; + static const double _w3 [7] ; + static const double _p3 [7][3] ; + static const double _w5 [7] ; + static const double _p5 [7][3] ; + static const double _w7 [16] ; + static const double _p7 [16][3] ; +} ; + +template < class A > class quadraturTriang2D : private quadraturTriang2Dbasis { + LinearSurfaceMapping _map ; + public: + typedef typename A :: val_t val_t; + typedef typename A :: arg_t arg_t; + quadraturTriang2D(const LinearSurfaceMapping & m) : _map (m) {} + ~quadraturTriang2D() { } + inline val_t integrate1 (val_t, const arg_t & = arg_t()) ; + inline val_t integrate3 (val_t, const arg_t & = arg_t()) ; + inline val_t integrate5 (val_t, const arg_t & = arg_t()) ; + inline val_t integrate7 (val_t, const arg_t & = arg_t()) ; +} ; + +template < class A > class quadraturTriang2D_1 : private quadraturTriang2Dbasis { + LinearSurfaceMapping _map ; + public: + typedef typename A :: val_t val_t; + typedef typename A :: arg_t arg_t; + quadraturTriang2D_1(const LinearSurfaceMapping & m) : _map (m) {} + ~quadraturTriang2D_1() { } + inline val_t integrate1 (val_t, const arg_t & = arg_t()) ; + inline val_t integrate3 (val_t, const arg_t & = arg_t()) ; + inline val_t integrate5 (val_t, const arg_t & = arg_t()) ; + inline val_t integrate7 (val_t, const arg_t & = arg_t()) ; +} ; +/*********** INLINES ********************************************************/ + +inline LinearMapping :: LinearMapping(const double (&x0)[3], const double (&x1)[3], const double (&x2)[3], const double (&x3)[3]) + : p0(x0), p1(x1), p2(x2), p3(x3) { + a[0][0] = p3[0] ; + a[0][1] = p3[1] ; + a[0][2] = p3[2] ; + Df [0][0] = a[1][0] = p0[0] - p3[0] ; + Df [0][1] = a[1][1] = p0[1] - p3[1] ; + Df [0][2] = a[1][2] = p0[2] - p3[2] ; + Df [1][0] = a[2][0] = p1[0] - p3[0] ; + Df [1][1] = a[2][1] = p1[1] - p3[1] ; + Df [1][2] = a[2][2] = p1[2] - p3[2] ; + Df [2][0] = a[3][0] = p2[0] - p3[0] ; + Df [2][1] = a[3][1] = p2[1] - p3[1] ; + Df [2][2] = a[3][2] = p2[2] - p3[2] ; + DetDf = - (Df[0][0] * Df[1][1] * Df[2][2] - Df[0][0] * Df[1][2] * Df[2][1] - + Df[1][0] * Df[0][1] * Df[2][2] + Df[1][0] * Df[0][2] * Df[2][1] + + Df[2][0] * Df[0][1] * Df[1][2] - Df[2][0] * Df[0][2] * Df[1][1]) ; + return ; +} + +inline LinearMapping ::LinearMapping (const LinearMapping & map) + : p0 (map.p0), p1 (map.p1), p2 (map.p2), p3 (map.p3), DetDf (map.DetDf) { + memcpy (a, map.a, sizeof(double[4][3])) ; + memcpy (Df, map.Df, sizeof (double [3][3])) ; + return ; +} + +inline void LinearMapping :: map2world (const double (&p)[4], double (&world)[3]) const { + world[0] = a[0][0] + a[1][0] * p[0] + a[2][0] * p[1] + a[3][0] * p[2] ; + world[1] = a[0][1] + a[1][1] * p[0] + a[2][1] * p[1] + a[3][1] * p[2] ; + world[2] = a[0][2] + a[1][2] * p[0] + a[2][2] * p[1] + a[3][2] * p[2] ; + return ; +} + +inline void LinearMapping::map2world (const double x1, const double x2, const double x3, const double x4, double (&world)[3]) const { + double map [4] ; + map[0] = x1 ; + map[1] = x2 ; + map[2] = x3 ; + map[3] = x4 ; + map2world (map, world) ; + return ; +} + +template < class A > inline typename quadraturTetra3D < A > :: val_t quadraturTetra3D < A > :: integrate1 (val_t base, const arg_t & x) { + val_t t = A()( _p1 , _map, x) ; + base += (t *= ( _map.det () / 6.0)) ; + return base ; +} + +template < class A > inline typename quadraturTetra3D < A > :: val_t quadraturTetra3D < A > :: integrate2 (val_t base, const arg_t & x) { + for(int i = 0 ; i < 4 ; i ++) { + val_t t = A()( _p2 [i], _map, x) ; + base += (t *= ( _w2 [i] * _map.det ())) ; + } + return base ; +} + +template < class A > inline typename quadraturTetra3D < A > :: val_t quadraturTetra3D < A > :: integrate7 (val_t base, const arg_t & x) { + for(int i = 0 ; i < 64 ; i ++) { + val_t t = A()( _p7 [i], _map, x) ; + base += (t *= ( _w7 [i] * _map.det ())) ; + } + return base ; +} + +inline FunctionWrapper :: val_t FunctionWrapper :: operator () (const double (&coord)[4], LinearMapping &map, const arg_t &func ) { + return (*(func.f))(coord, map, func.user) ; +} + +inline LinearSurfaceMapping :: LinearSurfaceMapping (const double (&x0)[3], + const double (&x1)[3], const double (&x2)[3]) + : _p0 (x0), _p1 (x1), _p2 (x2) { + _b[0][0] = _p0[0] ; + _b[0][1] = _p0[1] ; + _b[0][2] = _p0[2] ; + _b[1][0] = _p1[0] ; + _b[1][1] = _p1[1] ; + _b[1][2] = _p1[2] ; + _b[2][0] = _p2[0] ; + _b[2][1] = _p2[1] ; + _b[2][2] = _p2[2] ; + + // Vorsicht: Im Unterschied zu der Originalversion von Mario ist + // die Dreiecksfl"achennormale hier mit -1/2 skaliert, wobei + // das Vorzeichen auf die widerspr"uchlichen Konventionen bei + // Dreiecks- und Vierecksfl"achen zur"uckgeht. + + _n[0] = -0.5 * ((_p1[1]-_p0[1]) *(_p2[2]-_p1[2]) - (_p2[1]-_p1[1]) *(_p1[2]-_p0[2])) ; + _n[1] = -0.5 * ((_p1[2]-_p0[2]) *(_p2[0]-_p1[0]) - (_p2[2]-_p1[2]) *(_p1[0]-_p0[0])) ; + _n[2] = -0.5 * ((_p1[0]-_p0[0]) *(_p2[1]-_p1[1]) - (_p2[0]-_p1[0]) *(_p1[1]-_p0[1])) ; + + return ; +} + +inline LinearSurfaceMapping :: LinearSurfaceMapping (const LinearSurfaceMapping & m) : _p0(m._p0), _p1(m._p1), _p2(m._p2) { + memcpy(_b, m._b, sizeof(double [3][3])) ; + memcpy(_n, m._n, sizeof(double [3])) ; + return ; +} + +inline void LinearSurfaceMapping :: map2world (const double (&map)[3], double (&wld)[3]) const { + double x = map [0] ; + double y = map [1] ; + double z = map [2] ; + wld[0] = x * _b[0][0] + y * _b[1][0] + z * _b[2][0] ; + wld[1] = x * _b[0][1] + y * _b[1][1] + z * _b[2][1] ; + wld[2] = x * _b[0][2] + y * _b[1][2] + z * _b[2][2] ; + return ; +} + +inline void LinearSurfaceMapping :: map2world(double x, double y, double z, double (&w)[3]) const { + double p [3] ; + p[0] = x ; + p[1] = y ; + p[2] = z ; + map2world (p,w) ; + return ; +} + +inline void LinearSurfaceMapping :: normal (double (&normal)[3]) const { + normal[0] = _n[0] ; + normal[1] = _n[1] ; + normal[2] = _n[2] ; + return ; +} + +template < class A > inline typename quadraturTriang2D < A > :: val_t +quadraturTriang2D < A > :: integrate1 (val_t base, const arg_t & x) { + double n [3] ; + _map.normal (n) ; + return base + A ()(_p1, n, x) ; +} + +template < class A > inline typename quadraturTriang2D < A > :: val_t +quadraturTriang2D < A > :: integrate3 (val_t base, const arg_t & x) { + double n [3] ; + _map.normal (n) ; + for (int i = 0 ; i < 7 ; i++) { + val_t t = A ()(_p3 [i], n, x) ; + base += (t *= _w3 [i]) ; + } + return base ; +} + +template < class A > inline typename quadraturTriang2D < A > :: val_t +quadraturTriang2D < A > :: integrate5 (val_t base, const arg_t & x) { + double n [3] ; + _map.normal (n) ; + for (int i = 0 ; i < 7 ; i++) { + val_t t = A ()(_p5 [i], n, x) ; + base += (t *= _w5 [i]) ; + } + return base ; +} + +template < class A > inline typename quadraturTriang2D < A > :: val_t +quadraturTriang2D < A > :: integrate7 (val_t base, const arg_t & x) { + double n [3] ; + _map.normal (n) ; + for (int i = 0 ; i < 16 ; i++) { + val_t t = A ()(_p7 [i], n, x) ; + base += (t *= _w7 [i]) ; + } + return base ; +} + +template < class A > inline typename quadraturTriang2D_1 < A > :: val_t +quadraturTriang2D_1 < A > :: integrate1 (val_t base, const arg_t & x) { + double n [3] ; + return base + A ()(_p1, _map, x) ; +} + +template < class A > inline typename quadraturTriang2D_1 < A > :: val_t +quadraturTriang2D_1 < A > :: integrate3 (val_t base, const arg_t & x) { + double n [3] ; + for (int i = 0 ; i < 7 ; i++) { + val_t t = A ()(_p3 [i], _map, x) ; + base += (t *= _w3 [i]) ; + } + return base ; +} + +template < class A > inline typename quadraturTriang2D_1 < A > :: val_t +quadraturTriang2D_1 < A > :: integrate5 (val_t base, const arg_t & x) { + double n [3] ; + for (int i = 0 ; i < 7 ; i++) { + val_t t = A ()(_p5 [i], _map, x) ; + base += (t *= _w5 [i]) ; + } + return base ; +} + +template < class A > inline typename quadraturTriang2D_1 < A > :: val_t +quadraturTriang2D_1 < A > :: integrate7 (val_t base, const arg_t & x) { + double n [3] ; + for (int i = 0 ; i < 16 ; i++) { + val_t t = A ()(_p7 [i], _map, x) ; + base += (t *= _w7 [i]) ; + } + return base ; +} +#include "mapp_tetra_3d_ext.h" + +#endif // MAPP_TETRA_3D_H_INCLUDED diff --git a/src/serial/mapp_tetra_3d_ext.h b/src/serial/mapp_tetra_3d_ext.h new file mode 100644 index 0000000000000000000000000000000000000000..f952d5da25f64d8dd64e0a9d8020076c00affc18 --- /dev/null +++ b/src/serial/mapp_tetra_3d_ext.h @@ -0,0 +1,29 @@ +#ifndef __MAPP_TETRA_3D_EXT_HH__ +#define __MAPP_TETRA_3D_EXT_HH__ + +// BSGridVecType is defined in BSGrid interface to dune or in gitter_sti.hh +class BSGridLinearSurfaceMapping : public LinearSurfaceMapping +{ +public: + inline BSGridLinearSurfaceMapping + (const double (&)[3], const double (&)[3], const double (&)[3]); + + // same as method normal of LinearSurfaceMapping, just for Dune Vecs + inline void normal(double * normal) const; +}; + + +inline BSGridLinearSurfaceMapping :: BSGridLinearSurfaceMapping (const double (&x0)[3], +const double (&x1)[3], const double (&x2)[3]) + : LinearSurfaceMapping (x0,x1,x2) +{ +} + +inline void BSGridLinearSurfaceMapping :: normal (double * normal) const +{ + normal[0] = this->_n[0]; + normal[1] = this->_n[1]; + normal[2] = this->_n[2]; + return ; +} +#endif diff --git a/src/serial/myalloc.cc b/src/serial/myalloc.cc new file mode 100644 index 0000000000000000000000000000000000000000..f07ef5d90e29af5fc758afcaa2da64bc5d99e04f --- /dev/null +++ b/src/serial/myalloc.cc @@ -0,0 +1,177 @@ +// (c) christian badura, 1998 + + // $Source$ + // $Revision$ + // $Name$ + // $State$ + + // Auf UNIX zum Raufsetzen des Speicherlimits (Breakvalue) + +/* $Id$ + * $Log$ + * Revision 1.1 2005/03/23 14:57:56 robertk + * all files for serial version of ALU3dGrid. + * + * Revision 1.3 2004/12/20 21:35:43 robertk + * gcc compile. + * + * Revision 1.2 2004/10/25 16:38:12 robertk + * All header end with .h now. Like the original. + * + * In the .cc this changes are done. + * + * Revision 1.1 2004/10/15 09:48:38 robertk + * Inititial version. Some extenxions for Dune made. Schould be compatible + * with all other applications done so far. + * + * Revision 1.4 2002/04/19 15:36:07 wesenber + * modifications required for IBM VisualAge C++ Version 5.0 + * + * Revision 1.3 2001/12/10 13:57:23 wesenber + * RCS Log history and/or RCSId-variable added + * + ***/ + +#ifdef IBM_XLC + #define _ANSI_HEADER +#endif + +#include <ulimit.h> + +#include <stdio.h> +#include <malloc.h> +#include <stdlib.h> +#include <assert.h> + +#ifdef _ANSI_HEADER + using namespace std; + #include <iostream> + #include <functional> + #include <deque> + #include <stack> + #include <map> +#else + #include <iostream.h> + #include <function.h> + #include <deque.h> + #include <stack.h> + #include <map.h> +#endif + +#include "myalloc.h" + +static volatile char RCSId_myalloc_cc [] = "$Id$" ; + +const long MyAlloc :: MAX_HOLD_ADD = 400000 ; // max MAX_HOLD_ADD Objekte werden gespeichert +const double MyAlloc :: MAX_HOLD_MULT = 1.3 ; // max das MAX_HOLD_MULT-fache der momentan + // aktiven Objekte werden gespeichert +long MyAlloc :: _init ; + +struct AllocEntry { + + // N verfolgt die Anzahl der angelegten Objekte der entsprechenden + // Gr"osse, die in Gebrauch sind, auf dem Stack liegen die Objekte, + // f"ur die delete aufgerufen wurde, die aber nicht an free () zur"uck- + // gegeben werden um Fragmentierung zu vermeiden. + + long N ; + +#ifdef IBM_XLC + // stack < deque < void * > > S ; + // ### Goettingen ### + stack <void * > S ; +#else + // Neuerung in der ANSI Standardbibliothek: + // stack < dequeue < void * > > -> stack <void * > + // dequeue < void * > ist dann default-argument. + + stack <void * > S ; +#endif + AllocEntry () : N (0), S () {} + ~AllocEntry () { + while (!S.empty ()) { + free (S.top ()) ; + S.pop () ; + } + return ; + } +} ; + +static map < size_t, AllocEntry, less < size_t > > * freeStore = 0 ; + +void * MyAlloc :: operator new (size_t s) throw (OutOfMemoryException) { + assert(s > 0); + //if (s == 0) { + // return 0 ; + //} else + { + AllocEntry & fs ((*freeStore) [s]) ; + ++ fs.N ; + if (fs.S.empty ()) { + void * p = malloc (s) ; + if (p == NULL) { + perror ("**FEHLER (FATAL) in MyAlloc :: operator new ()") ; + cerr << "**INFO MyAlloc :: operator new (" << s << "): Der gesamte belegte Speicherbereich war " +#ifdef IBM_XLC + << (mallinfo ().arena /1024) +#else + << "[FEHLER: mallinfo() nicht verfuegbar] " +#endif + << "kb als das Programm out-of-memory lief." << endl ; + throw OutOfMemoryException () ; + } + return p ; + } else { + void * p = fs.S.top () ; + fs.S.pop () ; + return p ; + } + } +} + +void MyAlloc :: operator delete (void *ptr, size_t s) { + AllocEntry & fs ((*freeStore) [s]) ; + assert (fs.N > 0) ; + --fs.N ; + fs.S.push (ptr) ; + if (fs.S.size () >= (unsigned) MAX_HOLD_ADD + && double (fs.S.size()) >= MAX_HOLD_MULT * double (fs.N)) { + assert (!fs.S.empty()) ; + free (fs.S.top ()) ; + fs.S.pop() ; + } + return ; +} + +MyAlloc :: Initializer :: Initializer () { + if (0 == MyAlloc :: _init ++) { +#ifdef IBM_XLC + { + // Auf der SP sollte immer das eingestellte Limit von 143 MB umgangen werden. + // Der Knoten hat 512 MB, und wird exklusiv benutzt - warum also sparsam sein. + // Die Programme m"ussen aber auch mit -bmaxdata:#bytes gelinkt werden, um den + // Platz adressieren zu k"onnen. + + long test = ulimit(UL_GETMAXBRK) ; + if (test == -1) { + cerr << "**WARNUNG (IGNORIERT) Hochsetzen des Limits f\"ur den Breakvalue hat nicht geklappt. In " << __FILE__ " Zeile " << __LINE__ << endl ; + } else { + unsigned long limit = ulimit (GET_DATALIM) ; + limit /= 0x00100000 ; + cout << "**INFO MyAlloc :: Initializer :: Initializer () Neues Limit f\"ur den Breakvalue : " << limit << " MBytes." << endl ; + } + } +#endif + freeStore = new map < size_t, AllocEntry, less < size_t > > ; + assert (freeStore) ; + } + return ; +} + +MyAlloc :: Initializer :: ~Initializer () { + if (0 == -- MyAlloc :: _init) { + delete freeStore ; + freeStore = 0 ; + } + return ; +} diff --git a/src/serial/myalloc.h b/src/serial/myalloc.h new file mode 100644 index 0000000000000000000000000000000000000000..3211515a29054de584af43cc94294f49067a3676 --- /dev/null +++ b/src/serial/myalloc.h @@ -0,0 +1,45 @@ +// (c) christian badura 1998 +// -*- C++ -*- + +#ifndef MYALLOC_H_INCLUDED +#define MYALLOC_H_INCLUDED + +#ifdef IBM_XLC + #define _ANSI_HEADER +#endif + +#ifdef _ANSI_HEADER + using namespace std; + #include <memory> // Def. von size_t, malloc (), free () +#else + #include <memory.h> // Def. von size_t, malloc (), free () +#endif + +class MyAlloc { + static const long MAX_HOLD_ADD ; + static const double MAX_HOLD_MULT ; + static long _init ; + public : + class Initializer { + // initializer versucht, die statischen Objekte der Speicherverwaltung + // vor allem anderen zu initialisieren, damit keine Fehler auftreten, + // falls statische Objekte irgendwo Instanzen mit MyAlloc als Basis- + // klasse angelegen. + public : + Initializer () ; + ~Initializer () ; + } ; + class OutOfMemoryException { }; + friend class Initializer; + protected : + MyAlloc () {} + ~MyAlloc () {} + public : + void * operator new (size_t) throw (OutOfMemoryException) ; + void operator delete (void *,size_t) ; +} ; + +static MyAlloc :: Initializer allocatorInitializer ; + +#endif // MYALLOC_H_INCLUDED + diff --git a/src/serial/parallel.h b/src/serial/parallel.h new file mode 100644 index 0000000000000000000000000000000000000000..5810f62460fe3547804b5bf87afe2f2ceab1b28d --- /dev/null +++ b/src/serial/parallel.h @@ -0,0 +1,114 @@ +// (c) bernhard schupp, 1997 - 1998 +// +#ifndef PARALLEL_H_INCLUDED +#define PARALLEL_H_INCLUDED + +typedef class VertexPllXIF VertexPllXIF_t ; +typedef class EdgePllXIF EdgePllXIF_t ; +typedef class FacePllXIF FacePllXIF_t ; +typedef class ElementPllXIF ElementPllXIF_t ; + +class Parallel { + public : + + class AccessPllException {} ; + + class VertexIF { + public : + typedef class Key1SLZ identifier_t ; + inline virtual VertexPllXIF_t & accessPllX () throw (AccessPllException) ; + inline virtual const VertexPllXIF_t & accessPllX () const throw (AccessPllException) ; + inline virtual void detachPllXFromMacro () throw (AccessPllException) ; + } ; + class EdgeIF { + public : + typedef class Key2SLZ identifier_t ; + inline virtual EdgePllXIF_t & accessPllX () throw (AccessPllException) ; + inline virtual const EdgePllXIF_t & accessPllX () const throw (AccessPllException) ; + inline virtual void detachPllXFromMacro () throw (AccessPllException) ; + } ; + class FaceIF { + public : + typedef class Key3SLZ identifier_t ; + inline virtual FacePllXIF_t & accessPllX () throw (AccessPllException) ; + inline virtual const FacePllXIF_t & accessPllX () const throw (AccessPllException) ; + inline virtual void detachPllXFromMacro () throw (AccessPllException) ; + } ; + class ElementIF { + public : + inline virtual ElementPllXIF_t & accessPllX () throw (AccessPllException) ; + inline virtual const ElementPllXIF_t & accessPllX () const throw (AccessPllException) ; + inline virtual void detachPllXFromMacro () throw (AccessPllException) ; + } ; +} ; + + // + // # # # # # # # ###### + // # ## # # # ## # # + // # # # # # # # # # ##### + // # # # # # # # # # # + // # # ## # # # ## # + // # # # ###### # # # ###### + // + + +inline VertexPllXIF_t & Parallel :: VertexIF :: accessPllX () throw (AccessPllException) { + assert ((abort (), (cerr << " FEHLER in " << __FILE__ << " " << __LINE__ << endl))) ; + throw AccessPllException () ; +} + +inline const VertexPllXIF_t & Parallel :: VertexIF :: accessPllX () const throw (AccessPllException) { + assert ((abort (), (cerr << " FEHLER in " << __FILE__ << " " << __LINE__ << endl))) ; + throw AccessPllException () ; +} + +inline void Parallel :: VertexIF :: detachPllXFromMacro () throw (AccessPllException) { + assert ((abort (), (cerr << " FEHLER in " << __FILE__ << " " << __LINE__ << endl))) ; + throw AccessPllException () ; +} + +inline EdgePllXIF_t & Parallel :: EdgeIF :: accessPllX () throw (AccessPllException) { + assert ((abort (), (cerr << " FEHLER in " << __FILE__ << " " << __LINE__ << endl))) ; + throw AccessPllException () ; +} + +inline const EdgePllXIF_t & Parallel :: EdgeIF :: accessPllX () const throw (AccessPllException) { + assert ((abort (), (cerr << " FEHLER in " << __FILE__ << " " << __LINE__ << endl))) ; + throw AccessPllException () ; +} + +inline void Parallel :: EdgeIF :: detachPllXFromMacro () throw (AccessPllException) { + assert ((abort (), (cerr << " FEHLER in " << __FILE__ << " " << __LINE__ << endl))) ; + throw AccessPllException () ; +} + +inline FacePllXIF_t & Parallel :: FaceIF :: accessPllX () throw (AccessPllException) { + assert ((abort (), (cerr << " FEHLER in " << __FILE__ << " " << __LINE__ << endl))) ; + throw AccessPllException () ; +} + +inline const FacePllXIF_t & Parallel :: FaceIF :: accessPllX () const throw (AccessPllException) { + assert ((abort (), (cerr << " FEHLER in " << __FILE__ << " " << __LINE__ << endl))) ; + throw AccessPllException () ; +} + +inline void Parallel :: FaceIF :: detachPllXFromMacro () throw (AccessPllException) { + assert ((abort (), (cerr << " FEHLER in " << __FILE__ << " " << __LINE__ << endl))) ; + throw AccessPllException () ; +} + +inline ElementPllXIF_t & Parallel :: ElementIF :: accessPllX () throw (AccessPllException) { + assert ((abort (), (cerr << " FEHLER in " << __FILE__ << " " << __LINE__ << endl))) ; + throw AccessPllException () ; +} + +inline const ElementPllXIF_t & Parallel :: ElementIF :: accessPllX () const throw (AccessPllException) { + assert ((abort (), (cerr << " FEHLER in " << __FILE__ << " " << __LINE__ << endl))) ; + throw AccessPllException () ; +} + +inline void Parallel :: ElementIF :: detachPllXFromMacro () throw (AccessPllException) { + assert ((abort (), (cerr << " FEHLER in " << __FILE__ << " " << __LINE__ << endl))) ; + throw AccessPllException () ; +} +#endif diff --git a/src/serial/serialize.h b/src/serial/serialize.h new file mode 100644 index 0000000000000000000000000000000000000000..e1ef7f03f26727a5f104dec85ab036e77ff9c10d --- /dev/null +++ b/src/serial/serialize.h @@ -0,0 +1,179 @@ +// (c) bernhard schupp, 1997 - 1998 + +#ifndef SERIALIZE_H_INCLUDED +#define SERIALIZE_H_INCLUDED + +#ifdef IBM_XLC + #define _ANSI_HEADER +#endif + +#include <stdio.h> +#include <stdlib.h> + +#ifdef _ANSI_HEADER + using namespace std; + #include <iomanip> + #include <strstream> + #include <utility> +#else + #include <iomanip.h> + #include <strstream.h> + #include <pair.h> +#endif + + // Die 'Serializable' Schnittstelle soll eine Objektserialisation er- + // m"oglichen, die etwas der in java vorgeschlagenen Situation "ahnelt, + // allerdings aus technischen Gr"unden erheblich primitiver ist. + +class ObjectStream; + +class Serializable { + friend class ObjectStream ; + virtual bool readObject (ObjectStream &) = 0 ; + virtual void writeObject (ObjectStream &) const = 0 ; +} ; + + // 'ObjectStream' ist bereits die volle Implementierung eines einfachen + // Objektstrommodells auf der Basis der Bibliotheksfunktionen f"ur + // den Stringstream (strstream). Die Implemetierung ist eher im Sinne + // eines rohen Datenformats mit einigen Testm"oglichkeiten zu sehen. + +class ObjectStream { + + // 1/4 Megabyte als Chunksize, und 16 MegaByte als oberes Limit, + // wobei dieses noch nicht getestet wird. + + enum { BufChunk = 0x40000, MemLimit = 0x1000000 } ; + char * _buf ; + int _rb, _wb, _len ; +// dequeue < pair < char *, int > > dqe ; + public : + class EOFException {} ; + class OutOfMemoryException {} ; + inline ObjectStream () throw (OutOfMemoryException) ; + inline ~ObjectStream () ; + inline ObjectStream (const ObjectStream &) throw (OutOfMemoryException) ; + inline const ObjectStream & operator = (const ObjectStream &) throw (OutOfMemoryException); + inline void writeObject (const Serializable &) throw (OutOfMemoryException) ; + inline void readObject (Serializable &) throw (EOFException) ; + inline void writeObject (double) throw (OutOfMemoryException) ; + inline void readObject (double &) throw (EOFException) ; + inline void writeObject (int) throw (OutOfMemoryException) ; + inline void readObject (int &) throw (EOFException) ; + friend class MpAccessMPI ; +} ; + + + // + // # # # # # # # ###### + // # ## # # # ## # # + // # # # # # # # # # ##### + // # # # # # # # # # # + // # # ## # # # ## # + // # # # ###### # # # ###### + // + +inline void ObjectStream :: readObject (Serializable & oi) throw (EOFException) { + oi.readObject (*this) ; + return ; ; +} + +inline void ObjectStream :: writeObject (const Serializable & oi) throw (OutOfMemoryException) { + oi.writeObject (*this) ; + return ; +} + +inline void ObjectStream :: readObject (double & a) throw (EOFException) { + int ap = sizeof (a) * ((_rb + sizeof (a) - 1)/sizeof (a)) ; + _rb = ap + sizeof (a) ; + if (_rb > _wb) throw EOFException () ; + a = (double &) _buf [ap] ; + return ; +} + +inline void ObjectStream :: writeObject (double a) throw (OutOfMemoryException) { + register int ap = sizeof (a) * ((_wb + sizeof (a) - 1)/sizeof (a)) ; + _wb = ap + sizeof (a) ; + if (_wb > _len) { + _buf = (char *) realloc (_buf, (_len += BufChunk)) ; + if (!_buf) { + perror ("**AUSNAHME in ObjectStream :: writeObject (double) ") ; + throw OutOfMemoryException () ; + } + } + (double &) _buf [ap] = a ; + return ; +} + +inline void ObjectStream :: readObject (int & i) throw (EOFException) { + int ap = sizeof (i) * ((_rb + sizeof (i) - 1)/sizeof (i)) ; + _rb = ap + sizeof (i) ; + if (_rb > _wb) throw EOFException () ; + i = (int &) _buf [ap] ; + return ; +} + +inline void ObjectStream :: writeObject (int i) throw (OutOfMemoryException) { + register int ap = sizeof (i) * ((_wb + sizeof (i) - 1)/sizeof (i)) ; + _wb = ap + sizeof (i) ; + if (_wb > _len) { + _buf = (char *) realloc (_buf, (_len += BufChunk)) ; + if (!_buf) { + perror ("**AUSNAHME in ObjectStream :: writeObject (int) ") ; + throw OutOfMemoryException () ; + } + } + (int &) _buf [ap] = i ; + return ; +} + +inline ObjectStream :: ObjectStream () throw (OutOfMemoryException) + : _buf (0), _rb (0), _wb (0), _len (BufChunk) { + _buf = (char *) malloc (BufChunk) ; + if (!_buf) { + perror ("**AUSNAHME in ObjectStream :: ObjectStream ()") ; + throw OutOfMemoryException () ; + } + return ; +} + +inline ObjectStream :: ~ObjectStream () { + free (_buf) ; + return ; +} + +inline ObjectStream :: ObjectStream (const ObjectStream & os) throw (OutOfMemoryException) + : _buf (0), _rb (os._rb), _wb (os._wb), _len (os._len) { + if (_len) { + _buf = (char *) malloc (_len) ; + if (_buf) { + memcpy (_buf, os._buf, _len) ; + } else { + perror (" in ObjectStream (const ObjectStream &) ") ; + throw OutOfMemoryException () ; + } + } + return ; +} + +inline const ObjectStream & ObjectStream :: operator = (const ObjectStream & os) throw (OutOfMemoryException) { + if (&os != this) { + _rb = os._rb ; + _wb = os._wb ; + _len = os._len ; + if (_len) { + _buf = (char *) realloc (_buf, _len) ; + if (_buf) { + memcpy (_buf, os._buf, _len) ; + } else { + perror (" in ObjectStream :: operator = (const ObjectStream &) ") ; + throw OutOfMemoryException () ; + } + } else { + free (_buf) ; + _buf = 0 ; + } + } + return os ; +} +#endif // SERIALIZE_H_INCLUDED diff --git a/src/serial/walk.h b/src/serial/walk.h new file mode 100644 index 0000000000000000000000000000000000000000..3a387fc09dbe62b6486a7c2b55cad566a63d27f3 --- /dev/null +++ b/src/serial/walk.h @@ -0,0 +1,549 @@ +// (c) bernhard schupp 1997 - 1998 +#ifndef WALK_H_INCLUDED +#define WALK_H_INCLUDED + +#ifdef IBM_XLC + #define _ANSI_HEADER +#endif + +#include <assert.h> + +#ifdef _ANSI_HEADER + using namespace std; + #include <functional> + #include <list> + #include <vector> +#else + #include <function.h> + #include <list.h> + #include <vector.h> +#endif + +#include "myalloc.h" +#include "gitter_sti.h" + +template < class A > class is_def_true { + public : + typedef A val_t ; + int operator () (const A * x) const { return 1 ; } + int operator () (const A & x) const { return 1 ; } +} ; + +template < class A > class is_leaf { + public : + typedef A val_t ; + int operator () (const A * x) const { return x->leaf() ; } + int operator () (const A & x) const { return x.leaf () ; } +} ; + +template < class A > class is_not_leaf { + public : + typedef A val_t ; + int operator () (const A * x) const { return ! x->leaf () ; } + int operator () (const A & x) const { return ! x.leaf () ; } +} ; + +template < class A > class any_has_level { + int lvl ; + public : + any_has_level (int i = 0) : lvl (i) { } + int operator () (const A * x) const { return x->level () == lvl ? 1 : 0 ; } + int operator () (const A & x) const { return x.level () == lvl ? 1 : 0 ; } +} ; + +template < class A > class leaf_has_level { + int lvl ; + public : + leaf_has_level (int i = 0) : lvl (i) { } + int operator () (const A * x) const { return x->level () == lvl ? x->leaf () : 0 ; } + int operator () (const A & x) const { return x.level () == lvl ? x.leaf () : 0 ; } +} ; + +template < class A > class has_int_vertex { + public : + int operator () (const A * x) const { return x->innerVertex () ? 1 : 0 ; } + int operator () (const A & x) const { return x.innerVertex () ? 1 : 0 ; } +} ; + +template < class A > class has_int_edge { + public : + int operator () (const A * x) const { return x->innerHedge () ? 1 : 0 ; } + int operator () (const A & x) const { return x.innerHedge () ? 1 : 0 ; } +} ; + +template < class A > class has_int_face { + public : + int operator () (const A * x) const { return x->innerHface () ? 1 : 0 ; } + int operator () (const A & x) const { return x.innerHface () ? 1 : 0 ; } +} ; + +template < class A > class unary_not { + public : + typedef typename A :: val_t val_t ; + int operator () (val_t * x) const { return ! A()(x) ; } + int operator () (val_t & x) const { return ! A()(x) ; } +} ; + +template < class A > class childs_are_leafs { + public : + int operator () (const A *) const ; + int operator () (const A &) const ; +} ; + +template < class A > class ListIterator : public IteratorSTI < A >, public MyAlloc { + list < A * > & _list ; + typename list < A * > :: iterator _curr ; + public : + inline ListIterator (const ListIterator < A > &) ; + inline ListIterator (const list < A * > &) ; + inline ~ListIterator () ; + inline void first () ; + inline void next () ; + inline int done () const ; + inline int size () ; + inline A & item () const ; +} ; + +template < class A, class B > class TreeIterator : public IteratorSTI < A >, public MyAlloc { + public : + typedef B comp_t ; + typedef A val_t ; + inline TreeIterator (A &, const B & = B()) ; + inline TreeIterator (A *, const B & = B()) ; + inline TreeIterator (const TreeIterator < A, B > &) ; + inline ~TreeIterator () ; + inline const TreeIterator < A, B > & operator = (const TreeIterator < A, B > &) ; + inline void first () ; + inline void next () ; + inline int size () ; + inline int done () const ; + inline val_t & item () const ; + private : + enum { max = 100 } ; + A * _seed ; + A * _stack [max] ; + B _cmp ; + int _pos ; + int _cnt ; + inline int pushdown () ; + inline int pullup () ; + inline int count () ; +} ; + +template < class A, class B > class Wrapper : public IteratorSTI < typename B :: val_t >, public MyAlloc { + A _walk ; + public : + typedef typename B :: val_t val_t ; + inline Wrapper (const A &) ; + inline Wrapper (const Wrapper < A, B > &) ; + inline ~Wrapper () ; + inline void first () ; + inline void next () ; + inline int size () ; + inline int done () const ; + inline val_t & item () const ; +} ; + +template < class A, class B, class C > class AlignIterator : public IteratorSTI < C >, public MyAlloc { + A _walk1 ; + B _walk2 ; + int _curr, _cnt ; + public : + inline AlignIterator (const A &, const B &) ; + inline AlignIterator (const AlignIterator < A, B, C > &) ; + inline ~AlignIterator () ; + inline void first() ; + inline void next () ; + inline int size () ; + inline int done () const ; + inline C & item () const ; +} ; + +template < class A > class VectorAlign : public IteratorSTI < A >, public MyAlloc { + typedef IteratorSTI < A > * pointer_t ; + vector < pointer_t > _it ; + typename vector < pointer_t > :: const_iterator _curr, _ahead ; + int _cnt ; + VectorAlign (const VectorAlign < A > &) ; + public : + inline VectorAlign (const vector < pointer_t > &) ; + inline ~VectorAlign () ; + inline void first () ; + inline void next () ; + inline int size () ; + inline int done () const ; + inline A & item () const ; +} ; + +template < class A, class B > class Insert : public IteratorSTI < typename B :: val_t >, public MyAlloc { + public : + typedef typename B :: comp_t comp_t ; + typedef typename B :: val_t val_t ; + Insert (const A &, comp_t = comp_t ()) ; + inline Insert (const Insert < A, B > &) ; + ~Insert () ; + void first () ; + void next () ; + int done () const ; + int size () ; + val_t & item () const ; + private : + A _outer ; + B * _inner ; + int _cnt ; + comp_t _cmp ; +} ; + + + // + // # # # # # # # ###### + // # ## # # # ## # # + // # # # # # # # # # ##### + // # # # # # # # # # # + // # # ## # # # ## # + // # # # ###### # # # ###### + // + + +template < class A > int childs_are_leafs < A > :: operator () (const A * x) const { + if (x->leaf ()) { + return 0 ; + } else { + for (const A * y = x->down () ; y ; y = y->next ()) if (!y->leaf ()) return 0 ; + } + return 1 ; +} + +template < class A > int childs_are_leafs < A > :: operator () (const A & x) const { + if (x.leaf ()) { + return 0 ; + } else { + for (const A * y = x.down () ; y ; y = y->next ()) if (!y->leaf ()) return 0 ; + } + return 1 ; +} + +template < class A > inline ListIterator < A > :: ListIterator (const list < A * > & l) : _list ((list < A * > &)l), _curr () { + return ; +} + +template < class A > inline ListIterator < A > :: ListIterator (const ListIterator < A > & w) : _list (w._list), _curr (w._curr) { + return ; +} + +template < class A > inline ListIterator < A > :: ~ListIterator () { + return ; +} + +template < class A > inline void ListIterator < A > :: first () { + _curr = _list.begin () ; + return ; +} + +template < class A > inline void ListIterator < A > :: next () { + _curr ++ ; + return ; +} + +template < class A > inline int ListIterator < A > :: done () const { + return _curr == _list.end () ; +} + +template < class A > inline int ListIterator < A > :: size () { + return _list.size () ; +} + +template < class A > inline A & ListIterator < A > :: item () const { + return ** _curr ; +} + +template < class A, class B > inline int TreeIterator < A, B > :: pushdown () { + A * e = _stack [_pos] ; + for( ; e ? ! _cmp (e) : 0 ; _stack [ ++ _pos] = (e = e->down ())) ; + return e ? 1 : (-- _pos, 0) ; +} + +template < class A, class B > inline int TreeIterator < A, B > :: pullup () { + for( ; _pos >= 0 ; _pos -- ) if (_stack [_pos] = _stack [_pos]->next ()) break ; + return _pos < 0 ? 0 : 1 ; +} + +template < class A, class B > inline int TreeIterator < A, B > :: count () { + int i = 0 ; + for (first () ; ! done () ; next ()) i ++ ; + return i ; +} + +template < class A, class B > inline TreeIterator < A, B > :: TreeIterator (A & s, const B & c) + : _seed (& s), _cmp (c), _pos (0), _cnt (-1) { + _stack [0] = 0 ; + _cnt = count () ; + return ; +} + +template < class A, class B > inline TreeIterator < A, B > :: TreeIterator (A * s, const B & c) + : _seed (s), _cnt (-1), _pos (0), _cmp (c) { + _stack [0] = 0 ; + _cnt = count () ; + return ; +} + +template < class A, class B > inline TreeIterator < A, B > :: TreeIterator ( const TreeIterator < A, B > & w) + : _seed (w._seed), _cmp (w._cmp), _pos (w._pos), _cnt (w._cnt) { + for(int i = 0 ; i <= _pos ; i ++) _stack [i] = w._stack [i] ; + return ; +} + +template < class A, class B > inline TreeIterator < A, B > :: ~TreeIterator () { + return ; +} + +template < class A, class B > inline const TreeIterator < A, B > & TreeIterator < A, B > :: operator = (const TreeIterator < A, B > & w) { + _seed = w._seed ; + _cnt = w._cnt ; + _pos = w._pos ; + _cmp = w._cmp ; + for (int i = 0 ; i < _pos + 1 ; i ++) _stack [i] = w._stack [i] ; + return w ; +} + +template < class A, class B > inline void TreeIterator < A , B > :: first () { + if (_seed) { + * _stack = _seed ; + _pos = 0 ; + do { + if(pushdown ()) return ; + } while(pullup ()) ; + } + _pos = 0 ; + * _stack = 0 ; + return ; +} + +template < class A, class B > inline void TreeIterator < A , B > :: next () { + A * e = _stack [_pos] ; + A * d = e->down () ; + if (d) { + _stack[++_pos] = d ; + if(pushdown ()) return ; + } + while (pullup ()) { + if (pushdown ()) return ; + } + _pos = 0 ; + * _stack = 0 ; + return ; +} + +template < class A, class B > inline int TreeIterator < A , B > :: size () { + assert (_cnt != -1) ; + return _cnt ; +} + +template < class A, class B > inline int TreeIterator < A , B > :: done () const { + return ! _stack [_pos] ; +} + +template < class A, class B > inline A & TreeIterator < A , B > :: item () const { + assert (! done ()) ; + return * _stack [_pos] ; +} + +template < class A, class B > inline Wrapper < A, B > :: Wrapper (const A & w) : _walk (w) { + return ; +} + +template < class A, class B > inline Wrapper < A, B > :: Wrapper (const Wrapper < A, B > & w) : _walk (w._walk) { + return ; +} + +template < class A, class B > inline Wrapper < A, B > :: ~Wrapper () { + return ; +} + +template < class A, class B > inline void Wrapper < A, B > :: first () { + _walk.A :: first () ; + return ; +} + +template < class A, class B > inline void Wrapper < A, B > :: next () { + _walk.A :: next () ; + return ; +} + +template < class A, class B > inline int Wrapper < A, B > :: size () { + return _walk.A :: size () ; +} + +template < class A, class B > inline int Wrapper < A, B > :: done () const { + return _walk.A :: done () ; +} + +template < class A, class B > inline typename Wrapper < A, B > :: val_t & +Wrapper < A, B > :: item () const { + assert (! done ()) ; + return B ()(_walk.A :: item ()) ; +} + +template < class A, class B, class C > +inline AlignIterator < A, B, C > :: +AlignIterator (const A & a, const B & b) + : _walk1 (a), _walk2 (b), _curr (0), _cnt (-1) { + return ; +} + +template < class A, class B, class C > +inline AlignIterator < A, B, C > :: AlignIterator (const AlignIterator < A, B, C > & a) + : _walk1 (a._walk1), _walk2 (a._walk2), _curr (a._curr), _cnt (-1) { + return ; +} + +template < class A, class B, class C > inline AlignIterator < A, B, C > :: ~AlignIterator () { + return ; +} + +template < class A, class B, class C > inline void AlignIterator < A, B, C > :: first() { + _curr = 0 ; + _walk1.A :: first() ; + if(_walk1.A :: done()) { + _curr = 1 ; + _walk2.B :: first() ; + } + return ; +} + +template < class A, class B, class C > inline void AlignIterator < A, B, C > :: next () { + !_curr ? (_walk1.A::next(), (_walk1.A::done() ? (_walk2.B::first(), _curr = 1) : 0)) : (_walk2.B::next(), 0) ; + return ; +} + +template < class A, class B, class C > inline int AlignIterator < A, B, C > :: size () { + return (_cnt == -1) ? (_cnt = _walk1.A::size () + _walk2.B::size ()) : _cnt ; +} + +template < class A, class B, class C > inline int AlignIterator < A, B, C > :: done () const { + return _curr ? _walk2.B::done () : 0 ; +} + +template < class A, class B, class C > inline C & AlignIterator < A, B, C > :: item () const { + assert (! done ()) ; + if (_curr) return (C &) _walk2.B::item () ; + else return (C &) _walk1.A::item () ; +} + +template < class A > inline VectorAlign < A > :: VectorAlign (const vector < pointer_t > & l) : _it (l), _curr (), _ahead (), _cnt (-1) { + return ; +} + +template < class A > VectorAlign < A > :: ~VectorAlign () { + for (typename vector < pointer_t > :: iterator p = _it.begin () + ; p != _it.end () ; delete (*p ++)) ; + return ; +} + +template < class A > void VectorAlign < A > :: first () { + for (_curr = _it.begin () ; (_curr == _it.end () ? 0 : ((*_curr)->first (), (*_curr)->done ())) ; _curr ++) ; + _ahead = _curr; + if (_ahead != _it.end ()) + _ahead++; + for ( ; (_ahead == _it.end () ? 0 : ((*_ahead)->first (), (*_ahead)->done ())) ; _ahead ++) ; + return ; +} + +template < class A > void VectorAlign < A > :: next () { + (*_curr)->next () ; + if ((*_curr)->done ()) + { + if (_ahead != _it.end ()) + (_curr = _ahead, _ahead ++) ; + for ( ; (_ahead == _it.end () ? 0 : ((*_ahead)->first (), (*_ahead)->done ())) ; _ahead ++) ; + } + return ; +} + +template < class A > int VectorAlign < A > :: size () { + if (_cnt == -1) { + _cnt = 0 ; + for (typename vector < pointer_t > :: iterator p = _it.begin () ; + p != _it.end () ; _cnt += (*p++)->size ()) ; + } + return _cnt ; +} + +template < class A > inline int VectorAlign < A > :: done () const { + return ((_ahead == _it.end ()) ? ((_curr == _it.end ()) ? 1 : (*_curr)->done ()) : 0); +} + +template < class A > inline A & VectorAlign < A > :: item () const { + assert (! done ()) ; + return (*_curr)->item () ; +} + +template < class A, class B > Insert < A, B > :: Insert (const A & w, comp_t c) + : _outer (w), _inner (0), _cnt (0), _cmp (c) { + for( first () ; ! done () ; next ()) _cnt ++ ; + return ; +} + +template < class A, class B > inline Insert < A, B > :: Insert (const Insert < A, B > & w) + : _outer (w._outer), _inner (0), _cnt (w._cnt), _cmp (w._cmp) { + _inner = w._inner ? new B (* w._inner) : 0 ; + return ; +} + +template < class A, class B > Insert < A, B > :: ~Insert () { + if (_inner) delete _inner ; + return ; +} + +template < class A, class B > void Insert < A, B > :: first () { + if (_inner) { + delete _inner ; + _inner = 0 ; + } + for (_outer.A::first () ; ! _outer.A::done () ; _outer.A::next ()) { + _inner = new B (_outer.A::item (), _cmp) ; + _inner->B::first () ; + if(!_inner->B::done ()) break ; + else { + delete _inner ; + _inner = 0 ; + } + } + return ; +} + +template < class A, class B > void Insert < A, B > :: next () { + assert(_inner) ; + _inner->B::next () ; + if(_inner->B::done ()) { + delete _inner ; + _inner = 0 ; + for(_outer.A::next () ; ! _outer.A::done () ; _outer.A::next ()) { + _inner = new B(_outer.A::item (), _cmp) ; + _inner->B::first () ; + if(!_inner->B::done ()) break ; + else { + delete _inner ; + _inner = 0 ; + } + } + } + return ; +} + +template < class A, class B > int Insert < A, B > :: done () const { + return _outer.A::done () ? 1 : _inner ? _inner->B::done () : 1 ; +} + +template < class A, class B > int Insert < A, B > :: size () { + return _cnt ; +} + +template < class A, class B > typename Insert < A, B > :: val_t & +Insert < A, B > :: item () const { + assert (! done ()) ; + return _inner->B::item () ; +} + +#endif // WALK_H_INCLUDED diff --git a/src/serial/xdrclass.cc b/src/serial/xdrclass.cc new file mode 100644 index 0000000000000000000000000000000000000000..fdc00d7aa73a92824539dd356a654ccdd3aae5ce --- /dev/null +++ b/src/serial/xdrclass.cc @@ -0,0 +1,78 @@ +#include "xdrclass.h" + +#ifdef IBM_XLC + typedef char xdrbuff_t; + typedef char xdraddr_t; +#else + typedef void xdrbuff_t; + typedef void xdraddr_t; +#endif + +static int read_xdr_file(void *file, xdrbuff_t *buffer, xdrsize_t size) +{ + int result; + + result = (int)fread(buffer, 1, (size_t)size, (FILE *)file); + + if(size > 0 && result == 0) + return -1; + + return result; +} + +static int write_xdr_file(void *file, xdrbuff_t *buffer, xdrsize_t size) +{ + return (fwrite(buffer, (size_t)size, 1, (FILE *)file) == 1 ? (int)size : 0); +} + +typedef struct { + FILE *fp; + char *filename; + bool_t gezipt; +} XDR_info; + +XDR *XDRopen(const char *filename,const xdr_op op) +{ + XDR *x=NULL; + XDR_info *info; + int gezipt=0; + FILE *fp; + if (op==XDR_DECODE) + fp=fopen(filename,"r"); + else if (op==XDR_ENCODE) + fp=fopen(filename,"w"); + else + abort(); + if (!fp && op==XDR_DECODE) + { + /* Schau nach geziptem File */ + /* ... */ + if (!fp) + return NULL; + } + assert(fp); + x=(XDR*) malloc(sizeof(XDR)); + info=(XDR_info*) malloc(sizeof(XDR_info)); + assert(x && info); + xdrrec_create(x, 65536, 65536, (xdraddr_t *)fp, + read_xdr_file, write_xdr_file); + x->x_op = op; + info->fp = fp; + info->gezipt = gezipt; + x->x_public = (caddr_t)info; + if (op==XDR_DECODE) + xdrrec_skiprecord(x); + return x; +} +XDR *XDRclose(XDR *x) +{ + XDR_info *info=(XDR_info*)x->x_public; + if (x->x_op==XDR_ENCODE) + xdrrec_endofrecord(x, TRUE); + xdr_destroy(x); + fclose(info->fp); + if (info->gezipt) {abort();} + free(info); + free(x); + return NULL; +} diff --git a/src/serial/xdrclass.h b/src/serial/xdrclass.h new file mode 100644 index 0000000000000000000000000000000000000000..28d53a965d1f5289c96f102928f0df856412059a --- /dev/null +++ b/src/serial/xdrclass.h @@ -0,0 +1,170 @@ +#ifndef __XDRCLASS_INCLUDED__ +#define __XDRCLASS_INCLUDED__ + +#include <rpc/rpc.h> +#include <rpc/xdr.h> +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> + +#ifdef IBM_XLC + typedef char xdrbuff_t; + typedef char xdraddr_t; + typedef int xdrsize_t; +#else + typedef void xdrbuff_t; + typedef void xdraddr_t; + typedef u_int xdrsize_t; +#endif + +int read_xdr_file(void *file, xdrbuff_t *buffer, xdrsize_t size); +int write_xdr_file(void *file, xdrbuff_t *buffer, xdrsize_t size); + +XDR *XDRopen(const char *filename,const xdr_op op); +XDR *XDRclose(XDR *x); + +class XDRstream +{ + XDR _xdrs; + FILE * _xdrfile; + unsigned int puts_; +public: + enum XDRdir { in , out }; + + XDRstream(const char * filename, XDRdir dir ) : puts_ (1) + { + if(dir == in) + _xdrfile = fopen(filename, "rb"); + if(dir == out) + _xdrfile = fopen(filename, "wb"); + + if(!_xdrfile) + { + printf( "\aERROR in XDRstream::XDRstream(..): couldnot open <%s>!\n", filename); + fflush(stderr); + abort(); + } + + // read xdr + xdrstdio_create(&_xdrs, _xdrfile, XDR_DECODE); + } + + ~XDRstream () + { + if(_xdrfile) fclose(_xdrfile); + } + + template <class T> + void put (const T & t) + { + assert(false); + cout << "Pute \n"; + //char * tp= const_cast<T *> (&t); + //xdr_bytes(&_xdrs, ((char **) &t) , 1, sizeof(T) ); + //xdr_bytes(&_xdrs, &tp , &puts_, sizeof(T) ); + //xdr_vector(&_xdrs,((char *) &t),1, sizeof(T) ,(xdrproc_t)xdr_double); + } + + /* + template <> + void put (const char & t) + { + cout << "put " << t << "\n"; + xdr_char(&_xdrs, const_cast<char *> (&t) ); + } + + template <> + void put (const int & t) + { + cout << "Put int \n"; + xdr_int(&_xdrs, const_cast<int *> (&t) ); + } + */ + + char get () const + { + char t; + read(t); + return t; + } + + template <class T> + void read (T &t) const + { + assert(false); + //xdr_bytes(&_xdrs, ((char **) &t) , 1, sizeof(T) ); + } + + /* + template <> + void read (char &t) const + { + cout << "read char \n"; + xdr_char(const_cast<XDR *> (&_xdrs), &t ); + cout << t << "\n"; + } + + template <> + void read (int &t) const + { + xdr_int(const_cast<XDR *> (&_xdrs), &t ); + } + */ + + bool operator ! () { + return _xdrfile ? true : false; + } + + XDRstream & operator << ( const char * t ) + { + cout << " schriebe char \n"; + xdr_char(&_xdrs, const_cast<char *> (t)); + return *this; + } + + XDRstream & operator >> ( const char * t ) + { + cout << " lese char \n"; + xdr_char(&_xdrs, const_cast<char *> (t)); + return *this; + } + + template <class T> + XDRstream & operator << (const T & t ) + { + put(t); + return *this; + } + + template <class T> + XDRstream & operator >> (T & t ) const + { + read(t); + return *this; + } + + void precision ( int pre ) + { + } + template <typename A, typename B> + void setf ( const A & a, const B & b ) + { + } +}; + +class XDRstream_out : public XDRstream +{ +public: + XDRstream_out(const char * filename) : XDRstream + (filename,XDRstream::out) {} +}; + +class XDRstream_in : public XDRstream +{ +public: + XDRstream_in(const char * filename) : XDRstream + (filename,XDRstream::in) {} +}; + +#endif +