55 RegisterCreatorFunction(
"LinearElasticSystem",
70 int n = geom->GetNumVerts(), i, j;
76 for (i = 0; i < n; ++i)
78 for (j = 0; j < n-1; ++j)
80 map(j,i) = (*geom->GetVertex(i))[j];
87 mapref(0,0) = -1.0; mapref(1,0) = -1.0;
88 mapref(0,1) = 1.0; mapref(1,1) = -1.0;
89 mapref(0,2) = -1.0; mapref(1,2) = 1.0;
93 mapref(0,0) = -1.0; mapref(1,0) = -1.0; mapref(2,0) = -1.0;
94 mapref(0,1) = 1.0; mapref(1,1) = -1.0; mapref(2,1) = -1.0;
95 mapref(0,2) = -1.0; mapref(1,2) = 1.0; mapref(2,2) = -1.0;
96 mapref(0,3) = -1.0; mapref(1,3) = -1.0; mapref(2,3) = 1.0;
104 for (i = 0; i < n-1; ++i)
106 for (j = 0; j < n-1; ++j)
108 mapred(i,j) = newmap(i,j);
134 EquationSystem::v_InitObject();
136 const int nVel =
m_fields[0]->GetCoordim(0);
139 ASSERTL0(nVel > 1,
"Linear elastic solver not set up for"
140 " this dimension (only 2D/3D supported).");
156 u->GetLocalToGlobalMap(),
168 u->GetLocalToGlobalMap(),
175 const int nEl =
m_fields[0]->GetExpSize();
188 for (n = 0; n < nEl; ++n)
191 sizeBnd[n] = nVel * exp->NumBndryCoeffs();
192 sizeInt[n] = nVel * exp->GetNcoeffs() - sizeBnd[n];
193 exp->GetBoundaryMap(
m_bmap[n]);
194 exp->GetInteriorMap(m_imap[n]);
200 sizeBnd, sizeBnd, blkmatStorage);
202 sizeBnd, sizeInt, blkmatStorage);
204 sizeInt, sizeBnd, blkmatStorage);
206 sizeInt, sizeInt, blkmatStorage);
232 const int nEl =
m_fields[0]->GetExpSize();
233 const int nVel =
m_fields[0]->GetCoordim(0);
245 bool verbose =
m_session->DefinesCmdLineArgument(
"verbose");
246 bool root =
m_session->GetComm()->GetRank() == 0;
251 for (n = 0; n < nEl; ++n)
254 const int nPhys = exp->GetTotPoints();
266 *exp, factors, varcoeffA);
269 *exp, factors, varcoeffD);
276 mat[0][0] = exp->GenMatrix(matkeyA);
278 mat[1][0] = mat[0][1];
279 mat[1][1] = exp->GenMatrix(matkeyD);
286 cout <<
"\rBuilding matrix system: "
287 << (int)(100.0 * n / nEl) <<
"%" << flush;
293 for (n = 0; n < nEl; ++n)
296 const int nPhys = exp->GetTotPoints();
313 *exp, factors, varcoeffA);
316 *exp, factors, varcoeffE);
319 *exp, factors, varcoeffI);
327 mat[0][0] = exp->GenMatrix(matkeyA);
331 mat[1][0] = mat[0][1];
332 mat[1][1] = exp->GenMatrix(matkeyE);
335 mat[2][0] = mat[0][2];
336 mat[2][1] = mat[1][2];
337 mat[2][2] = exp->GenMatrix(matkeyI);
344 cout <<
"\rBuilding matrix system: "
345 << (int)(100.0 * n / nEl) <<
"%" << flush;
352 cout <<
"\rBuilding matrix system: done." << endl;
361 EquationSystem::SessionSummary(s);
385 const int nVel =
m_fields[0]->GetCoordim(0);
417 const int nCoeffs =
m_fields[0]->GetNcoeffs();
430 m_session->LoadSolverInfo(
"Temperature", tempEval,
"None");
432 if (tempEval ==
"Jacobian")
437 for (nv = 0; nv < nVel; ++nv)
443 for (i = 0; i <
m_fields[0]->GetExpSize(); ++i)
449 exp->GetPointsKeys();
451 exp->GetMetricInfo()->GetJac(pkey);
453 int offset =
m_fields[0]->GetPhys_Offset(i);
455 if (exp->GetMetricInfo()->GetGtype() ==
470 else if (tempEval ==
"Metric")
473 m_graph->GetAllQuadGeoms().size() == 0) ||
475 m_graph->GetAllPrismGeoms().size() == 0 &&
476 m_graph->GetAllPyrGeoms ().size() == 0 &&
477 m_graph->GetAllHexGeoms ().size() == 0),
478 "LinearIdealMetric temperature only implemented for "
479 "two-dimensional triangular meshes or three-dimensional "
480 "tetrahedral meshes.");
485 for (nv = 0; nv < nVel; ++nv)
491 for (i = 0; i < nVel; ++i)
498 for (i = 0; i <
m_fields[0]->GetExpSize(); ++i)
505 exp->GetMetricInfo()->GetDeriv(pkey);
506 int offset =
m_fields[0]->GetPhys_Offset(i);
515 for (j = 0; j < deriv[0][0].num_elements(); ++j)
517 for (k = 0; k < nVel; ++k)
519 for (l = 0; l < nVel; ++l)
521 jac(l,k) = deriv[k][l][j];
525 jacIdeal = jac * i2rm;
530 char jobvl =
'N', jobvr =
'V';
531 int worklen = 8*nVel, info;
540 Lapack::Dgeev(jobvl, jobvr, nVel, metric.GetRawPtr(), nVel,
541 &(eval.GetPtr())[0], &wi[0], &vl[0], nVel,
542 &(evec.GetPtr())[0], nVel,
543 &work[0], worklen, info);
549 for (nv = 0; nv < nVel; ++nv)
551 eval(nv,nv) =
m_beta * (sqrt(eval(nv,nv)) - 1.0);
554 DNekMat beta = evec * eval * evecinv;
556 for (k = 0; k < nVel; ++k)
558 for (l = 0; l < nVel; ++l)
560 m_stress[k][l][offset+j] = beta(k,l);
565 if (deriv[0][0].num_elements() != exp->GetTotPoints())
568 for (k = 0; k < nVel; ++k)
570 for (l = 0; l < nVel; ++l)
573 exp->GetTotPoints(), m_stress[k][l][offset],
574 tmp = m_stress[k][l] + offset, 1);
582 for (i = 0; i < nVel; ++i)
584 for (j = 0; j < nVel; ++j)
586 m_fields[i]->PhysDeriv(j, m_stress[i][j], tmpderiv);
595 else if (tempEval !=
"None")
597 ASSERTL0(
false,
"Unknown temperature form: " + tempEval);
614 for (nv = 0; nv < nVel; ++nv)
618 m_fields[nv]->IProductWRTBase_IterPerExp(forcing[nv], tmp);
622 for (i = 0; i <
m_fields[nv]->GetExpSize(); ++i)
624 int nBnd =
m_bmap[i].num_elements();
625 int nInt =
m_imap[i].num_elements();
626 int offset =
m_fields[nv]->GetCoeff_Offset(i);
628 for (j = 0; j < nBnd; ++j)
630 forCoeffs[nVel*offset + nv*nBnd + j] =
633 for (j = 0; j < nInt; ++j)
635 forCoeffs[nVel*(offset + nBnd) + nv*nInt + j] =
647 map<int, vector<MultiRegions::ExtraDirDof> > &extraDirDofs =
649 map<int, vector<MultiRegions::ExtraDirDof> >
::iterator it;
651 for (nv = 0; nv < nVel; ++nv)
654 =
m_fields[nv]->GetBndCondExpansions();
657 for (it = extraDirDofs.begin(); it != extraDirDofs.end(); ++it)
659 for (i = 0; i < it->second.size(); ++i)
661 inout[it->second.at(i).get<1>()*nVel + nv] =
662 bndCondExp[it->first]->GetCoeffs()[
663 it->second.at(i).get<0>()]*it->second.at(i).get<2>();
674 for (nv = 0; nv < nVel; ++nv)
677 =
m_fields[nv]->GetBndCondExpansions();
681 for (i = 0; i < bndCondExp.num_elements(); ++i)
684 bndCondExp[i]->GetCoeffs();
686 for (j = 0; j < bndCondExp[i]->GetNcoeffs(); ++j)
691 inout[bndMap[bndcnt++]] = sign * bndCoeffs[j];
718 for (nv = 0; nv < nVel; ++nv)
720 for (i = 0; i <
m_fields[nv]->GetExpSize(); ++i)
722 int nBnd =
m_bmap[i].num_elements();
723 int nInt =
m_imap[i].num_elements();
724 int offset =
m_fields[nv]->GetCoeff_Offset(i);
726 for (j = 0; j < nBnd; ++j)
729 tmp[nVel*offset + nv*nBnd + j];
731 for (j = 0; j < nInt; ++j)
734 tmp[nVel*(offset + nBnd) + nv*nInt + j];
760 const int nVel = mat.GetRows();
761 const int nB = exp->NumBndryCoeffs();
762 const int nI = exp->GetNcoeffs() - nB;
763 const int nBnd = exp->NumBndryCoeffs() * nVel;
764 const int nInt = exp->GetNcoeffs() * nVel - nBnd;
777 for (i = 0; i < nVel; ++i)
779 for (j = 0; j < nVel; ++j)
782 for (k = 0; k < nB; ++k)
784 for (l = 0; l < nB; ++l)
786 (*A)(k + i*nB, l + j*nB) =
790 for (l = 0; l < nI; ++l)
792 (*B)(k + i*nB, l + j*nI) =
798 for (k = 0; k < nI; ++k)
800 for (l = 0; l < nB; ++l)
802 (*C)(k + i*nI, l + j*nB) =
806 for (l = 0; l < nI; ++l)
808 (*D)(k + i*nI, l + j*nI) =
818 (*A) = (*A) - (*B)*(*C);
848 const int nCoeffs = exp->GetNcoeffs();
849 const int nPhys = exp->GetTotPoints();
853 nCoeffs, nCoeffs, 0.0,
eFULL);
858 for (i = 0; i < nCoeffs; ++i)
863 exp->BwdTrans ( tmp1, tmp2);
864 exp->PhysDeriv (k1, tmp2, tmp3);
865 exp->IProductWRTDerivBase(k2, tmp3, tmp1);
868 nCoeffs, scale, &tmp1[0], 1, &(ret->GetPtr())[0]+i*nCoeffs, 1);
876 std::vector<std::string> &variables)
878 const int nVel =
m_fields[0]->GetCoordim(0);
879 const int nCoeffs =
m_fields[0]->GetNcoeffs();
886 for (
int i = 0; i < nVel; ++i)
890 fieldcoeffs.push_back(tFwd);
892 "ThermStressDiv" + boost::lexical_cast<std::string>(i));
900 for (
int i = 0; i < nVel; ++i)
902 for (
int j = 0; j < nVel; ++j)
906 fieldcoeffs.push_back(tFwd);
909 + boost::lexical_cast<std::string>(i)
910 + boost::lexical_cast<std::string>(j));
static EquationSystemSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession)
Creates an instance of this class.
#define ASSERTL0(condition, msg)
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.
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
#define sign(a, b)
return the sign(b)*a
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.
NekDouble m_nu
Poisson ratio.
virtual void v_DoSolve()
Solve elliptic linear elastic system.
NekDouble m_beta
Parameter dictating amount of thermal stress to add.
boost::shared_ptr< ContField2D > ContField2DSharedPtr
std::map< ConstFactorType, NekDouble > ConstFactorMap
DNekScalBlkMatSharedPtr m_BinvD
Matrix of elemental components.
boost::shared_ptr< DNekMat > DNekMatSharedPtr
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
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.
boost::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
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...
static std::string className
Name of class.
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.
SpatialDomains::BoundaryConditionsSharedPtr m_boundaryConditions
Pointer to boundary conditions object.
LinearElasticSystem(const LibUtilities::SessionReaderSharedPtr &pSession)
Default constructor.
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.
SOLVER_UTILS_EXPORT void EvaluateFunction(Array< OneD, Array< OneD, NekDouble > > &pArray, std::string pFunctionName, const NekDouble pTime=0.0, const int domain=0)
Evaluates a function as specified in the session file.
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.
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
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.
boost::shared_ptr< Expansion > ExpansionSharedPtr
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.
boost::shared_ptr< GlobalLinSys > GlobalLinSysSharedPtr
Pointer to a GlobalLinSys object.
void BuildMatrixSystem()
Build matrix system for linear elasticity equations.
SpatialDomains::MeshGraphSharedPtr m_graph
Pointer to graph defining mesh.
boost::shared_ptr< ContField3D > ContField3DSharedPtr
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.
boost::shared_ptr< Geometry > GeometrySharedPtr
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.