61 for (i=ts.
size()-1; i>=0; i--)
74 for (
label j=i; j>=0; j--)
80 Pout<<
" triSurface::triSurfInstance(const Time& d)"
81 <<
"reading " << foamName
93 Pout<<
" triSurface::triSurfInstance(const Time& d)"
94 <<
"reading " << foamName
95 <<
" from constant/" <<
endl;
104 const label defaultRegion
111 const face&
f = faces[facei];
116 <<
"Face at position " << facei
117 <<
" does not have three vertices:" <<
f
121 labelledTri& tri = triFaces[facei];
126 tri.region() = defaultRegion;
136 const label defaultRegion
145 labelledTri& tri = triFaces[facei];
150 tri.region() = defaultRegion;
159 void Foam::triSurface::printTriangle
163 const labelledTri&
f,
168 << pre.c_str() <<
"vertex numbers:"
169 <<
f[0] <<
' ' <<
f[1] <<
' ' <<
f[2] <<
endl
170 << pre.c_str() <<
"vertex coords :"
172 << pre.c_str() <<
"region :" <<
f.region() <<
endl
177 Foam::string Foam::triSurface::getLineNoComment(IFstream& is)
184 while ((line.empty() || line[0] ==
'#') && is.good());
190 Foam::scalar Foam::triSurface::pointNormalWeight
218 tmp<vectorField> tpointNormals
226 const labelList& meshPoints = this->meshPoints();
235 const triFace&
f = operator[](facei);
238 const scalar weight =
239 pointNormalWeight(
f, meshPoints[
pi], fa,
points);
241 pointNormals[
pi] += weight*fa;
244 pointNormals[
pi] /=
mag(pointNormals[
pi]) + vSmall;
247 return tpointNormals;
257 triadField& pointCoordSys = tpointCoordSys.ref();
260 const labelList& meshPoints = this->meshPoints();
265 const vector& normal = pointNormals[
pi];
267 if (
mag(normal) < small)
279 vector dir2 = dir1 ^ normal;
282 pointCoordSys[
pi] = triad(dir1, dir2, normal);
285 return pointCoordSys;
289 bool Foam::triSurface::read(Istream& is)
291 is >> patches_ >> storedPoints() >> storedFaces();
297 bool Foam::triSurface::read
299 const fileName&
name,
312 fileName unzipName =
name.lessExt();
315 return read(unzipName, unzipName.ext(),
false);
317 else if (ext ==
"ftr")
321 else if (ext ==
"stl")
323 return readSTL(
name);
325 else if (ext ==
"stlb")
327 return readSTLBINARY(
name);
329 else if (ext ==
"gts")
331 return readGTS(
name);
333 else if (ext ==
"obj")
335 return readOBJ(
name);
337 else if (ext ==
"off")
339 return readOFF(
name);
341 else if (ext ==
"tri")
343 return readTRI(
name);
345 else if (ext ==
"ac")
349 else if (ext ==
"nas")
351 return readNAS(
name);
353 else if (ext ==
"vtk")
355 return readVTK(
name);
360 <<
"unknown file extension " << ext
361 <<
". Supported extensions are '.ftr', '.stl', '.stlb', '.gts'"
362 <<
", '.obj', '.ac', '.off', '.nas', '.tri' and '.vtk'"
370 void Foam::triSurface::write
372 const fileName&
name,
381 else if (ext ==
"stl")
383 return writeSTLASCII(
sort, OFstream(
name)());
385 else if (ext ==
"stlb")
387 ofstream outFile(
name.c_str(), std::ios::binary);
389 writeSTLBINARY(outFile);
391 else if (ext ==
"gts")
393 return writeGTS(
sort, OFstream(
name)());
395 else if (ext ==
"obj")
399 else if (ext ==
"off")
403 else if (ext ==
"vtk")
407 else if (ext ==
"tri")
411 else if (ext ==
"ac")
413 writeAC(OFstream(
name)());
415 else if (ext ==
"smesh")
422 <<
"unknown file extension " << ext
423 <<
" for file " <<
name
424 <<
". Supported extensions are '.ftr', '.stl', '.stlb', "
425 <<
"'.gts', '.obj', '.vtk'"
426 <<
", '.off', '.dx', '.smesh', '.ac' and '.tri'"
435 SortableList<label> sortedRegion(size());
437 forAll(sortedRegion, facei)
439 sortedRegion[facei] = operator[](facei).region();
443 faceMap = sortedRegion.indices();
446 label maxRegion = patches_.size()-1;
453 operator[](
faceMap.last()).region()
471 label startFacei = 0;
472 forAll(newPatches, newPatchi)
474 surfacePatch& newPatch = newPatches[newPatchi];
476 newPatch.index() = newPatchi;
478 label oldPatchi = newPatchi;
481 newPatch.start() = startFacei;
485 if ((oldPatchi < patches_.size()) && (patches_[oldPatchi].name() !=
""))
487 newPatch.name() = patches_[oldPatchi].name();
491 newPatch.name() = word(
"patch") +
name(newPatchi);
496 (oldPatchi < patches_.size())
497 && (patches_[oldPatchi].geometricType() !=
"")
500 newPatch.geometricType() = patches_[oldPatchi].geometricType();
504 newPatch.geometricType() =
"empty";
507 startFacei += newPatch.size();
514 void Foam::triSurface::setDefaultPatches()
522 patches_.setSize(newPatches.size());
528 patches_[
patchi].geometricType() = newPatches[
patchi].geometricType();
540 sortedEdgeFacesPtr_(nullptr),
541 edgeOwnerPtr_(nullptr)
555 sortedEdgeFacesPtr_(nullptr),
556 edgeOwnerPtr_(nullptr)
571 sortedEdgeFacesPtr_(nullptr),
572 edgeOwnerPtr_(nullptr)
586 sortedEdgeFacesPtr_(nullptr),
587 edgeOwnerPtr_(nullptr)
600 sortedEdgeFacesPtr_(nullptr),
601 edgeOwnerPtr_(nullptr)
616 sortedEdgeFacesPtr_(nullptr),
617 edgeOwnerPtr_(nullptr)
628 sortedEdgeFacesPtr_(nullptr),
629 edgeOwnerPtr_(nullptr)
644 sortedEdgeFacesPtr_(nullptr),
645 edgeOwnerPtr_(nullptr)
658 sortedEdgeFacesPtr_(nullptr),
659 edgeOwnerPtr_(nullptr)
678 sortedEdgeFacesPtr_(nullptr),
679 edgeOwnerPtr_(nullptr)
688 sortedEdgeFacesPtr_(nullptr),
689 edgeOwnerPtr_(nullptr)
705 ParentType::clearTopology();
713 ParentType::clearPatchMeshAddr();
719 ParentType::clearOut();
722 clearPatchMeshAddr();
728 if (!sortedEdgeFacesPtr_)
730 calcSortedEdgeFaces();
733 return *sortedEdgeFacesPtr_;
744 return *edgeOwnerPtr_;
754 ParentType::clearGeom();
757 storedPoints() = newPoints;
764 if (scaleFactor > 0 && scaleFactor != 1.0)
770 ParentType::clearGeom();
772 storedPoints() *= scaleFactor;
788 if (
f[fp] < 0 ||
f[fp] > maxPointi)
792 <<
" uses point indices outside point range 0.."
806 bool hasInvalid =
false;
812 if ((
f[0] ==
f[1]) || (
f[0] ==
f[2]) || (
f[1] ==
f[2]))
815 valid[facei] =
false;
821 <<
"triangle " << facei
822 <<
" does not have three unique vertices:\n";
829 const labelList& fEdges = faceEdges()[facei];
836 const labelList& eFaces = edgeFaces()[fEdges[fp]];
840 label neighbour = eFaces[i];
842 if (neighbour > facei)
849 ((
f[0] ==
n[0]) || (
f[0] ==
n[1]) || (
f[0] ==
n[2]))
850 && ((
f[1] ==
n[0]) || (
f[1] ==
n[1]) || (
f[1] ==
n[2]))
851 && ((
f[2] ==
n[0]) || (
f[2] ==
n[1]) || (
f[2] ==
n[2]))
854 valid[facei] =
false;
860 <<
"triangles share the same vertices:\n"
861 <<
" face 1 :" << facei <<
endl;
867 << neighbour <<
endl;
888 (*this)[newFacei++] =
f;
895 <<
"Removing " << size() - newFacei
896 <<
" illegal faces." <<
endl;
898 (*this).setSize(newFacei);
912 const labelList& myFaces = eFaces[edgeI];
917 <<
"Edge " << edgeI <<
" with vertices " << edges()[edgeI]
918 <<
" has no edgeFaces"
921 else if (myFaces.
size() > 2 && verbose)
924 <<
"Edge " << edgeI <<
" with vertices " << edges()[edgeI]
925 <<
" has more than 2 faces connected to it : " << myFaces
935 stitchTriangles(small, verbose);
940 checkTriangles(verbose);
950 const label currentZone,
964 label facei = changedFaces[i];
966 const labelList& fEdges = faceEdges()[facei];
970 label edgeI = fEdges[i];
972 if (!borderEdge[edgeI])
974 const labelList& eFaces = edgeFaces()[edgeI];
978 label nbrFacei = eFaces[j];
983 newChangedFaces.
append(nbrFacei);
985 else if (
faceZone[nbrFacei] != currentZone)
989 <<
" at face " << nbrFacei
990 <<
" connects to zone " << currentZone
991 <<
" at face " << facei
999 if (newChangedFaces.
empty())
1004 changedFaces.
transfer(newChangedFaces);
1018 if (borderEdge.
size() != nEdges())
1021 <<
"borderEdge boolList not same size as number of edges" <<
endl
1022 <<
"borderEdge:" << borderEdge.
size() <<
endl
1023 <<
"nEdges :" << nEdges()
1029 for (
label startFacei = 0;; zoneI++)
1032 for (; startFacei < size(); startFacei++)
1040 if (startFacei >= size())
1047 markZone(borderEdge, startFacei, zoneI,
faceZone);
1072 forAll(include, oldFacei)
1074 if (include[oldFacei])
1085 if (!pointHad[labI])
1087 pointHad[labI] =
true;
1088 pointMap[pointi++] = labI;
1111 subsetMeshMap(include, pointMap,
faceMap);
1119 newPoints[pointi] = locPoints[pointMap[pointi]];
1120 oldToNew[pointMap[pointi]] = pointi;
1131 newTriangles[facei][0] = oldToNew[tri[0]];
1132 newTriangles[facei][1] = oldToNew[tri[1]];
1133 newTriangles[facei][2] = oldToNew[tri[2]];
1134 newTriangles[facei].region() = tri.
region();
1148 faces[facei] = operator[](facei).triFaceFace();
1162 const labelList& meshPoints = this->meshPoints();
1163 const Map<label>& meshPointMap = this->meshPointMap();
1167 this->weightedPointNormals()
1172 this->pointCoordSys(pointNormals)
1192 const edge&
e = fEdges[feI];
1194 edgeVectors[feI] =
e.vec(
points);
1195 normalDifferences[feI] =
1196 pointNormals[meshPointMap[
e[0]]]
1197 - pointNormals[meshPointMap[
e[1]]];
1201 const vector& e0 = edgeVectors[0];
1203 const vector e1 = (e0 ^ eN);
1205 if (
magSqr(eN) < rootVSmall)
1210 triad faceCoordSys(e0, e1, eN);
1218 for (
label i = 0; i < 3; ++i)
1220 const scalar
x = edgeVectors[i] & faceCoordSys[0];
1221 const scalar
y = edgeVectors[i] & faceCoordSys[1];
1229 const scalar dndx = normalDifferences[i] & faceCoordSys[0];
1230 const scalar dndy = normalDifferences[i] & faceCoordSys[1];
1233 Z[1] += dndx*
y + dndy*
x;
1240 const symmTensor2D secondFundamentalTensor(Z[0], Z[1], Z[2]);
1246 const label patchPointIndex = meshPointMap[
f[fpi]];
1248 const triad& ptCoordSys = pointCoordSys[patchPointIndex];
1250 if (!ptCoordSys.
set())
1261 const triad rotatedFaceCoordSys = rotTensor &
tensor(faceCoordSys);
1267 ptCoordSys[0] & rotatedFaceCoordSys[0],
1268 ptCoordSys[0] & rotatedFaceCoordSys[1]
1272 ptCoordSys[1] & rotatedFaceCoordSys[0],
1273 ptCoordSys[1] & rotatedFaceCoordSys[1]
1284 projTensor.
x() & (secondFundamentalTensor & projTensor.
x()),
1285 projTensor.
x() & (secondFundamentalTensor & projTensor.
y()),
1286 projTensor.
y() & (secondFundamentalTensor & projTensor.
y())
1290 const scalar weight = pointNormalWeight
1293 meshPoints[patchPointIndex],
1299 pointFundamentalTensors[patchPointIndex] +=
1300 weight*projectedFundamentalTensor;
1302 accumulatedWeights[patchPointIndex] += weight;
1308 pointFundamentalTensors[
pi] /= (accumulatedWeights[
pi] + small);
1310 const vector2D principalCurvatures =
1315 const scalar curvature =
max
1317 mag(principalCurvatures[0]),
1318 mag(principalCurvatures[1])
1322 curvaturePointField[meshPoints[
pi]] = curvature;
1325 return tcurvaturePointField;
1329 void Foam::triSurface::write
1332 const bool sortByRegion
1348 os.
check(
"triSurface::write(Ostream&)");
1352 void Foam::triSurface::write(
const Time& d)
const
1380 if (pointIsUsed.
set(pointi, 1))
1389 os <<
indent <<
"Triangles : " << size() <<
endl
1391 <<
indent <<
"Bounding Box : " << bb <<
endl;
1401 storedPoints() = ts.
points();
1410 storedPoints() = move(ts.points());
1411 patches_ = move(ts.patches());
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
#define forAll(list, i)
Loop across all elements in list.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
virtual bool check(const char *operation) const
Check IOstream status for given operation.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
void size(const label)
Override size to be inconsistent with allocated storage.
void operator=(const UList< T > &)
Assignment to UList operator. Takes linear time.
void setSize(const label)
Reset size of List.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
void set(const PackedList< 1 > &)
Set specified bits.
const Field< PointType > & points() const
Return reference to global points.
std::remove_reference< ::Foam::List< labelledTri > >::type::value_type FaceType
Templated 2D symmetric tensor derived from VectorSpace adding construction from 4 components,...
A templated 2D square symmetric matrix of objects of <T>, where the n x n matrix dimension is known a...
Templated 2D tensor derived from VectorSpace adding construction from 4 components,...
Vector2D< Cmpt > y() const
Vector2D< Cmpt > x() const
static const word & constant()
Return constant name.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
instantList times() const
Search the case for valid time directories.
fileName path() const
Explicitly inherit path from TimePaths to disambiguate from.
scalar userTimeValue() const
Return current user time value.
const fileName & caseName() const
Explicitly inherit caseName from TimePaths to disambiguate from.
label rcIndex(const label i) const
Return the reverse circular index, i.e. the previous index.
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
bool empty() const
Return true if the UList is empty (ie, size() is zero)
A bounding box defined in terms of the points at its extremities.
const point & min() const
Minimum point defining the bounding box.
const point & max() const
Maximum point defining the bounding box.
static const boundBox invertedBox
A very large inverted boundBox: min/max == +/- vGreat.
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Named list of face indices representing a sub-set of the mesh faces.
A face is a list of labels corresponding to mesh vertices.
A class for handling file names.
label size() const
Return fvMesh size.
Triangle with additional region number.
label region() const
Return region label.
Motion of the mesh specified as a list of pointMeshMovers.
A class for handling character strings derived from std::string.
A class for managing temporary objects.
T & ref() const
Return non-const reference or generate a fatal error.
A triangular face using a FixedList of labels corresponding to mesh vertices.
triSurface point mesh for fields on triSurface points
Triangulated surface description with patch information.
virtual void scalePoints(const scalar)
Scale points. A non-positive factor is ignored.
static fileName triSurfInstance(const Time &)
Name of triSurface directory to use.
triSurface()
Construct null.
triSurface subsetMesh(const boolList &include, labelList &pointMap, labelList &faceMap) const
Return new surface. Returns pointMap, faceMap from.
label markZones(const boolList &borderEdge, labelList &faceZone) const
(size and) fills faceZone with zone of face. Zone is area
tmp< scalarField > curvature() const
Return the curvature of surface at the points.
void operator=(const triSurface &)
void cleanup(const bool verbose)
Remove non-valid triangles.
const geometricSurfacePatchList & patches() const
void checkTriangles(const bool verbose)
Check/remove duplicate/degenerate triangles.
void checkEdges(const bool verbose)
Check triply (or more) connected edges.
void markZone(const boolList &borderEdge, const label facei, const label currentZone, labelList &faceZone) const
Fill faceZone with currentZone for every face reachable.
void writeStats(Ostream &) const
Write some statistics.
faceList faces() const
Return the list of triangles as a faceList.
const labelList & edgeOwner() const
If 2 face neighbours: label of face where ordering of edge.
void subsetMeshMap(const boolList &include, labelList &pointMap, labelList &faceMap) const
'Create' sub mesh, including only faces for which
void clearPatchMeshAddr()
const labelListList & sortedEdgeFaces() const
Return edge-face addressing sorted (for edges with more than.
virtual ~triSurface()
Destructor.
virtual void setPoints(const pointField &)
Move points.
Representation of a 3D Cartesian coordinate system as a Vector of vectors.
bool set(const direction d) const
Is the vector in the direction d set.
void normalise()
Normalise each set axis vector to have a unit magnitude.
Template function which returns the un-mangled name of a given type. Useful for types which do not ha...
A class for handling words, derived from string.
Template functions to aid in the implementation of demand driven data.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const fvPatchList & patches
#define WarningInFunction
Report a warning using Foam::Warning.
bool valid(const PtrList< ModelType > &l)
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
bool isFile(const fileName &, const bool checkVariants=true, const bool followLink=true)
Does the name exist as a file in the file system?
errorManipArg< error, int > exit(error &err, const int errNo=1)
bool read(const char *, int32_t &)
tensor rotationTensor(const vector &n1, const vector &n2)
Rotational transformation tensor from unit vector n1 to n2.
List< label > labelList
A List of labels.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Tensor< scalar > tensor
Tensor of scalars.
Ostream & endl(Ostream &os)
Add newline and flush stream.
void eigenValues(pointPatchField< vector > &, const pointPatchField< tensor > &)
void deleteDemandDrivenData(DataType *&dataPtr)
errorManip< error > abort(error &err)
bool exists(const fileName &, const bool checkVariants=true, const bool followLink=true)
Does the name exist (as directory or file) in the file system?
const fvMesh & region(const dictionary &dict)
Cast the give dictionary to the corresponding region fvMesh.
vectorField pointField
pointField is a vectorField.
vector point
Point is a vector.
Field< triad > triadField
Specialisation of Field<T> for triad.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
List< triFace > triFaceList
list of triFaces
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
Vector< scalar > vector
A scalar version of the templated Vector.
List< labelList > labelListList
A List of labelList.
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
Field< vector > vectorField
Specialisation of Field<T> for vector.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
void writeVTK(OFstream &os, const Type &value)
prefixOSstream Pout(cout, "Pout")
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
Ostream & operator<<(Ostream &os, const fvConstraints &constraints)
void LUsolve(scalarSquareMatrix &matrix, List< Type > &source)
Solve the matrix using LU decomposition with pivoting.
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
Ostream & indent(Ostream &os)
Indent stream.
void T(GeometricField< Type, GeoMesh, PrimitiveField1 > &gf, const GeometricField< Type, GeoMesh, PrimitiveField2 > &gf1)
List< surfacePatch > surfacePatchList
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=*(cellModeller::lookup("hex"));labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells]=cellShape(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< small) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} label minLabel=min(start, end);pointMap[start]=pointMap[end]=minLabel;} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};const label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &mergedCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< SLList< face > > pFaces[nBCs]