Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/SCOREC/core into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
yangf4 committed Aug 15, 2018
2 parents 06df5a0 + 2fbc7af commit 0d40949
Show file tree
Hide file tree
Showing 24 changed files with 494 additions and 67 deletions.
7 changes: 7 additions & 0 deletions apf/apf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,13 @@ Field* createUserField(Mesh* m, const char* name, int valueType, FieldShape* s,
return makeField(m, name, valueType, 0, s, new UserData(f));
}

void updateUserField(Field* field, Function* newFunc)
{
UserData* ud = dynamic_cast<UserData*>(field->getData());
// ud will be null if the data is not user data
if (ud) ud->setFunction(newFunc);
}

void copyData(Field* to, Field* from)
{
copyFieldData(from->getData(), to->getData());
Expand Down
18 changes: 13 additions & 5 deletions apf/apf.h
Original file line number Diff line number Diff line change
Expand Up @@ -668,14 +668,22 @@ struct Function
virtual void eval(MeshEntity* e, double* result) = 0;
};

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

/* \brief update the analytic function from a user field
* \details this field updates the apf::Function which the UserField refers to
*/
void updateUserField(Field* field, Function* newFunc);

/** \brief Compute a nodal gradient field from a nodal input field
\details given a nodal field, compute approximate nodal gradient
values by giving each node a volume-weighted average of the
Expand Down
8 changes: 8 additions & 0 deletions apf/apfArrayData.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ class ArrayDataOf : public FieldDataOf<T>
T* getDataArray() {
return this->dataArray;
}
virtual FieldData* clone() {
//FieldData* newData = new TagDataOf<double>();
FieldData* newData = new ArrayDataOf<T>();
newData->init(this->field);
copyFieldData(static_cast<FieldDataOf<T>*>(newData),
static_cast<FieldDataOf<T>*>(this->field->getData()));
return newData;
}

private:
/* data variables go here */
Expand Down
111 changes: 107 additions & 4 deletions apf/apfConvert.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "apfNumbering.h"
#include <map>
#include <pcu_util.h>
#include <iostream>
#include <cstdlib>

namespace apf {

Expand All @@ -31,6 +33,9 @@ class Converter
convertFields();
convertNumberings();
convertGlobalNumberings();
// this must be called after anything that might create tags e.g. fields
// or numberings to avoid problems with tag duplication
convertTags();
outMesh->acceptChanges();
}
ModelEntity* getNewModelFromOld(ModelEntity* oldC)
Expand Down Expand Up @@ -210,6 +215,48 @@ class Converter
}
}
}
void convertTag(Mesh* inMesh, MeshTag* in, Mesh* outMesh, MeshTag* out)
{
for (int d = 0; d <= 3; ++d) {
int tagType = inMesh->getTagType(in);
int tagSize = inMesh->getTagSize(in);
PCU_DEBUG_ASSERT(tagType == outMesh->getTagType(out));
PCU_DEBUG_ASSERT(tagSize == outMesh->getTagSize(out));
MeshIterator* it = inMesh->begin(d);
MeshEntity* e;
while ((e = inMesh->iterate(it))) {
if(inMesh->hasTag(e, in)) {
// these initializations cannot go into the cases due to compiler
// warnings on gcc 7.3.0
double* dblData;
int* intData;
long* lngData;
switch (tagType) {
case apf::Mesh::DOUBLE:
dblData = new double[tagSize];
inMesh->getDoubleTag(e, in, dblData);
outMesh->setDoubleTag(newFromOld[e], out, dblData);
break;
case apf::Mesh::INT:
intData = new int[tagSize];
inMesh->getIntTag(e, in, intData);
outMesh->setIntTag(newFromOld[e], out, intData);
break;
case apf::Mesh::LONG:
lngData = new long[tagSize];
inMesh->getLongTag(e, in, lngData);
outMesh->setLongTag(newFromOld[e], out, lngData);
break;
default:
std::cerr << "Tried to convert unknown tag type\n";
abort();
break;
}
}
}
inMesh->end(it);
}
}
void convertFields()
{
for (int i = 0; i < inMesh->countFields(); ++i) {
Expand All @@ -222,20 +269,76 @@ class Converter
{
for (int i = 0; i < inMesh->countNumberings(); ++i) {
Numbering* in = inMesh->getNumbering(i);
Numbering* out = createNumbering(outMesh,
getName(in), getShape(in), countComponents(in));
Numbering* out;
if (getField(in)) {
// here we assume that the fields have already been copied into the
// mesh
Field* outField = outMesh->findField(getName(getField(in)));
PCU_DEBUG_ASSERT(outField);
out = createNumbering(outField);
}
else {
out = createNumbering(outMesh, getName(in), getShape(in),
countComponents(in));
}
convertNumbering(in, out);
}
}
void convertGlobalNumberings()
{
for (int i = 0; i < inMesh->countGlobalNumberings(); ++i) {
GlobalNumbering* in = inMesh->getGlobalNumbering(i);
GlobalNumbering* out = createGlobalNumbering(outMesh,
getName(in), getShape(in), countComponents(in));
GlobalNumbering* out;
if (getField(in)) {
// here we assume that the fields have already been copied into the
// mesh
Field* outField = outMesh->findField(getName(getField(in)));
PCU_DEBUG_ASSERT(outField);
out = createGlobalNumbering(outField);
}
else {
out = createGlobalNumbering(outMesh, getName(in), getShape(in),
countComponents(in));
}
convertGlobalNumbering(in, out);
}
}
void convertTags()
{
DynamicArray<MeshTag*> tags;
inMesh->getTags(tags);
for (std::size_t i = 0; i < tags.getSize(); ++i) {
apf::MeshTag* in = tags[i];
PCU_DEBUG_ASSERT(in);
// create a new tag on the outMesh
int tagType = inMesh->getTagType(in);
int tagSize = inMesh->getTagSize(in);
const char* tagName = inMesh->getTagName(in);
PCU_DEBUG_ASSERT(tagName);
// need to make sure that the tag wasn't already created by a field or
// numbering
if (!outMesh->findTag(tagName)) {
apf::MeshTag* out = NULL;
switch (tagType) {
case apf::Mesh::DOUBLE:
out = outMesh->createDoubleTag(tagName, tagSize);
break;
case apf::Mesh::INT:
out = outMesh->createIntTag(tagName, tagSize);
break;
case apf::Mesh::LONG:
out = outMesh->createLongTag(tagName, tagSize);
break;
default:
std::cerr << "Tried to convert unknown tag type\n";
abort();
}
PCU_DEBUG_ASSERT(out);
// copy the tag on the inMesh to the outMesh
convertTag(inMesh, in, outMesh, out);
}
}
}
void convertQuadratic()
{
if (inMesh->getShape() != getLagrange(2) && inMesh->getShape() != getSerendipity())
Expand Down
8 changes: 8 additions & 0 deletions apf/apfCoordData.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@

namespace apf {

FieldData* CoordData::clone() {
FieldData* newData = new CoordData();
newData->init(field);
copyFieldData(static_cast<FieldDataOf<double>*>(newData),
static_cast<FieldDataOf<double>*>(field->getData()));
return newData;

}
void CoordData::init(FieldBase* f)
{
FieldData::field = f;
Expand Down
1 change: 1 addition & 0 deletions apf/apfCoordData.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class CoordData : public FieldDataOf<double>
virtual void get(MeshEntity* e, double* data);
virtual void set(MeshEntity* e, double const* data);
virtual bool isFrozen() { return false; }
virtual FieldData* clone();
private:
Mesh* mesh;
FieldShape* shape;
Expand Down
5 changes: 0 additions & 5 deletions apf/apfFieldData.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ FieldData::~FieldData()
{
}

FieldData* FieldData::clone()
{
abort();
}

void FieldData::rename(const char*)
{
abort();
Expand Down
3 changes: 2 additions & 1 deletion apf/apfFieldData.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class FieldData
virtual bool hasEntity(MeshEntity* e) = 0;
virtual void removeEntity(MeshEntity* e) = 0;
virtual bool isFrozen() = 0;
virtual FieldData* clone();
virtual FieldData* clone() = 0;
virtual void rename(const char* newName);
FieldBase* getField() {return field;}
protected:
Expand Down Expand Up @@ -55,6 +55,7 @@ class FieldDataOf : public FieldData
void setNodeComponents(MeshEntity* e, int node, T const* components);
void getNodeComponents(MeshEntity* e, int node, T* components);
int getElementData(MeshEntity* entity, NewArray<T>& data);
virtual FieldData* clone()=0;
};

} //namespace apf
Expand Down
15 changes: 15 additions & 0 deletions apf/apfMesh.cc
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ bool Mesh::canSnap()
return gmi_can_eval(getModel());
}

bool Mesh::canGetClosestPoint()
{
return gmi_can_get_closest_point(getModel());
}

bool Mesh::canGetModelNormal()
{
return gmi_has_normal(getModel());
Expand Down Expand Up @@ -252,6 +257,16 @@ bool Mesh::isInClosureOf(ModelEntity* g, ModelEntity* target){
return (res == 1) ? true : false;
}

bool Mesh::isOnModel(ModelEntity* g, Vector3 p, double scale)
{
Vector3 to;
double param[2];
gmi_ent* c = (gmi_ent*)g;
gmi_closest_point(getModel(), c, &p[0], &to[0], param);
double ratio = (to - p).getLength() / scale;
return ratio < 0.001;
}

void Mesh::getPoint(MeshEntity* e, int node, Vector3& p)
{
getVector(coordinateField,e,node,p);
Expand Down
4 changes: 4 additions & 0 deletions apf/apfMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ class Mesh
ModelEntity* findModelEntity(int type, int tag);
/** \brief return true if the geometric model supports snapping */
bool canSnap();
/** \brief return true if the geometric model supports get closest point */
bool canGetClosestPoint();
/** \brief return true if the geometric model supports normal computation */
bool canGetModelNormal();
/** \brief evaluate parametric coordinate (p) as a spatial point (x) */
Expand All @@ -310,6 +312,8 @@ class Mesh
Vector3 const& param, Vector3& x);
/** \brief checks if g is in the closure of the target */
bool isInClosureOf(ModelEntity* g, ModelEntity* target);
/** \brief checks if p is on model g */
bool isOnModel(ModelEntity* g, Vector3 p, double scale);
/** \brief get the distribution of the mesh's coordinate field */
FieldShape* getShape() const;
/** \brief get the mesh's coordinate field */
Expand Down
10 changes: 9 additions & 1 deletion apf/apfNumbering.cc
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,14 @@ GlobalNumbering* createGlobalNumbering(
return n;
}

GlobalNumbering* createGlobalNumbering(Field* f)
{
GlobalNumbering* n = new GlobalNumbering();
n->init(f);
f->getMesh()->addGlobalNumbering(n);
return n;
}

FieldShape* getShape(GlobalNumbering* n)
{
return n->getShape();
Expand Down Expand Up @@ -601,5 +609,5 @@ void getNodes(GlobalNumbering* n, DynamicArray<Node>& nodes)
getFieldNodes(n,nodes);
}

Field* getField(GlobalNumbering* n) { return n->getField(); }
}

8 changes: 8 additions & 0 deletions apf/apfNumbering.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ GlobalNumbering* createGlobalNumbering(
const char* name,
FieldShape* shape,
int components=1);

/** \brief Create a Numbering of degrees of freedom of a Field.
*/
GlobalNumbering* createGlobalNumbering(Field* f);

FieldShape* getShape(GlobalNumbering* n);
const char* getName(GlobalNumbering* n);
/** \brief get the mesh associated with a global numbering */
Expand All @@ -176,6 +181,9 @@ long getNumber(GlobalNumbering* n, MeshEntity* e, int node, int component=0);
/** \brief get an element's global node numbers */
int getElementNumbers(GlobalNumbering* n, MeshEntity* e,
NewArray<long>& numbers);
/** \brief get the field being numbered
*/
Field* getField(GlobalNumbering* n);

/** \brief converts a local numbering into a global numbering.
\param destroy Should the input Numbering* be destroyed?
Expand Down
9 changes: 9 additions & 0 deletions apf/apfUserData.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,13 @@ bool UserData::isFrozen()
return false;
}

FieldData* UserData::clone()
{
FieldData* newData = new UserData(function);
newData->init(field);
copyFieldData(static_cast<FieldDataOf<double>*>(newData),
static_cast<FieldDataOf<double>*>(field->getData()));
return newData;
}

}
8 changes: 6 additions & 2 deletions apf/apfUserData.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ struct UserData : public FieldDataOf<double>
void get(MeshEntity* e, double* data);
void set(MeshEntity* e, double const* data);
bool isFrozen();
virtual FieldData* clone();
// using const * const gives an error on gcc/7.3.0 because the return is an
// r-value which cannot be modified anyways
Function const* getFunction() const { return function; }
void setFunction(Function* func) { function = func; }
private:
Function* function;
};

}

#endif


2 changes: 1 addition & 1 deletion crv/crvBezier.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ void getGregoryBlendedTransformationCoefficients(int blend, int type,
apf::NewArray<double>& c);

/** \brief a per entity version of above */
void snapToInterpolate(apf::Mesh2* m, apf::MeshEntity* e);
void snapToInterpolate(apf::Mesh2* m, apf::MeshEntity* e, bool isNew = false);

/** \brief compute the matrix to transform between Bezier and Lagrange Points
\details this is a support function, not actual ever needed.
Expand Down
Loading

0 comments on commit 0d40949

Please sign in to comment.