Liebe Gitlab-Nutzer, lieber Gitlab-Nutzer,
es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Die Konten der externen Nutzer:innen sind über den Reiter "Standard" erreichbar.
Die Administratoren


Dear Gitlab user,
it is now possible to log in to our service using the ZIH login/LDAP. The accounts of external users can be accessed via the "Standard" tab.
The administrators

DOFAdmin.cc 9.11 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
#include <algorithm>

#include "QPsiPhi.h"
#include "BasisFunction.h"
#include "Boundary.h"
#include "DOFAdmin.h"
#include "ElInfo.h"
#include "Error.h"
#include "FiniteElemSpace.h"
#include "Mesh.h"
#include "DOFVector.h"
#include "DOFIterator.h"
13
#include "Serializer.h"
14 15 16 17 18 19 20 21 22

namespace AMDiS {

  const int DOFAdmin::sizeIncrement = 10;

  DOFAdmin::DOFAdmin(Mesh* m) 
    : mesh(m), 
      nrDOF(mesh->getDim(), NO_INIT),
      nr0DOF(mesh->getDim(), NO_INIT)
Thomas Witkowski's avatar
Thomas Witkowski committed
23 24 25
  { 
    init(); 
  }
26

27
  DOFAdmin::DOFAdmin(Mesh* m, std::string aName) 
28 29 30 31 32 33 34 35
    : name(aName), 
      mesh(m), 
      nrDOF(mesh->getDim(), NO_INIT),
      nr0DOF(mesh->getDim(), NO_INIT)
  { 
    init(); 
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
36 37 38
  DOFAdmin::~DOFAdmin() 
  {}

39 40
  void DOFAdmin::init()
  {
41 42 43 44 45
    firstHole = 0;
    size = 0;
    usedCount = 0;
    holeCount = 0;
    sizeUsed = 0;
46 47 48
    dofFree.clear();
  }

49 50
  DOFAdmin& DOFAdmin::operator=(const DOFAdmin& src) 
  {
51 52 53 54 55 56 57 58 59
    if (this != &src) { 
      mesh = src.mesh;
      name = src.name;
      dofFree = src.dofFree;
      firstHole = src.firstHole;
      size = src.size;
      usedCount = src.usedCount;
      holeCount = src.holeCount;
      sizeUsed = src.sizeUsed;
60
      for (int i = 0; i <= mesh->getDim(); i++) {
61
	nrDOF[i] = src.nrDOF[i];
62
	nr0DOF[i] = src.nr0DOF[i];
63
      }
64 65
      dofIndexedList = src.dofIndexedList;
      dofContainerList = src.dofContainerList;
66
    }
67

68 69 70 71 72 73 74 75 76
    return *this;
  }
  /****************************************************************************/
  /*      use a bit vector to indicate used/unused dofs			    */
  /*      storage needed: one bit per dof                     		    */
  /****************************************************************************/

  bool DOFAdmin::operator==(const DOFAdmin& ad) const
  {
77 78 79 80 81
    if (name != ad.name) 
      return false;
    if (mesh != ad.mesh) 
      return false;

82 83 84 85 86
    return true;
  }


  DOFAdmin::DOFAdmin(const DOFAdmin&)
87
  {
88 89 90
    FUNCNAME("DOFAdmin::DOFAdmin()");

    ERROR_EXIT("TODO\n");
91
  }
92

93 94
  void DOFAdmin::freeDOFIndex(int dof) 
  {    
95
    FUNCNAME("DOFAdmin::freeDOFIndex()");
96

97 98
    TEST_EXIT_DBG(usedCount > 0)("no dofs in use\n");
    TEST_EXIT_DBG((dof >= 0) && (dof < size))("invalid dof index %d\n",dof);
99

100 101
    std::list<DOFIndexedBase*>::iterator di;
    std::list<DOFIndexedBase*>::iterator end = dofIndexedList.end();
102

103
    for (di = dofIndexedList.begin(); di != end; ++di)
104 105
      (*di)->freeDOFContent(dof);

106 107
    std::list<DOFContainer*>::iterator dc;
    std::list<DOFContainer*>::iterator dcend = dofContainerList.end();
108

109
    for (dc = dofContainerList.begin(); dc != dcend; ++dc)
110 111 112
      (*dc)->freeDOFIndex(dof);

    dofFree[dof] = true;
113
    
114 115
    if (static_cast<int>(firstHole) > dof) 
      firstHole = dof;
116 117 118 119 120 121 122

    usedCount--;
    holeCount++;
  }

  int DOFAdmin::getDOFIndex()
  {
123
    FUNCNAME("DOFAdmin::getDOFIndex()");
124
    int dof = 0;
125 126

    // if there is a hole
127
    if (firstHole < static_cast<int>(dofFree.size())) {      
128
      TEST_EXIT_DBG(dofFree[firstHole])("no hole at firstHole!\n");
129 130 131 132 133
      // its no longer a hole
      dofFree[firstHole] = false;
      dof = firstHole;
      // search new hole
      int dfsize = static_cast<int>(dofFree.size());
134
      int i = firstHole + 1;
135 136
      for (; i < dfsize; i++)
	if (dofFree[i])
137
	  break;
138

139
      firstHole = i;
140
    } else {                    // if there is no hole
141
      // enlarge dof-list
142
      enlargeDOFLists();
143

144
      TEST_EXIT_DBG(firstHole < static_cast<int>(dofFree.size()))
145
	("no free entry after enlargeDOFLists\n");
146
      TEST_EXIT_DBG(dofFree[firstHole])("no free bit at firstHole\n");
147 148 149 150 151 152
      dofFree[firstHole] = false;
      dof = firstHole;
      firstHole++;
    }

    usedCount++;
153 154 155
    if (holeCount > 0) 
      holeCount--;
    sizeUsed = max(sizeUsed, dof + 1);
156

157
    return dof;
158 159 160 161
  }

  void DOFAdmin::enlargeDOFLists(int minsize)
  {
162
    FUNCNAME("DOFAdmin::enlargeDOFLists()");
163
  
164
    int old = size;
165 166 167
    if (minsize > 0)
      if (old > minsize) 
	return;
168
  
169
    int newval = max(minsize, static_cast<int>((dofFree.size() + sizeIncrement)));
170 171 172 173 174 175 176 177 178 179 180

    size = newval;
  
    // stl resizes dofFree to at least newval and sets all new values true
    dofFree.resize(newval, true);

    firstHole = old;
  
    // enlarge all vectors and matrices
    // but DOFVectors<int> don't have to be changed
  
181
    std::list<DOFIndexedBase*>::iterator di;
182
    for (di = dofIndexedList.begin(); di != dofIndexedList.end(); ++di)
183
      if ((*di)->getSize() < newval)
184
 	(*di)->resize(newval);
185 186
  }

187 188
  void DOFAdmin::addDOFIndexed(DOFIndexedBase* dofIndexed) 
  {
189
    FUNCNAME("DOFAdmin::addDOFIndexed()");
190

191
    TEST_EXIT(dofIndexed)("no dofIndexed\n");
192

193 194 195 196
#ifdef _OPENMP
#pragma omp critical (dofIndexAccess)
#endif
    {
197
      if (dofIndexed->getSize() < size)
198 199 200 201
	dofIndexed->resize(size);
      
      dofIndexedList.push_back(dofIndexed);
    }
202 203 204 205
  }

  void DOFAdmin::removeDOFIndexed(DOFIndexedBase* dofIndexed)
  {
206 207
    FUNCNAME("DOFAdmin::removeDOFIndexed()");

208 209 210 211 212 213 214 215 216 217 218 219 220
    bool removed = false;
#ifdef _OPENMP
#pragma omp critical (dofIndexAccess)
#endif
    {
      std::list<DOFIndexedBase*>::iterator it;
      std::list<DOFIndexedBase*>::iterator end = dofIndexedList.end();
      for (it = dofIndexedList.begin(); it != end; ++it) {
	if (*it == dofIndexed) {
	  dofIndexedList.erase(it);
	  removed = true;
	  break;
	}
221 222
      }
    }
223

224
    TEST_EXIT(removed)("DOFIndexed not in list\n");
225 226 227 228
  }

  void DOFAdmin::addDOFContainer(DOFContainer* cont)
  {
229
    FUNCNAME("DOFAdmin::addDOFContainer()");
230
    TEST_EXIT_DBG(cont)("no container\n");
231 232 233 234 235
    dofContainerList.push_back(cont);  
  }

  void DOFAdmin::removeDOFContainer(DOFContainer* cont)
  {
236 237
    FUNCNAME("DOFAdmin::removeDOFContainer()");

238 239
    std::list<DOFContainer*>::iterator it;
    std::list<DOFContainer*>::iterator end = dofContainerList.end();
240 241
    for (it = dofContainerList.begin(); it != end; ++it) {
      if (*it == cont) {
242 243 244 245 246 247 248
	dofContainerList.erase(it);
	return;
      }
    }
    ERROR("container not in list\n");
  }

249
  void DOFAdmin::compress(std::vector<DegreeOfFreedom> &new_dof)
250
  {
251
    FUNCNAME("DOFAdmin::compress()");
252 253 254 255 256 257 258

    // nothing to do ?
    if (size < 1) return;
    if (usedCount < 1) return;
    if (holeCount < 1) return;

    // vector to mark used dofs
259
    for (int i = 0; i < size; i++)
260 261 262 263
      new_dof[i] = -1;

    // mark used dofs
    DOFIteratorBase it(this, USED_DOFS);
264
    for (it.reset(); !it.end(); ++it)
265
      new_dof[it.getDOFIndex()] = 1;
266
    
267 268
    int n = 0, last = 0;
    for (int i = 0; i < size; i++) {             /* create a MONOTONE compress */
269 270 271 272 273 274
      if (new_dof[i] == 1) {
	new_dof[i] = n++;
	last = i;
      }
    }
  
275
    TEST_EXIT_DBG(n == usedCount)("count %d != usedCount %d\n", n, usedCount);
276 277
  
    // mark used dofs in compressed dofFree
278
    for (int i = 0; i < n; i++)
279
      dofFree[i] = false;
280

281
    // mark unused dofs in compressed dofFree
282
    for (int i = n; i < size; i++)
283 284 285 286 287 288 289
      dofFree[i] = true;

    firstHole = n;  
    holeCount = 0;
    sizeUsed  = n;
  
    // get index of first changed dof
290 291
    int first = last;
    for (int i = 0; i<size; i++) {
292 293 294 295 296 297
      if ((new_dof[i] < i) && (new_dof[i] >= 0)) {
	first = i;
	break;
      }
    }

298 299
    std::list<DOFIndexedBase*>::iterator di;
    std::list<DOFIndexedBase*>::iterator end = dofIndexedList.end();
300
    for (di = dofIndexedList.begin(); di != end; ++di)
301 302 303
      (*di)->compressDOFIndexed(first, last, new_dof);

  
304 305
    std::list<DOFContainer*>::iterator dc;
    std::list<DOFContainer*>::iterator endc = dofContainerList.end();
306
    for (dc = dofContainerList.begin(); dc != endc; dc++)
307 308 309
      (*dc)->compressDOFContainer(n, new_dof);
  }

310
  void DOFAdmin::setNumberOfDOFs(int i, int v) 
311
  { 
312 313 314
    FUNCNAME("DOFAdmin::setNumberOfDOFs()");

    TEST_EXIT_DBG(0 <= i && 4 > i)("Should not happen!\n");
315 316

    nrDOF[i] = v; 
317 318
  }

319 320
  void DOFAdmin::setNumberOfPreDOFs(int i, int v) 
  { 
321 322 323
    FUNCNAME("DOFAdmin::setNumberOfPreDOFs()");

    TEST_EXIT_DBG(0 <= i && 4 > i)("Should not happen!\n"); 
324 325

    nr0DOF[i] = v; 
326 327
  }

328 329 330 331 332
  int DOFAdmin::calcMemoryUsage()
  {
    return sizeof(DOFAdmin);
  }

333
  void DOFAdmin::serialize(std::ostream &out) 
334 335
  {
    // write name
Thomas Witkowski's avatar
Thomas Witkowski committed
336
    out << name << "\n";
337 338 339

    // write dofFree
    int s = static_cast<int>(dofFree.size());
340
    SerUtil::serialize(out, s);
341
    for (int i = 0; i < s; i++) {
342 343
      bool free = dofFree[i];     
      SerUtil::serialize(out, free);
344 345
    }

346 347 348 349 350
    SerUtil::serialize(out, firstHole);
    SerUtil::serialize(out, size);
    SerUtil::serialize(out, usedCount);
    SerUtil::serialize(out, holeCount);
    SerUtil::serialize(out, sizeUsed);
351 352 353 354 355

    nrDOF.serialize(out);
    nr0DOF.serialize(out);
}

356
  void DOFAdmin::deserialize(std::istream &in)
357 358 359 360 361 362 363
  {
    // read name
    in >> name;
    in.get();

    // read dofFree
    int s;
364
    SerUtil::deserialize(in, s);
365
    dofFree.resize(s);
366
    for (int i = 0; i < s; i++) {
367
      bool free;
368
      SerUtil::deserialize(in, free);
369 370 371
      dofFree[i] = free;
    }

372 373 374 375 376
    SerUtil::deserialize(in, firstHole);
    SerUtil::deserialize(in, size);
    SerUtil::deserialize(in, usedCount);
    SerUtil::deserialize(in, holeCount);
    SerUtil::deserialize(in, sizeUsed);
377 378 379 380

    nrDOF.deserialize(in);
    nr0DOF.deserialize(in);

381 382
    std::list<DOFIndexedBase*>::iterator di;
    std::list<DOFIndexedBase*>::iterator end = dofIndexedList.end();
383

384
    for (di = dofIndexedList.begin(); di != end; ++di)
385 386 387 388
      (*di)->resize(size);
  }

}