Skip to content

Commit ecc64db

Browse files
Nightly Botcwsmith
Nightly Bot
authored andcommitted
Merging develop into master
2 parents 4c4ba24 + 0d40949 commit ecc64db

16 files changed

+323
-19
lines changed

Diff for: apf/apf.cc

+7
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,13 @@ Field* createUserField(Mesh* m, const char* name, int valueType, FieldShape* s,
463463
return makeField(m, name, valueType, 0, s, new UserData(f));
464464
}
465465

466+
void updateUserField(Field* field, Function* newFunc)
467+
{
468+
UserData* ud = dynamic_cast<UserData*>(field->getData());
469+
// ud will be null if the data is not user data
470+
if (ud) ud->setFunction(newFunc);
471+
}
472+
466473
void copyData(Field* to, Field* from)
467474
{
468475
copyFieldData(from->getData(), to->getData());

Diff for: apf/apf.h

+13-5
Original file line numberDiff line numberDiff line change
@@ -668,14 +668,22 @@ struct Function
668668
virtual void eval(MeshEntity* e, double* result) = 0;
669669
};
670670

671-
/** \brief Create a Field from a user's analytic function.
672-
\details This field will use no memory, has values on all
673-
nodes, and calls the user Function for all value queries.
674-
Writing to this field does nothing.
675-
*/
671+
/* \brief Create a Field from a user's analytic function.
672+
* \details This field will use no memory, has values on all
673+
* nodes, and calls the user Function for all value queries.
674+
* Writing to this field does nothing.
675+
* \warning if you copy the mesh with apf::convert you may want to use
676+
* apf::updateUserField to update function that this field refers to. This is
677+
* extremely important if the analytic function you use references user fields.
678+
*/
676679
Field* createUserField(Mesh* m, const char* name, int valueType, FieldShape* s,
677680
Function* f);
678681

682+
/* \brief update the analytic function from a user field
683+
* \details this field updates the apf::Function which the UserField refers to
684+
*/
685+
void updateUserField(Field* field, Function* newFunc);
686+
679687
/** \brief Compute a nodal gradient field from a nodal input field
680688
\details given a nodal field, compute approximate nodal gradient
681689
values by giving each node a volume-weighted average of the

Diff for: apf/apfArrayData.cc

+8
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ class ArrayDataOf : public FieldDataOf<T>
7979
T* getDataArray() {
8080
return this->dataArray;
8181
}
82+
virtual FieldData* clone() {
83+
//FieldData* newData = new TagDataOf<double>();
84+
FieldData* newData = new ArrayDataOf<T>();
85+
newData->init(this->field);
86+
copyFieldData(static_cast<FieldDataOf<T>*>(newData),
87+
static_cast<FieldDataOf<T>*>(this->field->getData()));
88+
return newData;
89+
}
8290

8391
private:
8492
/* data variables go here */

Diff for: apf/apfConvert.cc

+107-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "apfNumbering.h"
88
#include <map>
99
#include <pcu_util.h>
10+
#include <iostream>
11+
#include <cstdlib>
1012

1113
namespace 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())

Diff for: apf/apfCoordData.cc

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@
1111

1212
namespace apf {
1313

14+
FieldData* CoordData::clone() {
15+
FieldData* newData = new CoordData();
16+
newData->init(field);
17+
copyFieldData(static_cast<FieldDataOf<double>*>(newData),
18+
static_cast<FieldDataOf<double>*>(field->getData()));
19+
return newData;
20+
21+
}
1422
void CoordData::init(FieldBase* f)
1523
{
1624
FieldData::field = f;

Diff for: apf/apfCoordData.h

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class CoordData : public FieldDataOf<double>
3333
virtual void get(MeshEntity* e, double* data);
3434
virtual void set(MeshEntity* e, double const* data);
3535
virtual bool isFrozen() { return false; }
36+
virtual FieldData* clone();
3637
private:
3738
Mesh* mesh;
3839
FieldShape* shape;

Diff for: apf/apfFieldData.cc

-5
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@ FieldData::~FieldData()
1010
{
1111
}
1212

13-
FieldData* FieldData::clone()
14-
{
15-
abort();
16-
}
17-
1813
void FieldData::rename(const char*)
1914
{
2015
abort();

Diff for: apf/apfFieldData.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class FieldData
2222
virtual bool hasEntity(MeshEntity* e) = 0;
2323
virtual void removeEntity(MeshEntity* e) = 0;
2424
virtual bool isFrozen() = 0;
25-
virtual FieldData* clone();
25+
virtual FieldData* clone() = 0;
2626
virtual void rename(const char* newName);
2727
FieldBase* getField() {return field;}
2828
protected:
@@ -55,6 +55,7 @@ class FieldDataOf : public FieldData
5555
void setNodeComponents(MeshEntity* e, int node, T const* components);
5656
void getNodeComponents(MeshEntity* e, int node, T* components);
5757
int getElementData(MeshEntity* entity, NewArray<T>& data);
58+
virtual FieldData* clone()=0;
5859
};
5960

6061
} //namespace apf

Diff for: apf/apfNumbering.cc

+9-1
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,14 @@ GlobalNumbering* createGlobalNumbering(
461461
return n;
462462
}
463463

464+
GlobalNumbering* createGlobalNumbering(Field* f)
465+
{
466+
GlobalNumbering* n = new GlobalNumbering();
467+
n->init(f);
468+
f->getMesh()->addGlobalNumbering(n);
469+
return n;
470+
}
471+
464472
FieldShape* getShape(GlobalNumbering* n)
465473
{
466474
return n->getShape();
@@ -601,5 +609,5 @@ void getNodes(GlobalNumbering* n, DynamicArray<Node>& nodes)
601609
getFieldNodes(n,nodes);
602610
}
603611

612+
Field* getField(GlobalNumbering* n) { return n->getField(); }
604613
}
605-

Diff for: apf/apfNumbering.h

+8
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@ GlobalNumbering* createGlobalNumbering(
159159
const char* name,
160160
FieldShape* shape,
161161
int components=1);
162+
163+
/** \brief Create a Numbering of degrees of freedom of a Field.
164+
*/
165+
GlobalNumbering* createGlobalNumbering(Field* f);
166+
162167
FieldShape* getShape(GlobalNumbering* n);
163168
const char* getName(GlobalNumbering* n);
164169
/** \brief get the mesh associated with a global numbering */
@@ -176,6 +181,9 @@ long getNumber(GlobalNumbering* n, MeshEntity* e, int node, int component=0);
176181
/** \brief get an element's global node numbers */
177182
int getElementNumbers(GlobalNumbering* n, MeshEntity* e,
178183
NewArray<long>& numbers);
184+
/** \brief get the field being numbered
185+
*/
186+
Field* getField(GlobalNumbering* n);
179187

180188
/** \brief converts a local numbering into a global numbering.
181189
\param destroy Should the input Numbering* be destroyed?

Diff for: apf/apfUserData.cc

+9
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,13 @@ bool UserData::isFrozen()
4242
return false;
4343
}
4444

45+
FieldData* UserData::clone()
46+
{
47+
FieldData* newData = new UserData(function);
48+
newData->init(field);
49+
copyFieldData(static_cast<FieldDataOf<double>*>(newData),
50+
static_cast<FieldDataOf<double>*>(field->getData()));
51+
return newData;
52+
}
53+
4554
}

Diff for: apf/apfUserData.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,15 @@ struct UserData : public FieldDataOf<double>
2121
void get(MeshEntity* e, double* data);
2222
void set(MeshEntity* e, double const* data);
2323
bool isFrozen();
24+
virtual FieldData* clone();
25+
// using const * const gives an error on gcc/7.3.0 because the return is an
26+
// r-value which cannot be modified anyways
27+
Function const* getFunction() const { return function; }
28+
void setFunction(Function* func) { function = func; }
29+
private:
2430
Function* function;
2531
};
2632

2733
}
2834

2935
#endif
30-
31-

Diff for: cmake/FindSimModSuite.cmake

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ string(REGEX REPLACE
7474
"${SIM_VERSION}")
7575

7676
set(MIN_VALID_SIM_VERSION 11.0.170826)
77-
set(MAX_VALID_SIM_VERSION 12.0.180713)
77+
set(MAX_VALID_SIM_VERSION 12.0.180811)
7878
if( (SIM_DOT_VERSION VERSION_LESS MIN_VALID_SIM_VERSION) OR
7979
(SIM_DOT_VERSION VERSION_GREATER MAX_VALID_SIM_VERSION) )
8080
MESSAGE(FATAL_ERROR

Diff for: test/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ util_exe_func(describe describe.cc)
2020
test_exe_func(quality quality.cc)
2121
test_exe_func(writeVtxPtn writeVtxPtn.cc)
2222
test_exe_func(verify_2nd_order_shapes verify_2nd_order_shapes.cc)
23+
test_exe_func(verify_convert verify_convert.cc)
2324

2425
# Geometric model utilities
2526
if(ENABLE_SIMMETRIX)

Diff for: test/testing.cmake

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ mpi_test(integrate 1 ./integrate)
3333
mpi_test(qr_test 1 ./qr)
3434
mpi_test(base64 1 ./base64)
3535
mpi_test(tensor_test 1 ./tensor)
36+
mpi_test(verify_convert 1 ./verify_convert)
3637

3738
if(ENABLE_SIMMETRIX)
3839
mpi_test(in_closure_of 1

0 commit comments

Comments
 (0)