Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 3 : 4 : // This library is free software; you can redistribute it and/or 5 : // modify it under the terms of the GNU Lesser General Public 6 : // License as published by the Free Software Foundation; either 7 : // version 2.1 of the License, or (at your option) any later version. 8 : 9 : // This library is distributed in the hope that it will be useful, 10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : // Lesser General Public License for more details. 13 : 14 : // You should have received a copy of the GNU Lesser General Public 15 : // License along with this library; if not, write to the Free Software 16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : 18 : // Local includes 19 : #include "libmesh/face_tri3_subdivision.h" 20 : #include "libmesh/mesh_subdivision_support.h" 21 : #include "libmesh/enum_order.h" 22 : 23 : namespace libMesh 24 : { 25 : 26 : 27 : 28 : // ------------------------------------------------------------ 29 : // Tri3 subdivision class member functions 30 : 31 60799 : Tri3Subdivision::Tri3Subdivision(Elem * p) : 32 : Tri3(p), 33 60799 : _subdivision_updated(p ? true : false), 34 62585 : _is_ghost(p ? true : false) 35 : { 36 60799 : if (p) 37 : { 38 0 : libmesh_assert_equal_to(p->type(), TRI3SUBDIVISION); 39 0 : Tri3Subdivision * sd_elem = static_cast<Tri3Subdivision *>(p); 40 0 : _is_ghost = sd_elem->is_ghost(); 41 : 42 0 : if (!_is_ghost) 43 : { 44 0 : _ordered_nodes[0] = sd_elem->get_ordered_node(0); 45 0 : _ordered_nodes[1] = sd_elem->get_ordered_node(1); 46 0 : _ordered_nodes[2] = sd_elem->get_ordered_node(2); 47 : } 48 : } 49 60799 : } 50 : 51 : 52 : 53 119360 : Order Tri3Subdivision::default_order() const 54 : { 55 119360 : return FOURTH; 56 : } 57 : 58 : 59 : 60 18176 : void Tri3Subdivision::prepare_subdivision_properties() 61 : { 62 : /* 63 : * Find the index of the irregular vertex, if any. 64 : * The current implementation can only handle triangles with 65 : * no more than one irregular vertex. That is, a vertex with 66 : * valence != 6. 67 : */ 68 512 : unsigned int irregular_idx = 0; 69 72704 : for (unsigned int i = 0; i < 3; ++i) 70 : { 71 56064 : if (this->node_ptr(i)->valence() != 6) 72 : { 73 8 : irregular_idx = i; 74 292 : libmesh_error_msg_if(this->node_ptr(MeshTools::Subdivision::next[i])->valence() != 6 || 75 : this->node_ptr(MeshTools::Subdivision::prev[i])->valence() != 6, 76 : "Error: The mesh contains elements with more than one irregular vertex!"); 77 : } 78 : } 79 : 80 : /* 81 : * Rotate ordered vertices such that ordered_nodes[0] is the 82 : * irregular vertex. Doing this once in advance lets the evaluation 83 : * of subdivision interpolation be much more efficient afterward. 84 : */ 85 18176 : switch (irregular_idx) 86 : { 87 17892 : case 0: 88 18396 : _ordered_nodes[0] = this->node_ptr(0); 89 17892 : _ordered_nodes[1] = this->node_ptr(1); 90 17892 : _ordered_nodes[2] = this->node_ptr(2); 91 17892 : break; 92 0 : case 1: 93 0 : _ordered_nodes[0] = this->node_ptr(1); 94 0 : _ordered_nodes[1] = this->node_ptr(2); 95 0 : _ordered_nodes[2] = this->node_ptr(0); 96 0 : break; 97 284 : case 2: 98 292 : _ordered_nodes[0] = this->node_ptr(2); 99 284 : _ordered_nodes[1] = this->node_ptr(0); 100 284 : _ordered_nodes[2] = this->node_ptr(1); 101 284 : break; 102 0 : default: 103 0 : libmesh_error_msg("Unrecognized irregular_idx = " << irregular_idx); 104 : } 105 : 106 18176 : _subdivision_updated = true; 107 18176 : } 108 : 109 : 110 481690 : unsigned int Tri3Subdivision::local_node_number(unsigned int node_id) const 111 : { 112 481690 : return (_nodes[0]->id() == node_id) ? 0 : ( (_nodes[1]->id() == node_id) ? 1 : ( (_nodes[2]->id() == node_id) ? 2 : 3 ) ); 113 : } 114 : 115 : 116 49977 : unsigned int Tri3Subdivision::get_ordered_valence(unsigned int node_id) const 117 : { 118 4640 : libmesh_assert_less(node_id, n_neighbors()); 119 4640 : libmesh_assert(_subdivision_updated); 120 49977 : return get_ordered_node(node_id)->valence(); 121 : } 122 : 123 : 124 192260 : Node * Tri3Subdivision::get_ordered_node(unsigned int node_id) const 125 : { 126 19360 : libmesh_assert_less(node_id, 3); 127 19360 : libmesh_assert(_subdivision_updated); 128 192260 : return _ordered_nodes[node_id]; 129 : } 130 : 131 : } // namespace libMesh