Line data Source code
1 : /**********************************************************************/ 2 : /* DO NOT MODIFY THIS HEADER */ 3 : /* MAGPIE - Mesoscale Atomistic Glue Program for Integrated Execution */ 4 : /* */ 5 : /* Copyright 2017 Battelle Energy Alliance, LLC */ 6 : /* ALL RIGHTS RESERVED */ 7 : /**********************************************************************/ 8 : 9 : #include "PointLocatorRegularOrthogonalData.h" 10 : #include "MooseError.h" 11 : #include "libmesh/mesh_base.h" 12 : #include "libmesh/elem.h" 13 : 14 101 : PointLocatorRegularOrthogonalData::PointLocatorRegularOrthogonalData( 15 : const std::vector<unsigned int> & cell_count, 16 : const Point & min_corner, 17 : const Point & max_corner, 18 101 : const MeshBase & mesh) 19 101 : : _dim(cell_count.size()), 20 101 : _cell_count(cell_count), 21 101 : _min_corner(min_corner), 22 101 : _cell_size(max_corner - min_corner) 23 : { 24 : // determine total number of cells and their size 25 : unsigned int num_root_elems = 1; 26 373 : for (unsigned int i = 0; i < _dim; ++i) 27 : { 28 272 : if (_cell_count[i] == 0) 29 0 : mooseError("Cannot have zero cells in any spatial direction"); 30 : 31 272 : num_root_elems *= _cell_count[i]; 32 272 : _cell_size(i) /= _cell_count[i]; 33 : } 34 : 35 : // initialize cell storage 36 101 : _root_elems.assign(num_root_elems, nullptr); 37 : 38 : // sort all level 0 elements into the table 39 101 : auto el = mesh.level_elements_begin(0); 40 101 : const auto end_el = mesh.level_elements_end(0); 41 1375875 : for (; el != end_el; ++el) 42 : { 43 687887 : const Elem * elem = *el; 44 687887 : const unsigned int index = rootElementIndex(elem->vertex_average()); 45 687887 : _root_elems[index] = elem; 46 : } 47 : 48 : // sanity check 49 687988 : for (auto el : _root_elems) 50 687887 : if (el == nullptr) 51 0 : mooseError("Found a null root element"); 52 101 : } 53 : 54 : const Elem * 55 73445431 : PointLocatorRegularOrthogonalData::rootElement(const Point & p, Point & el_pos) const 56 : { 57 : unsigned int index = 0; 58 : const Point p0 = p - _min_corner; 59 : 60 288625325 : for (unsigned int i = 0; i < _dim; ++i) 61 : { 62 215205052 : const int n = p0(i) / _cell_size(i); 63 : 64 : // outside of mesh, return null 65 215205052 : if (n < 0 || n >= _cell_count[i]) 66 : return nullptr; 67 : 68 : // cell internal coordinates from 0..1 used for bisecting refined cells 69 215179894 : el_pos(i) = p0(i) / _cell_size(i) - n; 70 : 71 : // construct root element index 72 215179894 : index = index * _cell_count[i] + n; 73 : } 74 : 75 73420273 : return _root_elems[index]; 76 : } 77 : 78 : unsigned int 79 687887 : PointLocatorRegularOrthogonalData::rootElementIndex(const Point & p) const 80 : { 81 : unsigned int index = 0; 82 2707692 : for (unsigned int i = 0; i < _dim; ++i) 83 : { 84 2019805 : const int n = (p(i) - _min_corner(i)) / _cell_size(i); 85 : 86 2019805 : if (n < 0 || n >= _cell_count[i]) 87 0 : mooseError("Point not inside regular orthogonal mesh"); 88 : 89 2019805 : index = index * _cell_count[i] + n; 90 : } 91 : 92 687887 : return index; 93 : }