Branch data Line data Source code
1 : : /* *****************************************************************
2 : : MESQUITE -- The Mesh Quality Improvement Toolkit
3 : :
4 : : Copyright 2007 Sandia National Laboratories. Developed at the
5 : : University of Wisconsin--Madison under SNL contract number
6 : : 624796. The U.S. Government and the University of Wisconsin
7 : : retain certain rights to this software.
8 : :
9 : : This library is free software; you can redistribute it and/or
10 : : modify it under the terms of the GNU Lesser General Public
11 : : License as published by the Free Software Foundation; either
12 : : version 2.1 of the License, or (at your option) any later version.
13 : :
14 : : This library is distributed in the hope that it will be useful,
15 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : Lesser General Public License for more details.
18 : :
19 : : You should have received a copy of the GNU Lesser General Public License
20 : : (lgpl.txt) along with this library; if not, write to the Free Software
21 : : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 : :
23 : : (2009) [email protected]
24 : :
25 : : ***************************************************************** */
26 : :
27 : : /** \file SlaveBoundaryVertices.cpp
28 : : * \brief
29 : : * \author Jason Kraftcheck
30 : : */
31 : :
32 : : #include "SlaveBoundaryVertices.hpp"
33 : : #include "Settings.hpp"
34 : : #include "MsqError.hpp"
35 : : #include "MeshInterface.hpp"
36 : : #include "MsqVertex.hpp"
37 : :
38 : : #include <vector>
39 : : #include <algorithm>
40 : :
41 : : namespace MBMesquite
42 : : {
43 : :
44 : 2 : SlaveBoundaryVertices::SlaveBoundaryVertices( unsigned depth, unsigned dim ) : elemDepth( depth ), domainDoF( dim ) {}
45 : :
46 : 0 : std::string SlaveBoundaryVertices::get_name() const
47 : : {
48 [ # # ]: 0 : return "SlaveBoundaryVertices";
49 : : }
50 : :
51 : 1 : double SlaveBoundaryVertices::loop_over_mesh( MeshDomainAssoc* mesh_and_domain, const Settings* settings,
52 : : MsqError& err )
53 : : {
54 [ + - ]: 1 : Mesh* mesh = mesh_and_domain->get_mesh();
55 [ + - ]: 1 : MeshDomain* domain = mesh_and_domain->get_domain();
56 : :
57 [ + - ][ - + ]: 1 : if( settings->get_slaved_ho_node_mode() != Settings::SLAVE_CALCULATED )
58 : : {
59 : : MSQ_SETERR( err )
60 : : ( "Request to calculate higher-order node slaved status "
61 : : "when Settings::get_get_slaved_ho_node_mode() "
62 : : "!= SLAVE_CALCUALTED",
63 [ # # ][ # # ]: 0 : MsqError::INVALID_STATE );
64 : 0 : return 0.0;
65 : : }
66 : :
67 : : // If user said that we should treat fixed vertices as the
68 : : // boundary, but specified that fixed vertices are defined
69 : : // by the dimension of their geometric domain, then just
70 : : // do distance from the geometric domain.
71 : 1 : int dim = this->domainDoF;
72 [ + - ][ + - ]: 1 : if( dim >= 4 && settings->get_fixed_vertex_mode() != Settings::FIXED_FLAG ) dim = settings->get_fixed_vertex_mode();
[ - + ][ - + ]
[ # # ]
73 : :
74 : : // Create a map to contain vertex depth. Intiliaze all to
75 : : // elemDepth+1.
76 [ + - ]: 1 : std::vector< Mesh::VertexHandle > vertices;
77 [ + - ]: 1 : mesh->get_all_vertices( vertices, err );
78 [ + - ][ - + ]: 1 : MSQ_ERRZERO( err );
[ # # ][ # # ]
[ - + ]
79 [ - + ]: 1 : if( vertices.empty() ) return 0.0;
80 [ + - ]: 1 : std::sort( vertices.begin(), vertices.end() );
81 [ + - ]: 2 : std::vector< unsigned short > depth( vertices.size(), elemDepth + 1 );
82 [ + - ]: 2 : std::vector< bool > fixed;
83 [ + - ][ + - ]: 1 : mesh->vertices_get_fixed_flag( arrptr( vertices ), fixed, vertices.size(), err );
84 [ + - ][ - + ]: 1 : MSQ_ERRZERO( err );
[ # # ][ # # ]
[ - + ]
85 : :
86 : : // Initialize map with boundary vertices.
87 [ + - ]: 1 : if( dim >= 4 )
88 : : {
89 [ + + ]: 122 : for( size_t i = 0; i < vertices.size(); ++i )
90 [ + - ][ + + ]: 121 : if( fixed[i] ) depth[i] = 0;
[ + - ]
91 : : }
92 : : else
93 : : {
94 [ # # ]: 0 : if( !domain )
95 : : {
96 : : MSQ_SETERR( err )
97 : : ( "Request to calculate higher-order node slaved status "
98 : : "by distance from bounding domain without a domain.",
99 [ # # ][ # # ]: 0 : MsqError::INVALID_STATE );
100 : 0 : return 0.0;
101 : : }
102 : :
103 [ # # ]: 0 : std::vector< unsigned short > dof( vertices.size() );
104 [ # # ][ # # ]: 0 : domain->domain_DoF( arrptr( vertices ), arrptr( dof ), vertices.size(), err );
[ # # ]
105 [ # # ][ # # ]: 0 : MSQ_ERRZERO( err );
[ # # ][ # # ]
[ # # ]
106 [ # # ][ # # ]: 0 : for( size_t i = 0; i < vertices.size(); ++i )
107 [ # # ][ # # ]: 0 : if( dof[i] <= dim ) depth[i] = 0;
[ # # ]
108 : : }
109 : :
110 : : // Now iterate over elements repeatedly until we've found all of the
111 : : // elements near the boundary. This could be done much more efficiently
112 : : // using vertex-to-element adjacencies, but it is to common for
113 : : // applications not to implement that unless doing relaxation smoothing.
114 : : // This is O(elemDepth * elements.size() * ln(vertices.size()));
115 [ + - ]: 2 : std::vector< Mesh::ElementHandle > elements;
116 : 1 : std::vector< Mesh::ElementHandle >::const_iterator j, k;
117 [ + - ]: 2 : std::vector< Mesh::VertexHandle > conn;
118 [ + - ]: 2 : std::vector< size_t > junk( 2 );
119 [ + - ]: 1 : mesh->get_all_elements( elements, err );
120 [ + - ][ - + ]: 1 : MSQ_ERRZERO( err );
[ # # ][ # # ]
[ - + ]
121 [ - + ]: 1 : if( elements.empty() ) return 0.0;
122 : : bool some_changed;
123 [ + + ]: 2 : do
124 : : {
125 : 2 : some_changed = false;
126 [ + - ][ + - ]: 102 : for( j = elements.begin(); j != elements.end(); ++j )
[ + - ][ + + ]
127 : : {
128 : 100 : conn.clear();
129 : 100 : junk.clear();
130 [ + - ][ + - ]: 100 : mesh->elements_get_attached_vertices( &*j, 1, conn, junk, err );
131 [ + - ][ - + ]: 100 : MSQ_ERRZERO( err );
[ # # ][ # # ]
[ - + ]
132 : 100 : unsigned short elem_depth = elemDepth + 1;
133 [ + - ][ + - ]: 700 : for( k = conn.begin(); k != conn.end(); ++k )
[ + - ][ + + ]
134 : : {
135 [ + - ][ + - ]: 600 : size_t i = std::lower_bound( vertices.begin(), vertices.end(), *k ) - vertices.begin();
[ + - ]
136 [ - + ]: 600 : if( i == vertices.size() )
137 : : {
138 : : MSQ_SETERR( err )
139 [ # # ][ # # ]: 0 : ( "Invalid vertex handle in element connectivity list.", MsqError::INVALID_MESH );
140 : 0 : return 0.0;
141 : : }
142 [ + - ][ + + ]: 600 : if( depth[i] < elem_depth ) elem_depth = depth[i];
[ + - ]
143 : : }
144 [ + + ]: 100 : if( elem_depth == elemDepth + 1 ) continue;
145 : :
146 : 80 : ++elem_depth;
147 [ + - ][ + - ]: 560 : for( k = conn.begin(); k != conn.end(); ++k )
[ + - ][ + + ]
148 : : {
149 [ + - ][ + - ]: 480 : size_t i = std::lower_bound( vertices.begin(), vertices.end(), *k ) - vertices.begin();
[ + - ]
150 [ + - ][ + + ]: 480 : if( depth[i] > elem_depth )
151 : : {
152 [ + - ]: 56 : depth[i] = elem_depth;
153 : 56 : some_changed = true;
154 : : }
155 : : }
156 : : } // for(elements)
157 : : } while( some_changed );
158 : :
159 : : // Now remove any corner vertices from the slaved set
160 : 1 : std::vector< Mesh::VertexHandle >::iterator p;
161 [ + - ]: 2 : std::vector< EntityTopology > types( elements.size() );
162 [ + - ][ + - ]: 1 : mesh->elements_get_topologies( arrptr( elements ), arrptr( types ), elements.size(), err );
[ + - ]
163 [ + - ][ - + ]: 1 : MSQ_ERRZERO( err );
[ # # ][ # # ]
[ - + ]
164 [ + - ][ + - ]: 51 : for( j = elements.begin(); j != elements.end(); ++j )
[ + - ][ + + ]
165 : : {
166 [ + - ][ + - ]: 50 : const unsigned corners = TopologyInfo::corners( types[j - elements.begin()] );
[ + - ]
167 : 50 : conn.clear();
168 : 50 : junk.clear();
169 [ + - ][ + - ]: 50 : mesh->elements_get_attached_vertices( &*j, 1, conn, junk, err );
170 [ + - ][ - + ]: 50 : MSQ_ERRZERO( err );
[ # # ][ # # ]
[ - + ]
171 [ + + ]: 200 : for( unsigned i = 0; i < corners; ++i )
172 : : {
173 [ + - ][ + - ]: 150 : p = std::lower_bound( vertices.begin(), vertices.end(), conn[i] );
174 [ + - ][ + - ]: 150 : depth[p - vertices.begin()] = 0;
175 : : }
176 : : }
177 : :
178 : : // Now mark all vertices *not* within specified depth as slave vertices.
179 [ + - ]: 2 : std::vector< unsigned char > bytes( vertices.size() );
180 [ + - ][ + - ]: 1 : mesh->vertices_get_byte( arrptr( vertices ), arrptr( bytes ), vertices.size(), err );
[ + - ]
181 [ + - ][ - + ]: 1 : MSQ_ERRZERO( err );
[ # # ][ # # ]
[ - + ]
182 [ + + ]: 122 : for( size_t i = 0; i < vertices.size(); ++i )
183 : : {
184 [ + - ][ + + ]: 121 : if( depth[i] <= elemDepth || fixed[i] )
[ + - ][ - + ]
[ + + ]
[ + + # # ]
185 [ + - ]: 100 : bytes[i] &= ~MsqVertex::MSQ_DEPENDENT;
186 : : else
187 [ + - ]: 21 : bytes[i] |= MsqVertex::MSQ_DEPENDENT;
188 : : }
189 : :
190 [ + - ][ + - ]: 1 : mesh->vertices_set_byte( arrptr( vertices ), arrptr( bytes ), vertices.size(), err );
[ + - ]
191 [ + - ][ - + ]: 1 : MSQ_ERRZERO( err );
[ # # ][ # # ]
[ - + ]
192 : 2 : return 0.0;
193 : : }
194 : :
195 : 1 : void SlaveBoundaryVertices::initialize_queue( MeshDomainAssoc*, const Settings*, MsqError& ) {}
196 : :
197 [ + - ][ + - ]: 4 : } // namespace MBMesquite
|