Fixed evaluation of secondary solution when integrandType==2: Must use 2nd derivatives

git-svn-id: http://svn.sintef.no/trondheim/IFEM/trunk@1202 e10b68d5-8a6e-419e-a041-bce267b0401d
This commit is contained in:
kmo 2011-09-24 17:53:03 +00:00 committed by Knut Morten Okstad
parent 56e2e2642f
commit e52597abb6
2 changed files with 82 additions and 102 deletions

View File

@ -692,7 +692,7 @@ Vec3 ASMu2D::getCoord (size_t inod) const
}
void ASMu2D::getGaussPointParameters (Vector& uGP, int dir, int nGauss,
void ASMu2D::getGaussPointParameters (RealArray& uGP, int dir, int nGauss,
int iel, const double* xi) const
{
#ifdef INDEX_CHECK
@ -709,8 +709,8 @@ void ASMu2D::getGaussPointParameters (Vector& uGP, int dir, int nGauss,
double ustart = (dir==0) ? el->umin() : el->vmin();
double ustop = (dir==0) ? el->umax() : el->vmax();
for (int i = 1; i <= nGauss; i++)
uGP(i) = 0.5*((ustop-ustart)*xi[i-1] + ustop+ustart);
for (int i = 0; i < nGauss; i++)
uGP[i] = 0.5*((ustop-ustart)*xi[i] + ustop+ustart);
}
@ -836,7 +836,7 @@ bool ASMu2D::integrate (Integrand& integrand,
if (!this->getElementCoordinates(Xnod,iel)) return false;
// Compute parameter values of the Gauss points over this element
Vector gpar[2], redpar[2];
RealArray gpar[2], redpar[2];
for (int d = 0; d < 2; d++)
{
this->getGaussPointParameters(gpar[d],d,nGauss,iel,xg);
@ -899,25 +899,25 @@ bool ASMu2D::integrate (Integrand& integrand,
LocalIntegral* elmInt = locInt.empty() ? 0 : locInt[fe.iel-1];
#if 0
if (integrand.getIntegrandType() > 10)
{
// --- Selective reduced integration loop ------------------------------
int ip = ((i2-p2)*nRed*nel1 + i1-p1)*nRed;
for (int j = 0; j < nRed; j++, ip += nRed*(nel1-1))
for (int i = 0; i < nRed; i++, ip++)
for (int j = 0; j < nRed; j++)
for (int i = 0; i < nRed; i++)
{
// Local element coordinates of current integration point
fe.xi = xr[i];
fe.eta = xr[j];
// Parameter values of current integration point
fe.u = redpar[0](i+1,i1-p1+1);
fe.v = redpar[1](j+1,i2-p2+1);
fe.u = redpar[0][i];
fe.v = redpar[1][j];
// Fetch basis function derivatives at current point
extractBasis(splineRed[ip],fe.N,dNdu);
// Compute basis function derivatives at current point
Go::BasisDerivsSf spline;
lrspline->computeBasis(fe.u,fe.v,spline,iel-1);
extractBasis(spline,fe.N,dNdu);
// Compute Jacobian inverse and derivatives
fe.detJxW = utl::Jacobian(Jac,fe.dNdX,Xnod,dNdu);
@ -927,7 +927,6 @@ bool ASMu2D::integrate (Integrand& integrand,
return false;
}
}
#endif
// --- Integration loop over all Gauss points in each direction ----------
@ -940,35 +939,28 @@ bool ASMu2D::integrate (Integrand& integrand,
fe.eta = xg[j];
// Parameter values of current integration point
fe.u = gpar[0](i+1);
fe.v = gpar[1](j+1);
fe.u = gpar[0][i];
fe.v = gpar[1][j];
// compute basis function values at integration point
Go::BasisDerivsSf spline;
Go::BasisDerivsSf2 spline2;
Go::BasisDerivsSf splineRed;
if (integrand.getIntegrandType() == 2)
lrspline->computeBasis(fe.u,fe.v,spline2, iel-1);
else
// Compute basis function derivatives at current integration point
if (integrand.getIntegrandType() == 2) {
Go::BasisDerivsSf2 spline;
lrspline->computeBasis(fe.u,fe.v,spline, iel-1);
extractBasis(spline,fe.N,dNdu,d2Ndu2);
}
else {
Go::BasisDerivsSf spline;
lrspline->computeBasis(fe.u,fe.v,spline, iel-1);
if (integrand.getIntegrandType() > 10)
lrspline->computeBasis(fe.u,fe.v,splineRed, iel-1);
// Fetch basis function derivatives at current integration point
if (integrand.getIntegrandType() == 2)
extractBasis(spline2,fe.N,dNdu,d2Ndu2);
else
extractBasis(spline,fe.N,dNdu);
#if SP_DEBUG > 4
std::cout <<"\nBasis functions at a integration point ";
std::cout <<" : (u,v) = "<< spline.param[0] <<" "<< spline.param[1]
<<" left_idx = "<< spline.left_idx[0] <<" "<< spline.left_idx[1] << std::endl;
for (size_t ii = 0; ii < spline.basisValues.size(); ii++)
std::cout << 1+ii <<'\t'<< spline.basisValues[ii] <<'\t'
<< spline.basisDerivs_u[ii] <<'\t'<< spline.basisDerivs_v[ii] << std::endl;
std::cout <<"\nBasis functions at a integration point ";
std::cout <<" : (u,v) = "<< spline.param[0] <<" "<< spline.param[1]
<<" left_idx = "<< spline.left_idx[0] <<" "<< spline.left_idx[1] << std::endl;
for (size_t ii = 0; ii < spline.basisValues.size(); ii++)
std::cout << 1+ii <<'\t'<< spline.basisValues[ii] <<'\t'
<< spline.basisDerivs_u[ii] <<'\t'<< spline.basisDerivs_v[ii] << std::endl;
#endif
}
// Compute Jacobian inverse of coordinate mapping and derivatives
fe.detJxW = utl::Jacobian(Jac,fe.dNdX,Xnod,dNdu);
@ -1277,21 +1269,6 @@ bool ASMu2D::tesselate (ElementBlock& grid, const int* npe) const
return true;
}
#if 0
void ASMu2D::scatterInd (int n1, int n2, int p1, int p2,
const int* start, IntVec& index)
{
index.reserve(p1*p2);
int ip = ((start[1]-p2+1))*n1 + (start[0]-p1+1);
for (int i2 = 0; i2 < p2; i2++, ip += n1-p1)
for (int i1 = 0; i1 < p1; i1++, ip++)
index.push_back(ip);
}
#endif
bool ASMu2D::evalSolution (Matrix& sField, const Vector& locSol,
const int* npe) const
@ -1335,7 +1312,7 @@ bool ASMu2D::evalSolution (Matrix& sField, const Vector& locSol,
int iel = i/4; // points are always listed in the same order as the elemnts, 4 pts per element
// fetch index of non-zero basis functions on this element
IntVec ip = MNPC[iel];
const IntVec& ip = MNPC[iel];
// evaluate the basis functions at current parametric point
Go::BasisPtsSf spline;
@ -1434,56 +1411,65 @@ bool ASMu2D::evalSolution (Matrix& sField, const Integrand& integrand,
const RealArray* gpar, bool regular) const
{
#ifdef SP_DEBUG
std::cout << "ASMu2D::evalSolution( )\n";
std::cout <<"ASMu2D::evalSolution(Matrix&,const Integrand&,const RealArray*,bool)\n";
#endif
// TODO: investigate the possibility of doing "regular" refinement by unfiorm
// tesselation grid and ignoring LR meshlines
if(gpar[0].size() != gpar[1].size())
return false;
sField.resize(0,0);
sField.resize(0,0);
// TODO: investigate the possibility of doing "regular" refinement by
// uniform tesselation grid and ignoring LR mesh lines
// Fetch nodal (control point) coordinates
Matrix Xnod;
if (gpar[0].size() != gpar[1].size())
return false;
IntVec ip;
Vector solPt;
Matrix dNdu, dNdX, Jac;
Vector solPt;
Matrix dNdu, dNdX, Jac, Xnod;
Matrix3D d2Ndu2, d2NdX2, Hess;
// Evaluate the secondary solution field at each point
size_t nPoints = gpar[0].size();
size_t nPoints = gpar[0].size();
bool use2ndDer = integrand.getIntegrandType() == 2;
for (size_t i = 0; i < nPoints; i++)
{
// fetch element containing evaluation point
int iel = i/4; // points are always listed in the same order as the elemnts, 4 pts per element
// Evaluate the secondary solution field at each point
for (size_t i = 0; i < nPoints; i++)
{
// Fetch element containing evaluation point. Points are always listed
int iel = i/4; // in the same order as the elements, 4 pts per element.
// fetch number of nonzero basis functions on this element as well as their indices
int nBasis = lrspline->getElement(iel)->nBasisFunctions();
Vector N(nBasis);
ip = MNPC[iel];
// Evaluate the basis functions at current parametric point
Vector N(lrspline->getElement(iel)->nBasisFunctions());
if (use2ndDer)
{
Go::BasisDerivsSf2 spline;
lrspline->computeBasis(gpar[0][i],gpar[1][i],spline,iel);
extractBasis(spline,N,dNdu,d2Ndu2);
}
else
{
Go::BasisDerivsSf spline;
lrspline->computeBasis(gpar[0][i],gpar[1][i],spline,iel);
extractBasis(spline,N,dNdu);
}
// evaluate the basis functions at current parametric point
Go::BasisDerivsSf spline;
lrspline->computeBasis(gpar[0][i], gpar[1][i], spline, iel);
extractBasis(spline, N, dNdu);
// Set up control point (nodal) coordinates for current element
if (!this->getElementCoordinates(Xnod,iel+1)) return false;
// Set up control point (nodal) coordinates for current element
if (!this->getElementCoordinates(Xnod,iel+1)) return false;
// Compute the Jacobian inverse
if (utl::Jacobian(Jac,dNdX,Xnod,dNdu) == 0.0) // Jac = (Xnod * dNdu)^-1
continue; // skip singular points
// Compute the Jacobian inverse
if (utl::Jacobian(Jac,dNdX,Xnod,dNdu) == 0.0) // Jac = (Xnod * dNdu)^-1
continue; // skip singular points
// Compute Hessian of coordinate mapping and 2nd order derivatives
if (use2ndDer)
if (!utl::Hessian(Hess,d2NdX2,Jac,Xnod,d2Ndu2,dNdu))
continue;
// Now evaluate the solution field
if (!integrand.evalSol(solPt,N,dNdX,Xnod*N,ip))
return false;
else if (sField.empty())
sField.resize(solPt.size(),nPoints,true);
// Now evaluate the solution field
if (!integrand.evalSol(solPt,N,dNdX,d2NdX2,Xnod*N,MNPC[iel]))
return false;
else if (sField.empty())
sField.resize(solPt.size(),nPoints,true);
sField.fillColumn(1+i,solPt);
}
sField.fillColumn(1+i,solPt);
}
return true;
return true;
}

View File

@ -149,13 +149,13 @@ public:
//! \param[in] dir Parameter direction to refine
//! \param[in] nInsert Number of extra knots to insert in each knot-span
bool uniformRefine(int dir, int nInsert);
//! \brief Refine the parametrization by inserting extra tensor knots.
//! \brief Refines the parametrization by inserting extra tensor knots.
//! \details This method is mainly kept for backward compatability with the
//! "REFINE" keyword in the input file.
//! \param[in] dir Parameter direction to refine
//! \param[in] xi Relative positions of added knots in each existing knot span
bool refine(int dir, const RealArray& xi);
//! \brief Raise the order of the tensor spline object for this patch.
//! \brief Raises the order of the tensor spline object for this patch.
//! \details This method is mainly kept for backward compatability with the
//! "RAISEORDER" keyword in the input file.
//! \param[in] ru Number of times to raise the order in u-direction
@ -352,7 +352,7 @@ protected:
//! \param[in] nGauss Number of Gauss points along a knot-span
//! \param[in] iel Element index
//! \param[in] xi Dimensionless Gauss point coordinates [-1,1]
void getGaussPointParameters(Vector& uGP, int dir, int nGauss,
void getGaussPointParameters(RealArray& uGP, int dir, int nGauss,
int iel, const double* xi) const;
//! \brief Calculates parameter values for the Greville points.
@ -384,16 +384,10 @@ protected:
static void extractBasis(const Go::BasisDerivsSf2& spline,
Vector& N, Matrix& dNdu, Matrix3D& d2Ndu2);
//! \brief Auxilliary function for computation of basis function indices.
static void scatterInd(int n1, int n2, int p1, int p2,
const int* start, IntVec& index);
private:
protected:
LR::LRSplineSurface* lrspline; //!< Pointer to the actual spline surface object
Go::SplineSurface* tensorspline; //!< Pointer to the original tensor spline object
private:
Go::SplineSurface* tensorspline; //!< Pointer to the original tensor spline object
// the tensor spline object is kept for backwards compatability with the REFINE and RAISEORDER
// key-words, although we take note that there is a possibility of optimization since all mapping
// values and jacobians may be performed on this object for increased efficiency