コード例 #1
0
ファイル: mainWin.cpp プロジェクト: prodigeni/pcbsd
void mainWin::slotInstallClicked()
{
  // Sanity check our install choices
  if (!sanityCheck())
    return;

  // Start the installation
  doUpdates();
}
コード例 #2
0
void KstDataManagerI::delete_I() {
  QListViewItem *qi = DataView->selectedItems().at(0);
  KstObjectItem *koi = static_cast<KstObjectItem*>(qi);

  if (qi->rtti() == RTTI_OBJ_OBJECT) {
    doc->removeDataObject(koi->tagName());
  } else if (qi->rtti() == RTTI_OBJ_DATA_VECTOR) {
    KST::vectorList.removeTag(koi->tagName());
    doUpdates();
  }
}
コード例 #3
0
void UpdateThread::run() {
  bool force;
  int  updateTime;

#if UPDATEDEBUG > 0
  qDebug() << "Update thread running, tid=" << (int)QThread::currentThread() << endl;
#if UPDATEDEBUG > 2
  qDebug() << "dataObjectList lock is at " << (void*)(&KST::dataObjectList.lock()) << endl;
  qDebug() << "dataSourceList lock is at " << (void*)(&KST::dataSourceList.lock()) << endl;
#endif
#endif

  _done = false;

  while (!_done) {
    _statusMutex.lock();
    updateTime = _updateTime;

    if (_waitCondition.wait(&_statusMutex, _updateTime)) {
#if UPDATEDEBUG > 0
      qDebug() << "Update timer " << _updateTime << endl;
#endif
      if (!_force) {
        break;
      }
    }

    if (_done) {
      _statusMutex.unlock();
      break;
    }
    force = _force;
    _force = false;
    _statusMutex.unlock();

    if (_paused && !force) {
#if UPDATEDEBUG > 0
      qDebug() << "Update thread paused..." << endl;
#endif
      continue;
    }

    bool gotData = false;
    if (doUpdates(force, &gotData) && !_done) {
#if UPDATEDEBUG > 1
      qDebug() << "Update resulted in: TRUE!" << endl;
#endif
      if (gotData) {
        qDebug() << "Posting UpdateDataDialogs" << endl;
        ThreadEvent *e = new ThreadEvent(ThreadEvent::UpdateDataDialogs);
        e->_curves = _updatedCurves;
        e->_counter = _updateCounter;
        QApplication::postEvent(_doc, e);
        // this event also triggers an implicit repaint
      } else {
        QApplication::postEvent(_doc, new ThreadEvent(ThreadEvent::Repaint));
      }
      // Wait for UI thread to finish events.  If we don't wait
      // 1: the UI thread could get flooded with events
      // 2: the update thread could change vectors during a paint, causing
      //    inconsistent curves to be plotted ie, the X vector updated
      //    and the Y vector not yet updated...

      // Race warning: Syncronization of updating() is not assured,
      // but updating() will always return a valid answer which was
      // true 'close' to when we asked.  This will safely keep the
      // update thread from over filling the UI thread.  The usleeps
      // will hopefully give the UI thread a chance to set itself...

      usleep(1000); // 1 ms on 2.6 kernel. 10ms on 2.4 kernel

      while (!_done && _doc->updating()) {  // wait for the UI to finish old events
        usleep(1000);
      }
      usleep(1000);
      // check again... not strictly needed given implicit repaint below,
      // but it should just return false, so no harm done.
      while (!_done && _doc->updating()) {
        usleep(1000);
      }
    } else {
      QApplication::postEvent(_doc, new ThreadEvent(ThreadEvent::NoUpdate));
    }
  }

  QApplication::postEvent(_doc, new ThreadEvent(ThreadEvent::Done));
}
コード例 #4
0
void KstDataManagerI::delete_I() {
  QListViewItem *qi = DataView->selectedItems().at(0);
  if (!qi) {
    return;
  }
  KstObjectItem *koi = static_cast<KstObjectItem*>(qi);

  if (koi->removable()) {
    if (qi->rtti() == RTTI_OBJ_OBJECT) {
      doc->removeDataObject(koi->tag().tag());
    } else if (qi->rtti() == RTTI_OBJ_DATA_VECTOR) {
      KST::vectorList.lock().writeLock();
      KST::vectorList.removeTag(koi->tag().tag());
      KST::vectorList.lock().unlock();
      doUpdates();
    } else if (qi->rtti() == RTTI_OBJ_STATIC_VECTOR) {
      KST::vectorList.lock().writeLock();
      KST::vectorList.removeTag(koi->tag().tag());
      KST::vectorList.lock().unlock();
      doUpdates();
    } else if (qi->rtti() == RTTI_OBJ_DATA_MATRIX) {
      KST::matrixList.lock().writeLock();
      KST::matrixList.removeTag(koi->tag().tag());
      KST::matrixList.lock().unlock();  
      doUpdates();
    } else if (qi->rtti() == RTTI_OBJ_STATIC_MATRIX) {
      KST::matrixList.lock().writeLock();
      KST::matrixList.removeTag(koi->tag().tag());
      KST::matrixList.lock().unlock();  
      doUpdates();
    }
    update();
  } else {
    // Don't prompt for base curves
    KstBaseCurvePtr bc = kst_cast<KstBaseCurve>(koi->dataObject());
    if (bc || KMessageBox::warningYesNo(this, i18n("There are other objects in memory that depend on %1.  Do you wish to delete them too?").arg(koi->tag().tag())) == KMessageBox::Yes) {

      if (qi->rtti() == RTTI_OBJ_OBJECT) {
        koi->dataObject()->deleteDependents();
        doc->removeDataObject(koi->tag().tag());
      } else if (qi->rtti() == RTTI_OBJ_DATA_VECTOR) {
        KstRVectorPtr x = kst_cast<KstRVector>(*KST::vectorList.findTag(koi->tag().tag()));
        if (x) {
          x->deleteDependents();
          x = 0L;
          KST::vectorList.lock().writeLock();
          KST::vectorList.removeTag(koi->tag().tag());
          KST::vectorList.lock().unlock();
          doUpdates();
        } else {
          KMessageBox::sorry(this, i18n("Unknown error deleting data vector."));
        }
      } else if (qi->rtti() == RTTI_OBJ_STATIC_VECTOR) {
        KstSVectorPtr x = kst_cast<KstSVector>(*KST::vectorList.findTag(koi->tag().tag()));
        if (x) {
          x->deleteDependents();
          x = 0L;
          KST::vectorList.lock().writeLock();
          KST::vectorList.removeTag(koi->tag().tag());
          KST::vectorList.lock().unlock();
          doUpdates();
        } else {
          KMessageBox::sorry(this, i18n("Unknown error deleting static vector."));
        }
      } else if (qi->rtti() == RTTI_OBJ_DATA_MATRIX) {
        KstRMatrixPtr x = kst_cast<KstRMatrix>(*KST::matrixList.findTag(koi->tag().tag()));
        if (x) {
          x->deleteDependents();
          x = 0L;
          KST::matrixList.lock().writeLock();
          KST::matrixList.removeTag(koi->tag().tag());
          KST::matrixList.lock().unlock();
          doUpdates();
        } else {
          KMessageBox::sorry(this, i18n("Unknown error deleting data matrix."));
        }
      } else if (qi->rtti() == RTTI_OBJ_STATIC_MATRIX) {
        KstSMatrixPtr x = kst_cast<KstSMatrix>(*KST::matrixList.findTag(koi->tag().tag()));
        if (x) {
          x->deleteDependents();
          x = 0L;
          KST::matrixList.lock().writeLock();
          KST::matrixList.removeTag(koi->tag().tag());
          KST::matrixList.lock().unlock();
          doUpdates();
        } else {
          KMessageBox::sorry(this, i18n("Unknown error deleting static matrix."));
        }  
      }
      KstApp::inst()->paintAll(KstPainter::P_PLOT);
      update();
    } else {
      KMessageBox::sorry(this, i18n("Cannot delete objects with dependencies."));
    }
  }
}
コード例 #5
0
void KstDataManagerI::update() {
  if (!isShown()) {
    return;
  }

  QListViewItem *currentItem = DataView->selectedItem();
  QPtrStack<QListViewItem> trash;

  KST::dataObjectList.lock().writeLock();
  KST::vectorList.lock().writeLock();
  KST::matrixList.lock().writeLock();

  // garbage collect first
  for (QListViewItem *i = DataView->firstChild(); i; i = i->nextSibling()) {
    KstObjectItem *oi = static_cast<KstObjectItem*>(i);
    if (i->rtti() == RTTI_OBJ_OBJECT) {
      if (KST::dataObjectList.findTag(oi->tag().tag()) == KST::dataObjectList.end()) {
        trash.push(i);
      }
    } else if (i->rtti() == RTTI_OBJ_DATA_MATRIX || 
               i->rtti() == RTTI_OBJ_MATRIX ||
               i->rtti() == RTTI_OBJ_STATIC_MATRIX) {
      if (KST::matrixList.findTag(oi->tag().tag()) == KST::matrixList.end()) {
        trash.push(i);  
      }
    } else {
      if (KST::vectorList.findTag(oi->tag().tag()) == KST::vectorList.end()) {
        trash.push(i);
      }
    }
  }

  trash.setAutoDelete(true);
  DataView->blockSignals(true);
  trash.clear();
  DataView->blockSignals(false);

  // update the data objects
  for (KstDataObjectList::iterator it = KST::dataObjectList.begin();
                                    it != KST::dataObjectList.end();
                                                               ++it) {
    KstReadLocker dol(*it);
    bool found = false;
    for (QListViewItem *i = DataView->firstChild(); i; i = i->nextSibling()) {
      KstObjectItem *oi = static_cast<KstObjectItem*>(i);
      if (oi->rtti() == RTTI_OBJ_OBJECT && oi->tag().tag() == (*it)->tag().tag()) {
        oi->update();
        found = true;
        break;
      }
    }
    if (!found) {
      KstObjectItem *i = new KstObjectItem(DataView, *it, this);
      connect(i, SIGNAL(updated()), this, SLOT(doUpdates()));
    }
  }

  KST::dataObjectList.lock().unlock();

  // update the data vectors
  KstRVectorList rvl = kstObjectSubList<KstVector,KstRVector>(KST::vectorList);
  for (KstRVectorList::iterator it = rvl.begin(); it != rvl.end(); ++it) {
    KstReadLocker vl(*it);
    bool found = false;
    for (QListViewItem *i = DataView->firstChild(); i; i = i->nextSibling()) {
      KstObjectItem *oi = static_cast<KstObjectItem*>(i);
      if (oi->rtti() == RTTI_OBJ_DATA_VECTOR && oi->tag().tag() == (*it)->tag().tag()) {
        oi->update(true, 1);
        found = true;
        break;
      }
    }
    if (!found) {
      KstObjectItem *i = new KstObjectItem(DataView, *it, this, 1);
      connect(i, SIGNAL(updated()), this, SLOT(doUpdates()));
    }
  }

  // update the static vectors
  KstSVectorList svl = kstObjectSubList<KstVector,KstSVector>(KST::vectorList);
  for (KstSVectorList::iterator it = svl.begin(); it != svl.end(); ++it) {
    KstReadLocker vl(*it);
    bool found = false;
    for (QListViewItem *i = DataView->firstChild(); i; i = i->nextSibling()) {
      KstObjectItem *oi = static_cast<KstObjectItem*>(i);
      if (oi->rtti() == RTTI_OBJ_STATIC_VECTOR && oi->tag().tag() == (*it)->tag().tag()) {
        oi->update(true, 1);
        found = true;
        break;
      }
    }
    if (!found) {
      KstObjectItem *i = new KstObjectItem(DataView, *it, this, 1);
      connect(i, SIGNAL(updated()), this, SLOT(doUpdates()));
    }
  }

  KST::vectorList.lock().unlock();

  // update the data matrices 
  KstRMatrixList rml = kstObjectSubList<KstMatrix,KstRMatrix>(KST::matrixList);
  for (KstRMatrixList::iterator it = rml.begin(); it != rml.end(); ++it) {
    KstReadLocker ml(*it);
    bool found = false;
    for (QListViewItem *i = DataView->firstChild(); i; i = i->nextSibling()) {
      KstObjectItem *oi = static_cast<KstObjectItem*>(i);
      if (oi->rtti() == RTTI_OBJ_DATA_MATRIX && oi->tag().tag() == (*it)->tag().tag()) {
        oi->update(true, 1);
        found = true;
        break;
      }
    }
    if (!found) {
      KstObjectItem *i = new KstObjectItem(DataView, *it, this, 1);
      connect(i, SIGNAL(updated()), this, SLOT(doUpdates()));
    }
  }

  // update the static matrices
  KstSMatrixList sml = kstObjectSubList<KstMatrix,KstSMatrix>(KST::matrixList);
  for (KstSMatrixList::iterator it = sml.begin(); it != sml.end(); ++it) {
    KstReadLocker ml(*it);
    bool found = false;
    for (QListViewItem *i = DataView->firstChild(); i; i = i->nextSibling()) {
      KstObjectItem *oi = static_cast<KstObjectItem*>(i);
      if (oi->rtti() == RTTI_OBJ_STATIC_MATRIX && oi->tag().tag() == (*it)->tag().tag()) {
        oi->update(true, 1);
        found = true;
        break;
      }
    }
    if (!found) {
      KstObjectItem *i = new KstObjectItem(DataView, *it, this, 1);
      connect(i, SIGNAL(updated()), this, SLOT(doUpdates()));
    }
  }

  KST::matrixList.lock().unlock();

  // is this really necessary?  I would think not...
  for (QListViewItem *i = DataView->firstChild(); i; i = i->nextSibling()) {
    if (i == currentItem) {
      DataView->setCurrentItem(i);
      DataView->setSelected(i, true);
      break;
    }
  }

  if (DataView->selectedItem()) {
    static_cast<KstObjectItem*>(DataView->currentItem())->updateButtons();
  } else {
    Edit->setEnabled(false);
    Delete->setEnabled(false);
  }
}
コード例 #6
0
//------------------------------------------------------------------------------
//                           SOLVE BILATERAL
//------------------------------------------------------------------------------
bool PGSImpulseSolver::
solveBilateral
   (const Array_<MultiplierIndex>&  participating, // p<=m of these
    const Matrix&                   A,     // m X m, symmetric
    const Vector&                   D,     // m, diag>=0 added to A
    const Vector&                   rhs,   // m, RHS
    Vector&                         pi     // m, unknown result
    ) const
{
    SimTK_DEBUG("--------------------------------\n");
    SimTK_DEBUG(  "PGS BILATERAL SOLVER:\n");
    ++m_nBilateralSolves;

    const int m=A.nrow();
    const int p = (int)participating.size();

    assert(A.ncol()==m);
    assert(D.size()==0 || D.size()==m);
    assert(rhs.size()==m);
    assert(p<=m);

    pi.resize(m);
    pi.setToZero(); // That takes care of all non-participators.

    if (p == 0) {
        SimTK_DEBUG("  no bilateral participators. Nothing to do.\n");
        SimTK_DEBUG("--------------------------------\n");
        return true;
    }


    // Track total error for all included equations, and the error for just
    // those equations that are being enforced.
    bool converged = false;
    Real normRMSenf = Infinity, sor = m_SOR;
    Real prevNormRMSenf = NaN;
    int its = 1;
    Array_<Real> rowSums; // handy temp
    for (; its <= m_maxIters; ++its) {
        ++m_nBilateralIters;
        Real sum2enf = 0; // track solution errors
        prevNormRMSenf = normRMSenf;

        // All the participating constraints are unconditionally active.
        Array_<MultiplierIndex> mults(1);
        for (int k=0; k < p; ++k) {
            mults[0] = participating[k];
            doRowSums(participating,mults,A,D,pi,rowSums);
            const Real localEr2=doUpdates(mults,A,D,rhs,sor,rowSums,pi);
            sum2enf += localEr2;
        }

        normRMSenf = std::sqrt(sum2enf/p);
        const Real rate = normRMSenf/prevNormRMSenf;

        if (rate > 1) {
            SimTK_DEBUG3("GOT WORSE@%d: sor=%g rate=%g\n", its, sor, rate);
            if (sor > .1)
                sor = std::max(.8*sor, .1);
        }

        #ifndef NDEBUG
        printf("iter %d: EST rmsEnf=%g rate=%g\n", its,
                     normRMSenf, normRMSenf/prevNormRMSenf);
        #endif

        if (normRMSenf < m_convergenceTol) //TODO: add failure-to-improve check
        {
            SimTK_DEBUG2("BILATERAL PGS converged to %g in %d iters\n",
                         normRMSenf, its);
            converged = true;
            break;
        }
        #ifndef NDEBUG
        cout << "pi=" << pi << " err=" << normRMSenf << " rate=" << rate << endl;
        #endif
    }

    if (!converged) {
        SimTK_DEBUG2("BILATERAL PGS CONVERGENCE FAILURE: %d iters -> norm=%g\n",
              its, normRMSenf);
        ++m_nBilateralFail;
    }

    #ifndef NDEBUG
    cout << "A=" << A;
    cout << "D=" << D << endl;
    cout << "rhs=" << rhs << endl;
    cout << "active=" << participating << endl;
    cout << "-> pi=" << pi << endl;
    if (D.size()) cout << "resid=" << A*pi+D.elementwiseMultiply(pi)-rhs << endl;
    else cout << "resid=" << A*pi-rhs << endl;
    #endif
    SimTK_DEBUG("--------------------------------\n");
    return converged;

}
コード例 #7
0
//------------------------------------------------------------------------------
//                                 SOLVE
//------------------------------------------------------------------------------
bool PGSImpulseSolver::
solve(int                                 phase,
      const Array_<MultiplierIndex>&      participating, // p<=m of these
      const Matrix&                       A,     // m X m, symmetric
      const Vector&                       D,     // m, diag >= 0 added to A
      const Array_<MultiplierIndex>&      expanding,
      Vector&                             piExpand,   // m
      Vector&                             verrStart, // m, in/out
      Vector&                             verrApplied, // m
      Vector&                             pi,         // m, piUnknown
      Array_<UncondRT>&                   unconditional,
      Array_<UniContactRT>&               uniContact, // with friction
      Array_<UniSpeedRT>&                 uniSpeed,
      Array_<BoundedRT>&                  bounded,
      Array_<ConstraintLtdFrictionRT>&    consLtdFriction,
      Array_<StateLtdFrictionRT>&         stateLtdFriction
      ) const
{
    SimTK_DEBUG("\n-----------------\n");
    SimTK_DEBUG(  "START PGS SOLVER:\n");
    ++m_nSolves[phase];

#ifndef NDEBUG
   {FactorQTZ fac(A);
    cout << "A=" << A; cout << "D=" << D;
    cout << "verrStart=" << verrStart << endl;
    cout << "verrApplied=" << verrApplied << endl;
    cout << "expanding mx=" << expanding << endl;
    cout << "piExpand=" << piExpand << endl;
    Vector verrDbg, x;
    verrDbg = verrStart;
    if (verrApplied.size()) verrDbg += verrApplied;
    fac.solve(verrDbg, x);
    cout << "x=" << x << endl;
    cout << "resid=" << A*x-verrDbg << endl;}
#endif

    const int m=A.nrow();
    assert(A.ncol()==m); assert(D.size()==m);
    assert(verrStart.size()==m);
    assert(verrApplied.size()==0 || verrApplied.size()==m);
    assert(piExpand.size()==m);

    const int p = (int)participating.size();
    const int nx = (int)expanding.size();
    assert(p<=m); assert(nx<=m);

    pi.resize(m);
    pi.setToZero(); // Use this for piUnknown

    // If there are applied forces, add them to the rhs.
    if (verrApplied.size())
        verrStart += verrApplied;

    // Move expansion impulse to RHS. We will always apply the full expansion
    // impulse in one interval in this solver.
    if (nx)
        for (MultiplierIndex mx(0); mx < m; ++mx) {
            verrStart[mx] -= multRowTimesSparseCol(A,mx,expanding,piExpand)
                             + D[mx]*piExpand[mx];
        }

    // Now rhs = verrStart + verrApplied - [A+D]*piExpand.
    #ifndef NDEBUG
    printf("PGS::solve(): using verr="); cout << verrStart << endl;
    #endif


    // Partitions of selected subset.
    const int mUncond   = (int)unconditional.size();
    const int mUniSpeed = (int)uniSpeed.size();
    const int mBounded  = (int)bounded.size();
    // State limited friction has no dependence on unknown multipliers.
    const int mStateLtd = (int)stateLtdFriction.size();
    // Must do unilateral friction and constraint-limited friction last because
    // they depend on normal multipliers.
    const int mUniCont  = (int)uniContact.size();
    const int mConsLtd  = (int)consLtdFriction.size();

    // If debugging, check for consistent constraint equation count.
    #ifndef NDEBUG
    {int mCount = mUniSpeed + mBounded; // 1 each
    for (int k=0; k<mUncond; ++k)
        mCount += unconditional[k].m_mults.size();
    for (int k=0; k<mUniCont; ++k) {
        if (uniContact[k].m_type==Observing)
            continue; // neither normal nor friction participate
        if (uniContact[k].m_type==Participating)
            ++mCount; // normal participates
        if (uniContact[k].hasFriction())
            mCount += 2; // friction participates even if normal is Known
    }
    for (int k=0; k<mStateLtd; ++k)
        mCount += stateLtdFriction[k].m_Fk.size();
    for (int k=0; k<mConsLtd; ++k)
        mCount += consLtdFriction[k].m_Fk.size();
    assert(mCount == p);}
    #endif

    if (p == 0) {
        SimTK_DEBUG1("PGS %d: nothing to do; converged in 0 iters.\n", phase);
        // Returning pi=0; can still have piExpand!=0 so verr is updated.
        return true;
    }

    // Track total error for all included equations, and the error for just
    // those equations that are being enforced.
    bool converged = false;
    Real normRMSall = Infinity, normRMSenf = Infinity, sor = m_SOR;
    Real prevNormRMSenf = NaN;
    int its = 1;
    Array_<Real> rowSums; // handy temp
    for (; its <= m_maxIters; ++its) {
        ++m_nIters[phase];
        Real sum2all = 0, sum2enf = 0; // track solution errors
        prevNormRMSenf = normRMSenf;

        // UNCONDITIONAL: these are always on.
        for (int k=0; k < mUncond; ++k) {
            const UncondRT& rt = unconditional[k];
            doRowSums(participating,rt.m_mults,A,D,pi,rowSums);
            const Real er2=doUpdates(rt.m_mults,A,D,verrStart,sor,rowSums,pi);
            sum2all += er2; sum2enf += er2;
        }

        // UNILATERAL CONTACT NORMALS. Do all of these before any friction.
        for (int k=0; k < mUniCont; ++k) {
            UniContactRT& rt = uniContact[k];
            if (rt.m_type != Participating)
                continue;
            const MultiplierIndex Nk = rt.m_Nk;
            const Real rowSum=doRowSum(participating,Nk,A,D,pi);
            const Real er2=doUpdate(Nk,A,D,verrStart,sor,rowSum,pi);
            sum2all += er2;
            rt.m_contactCond = boundUnilateral(rt.m_sign, pi[Nk]);
            if (rt.m_contactCond == UniActive)
                sum2enf += er2;
        }

        // UNILATERAL CONTACT FRICTION. These are limited by the normal
        // multiplier or by a known normal force during Poisson expansion.
        for (int k=0; k < mUniCont; ++k) {
            UniContactRT& rt = uniContact[k];
            if (rt.m_type == Observing || !rt.hasFriction())
                continue;
            const MultiplierIndex Nk = rt.m_Nk;
            const Array_<MultiplierIndex>& Fk = rt.m_Fk;
            doRowSums(participating,Fk,A,D,pi,rowSums);
            const Real er2=doUpdates(Fk,A,D,verrStart,sor,rowSums,pi);
            sum2all += er2;
            Real N = std::abs(pi[Nk] + piExpand[Nk]);
            rt.m_frictionCond=boundVector(rt.m_effMu*N, Fk, pi);
            if (rt.m_frictionCond==Rolling)
                sum2enf += er2;
        }

        // BOUNDED: conditional scalar constraints with constant bounds
        // on resulting pi.
        for (int k=0; k < mBounded; ++k) {
            BoundedRT& rt = bounded[k];
            const MultiplierIndex rx = rt.m_ix;
            const Real rowSum=doRowSum(participating,rx,A,D,pi);
            const Real er2=doUpdate(rx,A,D,verrStart,sor,rowSum,pi);
            sum2all += er2;
            rt.m_boundedCond=boundScalar(rt.m_lb, pi[rx], rt.m_ub);
            if (rt.m_boundedCond == Engaged)
                sum2enf += er2;
        }

        // STATE LIMITED FRICTION: a set of constraint equations forming a
        // vector whose maximum length is limited.
        for (int k=0; k < mStateLtd; ++k) {
            StateLtdFrictionRT& rt = stateLtdFriction[k];
            const Array_<MultiplierIndex>& Fk = rt.m_Fk;
            doRowSums(participating,Fk,A,D,pi,rowSums);
            const Real localEr2=doUpdates(Fk,A,D,verrStart,sor,rowSums,pi);
            sum2all += localEr2;
            rt.m_frictionCond=boundVector(rt.m_effMu*rt.m_knownN, Fk, pi);
            if (rt.m_frictionCond==Rolling)
                sum2enf += localEr2;
        }

        // CONSTRAINT LIMITED FRICTION: a set of constraint equations forming
        // a vector whose maximum length is limited by the norm of other
        // multipliers pi.
        for (int k=0; k < mConsLtd; ++k) {
            ConstraintLtdFrictionRT& rt = consLtdFriction[k];
            const Array_<int>& Fk = rt.m_Fk; // friction components
            const Array_<int>& Nk = rt.m_Nk; // normal components
            doRowSums(participating,Fk,A,D,pi,rowSums);
            const Real localEr2=doUpdates(Fk,A,D,verrStart,sor,rowSums,pi);
            sum2all += localEr2;
            rt.m_frictionCond=boundFriction(rt.m_effMu,Nk,Fk,pi);
            if (rt.m_frictionCond==Rolling)
                sum2enf += localEr2;
        }
        normRMSall = std::sqrt(sum2all/p);
        normRMSenf = std::sqrt(sum2enf/p);

        const Real rate = normRMSenf/prevNormRMSenf;

        if (rate > 1) {
            SimTK_DEBUG3("GOT WORSE@%d: sor=%g rate=%g\n", its, sor, rate);
            if (sor > .1)
                sor = std::max(.8*sor, .1);
        }

        #ifndef NDEBUG
        printf("%d/%d: EST rmsAll=%g rmsEnf=%g rate=%g\n", phase, its,
                     normRMSall, normRMSenf,
                     normRMSenf/prevNormRMSenf);
        #endif
        //#ifdef NDEBUG // i.e., NOT debugging (TODO)
        //if (its > 90)
        //    printf("%d/%d: EST rmsAll=%g rmsEnf=%g rate=%g\n", phase, its,
        //             normRMSall, normRMSenf,
        //             normRMSenf/prevNormRMSenf);
        //#endif
        if (normRMSenf < m_convergenceTol) //TODO: add failure-to-improve check
        {
            SimTK_DEBUG3("PGS %d converged to %g in %d iters\n",
                         phase, normRMSenf, its);
            converged = true;
            break;
        }
        #ifndef NDEBUG
        cout << "pi=" << pi << " err=" << normRMSenf << " rate=" << rate << endl;
        #endif
    }

    if (!converged) {
        SimTK_DEBUG3("PGS %d CONVERGENCE FAILURE: %d iters -> norm=%g\n",
               phase, its, normRMSenf);
        ++m_nFail[phase];
    }

    verrStart -= A*pi;
    verrStart -= D.elementwiseMultiply(pi);
    #ifndef NDEBUG
    cout << "FINAL@" << its << " pi=" << pi << " verr=" << verrStart
         <<  " resid=" << normRMSenf << endl;
    #endif
    return converged;
}
コード例 #8
0
void KstDataManagerI::update() {
if (!isShown()) {
  return;
}

QPtrStack<QListViewItem> trash;

  // Garbage collect first
  for (QListViewItem *i = DataView->firstChild(); i; i = i->nextSibling()) {
    KstObjectItem *oi = static_cast<KstObjectItem*>(i);
    if (i->rtti() == RTTI_OBJ_OBJECT) {
      if (KST::dataObjectList.findTag(oi->tagName()) == KST::dataObjectList.end()) {
        trash.push(i);
      }
    } else {
      if (KST::vectorList.findTag(oi->tagName()) == KST::vectorList.end()) {
        trash.push(i);
      }
    }
  }

  trash.setAutoDelete(true);
  trash.clear();

  for (KstDataObjectList::iterator it = KST::dataObjectList.begin();
                                    it != KST::dataObjectList.end();
                                                               ++it) {
    bool found = false;
    for (QListViewItem *i = DataView->firstChild(); i; i = i->nextSibling()) {
      KstObjectItem *oi = static_cast<KstObjectItem*>(i);
      if (oi->rtti() == RTTI_OBJ_OBJECT && oi->tagName() == (*it)->tagName()) {
        oi->update();
        found = true;
        break;
      }
    }
    if (!found) {
        KstObjectItem *i = new KstObjectItem(DataView, *it, this);
        connect(i, SIGNAL(updated()), this, SLOT(doUpdates()));
    }
  }

  KstRVectorList rvl = kstObjectSubList<KstVector,KstRVector>(KST::vectorList);
  for (KstRVectorList::iterator it = rvl.begin(); it != rvl.end(); ++it) {
    bool found = false;
    for (QListViewItem *i = DataView->firstChild(); i; i = i->nextSibling()) {
      KstObjectItem *oi = static_cast<KstObjectItem*>(i);
      if (oi->rtti() == RTTI_OBJ_DATA_VECTOR && oi->tagName() == (*it)->tagName()) {
        oi->update();
        found = true;
        break;
      }
    }
    if (!found) {
        KstObjectItem *i = new KstObjectItem(DataView, *it, this);
        connect(i, SIGNAL(updated()), this, SLOT(doUpdates()));
    }
  }

  if (DataView->selectedItem()) {
    static_cast<KstObjectItem*>(DataView->currentItem())->updateButtons();
  } else {
    Edit->setEnabled(false);
    Delete->setEnabled(false);
  }
}