54 #ifdef NEKTAR_USE_PETSC 64 RegisterCreatorFunction(
"LinearElasticSystem",
65 LinearElasticSystem::create);
79 int n = geom->GetNumVerts(), i, j;
85 for (i = 0; i < n; ++i)
87 for (j = 0; j < n-1; ++j)
89 map(j,i) = (*geom->GetVertex(i))[j];
96 mapref(0,0) = -1.0; mapref(1,0) = -1.0;
97 mapref(0,1) = 1.0; mapref(1,1) = -1.0;
98 mapref(0,2) = -1.0; mapref(1,2) = 1.0;
102 mapref(0,0) = -1.0; mapref(1,0) = -1.0; mapref(2,0) = -1.0;
103 mapref(0,1) = 1.0; mapref(1,1) = -1.0; mapref(2,1) = -1.0;
104 mapref(0,2) = -1.0; mapref(1,2) = 1.0; mapref(2,2) = -1.0;
105 mapref(0,3) = -1.0; mapref(1,3) = -1.0; mapref(2,3) = 1.0;
113 for (i = 0; i < n-1; ++i)
115 for (j = 0; j < n-1; ++j)
117 mapred(i,j) = newmap(i,j);
128 LinearElasticSystem::LinearElasticSystem(
146 const int nVel =
m_fields[0]->GetCoordim(0);
149 ASSERTL0(nVel > 1,
"Linear elastic solver not set up for" 150 " this dimension (only 2D/3D supported).");
166 u->GetLocalToGlobalMap(),
178 u->GetLocalToGlobalMap(),
185 const int nEl =
m_fields[0]->GetExpSize();
198 for (n = 0; n < nEl; ++n)
201 sizeBnd[n] = nVel * exp->NumBndryCoeffs();
202 sizeInt[n] = nVel * exp->GetNcoeffs() - sizeBnd[n];
203 exp->GetBoundaryMap(
m_bmap[n]);
204 exp->GetInteriorMap(m_imap[n]);
210 sizeBnd, sizeBnd, blkmatStorage);
212 sizeBnd, sizeInt, blkmatStorage);
214 sizeInt, sizeBnd, blkmatStorage);
216 sizeInt, sizeInt, blkmatStorage);
242 const int nEl =
m_fields[0]->GetExpSize();
243 const int nVel =
m_fields[0]->GetCoordim(0);
255 bool verbose =
m_session->DefinesCmdLineArgument(
"verbose");
256 bool root =
m_session->GetComm()->GetRank() == 0;
261 for (n = 0; n < nEl; ++n)
264 const int nPhys = exp->GetTotPoints();
276 *exp, factors, varcoeffA);
279 *exp, factors, varcoeffD);
286 mat[0][0] = exp->GenMatrix(matkeyA);
288 mat[1][0] = mat[0][1];
289 mat[1][1] = exp->GenMatrix(matkeyD);
296 cout <<
"\rBuilding matrix system: " 297 << (int)(100.0 * n / nEl) <<
"%" << flush;
303 for (n = 0; n < nEl; ++n)
306 const int nPhys = exp->GetTotPoints();
323 *exp, factors, varcoeffA);
326 *exp, factors, varcoeffE);
329 *exp, factors, varcoeffI);
337 mat[0][0] = exp->GenMatrix(matkeyA);
341 mat[1][0] = mat[0][1];
342 mat[1][1] = exp->GenMatrix(matkeyE);
345 mat[2][0] = mat[0][2];
346 mat[2][1] = mat[1][2];
347 mat[2][2] = exp->GenMatrix(matkeyI);
354 cout <<
"\rBuilding matrix system: " 355 << (int)(100.0 * n / nEl) <<
"%" << flush;
362 cout <<
"\rBuilding matrix system: done." << endl;
395 const int nVel =
m_fields[0]->GetCoordim(0);
424 #ifdef NEKTAR_USE_PETSC 434 #ifdef NEKTAR_USE_MPI 447 const int nCoeffs =
m_fields[0]->GetNcoeffs();
460 m_session->LoadSolverInfo(
"Temperature", tempEval,
"None");
462 if (tempEval ==
"Jacobian")
467 for (nv = 0; nv < nVel; ++nv)
473 for (i = 0; i <
m_fields[0]->GetExpSize(); ++i)
479 exp->GetPointsKeys();
481 exp->GetMetricInfo()->GetJac(pkey);
483 int offset =
m_fields[0]->GetPhys_Offset(i);
485 if (exp->GetMetricInfo()->GetGtype() ==
500 else if (tempEval ==
"Metric")
503 m_graph->GetAllQuadGeoms().size() == 0) ||
505 m_graph->GetAllPrismGeoms().size() == 0 &&
506 m_graph->GetAllPyrGeoms ().size() == 0 &&
507 m_graph->GetAllHexGeoms ().size() == 0),
508 "LinearIdealMetric temperature only implemented for " 509 "two-dimensional triangular meshes or three-dimensional " 510 "tetrahedral meshes.");
515 for (nv = 0; nv < nVel; ++nv)
521 for (i = 0; i < nVel; ++i)
528 for (i = 0; i <
m_fields[0]->GetExpSize(); ++i)
535 exp->GetMetricInfo()->GetDeriv(pkey);
536 int offset =
m_fields[0]->GetPhys_Offset(i);
545 for (j = 0; j < deriv[0][0].num_elements(); ++j)
547 for (k = 0; k < nVel; ++k)
549 for (l = 0; l < nVel; ++l)
551 jac(l,k) = deriv[k][l][j];
555 jacIdeal = jac * i2rm;
560 char jobvl =
'N', jobvr =
'V';
561 int worklen = 8*nVel, info;
571 &(eval.GetPtr())[0], &wi[0], &vl[0], nVel,
572 &(evec.GetPtr())[0], nVel,
573 &work[0], worklen, info);
579 for (nv = 0; nv < nVel; ++nv)
581 eval(nv,nv) =
m_beta * (sqrt(eval(nv,nv)) - 1.0);
584 DNekMat beta = evec * eval * evecinv;
586 for (k = 0; k < nVel; ++k)
588 for (l = 0; l < nVel; ++l)
590 m_stress[k][l][offset+j] = beta(k,l);
595 if (deriv[0][0].num_elements() != exp->GetTotPoints())
598 for (k = 0; k < nVel; ++k)
600 for (l = 0; l < nVel; ++l)
603 exp->GetTotPoints(), m_stress[k][l][offset],
604 tmp = m_stress[k][l] + offset, 1);
612 for (i = 0; i < nVel; ++i)
614 for (j = 0; j < nVel; ++j)
616 m_fields[i]->PhysDeriv(j, m_stress[i][j], tmpderiv);
625 else if (tempEval !=
"None")
627 ASSERTL0(
false,
"Unknown temperature form: " + tempEval);
644 for (nv = 0; nv < nVel; ++nv)
648 m_fields[nv]->IProductWRTBase_IterPerExp(forcing[nv], tmp);
652 for (i = 0; i <
m_fields[nv]->GetExpSize(); ++i)
654 int nBnd =
m_bmap[i].num_elements();
655 int nInt =
m_imap[i].num_elements();
656 int offset =
m_fields[nv]->GetCoeff_Offset(i);
658 for (j = 0; j < nBnd; ++j)
660 forCoeffs[nVel*offset + nv*nBnd + j] =
663 for (j = 0; j < nInt; ++j)
665 forCoeffs[nVel*(offset + nBnd) + nv*nInt + j] =
677 map<int, vector<MultiRegions::ExtraDirDof> > &extraDirDofs =
680 for (nv = 0; nv < nVel; ++nv)
683 =
m_fields[nv]->GetBndCondExpansions();
686 for (
auto &it : extraDirDofs)
688 for (i = 0; i < it.second.size(); ++i)
690 inout[std::get<1>(it.second.at(i))*nVel + nv] =
691 bndCondExp[it.first]->GetCoeffs()[
692 std::get<0>(it.second.at(i))]*std::get<2>(it.second.at(i));
703 for (nv = 0; nv < nVel; ++nv)
706 =
m_fields[nv]->GetBndCondExpansions();
710 for (i = 0; i < bndCondExp.num_elements(); ++i)
712 if (
m_fields[nv]->GetBndConditions()[i]->GetBoundaryConditionType()
716 bndCondExp[i]->GetCoeffs();
718 for (j = 0; j < bndCondExp[i]->GetNcoeffs(); ++j)
723 inout[bndMap[bndcnt++]] = sign * bndCoeffs[j];
728 bndcnt += bndCondExp[i]->GetNcoeffs();
755 for (nv = 0; nv < nVel; ++nv)
757 for (i = 0; i <
m_fields[nv]->GetExpSize(); ++i)
759 int nBnd =
m_bmap[i].num_elements();
760 int nInt =
m_imap[i].num_elements();
761 int offset =
m_fields[nv]->GetCoeff_Offset(i);
763 for (j = 0; j < nBnd; ++j)
766 tmp[nVel*offset + nv*nBnd + j];
768 for (j = 0; j < nInt; ++j)
771 tmp[nVel*(offset + nBnd) + nv*nInt + j];
797 const int nVel = mat.GetRows();
798 const int nB = exp->NumBndryCoeffs();
799 const int nI = exp->GetNcoeffs() - nB;
800 const int nBnd = exp->NumBndryCoeffs() * nVel;
801 const int nInt = exp->GetNcoeffs() * nVel - nBnd;
814 for (i = 0; i < nVel; ++i)
816 for (j = 0; j < nVel; ++j)
819 for (k = 0; k < nB; ++k)
821 for (l = 0; l < nB; ++l)
823 (*A)(k + i*nB, l + j*nB) =
827 for (l = 0; l < nI; ++l)
829 (*B)(k + i*nB, l + j*nI) =
835 for (k = 0; k < nI; ++k)
837 for (l = 0; l < nB; ++l)
839 (*C)(k + i*nI, l + j*nB) =
843 for (l = 0; l < nI; ++l)
845 (*D)(k + i*nI, l + j*nI) =
855 (*A) = (*A) - (*B)*(*C);
885 const int nCoeffs = exp->GetNcoeffs();
886 const int nPhys = exp->GetTotPoints();
890 nCoeffs, nCoeffs, 0.0,
eFULL);
895 for (i = 0; i < nCoeffs; ++i)
900 exp->BwdTrans ( tmp1, tmp2);
901 exp->PhysDeriv (k1, tmp2, tmp3);
902 exp->IProductWRTDerivBase(k2, tmp3, tmp1);
905 nCoeffs, scale, &tmp1[0], 1, &(ret->GetPtr())[0]+i*nCoeffs, 1);
913 std::vector<std::string> &variables)
915 const int nVel =
m_fields[0]->GetCoordim(0);
916 const int nCoeffs =
m_fields[0]->GetNcoeffs();
923 for (
int i = 0; i < nVel; ++i)
927 fieldcoeffs.push_back(tFwd);
929 "ThermStressDiv" + boost::lexical_cast<std::string>(i));
937 for (
int i = 0; i < nVel; ++i)
939 for (
int j = 0; j < nVel; ++j)
943 fieldcoeffs.push_back(tFwd);
946 + boost::lexical_cast<std::string>(i)
947 + boost::lexical_cast<std::string>(j));
#define ASSERTL0(condition, msg)
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
virtual void v_InitObject()
Set up the linear elasticity system.
void SetStaticCondBlock(const int n, const LocalRegions::ExpansionSharedPtr exp, Array< TwoD, DNekMatSharedPtr > &mat)
Given a block matrix for an element, construct its static condensation matrices.
std::vector< PointsKey > PointsKeyVector
A base class for describing how to solve specific equations.
#define sign(a, b)
return the sign(b)*a
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
virtual void v_ExtraFldOutput(std::vector< Array< OneD, NekDouble > > &fieldcoeffs, std::vector< std::string > &variables)
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
std::vector< std::pair< std::string, std::string > > SummaryList
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
std::shared_ptr< ContField2D > ContField2DSharedPtr
NekDouble m_nu
Poisson ratio.
std::shared_ptr< GlobalLinSys > GlobalLinSysSharedPtr
Pointer to a GlobalLinSys object.
virtual void v_DoSolve()
Solve elliptic linear elastic system.
NekDouble m_beta
Parameter dictating amount of thermal stress to add.
std::map< ConstFactorType, NekDouble > ConstFactorMap
std::shared_ptr< DNekMat > DNekMatSharedPtr
DNekScalBlkMatSharedPtr m_BinvD
Matrix of elemental components.
Array< OneD, Array< OneD, NekDouble > > m_temperature
Storage for the temperature terms.
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_stress
Storage for the thermal stress terms.
static void Dgeev(const char &uplo, const char &lrev, const int &n, const double *a, const int &lda, double *wr, double *wi, double *rev, const int &ldr, double *lev, const int &ldv, double *work, const int &lwork, int &info)
Solve general real matrix eigenproblem.
virtual SOLVER_UTILS_EXPORT void v_InitObject()
Initialisation object for EquationSystem.
std::shared_ptr< ContField3D > ContField3DSharedPtr
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*y.
static PreconditionerSharedPtr NullPreconditionerSharedPtr
This class is the abstraction of a global continuous two- dimensional spectral/hp element expansion w...
virtual void v_GenerateSummary(SolverUtils::SummaryList &s)
Generate summary at runtime.
std::map< StdRegions::VarCoeffType, Array< OneD, NekDouble > > VarCoeffMap
void AddSummaryItem(SummaryList &l, const std::string &name, const std::string &value)
Adds a summary item to the summary info list.
DNekScalBlkMatSharedPtr m_Dinv
Matrix of elemental components.
std::shared_ptr< Geometry > GeometrySharedPtr
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
void Neg(int n, T *x, const int incx)
Negate x = -x.
Array< OneD, Array< OneD, unsigned int > > m_imap
Interior maps for each of the fields.
Describe a linear system.
DNekScalBlkMatSharedPtr m_schurCompl
Schur complement boundary-boundary matrix.
EquationSystemFactory & GetEquationSystemFactory()
DNekScalBlkMatSharedPtr m_C
Matrix of elemental components.
NekDouble m_E
Young's modulus.
std::shared_ptr< Expansion > ExpansionSharedPtr
SOLVER_UTILS_EXPORT SessionFunctionSharedPtr GetFunction(std::string name, const MultiRegions::ExpListSharedPtr &field=MultiRegions::NullExpListSharedPtr, bool cache=false)
Get a SessionFunction by name.
DNekMatSharedPtr BuildLaplacianIJMatrix(const int k1, const int k2, const NekDouble scale, LocalRegions::ExpansionSharedPtr exp)
Construct a LaplacianIJ matrix for a given expansion.
SOLVER_UTILS_EXPORT int GetNpoints()
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
CoupledAssemblyMapSharedPtr m_assemblyMap
Assembly map for the coupled (u,v,w) system.
Array< OneD, Array< OneD, unsigned int > > m_bmap
Boundary maps for each of the fields.
SOLVER_UTILS_EXPORT void SessionSummary(SummaryList &vSummary)
Write out a session summary.
void BuildMatrixSystem()
Build matrix system for linear elasticity equations.
SpatialDomains::MeshGraphSharedPtr m_graph
Pointer to graph defining mesh.
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs
DNekMat MappingIdealToRef(SpatialDomains::GeometrySharedPtr geom)
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Geometry is curved or has non-constant factors.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.