36 #ifndef ABSTRACTNONLINEARELASTICITYSOLVER_HPP_ 37 #define ABSTRACTNONLINEARELASTICITYSOLVER_HPP_ 41 #include "AbstractContinuumMechanicsSolver.hpp" 42 #include "LinearSystem.hpp" 43 #include "LogFile.hpp" 44 #include "MechanicsEventHandler.hpp" 45 #include "ReplicatableVector.hpp" 46 #include "FourthOrderTensor.hpp" 47 #include "CmguiDeformedSolutionsWriter.hpp" 48 #include "AbstractMaterialLaw.hpp" 49 #include "QuadraticBasisFunction.hpp" 50 #include "SolidMechanicsProblemDefinition.hpp" 52 #include "AbstractPerElementWriter.hpp" 53 #include "petscsnes.h" 61 typedef enum StrainType_
63 DEFORMATION_GRADIENT_F = 0,
69 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2 86 template<
unsigned DIM>
87 PetscErrorCode AbstractNonlinearElasticitySolver_ComputeResidual(SNES snes,
92 #if ((PETSC_VERSION_MAJOR==3) && (PETSC_VERSION_MINOR>=5)) 105 template<
unsigned DIM>
106 PetscErrorCode AbstractNonlinearElasticitySolver_ComputeJacobian(SNES snes,
123 template<
unsigned DIM>
124 PetscErrorCode AbstractNonlinearElasticitySolver_ComputeJacobian(SNES snes,
126 Mat* pGlobalJacobian,
127 Mat* pPreconditioner,
128 MatStructure* pMatStructure,
132 template <
unsigned DIM>
141 template<
unsigned DIM>
171 assert(localIndex == pElement->
GetIndex());
174 for (
unsigned i=0; i<DIM; i++)
176 for (
unsigned j=0; j<DIM; j++)
178 rData[i*DIM+j] = data(i,j);
195 template<
unsigned DIM>
205 static const size_t NUM_VERTICES_PER_ELEMENT = DIM+1;
208 static const size_t NUM_NODES_PER_ELEMENT = (DIM+1)*(DIM+2)/2;
211 static const size_t NUM_NODES_PER_BOUNDARY_ELEMENT = DIM*(DIM+1)/2;
217 static const size_t BOUNDARY_STENCIL_SIZE = DIM*NUM_NODES_PER_BOUNDARY_ELEMENT;
340 std::vector<c_vector<
double,DIM*(DIM+1)/2> > mAverageStressesPerElement;
349 void AddStressToAverageStressPerElement(c_matrix<double,DIM,DIM>& rT,
unsigned elementIndex);
359 virtual void SetKspSolverAndPcType(KSP solver);
374 virtual void AssembleSystem(
bool assembleResidual,
bool assembleLinearSystem)=0;
383 virtual void FinishAssembleSystem(
bool assembleResidual,
bool assembleLinearSystem);
398 void GetElementCentroidStrain(StrainType strainType,
400 c_matrix<double,DIM,DIM>& rDeformationGradient);
421 unsigned elementIndex,
422 unsigned currentQuadPointGlobalIndex,
423 c_matrix<double,DIM,DIM>& rT,
460 c_matrix<double, BOUNDARY_STENCIL_SIZE, BOUNDARY_STENCIL_SIZE>& rAelem,
461 c_vector<double, BOUNDARY_STENCIL_SIZE>& rBelem,
462 bool assembleResidual,
463 bool assembleJacobian,
464 unsigned boundaryConditionIndex);
481 bool ShouldAssembleMatrixTermForPressureOnDeformedBc();
503 c_matrix<double,BOUNDARY_STENCIL_SIZE,BOUNDARY_STENCIL_SIZE>& rAelem,
504 c_vector<double,BOUNDARY_STENCIL_SIZE>& rBelem,
505 bool assembleResidual,
506 bool assembleJacobian,
507 unsigned boundaryConditionIndex);
526 double ComputeResidualAndGetNorm(
bool allowException);
529 double CalculateResidualNorm();
540 void VectorSum(std::vector<double>& rX,
ReplicatableVector& rY,
double a, std::vector<double>& rZ);
549 void PrintLineSearchResult(
double s,
double residNorm);
558 double TakeNewtonStep();
569 double UpdateSolutionUsingLineSearch(
Vec solution);
578 virtual void PostNewtonStep(
unsigned counter,
double normResidual);
585 void SolveNonSnes(
double tol=-1.0);
600 void ComputeResidual(
Vec currentGuess,
Vec residualVector);
609 void ComputeJacobian(
Vec currentGuess,
Mat* pJacobian,
Mat* pPreconditioner);
632 std::string outputDirectory,
633 CompressibilityType compressibilityType);
645 void Solve(
double tol=-1.0);
658 mIncludeActiveTension = includeActiveTension;
664 unsigned GetNumNewtonIterations();
676 mWriteOutputEachNewtonIteration = writeOutputEachNewtonIteration;
687 assert(kspAbsoluteTolerance > 0);
688 mKspAbsoluteTol = kspAbsoluteTolerance;
706 mTakeFullFirstNewtonStep = takeFullFirstStep;
724 mPetscDirectSolve = usePetscDirectSolve;
743 void CreateCmguiOutput();
759 void WriteCurrentStrains(StrainType strainType, std::string fileName,
int counterToAppend = -1);
767 void SetComputeAverageStressPerElementDuringSolve(
bool setComputeAverageStressPerElement =
true);
782 void WriteCurrentAverageElementStresses(std::string fileName,
int counterToAppend = -1);
788 std::vector<c_vector<double,DIM> >& rGetSpatialSolution();
794 std::vector<c_vector<double,DIM> >& rGetDeformedPosition();
804 c_matrix<double,DIM,DIM> GetAverageStressPerElement(
unsigned elementIndex);
811 template<
unsigned DIM>
814 std::string outputDirectory,
815 CompressibilityType compressibilityType)
817 mrProblemDefinition(rProblemDefinition),
818 mrJacobianMatrix(this->mSystemLhsMatrix),
820 mWriteOutputEachNewtonIteration(false),
821 mNumNewtonIterations(0),
823 mCheckedOutwardNormals(false),
824 mLastDampingValue(0.0),
825 mIncludeActiveTension(true),
826 mSetComputeAverageStressPerElement(false)
837 template<
unsigned DIM>
842 template<
unsigned DIM>
847 if (assembleJacobian)
856 if (assembleJacobian)
860 else if (assembleResidual)
865 if (assembleResidual)
869 if (assembleJacobian)
877 template<
unsigned DIM>
884 for (
unsigned j=0; j<DIM; j++)
892 template<
unsigned DIM>
898 template<
unsigned DIM>
906 std::stringstream file_name;
907 file_name << fileName;
908 if (counterToAppend >= 0)
910 file_name <<
"_" << counterToAppend;
912 file_name <<
".strain";
916 c_matrix<double,DIM,DIM> strain;
923 for (
unsigned i=0; i<DIM; i++)
925 for (
unsigned j=0; j<DIM; j++)
927 *p_file << strain(i,j) <<
" ";
935 template<
unsigned DIM>
945 EXCEPTION(
"Call SetComputeAverageStressPerElementDuringSolve() before solve if calling WriteCurrentAverageElementStresses()");
948 std::stringstream file_name;
949 file_name << fileName;
950 if (counterToAppend >= 0)
952 file_name <<
"_" << counterToAppend;
954 file_name <<
".stress";
961 template<
unsigned DIM>
966 EXCEPTION(
"No output directory was given so no output was written, cannot convert to cmgui format");
972 WRITE_QUADRATIC_MESH);
980 template<
unsigned DIM>
990 template<
unsigned DIM>
1004 for (
unsigned i=0; i<DIM*(DIM+1)/2; i++)
1015 row = i<=2 ? 0 : (i<=4? 1 : 2);
1016 col = i==0 ? 0 : (i==1 || i==3? 1 : 2);
1023 template<
unsigned DIM>
1028 EXCEPTION(
"Call SetComputeAverageStressPerElementDuringSolve() before solve if calling GetAverageStressesPerElement()");
1032 c_matrix<double,DIM,DIM> stress;
1065 template<
unsigned DIM>
1068 c_matrix<double,DIM,DIM>& rStrain)
1070 static c_matrix<double,DIM,DIM> jacobian;
1071 static c_matrix<double,DIM,DIM> inverse_jacobian;
1072 double jacobian_determinant;
1077 static c_matrix<double,DIM,NUM_NODES_PER_ELEMENT> element_current_displacements;
1080 for (
unsigned JJ=0; JJ<DIM; JJ++)
1087 static c_matrix<double, DIM, NUM_NODES_PER_ELEMENT> grad_quad_phi;
1088 static c_matrix<double,DIM,DIM> grad_u;
1109 grad_u = zero_matrix<double>(DIM,DIM);
1112 for (
unsigned i=0; i<DIM; i++)
1114 for (
unsigned M=0; M<DIM; M++)
1116 grad_u(i,M) += grad_quad_phi(M,node_index)*element_current_displacements(i,node_index);
1121 c_matrix<double,DIM,DIM> deformation_gradient;
1123 for (
unsigned i=0; i<DIM; i++)
1125 for (
unsigned M=0; M<DIM; M++)
1127 deformation_gradient(i,M) = (i==M?1:0) + grad_u(i,M);
1133 case DEFORMATION_GRADIENT_F:
1135 rStrain = deformation_gradient;
1138 case DEFORMATION_TENSOR_C:
1140 rStrain = prod(trans(deformation_gradient),deformation_gradient);
1143 case LAGRANGE_STRAIN_E:
1145 c_matrix<double,DIM,DIM> C = prod(trans(deformation_gradient),deformation_gradient);
1146 for (
unsigned M=0; M<DIM; M++)
1148 for (
unsigned N=0; N<DIM; N++)
1150 rStrain(M,N) = 0.5* ( C(M,N)-(M==N?1:0) );
1163 template<
unsigned DIM>
1166 c_matrix<double,BOUNDARY_STENCIL_SIZE,BOUNDARY_STENCIL_SIZE>& rAelem,
1167 c_vector<double,BOUNDARY_STENCIL_SIZE>& rBelem,
1168 bool assembleResidual,
1169 bool assembleJacobian,
1170 unsigned boundaryConditionIndex)
1173 || this->
mrProblemDefinition.GetTractionBoundaryConditionType() == FUNCTIONAL_PRESSURE_ON_DEFORMED)
1176 assembleResidual, assembleJacobian, boundaryConditionIndex);
1183 if (assembleJacobian && !assembleResidual)
1189 c_vector<double, DIM> weighted_direction;
1190 double jacobian_determinant;
1193 c_vector<double,NUM_NODES_PER_BOUNDARY_ELEMENT> phi;
1205 c_vector<double,DIM> traction = zero_vector<double>(DIM);
1208 case FUNCTIONAL_TRACTION:
1210 c_vector<double,DIM> X = zero_vector<double>(DIM);
1218 case ELEMENTWISE_TRACTION:
1230 unsigned spatial_dim = index%DIM;
1231 unsigned node_index = (index-spatial_dim)/DIM;
1235 rBelem(index) -= traction(spatial_dim)
1242 template<
unsigned DIM>
1264 template<
unsigned DIM>
1267 c_matrix<double,BOUNDARY_STENCIL_SIZE,BOUNDARY_STENCIL_SIZE>& rAelem,
1268 c_vector<double,BOUNDARY_STENCIL_SIZE>& rBelem,
1269 bool assembleResidual,
1270 bool assembleJacobian,
1271 unsigned boundaryConditionIndex)
1273 assert( this->
mrProblemDefinition.GetTractionBoundaryConditionType()==PRESSURE_ON_DEFORMED
1274 || this->
mrProblemDefinition.GetTractionBoundaryConditionType()==FUNCTIONAL_PRESSURE_ON_DEFORMED);
1279 c_vector<double, DIM> weighted_direction;
1280 double jacobian_determinant;
1291 std::set<unsigned> potential_elements = rBoundaryElement.
GetNode(0)->rGetContainingElementIndices();
1292 for (std::set<unsigned>::iterator iter = potential_elements.begin();
1293 iter != potential_elements.end();
1298 bool this_vol_ele_contains_surf_ele =
true;
1303 bool found_this_node =
false;
1304 for (
unsigned j=0; j<p_containing_vol_element->
GetNumNodes(); j++)
1307 if (surf_element_node_index == vol_element_node_index)
1309 found_this_node =
true;
1313 if (!found_this_node)
1315 this_vol_ele_contains_surf_ele =
false;
1319 if (this_vol_ele_contains_surf_ele)
1334 surf_to_vol_map[i] = j;
1343 static c_matrix<double,DIM,DIM> jacobian_vol_element;
1344 static c_matrix<double,DIM,DIM> inverse_jacobian_vol_element;
1345 double jacobian_determinant_vol_element;
1349 static c_matrix<double,DIM,NUM_NODES_PER_ELEMENT> element_current_displacements;
1352 for (
unsigned JJ=0; JJ<DIM; JJ++)
1360 static c_matrix<double, DIM, NUM_NODES_PER_ELEMENT> grad_quad_phi_vol_element;
1362 c_vector<double,NUM_NODES_PER_BOUNDARY_ELEMENT> quad_phi_surf_element;
1364 static c_matrix<double, DIM, NUM_NODES_PER_BOUNDARY_ELEMENT> grad_quad_phi_surf_element;
1366 c_matrix<double,DIM,DIM> F;
1367 c_matrix<double,DIM,DIM> invF;
1370 c_matrix<double,1,DIM> normal_as_mat;
1371 for (
unsigned i=0; i<DIM; i++)
1373 normal_as_mat(0,i) = normal(i);
1376 double normal_pressure;
1379 case PRESSURE_ON_DEFORMED:
1382 case FUNCTIONAL_PRESSURE_ON_DEFORMED:
1402 c_vector<double,DIM> X = zero_vector<double>(DIM);
1405 X += quad_phi_surf_element(node_index)*rBoundaryElement.
GetNode(node_index)->rGetLocation();
1411 c_vector<double,DIM> xi;
1412 for (
unsigned i=0; i<DIM; i++)
1414 xi(i) = weight(i+1);
1420 assert( DIM!=2 || (fabs(weight(0))<1e-6) || (fabs(weight(1))<1e-6) || (fabs(weight(2))<1e-6) );
1424 assert( DIM!=3 || (fabs(weight(0))<1e-6) || (fabs(weight(1))<1e-6) || (fabs(weight(2))<1e-6) || (fabs(weight(3))<1e-6) );
1430 F = identity_matrix<double>(DIM,DIM);
1433 for (
unsigned i=0; i<DIM; i++)
1435 for (
unsigned M=0; M<DIM; M++)
1437 F(i,M) += grad_quad_phi_vol_element(M,node_index)*element_current_displacements(i,node_index);
1445 if (assembleResidual)
1447 c_vector<double,DIM> traction = detF*normal_pressure*prod(trans(invF),normal);
1450 for (
unsigned index=0; index<NUM_NODES_PER_BOUNDARY_ELEMENT*DIM; index++)
1452 unsigned spatial_dim = index%DIM;
1453 unsigned node_index = (index-spatial_dim)/DIM;
1455 assert(node_index < NUM_NODES_PER_BOUNDARY_ELEMENT);
1457 rBelem(index) -= traction(spatial_dim)
1458 * quad_phi_surf_element(node_index)
1470 for (
unsigned N=0; N<DIM; N++)
1472 grad_quad_phi_surf_element(N,II) = grad_quad_phi_vol_element(N,surf_to_vol_map[II]);
1477 for (
unsigned N=0; N<DIM; N++)
1479 for (
unsigned e=0; e<DIM; e++)
1481 for (
unsigned M=0; M<DIM; M++)
1483 for (
unsigned d=0; d<DIM; d++)
1485 tensor1(N,e,M,d) = invF(N,e)*invF(M,d) - invF(M,e)*invF(N,d);
1493 tensor2.template SetAsContractionOnFirstDimension<DIM>( trans(grad_quad_phi_surf_element), tensor1);
1498 tensor3.template SetAsContractionOnThirdDimension<DIM>( normal_as_mat, tensor2);
1500 for (
unsigned index1=0; index1<NUM_NODES_PER_BOUNDARY_ELEMENT*DIM; index1++)
1502 unsigned spatial_dim1 = index1%DIM;
1503 unsigned node_index1 = (index1-spatial_dim1)/DIM;
1505 for (
unsigned index2=0; index2<NUM_NODES_PER_BOUNDARY_ELEMENT*DIM; index2++)
1507 unsigned spatial_dim2 = index2%DIM;
1508 unsigned node_index2 = (index2-spatial_dim2)/DIM;
1510 rAelem(index1,index2) -= normal_pressure
1512 * tensor3(node_index2,spatial_dim2,0,spatial_dim1)
1513 * quad_phi_surf_element(node_index1)
1521 template<
unsigned DIM>
1535 mCheckedOutwardNormals =
true;
1565 template<
unsigned DIM>
1576 KSPGetPC(solver, &pc);
1582 KSPSetType(solver,KSPPREONLY);
1585 PCSetType(pc, PCLU);
1594 KSPSetType(solver,KSPCG);
1597 PCSetType(pc, PCICC);
1601 #if (PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR >= 1) //PETSc 3.1 or later 1609 PCSetType(pc, PCBJACOBI);
1614 unsigned num_restarts = 100;
1615 KSPSetType(solver,KSPGMRES);
1616 KSPGMRESSetRestart(solver,num_restarts);
1618 #ifndef MECH_USE_HYPRE 1619 PCSetType(pc, PCBJACOBI);
1629 PCSetType(pc, PCHYPRE);
1630 #if (PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR >=2) //PETSc 3.2 or later 1631 KSPSetPCSide(solver, PC_RIGHT);
1633 KSPSetPreconditionerSide(solver, PC_RIGHT);
1651 template<
unsigned DIM>
1654 if (!allowException)
1677 template<
unsigned DIM>
1687 template<
unsigned DIM>
1691 std::vector<double>& rZ)
1693 assert(rX.size()==rY.
GetSize());
1694 assert(rY.
GetSize()==rZ.size());
1695 for (
unsigned i=0; i<rX.size(); i++)
1697 rZ[i] = rX[i] + a*rY[i];
1701 template<
unsigned DIM>
1729 KSPCreate(PETSC_COMM_WORLD,&solver);
1731 #if ((PETSC_VERSION_MAJOR==3) && (PETSC_VERSION_MINOR>=5)) 1743 KSPSetFromOptions(solver);
1756 Vec linsys_residual;
1760 double initial_resid_norm;
1761 VecNorm(linsys_residual, NORM_2, &initial_resid_norm);
1767 double ksp_rel_tol = 1e-6;
1768 double absolute_tol = ksp_rel_tol * initial_resid_norm;
1769 if (absolute_tol < 1e-12)
1771 absolute_tol = 1e-12;
1773 KSPSetTolerances(solver, 1e-16, absolute_tol, PETSC_DEFAULT, 1000 );
1777 KSPSetTolerances(solver, 1e-16,
mKspAbsoluteTol, PETSC_DEFAULT, 1000 );
1811 KSPConvergedReason reason;
1812 KSPGetConvergedReason(solver,&reason);
1814 if (reason != KSP_DIVERGED_ITS)
1832 WARN_ONCE_ONLY(
"Linear solve (within a mechanics solve) didn't converge, but this may not stop nonlinear solve converging")
1838 KSPGetIterationNumber(solver, &num_iters);
1843 EXCEPTION(
"KSP Absolute tolerance was too high, linear system wasn't solved - there will be no decrease in Newton residual. Decrease KspAbsoluteTolerance");
1850 std::cout <<
"[" <<
PetscTools::GetMyRank() <<
"]: Num iterations = " << num_iters <<
"\n" << std::flush;
1875 return new_norm_resid;
1878 template<
unsigned DIM>
1883 std::cout <<
"\tTesting s = " << s <<
", |f| = " << residNorm <<
"\n" << std::flush;
1887 template<
unsigned DIM>
1893 std::cout <<
"\tInitial |f| [corresponding to s=0] is " << initial_norm_resid <<
"\n" << std::flush;
1900 std::vector<double> damping_values;
1901 for (
unsigned i=10; i>=1; i--)
1903 damping_values.push_back((
double)i/10.0);
1905 damping_values.push_back(0.05);
1906 assert(damping_values.size()==11);
1925 while ( (next_resid_norm==DBL_MAX)
1926 || ( (next_resid_norm < current_resid_norm) && (index<damping_values.size()) ) )
1928 current_resid_norm = next_resid_norm;
1938 unsigned best_index;
1940 if (index==damping_values.size() && (next_resid_norm < current_resid_norm))
1950 current_resid_norm = next_resid_norm;
1951 best_index = index-1;
1958 best_index = index-2;
1966 if (initial_norm_resid < current_resid_norm && !full_first_step)
1969 EXCEPTION(
"Residual does not appear to decrease in newton direction, quitting");
1974 if (full_first_step)
1978 std::cout <<
"\tTaking full first Newton step...\n";
1985 std::cout <<
"\tChoosing s = " << damping_values[best_index] <<
"\n" << std::flush;
2023 return current_resid_norm;
2026 template<
unsigned DIM>
2031 template<
unsigned DIM>
2045 std::cout <<
"\nNorm of residual is " << norm_resid <<
"\n";
2049 unsigned iteration_number = 1;
2069 std::cout <<
"Solving with tolerance " << tol <<
"\n";
2072 while (norm_resid > tol)
2076 std::cout <<
"\n-------------------\n" 2077 <<
"Newton iteration " << iteration_number
2078 <<
":\n-------------------\n";
2087 std::cout <<
"Norm of residual is " << norm_resid <<
"\n";
2100 if (iteration_number==20)
2103 EXCEPTION(
"Not converged after 20 newton iterations, quitting");
2108 if (norm_resid > tol)
2116 template<
unsigned DIM>
2126 template<
unsigned DIM>
2132 double* p_initial_guess;
2133 VecGetArray(initial_guess, &p_initial_guess);
2135 VecGetOwnershipRange(initial_guess, &lo, &hi);
2136 for (
int global_index=lo; global_index<hi; global_index++)
2138 int local_index = global_index - lo;
2141 VecRestoreArray(initial_guess, &p_initial_guess);
2144 Vec snes_residual_vec;
2149 SNESCreate(PETSC_COMM_WORLD, &snes);
2150 SNESSetFunction(snes, snes_residual_vec, &AbstractNonlinearElasticitySolver_ComputeResidual<DIM>,
this);
2152 #if (PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR >= 4) //PETSc 3.4 or later 2153 SNESSetType(snes, SNESNEWTONLS);
2155 SNESSetType(snes, SNESLS);
2157 SNESSetTolerances(snes, 1e-5, 1e-5, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT);
2159 #if (PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR == 3) //PETSc 3.3 2160 SNESLineSearch linesearch;
2161 SNESGetSNESLineSearch(snes, &linesearch);
2163 SNESLineSearchSetType(linesearch,
"cp");
2164 #elif (PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR >= 4) //PETSc 3.4 or later 2165 SNESLineSearch linesearch;
2166 SNESGetLineSearch(snes, &linesearch);
2168 SNESLineSearchSetType(linesearch,
"cp");
2171 SNESSetMaxLinearSolveFailures(snes,100);
2174 SNESGetKSP(snes, &ksp);
2176 KSPSetTolerances(ksp, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, 1000 );
2185 SNESSetFromOptions(snes);
2187 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2 2188 PetscErrorCode err = SNESSolve(snes, initial_guess);
2190 PetscErrorCode err = SNESSolve(snes, PETSC_NULL, initial_guess);
2193 SNESConvergedReason reason;
2194 SNESGetConvergedReason(snes,&reason);
2199 std::stringstream err_stream;
2204 EXCEPTION(
"Nonlinear Solver failed. PETSc error code: "+err_stream.str()+
" .");
2209 std::stringstream reason_stream;
2210 reason_stream << reason;
2214 EXCEPTION(
"Nonlinear Solver did not converge. PETSc reason code: "+reason_stream.str()+
" .");
2219 SNESGetIterationNumber(snes,&num_iters);
2227 template<
unsigned DIM>
2235 for (
unsigned i=0; i<guess_repl.
GetSize(); i++)
2243 template<
unsigned DIM>
2258 for (
unsigned i=0; i<guess_repl.
GetSize(); i++)
2267 template<
unsigned DIM>
2268 PetscErrorCode AbstractNonlinearElasticitySolver_ComputeResidual(SNES snes,
2279 template<
unsigned DIM>
2280 #if ((PETSC_VERSION_MAJOR==3) && (PETSC_VERSION_MINOR>=5)) 2281 PetscErrorCode AbstractNonlinearElasticitySolver_ComputeJacobian(SNES snes,
2289 p_solver->
ComputeJacobian(currentGuess, &globalJacobian, &preconditioner);
2293 PetscErrorCode AbstractNonlinearElasticitySolver_ComputeJacobian(SNES snes,
2295 Mat* pGlobalJacobian,
2296 Mat* pPreconditioner,
2297 MatStructure* pMatStructure,
2302 p_solver->
ComputeJacobian(currentGuess, pGlobalJacobian, pPreconditioner);
2310 template<
unsigned DIM>
2313 template<
unsigned DIM>
2316 template<
unsigned DIM>
void SetComputeAverageStressPerElementDuringSolve(bool setComputeAverageStressPerElement=true)
ElementIterator GetElementIteratorBegin(bool skipDeletedElements=true)
void ApplyDirichletBoundaryConditions(ApplyDirichletBcsType type, bool symmetricProblem)
void GetElementCentroidStrain(StrainType strainType, Element< DIM, DIM > &rElement, c_matrix< double, DIM, DIM > &rDeformationGradient)
static double NEWTON_REL_TOL
Vec mLinearSystemRhsVector
c_vector< double, DIM > & rGetLocation()
AbstractTetrahedralMesh< DIM, DIM > & mrQuadMesh
boost::numeric::ublas::c_matrix< T, 1, 1 > Inverse(const boost::numeric::ublas::c_matrix< T, 1, 1 > &rM)
AbstractNonlinearElasticitySolver(AbstractTetrahedralMesh< DIM, DIM > &rQuadMesh, SolidMechanicsProblemDefinition< DIM > &rProblemDefinition, std::string outputDirectory, CompressibilityType compressibilityType)
unsigned GetNodeGlobalIndex(unsigned localIndex) const
void SetCurrentTime(double time)
ElementIterator GetElementIteratorEnd()
void WriteCurrentSpatialSolution(std::string fileName, std::string fileExtension, int counterToAppend=-1)
Node< SPACE_DIM > * GetNode(unsigned index) const
unsigned GetNumNewtonIterations()
virtual unsigned GetNumElements() const
#define EXCEPTION(message)
static void BeginEvent(unsigned event)
Element< ELEMENT_DIM, SPACE_DIM > * GetElement(unsigned index) const
virtual void AddActiveStressAndStressDerivative(c_matrix< double, DIM, DIM > &rC, unsigned elementIndex, unsigned currentQuadPointGlobalIndex, c_matrix< double, DIM, DIM > &rT, FourthOrderTensor< DIM, DIM, DIM, DIM > &rDTdE, bool addToDTdE)
std::vector< c_vector< double, DIM *(DIM+1)/2 > > mAverageStressesPerElement
static void ComputeTransformedBasisFunctionDerivatives(const ChastePoint< ELEMENT_DIM > &rPoint, const c_matrix< double, ELEMENT_DIM, ELEMENT_DIM > &rInverseJacobian, c_matrix< double, ELEMENT_DIM,(ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2 > &rReturnValue)
T Determinant(const boost::numeric::ublas::c_matrix< T, 1, 1 > &rM)
bool mTakeFullFirstNewtonStep
c_matrix< double, DIM, DIM > GetAverageStressPerElement(unsigned elementIndex)
std::vector< c_vector< double, DIM > > mSpatialSolution
AbstractNonlinearElasticitySolver< DIM > * mpSolver
virtual unsigned GetNumNodes() const
virtual void SetupChangeOfBasisMatrix(unsigned elementIndex, unsigned currentQuadPointGlobalIndex)
void CheckOutwardNormals()
bool mCheckedOutwardNormals
static void PrintAndReset(std::string message)
unsigned GetNumQuadPoints() const
virtual void GetInverseJacobianForElement(unsigned elementIndex, c_matrix< double, SPACE_DIM, ELEMENT_DIM > &rJacobian, double &rJacobianDeterminant, c_matrix< double, ELEMENT_DIM, SPACE_DIM > &rInverseJacobian) const
void PrintLineSearchResult(double s, double residNorm)
bool OptionExists(const std::string &rOption)
Node< SPACE_DIM > * GetNode(unsigned localIndex) const
void Visit(Element< DIM, DIM > *pElement, unsigned localIndex, c_vector< double, DIM *DIM > &rData)
out_stream OpenOutputFile(const std::string &rFileName, std::ios_base::openmode mode=std::ios::out|std::ios::trunc) const
static const size_t NUM_NODES_PER_ELEMENT
double CalculateResidualNorm()
void RemovePressureDummyValuesThroughLinearInterpolation()
void SetTakeFullFirstNewtonStep(bool takeFullFirstStep=true)
SolidMechanicsProblemDefinition< DIM > & mrProblemDefinition
virtual void AssembleSystem(bool assembleResidual, bool assembleLinearSystem)=0
StressPerElementWriter(AbstractTetrahedralMesh< DIM, DIM > *pMesh, AbstractNonlinearElasticitySolver< DIM > *pSolver)
virtual void PostNewtonStep(unsigned counter, double normResidual)
void SolveNonSnes(double tol=-1.0)
static double MAX_NEWTON_ABS_TOL
void SetKspAbsoluteTolerance(double kspAbsoluteTolerance)
virtual void GetWeightedDirectionForBoundaryElement(unsigned elementIndex, c_vector< double, SPACE_DIM > &rWeightedDirection, double &rJacobianDeterminant) const
static const size_t NUM_NODES_PER_BOUNDARY_ELEMENT
static void ComputeBasisFunctions(const ChastePoint< ELEMENT_DIM > &rPoint, c_vector< double,(ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2 > &rReturnValue)
c_matrix< double, DIM, DIM > mChangeOfBasisMatrix
void Solve(double tol=-1.0)
virtual void SetKspSolverAndPcType(KSP solver)
unsigned GetNumNodes() const
bool mSetComputeAverageStressPerElement
virtual ~AbstractNonlinearElasticitySolver()
std::vector< c_vector< double, DIM > > & rGetSpatialSolution()
bool mIncludeActiveTension
void AssembleOnBoundaryElementForPressureOnDeformedBc(BoundaryElement< DIM-1, DIM > &rBoundaryElement, c_matrix< double, BOUNDARY_STENCIL_SIZE, BOUNDARY_STENCIL_SIZE > &rAelem, c_vector< double, BOUNDARY_STENCIL_SIZE > &rBelem, bool assembleResidual, bool assembleJacobian, unsigned boundaryConditionIndex)
double UpdateSolutionUsingLineSearch(Vec solution)
OutputFileHandler * mpOutputFileHandler
void ComputeResidual(Vec currentGuess, Vec residualVector)
CompressibilityType mCompressibilityType
void AssembleOnBoundaryElement(BoundaryElement< DIM-1, DIM > &rBoundaryElement, c_matrix< double, BOUNDARY_STENCIL_SIZE, BOUNDARY_STENCIL_SIZE > &rAelem, c_vector< double, BOUNDARY_STENCIL_SIZE > &rBelem, bool assembleResidual, bool assembleJacobian, unsigned boundaryConditionIndex)
bool mWriteOutputEachNewtonIteration
void AddStressToAverageStressPerElement(c_matrix< double, DIM, DIM > &rT, unsigned elementIndex)
c_vector< double, SPACE_DIM > CalculateNormal()
void VectorSum(std::vector< double > &rX, ReplicatableVector &rY, double a, std::vector< double > &rZ)
std::vector< double > mCurrentSolution
void WriteCurrentAverageElementStresses(std::string fileName, int counterToAppend=-1)
unsigned mNumNewtonIterations
void ComputeJacobian(Vec currentGuess, Mat *pJacobian, Mat *pPreconditioner)
unsigned GetIndex() const
void SetWriteOutputEachNewtonIteration(bool writeOutputEachNewtonIteration=true)
unsigned mProblemDimension
double GetWeight(unsigned index) const
static CommandLineArguments * Instance()
static double MIN_NEWTON_ABS_TOL
virtual void FinishAssembleSystem(bool assembleResidual, bool assembleLinearSystem)
static void EndEvent(unsigned event)
GaussianQuadratureRule< DIM-1 > * mpBoundaryQuadratureRule
void SetIncludeActiveTension(bool includeActiveTension=true)
const ChastePoint< ELEMENT_DIM > & rGetQuadPoint(unsigned index) const
std::string mOutputDirectory
void WriteCurrentStrains(StrainType strainType, std::string fileName, int counterToAppend=-1)
bool ShouldAssembleMatrixTermForPressureOnDeformedBc()
c_vector< double, SPACE_DIM+1 > CalculateInterpolationWeights(const ChastePoint< SPACE_DIM > &rTestPoint)
void SetUsePetscDirectSolve(bool usePetscDirectSolve=true)
FourthOrderTensor< DIM, DIM, DIM, DIM > dTdE
double ComputeResidualAndGetNorm(bool allowException)
std::vector< c_vector< double, DIM > > & rGetDeformedPosition()