Esempio n. 1
0
// =============================================================================
int Mesh2DUtils::last_nonlarger_knotvalue_ix(const Mesh2D&m, Direction2D d, 
					     double par)
// =============================================================================
{
  const double* a = m.knotsBegin(d);
  const double* b = m.knotsEnd(d);
  
  double tol = 1.0e-8;
  // if (par < a[0] && par >= a[0]-tol)
  //   par = a[0];
  // if (par > b[-1] && par <= b[-1]+tol)
  //   par = b[-1];

  // searching for last nonlarger knotvalue using bisection
  for (int diff = (b-a)/2; diff != 0; diff = (b-a)/2) {
    if (par < a[0]+tol && par >= a[0]-tol)
      par = a[0];
    if (par > b[-1]-tol && par <= b[-1]+tol)
      par = b[-1];
    const double* mid = a + diff;
    ( (*mid > par) ? b : a) = mid;
  }

  if (b == m.knotsEnd(d))
    --b;
  if (fabs(par-b[0]) < tol && fabs(par-a[0]) > tol)
    return (b - m.knotsBegin(d));
  else
    return (a - m.knotsBegin(d)); // if index becomes negative, it signalizes that 'par' 
                                // is smaller than even the first knot value
}
Esempio n. 2
0
//==============================================================================
// if 'b' can be split at least once in the mesh 'm', split it once, and return the
// result through 'b1' and 'b2'.  The function never carries out more than one split,
// even when several splits are possible.
bool LRBSpline2DUtils::try_split_once(const LRBSpline2D& b, const Mesh2D& mesh,
                                      LRBSpline2D*& b1,
                                      LRBSpline2D*& b2)
//==============================================================================
{
    const int umin = b.suppMin(XFIXED);
    const int vmin = b.suppMin(YFIXED);
    const int umax = b.suppMax(XFIXED);
    const int vmax = b.suppMax(YFIXED);
    const vector<int> m_kvec_u = derive_knots(mesh, XFIXED, umin, umax, vmin, vmax);
    const vector<int> m_kvec_v = derive_knots(mesh, YFIXED, vmin, vmax, umin, umax);

    // @@ The assertions below should always hold if function is called with correct
    // argument. When code is properly debugged and tested, they can be taken away for
    // efficiency (asserts should go away anyway when compiling in optimized mode).
    // Alternatively, if it is a concern that users might call this function with wrong
    // argument, the assertions could be replaced by exception-throwing 'if'-statements.
    assert(std::includes(m_kvec_u.begin(), m_kvec_u.end(), b.kvec(XFIXED).begin(), b.kvec(XFIXED).end()));
    assert(std::includes(m_kvec_v.begin(), m_kvec_v.end(), b.kvec(YFIXED).begin(), b.kvec(YFIXED).end()));

    if (num_inner_knots(m_kvec_u) > num_inner_knots(b.kvec(XFIXED))) {
        // Since we know that m_kvec_u contains more elements than b.kvec(XFIXED) and since
        // we know that the latter is included in the former, we know that there must be at least
        // one knot in 'm_kvec_u' that is not found in b.kvec(XFIXED).  We can therefore call
        // the following function without risking an exception to be thrown.
        const int new_ix = find_uncovered_inner_knot(m_kvec_u, b.kvec(XFIXED));

        // @@@ VSK. Cannot set pointers to the new bsplines before it is placed in the
        // global array. Will the position of the element change when a bspline is removed?
        split_function(b, mesh, XFIXED, mesh.knotsBegin(XFIXED), new_ix, b1, b2);
        return true;

    } else if (num_inner_knots(m_kvec_v) > num_inner_knots(b.kvec(YFIXED))) {
        // same comment as above
        const int new_ix = find_uncovered_inner_knot(m_kvec_v, b.kvec(YFIXED));
        split_function(b, mesh, YFIXED, mesh.knotsBegin(YFIXED), new_ix, b1, b2);
        return true;
    }
    // No splits possible
    return false;
}