Skip to content

Commit 0d40949

Browse files
committed
Merge branch 'develop' of https://github.com/SCOREC/core into develop
2 parents 06df5a0 + 2fbc7af commit 0d40949

24 files changed

+494
-67
lines changed

apf/apf.cc

Lines changed: 7 additions & 0 deletions
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());

apf/apf.h

Lines changed: 13 additions & 5 deletions
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

apf/apfArrayData.cc

Lines changed: 8 additions & 0 deletions
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 */

apf/apfConvert.cc

Lines changed: 107 additions & 4 deletions
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())

apf/apfCoordData.cc

Lines changed: 8 additions & 0 deletions
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;

apf/apfCoordData.h

Lines changed: 1 addition & 0 deletions
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;

apf/apfFieldData.cc

Lines changed: 0 additions & 5 deletions
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();

apf/apfFieldData.h

Lines changed: 2 additions & 1 deletion
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

apf/apfMesh.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,11 @@ bool Mesh::canSnap()
175175
return gmi_can_eval(getModel());
176176
}
177177

178+
bool Mesh::canGetClosestPoint()
179+
{
180+
return gmi_can_get_closest_point(getModel());
181+
}
182+
178183
bool Mesh::canGetModelNormal()
179184
{
180185
return gmi_has_normal(getModel());
@@ -252,6 +257,16 @@ bool Mesh::isInClosureOf(ModelEntity* g, ModelEntity* target){
252257
return (res == 1) ? true : false;
253258
}
254259

260+
bool Mesh::isOnModel(ModelEntity* g, Vector3 p, double scale)
261+
{
262+
Vector3 to;
263+
double param[2];
264+
gmi_ent* c = (gmi_ent*)g;
265+
gmi_closest_point(getModel(), c, &p[0], &to[0], param);
266+
double ratio = (to - p).getLength() / scale;
267+
return ratio < 0.001;
268+
}
269+
255270
void Mesh::getPoint(MeshEntity* e, int node, Vector3& p)
256271
{
257272
getVector(coordinateField,e,node,p);

apf/apfMesh.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,8 @@ class Mesh
285285
ModelEntity* findModelEntity(int type, int tag);
286286
/** \brief return true if the geometric model supports snapping */
287287
bool canSnap();
288+
/** \brief return true if the geometric model supports get closest point */
289+
bool canGetClosestPoint();
288290
/** \brief return true if the geometric model supports normal computation */
289291
bool canGetModelNormal();
290292
/** \brief evaluate parametric coordinate (p) as a spatial point (x) */
@@ -310,6 +312,8 @@ class Mesh
310312
Vector3 const& param, Vector3& x);
311313
/** \brief checks if g is in the closure of the target */
312314
bool isInClosureOf(ModelEntity* g, ModelEntity* target);
315+
/** \brief checks if p is on model g */
316+
bool isOnModel(ModelEntity* g, Vector3 p, double scale);
313317
/** \brief get the distribution of the mesh's coordinate field */
314318
FieldShape* getShape() const;
315319
/** \brief get the mesh's coordinate field */

0 commit comments

Comments
 (0)