30 template<
class Triangulation,
class Type>
33 const Triangulation& mesh,
34 const Field<Type>& field
37 tmp<Field<Type>> tNewField(
new Field<Type>(field.size()));
38 Field<Type>& newField = tNewField();
45 typename Triangulation::Finite_vertices_iterator vit =
46 mesh.finite_vertices_begin();
47 vit != mesh.finite_vertices_end();
53 newField[added++] = field[
count];
59 newField.resize(added);
65 template<
class Triangulation>
67 Foam::smoothAlignmentSolver::buildReferredMap
69 const Triangulation& mesh,
73 globalIndex globalIndexing(mesh.vertexCount());
75 DynamicList<label> dynIndices(mesh.vertexCount()/10);
79 typename Triangulation::Finite_vertices_iterator vit =
80 mesh.finite_vertices_begin();
81 vit != mesh.finite_vertices_end();
89 globalIndexing.toGlobal(vit->procIndex(), vit->index())
94 indices.transfer(dynIndices);
96 List<Map<label>> compactMap;
97 return autoPtr<distributionMap>
109 template<
class Triangulation>
112 const Triangulation& mesh,
116 pointPoints.setSize(mesh.vertexCount());
118 globalIndex globalIndexing(mesh.vertexCount());
122 typename Triangulation::Finite_vertices_iterator vit =
123 mesh.finite_vertices_begin();
124 vit != mesh.finite_vertices_end();
133 std::list<typename Triangulation::Vertex_handle> adjVerts;
134 mesh.finite_adjacent_vertices(vit, std::back_inserter(adjVerts));
136 DynamicList<label> indices(adjVerts.size());
140 typename std::list<typename Triangulation::Vertex_handle>::
141 const_iterator adjVertI = adjVerts.begin();
142 adjVertI != adjVerts.end();
146 typename Triangulation::Vertex_handle vh = *adjVertI;
152 globalIndexing.toGlobal(vh->procIndex(), vh->index())
157 pointPoints[vit->index()].transfer(indices);
160 List<Map<label>> compactMap;
161 return autoPtr<distributionMap>
173 template<
class Triangulation>
176 const Triangulation& mesh
179 tmp<triadField> tAlignments
187 typename Triangulation::Finite_vertices_iterator vit =
188 mesh.finite_vertices_begin();
189 vit != mesh.finite_vertices_end();
198 alignments[vit->index()] = vit->alignment();
205 template<
class Triangulation>
208 const Triangulation& mesh
211 tmp<pointField> tPoints
219 typename Triangulation::Finite_vertices_iterator vit =
220 mesh.finite_vertices_begin();
221 vit != mesh.finite_vertices_end();
230 points[vit->index()] =
topoint(vit->point());
237 void Foam::smoothAlignmentSolver::applyBoundaryConditions
239 const triad& fixedAlignment,
245 forAll(fixedAlignment, dirI)
247 if (fixedAlignment.set(dirI))
255 forAll(fixedAlignment, dirI)
257 if (fixedAlignment.set(dirI))
259 t.align(fixedAlignment[dirI]);
263 else if (nFixed == 2)
265 forAll(fixedAlignment, dirI)
267 if (fixedAlignment.set(dirI))
269 t[dirI] = fixedAlignment[dirI];
279 else if (nFixed == 3)
281 forAll(fixedAlignment, dirI)
283 if (fixedAlignment.set(dirI))
285 t[dirI] = fixedAlignment[dirI];
310 const label maxSmoothingIterations
313 scalar minResidual = 0;
316 autoPtr<distributionMap> meshDistributor = buildMap
322 triadField alignments(buildAlignmentField(mesh_));
330 CellSizeDelaunay::Finite_vertices_iterator vit =
331 mesh_.finite_vertices_begin();
332 vit != mesh_.finite_vertices_end();
338 fixedAlignments[vit->index()] = vit->alignment();
345 for (
label iter = 0; iter < maxSmoothingIterations; iter++)
347 Info<<
"Iteration " << iter;
349 meshDistributor().distribute(points);
350 meshDistributor().distribute(fixedAlignments);
351 meshDistributor().distribute(alignments);
359 const labelList& pPoints = pointPoints[pI];
366 triad& newTriad = triadAv[pI];
368 forAll(pPoints, adjPointi)
370 const label adjPointIndex = pPoints[adjPointi];
372 scalar dist =
mag(points[pI] - points[adjPointIndex]);
374 triad tmpTriad = alignments[adjPointIndex];
378 if (tmpTriad.set(dir))
380 tmpTriad[dir] *= 1.0/(dist + small);
384 newTriad += tmpTriad;
391 const triad& oldTriad = alignments[pI];
392 triad& newTriad = triadAv[pI];
394 newTriad.normalise();
395 newTriad.orthogonalise();
398 const triad& fixedAlignment = fixedAlignments[pI];
400 applyBoundaryConditions
406 newTriad = newTriad.sortxyz();
415 && !fixedAlignment.set(dir)
418 residual +=
diff(oldTriad, newTriad);
422 alignments[pI] = newTriad;
425 reduce(residual, sumOp<scalar>());
427 Info<<
", Residual = " 432 if (iter > 0 && residual <= minResidual)
438 meshDistributor().distribute(alignments);
442 CellSizeDelaunay::Finite_vertices_iterator vit =
443 mesh_.finite_vertices_begin();
444 vit != mesh_.finite_vertices_end();
450 vit->alignment() = alignments[vit->index()];
455 autoPtr<distributionMap> referredDistributor = buildReferredMap
462 referredDistributor().distribute(alignments);
467 CellSizeDelaunay::Finite_vertices_iterator vit =
468 mesh_.finite_vertices_begin();
469 vit != mesh_.finite_vertices_end();
475 vit->alignment() = alignments[referredPoints[referredI++]];
List< labelList > labelListList
A List of labelList.
scalar diff(const triad &A, const triad &B)
Return a quantity of the difference between two triads.
#define forAll(list, i)
Loop across all elements in list.
FvWallInfoData< WallInfo, label > label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
pointFromPoint topoint(const Point &P)
void smoothAlignments(const label maxSmoothingIterations)
Smooth the alignments on the mesh.
Ostream & endl(Ostream &os)
Add newline and flush stream.
label count(const ListType &l, typename ListType::const_reference x)
Count the number of occurrences of a value in a list.
void orthogonalise()
Orthogonalise this triad so that it is ortho-normal.
vectorField pointField
pointField is a vectorField.
smoothAlignmentSolver(cellShapeControlMesh &mesh)
Construct null.
List< label > labelList
A List of labels.
Field< triad > triadField
Specialisation of Field<T> for triad.
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
label vertexCount() const
Return the vertex count (the next unique vertex index)
vector point
Point is a vector.
dimensioned< scalar > mag(const dimensioned< Type > &)
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
A class for managing temporary objects.
~smoothAlignmentSolver()
Destructor.