LifeV
WallTensionEstimatorCylindricalCoordinates.hpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  * @file
29  * @brief This file contains a class which can be used to evaluate the wall tension in the arterial wall.
30  *
31  * @version 1.0
32  * @date 01-01-2010
33  * @author Paolo Tricerri
34  *
35  * @maintainer Paolo Tricerri <paolo.tricerri@epfl.ch>
36  *
37  */
38 
39 #ifndef WALLTENSIONCYLINDRICAL_H
40 #define WALLTENSIONCYLINDRICAL_H 1
41 
42 #include <string>
43 #include <sstream>
44 #include <iostream>
45 #include <stdexcept>
46 #include <boost/scoped_ptr.hpp>
47 #include <boost/multi_array.hpp>
48 
49 #pragma GCC diagnostic ignored "-Wunused-variable"
50 #pragma GCC diagnostic ignored "-Wunused-parameter"
51 
52 //Trilinos include
53 #include <Epetra_SerialDenseMatrix.h>
54 #include <iostream>
55 #pragma GCC diagnostic ignored "-Wunused-variable"
56 #pragma GCC diagnostic ignored "-Wunused-parameter"
57 
58 // LifeV core includes
59 #include <lifev/core/array/MatrixElemental.hpp>
60 #include <lifev/core/array/VectorElemental.hpp>
61 #include <lifev/core/array/MatrixEpetra.hpp>
62 #include <lifev/core/array/VectorEpetra.hpp>
63 
64 #include <lifev/core/fem/Assembly.hpp>
65 #include <lifev/core/fem/AssemblyElemental.hpp>
66 #include <lifev/core/fem/FESpace.hpp>
67 #include <lifev/core/LifeV.hpp>
68 #include <lifev/core/util/Displayer.hpp>
69 #include <lifev/core/array/MapEpetra.hpp>
70 
71 #include <lifev/core/filter/ExporterEnsight.hpp>
72 #ifdef HAVE_HDF5
73 #include <lifev/core/filter/ExporterHDF5.hpp>
74 #endif
75 #include <lifev/core/filter/ExporterEmpty.hpp>
76 
77 // Structure module include
78 #include <lifev/structure/fem/AssemblyElementalStructure.hpp>
79 #include <lifev/structure/solver/StructuralConstitutiveLawData.hpp>
80 
81 //Mother class
82 #include <lifev/structure/solver/WallTensionEstimatorData.hpp>
83 #include <lifev/structure/solver/WallTensionEstimator.hpp>
84 
85 namespace LifeV
86 {
87 /*!
88  \class WallTensionEstimator
89  \brief
90  This class lets to compute the wall tensions inside the arterial wall using the cylindrical coordinates
91  r, \theta, z. The tensorial operations
92  that are needed to compute the stress tensor are defined in AssemblyElementalStructure. When a new
93  type of analysis wants to be performed new methods can be added
94 */
95 
96 template <typename Mesh>
97 class WallTensionEstimatorCylindricalCoordinates : public WallTensionEstimator<Mesh>
98 {
99 public:
100 
101  //!@name Type definitions
102  //@{
103 
104  // Data classes
105  typedef WallTensionEstimator<Mesh> super;
106 
107  // Communicator
108  typedef typename super::comm_Type comm_Type;
109  typedef typename super::commPtr_Type commPtr_Type;
110 
111  // FE space
112  typedef typename super::feSpace_Type feSpace_Type;
114 
117 
119  typedef WallTensionEstimatorData analysisData_Type;
120  typedef typename std::shared_ptr<data_Type> dataPtr_Type;
122 
123  //Matrices 3x3 and std::vector for the invariants
128 
129  // These two are to handle the vector displacement read from hdf5
130  typedef VectorEpetra solutionVect_Type;
132 
133  // Displayer and Exporter classes
134  typedef typename std::shared_ptr<const Displayer> displayerPtr_Type;
135  typedef typename std::shared_ptr< Exporter<Mesh> > exporterPtr_Type;
136 
137  // Materials
138  typedef StructuralConstitutiveLaw<Mesh> material_Type;
140 
141  //@}
142 
143 
144  //! @name Constructor & Deconstructor
145  //@{
146 
148 
150 
151  //@}
152 
153 
154  //!@name Methods
155  //@{
156 
157  //! Setup the created object of the class WallTensionEstimatorCylindricalCoordinates
158  /*!
159  \param dataMaterial: the class containing the VenantKirchhoffElasticData
160  \param tensionData: the class containing the WallTensionEstimatorData
161  \param dFESpace: the FiniteElement Space
162  \param displayer: the displayer object
163  */
164  void setup ( const dataPtr_Type& dataMaterial,
165  const analysisDataPtr_Type& tensionData,
166  const feSpacePtr_Type& FESpace,
167  const feSpaceETPtr_Type& ETFESpace,
168  const commPtr_Type& comm,
169  UInt marker);
170 
171 
172 
173  //! Analyze Tensions: This method computes the Cauchy stress tensor and its principal values. It uses the displacement vector that has to be set
174  /*!
175  \param NONE FESpace<Mesh, MapEpetra>& copyFESpace
176  */
177  void analyzeTensions();
178 
179  //! Analyze Tensions: This method computes the Cauchy stress tensor and its principal values. It uses the displacement vector that has to be set
180  /*!
181  \param NONE
182  */
184 
185  //! Analyze Tensions: This method computes the Cauchy stress tensor and its principal values. It uses the displacement vector that has to be set
186  /*!
187  \param NONE
188  */
190 
191  //! Analyze Tensions: This method computes the Cauchy stress tensor and its principal values. It uses the displacement vector that has to be set
192  /*!
193  \param NONE
194  */
196 
197  //@}
198 
199 
200  //! @name Set Methods
201  //@{
202 
203  //@}
204 
205 
206  //! @name Get Methods
207  //@{
208 
209  //@}
210 
211 protected:
212 
213  //! @name Protected methods
214  //@{
215  //! moveToCylindricalCoordinates: This methods brings the gradient of the displacement field computed with respect to
216  //! the classical x,y,z reference system to the cylindrical one r, \theta, zeta
217  /*!
218  \param deformationF: the gradient of the displacement with respect to the normal coordinates x,y,z
219  \param deformationCylindricalF: the tensor F with respect to the second reference system
220  */
221 
222  void moveToCylindricalCoordinates (matrix_Type& gradientDispl,
223  UInt iloc,
224  matrix_Type& deformationCylindricalF);
225 
226  //! constructGlobalStressVector: This method construct the vectors \sigma_{.,i} for i=x,y,z to have for each DOF the tensor \sigma
227  /*!
228  \param NONE
229  */
231 
232  //@}
233 
234 
235  //! @name Protected members
236  //@{
237 
238  //! Elementary matrix for the tensor F
240 
241  //Construct the matrix of change of variables given the position of the DOF
243 
244  //@}
245 };
246 
247 //=====================================
248 // Constructor
249 //=====================================
250 
251 template <typename Mesh>
253  super( ),
256 {
257 
258 }
259 
260 
261 
262 //====================================
263 // Public Methods
264 //===================================
265 template <typename Mesh>
266 void
267 WallTensionEstimatorCylindricalCoordinates<Mesh >::setup ( const dataPtr_Type& dataMaterial,
268  const analysisDataPtr_Type& tensionData,
269  const feSpacePtr_Type& FESpace,
270  const feSpaceETPtr_Type& ETFESpace,
271  const commPtr_Type& comm,
272  UInt marker )
273 {
274  super::setup (dataMaterial, tensionData, FESpace, ETFESpace, comm, marker);
275  M_deformationCylindricalF.reset ( new matrix_Type ( this->M_FESpace->fieldDim(), this->M_FESpace->fieldDim() ) );
276  M_changeOfVariableMatrix.reset ( new matrix_Type (this->M_FESpace->fieldDim(), this->M_FESpace->fieldDim() ) );
277 }
278 
279 template <typename Mesh>
280 void
282 {
283  //Initialize the global vector to zero
284  * (this->M_globalEigenvalues) *= 0.0;
285  if ( !this->M_analysisData->recoveryVariable().compare ("displacement") )
286  {
288  }
289  else if ( !this->M_analysisData->recoveryVariable().compare ("eigenvalues") )
290  {
292  }
293  else
294  {
296  }
297 }
298 
299 template <typename Mesh>
300 void
302 {
303 
304  LifeChrono chrono;
305 
306  this->M_displayer->leaderPrint (" \n*********************************\n ");
307  this->M_displayer->leaderPrint (" Performing the analysis recovering the displacement..., ", this->M_dataMaterial->solidTypeIsotropic() );
308  this->M_displayer->leaderPrint (" \n*********************************\n ");
309 
310  solutionVectPtr_Type grDisplX ( new solutionVect_Type (* (this->M_FESpace->mapPtr() ) ) );
311  solutionVectPtr_Type grDisplY ( new solutionVect_Type (* (this->M_FESpace->mapPtr() ) ) );
312  solutionVectPtr_Type grDisplZ ( new solutionVect_Type (* (this->M_FESpace->mapPtr() ) ) );
313 
314  //Compute the deformation gradient tensor F of the displ field
315  super::computeDisplacementGradient ( grDisplX, grDisplY, grDisplZ);
316 
317  solutionVect_Type grXRep (*grDisplX, Repeated);
318  solutionVect_Type grYRep (*grDisplY, Repeated);
319  solutionVect_Type grZRep (*grDisplZ, Repeated);
320  solutionVect_Type dRep (* (this->M_displacement), Repeated);
321 
322  //For each of the DOF, the Cauchy tensor is computed.
323  //Therefore the tensor C,P, \sigma are computed for each DOF
324 
325  chrono.start();
326 
327  for ( UInt i (0); i < this->M_FESpace->mesh()->numVolumes(); ++i )
328  {
329 
330  //Setup quantities
331  this->M_FESpace->fe().updateFirstDerivQuadPt ( this->M_FESpace->mesh()->volumeList ( i ) );
332  UInt eleID = this->M_FESpace->fe().currentLocalId();
333  this->M_marker = this->M_FESpace->mesh()->volumeList ( i ).markerID();
334 
335  //store the local \grad(u)
336  matrix_Type gradientDispl ( this->M_FESpace->fieldDim(), this->M_FESpace->fieldDim() );
337  gradientDispl.Scale ( 0.0 );
338 
339  //Extracting the local displacement
340  for ( UInt iNode = 0; iNode < ( UInt ) this->M_FESpace->fe().nbFEDof(); iNode++ )
341  {
342  UInt iloc = this->M_FESpace->fe().patternFirst ( iNode );
343 
344  for ( UInt iComp = 0; iComp < this->M_FESpace->fieldDim(); ++iComp )
345  {
346  UInt ig = this->M_FESpace->dof().localToGlobalMap ( eleID, iloc ) + iComp * this->M_FESpace->dim() + this->M_offset;
347 
348  gradientDispl (iComp, 0) = grXRep[ig];
349  gradientDispl (iComp, 1) = grYRep[ig];
350  gradientDispl (iComp, 2) = grZRep[ig];
351  }
352 
353  //Reinitialization of matrices and arrays
354  ( * (this->M_cofactorF) ).Scale (0.0);
355  ( * (this->M_firstPiola) ).Scale (0.0);
356  ( * (this->M_sigma) ).Scale (0.0);
357 
358  //Moving to cylindrical coordinates
359  moveToCylindricalCoordinates ( gradientDispl, iloc, *M_deformationCylindricalF );
360 
361  //Compute the rightCauchyC tensor
362  AssemblyElementalStructure::computeInvariantsRightCauchyGreenTensor (this->M_invariants, *M_deformationCylindricalF, * (this->M_cofactorF) );
363 
364  //Compute the first Piola-Kirchhoff tensor
365  this->M_material->computeLocalFirstPiolaKirchhoffTensor (* (this->M_firstPiola), *M_deformationCylindricalF, * (this->M_cofactorF), this->M_invariants, this->M_marker);
366 
367  //Compute the Cauchy tensor
368  AssemblyElementalStructure::computeCauchyStressTensor (* (this->M_sigma), * (this->M_firstPiola), this->M_invariants[3], *M_deformationCylindricalF);
369 
370  //Compute the eigenvalue
371  AssemblyElementalStructure::computeEigenvalues (* (this->M_sigma), this->M_eigenvaluesR, this->M_eigenvaluesI);
372 
373  //The Cauchy tensor is symmetric and therefore, the eigenvalues are real
374  //Check on the imaginary part of eigen values given by the Lapack method
375  Real sum (0);
376  for ( UInt j (0); j < this->M_eigenvaluesI.size(); ++j )
377  {
378  sum += std::abs ( this->M_eigenvaluesI[j] );
379  }
380 
381  ASSERT ( sum < 1e-6 , "The eigenvalues of the Cauchy stress tensors have to be real!" );
382 
383  std::sort ( this->M_eigenvaluesR.begin(), this->M_eigenvaluesR.end() );
384 
385  std::cout << "Saving eigenvalues" << i << std::endl;
386 
387  //Save the eigenvalues in the global vector
388  for ( UInt icoor = 0; icoor < this->M_FESpace->fieldDim(); ++icoor )
389  {
390  UInt ig = this->M_FESpace->dof().localToGlobalMap ( eleID, iloc ) + icoor * this->M_FESpace->dim() + this->M_offset;
391  (* (this->M_globalEigenvalues) ) (ig) = this->M_eigenvaluesR[icoor];
392  // Int LIDid = this->M_displacement->blockMap().LID(ig);
393  // if( this->M_globalEigenvalues->blockMap().LID(ig) != -1 )
394  // {
395  // Int GIDid = this->M_globalEigenvalues->blockMap().GID(LIDid);
396 
397  // }
398  }
399  }
400  }
401 
402  chrono.stop();
403  this->M_displayer->leaderPrint ("Analysis done in: ", chrono.diff() );
404 
405 }
406 
407 
408 template <typename Mesh>
409 void
411 {
412 
413  LifeChrono chrono;
414 
415  this->M_displayer->leaderPrint (" \n*********************************\n ");
416  this->M_displayer->leaderPrint (" Performing the analysis recovering the tensions..., ", this->M_dataMaterial->solidTypeIsotropic() );
417  this->M_displayer->leaderPrint (" \n*********************************\n ");
418 
419  solutionVect_Type patchArea (* (this->M_displacement), Unique, Add);
420  patchArea *= 0.0;
421 
422  super::constructPatchAreaVector ( patchArea );
423 
424  //Before assembling the reconstruction process is done
425  solutionVect_Type patchAreaR (patchArea, Repeated);
426 
427  QuadratureRule fakeQuadratureRule;
428 
429  Real refElemArea (0); //area of reference element
430  //compute the area of reference element
431  for (UInt iq = 0; iq < this->M_FESpace->qr().nbQuadPt(); iq++)
432  {
433  refElemArea += this->M_FESpace->qr().weight (iq);
434  }
435 
436  Real wQuad (refElemArea / this->M_FESpace->refFE().nbDof() );
437 
438  //Setting the quadrature Points = DOFs of the element and weight = 1
439  std::vector<GeoVector> coords = this->M_FESpace->refFE().refCoor();
440  std::vector<Real> weights (this->M_FESpace->fe().nbFEDof(), wQuad);
441  fakeQuadratureRule.setDimensionShape ( shapeDimension (this->M_FESpace->refFE().shape() ), this->M_FESpace->refFE().shape() );
442  fakeQuadratureRule.setPoints (coords, weights);
443 
444  //Set the new quadrature rule
445  this->M_FESpace->setQuadRule (fakeQuadratureRule);
446 
447  UInt totalDof = this->M_FESpace->dof().numTotalDof();
448  VectorElemental dk_loc (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );
449 
450  //Vectors for the deformation tensor
451  std::vector<matrix_Type> vectorDeformationF (this->M_FESpace->fe().nbFEDof(), * (this->M_deformationF) );
452  //Copying the displacement field into a vector with repeated map for parallel computations
453  solutionVect_Type dRep (* (this->M_displacement), Repeated);
454 
455  VectorElemental elVecTens (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );
456 
457  chrono.start();
458 
459  //Loop on each volume
460  for ( UInt i = 0; i < this->M_FESpace->mesh()->numVolumes(); ++i )
461  {
462  this->M_FESpace->fe().updateFirstDerivQuadPt ( this->M_FESpace->mesh()->volumeList ( i ) );
463  elVecTens.zero();
464 
465  this->M_marker = this->M_FESpace->mesh()->volumeList ( i ).markerID();
466 
467  UInt eleID = this->M_FESpace->fe().currentLocalId();
468 
469  //Extracting the local displacement
470  for ( UInt iNode = 0; iNode < ( UInt ) this->M_FESpace->fe().nbFEDof(); iNode++ )
471  {
472  UInt iloc = this->M_FESpace->fe().patternFirst ( iNode );
473 
474  for ( UInt iComp = 0; iComp < this->M_FESpace->fieldDim(); ++iComp )
475  {
476  UInt ig = this->M_FESpace->dof().localToGlobalMap ( eleID, iloc ) + iComp * this->M_FESpace->dim() + this->M_offset;
477  dk_loc[iloc + iComp * this->M_FESpace->fe().nbFEDof()] = dRep[ig];
478  }
479  }
480 
481  //Compute the element tensor F
482  AssemblyElementalStructure::computeLocalDeformationGradientWithoutIdentity ( dk_loc, vectorDeformationF, this->M_FESpace->fe() );
483 
484  //Compute the local vector of the principal stresses
485  for ( UInt nDOF = 0; nDOF < ( UInt ) this->M_FESpace->fe().nbFEDof(); nDOF++ )
486  {
487  UInt iloc = this->M_FESpace->fe().patternFirst ( nDOF );
488  vector_Type localDisplacement (this->M_FESpace->fieldDim(), 0.0);
489 
490  for ( UInt coor = 0; coor < this->M_FESpace->fieldDim(); coor++ )
491  {
492  localDisplacement[coor] = iloc + coor * this->M_FESpace->fe().nbFEDof();
493  }
494 
495  this->M_sigma->Scale (0.0);
496  this->M_firstPiola->Scale (0.0);
497  this->M_cofactorF->Scale (0.0);
498  M_deformationCylindricalF->Scale (0.0);
499 
500  moveToCylindricalCoordinates (vectorDeformationF[nDOF], iloc, *M_deformationCylindricalF);
501 
502  //Compute the rightCauchyC tensor
503  AssemblyElementalStructure::computeInvariantsRightCauchyGreenTensor (this->M_invariants, *M_deformationCylindricalF, * (this->M_cofactorF) );
504 
505  //Compute the first Piola-Kirchhoff tensor
506  this->M_material->computeLocalFirstPiolaKirchhoffTensor (* (this->M_firstPiola), *M_deformationCylindricalF, * (this->M_cofactorF), this->M_invariants, this->M_marker);
507 
508  //Compute the Cauchy tensor
509  AssemblyElementalStructure::computeCauchyStressTensor (* (this->M_sigma), * (this->M_firstPiola), this->M_invariants[3], *M_deformationCylindricalF);
510 
511  //Compute the eigenvalue
512  AssemblyElementalStructure::computeEigenvalues (* (this->M_sigma), this->M_eigenvaluesR, this->M_eigenvaluesI);
513 
514  //The Cauchy tensor is symmetric and therefore, the eigenvalues are real
515  //Check on the imaginary part of eigen values given by the Lapack method
516  Real sum (0);
517  for ( int i = 0; i < this->M_eigenvaluesI.size(); i++ )
518  {
519  sum += std::abs (this->M_eigenvaluesI[i]);
520  }
521  ASSERT_PRE ( sum < 1e-6 , "The eigenvalues of the Cauchy stress tensors have to be real!" );
522 
523  std::sort ( this->M_eigenvaluesR.begin(), this->M_eigenvaluesR.end() );
524 
525  //Assembling the local vector
526  for ( int coor = 0; coor < this->M_eigenvaluesR.size(); coor++ )
527  {
528  elVecTens[iloc + coor * this->M_FESpace->fe().nbFEDof()] = this->M_eigenvaluesR[coor];
529  }
530  }
531 
532  super::reconstructElementaryVector ( elVecTens, patchAreaR, *this->M_FESpace );
533 
534  //Assembling the local into global vector
535  for ( UInt ic = 0; ic < this->M_FESpace->fieldDim(); ++ic )
536  {
537  assembleVector (* (this->M_globalEigenvalues), elVecTens, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset + ic * totalDof );
538  }
539  }
540 
541  this->M_globalEigenvalues->globalAssemble();
542 
543  chrono.stop();
544  this->M_displayer->leaderPrint ("Analysis done in: ", chrono.diff() );
545 }
546 
547 template <typename Mesh>
548 void
550 {
551 
552  LifeChrono chrono;
553 
554  chrono.start();
555  UInt dim = this->M_FESpace->dim();
556 
558 
559 
560  for ( UInt iDOF = 0; iDOF < ( UInt ) this->M_FESpace->dof().numTotalDof(); iDOF++ )
561  {
562 
563  if ( this->M_displacement->blockMap().LID ( static_cast<EpetraInt_Type> (iDOF) ) != -1 ) // The Global ID is on the calling processors
564  {
565 
566  (* (this->M_sigma) ).Scale (0.0);
567 
568  //Extracting the gradient of U on the current DOF
569  for ( UInt iComp = 0; iComp < this->M_FESpace->fieldDim(); ++iComp )
570  {
571  Int LIDid = this->M_displacement->blockMap().LID ( static_cast<EpetraInt_Type> (iDOF + iComp * dim + this->M_offset ) );
572  Int GIDid = this->M_displacement->blockMap().GID (static_cast<EpetraInt_Type> (LIDid) );
573  (* (this->M_sigma) ) (iComp, 0) = (*this->M_sigmaX) (GIDid); // (d_xX,d_yX,d_zX)
574  (* (this->M_sigma) ) (iComp, 1) = (*this->M_sigmaY) (GIDid); // (d_xY,d_yY,d_zY)
575  (* (this->M_sigma) ) (iComp, 2) = (*this->M_sigmaZ) (GIDid); // (d_xZ,d_yZ,d_zZ)
576  }
577 
578  //Compute the eigenvalue
579  AssemblyElementalStructure::computeEigenvalues (* (this->M_sigma), this->M_eigenvaluesR, this->M_eigenvaluesI);
580 
581  //The Cauchy tensor is symmetric and therefore, the eigenvalues are real
582  //Check on the imaginary part of eigen values given by the Lapack method
583  Real sum (0);
584  for ( int i = 0; i < this->M_eigenvaluesI.size(); i++ )
585  {
586  sum += std::abs (this->M_eigenvaluesI[i]);
587  }
588  ASSERT_PRE ( sum < 1e-6 , "The eigenvalues of the Cauchy stress tensors have to be real!" );
589 
590  std::sort ( this->M_eigenvaluesR.begin(), this->M_eigenvaluesR.end() );
591 
592  //Save the eigenvalues in the global vector
593  for ( UInt icoor = 0; icoor < this->M_FESpace->fieldDim(); ++icoor )
594  {
595  Int LIDid = this->M_displacement->blockMap().LID ( static_cast<EpetraInt_Type> (iDOF + icoor * dim + this->M_offset) );
596  Int GIDid = this->M_displacement->blockMap().GID (static_cast<EpetraInt_Type> (LIDid) );
597  (* (this->M_globalEigenvalues) ) (GIDid) = this->M_eigenvaluesR[icoor];
598  }
599 
600  }
601  }
602 
603  chrono.stop();
604  this->M_displayer->leaderPrint ("Analysis done in: ", chrono.diff() );
605 
606 }
607 
608 template <typename Mesh>
609 void
611 {
612 
613  //Creating the local stress tensors
614  VectorElemental elVecSigmaX (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );
615  VectorElemental elVecSigmaY (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );
616  VectorElemental elVecSigmaZ (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );
617 
618  LifeChrono chrono;
619 
620  //Constructing the patch area vector for reconstruction purposes
621  solutionVect_Type patchArea (* (this->M_displacement), Unique, Add);
622  patchArea *= 0.0;
623 
624  super::constructPatchAreaVector ( patchArea );
625 
626  //Before assembling the reconstruction process is done
627  solutionVect_Type patchAreaR (patchArea, Repeated);
628 
629  QuadratureRule fakeQuadratureRule;
630 
631  Real refElemArea (0); //area of reference element
632  //compute the area of reference element
633  for (UInt iq = 0; iq < this->M_FESpace->qr().nbQuadPt(); iq++)
634  {
635  refElemArea += this->M_FESpace->qr().weight (iq);
636  }
637 
638  Real wQuad (refElemArea / this->M_FESpace->refFE().nbDof() );
639 
640  //Setting the quadrature Points = DOFs of the element and weight = 1
641  std::vector<GeoVector> coords = this->M_FESpace->refFE().refCoor();
642  std::vector<Real> weights (this->M_FESpace->fe().nbFEDof(), wQuad);
643  fakeQuadratureRule.setDimensionShape ( shapeDimension (this->M_FESpace->refFE().shape() ), this->M_FESpace->refFE().shape() );
644  fakeQuadratureRule.setPoints (coords, weights);
645 
646  //Set the new quadrature rule
647  this->M_FESpace->setQuadRule (fakeQuadratureRule);
648 
649  this->M_displayer->leaderPrint (" \n*********************************\n ");
650  this->M_displayer->leaderPrint (" Performing the analysis recovering the Cauchy stresses..., ", this->M_dataMaterial->solidTypeIsotropic() );
651  this->M_displayer->leaderPrint (" \n*********************************\n ");
652 
653  UInt totalDof = this->M_FESpace->dof().numTotalDof();
654  VectorElemental dk_loc (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );
655 
656  //Vectors for the deformation tensor
657  std::vector<matrix_Type> vectorDeformationF (this->M_FESpace->fe().nbFEDof(), * (this->M_deformationF) );
658  //Copying the displacement field into a vector with repeated map for parallel computations
659  solutionVect_Type dRep (* (this->M_displacement), Repeated);
660 
661  chrono.start();
662 
663  //Loop on each volume
664  for ( UInt i = 0; i < this->M_FESpace->mesh()->numVolumes(); ++i )
665  {
666  this->M_FESpace->fe().updateFirstDerivQuadPt ( this->M_FESpace->mesh()->volumeList ( i ) );
667 
668  elVecSigmaX.zero();
669  elVecSigmaY.zero();
670  elVecSigmaZ.zero();
671 
672  this->M_marker = this->M_FESpace->mesh()->volumeList ( i ).markerID();
673 
674  UInt eleID = this->M_FESpace->fe().currentLocalId();
675 
676  //Extracting the local displacement
677  for ( UInt iNode = 0; iNode < ( UInt ) this->M_FESpace->fe().nbFEDof(); iNode++ )
678  {
679  UInt iloc = this->M_FESpace->fe().patternFirst ( iNode );
680 
681  for ( UInt iComp = 0; iComp < this->M_FESpace->fieldDim(); ++iComp )
682  {
683  UInt ig = this->M_FESpace->dof().localToGlobalMap ( eleID, iloc ) + iComp * this->M_FESpace->dim() + this->M_offset;
684  dk_loc[iloc + iComp * this->M_FESpace->fe().nbFEDof()] = dRep[ig];
685  }
686  }
687 
688  //Compute the element tensor F
689  AssemblyElementalStructure::computeLocalDeformationGradientWithoutIdentity ( dk_loc, vectorDeformationF, this->M_FESpace->fe() );
690 
691  //Compute the local vector of the principal stresses
692  for ( UInt nDOF = 0; nDOF < ( UInt ) this->M_FESpace->fe().nbFEDof(); nDOF++ )
693  {
694  UInt iloc = this->M_FESpace->fe().patternFirst ( nDOF );
695 
696  vector_Type localDisplacement (this->M_FESpace->fieldDim(), 0.0);
697 
698  for ( UInt coor = 0; coor < this->M_FESpace->fieldDim(); coor++ )
699  {
700  localDisplacement[coor] = iloc + coor * this->M_FESpace->fe().nbFEDof();
701  }
702 
703  this->M_sigma->Scale (0.0);
704  this->M_firstPiola->Scale (0.0);
705  this->M_cofactorF->Scale (0.0);
706  this->M_deformationCylindricalF->Scale (0.0);
707 
708  moveToCylindricalCoordinates (vectorDeformationF[nDOF], iloc, *M_deformationCylindricalF);
709 
710  //Compute the rightCauchyC tensor
711  AssemblyElementalStructure::computeInvariantsRightCauchyGreenTensor (this->M_invariants, *M_deformationCylindricalF, * (this->M_cofactorF) );
712 
713  //Compute the first Piola-Kirchhoff tensor
714  this->M_material->computeLocalFirstPiolaKirchhoffTensor (* (this->M_firstPiola), *M_deformationCylindricalF, * (this->M_cofactorF), this->M_invariants, this->M_marker);
715 
716  //Compute the Cauchy tensor
717  AssemblyElementalStructure::computeCauchyStressTensor (* (this->M_sigma), * (this->M_firstPiola), this->M_invariants[3], *M_deformationCylindricalF);
718 
719  //Assembling the local vectors for local tensions Component X
720  for ( int coor = 0; coor < this->M_FESpace->fieldDim(); coor++ )
721  {
722  (elVecSigmaX) [iloc + coor * this->M_FESpace->fe().nbFEDof()] = (* (this->M_sigma) ) (coor, 0);
723  }
724 
725  //Assembling the local vectors for local tensions Component Y
726  for ( int coor = 0; coor < this->M_FESpace->fieldDim(); coor++ )
727  {
728  (elVecSigmaY) [iloc + coor * this->M_FESpace->fe().nbFEDof()] = (* (this->M_sigma) ) (coor, 1);
729  }
730 
731  //Assembling the local vectors for local tensions Component Z
732  for ( int coor = 0; coor < this->M_FESpace->fieldDim(); coor++ )
733  {
734  (elVecSigmaZ) [iloc + coor * this->M_FESpace->fe().nbFEDof()] = (* (this->M_sigma) ) (coor, 2);
735  }
736 
737  }
738 
739  super::reconstructElementaryVector ( elVecSigmaX, patchAreaR, *this->M_FESpace );
740  super::reconstructElementaryVector ( elVecSigmaY, patchAreaR, *this->M_FESpace );
741  super::reconstructElementaryVector ( elVecSigmaZ, patchAreaR, *this->M_FESpace );
742 
743  //Assembling the three elemental vector in the three global
744  for ( UInt ic = 0; ic < this->M_FESpace->fieldDim(); ++ic )
745  {
746  assembleVector (*this->M_sigmaX, elVecSigmaX, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset + ic * totalDof );
747  assembleVector (*this->M_sigmaY, elVecSigmaY, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset + ic * totalDof );
748  assembleVector (*this->M_sigmaZ, elVecSigmaZ, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset + ic * totalDof );
749  }
750  }
751 
752 
753  this->M_sigmaX->globalAssemble();
754  this->M_sigmaY->globalAssemble();
755  this->M_sigmaZ->globalAssemble();
756 }
757 
758 template <typename Mesh>
759 void
761  UInt iloc,
762  matrix_Type& deformationCylindricalF)
763 {
764  //Reinitialize
765  (*M_changeOfVariableMatrix).Scale ( 0.0 );
766  (*M_deformationCylindricalF).Scale ( 0.0 );
767 
768  //Extracting the coordinates of the iloc DOF on the reference element
769  Real xi ( this->M_FESpace->refFE().xi (iloc) );
770  Real eta ( this->M_FESpace->refFE().eta (iloc) );
771  Real zeta ( this->M_FESpace->refFE().zeta (iloc) );
772  //Trasforming them in the local coordinates
773  Real x (0);
774  Real y (0);
775  Real z (0);
776  this->M_FESpace->fe().coorMap (x, y, z, xi, eta, zeta);
777 
778  // Defining the new variables
779  //Real radius= std::sqrt( x*x + y*y );
780  Real theta = std::atan ( y / x );
781 
782  //Filling the change of variable Matrix and its derivative with respect to theta
783  (*M_changeOfVariableMatrix) (0, 0) = std::cos (theta);
784  (*M_changeOfVariableMatrix) (1, 0) = - std::sin (theta);
785  (*M_changeOfVariableMatrix) (2, 0) = 0.0;
786  (*M_changeOfVariableMatrix) (0, 1) = std::sin (theta);
787  (*M_changeOfVariableMatrix) (1, 1) = std::cos (theta);
788  (*M_changeOfVariableMatrix) (2, 1) = 0.0;
789  (*M_changeOfVariableMatrix) (0, 2) = 0.0;
790  (*M_changeOfVariableMatrix) (1, 2) = 0.0;
791  (*M_changeOfVariableMatrix) (2, 2) = 1.0;
792 
793  //Move to cylindrical gradient at the DOF
794  deformationCylindricalF.Multiply ('N', 'T', 1.0, gradientDispl, *M_changeOfVariableMatrix, 0.0 );
795 
796  //Add the identity
797  for ( Int icoor (0); icoor < this->M_FESpace->fieldDim(); icoor++ )
798  {
799  deformationCylindricalF ( icoor, icoor ) += 1.0;
800  }
801 
802 }
803 
804 }
805 
806 #endif /*WALLTENSIONCYLINDRICAL_H 1*/
matrixPtr_Type M_deformationCylindricalF
Elementary matrix for the tensor F.
void setup(const dataPtr_Type &dataMaterial, const analysisDataPtr_Type &tensionData, const feSpacePtr_Type &FESpace, const feSpaceETPtr_Type &ETFESpace, const commPtr_Type &comm, UInt marker)
Setup the created object of the class WallTensionEstimatorCylindricalCoordinates. ...
void setDimensionShape(const UInt &newDim, const ReferenceShapes &newShape)
Change the dimension and the shape.
void analyzeTensions()
Analyze Tensions: This method computes the Cauchy stress tensor and its principal values...
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
#define ASSERT_PRE(X, A)
Definition: LifeAssert.hpp:96
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
void analyzeTensionsRecoveryCauchyStressesCylindrical()
Analyze Tensions: This method computes the Cauchy stress tensor and its principal values...
void analyzeTensionsRecoveryEigenvaluesCylindrical()
Analyze Tensions: This method computes the Cauchy stress tensor and its principal values...
void analyzeTensionsRecoveryDisplacementCylindrical()
Analyze Tensions: This method computes the Cauchy stress tensor and its principal values...
double Real
Generic real data.
Definition: LifeV.hpp:175
QuadratureRule - The basis class for storing and accessing quadrature rules.
DataElasticStructure - Data container for solid problems with elastic structure.
void moveToCylindricalCoordinates(matrix_Type &gradientDispl, UInt iloc, matrix_Type &deformationCylindricalF)
moveToCylindricalCoordinates: This methods brings the gradient of the displacement field computed wit...
int EpetraInt_Type
Epetra int type (can be int or long long, accordingly to release notes)
Definition: LifeV.hpp:200
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
void constructGlobalStressVector()
constructGlobalStressVector: This method construct the vectors {.,i} for i=x,y,z to have for each DOF...