77#include  " apfNumbering.h" 
88#include  < map> 
99#include  < pcu_util.h> 
10+ #include  < iostream> 
11+ #include  < cstdlib> 
1012
1113namespace  apf  {
1214
@@ -31,6 +33,9 @@ class Converter
3133      convertFields ();
3234      convertNumberings ();
3335      convertGlobalNumberings ();
36+       //  this must be called after anything that might create tags e.g. fields
37+       //  or numberings to avoid problems with tag duplication
38+       convertTags ();
3439      outMesh->acceptChanges ();
3540    }
3641    ModelEntity* getNewModelFromOld (ModelEntity* oldC)
@@ -210,6 +215,48 @@ class Converter
210215        }
211216      }
212217    }
218+     void  convertTag (Mesh* inMesh, MeshTag* in, Mesh* outMesh, MeshTag* out)
219+     {
220+       for  (int  d = 0 ; d <= 3 ; ++d) {
221+         int  tagType = inMesh->getTagType (in);
222+         int  tagSize = inMesh->getTagSize (in);
223+         PCU_DEBUG_ASSERT (tagType == outMesh->getTagType (out));
224+         PCU_DEBUG_ASSERT (tagSize == outMesh->getTagSize (out));
225+         MeshIterator* it = inMesh->begin (d);
226+         MeshEntity* e;
227+         while  ((e = inMesh->iterate(it))) {
228+           if (inMesh->hasTag (e, in)) {
229+             //  these initializations cannot go into the cases due to compiler
230+             //  warnings on gcc 7.3.0
231+             double * dblData;
232+             int * intData;
233+             long * lngData; 
234+             switch  (tagType) {
235+               case  apf::Mesh::DOUBLE:
236+                 dblData = new  double [tagSize];
237+                 inMesh->getDoubleTag (e, in, dblData);
238+                 outMesh->setDoubleTag (newFromOld[e], out, dblData);
239+                 break ;
240+               case  apf::Mesh::INT:
241+                 intData = new  int [tagSize];
242+                 inMesh->getIntTag (e, in, intData);
243+                 outMesh->setIntTag (newFromOld[e], out, intData);
244+                 break ;
245+               case  apf::Mesh::LONG:
246+                 lngData = new  long [tagSize];
247+                 inMesh->getLongTag (e, in, lngData);
248+                 outMesh->setLongTag (newFromOld[e], out, lngData);
249+                 break ;
250+               default :
251+                 std::cerr << " Tried to convert unknown tag type\n "  ;
252+                 abort ();
253+                 break ;
254+             }
255+         }
256+         }
257+         inMesh->end (it);
258+       }
259+     }
213260    void  convertFields ()
214261    {
215262      for  (int  i = 0 ; i < inMesh->countFields (); ++i) {
@@ -222,20 +269,76 @@ class Converter
222269    {
223270      for  (int  i = 0 ; i < inMesh->countNumberings (); ++i) {
224271        Numbering* in = inMesh->getNumbering (i);
225-         Numbering* out = createNumbering (outMesh,
226-             getName (in), getShape (in), countComponents (in));
272+         Numbering* out;
273+         if  (getField (in)) {
274+           //  here we assume that the fields have already been copied into the
275+           //  mesh
276+           Field* outField = outMesh->findField (getName (getField (in)));
277+           PCU_DEBUG_ASSERT (outField);
278+           out = createNumbering (outField);
279+         }
280+         else  {
281+           out = createNumbering (outMesh, getName (in), getShape (in),
282+                                 countComponents (in));
283+         }
227284        convertNumbering (in, out);
228285      }
229286    }
230287    void  convertGlobalNumberings ()
231288    {
232289      for  (int  i = 0 ; i < inMesh->countGlobalNumberings (); ++i) {
233290        GlobalNumbering* in = inMesh->getGlobalNumbering (i);
234-         GlobalNumbering* out = createGlobalNumbering (outMesh,
235-             getName (in), getShape (in), countComponents (in));
291+         GlobalNumbering* out;
292+         if  (getField (in)) {
293+           //  here we assume that the fields have already been copied into the
294+           //  mesh
295+           Field* outField = outMesh->findField (getName (getField (in)));
296+           PCU_DEBUG_ASSERT (outField);
297+           out = createGlobalNumbering (outField);
298+         }
299+         else  {
300+           out = createGlobalNumbering (outMesh, getName (in), getShape (in),
301+                                       countComponents (in));
302+         }
236303        convertGlobalNumbering (in, out);
237304      }
238305    }
306+     void  convertTags ()
307+     {
308+       DynamicArray<MeshTag*> tags;
309+       inMesh->getTags (tags);
310+       for  (std::size_t  i = 0 ; i < tags.getSize (); ++i) {
311+         apf::MeshTag* in = tags[i];
312+         PCU_DEBUG_ASSERT (in);
313+         //  create a new tag on the outMesh
314+         int  tagType = inMesh->getTagType (in);
315+         int  tagSize = inMesh->getTagSize (in);
316+         const  char * tagName = inMesh->getTagName (in);
317+         PCU_DEBUG_ASSERT (tagName);
318+         //  need to make sure that the tag wasn't already created by a field or
319+         //  numbering
320+         if  (!outMesh->findTag (tagName)) {
321+           apf::MeshTag* out = NULL ;
322+           switch  (tagType) {
323+             case  apf::Mesh::DOUBLE:
324+               out = outMesh->createDoubleTag (tagName, tagSize);
325+               break ;
326+             case  apf::Mesh::INT:
327+               out = outMesh->createIntTag (tagName, tagSize);
328+               break ;
329+             case  apf::Mesh::LONG:
330+               out = outMesh->createLongTag (tagName, tagSize);
331+               break ;
332+             default :
333+               std::cerr << " Tried to convert unknown tag type\n "  ;
334+               abort ();
335+           }
336+           PCU_DEBUG_ASSERT (out);
337+           //  copy the tag on the inMesh to the outMesh
338+           convertTag (inMesh, in, outMesh, out);
339+         }
340+       }
341+     }
239342    void  convertQuadratic ()
240343    {
241344      if  (inMesh->getShape () != getLagrange (2 ) && inMesh->getShape () != getSerendipity ())
0 commit comments