PageRenderTime 54ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/dolfin/refinement/BisectionRefinement.cpp

https://bitbucket.org/mylese/dolfin
C++ | 181 lines | 47 code | 14 blank | 120 comment | 4 complexity | e21dff8c71c670af6898172cb28c6e27 MD5 | raw file
  1. // Copyright (C) 2006 Johan Hoffman
  2. //
  3. // This file is part of DOLFIN.
  4. //
  5. // DOLFIN is free software: you can redistribute it and/or modify
  6. // it under the terms of the GNU Lesser General Public License as published by
  7. // the Free Software Foundation, either version 3 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // DOLFIN is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU Lesser General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU Lesser General Public License
  16. // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
  17. //
  18. // Modified by Anders Logg, 2009-2011.
  19. // Modified by Garth N. Wells, 2010-2011.
  20. // Modified by Marie E. Rognes, 2011.
  21. //
  22. // First added: 2006-11-01
  23. // Last changed: 2011-04-07
  24. #include <memory>
  25. #include <dolfin/log/dolfin_log.h>
  26. #include <dolfin/mesh/Mesh.h>
  27. #include <dolfin/mesh/Facet.h>
  28. #include <dolfin/mesh/Cell.h>
  29. #include <dolfin/mesh/MeshFunction.h>
  30. #include "RivaraRefinement.h"
  31. #include "BisectionRefinement.h"
  32. using namespace dolfin;
  33. //-----------------------------------------------------------------------------
  34. void BisectionRefinement::refine_by_recursive_bisection(Mesh& refined_mesh,
  35. const Mesh& mesh, const MeshFunction<bool>& cell_marker)
  36. {
  37. not_working_in_parallel("BisectionRefinement::refine");
  38. // Transformation maps
  39. MeshFunction<std::size_t> cell_map;
  40. std::vector<int> facet_map;
  41. // Call Rivara refinement
  42. RivaraRefinement::refine(refined_mesh, mesh, cell_marker, cell_map,
  43. facet_map);
  44. // Store child->parent cell and facet information as mesh data
  45. const std::size_t D = refined_mesh.topology().dim();
  46. std::vector<std::size_t>& cf
  47. = refined_mesh.data().create_array("parent_cell", D);
  48. cf.resize(refined_mesh.num_cells());
  49. for(std::size_t i = 0; i < refined_mesh.num_cells(); i++)
  50. cf[i] = cell_map[i];
  51. // Create mesh function in refined mesh encoding parent facet maps
  52. refined_mesh.init(D - 1);
  53. std::vector<std::size_t>& ff
  54. = refined_mesh.data().create_array("parent_facet", D - 1);
  55. ff.resize(refined_mesh.num_facets());
  56. // Fill ff from facet_map
  57. mesh.init(D, D - 1);
  58. refined_mesh.init(D - 1, D);
  59. const std::size_t orphan = mesh.num_facets() + 1;
  60. for (FacetIterator facet(refined_mesh); !facet.end(); ++facet)
  61. {
  62. // Extract (arbitrary) cell that this facet belongs to
  63. Cell cell(refined_mesh, facet->entities(D)[0]);
  64. // Extract local facet number of this facet with that cell
  65. const std::size_t local_facet = cell.index(*facet);
  66. // Extract local facet index of parent cell (using facet_map)
  67. const std::size_t index = cell.index()*(D + 1) + local_facet;
  68. const int parent_local_facet_index = facet_map[index];
  69. // Ignore if orphaned facet
  70. if (parent_local_facet_index == -1)
  71. {
  72. ff[facet->index()] = orphan;
  73. continue;
  74. }
  75. // Get parent cell
  76. Cell parent_cell(mesh, cf[cell.index()]);
  77. // Figure out global facet number of local facet number of parent
  78. const std::size_t parent_facet_index
  79. = parent_cell.entities(D - 1)[parent_local_facet_index];
  80. // Assign parent facet index to this facet
  81. ff[facet->index()] = parent_facet_index;
  82. }
  83. }
  84. /*
  85. //-----------------------------------------------------------------------------
  86. void BisectionRefinement::transform_data(Mesh& newmesh, const Mesh& oldmesh,
  87. const MeshFunction<std::size_t>& cell_map,
  88. const std::vector<int>& facet_map)
  89. {
  90. newmesh.data().clear();
  91. // Rewrite materials
  92. if (oldmesh.data().mesh_function("material_indicators"))
  93. {
  94. std::shared_ptr<MeshFunction<std::size_t> > mat;
  95. mat = newmesh.data().create_mesh_function("material_indicators", newmesh.type().dim());
  96. for(std::size_t i=0; i < newmesh.num_cells(); i++)
  97. (*mat)[i] = (*oldmesh.data().mesh_function("material_indicators"))[cell_map[i]];
  98. log(TRACE, "MeshData MeshFunction \"material_indicators\" transformed.");
  99. }
  100. // Rewrite boundary indicators
  101. if (oldmesh.data().array("boundary facet cells")
  102. && oldmesh.data().array("boundary facet numbers")
  103. && oldmesh.data().array("boundary indicators"))
  104. {
  105. std::size_t num_ent = oldmesh.type().num_entities(0);
  106. std::vector<std::size_t>* bfc = oldmesh.data().array("boundary facet cells");
  107. std::vector<std::size_t>* bfn = oldmesh.data().array("boundary facet numbers");
  108. std::vector<std::size_t>* bi = oldmesh.data().array("boundary indicators");
  109. std::size_t bi_table_size = oldmesh.num_cells()*num_ent;
  110. std::vector<int> bi_table;
  111. bi_table.resize(bi_table_size);
  112. for(std::size_t i= 0 ; i< bi_table_size; i++)
  113. bi_table[i] = -1;
  114. for(std::size_t i = 0; i < bi->size(); i++)
  115. bi_table[(*bfc)[i]*num_ent+(*bfn)[i]] = (*bi)[i];
  116. // Empty loop to count elements
  117. std::size_t bi_size = 0;
  118. for(std::size_t c = 0; c < newmesh.num_cells(); c++)
  119. {
  120. for(std::size_t f = 0; f < num_ent; f++)
  121. {
  122. if (facet_map[c*num_ent+f] != -1)
  123. {
  124. std::size_t table_map = cell_map[c]*num_ent + facet_map[c*num_ent+f];
  125. if (bi_table[table_map] != -1)
  126. bi_size++;
  127. }
  128. }
  129. }
  130. // Create new MeshData std::vectors for boundary indicators
  131. std::vector<std::size_t>* bfc_new = newmesh.data().create_array("boundary facet cells", bi_size);
  132. std::vector<std::size_t>* bfn_new = newmesh.data().create_array("boundary facet numbers", bi_size);
  133. std::vector<std::size_t>* bi_new = newmesh.data().create_array("boundary indicators", bi_size);
  134. // Main transformation loop
  135. std::size_t number_bi = 0;
  136. for(std::size_t c = 0; c < newmesh.num_cells(); c++)
  137. {
  138. for(std::size_t f = 0; f < num_ent; f++)
  139. {
  140. if (facet_map[c*num_ent+f] != -1)
  141. {
  142. std::size_t table_map = cell_map[c]*num_ent + facet_map[c*num_ent+f];
  143. if (bi_table[table_map] != -1)
  144. {
  145. (*bfc_new)[number_bi] = c;
  146. (*bfn_new)[number_bi] = f;
  147. (*bi_new)[number_bi] = bi_table[table_map];
  148. number_bi++;
  149. }
  150. }
  151. }
  152. }
  153. log(TRACE, "MeshData \"boundary indicators\" transformed.");
  154. }
  155. }
  156. //-----------------------------------------------------------------------------
  157. */