DofComm.h 5.84 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
// ==  http://www.amdis-fem.org                                              ==
// ==                                                                        ==
// ============================================================================
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology 
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.



/** \file DofComm.h */

#ifndef AMDIS_DOF_COMM_H
#define AMDIS_DOF_COMM_H

#include <map>
27
#include "parallel/ParallelTypes.h"
28 29 30 31 32 33 34 35 36 37
#include "FiniteElemSpace.h"
#include "Global.h"

namespace AMDiS {

  using namespace std;

  class DofComm
  {
  public:
38
    DofComm() 
39 40 41
      : recvDofs(1),
	sendDofs(1),
	periodicDofs(0)
42
    {}
43 44 45
    
    typedef map<const FiniteElemSpace*, DofContainer> FeMapType;
    typedef FeMapType::iterator FeMapIter;
46
    typedef map<int, FeMapType> DataType;
47
    typedef DataType::iterator DataIter;
48 49
    // meshLevel: map[rank -> map[feSpace -> DofContainer]]
    typedef vector<DataType> LevelDataType;
50

51
    void init(int n, vector<const FiniteElemSpace*> &fe)
52
    {
53 54 55 56
      FUNCNAME("DofComm::init()");

      TEST_EXIT_DBG(n >= 1)("Should not happen!\n");

57 58 59
      nLevel = n;
      feSpaces = fe;

60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
      sendDofs.clear();
      recvDofs.clear();
      periodicDofs.clear();

      sendDofs.resize(nLevel);
      recvDofs.resize(nLevel);
      periodicDofs.resize(nLevel);
    }

    void create(InteriorBoundary &boundary);

    LevelDataType& getSendDofs()
    {
      return sendDofs;
    }

    LevelDataType& getRecvDofs()
    {
      return recvDofs;
79 80
    }

81
    LevelDataType& getPeriodicDofs()
82
    {
83
      return periodicDofs;
84 85
    }

86 87 88 89 90
    // Writes all data of this object to an output stream.
    void serialize(ostream &out)
    {
      ERROR_EXIT("MUST BE IMPLEMENTED!\n");
    }
91

92 93 94 95 96 97 98 99 100 101 102 103 104
    // Reads the object data from an input stream.
    void deserialize(istream &in, 
		     map<const FiniteElemSpace*, map<int, const DegreeOfFreedom*> > dofIndexMap)
    {
      ERROR_EXIT("MUST BE IMPLEMENTED!\n");
    }

    int getNumberDofs(LevelDataType &data, 
		      int level, 
		      const FiniteElemSpace *feSpace);

  protected:
    void createContainer(RankToBoundMap &boundary, LevelDataType &data);
105

106
  protected:
107 108 109 110 111 112 113 114 115 116 117 118 119 120
    /// This map contains for each rank the list of DOFs the current rank must 
    /// end to exchange solution DOFs at the interior boundaries.
    LevelDataType sendDofs;

    /// This map contains on each rank the list of DOFs from which the current 
    /// rank will receive DOF values (i.e., this are all DOFs at an interior 
    /// boundary). The DOF indices are given in rank's local numbering.
    LevelDataType recvDofs;

    /// This map contains on each rank a list of DOFs along the interior bound-
    /// aries to communicate with other ranks. The DOF indices are given in rank's
    /// local numbering. Periodic boundaries within one subdomain are not 
    /// considered here. 
    LevelDataType periodicDofs;
121

122 123 124 125
    int nLevel;

    vector<const FiniteElemSpace*> feSpaces;

126 127 128 129 130 131
    friend class Iterator;

  public:
    class Iterator
    {
    public:
132
      Iterator(LevelDataType &d,
133
	       const FiniteElemSpace *fe = NULL)
134
	: data(d),
135
	  dofCounter(-1),
136 137
	  traverseFeSpace(fe),
	  traverseLevel(0)
138
      {
139 140
	goFirst();
      }
141

142
      Iterator(LevelDataType &d,
143 144
	       int level,
	       const FiniteElemSpace *fe = NULL)
145
	: data(d),
146 147 148 149 150
	  dofCounter(-1),
	  traverseFeSpace(fe),
	  traverseLevel(level)
      {
	goFirst();
151 152 153 154
      }

      inline bool end()
      {
155
	return (dataIter == data[traverseLevel].end());
156 157 158 159
      }
      
      inline void nextRank()
      {
160 161 162
	do {
	  ++dataIter;
	} while (setNextFeMap() == false);
163 164 165 166 167 168 169
      }

      inline void nextFeSpace()
      {
	++feMapIter;
      }

170 171 172 173
      inline void next()
      {
	++feMapIter;
	if (feMapIter == dataIter->second.end()) {
174 175 176
	  do {
	    ++dataIter;
	  } while (setNextFeMap() == false);
177 178 179 180 181 182
	} else {
	  dofIter = feMapIter->second.begin();
	  dofCounter = 0;
	}
      }

183 184 185 186 187 188 189 190 191 192 193 194
      inline void beginDofIter(const FiniteElemSpace *fe = NULL)
      {
	FUNCNAME("DofComm::Iterator::beginDofIter()");

	if (fe != NULL) {
	  feMapIter = dataIter->second.begin();

	  while (feMapIter->first != fe &&
		 feMapIter != dataIter->second.end())
	    ++feMapIter;
	}

195 196 197 198
	if (feMapIter != dataIter->second.end()) {
	  dofIter = feMapIter->second.begin();
	  dofCounter = 0;
	}
199 200 201 202
      }

      inline bool endDofIter()
      {
203 204 205
	if (feMapIter == dataIter->second.end())
	  return true;

206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
	return (dofIter == feMapIter->second.end());
      }
      
      inline void nextDof()
      {
	++dofIter;
	++dofCounter;
      }

      inline int getRank()
      {
	return dataIter->first;
      }

      inline const FiniteElemSpace* getFeSpace()
      {
	return feMapIter->first;
      }

      inline DofContainer& getDofs()
      {
	return feMapIter->second;
      }

      inline const DegreeOfFreedom* getDof()
      {
	return *dofIter;
      }

      inline DegreeOfFreedom getDofIndex()
      {
	return **dofIter;
      }

      inline int getDofCounter()
      {
	return dofCounter;
      }

    protected:
246 247
      void goFirst()
      {
248
	dataIter = data[traverseLevel].begin();
249 250 251 252 253

	while (setNextFeMap() == false)
	  ++dataIter;
      }

254
      bool setNextFeMap();
255 256

    protected:
257
      LevelDataType &data;
258 259 260 261 262 263 264 265 266 267
      
      DofComm::DataIter dataIter;
      
      DofComm::FeMapIter feMapIter;

      DofContainer::iterator dofIter;

      int dofCounter;

      const FiniteElemSpace *traverseFeSpace;
268 269

      int traverseLevel;
270 271 272 273 274 275 276 277
    };


  };

}

#endif // AMDIS_DOF_COMM_H