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

71
      if (mesh->getNumberOfDofs(VERTEX) && !mesh->queryCoarseDOFs()) {
72
	int node = mesh->getNode(VERTEX);
73 74
	parent->setDof(node+0, const_cast<int*>( child[0]->getDof(node+0)));
	parent->setDof(node+1, const_cast<int*>( child[1]->getDof(node+1)));
75 76
      }

77
      if (mesh->getNumberOfDofs(CENTER) && !mesh->queryCoarseDOFs()) {
78
	parent->setDof(mesh->getNode(CENTER), mesh->getDof(CENTER));
79 80 81 82 83 84 85 86 87 88 89 90
      }

      /*--------------------------------------------------------------------------*/
      /*  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
	for(it = admin->beginDOFIndexed(); it != end; ++it)
	  (*it)->coarseRestrict(coarsenList, 1);
      }
 

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

103
      if (mesh->getNumberOfDofs(VERTEX))    /*---  midpoint of parent          ---*/
104
	{
105
	  mesh->freeDof(const_cast<int*>( child[1]->getDof(mesh->getNode(VERTEX))), VERTEX);
106 107
	}

108
      if (mesh->getNumberOfDofs(CENTER))    /*--- center of the children       ---*/
109
	{
110 111
	  mesh->freeDof(const_cast<int*>( child[0]->getDof(mesh->getNode(CENTER))), CENTER);
	  mesh->freeDof(const_cast<int*>( child[1]->getDof(mesh->getNode(CENTER))), CENTER);
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
	}

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

}