bool ASMs3DLag::evalSolution (Matrix& sField, const IntegrandBase& integrand, const RealArray*, bool) const { sField.resize(0,0); const int p1 = svol->order(0); const int p2 = svol->order(1); const int p3 = svol->order(2); double incx = 2.0/double(p1-1); double incy = 2.0/double(p2-1); double incz = 2.0/double(p3-1); size_t nPoints = coord.size(); IntVec check(nPoints,0); FiniteElement fe(p1*p2*p3); Vector solPt; Vectors globSolPt(nPoints); Matrix dNdu, Xnod, Jac; // Evaluate the secondary solution field at each point const int nel = this->getNoElms(true); for (int iel = 1; iel <= nel; iel++) { const IntVec& mnpc = MNPC[iel-1]; this->getElementCoordinates(Xnod,iel); int i, j, k, loc = 0; for (k = 0; k < p3; k++) for (j = 0; j < p2; j++) for (i = 0; i < p1; i++, loc++) { fe.xi = -1.0 + i*incx; fe.eta = -1.0 + j*incy; fe.zeta = -1.0 + k*incz; if (!Lagrange::computeBasis(fe.N,dNdu,p1,fe.xi,p2,fe.eta,p3,fe.zeta)) return false; // Compute the Jacobian inverse fe.detJxW = utl::Jacobian(Jac,fe.dNdX,Xnod,dNdu); // Now evaluate the solution field if (!integrand.evalSol(solPt,fe,Xnod*fe.N,mnpc)) return false; else if (sField.empty()) sField.resize(solPt.size(),nPoints,true); if (++check[mnpc[loc]] == 1) globSolPt[mnpc[loc]] = solPt; else globSolPt[mnpc[loc]] += solPt; } } for (size_t i = 0; i < nPoints; i++) sField.fillColumn(1+i,globSolPt[i] /= check[i]); return true; }
bool ASMs2DSpec::evalSolution (Matrix& sField, const IntegrandBase& integrand, const RealArray*, bool) const { sField.resize(0,0); Vector wg1,xg1,wg2,xg2; if (!Legendre::GLL(wg1,xg1,p1)) return false; if (!Legendre::GLL(wg2,xg2,p2)) return false; Matrix D1, D2; if (!Legendre::basisDerivatives(p1,D1)) return false; if (!Legendre::basisDerivatives(p2,D2)) return false; size_t nPoints = this->getNoNodes(); IntVec check(nPoints,0); FiniteElement fe(p1*p2); Vector solPt; Vectors globSolPt(nPoints); Matrix dNdu(p1*p2,2), Xnod, Jac; // Evaluate the secondary solution field at each point const int nel = this->getNoElms(); for (int iel = 1; iel <= nel; iel++) { const IntVec& mnpc = MNPC[iel-1]; this->getElementCoordinates(Xnod,iel); int i, j, loc = 0; for (j = 0; j < p2; j++) for (i = 0; i < p1; i++, loc++) { evalBasis(i+1,j+1,p1,p2,D1,D2,fe.N,dNdu); // Compute the Jacobian inverse fe.detJxW = utl::Jacobian(Jac,fe.dNdX,Xnod,dNdu); // Now evaluate the solution field if (!integrand.evalSol(solPt,fe,Xnod.getColumn(loc+1),mnpc)) return false; else if (sField.empty()) sField.resize(solPt.size(),nPoints,true); if (++check[mnpc[loc]] == 1) globSolPt[mnpc[loc]] = solPt; else globSolPt[mnpc[loc]] += solPt; } } for (size_t i = 0; i < nPoints; i++) sField.fillColumn(1+i,globSolPt[i] /= check[i]); return true; }
bool ASMs1DSpec::evalSolution (Matrix& sField, const IntegrandBase& integrand, const RealArray*, bool) const { sField.resize(0,0); if (!curv) return false; const int p1 = curv->order(); Matrix D1; if (!Legendre::basisDerivatives(p1,D1)) return false; size_t nPoints = this->getNoNodes(); IntVec check(nPoints,0); FiniteElement fe(p1); Vector solPt; Vectors globSolPt(nPoints); Matrix dNdu(p1,1), Xnod, Jac; // Evaluate the secondary solution field at each point const int nel = this->getNoElms(); for (int iel = 1; iel <= nel; iel++) { const IntVec& mnpc = MNPC[iel-1]; this->getElementCoordinates(Xnod,iel); for (int i = 0; i < p1; i++) { fe.N.fill(0.0); fe.N(i+1) = 1.0; dNdu.fillColumn(1,D1.getRow(i+1)); // Compute the Jacobian inverse fe.detJxW = utl::Jacobian(Jac,fe.dNdX,Xnod,dNdu); // Now evaluate the solution field if (!integrand.evalSol(solPt,fe,Xnod.getColumn(i+1),mnpc)) return false; else if (sField.empty()) sField.resize(solPt.size(),nPoints,true); if (++check[mnpc[i]] == 1) globSolPt[mnpc[i]] = solPt; else globSolPt[mnpc[i]] += solPt; } } for (size_t i = 0; i < nPoints; i++) sField.fillColumn(1+i,globSolPt[i] /= check[i]); return true; }
bool ASMs2DmxLag::evalSolution (Matrix& sField, const IntegrandBase& integrand, const RealArray*, bool) const { sField.resize(0,0); double incx = 2.0/double(p1-1); double incy = 2.0/double(p2-1); size_t nPoints = nb[0]; IntVec check(nPoints,0); MxFiniteElement fe(elem_size); Vector solPt; Vectors globSolPt(nPoints); Matrices dNxdu(nxx.size()); Matrix Xnod, Jac; // Evaluate the secondary solution field at each point for (size_t iel = 1; iel <= nel; iel++) { IntVec::const_iterator f2start = geoBasis == 1? MNPC[iel-1].begin() : MNPC[iel-1].begin() + std::accumulate(elem_size.begin()+geoBasis-2, elem_size.begin()+geoBasis-1, 0); IntVec::const_iterator f2end = f2start + elem_size[geoBasis-1]; IntVec mnpc1(f2start,f2end); this->getElementCoordinates(Xnod,iel); int i, j, loc = 0; for (j = 0; j < p2; j++) for (i = 0; i < p1; i++, loc++) { double xi = -1.0 + i*incx; double eta = -1.0 + j*incy; for (size_t b = 0; b < nxx.size(); ++b) if (!Lagrange::computeBasis(fe.basis(b+1),dNxdu[b],elem_sizes[b][0],xi, elem_sizes[b][1],eta)) return false; // Compute the Jacobian inverse fe.detJxW = utl::Jacobian(Jac,fe.grad(geoBasis),Xnod,dNxdu[geoBasis-1]); for (size_t b = 1; b <= nxx.size(); b++) if (b != (size_t)geoBasis) { if (fe.detJxW == 0.0) fe.grad(b).clear(); else fe.grad(b).multiply(dNxdu[b-1],Jac); } // Now evaluate the solution field if (!integrand.evalSol(solPt,fe,Xnod*fe.basis(geoBasis),MNPC[iel-1],elem_size,nb)) return false; else if (sField.empty()) sField.resize(solPt.size(),nPoints,true); if (++check[mnpc1[loc]] == 1) globSolPt[mnpc1[loc]] = solPt; else globSolPt[mnpc1[loc]] += solPt; } } for (size_t i = 0; i < nPoints; i++) sField.fillColumn(1+i,globSolPt[i] /= check[i]); return true; }