From 20dd32e1d613bba4ae07823da40d24f93857bb6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Kl=C3=B6fkorn?= <robertk@mathematik.uni-stuttgart.de> Date: Wed, 23 Mar 2005 14:59:02 +0000 Subject: [PATCH] All files for dune interface of ALU3DGrid. git-svn-id: https://dune.mathematik.uni-freiburg.de/svn/alugrid/trunk@150 0d966ed9-3843-0410-af09-ebfb50bd7c74 --- src/duneinterface/gitter_dune_impl.cc | 181 ++++++ src/duneinterface/gitter_dune_impl.h | 30 + src/duneinterface/gitter_dune_pll_impl.cc | 638 ++++++++++++++++++++++ src/duneinterface/gitter_dune_pll_impl.h | 80 +++ src/duneinterface/gitter_dune_pll_mgb.cc | 560 +++++++++++++++++++ 5 files changed, 1489 insertions(+) create mode 100644 src/duneinterface/gitter_dune_impl.cc create mode 100644 src/duneinterface/gitter_dune_impl.h create mode 100644 src/duneinterface/gitter_dune_pll_impl.cc create mode 100644 src/duneinterface/gitter_dune_pll_impl.h create mode 100644 src/duneinterface/gitter_dune_pll_mgb.cc diff --git a/src/duneinterface/gitter_dune_impl.cc b/src/duneinterface/gitter_dune_impl.cc new file mode 100644 index 000000000..d1e1a7c77 --- /dev/null +++ b/src/duneinterface/gitter_dune_impl.cc @@ -0,0 +1,181 @@ +// Robert Kloefkorn (c) 2004 - 2005 +#ifndef GITTER_DUNE_IMPL_CC_INCLUDED +#define GITTER_DUNE_IMPL_CC_INCLUDED + +#include "gitter_dune_impl.h" + +void GitterDuneBasis :: backupIndices (ostream & out) +{ + // backup indices + bool indices = true; out.put(indices); // indices == true + + // store max indices + for(int i=0; i< numOfIndexManager ; i++) + indexManager(i).backupIndexSet(out); + + { // backup index of elements + AccessIterator <helement_STI> :: Handle ew (container ()) ; + for (ew.first () ; ! ew.done () ; ew.next ()) ew.item ().backupIndex (out) ; + } + { + // backup index of vertices + LeafIterator < vertex_STI > w ( *this ); + for( w->first(); ! w->done() ; w->next () ) w->item().backupIndex(out); + } + + return ; +} + +// go down all children and check index +inline void GitterDuneBasis :: +goDownHelement( Gitter::helement_STI & el , vector<bool> & idxcheck) +{ + typedef Gitter :: helement_STI ElType; + assert( (static_cast<size_t> (el.getIndex())) < idxcheck.size() ); + idxcheck[ el.getIndex() ] = false; + for( ElType * ch = el.down() ; ch ; ch = ch->next()) + goDownHelement( *ch , idxcheck ); + + return ; +} + +void GitterDuneBasis ::restoreIndices (istream & in) +{ + bool indices = in.get(); + if(indices) + { + for(int i=0; i< numOfIndexManager ; i++) + this->indexManager(i).restoreIndexSet( in ); + + // restore index of elements + { + AccessIterator < helement_STI >:: Handle ew(container()); + for ( ew.first(); !ew.done(); ew.next()) ew.item().restoreIndex (in); + } + // restore index of vertices + { + LeafIterator < vertex_STI > w ( *this ); + for( w->first(); ! w->done() ; w->next () ) w->item().restoreIndex(in); + } + + { // reconstruct holes + { + enum { elements = 0 }; + // for elements + int idxsize = this->indexManager(elements).getMaxIndex(); + vector < bool > checkidx ( idxsize ); + for(int i=0; i<idxsize; i++) checkidx[i] = true; + + AccessIterator < helement_STI >:: Handle ew(container()); + for ( ew.first(); !ew.done(); ew.next()) + { + goDownHelement( ew.item() , checkidx ); + } + + for(int i=0; i<idxsize; i++) + { + if(checkidx[i] == true) + this->indexManager(elements).freeIndex(i); + } + } + { + enum { vertices = 3 }; + // for vertices + LeafIterator < vertex_STI > w ( *this ); + int idxsize = this->indexManager(vertices).getMaxIndex(); + + vector < bool > checkidx ( idxsize ); + for(int i=0; i<idxsize; i++) checkidx[i] = true; + for( w->first(); ! w->done() ; w->next () ) + { + assert( (static_cast<size_t> (w->item().getIndex())) < checkidx.size() ); + checkidx[ w->item().getIndex() ] = false; + } + + for(int i=0; i<idxsize; i++) + { + if(checkidx[i] == true) + this->indexManager(vertices).freeIndex(i); + } + } + } + } + else + { + cerr<< "WARNING: indices not read! file = "<< __FILE__ << ", line = " << __LINE__ << "\n"; + } + + return ; +} + +// wird von Dune verwendet +void GitterDuneBasis :: duneBackup (const char * fileName) +{ + // diese Methode wird von der Dune Schnittstelle aufgerufen und ruft + // intern lediglich backup (siehe oben) und backupCMode des Makrogitters + // auf, allerdings wird hier der path und filename in einer variablen + // uebergeben + + assert (debugOption (20) ? (cout << "**INFO GitterDuneBasis :: duneBackup (const char * = \"" + << fileName << "\") " << endl, 1) : 1) ; + + ofstream out (fileName) ; + if (!out) { + cerr << "**WARNUNG (IGNORIERT) GitterDuneBasis :: duneBackup (const char *, double) Fehler beim Anlegen von < " + << (fileName ? fileName : "null") << " >" << endl ; + } + else + { + FSLock lock (fileName) ; + Gitter :: backup (out) ; + GitterDuneBasis :: backupIndices (out) ; + + { + char *fullName = new char[strlen(fileName)+20]; + if(!fullName) + { + cerr << "**WARNUNG GitterDuneBasis :: duneBackup (, const char *, double) :"; + cerr << "couldn't allocate fullName! " << endl; + abort(); + } + sprintf(fullName,"%s.macro",fileName); + ofstream macro (fullName) ; + + if(!macro) + { + cerr << "**WARNUNG (IGNORIERT) GitterDuneBasis :: duneBackup (const char *, const char *) Fehler beim Anlegen von < " + << (fullName ? fullName : "null") << " >" << endl ; + } + else + { + container ().backupCMode (macro) ; + } + delete [] fullName; + } + } + return ; +} + +// wird von Dune verwendet +void GitterDuneBasis :: duneRestore (const char * fileName) +{ + // diese Methode wird von der Dune Schnittstelle aufgerufen + // diese Methode ruft intern restore auf, hier wird lediglich + // der path und filename in einer variablen uebergeben + + assert (debugOption (20) ? (cout << "**INFO GitterDuneBasis :: duneRestore (const char * = \"" + << fileName << "\") " << endl, 1) : 1) ; + + ifstream in (fileName) ; + if (!in) { + cerr << "**WARNUNG (IGNORIERT) GitterDuneBasis :: duneRestore (const char *, double & ) Fehler beim \"Offnen von < " + << (fileName ? fileName : "null") << " > " << endl ; + } else { + Gitter :: restore (in) ; + GitterDuneBasis :: restoreIndices (in); + } + return ; +} + + +#endif diff --git a/src/duneinterface/gitter_dune_impl.h b/src/duneinterface/gitter_dune_impl.h new file mode 100644 index 000000000..ef6a26ee4 --- /dev/null +++ b/src/duneinterface/gitter_dune_impl.h @@ -0,0 +1,30 @@ +#ifndef GITTER_DUNE_IMPL_H_INCLUDED +#define GITTER_DUNE_IMPL_H_INCLUDED + +#include "gitter_impl.h" +#include "lock.h" + +class GitterDuneBasis : public virtual GitterBasis +{ +protected: + void backupIndices (ostream & out); + void restoreIndices (istream & in ); + + inline void goDownHelement( helement_STI & el , vector<bool> & idxcheck); + +public: + // write status of grid + virtual void duneBackup (const char*) ; + + // read status of grid + virtual void duneRestore (const char*) ; + // Constructor getting macro file name +}; + +class GitterDuneImpl : public GitterBasisImpl , public GitterDuneBasis +{ +public: + inline GitterDuneImpl (const char *filename) : GitterBasisImpl ( filename ) {} +}; + +#endif diff --git a/src/duneinterface/gitter_dune_pll_impl.cc b/src/duneinterface/gitter_dune_pll_impl.cc new file mode 100644 index 000000000..5f7682993 --- /dev/null +++ b/src/duneinterface/gitter_dune_pll_impl.cc @@ -0,0 +1,638 @@ +#ifndef GITTER_DUNE_PLL_IMPL_CC_INCLUDED +#define GITTER_DUNE_PLL_IMPL_CC_INCLUDED + +#include "gitter_dune_pll_impl.h" +#include "gitter_dune_pll_mgb.cc" + +bool GitterDunePll :: duneNotifyNewGrid () +{ + assert (debugOption (20) ? (cout << "**GitterPll :: loadBalancerGridChangesNotify () " << endl, 1) : 1) ; + const int start = clock (), me = mpAccess ().myrank (), np = mpAccess ().psize () ; + LoadBalancer :: DataBase db ; + { + AccessIterator < hface_STI > :: Handle w (containerPll ()) ; + for (w.first () ; ! w.done () ; w.next ()) w.item ().accessPllX ().ldbUpdateGraphEdge (db) ; + } + { + AccessIterator < helement_STI > :: Handle w (containerPll ()) ; + for (w.first () ; ! w.done () ; w.next ()) w.item ().accessPllX ().ldbUpdateGraphVertex (db) ; + } + bool neu = false ; + { + // Kriterium, wann eine Lastneuverteilung vorzunehmen ist: + // + // load - eigene ElementLast + // mean - mittlere ElementLast + // nload - Lastverh"altnis + + double load = db.accVertexLoad () ; + vector < double > v (mpAccess ().gcollect (load)) ; + double mean = accumulate (v.begin (), v.end (), 0.0) / double (np) ; + + for (vector < double > :: iterator i = v.begin () ; i != v.end () ; i ++) + neu |= (*i > mean ? (*i > (_ldbOver * mean) ? true : false) : (*i < (_ldbUnder * mean) ? true : false)) ; + } + return neu; +} + + + +void GitterDunePll :: duneNotifyGridChanges () +{ + Gitter :: notifyGridChanges () ; + duneExchangeDynamicState () ; + return ; +} + + +// done call notify and loadBalancer +bool GitterDunePll :: duneAdapt () +{ + __STATIC_myrank = mpAccess ().myrank () ; + __STATIC_turn ++ ; + assert (debugOption (20) ? (cout << "**INFO GitterDunePll :: duneAdapt ()" << endl, 1) : 1) ; + assert (! iterators_attached ()) ; + int start = clock () ; + bool refined = this->refine() ; + int lap = clock () ; + this->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 GitterDunePll :: adapt () [ref (loops)|cse|all] " << u1 << " (" + << _refineLoops << ") " << u2 << " " << u3 << endl ; + } + duneNotifyGridChanges () ; + balanceGrid_ = duneNotifyNewGrid(); + + return refined; +} + + + +bool GitterDunePll :: duneLoadBalance () +{ + loadBalancerGridChangesNotify () ; + return true; +} + +bool GitterDunePll :: duneLoadBalance (GatherScatterType & gs) { + assert (debugOption (20) ? (cout << "**GitterDunePll :: loadBalancerGridChangesNotify () " << endl, 1) : 1) ; + const int start = clock (), me = mpAccess ().myrank (), np = mpAccess ().psize () ; + LoadBalancer :: DataBase db ; + { + AccessIterator < hface_STI > :: Handle w (containerPll ()) ; + for (w.first () ; ! w.done () ; w.next ()) w.item ().accessPllX ().ldbUpdateGraphEdge (db) ; + } + { + AccessIterator < helement_STI > :: Handle w (containerPll ()) ; + for (w.first () ; ! w.done () ; w.next ()) w.item ().accessPllX ().ldbUpdateGraphVertex (db) ; + } + bool neu = false ; + { + // Kriterium, wann eine Lastneuverteilung vorzunehmen ist: + // + // load - eigene ElementLast + // mean - mittlere ElementLast + // nload - Lastverh"altnis + + double load = db.accVertexLoad () ; + vector < double > v (mpAccess ().gcollect (load)) ; + double mean = accumulate (v.begin (), v.end (), 0.0) / double (np) ; + + for (vector < double > :: iterator i = v.begin () ; i != v.end () ; i ++) + neu |= (*i > mean ? (*i > (_ldbOver * mean) ? true : false) : (*i < (_ldbUnder * mean) ? true : false)); + } + if (neu) + { + if (mpAccess ().gmax (_ldbMethod)) + { + duneRepartitionMacroGrid (db, gs) ; + notifyMacroGridChanges () ; + } + } + return true; +} + +void GitterDunePll :: duneExchangeDynamicState () +{ + // Die Methode wird jedesmal aufgerufen, wenn sich der dynamische + // Zustand des Gitters ge"andert hat: Verfeinerung und alle Situationen + // die einer "Anderung des statischen Zustands entsprechen. Sie wird in + // diesem Fall NACH dem Update des statischen Zustands aufgerufen, und + // kann demnach von einem korrekten statischen Zustand ausgehen. F"ur + // Methoden die noch h"aufigere Updates erfordern m"ussen diese in der + // Regel hier eingeschleift werden. + { + int mallocedsize; + const int nl = mpAccess ().nlinks () ; + const int start = clock () ; + try + { + typedef Insert < AccessIteratorTT < hface_STI > :: InnerHandle, + TreeIterator < hface_STI, is_def_true < hface_STI > > > InnerIteratorType; + typedef Insert < AccessIteratorTT < hface_STI > :: OuterHandle, + TreeIterator < hface_STI, is_def_true < hface_STI > > > OuterIteratorType; + + vector < ObjectStream > osv (nl) ; + { + for (int l = 0 ; l < nl ; l ++) + { + { + AccessIteratorTT < hface_STI > :: InnerHandle mif (this->containerPll (),l) ; + AccessIteratorTT < hface_STI > :: OuterHandle mof (this->containerPll (),l) ; + + InnerIteratorType wi (mif); + for (wi.first () ; ! wi.done () ; wi.next ()) + { + pair < ElementPllXIF_t *, int > p = wi.item ().accessPllX ().accessInnerPllX () ; + p.first->writeDynamicState (osv [l], p.second) ; + } + + OuterIteratorType wo (mof); + for (wo.first () ; ! wo.done () ; wo.next ()) + { + pair < ElementPllXIF_t *, int > p = wo.item ().accessPllX ().accessInnerPllX () ; + p.first->writeDynamicState (osv [l], p.second) ; + } + } + } + } + + osv = mpAccess ().exchange (osv) ; + + { + for (int l = 0 ; l < nl ; l ++ ) + { + { + AccessIteratorTT < hface_STI > :: OuterHandle mof (this->containerPll (),l) ; + AccessIteratorTT < hface_STI > :: InnerHandle mif (this->containerPll (),l) ; + + OuterIteratorType wo (mof) ; + for (wo.first () ; ! wo.done () ; wo.next ()) + { + pair < ElementPllXIF_t *, int > p = wo.item ().accessPllX ().accessOuterPllX () ; + p.first->readDynamicState (osv [l], p.second) ; + } + + InnerIteratorType wi (mif); + for (wi.first () ; ! wi.done () ; wi.next ()) + { + pair < ElementPllXIF_t *, int > p = wi.item ().accessPllX ().accessOuterPllX () ; + p.first->readDynamicState (osv [l], p.second) ; + } + } + } + } + } + catch (Parallel :: AccessPllException) + { + cerr << " FEHLER Parallel :: AccessPllException entstanden in: " << __FILE__ << " " << __LINE__ << endl ; + } + assert (debugOption (20) ? (cout << "**INFO GitterDunePll :: exchangeDynamicState () used " << (float)(clock () - start)/(float)(CLOCKS_PER_SEC) << " sec. " << endl, 1) : 1 ) ; + } +} + +void GitterDunePll :: duneExchangeData (GatherScatterType & gs) +{ + // Die Methode wird jedesmal aufgerufen, wenn sich der dynamische + // Zustand des Gitters ge"andert hat: Verfeinerung und alle Situationen + // die einer "Anderung des statischen Zustands entsprechen. Sie wird in + // diesem Fall NACH dem Update des statischen Zustands aufgerufen, und + // kann demnach von einem korrekten statischen Zustand ausgehen. F"ur + // Methoden die noch h"aufigere Updates erfordern m"ussen diese in der + // Regel hier eingeschleift werden. + { + int mallocedsize; + const int nl = mpAccess ().nlinks () ; + const int start = clock () ; + try + { + typedef Insert < AccessIteratorTT < hface_STI > :: InnerHandle, + TreeIterator < hface_STI, is_def_true < hface_STI > > > InnerIteratorType; + typedef Insert < AccessIteratorTT < hface_STI > :: OuterHandle, + TreeIterator < hface_STI, is_def_true < hface_STI > > > OuterIteratorType; + + vector < ObjectStream > osv (nl) ; + { + for (int l = 0 ; l < nl ; l ++) + { + { + AccessIteratorTT < hface_STI > :: InnerHandle mif (this->containerPll (),l) ; + AccessIteratorTT < hface_STI > :: OuterHandle mof (this->containerPll (),l) ; + + InnerIteratorType wi (mif); + for (wi.first () ; ! wi.done () ; wi.next ()) + { + pair < ElementPllXIF_t *, int > p = wi.item ().accessPllX ().accessInnerPllX () ; + p.first->writeDynamicState (osv [l], p.second) ; + p.first->writeDynamicState (osv [l], gs) ; + } + + OuterIteratorType wo (mof); + for (wo.first () ; ! wo.done () ; wo.next ()) + { + pair < ElementPllXIF_t *, int > p = wo.item ().accessPllX ().accessInnerPllX () ; + p.first->writeDynamicState (osv [l], p.second) ; + p.first->writeDynamicState (osv [l], gs) ; + } + } + } + } + + osv = mpAccess ().exchange (osv) ; + + { + for (int l = 0 ; l < nl ; l ++ ) + { + { + AccessIteratorTT < hface_STI > :: OuterHandle mof (this->containerPll (),l) ; + AccessIteratorTT < hface_STI > :: InnerHandle mif (this->containerPll (),l) ; + + OuterIteratorType wo (mof) ; + for (wo.first () ; ! wo.done () ; wo.next ()) + { + pair < ElementPllXIF_t *, int > p = wo.item ().accessPllX ().accessOuterPllX () ; + p.first->readDynamicState (osv [l], p.second) ; + p.first->readDynamicState (osv [l], gs) ; + } + + InnerIteratorType wi (mif); + for (wi.first () ; ! wi.done () ; wi.next ()) + { + pair < ElementPllXIF_t *, int > p = wi.item ().accessPllX ().accessOuterPllX () ; + p.first->readDynamicState (osv [l], p.second) ; + p.first->readDynamicState (osv [l], gs ) ; + } + } + } + } + } + catch (Parallel :: AccessPllException) + { + cerr << " FEHLER Parallel :: AccessPllException entstanden in: " << __FILE__ << " " << __LINE__ << endl ; + } + assert (debugOption (20) ? (cout << "**INFO GitterDunePll :: exchangeDynamicState () used " << (float)(clock () - start)/(float)(CLOCKS_PER_SEC) << " sec. " << endl, 1) : 1 ) ; + } +} + +bool GitterDunePll :: refine () { + assert (debugOption (5) ? (cout << "**INFO GitterPll :: refine () " << endl, 1) : 1) ; + const int nl = mpAccess ().nlinks (), start = clock () ; + bool state = false ; + vector < vector < hedge_STI * > > innerEdges (nl), outerEdges (nl) ; + vector < vector < hface_STI * > > innerFaces (nl), outerFaces (nl) ; + { + // Erst die Zeiger auf alle Fl"achen und Kanten mit paralleler + // Mehrdeutigkeit sichern, da die LeafIteratorTT < . > nach dem + // Verfeinern auf gitter nicht mehr stimmen werden. Die Technik + // ist zul"assig, da keine mehrfache Verfeinerung entstehen kann. + + {for (int l = 0 ; l < nl ; l ++) { + //cout << "refinepll \n"; + LeafIteratorTT < hface_STI > fw (*this,l) ; + LeafIteratorTT < hedge_STI > dw (*this,l) ; + for (fw.outer ().first () ; ! fw.outer().done () ; fw.outer ().next ()) + outerFaces [l].push_back (& fw.outer ().item ()) ; + for (fw.inner ().first () ; ! fw.inner ().done () ; fw.inner ().next ()) + innerFaces [l].push_back (& fw.inner ().item ()) ; + for (dw.outer ().first () ; ! dw.outer().done () ; dw.outer ().next ()) + outerEdges [l].push_back (& dw.outer ().item ()) ; + for (dw.inner ().first () ; ! dw.inner ().done () ; dw.inner ().next ()) + innerEdges [l].push_back (& dw.inner ().item ()) ; + }} + // jetzt normal verfeinern und den Status der Verfeinerung + // [unvollst"andige / vollst"andige Verfeinerung] sichern. + + __STATIC_phase = 1 ; + + state = Gitter :: refine () ; + + // Phase des Fl"achenausgleichs an den Schnittfl"achen des + // verteilten Gitters. Weil dort im sequentiellen Fall pseudorekursive + // Methodenaufrufe vorliegen k"onnen, muss solange iteriert werden, + // bis die Situation global station"ar ist. + + __STATIC_phase = 2 ; + + bool repeat (false) ; + _refineLoops = 0 ; + do { + repeat = false ; + { + vector < ObjectStream > osv (nl) ; + try { + //cout << "refinepll 2 \n"; + for (int l = 0 ; l < nl ; l ++) { + {for (vector < hface_STI * > :: const_iterator i = outerFaces [l].begin () ; + i != outerFaces [l].end () ; (*i ++)->accessPllX ().accessOuterPllX ().first->getRefinementRequest (osv [l])) ; } + {for (vector < hface_STI * > :: const_iterator i = innerFaces [l].begin () ; + i != innerFaces [l].end () ; (*i ++)->accessPllX ().accessOuterPllX ().first->getRefinementRequest (osv [l])) ; } + } + } catch (Parallel :: AccessPllException) { + cerr << "**FEHLER (FATAL) AccessPllException in " << __FILE__ << " " << __LINE__ << endl ; abort () ; + } + + osv = mpAccess ().exchange (osv) ; + + try { + for (int l = 0 ; l < nl ; l ++) { + {for (vector < hface_STI * > :: const_iterator i = innerFaces [l].begin () ; + i != innerFaces [l].end () ; repeat |= (*i ++)->accessPllX ().accessOuterPllX ().first->setRefinementRequest (osv [l])) ; } + {for (vector < hface_STI * > :: const_iterator i = outerFaces [l].begin () ; + i != outerFaces [l].end () ; repeat |= (*i ++)->accessPllX ().accessOuterPllX ().first->setRefinementRequest (osv [l])) ; } + } + } catch (Parallel :: AccessPllException) { + cerr << "**FEHLER (FATAL) AccessPllException in " << __FILE__ << " " << __LINE__ << endl ; abort () ; + } + } + + _refineLoops ++ ; + } while (mpAccess ().gmax (repeat ? 1 : 0)) ; + + // Jetzt noch die Kantensituation richtigstellen, es gen"ugt ein Durchlauf, + // weil die Verfeinerung einer Kante keine Fernwirkungen hat. Vorsicht: Die + // Kanten sind bez"uglich ihrer Identifikation sternf"ormig organisiert, d.h. + // es muss die Verfeinerungsinformation einmal am Eigent"umer gesammelt und + // dann wieder zur"ucktransportiert werden, eine einfache L"osung, wie bei + // den Fl"achen (1/1 Beziehung) scheidet aus. + + __STATIC_phase = 3 ; + + { + vector < ObjectStream > osv (nl) ; + {for (int l = 0 ; l < nl ; l ++) + for (vector < hedge_STI * > :: const_iterator i = outerEdges [l].begin () ; + i != outerEdges [l].end () ; (*i ++)->accessPllX ().getRefinementRequest (osv [l])) ; + } + osv = mpAccess ().exchange (osv) ; + {for (int l = 0 ; l < nl ; l ++) + for (vector < hedge_STI * > :: const_iterator i = innerEdges [l].begin () ; + i != innerEdges [l].end () ; (*i ++)->accessPllX ().setRefinementRequest (osv [l])) ; + } + } // ~vector < ObjectStream > ... + { + vector < ObjectStream > osv (nl) ; + {for (int l = 0 ; l < nl ; l ++) + for (vector < hedge_STI * > :: const_iterator i = innerEdges [l].begin () ; + i != innerEdges [l].end () ; (*i ++)->accessPllX ().getRefinementRequest (osv [l])) ; + } + osv = mpAccess ().exchange (osv) ; + {for (int l = 0 ; l < nl ; l ++) + for (vector < hedge_STI * > :: const_iterator i = outerEdges [l].begin () ; + i != outerEdges [l].end () ; (*i ++)->accessPllX ().setRefinementRequest (osv [l])) ; + } + } // ~vector < ObjectStream > ... + } + + __STATIC_phase = -1 ; + + return state ; +} + +void GitterDunePll :: coarse () { + assert (debugOption (20) ? (cout << "**INFO GitterPll :: coarse () " << endl, 1) : 1) ; + const int nl = mpAccess ().nlinks () ; + + { + vector < vector < hedge_STI * > > innerEdges (nl), outerEdges (nl) ; + vector < vector < hface_STI * > > innerFaces (nl), outerFaces (nl) ; + + for (int l = 0 ; l < nl ; l ++) { + + // Zun"achst werden f"ur alle Links die Zeiger auf Gitterojekte mit + // Mehrdeutigkeit gesichert, die an der Wurzel einer potentiellen + // Vergr"oberungsoperation sitzen -> es sind die Knoten in der Hierarchie, + // deren Kinder alle Bl"atter sind. Genau diese Knoten sollen gegen"uber + // der Vergr"oberung blockiert werden und dann die Vergr"oberung falls + // sie zul"assig ist, sp"ater durchgef"uhrt werden (pending) ; + + AccessIteratorTT < hface_STI > :: InnerHandle mfwi (containerPll (),l) ; + AccessIteratorTT < hface_STI > :: OuterHandle mfwo (containerPll (),l) ; + AccessIteratorTT < hedge_STI > :: InnerHandle mdwi (containerPll (),l) ; + AccessIteratorTT < hedge_STI > :: OuterHandle mdwo (containerPll (),l) ; + + // Die inneren und a"usseren Iteratoren der potentiell vergr"oberungsf"ahigen + // Fl"achen "uber den Grobgitterfl"achen. In den Elementen passiert erstmal + // nichts, solange nicht mit mehrfachen Grobgitterelementen gearbeitet wird. + + Insert < AccessIteratorTT < hface_STI > :: InnerHandle, + TreeIterator < hface_STI, childs_are_leafs < hface_STI > > > fwi (mfwi) ; + Insert < AccessIteratorTT < hface_STI > :: OuterHandle, + TreeIterator < hface_STI, childs_are_leafs < hface_STI > > > fwo (mfwo) ; + + // Die inneren und a"usseren Iteratoren der potentiell vergr"oberungsf"ahigen + // Kanten "uber den Grobgitterkanten. + + Insert < AccessIteratorTT < hedge_STI > :: InnerHandle, + TreeIterator < hedge_STI, childs_are_leafs < hedge_STI > > > dwi (mdwi) ; + Insert < AccessIteratorTT < hedge_STI > :: OuterHandle, + TreeIterator < hedge_STI, childs_are_leafs < hedge_STI > > > dwo (mdwo) ; + + // Die inneren und a"usseren Iteratoren der potentiell vergr"oberungsf"ahigen + // Kanten "uber den Grobgitterfl"achen. Diese Konstruktion wird beim Tetraeder- + // gitter notwendig, weil dort keine Aussage der Form: + // + + Insert < AccessIteratorTT < hface_STI > :: InnerHandle, + TreeIterator < hface_STI, has_int_edge < hface_STI > > > efi (mfwi) ; + Insert < AccessIteratorTT < hface_STI > :: OuterHandle, + TreeIterator < hface_STI, has_int_edge < hface_STI > > > efo (mfwo) ; + Wrapper < Insert < AccessIteratorTT < hface_STI > :: InnerHandle, + TreeIterator < hface_STI, has_int_edge < hface_STI > > >, InternalEdge > eifi (efi) ; + Wrapper < Insert < AccessIteratorTT < hface_STI > :: OuterHandle, + TreeIterator < hface_STI, has_int_edge < hface_STI > > >, InternalEdge > eifo (efo) ; + Insert < Wrapper < Insert < AccessIteratorTT < hface_STI > :: InnerHandle, + TreeIterator < hface_STI, has_int_edge < hface_STI > > >, InternalEdge >, + TreeIterator < hedge_STI, childs_are_leafs < hedge_STI > > > dfi (eifi) ; + Insert < Wrapper < Insert < AccessIteratorTT < hface_STI > :: OuterHandle, + TreeIterator < hface_STI, has_int_edge < hface_STI > > >, InternalEdge >, + TreeIterator < hedge_STI, childs_are_leafs < hedge_STI > > > dfo (eifo) ; + + // Die 'item ()' Resultatwerte (Zeiger) werden in Vektoren gesichert, weil die + // Kriterien die zur Erzeugung der Iteratoren angewendet wurden (Filter) nach + // einer teilweisen Vergr"oberung nicht mehr g"ultig sein werden, d.h. die + // Iterationsobjekte "andern w"ahrend der Vergr"oberung ihre Eigenschaften. + // Deshalb werden sie auch am Ende des Blocks aufgegeben. Der Vektor 'cache' + // ist zul"assig, weil kein Objekt auf das eine Referenz im 'cache' vorliegt + // beseitigt werden kann. Sie sind alle ein Niveau darunter. + + for (fwi.first () ; ! fwi.done () ; fwi.next ()) innerFaces [l].push_back (& fwi.item ()) ; + for (fwo.first () ; ! fwo.done () ; fwo.next ()) outerFaces [l].push_back (& fwo.item ()) ; + for (dwo.first () ; ! dwo.done () ; dwo.next ()) outerEdges [l].push_back (& dwo.item ()) ; + for (dfo.first () ; ! dfo.done () ; dfo.next ()) outerEdges [l].push_back (& dfo.item ()) ; + for (dwi.first () ; ! dwi.done () ; dwi.next ()) innerEdges [l].push_back (& dwi.item ()) ; + for (dfi.first () ; ! dfi.done () ; dfi.next ()) innerEdges [l].push_back (& dfi.item ()) ; + } + try { + // Erstmal alles was mehrdeutig ist, gegen die drohende Vergr"oberung sichern. + // Danach werden sukzessive die Fl"achenlocks aufgehoben, getestet und + // eventuell vergr"obert, dann das gleiche Spiel mit den Kanten. + + for (int l = 0 ; l < nl ; l ++) { + {for (vector < hedge_STI * > :: iterator i = outerEdges [l].begin () ; + i != outerEdges [l].end () ; (*i ++)->accessPllX ().lockAndTry ()) ; } + {for (vector < hedge_STI * > :: iterator i = innerEdges [l].begin () ; + i != innerEdges [l].end () ; (*i ++)->accessPllX ().lockAndTry ()) ; } + {for (vector < hface_STI * > :: iterator i = outerFaces [l].begin () ; + i != outerFaces [l].end () ; (*i ++)->accessPllX ().accessOuterPllX ().first->lockAndTry ()) ; } + {for (vector < hface_STI * > :: iterator i = innerFaces [l].begin () ; + i != innerFaces [l].end () ; (*i ++)->accessPllX ().accessOuterPllX ().first->lockAndTry ()) ; } + } + + // Gitter :: coarse () ist elementorientiert, d.h. die Vergr"oberung auf Fl"achen und + // Kanten wird nur durch Vermittlung eines sich vergr"obernden Knotens in der Element- + // hierarchie angestossen. In allen gegen Vergr"oberung 'gelockten' Fl"achen und Kanten + // wird die angeforderte Operation zur"uckgewiesen, um erst sp"ater von aussen nochmals + // angestossen zu werden. + + __STATIC_phase = 4 ; + + Gitter :: coarse () ; + + } catch (Parallel :: AccessPllException) { + cerr << "**FEHLER (FATAL) AccessPllException beim Vergr\"obern der Elementhierarchie oder\n" ; + cerr << " beim locken der Fl\"achen- bzw. Kantenb\"aume aufgetreten. In " << __FILE__ << " " << __LINE__ << endl ; + abort () ; + } + try { + + // Phase des Fl"achenausgleichs des verteilten Vergr"oberungsalgorithmus + // alle Schnittfl"achenpaare werden daraufhin untersucht, ob eine + // Vergr"oberung in beiden Teilgittern durchgef"uhrt werden darf, + // wenn ja, wird in beiden Teilgittern vergr"obert und der Vollzug + // getestet. + + __STATIC_phase = 5 ; + + vector < vector < int > > clean (nl) ; + { + vector < vector < int > > inout (nl) ; + {for (int l = 0 ; l < nl ; l ++) + for (vector < hface_STI * > :: iterator i = outerFaces [l].begin () ; i != outerFaces [l].end () ; i ++) + inout [l].push_back ((*i)->accessPllX ().accessOuterPllX ().first->lockAndTry ()) ; + } + inout = mpAccess ().exchange (inout) ; + {for (int l = 0 ; l < nl ; l ++) { + clean [l] = vector < int > (innerFaces [l].size (), long (true)) ; + vector < int > :: iterator j = clean [l].begin (), k = inout [l].begin () ; + for (vector < hface_STI * > :: iterator i = innerFaces [l].begin () ; i != innerFaces [l].end () ; i ++, j++, k++) { + assert (j != clean [l].end ()) ; assert (k != inout [l].end ()) ; + (*j) &= (*k) && (*i)->accessPllX ().accessOuterPllX ().first->lockAndTry () ; + } + }} + } + { + vector < vector < int > > inout (nl) ; + {for (int l = 0 ; l < nl ; l ++) { + vector < int > :: iterator j = clean [l].begin () ; + for (vector < hface_STI * > :: iterator i = innerFaces [l].begin () ; i != innerFaces [l].end () ; i ++, j++) { + inout [l].push_back (*j) ; + (*i)->accessPllX ().accessOuterPllX ().first->unlockAndResume (bool (*j)) ; + } + }} + + inout = mpAccess ().exchange (inout) ; + + {for (int l = 0 ; l < nl ; l ++) { + vector < int > :: iterator j = inout [l].begin () ; + for (vector < hface_STI * > :: iterator i = outerFaces [l].begin () ; i != outerFaces [l].end () ; i ++, j++) { + assert (j != inout [l].end ()) ; + (*i)->accessPllX ().accessOuterPllX ().first->unlockAndResume (bool (*j)) ; + } + }} + } + } catch (Parallel :: AccessPllException) { + cerr << "**FEHLER (FATAL) AccessPllException beim Vergr\"obern der Fl\"achenb\"aume\n" ; + cerr << " aufgetreten. In " << __FILE__ << " " << __LINE__ << endl ; + abort () ; + } + try { + + // Phase des Kantenausgleichs im parallelen Vergr"oberungsalgorithmus: + + __STATIC_phase = 6 ; + + // Weil hier jede Kante nur eindeutig auftreten darf, muss sie in einem + // map als Adresse hinterlegt werden, dann k"onnen die verschiedenen + // Refcounts aus den verschiedenen Links tats"achlich global miteinander + // abgemischt werden. Dazu werden zun"achst alle eigenen Kanten auf ihre + // Vergr"oberbarkeit hin untersucht und dieser Zustand (true = vergr"oberbar + // false = darf nicht vergr"obert werden) im map 'clean' hinterlegt. Dazu + // kommt noch ein zweiter 'bool' Wert, der anzeigt ob die Kante schon ab- + // schliessend vergr"obert wurde oder nicht. + + map < hedge_STI *, pair < bool, bool >, less < hedge_STI * > > clean ; + + {for (int l = 0 ; l < nl ; l ++) + for (vector < hedge_STI * > :: iterator i = innerEdges [l].begin () ; i != innerEdges [l].end () ; i ++) + if (clean.find (*i) == clean.end ()) clean [*i] = pair < bool, bool > ((*i)->accessPllX ().lockAndTry (), true) ; + } + { + vector < vector < int > > inout (nl) ; + {for (int l = 0 ; l < nl ; l ++) + for (vector < hedge_STI * > :: iterator i = outerEdges [l].begin () ; i != outerEdges [l].end () ; i ++) + inout [l].push_back ((*i)->accessPllX ().lockAndTry ()) ; + } + inout = mpAccess ().exchange (inout) ; + {for (int l = 0 ; l < nl ; l ++) { + vector < int > :: const_iterator j = inout [l].begin () ; + for (vector < hedge_STI * > :: iterator i = innerEdges [l].begin () ; i != innerEdges [l].end () ; i ++, j++) { + assert (j != inout [l].end ()) ; + assert (clean.find (*i) != clean.end ()) ; + if (*j == false) clean [*i] = pair < bool, bool > (false, clean[*i].second) ; + } + }} + } + { + vector < vector < int > > inout (nl) ; + {for (int l = 0 ; l < nl ; l ++) { + for (vector < hedge_STI * > :: iterator i = innerEdges [l].begin () ; i != innerEdges [l].end () ; i ++) { + assert (clean.find (*i) != clean.end ()) ; + pair < bool, bool > & a = clean [*i] ; + inout [l].push_back (a.first) ; + if (a.second) { + + // Wenn wir hier sind, kann die Kante tats"achlich vergr"obert werden, genauer gesagt, + // sie wird es auch und der R"uckgabewert testet den Vollzug der Aktion. Weil aber nur + // einmal vergr"obert werden kann, und die Iteratoren 'innerEdges [l]' aber eventuell + // mehrfach "uber eine Kante hinweglaufen, muss diese Vergr"oberung im map 'clean' + // vermerkt werden. Dann wird kein zweiter Versuch unternommen. + + a.second = false ; + bool b = (*i)->accessPllX ().unlockAndResume (a.first) ; + assert (b == a.first) ; + } + } + }} + inout = mpAccess ().exchange (inout) ; + {for (int l = 0 ; l < nl ; l ++) { + vector < int > :: iterator j = inout [l].begin () ; + for (vector < hedge_STI * > :: iterator i = outerEdges [l].begin () ; i != outerEdges [l].end () ; i ++, j++) { + assert (j != inout [l].end ()) ; + + // Selbe Situation wie oben, aber der Eigent"umer der Kante hat mitgeteilt, dass sie + // vergr"obert werden darf und auch wird auf allen Teilgebieten also auch hier. Der + // Vollzug der Vergr"oberung wird durch den R"uckgabewert getestet. + + bool b = (*i)->accessPllX ().unlockAndResume (bool (*j)) ; + assert (b == bool (*j)) ; + } + }} + } + } catch (Parallel :: AccessPllException) { + cerr << "**FEHLER (FATAL) AccessPllException beim Vergr\"obern der Kantenb\"aume\n" ; + cerr << " aufgetreten. In " << __FILE__ << " " << __LINE__ << endl ; + abort () ; + } + } + + __STATIC_phase = -1 ; + + return ; +} + +#endif diff --git a/src/duneinterface/gitter_dune_pll_impl.h b/src/duneinterface/gitter_dune_pll_impl.h new file mode 100644 index 000000000..3179341fb --- /dev/null +++ b/src/duneinterface/gitter_dune_pll_impl.h @@ -0,0 +1,80 @@ +#ifndef GITTER_DUNE_PLL_IMPL_H_INCLUDED +#define GITTER_DUNE_PLL_IMPL_H_INCLUDED + +#ifdef _ANSI_HEADER + using namespace std; + #include <numeric> +#else +#endif + +#include "gitter_dune_impl.h" + +#include "gitter_pll_impl.h" +#include "gitter_pll_ldb.h" + +static bool writeLogFile = false; + +class GitterDunePll : public GitterBasisPll , public virtual GitterDuneBasis +{ + +protected: + bool balanceGrid_; + +public: + typedef Gitter :: Geometric Geometric; + typedef GitterDuneImpl :: Objects Objects; + + GitterDunePll (const char * filename , MpAccessLocal &mp) + : GitterBasisPll (filename,mp) , balanceGrid_ (false) + { + // logfile is defined in gitter_impl.h + /* + char logFileName [32]; + sprintf(logFileName,"logfile.%d",mpAccess().myrank()); + cerr << "open logfile = " << logFileName << "\n"; + + logFile.close(); + logFile.open (logFileName); + logFile << "logfile of processor " << mpAccess().myrank() << "\n"; + */ + }; + + ~GitterDunePll () { + /* + logFile.close(); + */ + } + + bool refine (); + + void coarse (); + + // done call notify and loadBalancer + bool duneAdapt (); + + // return true if grid has to be balanced again + bool duneNotifyNewGrid (); + + bool duneLoadBalance () ; // call loadBalancer + bool duneLoadBalance (GatherScatterType & ) ; // call loadBalancer a + + void duneRepartitionMacroGrid (LoadBalancer :: DataBase &, GatherScatterType & gs) ; + void repartitionMacroGrid (LoadBalancer :: DataBase &) ; + + // notifyGridChanges for dune + void duneNotifyGridChanges (); + + // exchange changed elements + void duneExchangeDynamicState (); + + // exchange data of dune + void duneExchangeData (GatherScatterType &); + + // return indexmanger + IndexManagerType & indexManager(int codim) + { + return containerPll().indexManager(codim); + } + +}; +#endif diff --git a/src/duneinterface/gitter_dune_pll_mgb.cc b/src/duneinterface/gitter_dune_pll_mgb.cc new file mode 100644 index 000000000..0843733bb --- /dev/null +++ b/src/duneinterface/gitter_dune_pll_mgb.cc @@ -0,0 +1,560 @@ +// (c) Robert Kloefkorn 2004 - 2005 +#ifndef GITTER_DUNE_PLL_MGB_CC_INCLUDED +#define GITTER_DUNE_PLL_MGB_CC_INCLUDED + +#ifdef IBM_XLC + #define _ANSI_HEADER +#endif + +#include <assert.h> +#include <time.h> +#include <stdio.h> + +#ifdef _ANSI_HEADER + using namespace std; + #include <iostream> + #include <iomanip> + #include <algorithm> +#else + #include <iostream.h> + #include <iomanip.h> + #include <algo.h> +#endif + +#include "serialize.h" +#include "gitter_mgb.h" + +#include "gitter_pll_sti.h" +#include "gitter_pll_mgb.h" + +class DuneParallelGridMover : public ParallelGridMover { + public : + DuneParallelGridMover (BuilderIF &i); + + // if not finalized yet, finalize is called + ~DuneParallelGridMover () ; + inline void initialize (); //former constructor + inline void finalize (); //former destructor + + // overlaoded, because calles unpackHbnd3 + inline void unpackAll (vector < ObjectStream > &) ; + inline void duneUnpackAll (vector < ObjectStream > &, GatherScatterType & ) ; + + protected : + void duneUnpackTetra (ObjectStream &,GatherScatterType &) ; + // overloaded, because calles InsertUniqueHbnd3_withPoint + inline void unpackHbnd3Int (ObjectStream & os); + + bool InsertUniqueHbnd3_withPoint (int (&)[3], Gitter :: hbndseg :: + bnd_t,const double (&p) [3]) ; + +}; + +// new method that gets coord of ghost point +bool DuneParallelGridMover :: InsertUniqueHbnd3_withPoint (int (&v)[3], + Gitter :: hbndseg_STI ::bnd_t bt, const double (&p)[3]) { + 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 ; + // here the point is stored + _hbnd3Int [key] = new Hbnd3IntStorage (face,twst,p) ; + 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 ; +} + +// overloaded method because here we call insertion with point +inline void DuneParallelGridMover :: unpackHbnd3Int (ObjectStream & os) +{ + double p [3] = {0.0,0.0,0.0}; + int bfake, v [3] ; + os.readObject (bfake) ; + Gitter :: hbndseg :: bnd_t b = (Gitter :: hbndseg :: bnd_t) bfake; + + os.readObject (v[0]) ; + os.readObject (v[1]) ; + os.readObject (v[2]) ; + + int readPoint = 0; + os.readObject( readPoint ); + + if( readPoint ) + { + os.readObject (p[0]) ; + os.readObject (p[1]) ; + os.readObject (p[2]) ; + } + + if(b == Gitter :: hbndseg :: closure) + { + //cout << "Insert Unique Hbnd3 p \n"; + InsertUniqueHbnd3_withPoint (v, b, p ) ; + } + else + { + assert(readPoint == 0); + // old method defined in base class + InsertUniqueHbnd3 (v, b ) ; + } + return ; +} + + +void DuneParallelGridMover :: duneUnpackTetra (ObjectStream & os, GatherScatterType & gs) { + int v [4] ; + os.readObject (v[0]) ; + os.readObject (v[1]) ; + os.readObject (v[2]) ; + os.readObject (v[3]) ; + pair < tetra_GEO *, bool > p = InsertUniqueTetra (v) ; + p.first->accessPllX ().duneUnpackSelf (os,gs,p.second) ; + return ; +} + +void DuneParallelGridMover :: unpackAll (vector < ObjectStream > & osv) { + for (vector < ObjectStream > :: iterator j = osv.begin () ; j != osv.end () ; j ++) { + ObjectStream & os (*j) ; + int code = MacroGridMoverIF :: ENDMARKER ; + for (os.readObject (code) ; code != MacroGridMoverIF :: ENDMARKER ; os.readObject (code)) { + switch (code) { + case MacroGridMoverIF:: VERTEX : + unpackVertex (os) ; + break ; + case MacroGridMoverIF :: EDGE1 : + unpackHedge1 (os) ; + break ; + case MacroGridMoverIF :: FACE3 : + unpackHface3 (os) ; + break ; + case MacroGridMoverIF :: FACE4 : + unpackHface4 (os) ; + break ; + case MacroGridMoverIF :: TETRA : + unpackTetra (os) ; + break ; + case MacroGridMoverIF :: HEXA : + unpackHexa (os) ; + break ; + case MacroGridMoverIF :: PERIODIC3 : + unpackPeriodic3 (os) ; + break ; + case MacroGridMoverIF :: PERIODIC4 : + unpackPeriodic4 (os) ; + break ; + case MacroGridMoverIF :: HBND3INT : + unpackHbnd3Int (os) ; + break ; + case MacroGridMoverIF :: HBND3EXT : + unpackHbnd3Ext (os) ; + break ; + case MacroGridMoverIF :: HBND4INT : + case MacroGridMoverIF :: HBND4EXT : + unpackHbnd4 (os) ; + break ; + default : + cerr << "**FEHLER (FATAL) Unbekannte Gitterobjekt-Codierung gelesen [" << code << "]\n" ; + cerr << " Weitermachen unm\"oglich. In " << __FILE__ << " " << __LINE__ << endl ; + abort () ; + break ; + } + } + } + return ; +} + +void DuneParallelGridMover :: duneUnpackAll (vector < ObjectStream > & osv, + GatherScatterType & gs) { + for (vector < ObjectStream > :: iterator j = osv.begin () ; j != osv.end () ; j ++) { + ObjectStream & os (*j) ; + int code = MacroGridMoverIF :: ENDMARKER ; + for (os.readObject (code) ; code != MacroGridMoverIF :: ENDMARKER ; os.readObject (code)) { + switch (code) { + case MacroGridMoverIF:: VERTEX : + unpackVertex (os) ; + break ; + case MacroGridMoverIF :: EDGE1 : + unpackHedge1 (os) ; + break ; + case MacroGridMoverIF :: FACE3 : + unpackHface3 (os) ; + break ; + case MacroGridMoverIF :: FACE4 : + unpackHface4 (os) ; + break ; + case MacroGridMoverIF :: TETRA : + duneUnpackTetra (os,gs) ; + break ; + case MacroGridMoverIF :: HEXA : + unpackHexa (os) ; + break ; + case MacroGridMoverIF :: PERIODIC3 : + unpackPeriodic3 (os) ; + break ; +// Anfang - Neu am 23.5.02 (BS) + case MacroGridMoverIF :: PERIODIC4 : + unpackPeriodic4 (os) ; + break ; +// Ende - Neu am 23.5.02 (BS) + case MacroGridMoverIF :: HBND3INT : + unpackHbnd3Int (os) ; + break ; + case MacroGridMoverIF :: HBND3EXT : + unpackHbnd3Ext (os) ; + break ; + case MacroGridMoverIF :: HBND4INT : + case MacroGridMoverIF :: HBND4EXT : + unpackHbnd4 (os) ; + break ; + default : + cerr << "**FEHLER (FATAL) Unbekannte Gitterobjekt-Codierung gelesen [" << code << "]\n" ; + cerr << " Weitermachen unm\"oglich. In " << __FILE__ << " " << __LINE__ << endl ; + abort () ; + break ; + } + } + } + return ; +} + +// calles initialize, former Constructor of MacroGridBuilder +DuneParallelGridMover :: DuneParallelGridMover (BuilderIF & i) : ParallelGridMover (i,false) +{ + initialize(); +} + +// overloaded, because here we use the new insertInternal method +void DuneParallelGridMover :: 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) + { + // change + if((*i)->getGhost()) + { + typedef Gitter :: Geometric :: tetra_GEO tetra_GEO; + tetra_GEO * gh = static_cast<tetra_GEO *> ((*i)->getGhost()); + // see insert_ghosttetra, point 3 is the new point + _hbnd3Int [key] = new Hbnd3IntStorage ((*i)->myhface3 (0), (*i)->twist (0), gh->myvertex(3)->Point()) ; + } + // until here + else + _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) ; + }} + {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) ; + }} + { + 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) ; + } + + // from constructor ParallelGridMover + vector < elementKey_t > toDelete ; + {for (elementMap_t :: iterator i = _hexaMap.begin () ; i != _hexaMap.end () ; i ++) + if (Gitter :: InternalElement ()(*((hexa_GEO *)(*i).second)).accessPllX ().erasable ()) { + toDelete.push_back ((*i).first) ; + } + } + {for (elementMap_t :: iterator i = _tetraMap.begin () ; i != _tetraMap.end () ; i ++) + if (Gitter :: InternalElement ()(*((tetra_GEO *)(*i).second)).accessPllX ().erasable ()) { + toDelete.push_back ((*i).first) ; + } + } + {for (elementMap_t :: iterator i = _periodic3Map.begin () ; i != _periodic3Map.end () ; i ++) + if (Gitter :: InternalElement ()(*((periodic3_GEO *)(*i).second)).accessPllX ().erasable ()) { + toDelete.push_back ((*i).first) ; + } + } + {for (elementMap_t :: iterator i = _periodic4Map.begin () ; i != _periodic4Map.end () ; i ++) + if (Gitter :: InternalElement ()(*((periodic4_GEO *)(*i).second)).accessPllX ().erasable ()) { + toDelete.push_back ((*i).first) ; + } + } + {for (vector < elementKey_t > :: iterator i = toDelete.begin () ; i != toDelete.end () ; i ++ ) + removeElement (*i) ; + } + + this->_initialized = true; + return ; +} + +// destructor calles finalize if not finalized yet +DuneParallelGridMover :: ~DuneParallelGridMover () +{ + if(!_finalized) finalize(); +} + +// overloaded, because here we use the new insertInternal method +void DuneParallelGridMover :: finalize () +{ + //cout << "finalize on DuneParallelGridMover called! \n"; + {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 , p.getPoint() ); + 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 ! + this->_finalized = true; + return ; +} + +//************************************************************************* +// repartition method of class GitterDunePll +//************************************************************************* +// method was overloaded because here we use our DuneParallelGridMover +void GitterDunePll :: repartitionMacroGrid (LoadBalancer :: DataBase & db) { + + if (db.repartition (mpAccess (), LoadBalancer :: DataBase :: method (_ldbMethod))) { + + const long start = clock () ; + long lap1 (start), lap2 (start), lap3 (start), lap4 (start) ; + mpAccess ().removeLinkage () ; + mpAccess ().insertRequestSymetric (db.scan ()) ; + const int me = mpAccess ().myrank (), nl = mpAccess ().nlinks () ; + { + AccessIterator < helement_STI > :: Handle w (containerPll ()) ; + for (w.first () ; ! w.done () ; w.next ()) { + int to = db.getDestination (w.item ().accessPllX ().ldbVertexIndex ()) ; + if (me != to) + w.item ().accessPllX ().attach2 (mpAccess ().link (to)) ; + } + } + lap1 = clock () ; + vector < ObjectStream > osv (nl) ; + { + AccessIterator < vertex_STI > :: Handle w (containerPll ()) ; + for (w.first () ; ! w.done () ; w.next ()) w.item ().accessPllX ().packAll (osv) ; + } + { + AccessIterator < hedge_STI > :: Handle w (containerPll ()) ; + for (w.first () ; ! w.done () ; w.next ()) w.item ().accessPllX ().packAll (osv) ; + } + { + AccessIterator < hface_STI > :: Handle w (containerPll ()) ; + for (w.first () ; ! w.done () ; w.next ()) w.item ().accessPllX ().packAll (osv) ; + } + { + AccessIterator < helement_STI > :: Handle w (containerPll ()) ; + for (w.first () ; ! w.done () ; w.next ()) w.item ().accessPllX ().packAll (osv) ; + } + { + for (vector < ObjectStream > :: iterator i = osv.begin () ; i != osv.end () ; + (*i++).writeObject (MacroGridMoverIF :: ENDMARKER)) ; + } + lap2 = clock () ; + osv = mpAccess ().exchange (osv) ; + lap3 = clock () ; + { + DuneParallelGridMover pgm (containerPll ()) ; + pgm.unpackAll (osv) ; + } + lap4 = clock () ; + if (MacroGridBuilder :: debugOption (20)) { + cout << "**INFO GitterDunePll :: repartitionMacroGrid () [ass|pck|exc|upk|all] " ; + cout << setw (5) << (float)(lap1 - start)/(float)(CLOCKS_PER_SEC) << " " ; + cout << setw (5) << (float)(lap2 - lap1)/(float)(CLOCKS_PER_SEC) << " " ; + cout << setw (5) << (float)(lap3 - lap2)/(float)(CLOCKS_PER_SEC) << " " ; + cout << setw (5) << (float)(lap4 - lap3)/(float)(CLOCKS_PER_SEC) << " " ; + cout << setw (5) << (float)(lap4 - start)/(float)(CLOCKS_PER_SEC) << " sec." << endl ; + } + } + return ; +} +void GitterDunePll :: duneRepartitionMacroGrid (LoadBalancer :: DataBase & db, GatherScatterType & gs) { + + if (db.repartition (mpAccess (), LoadBalancer :: DataBase :: method (_ldbMethod))) { + const long start = clock () ; + long lap1 (start), lap2 (start), lap3 (start), lap4 (start) ; + mpAccess ().removeLinkage () ; + mpAccess ().insertRequestSymetric (db.scan ()) ; + const int me = mpAccess ().myrank (), nl = mpAccess ().nlinks () ; + { + AccessIterator < helement > :: Handle w (containerPll ()) ; + for (w.first () ; ! w.done () ; w.next ()) { + int to = db.getDestination (w.item ().accessPllX ().ldbVertexIndex ()) ; + if (me != to) + w.item ().accessPllX ().attach2 (mpAccess ().link (to)) ; + } + } + lap1 = clock () ; + vector < ObjectStream > osv (nl) ; + { + AccessIterator < vertex_STI > :: Handle w (containerPll ()) ; + for (w.first () ; ! w.done () ; w.next ()) w.item ().accessPllX ().packAll (osv) ; + } + { + AccessIterator < hedge_STI > :: Handle w (containerPll ()) ; + for (w.first () ; ! w.done () ; w.next ()) w.item ().accessPllX ().packAll (osv) ; + } + { + AccessIterator < hface_STI > :: Handle w (containerPll ()) ; + for (w.first () ; ! w.done () ; w.next ()) w.item ().accessPllX ().packAll (osv) ; + } + { + AccessIterator < helement_STI > :: Handle w (containerPll ()) ; + for (w.first () ; ! w.done () ; w.next ()) w.item ().accessPllX ().dunePackAll (osv,gs) ; + } + { + for (vector < ObjectStream > :: iterator i = osv.begin () ; i != osv.end () ; + (*i++).writeObject (MacroGridMoverIF :: ENDMARKER)) ; + } + lap2 = clock () ; + osv = mpAccess ().exchange (osv) ; + lap3 = clock () ; + { + DuneParallelGridMover pgm (containerPll ()) ; + pgm.duneUnpackAll (osv,gs) ; + } + lap4 = clock () ; + if (MacroGridBuilder :: debugOption (20)) { + cout << "**INFO GitterDunePll :: repartitionMacroGrid () [ass|pck|exc|upk|all] " ; + cout << setw (5) << (float)(lap1 - start)/(float)(CLOCKS_PER_SEC) << " " ; + cout << setw (5) << (float)(lap2 - lap1)/(float)(CLOCKS_PER_SEC) << " " ; + cout << setw (5) << (float)(lap3 - lap2)/(float)(CLOCKS_PER_SEC) << " " ; + cout << setw (5) << (float)(lap4 - lap3)/(float)(CLOCKS_PER_SEC) << " " ; + cout << setw (5) << (float)(lap4 - start)/(float)(CLOCKS_PER_SEC) << " sec." << endl ; + } + } + return ; +} + +#endif -- GitLab