#ifndef FILE_PARALLELTOP #define FILE_PARALLELTOP #include extern int ntasks; class ParallelMeshTopology { const Mesh & mesh; // number of local elements, vertices, points (?), edges, faces int ne, nv, np, ned, nfa; // number of local segments and surface elements int nseg, nsurfel; // number of global elements, vertices, ???, faces int neglob, nvglob; int nparel; int nfaglob; /** mapping from local to distant vertex number each row of the table corresponds to one vertex each row contains a list of pairs (procnr, dist_vnum) */ TABLE loc2distvert; TABLE loc2distedge, loc2distface, loc2distel; TABLE loc2distsegm, loc2distsurfel; BitArray * isexchangeface, * isexchangevert, * isexchangeedge, * isexchangeel; BitArray isghostedge, isghostface; bool coarseupdate; int overlap; public: ParallelMeshTopology (const Mesh & amesh); ~ParallelMeshTopology (); /// set number of local vertices, reset sizes of loc2dist_vert, isexchangevert... void SetNV ( int anv ); void SetNE ( int ane ); void SetNSE ( int anse ); void SetNSegm ( int anseg ); void Reset (); void SetLoc2Glob_Vert ( int locnum, int globnum ) { loc2distvert[locnum][0] = globnum; } void SetLoc2Glob_VolEl ( int locnum, int globnum ) { loc2distel[locnum-1][0] = globnum; } void SetLoc2Glob_SurfEl ( int locnum, int globnum ) { loc2distsurfel[locnum-1][0] = globnum; } void SetLoc2Glob_Segm ( int locnum, int globnum ) { loc2distsegm[locnum-1][0] = globnum; } int GetLoc2Glob_Vert ( int locnum ) const { return loc2distvert[locnum][0]; } int GetLoc2Glob_VolEl ( int locnum ) const { return loc2distel[locnum-1][0]; } void GetVertNeighbours ( int vnum, Array & dests ) const; int Glob2Loc_SurfEl ( int globnum ); int Glob2Loc_VolEl ( int globnum ); int Glob2Loc_Segm ( int globnum ); int Glob2Loc_Vert ( int globnum ); int GetNDistantPNums ( int locpnum ) const { return loc2distvert[locpnum].Size() / 2 + 1; } int GetNDistantFaceNums ( int locfacenum ) const { return loc2distface[locfacenum-1].Size() / 2 + 1; } int GetNDistantEdgeNums ( int locedgenum ) const { return loc2distedge[locedgenum-1].Size() / 2 + 1; } int GetNDistantElNums ( int locelnum ) const { return loc2distel[locelnum-1].Size() / 2 + 1; } int GetDistantPNum ( int proc, int locpnum ) const; int GetDistantEdgeNum ( int proc, int locedgenum ) const; int GetDistantFaceNum ( int proc, int locedgenum ) const; int GetDistantElNum ( int proc, int locelnum ) const; int GetDistantPNums ( int locpnum, int * distpnums ) const; int GetDistantEdgeNums ( int locedgenum, int * distedgenums ) const; int GetDistantFaceNums ( int locedgenum, int * distfacenums ) const; int GetDistantElNums ( int locelnum, int * distfacenums ) const; void Print() const; void SetExchangeFace ( int fnr ) { isexchangeface->Set( (fnr-1)*(ntasks+1) ); } void SetExchangeVert ( int vnum ) { isexchangevert->Set( (vnum-1)*(ntasks+1) ); } void SetExchangeElement ( int elnum ) { isexchangeel->Set((elnum-1)*(ntasks+1) ); } void SetExchangeEdge ( int ednum ) { isexchangeedge->Set ((ednum-1)*(ntasks+1)); } // fuer diese Fkts kann man ja O(N) - bitarrays lassen bool IsExchangeVert ( PointIndex vnum ) const { return loc2distvert[vnum].Size() > 1; // return isexchangevert->Test((vnum-1)*(ntasks+1)); } bool IsExchangeEdge ( int ednum ) const { /* if ( isexchangeedge->Test( (ednum-1)*(ntasks+1) ) != ( loc2distedge[ednum-1].Size() > 1) ) { cerr << "isexedge differs, id = " << id << ", ednum = " << ednum << endl; } */ // return loc2distedge[ednum-1].Size() > 1; int i = (ednum-1)*(ntasks+1); return isexchangeedge->Test(i); } bool IsExchangeFace ( int fnum ) const { /* if ( isexchangeface->Test( (fnum-1)*(ntasks+1) ) != ( loc2distface[fnum-1].Size() > 1) ) { cerr << "it differs, id = " << id << ", fnum = " << fnum << endl; } */ // nur hier funktioniert's so nicht ???? (JS) // return loc2distface[fnum-1].Size() > 1; return isexchangeface->Test( (fnum-1)*(ntasks+1) ); } bool IsExchangeElement ( int elnum ) const { // return loc2distel[elnum-1].Size() > 1; return isexchangeel->Test((elnum-1)*(ntasks+1)); } bool IsExchangeSEl ( int selnum ) const { return loc2distsurfel[selnum-1].Size() > 1; } void SetExchangeFace (int dest, int fnr ) { // isexchangeface->Set((fnr-1)*(ntasks+1) + (dest+1)); } void SetExchangeVert (int dest, int vnum ) { // isexchangevert->Set((vnum-1)*(ntasks+1) + (dest+1) ); } void SetExchangeElement (int dest, int vnum ) { isexchangeel->Set( (vnum-1)*(ntasks+1) + (dest+1) ); } void SetExchangeEdge (int dest, int ednum ) { // isexchangeedge->Set ( (ednum-1)*(ntasks+1) + (dest+1) ); } bool IsExchangeVert (int dest, int vnum ) const { FlatArray exchange = loc2distvert[vnum]; for (int i = 1; i < exchange.Size(); i += 2) if (exchange[i] == dest) return true; return false; // return isexchangevert->Test((vnum-1)*(ntasks+1) + (dest+1) ); } bool IsExchangeEdge (int dest, int ednum ) const { FlatArray exchange = loc2distedge[ednum-1]; for (int i = 1; i < exchange.Size(); i += 2) if (exchange[i] == dest) return true; return false; // return isexchangeedge->Test((ednum-1)*(ntasks+1) + (dest+1)); } bool IsExchangeFace (int dest, int fnum ) const { FlatArray exchange = loc2distface[fnum-1]; for (int i = 1; i < exchange.Size(); i += 2) if (exchange[i] == dest) return true; return false; // return isexchangeface->Test((fnum-1)*(ntasks+1) + (dest+1) ); } bool IsExchangeElement (int dest, int elnum ) const { // das geht auch nicht /* FlatArray exchange = loc2distel[elnum-1]; for (int i = 1; i < exchange.Size(); i += 2) if (exchange[i] == dest) return true; return false; */ return isexchangeel->Test((elnum-1)*(ntasks+1) + (dest+1)); } int Overlap() const { return overlap; } int IncreaseOverlap () { overlap++; return overlap; } void Update(); void UpdateCoarseGrid(); void UpdateCoarseGridOverlap(); void UpdateRefinement (); void UpdateTopology (); void UpdateExchangeElements(); void UpdateCoarseGridGlobal(); bool DoCoarseUpdate() const { return !coarseupdate; } void SetDistantFaceNum ( int dest, int locnum, int distnum ); void SetDistantPNum ( int dest, int locnum, int distnum ); void SetDistantEdgeNum ( int dest, int locnum, int distnum ); void SetDistantEl ( int dest, int locnum, int distnum ); void SetDistantSurfEl ( int dest, int locnum, int distnum ); void SetDistantSegm ( int dest, int locnum, int distnum ); bool IsGhostEl ( int elnum ) const { return mesh.VolumeElement(elnum).IsGhost(); } bool IsGhostFace ( int fanum ) const { return isghostface.Test(fanum-1); } bool IsGhostEdge ( int ednum ) const { return isghostedge.Test(ednum-1); } bool IsGhostVert ( int pnum ) const { return mesh.Point(pnum).IsGhost(); } // inline void SetGhostVert ( const int pnum ) // { isghostvert.Set(pnum-1); } void SetGhostEdge ( int ednum ) { isghostedge.Set(ednum-1); } void ClearGhostEdge ( int ednum ) { isghostedge.Clear(ednum-1); } void SetGhostFace ( int fanum ) { isghostface.Set(fanum-1); } void ClearGhostFace ( int fanum ) { isghostface.Clear(fanum-1); } bool IsElementInPartition ( int elnum, int dest ) const { return IsExchangeElement ( dest, elnum); } void SetElementInPartition ( int elnum, int dest ) { SetExchangeElement ( dest, elnum ); } void SetNVGlob ( int anvglob ) { nvglob = anvglob; } void SetNEGlob ( int aneglob ) { neglob = aneglob; } int GetNVGlob () { return nvglob; } int GetNEGlob () { return neglob; } }; #endif