Branch data Line data Source code
1 : : /**
2 : : * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3 : : * storing and accessing finite element mesh data.
4 : : *
5 : : * Copyright 2004 Sandia Corporation. Under the terms of Contract
6 : : * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7 : : * retains certain rights in this software.
8 : : *
9 : : * This library is free software; you can redistribute it and/or
10 : : * modify it under the terms of the GNU Lesser General Public
11 : : * License as published by the Free Software Foundation; either
12 : : * version 2.1 of the License, or (at your option) any later version.
13 : : *
14 : : */
15 : :
16 : : #ifdef WIN32
17 : : #ifdef _DEBUG
18 : : // turn off warnings that say they debugging identifier has been truncated
19 : : // this warning comes up when using some STL containers
20 : : #pragma warning( disable : 4786 )
21 : : #endif
22 : : #endif
23 : :
24 : : #include "WriteTemplate.hpp"
25 : :
26 : : #include <utility>
27 : : #include <algorithm>
28 : : #include <time.h>
29 : : #include <string>
30 : : #include <vector>
31 : : #include <stdio.h>
32 : : #include <string.h>
33 : : #include <iostream>
34 : :
35 : : #include "moab/Interface.hpp"
36 : : #include "moab/Range.hpp"
37 : : #include "moab/CN.hpp"
38 : : #include "assert.h"
39 : : #include "Internals.hpp"
40 : : #include "ExoIIUtil.hpp"
41 : : #include "MBTagConventions.hpp"
42 : : #include "moab/WriteUtilIface.hpp"
43 : :
44 : : namespace moab
45 : : {
46 : :
47 : : #define INS_ID( stringvar, prefix, id ) sprintf( stringvar, prefix, id )
48 : :
49 : 0 : WriterIface* WriteTemplate::factory( Interface* iface )
50 : : {
51 [ # # ]: 0 : return new WriteTemplate( iface );
52 : : }
53 : :
54 [ # # ]: 0 : WriteTemplate::WriteTemplate( Interface* impl ) : mbImpl( impl )
55 : : {
56 [ # # ]: 0 : assert( impl != NULL );
57 : :
58 [ # # ]: 0 : impl->query_interface( mWriteIface );
59 : :
60 : : // Initialize in case tag_get_handle fails below
61 : : //! Get and cache predefined tag handles
62 : 0 : int negone = -1;
63 : : impl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mMaterialSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
64 [ # # ]: 0 : &negone );
65 : :
66 : : impl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mDirichletSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
67 [ # # ]: 0 : &negone );
68 : :
69 : : impl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mNeumannSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
70 [ # # ]: 0 : &negone );
71 : :
72 [ # # ]: 0 : mGlobalIdTag = impl->globalId_tag();
73 : :
74 [ # # ]: 0 : impl->tag_get_handle( "WriteTemplate element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT );
75 : 0 : }
76 : :
77 : 0 : WriteTemplate::~WriteTemplate()
78 : : {
79 : 0 : mbImpl->release_interface( mWriteIface );
80 : 0 : mbImpl->tag_delete( mEntityMark );
81 [ # # ]: 0 : }
82 : :
83 : 0 : void WriteTemplate::reset_matset( std::vector< WriteTemplate::MaterialSetData >& matset_info )
84 : : {
85 : 0 : std::vector< WriteTemplate::MaterialSetData >::iterator iter;
86 : :
87 [ # # ][ # # ]: 0 : for( iter = matset_info.begin(); iter != matset_info.end(); ++iter )
[ # # ]
88 [ # # ][ # # ]: 0 : delete( *iter ).elements;
89 : 0 : }
90 : :
91 : 0 : ErrorCode WriteTemplate::write_file( const char* file_name,
92 : : const bool /* overwrite (commented out to remove warning) */,
93 : : const FileOptions& /*opts*/, const EntityHandle* ent_handles, const int num_sets,
94 : : const std::vector< std::string >& /* qa_list */, const Tag* /* tag_list */,
95 : : int /* num_tags */, int /* export_dimension */ )
96 : : {
97 [ # # ][ # # ]: 0 : assert( 0 != mMaterialSetTag && 0 != mNeumannSetTag && 0 != mDirichletSetTag );
[ # # ]
98 : :
99 : : // Check the file name
100 [ # # ]: 0 : if( NULL == strstr( file_name, ".template" ) ) return MB_FAILURE;
101 : :
102 [ # # ][ # # ]: 0 : std::vector< EntityHandle > matsets, dirsets, neusets;
[ # # ]
103 : :
104 [ # # ]: 0 : fileName = file_name;
105 : :
106 : : // Separate into material sets, dirichlet sets, neumann sets
107 : :
108 [ # # ]: 0 : if( num_sets == 0 )
109 : : {
110 : : // Default to all defined sets
111 [ # # ]: 0 : Range this_range;
112 [ # # ]: 0 : mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mMaterialSetTag, NULL, 1, this_range );
113 [ # # ][ # # ]: 0 : std::copy( this_range.begin(), this_range.end(), std::back_inserter( matsets ) );
[ # # ][ # # ]
114 [ # # ]: 0 : this_range.clear();
115 [ # # ]: 0 : mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mDirichletSetTag, NULL, 1, this_range );
116 [ # # ][ # # ]: 0 : std::copy( this_range.begin(), this_range.end(), std::back_inserter( dirsets ) );
[ # # ][ # # ]
117 [ # # ]: 0 : this_range.clear();
118 [ # # ]: 0 : mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mNeumannSetTag, NULL, 1, this_range );
119 [ # # ][ # # ]: 0 : std::copy( this_range.begin(), this_range.end(), std::back_inserter( neusets ) );
[ # # ][ # # ]
120 : : }
121 : : else
122 : : {
123 : : int dummy;
124 [ # # ]: 0 : for( const EntityHandle* iter = ent_handles; iter < ent_handles + num_sets; ++iter )
125 : : {
126 [ # # ][ # # ]: 0 : if( MB_SUCCESS == mbImpl->tag_get_data( mMaterialSetTag, &( *iter ), 1, &dummy ) )
127 [ # # ]: 0 : matsets.push_back( *iter );
128 [ # # ][ # # ]: 0 : else if( MB_SUCCESS == mbImpl->tag_get_data( mDirichletSetTag, &( *iter ), 1, &dummy ) )
129 [ # # ]: 0 : dirsets.push_back( *iter );
130 [ # # ][ # # ]: 0 : else if( MB_SUCCESS == mbImpl->tag_get_data( mNeumannSetTag, &( *iter ), 1, &dummy ) )
131 [ # # ]: 0 : neusets.push_back( *iter );
132 : : }
133 : : }
134 : :
135 : : // If there is nothing to write just return.
136 [ # # ][ # # ]: 0 : if( matsets.empty() && dirsets.empty() && neusets.empty() ) return MB_FILE_WRITE_ERROR;
[ # # ][ # # ]
137 : :
138 [ # # ]: 0 : std::vector< WriteTemplate::MaterialSetData > matset_info;
139 [ # # ]: 0 : std::vector< WriteTemplate::DirichletSetData > dirset_info;
140 [ # # ]: 0 : std::vector< WriteTemplate::NeumannSetData > neuset_info;
141 : :
142 [ # # ]: 0 : MeshInfo mesh_info;
143 : :
144 : 0 : matset_info.clear();
145 [ # # ][ # # ]: 0 : if( gather_mesh_information( mesh_info, matset_info, neuset_info, dirset_info, matsets, neusets, dirsets ) !=
146 : : MB_SUCCESS )
147 : : {
148 [ # # ]: 0 : reset_matset( matset_info );
149 : 0 : return MB_FAILURE;
150 : : }
151 : :
152 : : // Try to open the file after gather mesh info succeeds
153 : : if( /* Test for file open failure */ false )
154 : : {
155 : : reset_matset( matset_info );
156 : : return MB_FAILURE;
157 : : }
158 : :
159 [ # # ][ # # ]: 0 : if( initialize_file( mesh_info ) != MB_SUCCESS )
160 : : {
161 [ # # ]: 0 : reset_matset( matset_info );
162 : 0 : return MB_FAILURE;
163 : : }
164 : :
165 [ # # ][ # # ]: 0 : if( write_nodes( mesh_info.num_nodes, mesh_info.nodes, mesh_info.num_dim ) != MB_SUCCESS )
166 : : {
167 [ # # ]: 0 : reset_matset( matset_info );
168 : 0 : return MB_FAILURE;
169 : : }
170 : :
171 [ # # ][ # # ]: 0 : if( write_matsets( mesh_info, matset_info, neuset_info ) )
172 : : {
173 [ # # ]: 0 : reset_matset( matset_info );
174 : 0 : return MB_FAILURE;
175 : : }
176 : :
177 : 0 : return MB_SUCCESS;
178 : : }
179 : :
180 : 0 : ErrorCode WriteTemplate::gather_mesh_information( MeshInfo& mesh_info,
181 : : std::vector< WriteTemplate::MaterialSetData >& matset_info,
182 : : std::vector< WriteTemplate::NeumannSetData >& neuset_info,
183 : : std::vector< WriteTemplate::DirichletSetData >& dirset_info,
184 : : std::vector< EntityHandle >& matsets,
185 : : std::vector< EntityHandle >& neusets,
186 : : std::vector< EntityHandle >& dirsets )
187 : : {
188 : 0 : std::vector< EntityHandle >::iterator vector_iter, end_vector_iter;
189 : :
190 : 0 : mesh_info.num_nodes = 0;
191 : 0 : mesh_info.num_elements = 0;
192 : 0 : mesh_info.num_matsets = 0;
193 : :
194 : 0 : int id = 0;
195 : :
196 : 0 : vector_iter = matsets.begin();
197 : 0 : end_vector_iter = matsets.end();
198 : :
199 : 0 : mesh_info.num_matsets = matsets.size();
200 : :
201 [ # # ]: 0 : std::vector< EntityHandle > parent_meshsets;
202 : :
203 : : // Clean out the bits for the element mark
204 [ # # ]: 0 : mbImpl->tag_delete( mEntityMark );
205 [ # # ]: 0 : mbImpl->tag_get_handle( "WriteTemplate element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT );
206 : :
207 : 0 : int highest_dimension_of_element_matsets = 0;
208 : :
209 [ # # ][ # # ]: 0 : for( vector_iter = matsets.begin(); vector_iter != matsets.end(); ++vector_iter )
[ # # ]
210 : : {
211 : : WriteTemplate::MaterialSetData matset_data;
212 [ # # ][ # # ]: 0 : matset_data.elements = new Range;
213 : :
214 : : // For the purpose of qa records, get the parents of these matsets
215 [ # # ][ # # ]: 0 : if( mbImpl->get_parent_meshsets( *vector_iter, parent_meshsets ) != MB_SUCCESS ) return MB_FAILURE;
[ # # ]
216 : :
217 : : // Get all Entity Handles in the mesh set
218 [ # # ]: 0 : Range dummy_range;
219 [ # # ][ # # ]: 0 : mbImpl->get_entities_by_handle( *vector_iter, dummy_range, true );
220 : :
221 : : // Find the dimension of the last entity in this range
222 [ # # ]: 0 : Range::iterator entity_iter = dummy_range.end();
223 [ # # ]: 0 : --entity_iter;
224 [ # # ][ # # ]: 0 : int this_dim = CN::Dimension( TYPE_FROM_HANDLE( *entity_iter ) );
[ # # ]
225 [ # # ]: 0 : entity_iter = dummy_range.begin();
226 [ # # ][ # # ]: 0 : while( entity_iter != dummy_range.end() && CN::Dimension( TYPE_FROM_HANDLE( *entity_iter ) ) != this_dim )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
227 [ # # ]: 0 : ++entity_iter;
228 : :
229 [ # # ][ # # ]: 0 : if( entity_iter != dummy_range.end() )
[ # # ]
230 [ # # ][ # # ]: 0 : std::copy( entity_iter, dummy_range.end(), range_inserter( *( matset_data.elements ) ) );
[ # # ]
231 : :
232 [ # # ][ # # ]: 0 : assert( matset_data.elements->begin() == matset_data.elements->end() ||
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
233 [ # # ]: 0 : CN::Dimension( TYPE_FROM_HANDLE( *( matset_data.elements->begin() ) ) ) == this_dim );
234 : :
235 : : // Get the matset's id
236 [ # # ][ # # ]: 0 : if( mbImpl->tag_get_data( mMaterialSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS )
[ # # ]
237 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "Couldn't get matset id from a tag for an element matset" ); }
[ # # ][ # # ]
[ # # ]
238 : :
239 : 0 : matset_data.id = id;
240 : 0 : matset_data.number_attributes = 0;
241 : :
242 : : // Iterate through all the elements in the meshset
243 [ # # ][ # # ]: 0 : Range::iterator elem_range_iter, end_elem_range_iter;
244 [ # # ]: 0 : elem_range_iter = matset_data.elements->begin();
245 [ # # ]: 0 : end_elem_range_iter = matset_data.elements->end();
246 : :
247 : : // Get the entity type for this matset, verifying that it's the same for all elements
248 : : // THIS ASSUMES HANDLES SORT BY TYPE!!!
249 [ # # ][ # # ]: 0 : EntityType entity_type = TYPE_FROM_HANDLE( *elem_range_iter );
250 [ # # ]: 0 : --end_elem_range_iter;
251 [ # # ][ # # ]: 0 : if( entity_type != TYPE_FROM_HANDLE( *( end_elem_range_iter++ ) ) )
[ # # ][ # # ]
252 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "Entities in matset " << id << " not of common type" ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
253 : :
254 [ # # ]: 0 : int dimension = CN::Dimension( entity_type );
255 : :
256 [ # # ]: 0 : if( dimension > highest_dimension_of_element_matsets ) highest_dimension_of_element_matsets = dimension;
257 : :
258 [ # # ][ # # ]: 0 : matset_data.moab_type = mbImpl->type_from_handle( *( matset_data.elements->begin() ) );
[ # # ]
259 [ # # ]: 0 : if( MBMAXTYPE == matset_data.moab_type ) return MB_FAILURE;
260 : :
261 [ # # ][ # # ]: 0 : std::vector< EntityHandle > tmp_conn;
262 [ # # ][ # # ]: 0 : mbImpl->get_connectivity( &( *( matset_data.elements->begin() ) ), 1, tmp_conn );
[ # # ]
263 : : matset_data.element_type =
264 [ # # ]: 0 : ExoIIUtil::get_element_type_from_num_verts( tmp_conn.size(), entity_type, dimension );
265 : :
266 [ # # ]: 0 : if( matset_data.element_type == EXOII_MAX_ELEM_TYPE )
267 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "Element type in matset " << id << " didn't get set correctly" ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
268 : :
269 : 0 : matset_data.number_nodes_per_element = ExoIIUtil::VerticesPerElement[matset_data.element_type];
270 : :
271 : : // Number of nodes for this matset
272 [ # # ]: 0 : matset_data.number_elements = matset_data.elements->size();
273 : :
274 : : // Total number of elements
275 : 0 : mesh_info.num_elements += matset_data.number_elements;
276 : :
277 : : // Get the nodes for the elements
278 [ # # ]: 0 : mWriteIface->gather_nodes_from_elements( *matset_data.elements, mEntityMark, mesh_info.nodes );
279 : :
280 [ # # ]: 0 : if( !neusets.empty() )
281 : : {
282 : : // If there are neusets, keep track of which elements are being written out
283 [ # # ][ # # ]: 0 : for( Range::iterator iter = matset_data.elements->begin(); iter != matset_data.elements->end(); ++iter )
[ # # ][ # # ]
[ # # ]
284 : : {
285 : 0 : unsigned char bit = 0x1;
286 [ # # ][ # # ]: 0 : mbImpl->tag_set_data( mEntityMark, &( *iter ), 1, &bit );
287 : : }
288 : : }
289 : :
290 [ # # ][ # # ]: 0 : matset_info.push_back( matset_data );
291 : 0 : }
292 : :
293 : : // If user hasn't entered dimension, we figure it out
294 [ # # ]: 0 : if( mesh_info.num_dim == 0 )
295 : : {
296 : : // Never want 1 or zero dimensions
297 [ # # ]: 0 : if( highest_dimension_of_element_matsets < 2 )
298 : 0 : mesh_info.num_dim = 3;
299 : : else
300 : 0 : mesh_info.num_dim = highest_dimension_of_element_matsets;
301 : : }
302 : :
303 [ # # ][ # # ]: 0 : Range::iterator range_iter, end_range_iter;
304 [ # # ]: 0 : range_iter = mesh_info.nodes.begin();
305 [ # # ]: 0 : end_range_iter = mesh_info.nodes.end();
306 : :
307 [ # # ]: 0 : mesh_info.num_nodes = mesh_info.nodes.size();
308 : :
309 : : //------dirsets--------
310 : :
311 : 0 : vector_iter = dirsets.begin();
312 : 0 : end_vector_iter = dirsets.end();
313 : :
314 [ # # ][ # # ]: 0 : for( ; vector_iter != end_vector_iter; ++vector_iter )
[ # # ]
315 : : {
316 [ # # ]: 0 : WriteTemplate::DirichletSetData dirset_data;
317 : 0 : dirset_data.id = 0;
318 : 0 : dirset_data.number_nodes = 0;
319 : :
320 : : // Get the dirset's id
321 [ # # ][ # # ]: 0 : if( mbImpl->tag_get_data( mDirichletSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS )
[ # # ]
322 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "Couldn't get id tag for dirset " << id ); }
[ # # ][ # # ]
[ # # ][ # # ]
323 : :
324 : 0 : dirset_data.id = id;
325 : :
326 [ # # ][ # # ]: 0 : std::vector< EntityHandle > node_vector;
327 : : // Get the nodes of the dirset that are in mesh_info.nodes
328 [ # # ][ # # ]: 0 : if( mbImpl->get_entities_by_handle( *vector_iter, node_vector, true ) != MB_SUCCESS )
[ # # ]
329 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "Couldn't get nodes in dirset " << id ); }
[ # # ][ # # ]
[ # # ][ # # ]
330 : :
331 : 0 : std::vector< EntityHandle >::iterator iter, end_iter;
332 : 0 : iter = node_vector.begin();
333 : 0 : end_iter = node_vector.end();
334 : :
335 : 0 : int j = 0;
336 : 0 : unsigned char node_marked = 0;
337 : : ErrorCode result;
338 [ # # ][ # # ]: 0 : for( ; iter != end_iter; ++iter )
[ # # ]
339 : : {
340 [ # # ][ # # ]: 0 : if( TYPE_FROM_HANDLE( *iter ) != MBVERTEX ) continue;
[ # # ]
341 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( mEntityMark, &( *iter ), 1, &node_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
342 : :
343 [ # # ][ # # ]: 0 : if( 0x1 == node_marked ) dirset_data.nodes.push_back( *iter );
[ # # ]
344 : 0 : j++;
345 : : }
346 : :
347 : 0 : dirset_data.number_nodes = dirset_data.nodes.size();
348 [ # # ][ # # ]: 0 : dirset_info.push_back( dirset_data );
349 : 0 : }
350 : :
351 : : //------neusets--------
352 : 0 : vector_iter = neusets.begin();
353 : 0 : end_vector_iter = neusets.end();
354 : :
355 [ # # ][ # # ]: 0 : for( ; vector_iter != end_vector_iter; ++vector_iter )
[ # # ]
356 : : {
357 [ # # ]: 0 : WriteTemplate::NeumannSetData neuset_data;
358 : :
359 : : // Get the neuset's id
360 [ # # ][ # # ]: 0 : if( mbImpl->tag_get_data( mNeumannSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS ) return MB_FAILURE;
[ # # ]
361 : :
362 : 0 : neuset_data.id = id;
363 [ # # ]: 0 : neuset_data.mesh_set_handle = *vector_iter;
364 : :
365 : : // Get the sides in two lists, one forward the other reverse; starts with forward sense
366 : : // by convention
367 [ # # ][ # # ]: 0 : Range forward_elems, reverse_elems;
[ # # ][ # # ]
368 [ # # ][ # # ]: 0 : if( get_neuset_elems( *vector_iter, 0, forward_elems, reverse_elems ) == MB_FAILURE ) return MB_FAILURE;
[ # # ]
369 : :
370 [ # # ][ # # ]: 0 : ErrorCode result = get_valid_sides( forward_elems, 1, neuset_data );MB_CHK_SET_ERR( result, "Couldn't get valid sides data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
371 [ # # ][ # # ]: 0 : result = get_valid_sides( reverse_elems, -1, neuset_data );MB_CHK_SET_ERR( result, "Couldn't get valid sides data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
372 : :
373 : 0 : neuset_data.number_elements = neuset_data.elements.size();
374 [ # # ][ # # ]: 0 : neuset_info.push_back( neuset_data );
375 : 0 : }
376 : :
377 : 0 : return MB_SUCCESS;
378 : : }
379 : :
380 : 0 : ErrorCode WriteTemplate::get_valid_sides( Range& elems, const int sense, WriteTemplate::NeumannSetData& neuset_data )
381 : : {
382 : : // This is where we see if underlying element of side set element is included in output
383 : :
384 : 0 : unsigned char element_marked = 0;
385 : : ErrorCode result;
386 [ # # ][ # # ]: 0 : for( Range::iterator iter = elems.begin(); iter != elems.end(); ++iter )
[ # # ][ # # ]
[ # # ]
387 : : {
388 : : // Should insert here if "side" is a quad/tri on a quad/tri mesh
389 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( mEntityMark, &( *iter ), 1, &element_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
390 : :
391 [ # # ]: 0 : if( 0x1 == element_marked )
392 : : {
393 [ # # ][ # # ]: 0 : neuset_data.elements.push_back( *iter );
394 : :
395 : : // TJT TODO: the sense should really be # edges + 1or2
396 [ # # ][ # # ]: 0 : neuset_data.side_numbers.push_back( ( sense == 1 ? 1 : 2 ) );
397 : : }
398 : : else
399 : : { // Then "side" is probably a quad/tri on a hex/tet mesh
400 [ # # ]: 0 : std::vector< EntityHandle > parents;
401 [ # # ][ # # ]: 0 : int dimension = CN::Dimension( TYPE_FROM_HANDLE( *iter ) );
[ # # ]
402 : :
403 : : // Get the adjacent parent element of "side"
404 [ # # ][ # # ]: 0 : if( mbImpl->get_adjacencies( &( *iter ), 1, dimension + 1, false, parents ) != MB_SUCCESS )
[ # # ]
405 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "Couldn't get adjacencies for neuset" ); }
[ # # ][ # # ]
[ # # ]
406 : :
407 [ # # ]: 0 : if( !parents.empty() )
408 : : {
409 : : // Make sure the adjacent parent element will be output
410 [ # # ]: 0 : for( unsigned int k = 0; k < parents.size(); k++ )
411 : : {
412 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( mEntityMark, &( parents[k] ), 1, &element_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
413 : :
414 : : int side_no, this_sense, this_offset;
415 [ # # ][ # # ]: 0 : if( 0x1 == element_marked &&
416 [ # # ][ # # ]: 0 : mbImpl->side_number( parents[k], *iter, side_no, this_sense, this_offset ) == MB_SUCCESS &&
[ # # ][ # # ]
[ # # ]
417 : 0 : this_sense == sense )
418 : : {
419 [ # # ][ # # ]: 0 : neuset_data.elements.push_back( parents[k] );
420 [ # # ]: 0 : neuset_data.side_numbers.push_back( side_no + 1 );
421 : 0 : break;
422 : : }
423 : : }
424 : : }
425 : : else
426 : : {
427 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "No parent element exists for element in neuset " << neuset_data.id );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
428 : 0 : }
429 : : }
430 : : }
431 : :
432 : 0 : return MB_SUCCESS;
433 : : }
434 : :
435 : 0 : ErrorCode WriteTemplate::write_nodes( const int num_nodes, const Range& nodes, const int dimension )
436 : : {
437 : : // See if should transform coordinates
438 : : ErrorCode result;
439 : : Tag trans_tag;
440 [ # # ]: 0 : result = mbImpl->tag_get_handle( MESH_TRANSFORM_TAG_NAME, 16, MB_TYPE_DOUBLE, trans_tag );
441 : 0 : bool transform_needed = true;
442 [ # # ]: 0 : if( result == MB_TAG_NOT_FOUND ) transform_needed = false;
443 : :
444 [ # # ]: 0 : int num_coords_to_fill = transform_needed ? 3 : dimension;
445 : :
446 [ # # ]: 0 : std::vector< double* > coord_arrays( 3 );
447 [ # # ][ # # ]: 0 : coord_arrays[0] = new double[num_nodes];
[ # # ]
448 [ # # ][ # # ]: 0 : coord_arrays[1] = new double[num_nodes];
[ # # ]
449 [ # # ]: 0 : coord_arrays[2] = NULL;
450 : :
451 [ # # ][ # # ]: 0 : if( num_coords_to_fill == 3 ) coord_arrays[2] = new double[num_nodes];
[ # # ][ # # ]
452 : :
453 [ # # ]: 0 : result = mWriteIface->get_node_coords( dimension, num_nodes, nodes, mGlobalIdTag, 0, coord_arrays );
454 [ # # ]: 0 : if( result != MB_SUCCESS )
455 : : {
456 [ # # ][ # # ]: 0 : delete[] coord_arrays[0];
457 [ # # ][ # # ]: 0 : delete[] coord_arrays[1];
458 [ # # ][ # # ]: 0 : if( coord_arrays[2] ) delete[] coord_arrays[2];
[ # # ][ # # ]
459 : 0 : return result;
460 : : }
461 : :
462 [ # # ]: 0 : if( transform_needed )
463 : : {
464 : : double trans_matrix[16];
465 : 0 : const EntityHandle mesh = 0;
466 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( trans_tag, &mesh, 1, trans_matrix );MB_CHK_SET_ERR( result, "Couldn't get transform data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
467 : :
468 [ # # ]: 0 : for( int i = 0; i < num_nodes; i++ )
469 : : {
470 : : double vec1[3];
471 : : double vec2[3];
472 : :
473 [ # # ]: 0 : vec2[0] = coord_arrays[0][i];
474 [ # # ]: 0 : vec2[1] = coord_arrays[1][i];
475 [ # # ]: 0 : vec2[2] = coord_arrays[2][i];
476 : :
477 [ # # ]: 0 : for( int row = 0; row < 3; row++ )
478 : : {
479 : 0 : vec1[row] = 0.0;
480 [ # # ]: 0 : for( int col = 0; col < 3; col++ )
481 : 0 : vec1[row] += ( trans_matrix[( row * 4 ) + col] * vec2[col] );
482 : : }
483 : :
484 [ # # ]: 0 : coord_arrays[0][i] = vec1[0];
485 [ # # ]: 0 : coord_arrays[1][i] = vec1[1];
486 [ # # ]: 0 : coord_arrays[2][i] = vec1[2];
487 : : }
488 : : }
489 : :
490 : : // Write the nodes
491 : :
492 : : /* Template - write nodes to file here in some way */
493 : :
494 : : // Clean up
495 [ # # ][ # # ]: 0 : delete[] coord_arrays[0];
496 [ # # ][ # # ]: 0 : delete[] coord_arrays[1];
497 [ # # ][ # # ]: 0 : if( coord_arrays[2] ) delete[] coord_arrays[2];
[ # # ][ # # ]
498 : :
499 : 0 : return MB_SUCCESS;
500 : : }
501 : :
502 : 0 : ErrorCode WriteTemplate::write_matsets(
503 : : MeshInfo& /* mesh_info (commented out to remove warning) */,
504 : : std::vector< WriteTemplate::MaterialSetData >& matset_data,
505 : : std::vector< WriteTemplate::NeumannSetData >& /* neuset_data (commented out to remove warning) */ )
506 : : {
507 : : unsigned int i;
508 [ # # ]: 0 : std::vector< int > connect;
509 : : const EntityHandle* connecth;
510 : : int num_connecth;
511 : : ErrorCode result;
512 : :
513 : : // Don't usually have anywhere near 31 nodes per element
514 [ # # ]: 0 : connect.reserve( 31 );
515 [ # # ]: 0 : Range::iterator rit;
516 : :
517 : : WriteTemplate::MaterialSetData matset;
518 [ # # ]: 0 : for( i = 0; i < matset_data.size(); i++ )
519 : : {
520 [ # # ]: 0 : matset = matset_data[i];
521 : :
522 [ # # ][ # # ]: 0 : for( rit = matset.elements->begin(); rit != matset.elements->end(); ++rit )
[ # # ][ # # ]
[ # # ]
523 : : {
524 : : // Get the connectivity of this element
525 [ # # ][ # # ]: 0 : result = mbImpl->get_connectivity( *rit, connecth, num_connecth );
526 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
527 : :
528 : : // Get the vertex ids
529 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( mGlobalIdTag, connecth, num_connecth, &connect[0] );
530 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
531 : :
532 : : // Write the data
533 : : /* Template - write element connectivity here */
534 : :
535 : : if( /* Template - check for error condition! */ false ) return MB_FAILURE;
536 : : }
537 : : }
538 : :
539 : 0 : return MB_SUCCESS;
540 : : }
541 : :
542 : 0 : ErrorCode WriteTemplate::initialize_file( MeshInfo& mesh_info )
543 : : {
544 : : // Perform the initializations
545 : :
546 : : int coord_size, ncoords;
547 : :
548 : 0 : coord_size = mesh_info.num_dim;
549 : 0 : std::cout << "Coord_size = " << coord_size << std::endl;
550 : : /* Template - write coord size */
551 : :
552 : 0 : ncoords = mesh_info.num_nodes;
553 : 0 : std::cout << "ncoords = " << ncoords << std::endl;
554 : : /* Template - write num nodes*/
555 : :
556 : : /* Template - write information on the element types & numbers (depends
557 : : on material and other sets) */
558 : :
559 : : /* Node coordinate arrays: */
560 : : /* Template - initialize variable to hold coordinate arrays */
561 : :
562 : 0 : return MB_SUCCESS;
563 : : }
564 : :
565 : 0 : ErrorCode WriteTemplate::open_file( const char* filename )
566 : : {
567 : : // Not a valid filename
568 [ # # ][ # # ]: 0 : if( strlen( (const char*)filename ) == 0 ) { MB_SET_ERR( MB_FAILURE, "Output filename not specified" ); }
[ # # ][ # # ]
[ # # ][ # # ]
569 : :
570 : : /* Template - open file & store somewhere */
571 : :
572 : : // File couldn't be opened
573 : : if( /* Template - check for file open error here! */ false )
574 : : { MB_SET_ERR( MB_FAILURE, "Cannot open " << filename ); }
575 : :
576 : 0 : return MB_SUCCESS;
577 : : }
578 : :
579 : 0 : ErrorCode WriteTemplate::get_neuset_elems( EntityHandle neuset, int current_sense, Range& forward_elems,
580 : : Range& reverse_elems )
581 : : {
582 [ # # ][ # # ]: 0 : Range neuset_elems, neuset_meshsets;
583 : :
584 : : // Get the sense tag; don't need to check return, might be an error if the tag
585 : : // hasn't been created yet
586 : 0 : Tag sense_tag = 0;
587 [ # # ]: 0 : mbImpl->tag_get_handle( "SENSE", 1, MB_TYPE_INTEGER, sense_tag );
588 : :
589 : : // Get the entities in this set
590 [ # # ]: 0 : ErrorCode result = mbImpl->get_entities_by_handle( neuset, neuset_elems, true );
591 [ # # ]: 0 : if( MB_FAILURE == result ) return result;
592 : :
593 : : // Now remove the meshsets into the neuset_meshsets; first find the first meshset,
594 [ # # ]: 0 : Range::iterator range_iter = neuset_elems.begin();
595 [ # # ][ # # ]: 0 : while( TYPE_FROM_HANDLE( *range_iter ) != MBENTITYSET && range_iter != neuset_elems.end() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
[ # # # # ]
596 [ # # ]: 0 : ++range_iter;
597 : :
598 : : // Then, if there are some, copy them into neuset_meshsets and erase from neuset_elems
599 [ # # ][ # # ]: 0 : if( range_iter != neuset_elems.end() )
[ # # ]
600 : : {
601 [ # # ][ # # ]: 0 : std::copy( range_iter, neuset_elems.end(), range_inserter( neuset_meshsets ) );
[ # # ]
602 [ # # ][ # # ]: 0 : neuset_elems.erase( range_iter, neuset_elems.end() );
603 : : }
604 : :
605 : : // OK, for the elements, check the sense of this set and copy into the right range
606 : : // (if the sense is 0, copy into both ranges)
607 : :
608 : : // Need to step forward on list until we reach the right dimension
609 [ # # ]: 0 : Range::iterator dum_it = neuset_elems.end();
610 [ # # ]: 0 : --dum_it;
611 [ # # ][ # # ]: 0 : int target_dim = CN::Dimension( TYPE_FROM_HANDLE( *dum_it ) );
[ # # ]
612 [ # # ]: 0 : dum_it = neuset_elems.begin();
613 [ # # ][ # # ]: 0 : while( target_dim != CN::Dimension( TYPE_FROM_HANDLE( *dum_it ) ) && dum_it != neuset_elems.end() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
614 [ # # ]: 0 : ++dum_it;
615 : :
616 [ # # ][ # # ]: 0 : if( current_sense == 1 || current_sense == 0 )
617 [ # # ][ # # ]: 0 : std::copy( dum_it, neuset_elems.end(), range_inserter( forward_elems ) );
[ # # ]
618 [ # # ][ # # ]: 0 : if( current_sense == -1 || current_sense == 0 )
619 [ # # ][ # # ]: 0 : std::copy( dum_it, neuset_elems.end(), range_inserter( reverse_elems ) );
[ # # ]
620 : :
621 : : // Now loop over the contained meshsets, getting the sense of those and calling this
622 : : // function recursively
623 [ # # ][ # # ]: 0 : for( range_iter = neuset_meshsets.begin(); range_iter != neuset_meshsets.end(); ++range_iter )
[ # # ][ # # ]
[ # # ]
624 : : {
625 : : // First get the sense; if it's not there, by convention it's forward
626 : : int this_sense;
627 [ # # ][ # # ]: 0 : if( 0 == sense_tag || MB_FAILURE == mbImpl->tag_get_data( sense_tag, &( *range_iter ), 1, &this_sense ) )
[ # # ][ # # ]
[ # # ]
628 : 0 : this_sense = 1;
629 : :
630 : : // Now get all the entities on this meshset, with the proper (possibly reversed) sense
631 [ # # ][ # # ]: 0 : get_neuset_elems( *range_iter, this_sense * current_sense, forward_elems, reverse_elems );
632 : : }
633 : :
634 : 0 : return result;
635 : : }
636 : :
637 [ + - ][ + - ]: 228 : } // namespace moab
|