55 #ifdef NEKTAR_USE_PETSC
63 RegisterCreatorFunction(
"LinearElasticSystem",
78 int n = geom->GetNumVerts(), i, j;
84 for (i = 0; i < n; ++i)
86 for (j = 0; j < n-1; ++j)
88 map(j,i) = (*geom->GetVertex(i))[j];
95 mapref(0,0) = -1.0; mapref(1,0) = -1.0;
96 mapref(0,1) = 1.0; mapref(1,1) = -1.0;
97 mapref(0,2) = -1.0; mapref(1,2) = 1.0;
101 mapref(0,0) = -1.0; mapref(1,0) = -1.0; mapref(2,0) = -1.0;
102 mapref(0,1) = 1.0; mapref(1,1) = -1.0; mapref(2,1) = -1.0;
103 mapref(0,2) = -1.0; mapref(1,2) = 1.0; mapref(2,2) = -1.0;
104 mapref(0,3) = -1.0; mapref(1,3) = -1.0; mapref(2,3) = 1.0;
112 for (i = 0; i < n-1; ++i)
114 for (j = 0; j < n-1; ++j)
116 mapred(i,j) = newmap(i,j);
142 EquationSystem::v_InitObject();
144 const int nVel =
m_fields[0]->GetCoordim(0);
147 ASSERTL0(nVel > 1,
"Linear elastic solver not set up for"
148 " this dimension (only 2D/3D supported).");
164 u->GetLocalToGlobalMap(),
176 u->GetLocalToGlobalMap(),
183 const int nEl =
m_fields[0]->GetExpSize();
196 for (n = 0; n < nEl; ++n)
199 sizeBnd[n] = nVel * exp->NumBndryCoeffs();
200 sizeInt[n] = nVel * exp->GetNcoeffs() - sizeBnd[n];
201 exp->GetBoundaryMap(
m_bmap[n]);
202 exp->GetInteriorMap(m_imap[n]);
208 sizeBnd, sizeBnd, blkmatStorage);
210 sizeBnd, sizeInt, blkmatStorage);
212 sizeInt, sizeBnd, blkmatStorage);
214 sizeInt, sizeInt, blkmatStorage);
240 const int nEl =
m_fields[0]->GetExpSize();
241 const int nVel =
m_fields[0]->GetCoordim(0);
253 bool verbose =
m_session->DefinesCmdLineArgument(
"verbose");
254 bool root =
m_session->GetComm()->GetRank() == 0;
259 for (n = 0; n < nEl; ++n)
262 const int nPhys = exp->GetTotPoints();
274 *exp, factors, varcoeffA);
277 *exp, factors, varcoeffD);
284 mat[0][0] = exp->GenMatrix(matkeyA);
286 mat[1][0] = mat[0][1];
287 mat[1][1] = exp->GenMatrix(matkeyD);
294 cout <<
"\rBuilding matrix system: "
295 << (int)(100.0 * n / nEl) <<
"%" << flush;
301 for (n = 0; n < nEl; ++n)
304 const int nPhys = exp->GetTotPoints();
321 *exp, factors, varcoeffA);
324 *exp, factors, varcoeffE);
327 *exp, factors, varcoeffI);
335 mat[0][0] = exp->GenMatrix(matkeyA);
339 mat[1][0] = mat[0][1];
340 mat[1][1] = exp->GenMatrix(matkeyE);
343 mat[2][0] = mat[0][2];
344 mat[2][1] = mat[1][2];
345 mat[2][2] = exp->GenMatrix(matkeyI);
352 cout <<
"\rBuilding matrix system: "
353 << (int)(100.0 * n / nEl) <<
"%" << flush;
360 cout <<
"\rBuilding matrix system: done." << endl;
369 EquationSystem::SessionSummary(s);
393 const int nVel =
m_fields[0]->GetCoordim(0);
422 #ifdef NEKTAR_USE_PETSC
432 #ifdef NEKTAR_USE_MPI
445 const int nCoeffs =
m_fields[0]->GetNcoeffs();
458 m_session->LoadSolverInfo(
"Temperature", tempEval,
"None");
460 if (tempEval ==
"Jacobian")
465 for (nv = 0; nv < nVel; ++nv)
471 for (i = 0; i <
m_fields[0]->GetExpSize(); ++i)
477 exp->GetPointsKeys();
479 exp->GetMetricInfo()->GetJac(pkey);
481 int offset =
m_fields[0]->GetPhys_Offset(i);
483 if (exp->GetMetricInfo()->GetGtype() ==
498 else if (tempEval ==
"Metric")
501 m_graph->GetAllQuadGeoms().size() == 0) ||
503 m_graph->GetAllPrismGeoms().size() == 0 &&
504 m_graph->GetAllPyrGeoms ().size() == 0 &&
505 m_graph->GetAllHexGeoms ().size() == 0),
506 "LinearIdealMetric temperature only implemented for "
507 "two-dimensional triangular meshes or three-dimensional "
508 "tetrahedral meshes.");
513 for (nv = 0; nv < nVel; ++nv)
519 for (i = 0; i < nVel; ++i)
526 for (i = 0; i <
m_fields[0]->GetExpSize(); ++i)
533 exp->GetMetricInfo()->GetDeriv(pkey);
534 int offset =
m_fields[0]->GetPhys_Offset(i);
543 for (j = 0; j < deriv[0][0].num_elements(); ++j)
545 for (k = 0; k < nVel; ++k)
547 for (l = 0; l < nVel; ++l)
549 jac(l,k) = deriv[k][l][j];
553 jacIdeal = jac * i2rm;
558 char jobvl =
'N', jobvr =
'V';
559 int worklen = 8*nVel, info;
568 Lapack::Dgeev(jobvl, jobvr, nVel, metric.GetRawPtr(), nVel,
569 &(eval.GetPtr())[0], &wi[0], &vl[0], nVel,
570 &(evec.GetPtr())[0], nVel,
571 &work[0], worklen, info);
577 for (nv = 0; nv < nVel; ++nv)
579 eval(nv,nv) =
m_beta * (sqrt(eval(nv,nv)) - 1.0);
582 DNekMat beta = evec * eval * evecinv;
584 for (k = 0; k < nVel; ++k)
586 for (l = 0; l < nVel; ++l)
588 m_stress[k][l][offset+j] = beta(k,l);
593 if (deriv[0][0].num_elements() != exp->GetTotPoints())
596 for (k = 0; k < nVel; ++k)
598 for (l = 0; l < nVel; ++l)
601 exp->GetTotPoints(), m_stress[k][l][offset],
602 tmp = m_stress[k][l] + offset, 1);
610 for (i = 0; i < nVel; ++i)
612 for (j = 0; j < nVel; ++j)
614 m_fields[i]->PhysDeriv(j, m_stress[i][j], tmpderiv);
623 else if (tempEval !=
"None")
625 ASSERTL0(
false,
"Unknown temperature form: " + tempEval);
642 for (nv = 0; nv < nVel; ++nv)
646 m_fields[nv]->IProductWRTBase_IterPerExp(forcing[nv], tmp);
650 for (i = 0; i <
m_fields[nv]->GetExpSize(); ++i)
652 int nBnd =
m_bmap[i].num_elements();
653 int nInt =
m_imap[i].num_elements();
654 int offset =
m_fields[nv]->GetCoeff_Offset(i);
656 for (j = 0; j < nBnd; ++j)
658 forCoeffs[nVel*offset + nv*nBnd + j] =
661 for (j = 0; j < nInt; ++j)
663 forCoeffs[nVel*(offset + nBnd) + nv*nInt + j] =
675 map<int, vector<MultiRegions::ExtraDirDof> > &extraDirDofs =
677 map<int, vector<MultiRegions::ExtraDirDof> >
::iterator it;
679 for (nv = 0; nv < nVel; ++nv)
682 =
m_fields[nv]->GetBndCondExpansions();
685 for (it = extraDirDofs.begin(); it != extraDirDofs.end(); ++it)
687 for (i = 0; i < it->second.size(); ++i)
689 inout[it->second.at(i).get<1>()*nVel + nv] =
690 bndCondExp[it->first]->GetCoeffs()[
691 it->second.at(i).get<0>()]*it->second.at(i).get<2>();
702 for (nv = 0; nv < nVel; ++nv)
705 =
m_fields[nv]->GetBndCondExpansions();
709 for (i = 0; i < bndCondExp.num_elements(); ++i)
711 if (
m_fields[nv]->GetBndConditions()[i]->GetBoundaryConditionType()
715 bndCondExp[i]->GetCoeffs();
717 for (j = 0; j < bndCondExp[i]->GetNcoeffs(); ++j)
722 inout[bndMap[bndcnt++]] = sign * bndCoeffs[j];
727 bndcnt += bndCondExp[i]->GetNcoeffs();
754 for (nv = 0; nv < nVel; ++nv)
756 for (i = 0; i <
m_fields[nv]->GetExpSize(); ++i)
758 int nBnd =
m_bmap[i].num_elements();
759 int nInt =
m_imap[i].num_elements();
760 int offset =
m_fields[nv]->GetCoeff_Offset(i);
762 for (j = 0; j < nBnd; ++j)
765 tmp[nVel*offset + nv*nBnd + j];
767 for (j = 0; j < nInt; ++j)
770 tmp[nVel*(offset + nBnd) + nv*nInt + j];
796 const int nVel = mat.GetRows();
797 const int nB = exp->NumBndryCoeffs();
798 const int nI = exp->GetNcoeffs() - nB;
799 const int nBnd = exp->NumBndryCoeffs() * nVel;
800 const int nInt = exp->GetNcoeffs() * nVel - nBnd;
813 for (i = 0; i < nVel; ++i)
815 for (j = 0; j < nVel; ++j)
818 for (k = 0; k < nB; ++k)
820 for (l = 0; l < nB; ++l)
822 (*A)(k + i*nB, l + j*nB) =
826 for (l = 0; l < nI; ++l)
828 (*B)(k + i*nB, l + j*nI) =
834 for (k = 0; k < nI; ++k)
836 for (l = 0; l < nB; ++l)
838 (*C)(k + i*nI, l + j*nB) =
842 for (l = 0; l < nI; ++l)
844 (*D)(k + i*nI, l + j*nI) =
854 (*A) = (*A) - (*B)*(*C);
884 const int nCoeffs = exp->GetNcoeffs();
885 const int nPhys = exp->GetTotPoints();
889 nCoeffs, nCoeffs, 0.0,
eFULL);
894 for (i = 0; i < nCoeffs; ++i)
899 exp->BwdTrans ( tmp1, tmp2);
900 exp->PhysDeriv (k1, tmp2, tmp3);
901 exp->IProductWRTDerivBase(k2, tmp3, tmp1);
904 nCoeffs, scale, &tmp1[0], 1, &(ret->GetPtr())[0]+i*nCoeffs, 1);
912 std::vector<std::string> &variables)
914 const int nVel =
m_fields[0]->GetCoordim(0);
915 const int nCoeffs =
m_fields[0]->GetNcoeffs();
922 for (
int i = 0; i < nVel; ++i)
926 fieldcoeffs.push_back(tFwd);
928 "ThermStressDiv" + boost::lexical_cast<std::string>(i));
936 for (
int i = 0; i < nVel; ++i)
938 for (
int j = 0; j < nVel; ++j)
942 fieldcoeffs.push_back(tFwd);
945 + boost::lexical_cast<std::string>(i)
946 + 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.
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.
boost::shared_ptr< Expansion > ExpansionSharedPtr
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.
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.