MOAB: Mesh Oriented datABase  (version 5.2.1)
TargetWriter.cpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2006 Sandia National Laboratories.  Developed at the
00005     University of Wisconsin--Madison under SNL contract number
00006     624796.  The U.S. Government and the University of Wisconsin
00007     retain certain rights to 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 TargetWriter.cpp
00028  *  \brief
00029  *  \author Jason Kraftcheck
00030  */
00031 
00032 #include "Mesquite.hpp"
00033 #include "TargetWriter.hpp"
00034 #include "TargetCalculator.hpp"
00035 #include "WeightCalculator.hpp"
00036 #include "MeshInterface.hpp"
00037 #include "MsqMatrix.hpp"
00038 #include "PatchData.hpp"
00039 #include "PatchSet.hpp"
00040 #include "MsqError.hpp"
00041 #include "ElementPatches.hpp"
00042 #include "ElemSampleQM.hpp"
00043 #include <sstream>
00044 
00045 namespace MBMesquite
00046 {
00047 
00048 TargetWriter::TargetWriter( TargetCalculator* tc, WeightCalculator* wc, std::string target_base_name,
00049                             std::string weight_base_name )
00050     : targetCalc( tc ), weightCalc( wc ), targetName( target_base_name ), weightName( weight_base_name )
00051 {
00052 }
00053 
00054 TargetWriter::~TargetWriter() {}
00055 
00056 std::string TargetWriter::get_name() const
00057 {
00058     return "TargetWriter";
00059 }
00060 
00061 double TargetWriter::loop_over_mesh( MeshDomainAssoc* mesh_and_domain, const Settings* settings, MsqError& err )
00062 {
00063     Mesh* mesh         = mesh_and_domain->get_mesh();
00064     MeshDomain* domain = mesh_and_domain->get_domain();
00065 
00066     PatchData patch;
00067     patch.set_mesh( mesh );
00068     patch.set_domain( domain );
00069     if( settings ) patch.attach_settings( settings );
00070 
00071     ElementPatches patch_set;
00072     patch_set.set_mesh( mesh );
00073     std::vector< PatchSet::PatchHandle > patches;
00074     std::vector< PatchSet::PatchHandle >::iterator p;
00075     std::vector< Mesh::VertexHandle > patch_verts;
00076     std::vector< Mesh::ElementHandle > patch_elems;
00077 
00078     patch_set.get_patch_handles( patches, err );
00079     MSQ_ERRZERO( err );
00080 
00081     std::vector< MsqMatrix< 3, 3 > > targets3d;
00082     std::vector< MsqMatrix< 3, 2 > > targets2dorient;
00083     std::vector< MsqMatrix< 2, 2 > > targets2d;
00084     std::vector< double > weights;
00085     std::vector< Sample > samples;
00086     for( p = patches.begin(); p != patches.end(); ++p )
00087     {
00088         patch_verts.clear();
00089         patch_elems.clear();
00090         patch_set.get_patch( *p, patch_elems, patch_verts, err );
00091         MSQ_ERRZERO( err );
00092         patch.set_mesh_entities( patch_elems, patch_verts, err );
00093         MSQ_ERRZERO( err );
00094         assert( patch.num_elements() == 1 );
00095 
00096         MsqMeshEntity& elem = patch.element_by_index( 0 );
00097         EntityTopology type = elem.get_element_type();
00098         patch.get_samples( 0, samples, err );
00099         MSQ_ERRZERO( err );
00100         if( samples.empty() ) continue;
00101 
00102         if( targetCalc )
00103         {
00104             const unsigned dim = TopologyInfo::dimension( type );
00105             if( dim == 3 )
00106             {
00107                 targets3d.resize( samples.size() );
00108                 for( unsigned i = 0; i < samples.size(); ++i )
00109                 {
00110                     targetCalc->get_3D_target( patch, 0, samples[i], targets3d[i], err );
00111                     MSQ_ERRZERO( err );
00112 
00113                     if( DBL_EPSILON > det( targets3d[i] ) )
00114                     {
00115                         MSQ_SETERR( err )( "Inverted 3D target", MsqError::INVALID_ARG );
00116                         return 0.0;
00117                     }
00118                 }
00119 
00120                 TagHandle tag = get_target_tag( 3, samples.size(), mesh, err );
00121                 MSQ_ERRZERO( err );
00122                 mesh->tag_set_element_data( tag, 1, patch.get_element_handles_array(), arrptr( targets3d ), err );
00123                 MSQ_ERRZERO( err );
00124             }
00125             else if( targetCalc->have_surface_orient() )
00126             {
00127                 targets2dorient.resize( samples.size() );
00128                 for( unsigned i = 0; i < samples.size(); ++i )
00129                 {
00130                     targetCalc->get_surface_target( patch, 0, samples[i], targets2dorient[i], err );
00131                     MSQ_ERRZERO( err );
00132 
00133                     MsqMatrix< 3, 1 > cross = targets2dorient[i].column( 0 ) * targets2dorient[i].column( 1 );
00134                     if( DBL_EPSILON > ( cross % cross ) )
00135                     {
00136                         MSQ_SETERR( err )( "Degenerate 2D target", MsqError::INVALID_ARG );
00137                         return 0.0;
00138                     }
00139                 }
00140 
00141                 TagHandle tag = get_target_tag( 2, samples.size(), mesh, err );
00142                 MSQ_ERRZERO( err );
00143                 mesh->tag_set_element_data( tag, 1, patch.get_element_handles_array(), arrptr( targets2dorient ), err );
00144                 MSQ_ERRZERO( err );
00145             }
00146             else
00147             {
00148                 targets2d.resize( samples.size() );
00149                 for( unsigned i = 0; i < samples.size(); ++i )
00150                 {
00151                     targetCalc->get_2D_target( patch, 0, samples[i], targets2d[i], err );
00152                     MSQ_ERRZERO( err );
00153 
00154                     if( DBL_EPSILON > det( targets2d[i] ) )
00155                     {
00156                         MSQ_SETERR( err )( "Degenerate/Inverted 2D target", MsqError::INVALID_ARG );
00157                         return 0.0;
00158                     }
00159                 }
00160 
00161                 TagHandle tag = get_target_tag( 2, samples.size(), mesh, err );
00162                 MSQ_ERRZERO( err );
00163                 mesh->tag_set_element_data( tag, 1, patch.get_element_handles_array(), arrptr( targets2d ), err );
00164                 MSQ_ERRZERO( err );
00165             }
00166         }
00167 
00168         if( weightCalc )
00169         {
00170             weights.resize( samples.size() );
00171             for( unsigned i = 0; i < samples.size(); ++i )
00172             {
00173                 weights[i] = weightCalc->get_weight( patch, 0, samples[i], err );
00174                 MSQ_ERRZERO( err );
00175             }
00176             TagHandle tag = get_weight_tag( samples.size(), mesh, err );
00177             MSQ_ERRZERO( err );
00178             mesh->tag_set_element_data( tag, 1, patch.get_element_handles_array(), arrptr( weights ), err );
00179             MSQ_ERRZERO( err );
00180         }
00181     }
00182 
00183     return 0.0;
00184 }
00185 
00186 TagHandle TargetWriter::get_target_tag( unsigned dim, unsigned count, Mesh* mesh, MsqError& err )
00187 {
00188     if( dim == 2 && !targetCalc->have_surface_orient() )
00189         count *= 4;
00190     else
00191         count *= 3 * dim;  // num doubles
00192     if( targetTags.size() <= count ) targetTags.resize( count + 1, 0 );
00193     if( !targetTags[count] )
00194     {
00195         targetTags[count] = get_tag_handle( targetName, count, mesh, err );
00196         if( MSQ_CHKERR( err ) )
00197         {
00198             targetTags[count] = 0;
00199             return 0;
00200         }
00201     }
00202     return targetTags[count];
00203 }
00204 
00205 TagHandle TargetWriter::get_weight_tag( unsigned count, Mesh* mesh, MsqError& err )
00206 {
00207     if( weightTags.size() <= count ) weightTags.resize( count + 1, 0 );
00208     if( !weightTags[count] )
00209     {
00210         weightTags[count] = get_tag_handle( weightName, count, mesh, err );
00211         if( MSQ_CHKERR( err ) )
00212         {
00213             weightTags[count] = 0;
00214             return 0;
00215         }
00216     }
00217     return weightTags[count];
00218 }
00219 
00220 TagHandle TargetWriter::get_tag_handle( const std::string& base_name, unsigned num_dbl, Mesh* mesh, MsqError& err )
00221 {
00222     std::ostringstream sstr;
00223     sstr << base_name << num_dbl;
00224 
00225     TagHandle handle = mesh->tag_get( sstr.str().c_str(), err );
00226     if( !MSQ_CHKERR( err ) )
00227     {
00228         std::string temp_name;
00229         Mesh::TagType temp_type;
00230         unsigned temp_length;
00231         mesh->tag_properties( handle, temp_name, temp_type, temp_length, err );
00232         MSQ_ERRZERO( err );
00233 
00234         if( temp_type != Mesh::DOUBLE || temp_length != num_dbl )
00235         {
00236             MSQ_SETERR( err )
00237             ( MsqError::TAG_ALREADY_EXISTS, "Mismatched type or length for existing tag \"%s\"", sstr.str().c_str() );
00238         }
00239     }
00240     else if( err.error_code() == MsqError::TAG_NOT_FOUND )
00241     {
00242         err.clear();
00243         handle = mesh->tag_create( sstr.str().c_str(), Mesh::DOUBLE, num_dbl, 0, err );
00244         MSQ_ERRZERO( err );
00245     }
00246     return handle;
00247 }
00248 
00249 void TargetWriter::initialize_queue( MeshDomainAssoc*, const Settings*, MsqError& ) {}
00250 }  // namespace MBMesquite
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines