RefinementManager1d.cc 4.94 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
  int RefinementManager1d::recursiveRefineFunction(ElInfo* elInfo)
17
  {
18
    Line *el = dynamic_cast<Line*>(const_cast<Element*>(elInfo->getElement())), *child[2];
19

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

22
    if (elInfo->getProjection(0)) {
23
24
25
26
27
28
      traversePtr->newCoord(true);
    }

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

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
46
47
48
49
50
51
52
53
54

    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]);
  
    if (child[0]->getMark() > 0) traversePtr->doMoreRecursiveRefine = true;

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

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

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

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

67
68
69
70
71
72
73
    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)));
    }
74
75
76
77
78
79
80
81
82

    /*--------------------------------------------------------------------------*/
    /*  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();
83
    for (int iadmin = 0; iadmin < nrAdmin; iadmin++) {
84
      std::list<DOFIndexedBase*>::iterator it;
85
      DOFAdmin* admin = const_cast<DOFAdmin*>(&mesh->getDOFAdmin(iadmin));
86
      std::list<DOFIndexedBase*>::iterator end = admin->endDOFIndexed();
87
      for (it = admin->beginDOFIndexed(); it != end; it++)
88
89
90
	(*it)->refineInterpol(ref_list, 1);
    }

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

    return 0;
  }

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

    doMoreRecursiveRefine = true;
105
106
107
108
109
110
    while (doMoreRecursiveRefine) {
      doMoreRecursiveRefine = false;
      traversePtr = this;
      mesh->traverse(-1, Mesh::CALL_LEAF_EL | Mesh::FILL_BOUND | Mesh::FILL_COORDS,
		     recursiveRefineFunction);
    }
111
  
112
    nElements = mesh->getNumberOfLeaves() - nElements;
113

114
    if (newCoords) {
115
116
117
      setNewCoords(); // call of sub-class method  
    }

118
    return (nElements ? MESH_REFINED : Flag(0));
119
120
  }

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

126
    Projection *projector = elInfo->getProjection(0);
127

128
129
130
131
132
133
134
135
136
    if (el->getFirstChild() && projector && (!el->isNewCoordSet())) {
      WorldVector<double> *new_coord = NEW WorldVector<double>;
      
      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);
    }
137
138
139
140
141
142

    return 0;
  }

  void RefinementManager1d::setNewCoords()
  {
143
    Flag fillFlag = Mesh::CALL_EVERY_EL_PREORDER | Mesh::FILL_BOUND | Mesh::FILL_COORDS;
144
145
146
147
148
  
    mesh->traverse(-1, fillFlag, newCoordsFct);
  }

}