35 #include <boost/core/ignore_unused.hpp>
37 #include <MatrixFreeOps/Operator.hpp>
47 namespace Collections {
76 boost::ignore_unused(entry2,entry3,wsp);
78 unsigned int nmodes = m_expList[0]->GetNcoeffs();
81 for(
int n = 0; n < m_numElmt; ++n)
84 (m_expList)[n]->DetShapeType(),
85 *(m_expList)[n], m_factors);
86 m_expList[n]->GeneralMatrixOp(entry0 + n *nmodes,
87 tmp = entry1 + n * nmodes,
97 boost::ignore_unused(dir, input, output, wsp);
98 NEKERROR(ErrorUtil::efatal,
"Not valid for this operator.");
102 int coll_phys_offset)
104 boost::ignore_unused(coll_phys_offset);
117 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
120 :
Operator(pCollExp, pGeomData, factors)
122 m_expList = pCollExp;
123 m_dim = pCollExp[0]->GetNumBases();
124 m_coordim = pCollExp[0]->GetCoordim();
131 OperatorKey Helmholtz_NoCollection::m_typeArr[] = {
134 Helmholtz_NoCollection::create,
135 "Helmholtz_NoCollection_Seg"),
138 Helmholtz_NoCollection::create,
139 "Helmholtz_NoCollection_Tri"),
142 Helmholtz_NoCollection::create,
143 "Helmholtz_NoCollection_NodalTri"),
146 Helmholtz_NoCollection::create,
147 "Helmholtz_NoCollection_Quad"),
150 Helmholtz_NoCollection::create,
151 "Helmholtz_NoCollection_Tet"),
154 Helmholtz_NoCollection::create,
155 "Helmholtz_NoCollection_NodalTet"),
158 Helmholtz_NoCollection::create,
159 "Helmholtz_NoCollection_Pyr"),
162 Helmholtz_NoCollection::create,
163 "Helmholtz_NoCollection_Prism"),
166 Helmholtz_NoCollection::create,
167 "Helmholtz_NoCollection_NodalPrism"),
170 Helmholtz_NoCollection::create,
171 "Helmholtz_NoCollection_Hex")
194 boost::ignore_unused(output1,output2);
196 const int nCoeffs = m_stdExp->GetNcoeffs();
197 const int nPhys = m_stdExp->GetTotPoints();
199 ASSERTL1(input.size() >= m_numElmt*nCoeffs,
200 "input array size is insufficient");
201 ASSERTL1(output.size() >= m_numElmt*nCoeffs,
202 "output array size is insufficient");
209 for(
int i = 1; i < m_coordim+1; ++i)
211 dtmp[i-1] = wsp + i*nPhys;
212 tmp [i-1] = wsp + (i+m_coordim)*nPhys;
215 for (
int i = 0; i < m_numElmt; ++i)
217 m_stdExp->BwdTrans(input + i*nCoeffs, tmpphys);
220 m_stdExp->PhysDeriv(tmpphys, dtmp[0], dtmp[1], dtmp[2]);
225 Vmath::Vmul(nPhys,m_jac+i*nPhys,1,tmpphys,1,tmpphys,1);
232 m_stdExp->IProductWRTBase(tmpphys,t1 = output + i*nCoeffs);
234 t1 = output+i*nCoeffs,1);
239 for(
int j = 0; j < m_coordim; ++j)
242 m_derivFac[j*m_dim].origin() + i*nPhys, 1,
243 &dtmp[0][0], 1, &tmp[j][0], 1);
245 for(
int k = 1; k < m_dim; ++k)
248 + i*nPhys, 1, &dtmp[k][0], 1,
249 &tmp[j][0], 1, &tmp[j][0], 1);
253 if(m_HasVarCoeffDiff)
262 for(
int l = 1; l < m_coordim; ++l)
265 &tmpphys[0], 1, &tmpphys[0], 1);
268 for(
int j = 0; j < m_dim; ++j)
271 m_derivFac[j].origin() + i*nPhys, 1,
272 &tmpphys[0], 1, &dtmp[j][0], 1);
276 for(
int k = 1; k < m_coordim; ++k)
280 for(
int l = 1; l < m_coordim; ++l)
283 &tmpphys[0], 1, &tmpphys[0], 1);
286 for(
int j = 0; j < m_dim; ++j)
289 m_derivFac[j +k*m_dim].origin()
292 &dtmp[j][0], 1, &dtmp[j][0], 1);
300 for(
int j = 0; j < m_dim; ++j)
303 m_derivFac[j].origin() + i*nPhys, 1,
304 &tmp[0][0], 1, &dtmp[j][0], 1);
306 for(
int k = 1; k < m_coordim; ++k)
309 m_derivFac[j +k*m_dim].origin()
310 + i*nPhys, 1, &tmp[k][0], 1,
311 &dtmp[j][0], 1, &dtmp[j][0], 1);
317 for(
int j = 0; j < m_dim; ++j)
321 Vmath::Vmul(nPhys,m_jac+i*nPhys,1,dtmp[j],1,dtmp[j],1);
323 m_stdExp->IProductWRTDerivBase(j,dtmp[j],tmp[0]);
325 t1 = output+i*nCoeffs,1);
331 for(
int j = 0; j < m_coordim; ++j)
334 &dtmp[0][0], 1, &tmp[j][0], 1);
336 for(
int k = 1; k < m_dim; ++k)
346 if(m_HasVarCoeffDiff)
355 for(
int l = 1; l < m_coordim; ++l)
358 &tmpphys[0], 1, &tmpphys[0], 1);
361 for(
int j = 0; j < m_dim; ++j)
364 &tmpphys[0], 1, &dtmp[j][0], 1);
368 for(
int k = 1; k < m_coordim; ++k)
372 for(
int l = 1; l < m_coordim; ++l)
375 &tmpphys[0], 1, &tmpphys[0], 1);
378 for(
int j = 0; j < m_dim; ++j)
381 &tmpphys[0], 1, &dtmp[j][0], 1,
390 for(
int j = 0; j < m_dim; ++j)
393 &tmp[0][0], 1, &dtmp[j][0],1);
395 for(
int k = 1; k < m_coordim; ++k)
398 &tmp[k][0], 1, &dtmp[j][0], 1,
405 for(
int j = 0; j < m_dim; ++j)
410 m_stdExp->IProductWRTDerivBase(j,dtmp[j],tmp[0]);
412 t1 = output+i*nCoeffs,1);
423 boost::ignore_unused(dir, input, output, wsp);
424 NEKERROR(ErrorUtil::efatal,
"Not valid for this operator.");
435 int coll_phys_offset)
437 boost::ignore_unused(coll_phys_offset);
440 if (m_factors == factors)
450 "Constant factor not defined: "
453 m_lambda = x->second;
456 m_HasVarCoeffDiff =
false;
458 if (d == factors.end())
464 for(
int i = 0; i < m_coordim; ++i)
469 for(
int i = 0; i < m_coordim; ++i)
471 d = factors.find(m_factorCoeffDef[i][i]);
472 if (d != factors.end())
474 m_diff[i][i] = d->second;
481 for(
int j = i+1; j < m_coordim; ++j)
483 d = factors.find(m_factorCoeffDef[i][j]);
484 if (d != factors.end())
486 m_diff[i][j] = m_diff[j][i] = d->second;
490 m_HasVarCoeffDiff =
true;
513 vector<StdRegions::StdExpansionSharedPtr> pCollExp,
516 :
Operator(pCollExp, pGeomData, factors)
519 m_dim = PtsKey.size();
520 m_coordim = pCollExp[0]->GetCoordim();
521 int nqtot = m_stdExp->GetTotPoints();
523 m_derivFac = pGeomData->GetDerivFactors(pCollExp);
524 m_jac = pGeomData->GetJac(pCollExp);
525 m_wspSize = (2*m_coordim+1)*nqtot;
528 m_HasVarCoeffDiff =
false;
530 this->CheckFactors(factors, 0);
538 Helmholtz_IterPerExp::create,
539 "Helmholtz_IterPerExp_Seg"),
542 Helmholtz_IterPerExp::create,
543 "Helmholtz_IterPerExp_Tri"),
546 Helmholtz_IterPerExp::create,
547 "Helmholtz_IterPerExp_NodalTri"),
550 Helmholtz_IterPerExp::create,
551 "Helmholtz_IterPerExp_Quad"),
554 Helmholtz_IterPerExp::create,
555 "Helmholtz_IterPerExp_Tet"),
558 Helmholtz_IterPerExp::create,
559 "Helmholtz_IterPerExp_NodalTet"),
562 Helmholtz_IterPerExp::create,
563 "Helmholtz_IterPerExp_Pyr"),
566 Helmholtz_IterPerExp::create,
567 "Helmholtz_IterPerExp_Prism"),
570 Helmholtz_IterPerExp::create,
571 "Helmholtz_IterPerExp_NodalPrism"),
574 Helmholtz_IterPerExp::create,
575 "Helmholtz_IterPerExp_Hex")
598 boost::ignore_unused(output1,output2,wsp);
604 (*m_oper)(m_input, m_output);
609 (*m_oper)(input, output0);
618 boost::ignore_unused(dir,input,output,wsp);
619 NEKERROR(ErrorUtil::efatal,
"Not valid for this operator.");
627 int coll_phys_offset)
629 boost::ignore_unused(coll_phys_offset);
631 if (factors == m_factors)
641 "Constant factor not defined: "
644 m_oper->SetLambda(x->second);
647 bool isConstVarDiff =
false;
649 diff[0] = diff[2] = diff[5] = 1.0;
652 if (xd00 != factors.end() && xd00->second != 1.0) {
653 isConstVarDiff =
true;
654 diff[0] = xd00->second;
658 if (xd01 != factors.end() && xd01->second != 0.0) {
659 isConstVarDiff =
true;
660 diff[1] = xd01->second;
664 if (xd11 != factors.end() && xd11->second != 1.0) {
665 isConstVarDiff =
true;
666 diff[2] = xd11->second;
670 if (xd02 != factors.end() && xd02->second != 0.0) {
671 isConstVarDiff =
true;
672 diff[3] = xd02->second;
676 if (xd12 != factors.end() && xd12->second != 0.0) {
677 isConstVarDiff =
true;
678 diff[4] = xd12->second;
682 if (xd22 != factors.end() && xd22->second != 1.0) {
683 isConstVarDiff =
true;
684 diff[5] = xd22->second;
687 if (isConstVarDiff) {
688 m_oper->SetConstVarDiffusion(diff);
693 if (k != factors.end() && k->second != 0.0) {
694 m_oper->SetVarDiffusion(diff);
699 std::shared_ptr<MatrixFree::Helmholtz>
m_oper;
706 :
Operator(pCollExp, pGeomData, factors),
708 pCollExp[0]->GetStdExp()->GetNcoeffs(),
712 m_nmtot = m_numElmt*pCollExp[0]->GetStdExp()->GetNcoeffs();
714 const auto dim = pCollExp[0]->GetStdExp()->GetShapeDimension();
717 std::vector<LibUtilities::BasisSharedPtr> basis(dim);
718 for (
auto i = 0; i < dim; ++i)
720 basis[i] = pCollExp[0]->GetBasis(i);
724 auto shapeType = pCollExp[0]->GetStdExp()->DetShapeType();
727 std::string op_string =
"Helmholtz";
728 op_string += MatrixFree::GetOpstring(shapeType, m_isDeformed);
730 CreateInstance(op_string, basis, m_nElmtPad);
733 oper->SetJac(pGeomData->GetJacInterLeave(pCollExp,m_nElmtPad));
736 oper->SetDF(pGeomData->GetDerivFactorsInterLeave
737 (pCollExp,m_nElmtPad));
739 m_oper = std::dynamic_pointer_cast<MatrixFree::Helmholtz>(oper);
740 ASSERTL0(m_oper,
"Failed to cast pointer.");
744 this->CheckFactors(factors, 0);
753 Helmholtz_MatrixFree::create,
"Helmholtz_MatrixFree_Quad"),
756 Helmholtz_MatrixFree::create,
"Helmholtz_MatrixFree_Tri"),
759 Helmholtz_MatrixFree::create,
"Helmholtz_MatrixFree_Hex"),
762 Helmholtz_MatrixFree::create,
"Helmholtz_MatrixFree_Prism"),
765 Helmholtz_MatrixFree::create,
"Helmholtz_MatrixFree_Pyr"),
768 Helmholtz_MatrixFree::create,
"Helmholtz_MatrixFree_Tet"),
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define OPERATOR_CREATE(cname)
Helmholtz operator using LocalRegions implementation.
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
virtual void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset)
Check the validity of supplied constant factors.
StdRegions::FactorMap m_factors
Array< TwoD, const NekDouble > m_derivFac
Helmholtz_IterPerExp(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
void operator()(const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &output1, Array< OneD, NekDouble > &output2, Array< OneD, NekDouble > &wsp) final
Perform operation.
Array< OneD, Array< OneD, NekDouble > > m_diff
Array< OneD, const NekDouble > m_jac
~Helmholtz_IterPerExp() final
Helmholtz operator using matrix free operators.
virtual void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset)
Check the validity of the supplied factor map.
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
std::shared_ptr< MatrixFree::Helmholtz > m_oper
StdRegions::FactorMap m_factors
~Helmholtz_MatrixFree() final
void operator()(const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output0, Array< OneD, NekDouble > &output1, Array< OneD, NekDouble > &output2, Array< OneD, NekDouble > &wsp) final
Perform operation.
Helmholtz_MatrixFree(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
Helmholtz operator using LocalRegions implementation.
virtual void CheckFactors(StdRegions::FactorMap factors, int coll_phys_offset)
Check the validity of the supplied factor map.
Helmholtz_NoCollection(vector< StdRegions::StdExpansionSharedPtr > pCollExp, CoalescedGeomDataSharedPtr pGeomData, StdRegions::FactorMap factors)
void operator()(const Array< OneD, const NekDouble > &entry0, Array< OneD, NekDouble > &entry1, Array< OneD, NekDouble > &entry2, Array< OneD, NekDouble > &entry3, Array< OneD, NekDouble > &wsp) final
Perform operation.
void operator()(int dir, const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output, Array< OneD, NekDouble > &wsp) final
StdRegions::FactorMap m_factors
~Helmholtz_NoCollection() final
vector< StdRegions::StdExpansionSharedPtr > m_expList
Base class for operators on a collection of elements.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
std::tuple< LibUtilities::ShapeType, OperatorType, ImplementationType, ExpansionIsNodal > OperatorKey
Key for describing an Operator.
std::shared_ptr< CoalescedGeomData > CoalescedGeomDataSharedPtr
OperatorFactory & GetOperatorFactory()
Returns the singleton Operator factory object.
std::vector< PointsKey > PointsKeyVector
static FactorMap NullFactorMap
const char *const ConstFactorTypeMap[]
The above copyright notice and this permission notice shall be included.
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
void Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
svtvp (scalar times vector plus vector): z = alpha*x + y
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
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.
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)