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