MOAB: Mesh Oriented datABase  (version 5.2.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) kraftche@cae.wisc.edu
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, unsigned num_matrices, unsigned dimension, const char* base_name,
00044                           bool orient_surface, MsqError& err )
00045 {
00046     unsigned matrix_size;
00047     if( dimension == 2 && !orient_surface )
00048         matrix_size = 4;
00049     else
00050         matrix_size = dimension * 3;
00051     unsigned num_doubles = num_matrices * matrix_size;
00052     std::ostringstream str;
00053     str << base_name << num_doubles;
00054 
00055     TagHandle handle = mesh->tag_get( str.str().c_str(), err );
00056     MSQ_ERRZERO( err );
00057 
00058     // check tag type
00059     std::string temp_name;
00060     Mesh::TagType temp_type;
00061     unsigned temp_length;
00062     mesh->tag_properties( handle, temp_name, temp_type, temp_length, err );
00063     MSQ_ERRZERO( err );
00064 
00065     if( temp_type != Mesh::DOUBLE || temp_length != num_doubles )
00066     {
00067         MSQ_SETERR( err )
00068         ( MsqError::TAG_ALREADY_EXISTS, "Mismatched type or length for existing tag \"%s\"", str.str().c_str() );
00069     }
00070 
00071     return handle;
00072 }
00073 
00074 TargetReader::TargetReader( bool orient2d, std::string name ) : tagBaseName( name ), orient2D( orient2d ) {}
00075 
00076 TargetReader::~TargetReader() {}
00077 
00078 bool TargetReader::get_3D_target( PatchData& pd, size_t element, Sample sample, MsqMatrix< 3, 3 >& W_out,
00079                                   MsqError& err )
00080 {
00081     // calculate index of sample in array
00082     NodeSet all_samples = pd.get_samples( element );
00083     unsigned offset     = all_samples.num_before( sample );
00084 
00085     int dim = TopologyInfo::dimension( pd.element_by_index( element ).get_element_type() );
00086     if( dim == 2 )
00087     {
00088         MSQ_SETERR( err )
00089         ( "Attempt to read 3D target for surface element", MsqError::INVALID_STATE );
00090         return false;
00091     }
00092 
00093     TargetReaderData& data = get_data( pd );
00094     if( !data.targets3D.empty() && data.elementIndex == element )
00095     {
00096         assert( offset < data.targets3D.size() );
00097         W_out = data.targets3D[offset];
00098         return true;
00099     }
00100     const unsigned num_samples = all_samples.num_nodes();
00101     const unsigned handle_idx  = num_samples - 1;
00102 
00103     // get the tag handle
00104     const size_t INVALID_HANDLE = (size_t)-1;
00105     if( data.handles3D.size() <= handle_idx ) data.handles3D.resize( handle_idx + 1, (TagHandle)INVALID_HANDLE );
00106     TagHandle& tag_handle = data.handles3D[handle_idx];
00107     if( tag_handle == (TagHandle)INVALID_HANDLE )
00108     {
00109         tag_handle = get_tag( pd.get_mesh(), num_samples, 3, tagBaseName.c_str(), orient2D, err );
00110         MSQ_ERRZERO( err );
00111         assert( tag_handle != (TagHandle)INVALID_HANDLE );
00112     }
00113 
00114     // get the tag data
00115     data.targets3D.resize( num_samples );
00116     pd.get_mesh()->tag_get_element_data( tag_handle, 1, pd.get_element_handles_array() + element, &data.targets3D[0],
00117                                          err );
00118     if( MSQ_CHKERR( err ) )
00119     {
00120         data.targets3D.clear();
00121         return false;
00122     }
00123 
00124     data.elementIndex = element;
00125     W_out             = data.targets3D[offset];
00126     return true;
00127 }
00128 
00129 bool TargetReader::get_2D_target( PatchData& pd, size_t element, Sample sample, MsqMatrix< 2, 2 >& W_out,
00130                                   MsqError& err )
00131 {
00132     // which type of 2D target do we actually have
00133     if( orient2D )
00134     {
00135         MSQ_SETERR( err )( "Incorrect surface mesh target type", MsqError::INTERNAL_ERROR );
00136         return false;
00137     }
00138 
00139     // calculate index of sample in array
00140     NodeSet all_samples = pd.get_samples( element );
00141     unsigned offset     = all_samples.num_before( sample );
00142 
00143     int dim = TopologyInfo::dimension( pd.element_by_index( element ).get_element_type() );
00144     if( dim == 3 )
00145     {
00146         MSQ_SETERR( err )
00147         ( "Attempt to read surface target for region element", MsqError::INVALID_STATE );
00148         return false;
00149     }
00150 
00151     TargetReaderData& data = get_data( pd );
00152     if( !data.targets2D.empty() && data.elementIndex == element )
00153     {
00154         assert( offset < data.targets2D.size() );
00155         W_out = data.targets2D[offset];
00156         return true;
00157     }
00158     const unsigned num_samples = all_samples.num_nodes();
00159     const unsigned handle_idx  = num_samples - 1;
00160 
00161     // get the tag handle
00162     const size_t INVALID_HANDLE = (size_t)-1;
00163     if( data.handles2D.size() <= handle_idx ) data.handles2D.resize( handle_idx + 1, (TagHandle)INVALID_HANDLE );
00164     TagHandle& tag_handle = data.handles2D[handle_idx];
00165     if( tag_handle == (TagHandle)INVALID_HANDLE )
00166     {
00167         tag_handle = get_tag( pd.get_mesh(), num_samples, 2, tagBaseName.c_str(), orient2D, err );
00168         MSQ_ERRZERO( err );
00169         assert( tag_handle != (TagHandle)INVALID_HANDLE );
00170     }
00171 
00172     // get the tag data
00173     data.targets2D.resize( num_samples );
00174     pd.get_mesh()->tag_get_element_data( tag_handle, 1, pd.get_element_handles_array() + element, &data.targets2D[0],
00175                                          err );
00176     if( MSQ_CHKERR( err ) )
00177     {
00178         data.targets2D.clear();
00179         return false;
00180     }
00181 
00182     data.elementIndex = element;
00183     W_out             = data.targets2D[offset];
00184     return true;
00185 }
00186 
00187 bool TargetReader::get_surface_target( PatchData& pd, size_t element, Sample sample, MsqMatrix< 3, 2 >& W_out,
00188                                        MsqError& err )
00189 {
00190     // which type of 2D target do we actually have
00191     if( !orient2D )
00192     {
00193         MSQ_SETERR( err )( "Incorrect surface mesh target type", MsqError::INTERNAL_ERROR );
00194         return false;
00195     }
00196 
00197     // calculate index of sample in array
00198     NodeSet all_samples = pd.get_samples( element );
00199     unsigned offset     = all_samples.num_before( sample );
00200 
00201     int dim = TopologyInfo::dimension( pd.element_by_index( element ).get_element_type() );
00202     if( dim == 3 )
00203     {
00204         MSQ_SETERR( err )
00205         ( "Attempt to read surface target for region element", MsqError::INVALID_STATE );
00206         return false;
00207     }
00208 
00209     TargetReaderData& data = get_data( pd );
00210     if( !data.targetsSurface.empty() && data.elementIndex == element )
00211     {
00212         assert( offset < data.targetsSurface.size() );
00213         W_out = data.targetsSurface[offset];
00214         return true;
00215     }
00216     const unsigned num_samples = all_samples.num_nodes();
00217     const unsigned handle_idx  = num_samples - 1;
00218 
00219     // get the tag handle
00220     const size_t INVALID_HANDLE = (size_t)-1;
00221     if( data.handles2D.size() <= handle_idx ) data.handles2D.resize( handle_idx + 1, (TagHandle)INVALID_HANDLE );
00222     TagHandle& tag_handle = data.handles2D[handle_idx];
00223     if( tag_handle == (TagHandle)INVALID_HANDLE )
00224     {
00225         tag_handle = get_tag( pd.get_mesh(), num_samples, 2, tagBaseName.c_str(), orient2D, err );
00226         MSQ_ERRZERO( err );
00227         assert( tag_handle != (TagHandle)INVALID_HANDLE );
00228     }
00229 
00230     // get the tag data
00231     data.targetsSurface.resize( num_samples );
00232     pd.get_mesh()->tag_get_element_data( tag_handle, 1, pd.get_element_handles_array() + element,
00233                                          &data.targetsSurface[0], err );
00234     if( MSQ_CHKERR( err ) )
00235     {
00236         data.targetsSurface.clear();
00237         return false;
00238     }
00239 
00240     data.elementIndex = element;
00241     W_out             = data.targetsSurface[offset];
00242     return true;
00243 }
00244 
00245 void TargetReader::notify_patch_destroyed( TargetReaderData& data )
00246 {
00247     data.handles2D.clear();
00248     data.handles3D.clear();
00249     data.targets3D.clear();
00250     data.targets2D.clear();
00251     data.targetsSurface.clear();
00252 }
00253 
00254 void TargetReader::notify_new_patch( PatchData&, TargetReaderData& data )
00255 {
00256     data.targets3D.clear();
00257     data.targets2D.clear();
00258     data.targetsSurface.clear();
00259 }
00260 
00261 void TargetReader::notify_sub_patch( PatchData& /*pd*/, TargetReaderData& data, PatchData& subpatch, const size_t*,
00262                                      const size_t*, MsqError& /*err*/ )
00263 {
00264     TargetReaderData& other = get_data( subpatch );
00265     if( other.handles2D.empty() && other.handles3D.empty() )
00266     {
00267         other.handles2D = data.handles2D;
00268         other.handles3D = data.handles3D;
00269     }
00270 }
00271 
00272 }  // namespace MBMesquite
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines