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 "WriteSLAC.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 : : #include <assert.h>
35 : :
36 : : #include "netcdf.h"
37 : : #include "moab/Interface.hpp"
38 : : #include "moab/Range.hpp"
39 : : #include "moab/CN.hpp"
40 : : #include "Internals.hpp"
41 : : #include "ExoIIUtil.hpp"
42 : : #include "MBTagConventions.hpp"
43 : : #include "moab/WriteUtilIface.hpp"
44 : :
45 : : #ifndef MOAB_HAVE_NETCDF
46 : : #error Attempt to compile WriteSLAC with NetCDF disabled.
47 : : #endif
48 : :
49 : : namespace moab
50 : : {
51 : :
52 : : #define INS_ID( stringvar, prefix, id ) sprintf( stringvar, prefix, id )
53 : :
54 : : #define GET_VAR( name, id, dims ) \
55 : : { \
56 : : id = -1; \
57 : : int gvfail = nc_inq_varid( ncFile, name, &id ); \
58 : : if( NC_NOERR == gvfail ) \
59 : : { \
60 : : int ndims; \
61 : : gvfail = nc_inq_varndims( ncFile, id, &ndims ); \
62 : : if( NC_NOERR == gvfail ) \
63 : : { \
64 : : dims.resize( ndims ); \
65 : : gvfail = nc_inq_vardimid( ncFile, id, &dims[0] ); \
66 : : } \
67 : : } \
68 : : }
69 : :
70 : 0 : WriterIface* WriteSLAC::factory( Interface* iface )
71 : : {
72 [ # # ]: 0 : return new WriteSLAC( iface );
73 : : }
74 : :
75 [ # # ]: 0 : WriteSLAC::WriteSLAC( Interface* impl ) : mbImpl( impl ), ncFile( 0 )
76 : : {
77 [ # # ]: 0 : assert( impl != NULL );
78 : :
79 [ # # ]: 0 : impl->query_interface( mWriteIface );
80 : :
81 : : // Initialize in case tag_get_handle fails below
82 : : //! get and cache predefined tag handles
83 : 0 : int negone = -1;
84 : : impl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mMaterialSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
85 [ # # ]: 0 : &negone );
86 : :
87 : : impl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mDirichletSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
88 [ # # ]: 0 : &negone );
89 : :
90 : : impl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mNeumannSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
91 [ # # ]: 0 : &negone );
92 : :
93 [ # # ]: 0 : mGlobalIdTag = impl->globalId_tag();
94 : :
95 : 0 : int dum_val = -1;
96 [ # # ]: 0 : impl->tag_get_handle( "__matSetIdTag", 1, MB_TYPE_INTEGER, mMatSetIdTag, MB_TAG_DENSE | MB_TAG_CREAT, &dum_val );
97 : :
98 [ # # ]: 0 : impl->tag_get_handle( "WriteSLAC element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT );
99 : 0 : }
100 : :
101 : 0 : WriteSLAC::~WriteSLAC()
102 : : {
103 : 0 : mbImpl->release_interface( mWriteIface );
104 : 0 : mbImpl->tag_delete( mEntityMark );
105 [ # # ]: 0 : }
106 : :
107 : 0 : void WriteSLAC::reset_matset( std::vector< WriteSLAC::MaterialSetData >& matset_info )
108 : : {
109 : 0 : std::vector< WriteSLAC::MaterialSetData >::iterator iter;
110 : :
111 [ # # ][ # # ]: 0 : for( iter = matset_info.begin(); iter != matset_info.end(); ++iter )
[ # # ]
112 [ # # ][ # # ]: 0 : delete( *iter ).elements;
113 : 0 : }
114 : :
115 : 0 : ErrorCode WriteSLAC::write_file( const char* file_name, const bool overwrite, const FileOptions&,
116 : : const EntityHandle* ent_handles, const int num_sets,
117 : : const std::vector< std::string >& /* qa_list */, const Tag* /* tag_list */,
118 : : int /* num_tags */, int /* export_dimension */ )
119 : : {
120 [ # # ][ # # ]: 0 : assert( 0 != mMaterialSetTag && 0 != mNeumannSetTag && 0 != mDirichletSetTag );
[ # # ]
121 : :
122 : : // Check the file name
123 [ # # ]: 0 : if( NULL == strstr( file_name, ".ncdf" ) ) return MB_FAILURE;
124 : :
125 [ # # ][ # # ]: 0 : std::vector< EntityHandle > matsets, dirsets, neusets, entities;
[ # # ][ # # ]
126 : :
127 [ # # ]: 0 : fileName = file_name;
128 : :
129 : : // Separate into material sets, dirichlet sets, neumann sets
130 : :
131 [ # # ]: 0 : if( num_sets == 0 )
132 : : {
133 : : // Default to all defined sets
134 [ # # ]: 0 : Range this_range;
135 [ # # ]: 0 : mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mMaterialSetTag, NULL, 1, this_range );
136 [ # # ][ # # ]: 0 : std::copy( this_range.begin(), this_range.end(), std::back_inserter( matsets ) );
[ # # ][ # # ]
137 [ # # ]: 0 : this_range.clear();
138 [ # # ]: 0 : mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mDirichletSetTag, NULL, 1, this_range );
139 [ # # ][ # # ]: 0 : std::copy( this_range.begin(), this_range.end(), std::back_inserter( dirsets ) );
[ # # ][ # # ]
140 [ # # ]: 0 : this_range.clear();
141 [ # # ]: 0 : mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mNeumannSetTag, NULL, 1, this_range );
142 [ # # ][ # # ]: 0 : std::copy( this_range.begin(), this_range.end(), std::back_inserter( neusets ) );
[ # # ][ # # ]
143 : : }
144 : : else
145 : : {
146 : : int dummy;
147 [ # # ]: 0 : for( const EntityHandle* iter = ent_handles; iter < ent_handles + num_sets; ++iter )
148 : : {
149 [ # # ][ # # ]: 0 : if( MB_SUCCESS == mbImpl->tag_get_data( mMaterialSetTag, &( *iter ), 1, &dummy ) )
150 [ # # ]: 0 : matsets.push_back( *iter );
151 [ # # ][ # # ]: 0 : else if( MB_SUCCESS == mbImpl->tag_get_data( mDirichletSetTag, &( *iter ), 1, &dummy ) )
152 [ # # ]: 0 : dirsets.push_back( *iter );
153 [ # # ][ # # ]: 0 : else if( MB_SUCCESS == mbImpl->tag_get_data( mNeumannSetTag, &( *iter ), 1, &dummy ) )
154 [ # # ]: 0 : neusets.push_back( *iter );
155 : : }
156 : : }
157 : :
158 : : // If there is nothing to write just return.
159 [ # # ][ # # ]: 0 : if( matsets.empty() && dirsets.empty() && neusets.empty() ) return MB_FILE_WRITE_ERROR;
[ # # ][ # # ]
160 : :
161 [ # # ]: 0 : std::vector< WriteSLAC::MaterialSetData > matset_info;
162 [ # # ]: 0 : std::vector< WriteSLAC::DirichletSetData > dirset_info;
163 [ # # ]: 0 : std::vector< WriteSLAC::NeumannSetData > neuset_info;
164 : :
165 [ # # ]: 0 : MeshInfo mesh_info;
166 : :
167 : 0 : matset_info.clear();
168 [ # # ][ # # ]: 0 : if( gather_mesh_information( mesh_info, matset_info, neuset_info, dirset_info, matsets, neusets, dirsets ) !=
169 : : MB_SUCCESS )
170 : : {
171 [ # # ]: 0 : reset_matset( matset_info );
172 : 0 : return MB_FAILURE;
173 : : }
174 : :
175 : : // Try to open the file after gather mesh info succeeds
176 [ # # ][ # # ]: 0 : int fail = nc_create( file_name, overwrite ? NC_CLOBBER : NC_NOCLOBBER, &ncFile );
177 [ # # ]: 0 : if( NC_NOERR != fail )
178 : : {
179 [ # # ]: 0 : reset_matset( matset_info );
180 : 0 : return MB_FAILURE;
181 : : }
182 : :
183 [ # # ][ # # ]: 0 : if( initialize_file( mesh_info ) != MB_SUCCESS )
184 : : {
185 [ # # ]: 0 : reset_matset( matset_info );
186 : 0 : return MB_FAILURE;
187 : : }
188 : :
189 [ # # ][ # # ]: 0 : if( write_nodes( mesh_info.num_nodes, mesh_info.nodes, mesh_info.num_dim ) != MB_SUCCESS )
190 : : {
191 [ # # ]: 0 : reset_matset( matset_info );
192 : 0 : return MB_FAILURE;
193 : : }
194 : :
195 [ # # ][ # # ]: 0 : if( write_matsets( mesh_info, matset_info, neuset_info ) )
196 : : {
197 [ # # ]: 0 : reset_matset( matset_info );
198 : 0 : return MB_FAILURE;
199 : : }
200 : :
201 [ # # ]: 0 : fail = nc_close( ncFile );
202 [ # # ]: 0 : if( NC_NOERR != fail ) return MB_FAILURE;
203 : :
204 : 0 : return MB_SUCCESS;
205 : : }
206 : :
207 : 0 : ErrorCode WriteSLAC::gather_mesh_information(
208 : : MeshInfo& mesh_info, std::vector< WriteSLAC::MaterialSetData >& matset_info,
209 : : std::vector< WriteSLAC::NeumannSetData >& neuset_info, std::vector< WriteSLAC::DirichletSetData >& dirset_info,
210 : : std::vector< EntityHandle >& matsets, std::vector< EntityHandle >& neusets, std::vector< EntityHandle >& dirsets )
211 : : {
212 : 0 : std::vector< EntityHandle >::iterator vector_iter, end_vector_iter;
213 : :
214 : 0 : mesh_info.num_nodes = 0;
215 : 0 : mesh_info.num_elements = 0;
216 : 0 : mesh_info.num_matsets = 0;
217 : :
218 : 0 : int id = 0;
219 : :
220 : 0 : vector_iter = matsets.begin();
221 : 0 : end_vector_iter = matsets.end();
222 : :
223 : 0 : mesh_info.num_matsets = matsets.size();
224 : :
225 [ # # ]: 0 : std::vector< EntityHandle > parent_meshsets;
226 : :
227 : : // Clean out the bits for the element mark
228 [ # # ]: 0 : mbImpl->tag_delete( mEntityMark );
229 [ # # ]: 0 : mbImpl->tag_get_handle( "WriteSLAC element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT );
230 : :
231 : 0 : int highest_dimension_of_element_matsets = 0;
232 : :
233 [ # # ][ # # ]: 0 : for( vector_iter = matsets.begin(); vector_iter != matsets.end(); ++vector_iter )
[ # # ]
234 : : {
235 : : WriteSLAC::MaterialSetData matset_data;
236 [ # # ][ # # ]: 0 : matset_data.elements = new Range;
237 : :
238 : : // For the purpose of qa records, get the parents of these matsets
239 [ # # ][ # # ]: 0 : if( mbImpl->get_parent_meshsets( *vector_iter, parent_meshsets ) != MB_SUCCESS ) return MB_FAILURE;
[ # # ]
240 : :
241 : : // Get all Entity Handles in the mesh set
242 [ # # ]: 0 : Range dummy_range;
243 [ # # ][ # # ]: 0 : mbImpl->get_entities_by_handle( *vector_iter, dummy_range, true );
244 : :
245 : : // Wait a minute, we are doing some filtering here that doesn't make sense at this level CJS
246 : :
247 : : // Find the dimension of the last entity in this range
248 [ # # ]: 0 : Range::iterator entity_iter = dummy_range.end();
249 [ # # ]: 0 : entity_iter = dummy_range.end();
250 [ # # ]: 0 : --entity_iter;
251 [ # # ][ # # ]: 0 : int this_dim = CN::Dimension( TYPE_FROM_HANDLE( *entity_iter ) );
[ # # ]
252 [ # # ]: 0 : entity_iter = dummy_range.begin();
253 [ # # ][ # # ]: 0 : while( entity_iter != dummy_range.end() && CN::Dimension( TYPE_FROM_HANDLE( *entity_iter ) ) != this_dim )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
254 [ # # ]: 0 : ++entity_iter;
255 : :
256 [ # # ][ # # ]: 0 : if( entity_iter != dummy_range.end() )
[ # # ]
257 [ # # ][ # # ]: 0 : std::copy( entity_iter, dummy_range.end(), range_inserter( *( matset_data.elements ) ) );
[ # # ]
258 : :
259 [ # # ][ # # ]: 0 : assert( matset_data.elements->begin() == matset_data.elements->end() ||
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
260 [ # # ]: 0 : CN::Dimension( TYPE_FROM_HANDLE( *( matset_data.elements->begin() ) ) ) == this_dim );
261 : :
262 : : // Get the matset's id
263 [ # # ][ # # ]: 0 : if( mbImpl->tag_get_data( mMaterialSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS )
[ # # ]
264 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "Couldn't get matset id from a tag for an element matset" ); }
[ # # ][ # # ]
[ # # ]
265 : :
266 : 0 : matset_data.id = id;
267 : 0 : matset_data.number_attributes = 0;
268 : :
269 : : // Iterate through all the elements in the meshset
270 [ # # ][ # # ]: 0 : Range::iterator elem_range_iter, end_elem_range_iter;
271 [ # # ]: 0 : elem_range_iter = matset_data.elements->begin();
272 [ # # ]: 0 : end_elem_range_iter = matset_data.elements->end();
273 : :
274 : : // Get the entity type for this matset, verifying that it's the same for all elements
275 : : // THIS ASSUMES HANDLES SORT BY TYPE!!!
276 [ # # ][ # # ]: 0 : EntityType entity_type = TYPE_FROM_HANDLE( *elem_range_iter );
277 [ # # ]: 0 : --end_elem_range_iter;
278 [ # # ][ # # ]: 0 : if( entity_type != TYPE_FROM_HANDLE( *( end_elem_range_iter++ ) ) )
[ # # ][ # # ]
279 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "Entities in matset " << id << " not of common type" ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
280 : :
281 : 0 : int dimension = -1;
282 [ # # ][ # # ]: 0 : if( entity_type == MBQUAD || entity_type == MBTRI )
283 : 0 : dimension = 3; // Output shells by default
284 [ # # ]: 0 : else if( entity_type == MBEDGE )
285 : 0 : dimension = 2;
286 : : else
287 [ # # ]: 0 : dimension = CN::Dimension( entity_type );
288 : :
289 [ # # ]: 0 : if( dimension > highest_dimension_of_element_matsets ) highest_dimension_of_element_matsets = dimension;
290 : :
291 [ # # ][ # # ]: 0 : matset_data.moab_type = mbImpl->type_from_handle( *( matset_data.elements->begin() ) );
[ # # ]
292 [ # # ]: 0 : if( MBMAXTYPE == matset_data.moab_type ) return MB_FAILURE;
293 : :
294 [ # # ][ # # ]: 0 : std::vector< EntityHandle > tmp_conn;
295 [ # # ][ # # ]: 0 : mbImpl->get_connectivity( &( *( matset_data.elements->begin() ) ), 1, tmp_conn );
[ # # ]
296 : : matset_data.element_type =
297 [ # # ]: 0 : ExoIIUtil::get_element_type_from_num_verts( tmp_conn.size(), entity_type, dimension );
298 : :
299 [ # # ]: 0 : if( matset_data.element_type == EXOII_MAX_ELEM_TYPE )
300 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "Element type in matset " << id << " didn't get set correctly" ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
301 : :
302 : 0 : matset_data.number_nodes_per_element = ExoIIUtil::VerticesPerElement[matset_data.element_type];
303 : :
304 : : // Number of nodes for this matset
305 [ # # ]: 0 : matset_data.number_elements = matset_data.elements->size();
306 : :
307 : : // Total number of elements
308 : 0 : mesh_info.num_elements += matset_data.number_elements;
309 : :
310 : : // Get the nodes for the elements
311 [ # # ]: 0 : mWriteIface->gather_nodes_from_elements( *matset_data.elements, mEntityMark, mesh_info.nodes );
312 : :
313 [ # # ]: 0 : if( !neusets.empty() )
314 : : {
315 : : // If there are neusets, keep track of which elements are being written out
316 [ # # ][ # # ]: 0 : for( Range::iterator iter = matset_data.elements->begin(); iter != matset_data.elements->end(); ++iter )
[ # # ][ # # ]
[ # # ]
317 : : {
318 : 0 : unsigned char bit = 0x1;
319 [ # # ][ # # ]: 0 : mbImpl->tag_set_data( mEntityMark, &( *iter ), 1, &bit );
320 : : }
321 : : }
322 : :
323 [ # # ][ # # ]: 0 : matset_info.push_back( matset_data );
324 : 0 : }
325 : :
326 : : // If user hasn't entered dimension, we figure it out
327 [ # # ]: 0 : if( mesh_info.num_dim == 0 )
328 : : {
329 : : // Never want 1 or zero dimensions
330 [ # # ]: 0 : if( highest_dimension_of_element_matsets < 2 )
331 : 0 : mesh_info.num_dim = 3;
332 : : else
333 : 0 : mesh_info.num_dim = highest_dimension_of_element_matsets;
334 : : }
335 : :
336 [ # # ][ # # ]: 0 : Range::iterator range_iter, end_range_iter;
337 [ # # ]: 0 : range_iter = mesh_info.nodes.begin();
338 [ # # ]: 0 : end_range_iter = mesh_info.nodes.end();
339 : :
340 [ # # ]: 0 : mesh_info.num_nodes = mesh_info.nodes.size();
341 : :
342 : : //------dirsets--------
343 : :
344 : 0 : vector_iter = dirsets.begin();
345 : 0 : end_vector_iter = dirsets.end();
346 : :
347 [ # # ][ # # ]: 0 : for( ; vector_iter != end_vector_iter; ++vector_iter )
[ # # ]
348 : : {
349 [ # # ]: 0 : WriteSLAC::DirichletSetData dirset_data;
350 : 0 : dirset_data.id = 0;
351 : 0 : dirset_data.number_nodes = 0;
352 : :
353 : : // Get the dirset's id
354 [ # # ][ # # ]: 0 : if( mbImpl->tag_get_data( mDirichletSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS )
[ # # ]
355 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "Couldn't get id tag for dirset " << id ); }
[ # # ][ # # ]
[ # # ][ # # ]
356 : :
357 : 0 : dirset_data.id = id;
358 : :
359 [ # # ][ # # ]: 0 : std::vector< EntityHandle > node_vector;
360 : : // Get the nodes of the dirset that are in mesh_info.nodes
361 [ # # ][ # # ]: 0 : if( mbImpl->get_entities_by_handle( *vector_iter, node_vector, true ) != MB_SUCCESS )
[ # # ]
362 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "Couldn't get nodes in dirset " << id ); }
[ # # ][ # # ]
[ # # ][ # # ]
363 : :
364 : 0 : std::vector< EntityHandle >::iterator iter, end_iter;
365 : 0 : iter = node_vector.begin();
366 : 0 : end_iter = node_vector.end();
367 : :
368 : 0 : int j = 0;
369 : 0 : unsigned char node_marked = 0;
370 : : ErrorCode result;
371 [ # # ][ # # ]: 0 : for( ; iter != end_iter; ++iter )
[ # # ]
372 : : {
373 [ # # ][ # # ]: 0 : if( TYPE_FROM_HANDLE( *iter ) != MBVERTEX ) continue;
[ # # ]
374 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( mEntityMark, &( *iter ), 1, &node_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
375 : :
376 [ # # ][ # # ]: 0 : if( 0x1 == node_marked ) dirset_data.nodes.push_back( *iter );
[ # # ]
377 : 0 : j++;
378 : : }
379 : :
380 : 0 : dirset_data.number_nodes = dirset_data.nodes.size();
381 [ # # ][ # # ]: 0 : dirset_info.push_back( dirset_data );
382 : 0 : }
383 : :
384 : : //------neusets--------
385 : 0 : vector_iter = neusets.begin();
386 : 0 : end_vector_iter = neusets.end();
387 : :
388 [ # # ][ # # ]: 0 : for( ; vector_iter != end_vector_iter; ++vector_iter )
[ # # ]
389 : : {
390 [ # # ]: 0 : WriteSLAC::NeumannSetData neuset_data;
391 : :
392 : : // Get the neuset's id
393 [ # # ][ # # ]: 0 : if( mbImpl->tag_get_data( mNeumannSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS ) return MB_FAILURE;
[ # # ]
394 : :
395 : 0 : neuset_data.id = id;
396 [ # # ]: 0 : neuset_data.mesh_set_handle = *vector_iter;
397 : :
398 : : // Get the sides in two lists, one forward the other reverse; starts with forward sense
399 : : // by convention
400 [ # # ][ # # ]: 0 : Range forward_elems, reverse_elems;
[ # # ][ # # ]
401 [ # # ][ # # ]: 0 : if( get_neuset_elems( *vector_iter, 0, forward_elems, reverse_elems ) == MB_FAILURE ) return MB_FAILURE;
[ # # ]
402 : :
403 [ # # ][ # # ]: 0 : ErrorCode result = get_valid_sides( forward_elems, 1, neuset_data );MB_CHK_SET_ERR( result, "Couldn't get valid sides data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
404 [ # # ][ # # ]: 0 : result = get_valid_sides( reverse_elems, -1, neuset_data );MB_CHK_SET_ERR( result, "Couldn't get valid sides data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
405 : :
406 : 0 : neuset_data.number_elements = neuset_data.elements.size();
407 [ # # ][ # # ]: 0 : neuset_info.push_back( neuset_data );
408 : 0 : }
409 : :
410 : : // Get information about interior/exterior tets/hexes, and mark matset ids
411 [ # # ]: 0 : return gather_interior_exterior( mesh_info, matset_info, neuset_info );
412 : : }
413 : :
414 : 0 : ErrorCode WriteSLAC::get_valid_sides( Range& elems, const int sense, WriteSLAC::NeumannSetData& neuset_data )
415 : : {
416 : : // This is where we see if underlying element of side set element is included in output
417 : :
418 : 0 : unsigned char element_marked = 0;
419 : : ErrorCode result;
420 [ # # ][ # # ]: 0 : for( Range::iterator iter = elems.begin(); iter != elems.end(); ++iter )
[ # # ][ # # ]
[ # # ]
421 : : {
422 : : // Should insert here if "side" is a quad/tri on a quad/tri mesh
423 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( mEntityMark, &( *iter ), 1, &element_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
424 : :
425 [ # # ]: 0 : if( 0x1 == element_marked )
426 : : {
427 [ # # ][ # # ]: 0 : neuset_data.elements.push_back( *iter );
428 : :
429 : : // TJT TODO: the sense should really be # edges + 1or2
430 [ # # ][ # # ]: 0 : neuset_data.side_numbers.push_back( ( sense == 1 ? 1 : 2 ) );
431 : : }
432 : : else
433 : : { // Then "side" is probably a quad/tri on a hex/tet mesh
434 [ # # ]: 0 : std::vector< EntityHandle > parents;
435 [ # # ][ # # ]: 0 : int dimension = CN::Dimension( TYPE_FROM_HANDLE( *iter ) );
[ # # ]
436 : :
437 : : // Get the adjacent parent element of "side"
438 [ # # ][ # # ]: 0 : if( mbImpl->get_adjacencies( &( *iter ), 1, dimension + 1, false, parents ) != MB_SUCCESS )
[ # # ]
439 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "Couldn't get adjacencies for neuset" ); }
[ # # ][ # # ]
[ # # ]
440 : :
441 [ # # ]: 0 : if( !parents.empty() )
442 : : {
443 : : // Make sure the adjacent parent element will be output
444 [ # # ]: 0 : for( unsigned int k = 0; k < parents.size(); k++ )
445 : : {
446 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( mEntityMark, &( parents[k] ), 1, &element_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
447 : :
448 : : int side_no, this_sense, this_offset;
449 [ # # ][ # # ]: 0 : if( 0x1 == element_marked &&
450 [ # # ][ # # ]: 0 : mbImpl->side_number( parents[k], *iter, side_no, this_sense, this_offset ) == MB_SUCCESS &&
[ # # ][ # # ]
[ # # ]
451 : 0 : this_sense == sense )
452 : : {
453 [ # # ][ # # ]: 0 : neuset_data.elements.push_back( parents[k] );
454 [ # # ]: 0 : neuset_data.side_numbers.push_back( side_no + 1 );
455 : 0 : break;
456 : : }
457 : : }
458 : : }
459 : : else
460 : : {
461 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "No parent element exists for element in neuset " << neuset_data.id );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
462 : 0 : }
463 : : }
464 : : }
465 : :
466 : 0 : return MB_SUCCESS;
467 : : }
468 : :
469 : 0 : ErrorCode WriteSLAC::write_nodes( const int num_nodes, const Range& nodes, const int dimension )
470 : : {
471 : : // See if should transform coordinates
472 : : ErrorCode result;
473 : : Tag trans_tag;
474 [ # # ]: 0 : result = mbImpl->tag_get_handle( MESH_TRANSFORM_TAG_NAME, 16, MB_TYPE_DOUBLE, trans_tag );
475 : 0 : bool transform_needed = true;
476 [ # # ]: 0 : if( result == MB_TAG_NOT_FOUND ) transform_needed = false;
477 : :
478 [ # # ]: 0 : int num_coords_to_fill = transform_needed ? 3 : dimension;
479 : :
480 [ # # ]: 0 : std::vector< double* > coord_arrays( 3 );
481 [ # # ][ # # ]: 0 : coord_arrays[0] = new double[num_nodes];
[ # # ]
482 [ # # ][ # # ]: 0 : coord_arrays[1] = new double[num_nodes];
[ # # ]
483 [ # # ]: 0 : coord_arrays[2] = NULL;
484 : :
485 [ # # ][ # # ]: 0 : if( num_coords_to_fill == 3 ) coord_arrays[2] = new double[num_nodes];
[ # # ][ # # ]
486 : :
487 [ # # ]: 0 : result = mWriteIface->get_node_coords( dimension, num_nodes, nodes, mGlobalIdTag, 0, coord_arrays );
488 [ # # ]: 0 : if( result != MB_SUCCESS )
489 : : {
490 [ # # ][ # # ]: 0 : delete[] coord_arrays[0];
491 [ # # ][ # # ]: 0 : delete[] coord_arrays[1];
492 [ # # ][ # # ]: 0 : if( coord_arrays[2] ) delete[] coord_arrays[2];
[ # # ][ # # ]
493 : 0 : return result;
494 : : }
495 : :
496 [ # # ]: 0 : if( transform_needed )
497 : : {
498 : : double trans_matrix[16];
499 : 0 : const EntityHandle mesh = 0;
500 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( trans_tag, &mesh, 1, trans_matrix );MB_CHK_SET_ERR( result, "Couldn't get transform data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
501 : :
502 [ # # ]: 0 : for( int i = 0; i < num_nodes; i++ )
503 : : {
504 : : double vec1[3];
505 : : double vec2[3];
506 : :
507 [ # # ]: 0 : vec2[0] = coord_arrays[0][i];
508 [ # # ]: 0 : vec2[1] = coord_arrays[1][i];
509 [ # # ]: 0 : vec2[2] = coord_arrays[2][i];
510 : :
511 [ # # ]: 0 : for( int row = 0; row < 3; row++ )
512 : : {
513 : 0 : vec1[row] = 0.0;
514 [ # # ]: 0 : for( int col = 0; col < 3; col++ )
515 : 0 : vec1[row] += ( trans_matrix[( row * 4 ) + col] * vec2[col] );
516 : : }
517 : :
518 [ # # ]: 0 : coord_arrays[0][i] = vec1[0];
519 [ # # ]: 0 : coord_arrays[1][i] = vec1[1];
520 [ # # ]: 0 : coord_arrays[2][i] = vec1[2];
521 : : }
522 : : }
523 : :
524 : : // Write the nodes
525 : 0 : int nc_var = -1;
526 [ # # ]: 0 : std::vector< int > dims;
527 [ # # ][ # # ]: 0 : GET_VAR( "coords", nc_var, dims );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
528 [ # # ]: 0 : if( -1 == nc_var ) return MB_FAILURE;
529 : 0 : size_t start[2] = { 0, 0 }, count[2] = { static_cast< size_t >( num_nodes ), 1 };
530 [ # # ][ # # ]: 0 : int fail = nc_put_vara_double( ncFile, nc_var, start, count, coord_arrays[0] );
531 [ # # ]: 0 : if( NC_NOERR != fail ) return MB_FAILURE;
532 : 0 : start[1] = 1;
533 [ # # ][ # # ]: 0 : fail = nc_put_vara_double( ncFile, nc_var, start, count, coord_arrays[1] );
534 [ # # ]: 0 : if( NC_NOERR != fail ) return MB_FAILURE;
535 : 0 : start[1] = 2;
536 [ # # ][ # # ]: 0 : fail = nc_put_vara_double( ncFile, nc_var, start, count, coord_arrays[2] );
537 [ # # ]: 0 : if( NC_NOERR != fail ) return MB_FAILURE;
538 : :
539 [ # # ][ # # ]: 0 : delete[] coord_arrays[0];
540 [ # # ][ # # ]: 0 : delete[] coord_arrays[1];
541 [ # # ][ # # ]: 0 : if( coord_arrays[2] ) delete[] coord_arrays[2];
[ # # ][ # # ]
542 : :
543 : 0 : return MB_SUCCESS;
544 : : }
545 : :
546 : 0 : ErrorCode WriteSLAC::gather_interior_exterior( MeshInfo& mesh_info,
547 : : std::vector< WriteSLAC::MaterialSetData >& matset_data,
548 : : std::vector< WriteSLAC::NeumannSetData >& neuset_data )
549 : : {
550 : : // Need to assign a tag with the matset id
551 : : Tag matset_id_tag;
552 : : unsigned int i;
553 : 0 : int dum = -1;
554 : : ErrorCode result =
555 [ # # ]: 0 : mbImpl->tag_get_handle( "__matset_id", 4, MB_TYPE_INTEGER, matset_id_tag, MB_TAG_DENSE | MB_TAG_CREAT, &dum );
556 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
557 : :
558 [ # # ]: 0 : Range::iterator rit;
559 : 0 : mesh_info.num_int_hexes = mesh_info.num_int_tets = 0;
560 : :
561 [ # # ]: 0 : for( i = 0; i < matset_data.size(); i++ )
562 : : {
563 [ # # ]: 0 : WriteSLAC::MaterialSetData matset = matset_data[i];
564 [ # # ]: 0 : if( matset.moab_type == MBHEX )
565 [ # # ]: 0 : mesh_info.num_int_hexes += matset.elements->size();
566 [ # # ]: 0 : else if( matset.moab_type == MBTET )
567 [ # # ]: 0 : mesh_info.num_int_tets += matset.elements->size();
568 : : else
569 : : {
570 [ # # ][ # # ]: 0 : std::cout << "WriteSLAC doesn't support elements of type " << CN::EntityTypeName( matset.moab_type )
[ # # ]
571 [ # # ]: 0 : << std::endl;
572 : 0 : continue;
573 : : }
574 : :
575 [ # # ][ # # ]: 0 : for( rit = matset.elements->begin(); rit != matset.elements->end(); ++rit )
[ # # ][ # # ]
[ # # ]
576 : : {
577 [ # # ][ # # ]: 0 : result = mbImpl->tag_set_data( mMatSetIdTag, &( *rit ), 1, &( matset.id ) );
578 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
579 : : }
580 : : }
581 : :
582 : : // Now go through the neumann sets, pulling out the hexes with faces on the
583 : : // boundary
584 : 0 : std::vector< EntityHandle >::iterator vit;
585 [ # # ]: 0 : for( i = 0; i < neuset_data.size(); i++ )
586 : : {
587 [ # # ][ # # ]: 0 : WriteSLAC::NeumannSetData neuset = neuset_data[i];
588 [ # # ][ # # ]: 0 : for( vit = neuset.elements.begin(); vit != neuset.elements.end(); ++vit )
[ # # ]
589 : : {
590 [ # # ][ # # ]: 0 : if( TYPE_FROM_HANDLE( *vit ) == MBHEX )
[ # # ]
591 [ # # ][ # # ]: 0 : mesh_info.bdy_hexes.insert( *vit );
592 [ # # ][ # # ]: 0 : else if( TYPE_FROM_HANDLE( *vit ) == MBTET )
[ # # ]
593 [ # # ][ # # ]: 0 : mesh_info.bdy_tets.insert( *vit );
594 : : }
595 : 0 : }
596 : :
597 : : // Now we have the number of bdy hexes and tets, we know how many interior ones
598 : : // there are too
599 [ # # ]: 0 : mesh_info.num_int_hexes -= mesh_info.bdy_hexes.size();
600 [ # # ]: 0 : mesh_info.num_int_tets -= mesh_info.bdy_tets.size();
601 : :
602 : 0 : return MB_SUCCESS;
603 : : }
604 : :
605 : 0 : ErrorCode WriteSLAC::write_matsets( MeshInfo& mesh_info, std::vector< WriteSLAC::MaterialSetData >& matset_data,
606 : : std::vector< WriteSLAC::NeumannSetData >& neuset_data )
607 : : {
608 : : unsigned int i;
609 [ # # ]: 0 : std::vector< int > connect;
610 : : const EntityHandle* connecth;
611 : : int num_connecth;
612 : : ErrorCode result;
613 : :
614 : : // First write the interior hexes
615 : 0 : int hex_conn = -1;
616 [ # # ]: 0 : std::vector< int > dims;
617 [ # # ][ # # ]: 0 : if( mesh_info.bdy_hexes.size() != 0 || mesh_info.num_int_hexes != 0 )
[ # # ][ # # ]
618 : : {
619 [ # # ][ # # ]: 0 : GET_VAR( "hexahedron_interior", hex_conn, dims );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
620 [ # # ]: 0 : if( -1 == hex_conn ) return MB_FAILURE;
621 : : }
622 [ # # ]: 0 : connect.reserve( 13 );
623 [ # # ]: 0 : Range::iterator rit;
624 : :
625 : 0 : int elem_num = 0;
626 : : WriteSLAC::MaterialSetData matset;
627 : 0 : size_t start[2] = { 0, 0 }, count[2] = { 1, 1 };
628 : : int fail;
629 [ # # ]: 0 : for( i = 0; i < matset_data.size(); i++ )
630 : : {
631 [ # # ]: 0 : matset = matset_data[i];
632 [ # # ]: 0 : if( matset.moab_type != MBHEX ) continue;
633 : :
634 : 0 : int id = matset.id;
635 [ # # ]: 0 : connect[0] = id;
636 : :
637 [ # # ][ # # ]: 0 : for( rit = matset.elements->begin(); rit != matset.elements->end(); ++rit )
[ # # ][ # # ]
[ # # ]
638 : : {
639 : : // Skip if it's on the bdy
640 [ # # ][ # # ]: 0 : if( mesh_info.bdy_hexes.find( *rit ) != mesh_info.bdy_hexes.end() ) continue;
[ # # ][ # # ]
[ # # ]
641 : :
642 : : // Get the connectivity of this element
643 [ # # ][ # # ]: 0 : result = mbImpl->get_connectivity( *rit, connecth, num_connecth );
644 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
645 : :
646 : : // Get the vertex ids
647 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( mGlobalIdTag, connecth, num_connecth, &connect[1] );
648 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
649 : :
650 : : // Put the variable at the right position
651 : 0 : start[0] = elem_num++;
652 : 0 : count[1] = 9;
653 : :
654 : : // Write the data
655 [ # # ][ # # ]: 0 : fail = nc_put_vara_int( ncFile, hex_conn, start, count, &connect[0] );
656 [ # # ]: 0 : if( NC_NOERR != fail ) return MB_FAILURE;
657 : : }
658 : : }
659 : :
660 : 0 : int tet_conn = -1;
661 [ # # ][ # # ]: 0 : if( mesh_info.bdy_tets.size() != 0 || mesh_info.num_int_tets != 0 )
[ # # ][ # # ]
662 : : {
663 [ # # ][ # # ]: 0 : GET_VAR( "tetrahedron_interior", tet_conn, dims );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
664 [ # # ]: 0 : if( -1 == tet_conn ) return MB_FAILURE;
665 : : }
666 : :
667 : : // Now the interior tets
668 : 0 : elem_num = 0;
669 [ # # ]: 0 : for( i = 0; i < matset_data.size(); i++ )
670 : : {
671 [ # # ]: 0 : matset = matset_data[i];
672 [ # # ]: 0 : if( matset.moab_type != MBTET ) continue;
673 : :
674 : 0 : int id = matset.id;
675 [ # # ]: 0 : connect[0] = id;
676 : 0 : elem_num = 0;
677 [ # # ][ # # ]: 0 : for( rit = matset.elements->begin(); rit != matset.elements->end(); ++rit )
[ # # ][ # # ]
[ # # ]
678 : : {
679 : : // Skip if it's on the bdy
680 [ # # ][ # # ]: 0 : if( mesh_info.bdy_tets.find( *rit ) != mesh_info.bdy_tets.end() ) continue;
[ # # ][ # # ]
[ # # ]
681 : :
682 : : // Get the connectivity of this element
683 [ # # ][ # # ]: 0 : result = mbImpl->get_connectivity( *rit, connecth, num_connecth );
684 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
685 : :
686 : : // Get the vertex ids
687 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( mGlobalIdTag, connecth, num_connecth, &connect[1] );
688 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
689 : :
690 : : // Put the variable at the right position
691 : 0 : start[0] = elem_num++;
692 : 0 : count[1] = 5;
693 [ # # ][ # # ]: 0 : fail = nc_put_vara_int( ncFile, tet_conn, start, count, &connect[0] );
694 : : // Write the data
695 [ # # ]: 0 : if( NC_NOERR != fail ) return MB_FAILURE;
696 : : }
697 : : }
698 : :
699 : : // Now the exterior hexes
700 [ # # ][ # # ]: 0 : if( mesh_info.bdy_hexes.size() != 0 )
701 : : {
702 : 0 : hex_conn = -1;
703 [ # # ][ # # ]: 0 : GET_VAR( "hexahedron_exterior", hex_conn, dims );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
704 [ # # ]: 0 : if( -1 == hex_conn ) return MB_FAILURE;
705 : :
706 [ # # ]: 0 : connect.reserve( 15 );
707 : 0 : elem_num = 0;
708 : :
709 : : // Write the elements
710 [ # # ][ # # ]: 0 : for( rit = mesh_info.bdy_hexes.begin(); rit != mesh_info.bdy_hexes.end(); ++rit )
[ # # ][ # # ]
[ # # ]
711 : : {
712 : : // Get the material set for this hex
713 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( mMatSetIdTag, &( *rit ), 1, &connect[0] );
[ # # ]
714 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
715 : :
716 : : // Get the connectivity of this element
717 [ # # ][ # # ]: 0 : result = mbImpl->get_connectivity( *rit, connecth, num_connecth );
718 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
719 : :
720 : : // Get the vertex ids
721 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( mGlobalIdTag, connecth, num_connecth, &connect[1] );
722 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
723 : :
724 : : // Preset side numbers
725 [ # # ]: 0 : for( i = 9; i < 15; i++ )
726 [ # # ]: 0 : connect[i] = -1;
727 : :
728 : : // Now write the side numbers
729 [ # # ]: 0 : for( i = 0; i < neuset_data.size(); i++ )
730 : : {
731 : : std::vector< EntityHandle >::iterator vit =
732 [ # # ][ # # ]: 0 : std::find( neuset_data[i].elements.begin(), neuset_data[i].elements.end(), *rit );
[ # # ][ # # ]
733 [ # # ][ # # ]: 0 : while( vit != neuset_data[i].elements.end() )
[ # # ]
734 : : {
735 : : // Have a side - get the side # and put in connect array
736 [ # # ][ # # ]: 0 : int side_no = neuset_data[i].side_numbers[vit - neuset_data[i].elements.begin()];
[ # # ][ # # ]
737 [ # # ][ # # ]: 0 : connect[9 + side_no] = neuset_data[i].id;
738 [ # # ]: 0 : ++vit;
739 [ # # ][ # # ]: 0 : vit = std::find( vit, neuset_data[i].elements.end(), *rit );
[ # # ]
740 : : }
741 : : }
742 : :
743 : : // Put the variable at the right position
744 : 0 : start[0] = elem_num++;
745 : 0 : count[1] = 15;
746 [ # # ][ # # ]: 0 : fail = nc_put_vara_int( ncFile, hex_conn, start, count, &connect[0] );
747 : : // Write the data
748 [ # # ]: 0 : if( NC_NOERR != fail ) return MB_FAILURE;
749 : : }
750 : : }
751 : :
752 : : // Now the exterior tets
753 [ # # ][ # # ]: 0 : if( mesh_info.bdy_tets.size() != 0 )
754 : : {
755 : 0 : tet_conn = -1;
756 [ # # ][ # # ]: 0 : GET_VAR( "tetrahedron_exterior", tet_conn, dims );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
757 [ # # ]: 0 : if( -1 == tet_conn ) return MB_FAILURE;
758 : :
759 [ # # ]: 0 : connect.reserve( 9 );
760 : 0 : elem_num = 0;
761 : :
762 : : // Write the elements
763 [ # # ][ # # ]: 0 : for( rit = mesh_info.bdy_tets.begin(); rit != mesh_info.bdy_tets.end(); ++rit )
[ # # ][ # # ]
[ # # ]
764 : : {
765 : : // Get the material set for this tet
766 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( mMatSetIdTag, &( *rit ), 1, &connect[0] );
[ # # ]
767 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
768 : :
769 : : // Get the connectivity of this element
770 [ # # ][ # # ]: 0 : result = mbImpl->get_connectivity( *rit, connecth, num_connecth );
771 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
772 : :
773 : : // Get the vertex ids
774 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( mGlobalIdTag, connecth, num_connecth, &connect[1] );
775 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
776 : :
777 : : // Preset side numbers
778 [ # # ]: 0 : for( i = 5; i < 9; i++ )
779 [ # # ]: 0 : connect[i] = -1;
780 : :
781 : : // Now write the side numbers
782 [ # # ]: 0 : for( i = 0; i < neuset_data.size(); i++ )
783 : : {
784 : : std::vector< EntityHandle >::iterator vit =
785 [ # # ][ # # ]: 0 : std::find( neuset_data[i].elements.begin(), neuset_data[i].elements.end(), *rit );
[ # # ][ # # ]
786 [ # # ][ # # ]: 0 : while( vit != neuset_data[i].elements.end() )
[ # # ]
787 : : {
788 : : // Have a side - get the side # and put in connect array
789 [ # # ][ # # ]: 0 : int side_no = neuset_data[i].side_numbers[vit - neuset_data[i].elements.begin()];
[ # # ][ # # ]
790 [ # # ][ # # ]: 0 : connect[5 + side_no] = neuset_data[i].id;
791 [ # # ]: 0 : ++vit;
792 [ # # ][ # # ]: 0 : vit = std::find( vit, neuset_data[i].elements.end(), *rit );
[ # # ]
793 : : }
794 : : }
795 : :
796 : : // Put the variable at the right position
797 : 0 : start[0] = elem_num++;
798 : 0 : count[1] = 9;
799 [ # # ][ # # ]: 0 : fail = nc_put_vara_int( ncFile, tet_conn, start, count, &connect[0] );
800 : : // Write the data
801 [ # # ]: 0 : if( NC_NOERR != fail ) return MB_FAILURE;
802 : : }
803 : : }
804 : :
805 : 0 : return MB_SUCCESS;
806 : : }
807 : :
808 : 0 : ErrorCode WriteSLAC::initialize_file( MeshInfo& mesh_info )
809 : : {
810 : : // Perform the initializations
811 : :
812 : 0 : int coord_size = -1, ncoords = -1;
813 : : // Initialization to avoid warnings on Linux
814 : 0 : int hexinterior = -1, hexinteriorsize, hexexterior = -1, hexexteriorsize = -1;
815 : 0 : int tetinterior = -1, tetinteriorsize, tetexterior = -1, tetexteriorsize = -1;
816 : :
817 [ # # ][ # # ]: 0 : if( nc_def_dim( ncFile, "coord_size", (size_t)mesh_info.num_dim, &coord_size ) != NC_NOERR )
818 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "WriteSLAC: failed to define number of dimensions" ); }
[ # # ][ # # ]
[ # # ]
819 : :
820 [ # # ][ # # ]: 0 : if( nc_def_dim( ncFile, "ncoords", (size_t)mesh_info.num_nodes, &ncoords ) != NC_NOERR )
821 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "WriteSLAC: failed to define number of nodes" ); }
[ # # ][ # # ]
[ # # ]
822 : :
823 [ # # ][ # # ]: 0 : if( 0 != mesh_info.num_int_hexes &&
[ # # ]
824 [ # # ]: 0 : nc_def_dim( ncFile, "hexinterior", (size_t)mesh_info.num_int_hexes, &hexinterior ) != NC_NOERR )
825 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "WriteSLAC: failed to define number of interior hex elements" ); }
[ # # ][ # # ]
[ # # ]
826 : :
827 [ # # ][ # # ]: 0 : if( nc_def_dim( ncFile, "hexinteriorsize", (size_t)9, &hexinteriorsize ) != NC_NOERR )
828 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "WriteSLAC: failed to define interior hex element size" ); }
[ # # ][ # # ]
[ # # ]
829 : :
830 [ # # ][ # # ]: 0 : if( 0 != mesh_info.bdy_hexes.size() &&
[ # # ][ # # ]
831 [ # # ][ # # ]: 0 : nc_def_dim( ncFile, "hexexterior", (size_t)mesh_info.bdy_hexes.size(), &hexexterior ) != NC_NOERR )
832 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "WriteSLAC: failed to define number of exterior hex elements" ); }
[ # # ][ # # ]
[ # # ]
833 : :
834 [ # # ][ # # ]: 0 : if( nc_def_dim( ncFile, "hexexteriorsize", (size_t)15, &hexexteriorsize ) != NC_NOERR )
835 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "WriteSLAC: failed to define exterior hex element size" ); }
[ # # ][ # # ]
[ # # ]
836 : :
837 [ # # ][ # # ]: 0 : if( 0 != mesh_info.num_int_tets &&
[ # # ]
838 [ # # ]: 0 : nc_def_dim( ncFile, "tetinterior", (size_t)mesh_info.num_int_tets, &tetinterior ) != NC_NOERR )
839 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "WriteSLAC: failed to define number of interior tet elements" ); }
[ # # ][ # # ]
[ # # ]
840 : :
841 [ # # ][ # # ]: 0 : if( nc_def_dim( ncFile, "tetinteriorsize", (size_t)5, &tetinteriorsize ) != NC_NOERR )
842 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "WriteSLAC: failed to define interior tet element size" ); }
[ # # ][ # # ]
[ # # ]
843 : :
844 [ # # ][ # # ]: 0 : if( 0 != mesh_info.bdy_tets.size() &&
[ # # ][ # # ]
845 [ # # ][ # # ]: 0 : nc_def_dim( ncFile, "tetexterior", (size_t)mesh_info.bdy_tets.size(), &tetexterior ) != NC_NOERR )
846 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "WriteSLAC: failed to define number of exterior tet elements" ); }
[ # # ][ # # ]
[ # # ]
847 : :
848 [ # # ][ # # ]: 0 : if( nc_def_dim( ncFile, "tetexteriorsize", (size_t)9, &tetexteriorsize ) != NC_NOERR )
849 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "WriteSLAC: failed to define exterior tet element size" ); }
[ # # ][ # # ]
[ # # ]
850 : :
851 : : /* ...and some variables */
852 : :
853 : : int dims[2];
854 : 0 : dims[0] = hexinterior;
855 : 0 : dims[1] = hexinteriorsize;
856 : : int dum_var;
857 [ # # ][ # # ]: 0 : if( 0 != mesh_info.num_int_hexes &&
[ # # ]
858 [ # # ]: 0 : NC_NOERR != nc_def_var( ncFile, "hexahedron_interior", NC_LONG, 2, dims, &dum_var ) )
859 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "WriteSLAC: failed to create connectivity array for interior hexes" ); }
[ # # ][ # # ]
[ # # ]
860 : :
861 : 0 : dims[0] = hexexterior;
862 : 0 : dims[1] = hexexteriorsize;
863 [ # # ][ # # ]: 0 : if( 0 != mesh_info.bdy_hexes.size() &&
[ # # ][ # # ]
864 [ # # ]: 0 : NC_NOERR != nc_def_var( ncFile, "hexahedron_exterior", NC_LONG, 2, dims, &dum_var ) )
865 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "WriteSLAC: failed to create connectivity array for exterior hexes" ); }
[ # # ][ # # ]
[ # # ]
866 : :
867 : 0 : dims[0] = tetinterior;
868 : 0 : dims[1] = tetinteriorsize;
869 [ # # ][ # # ]: 0 : if( 0 != mesh_info.num_int_tets &&
[ # # ]
870 [ # # ]: 0 : NC_NOERR != nc_def_var( ncFile, "tetrahedron_exterior", NC_LONG, 2, dims, &dum_var ) )
871 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "WriteSLAC: failed to create connectivity array for interior tets" ); }
[ # # ][ # # ]
[ # # ]
872 : :
873 : 0 : dims[0] = tetexterior;
874 : 0 : dims[1] = tetexteriorsize;
875 [ # # ][ # # ]: 0 : if( 0 != mesh_info.bdy_tets.size() &&
[ # # ][ # # ]
876 [ # # ]: 0 : NC_NOERR != nc_def_var( ncFile, "tetrahedron_exterior", NC_LONG, 2, dims, &dum_var ) )
877 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "WriteSLAC: failed to create connectivity array for exterior tets" ); }
[ # # ][ # # ]
[ # # ]
878 : :
879 : : /* Node coordinate arrays: */
880 : :
881 : 0 : dims[0] = ncoords;
882 : 0 : dims[1] = coord_size;
883 [ # # ][ # # ]: 0 : if( NC_NOERR != nc_def_var( ncFile, "coords", NC_DOUBLE, 2, dims, &dum_var ) )
884 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "WriteSLAC: failed to define node coordinate array" ); }
[ # # ][ # # ]
[ # # ]
885 : :
886 : 0 : return MB_SUCCESS;
887 : : }
888 : :
889 : 0 : ErrorCode WriteSLAC::open_file( const char* filename )
890 : : {
891 : : // Not a valid filname
892 [ # # ][ # # ]: 0 : if( strlen( (const char*)filename ) == 0 ) { MB_SET_ERR( MB_FAILURE, "Output filename not specified" ); }
[ # # ][ # # ]
[ # # ][ # # ]
893 : :
894 : 0 : int fail = nc_create( filename, NC_CLOBBER, &ncFile );
895 : : // File couldn't be opened
896 [ # # ][ # # ]: 0 : if( NC_NOERR != fail ) { MB_SET_ERR( MB_FAILURE, "Cannot open " << filename ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
897 : :
898 : 0 : return MB_SUCCESS;
899 : : }
900 : :
901 : 0 : ErrorCode WriteSLAC::get_neuset_elems( EntityHandle neuset, int current_sense, Range& forward_elems,
902 : : Range& reverse_elems )
903 : : {
904 [ # # ][ # # ]: 0 : Range ss_elems, ss_meshsets;
905 : :
906 : : // Get the sense tag; don't need to check return, might be an error if the tag
907 : : // hasn't been created yet
908 : 0 : Tag sense_tag = 0;
909 [ # # ]: 0 : mbImpl->tag_get_handle( "SENSE", 1, MB_TYPE_INTEGER, sense_tag );
910 : :
911 : : // Get the entities in this set
912 [ # # ]: 0 : ErrorCode result = mbImpl->get_entities_by_handle( neuset, ss_elems, true );
913 [ # # ]: 0 : if( MB_FAILURE == result ) return result;
914 : :
915 : : // Now remove the meshsets into the ss_meshsets; first find the first meshset,
916 [ # # ]: 0 : Range::iterator range_iter = ss_elems.begin();
917 [ # # ][ # # ]: 0 : while( TYPE_FROM_HANDLE( *range_iter ) != MBENTITYSET && range_iter != ss_elems.end() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
[ # # # # ]
918 [ # # ]: 0 : ++range_iter;
919 : :
920 : : // Then, if there are some, copy them into ss_meshsets and erase from ss_elems
921 [ # # ][ # # ]: 0 : if( range_iter != ss_elems.end() )
[ # # ]
922 : : {
923 [ # # ][ # # ]: 0 : std::copy( range_iter, ss_elems.end(), range_inserter( ss_meshsets ) );
[ # # ]
924 [ # # ][ # # ]: 0 : ss_elems.erase( range_iter, ss_elems.end() );
925 : : }
926 : :
927 : : // OK, for the elements, check the sense of this set and copy into the right range
928 : : // (if the sense is 0, copy into both ranges)
929 : :
930 : : // Need to step forward on list until we reach the right dimension
931 [ # # ]: 0 : Range::iterator dum_it = ss_elems.end();
932 [ # # ]: 0 : --dum_it;
933 [ # # ][ # # ]: 0 : int target_dim = CN::Dimension( TYPE_FROM_HANDLE( *dum_it ) );
[ # # ]
934 [ # # ]: 0 : dum_it = ss_elems.begin();
935 [ # # ][ # # ]: 0 : while( target_dim != CN::Dimension( TYPE_FROM_HANDLE( *dum_it ) ) && dum_it != ss_elems.end() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
936 [ # # ]: 0 : ++dum_it;
937 : :
938 [ # # ][ # # ]: 0 : if( current_sense == 1 || current_sense == 0 ) std::copy( dum_it, ss_elems.end(), range_inserter( forward_elems ) );
[ # # ][ # # ]
[ # # ]
939 [ # # ][ # # ]: 0 : if( current_sense == -1 || current_sense == 0 )
940 [ # # ][ # # ]: 0 : std::copy( dum_it, ss_elems.end(), range_inserter( reverse_elems ) );
[ # # ]
941 : :
942 : : // Now loop over the contained meshsets, getting the sense of those and calling this
943 : : // function recursively
944 [ # # ][ # # ]: 0 : for( range_iter = ss_meshsets.begin(); range_iter != ss_meshsets.end(); ++range_iter )
[ # # ][ # # ]
[ # # ]
945 : : {
946 : : // First get the sense; if it's not there, by convention it's forward
947 : : int this_sense;
948 [ # # ][ # # ]: 0 : if( 0 == sense_tag || MB_FAILURE == mbImpl->tag_get_data( sense_tag, &( *range_iter ), 1, &this_sense ) )
[ # # ][ # # ]
[ # # ]
949 : 0 : this_sense = 1;
950 : :
951 : : // Now get all the entities on this meshset, with the proper (possibly reversed) sense
952 [ # # ][ # # ]: 0 : get_neuset_elems( *range_iter, this_sense * current_sense, forward_elems, reverse_elems );
953 : : }
954 : :
955 : 0 : return result;
956 : : }
957 : :
958 [ + - ][ + - ]: 228 : } // namespace moab
|