42 #ifndef _STRUCTURALOPERATOR_H_ 43 #define _STRUCTURALOPERATOR_H_ 1
46 #include <Epetra_Vector.h> 47 #include <EpetraExt_MatrixMatrix.h> 50 #include <lifev/core/util/LifeChrono.hpp> 51 #include <lifev/core/util/Displayer.hpp> 53 #include <lifev/core/array/MatrixElemental.hpp> 54 #include <lifev/core/array/VectorElemental.hpp> 55 #include <lifev/core/array/MatrixEpetra.hpp> 56 #include <lifev/core/array/VectorEpetra.hpp> 58 #include <lifev/core/fem/AssemblyElemental.hpp> 59 #include <lifev/structure/fem/AssemblyElementalStructure.hpp> 60 #include <lifev/core/fem/Assembly.hpp> 61 #include <lifev/core/fem/BCManage.hpp> 62 #include <lifev/core/fem/FESpace.hpp> 64 #include <lifev/core/mesh/MeshEntityContainer.hpp> 66 #include <lifev/core/algorithm/NonLinearRichardson.hpp> 68 #include <lifev/structure/solver/StructuralConstitutiveLawData.hpp> 69 #include <lifev/structure/solver/StructuralConstitutiveLaw.hpp> 71 #include <Epetra_SerialDenseMatrix.h> 75 #include <Teuchos_ParameterList.hpp> 76 #include <Teuchos_XMLParameterListHelpers.hpp> 77 #include <Teuchos_RCP.hpp> 78 #include <lifev/core/algorithm/PreconditionerIfpack.hpp> 79 #include <lifev/core/algorithm/PreconditionerML.hpp> 80 #include <lifev/core/algorithm/LinearSolver.hpp> 84 #include <lifev/eta/fem/ETFESpace.hpp> 85 #include <lifev/eta/expression/Integrate.hpp> 86 #include <lifev/eta/expression/Evaluate.hpp> 89 #include <lifev/core/fem/TimeAdvance.hpp> 90 #include <lifev/core/fem/TimeAdvanceNewmark.hpp> 91 #include <lifev/core/fem/TimeAdvanceBDF.hpp> 101 template <
typename MeshEntityType,
102 typename ComparisonPolicyType = std::function <
bool (
108 typedef MeshEntityType meshEntity_Type;
109 typedef ComparisonPolicyType comparisonPolicy_Type;
111 MarkerSelector (
const UInt materialFlagReference,
112 comparisonPolicy_Type
const& policy = std::equal_to<UInt>() )
113 : M_reference ( materialFlagReference ),
114 M_policy ( policy ) {}
116 bool operator() (
const meshEntity_Type& entity )
const 119 UInt flagChecked = entity.markerID();
121 return M_policy ( flagChecked, M_reference );
126 const comparisonPolicy_Type M_policy;
132 class sourceVectorialFunctor
135 typedef std::function<VectorSmall<3> ( Real
const&, Real
const&, Real
const&, Real
const& ) > volumeForce_Type;
136 typedef std::shared_ptr<volumeForce_Type > volumeForcePtr_Type;
139 sourceVectorialFunctor (
const volumeForcePtr_Type volumeSource )
140 : M_volumeSource ( volumeSource ), M_currentTime( 0.0 )
143 void setCurrentTime(
const Real time )
145 M_currentTime = time;
151 return (*M_volumeSource)( M_currentTime, spaceCoordinates[0], spaceCoordinates[1], spaceCoordinates[2] );
155 volumeForcePtr_Type M_volumeSource;
166 template <
typename Mesh>
167 class StructuralOperator
174 typedef std::function<Real ( Real
const&, Real
const&, Real
const&, Real
const&, ID
const& ) > source_Type;
176 typedef StructuralConstitutiveLaw<Mesh> material_Type;
177 typedef std::shared_ptr<material_Type> materialPtr_Type;
179 typedef BCHandler bcHandlerRaw_Type;
180 typedef std::shared_ptr<bcHandlerRaw_Type> bcHandler_Type;
182 typedef LinearSolver solver_Type;
184 typedef typename solver_Type::matrix_Type matrix_Type;
185 typedef std::shared_ptr<matrix_Type> matrixPtr_Type;
186 typedef typename solver_Type::vector_Type vector_Type;
187 typedef std::shared_ptr<vector_Type> vectorPtr_Type;
188 typedef vector_Type solution_Type;
189 typedef std::shared_ptr<solution_Type> solutionPtr_Type;
193 typedef RegionMesh<LinearTetra > mesh_Type;
194 typedef std::vector< mesh_Type::element_Type* > vectorVolumes_Type;
195 typedef std::vector< UInt > vectorIndexes_Type;
197 typedef std::map< UInt, vectorVolumes_Type> mapMarkerVolumes_Type;
198 typedef std::map< UInt, vectorIndexes_Type> mapMarkerIndexes_Type;
199 typedef std::shared_ptr<mapMarkerVolumes_Type> mapMarkerVolumesPtr_Type;
200 typedef std::shared_ptr<mapMarkerIndexes_Type> mapMarkerIndexesPtr_Type;
201 typedef mapMarkerVolumes_Type::const_iterator mapIterator_Type;
203 typedef typename mesh_Type::element_Type meshEntity_Type;
205 typedef typename std::function<
bool (
const UInt,
const UInt) > comparisonPolicy_Type;
207 typedef MarkerSelector<meshEntity_Type, comparisonPolicy_Type> markerSelector_Type;
208 typedef std::unique_ptr<markerSelector_Type> markerSelectorPtr_Type;
210 typedef ETFESpace< RegionMesh<LinearTetra>, MapEpetra, 3, 3 > ETFESpace_Type;
211 typedef std::shared_ptr<ETFESpace_Type> ETFESpacePtr_Type;
213 typedef FESpace< RegionMesh<LinearTetra>, MapEpetra > FESpace_Type;
214 typedef std::shared_ptr<FESpace_Type> FESpacePtr_Type;
217 typedef LifeV::Preconditioner basePrec_Type;
218 typedef std::shared_ptr<basePrec_Type> basePrecPtr_Type;
219 typedef LifeV::PreconditionerIfpack precIfpack_Type;
220 typedef std::shared_ptr<precIfpack_Type> precIfpackPtr_Type;
221 typedef LifeV::PreconditionerML precML_Type;
222 typedef std::shared_ptr<precML_Type> precMLPtr_Type;
225 typedef TimeAdvance< vector_Type > timeAdvance_Type;
226 typedef std::shared_ptr< timeAdvance_Type > timeAdvancePtr_Type;
228 typedef Epetra_SerialDenseMatrix matrixSerialDense_Type;
229 typedef std::shared_ptr<matrixSerialDense_Type> matrixSerialDensePtr_Type;
230 typedef std::vector<LifeV::Real> vectorInvariants_Type;
232 typedef std::shared_ptr<vectorInvariants_Type> vectorInvariantsPtr_Type;
236 typedef std::function<VectorSmall<3> ( Real
const&,
const Real&,
const Real&,
const Real& ) > volumeForce_Type;
237 typedef std::shared_ptr<volumeForce_Type> volumeForcePtr_Type;
238 typedef sourceVectorialFunctor sourceFunctor_Type;
239 typedef std::shared_ptr<sourceFunctor_Type> sourceFunctorPtr_Type;
246 StructuralOperator();
248 virtual ~StructuralOperator() {};
262 void setup ( std::shared_ptr<data_Type> data,
263 const FESpacePtr_Type& dFESpace,
264 const ETFESpacePtr_Type& dETFESpace,
266 std::shared_ptr<Epetra_Comm>& comm
274 void setup ( std::shared_ptr<data_Type> data,
275 const FESpacePtr_Type& dFESpace,
276 const ETFESpacePtr_Type& dETFESpace,
277 std::shared_ptr<Epetra_Comm>& comm
287 void setup ( std::shared_ptr<data_Type> data,
288 const FESpacePtr_Type& dFESpace,
289 const ETFESpacePtr_Type& dETFESpace,
290 std::shared_ptr<Epetra_Comm>& comm,
291 const std::shared_ptr<
const MapEpetra>& monolithicMap,
297 void updateSystem (
void );
303 void updateSystem ( matrixPtr_Type& mat_stiff);
309 void updateRightHandSideWithBodyForce (
const Real currentTime,
const vector_Type& rhsTimeAdvance );
315 void setRightHandSide (
const vector_Type& rightHandSide)
317 *M_rhsNoBC = rightHandSide;
321 void computeRHSNoBC (
void );
324 void buildSystem (
const Real coefficient );
333 void computeMassMatrix (
const Real factor = 1.);
339 void iterate (
const bcHandler_Type& bch );
345 void iterateLin ( bcHandler_Type& bch );
352 void showMe ( std::ostream& c = std::cout )
const;
359 void updateJacobian (
const vector_Type& solution, matrixPtr_Type& jacobian );
365 void updateJacobian (
const vector_Type& solution );
374 void solveJac ( vector_Type& step,
375 const vector_Type& residual,
376 Real& linear_rel_tol ) ;
387 void solveJacobian ( vector_Type& step,
388 const vector_Type& residual,
389 Real& linear_rel_tol,
390 bcHandler_Type& BCd ) ;
399 void evalResidual ( vector_Type& residual,
const vector_Type& solution,
Int iter);
405 void evalResidualDisplacement (
const vector_Type& solution );
411 void evalResidualDisplacementLin (
const vector_Type& solution );
419 void initialize (
const function& d0 );
427 void initialize ( vectorPtr_Type d0 );
437 void reduceSolution ( Vector& displacement, Vector& velocity );
452 void computeMatrix ( matrixPtr_Type& stiff,
const vector_Type& sol,
Real const& factor,
const UInt iter );
459 void jacobianDistribution ( vectorPtr_Type displacement, vector_Type& jacobianDistribution );
467 void colorMesh ( vector_Type& meshColors );
474 void computeCauchyStressTensor (
const vectorPtr_Type disp,
const QuadratureRule& evalQuad,
475 vectorPtr_Type sigma_1, vectorPtr_Type sigma_2, vectorPtr_Type sigma_3);
483 void computePrincipalTensions ( vectorPtr_Type sigma_1, vectorPtr_Type sigma_2,
484 vectorPtr_Type sigma_3, vectorPtr_Type vectorEigenvalue);
496 void setBC (
const bcHandler_Type& BCd)
506 void setSourceTerm ( source_Type
const& )
512 void setSourceTerm (
const volumeForcePtr_Type s )
514 M_source.reset(
new sourceFunctor_Type( s ) );
518 void setHavingSourceTerm (
const bool havingSource )
520 M_havingSource = havingSource;
536 void setDataFromGetPot (
const GetPot& dataFile );
538 void setTimeAdvance (
const timeAdvancePtr_Type& timeAdvancePtr )
540 M_timeAdvance = timeAdvancePtr;
547 void constructPatchAreaVector ( vector_Type& patchArea,
const vector_Type& solution );
554 void reconstructElementaryVector ( VectorElemental& elVecSigma, vector_Type& patchArea,
UInt nVol );
564 MapEpetra
const& map()
const 570 Displayer
const& displayer()
const 575 std::shared_ptr<
const Displayer>
const& displayerPtr()
const 584 matrixPtr_Type
const massMatrix()
const 590 FESpace_Type& dispFESpace()
592 return *M_dispFESpace;
596 ETFESpace_Type& dispETFESpace()
598 return *M_dispETFESpace;
602 bcHandler_Type
const& bcHandler()
const 608 vector_Type& residual()
610 return *M_residual_d;
614 const bool havingSourceTerm()
const 616 return M_havingSource;
621 vector_Type& displacement()
626 vectorPtr_Type displacementPtr()
632 vectorPtr_Type& rhsWithoutBC()
637 solver_Type& linearSolver()
639 return *M_linearSolver;
643 vector_Type& rhsCopy()
647 vector_Type& residualCopy()
649 return *M_residualCopy;
652 vector_Type& bodyForce()
654 return *M_bodyForceVector;
658 std::shared_ptr<Epetra_Comm>
const& comunicator()
const 660 return M_Displayer->comm();
666 return M_rescaleFactor;
672 const UInt& offset()
const 680 const materialPtr_Type& material()
const 689 void solidMatrix ( matrixPtr_Type& )
695 Real thickness()
const 697 return M_data->thickness();
701 Real young ( UInt material = 1)
const 703 return M_data->young ( material );
707 Real poisson ( UInt material = 1 )
const 709 return M_data->poisson ( material );
715 return M_data->rho();
719 const std::shared_ptr<data_Type>& data()
const 724 void apply (
const vector_Type& sol, vector_Type& res)
const;
727 mapMarkerVolumesPtr_Type mapMarkersVolumes()
const 729 return M_mapMarkersVolumes;
733 mapMarkerIndexesPtr_Type mapMarkersIndexes()
const 735 return M_mapMarkersIndexes;
738 const timeAdvancePtr_Type& timeAdvancePtr()
const 740 return M_timeAdvance;
754 void applyBoundaryConditions (matrix_Type& matrix,
762 return M_dispFESpace->dim();
771 void setupMapMarkersVolumes (
void );
776 std::shared_ptr<data_Type> M_data;
778 FESpacePtr_Type M_dispFESpace;
780 ETFESpacePtr_Type M_dispETFESpace;
782 std::shared_ptr<
const Displayer> M_Displayer;
787 std::shared_ptr<solver_Type> M_linearSolver;
788 basePrecPtr_Type M_preconditioner;
791 std::shared_ptr<MatrixElemental> M_elmatM;
794 vectorPtr_Type M_disp;
797 vectorPtr_Type M_rhs;
799 vectorPtr_Type M_rhsCopy;
800 vectorPtr_Type M_residualCopy;
803 vectorPtr_Type M_rhsNoBC;
805 vectorPtr_Type M_bodyForceVector;
810 std::shared_ptr<vector_Type> M_residual_d;
813 std::ofstream M_out_iter;
814 std::ofstream M_out_res;
817 bcHandler_Type M_BCh;
820 std::shared_ptr<
const MapEpetra> M_localMap;
823 matrixPtr_Type M_massMatrix;
826 matrixPtr_Type M_systemMatrix;
830 matrixPtr_Type M_jacobian;
837 sourceFunctorPtr_Type M_source;
845 materialPtr_Type M_material;
848 mapMarkerVolumesPtr_Type M_mapMarkersVolumes;
851 mapMarkerIndexesPtr_Type M_mapMarkersIndexes;
854 matrixSerialDensePtr_Type M_deformationF;
855 vectorInvariants_Type M_invariants;
858 timeAdvancePtr_Type M_timeAdvance;
865 template <
typename Mesh>
866 StructuralOperator<Mesh>::StructuralOperator( ) :
873 M_preconditioner ( ),
877 M_bodyForceVector ( ),
889 M_havingSource (
false ),
892 M_rescaleFactor ( 1. ),
896 M_mapMarkersVolumes ( ),
897 M_mapMarkersIndexes ( ),
904 template <
typename Mesh>
906 StructuralOperator<Mesh>::setup (std::shared_ptr<data_Type> data,
907 const FESpacePtr_Type& dFESpace,
908 const ETFESpacePtr_Type& dETFESpace,
910 std::shared_ptr<Epetra_Comm>& comm)
912 setup (data, dFESpace, dETFESpace, comm);
916 template <
typename Mesh>
918 StructuralOperator<Mesh>::setup (std::shared_ptr<data_Type> data,
919 const FESpacePtr_Type& dFESpace,
920 const ETFESpacePtr_Type& dETFESpace,
921 std::shared_ptr<Epetra_Comm>& comm)
923 setup ( data, dFESpace, dETFESpace, comm, dFESpace->mapPtr(), (UInt) 0 );
925 M_rhs.reset (
new vector_Type (*M_localMap) );
927 M_rhsCopy.reset (
new vector_Type (*M_localMap) );
928 M_residualCopy.reset (
new vector_Type (*M_localMap) );
930 M_rhsNoBC.reset (
new vector_Type (*M_localMap) );
931 M_bodyForceVector.reset (
new vector_Type (*M_localMap) );
932 M_linearSolver.reset (
new LinearSolver ( comm ) );
933 M_disp.reset (
new vector_Type (*M_localMap) );
936 template <
typename Mesh>
938 StructuralOperator<Mesh>::setup (std::shared_ptr<data_Type> data,
939 const FESpacePtr_Type& dFESpace,
940 const ETFESpacePtr_Type& dETFESpace,
941 std::shared_ptr<Epetra_Comm>& comm,
942 const std::shared_ptr<
const MapEpetra>& monolithicMap,
946 M_dispFESpace = dFESpace;
947 M_dispETFESpace = dETFESpace;
948 M_Displayer.reset (
new Displayer (comm) );
949 M_me = comm->MyPID();
950 M_elmatM.reset (
new MatrixElemental ( M_dispFESpace->fe().nbFEDof(), nDimensions, nDimensions ) );
951 M_localMap = monolithicMap;
952 M_massMatrix.reset (
new matrix_Type (*M_localMap) );
953 M_systemMatrix.reset (
new matrix_Type (*M_localMap) );
954 M_jacobian.reset (
new matrix_Type (*M_localMap) );
958 M_material.reset(
new material_Type() );
959 M_material->setup ( dFESpace, dETFESpace, M_localMap, M_offset, M_data, M_Displayer );
961 if ( M_data->verbose() )
963 M_out_iter.open (
"out_iter_solid" );
964 M_out_res.open (
"out_res_solid" );
966 M_mapMarkersVolumes.reset (
new mapMarkerVolumes_Type() );
967 M_mapMarkersIndexes.reset (
new mapMarkerIndexes_Type() );
969 this->setupMapMarkersVolumes();
973 template <
typename Mesh>
974 void StructuralOperator<Mesh>::setupMapMarkersVolumes (
void )
979 this->M_Displayer->leaderPrint (
" S- Starting the time: \n");
984 this->M_Displayer->leaderPrint (
" S- Building the map between volumesMarkers <--> volumes \n");
987 for ( UInt i (0); i < M_data->vectorFlags().size(); i++ )
991 markerSelectorPtr_Type ref (
new markerSelector_Type (M_data->vectorFlags() [i]) );
994 UInt numExtractedVolumes =
this->M_dispFESpace->mesh()->elementList().countAccordingToPredicate ( *ref );
996 this->M_Displayer->leaderPrint (
" Current marker: ", M_data->vectorFlags() [i]);
997 this->M_Displayer->leaderPrint (
" \n");
998 this->M_Displayer->leaderPrint (
" Number of volumes:", numExtractedVolumes);
999 this->M_Displayer->leaderPrint (
" \n");
1002 vectorVolumes_Type extractedVolumes ( numExtractedVolumes );
1003 vectorIndexes_Type extractedIndexes;
1006 extractedVolumes =
this->M_dispFESpace->mesh()->elementList().extractAccordingToPredicateNonConstElement ( *ref, extractedIndexes );
1009 M_mapMarkersVolumes->insert ( std::pair<UInt, vectorVolumes_Type> (M_data->vectorFlags() [i], extractedVolumes) ) ;
1010 M_mapMarkersIndexes->insert ( std::pair<UInt, vectorIndexes_Type> (M_data->vectorFlags() [i], extractedIndexes) ) ;
1016 extractedVolumes.clear();
1017 extractedIndexes.clear();
1023 this->M_Displayer->leaderPrint (
" S- Time to build the map:", time.diff() );
1026 template <
typename Mesh>
1027 void StructuralOperator<Mesh>::updateSystem (
void )
1029 updateSystem (M_systemMatrix);
1032 template <
typename Mesh>
1033 void StructuralOperator<Mesh>::updateSystem ( matrixPtr_Type& mat_stiff)
1035 M_Displayer->leaderPrint (
" S- Updating mass term on right hand side... ");
1040 if ( M_data->lawType() ==
"linear" )
1042 *mat_stiff += *M_material->stiffMatrix();
1043 mat_stiff->globalAssemble();
1050 M_material->computeStiffness (*M_disp, 0 , M_rescaleFactor, M_data, M_mapMarkersVolumes, M_mapMarkersIndexes, M_Displayer);
1054 M_Displayer->leaderPrintMax (
"done in ", chrono.diff() );
1058 template <
typename Mesh>
1059 void StructuralOperator<Mesh>::updateRightHandSideWithBodyForce (
const Real currentTime,
const vector_Type& rhsTimeAdvance )
1063 M_source->setCurrentTime( currentTime );
1065 vectorPtr_Type rhs (
new vector_Type (*M_localMap) );
1067 integrate ( elements (
this->M_dispETFESpace->mesh() ) ,
1068 this->M_dispFESpace->qr(),
1069 this->M_dispETFESpace,
1070 value ( M_data->rho() ) * dot ( eval( M_source, X ), phi_i )
1073 M_bodyForceVector = rhs;
1075 *rhs += rhsTimeAdvance;
1081 template <
typename Mesh>
1082 void StructuralOperator<Mesh>::buildSystem (
const Real coefficient )
1084 M_Displayer->leaderPrint (
" S- Computing constant matrices ... ");
1088 computeMassMatrix ( coefficient );
1089 M_material->computeLinearStiff (M_data, M_mapMarkersVolumes, M_mapMarkersIndexes);
1092 M_Displayer->leaderPrintMax (
"done in ", chrono.diff() );
1096 template <
typename Mesh>
1098 StructuralOperator<Mesh>::computeMassMatrix (
const Real factor)
1106 const Real factorMassMatrix = factor * M_data->rho();
1113 integrate ( elements (M_dispETFESpace->mesh() ),
1114 M_dispFESpace->qr(),
1117 value (factorMassMatrix) * dot ( phi_j , phi_i ) ) >> M_massMatrix;
1119 M_massMatrix->globalAssemble();
1154 template <
typename Mesh>
1156 StructuralOperator<Mesh>::iterate (
const bcHandler_Type& bch )
1161 M_Displayer->leaderPrint (
" S- Solving the system ... \n");
1165 Real abstol = M_data->absoluteTolerance();
1166 Real reltol = M_data->relativeTolerance();
1167 UInt maxiter = M_data->maxSubIterationNumber();
1168 Real etamax = M_data->errorTolerance();
1169 Int NonLinearLineSearch = M_data->NonLinearLineSearch();
1171 Real time = M_data->dataTime()->time();
1175 if ( M_data->verbose() )
1177 status = NonLinearRichardson ( *M_disp, *
this, abstol, reltol, maxiter, etamax, NonLinearLineSearch, 0, 2, M_out_res, M_data->dataTime()->time() );
1181 status = NonLinearRichardson ( *M_disp, *
this, abstol, reltol, maxiter, etamax, NonLinearLineSearch );
1187 std::ostringstream ex;
1188 ex <<
"StructuralOperator::iterate() Inners nonLinearRichardson iterations failed to converge\n";
1189 throw std::logic_error ( ex.str() );
1198 if ( M_data->verbose() )
1200 M_out_iter << time <<
" " << maxiter << std::endl;
1208 evalResidualDisplacement (*M_disp);
1211 template <
typename Mesh>
1213 StructuralOperator<Mesh>::iterateLin ( bcHandler_Type& bch )
1215 vector_Type rhsFull (M_rhsNoBC->map() );
1217 if ( !bch->bcUpdateDone() )
1219 bch->bcUpdate ( *M_dispFESpace->mesh(), M_dispFESpace->feBd(), M_dispFESpace->dof() );
1221 bcManageVector ( rhsFull, *M_dispFESpace->mesh(), M_dispFESpace->dof(), *bch, M_dispFESpace->feBd(), M_data->dataTime()->time(), 1.0 );
1222 solveJacobian (*M_disp, rhsFull, zero, bch);
1223 evalResidualDisplacementLin (*M_disp);
1227 template <
typename Mesh>
1229 StructuralOperator<Mesh>::showMe ( std::ostream& c )
const 1231 c <<
"\n*** StructuralOperator::showMe method" << std::endl;
1233 M_data->showMe ( c );
1237 template <
typename Mesh>
1238 void StructuralOperator<Mesh>::computeMatrix ( matrixPtr_Type& stiff,
const vector_Type& sol,
1241 M_Displayer->leaderPrint (
" Computing residual ... \t\t\t");
1246 if ( M_data->lawType() ==
"linear" )
1248 *stiff = *M_material->stiffMatrix();
1249 *stiff += *M_massMatrix;
1250 stiff->globalAssemble();
1256 M_material->computeStiffness ( sol, iter, 1., M_data, M_mapMarkersVolumes, M_mapMarkersIndexes, M_Displayer);
1259 M_Displayer->leaderPrintMax (
"done in ", chrono.diff() );
1264 template <
typename Mesh>
1265 void StructuralOperator<Mesh>::jacobianDistribution ( vectorPtr_Type displacement, vector_Type& jacobianDistribution )
1267 M_Displayer->leaderPrint (
" Computing the jacobian for all the volumes ... \t\t\t");
1270 M_deformationF.reset (
new matrixSerialDense_Type ( M_dispFESpace->fieldDim(), M_dispFESpace->fieldDim() ) );
1272 vector_Type vectorJacobian ( jacobianDistribution );
1273 vectorJacobian *= 0.0;
1279 vector_Type patchArea (*displacement, Unique, Add);
1282 constructPatchAreaVector ( patchArea, *displacement );
1285 vector_Type patchAreaR (patchArea,
Repeated);
1290 vector_Type dRep (*displacement, Repeated);
1291 UInt totalDof = M_dispFESpace->dof().numTotalDof();
1292 VectorElemental dk_loc ( M_dispFESpace->fe().nbFEDof(),
this->M_dispFESpace->fieldDim() );
1293 VectorElemental elVecDet ( M_dispFESpace->fe().nbFEDof(),
this->M_dispFESpace->fieldDim() );
1298 Real refElemArea (0);
1300 for (UInt iq = 0; iq < M_dispFESpace->qr().nbQuadPt(); iq++)
1302 refElemArea += M_dispFESpace->qr().weight (iq);
1305 Real wQuad (refElemArea / M_dispFESpace->refFE().nbDof() );
1308 std::vector<GeoVector> coords = M_dispFESpace->refFE().refCoor();
1309 std::vector<Real> weights (M_dispFESpace->fe().nbFEDof(), wQuad);
1310 fakeQuadratureRule.setDimensionShape ( shapeDimension (M_dispFESpace->refFE().shape() ), M_dispFESpace->refFE().shape() );
1311 fakeQuadratureRule.setPoints (coords, weights);
1314 M_dispFESpace->setQuadRule (fakeQuadratureRule);
1318 for ( UInt i = 0; i < M_dispFESpace->mesh()->numVolumes(); ++i )
1322 std::vector<matrixSerialDense_Type> vectorDeformationF (M_dispFESpace->fe().nbFEDof(), *M_deformationF);
1323 M_invariants.resize ( M_dispFESpace->fieldDim() + 1 );
1326 M_dispFESpace->fe().updateFirstDerivQuadPt ( M_dispFESpace->mesh()->volumeList ( i ) );
1328 UInt eleID = M_dispFESpace->fe().currentLocalId();
1331 for ( UInt iNode = 0; iNode < ( UInt ) M_dispFESpace->fe().nbFEDof(); iNode++ )
1333 UInt iloc = M_dispFESpace->fe().patternFirst ( iNode );
1335 for ( UInt iComp = 0; iComp <
this->M_dispFESpace->fieldDim(); ++iComp )
1337 UInt ig = M_dispFESpace->dof().localToGlobalMap ( eleID, iloc ) + iComp * M_dispFESpace->dim() +
this->M_offset;
1338 dk_loc[iloc + iComp * M_dispFESpace->fe().nbFEDof()] = dRep[ig];
1343 AssemblyElementalStructure::computeLocalDeformationGradient ( dk_loc, vectorDeformationF, M_dispFESpace->fe() );
1347 for ( UInt nDOF = 0; nDOF < ( UInt ) M_dispFESpace->fe().nbFEDof(); nDOF++ )
1349 UInt iloc = M_dispFESpace->fe().patternFirst ( nDOF );
1352 AssemblyElementalStructure::computeInvariantsRightCauchyGreenTensor ( M_invariants, vectorDeformationF[nDOF] );
1355 (elVecDet) [ iloc ] = M_invariants[3];
1356 (elVecDet) [ iloc + M_dispFESpace->fe().nbFEDof() ] = 0.0;
1357 (elVecDet) [ iloc + 2 * M_dispFESpace->fe().nbFEDof() ] = 0.0;
1362 reconstructElementaryVector ( elVecDet, patchAreaR, i );
1365 for ( UInt ic = 0; ic <
this->M_dispFESpace->fieldDim(); ++ic )
1367 assembleVector (vectorJacobian, elVecDet, M_dispFESpace->fe(), M_dispFESpace->dof(), ic,
this->M_offset + ic * totalDof );
1370 vectorDeformationF.clear();
1371 M_invariants.clear();
1375 vectorJacobian.globalAssemble();
1378 M_Displayer->leaderPrintMax (
"done in ", chrono.diff() );
1380 jacobianDistribution = vectorJacobian;
1384 template <
typename Mesh>
1385 void StructuralOperator<Mesh >::constructPatchAreaVector ( vector_Type& patchArea,
1386 const vector_Type& solution )
1389 vector_Type patchAreaR (solution,
Repeated);
1392 Real refElemArea (0);
1393 UInt totalDof = M_dispFESpace->dof().numTotalDof();
1395 for (UInt iq = 0; iq < M_dispFESpace->qr().nbQuadPt(); iq++)
1397 refElemArea += M_dispFESpace->qr().weight (iq);
1402 interpQuad.setDimensionShape (shapeDimension (M_dispFESpace->refFE().shape() ), M_dispFESpace->refFE().shape() );
1403 Real wQuad (refElemArea / M_dispFESpace->refFE().nbDof() );
1405 for (UInt i (0); i < M_dispFESpace->refFE().nbDof(); ++i)
1407 interpQuad.addPoint (QuadraturePoint (M_dispFESpace->refFE().xi (i), M_dispFESpace->refFE().eta (i), M_dispFESpace->refFE().zeta (i), wQuad) );
1410 UInt totalNumberVolumes (M_dispFESpace->mesh()->numVolumes() );
1411 UInt numberLocalDof (M_dispFESpace->dof().numLocalDof() );
1413 CurrentFE interpCFE (M_dispFESpace->refFE(), getGeometricMap (* (M_dispFESpace->mesh() ) ), interpQuad);
1416 for (
UInt iterElement (0); iterElement < totalNumberVolumes; iterElement++)
1418 interpCFE.update (M_dispFESpace->mesh()->volumeList ( iterElement ), UPDATE_WDET );
1420 for (
UInt iterDof (0); iterDof < numberLocalDof; iterDof++)
1422 for (UInt iDim (0); iDim < M_dispFESpace->fieldDim(); ++iDim)
1424 ID globalDofID (M_dispFESpace->dof().localToGlobalMap (iterElement, iterDof) + iDim * totalDof);
1425 patchAreaR[globalDofID] += interpCFE.measure();
1430 vector_Type final (patchAreaR, Unique, Add);
1432 patchArea.add (final);
1435 template <
typename Mesh>
1437 StructuralOperator<Mesh >::reconstructElementaryVector ( VectorElemental& elVecDet,
1438 vector_Type& patchArea,
1444 Real measure = M_dispFESpace->fe().measure();
1445 UInt eleID = M_dispFESpace->fe().currentLocalId();
1447 for (UInt iDof = 0; iDof < M_dispFESpace->fe().nbFEDof(); iDof++)
1449 UInt iloc = M_dispFESpace->fe().patternFirst ( iDof );
1451 for ( UInt icoor = 0; icoor < M_dispFESpace->fieldDim(); icoor++ )
1453 ID globalDofID (M_dispFESpace->dof().localToGlobalMap (eleID, iDof) + icoor * M_dispFESpace->dof().numTotalDof() );
1454 elVecDet[iloc + icoor * M_dispFESpace->fe().nbFEDof()] *= ( measure / patchArea[globalDofID] );
1461 template <
typename Mesh>
1462 void StructuralOperator<Mesh>::colorMesh ( vector_Type& meshColors )
1464 UInt totalDof =
this->M_dispFESpace->dof().numTotalDof();
1466 mapIterator_Type it;
1468 for ( it = (*M_mapMarkersVolumes).begin(); it != (*M_mapMarkersVolumes).end(); it++ )
1472 UInt marker = it->first;
1474 for ( UInt j (0); j < it->second.size(); j++ )
1476 this->M_dispFESpace->fe().updateFirstDerivQuadPt ( * (it->second[j]) );
1478 UInt eleID =
this->M_dispFESpace->fe().currentLocalId();
1480 for ( UInt iNode = 0; iNode < ( UInt )
this->M_dispFESpace->fe().nbFEDof(); iNode++ )
1482 UInt iloc =
this->M_dispFESpace->fe().patternFirst ( iNode );
1485 UInt globalIDofDOF =
this->M_dispFESpace->dof().localToGlobalMap ( eleID, iloc );
1487 if ( meshColors.blockMap().LID (
static_cast<EpetraInt_Type>(globalIDofDOF)) != -1 )
1489 Int LIDid = meshColors.blockMap().LID (
static_cast<EpetraInt_Type>(globalIDofDOF) );
1490 Int GIDid = meshColors.blockMap().GID ( LIDid );
1491 meshColors[ GIDid ] = marker;
1501 template <
typename Mesh>
1502 void StructuralOperator<Mesh>::computeCauchyStressTensor(
const vectorPtr_Type disp,
1504 vectorPtr_Type sigma_1,
1505 vectorPtr_Type sigma_2,
1506 vectorPtr_Type sigma_3)
1514 M_material->computeCauchyStressTensor ( disp, evalQuad, sigma_1, sigma_2, sigma_3 );
1517 template <
typename Mesh>
1518 void StructuralOperator<Mesh>::computePrincipalTensions( vectorPtr_Type sigma_1, vectorPtr_Type sigma_2,
1519 vectorPtr_Type sigma_3, vectorPtr_Type vectorEigenvalues)
1533 for ( UInt iDOF = 0; iDOF < ( UInt ) M_dispFESpace->dof().numTotalDof(); ++iDOF )
1535 if( sigma_1->blockMap().LID(
static_cast<EpetraInt_Type>(iDOF) ) != -1 )
1538 Int GIDnode = sigma_1->blockMap().GID( iDOF );
1541 Epetra_LAPACK lapack;
1550 Int Dim = nDimensions;
1553 double WR[nDimensions];
1554 double WI[nDimensions];
1557 Int LDVR = nDimensions;
1558 Int LDVL = nDimensions;
1561 Int length = nDimensions * 3;
1574 for (UInt j (0); j < nDimensions; j++)
1576 Int LIDid = sigma_1->blockMap().LID (
static_cast<EpetraInt_Type>(iDOF + j * M_dispFESpace->dof().numTotalDof() + M_offset));
1577 Int GIDid = sigma_1->blockMap().GID (LIDid);
1579 A[ nDimensions * j ] = (*sigma_1)( GIDid );
1580 A[ nDimensions * j + 1 ] = (*sigma_2)( GIDid );
1581 A[ nDimensions * j + 2 ] = (*sigma_3)( GIDid );
1584 lapack.GEEV (JOBVL, JOBVR, Dim, A , Dim, &WR[0], &WI[0], VL, LDVL, VR, LDVR, WORK, LWORK, &INFO);
1585 ASSERT ( !INFO,
"Calculation of the Eigenvalues failed!!!" );
1592 for( UInt k(0); k < nDimensions; k++ )
1595 ASSERT( sum < 1e-6,
"The eigenvalues are not real!");
1597 std::vector<
double> eigenvalues(nDimensions);
1598 for( UInt l(0); l < nDimensions; l++ )
1600 eigenvalues[ l ] = WR[ l ];
1603 std::sort( eigenvalues.begin(), eigenvalues.end() );
1606 for( UInt m(0); m < nDimensions; m++ )
1608 Int LIDid = vectorEigenvalues->blockMap().LID (
static_cast<EpetraInt_Type>(iDOF + m * M_dispFESpace->dof().numTotalDof() + M_offset));
1609 Int GIDid = vectorEigenvalues->blockMap().GID (LIDid);
1611 (*vectorEigenvalues)( GIDid ) = eigenvalues[ m ];
1618 template <
typename Mesh>
1620 StructuralOperator<Mesh>::evalResidual ( vector_Type& residual,
const vector_Type& solution,
Int iter)
1624 computeMatrix (M_systemMatrix, solution, 1., iter);
1627 M_Displayer->leaderPrint (
" S- Updating the boundary conditions ... \t");
1630 if ( !M_BCh->bcUpdateDone() )
1632 M_BCh->bcUpdate ( *M_dispFESpace->mesh(), M_dispFESpace->feBd(), M_dispFESpace->dof() );
1636 if ( M_data->lawType() ==
"linear" )
1640 matrix_Type matrixFull (*M_systemMatrix);
1644 *M_rhs = *M_rhsNoBC;
1646 bcManageVector ( *M_rhs, *M_dispFESpace->mesh(), M_dispFESpace->dof(), *M_BCh, M_dispFESpace->feBd(), M_data->dataTime()->time(), 1.0 );
1656 bcManageMatrix ( matrixFull, *M_dispFESpace->mesh(), M_dispFESpace->dof(), *M_BCh, M_dispFESpace->feBd(), 1.0 );
1658 residual = matrixFull * solution;
1661 M_Displayer->leaderPrintMax (
"done in ", chrono.diff() );
1666 *M_rhs = *M_rhsNoBC;
1667 residual = *M_massMatrix * solution;
1668 residual += *M_material->stiffVector();
1669 vector_Type solRep (solution,
Repeated);
1670 bcManageResidual ( residual, *M_rhs, solRep, *M_dispFESpace->mesh(), M_dispFESpace->dof(), *M_BCh, M_dispFESpace->feBd(), M_data->dataTime()->time(), 1.0 );
1673 M_Displayer->leaderPrintMax (
"done in ", chrono.diff() );
1679 *M_residualCopy = residual;
1684 template <
typename Mesh>
1686 StructuralOperator<Mesh>::evalResidualDisplacement (
const vector_Type& solution )
1689 M_Displayer->leaderPrint (
" S- Computing the residual displacement for the structure..... \t");
1693 if ( M_data->lawType() ==
"linear" )
1695 M_residual_d.reset (
new vector_Type ( *M_systemMatrix * solution ) );
1696 *M_residual_d -= *M_rhsNoBC;
1700 M_residual_d.reset (
new vector_Type ( *M_material->stiffVector() ) );
1701 *M_residual_d -= *M_rhsNoBC;
1704 M_Displayer->leaderPrintMax (
"done in ", chrono.diff() );
1708 template <
typename Mesh>
1710 StructuralOperator<Mesh>::evalResidualDisplacementLin (
const vector_Type& solution )
1713 M_Displayer->leaderPrint (
" S- Computing the residual displacement for the structure..... \t");
1718 M_residual_d.reset (
new vector_Type ( (*M_jacobian) *solution) );
1721 M_Displayer->leaderPrintMax (
"done in ", chrono.diff() );
1725 template <
typename Mesh>
1727 StructuralOperator<Mesh>::initialize ( vectorPtr_Type disp )
1732 template <
typename Mesh>
1734 StructuralOperator<Mesh>::initialize (
const function& d0 )
1736 M_dispFESpace->interpolate (
static_cast<
typename FESpace<Mesh, MapEpetra>::function_Type> ( d0 ), *M_disp, 0.0);
1739 template<
typename Mesh>
1741 StructuralOperator<Mesh>::reduceSolution ( Vector& displacement, Vector& velocity )
1743 vector_Type disp (*M_disp, 0);
1746 if ( comunicator()->MyPID() == 0 )
1750 disp[ iDof ] = displacement[ iDof + 1 ];
1756 template <
typename Mesh>
1758 StructuralOperator<Mesh>::setDataFromGetPot (
const GetPot& dataFile )
1761 M_Displayer->leaderPrint (
"Setting up Preconditioner... \n" );
1763 const std::string preconditionerType = dataFile (
"solid/prec/prectype",
"Ifpack" );
1764 const std::string xmlFileName = dataFile (
"solid/prec/xmlName",
"xmlParameters.xml" );
1765 basePrecPtr_Type precPtr;
1767 if ( ! ( preconditionerType.compare (
"Ifpack") ) )
1769 precIfpack_Type* precRawPtr;
1770 precRawPtr =
new precIfpack_Type;
1771 precRawPtr->setDataFromGetPot ( dataFile,
"solid/prec" );
1774 M_preconditioner.reset ( precRawPtr );
1778 precML_Type* precRawPtr;
1779 precRawPtr =
new precML_Type;
1780 precRawPtr->setDataFromGetPot ( dataFile,
"solid/prec" );
1783 M_preconditioner.reset ( precRawPtr );
1787 M_Displayer->leaderPrint (
"Setting up LinearSolver... \n" );
1789 Teuchos::RCP< Teuchos::ParameterList > paramList = Teuchos::rcp (
new Teuchos::ParameterList );
1790 paramList = Teuchos::getParametersFromXmlFile ( xmlFileName );
1793 M_linearSolver->setParameters ( *paramList );
1794 M_linearSolver->setPreconditioner ( M_preconditioner );
1795 M_rescaleFactor = dataFile (
"solid/rescaleFactor", 0. );
1800 template <
typename Mesh>
1801 void StructuralOperator<Mesh>::updateJacobian (
const vector_Type& sol, matrixPtr_Type& jacobian )
1803 M_Displayer->leaderPrint (
" S- Solid: Updating JACOBIAN... ");
1808 M_material->updateJacobianMatrix (sol, M_data, M_mapMarkersVolumes, M_mapMarkersIndexes, M_Displayer);
1810 jacobian.reset (
new matrix_Type (*M_localMap) );
1811 *jacobian += * (M_material->jacobian() );
1820 *jacobian += *M_massMatrix;
1822 jacobian->globalAssemble();
1825 M_Displayer->leaderPrintMax (
" ... done in ", chrono.diff() );
1830 template <
typename Mesh>
1831 void StructuralOperator<Mesh>::updateJacobian (
const vector_Type& sol)
1833 updateJacobian (sol, M_jacobian);
1837 template <
typename Mesh>
1838 void StructuralOperator<Mesh>::
1839 solveJac ( vector_Type& step,
const vector_Type& res, Real& linear_rel_tol)
1841 updateJacobian ( *M_disp, M_jacobian );
1842 solveJacobian (step, res, linear_rel_tol, M_BCh);
1847 template <
typename Mesh>
1848 void StructuralOperator<Mesh>::
1849 solveJacobian (vector_Type& step,
1850 const vector_Type& res,
1857 vectorPtr_Type pointerToRes (
new vector_Type (res) );
1858 vectorPtr_Type pointerToStep (
new vector_Type (*M_localMap) );
1861 *pointerToStep *= 0.0;
1863 matrixPtr_Type matrFull (
new matrix_Type (*M_localMap) );
1864 *matrFull += *M_jacobian;
1866 M_Displayer->leaderPrint (
"\tS'- Solving the linear system ... \n");
1868 M_Displayer->leaderPrint (
"\tS'- Applying boundary conditions ... ");
1871 if ( !M_BCh->bcUpdateDone() )
1873 M_BCh->bcUpdate ( *M_dispFESpace->mesh(), M_dispFESpace->feBd(), M_dispFESpace->dof() );
1875 bcManageMatrix ( *matrFull, *M_dispFESpace->mesh(), M_dispFESpace->dof(), *M_BCh, M_dispFESpace->feBd(), 1.0 );
1877 M_Displayer->leaderPrintMax (
"done in ", chrono.diff() );
1879 M_Displayer->leaderPrint (
"\tS'- Solving system ... \n");
1883 M_linearSolver->setOperator ( matrFull );
1884 M_linearSolver->setRightHandSide ( pointerToRes );
1887 M_linearSolver->solve ( pointerToStep );
1889 step = *pointerToStep;
1894 template<
typename Mesh>
1895 void StructuralOperator<Mesh>::apply (
const vector_Type& sol, vector_Type& res)
const 1897 M_material->apply (sol, res, M_mapMarkersVolumes, M_mapMarkersIndexes);
1898 res += (*M_massMatrix) * sol;
1901 template<
typename Mesh>
1903 StructuralOperator<Mesh>::applyBoundaryConditions ( matrix_Type& matrix,
1905 bcHandler_Type& BCh,
1911 BCh->setOffset (offset);
1913 if ( !BCh->bcUpdateDone() )
1915 BCh->bcUpdate ( *M_dispFESpace->mesh(), M_dispFESpace->feBd(), M_dispFESpace->dof() );
1919 vector_Type rhsFull (rhs, Unique);
1921 bcManage ( matrix, rhsFull, *M_dispFESpace->mesh(), M_dispFESpace->dof(), *BCh, M_dispFESpace->feBd(), 1., M_data->dataTime()->time() );
int32_type Int
Generic integer data.
double Real
Generic real data.
CurrentFE - A primordial class for the assembly of the local matrices/vectors retaining the values on...
const UInt nDimensions(NDIM)
QuadratureRule - The basis class for storing and accessing quadrature rules.
DataElasticStructure - Data container for solid problems with elastic structure.
uint32_type UInt
generic unsigned integer (used mainly for addressing)