CoarseningManager1d.cc 4.44 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "CoarseningManager1d.h"
#include "Mesh.h"
#include "AdaptStationary.h"
#include "AdaptInstationary.h"
#include "Traverse.h"
#include "MacroElement.h"
#include "RCNeighbourList.h"
#include "FixVec.h"
#include "DOFIndexed.h"

namespace AMDiS {

  Flag CoarseningManager1d::coarsenMesh(Mesh *aMesh)
  {
    mesh = aMesh;

17
    std::deque<MacroElement*>::const_iterator mel;
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    int n_elements = mesh->getNumberOfLeaves();

    for (mel = mesh->firstMacroElement(); 
	 mel != mesh->endOfMacroElements(); 
	 mel++) 
      {
	coarsenRecursive(dynamic_cast<Line*>(const_cast<Element*>((*mel)->getElement())));
      }

    return(mesh->getNumberOfLeaves() < n_elements ? MESH_COARSENED : Flag(0));
  }

  int CoarseningManager1d::coarsenRecursive(Line *parent)
  {
    FUNCNAME("CoarseningManager1d::coarsenRecursive");
    int  mark;

    INFO(0,2)("\n");
    if (parent->isLeaf())  // leaf element, clean element marker
      {
	mark = parent->getMark();
	parent->setMark(0);
	return(mark);
      }
    else {                 // no leaf element, first coarse children
      Line *child[2];

      int  mark0 = coarsenRecursive(dynamic_cast<Line*>(const_cast<Element*>(parent->getChild(0))));
      int  mark1 = coarsenRecursive(dynamic_cast<Line*>(const_cast<Element*>( parent->getChild(1))));

      mark = max(mark0, mark1);

      child[0] = dynamic_cast<Line*>(const_cast<Element*>( parent->getChild(0)));
      child[1] = dynamic_cast<Line*>(const_cast<Element*>( parent->getChild(1))); 

      if (mark >= 0) {     // element must not be coarsend
	parent->setMark(0);
	if (child[0]) {
	  child[0]->setMark(0);
	  child[1]->setMark(0);
	}

	return(0);
      }

      /*--------------------------------------------------------------------------*/
      /*--- and now coarsen child[0] and child[1] into parent                  ---*/
      /*--------------------------------------------------------------------------*/
  
      /*--------------------------------------------------------------------------*/
      /*--- hand DOFs from children to parent, and add DOF at center           ---*/
      /*--------------------------------------------------------------------------*/

      if (mesh->getNumberOfDOFs(VERTEX) && !mesh->queryCoarseDOFs()) {
	int node = mesh->getNode(VERTEX);
	parent->setDOF(node+0, const_cast<int*>( child[0]->getDOF(node+0)));
	parent->setDOF(node+1, const_cast<int*>( child[1]->getDOF(node+1)));
      }

      if (mesh->getNumberOfDOFs(CENTER) && !mesh->queryCoarseDOFs()) {
	parent->setDOF(mesh->getNode(CENTER), mesh->getDOF(CENTER));
      }

      /*--------------------------------------------------------------------------*/
      /*  restrict dof vectors to the parents on the patch                        */
      /*--------------------------------------------------------------------------*/


      RCNeighbourList coarsenList(1); // = {{nil, 0, 0}};
      coarsenList.setElement(0, parent);
      int iadmin;
      int nrAdmin = mesh->getNumberOfDOFAdmin();
      for(iadmin = 0; iadmin < nrAdmin; iadmin++) {
91
	std::list<DOFIndexedBase*>::iterator it;
92
	DOFAdmin* admin = const_cast<DOFAdmin*>(&(mesh->getDOFAdmin(iadmin)));
93
	std::list<DOFIndexedBase*>::iterator end = admin->endDOFIndexed();
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
	for(it = admin->beginDOFIndexed(); it != end; ++it)
	  (*it)->coarseRestrict(coarsenList, 1);
      }
 

      /*--------------------------------------------------------------------------*/
      /*--- remove all DOFs of children that are not used anymore              ---*/
      /*--------------------------------------------------------------------------*/

      if (mesh->getNumberOfDOFs(VERTEX))    /*---  midpoint of parent          ---*/
	{
	  mesh->freeDOF(const_cast<int*>( child[1]->getDOF(mesh->getNode(VERTEX))), VERTEX);
	}

      if (mesh->getNumberOfDOFs(CENTER))    /*--- center of the children       ---*/
	{
	  mesh->freeDOF(const_cast<int*>( child[0]->getDOF(mesh->getNode(CENTER))), CENTER);
	  mesh->freeDOF(const_cast<int*>( child[1]->getDOF(mesh->getNode(CENTER))), CENTER);
	}

      parent->coarsenElementData(child[0], child[1]);

      parent->setFirstChild(NULL);
      parent->setSecondChild(NULL);

      mesh->freeElement(child[0]);
      mesh->freeElement(child[1]);

      mesh->incrementNumberOfLeaves(-1);
      mesh->incrementNumberOfElements(-2);
      mesh->incrementNumberOfVertices(-1);

      mark++;
127
      parent->setMark(std::min(mark,0));
128
129
130
131
132
133
134
135

      return(parent->getMark());
    }

    return(0);  /*--- statement never reached                              ---*/
  }

}