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] ;
247 return inarray[0][0] * inarray[0][0]
248 + inarray[0][1] * inarray[0][1]
249 + inarray[1][0] * inarray[1][0]
250 + inarray[1][1] * inarray[1][1] ;
256 return inarray[0][0] * inarray[0][0]
257 + inarray[0][1] * inarray[0][1]
258 + inarray[0][2] * inarray[0][2]
259 + inarray[1][0] * inarray[1][0]
260 + inarray[1][1] * inarray[1][1]
261 + inarray[1][2] * inarray[1][2]
262 + inarray[2][0] * inarray[2][0]
263 + inarray[2][1] * inarray[2][1]
264 + inarray[2][2] * inarray[2][2] ;
276 map<LibUtilities::ShapeType, vector<ElUtilSharedPtr> >
::iterator typeIt;
277 map<LibUtilities::ShapeType, DerivArray> derivs;
279 for (typeIt = m_data.begin(); typeIt != m_data.end(); typeIt++)
281 int nElmt = typeIt->second.size();
282 int totpts = m_derivUtils[typeIt->first]->ptsStd * nElmt;
286 for (
int i = 0, cnt = 0; i < nElmt; ++i)
288 for (
int j = 0; j < m_derivUtils[typeIt->first]->ptsStd; ++j)
290 for (
int d = 0; d < DIM; ++d)
292 X[cnt + d * m_derivUtils[typeIt->first]->ptsStd + j] =
293 *(typeIt->second[i]->nodes[j][d]);
296 cnt += DIM * m_derivUtils[typeIt->first]->ptsStd;
304 derivs.insert(std::make_pair(
306 DerivArray(boost::extents[DIM][nElmt][DIM]
307 [m_derivUtils[typeIt->first]->pts])));
310 for (
int d = 0; d < DIM; ++d)
312 Blas::Dgemm(
'N',
'N', m_derivUtils[typeIt->first]->pts, DIM * nElmt,
313 m_derivUtils[typeIt->first]->ptsStd, 1.0,
314 m_derivUtils[typeIt->first]->VdmD[d].GetRawPtr(),
315 m_derivUtils[typeIt->first]->pts, X,
316 m_derivUtils[typeIt->first]->ptsStd, 0.0,
317 &derivs[typeIt->first][d][0][0][0],
318 m_derivUtils[typeIt->first]->pts);
322 minJacNew = std::numeric_limits<double>::max();
325 m_minJac < 0.0 ? sqrt(1e-8 + 0.04 * m_minJac * m_minJac) : 1e-4;
334 const NekDouble mu = 1.0 / 2.0 / (1.0 + nu);
335 const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu);
337 for (typeIt = m_data.begin(); typeIt != m_data.end(); typeIt++)
340 m_derivUtils[typeIt->first]->quadW;
341 for (
int i = 0; i < typeIt->second.size(); ++i)
343 for (
int k = 0; k < m_derivUtils[typeIt->first]->pts; ++k)
346 for (
int l = 0; l < DIM; ++l)
348 for (
int n = 0; n < DIM; ++n)
351 derivs[typeIt->first][l][i][n][k];
355 for (
int m = 0; m < DIM; ++m)
357 for (
int n = 0; n < DIM; ++n)
359 jacIdeal[n][m] = 0.0;
360 for (
int l = 0; l < DIM; ++l)
362 jacIdeal[n][m] += phiM[n][l] *
363 typeIt->second[i]->maps[k][m * 3 + l];
370 NekDouble absIdealMapDet = fabs(typeIt->second[i]->maps[k][9]);
371 minJacNew = min(minJacNew, jacDet);
374 EMatrix<DIM>(jacIdeal, Emat);
376 NekDouble trEtE = FrobProd<DIM>(Emat, Emat);
379 (jacDet + sqrt(jacDet * jacDet + 4.0 * ep * ep));
381 if (sigma < numeric_limits<double>::min() && !gradient)
383 return numeric_limits<double>::max();
385 ASSERTL0(sigma > numeric_limits<double>::min(),
386 std::string(
"dividing by zero ") +
387 boost::lexical_cast<string>(sigma) +
" " +
388 boost::lexical_cast<string>(jacDet) +
" " +
389 boost::lexical_cast<string>(ep));
392 integral += quadW[k] *
394 (K * 0.5 * lsigma * lsigma + mu * trEtE);
401 NekDouble derivDet = Determinant<DIM>(phiM);
403 InvTrans<DIM>(phiM, jacInvTrans);
406 for (
int m = 0; m < DIM; ++m)
409 m_derivUtils[typeIt->first]->VdmD[m])(
410 k, typeIt->second[i]->NodeId(m_node->m_id));
417 for (
int l = 0; l < DIM; ++l)
419 jacDeriv[l] = basisDeriv[l];
424 for (
int n = 0; n < DIM; ++n)
426 jacDerivPhi[n] = 0.0;
427 for (
int l = 0; l < DIM; ++l)
429 jacDerivPhi[n] += jacDeriv[l] *
430 typeIt->second[i]->maps[k][l + 3 * n];
434 for (
int m = 0; m < DIM; ++m)
436 jacDetDeriv[m] = 0.0;
437 for (
int n = 0; n < DIM; ++n)
439 jacDetDeriv[m] += jacInvTrans[m][n] * basisDeriv[n];
441 jacDetDeriv[m] *= derivDet / absIdealMapDet;
450 for(
int d = 0; d < DIM; d++)
452 for (
int m = 0; m < DIM; ++m)
454 for (
int n = 0; n < DIM; ++n)
456 M2[d][m][n] = 0.5*(jacDerivPhi[m] * jacIdeal[d][n]
457 + jacIdeal[d][m] * jacDerivPhi[n]);
462 for (
int m = 0; m < DIM; ++m)
464 NekDouble frobProdA = FrobProd<DIM>(M2[m], Emat);
467 quadW[k] * absIdealMapDet *
468 (2.0 * mu * frobProdA +
469 K * lsigma * jacDetDeriv[m] /
470 (2.0 * sigma - jacDet));
474 for (
int m = 0; m < DIM; ++m)
476 for (
int l = m; l < DIM; ++l, ct++)
478 NekDouble frobProdBC = FrobProd<DIM>(M2[m], M2[l]);
485 for (
int p = 0;
p < DIM; ++
p)
487 for (
int q = 0; q < DIM; ++q)
489 M3[
p][q] = jacDerivPhi[
p] * jacDerivPhi[q];
492 frobProdBC += FrobProd<DIM>(M3,Emat);
496 quadW[k] * absIdealMapDet *
497 (2.0 * mu * frobProdBC +
498 jacDetDeriv[m] * jacDetDeriv[l] * K /
499 (2.0 * sigma - jacDet) /
500 (2.0 * sigma - jacDet) *
501 (1.0 - jacDet * lsigma /
502 (2.0 * sigma - jacDet)));
515 const NekDouble mu = 1.0 / 2.0 / (1.0 + nu);
516 const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu);
518 for (typeIt = m_data.begin(); typeIt != m_data.end(); typeIt++)
521 m_derivUtils[typeIt->first]->quadW;
522 for (
int i = 0; i < typeIt->second.size(); ++i)
524 for (
int k = 0; k < m_derivUtils[typeIt->first]->pts; ++k)
527 for (
int l = 0; l < DIM; ++l)
529 for (
int n = 0; n < DIM; ++n)
532 derivs[typeIt->first][l][i][n][k];
536 for (
int m = 0; m < DIM; ++m)
538 for (
int n = 0; n < DIM; ++n)
540 jacIdeal[n][m] = 0.0;
541 for (
int l = 0; l < DIM; ++l)
543 jacIdeal[n][m] += phiM[n][l] *
544 typeIt->second[i]->maps[k][m * 3 + l];
551 minJacNew = min(minJacNew, jacDet);
553 NekDouble absIdealMapDet = fabs(typeIt->second[i]->maps[k][9]);
559 (jacDet + sqrt(jacDet * jacDet + 4.0 * ep * ep));
561 if (sigma < numeric_limits<double>::min() && !gradient)
563 return numeric_limits<double>::max();
566 ASSERTL0(sigma > numeric_limits<double>::min(),
567 std::string(
"dividing by zero ") +
568 boost::lexical_cast<string>(sigma) +
" " +
569 boost::lexical_cast<string>(jacDet) +
" " +
570 boost::lexical_cast<string>(ep));
573 integral += quadW[k] * absIdealMapDet *
574 (0.5 * mu * (I1 - 3.0 - 2.0 * lsigma) +
575 0.5 * K * lsigma * lsigma);
583 NekDouble derivDet = Determinant<DIM>(phiM);
585 InvTrans<DIM>(phiM, jacInvTrans);
588 for (
int m = 0; m < DIM; ++m)
591 m_derivUtils[typeIt->first]->VdmD[m])(
592 k, typeIt->second[i]->NodeId(m_node->m_id));
599 for (
int l = 0; l < DIM; ++l)
601 jacDeriv[l] = basisDeriv[l];
606 for (
int n = 0; n < DIM; ++n)
608 jacDerivPhi[n] = 0.0;
609 for (
int l = 0; l < DIM; ++l)
611 jacDerivPhi[n] += jacDeriv[l] *
612 typeIt->second[i]->maps[k][l + 3 * n];
616 for (
int m = 0; m < DIM; ++m)
618 jacDetDeriv[m] = 0.0;
619 for (
int n = 0; n < DIM; ++n)
621 jacDetDeriv[m] += jacInvTrans[m][n] * basisDeriv[n];
623 jacDetDeriv[m] *= derivDet / absIdealMapDet;
627 for (
int m = 0; m < DIM; ++m)
632 ScalarProd<DIM>(jacIdeal[m],jacDerivPhi);
635 quadW[k] * absIdealMapDet *
637 (jacDetDeriv[m] / (2.0 * sigma - jacDet) *
642 for (
int m = 0; m < DIM; ++m)
644 for (
int l = m; l < DIM; ++l, ct++)
653 frobProdHes = ScalarProd<DIM>(jacDerivPhi,jacDerivPhi);
657 quadW[k] * absIdealMapDet *
659 jacDetDeriv[m] * jacDetDeriv[l] /
660 (2.0 * sigma - jacDet) /
661 (2.0 * sigma - jacDet) *
662 (K - jacDet * (K * lsigma - mu) /
663 (2.0 * sigma - jacDet)));
675 for (typeIt = m_data.begin(); typeIt != m_data.end(); typeIt++)
678 m_derivUtils[typeIt->first]->quadW;
679 for (
int i = 0; i < typeIt->second.size(); ++i)
681 for (
int k = 0; k < m_derivUtils[typeIt->first]->pts; ++k)
684 for (
int l = 0; l < DIM; ++l)
686 for (
int n = 0; n < DIM; ++n)
689 derivs[typeIt->first][l][i][n][k];
693 for (
int m = 0; m < DIM; ++m)
695 for (
int n = 0; n < DIM; ++n)
697 jacIdeal[n][m] = 0.0;
698 for (
int l = 0; l < DIM; ++l)
700 jacIdeal[n][m] += phiM[n][l] *
701 typeIt->second[i]->maps[k][m * 3 + l];
708 NekDouble absIdealMapDet = fabs(typeIt->second[i]->maps[k][9]);
709 minJacNew = min(minJacNew, jacDet);
713 (jacDet + sqrt(jacDet * jacDet + 4.0 * ep * ep));
715 if (sigma < numeric_limits<double>::min() && !gradient)
717 return numeric_limits<double>::max();
720 ASSERTL0(sigma > numeric_limits<double>::min(),
721 std::string(
"dividing by zero ") +
722 boost::lexical_cast<string>(sigma) +
" " +
723 boost::lexical_cast<string>(jacDet) +
" " +
724 boost::lexical_cast<string>(ep));
726 NekDouble W = frob / DIM / pow(fabs(sigma), 2.0 / DIM);
728 quadW[k] * absIdealMapDet * W;
736 NekDouble derivDet = Determinant<DIM>(phiM);
738 InvTrans<DIM>(phiM, jacInvTrans);
741 for (
int m = 0; m < DIM; ++m)
744 m_derivUtils[typeIt->first]->VdmD[m])(
745 k, typeIt->second[i]->NodeId(m_node->m_id));
752 for (
int l = 0; l < DIM; ++l)
754 jacDeriv[l] = basisDeriv[l];
759 for (
int n = 0; n < DIM; ++n)
761 jacDerivPhi[n] = 0.0;
762 for (
int l = 0; l < DIM; ++l)
764 jacDerivPhi[n] += jacDeriv[l] *
765 typeIt->second[i]->maps[k][l + 3 * n];
769 for (
int m = 0; m < DIM; ++m)
771 jacDetDeriv[m] = 0.0;
772 for (
int n = 0; n < DIM; ++n)
774 jacDetDeriv[m] += jacInvTrans[m][n] * basisDeriv[n];
776 jacDetDeriv[m] *= derivDet / absIdealMapDet;
782 for (
int m = 0; m < DIM; ++m)
786 frobProd[m] = ScalarProd<DIM>(jacIdeal[m],jacDerivPhi);
789 quadW[k] * absIdealMapDet *
790 (2.0 * W * (frobProd[m] / frob -
791 jacDetDeriv[m] / DIM /
792 (2.0 * sigma - jacDet)));
799 for (
int m = 0; m < DIM; ++m)
801 for (
int l = m; l < DIM; ++l, ct++)
810 frobProdHes = ScalarProd<DIM>(jacDerivPhi,jacDerivPhi);
814 quadW[k] * absIdealMapDet *
815 (inc[m] * inc[l] / W +
817 (frobProdHes / frob -
818 2.0 * frobProd[m] * frobProd[l] /
820 jacDetDeriv[m] * jacDetDeriv[l] *
822 (2.0 * sigma - jacDet) /
823 (2.0 * sigma - jacDet) /
824 (2.0 * sigma - jacDet) /
837 for (typeIt = m_data.begin(); typeIt != m_data.end(); typeIt++)
840 m_derivUtils[typeIt->first]->quadW;
841 for (
int i = 0; i < typeIt->second.size(); ++i)
843 for (
int k = 0; k < m_derivUtils[typeIt->first]->pts; ++k)
846 for (
int l = 0; l < DIM; ++l)
848 for (
int n = 0; n < DIM; ++n)
851 derivs[typeIt->first][l][i][n][k];
855 for (
int m = 0; m < DIM; ++m)
857 for (
int n = 0; n < DIM; ++n)
859 jacIdeal[n][m] = 0.0;
860 for (
int l = 0; l < DIM; ++l)
862 jacIdeal[n][m] += phiM[n][l] *
863 typeIt->second[i]->maps[k][m * 3 + l];
870 NekDouble absIdealMapDet = fabs(typeIt->second[i]->maps[k][9]);
871 minJacNew = min(minJacNew, jacDet);
875 (jacDet + sqrt(jacDet * jacDet + 4.0 * ep * ep));
877 if (sigma < numeric_limits<double>::min() && !gradient)
879 return numeric_limits<double>::max();
882 ASSERTL0(sigma > numeric_limits<double>::min(),
883 std::string(
"dividing by zero ") +
884 boost::lexical_cast<string>(sigma) +
" " +
885 boost::lexical_cast<string>(jacDet) +
" " +
886 boost::lexical_cast<string>(ep));
890 quadW[k] * absIdealMapDet * W;
898 NekDouble derivDet = Determinant<DIM>(phiM);
900 InvTrans<DIM>(phiM, jacInvTrans);
903 for (
int m = 0; m < DIM; ++m)
906 m_derivUtils[typeIt->first]->VdmD[m])(
907 k, typeIt->second[i]->NodeId(m_node->m_id));
914 for (
int l = 0; l < DIM; ++l)
916 jacDeriv[l] = basisDeriv[l];
921 for (
int n = 0; n < DIM; ++n)
923 jacDerivPhi[n] = 0.0;
924 for (
int l = 0; l < DIM; ++l)
926 jacDerivPhi[n] += jacDeriv[l] *
927 typeIt->second[i]->maps[k][l + 3 * n];
931 for (
int m = 0; m < DIM; ++m)
933 jacDetDeriv[m] = 0.0;
934 for (
int n = 0; n < DIM; ++n)
936 jacDetDeriv[m] += jacInvTrans[m][n] * basisDeriv[n];
938 jacDetDeriv[m] *= derivDet / absIdealMapDet;
944 for (
int m = 0; m < DIM; ++m)
948 frobProd[m] = ScalarProd<DIM>(jacIdeal[m],jacDerivPhi);
954 (2.0 * frobProd[m] / frob -
955 jacDetDeriv[m] / (2.0 * sigma - jacDet)));
960 for (
int m = 0; m < DIM; ++m)
962 for (
int l = m; l < DIM; ++l, ct++)
971 frobProdHes = ScalarProd<DIM>(jacDerivPhi,jacDerivPhi);
975 quadW[k] * absIdealMapDet *
976 (inc[m] * inc[l] / W +
978 (frobProdHes / frob -
979 2.0 * frobProd[m] * frobProd[l] /
981 0.5 * jacDetDeriv[m] *
982 jacDetDeriv[l] * jacDet /
983 (2.0 * sigma - jacDet) /
984 (2.0 * sigma - jacDet) /
985 (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])
boost::multi_array< NekDouble, 4 > DerivArray
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])