@@ -58,7 +58,8 @@ namespace {
5858 const StringIdVector & variable_list , const SystemInterface & interFace );
5959 bool define_element_fields (const Ioss ::Region & output_region , const RegionVector & part_mesh ,
6060 const StringIdVector & variable_list );
61- bool define_nset_fields (const Ioss ::Region & output_region , const StringIdVector & variable_list );
61+ bool define_nset_fields (const Ioss ::Region & output_region , const RegionVector & part_mesh ,
62+ const StringIdVector & variable_list );
6263 bool define_sset_fields (const Ioss ::Region & output_region , const RegionVector & part_mesh ,
6364 const StringIdVector & variable_list );
6465 void define_nodal_nodeset_fields (const Ioss ::Region & output_region , const RegionVector & part_mesh ,
@@ -73,7 +74,8 @@ namespace {
7374 const std ::vector < INT > & local_node_map ,
7475 const std ::vector < INT > & local_element_map , bool ignore_element_ids ) ;
7576 template < typename INT >
76- void output_nodeset (Ioss ::Region & output_region , const std ::vector < INT > & local_node_map ) ;
77+ void output_nodeset (Ioss ::Region & output_region , RegionVector & part_mesh ,
78+ const std ::vector < INT > & local_node_map ) ;
7779 template < typename INT >
7880 void output_sideset (Ioss ::Region & output_region , RegionVector & part_mesh ,
7981 const std ::vector < INT > & local_element_map ) ;
@@ -129,8 +131,7 @@ namespace {
129131 void transfer_elementblock (const Ioss ::Region & region , Ioss ::Region & output_region ,
130132 bool create_assemblies , bool debug );
131133 void transfer_assembly (const Ioss ::Region & region , Ioss ::Region & output_region , bool debug );
132- void transfer_nodesets (const Ioss ::Region & region , Ioss ::Region & output_region ,
133- bool combine_similar , bool debug );
134+ void transfer_nodesets (const Ioss ::Region & region , Ioss ::Region & output_region , bool debug );
134135 void transfer_sidesets (const Ioss ::Region & region , Ioss ::Region & output_region , bool debug );
135136 void create_nodal_nodeset (const Ioss ::Region & region , Ioss ::Region & output_region , bool debug );
136137 void transfer_fields (Ioss ::GroupingEntity * ige , Ioss ::GroupingEntity * oge ,
@@ -148,19 +149,21 @@ namespace {
148149 // This only handles the entity count.
149150 void add_to_entity_count (Ioss ::GroupingEntity * ge , int64_t entity_count_increment )
150151 {
151- int64_t new_count = ge -> entity_count () + entity_count_increment ;
152- ge -> reset_entity_count (new_count );
152+ auto ec_property = ge -> get_property ("entity_count" );
153+ auto old_count = ec_property .get_int ();
154+
155+ auto origin = ec_property .get_origin ();
156+ ge -> property_erase ("entity_count" );
157+ ge -> property_add (Ioss ::Property ("entity_count" , entity_count_increment + old_count , origin ));
158+
153159 auto field_names = ge -> field_describe ();
154160 for (const auto & field_name : field_names ) {
155161 const auto & field_ref = ge -> get_fieldref (field_name );
156- const_cast < Ioss ::Field & > (field_ref ).reset_count (new_count );
162+ const_cast < Ioss ::Field & > (field_ref ).reset_count (entity_count_increment + old_count );
157163 }
158164 }
159165} // namespace
160166
161- std ::map < Ioss ::GroupingEntity * , std ::vector < std ::pair < Ioss ::GroupingEntity * , size_t >>>
162- output_input_map ;
163-
164167template < typename INT >
165168double ejoin (SystemInterface & interFace , std ::vector < Ioss ::Region * > & part_mesh , INT dummy );
166169
@@ -444,7 +447,7 @@ double ejoin(SystemInterface &interFace, std::vector<Ioss::Region *> &part_mesh,
444447 create_nodal_nodeset (* part_mesh [p ], output_region , false);
445448 }
446449 if (!interFace .omit_nodesets ()) {
447- transfer_nodesets (* part_mesh [p ], output_region , interFace . combine_nodesets (), false);
450+ transfer_nodesets (* part_mesh [p ], output_region , false);
448451 }
449452 if (!interFace .omit_sidesets ()) {
450453 transfer_sidesets (* part_mesh [p ], output_region , false);
@@ -481,7 +484,7 @@ double ejoin(SystemInterface &interFace, std::vector<Ioss::Region *> &part_mesh,
481484 output_nodal_nodeset (output_region , part_mesh , interFace , local_node_map );
482485
483486 if (!interFace .omit_nodesets ()) {
484- output_nodeset (output_region , local_node_map );
487+ output_nodeset (output_region , part_mesh , local_node_map );
485488 }
486489 if (!interFace .omit_sidesets ()) {
487490 output_sideset (output_region , part_mesh , local_element_map );
@@ -508,7 +511,7 @@ double ejoin(SystemInterface &interFace, std::vector<Ioss::Region *> &part_mesh,
508511 error |= define_element_fields (output_region , part_mesh , interFace .elem_var_names ());
509512
510513 if (!interFace .omit_nodesets ()) {
511- error |= define_nset_fields (output_region , interFace .nset_var_names ());
514+ error |= define_nset_fields (output_region , part_mesh , interFace .nset_var_names ());
512515 }
513516 if (!interFace .omit_sidesets ()) {
514517 error |= define_sset_fields (output_region , part_mesh , interFace .sset_var_names ());
@@ -770,7 +773,6 @@ namespace {
770773 size_t count = region .get_property ("node_count" ).get_int ();
771774 auto * ns = new Ioss ::NodeSet (output_region .get_database (), name , count );
772775 output_region .add (ns );
773- output_input_map [ns ].emplace_back (nullptr , 0 );
774776 }
775777
776778 // Output the bulk data for a nodeset on the output region
@@ -844,10 +846,10 @@ namespace {
844846 }
845847 }
846848
847- void transfer_nodesets (const Ioss ::Region & region , Ioss ::Region & output_region ,
848- bool combine_similar , bool /*debug*/ )
849+ void transfer_nodesets (const Ioss ::Region & region , Ioss ::Region & output_region , bool debug )
849850 {
850- const std ::string & prefix = region .name ();
851+ bool combine_similar = false;
852+ const std ::string & prefix = region .name ();
851853
852854 const Ioss ::NodeSetContainer & nss = region .get_nodesets ();
853855 for (const auto & ns : nss ) {
@@ -857,7 +859,6 @@ namespace {
857859 if (ons != nullptr ) {
858860 if (combine_similar ) {
859861 // Combine nodesets with similar names...
860- output_input_map [ons ].emplace_back (ns , ons -> entity_count ());
861862 size_t count = ns -> entity_count ();
862863 add_to_entity_count (ons , count );
863864 continue ;
@@ -870,10 +871,12 @@ namespace {
870871 }
871872 }
872873 }
873- // This is a new output nodeset at this point...
874+ ns -> property_add (Ioss ::Property ("name_in_output" , name ));
875+ if (debug ) {
876+ fmt ::print (stderr , "{}, " , name );
877+ }
874878 size_t count = ns -> entity_count ();
875879 auto * node_set = new Ioss ::NodeSet (output_region .get_database (), name , count );
876- output_input_map [node_set ].emplace_back (ns , 0 );
877880 output_region .add (node_set );
878881 set_id (ns , node_set );
879882 }
@@ -1009,38 +1012,42 @@ namespace {
10091012 }
10101013
10111014 template < typename INT >
1012- void output_nodeset (Ioss ::Region & output_region , const std ::vector < INT > & local_node_map )
1015+ void output_nodeset (Ioss ::Region & output_region , RegionVector & part_mesh ,
1016+ const std ::vector < INT > & local_node_map )
10131017 {
1014- const auto & output_nodesets = output_region .get_nodesets ();
1015- if (output_nodesets .empty ()) {
1018+ if (output_region .get_nodesets ().empty ()) {
10161019 return ;
10171020 }
10181021
1019- for (const auto & ons : output_nodesets ) {
1020- if (output_input_map .find (ons ) != output_input_map .end ()) {
1021- const auto & ons_inputs = output_input_map [ons ];
1022- if (!ons_inputs .empty () && (ons_inputs [0 ].first != nullptr && ons_inputs [0 ].second != 0 )) {
1023- int64_t count = ons -> entity_count ();
1024- std ::vector < INT > nodelist (count );
1025- std ::vector < double > df (count );
1026- for (const auto & [ins , offset ] : ons_inputs ) {
1027- if (ins != nullptr ) {
1028- ins -> get_field_data ("ids" , & nodelist [offset ], -1 );
1029-
1030- auto * input_region = dynamic_cast < const Ioss ::Region * > (ins -> contained_in ());
1031- size_t node_offset = input_region -> get_property ("node_offset" ).get_int ();
1032- for (int64_t i = 0 ; i < ins -> entity_count (); i ++ ) {
1033- size_t loc_node =
1034- input_region -> node_global_to_local (nodelist [offset + i ], true) - 1 ;
1035- auto gpos = local_node_map [node_offset + loc_node ];
1036- if (gpos >= 0 ) {
1037- nodelist [offset + i ] = gpos + 1 ;
1038- }
1039- }
1040- ins -> get_field_data ("distribution_factors" , & df [offset ], -1 );
1022+ for (const auto & pm : part_mesh ) {
1023+ size_t node_offset = pm -> get_property ("node_offset" ).get_int ();
1024+ const Ioss ::NodeSetContainer & ins = pm -> get_nodesets ();
1025+ for (const auto & in : ins ) {
1026+ if (!entity_is_omitted (in )) {
1027+ std ::vector < INT > nodelist ;
1028+ in -> get_field_data ("ids" , nodelist );
1029+
1030+ std ::string name = pm -> name () + "_" + in -> name ();
1031+ Ioss ::NodeSet * ons = output_region .get_nodeset (name );
1032+ if (ons == nullptr ) {
1033+ name = in -> name ();
1034+ ons = output_region .get_nodeset (name );
1035+ }
1036+ SMART_ASSERT (ons != nullptr )(name );
1037+ SMART_ASSERT (in -> entity_count () == ons -> entity_count ());
1038+
1039+ // This needs to make sure that the nodelist comes back as local id (1..numnodes)
1040+ for (auto & node : nodelist ) {
1041+ size_t loc_node = pm -> node_global_to_local (node , true) - 1 ;
1042+ auto gpos = local_node_map [node_offset + loc_node ];
1043+ if (gpos >= 0 ) {
1044+ node = gpos + 1 ;
10411045 }
10421046 }
10431047 ons -> put_field_data ("ids_raw" , nodelist );
1048+
1049+ std ::vector < double > df ;
1050+ in -> get_field_data ("distribution_factors" , df );
10441051 ons -> put_field_data ("distribution_factors" , df );
10451052 }
10461053 }
@@ -1208,30 +1215,29 @@ namespace {
12081215 }
12091216 }
12101217
1211- void output_nset (Ioss ::Region & output_region )
1218+ void output_nset (Ioss ::Region & output_region , RegionVector & part_mesh )
12121219 {
1213- const auto & output_nodesets = output_region .get_nodesets ();
1214- if (output_nodesets .empty ()) {
1220+ if (output_region .get_nodesets ().empty ()) {
12151221 return ;
12161222 }
12171223
1218- for (const auto & ons : output_nodesets ) {
1219- if (output_input_map .find (ons ) != output_input_map .end ()) {
1220- const auto & ons_inputs = output_input_map [ons ];
1221- if (!ons_inputs .empty () && (ons_inputs [0 ].first != nullptr && ons_inputs [0 ].second != 0 )) {
1222- Ioss ::NameList fields = ons -> field_describe (Ioss ::Field ::TRANSIENT );
1223- int64_t count = ons -> entity_count ();
1224+ for (const auto & pm : part_mesh ) {
1225+ const Ioss ::NodeSetContainer & ins = pm -> get_nodesets ();
1226+ for (const auto & in : ins ) {
1227+ if (!entity_is_omitted (in )) {
1228+ std ::string name = pm -> name () + "_" + in -> name ();
1229+ Ioss ::NodeSet * ons = output_region .get_nodeset (name );
1230+ if (ons == nullptr ) {
1231+ name = in -> name ();
1232+ ons = output_region .get_nodeset (name );
1233+ }
1234+ SMART_ASSERT (ons != nullptr )(name );
12241235
1236+ Ioss ::NameList fields = in -> field_describe (Ioss ::Field ::TRANSIENT );
12251237 for (const auto & field : fields ) {
1226- int64_t comp_count =
1227- ons -> get_field (field ).get_component_count (Ioss ::Field ::InOut ::OUTPUT );
1228- std ::vector < double > field_data (comp_count * count );
1229- for (const auto & [ins , offset ] : ons_inputs ) {
1230- if (ins != nullptr ) {
1231- ins -> get_field_data (field , & field_data [comp_count * offset ], -1 );
1232- }
1238+ if (ons -> field_exists (field )) {
1239+ transfer_field_data_internal (in , ons , field );
12331240 }
1234- ons -> put_field_data (field , field_data );
12351241 }
12361242 }
12371243 }
@@ -1315,7 +1321,7 @@ namespace {
13151321 output_element (output_region , part_mesh );
13161322 output_nodal_nodeset_fields (output_region , part_mesh , interFace );
13171323 if (!interFace .omit_nodesets ()) {
1318- output_nset (output_region );
1324+ output_nset (output_region , part_mesh );
13191325 }
13201326 if (!interFace .omit_sidesets ()) {
13211327 output_sset (output_region , part_mesh );
@@ -1488,7 +1494,8 @@ namespace {
14881494 return error ;
14891495 }
14901496
1491- bool define_nset_fields (const Ioss ::Region & output_region , const StringIdVector & variable_list )
1497+ bool define_nset_fields (const Ioss ::Region & output_region , const RegionVector & part_mesh ,
1498+ const StringIdVector & variable_list )
14921499 {
14931500 bool error = false;
14941501 // Nodeset fields...
@@ -1499,30 +1506,26 @@ namespace {
14991506 bool subsetting_fields = !variable_list .empty () && variable_list [0 ].first != "all" ;
15001507 Ioss ::NameList defined_fields ;
15011508
1502- const auto & output_nodesets = output_region .get_nodesets ();
1503- if (output_nodesets .empty ()) {
1504- return error ;
1505- }
1506-
1507- for (const auto & ons : output_nodesets ) {
1508- if (output_input_map .find (ons ) != output_input_map .end ()) {
1509- const auto & ons_inputs = output_input_map [ons ];
1510- if (!ons_inputs .empty () && (ons_inputs [0 ].first != nullptr && ons_inputs [0 ].second != 0 )) {
1511- int64_t count = ons -> entity_count ();
1512- const auto & [ins , offset ] = ons_inputs [0 ];
1513- if (ins != nullptr) {
1514- // Here we assume that the nodeset fields are the same on all parts if combining
1515- // nodesets
1516- size_t id = ins -> get_property ("id" ).get_int ();
1517- Ioss ::NameList fields = ins -> field_describe (Ioss ::Field ::TRANSIENT );
1518- for (const auto & field_name : fields ) {
1519- if (valid_variable (field_name , id , variable_list )) {
1520- Ioss ::Field field = ins -> get_field (field_name );
1521- field .reset_count (count );
1522- ons -> field_add (std ::move (field ));
1523- if (subsetting_fields ) {
1524- defined_fields .push_back (field_name );
1525- }
1509+ for (const auto & pm : part_mesh ) {
1510+ const Ioss ::NodeSetContainer & ins = pm -> get_nodesets ();
1511+ for (const auto & in : ins ) {
1512+ if (!entity_is_omitted (in )) {
1513+ std ::string name = pm -> name () + "_" + in -> name ();
1514+ Ioss ::NodeSet * ons = output_region .get_nodeset (name );
1515+ if (ons == nullptr ) {
1516+ name = in -> name ();
1517+ ons = output_region .get_nodeset (name );
1518+ }
1519+ SMART_ASSERT (ons != nullptr )(name );
1520+
1521+ size_t id = in -> get_property ("id" ).get_int ();
1522+ Ioss ::NameList fields = in -> field_describe (Ioss ::Field ::TRANSIENT );
1523+ for (const auto & field_name : fields ) {
1524+ if (valid_variable (field_name , id , variable_list )) {
1525+ Ioss ::Field field = in -> get_field (field_name );
1526+ ons -> field_add (std ::move (field ));
1527+ if (subsetting_fields ) {
1528+ defined_fields .push_back (field_name );
15261529 }
15271530 }
15281531 }
0 commit comments