1
42
43 #ifdef WIN32
44 #ifdef _DEBUG
45
46
47 #pragma warning( disable : 4786 )
48 #endif
49 #endif
50
51 #include "WriteCCMIO.hpp"
52 #include "ccmio.h"
53 #include "ccmioutility.h"
54 #include "ccmiocore.h"
55 #include <utility>
56 #include <algorithm>
57 #include <ctime>
58 #include <string>
59 #include <vector>
60 #include <cstdio>
61 #include <iostream>
62 #include <algorithm>
63 #include <sstream>
64
65 #include "moab/Interface.hpp"
66 #include "moab/Range.hpp"
67 #include "moab/CN.hpp"
68 #include "moab/Skinner.hpp"
69 #include <cassert>
70 #include "Internals.hpp"
71 #include "ExoIIUtil.hpp"
72 #include "MBTagConventions.hpp"
73 #ifdef MOAB_HAVE_MPI
74 #include "MBParallelConventions.h"
75 #endif
76 #include "moab/WriteUtilIface.hpp"
77
78 namespace moab
79 {
80
81 static char const kStateName[] = "default";
82
83
98
99 #define CHK_SET_CCMERR( ccm_err_code, ccm_err_msg ) \
100 { \
101 if( kCCMIONoErr != ( ccm_err_code ) ) MB_SET_ERR( MB_FAILURE, ccm_err_msg ); \
102 }
103
104 WriterIface* WriteCCMIO::factory( Interface* iface )
105 {
106 return new WriteCCMIO( iface );
107 }
108
109 WriteCCMIO::WriteCCMIO( Interface* impl )
110 : mbImpl( impl ), mCurrentMeshHandle( 0 ), mPartitionSetTag( 0 ), mNameTag( 0 ), mMaterialIdTag( 0 ),
111 mMaterialTypeTag( 0 ), mRadiationTag( 0 ), mPorosityIdTag( 0 ), mSpinIdTag( 0 ), mGroupIdTag( 0 ),
112 mColorIdxTag( 0 ), mProcessorIdTag( 0 ), mLightMaterialTag( 0 ), mFreeSurfaceMaterialTag( 0 ), mThicknessTag( 0 ),
113 mProstarRegionNumberTag( 0 ), mBoundaryTypeTag( 0 ), mCreatingProgramTag( 0 ), mDimension( 0 ),
114 mWholeMesh( false )
115 {
116 assert( impl != NULL );
117
118 impl->query_interface( mWriteIface );
119
120
121
122 int negone = -1;
123 impl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mMaterialSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
124 &negone );
125
126 impl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mDirichletSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
127 &negone );
128
129 impl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mNeumannSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
130 &negone );
131
132 mGlobalIdTag = impl->globalId_tag();
133
134 #ifdef MOAB_HAVE_MPI
135 impl->tag_get_handle( PARALLEL_PARTITION_TAG_NAME, 1, MB_TYPE_INTEGER, mPartitionSetTag, MB_TAG_SPARSE );
136
137 #endif
138
139 int dum_val_array[] = { -1, -1, -1, -1 };
140 impl->tag_get_handle( HAS_MID_NODES_TAG_NAME, 4, MB_TYPE_INTEGER, mHasMidNodesTag, MB_TAG_SPARSE | MB_TAG_CREAT,
141 dum_val_array );
142
143 impl->tag_get_handle( "__WriteCCMIO element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT );
144
145
146 mbImpl->tag_get_handle( NAME_TAG_NAME, NAME_TAG_SIZE, MB_TYPE_OPAQUE, mNameTag );
147 }
148
149 WriteCCMIO::~WriteCCMIO()
150 {
151 mbImpl->release_interface( mWriteIface );
152 mbImpl->tag_delete( mEntityMark );
153 }
154
155 ErrorCode WriteCCMIO::write_file( const char* file_name,
156 const bool overwrite,
157 const FileOptions&,
158 const EntityHandle* ent_handles,
159 const int num_sets,
160 const std::vector< std::string >& ,
161 const Tag* ,
162 int ,
163 int )
164 {
165 assert( 0 != mMaterialSetTag && 0 != mNeumannSetTag && 0 != mDirichletSetTag );
166
167 ErrorCode result;
168
169
170 if( !overwrite )
171 {
172 FILE* file = fopen( file_name, "r" );
173 if( file )
174 {
175 fclose( file );
176 MB_SET_ERR( MB_FILE_WRITE_ERROR, "File exists but overwrite set to false" );
177 }
178 }
179
180 mDimension = 3;
181
182 std::vector< EntityHandle > matsets, dirsets, neusets, partsets;
183
184
185 result = get_sets( ent_handles, num_sets, matsets, dirsets, neusets, partsets );MB_CHK_SET_ERR( result, "Failed to get material/etc. sets" );
186
187
188 if( ent_handles && matsets.empty() )
189 {
190 MB_SET_ERR( MB_FILE_WRITE_ERROR, "Sets input to write but no material sets found" );
191 }
192
193
194 if( matsets.empty() ) matsets.push_back( 0 );
195
196 std::vector< MaterialSetData > matset_info;
197 Range all_verts;
198 result = gather_matset_info( matsets, matset_info, all_verts );MB_CHK_SET_ERR( result, "gathering matset info failed" );
199
200
201 result = mWriteIface->assign_ids( all_verts, mGlobalIdTag, 1 );MB_CHK_SET_ERR( result, "Failed to assign vertex global ids" );
202
203
204 CCMIOID rootID, topologyID, stateID, problemID, verticesID, processorID;
205
206
207 result = open_file( file_name, overwrite, rootID );MB_CHK_SET_ERR( result, "Couldn't open file or create state" );
208
209 result = create_ccmio_structure( rootID, stateID, processorID );MB_CHK_SET_ERR( result, "Problem creating CCMIO file structure" );
210
211 result = write_nodes( rootID, all_verts, mDimension, verticesID );MB_CHK_SET_ERR( result, "write_nodes failed" );
212
213 std::vector< NeumannSetData > neuset_info;
214 result = gather_neuset_info( neusets, neuset_info );MB_CHK_SET_ERR( result, "Failed to get neumann set info" );
215
216 result = write_cells_and_faces( rootID, matset_info, neuset_info, all_verts, topologyID );MB_CHK_SET_ERR( result, "write_cells_and_faces failed" );
217
218 result = write_problem_description( rootID, stateID, problemID, processorID, matset_info, neuset_info );MB_CHK_SET_ERR( result, "write_problem_description failed" );
219
220 result = write_solution_data();MB_CHK_SET_ERR( result, "Trouble writing solution data" );
221
222 result = write_processor( processorID, verticesID, topologyID );MB_CHK_SET_ERR( result, "Trouble writing processor" );
223
224 result = close_and_compress( file_name, rootID );MB_CHK_SET_ERR( result, "Close or compress failed" );
225
226 return MB_SUCCESS;
227 }
228
229 ErrorCode WriteCCMIO::write_solution_data()
230 {
231
232 return MB_SUCCESS;
233 }
234
235 ErrorCode WriteCCMIO::write_processor( CCMIOID processorID, CCMIOID verticesID, CCMIOID topologyID )
236 {
237 CCMIOError error = kCCMIONoErr;
238
239
240
241 CCMIOWriteProcessor( &error, processorID, NULL, &verticesID, NULL, &topologyID, NULL, NULL, NULL, NULL );
242 CHK_SET_CCMERR( error, "Problem writing CCMIO processor" );
243
244 return MB_SUCCESS;
245 }
246
247 ErrorCode WriteCCMIO::create_ccmio_structure( CCMIOID rootID, CCMIOID& stateID, CCMIOID& processorID )
248 {
249
250 CCMIOError error = kCCMIONoErr;
251
252
253 if( CCMIOGetState( NULL, rootID, kStateName, NULL, &stateID ) != kCCMIONoErr )
254 {
255 CCMIONewState( &error, rootID, kStateName, NULL, NULL, &stateID );
256 CHK_SET_CCMERR( error, "Trouble creating state" );
257 }
258
259
260 CCMIOSize_t i = CCMIOSIZEC( 0 );
261 if( CCMIONextEntity( NULL, stateID, kCCMIOProcessor, &i, &processorID ) != kCCMIONoErr )
262 {
263 CCMIONewEntity( &error, stateID, kCCMIOProcessor, NULL, &processorID );
264 CHK_SET_CCMERR( error, "Trouble creating processor node" );
265 }
266
267
268 else
269 {
270 CCMIOClearProcessor( &error, stateID, processorID, TRUE, TRUE, TRUE, TRUE, TRUE );
271 CHK_SET_CCMERR( error, "Trouble clearing processor data" );
272 }
273
274
281 return MB_SUCCESS;
282 }
283
284 ErrorCode WriteCCMIO::close_and_compress( const char*, CCMIOID rootID )
285 {
286 CCMIOError error = kCCMIONoErr;
287 CCMIOCloseFile( &error, rootID );
288 CHK_SET_CCMERR( error, "File close failed" );
289
290
291
292
293
294
295
296
297
298
299 return MB_SUCCESS;
300 }
301
302 ErrorCode WriteCCMIO::open_file( const char* filename, bool, CCMIOID& rootID )
303 {
304 CCMIOError error = kCCMIONoErr;
305 CCMIOOpenFile( &error, filename, kCCMIOWrite, &rootID );
306 CHK_SET_CCMERR( error, "Cannot open file" );
307
308 return MB_SUCCESS;
309 }
310
311 ErrorCode WriteCCMIO::get_sets( const EntityHandle* ent_handles,
312 int num_sets,
313 std::vector< EntityHandle >& matsets,
314 std::vector< EntityHandle >& dirsets,
315 std::vector< EntityHandle >& neusets,
316 std::vector< EntityHandle >& partsets )
317 {
318 if( num_sets == 0 )
319 {
320
321 Range this_range;
322 mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mMaterialSetTag, NULL, 1, this_range );
323 std::copy( this_range.begin(), this_range.end(), std::back_inserter( matsets ) );
324 this_range.clear();
325 mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mDirichletSetTag, NULL, 1, this_range );
326 std::copy( this_range.begin(), this_range.end(), std::back_inserter( dirsets ) );
327 this_range.clear();
328 mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mNeumannSetTag, NULL, 1, this_range );
329 std::copy( this_range.begin(), this_range.end(), std::back_inserter( neusets ) );
330 if( mPartitionSetTag )
331 {
332 this_range.clear();
333 mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mPartitionSetTag, NULL, 1, this_range );
334 std::copy( this_range.begin(), this_range.end(), std::back_inserter( partsets ) );
335 }
336 }
337 else
338 {
339 int dummy;
340 for( const EntityHandle* iter = ent_handles; iter < ent_handles + num_sets; ++iter )
341 {
342 if( MB_SUCCESS == mbImpl->tag_get_data( mMaterialSetTag, &( *iter ), 1, &dummy ) )
343 matsets.push_back( *iter );
344 else if( MB_SUCCESS == mbImpl->tag_get_data( mDirichletSetTag, &( *iter ), 1, &dummy ) )
345 dirsets.push_back( *iter );
346 else if( MB_SUCCESS == mbImpl->tag_get_data( mNeumannSetTag, &( *iter ), 1, &dummy ) )
347 neusets.push_back( *iter );
348 else if( mPartitionSetTag && MB_SUCCESS == mbImpl->tag_get_data( mPartitionSetTag, &( *iter ), 1, &dummy ) )
349 partsets.push_back( *iter );
350 }
351 }
352
353 return MB_SUCCESS;
354 }
355
356 ErrorCode WriteCCMIO::write_problem_description( CCMIOID rootID,
357 CCMIOID stateID,
358 CCMIOID& problemID,
359 CCMIOID processorID,
360 std::vector< WriteCCMIO::MaterialSetData >& matset_data,
361 std::vector< WriteCCMIO::NeumannSetData >& neuset_data )
362 {
363
364
365
366 CCMIOID id;
367 CCMIOError error = kCCMIONoErr;
368 ErrorCode rval;
369 const EntityHandle mesh = 0;
370
371 bool root_tagged = false, other_set_tagged = false;
372 Tag simname;
373 Range dum_sets;
374 rval = mbImpl->tag_get_handle( "Title", 0, MB_TYPE_OPAQUE, simname, MB_TAG_ANY );
375 if( MB_SUCCESS == rval )
376 {
377 int tag_size;
378 rval = mbImpl->tag_get_bytes( simname, tag_size );
379 if( MB_SUCCESS == rval )
380 {
381 std::vector< char > title_tag( tag_size + 1 );
382 rval = mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &simname, NULL, 1, dum_sets );
383 if( MB_SUCCESS == rval && !dum_sets.empty() )
384 {
385 rval = mbImpl->tag_get_data( simname, &( *dum_sets.begin() ), 1, &title_tag[0] );MB_CHK_SET_ERR( rval, "Problem getting simulation name tag" );
386 other_set_tagged = true;
387 }
388 else if( MB_SUCCESS == rval )
389 {
390
391 rval = mbImpl->tag_get_data( simname, &mesh, 1, &title_tag[0] );
392 if( MB_SUCCESS == rval )
393 root_tagged = true;
394 else
395 rval = MB_SUCCESS;
396 }
397 *title_tag.rbegin() = '\0';
398 if( root_tagged || other_set_tagged )
399 {
400 CCMIONode rootNode;
401 if( kCCMIONoErr == CCMIOGetEntityNode( &error, rootID, &rootNode ) )
402 {
403 CCMIOSetTitle( &error, rootNode, &title_tag[0] );
404 CHK_SET_CCMERR( error, "Trouble setting title" );
405 }
406 }
407 }
408 }
409
410 rval = mbImpl->tag_get_handle( "CreatingProgram", 0, MB_TYPE_OPAQUE, mCreatingProgramTag, MB_TAG_ANY );
411 if( MB_SUCCESS == rval )
412 {
413 int tag_size;
414 rval = mbImpl->tag_get_bytes( mCreatingProgramTag, tag_size );
415 if( MB_SUCCESS == rval )
416 {
417 std::vector< char > cp_tag( tag_size + 1 );
418 rval = mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mCreatingProgramTag, NULL, 1, dum_sets );
419 if( MB_SUCCESS == rval && !dum_sets.empty() )
420 {
421 rval = mbImpl->tag_get_data( mCreatingProgramTag, &( *dum_sets.begin() ), 1, &cp_tag[0] );MB_CHK_SET_ERR( rval, "Problem getting creating program tag" );
422 other_set_tagged = true;
423 }
424 else if( MB_SUCCESS == rval )
425 {
426
427 rval = mbImpl->tag_get_data( mCreatingProgramTag, &mesh, 1, &cp_tag[0] );
428 if( MB_SUCCESS == rval )
429 root_tagged = true;
430 else
431 rval = MB_SUCCESS;
432 }
433 *cp_tag.rbegin() = '\0';
434 if( root_tagged || other_set_tagged )
435 {
436 CCMIONode rootNode;
437 if( kCCMIONoErr == CCMIOGetEntityNode( &error, rootID, &rootNode ) )
438 {
439 CCMIOWriteOptstr( &error, processorID, "CreatingProgram", &cp_tag[0] );
440 CHK_SET_CCMERR( error, "Trouble setting creating program" );
441 }
442 }
443 }
444 }
445
446 CCMIONewEntity( &error, rootID, kCCMIOProblemDescription, NULL, &problemID );
447 CHK_SET_CCMERR( error, "Trouble creating problem node" );
448
449
450 for( unsigned int i = 0; i < matset_data.size(); i++ )
451 {
452 if( !matset_data[i].setName.empty() )
453 {
454 CCMIONewIndexedEntity( &error, problemID, kCCMIOCellType, matset_data[i].matsetId,
455 matset_data[i].setName.c_str(), &id );
456 CHK_SET_CCMERR( error, "Failure creating celltype node" );
457
458 CCMIOWriteOptstr( &error, id, "MaterialType", matset_data[i].setName.c_str() );
459 CHK_SET_CCMERR( error, "Error assigning material name" );
460 }
461 else
462 {
463 char dum_name[NAME_TAG_SIZE];
464 std::ostringstream os;
465 std::string mat_name = "Material", temp_str;
466 os << mat_name << ( i + 1 );
467 temp_str = os.str();
468 strcpy( dum_name, temp_str.c_str() );
469 CCMIONewIndexedEntity( &error, problemID, kCCMIOCellType, matset_data[i].matsetId, dum_name, &id );
470 CHK_SET_CCMERR( error, "Failure creating celltype node" );
471
472 CCMIOWriteOptstr( &error, id, "MaterialType", dum_name );
473 CHK_SET_CCMERR( error, "Error assigning material name" );
474
475 os.str( "" );
476 }
477 rval = write_int_option( "MaterialId", matset_data[i].setHandle, mMaterialIdTag, id );MB_CHK_SET_ERR( rval, "Trouble writing MaterialId option" );
478
479 rval = write_int_option( "Radiation", matset_data[i].setHandle, mRadiationTag, id );MB_CHK_SET_ERR( rval, "Trouble writing Radiation option" );
480
481 rval = write_int_option( "PorosityId", matset_data[i].setHandle, mPorosityIdTag, id );MB_CHK_SET_ERR( rval, "Trouble writing PorosityId option" );
482
483 rval = write_int_option( "SpinId", matset_data[i].setHandle, mSpinIdTag, id );MB_CHK_SET_ERR( rval, "Trouble writing SpinId option" );
484
485 rval = write_int_option( "GroupId", matset_data[i].setHandle, mGroupIdTag, id );MB_CHK_SET_ERR( rval, "Trouble writing GroupId option" );
486
487 rval = write_int_option( "ColorIdx", matset_data[i].setHandle, mColorIdxTag, id );MB_CHK_SET_ERR( rval, "Trouble writing ColorIdx option" );
488
489 rval = write_int_option( "ProcessorId", matset_data[i].setHandle, mProcessorIdTag, id );MB_CHK_SET_ERR( rval, "Trouble writing ProcessorId option" );
490
491 rval = write_int_option( "LightMaterial", matset_data[i].setHandle, mLightMaterialTag, id );MB_CHK_SET_ERR( rval, "Trouble writing LightMaterial option." );
492
493 rval = write_int_option( "FreeSurfaceMaterial", matset_data[i].setHandle, mFreeSurfaceMaterialTag, id );MB_CHK_SET_ERR( rval, "Trouble writing FreeSurfaceMaterial option" );
494
495 rval = write_dbl_option( "Thickness", matset_data[i].setHandle, mThicknessTag, id );MB_CHK_SET_ERR( rval, "Trouble writing Thickness option" );
496
497 rval = write_str_option( "MaterialType", matset_data[i].setHandle, mMaterialTypeTag, id );MB_CHK_SET_ERR( rval, "Trouble writing MaterialType option" );
498 }
499
500
501 for( unsigned int i = 0; i < neuset_data.size(); i++ )
502 {
503
504 std::ostringstream dum_id;
505 dum_id << neuset_data[i].neusetId;
506 CCMIONewIndexedEntity( &error, problemID, kCCMIOBoundaryRegion, neuset_data[i].neusetId, dum_id.str().c_str(),
507 &id );
508 CHK_SET_CCMERR( error, "Failure creating BoundaryRegion node" );
509
510 rval = write_str_option( "BoundaryName", neuset_data[i].setHandle, mNameTag, id );MB_CHK_SET_ERR( rval, "Trouble writing boundary type number" );
511
512 rval = write_str_option( "BoundaryType", neuset_data[i].setHandle, mBoundaryTypeTag, id );MB_CHK_SET_ERR( rval, "Trouble writing boundary type number" );
513
514 rval = write_int_option( "ProstarRegionNumber", neuset_data[i].setHandle, mProstarRegionNumberTag, id );MB_CHK_SET_ERR( rval, "Trouble writing prostar region number" );
515 }
516
517 CCMIOWriteState( &error, stateID, problemID, "Example state" );
518 CHK_SET_CCMERR( error, "Failure writing problem state" );
519
520
521
522
523
524
525
526 return MB_SUCCESS;
527 }
528
529 ErrorCode WriteCCMIO::write_int_option( const char* opt_name, EntityHandle seth, Tag& tag, CCMIOID& node )
530 {
531 ErrorCode rval;
532
533 if( !tag )
534 {
535 rval = mbImpl->tag_get_handle( opt_name, 1, MB_TYPE_INTEGER, tag );
536
537 if( MB_SUCCESS != rval ) return MB_SUCCESS;
538 }
539
540 int dum_val;
541 rval = mbImpl->tag_get_data( tag, &seth, 1, &dum_val );
542
543 if( MB_SUCCESS != rval ) return MB_SUCCESS;
544
545 CCMIOError error = kCCMIONoErr;
546 CCMIOWriteOpti( &error, node, opt_name, dum_val );
547 CHK_SET_CCMERR( error, "Trouble writing int option" );
548
549 return MB_SUCCESS;
550 }
551
552 ErrorCode WriteCCMIO::write_dbl_option( const char* opt_name, EntityHandle seth, Tag& tag, CCMIOID& node )
553 {
554 ErrorCode rval;
555
556 if( !tag )
557 {
558 rval = mbImpl->tag_get_handle( opt_name, 1, MB_TYPE_DOUBLE, tag );
559
560 if( MB_SUCCESS != rval ) return MB_SUCCESS;
561 }
562
563 double dum_val;
564 rval = mbImpl->tag_get_data( tag, &seth, 1, &dum_val );
565
566 if( MB_SUCCESS != rval ) return MB_SUCCESS;
567
568 CCMIOError error = kCCMIONoErr;
569 CCMIOWriteOptf( &error, node, opt_name, dum_val );
570 CHK_SET_CCMERR( error, "Trouble writing int option" );
571
572 return MB_SUCCESS;
573 }
574
575 ErrorCode WriteCCMIO::write_str_option( const char* opt_name,
576 EntityHandle seth,
577 Tag& tag,
578 CCMIOID& node,
579 const char* other_name )
580 {
581 int tag_size;
582 ErrorCode rval;
583
584 if( !tag )
585 {
586 rval = mbImpl->tag_get_handle( opt_name, 0, MB_TYPE_OPAQUE, tag, MB_TAG_ANY );
587
588 if( MB_SUCCESS != rval ) return MB_SUCCESS;
589 }
590
591 rval = mbImpl->tag_get_bytes( tag, tag_size );
592 if( MB_SUCCESS != rval ) return MB_SUCCESS;
593 std::vector< char > opt_val( tag_size + 1 );
594
595 rval = mbImpl->tag_get_data( tag, &seth, 1, &opt_val[0] );
596 if( MB_SUCCESS != rval ) return MB_SUCCESS;
597
598
599 if( std::find( opt_val.begin(), opt_val.end(), '\0' ) == opt_val.end() ) *opt_val.rbegin() = '\0';
600
601 CCMIOError error = kCCMIONoErr;
602 if( other_name )
603 {
604 CCMIOWriteOptstr( &error, node, other_name, &opt_val[0] );
605 CHK_SET_CCMERR( error, "Failure writing an option string MaterialType" );
606 }
607 else
608 {
609 CCMIOWriteOptstr( &error, node, opt_name, &opt_val[0] );
610 CHK_SET_CCMERR( error, "Failure writing an option string MaterialType" );
611 }
612
613 return MB_SUCCESS;
614 }
615
616 ErrorCode WriteCCMIO::gather_matset_info( std::vector< EntityHandle >& matsets,
617 std::vector< MaterialSetData >& matset_data,
618 Range& all_verts )
619 {
620 ErrorCode result;
621 matset_data.resize( matsets.size() );
622 if( 1 == matsets.size() && 0 == matsets[0] )
623 {
624
625 mWholeMesh = true;
626
627 result = mbImpl->get_entities_by_dimension( 0, mDimension, matset_data[0].elems );MB_CHK_SET_ERR( result, "Trouble getting all elements in mesh" );
628 result = mWriteIface->gather_nodes_from_elements( matset_data[0].elems, mEntityMark, all_verts );MB_CHK_SET_ERR( result, "Trouble gathering nodes from elements" );
629
630 return result;
631 }
632
633 std::vector< unsigned char > marks;
634 for( unsigned int i = 0; i < matsets.size(); i++ )
635 {
636 EntityHandle this_set = matset_data[i].setHandle = matsets[i];
637
638
639 result = mbImpl->get_entities_by_dimension( this_set, mDimension, matset_data[i].elems, true );MB_CHK_SET_ERR( result, "Trouble getting m-dimensional ents" );
640
641
642 result = mWriteIface->gather_nodes_from_elements( matset_data[i].elems, mEntityMark, all_verts );MB_CHK_SET_ERR( result, "Trouble getting vertices for a matset" );
643
644
645 EntityType start_type = mbImpl->type_from_handle( *matset_data[i].elems.begin() );
646 if( start_type == mbImpl->type_from_handle( *matset_data[i].elems.rbegin() ) )
647 matset_data[i].entityType = start_type;
648
649
650 marks.resize( matset_data[i].elems.size(), 0x1 );
651 result = mbImpl->tag_set_data( mEntityMark, matset_data[i].elems, &marks[0] );MB_CHK_SET_ERR( result, "Couln't mark entities being output" );
652
653
654 result = mbImpl->tag_get_data( mMaterialSetTag, &this_set, 1, &matset_data[i].matsetId );MB_CHK_SET_ERR( result, "Couln't get global id for material set" );
655
656
657 if( mNameTag )
658 {
659 char dum_name[NAME_TAG_SIZE];
660 result = mbImpl->tag_get_data( mNameTag, &this_set, 1, dum_name );
661 if( MB_SUCCESS == result ) matset_data[i].setName = dum_name;
662
663
664 result = MB_SUCCESS;
665 }
666 }
667
668 if( all_verts.empty() )
669 {
670 MB_SET_ERR( MB_FILE_WRITE_ERROR, "No vertices from elements" );
671 }
672
673 return MB_SUCCESS;
674 }
675
676 ErrorCode WriteCCMIO::gather_neuset_info( std::vector< EntityHandle >& neusets,
677 std::vector< NeumannSetData >& neuset_info )
678 {
679 ErrorCode result;
680
681 neuset_info.resize( neusets.size() );
682 for( unsigned int i = 0; i < neusets.size(); i++ )
683 {
684 EntityHandle this_set = neuset_info[i].setHandle = neusets[i];
685
686
687 result = mbImpl->get_entities_by_dimension( this_set, mDimension - 1, neuset_info[i].elems, true );MB_CHK_SET_ERR( result, "Trouble getting (m-1)-dimensional ents for neuset" );
688
689 result = mbImpl->tag_get_data( mGlobalIdTag, &this_set, 1, &neuset_info[i].neusetId );
690 if( MB_TAG_NOT_FOUND == result )
691 {
692 result = mbImpl->tag_get_data( mNeumannSetTag, &this_set, 1, &neuset_info[i].neusetId );
693 if( MB_SUCCESS != result )
694
695 neuset_info[i].neusetId = i;
696 }
697
698
699 if( mNameTag )
700 {
701 char dum_name[NAME_TAG_SIZE];
702 result = mbImpl->tag_get_data( mNameTag, &this_set, 1, dum_name );
703 if( MB_SUCCESS == result ) neuset_info[i].setName = dum_name;
704
705
706 result = MB_SUCCESS;
707 }
708 }
709
710 return MB_SUCCESS;
711 }
712
713 ErrorCode WriteCCMIO::get_gids( const Range& ents, int*& gids, int& minid, int& maxid )
714 {
715 int num_ents = ents.size();
716 gids = new int[num_ents];
717 ErrorCode result = mbImpl->tag_get_data( mGlobalIdTag, ents, &gids[0] );MB_CHK_SET_ERR( result, "Couldn't get global id data" );
718 minid = *std::min_element( gids, gids + num_ents );
719 maxid = *std::max_element( gids, gids + num_ents );
720 if( 0 == minid )
721 {
722
723 for( int i = 1; i <= num_ents; i++ )
724 gids[i] = i;
725 result = mbImpl->tag_set_data( mGlobalIdTag, ents, &gids[0] );MB_CHK_SET_ERR( result, "Couldn't set global id data" );
726 maxid = num_ents;
727 }
728
729 return MB_SUCCESS;
730 }
731
732 ErrorCode WriteCCMIO::write_nodes( CCMIOID rootID, const Range& verts, const int dimension, CCMIOID& verticesID )
733 {
734
735 unsigned int num_verts = verts.size();
736 std::vector< int > vgids( num_verts );
737 ErrorCode result = mbImpl->tag_get_data( mGlobalIdTag, verts, &vgids[0] );MB_CHK_SET_ERR( result, "Failed to get global ids for vertices" );
738
739
740 CCMIOID mapID;
741 CCMIOError error = kCCMIONoErr;
742 CCMIONewEntity( &error, rootID, kCCMIOMap, "Vertex map", &mapID );
743 CHK_SET_CCMERR( error, "Failure creating Vertex map node" );
744
745 int maxid = *std::max_element( vgids.begin(), vgids.end() );
746
747 CCMIOWriteMap( &error, mapID, CCMIOSIZEC( num_verts ), CCMIOSIZEC( maxid ), &vgids[0], CCMIOINDEXC( kCCMIOStart ),
748 CCMIOINDEXC( kCCMIOEnd ) );
749 CHK_SET_CCMERR( error, "Problem writing node map" );
750
751
752 CCMIONewEntity( &error, rootID, kCCMIOVertices, "Vertices", &verticesID );
753 CHK_SET_CCMERR( error, "Trouble creating vertices node" );
754
755
756 double* coords = new double[3 * num_verts];
757 std::vector< double* > coord_arrays( 3 );
758
759
760 coord_arrays[0] = coords;
761 coord_arrays[1] = coords + num_verts;
762 coord_arrays[2] = ( dimension == 3 ? coords + 2 * num_verts : NULL );
763 result = mWriteIface->get_node_coords( -1, verts.begin(), verts.end(), 3 * num_verts, coords );
764 if( result != MB_SUCCESS )
765 {
766 delete[] coords;
767 return result;
768 }
769
770
771 result = transform_coords( dimension, num_verts, coords );
772 if( result != MB_SUCCESS )
773 {
774 delete[] coords;
775 MB_SET_ERR( result, "Trouble transforming vertex coordinates" );
776 }
777
778
779 CCMIOWriteVerticesd( &error, verticesID, CCMIOSIZEC( dimension ), 1.0, mapID, coords, CCMIOINDEXC( kCCMIOStart ),
780 CCMIOINDEXC( kCCMIOEnd ) );
781 CHK_SET_CCMERR( error, "CCMIOWriteVertices failed" );
782
783
784 delete[] coords;
785
786 return MB_SUCCESS;
787 }
788
789 ErrorCode WriteCCMIO::transform_coords( const int dimension, const int num_nodes, double* coords )
790 {
791 Tag trans_tag;
792 ErrorCode result = mbImpl->tag_get_handle( MESH_TRANSFORM_TAG_NAME, 16, MB_TYPE_DOUBLE, trans_tag );
793 if( result == MB_TAG_NOT_FOUND )
794 return MB_SUCCESS;
795 else if( MB_SUCCESS != result )
796 return result;
797 double trans_matrix[16];
798 const EntityHandle mesh = 0;
799 result = mbImpl->tag_get_data( trans_tag, &mesh, 1, trans_matrix );MB_CHK_SET_ERR( result, "Couldn't get transform data" );
800
801 double* tmp_coords = coords;
802 for( int i = 0; i < num_nodes; i++, tmp_coords += 1 )
803 {
804 double vec1[3] = { 0.0, 0.0, 0.0 };
805 for( int row = 0; row < 3; row++ )
806 {
807 vec1[row] += ( trans_matrix[( row * 4 ) + 0] * coords[0] );
808 vec1[row] += ( trans_matrix[( row * 4 ) + 1] * coords[num_nodes] );
809 if( 3 == dimension ) vec1[row] += ( trans_matrix[( row * 4 ) + 2] * coords[2 * num_nodes] );
810 }
811
812 coords[0] = vec1[0];
813 coords[num_nodes] = vec1[1];
814 coords[2 * num_nodes] = vec1[2];
815 }
816
817 return MB_SUCCESS;
818 }
819
820 ErrorCode WriteCCMIO::write_cells_and_faces( CCMIOID rootID,
821 std::vector< MaterialSetData >& matset_data,
822 std::vector< NeumannSetData >& neuset_data,
823 Range& ,
824 CCMIOID& topologyID )
825 {
826 std::vector< int > connect;
827 ErrorCode result;
828 CCMIOID cellMapID, cells;
829 CCMIOError error = kCCMIONoErr;
830
831
832 connect.reserve( 31 );
833 Range::const_iterator rit;
834
835
836 CCMIONewEntity( &error, rootID, kCCMIOTopology, "Topology", &topologyID );
837 CHK_SET_CCMERR( error, "Trouble creating topology node" );
838
839 CCMIONewEntity( &error, rootID, kCCMIOMap, "Cell map", &cellMapID );
840 CHK_SET_CCMERR( error, "Failure creating Cell Map node" );
841
842 CCMIONewEntity( &error, topologyID, kCCMIOCells, "Cells", &cells );
843 CHK_SET_CCMERR( error, "Trouble creating Cell node under Topology node" );
844
845
846
847
848 Range all_elems;
849 unsigned int i, num_elems = 0;
850 int max_id = 1;
851 std::vector< int > egids;
852 int tot_elems = 0;
853
854 for( unsigned int m = 0; m < matset_data.size(); m++ )
855 tot_elems += matset_data[m].elems.size();
856
857 for( unsigned int m = 0; m < matset_data.size(); m++ )
858 {
859 unsigned int this_num = matset_data[m].elems.size();
860
861
862
863
864 all_elems.merge( matset_data[m].elems );
865
866
867
868
869 egids.resize( matset_data[m].elems.size() );
870 for( i = 0; i < this_num; i++ )
871 egids[i] = max_id++;
872 result = mbImpl->tag_set_data( mGlobalIdTag, matset_data[m].elems, &egids[0] );MB_CHK_SET_ERR( result, "Failed to assign global ids for all elements being written" );
873
874
875
876
877 CCMIOWriteMap( &error, cellMapID, CCMIOSIZEC( tot_elems ), CCMIOSIZEC( tot_elems ), &egids[0],
878 CCMIOINDEXC( 0 == m ? kCCMIOStart : num_elems ),
879 CCMIOINDEXC( matset_data.size() == m ? kCCMIOEnd : num_elems + this_num ) );
880 CHK_SET_CCMERR( error, "Trouble writing cell map" );
881
882 if( -1 == matset_data[m].matsetId )
883 {
884 for( i = 0; i < this_num; i++ )
885 egids[i] = m;
886 }
887 else
888 {
889 for( i = 0; i < this_num; i++ )
890 egids[i] = matset_data[m].matsetId;
891 }
892
893 CCMIOWriteCells( &error, cells, cellMapID, &egids[0], CCMIOINDEXC( 0 == m ? kCCMIOStart : num_elems ),
894 CCMIOINDEXC( matset_data.size() == m ? kCCMIOEnd : num_elems + this_num ) );
895 CHK_SET_CCMERR( error, "Trouble writing Cell node" );
896
897
898
899
900 const EntityHandle* conn;
901 int num_conn;
902 int has_mid_nodes[4];
903 std::vector< EntityHandle > storage;
904 for( i = 0, rit = matset_data[m].elems.begin(); i < this_num; i++, ++rit )
905 {
906 result = mbImpl->get_connectivity( *rit, conn, num_conn, false, &storage );MB_CHK_SET_ERR( result, "Trouble getting connectivity for entity type check" );
907 CN::HasMidNodes( mbImpl->type_from_handle( *rit ), num_conn, has_mid_nodes );
908 egids[i] = moab_to_ccmio_type( mbImpl->type_from_handle( *rit ), has_mid_nodes );
909 }
910
911 CCMIOWriteOpt1i( &error, cells, "CellTopologyType", CCMIOSIZEC( tot_elems ), &egids[0],
912 CCMIOINDEXC( 0 == m ? kCCMIOStart : num_elems ),
913 CCMIOINDEXC( matset_data.size() == m ? kCCMIOEnd : num_elems + this_num ) );
914 CHK_SET_CCMERR( error, "Failed to write cell topo types" );
915
916 num_elems += this_num;
917 }
918
919
920
921
922 Range neuset_facets, skin_facets;
923 Skinner skinner( mbImpl );
924 result = skinner.find_skin( 0, all_elems, mDimension - 1, skin_facets );MB_CHK_SET_ERR( result, "Failed to get skin facets" );
925
926
927
928 for( i = 0; i < neuset_data.size(); i++ )
929 neuset_facets.merge( neuset_data[i].elems );
930
931 skin_facets -= neuset_facets;
932
933 neuset_facets.merge( skin_facets );
934 result = mWriteIface->assign_ids( neuset_facets, mGlobalIdTag, 1 );
935
936 int fmaxid = neuset_facets.size();
937
938
939
940
941 for( i = 0; i < neuset_data.size(); i++ )
942 {
943 Range::reverse_iterator rrit;
944 unsigned char cmarks[2];
945 Range ext_faces;
946 std::vector< EntityHandle > mcells;
947
948 for( rrit = neuset_data[i].elems.rbegin(); rrit != neuset_data[i].elems.rend(); ++rrit )
949 {
950 mcells.clear();
951 result = mbImpl->get_adjacencies( &( *rrit ), 1, mDimension, false, mcells );MB_CHK_SET_ERR( result, "Trouble getting bounding cells" );
952
953 result = mbImpl->tag_get_data( mEntityMark, &mcells[0], mcells.size(), cmarks );MB_CHK_SET_ERR( result, "Trouble getting mark tags on cells bounding facets" );
954
955 if( mcells.size() == 2 && ( mWholeMesh || ( cmarks[0] && cmarks[1] ) ) )
956 {
957 }
958 else
959 {
960
961 ext_faces.insert( *rrit );
962 }
963 }
964 if( ext_faces.size() != 0 && neuset_data[i].neusetId != 0 )
965 {
966 result = write_external_faces( rootID, topologyID, neuset_data[i].neusetId, ext_faces );MB_CHK_SET_ERR( result, "Trouble writing Neumann set facets" );
967 }
968 ext_faces.clear();
969 }
970
971 if( !skin_facets.empty() )
972 {
973 result = write_external_faces( rootID, topologyID, 0, skin_facets );MB_CHK_SET_ERR( result, "Trouble writing skin facets" );
974 }
975
976
977
978
979
980
981 if( num_elems > 1 )
982 {
983 Tag fmark_tag;
984 unsigned char mval = 0x0, omval;
985 result = mbImpl->tag_get_handle( "__fmark", 1, MB_TYPE_OPAQUE, fmark_tag, MB_TAG_DENSE | MB_TAG_CREAT, &mval );MB_CHK_SET_ERR( result, "Couldn't create mark tag" );
986
987 std::vector< EntityHandle > tmp_face_cells, storage;
988 std::vector< int > iface_connect, iface_cells;
989 EntityHandle tmp_connect[CN::MAX_NODES_PER_ELEMENT];
990 const EntityHandle *connectc, *oconnectc;
991 int num_connectc;
992 const EntityHandle* connectf;
993 int num_connectf;
994
995 for( i = 0, rit = all_elems.begin(); i < num_elems; i++, ++rit )
996 {
997 EntityType etype = TYPE_FROM_HANDLE( *rit );
998
999
1000
1001
1002 if( MBPOLYHEDRON != etype && MBPOLYGON != etype )
1003 {
1004 result = mbImpl->tag_get_data( fmark_tag, &( *rit ), 1, &mval );MB_CHK_SET_ERR( result, "Couldn't get mark data" );
1005 }
1006
1007
1008
1009
1010 result = mbImpl->get_connectivity( *rit, connectc, num_connectc, false, &storage );MB_CHK_SET_ERR( result, "Couldn't get entity connectivity" );
1011
1012
1013 bool is_polyh = ( MBPOLYHEDRON == etype );
1014
1015 int num_facets = ( is_polyh ? num_connectc : CN::NumSubEntities( etype, mDimension - 1 ) );
1016
1017
1018
1019
1020 for( int f = 0; f < num_facets; f++ )
1021 {
1022
1023
1024
1025 if( !is_polyh && ( ( mval >> f ) & 0x1 ) ) continue;
1026
1027
1028
1029
1030 if( !is_polyh )
1031 {
1032
1033 CN::SubEntityConn( connectc, etype, mDimension - 1, f, tmp_connect, num_connectf );
1034 connectf = tmp_connect;
1035 }
1036 else
1037 {
1038
1039 result = mbImpl->get_connectivity( connectc[f], connectf, num_connectf, false );MB_CHK_SET_ERR( result, "Couldn't get polyhedron connectivity" );
1040 }
1041
1042
1043
1044
1045
1046 tmp_face_cells.clear();
1047 result = mbImpl->get_adjacencies( connectf, num_connectf, mDimension, false, tmp_face_cells );MB_CHK_SET_ERR( result, "Error getting adj hexes" );
1048
1049
1050
1051
1052
1053 if( tmp_face_cells.size() != 2 ) continue;
1054
1055
1056
1057
1058
1059 int side_num = 0, sense = 0, offset = 0;
1060 if( !is_polyh && tmp_face_cells[0] != *rit )
1061 {
1062 EntityHandle tmph = tmp_face_cells[0];
1063 tmp_face_cells[0] = tmp_face_cells[1];
1064 tmp_face_cells[1] = tmph;
1065 }
1066
1067
1068
1069
1070 assert( tmp_face_cells[0] != tmp_face_cells[1] );
1071 iface_cells.resize( iface_cells.size() + 2 );
1072 result = mbImpl->tag_get_data( mGlobalIdTag, &tmp_face_cells[0], tmp_face_cells.size(),
1073 &iface_cells[iface_cells.size() - 2] );MB_CHK_SET_ERR( result, "Trouble getting global ids for bounded cells" );
1074 iface_connect.push_back( num_connectf );
1075
1076
1077
1078
1079 unsigned int tmp_size = iface_connect.size();
1080 iface_connect.resize( tmp_size + num_connectf );
1081 result = mbImpl->tag_get_data( mGlobalIdTag, connectf, num_connectf, &iface_connect[tmp_size] );MB_CHK_SET_ERR( result, "Trouble getting global id for internal face" );
1082
1083
1084
1085
1086 if( !is_polyh )
1087 {
1088
1089
1090 result = mbImpl->get_connectivity( tmp_face_cells[1], oconnectc, num_connectc, false, &storage );MB_CHK_SET_ERR( result, "Couldn't get other entity connectivity" );
1091
1092
1093 CN::SideNumber( TYPE_FROM_HANDLE( tmp_face_cells[1] ), oconnectc, connectf, num_connectf,
1094 mDimension - 1, side_num, sense, offset );
1095
1096 result = mbImpl->tag_get_data( fmark_tag, &tmp_face_cells[1], 1, &omval );MB_CHK_SET_ERR( result, "Couldn't get mark data for other cell" );
1097 }
1098
1099 omval |= ( 0x1 << (unsigned int)side_num );
1100 result = mbImpl->tag_set_data( fmark_tag, &tmp_face_cells[1], 1, &omval );MB_CHK_SET_ERR( result, "Couldn't set mark data for other cell" );
1101 }
1102 }
1103
1104
1105
1106
1107
1108 CCMIOID mapID;
1109 CCMIONewEntity( &error, rootID, kCCMIOMap, NULL, &mapID );
1110 CHK_SET_CCMERR( error, "Trouble creating Internal Face map node" );
1111
1112 unsigned int num_ifaces = iface_cells.size() / 2;
1113
1114
1115 egids.resize( num_ifaces );
1116 for( i = 1; i <= num_ifaces; i++ )
1117 egids[i - 1] = fmaxid + i;
1118 CCMIOWriteMap( &error, mapID, CCMIOSIZEC( num_ifaces ), CCMIOSIZEC( fmaxid + num_ifaces ), &egids[0],
1119 CCMIOINDEXC( kCCMIOStart ), CCMIOINDEXC( kCCMIOEnd ) );
1120 CHK_SET_CCMERR( error, "Trouble writing Internal Face map node" );
1121
1122 CCMIOID id;
1123 CCMIONewEntity( &error, topologyID, kCCMIOInternalFaces, "Internal faces", &id );
1124 CHK_SET_CCMERR( error, "Failed to create Internal face node under Topology node" );
1125 CCMIOWriteFaces( &error, id, kCCMIOInternalFaces, mapID, CCMIOSIZEC( iface_connect.size() ), &iface_connect[0],
1126 CCMIOINDEXC( kCCMIOStart ), CCMIOINDEXC( kCCMIOEnd ) );
1127 CHK_SET_CCMERR( error, "Failure writing Internal face connectivity" );
1128 CCMIOWriteFaceCells( &error, id, kCCMIOInternalFaces, mapID, &iface_cells[0], CCMIOINDEXC( kCCMIOStart ),
1129 CCMIOINDEXC( kCCMIOEnd ) );
1130 CHK_SET_CCMERR( error, "Failure writing Internal face cells" );
1131 }
1132
1133 return MB_SUCCESS;
1134 }
1135
1136 int WriteCCMIO::moab_to_ccmio_type( EntityType etype, int has_mid_nodes[] )
1137 {
1138 int ctype = -1;
1139 if( has_mid_nodes[0] || has_mid_nodes[2] || has_mid_nodes[3] ) return ctype;
1140
1141 switch( etype )
1142 {
1143 case MBVERTEX:
1144 ctype = 1;
1145 break;
1146 case MBEDGE:
1147 if( !has_mid_nodes[1] )
1148 ctype = 2;
1149 else
1150 ctype = 28;
1151 break;
1152 case MBQUAD:
1153 if( has_mid_nodes[1] )
1154 ctype = 4;
1155 else
1156 ctype = 3;
1157 break;
1158 case MBTET:
1159 if( has_mid_nodes[1] )
1160 ctype = 23;
1161 else
1162 ctype = 13;
1163 break;
1164 case MBPRISM:
1165 if( has_mid_nodes[1] )
1166 ctype = 22;
1167 else
1168 ctype = 12;
1169 break;
1170 case MBPYRAMID:
1171 if( has_mid_nodes[1] )
1172 ctype = 24;
1173 else
1174 ctype = 14;
1175 break;
1176 case MBHEX:
1177 if( has_mid_nodes[1] )
1178 ctype = 21;
1179 else
1180 ctype = 11;
1181 break;
1182 case MBPOLYHEDRON:
1183 ctype = 255;
1184 break;
1185 default:
1186 break;
1187 }
1188
1189 return ctype;
1190 }
1191
1192 ErrorCode WriteCCMIO::write_external_faces( CCMIOID rootID, CCMIOID topologyID, int set_num, Range& facets )
1193 {
1194 CCMIOError error = kCCMIONoErr;
1195 CCMIOID mapID, id;
1196
1197
1198 int *gids = NULL, minid, maxid;
1199 ErrorCode result = get_gids( facets, gids, minid, maxid );MB_CHK_SET_ERR( result, "Trouble getting global ids for facets" );
1200
1201
1202 CCMIONewEntity( &error, rootID, kCCMIOMap, NULL, &mapID );
1203 CHK_SET_CCMERR( error, "Problem creating face id map" );
1204
1205 CCMIOWriteMap( &error, mapID, CCMIOSIZEC( facets.size() ), CCMIOSIZEC( maxid ), gids, CCMIOINDEXC( kCCMIOStart ),
1206 CCMIOINDEXC( kCCMIOEnd ) );
1207 CHK_SET_CCMERR( error, "Problem writing face id map" );
1208
1209
1210 const EntityHandle* connect;
1211 int num_connect;
1212 result = mbImpl->get_connectivity( *facets.rbegin(), connect, num_connect );MB_CHK_SET_ERR( result, "Failed to get connectivity of last facet" );
1213 std::vector< int > fconnect( facets.size() * ( num_connect + 1 ) );
1214
1215 result = mWriteIface->get_element_connect( facets.begin(), facets.end(), num_connect, mGlobalIdTag, fconnect.size(),
1216 &fconnect[0], true );MB_CHK_SET_ERR( result, "Failed to get facet connectivity" );
1217
1218
1219 CCMIONewIndexedEntity( &error, topologyID, kCCMIOBoundaryFaces, set_num, "Boundary faces", &id );
1220 CHK_SET_CCMERR( error, "Problem creating boundary face entity" );
1221
1222 CCMIOWriteFaces( &error, id, kCCMIOBoundaryFaces, mapID, CCMIOSIZEC( fconnect.size() ), &fconnect[0],
1223 CCMIOINDEXC( kCCMIOStart ), CCMIOINDEXC( kCCMIOEnd ) );
1224 CHK_SET_CCMERR( error, "Problem writing boundary faces" );
1225
1226
1227 std::vector< EntityHandle > cells;
1228 unsigned char cmarks[2];
1229 int i, j = 0;
1230 Range dead_facets;
1231 Range::iterator rit;
1232
1233
1234
1235 for( rit = facets.begin(), i = 0; rit != facets.end(); ++rit, i++ )
1236 {
1237 cells.clear();
1238
1239
1240 result = mbImpl->get_adjacencies( &( *rit ), 1, mDimension, false, cells );MB_CHK_SET_ERR( result, "Trouble getting bounding cells" );
1241 if( cells.empty() )
1242 {
1243 MB_SET_ERR( MB_FILE_WRITE_ERROR, "External facet with no output bounding cell" );
1244 }
1245
1246
1247 result = mbImpl->tag_get_data( mEntityMark, &cells[0], cells.size(), cmarks );MB_CHK_SET_ERR( result, "Trouble getting mark tags on cells bounding facets" );
1248 if( cells.size() == 2 && ( mWholeMesh || ( cmarks[0] && cmarks[1] ) ) )
1249 {
1250 MB_SET_ERR( MB_FILE_WRITE_ERROR, "External facet with two output bounding cells" );
1251 }
1252 else if( 1 == cells.size() && !mWholeMesh && !cmarks[0] )
1253 {
1254 MB_SET_ERR( MB_FILE_WRITE_ERROR, "External facet with no output bounding cells" );
1255 }
1256
1257
1258 if( 2 == cells.size() && !( cmarks[0] | 0x0 ) && ( cmarks[1] & 0x1 ) ) cells[0] = cells[1];
1259
1260
1261 result = mbImpl->tag_get_data( mGlobalIdTag, &cells[0], 1, &fconnect[j] );MB_CHK_SET_ERR( result, "Couldn't get global id tag for bounded cell" );
1262
1263 j++;
1264 }
1265
1266
1267 CCMIOWriteFaceCells( &error, id, kCCMIOBoundaryFaces, mapID, &fconnect[0], CCMIOINDEXC( kCCMIOStart ),
1268 CCMIOINDEXC( kCCMIOEnd ) );
1269 CHK_SET_CCMERR( error, "Problem writing boundary cell data" );
1270
1271 return MB_SUCCESS;
1272 }
1273
1274 ErrorCode WriteCCMIO::get_neuset_elems( EntityHandle neuset,
1275 int current_sense,
1276 Range& forward_elems,
1277 Range& reverse_elems )
1278 {
1279 Range neuset_elems, neuset_meshsets;
1280
1281
1282
1283 Tag sense_tag = 0;
1284 mbImpl->tag_get_handle( "SENSE", 1, MB_TYPE_INTEGER, sense_tag );
1285
1286
1287 ErrorCode result = mbImpl->get_entities_by_handle( neuset, neuset_elems );
1288 if( MB_FAILURE == result ) return result;
1289
1290
1291 Range::iterator range_iter = neuset_elems.begin();
1292 while( TYPE_FROM_HANDLE( *range_iter ) != MBENTITYSET && range_iter != neuset_elems.end() )
1293 ++range_iter;
1294
1295
1296 if( range_iter != neuset_elems.end() )
1297 {
1298 std::copy( range_iter, neuset_elems.end(), range_inserter( neuset_meshsets ) );
1299 neuset_elems.erase( range_iter, neuset_elems.end() );
1300 }
1301
1302
1303
1304
1305
1306 Range::iterator dum_it = neuset_elems.end();
1307 --dum_it;
1308 int target_dim = CN::Dimension( TYPE_FROM_HANDLE( *dum_it ) );
1309 dum_it = neuset_elems.begin();
1310 while( target_dim != CN::Dimension( TYPE_FROM_HANDLE( *dum_it ) ) && dum_it != neuset_elems.end() )
1311 ++dum_it;
1312
1313 if( current_sense == 1 || current_sense == 0 )
1314 std::copy( dum_it, neuset_elems.end(), range_inserter( forward_elems ) );
1315 if( current_sense == -1 || current_sense == 0 )
1316 std::copy( dum_it, neuset_elems.end(), range_inserter( reverse_elems ) );
1317
1318
1319
1320 for( range_iter = neuset_meshsets.begin(); range_iter != neuset_meshsets.end(); ++range_iter )
1321 {
1322
1323 int this_sense;
1324 if( 0 == sense_tag || MB_FAILURE == mbImpl->tag_get_data( sense_tag, &( *range_iter ), 1, &this_sense ) )
1325 this_sense = 1;
1326
1327
1328 get_neuset_elems( *range_iter, this_sense * current_sense, forward_elems, reverse_elems );
1329 }
1330
1331 return result;
1332 }
1333 }