MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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