1
12
13 #include "moab/Core.hpp"
14 #include "moab/Range.hpp"
15 #include "moab/Skinner.hpp"
16 #include "moab/LloydSmoother.hpp"
17 #include "moab/ProgOptions.hpp"
18 #include "moab/BoundBox.hpp"
19 #include "moab/SpatialLocator.hpp"
20 #include "MBTagConventions.hpp"
21 #include "DataCoupler.hpp"
22
23 #ifdef USE_MPI
24 #include "moab/ParallelComm.hpp"
25 #endif
26
27 #include <iostream>
28 #include <set>
29 #include <sstream>
30 #include <cassert>
31
32 using namespace moab;
33 using namespace std;
34
35 #ifndef MESH_DIR
36 #define MESH_DIR "."
37 #endif
38
39 ErrorCode read_file( string& fname,
40 EntityHandle& seth,
41 Range& solids,
42 Range& solid_elems,
43 Range& fluids,
44 Range& fluid_elems );
45 void deform_func( const BoundBox& bbox, double* xold, double* xnew );
46 ErrorCode deform_master( Range& fluid_elems, Range& solid_elems, Tag& xnew );
47 ErrorCode smooth_master( int dim, Tag xnew, EntityHandle& master, Range& fluids );
48 ErrorCode write_to_coords( Range& elems, Tag tagh );
49
50 const int SOLID_SETNO = 100, FLUID_SETNO = 200;
51
52 Interface* mb;
53
54 const bool debug = true;
55
56 class DeformMeshRemap
57 {
58 public:
59
60 enum
61 {
62 MASTER = 0,
63 SLAVE,
64 SOLID,
65 FLUID
66 };
67
68
69
70
71
72 DeformMeshRemap( Interface* impl, ParallelComm* master = NULL, ParallelComm* slave = NULL );
73
74
75 ~DeformMeshRemap();
76
77
78 ErrorCode execute();
79
80
81 ErrorCode add_set_no( int m_or_s, int fluid_or_solid, int set_no );
82
83
84 ErrorCode remove_set_no( int m_or_s, int fluid_or_solid, int set_no );
85
86
87 ErrorCode get_set_nos( int m_or_s, int fluid_or_solid, set< int >& set_nos ) const;
88
89
90 inline Tag x_new() const
91 {
92 return xNew;
93 }
94
95
96 string x_new_name() const
97 {
98 return xNewName;
99 }
100
101
102 void x_new_name( const string& name )
103 {
104 xNewName = name;
105 }
106
107
108 string get_file_name( int m_or_s ) const;
109
110
111 void set_file_name( int m_or_s, const string& name );
112
113
114 string xdisp_name( int idx = 0 );
115 void xdisp_name( const string& nm, int idx = 0 );
116
117 private:
118
119
120 ErrorCode deform_master( Range& fluid_elems, Range& solid_elems, const char* tag_name = NULL );
121
122
123 ErrorCode read_file( int m_or_s, string& fname, EntityHandle& seth );
124
125
126
127 ErrorCode write_to_coords( Range& elems, Tag tagh, Tag tmp_tag = 0 );
128
129
130
131 ErrorCode write_and_save( Range& ents,
132 EntityHandle seth,
133 Tag tagh,
134 const char* filename,
135 bool restore_coords = false );
136
137
138 ErrorCode find_other_sets( int m_or_s, EntityHandle file_set );
139
140
141 Interface* mbImpl;
142
143 #ifdef USE_MPI
144
145 ParallelComm *pcMaster, *pcSlave;
146 #endif
147
148
149 set< int > fluidSetNos[2];
150
151
152 set< int > solidSetNos[2];
153
154
155 EntityHandle masterSet, slaveSet;
156
157
158 Range fluidSets[2], solidSets[2];
159
160
161 Range fluidElems[2], solidElems[2];
162
163
164 string masterFileName, slaveFileName;
165
166
167 Tag xDisp[3];
168
169
170 Tag xNew;
171
172
173 string xDispNames[3];
174
175
176 string xNewName;
177 };
178
179
180 inline ErrorCode DeformMeshRemap::add_set_no( int m_or_s, int f_or_s, int set_no )
181 {
182 set< int >* this_set;
183 assert( ( m_or_s == MASTER || m_or_s == SLAVE ) && "m_or_s should be MASTER or SLAVE." );
184 if( m_or_s != MASTER && m_or_s != SLAVE ) return MB_INDEX_OUT_OF_RANGE;
185
186 switch( f_or_s )
187 {
188 case FLUID:
189 this_set = &fluidSetNos[m_or_s];
190 break;
191 case SOLID:
192 this_set = &solidSetNos[m_or_s];
193 break;
194 default:
195 assert( false && "f_or_s should be FLUID or SOLID." );
196 return MB_FAILURE;
197 }
198
199 this_set->insert( set_no );
200
201 return MB_SUCCESS;
202 }
203
204
205 inline ErrorCode DeformMeshRemap::remove_set_no( int m_or_s, int f_or_s, int set_no )
206 {
207 set< int >* this_set;
208 assert( ( m_or_s == MASTER || m_or_s == SLAVE ) && "m_or_s should be MASTER or SLAVE." );
209 if( m_or_s != MASTER && m_or_s != SLAVE ) return MB_INDEX_OUT_OF_RANGE;
210 switch( f_or_s )
211 {
212 case FLUID:
213 this_set = &fluidSetNos[m_or_s];
214 break;
215 case SOLID:
216 this_set = &solidSetNos[m_or_s];
217 break;
218 default:
219 assert( false && "f_or_s should be FLUID or SOLID." );
220 return MB_FAILURE;
221 }
222 set< int >::iterator sit = this_set->find( set_no );
223 if( sit != this_set->end() )
224 {
225 this_set->erase( *sit );
226 return MB_SUCCESS;
227 }
228
229 return MB_FAILURE;
230 }
231
232
233 inline ErrorCode DeformMeshRemap::get_set_nos( int m_or_s, int f_or_s, set< int >& set_nos ) const
234 {
235 const set< int >* this_set;
236 assert( ( m_or_s == MASTER || m_or_s == SLAVE ) && "m_or_s should be MASTER or SLAVE." );
237 if( m_or_s != MASTER && m_or_s != SLAVE ) return MB_INDEX_OUT_OF_RANGE;
238 switch( f_or_s )
239 {
240 case FLUID:
241 this_set = &fluidSetNos[m_or_s];
242 break;
243 case SOLID:
244 this_set = &solidSetNos[m_or_s];
245 break;
246 default:
247 assert( false && "f_or_s should be FLUID or SOLID." );
248 return MB_FAILURE;
249 }
250
251 set_nos = *this_set;
252
253 return MB_SUCCESS;
254 }
255
256 inline string DeformMeshRemap::xdisp_name( int idx )
257 {
258 return xDispNames[idx];
259 }
260
261 void DeformMeshRemap::xdisp_name( const string& nm, int idx )
262 {
263 xDispNames[idx] = nm;
264 }
265
266 ErrorCode DeformMeshRemap::execute()
267 {
268
269 ErrorCode rval = read_file( MASTER, masterFileName, masterSet );MB_CHK_ERR( rval );
270
271 if( solidSetNos[MASTER].empty() || fluidSetNos[MASTER].empty() )
272 {
273 rval = find_other_sets( MASTER, masterSet );MB_CHK_SET_ERR( rval, "Failed to find other sets in master mesh" );
274 }
275
276 bool have_slave = !( slaveFileName == "none" );
277 if( have_slave )
278 {
279 rval = read_file( SLAVE, slaveFileName, slaveSet );MB_CHK_ERR( rval );
280
281 if( solidSetNos[SLAVE].empty() || fluidSetNos[SLAVE].empty() )
282 {
283 rval = find_other_sets( SLAVE, slaveSet );MB_CHK_SET_ERR( rval, "Failed to find other sets in slave mesh" );
284 }
285 }
286
287 if( debug ) cout << "Constructing data coupler/search tree on master mesh..." << endl;
288
289 Range src_elems = solidElems[MASTER];
290 src_elems.merge( fluidElems[MASTER] );
291
292
293 DataCoupler dc_master( mbImpl, src_elems, 0, NULL );
294
295 Range tgt_verts;
296 if( have_slave )
297 {
298
299
300 Range tmp_range = solidElems[SLAVE];
301 tmp_range.merge( fluidElems[SLAVE] );
302 rval = mbImpl->get_adjacencies( tmp_range, 0, false, tgt_verts, Interface::UNION );MB_CHK_SET_ERR( rval, "Failed to get target verts" );
303
304
305 if( debug ) cout << "Locating slave vertices in master mesh..." << endl;
306 rval = dc_master.locate_points( tgt_verts );MB_CHK_SET_ERR( rval, "Point location of tgt verts failed" );
307 int num_located = dc_master.spatial_locator()->local_num_located();
308 if( num_located != (int)tgt_verts.size() )
309 {
310 rval = MB_FAILURE;
311 cout << "Only " << num_located << " out of " << tgt_verts.size() << " target points successfully located."
312 << endl;
313 return rval;
314 }
315 }
316
317
318 if( debug ) cout << "Deforming fluid elements in master mesh..." << endl;
319 rval = deform_master( fluidElems[MASTER], solidElems[MASTER], "xnew" );MB_CHK_ERR( rval );
320
321 {
322 if( debug )
323 {
324
325
326 Skinner skinner( mbImpl );
327 Range skin;
328 rval = skinner.find_skin( 0, fluidElems[MASTER], false, skin );MB_CHK_SET_ERR( rval, "Unable to find skin" );
329 EntityHandle skin_set;
330 cout << "Writing skin_mesh.g and fluid_mesh.g." << endl;
331 rval = mbImpl->create_meshset( MESHSET_SET, skin_set );MB_CHK_SET_ERR( rval, "Failed to create skin set" );
332 rval = mbImpl->add_entities( skin_set, skin );MB_CHK_SET_ERR( rval, "Failed to add skin entities to set" );
333 rval = mbImpl->write_file( "skin_mesh.vtk", NULL, NULL, &skin_set, 1 );MB_CHK_SET_ERR( rval, "Failure to write skin set" );
334 rval = mbImpl->remove_entities( skin_set, skin );MB_CHK_SET_ERR( rval, "Failed to remove skin entities from set" );
335 rval = mbImpl->add_entities( skin_set, fluidElems[MASTER] );MB_CHK_SET_ERR( rval, "Failed to add fluid entities to set" );
336 rval = mbImpl->write_file( "fluid_mesh.vtk", NULL, NULL, &skin_set, 1 );MB_CHK_SET_ERR( rval, "Failure to write fluid set" );
337 rval = mbImpl->delete_entities( &skin_set, 1 );MB_CHK_SET_ERR( rval, "Failed to delete skin set" );
338 }
339
340
341 if( debug ) cout << "Smoothing fluid elements in master mesh..." << endl;
342 LloydSmoother ll( mbImpl, NULL, fluidElems[MASTER], xNew );
343 rval = ll.perform_smooth();MB_CHK_SET_ERR( rval, "Failed in lloyd smoothing" );
344 cout << "Lloyd smoothing required " << ll.num_its() << " iterations." << endl;
345 }
346
347
348 if( debug ) cout << "Transferring coords tag to vertex coordinates in master mesh..." << endl;
349 rval = write_to_coords( solidElems[MASTER], xNew );MB_CHK_SET_ERR( rval, "Failed writing tag to master fluid verts" );
350 rval = write_to_coords( fluidElems[MASTER], xNew );MB_CHK_SET_ERR( rval, "Failed writing tag to master fluid verts" );
351
352 if( have_slave )
353 {
354
355
356 if( debug ) cout << "Interpolating new coordinates to slave vertices..." << endl;
357 rval = dc_master.interpolate( (int)DataCoupler::VOLUME, "xnew" );MB_CHK_SET_ERR( rval, "Failed to interpolate target solution" );
358
359 if( debug ) cout << "Transferring coords tag to vertex coordinates in slave mesh..." << endl;
360 rval = write_to_coords( tgt_verts, xNew );MB_CHK_SET_ERR( rval, "Failed writing tag to slave verts" );
361 }
362
363 if( debug )
364 {
365 string str;
366 #ifdef USE_MPI
367 if( pcMaster && pcMaster->size() > 1 ) str = "PARALLEL=WRITE_PART";
368 #endif
369 if( debug ) cout << "Writing smoothed_master.h5m..." << endl;
370 rval = mbImpl->write_file( "smoothed_master.h5m", NULL, str.c_str(), &masterSet, 1 );
371
372 if( have_slave )
373 {
374 #ifdef USE_MPI
375 str.clear();
376 if( pcSlave && pcSlave->size() > 1 ) str = "PARALLEL=WRITE_PART";
377 #endif
378 if( debug ) cout << "Writing slave_interp.h5m..." << endl;
379 rval = mbImpl->write_file( "slave_interp.h5m", NULL, str.c_str(), &slaveSet, 1 );
380 }
381 }
382
383 if( debug ) dc_master.spatial_locator()->get_tree()->tree_stats().print();
384
385 return MB_SUCCESS;
386 }
387
388 string DeformMeshRemap::get_file_name( int m_or_s ) const
389 {
390 switch( m_or_s )
391 {
392 case MASTER:
393 return masterFileName;
394 case SLAVE:
395 return slaveFileName;
396 default:
397 assert( false && "m_or_s should be MASTER or SLAVE." );
398 return string();
399 }
400 }
401
402 void DeformMeshRemap::set_file_name( int m_or_s, const string& name )
403 {
404 switch( m_or_s )
405 {
406 case MASTER:
407 masterFileName = name;
408 break;
409 case SLAVE:
410 slaveFileName = name;
411 break;
412 default:
413 assert( false && "m_or_s should be MASTER or SLAVE." );
414 }
415 }
416
417 DeformMeshRemap::DeformMeshRemap( Interface* impl, ParallelComm* master, ParallelComm* slave )
418 : mbImpl( impl ), pcMaster( master ), pcSlave( slave ), masterSet( 0 ), slaveSet( 0 ), xNew( 0 ), xNewName( "xnew" )
419 {
420 xDisp[0] = xDisp[1] = xDisp[2] = 0;
421
422 if( !pcSlave && pcMaster ) pcSlave = pcMaster;
423 }
424
425 DeformMeshRemap::~DeformMeshRemap() {}
426
427 int main( int argc, char** argv )
428 {
429 ErrorCode rval;
430
431 ProgOptions po( "Deformed mesh options" );
432 po.addOpt< string >( "master,m", "Specify the master meshfile name" );
433 po.addOpt< string >( "worker,w", "Specify the slave/worker meshfile name, or 'none' (no quotes) if master only" );
434 po.addOpt< string >( "d1,", "Tag name for displacement x or xyz" );
435 po.addOpt< string >( "d2,", "Tag name for displacement y" );
436 po.addOpt< string >( "d3,", "Tag name for displacement z" );
437 po.addOpt< int >( "fm,", "Specify master fluid material set number(s). If none specified, "
438 "fluid sets derived from complement of solid sets." );
439 po.addOpt< int >( "fs,", "Specify master solid material set number(s). If none specified, "
440 "solid sets derived from complement of fluid sets." );
441 po.addOpt< int >( "sm,", "Specify slave fluid material set number(s). If none specified, fluid "
442 "sets derived from complement of solid sets." );
443 po.addOpt< int >( "ss,", "Specify slave solid material set number(s). If none specified, solid "
444 "sets derived from complement of fluid sets." );
445
446 po.parseCommandLine( argc, argv );
447
448 mb = new Core();
449
450 DeformMeshRemap* dfr;
451 #ifdef USE_MPI
452 ParallelComm* pc = new ParallelComm( mb, MPI_COMM_WORLD );
453 dfr = new DeformMeshRemap( mb, pc );
454 #else
455 dfr = new DeformMeshRemap( mb );
456 #endif
457
458 string masterf, slavef;
459 if( !po.getOpt( "master", &masterf ) ) masterf = string( MESH_DIR ) + string( "/rodquad.g" );
460 dfr->set_file_name( DeformMeshRemap::MASTER, masterf );
461
462 if( !po.getOpt( "worker", &slavef ) ) slavef = string( MESH_DIR ) + string( "/rodtri.g" );
463 dfr->set_file_name( DeformMeshRemap::SLAVE, slavef );
464 if( slavef.empty() )
465 {
466 cerr << "Empty slave file name; if no slave, use filename 'none' (no quotes)." << endl;
467 return 1;
468 }
469
470 vector< int > set_nos;
471 po.getOptAllArgs( "fm", set_nos );
472 for( vector< int >::iterator vit = set_nos.begin(); vit != set_nos.end(); ++vit )
473 dfr->add_set_no( DeformMeshRemap::MASTER, DeformMeshRemap::FLUID, *vit );
474 set_nos.clear();
475
476 po.getOptAllArgs( "fs", set_nos );
477 for( vector< int >::iterator vit = set_nos.begin(); vit != set_nos.end(); ++vit )
478 dfr->add_set_no( DeformMeshRemap::SLAVE, DeformMeshRemap::FLUID, *vit );
479 set_nos.clear();
480
481 po.getOptAllArgs( "sm", set_nos );
482 for( vector< int >::iterator vit = set_nos.begin(); vit != set_nos.end(); ++vit )
483 dfr->add_set_no( DeformMeshRemap::MASTER, DeformMeshRemap::SOLID, *vit );
484
485 po.getOptAllArgs( "ss", set_nos );
486 for( vector< int >::iterator vit = set_nos.begin(); vit != set_nos.end(); ++vit )
487 dfr->add_set_no( DeformMeshRemap::SLAVE, DeformMeshRemap::SOLID, *vit );
488
489 string tnames[3];
490 po.getOpt( "d1", &tnames[0] );
491 po.getOpt( "d2", &tnames[1] );
492 po.getOpt( "d3", &tnames[2] );
493 for( int i = 0; i < 3; i++ )
494 if( !tnames[i].empty() ) dfr->xdisp_name( tnames[i], i );
495
496 rval = dfr->execute();
497
498 delete dfr;
499 delete mb;
500
501 return rval;
502 }
503
504 ErrorCode DeformMeshRemap::write_and_save( Range& ents,
505 EntityHandle seth,
506 Tag tagh,
507 const char* filename,
508 bool restore_coords )
509 {
510 Tag tmp_tag = 0;
511 ErrorCode rval;
512 if( restore_coords ) rval = mbImpl->tag_get_handle( "", 3, MB_TYPE_DOUBLE, tmp_tag, MB_TAG_CREAT | MB_TAG_DENSE );
513
514 rval = write_to_coords( ents, tagh, tmp_tag );MB_CHK_ERR( rval );
515 rval = mbImpl->write_file( filename, NULL, NULL, &seth, 1 );MB_CHK_ERR( rval );
516 if( restore_coords )
517 {
518 rval = write_to_coords( ents, tmp_tag );MB_CHK_ERR( rval );
519 rval = mbImpl->tag_delete( tmp_tag );MB_CHK_ERR( rval );
520 }
521
522 return rval;
523 }
524
525 ErrorCode DeformMeshRemap::write_to_coords( Range& elems, Tag tagh, Tag tmp_tag )
526 {
527
528 Range verts;
529 ErrorCode rval = mbImpl->get_adjacencies( elems, 0, false, verts, Interface::UNION );MB_CHK_SET_ERR( rval, "Failed to get adj vertices" );
530 vector< double > coords( 3 * verts.size() );
531
532 if( tmp_tag )
533 {
534
535 rval = mbImpl->get_coords( verts, &coords[0] );MB_CHK_SET_ERR( rval, "Failed to get tmp copy of coords" );
536 rval = mbImpl->tag_set_data( tmp_tag, verts, &coords[0] );MB_CHK_SET_ERR( rval, "Failed to save tmp copy of coords" );
537 }
538
539 rval = mbImpl->tag_get_data( tagh, verts, &coords[0] );MB_CHK_SET_ERR( rval, "Failed to get tag data" );
540 rval = mbImpl->set_coords( verts, &coords[0] );MB_CHK_SET_ERR( rval, "Failed to set coordinates" );
541 return MB_SUCCESS;
542 }
543
544 void deform_func( const BoundBox& bbox, double* xold, double* xnew )
545 {
546
556
557 double frac = 0.01;
558 CartVect *xo = reinterpret_cast< CartVect* >( xold ), *xn = reinterpret_cast< CartVect* >( xnew );
559 CartVect disp = frac * ( *xo - bbox.bMin );
560 *xn = *xo + disp;
561 }
562
563 ErrorCode DeformMeshRemap::deform_master( Range& fluid_elems, Range& solid_elems, const char* tag_name )
564 {
565
566 ErrorCode rval;
567
568
569 Range solid_verts, fluid_verts;
570 rval = mbImpl->get_adjacencies( solid_elems, 0, false, solid_verts, Interface::UNION );MB_CHK_SET_ERR( rval, "Failed to get vertices" );
571 vector< double > coords( 3 * solid_verts.size() ), new_coords( 3 * solid_verts.size() );
572 rval = mbImpl->get_coords( solid_verts, &coords[0] );MB_CHK_SET_ERR( rval, "Failed to get vertex coords" );
573 unsigned int num_verts = solid_verts.size();
574
575
576 if( !xDispNames[0].empty() && !xDispNames[1].empty() && !xDispNames[2].empty() )
577 {
578
579 rval = mbImpl->tag_get_handle( ( tag_name ? tag_name : "" ), 3, MB_TYPE_DOUBLE, xNew,
580 MB_TAG_CREAT | MB_TAG_DENSE );MB_CHK_SET_ERR( rval, "Failed to create xnew tag" );
581 vector< double > disps( num_verts );
582 for( int i = 0; i < 3; i++ )
583 {
584 rval = mbImpl->tag_get_handle( xDispNames[0].c_str(), 1, MB_TYPE_DOUBLE, xDisp[i] );MB_CHK_SET_ERR( rval, "Failed to get xDisp tag" );
585 rval = mbImpl->tag_get_data( xDisp[i], solid_verts, &disps[0] );MB_CHK_SET_ERR( rval, "Failed to get xDisp tag values" );
586 for( unsigned int j = 0; j < num_verts; j++ )
587 new_coords[3 * j + i] = coords[3 * j + i] + disps[j];
588 }
589 }
590 else if( !xDispNames[0].empty() )
591 {
592 rval = mbImpl->tag_get_handle( xDispNames[0].c_str(), 3, MB_TYPE_DOUBLE, xDisp[0] );MB_CHK_SET_ERR( rval, "Failed to get first xDisp tag" );
593 xNew = xDisp[0];
594 vector< double > disps( 3 * num_verts );
595 rval = mbImpl->tag_get_data( xDisp[0], solid_verts, &disps[0] );
596 for( unsigned int j = 0; j < 3 * num_verts; j++ )
597 new_coords[j] = coords[j] + disps[j];
598 }
599 else
600 {
601
602 BoundBox bbox;
603 bbox.update( *mbImpl, solid_elems );
604
605 for( unsigned int j = 0; j < num_verts; j++ )
606 deform_func( bbox, &coords[3 * j], &new_coords[3 * j] );
607 }
608
609 if( debug )
610 {
611 double len = 0.0;
612 for( unsigned int i = 0; i < num_verts; i++ )
613 {
614 CartVect dx = CartVect( &new_coords[3 * i] ) - CartVect( &coords[3 * i] );
615 double tmp_len = dx.length_squared();
616 if( tmp_len > len ) len = tmp_len;
617 }
618 Range tmp_elems( fluid_elems );
619 tmp_elems.merge( solid_elems );
620 BoundBox box;
621 box.update( *mbImpl, tmp_elems );
622 double max_len =
623 std::max( box.bMax[2] - box.bMin[2], std::max( box.bMax[1] - box.bMin[1], box.bMax[0] - box.bMin[0] ) );
624
625 cout << "Max displacement = " << len << " (" << 100.0 * len / max_len << "% of max box length)" << endl;
626 }
627
628 if( !xNew )
629 {
630 rval = mbImpl->tag_get_handle( ( tag_name ? tag_name : "" ), 3, MB_TYPE_DOUBLE, xDisp[0],
631 MB_TAG_CREAT | MB_TAG_DENSE );MB_CHK_SET_ERR( rval, "Failed to get xNew tag" );
632 xNew = xDisp[0];
633 }
634
635
636 rval = mbImpl->tag_set_data( xNew, solid_verts, &new_coords[0] );MB_CHK_SET_ERR( rval, "Failed to set tag data" );
637
638
639 rval = mbImpl->get_adjacencies( fluid_elems, 0, false, fluid_verts, Interface::UNION );MB_CHK_SET_ERR( rval, "Failed to get vertices" );
640 fluid_verts = subtract( fluid_verts, solid_verts );
641
642 if( coords.size() < 3 * fluid_verts.size() ) coords.resize( 3 * fluid_verts.size() );
643 rval = mbImpl->get_coords( fluid_verts, &coords[0] );MB_CHK_SET_ERR( rval, "Failed to get vertex coords" );
644 rval = mbImpl->tag_set_data( xNew, fluid_verts, &coords[0] );MB_CHK_SET_ERR( rval, "Failed to set xnew tag on fluid verts" );
645
646 if( debug )
647 {
648
649 Range tmp_range( fluidElems[MASTER] );
650 tmp_range.merge( solidElems[MASTER] );
651 rval = write_and_save( tmp_range, masterSet, xNew, "deformed_master.h5m", true );MB_CHK_ERR( rval );
652 }
653
654 return MB_SUCCESS;
655 }
656
657 ErrorCode DeformMeshRemap::read_file( int m_or_s, string& fname, EntityHandle& seth )
658 {
659
660 ErrorCode rval = mbImpl->create_meshset( 0, seth );MB_CHK_SET_ERR( rval, "Couldn't create master/slave set" );
661 ostringstream options;
662 #ifdef USE_MPI
663 ParallelComm* pc = ( m_or_s == MASTER ? pcMaster : pcSlave );
664 if( pc && pc->size() > 1 )
665 {
666 if( debug ) options << "DEBUG_IO=1;CPUTIME;";
667 options << "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS;"
668 << "PARALLEL_GHOSTS=2.0.1;PARALLEL_COMM=" << pc->get_id();
669 }
670 #endif
671 rval = mbImpl->load_file( fname.c_str(), &seth, options.str().c_str() );MB_CHK_SET_ERR( rval, "Couldn't load master/slave mesh" );
672
673 if( *solidSetNos[m_or_s].begin() == -1 || *fluidSetNos[m_or_s].begin() == -1 ) return MB_SUCCESS;
674
675
676 Tag tagh;
677 rval = mbImpl->tag_get_handle( MATERIAL_SET_TAG_NAME, tagh );MB_CHK_SET_ERR( rval, "Couldn't get material set tag name" );
678 for( set< int >::iterator sit = solidSetNos[m_or_s].begin(); sit != solidSetNos[m_or_s].end(); ++sit )
679 {
680 Range sets;
681 int set_no = *sit;
682 const void* setno_ptr = &set_no;
683 rval = mbImpl->get_entities_by_type_and_tag( seth, MBENTITYSET, &tagh, &setno_ptr, 1, sets );
684 if( MB_SUCCESS != rval || sets.empty() )
685 {
686 MB_SET_ERR( MB_FAILURE, "Couldn't find solid set #" << *sit );
687 }
688 else
689 solidSets[m_or_s].merge( sets );
690 }
691
692
693 Range tmp_range;
694 for( Range::iterator rit = solidSets[m_or_s].begin(); rit != solidSets[m_or_s].end(); ++rit )
695 {
696 rval = mbImpl->get_entities_by_handle( *rit, tmp_range, true );MB_CHK_SET_ERR( rval, "Failed to get entities in solid" );
697 }
698 if( !tmp_range.empty() )
699 {
700 int dim = mbImpl->dimension_from_handle( *tmp_range.rbegin() );
701 assert( dim > 0 && dim < 4 );
702 solidElems[m_or_s] = tmp_range.subset_by_dimension( dim );
703 }
704
705 if( debug )
706 cout << "Read " << solidElems[m_or_s].size() << " solid elements from " << solidSets[m_or_s].size()
707 << " sets in " << ( m_or_s == MASTER ? "master" : "slave" ) << " mesh." << endl;
708
709 for( set< int >::iterator sit = fluidSetNos[m_or_s].begin(); sit != fluidSetNos[m_or_s].end(); ++sit )
710 {
711 Range sets;
712 int set_no = *sit;
713 const void* setno_ptr = &set_no;
714 rval = mbImpl->get_entities_by_type_and_tag( seth, MBENTITYSET, &tagh, &setno_ptr, 1, sets );
715 if( MB_SUCCESS != rval || sets.empty() )
716 {
717 MB_SET_ERR( MB_FAILURE, "Couldn't find fluid set #" << *sit );
718 }
719 else
720 fluidSets[m_or_s].merge( sets );
721 }
722
723
724 tmp_range.clear();
725 for( Range::iterator rit = fluidSets[m_or_s].begin(); rit != fluidSets[m_or_s].end(); ++rit )
726 {
727 rval = mbImpl->get_entities_by_handle( *rit, tmp_range, true );MB_CHK_SET_ERR( rval, "Failed to get entities in fluid" );
728 }
729 if( !tmp_range.empty() )
730 {
731 int dim = mbImpl->dimension_from_handle( *tmp_range.rbegin() );
732 assert( dim > 0 && dim < 4 );
733 fluidElems[m_or_s] = tmp_range.subset_by_dimension( dim );
734 }
735
736 if( debug )
737 cout << "Read " << fluidElems[m_or_s].size() << " fluid elements from " << fluidSets[m_or_s].size()
738 << " sets in " << ( m_or_s == MASTER ? "master" : "slave" ) << " mesh." << endl;
739
740 return rval;
741 }
742
743 ErrorCode DeformMeshRemap::find_other_sets( int m_or_s, EntityHandle file_set )
744 {
745
746 Range *filled_sets = NULL, *unfilled_sets = NULL, *unfilled_elems = NULL;
747
748 if( fluidSets[m_or_s].empty() && !solidSets[m_or_s].empty() )
749 {
750 unfilled_sets = &fluidSets[m_or_s];
751 filled_sets = &solidSets[m_or_s];
752 unfilled_elems = &fluidElems[m_or_s];
753 if( debug )
754 cout << "Finding unspecified fluid elements in " << ( m_or_s == MASTER ? "master" : "slave" ) << " mesh...";
755 }
756 else if( !fluidSets[m_or_s].empty() && solidSets[m_or_s].empty() )
757 {
758 filled_sets = &fluidSets[m_or_s];
759 unfilled_sets = &solidSets[m_or_s];
760 unfilled_elems = &solidElems[m_or_s];
761 if( debug )
762 cout << "Finding unspecified solid elements in " << ( m_or_s == MASTER ? "master" : "slave" ) << " mesh...";
763 }
764
765
766 Tag tagh;
767 ErrorCode rval = mbImpl->tag_get_handle( MATERIAL_SET_TAG_NAME, tagh );MB_CHK_SET_ERR( rval, "Couldn't get material set tag name" );
768 Range matsets;
769 rval = mbImpl->get_entities_by_type_and_tag( file_set, MBENTITYSET, &tagh, NULL, 1, matsets );
770 if( MB_SUCCESS != rval || matsets.empty() )
771 {
772 MB_SET_ERR( MB_FAILURE, "Couldn't get any material sets" );
773 }
774 *unfilled_sets = subtract( matsets, *filled_sets );
775 if( unfilled_sets->empty() )
776 {
777 MB_SET_ERR( MB_FAILURE, "Failed to find any unfilled material sets" );
778 }
779 Range tmp_range;
780 for( Range::iterator rit = unfilled_sets->begin(); rit != unfilled_sets->end(); ++rit )
781 {
782 rval = mbImpl->get_entities_by_handle( *rit, tmp_range, true );MB_CHK_SET_ERR( rval, "Failed to get entities in unfilled set" );
783 }
784 int dim = mbImpl->dimension_from_handle( *tmp_range.rbegin() );
785 assert( dim > 0 && dim < 4 );
786 *unfilled_elems = tmp_range.subset_by_dimension( dim );
787 if( unfilled_elems->empty() )
788 {
789 MB_SET_ERR( MB_FAILURE, "Failed to find any unfilled set entities" );
790 }
791
792 if( debug )
793 cout << "found " << unfilled_sets->size() << " sets and " << unfilled_elems->size() << " elements." << endl;
794
795 return MB_SUCCESS;
796 }