Esempio n. 1
0
Go::SplineCurve* SplineUtils::project (const Go::SplineCurve* curve,
                                       const FunctionBase& f,
                                       int nComp, Real time)
{
  if (!curve || nComp < 1) return nullptr;

  const Go::BsplineBasis& basis = curve->basis();
  const int nPoints = basis.numCoefs();

  Go::Point X;
  RealArray gpar(nPoints), fval, fOfX;
  fval.reserve(nComp*nPoints);

  // Compute parameter values of the function sampling points (Greville points)
  // and evaluate the function at these points
  for (int i = 0; i < nPoints; i++)
  {
    gpar[i] = basis.grevilleParameter(i);
    curve->point(X,gpar[i]);
    fOfX = f.getValue(toVec4(X,time));
    fval.insert(fval.end(),fOfX.begin(),fOfX.begin()+nComp);
  }

  // Get weights for rational spline curves (NURBS)
  RealArray weights;
  if (curve->rational())
    curve->getWeights(weights);

  // Project the function onto the spline basis to find control point values
  return Go::CurveInterpolator::regularInterpolation(basis,gpar,fval,nComp,
                                                     curve->rational(),weights);
}
void SparseTileLayoutData<Dim>::initialize(const Domain_t &bbox,
					   const PatchList_t &plist,
					   const ContextMapper<Dim> &cmap)
{
  this->blocks_m = Loc<Dim>();
  initialize(bbox);
  TilePartition<Dim> gpar(plist);
  gpar.partition(bbox,this->all_m,cmap);
  syncPatch();
}
Esempio n. 3
0
TEST(TestSplineUtils, ExtractBasisVolume)
{
  Go::SphereVolume sphere(1.0, Go::Point(0.0, 0.0, 0.0),
                          Go::Point(0.0, 0.0, 1.0), Go::Point(1.0, 0.0, 0.0));
  Go::SplineVolume* vol = sphere.geometryVolume();
  vol->setParameterDomain(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);

  std::vector<Go::BasisDerivs> spline;
  std::vector<Go::BasisDerivs2> spline2;
  Matrix gpar(1, 1);
  gpar(1,1) = 0.3;
  vol->computeBasisGrid(gpar,gpar,gpar,spline);
  vol->raiseOrder(1,1,1);
  vol->computeBasisGrid(gpar,gpar,gpar,spline2);
  Vector N;
  Matrix dNdU;
  Matrix3D d2NdU2;
  SplineUtils::extractBasis(spline[0],N,dNdU);
  CHECK_VECTORS_EQUAL(N, "src/Utility/Test/refdata/ExtractBasis_vol_N.asc");
  CHECK_MATRICES_EQUAL(dNdU, "src/Utility/Test/refdata/ExtractBasis_vol_dNdU.asc");
  SplineUtils::extractBasis(spline2[0],N,dNdU,d2NdU2);
  CHECK_MATRICES3D_EQUAL(d2NdU2, "src/Utility/Test/refdata/ExtractBasis_vol_d2NdU2.asc");
}
Esempio n. 4
0
TEST(TestSplineUtils, ExtractBasisSurface)
{
  Go::Plane plane(Go::Point(0.0, 0.0, 0.0), Go::Point(0.0, 0.0, 1.0),
                  Go::Point(sqrt(2.0), sqrt(2.0), 0.0));
  Go::SplineSurface* srf = plane.createSplineSurface();
  srf->setParameterDomain(0.0, 1.0, 0.0, 1.0);

  std::vector<Go::BasisDerivsSf> spline;
  std::vector<Go::BasisDerivsSf2> spline2;
  Matrix gpar(1, 1);
  gpar(1,1) = 0.3;
  srf->computeBasisGrid(gpar,gpar,spline);
  srf->raiseOrder(1,1);
  srf->computeBasisGrid(gpar,gpar,spline2);
  Vector N;
  Matrix dNdU;
  Matrix3D d2NdU2;
  SplineUtils::extractBasis(spline[0],N,dNdU);
  CHECK_VECTORS_EQUAL(N, "src/Utility/Test/refdata/ExtractBasis_srf_N.asc");
  CHECK_MATRICES_EQUAL(dNdU, "src/Utility/Test/refdata/ExtractBasis_srf_dNdU.asc");
  SplineUtils::extractBasis(spline2[0],N,dNdU,d2NdU2);
  CHECK_MATRICES3D_EQUAL(d2NdU2, "src/Utility/Test/refdata/ExtractBasis_srf_d2NdU2.asc");
}
Esempio n. 5
0
File: ASMs1D.C Progetto: OPM/IFEM
bool ASMs1D::integrate (Integrand& integrand,
			GlobalIntegral& glInt,
			const TimeDomain& time)
{
  if (!curv) return true; // silently ignore empty patches

  // Get Gaussian quadrature points and weights
  const double* xg = GaussQuadrature::getCoord(nGauss);
  const double* wg = GaussQuadrature::getWeight(nGauss);
  if (!xg || !wg) return false;

  // Get the reduced integration quadrature points, if needed
  const double* xr = nullptr;
  const double* wr = nullptr;
  int nRed = integrand.getReducedIntegration(nGauss);
  if (nRed > 0)
  {
    xr = GaussQuadrature::getCoord(nRed);
    wr = GaussQuadrature::getWeight(nRed);
    if (!xr || !wr) return false;
  }
  else if (nRed < 0)
    nRed = nGauss; // The integrand needs to know nGauss

  if (integrand.getIntegrandType() & Integrand::SECOND_DERIVATIVES)
    if (curv->rational())
    {
      std::cerr <<" *** ASMs1D::integrate: Second-derivatives of NURBS "
                <<" is not implemented yet, sorry..."<< std::endl;
      return false;
    }

  // Compute parameter values of the Gauss points over the whole patch
  Matrix gpar, redpar;
  this->getGaussPointParameters(gpar,nGauss,xg);
  if (xr)
    this->getGaussPointParameters(redpar,nRed,xr);

  const int p1 = curv->order();

  FiniteElement fe(p1);
  Matrix   dNdu, Jac;
  Matrix3D d2Ndu2, Hess;
  Vec4     X;

  if (nsd > 1 && (integrand.getIntegrandType() & Integrand::SECOND_DERIVATIVES))
    fe.G.resize(nsd,2); // For storing d{X}/du and d2{X}/du2


  // === Assembly loop over all elements in the patch ==========================

  for (size_t iel = 0; iel < nel; iel++)
  {
    fe.iel = MLGE[iel];
    if (fe.iel < 1) continue; // zero-length element

    // Check that the current element has nonzero length
    double dL = this->getParametricLength(1+iel);
    if (dL < 0.0) return false; // topology error (probably logic error)

    // Set up control point coordinates for current element
    if (!this->getElementCoordinates(fe.Xn,1+iel)) return false;

    if (integrand.getIntegrandType() & Integrand::ELEMENT_CORNERS)
      this->getElementEnds(p1+iel,fe.XC);

    if (integrand.getIntegrandType() & Integrand::NODAL_ROTATIONS)
    {
      this->getElementNodalRotations(fe.Tn,iel);
      if (!elmCS.empty()) fe.Te = elmCS[iel];
    }

    // Initialize element matrices
    LocalIntegral* A = integrand.getLocalIntegral(fe.N.size(),fe.iel);
    bool ok = integrand.initElement(MNPC[iel],fe,X,nRed,*A);

    if (xr)
    {
      // --- Selective reduced integration loop --------------------------------

      for (int i = 0; i < nRed && ok; i++)
      {
	// Local element coordinates of current integration point
	fe.xi = xr[i];

	// Parameter values of current integration point
	fe.u = redpar(1+i,1+iel);

        if (integrand.getIntegrandType() & Integrand::NO_DERIVATIVES)
          this->extractBasis(fe.u,fe.N);
        else
        {
          // Fetch basis function derivatives at current point
          this->extractBasis(fe.u,fe.N,dNdu);
          // Compute Jacobian inverse and derivatives
          dNdu.multiply(0.5*dL); // Derivatives w.r.t. xi=[-1,1]
          fe.detJxW = utl::Jacobian(Jac,fe.dNdX,fe.Xn,dNdu)*wr[i];
        }

	// Cartesian coordinates of current integration point
	X = fe.Xn * fe.N;
	X.t = time.t;

	// Compute the reduced integration terms of the integrand
	ok = integrand.reducedInt(*A,fe,X);
      }
    }


    // --- Integration loop over all Gauss points in current element -----------

    int jp = iel*nGauss;
    fe.iGP = firstIp + jp; // Global integration point counter

    for (int i = 0; i < nGauss && ok; i++, fe.iGP++)
    {
      // Local element coordinate of current integration point
      fe.xi = xg[i];

      // Parameter value of current integration point
      fe.u = gpar(1+i,1+iel);

      // Compute basis functions and derivatives
      if (integrand.getIntegrandType() & Integrand::NO_DERIVATIVES)
        this->extractBasis(fe.u,fe.N);
      else if (integrand.getIntegrandType() & Integrand::SECOND_DERIVATIVES)
        this->extractBasis(fe.u,fe.N,dNdu,d2Ndu2);
      else
        this->extractBasis(fe.u,fe.N,dNdu);

      if (!dNdu.empty())
      {
        // Compute derivatives in terms of physical coordinates
        dNdu.multiply(0.5*dL); // Derivatives w.r.t. xi=[-1,1]
        fe.detJxW = utl::Jacobian(Jac,fe.dNdX,fe.Xn,dNdu)*wg[i];
        if (fe.detJxW == 0.0) continue; // skip singular points

        // Compute Hessian of coordinate mapping and 2nd order derivatives
        if (integrand.getIntegrandType() & Integrand::SECOND_DERIVATIVES)
        {
          d2Ndu2.multiply(0.25*dL*dL); // 2nd derivatives w.r.t. xi=[-1,1]
          if (!utl::Hessian(Hess,fe.d2NdX2,Jac,fe.Xn,d2Ndu2,fe.dNdX))
            ok = false;
          else if (fe.G.cols() == 2)
          {
            // Store the first and second derivatives of {X} w.r.t.
            // the parametric coordinate (xi), in the G-matrix
            fe.G.fillColumn(1,Jac.ptr());
            fe.G.fillColumn(2,Hess.ptr());
          }
        }
      }

      // Cartesian coordinates of current integration point
      X = fe.Xn * fe.N;
      X.t = time.t;

      // Evaluate the integrand and accumulate element contributions
      if (ok && !integrand.evalInt(*A,fe,time,X))
        ok = false;
    }

    // Finalize the element quantities
    if (ok && !integrand.finalizeElement(*A,fe,time,firstIp+jp))
      ok = false;

    // Assembly of global system integral
    if (ok && !glInt.assemble(A->ref(),fe.iel))
      ok = false;

    A->destruct();

    if (!ok) return false;
  }

  return true;
}
int main(int argc, char *argv[])
{
  // Initialize POOMA and output stream, using Tester class

  Pooma::initialize(argc, argv);
  Pooma::Tester tester(argc, argv);
  tester.out() << argv[0] << ": MP DynamicArray w/ shared layouts."
               << std::endl;
  tester.out() << "-------------------------------------------" << std::endl;

  // Create some Interval objects to create and index into Array's with

  tester.out() << "Creating Interval<1> objects ..." << std::endl;
  Interval<1> D1(3);
  tester.out() << "D1 = " << D1 << std::endl;

  // Create MultiPatch dynamic arrays that share a layout.

  tester.out() << "Creating MP DynamicArray using domain D1 ... " << std::endl;
  Loc<1> blocks(3);
  GridPartition<1> gpar(blocks);
  LocalMapper<1> cmap(gpar);  
  DynamicLayout dynlayout(D1,gpar,cmap);
  DynamicArray< int, MultiPatch<DynamicTag,Dynamic> > a2(dynlayout);
  tester.check("a2 size", a2.domain().size() == D1.size());
  tester.check("a2 patches", a2.layout().sizeLocal() == 3);

  tester.out() << "Creating MP DynamicArray w/ same layout ..." << std::endl;
  DynamicArray< int, MultiPatch<DynamicTag,Dynamic> > b2(a2.layout());
  tester.check("b2 size", b2.domain().size() == D1.size());
  tester.check("b2 patches", b2.layout().sizeLocal() == 3);

  // Test looping over layout nodes

  tester.out() << "DynamicArray< MultiPatch<DynamicTag,Dynamic> > layout:\n";
  tester.out() << a2.layout() << std::endl;

  // Initialize dynamic arrays with scalars.

  a2 = 30;
  b2 = 40;
  Pooma::blockAndEvaluate();
  tester.out() << "Initialized MP DynamicArray's to 30, 40:" << std::endl;
  tester.out() << "a2 = " << a2 << std::endl;
  tester.out() << "b2 = " << b2 << std::endl;
  tester.check("a2 initial sum", sum(a2) == (a2.domain().size() * 30));
  tester.check("b2 initial sum", sum(b2) == (b2.domain().size() * 40));

  // Create elements in the shared-layout MPE arrays

  tester.out() << "Creating 2 elements at end of a2 and b2 ..." << std::endl;
  a2.create(2);
  a2.sync();
  a2(3)=a2(4)=-50;
  b2(3)=b2(4)=-60;

  a2(a2.engine().domain().last()-1)=0;
  a2(a2.engine().domain().last())=0;
  
  tester.out() << "a2 = " << a2 << std::endl;
  tester.out() << "b2 = " << b2 << std::endl;
  tester.check("a2 size after create", a2.domain().size() == (D1.size() + 2));
  tester.check("b2 size after create", b2.domain().size() == (D1.size() + 2));

  // Delete an element in the shared-layout MPE arrays

  tester.out() << "Deleting 2nd element of a2 & b2 w/backfill ..."<<std::endl;
  b2.destroy(Interval<1>(1,1), BackFill());
  b2.sync();
  tester.out() << "a2 = " << a2 << std::endl;
  tester.out() << "b2 = " << b2 << std::endl;
  tester.check("a2 size after BackFill",a2.domain().size() == (D1.size() + 1));
  tester.check("b2 size after BackFill",b2.domain().size() == (D1.size() + 1));

  // Copy values from the beginning of a2 and b2 to their end

  tester.out() << "Copying first three elements of a2 and b2 ..." << std::endl;
  a2.copy(Interval<1>(3));
  a2.sync();
  tester.out() << "a2 = " << a2 << std::endl;
  tester.out() << "b2 = " << b2 << std::endl;
  tester.check("a2 size after copy", a2.domain().size() == (D1.size() + 4));
  tester.check("b2 size after copy", b2.domain().size() == (D1.size() + 4));

  // Return resulting error code and exit; Tester will shut down POOMA.

  tester.out() << "-------------------------------------------" << std::endl;
  int retval = tester.results("MP DynamicArray w/ shared layouts");
  Pooma::finalize();
  return retval;
}