Skip to content

Commit b31683d

Browse files
Nightly Botcwsmith
authored andcommitted
Merging develop into master
2 parents d9bec9f + 8521d59 commit b31683d

15 files changed

+482
-123
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,11 @@ For more information, start at our
5353

5454
* If you have a usage question or have found a bug please post an [issue](https://github.com/SCOREC/core/issues).
5555
* Otherwise, email [Cameron Smith](https://www.scorec.rpi.edu/~cwsmith) and [email protected].
56+
57+
### Citing PUMI
58+
59+
If you use these tools, please cite the following paper:
60+
61+
Daniel A. Ibanez, E. Seegyoung Seol, Cameron W. Smith, and Mark S. Shephard. 2016. PUMI: Parallel Unstructured Mesh Infrastructure. ACM Trans. Math. Softw. 42, 3, Article 17 (May 2016), 28 pages. DOI: https://doi.org/10.1145/2814935
62+
63+
We would be happy to provide feedback on journal submissions using PUMI prior to publication.

ma/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ set(SOURCES
2525
maLayerCollapse.cc
2626
maMatch.cc
2727
maSolutionTransfer.cc
28+
maSolutionTransferHelper.cc
2829
maSnap.cc
2930
maEdgeSwap.cc
3031
maShape.cc

ma/maAdapt.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ Cavity::Cavity()
353353
adapter = 0;
354354
solutionTransfer = 0;
355355
shape = 0;
356+
shouldTransferSizeField = false;
356357
}
357358

358359
void Cavity::init(Adapt* a)
@@ -368,6 +369,8 @@ void Cavity::init(Adapt* a)
368369
shouldTransfer = true;
369370
if (shape->hasNodesOn(d))
370371
shouldFit = true;
372+
if (adapter->sizeField->hasNodesOn(d))
373+
shouldTransferSizeField = true;
371374
}
372375
}
373376

@@ -409,6 +412,12 @@ void Cavity::transfer(EntityArray& oldElements)
409412
newEntities.retrieve(a);
410413
solutionTransfer->onCavity(oldElements,a);
411414
}
415+
if (shouldTransferSizeField)
416+
{
417+
EntityArray a;
418+
newEntities.retrieve(a);
419+
adapter->sizeField->onCavity(oldElements,a);
420+
}
412421
}
413422

414423
void Cavity::fit(EntityArray& oldElements)

ma/maAdapt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ class Cavity
137137
void fit(EntityArray& oldElements);
138138
bool shouldTransfer;
139139
bool shouldFit;
140+
bool shouldTransferSizeField;
140141
private:
141142
Adapt* adapter;
142143
SolutionTransfer* solutionTransfer;

ma/maFaceSplit.cc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,22 @@ void FaceSplit::cancel()
123123
void FaceSplit::transfer()
124124
{
125125
Mesh* m = adapter->mesh;
126+
int td;
127+
td = adapter->shape->getTransferDimension();
128+
for (int d = td; d <= m->getDimension(); ++d)
129+
for (size_t i = 0; i < toSplit[d].getSize(); ++i)
130+
adapter->shape->onRefine(toSplit[d][i], newEntities[d][i]);
131+
126132
SolutionTransfer* st = adapter->solutionTransfer;
127-
int td = st->getTransferDimension();
133+
td = st->getTransferDimension();
128134
for (int d = td; d <= m->getDimension(); ++d)
129135
for (size_t i = 0; i < toSplit[d].getSize(); ++i)
130136
st->onRefine(toSplit[d][i], newEntities[d][i]);
131137

132-
td = adapter->shape->getTransferDimension();
138+
td = adapter->sizeField->getTransferDimension();
133139
for (int d = td; d <= m->getDimension(); ++d)
134140
for (size_t i = 0; i < toSplit[d].getSize(); ++i)
135-
adapter->shape->onRefine(toSplit[d][i], newEntities[d][i]);
141+
adapter->sizeField->onRefine(toSplit[d][i], newEntities[d][i]);
136142
}
137143

138144
void FaceSplit::destroyOldElements()

ma/maRefine.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,13 @@ void transferElements(Refine* r)
357357
for (size_t i=0; i < r->toSplit[d].getSize(); ++i)
358358
st->onRefine(r->toSplit[d][i],r->newEntities[d][i]);
359359
}
360+
{
361+
SizeField* sf = a->sizeField;
362+
int td = sf->getTransferDimension();
363+
for (int d = td; d <= m->getDimension(); ++d)
364+
for (size_t i=0; i < r->toSplit[d].getSize(); ++i)
365+
sf->onRefine(r->toSplit[d][i],r->newEntities[d][i]);
366+
}
360367
}
361368

362369
void forgetNewEntities(Refine* r)

ma/maSize.cc

Lines changed: 97 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*******************************************************************************/
1010
#include <PCU.h>
1111
#include "maSize.h"
12+
#include "maSolutionTransferHelper.h"
1213
#include "apfMatrix.h"
1314
#include <apfShape.h>
1415
#include <cstdlib>
@@ -20,6 +21,32 @@ SizeField::~SizeField()
2021
{
2122
}
2223

24+
void SizeField::onRefine(Entity*, EntityArray&)
25+
{
26+
PCU_ALWAYS_ASSERT_VERBOSE(0,
27+
"unimplemented onRefine was called for a size-field!");
28+
}
29+
30+
void SizeField::onCavity(EntityArray&, EntityArray&)
31+
{
32+
PCU_ALWAYS_ASSERT_VERBOSE(0,
33+
"unimplemented onCavity was called for a size-field!");
34+
}
35+
36+
int SizeField::getTransferDimension()
37+
{
38+
// By default there should be no size_field transfer.
39+
// This is used in a loop to get the lowest dimension
40+
// entities that require transfer. So something bigger
41+
// than mesh dimension will ignore that loop
42+
return 4;
43+
}
44+
45+
bool SizeField::hasNodesOn(int)
46+
{
47+
return false;
48+
}
49+
2350
IdentitySizeField::IdentitySizeField(Mesh* m):
2451
mesh(m)
2552
{
@@ -96,14 +123,14 @@ static void orthogonalizeR(Matrix& R)
96123

97124
static void orthogonalEigenDecompForSymmetricMatrix(Matrix const& A, Vector& v, Matrix& R)
98125
{
99-
/* here we assume A to be real symmetric 3x3 matrix,
126+
/* here we assume A to be real symmetric 3x3 matrix,
100127
* we should be able to get 3 orthogonal eigen vectors
101128
* we also normalize the eigen vectors */
102129
double eigenValues[3];
103130
Vector eigenVectors[3];
104-
131+
105132
apf::eigen(A, eigenVectors, eigenValues);
106-
133+
107134
Matrix RT(eigenVectors); // eigen vectors are stored in the rows of RT
108135

109136
RT[0] = RT[0].normalize();
@@ -132,8 +159,8 @@ static double parentMeasure[apf::Mesh::TYPES] =
132159
class SizeFieldIntegrator : public apf::Integrator
133160
{
134161
public:
135-
SizeFieldIntegrator(SizeField* sF):
136-
Integrator(2),
162+
SizeFieldIntegrator(SizeField* sF, int order):
163+
Integrator(order),
137164
measurement(0),
138165
sizeField(sF),
139166
meshElement(0),
@@ -181,7 +208,8 @@ struct MetricSizeField : public SizeField
181208
{
182209
double measure(Entity* e)
183210
{
184-
SizeFieldIntegrator sFI(this);
211+
SizeFieldIntegrator sFI(this,
212+
std::max(mesh->getShape()->getOrder(), order)+1);
185213
apf::MeshElement* me = apf::createMeshElement(mesh, e);
186214
sFI.process(me);
187215
apf::destroyMeshElement(me);
@@ -201,6 +229,7 @@ struct MetricSizeField : public SizeField
201229
return measure(e) / parentMeasure[mesh->getType(e)];
202230
}
203231
Mesh* mesh;
232+
int order; // this is the underlying sizefield order (default 1)
204233
};
205234

206235
AnisotropicFunction::~AnisotropicFunction()
@@ -337,13 +366,16 @@ struct AnisoSizeField : public MetricSizeField
337366
{
338367
AnisoSizeField()
339368
{
369+
mesh = 0;
370+
order = 1;
340371
}
341372
AnisoSizeField(Mesh* m, AnisotropicFunction* f):
342373
bothEval(f),
343374
sizesEval(&bothEval),
344375
frameEval(&bothEval)
345376
{
346377
mesh = m;
378+
order = 1;
347379
hField = apf::createUserField(m, "ma_sizes", apf::VECTOR,
348380
apf::getLagrange(1), &sizesEval);
349381
rField = apf::createUserField(m, "ma_frame", apf::MATRIX,
@@ -357,6 +389,7 @@ struct AnisoSizeField : public MetricSizeField
357389
void init(Mesh* m, apf::Field* sizes, apf::Field* frames)
358390
{
359391
mesh = m;
392+
order = apf::getShape(sizes)->getOrder();
360393
hField = sizes;
361394
rField = frames;
362395
}
@@ -424,11 +457,14 @@ struct LogAnisoSizeField : public MetricSizeField
424457
{
425458
LogAnisoSizeField()
426459
{
460+
mesh = 0;
461+
order = 1;
427462
}
428463
LogAnisoSizeField(Mesh* m, AnisotropicFunction* f):
429464
logMEval(f)
430465
{
431466
mesh = m;
467+
order = 1;
432468
logMField = apf::createUserField(m, "ma_logM", apf::MATRIX,
433469
apf::getLagrange(1), &logMEval);
434470
}
@@ -439,20 +475,34 @@ struct LogAnisoSizeField : public MetricSizeField
439475
void init(Mesh* m, apf::Field* sizes, apf::Field* frames)
440476
{
441477
mesh = m;
442-
logMField = apf::createField(m, "ma_logM", apf::MATRIX, apf::getLagrange(1));
443-
Entity* v;
444-
Iterator* it = m->begin(0);
445-
while ( (v = m->iterate(it)) ) {
446-
Vector h;
447-
Matrix f;
448-
apf::getVector(sizes, v, 0, h);
449-
apf::getMatrix(frames, v, 0, f);
450-
Vector s(log(1/h[0]/h[0]), log(1/h[1]/h[1]), log(1/h[2]/h[2]));
451-
Matrix S(s[0], 0 , 0,
452-
0 , s[1], 0,
453-
0 , 0 , s[2]);
454-
apf::setMatrix(logMField, v, 0, f * S * transpose(f));
478+
order = apf::getShape(sizes)->getOrder();
479+
logMField = apf::createField(m, "ma_logM", apf::MATRIX,
480+
apf::getShape(sizes));
481+
int dim = m->getDimension();
482+
Entity* ent;
483+
Iterator* it;
484+
for (int d = 0; d <= dim; d++) {
485+
if (!apf::getShape(logMField)->countNodesOn(apf::Mesh::simplexTypes[d]))
486+
continue;
487+
it = m->begin(d);
488+
while( (ent = m->iterate(it)) ){
489+
int type = m->getType(ent);
490+
int non = apf::getShape(logMField)->countNodesOn(type);
491+
for (int i = 0; i < non; i++) {
492+
Vector h;
493+
Matrix f;
494+
apf::getVector(sizes, ent, i, h);
495+
apf::getMatrix(frames, ent, i, f);
496+
Vector s(log(1/h[0]/h[0]), log(1/h[1]/h[1]), log(1/h[2]/h[2]));
497+
Matrix S(s[0], 0 , 0,
498+
0 , s[1], 0,
499+
0 , 0 , s[2]);
500+
apf::setMatrix(logMField, ent, i, f * S * transpose(f));
501+
}
502+
}
503+
m->end(it);
455504
}
505+
fieldVal.allocate(apf::countComponents(logMField));
456506
}
457507
void getTransform(
458508
apf::MeshElement* me,
@@ -497,6 +547,34 @@ struct LogAnisoSizeField : public MetricSizeField
497547
0,value,0,
498548
0,0,value));
499549
}
550+
void onRefine(
551+
Entity* parent,
552+
EntityArray& newEntities)
553+
{
554+
transfer(logMField, &(fieldVal[0]), 1, &parent, newEntities);
555+
}
556+
void onCavity(
557+
EntityArray& oldElements,
558+
EntityArray& newEntities)
559+
{
560+
transfer(logMField, &(fieldVal[0]),
561+
oldElements.getSize(), &(oldElements[0]), newEntities);
562+
}
563+
int getTransferDimension()
564+
{
565+
int transferDimension = 4;
566+
for (int d = 1; d <=3; d++)
567+
if (hasNodesOn(d)) {
568+
transferDimension = d;
569+
break;
570+
}
571+
return transferDimension;
572+
}
573+
bool hasNodesOn(int dimension)
574+
{
575+
return apf::getShape(logMField)->hasNodesIn(dimension);
576+
}
577+
apf::NewArray<double> fieldVal;
500578
apf::Field* logMField;
501579
LogMEval logMEval;
502580
};

ma/maSize.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ class SizeField
3636
Vector const& xi,
3737
Matrix& t) = 0;
3838
virtual double getWeight(Entity* e) = 0;
39+
virtual void onRefine(
40+
Entity* parent,
41+
EntityArray& newEntities);
42+
virtual void onCavity(
43+
EntityArray& oldElements,
44+
EntityArray& newEntities);
45+
virtual int getTransferDimension();
46+
virtual bool hasNodesOn(int dimension);
3947
};
4048

4149
struct IdentitySizeField : public SizeField
@@ -54,6 +62,7 @@ struct IdentitySizeField : public SizeField
5462
Matrix& t);
5563
double getWeight(Entity*);
5664
Mesh* mesh;
65+
5766
};
5867

5968
struct UniformRefiner : public IdentitySizeField

0 commit comments

Comments
 (0)