26#include "../CSparse/Include/cs.h"
30CGeometrySolver::CGeometrySolver(
void)
31: m_dHeightTolerance(1e-3)
32, m_dDisabledStiffness(1e-4)
33, m_dContactStiffness(1e3)
34, m_bAdjustThickness(false)
35, m_dLongitudinalBendingModulus(1.0)
36, m_dTransverseBendingModulus(1.0)
37, m_dTensileStress(1.0)
48 vector<PLATE>::iterator itPlate;
58 vector<PLATE>::iterator itPlate;
68 vector<PLATE>::iterator itPlate;
102 for (i=0; i<iNumYarns; ++i)
108 Interp->SetForceInPlaneTangent(
true);
120 for (i=0; i<iNumNodes; ++i)
128 int iGlobalIndexCount = 0;
129 for (i=0; i<iNumNodes; ++i)
184 vector<PROJECTED_NODE>::iterator itProjectedNode;
185 vector<RAISED_NODE>::iterator itRaised;
189 for (j=0; j < (int)itProjectedNode->RaisedNodes.size()-1; ++j)
191 Spring.
iNode1 = itProjectedNode->RaisedNodes[j].iGlobalIndex;
192 Spring.
iNode2 = itProjectedNode->RaisedNodes[j+1].iGlobalIndex;
207 double dWidth = AABB.second.x - AABB.first.x;
208 double dHeight = AABB.second.y - AABB.first.y;
210 Repeats.push_back(
XYZ(dWidth, 0, 0));
211 Repeats.push_back(
XYZ(0, dHeight, 0));
221 const int iXDivs = 10, iYDivs = 10;
225 for (i=0; i<iXDivs; ++i)
227 u = i/double(iXDivs-1);
228 for (j=0; j<iYDivs; ++j)
230 v = j/double(iYDivs-1);
232 if (i<iXDivs-1 && j<iYDivs-1)
269 for (i=0; i<iXDivs*iYDivs; ++i)
272 Spring.
iNode2 = i + iXDivs*iYDivs;
293 Repeats.push_back(
XYZ(1, 0, 0));
294 Repeats.push_back(
XYZ(0, 1, 0));
300 set<int> YarnIndices;
301 insert_iterator<set<int> > iiYarnIndices(YarnIndices, YarnIndices.end());
302 set<int>::iterator itYarnIndex;
304 list<int>::iterator itIndex;
306 int i, j, iNode, iRegion;
309 for (itIndex = Indices.begin(), i=0; itIndex != Indices.end(); ++i)
313 iNode = *(itIndex++);
326 for (itYarnIndex=YarnIndices.begin(); itYarnIndex!=YarnIndices.end(); ++itYarnIndex)
330 Node.
dHeight = 0.5*(dMin+dMax);
341 vector<PLATE>::iterator itPlate;
344 if (itPlate->iNode1 == iIndex || itPlate->iNode2 == iIndex || itPlate->iNode3 == iIndex)
346 dArea += itPlate->BendingElement.GetArea();
357 list<int>::iterator itIter;
359 double dAverageLength = 0;
360 int iNumConnected = 0;
361 for (itIter = LineIndices.begin(); itIter != LineIndices.end(); )
365 if (i1 == iIndex || i2 == iIndex)
371 dAverageLength /= iNumConnected;
372 return dAverageLength;
377 list<int>::iterator itIndex;
380 vector<RAISED_NODE>::iterator itRaised1, itRaised2, itRaised3;
381 for (itIndex = Indices.begin(); itIndex != Indices.end(); )
395 if (itRaised1->iYarnIndex == itRaised2->iYarnIndex &&
396 itRaised2->iYarnIndex == itRaised3->iYarnIndex)
416 list<int>::iterator itIndex;
418 for (itIndex = Indices.begin(); itIndex != Indices.end(); )
420 Plate.
iNode1 = *(itIndex++);
421 Plate.
iNode2 = *(itIndex++);
422 Plate.
iNode3 = *(itIndex++);
441 vector<PLATE>::iterator itPlate;
442 vector<vector<pair<int, XYZ> > > PlateCenters;
444 PlateCenters.resize(iNumYarns);
452 PlateCenters[itPlate->iYarnIndex].push_back(make_pair(i, Center));
455 for (i=0; i<iNumYarns; ++i)
459 for (j=0; j<(int)PlateCenters[i].size(); ++j)
461 bool bInside = pYarn->
PointInsideYarn(PlateCenters[i][j].second, Translations, &Tangent);
484 vector<pair<int, int> > NodePairs;
485 vector<XYZ>::iterator itRepeat;
486 for (itRepeat = Repeats.begin(); itRepeat != Repeats.end(); ++itRepeat)
489 NodePairs.insert(NodePairs.end(), Temp.begin(), Temp.end());
493 vector<pair<int, int> >::iterator itNodePair;
494 for (itNodePair = NodePairs.begin(); itNodePair != NodePairs.end(); ++itNodePair)
496 if (
m_Nodes[itNodePair->first].iYarnIndex !=
m_Nodes[itNodePair->second].iYarnIndex)
503 pair<int, int> Pair = make_pair(itNodePair->first*3+i, itNodePair->second*3+i);
544 int iNumNodes = (int)
m_Nodes.size();
546 int iDOFs = iNumNodes*3 + iNumPlates;
547 map<pair<int, int>,
double> A;
548 map<pair<int, int>,
double>::iterator itA;
549 vector<double> x(iDOFs);
550 vector<double> b(iDOFs);
551 int iNumSwitches, iIteration = 0;
552 double dInitialLength, dCurrentLength;
553 double dContactDistance, dSeperationDistance;
556 int i, j, i1, i2, iPlateCount;
559 vector<SPRING>::iterator itSpring;
560 vector<PLATE>::iterator itPlate;
564 TGLOGINDENT(
"Solving geometry with " << iNumNodes <<
" nodes and " << iDOFs <<
" degrees of freedom");
568 TGLOG(
"Iteration " << iIteration);
571 fill(x.begin(), x.end(), 0.0);
572 fill(b.begin(), b.end(), 0.0);
577 iNodes[0] = itPlate->iNode1;
578 iNodes[1] = itPlate->iNode2;
579 iNodes[2] = itPlate->iNode3;
581 itPlate->BendingElement.GetKeMatrix(KeB);
584 iGlob = iNodes[i/3]*3+i%3;
586 iGlob = iNumNodes*3+iPlateCount;
587 assert(iGlob < iDOFs);
590 jGlob = iNodes[j/3]*3+j%3;
592 jGlob = iNumNodes*3+iPlateCount;
593 assert(jGlob < iDOFs);
594 A[make_pair(iGlob, jGlob)] += KeB(i, j);
598 itPlate->TensionElement.GetKeMatrix(KeT);
602 assert(iGlob < iDOFs);
606 assert(jGlob < iDOFs);
607 A[make_pair(iGlob, jGlob)] += KeT(i, j);
614 for (i=0; i<iNumNodes; ++i)
616 x[i*3] =
m_Nodes[i].Position.z;
625 for (itA = A.begin(); itA != A.end(); ++itA)
627 b[itA->first.first] -= itA->second * x[itA->first.second];
633 i1 = itSpring->iNode1;
634 i2 = itSpring->iNode2;
643 dSeperationDistance = dCurrentLength-dContactDistance;
646 if (dSeperationDistance > 0)
650 if (bEnabled != itSpring->bEnabled)
654 itSpring->bEnabled = bEnabled;
663 b[i1*3] += dStiffness*(dInitialLength-dContactDistance);
664 b[i2*3] -= dStiffness*(dInitialLength-dContactDistance);
665 A[make_pair(i1*3, i1*3)] += dStiffness;
666 A[make_pair(i2*3, i2*3)] += dStiffness;
667 A[make_pair(i1*3, i2*3)] -= dStiffness;
668 A[make_pair(i2*3, i1*3)] -= dStiffness;
671 set<int> ConstrainedDOFs;
674 vector<pair<int, double> >::iterator itConstraint;
677 if (ConstrainedDOFs.count(itConstraint->first))
679 TGERROR(
"Warning: Equation " << itConstraint->first <<
" is already constrained! Ignoring this boundary condition.");
682 for (i=0; i<iDOFs; ++i)
684 pair<int, int> Index = make_pair(itConstraint->first, i);
685 if (i==itConstraint->first)
690 b[itConstraint->first] = itConstraint->second;
691 ConstrainedDOFs.insert(itConstraint->first);
695 vector<pair<int, int> >::iterator itDOFLink;
699 int iRemovedDOF = itDOFLink->first;
700 int iCombinedDOF = itDOFLink->second;
701 if (ConstrainedDOFs.count(iRemovedDOF))
703 swap(iRemovedDOF, iCombinedDOF);
705 if (ConstrainedDOFs.count(iRemovedDOF))
707 TGERROR(
"Warning: Degrees of freedom " << itDOFLink->first <<
" and " << itDOFLink->second <<
708 " are already constrained! Ignoring this boundary condition.");
711 for (i=0; i<iDOFs; ++i)
713 pair<int, int> Index = make_pair(iRemovedDOF, i);
714 if (!ConstrainedDOFs.count(iCombinedDOF) && A.count(Index))
717 A[make_pair(iCombinedDOF, i)] += A[Index];
719 if (i==itDOFLink->first)
721 else if (i==itDOFLink->second)
727 if (!ConstrainedDOFs.count(iCombinedDOF))
728 b[iCombinedDOF] += b[iRemovedDOF];
730 ConstrainedDOFs.insert(iRemovedDOF);
739 cs* csT = cs_spalloc(iNumNodes, iNumNodes, A.size(), 1, 1);
740 for (itA = A.begin(); itA != A.end(); ++itA)
742 cs_entry(csT, itA->first.first, itA->first.second, itA->second);
744 cs* csA = cs_compress(csT);
747 int iSuccess = cs_lusol(1, csA, &x.front(), 1);
756 for (i=0; i<iNumNodes; ++i)
758 m_Nodes[i].dDisplacement = x[i*3];
762 TGLOG(
"Number of switches: " << iNumSwitches);
766 stringstream IterFileName;
767 IterFileName <<
"c://Program Files//TexGen//GeometrySolver//iter." << setfill(
'0') << setw(4) << iIteration;
770 }
while (iIteration == 1 || iNumSwitches > 0);
778 vector<TiXmlElement> AdditionalData;
788 for (i=0; i<(int)
m_Nodes.size(); ++i)
794 AdjustedThicknesses.
m_Data.push_back(
m_Nodes[i].GetAdjustedThickness());
800 vector<PLATE>::iterator itPlate;
803 YarnTangent.
m_Data.push_back(itPlate->BendingElement.GetFibreDirection());
804 CellYarnIndex.
m_Data.push_back(itPlate->iYarnIndex);
807 vector<SPRING>::iterator itSpring;
810 if (itSpring->bEnabled)
816 CellYarnIndex.
m_Data.push_back(-1);
819 vector<CMeshDataBase*> MeshData;
821 MeshData.push_back(&Displacements);
822 MeshData.push_back(&ThetaX);
823 MeshData.push_back(&ThetaY);
824 MeshData.push_back(&Thicknesses);
826 MeshData.push_back(&AdjustedThicknesses);
827 MeshData.push_back(&YarnIndex);
828 MeshData.push_back(&YarnTangent);
829 MeshData.push_back(&CellYarnIndex);
831 CopiedMesh.
SaveToVTK(Filename, &MeshData);
852 list<int>::const_iterator itIndex;
855 double dAccuracy = -1;
857 for (itIndex = Indices.begin(); itIndex != Indices.end(); )
869 dMin = min(Weights.
x, Weights.
y);
870 dMin = min(dMin, Weights.
z);
871 if (bFirst || dMin > dAccuracy)
#define TGLOGINDENT(MESSAGE)
Combines the TGLOG macro and TGLOGAUTOINDENT macro in one.
#define TGERROR(MESSAGE)
Macros used to report the file name and line number to the TexGenError and TexGenLog functions.
#define TEXGEN
Helper macro to get the texgen instance.
vector< CMesh > m_YarnMeshes
vector< PROJECTED_REGION > m_ProjectedRegions
vector< int > m_TriangleRegions
bool CreateBasicVolumes(CTextile &Textile)
void SetPeriodic(bool bPeriodic)
bool GetMeshVerticalBounds(const CMesh &Mesh, XYZ Point, double &dMinZ, double &dMaxZ, bool bForceFind=false)
const CMesh & GetMesh() const
Get the mesh representing the domain as a surface mesh.
vector< XYZ > GetTranslations(const CYarn &Yarn) const
Get the translation vectors necessary to fully fill the domain.
void SetFibreDirection(XYZ FibreDirection)
void SetNodeCoordinates(const CMatrix &P)
void SetLongitudinalBendingModulus(double E1)
void SetTransverseBendingModulus(double E2)
void SetTensileStress(double E)
double m_dHeightTolerance
CTextile * GetDeformedCopyOfTextile()
Create a copy of the textile and deform it, leaving the original textile intact.
void SaveToVTK(string Filename)
Save the results to a VTK file.
vector< pair< int, double > > m_DOFConstraints
void DeformTextile()
Deform the textile with the results.
vector< pair< int, int > > m_DOFLinks
void SetTransverseBendingModulus(double dBendingModulus)
void SetLongitudinalBendingModulus(double dBendingModulus)
void AssignFibreDirectionToElements()
vector< SPRING > m_Springs
void CreatePlateElements()
vector< PLATE > m_PlateElements
double m_dDisabledStiffness
void ApplyPeriodicBoundaryConditions(vector< XYZ > Repeats)
double GetDisplacement(XYZ Pos, int iYarn, XYZ &Disp) const
double m_dLongitudinalBendingModulus
void RaiseNodes(int iIndex)
double GetArea(int iIndex)
int SolveSystem()
Solve the system of equations.
void SetDisabledStiffness(double dDisabledStiffness)
void SetTensileStress(double dTensileStress)
vector< PROJECTED_NODE > m_ProjectedNodes
double GetAverageLength(int iIndex)
bool CreateSystem(CTextile &Textile)
Create the finite element system of equations for a given textile.
double m_dContactStiffness
void SetContactStiffness(double dContactStiffness)
double m_dTransverseBendingModulus
Class to represent a matrix and perform various operations on it.
Defines the nodes and elements of a surface or volume mesh.
vector< pair< int, int > > GetNodePairs(XYZ Vector, const double Tolerance=1e-6) const
Return a list of node pairs (A, B) where A == B + Vector.
const int AddNode(XYZ Node)
Append a node to the list of nodes, the integer returns the index of the node
const XYZ & GetNode(int iIndex) const
Get the node with given ID.
bool SaveToVTK(string Filename, const vector< CMeshDataBase * > *pMeshData=NULL) const
Save the mesh to VTK unstructured grid file format (.vtu)
static int GetNumNodes(ELEMENT_TYPE Type)
Get the number of nodes a particular element type contains.
const list< int > & GetIndices(ELEMENT_TYPE ElemType) const
Get the element indices of a given element type.
pair< XYZ, XYZ > GetAABB(double dGrowDistance=0) const
Get an axis aligned bounding box for the mesh.
void Clear()
Empty mesh nodes and indices.
void ConvertToSegmentMesh()
Convert all elements to segments.
Object container to help handle memory management issues.
CTextile * GetDeformedCopyOfTextile(CTextile &Textile, bool bDeformDomain=true)
virtual void DeformTextile(CTextile &Textile, bool bDeformDomain=true)
Represents a textile cell containing yarns.
const CDomain * GetDomain() const
const CYarn * GetYarn(int iIndex) const
Represents a yarn consisting of master nodes, section and interpolation function.
const CInterpolation * GetInterpolation() const
void AssignInterpolation(const CInterpolation &Interpolation)
Assign an interpolation function to the yarn.
bool PointInsideYarn(const XYZ &Point, XYZ *pTangent=NULL, XY *pLoc=NULL, double *pVolumeFraction=NULL, double *pDistanceToSurface=NULL, double dTolerance=1e-9, XYZ *pOrientation=NULL, XYZ *pUp=NULL, bool bSurface=false) const
Determine if the given point lies within the yarn (this function doesn't take the repeats into accoun...
Namespace containing a series of customised math operations not found in the standard c++ library.
XYZ GetBarycentricCoordinates(const XY &P1, const XY &P2, const XY &P3, const XY &P)
Get the barycentric coordinates of a point lying on a triangle.
XY Convert(const XYZ &Val)
double GetLength(const XYZ &Point1, const XYZ &Point2)
Get the length between two points.
double GetAdjustedThickness()
CElementTriBending BendingElement
CElementTriTension TensionElement
vector< RAISED_NODE > RaisedNodes
Struct for representing points in 3D space.