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>
68 const Triangulation& mesh,
72 globalIndex globalIndexing(mesh.vertexCount());
74 DynamicList<label> dynIndices(mesh.vertexCount()/10);
78 typename Triangulation::Finite_vertices_iterator vit =
79 mesh.finite_vertices_begin();
80 vit != mesh.finite_vertices_end();
88 globalIndexing.toGlobal(vit->procIndex(), vit->index())
93 indices.transfer(dynIndices);
95 List<Map<label>> compactMap;
96 return autoPtr<mapDistribute>
108 template<
class Triangulation>
111 const Triangulation& mesh,
115 pointPoints.setSize(mesh.vertexCount());
117 globalIndex globalIndexing(mesh.vertexCount());
121 typename Triangulation::Finite_vertices_iterator vit =
122 mesh.finite_vertices_begin();
123 vit != mesh.finite_vertices_end();
132 std::list<typename Triangulation::Vertex_handle> adjVerts;
133 mesh.finite_adjacent_vertices(vit, std::back_inserter(adjVerts));
135 DynamicList<label> indices(adjVerts.size());
139 typename std::list<typename Triangulation::Vertex_handle>::
140 const_iterator adjVertI = adjVerts.begin();
141 adjVertI != adjVerts.end();
145 typename Triangulation::Vertex_handle vh = *adjVertI;
151 globalIndexing.toGlobal(vh->procIndex(), vh->index())
156 pointPoints[vit->index()].transfer(indices);
159 List<Map<label>> compactMap;
160 return autoPtr<mapDistribute>
172 template<
class Triangulation>
175 const Triangulation& mesh
178 tmp<triadField> tAlignments
186 typename Triangulation::Finite_vertices_iterator vit =
187 mesh.finite_vertices_begin();
188 vit != mesh.finite_vertices_end();
197 alignments[vit->index()] = vit->alignment();
204 template<
class Triangulation>
207 const Triangulation& mesh
210 tmp<pointField> tPoints
218 typename Triangulation::Finite_vertices_iterator vit =
219 mesh.finite_vertices_begin();
220 vit != mesh.finite_vertices_end();
229 points[vit->index()] =
topoint(vit->point());
236 void Foam::smoothAlignmentSolver::applyBoundaryConditions
238 const triad& fixedAlignment,
244 forAll(fixedAlignment, dirI)
246 if (fixedAlignment.set(dirI))
254 forAll(fixedAlignment, dirI)
256 if (fixedAlignment.set(dirI))
258 t.align(fixedAlignment[dirI]);
262 else if (nFixed == 2)
264 forAll(fixedAlignment, dirI)
266 if (fixedAlignment.set(dirI))
268 t[dirI] = fixedAlignment[dirI];
278 else if (nFixed == 3)
280 forAll(fixedAlignment, dirI)
282 if (fixedAlignment.set(dirI))
284 t[dirI] = fixedAlignment[dirI];
293 Foam::smoothAlignmentSolver::smoothAlignmentSolver(cellShapeControlMesh& mesh)
309 const label maxSmoothingIterations
312 scalar minResidual = 0;
315 autoPtr<mapDistribute> meshDistributor = buildMap
321 triadField alignments(buildAlignmentField(mesh_));
329 CellSizeDelaunay::Finite_vertices_iterator vit =
330 mesh_.finite_vertices_begin();
331 vit != mesh_.finite_vertices_end();
337 fixedAlignments[vit->index()] = vit->alignment();
344 for (
label iter = 0; iter < maxSmoothingIterations; iter++)
346 Info<<
"Iteration " << iter;
348 meshDistributor().distribute(points);
349 meshDistributor().distribute(fixedAlignments);
350 meshDistributor().distribute(alignments);
358 const labelList& pPoints = pointPoints[pI];
365 triad& newTriad = triadAv[pI];
367 forAll(pPoints, adjPointi)
369 const label adjPointIndex = pPoints[adjPointi];
371 scalar dist =
mag(points[pI] - points[adjPointIndex]);
373 triad tmpTriad = alignments[adjPointIndex];
377 if (tmpTriad.set(dir))
379 tmpTriad[dir] *= 1.0/(dist + SMALL);
383 newTriad += tmpTriad;
390 const triad& oldTriad = alignments[pI];
391 triad& newTriad = triadAv[pI];
393 newTriad.normalize();
394 newTriad.orthogonalize();
397 const triad& fixedAlignment = fixedAlignments[pI];
399 applyBoundaryConditions
405 newTriad = newTriad.sortxyz();
414 && !fixedAlignment.set(dir)
417 residual +=
diff(oldTriad, newTriad);
421 alignments[pI] = newTriad;
424 reduce(residual, sumOp<scalar>());
426 Info<<
", Residual = " 431 if (iter > 0 && residual <= minResidual)
437 meshDistributor().distribute(alignments);
441 CellSizeDelaunay::Finite_vertices_iterator vit =
442 mesh_.finite_vertices_begin();
443 vit != mesh_.finite_vertices_end();
449 vit->alignment() = alignments[vit->index()];
454 autoPtr<mapDistribute> referredDistributor = buildReferredMap
461 referredDistributor().distribute(alignments);
466 CellSizeDelaunay::Finite_vertices_iterator vit =
467 mesh_.finite_vertices_begin();
468 vit != mesh_.finite_vertices_end();
474 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.
intWM_LABEL_SIZE_t 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.
void orthogonalize()
Orthogonalize this triad so that it is ortho-normal.
label vertexCount() const
Return the vertex count (the next unique vertex index)
vectorField pointField
pointField is a vectorField.
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)
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.