36 #ifndef UTILITIES_NEKMESH_NODEOPTI_EVALUATOR
37 #define UTILITIES_NEKMESH_NODEOPTI_EVALUATOR
62 return jac[0][0] * jac[1][1] - jac[0][1] * jac[1][0];
67 return jac[0][0] * (jac[1][1] * jac[2][2] - jac[2][1] * jac[1][2]) -
68 jac[0][1] * (jac[1][0] * jac[2][2] - jac[1][2] * jac[2][0]) +
69 jac[0][2] * (jac[1][0] * jac[2][1] - jac[1][1] * jac[2][0]);
89 out[0][0] = in[1][1] * invDet;
90 out[1][0] = -in[0][1] * invDet;
91 out[0][1] = -in[1][0] * invDet;
92 out[1][1] = in[0][0] * invDet;
99 out[0][0] = (in[1][1] * in[2][2] - in[2][1] * in[1][2]) * invdet;
100 out[1][0] = -(in[0][1] * in[2][2] - in[0][2] * in[2][1]) * invdet;
101 out[2][0] = (in[0][1] * in[1][2] - in[0][2] * in[1][1]) * invdet;
102 out[0][1] = -(in[1][0] * in[2][2] - in[1][2] * in[2][0]) * invdet;
103 out[1][1] = (in[0][0] * in[2][2] - in[0][2] * in[2][0]) * invdet;
104 out[2][1] = -(in[0][0] * in[1][2] - in[1][0] * in[0][2]) * invdet;
105 out[0][2] = (in[1][0] * in[2][1] - in[2][0] * in[1][1]) * invdet;
106 out[1][2] = -(in[0][0] * in[2][1] - in[2][0] * in[0][1]) * invdet;
107 out[2][2] = (in[0][0] * in[1][1] - in[1][0] * in[0][1]) * invdet;
140 return in1[0] * in2[0]
146 return in1[0] * in2[0]
168 out[0][0] = 0.5 * (in[0][0] * in[0][0] + in[1][0] * in[1][0] - 1.0);
169 out[1][0] = 0.5 * (in[0][0] * in[0][1] + in[1][0] * in[1][1]);
170 out[0][1] = 0.5 * (in[0][0] * in[0][1] + in[1][0] * in[1][1]);
171 out[1][1] = 0.5 * (in[1][1] * in[1][1] + in[0][1] * in[0][1] - 1.0);
176 out[0][0] = 0.5 * (in[0][0] * in[0][0] + in[1][0] * in[1][0] +
177 in[2][0] * in[2][0] - 1.0);
178 out[1][0] = 0.5 * (in[0][0] * in[1][0] + in[1][0] * in[1][1] +
179 in[2][0] * in[2][1]);
180 out[0][1] = out[1][0];
181 out[2][0] = 0.5 * (in[0][0] * in[0][2] + in[1][0] * in[1][2] +
182 in[2][0] * in[2][2]);
183 out[0][2] = out[2][0];
184 out[1][1] = 0.5 * (in[0][1] * in[0][1] + in[1][1] * in[1][1] +
185 in[2][1] * in[2][1] - 1.0);
186 out[1][2] = 0.5 * (in[0][1] * in[0][2] + in[1][1] * in[1][2] +
187 in[2][1] * in[2][2]);
188 out[2][1] = out[1][2];
189 out[2][2] = 0.5 * (in[0][2] * in[0][2] + in[1][2] * in[1][2] +
190 in[2][2] * in[2][2] - 1.0);
208 return in1[0][0] * in2[0][0]
209 + in1[0][1] * in2[0][1]
210 + in1[1][0] * in2[1][0]
211 + in1[1][1] * in2[1][1] ;
217 return in1[0][0] * in2[0][0]
218 + in1[0][1] * in2[0][1]
219 + in1[0][2] * in2[0][2]
220 + in1[1][0] * in2[1][0]
221 + in1[1][1] * in2[1][1]
222 + in1[1][2] * in2[1][2]
223 + in1[2][0] * in2[2][0]
224 + in1[2][1] * in2[2][1]
225 + in1[2][2] * in2[2][2] ;
242 return inarray[0][0] * inarray[0][0]
243 + inarray[0][1] * inarray[0][1]
244 + inarray[1][0] * inarray[1][0]
245 + inarray[1][1] * inarray[1][1] ;
251 return inarray[0][0] * inarray[0][0]
252 + inarray[0][1] * inarray[0][1]
253 + inarray[0][2] * inarray[0][2]
254 + inarray[1][0] * inarray[1][0]
255 + inarray[1][1] * inarray[1][1]
256 + inarray[1][2] * inarray[1][2]
257 + inarray[2][0] * inarray[2][0]
258 + inarray[2][1] * inarray[2][1]
259 + inarray[2][2] * inarray[2][2] ;
271 map<LibUtilities::ShapeType, vector<ElUtilSharedPtr> >
::iterator typeIt;
273 for (typeIt = m_data.begin(); typeIt != m_data.end(); typeIt++)
275 const int ptsStd = m_derivUtils[typeIt->first]->ptsStd;
276 const int pts = m_derivUtils[typeIt->first]->pts;
277 const int nElmt = typeIt->second.size();
282 for (
int i = 0, cnt = 0; i < nElmt; ++i)
284 for (
int j = 0; j < ptsStd; ++j)
286 for (
int d = 0; d < DIM; ++d)
288 X[cnt + d * ptsStd + j] =
289 *(typeIt->second[i]->nodes[j][d]);
302 for (
int d = 0; d < DIM; ++d)
304 Blas::Dgemm(
'N',
'N', pts, DIM * nElmt, ptsStd, 1.0,
305 m_derivUtils[typeIt->first]->VdmD[d].GetRawPtr(),
307 &m_derivs[typeIt->first][d][0][0][0], pts);
311 minJacNew = std::numeric_limits<double>::max();
314 m_minJac < 0.0 ? sqrt(1e-8 + 0.04 * m_minJac * m_minJac) : 1e-4;
323 const NekDouble mu = 1.0 / 2.0 / (1.0 + nu);
324 const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu);
326 for (typeIt = m_data.begin(); typeIt != m_data.end(); typeIt++)
328 const int nElmt = typeIt->second.size();
329 const int pts = m_derivUtils[typeIt->first]->pts;
332 m_derivUtils[typeIt->first]->quadW;
334 for (
int i = 0; i < nElmt; ++i)
336 for (
int k = 0; k < pts; ++k)
339 for (
int l = 0; l < DIM; ++l)
341 for (
int n = 0; n < DIM; ++n)
344 m_derivs[typeIt->first][l][i][n][k];
349 for (
int m = 0; m < DIM; ++m)
351 for (
int n = 0; n < DIM; ++n)
353 jacIdeal[n][m] = 0.0;
354 for (
int l = 0; l < DIM; ++l)
356 jacIdeal[n][m] += phiM[n][l] *
357 typeIt->second[i]->maps[k][m * 3 + l];
364 NekDouble absIdealMapDet = fabs(typeIt->second[i]->maps[k][9]);
365 minJacNew = min(minJacNew, jacDet);
368 EMatrix<DIM>(jacIdeal, Emat);
370 NekDouble trEtE = FrobProd<DIM>(Emat, Emat);
373 (jacDet + sqrt(jacDet * jacDet + 4.0 * ep * ep));
375 if (sigma < numeric_limits<double>::min() && !gradient)
377 return numeric_limits<double>::max();
379 ASSERTL0(sigma > numeric_limits<double>::min(),
380 std::string(
"dividing by zero ") +
381 boost::lexical_cast<string>(sigma) +
" " +
382 boost::lexical_cast<string>(jacDet) +
" " +
383 boost::lexical_cast<string>(ep));
386 integral += quadW[k] *
388 (K * 0.5 * lsigma * lsigma + mu * trEtE);
395 NekDouble derivDet = Determinant<DIM>(phiM);
397 InvTrans<DIM>(phiM, jacInvTrans);
400 for (
int m = 0; m < DIM; ++m)
403 m_derivUtils[typeIt->first]->VdmD[m])(
404 k, typeIt->second[i]->NodeId(m_node->m_id));
411 for (
int l = 0; l < DIM; ++l)
413 jacDeriv[l] = basisDeriv[l];
418 for (
int n = 0; n < DIM; ++n)
420 jacDerivPhi[n] = 0.0;
421 for (
int l = 0; l < DIM; ++l)
423 jacDerivPhi[n] += jacDeriv[l] *
424 typeIt->second[i]->maps[k][l + 3 * n];
428 for (
int m = 0; m < DIM; ++m)
430 jacDetDeriv[m] = 0.0;
431 for (
int n = 0; n < DIM; ++n)
433 jacDetDeriv[m] += jacInvTrans[m][n] * basisDeriv[n];
435 jacDetDeriv[m] *= derivDet / absIdealMapDet;
444 for(
int d = 0; d < DIM; d++)
446 for (
int m = 0; m < DIM; ++m)
448 for (
int n = 0; n < DIM; ++n)
450 M2[d][m][n] = 0.5*(jacDerivPhi[m] * jacIdeal[d][n]
451 + jacIdeal[d][m] * jacDerivPhi[n]);
456 for (
int m = 0; m < DIM; ++m)
458 NekDouble frobProdA = FrobProd<DIM>(M2[m], Emat);
461 quadW[k] * absIdealMapDet *
462 (2.0 * mu * frobProdA +
463 K * lsigma * jacDetDeriv[m] /
464 (2.0 * sigma - jacDet));
468 for (
int m = 0; m < DIM; ++m)
470 for (
int l = m; l < DIM; ++l, ct++)
472 NekDouble frobProdBC = FrobProd<DIM>(M2[m], M2[l]);
479 for (
int p = 0;
p < DIM; ++
p)
481 for (
int q = 0; q < DIM; ++q)
483 M3[
p][q] = jacDerivPhi[
p] * jacDerivPhi[q];
486 frobProdBC += FrobProd<DIM>(M3,Emat);
490 quadW[k] * absIdealMapDet *
491 (2.0 * mu * frobProdBC +
492 jacDetDeriv[m] * jacDetDeriv[l] * K /
493 (2.0 * sigma - jacDet) /
494 (2.0 * sigma - jacDet) *
495 (1.0 - jacDet * lsigma /
496 (2.0 * sigma - jacDet)));
509 const NekDouble mu = 1.0 / 2.0 / (1.0 + nu);
510 const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu);
512 for (typeIt = m_data.begin(); typeIt != m_data.end(); typeIt++)
514 const int nElmt = typeIt->second.size();
515 const int pts = m_derivUtils[typeIt->first]->pts;
518 m_derivUtils[typeIt->first]->quadW;
520 for (
int i = 0; i < nElmt; ++i)
522 for (
int k = 0; k < pts; ++k)
525 for (
int l = 0; l < DIM; ++l)
527 for (
int n = 0; n < DIM; ++n)
530 m_derivs[typeIt->first][l][i][n][k];
534 for (
int m = 0; m < DIM; ++m)
536 for (
int n = 0; n < DIM; ++n)
538 jacIdeal[n][m] = 0.0;
539 for (
int l = 0; l < DIM; ++l)
541 jacIdeal[n][m] += phiM[n][l] *
542 typeIt->second[i]->maps[k][m * 3 + l];
549 minJacNew = min(minJacNew, jacDet);
551 NekDouble absIdealMapDet = fabs(typeIt->second[i]->maps[k][9]);
557 (jacDet + sqrt(jacDet * jacDet + 4.0 * ep * ep));
559 if (sigma < numeric_limits<double>::min() && !gradient)
561 return numeric_limits<double>::max();
564 ASSERTL0(sigma > numeric_limits<double>::min(),
565 std::string(
"dividing by zero ") +
566 boost::lexical_cast<string>(sigma) +
" " +
567 boost::lexical_cast<string>(jacDet) +
" " +
568 boost::lexical_cast<string>(ep));
571 integral += quadW[k] * absIdealMapDet *
572 (0.5 * mu * (I1 - 3.0 - 2.0 * lsigma) +
573 0.5 * K * lsigma * lsigma);
581 NekDouble derivDet = Determinant<DIM>(phiM);
583 InvTrans<DIM>(phiM, jacInvTrans);
586 for (
int m = 0; m < DIM; ++m)
589 *(m_derivUtils[typeIt->first]->VdmD[m].GetRawPtr() +
590 typeIt->second[i]->NodeId(m_node->m_id) * pts + k);
598 for (
int l = 0; l < DIM; ++l)
600 jacDeriv[l] = basisDeriv[l];
605 for (
int n = 0; n < DIM; ++n)
607 jacDerivPhi[n] = 0.0;
608 for (
int l = 0; l < DIM; ++l)
610 jacDerivPhi[n] += jacDeriv[l] *
611 typeIt->second[i]->maps[k][l + 3 * n];
615 for (
int m = 0; m < DIM; ++m)
617 jacDetDeriv[m] = 0.0;
618 for (
int n = 0; n < DIM; ++n)
620 jacDetDeriv[m] += jacInvTrans[m][n] * basisDeriv[n];
622 jacDetDeriv[m] *= derivDet / absIdealMapDet;
626 for (
int m = 0; m < DIM; ++m)
631 ScalarProd<DIM>(jacIdeal[m],jacDerivPhi);
634 quadW[k] * absIdealMapDet *
636 (jacDetDeriv[m] / (2.0 * sigma - jacDet) *
641 for (
int m = 0; m < DIM; ++m)
643 for (
int l = m; l < DIM; ++l, ct++)
652 frobProdHes = ScalarProd<DIM>(jacDerivPhi,jacDerivPhi);
656 quadW[k] * absIdealMapDet *
658 jacDetDeriv[m] * jacDetDeriv[l] /
659 (2.0 * sigma - jacDet) /
660 (2.0 * sigma - jacDet) *
661 (K - jacDet * (K * lsigma - mu) /
662 (2.0 * sigma - jacDet)));
674 for (typeIt = m_data.begin(); typeIt != m_data.end(); typeIt++)
676 const int nElmt = typeIt->second.size();
677 const int pts = m_derivUtils[typeIt->first]->pts;
680 m_derivUtils[typeIt->first]->quadW;
682 for (
int i = 0; i < nElmt; ++i)
684 for (
int k = 0; k < pts; ++k)
687 for (
int l = 0; l < DIM; ++l)
689 for (
int n = 0; n < DIM; ++n)
692 m_derivs[typeIt->first][l][i][n][k];
696 for (
int m = 0; m < DIM; ++m)
698 for (
int n = 0; n < DIM; ++n)
700 jacIdeal[n][m] = 0.0;
701 for (
int l = 0; l < DIM; ++l)
703 jacIdeal[n][m] += phiM[n][l] *
704 typeIt->second[i]->maps[k][m * 3 + l];
711 NekDouble absIdealMapDet = fabs(typeIt->second[i]->maps[k][9]);
712 minJacNew = min(minJacNew, jacDet);
716 (jacDet + sqrt(jacDet * jacDet + 4.0 * ep * ep));
718 if (sigma < numeric_limits<double>::min() && !gradient)
720 return numeric_limits<double>::max();
723 ASSERTL0(sigma > numeric_limits<double>::min(),
724 std::string(
"dividing by zero ") +
725 boost::lexical_cast<string>(sigma) +
" " +
726 boost::lexical_cast<string>(jacDet) +
" " +
727 boost::lexical_cast<string>(ep));
729 NekDouble W = frob / DIM / pow(fabs(sigma), 2.0 / DIM);
731 quadW[k] * absIdealMapDet * W;
739 NekDouble derivDet = Determinant<DIM>(phiM);
741 InvTrans<DIM>(phiM, jacInvTrans);
744 for (
int m = 0; m < DIM; ++m)
747 m_derivUtils[typeIt->first]->VdmD[m])(
748 k, typeIt->second[i]->NodeId(m_node->m_id));
755 for (
int l = 0; l < DIM; ++l)
757 jacDeriv[l] = basisDeriv[l];
762 for (
int n = 0; n < DIM; ++n)
764 jacDerivPhi[n] = 0.0;
765 for (
int l = 0; l < DIM; ++l)
767 jacDerivPhi[n] += jacDeriv[l] *
768 typeIt->second[i]->maps[k][l + 3 * n];
772 for (
int m = 0; m < DIM; ++m)
774 jacDetDeriv[m] = 0.0;
775 for (
int n = 0; n < DIM; ++n)
777 jacDetDeriv[m] += jacInvTrans[m][n] * basisDeriv[n];
779 jacDetDeriv[m] *= derivDet / absIdealMapDet;
785 for (
int m = 0; m < DIM; ++m)
789 frobProd[m] = ScalarProd<DIM>(jacIdeal[m],jacDerivPhi);
792 quadW[k] * absIdealMapDet *
793 (2.0 * W * (frobProd[m] / frob -
794 jacDetDeriv[m] / DIM /
795 (2.0 * sigma - jacDet)));
802 for (
int m = 0; m < DIM; ++m)
804 for (
int l = m; l < DIM; ++l, ct++)
813 frobProdHes = ScalarProd<DIM>(jacDerivPhi,jacDerivPhi);
817 quadW[k] * absIdealMapDet *
818 (inc[m] * inc[l] / W +
820 (frobProdHes / frob -
821 2.0 * frobProd[m] * frobProd[l] /
823 jacDetDeriv[m] * jacDetDeriv[l] *
825 (2.0 * sigma - jacDet) /
826 (2.0 * sigma - jacDet) /
827 (2.0 * sigma - jacDet) /
840 for (typeIt = m_data.begin(); typeIt != m_data.end(); typeIt++)
842 const int nElmt = typeIt->second.size();
843 const int pts = m_derivUtils[typeIt->first]->pts;
846 m_derivUtils[typeIt->first]->quadW;
848 for (
int i = 0; i < nElmt; ++i)
850 for (
int k = 0; k < pts; ++k)
853 for (
int l = 0; l < DIM; ++l)
855 for (
int n = 0; n < DIM; ++n)
858 m_derivs[typeIt->first][l][i][n][k];
862 for (
int m = 0; m < DIM; ++m)
864 for (
int n = 0; n < DIM; ++n)
866 jacIdeal[n][m] = 0.0;
867 for (
int l = 0; l < DIM; ++l)
869 jacIdeal[n][m] += phiM[n][l] *
870 typeIt->second[i]->maps[k][m * 3 + l];
877 NekDouble absIdealMapDet = fabs(typeIt->second[i]->maps[k][9]);
878 minJacNew = min(minJacNew, jacDet);
882 (jacDet + sqrt(jacDet * jacDet + 4.0 * ep * ep));
884 if (sigma < numeric_limits<double>::min() && !gradient)
886 return numeric_limits<double>::max();
889 ASSERTL0(sigma > numeric_limits<double>::min(),
890 std::string(
"dividing by zero ") +
891 boost::lexical_cast<string>(sigma) +
" " +
892 boost::lexical_cast<string>(jacDet) +
" " +
893 boost::lexical_cast<string>(ep));
897 quadW[k] * absIdealMapDet * W;
905 NekDouble derivDet = Determinant<DIM>(phiM);
907 InvTrans<DIM>(phiM, jacInvTrans);
910 for (
int m = 0; m < DIM; ++m)
913 m_derivUtils[typeIt->first]->VdmD[m])(
914 k, typeIt->second[i]->NodeId(m_node->m_id));
921 for (
int l = 0; l < DIM; ++l)
923 jacDeriv[l] = basisDeriv[l];
928 for (
int n = 0; n < DIM; ++n)
930 jacDerivPhi[n] = 0.0;
931 for (
int l = 0; l < DIM; ++l)
933 jacDerivPhi[n] += jacDeriv[l] *
934 typeIt->second[i]->maps[k][l + 3 * n];
938 for (
int m = 0; m < DIM; ++m)
940 jacDetDeriv[m] = 0.0;
941 for (
int n = 0; n < DIM; ++n)
943 jacDetDeriv[m] += jacInvTrans[m][n] * basisDeriv[n];
945 jacDetDeriv[m] *= derivDet / absIdealMapDet;
951 for (
int m = 0; m < DIM; ++m)
955 frobProd[m] = ScalarProd<DIM>(jacIdeal[m],jacDerivPhi);
961 (2.0 * frobProd[m] / frob -
962 jacDetDeriv[m] / (2.0 * sigma - jacDet)));
967 for (
int m = 0; m < DIM; ++m)
969 for (
int l = m; l < DIM; ++l, ct++)
978 frobProdHes = ScalarProd<DIM>(jacDerivPhi,jacDerivPhi);
982 quadW[k] * absIdealMapDet *
983 (inc[m] * inc[l] / W +
985 (frobProdHes / frob -
986 2.0 * frobProd[m] * frobProd[l] /
988 0.5 * jacDetDeriv[m] *
989 jacDetDeriv[l] * jacDet /
990 (2.0 * sigma - jacDet) /
991 (2.0 * sigma - jacDet) /
992 (2.0 * sigma - jacDet)));
#define ASSERTL0(condition, msg)
void InvTrans< 3 >(NekDouble in[][3], NekDouble out[][3])
void InvTrans< 2 >(NekDouble in[][2], NekDouble out[][2])
NekDouble FrobeniusNorm< 3 >(NekDouble inarray[][3])
NekDouble ScalarProd< 3 >(NekDouble(&in1)[3], NekDouble(&in2)[3])
void EMatrix< 2 >(NekDouble in[][2], NekDouble out[][2])
NekDouble FrobProd< 3 >(NekDouble in1[][3], NekDouble in2[][3])
NekDouble Determinant< 2 >(NekDouble jac[][2])
NekDouble Determinant(NekDouble jac[][DIM])
Calculate determinant of input matrix.
void InvTrans(NekDouble in[][DIM], NekDouble out[][DIM])
Calculate inverse transpose of input matrix.
NekDouble FrobProd(NekDouble in1[][DIM], NekDouble in2[][DIM])
Calculate Frobenius inner product of input matrices.
NekDouble FrobProd< 2 >(NekDouble in1[][2], NekDouble in2[][2])
NekDouble FrobeniusNorm< 2 >(NekDouble inarray[][2])
NekDouble GetFunctional(NekDouble &minJacNew, bool gradient=true)
Evaluate functional for elements connected to a node.
NekDouble ScalarProd(NekDouble(&in1)[DIM], NekDouble(&in2)[DIM])
Calculate Scalar product of input vectors.
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
NekDouble ScalarProd< 2 >(NekDouble(&in1)[2], NekDouble(&in2)[2])
void EMatrix(NekDouble in[][DIM], NekDouble out[][DIM])
Calculate tensor used in derivation of linear elasticity gradients.
NekDouble FrobeniusNorm(NekDouble inarray[][DIM])
Calculate Frobenius norm of a matrix .
NekDouble Determinant< 3 >(NekDouble jac[][3])
void EMatrix< 3 >(NekDouble in[][3], NekDouble out[][3])