MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2006 Lawrence Livermore National Laboratory. Under 00005 the terms of Contract B545069 with the University of Wisconsin -- 00006 Madison, Lawrence Livermore National Laboratory retains certain 00007 rights in this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 (2006) [email protected] 00024 00025 ***************************************************************** */ 00026 00027 /** \file TargetReader.cpp 00028 * \brief 00029 * \author Jason Kraftcheck 00030 */ 00031 00032 #include "Mesquite.hpp" 00033 #include "TargetReader.hpp" 00034 #include "PatchData.hpp" 00035 #include "MsqError.hpp" 00036 #include "MsqMatrix.hpp" 00037 #include "ElemSampleQM.hpp" 00038 #include <sstream> 00039 00040 namespace MBMesquite 00041 { 00042 00043 static TagHandle get_tag( Mesh* mesh, 00044 unsigned num_matrices, 00045 unsigned dimension, 00046 const char* base_name, 00047 bool orient_surface, 00048 MsqError& err ) 00049 { 00050 unsigned matrix_size; 00051 if( dimension == 2 && !orient_surface ) 00052 matrix_size = 4; 00053 else 00054 matrix_size = dimension * 3; 00055 unsigned num_doubles = num_matrices * matrix_size; 00056 std::ostringstream str; 00057 str << base_name << num_doubles; 00058 00059 TagHandle handle = mesh->tag_get( str.str().c_str(), err ); 00060 MSQ_ERRZERO( err ); 00061 00062 // check tag type 00063 std::string temp_name; 00064 Mesh::TagType temp_type; 00065 unsigned temp_length; 00066 mesh->tag_properties( handle, temp_name, temp_type, temp_length, err ); 00067 MSQ_ERRZERO( err ); 00068 00069 if( temp_type != Mesh::DOUBLE || temp_length != num_doubles ) 00070 { 00071 MSQ_SETERR( err ) 00072 ( MsqError::TAG_ALREADY_EXISTS, "Mismatched type or length for existing tag \"%s\"", str.str().c_str() ); 00073 } 00074 00075 return handle; 00076 } 00077 00078 TargetReader::TargetReader( bool orient2d, std::string name ) : tagBaseName( name ), orient2D( orient2d ) {} 00079 00080 TargetReader::~TargetReader() {} 00081 00082 bool TargetReader::get_3D_target( PatchData& pd, 00083 size_t element, 00084 Sample sample, 00085 MsqMatrix< 3, 3 >& W_out, 00086 MsqError& err ) 00087 { 00088 // calculate index of sample in array 00089 NodeSet all_samples = pd.get_samples( element ); 00090 unsigned offset = all_samples.num_before( sample ); 00091 00092 int dim = TopologyInfo::dimension( pd.element_by_index( element ).get_element_type() ); 00093 if( dim == 2 ) 00094 { 00095 MSQ_SETERR( err ) 00096 ( "Attempt to read 3D target for surface element", MsqError::INVALID_STATE ); 00097 return false; 00098 } 00099 00100 TargetReaderData& data = get_data( pd ); 00101 if( !data.targets3D.empty() && data.elementIndex == element ) 00102 { 00103 assert( offset < data.targets3D.size() ); 00104 W_out = data.targets3D[offset]; 00105 return true; 00106 } 00107 const unsigned num_samples = all_samples.num_nodes(); 00108 const unsigned handle_idx = num_samples - 1; 00109 00110 // get the tag handle 00111 const size_t INVALID_HANDLE = (size_t)-1; 00112 if( data.handles3D.size() <= handle_idx ) data.handles3D.resize( handle_idx + 1, (TagHandle)INVALID_HANDLE ); 00113 TagHandle& tag_handle = data.handles3D[handle_idx]; 00114 if( tag_handle == (TagHandle)INVALID_HANDLE ) 00115 { 00116 tag_handle = get_tag( pd.get_mesh(), num_samples, 3, tagBaseName.c_str(), orient2D, err ); 00117 MSQ_ERRZERO( err ); 00118 assert( tag_handle != (TagHandle)INVALID_HANDLE ); 00119 } 00120 00121 // get the tag data 00122 data.targets3D.resize( num_samples ); 00123 pd.get_mesh()->tag_get_element_data( tag_handle, 1, pd.get_element_handles_array() + element, &data.targets3D[0], 00124 err ); 00125 if( MSQ_CHKERR( err ) ) 00126 { 00127 data.targets3D.clear(); 00128 return false; 00129 } 00130 00131 data.elementIndex = element; 00132 W_out = data.targets3D[offset]; 00133 return true; 00134 } 00135 00136 bool TargetReader::get_2D_target( PatchData& pd, 00137 size_t element, 00138 Sample sample, 00139 MsqMatrix< 2, 2 >& W_out, 00140 MsqError& err ) 00141 { 00142 // which type of 2D target do we actually have 00143 if( orient2D ) 00144 { 00145 MSQ_SETERR( err )( "Incorrect surface mesh target type", MsqError::INTERNAL_ERROR ); 00146 return false; 00147 } 00148 00149 // calculate index of sample in array 00150 NodeSet all_samples = pd.get_samples( element ); 00151 unsigned offset = all_samples.num_before( sample ); 00152 00153 int dim = TopologyInfo::dimension( pd.element_by_index( element ).get_element_type() ); 00154 if( dim == 3 ) 00155 { 00156 MSQ_SETERR( err ) 00157 ( "Attempt to read surface target for region element", MsqError::INVALID_STATE ); 00158 return false; 00159 } 00160 00161 TargetReaderData& data = get_data( pd ); 00162 if( !data.targets2D.empty() && data.elementIndex == element ) 00163 { 00164 assert( offset < data.targets2D.size() ); 00165 W_out = data.targets2D[offset]; 00166 return true; 00167 } 00168 const unsigned num_samples = all_samples.num_nodes(); 00169 const unsigned handle_idx = num_samples - 1; 00170 00171 // get the tag handle 00172 const size_t INVALID_HANDLE = (size_t)-1; 00173 if( data.handles2D.size() <= handle_idx ) data.handles2D.resize( handle_idx + 1, (TagHandle)INVALID_HANDLE ); 00174 TagHandle& tag_handle = data.handles2D[handle_idx]; 00175 if( tag_handle == (TagHandle)INVALID_HANDLE ) 00176 { 00177 tag_handle = get_tag( pd.get_mesh(), num_samples, 2, tagBaseName.c_str(), orient2D, err ); 00178 MSQ_ERRZERO( err ); 00179 assert( tag_handle != (TagHandle)INVALID_HANDLE ); 00180 } 00181 00182 // get the tag data 00183 data.targets2D.resize( num_samples ); 00184 pd.get_mesh()->tag_get_element_data( tag_handle, 1, pd.get_element_handles_array() + element, &data.targets2D[0], 00185 err ); 00186 if( MSQ_CHKERR( err ) ) 00187 { 00188 data.targets2D.clear(); 00189 return false; 00190 } 00191 00192 data.elementIndex = element; 00193 W_out = data.targets2D[offset]; 00194 return true; 00195 } 00196 00197 bool TargetReader::get_surface_target( PatchData& pd, 00198 size_t element, 00199 Sample sample, 00200 MsqMatrix< 3, 2 >& W_out, 00201 MsqError& err ) 00202 { 00203 // which type of 2D target do we actually have 00204 if( !orient2D ) 00205 { 00206 MSQ_SETERR( err )( "Incorrect surface mesh target type", MsqError::INTERNAL_ERROR ); 00207 return false; 00208 } 00209 00210 // calculate index of sample in array 00211 NodeSet all_samples = pd.get_samples( element ); 00212 unsigned offset = all_samples.num_before( sample ); 00213 00214 int dim = TopologyInfo::dimension( pd.element_by_index( element ).get_element_type() ); 00215 if( dim == 3 ) 00216 { 00217 MSQ_SETERR( err ) 00218 ( "Attempt to read surface target for region element", MsqError::INVALID_STATE ); 00219 return false; 00220 } 00221 00222 TargetReaderData& data = get_data( pd ); 00223 if( !data.targetsSurface.empty() && data.elementIndex == element ) 00224 { 00225 assert( offset < data.targetsSurface.size() ); 00226 W_out = data.targetsSurface[offset]; 00227 return true; 00228 } 00229 const unsigned num_samples = all_samples.num_nodes(); 00230 const unsigned handle_idx = num_samples - 1; 00231 00232 // get the tag handle 00233 const size_t INVALID_HANDLE = (size_t)-1; 00234 if( data.handles2D.size() <= handle_idx ) data.handles2D.resize( handle_idx + 1, (TagHandle)INVALID_HANDLE ); 00235 TagHandle& tag_handle = data.handles2D[handle_idx]; 00236 if( tag_handle == (TagHandle)INVALID_HANDLE ) 00237 { 00238 tag_handle = get_tag( pd.get_mesh(), num_samples, 2, tagBaseName.c_str(), orient2D, err ); 00239 MSQ_ERRZERO( err ); 00240 assert( tag_handle != (TagHandle)INVALID_HANDLE ); 00241 } 00242 00243 // get the tag data 00244 data.targetsSurface.resize( num_samples ); 00245 pd.get_mesh()->tag_get_element_data( tag_handle, 1, pd.get_element_handles_array() + element, 00246 &data.targetsSurface[0], err ); 00247 if( MSQ_CHKERR( err ) ) 00248 { 00249 data.targetsSurface.clear(); 00250 return false; 00251 } 00252 00253 data.elementIndex = element; 00254 W_out = data.targetsSurface[offset]; 00255 return true; 00256 } 00257 00258 void TargetReader::notify_patch_destroyed( TargetReaderData& data ) 00259 { 00260 data.handles2D.clear(); 00261 data.handles3D.clear(); 00262 data.targets3D.clear(); 00263 data.targets2D.clear(); 00264 data.targetsSurface.clear(); 00265 } 00266 00267 void TargetReader::notify_new_patch( PatchData&, TargetReaderData& data ) 00268 { 00269 data.targets3D.clear(); 00270 data.targets2D.clear(); 00271 data.targetsSurface.clear(); 00272 } 00273 00274 void TargetReader::notify_sub_patch( PatchData& /*pd*/, 00275 TargetReaderData& data, 00276 PatchData& subpatch, 00277 const size_t*, 00278 const size_t*, 00279 MsqError& /*err*/ ) 00280 { 00281 TargetReaderData& other = get_data( subpatch ); 00282 if( other.handles2D.empty() && other.handles3D.empty() ) 00283 { 00284 other.handles2D = data.handles2D; 00285 other.handles3D = data.handles3D; 00286 } 00287 } 00288 00289 } // namespace MBMesquite