forked from SCOREC/core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapfMesh2.h
235 lines (209 loc) · 8.58 KB
/
apfMesh2.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*
* Copyright 2011 Scientific Computation Research Center
*
* This work is open source software, licensed under the terms of the
* BSD license as described in the LICENSE file in the top-level directory.
*/
#ifndef APF_MESH2_H
#define APF_MESH2_H
/** \file apfMesh2.h
\brief The APF Mesh modification interface */
#include "apfMesh.h"
#include <set>
namespace apf {
/** \brief Extended mesh interface for modification
\details this interface, which is a superset of apf::Mesh,
includes methods for mesh modification.
Not all mesh databases support this, which is why the
two classes are separated.
In this case, mesh modification means any entity creation,
deletion, changing inter-part boundary links (including
remote copies, matching, etc), and changing node coordinates. */
class Mesh2 : public Mesh
{
public:
/** \brief Set the remote copies of an entity
\details this does not affect the residence or ownership,
so users are advised to use apf::stitchMesh after calling
this function. */
virtual void setRemotes(MeshEntity* e, Copies& remotes) = 0;
/** \brief Add just one remote copy to an entity */
virtual void addRemote(MeshEntity* e, int p, MeshEntity* r) = 0;
/** \brief Remove remote copies */
virtual void clearRemotes(MeshEntity* e) = 0;
// seol
/** \brief Add just one ghost copy to an entity */
virtual void addGhost(MeshEntity* e, int p, MeshEntity* r) = 0;
virtual void deleteGhost(MeshEntity* e) = 0;
/** \brief Set the resident part set of an entity
\details this is also known as partition model classification */
virtual void setResidence(MeshEntity* e, Parts& residence) = 0;
/** \brief Set the geometric parametric coordinates for a vertex */
virtual void setParam(MeshEntity* e, Vector3 const& p) = 0;
/** \brief Just increment an iterator */
virtual void increment(MeshIterator* it) = 0;
/** \brief Return true iff the iterator points past the end */
virtual bool isDone(MeshIterator* it) = 0;
/** \brief Just dereference an iterator without incrementing it
\details this is needed by apf::CavityOp, and Simmetrix meshes
don't support the separation of dereference and increment */
virtual MeshEntity* deref(MeshIterator* it) = 0;
/** \brief Set the spacial coordinates of a mesh node */
void setPoint(MeshEntity* e, int node, Vector3 const& p);
/** \brief Underlying implementation of apf::Mesh2::setPoint */
virtual void setPoint_(MeshEntity* e, int node, Vector3 const& p) = 0;
/** \brief Create a fully-specified vertex
\details this function sets geometric classification and coordinates
all at once. see apf::Mesh2::createVert for a more minimal interface */
MeshEntity* createVertex(ModelEntity* c, Vector3 const& point,
Vector3 const& param);
/** \brief require that no fields are stored in arrays */
void requireUnfrozen()
{
if (hasFrozenFields)
unfreezeFields(this);
}
/** \brief Underlying implementation of apf::Mesh2::createVert */
virtual MeshEntity* createVert_(ModelEntity* c) = 0;
/** \brief Just create a vertex
\param c geometric classification, which is very immutable in APF */
MeshEntity* createVert(ModelEntity* c)
{
requireUnfrozen();
return createVert_(c);
}
/** \brief Underlying implementation of apf::Mesh2::createEntity */
virtual MeshEntity* createEntity_(int type, ModelEntity* c,
MeshEntity** down) = 0;
/** \brief Create a non-vertex mesh entity
\details to create entities from more than one level down,
including intermediate entities, see apf::buildElement
\param type select from apf::Mesh::Type
\param c geometric classification, which is very immutable in APF
\param down array of one-level downward adjacent entities */
MeshEntity* createEntity(int type, ModelEntity* c, MeshEntity** down)
{
requireUnfrozen();
return createEntity_(type,c,down);
}
/** \brief Underlying implementation of apf::Mesh2::destroy */
virtual void destroy_(MeshEntity* e) = 0;
/** \brief Destroy a mesh entity
\details this does not destroy any other entities, including
downward adjacencies */
void destroy(MeshEntity* e)
{
requireUnfrozen();
destroy_(e);
}
/** \brief Change the geometric classification of an entity. */
virtual void setModelEntity(MeshEntity* e, ModelEntity* c) = 0;
/** \brief Add a matched copy to an entity */
virtual void addMatch(MeshEntity* e, int peer, MeshEntity* match) = 0;
/** \brief Remove all matched copies of an entity */
virtual void clearMatches(MeshEntity* e) = 0;
/** \brief Remove all entities */
virtual void clear_() = 0;
/** \brief Implementation-defined synchronization after modification
\details users are encouraged to call this function after finishing
mesh modifications so that all structures are properly updated before
using the mesh any further. */
virtual void acceptChanges() = 0;
};
/** \brief APF's migration function, works on apf::Mesh2
\details if your database implements apf::Mesh2
(and residence is separate from remote copies)
then you may use this to implement most of apf::Mesh::migrate.
Users of APF are encouraged to call apf::Mesh::migrate instead
of calling this directly */
void migrate(Mesh2* m, Migration* plan);
void migrateSilent(Mesh2* m, Migration* plan);
/** \brief set the maximum elements that apf::migrate moves at once
\details apf::migrate implements gradual limited migration
in an effort to help applications keep memory use to a minimum.
This function globally sets the limit on migration, which
causes any migration requests greater than the limit to
be performed as several consecutive migrations. */
void setMigrationLimit(size_t maxElements);
class Field;
/** \brief add a field (times a factor) to the mesh coordinates
\details this is useful in mechanical deformation problems
to transform the mesh from reference space to deformed space.
Setting the factor to -1 will undo the deformation */
void displaceMesh(Mesh2* m, Field* d, double factor=1.0);
/** \brief User-defined entity creation callback */
class BuildCallback
{
public:
/** \brief will be called after an entity is created */
virtual void call(MeshEntity* e) = 0;
};
/** \brief like apf::Mesh2::createEntity,
but returns already existing entities */
MeshEntity* makeOrFind(
Mesh2* m,
ModelEntity* c,
int type,
MeshEntity** down,
BuildCallback* cb = 0,
bool* p_made = 0);
/** \brief build an entity from its vertices
\details any missing intermediate entities will also be built,
and all will be classified to (c).
If a non-zero BuildCallback pointer is given, it will be called
for each entity created, including intermediate ones. */
MeshEntity* buildElement(
Mesh2* m,
ModelEntity* c,
int type,
MeshEntity** verts,
BuildCallback* cb = 0);
/** \brief build a one-element mesh
\details this is mostly useful for debugging
\todo this doesn't get used much, maybe remove it */
MeshEntity* buildOneElement(
Mesh2* m,
ModelEntity* c,
int type,
Vector3 const* points);
/** \brief Set entity residence based on remote copies
\details this function acts on all entities of one dimension */
void initResidence(Mesh2* m, int dim);
/** \brief infer all remote copies from those of vertices
\details
given that the remote copies of the vertices are set up correctly, this
function will synchronize the remote copies and resident part sets for all
other entities correctly. */
void stitchMesh(Mesh2* m);
/** \brief removes all entities and fields. */
void clear(Mesh2* m);
void packDataClone(Mesh2* m, int to);
void unpackDataClone(Mesh2* m);
// common functions for migration/ghosting/distribution
typedef std::vector<MeshEntity*> EntityVector;
void packParts(int to, Parts& parts);
void unpackParts(Parts& parts);
void moveEntities(
Mesh2* m,
EntityVector senders[4]);
void updateMatching(
Mesh2* m,
EntityVector affected[4],
EntityVector senders[4]);
void deleteOldEntities(
Mesh2* m,
EntityVector affected[4]);
void reduceMatchingToSenders(
Mesh2* m,
EntityVector senders[4]);
void getSenders(Mesh2* m,EntityVector affected[4],EntityVector senders[4]);
void split(Copies& remotes, Parts& parts, Parts& newParts);
// seol
void packEntity(Mesh2* m, int to, MeshEntity* e, DynamicArray<MeshTag*>& tags, bool ghosting=false);
void unpackRemotes(Mesh2* m, MeshEntity* e);
void unpackTags(Mesh2* m, MeshEntity* e, DynamicArray<MeshTag*>& tags);
void unpackCommon(Mesh2* m, MeshEntity*& sender, ModelEntity*& c, Parts& residence);
MeshEntity* unpackVertex(Mesh2* m, ModelEntity* c);
MeshEntity* unpackNonVertex(Mesh2* m,int type, ModelEntity* c);
}//namespace apf
#endif