void WallTensionEstimatorCylindricalCoordinates<Mesh >::constructGlobalStressVector() { //Creating the local stress tensors VectorElemental elVecSigmaX (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() ); VectorElemental elVecSigmaY (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() ); VectorElemental elVecSigmaZ (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() ); LifeChrono chrono; //Constructing the patch area vector for reconstruction purposes solutionVect_Type patchArea (* (this->M_displacement), Unique, Add); patchArea *= 0.0; super::constructPatchAreaVector ( patchArea ); //Before assembling the reconstruction process is done solutionVect_Type patchAreaR (patchArea, Repeated); QuadratureRule fakeQuadratureRule; Real refElemArea (0); //area of reference element //compute the area of reference element for (UInt iq = 0; iq < this->M_FESpace->qr().nbQuadPt(); iq++) { refElemArea += this->M_FESpace->qr().weight (iq); } Real wQuad (refElemArea / this->M_FESpace->refFE().nbDof() ); //Setting the quadrature Points = DOFs of the element and weight = 1 std::vector<GeoVector> coords = this->M_FESpace->refFE().refCoor(); std::vector<Real> weights (this->M_FESpace->fe().nbFEDof(), wQuad); fakeQuadratureRule.setDimensionShape ( shapeDimension (this->M_FESpace->refFE().shape() ), this->M_FESpace->refFE().shape() ); fakeQuadratureRule.setPoints (coords, weights); //Set the new quadrature rule this->M_FESpace->setQuadRule (fakeQuadratureRule); this->M_displayer->leaderPrint (" \n*********************************\n "); this->M_displayer->leaderPrint (" Performing the analysis recovering the Cauchy stresses..., ", this->M_dataMaterial->solidType() ); this->M_displayer->leaderPrint (" \n*********************************\n "); UInt totalDof = this->M_FESpace->dof().numTotalDof(); VectorElemental dk_loc (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() ); //Vectors for the deformation tensor std::vector<matrix_Type> vectorDeformationF (this->M_FESpace->fe().nbFEDof(), * (this->M_deformationF) ); //Copying the displacement field into a vector with repeated map for parallel computations solutionVect_Type dRep (* (this->M_displacement), Repeated); chrono.start(); //Loop on each volume for ( UInt i = 0; i < this->M_FESpace->mesh()->numVolumes(); ++i ) { this->M_FESpace->fe().updateFirstDerivQuadPt ( this->M_FESpace->mesh()->volumeList ( i ) ); elVecSigmaX.zero(); elVecSigmaY.zero(); elVecSigmaZ.zero(); this->M_marker = this->M_FESpace->mesh()->volumeList ( i ).markerID(); UInt eleID = this->M_FESpace->fe().currentLocalId(); //Extracting the local displacement for ( UInt iNode = 0; iNode < ( UInt ) this->M_FESpace->fe().nbFEDof(); iNode++ ) { UInt iloc = this->M_FESpace->fe().patternFirst ( iNode ); for ( UInt iComp = 0; iComp < this->M_FESpace->fieldDim(); ++iComp ) { UInt ig = this->M_FESpace->dof().localToGlobalMap ( eleID, iloc ) + iComp * this->M_FESpace->dim() + this->M_offset; dk_loc[iloc + iComp * this->M_FESpace->fe().nbFEDof()] = dRep[ig]; } } //Compute the element tensor F AssemblyElementalStructure::computeLocalDeformationGradientWithoutIdentity ( dk_loc, vectorDeformationF, this->M_FESpace->fe() ); //Compute the local vector of the principal stresses for ( UInt nDOF = 0; nDOF < ( UInt ) this->M_FESpace->fe().nbFEDof(); nDOF++ ) { UInt iloc = this->M_FESpace->fe().patternFirst ( nDOF ); vector_Type localDisplacement (this->M_FESpace->fieldDim(), 0.0); for ( UInt coor = 0; coor < this->M_FESpace->fieldDim(); coor++ ) { localDisplacement[coor] = iloc + coor * this->M_FESpace->fe().nbFEDof(); } this->M_sigma->Scale (0.0); this->M_firstPiola->Scale (0.0); this->M_cofactorF->Scale (0.0); this->M_deformationCylindricalF->Scale (0.0); moveToCylindricalCoordinates (vectorDeformationF[nDOF], iloc, *M_deformationCylindricalF); //Compute the rightCauchyC tensor AssemblyElementalStructure::computeInvariantsRightCauchyGreenTensor (this->M_invariants, *M_deformationCylindricalF, * (this->M_cofactorF) ); //Compute the first Piola-Kirchhoff tensor this->M_material->computeLocalFirstPiolaKirchhoffTensor (* (this->M_firstPiola), *M_deformationCylindricalF, * (this->M_cofactorF), this->M_invariants, this->M_marker); //Compute the Cauchy tensor AssemblyElementalStructure::computeCauchyStressTensor (* (this->M_sigma), * (this->M_firstPiola), this->M_invariants[3], *M_deformationCylindricalF); //Assembling the local vectors for local tensions Component X for ( int coor = 0; coor < this->M_FESpace->fieldDim(); coor++ ) { (elVecSigmaX) [iloc + coor * this->M_FESpace->fe().nbFEDof()] = (* (this->M_sigma) ) (coor, 0); } //Assembling the local vectors for local tensions Component Y for ( int coor = 0; coor < this->M_FESpace->fieldDim(); coor++ ) { (elVecSigmaY) [iloc + coor * this->M_FESpace->fe().nbFEDof()] = (* (this->M_sigma) ) (coor, 1); } //Assembling the local vectors for local tensions Component Z for ( int coor = 0; coor < this->M_FESpace->fieldDim(); coor++ ) { (elVecSigmaZ) [iloc + coor * this->M_FESpace->fe().nbFEDof()] = (* (this->M_sigma) ) (coor, 2); } } super::reconstructElementaryVector ( elVecSigmaX, patchAreaR, *this->M_FESpace ); super::reconstructElementaryVector ( elVecSigmaY, patchAreaR, *this->M_FESpace ); super::reconstructElementaryVector ( elVecSigmaZ, patchAreaR, *this->M_FESpace ); //Assembling the three elemental vector in the three global for ( UInt ic = 0; ic < this->M_FESpace->fieldDim(); ++ic ) { assembleVector (*this->M_sigmaX, elVecSigmaX, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset + ic * totalDof ); assembleVector (*this->M_sigmaY, elVecSigmaY, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset + ic * totalDof ); assembleVector (*this->M_sigmaZ, elVecSigmaZ, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset + ic * totalDof ); } } this->M_sigmaX->globalAssemble(); this->M_sigmaY->globalAssemble(); this->M_sigmaZ->globalAssemble(); }
void WallTensionEstimatorCylindricalCoordinates<Mesh >::analyzeTensionsRecoveryEigenvaluesCylindrical ( void ) { LifeChrono chrono; this->M_displayer->leaderPrint (" \n*********************************\n "); this->M_displayer->leaderPrint (" Performing the analysis recovering the tensions..., ", this->M_dataMaterial->solidType() ); this->M_displayer->leaderPrint (" \n*********************************\n "); solutionVect_Type patchArea (* (this->M_displacement), Unique, Add); patchArea *= 0.0; super::constructPatchAreaVector ( patchArea ); //Before assembling the reconstruction process is done solutionVect_Type patchAreaR (patchArea, Repeated); QuadratureRule fakeQuadratureRule; Real refElemArea (0); //area of reference element //compute the area of reference element for (UInt iq = 0; iq < this->M_FESpace->qr().nbQuadPt(); iq++) { refElemArea += this->M_FESpace->qr().weight (iq); } Real wQuad (refElemArea / this->M_FESpace->refFE().nbDof() ); //Setting the quadrature Points = DOFs of the element and weight = 1 std::vector<GeoVector> coords = this->M_FESpace->refFE().refCoor(); std::vector<Real> weights (this->M_FESpace->fe().nbFEDof(), wQuad); fakeQuadratureRule.setDimensionShape ( shapeDimension (this->M_FESpace->refFE().shape() ), this->M_FESpace->refFE().shape() ); fakeQuadratureRule.setPoints (coords, weights); //Set the new quadrature rule this->M_FESpace->setQuadRule (fakeQuadratureRule); UInt totalDof = this->M_FESpace->dof().numTotalDof(); VectorElemental dk_loc (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() ); //Vectors for the deformation tensor std::vector<matrix_Type> vectorDeformationF (this->M_FESpace->fe().nbFEDof(), * (this->M_deformationF) ); //Copying the displacement field into a vector with repeated map for parallel computations solutionVect_Type dRep (* (this->M_displacement), Repeated); VectorElemental elVecTens (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() ); chrono.start(); //Loop on each volume for ( UInt i = 0; i < this->M_FESpace->mesh()->numVolumes(); ++i ) { this->M_FESpace->fe().updateFirstDerivQuadPt ( this->M_FESpace->mesh()->volumeList ( i ) ); elVecTens.zero(); this->M_marker = this->M_FESpace->mesh()->volumeList ( i ).markerID(); UInt eleID = this->M_FESpace->fe().currentLocalId(); //Extracting the local displacement for ( UInt iNode = 0; iNode < ( UInt ) this->M_FESpace->fe().nbFEDof(); iNode++ ) { UInt iloc = this->M_FESpace->fe().patternFirst ( iNode ); for ( UInt iComp = 0; iComp < this->M_FESpace->fieldDim(); ++iComp ) { UInt ig = this->M_FESpace->dof().localToGlobalMap ( eleID, iloc ) + iComp * this->M_FESpace->dim() + this->M_offset; dk_loc[iloc + iComp * this->M_FESpace->fe().nbFEDof()] = dRep[ig]; } } //Compute the element tensor F AssemblyElementalStructure::computeLocalDeformationGradientWithoutIdentity ( dk_loc, vectorDeformationF, this->M_FESpace->fe() ); //Compute the local vector of the principal stresses for ( UInt nDOF = 0; nDOF < ( UInt ) this->M_FESpace->fe().nbFEDof(); nDOF++ ) { UInt iloc = this->M_FESpace->fe().patternFirst ( nDOF ); vector_Type localDisplacement (this->M_FESpace->fieldDim(), 0.0); for ( UInt coor = 0; coor < this->M_FESpace->fieldDim(); coor++ ) { localDisplacement[coor] = iloc + coor * this->M_FESpace->fe().nbFEDof(); } this->M_sigma->Scale (0.0); this->M_firstPiola->Scale (0.0); this->M_cofactorF->Scale (0.0); M_deformationCylindricalF->Scale (0.0); moveToCylindricalCoordinates (vectorDeformationF[nDOF], iloc, *M_deformationCylindricalF); //Compute the rightCauchyC tensor AssemblyElementalStructure::computeInvariantsRightCauchyGreenTensor (this->M_invariants, *M_deformationCylindricalF, * (this->M_cofactorF) ); //Compute the first Piola-Kirchhoff tensor this->M_material->computeLocalFirstPiolaKirchhoffTensor (* (this->M_firstPiola), *M_deformationCylindricalF, * (this->M_cofactorF), this->M_invariants, this->M_marker); //Compute the Cauchy tensor AssemblyElementalStructure::computeCauchyStressTensor (* (this->M_sigma), * (this->M_firstPiola), this->M_invariants[3], *M_deformationCylindricalF); //Compute the eigenvalue AssemblyElementalStructure::computeEigenvalues (* (this->M_sigma), this->M_eigenvaluesR, this->M_eigenvaluesI); //The Cauchy tensor is symmetric and therefore, the eigenvalues are real //Check on the imaginary part of eigen values given by the Lapack method Real sum (0); for ( int i = 0; i < this->M_eigenvaluesI.size(); i++ ) { sum += std::abs (this->M_eigenvaluesI[i]); } ASSERT_PRE ( sum < 1e-6 , "The eigenvalues of the Cauchy stress tensors have to be real!" ); std::sort ( this->M_eigenvaluesR.begin(), this->M_eigenvaluesR.end() ); //Assembling the local vector for ( int coor = 0; coor < this->M_eigenvaluesR.size(); coor++ ) { elVecTens[iloc + coor * this->M_FESpace->fe().nbFEDof()] = this->M_eigenvaluesR[coor]; } } super::reconstructElementaryVector ( elVecTens, patchAreaR, *this->M_FESpace ); //Assembling the local into global vector for ( UInt ic = 0; ic < this->M_FESpace->fieldDim(); ++ic ) { assembleVector (* (this->M_globalEigenvalues), elVecTens, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset + ic * totalDof ); } } this->M_globalEigenvalues->globalAssemble(); chrono.stop(); this->M_displayer->leaderPrint ("Analysis done in: ", chrono.diff() ); }