RefinementManager1d.cc 5.11 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "RefinementManager.h"
#include "Mesh.h"
#include "Traverse.h"
#include "ElInfo.h"
#include "DOFAdmin.h"
#include "AdaptStationary.h"
#include "AdaptInstationary.h"
#include "FixVec.h"
#include "RCNeighbourList.h"
#include "ProblemStatBase.h"
#include "DOFIndexed.h"
#include "Projection.h"

namespace AMDiS {

16
  void RefinementManager1d::recursiveRefineFunction(ElInfo* elInfo)
17
  {
18
19
    Line *el = 
      dynamic_cast<Line*>(const_cast<Element*>(elInfo->getElement())), *child[2];
20

21
    Mesh* mesh = elInfo->getMesh();
22

23
24
    if (elInfo->getProjection(0))
      newCoord(true);    
25
26

    if (el->getMark() <= 0)
27
      return;
28

29
30
    child[0] = dynamic_cast<Line*>(mesh->createNewElement(el));
    child[1] = dynamic_cast<Line*>(mesh->createNewElement(el));
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

    int mark = max(0, el->getMark() - 1);
    child[0]->setMark(mark);
    child[1]->setMark(mark);
    el->setMark(0);

    /*--------------------------------------------------------------------------*/
    /*  transfer hided data from parent to children                             */
    /*--------------------------------------------------------------------------*/

    el->refineElementData(child[0], child[1]);

    el->setFirstChild(child[0]);
    el->setSecondChild(child[1]);
  
46
47
    if (child[0]->getMark() > 0) 
      doMoreRecursiveRefine = true;
48
49
50
51
52
53
54
55

    DegreeOfFreedom *newVertexDOFs = mesh->getDOF(VERTEX);
    child[0]->setDOF(1, newVertexDOFs);
    child[1]->setDOF(0, newVertexDOFs);

    /*--------------------------------------------------------------------------*/
    /*  the other vertices are handed on from the parent                        */
    /*--------------------------------------------------------------------------*/
56
57
    child[0]->setDOF(0, const_cast<int*>(el->getDOF(0)));
    child[1]->setDOF(1, const_cast<int*>(el->getDOF(1)));
58
59
60
61
62
63
64
65
66
67

    /*--------------------------------------------------------------------------*/
    /*  there is one more leaf element, two hierachical elements,               */
    /*  one more vertex                                                         */
    /*--------------------------------------------------------------------------*/

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

68
69
70
71
72
73
74
    if (mesh->getNumberOfDOFs(CENTER)) {
      /*--------------------------------------------------------------------------*/
      /* there are dofs at the barycenter of the triangles                        */
      /*--------------------------------------------------------------------------*/
      child[0]->setDOF(mesh->getNode(CENTER), const_cast<int*>(mesh->getDOF(CENTER)));
      child[1]->setDOF(mesh->getNode(CENTER), const_cast<int*>(mesh->getDOF(CENTER)));
    }
75
76
77
78
79
80
81
82
83

    /*--------------------------------------------------------------------------*/
    /*  if there are functions to interpolate data to the finer grid, do so     */
    /*--------------------------------------------------------------------------*/
  
    RCNeighbourList  ref_list(1);  // = {{nil, 0, 0}};
    ref_list.setElement(0, el);
 
    int nrAdmin = mesh->getNumberOfDOFAdmin();
84
    for (int iadmin = 0; iadmin < nrAdmin; iadmin++) {
85
      std::list<DOFIndexedBase*>::iterator it;
86
      DOFAdmin* admin = const_cast<DOFAdmin*>(&mesh->getDOFAdmin(iadmin));
87
      std::list<DOFIndexedBase*>::iterator end = admin->endDOFIndexed();
88
      for (it = admin->beginDOFIndexed(); it != end; it++)
89
90
91
	(*it)->refineInterpol(ref_list, 1);
    }

92
    if (!mesh->queryCoarseDOFs() && mesh->getNumberOfDOFs(CENTER)) {
93
      mesh->freeDof(const_cast<int*>( el->getDOF(mesh->getNode(CENTER))), CENTER);
94
95
      el->setDOF(mesh->getNode(CENTER), NULL);
    }
96
97
98
99
100
  }

  Flag RefinementManager1d::refineMesh(Mesh *aMesh)
  {
    mesh = aMesh;
101
    int nElements = mesh->getNumberOfLeaves();
102
103

    doMoreRecursiveRefine = true;
104
105
    while (doMoreRecursiveRefine) {
      doMoreRecursiveRefine = false;
106
107
108
109
110
111
112
      
      TraverseStack stack;
      ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_BOUND | Mesh::FILL_COORDS);
      while (elInfo) {
	recursiveRefineFunction(elInfo);
	elInfo = stack.traverseNext(elInfo);
      }     
113
    }
114
  
115
    nElements = mesh->getNumberOfLeaves() - nElements;
116

117
    if (newCoords)
118
119
      setNewCoords(); // call of sub-class method  

120
    return (nElements ? MESH_REFINED : Flag(0));
121
122
  }

123
  void RefinementManager1d::newCoordsFct(ElInfo *elInfo)
124
  {
125
    Element *el = elInfo->getElement();
126
127
    int dow = Global::getGeo(WORLD);

128
    Projection *projector = elInfo->getProjection(0);
129

130
    if (el->getFirstChild() && projector && (!el->isNewCoordSet())) {
Thomas Witkowski's avatar
Thomas Witkowski committed
131
      WorldVector<double> *new_coord = new WorldVector<double>;
132
133
134
135
136
137
138
      
      for (int j = 0; j < dow; j++)
	(*new_coord)[j] = (elInfo->getCoord(0)[j] + elInfo->getCoord(1)[j]) * 0.5;
      
      projector->project(*new_coord);      
      el->setNewCoord(new_coord);
    }
139
140
141
142
  }

  void RefinementManager1d::setNewCoords()
  {
143
144
145
146
147
148
149
    TraverseStack stack;
    ElInfo *elInfo = stack.traverseFirst(mesh, -1, 
					 Mesh::CALL_EVERY_EL_PREORDER | Mesh::FILL_BOUND | Mesh::FILL_COORDS);
    while (elInfo) {
      newCoordsFct(elInfo);
      elInfo = stack.traverseNext(elInfo);
    }
150
151
152
  }

}