moab
WriteTemplate.cpp
Go to the documentation of this file.
00001 
00017 #ifdef WIN32
00018 #ifdef _DEBUG
00019 // turn off warnings that say they debugging identifier has been truncated
00020 // this warning comes up when using some STL containers
00021 #pragma warning(disable : 4786)
00022 #endif
00023 #endif
00024 
00025 
00026 #include "WriteTemplate.hpp"
00027 
00028 #include <utility>
00029 #include <algorithm>
00030 #include <time.h>
00031 #include <string>
00032 #include <vector>
00033 #include <stdio.h>
00034 #include <string.h>
00035 #include <iostream>
00036 
00037 #include "moab/Interface.hpp"
00038 #include "moab/Range.hpp"
00039 #include "moab/CN.hpp"
00040 #include "assert.h"
00041 #include "Internals.hpp"
00042 #include "ExoIIUtil.hpp"
00043 #include "MBTagConventions.hpp"
00044 #include "moab/WriteUtilIface.hpp"
00045 
00046 namespace moab {
00047 
00048 #define INS_ID(stringvar, prefix, id) \
00049           sprintf(stringvar, prefix, id)
00050 
00051 WriterIface* WriteTemplate::factory( Interface* iface )
00052   { return new WriteTemplate( iface ); }
00053 
00054 WriteTemplate::WriteTemplate(Interface *impl) 
00055     : mbImpl(impl), mCurrentMeshHandle(0)
00056 {
00057   assert(impl != NULL);
00058 
00059   impl->query_interface( mWriteIface );
00060 
00061   // initialize in case tag_get_handle fails below
00063   int zero = 0, negone = -1;
00064   impl->tag_get_handle(MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER,
00065                        mMaterialSetTag, MB_TAG_SPARSE|MB_TAG_CREAT, &negone);
00066 
00067   impl->tag_get_handle(DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER,
00068                        mDirichletSetTag, MB_TAG_SPARSE|MB_TAG_CREAT, &negone);
00069 
00070   impl->tag_get_handle(NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER,
00071                        mNeumannSetTag, MB_TAG_SPARSE|MB_TAG_CREAT, &negone);
00072 
00073   impl->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER,
00074                        mGlobalIdTag, MB_TAG_SPARSE|MB_TAG_CREAT, &zero);
00075 
00076   impl->tag_get_handle("WriteTemplate element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT);
00077 
00078 }
00079 
00080 WriteTemplate::~WriteTemplate() 
00081 {
00082   mbImpl->release_interface(mWriteIface);
00083 
00084   mbImpl->tag_delete(mEntityMark);
00085 
00086 }
00087 
00088 void WriteTemplate::reset_matset(std::vector<WriteTemplate::MaterialSetData> &matset_info)
00089 {
00090   std::vector<WriteTemplate::MaterialSetData>::iterator iter;
00091   
00092   for (iter = matset_info.begin(); iter != matset_info.end(); iter++)
00093   {
00094     delete (*iter).elements;
00095   }
00096 }
00097 
00098 ErrorCode WriteTemplate::write_file(const char *file_name, 
00099                                       const bool /* overwrite (commented out to remove warning) */,
00100                                       const FileOptions& /*opts*/,
00101                                       const EntityHandle *ent_handles,
00102                                       const int num_sets,
00103                                       const std::vector<std::string>&,
00104                                       const Tag* ,
00105                                       int ,
00106                                       int )
00107 {
00108   assert(0 != mMaterialSetTag &&
00109          0 != mNeumannSetTag &&
00110          0 != mDirichletSetTag);
00111 
00112     // check the file name
00113   if (NULL == strstr(file_name, ".template"))
00114     return MB_FAILURE;
00115 
00116   std::vector<EntityHandle> matsets, dirsets, neusets, entities;
00117 
00118   fileName = file_name;
00119   
00120     // separate into material sets, dirichlet sets, neumann sets
00121 
00122   if (num_sets == 0) {
00123       // default to all defined sets
00124     Range this_range;
00125     mbImpl->get_entities_by_type_and_tag(0, MBENTITYSET, &mMaterialSetTag, NULL, 1, this_range);
00126     std::copy(this_range.begin(), this_range.end(), std::back_inserter(matsets));
00127     this_range.clear();
00128     mbImpl->get_entities_by_type_and_tag(0, MBENTITYSET, &mDirichletSetTag, NULL, 1, this_range);
00129     std::copy(this_range.begin(), this_range.end(), std::back_inserter(dirsets));
00130     this_range.clear();
00131     mbImpl->get_entities_by_type_and_tag(0, MBENTITYSET, &mNeumannSetTag, NULL, 1, this_range);
00132     std::copy(this_range.begin(), this_range.end(), std::back_inserter(neusets));
00133   }
00134   else {
00135     int dummy;
00136     for (const EntityHandle *iter = ent_handles; iter < ent_handles+num_sets; iter++) 
00137     {
00138       if (MB_SUCCESS == mbImpl->tag_get_data(mMaterialSetTag, &(*iter), 1, &dummy))
00139         matsets.push_back(*iter);
00140       else if (MB_SUCCESS == mbImpl->tag_get_data(mDirichletSetTag, &(*iter), 1, &dummy))
00141         dirsets.push_back(*iter);
00142       else if (MB_SUCCESS == mbImpl->tag_get_data(mNeumannSetTag, &(*iter), 1, &dummy))
00143         neusets.push_back(*iter);
00144     }
00145   }
00146   
00147     // if there is nothing to write just return.
00148   if (matsets.empty() && dirsets.empty() && neusets.empty())
00149     return MB_FILE_WRITE_ERROR;
00150 
00151   std::vector<WriteTemplate::MaterialSetData> matset_info;
00152   std::vector<WriteTemplate::DirichletSetData> dirset_info;
00153   std::vector<WriteTemplate::NeumannSetData> neuset_info;
00154 
00155   MeshInfo mesh_info;
00156   
00157   matset_info.clear();
00158   if(gather_mesh_information(mesh_info, matset_info, neuset_info, dirset_info,
00159                              matsets, neusets, dirsets) != MB_SUCCESS)
00160   {
00161     reset_matset(matset_info);
00162     return MB_FAILURE;
00163   }
00164 
00165 
00166   // try to open the file after gather mesh info succeeds
00167   if (/* test for file open failure */ false) {
00168     reset_matset(matset_info);
00169     return MB_FAILURE;
00170   }
00171 
00172   if( initialize_file(mesh_info) != MB_SUCCESS)
00173   {
00174     reset_matset(matset_info);
00175     return MB_FAILURE;
00176   }
00177 
00178   if( write_nodes(mesh_info.num_nodes, mesh_info.nodes, mesh_info.num_dim) != MB_SUCCESS )
00179   {
00180     reset_matset(matset_info);
00181     return MB_FAILURE;
00182   }
00183 
00184   if( write_matsets(mesh_info, matset_info, neuset_info) )
00185   {
00186     reset_matset(matset_info);
00187     return MB_FAILURE;
00188   }
00189 
00190   return MB_SUCCESS;
00191 }
00192 
00193 ErrorCode WriteTemplate::gather_mesh_information(MeshInfo &mesh_info,
00194                                                    std::vector<WriteTemplate::MaterialSetData> &matset_info,
00195                                                    std::vector<WriteTemplate::NeumannSetData> &neuset_info,
00196                                                    std::vector<WriteTemplate::DirichletSetData> &dirset_info,
00197                                                    std::vector<EntityHandle> &matsets,
00198                                                    std::vector<EntityHandle> &neusets,
00199                                                    std::vector<EntityHandle> &dirsets)
00200 {
00201 
00202   std::vector<EntityHandle>::iterator vector_iter, end_vector_iter;
00203 
00204   mesh_info.num_nodes = 0;
00205   mesh_info.num_elements = 0;
00206   mesh_info.num_matsets = 0;
00207   
00208   int id = 0;
00209 
00210   vector_iter= matsets.begin();
00211   end_vector_iter = matsets.end();
00212 
00213   mesh_info.num_matsets = matsets.size();
00214 
00215   std::vector<EntityHandle> parent_meshsets;
00216 
00217   // clean out the bits for the element mark
00218   mbImpl->tag_delete(mEntityMark);
00219   mbImpl->tag_get_handle("WriteTemplate element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT);
00220 
00221   int highest_dimension_of_element_matsets = 0;
00222 
00223   for(vector_iter = matsets.begin(); vector_iter != matsets.end(); vector_iter++)
00224   {
00225        
00226     WriteTemplate::MaterialSetData matset_data;
00227     matset_data.elements = new Range;
00228 
00229     //for the purpose of qa records, get the parents of these matsets 
00230     if( mbImpl->get_parent_meshsets( *vector_iter, parent_meshsets ) != MB_SUCCESS )
00231       return MB_FAILURE;
00232 
00233     // get all Entity Handles in the mesh set
00234     Range dummy_range;
00235     mbImpl->get_entities_by_handle(*vector_iter, dummy_range, true );
00236 
00237       // find the dimension of the last entity in this range
00238     Range::iterator entity_iter = dummy_range.end();
00239     entity_iter = dummy_range.end();
00240     entity_iter--;
00241     int this_dim = CN::Dimension(TYPE_FROM_HANDLE(*entity_iter));
00242     entity_iter = dummy_range.begin();
00243     while (entity_iter != dummy_range.end() &&
00244            CN::Dimension(TYPE_FROM_HANDLE(*entity_iter)) != this_dim)
00245       entity_iter++;
00246     
00247     if (entity_iter != dummy_range.end())
00248       std::copy(entity_iter, dummy_range.end(), range_inserter(*(matset_data.elements)));
00249 
00250     assert(matset_data.elements->begin() == matset_data.elements->end() ||
00251            CN::Dimension(TYPE_FROM_HANDLE(*(matset_data.elements->begin()))) == this_dim);
00252     
00253     // get the matset's id
00254     if(mbImpl->tag_get_data(mMaterialSetTag, &(*vector_iter), 1, &id) != MB_SUCCESS ) {
00255       mWriteIface->report_error("Couldn't get matset id from a tag for an element matset.");
00256       return MB_FAILURE;
00257     }
00258     
00259     matset_data.id = id; 
00260     matset_data.number_attributes = 0;
00261  
00262      // iterate through all the elements in the meshset
00263     Range::iterator elem_range_iter, end_elem_range_iter;
00264     elem_range_iter = matset_data.elements->begin();
00265     end_elem_range_iter = matset_data.elements->end();
00266 
00267       // get the entity type for this matset, verifying that it's the same for all elements
00268       // THIS ASSUMES HANDLES SORT BY TYPE!!!
00269     EntityType entity_type = TYPE_FROM_HANDLE(*elem_range_iter);
00270     end_elem_range_iter--;
00271     if (entity_type != TYPE_FROM_HANDLE(*(end_elem_range_iter++))) {
00272       mWriteIface->report_error("Entities in matset %i not of common type", id);
00273       return MB_FAILURE;
00274     }
00275 
00276     int dimension = CN::Dimension(entity_type);
00277 
00278     if( dimension > highest_dimension_of_element_matsets )
00279       highest_dimension_of_element_matsets = dimension;
00280 
00281     matset_data.moab_type = mbImpl->type_from_handle(*(matset_data.elements->begin()));
00282     if (MBMAXTYPE == matset_data.moab_type) return MB_FAILURE;
00283     
00284     std::vector<EntityHandle> tmp_conn;
00285     mbImpl->get_connectivity(&(*(matset_data.elements->begin())), 1, tmp_conn);
00286     matset_data.element_type = 
00287       ExoIIUtil::get_element_type_from_num_verts(tmp_conn.size(), entity_type, dimension);
00288     
00289     if (matset_data.element_type == EXOII_MAX_ELEM_TYPE) {
00290       mWriteIface->report_error("Element type in matset %i didn't get set correctly", id);
00291       return MB_FAILURE;
00292     }
00293     
00294     matset_data.number_nodes_per_element = ExoIIUtil::VerticesPerElement[matset_data.element_type];
00295 
00296     // number of nodes for this matset
00297     matset_data.number_elements = matset_data.elements->size();
00298 
00299     // total number of elements
00300     mesh_info.num_elements += matset_data.number_elements;
00301 
00302     // get the nodes for the elements
00303     mWriteIface->gather_nodes_from_elements(*matset_data.elements, mEntityMark, mesh_info.nodes);
00304 
00305     if(!neusets.empty())
00306     {
00307       // if there are neusets, keep track of which elements are being written out
00308       for(Range::iterator iter = matset_data.elements->begin(); 
00309           iter != matset_data.elements->end(); ++iter)
00310       {
00311         unsigned char bit = 0x1;
00312         mbImpl->tag_set_data(mEntityMark, &(*iter), 1, &bit);
00313       }
00314     }
00315 
00316     matset_info.push_back( matset_data );
00317   
00318   }
00319  
00320 
00321   //if user hasn't entered dimension, we figure it out
00322   if( mesh_info.num_dim == 0 )
00323   {
00324     //never want 1 or zero dimensions
00325     if( highest_dimension_of_element_matsets < 2 )
00326       mesh_info.num_dim = 3;
00327     else
00328       mesh_info.num_dim = highest_dimension_of_element_matsets;
00329   }
00330 
00331   Range::iterator range_iter, end_range_iter;
00332   range_iter = mesh_info.nodes.begin();
00333   end_range_iter = mesh_info.nodes.end();
00334 
00335   mesh_info.num_nodes = mesh_info.nodes.size(); 
00336 
00337   //------dirsets--------
00338   
00339   vector_iter= dirsets.begin();
00340   end_vector_iter = dirsets.end();
00341 
00342   for(; vector_iter != end_vector_iter; vector_iter++)
00343   {
00344     
00345     WriteTemplate::DirichletSetData dirset_data;
00346     dirset_data.id = 0;
00347     dirset_data.number_nodes = 0;
00348 
00349     // get the dirset's id
00350     if(mbImpl->tag_get_data(mDirichletSetTag,&(*vector_iter), 1,&id) != MB_SUCCESS) {
00351       mWriteIface->report_error("Couldn't get id tag for dirset %i", id);
00352       return MB_FAILURE;
00353     }
00354     
00355     dirset_data.id = id; 
00356 
00357     std::vector<EntityHandle> node_vector;
00358     //get the nodes of the dirset that are in mesh_info.nodes
00359     if( mbImpl->get_entities_by_handle(*vector_iter, node_vector, true) != MB_SUCCESS ) {
00360       mWriteIface->report_error("Couldn't get nodes in dirset %i", id);
00361       return MB_FAILURE;
00362     }
00363 
00364     std::vector<EntityHandle>::iterator iter, end_iter;
00365     iter = node_vector.begin();
00366     end_iter= node_vector.end();
00367  
00368     int j=0; 
00369     unsigned char node_marked = 0;
00370     ErrorCode result;
00371     for(; iter != end_iter; iter++)
00372     {
00373       if (TYPE_FROM_HANDLE(*iter) != MBVERTEX) continue;
00374       result = mbImpl->tag_get_data(mEntityMark, &(*iter), 1, &node_marked);
00375       if (MB_SUCCESS != result) {
00376         mWriteIface->report_error("Couldn't get mark data.");
00377         return result;
00378       }
00379       
00380       if(node_marked == 0x1) dirset_data.nodes.push_back( *iter );    
00381       j++;
00382     } 
00383     
00384     dirset_data.number_nodes = dirset_data.nodes.size(); 
00385     dirset_info.push_back( dirset_data );
00386   }
00387 
00388   //------neusets--------
00389   vector_iter= neusets.begin();
00390   end_vector_iter = neusets.end();
00391 
00392   for(; vector_iter != end_vector_iter; vector_iter++)
00393   {
00394     WriteTemplate::NeumannSetData neuset_data;
00395 
00396     // get the neuset's id
00397     if(mbImpl->tag_get_data(mNeumannSetTag,&(*vector_iter), 1,&id) != MB_SUCCESS)
00398       return MB_FAILURE;
00399 
00400     neuset_data.id = id; 
00401     neuset_data.mesh_set_handle = *vector_iter; 
00402  
00403     //get the sides in two lists, one forward the other reverse; starts with forward sense
00404       // by convention
00405     Range forward_elems, reverse_elems;
00406     if(get_neuset_elems(*vector_iter, 0, forward_elems, reverse_elems) == MB_FAILURE)
00407       return MB_FAILURE;
00408 
00409     ErrorCode result = get_valid_sides(forward_elems, 1, neuset_data);
00410     if (MB_SUCCESS != result) {
00411       mWriteIface->report_error("Couldn't get valid sides data.");
00412       return result;
00413     }
00414     result = get_valid_sides(reverse_elems, -1, neuset_data);
00415     if (MB_SUCCESS != result) {
00416       mWriteIface->report_error("Couldn't get valid sides data.");
00417       return result;
00418     }
00419     
00420     neuset_data.number_elements = neuset_data.elements.size(); 
00421     neuset_info.push_back( neuset_data );
00422   }
00423 
00424   return MB_SUCCESS;
00425 }
00426 
00427 ErrorCode WriteTemplate::get_valid_sides(Range &elems, const int sense,
00428                                            WriteTemplate::NeumannSetData &neuset_data) 
00429 {
00430     // this is where we see if underlying element of side set element is included in output 
00431 
00432   unsigned char element_marked = 0;
00433   ErrorCode result;
00434   for(Range::iterator iter = elems.begin(); iter != elems.end(); iter++)
00435   {
00436       // should insert here if "side" is a quad/tri on a quad/tri mesh
00437     result = mbImpl->tag_get_data(mEntityMark, &(*iter), 1, &element_marked);
00438     if (MB_SUCCESS != result) {
00439       mWriteIface->report_error("Couldn't get mark data.");
00440       return result;
00441     }
00442     
00443     if(element_marked == 0x1)
00444     {
00445       neuset_data.elements.push_back( *iter );
00446 
00447         // TJT TODO: the sense should really be # edges + 1or2
00448       neuset_data.side_numbers.push_back((sense == 1 ? 1 : 2));
00449     }
00450     else //then "side" is probably a quad/tri on a hex/tet mesh
00451     {
00452       std::vector<EntityHandle> parents;
00453       int dimension = CN::Dimension( TYPE_FROM_HANDLE(*iter));
00454 
00455         //get the adjacent parent element of "side"
00456       if( mbImpl->get_adjacencies( &(*iter), 1, dimension+1, false, parents) != MB_SUCCESS ) {
00457         mWriteIface->report_error("Couldn't get adjacencies for neuset.");
00458         return MB_FAILURE;
00459       }
00460        
00461       if(!parents.empty())     
00462       {
00463           //make sure the adjacent parent element will be output
00464         for(unsigned int k=0; k<parents.size(); k++)
00465         {
00466           result = mbImpl->tag_get_data(mEntityMark, &(parents[k]), 1, &element_marked);
00467           if (MB_SUCCESS != result) {
00468             mWriteIface->report_error("Couldn't get mark data.");
00469             return result;
00470           }
00471         
00472           int side_no, this_sense, this_offset;
00473           if(element_marked == 0x1 &&
00474              mbImpl->side_number(parents[k], *iter, side_no, 
00475                                   this_sense, this_offset) == MB_SUCCESS &&
00476              this_sense == sense) {
00477             neuset_data.elements.push_back(parents[k]);
00478             neuset_data.side_numbers.push_back(side_no+1);
00479             break;
00480           }
00481         }
00482       }
00483       else
00484       {
00485         mWriteIface->report_error("No parent element exists for element in neuset %i", neuset_data.id);
00486         return MB_FAILURE;
00487       }
00488     }
00489   }
00490 
00491   return MB_SUCCESS;
00492 }
00493 
00494 ErrorCode WriteTemplate::write_nodes(const int num_nodes, const Range& nodes, const int dimension)
00495 {
00496   //see if should transform coordinates
00497   ErrorCode result;
00498   Tag trans_tag;
00499   result = mbImpl->tag_get_handle( MESH_TRANSFORM_TAG_NAME, 16, MB_TYPE_DOUBLE, trans_tag);
00500   bool transform_needed = true;
00501   if( result == MB_TAG_NOT_FOUND )
00502     transform_needed = false;
00503 
00504   int num_coords_to_fill = transform_needed ? 3 : dimension;
00505 
00506   std::vector<double*> coord_arrays(3);
00507   coord_arrays[0] = new double[num_nodes];
00508   coord_arrays[1] = new double[num_nodes];
00509   coord_arrays[2] = NULL;
00510 
00511   if( num_coords_to_fill == 3 ) 
00512     coord_arrays[2] = new double[num_nodes];
00513  
00514   result = mWriteIface->get_node_coords(dimension, num_nodes, nodes, 
00515                                         mGlobalIdTag, 0, coord_arrays);
00516   if(result != MB_SUCCESS)
00517   {
00518     delete [] coord_arrays[0];
00519     delete [] coord_arrays[1];
00520     if(coord_arrays[2]) delete [] coord_arrays[2];
00521     return result;
00522   }
00523 
00524   if( transform_needed )
00525   {
00526     double trans_matrix[16]; 
00527     const EntityHandle mesh = 0;
00528     result = mbImpl->tag_get_data( trans_tag, &mesh, 1, trans_matrix ); 
00529     if (MB_SUCCESS != result) {
00530       mWriteIface->report_error("Couldn't get transform data.");
00531       return result;
00532     }
00533       
00534     for( int i=0; i<num_nodes; i++)
00535     {
00536 
00537       double vec1[3];
00538       double vec2[3];
00539 
00540       vec2[0] =  coord_arrays[0][i];
00541       vec2[1] =  coord_arrays[1][i];
00542       vec2[2] =  coord_arrays[2][i];
00543 
00544       for( int row=0; row<3; row++ )
00545       {
00546         vec1[row] = 0.0;
00547         for( int col = 0; col<3; col++ )
00548         {
00549           vec1[row] += ( trans_matrix[ (row*4)+col ] * vec2[col] );
00550         }
00551       }
00552 
00553       coord_arrays[0][i] = vec1[0];
00554       coord_arrays[1][i] = vec1[1];
00555       coord_arrays[2][i] = vec1[2];
00556 
00557     }
00558   }
00559 
00560 
00561   // write the nodes 
00562 
00563   /* template - write nodes to file here in some way */
00564 
00565   // clean up
00566   delete [] coord_arrays[0];
00567   delete [] coord_arrays[1];
00568   if(coord_arrays[2]) 
00569     delete [] coord_arrays[2];
00570 
00571   return MB_SUCCESS;
00572 
00573 }
00574 
00575 ErrorCode WriteTemplate::write_matsets(MeshInfo & /* mesh_info (commented out to remove warning) */,
00576                                          std::vector<WriteTemplate::MaterialSetData> &matset_data,
00577                                          std::vector<WriteTemplate::NeumannSetData> &/* neuset_data (commented out to remove warning) */)
00578 {
00579 
00580   unsigned int i;
00581   std::vector<int> connect;
00582   const EntityHandle *connecth;
00583   int num_connecth;
00584   ErrorCode result;
00585   
00586     // don't usually have anywhere near 31 nodes per element
00587   connect.reserve(31);
00588   Range::iterator rit;
00589 
00590   WriteTemplate::MaterialSetData matset;
00591   for (i = 0; i < matset_data.size(); i++) {
00592     matset = matset_data[i];
00593     
00594     for (rit = matset.elements->begin(); rit != matset.elements->end(); rit++) {
00595       
00596         // get the connectivity of this element
00597       result = mbImpl->get_connectivity(*rit, connecth, num_connecth);
00598       if (MB_SUCCESS != result) return result;
00599       
00600         // get the vertex ids
00601       result = mbImpl->tag_get_data(mGlobalIdTag, connecth, num_connecth, &connect[0]);
00602       if (MB_SUCCESS != result) return result;
00603       
00604         // write the data
00605         /* template - write element connectivity here */
00606 
00607       if(/* template - check for error condition! */ false)
00608         return MB_FAILURE;
00609     }
00610   }
00611 
00612   return MB_SUCCESS;
00613 }
00614 
00615 ErrorCode WriteTemplate::initialize_file(MeshInfo &mesh_info)
00616 {
00617     // perform the initializations
00618 
00619   int coord_size, ncoords;
00620   
00621   coord_size = mesh_info.num_dim;
00622   std::cout << "Coord_size = " << coord_size << std::endl;  
00623     /* template - write coord size */
00624 
00625   ncoords = mesh_info.num_nodes;
00626   std::cout << "ncoords = " << ncoords << std::endl;
00627     /* template - write num nodes*/
00628   
00629     /* template - write information on the element types & numbers (depends
00630        on material and other sets) */
00631 
00632 /* node coordinate arrays: */
00633     /* template - initialize variable to hold coordinate arrays */
00634 
00635    return MB_SUCCESS;
00636 }
00637 
00638 
00639 ErrorCode WriteTemplate::open_file(const char* filename)
00640 {
00641    // not a valid filname
00642    if(strlen((const char*)filename) == 0)
00643    {
00644      mWriteIface->report_error("Output filename not specified");
00645       return MB_FAILURE;
00646    }
00647 
00648      /* template - open file & store somewhere */
00649 
00650    // file couldn't be opened
00651    if(/* template - check for file open error here! */ false)
00652    {
00653      mWriteIface->report_error("Cannot open %s", filename);
00654      return MB_FAILURE;
00655    }
00656    return MB_SUCCESS;
00657 }
00658 
00659 ErrorCode WriteTemplate::get_neuset_elems(EntityHandle neuset, int current_sense,
00660                                         Range &forward_elems, Range &reverse_elems) 
00661 {
00662   Range neuset_elems, neuset_meshsets;
00663 
00664     // get the sense tag; don't need to check return, might be an error if the tag
00665     // hasn't been created yet
00666   Tag sense_tag = 0;
00667   mbImpl->tag_get_handle("SENSE", 1, MB_TYPE_INTEGER, sense_tag);
00668 
00669     // get the entities in this set
00670   ErrorCode result = mbImpl->get_entities_by_handle(neuset, neuset_elems, true);
00671   if (MB_FAILURE == result) return result;
00672   
00673     // now remove the meshsets into the neuset_meshsets; first find the first meshset,
00674   Range::iterator range_iter = neuset_elems.begin();
00675   while (TYPE_FROM_HANDLE(*range_iter) != MBENTITYSET && range_iter != neuset_elems.end())
00676     range_iter++;
00677   
00678     // then, if there are some, copy them into neuset_meshsets and erase from neuset_elems
00679   if (range_iter != neuset_elems.end()) {
00680     std::copy(range_iter, neuset_elems.end(), range_inserter(neuset_meshsets));
00681     neuset_elems.erase(range_iter, neuset_elems.end());
00682   }
00683   
00684 
00685     // ok, for the elements, check the sense of this set and copy into the right range
00686     // (if the sense is 0, copy into both ranges)
00687 
00688     // need to step forward on list until we reach the right dimension
00689   Range::iterator dum_it = neuset_elems.end();
00690   dum_it--;
00691   int target_dim = CN::Dimension(TYPE_FROM_HANDLE(*dum_it));
00692   dum_it = neuset_elems.begin();
00693   while (target_dim != CN::Dimension(TYPE_FROM_HANDLE(*dum_it)) &&
00694          dum_it != neuset_elems.end()) 
00695     dum_it++;
00696 
00697   if (current_sense == 1 || current_sense == 0)
00698     std::copy(dum_it, neuset_elems.end(), range_inserter(forward_elems));
00699   if (current_sense == -1 || current_sense == 0)
00700     std::copy(dum_it, neuset_elems.end(), range_inserter(reverse_elems));
00701   
00702     // now loop over the contained meshsets, getting the sense of those and calling this
00703     // function recursively
00704   for (range_iter = neuset_meshsets.begin(); range_iter != neuset_meshsets.end(); range_iter++) {
00705 
00706       // first get the sense; if it's not there, by convention it's forward
00707     int this_sense;
00708     if (0 == sense_tag ||
00709         MB_FAILURE == mbImpl->tag_get_data(sense_tag, &(*range_iter), 1, &this_sense))
00710       this_sense = 1;
00711       
00712       // now get all the entities on this meshset, with the proper (possibly reversed) sense
00713     get_neuset_elems(*range_iter, this_sense*current_sense,
00714                       forward_elems, reverse_elems);
00715   }
00716   
00717   return result;
00718 }
00719 
00720 } // namespace moab
00721 
00722   
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines