CoarseningManager1d.cc 5.2 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/******************************************************************************
 *
 * AMDiS - Adaptive multidimensional simulations
 *
 * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
 * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
 *
 * Authors: 
 * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 *
 * This file is part of AMDiS
 *
 * See also license.opensource.txt in the distribution.
 * 
 ******************************************************************************/
20
21


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#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;

38
    std::deque<MacroElement*>::const_iterator mel;
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
    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))));

69
      mark = std::max(mark0, mark1);
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

      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           ---*/
      /*--------------------------------------------------------------------------*/

92
      if (mesh->getNumberOfDofs(VERTEX) && !mesh->queryCoarseDOFs()) {
93
	int node = mesh->getNode(VERTEX);
94
95
	parent->setDof(node+0, const_cast<DegreeOfFreedom*>( child[0]->getDof(node+0)));
	parent->setDof(node+1, const_cast<DegreeOfFreedom*>( child[1]->getDof(node+1)));
96
97
      }

98
      if (mesh->getNumberOfDofs(CENTER) && !mesh->queryCoarseDOFs()) {
99
	parent->setDof(mesh->getNode(CENTER), mesh->getDof(CENTER));
100
101
102
103
104
105
106
107
108
109
110
111
      }

      /*--------------------------------------------------------------------------*/
      /*  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++) {
112
	std::list<DOFIndexedBase*>::iterator it;
113
	DOFAdmin* admin = const_cast<DOFAdmin*>(&(mesh->getDofAdmin(iadmin)));
114
	std::list<DOFIndexedBase*>::iterator end = admin->endDOFIndexed();
115
116
117
118
119
120
121
122
123
	for(it = admin->beginDOFIndexed(); it != end; ++it)
	  (*it)->coarseRestrict(coarsenList, 1);
      }
 

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

124
      if (mesh->getNumberOfDofs(VERTEX))    /*---  midpoint of parent          ---*/
125
	{
126
	  mesh->freeDof(const_cast<DegreeOfFreedom*>( child[1]->getDof(mesh->getNode(VERTEX))), VERTEX);
127
128
	}

129
      if (mesh->getNumberOfDofs(CENTER))    /*--- center of the children       ---*/
130
	{
131
132
	  mesh->freeDof(const_cast<DegreeOfFreedom*>( child[0]->getDof(mesh->getNode(CENTER))), CENTER);
	  mesh->freeDof(const_cast<DegreeOfFreedom*>( child[1]->getDof(mesh->getNode(CENTER))), CENTER);
133
134
135
136
	}

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

137
138
      parent->setFirstChild(nullptr);
      parent->setSecondChild(nullptr);
139
140
141
142
143
144
145
146
147

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

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

      mark++;
148
      parent->setMark(std::min(mark,0));
149
150
151
152
153
154
155
156

      return(parent->getMark());
    }

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

}