MOAB: Mesh Oriented datABase  (version 5.4.1)
TargetReader.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines