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