Program: 70676
Project: 70676
Buggy source:
/** 
 * Updates the knot points in this wrappable segment. This is done by iterating until the first order physics resulting from the attractive forces between adjacent knots and repulsive forces from contacting wrappables results in a stable configuration.
 */
protected void updateWrapStrand(int maxIter){
  int icnt=0;
  boolean converged=false;
  double dscale=myDscale;
  updateContactingKnotPositions();
  int[] contactCnts=getContactCnts();
  int[] newContactCnts=new int[myWrappables.size()];
  updateForces();
  double prevEnergy=computeEnergy();
  double prevForceSqr=computeForceSqr();
  double prevForce=forceNorm();
  boolean wroteR=false;
  boolean wroteRx=false;
  do {
    double prevLength=myLength;
    if (inContact()) {
    }
    updateStiffness(0,dscale);
    boolean clipped=(factorAndSolve() < 1.0);
    double r0=forceDotDisp();
    double denom=forceNorm() * computeDvecLength();
    double cos=r0 / denom;
    double mincos=0.1;
    if (cos < mincos) {
      double lam=(denom * (mincos - cos) / computeForceSqr());
      modifyDvec(lam);
      r0=forceDotDisp();
      if (debugLevel > 0) {
        System.out.println("String_Node_Str" + cos + "String_Node_Str"+ r0 / (forceNorm() * computeDvecLength()));
      }
    }
    double computedFSqr=computeForceSqrDeriv();
    savePosToPrev();
    LineSearchFunc func=new EnergyFunc();
    double f0, df0;
    if (func instanceof ForceSqrFunc) {
      f0=computeForceSqr();
      df0=computeForceSqrDeriv();
    }
 else {
      f0=computeEnergy();
      df0=-forceDotDisp();
    }
    double h=1e-8;
    prevEnergy=computeEnergy();
    advancePosByDvec(h);
    updateContacts(null,false);
    updateForces();
    double forceSqr=computeForceSqr();
    double energy=computeEnergy();
    double ederiv=(energy - prevEnergy) / h;
    double fsqrDeriv=(forceSqr - prevForceSqr) / h;
    double s=1.0;
    advancePosByDvec(s);
    contactDebug=(icnt == 0);
    boolean contactChanged=updateContacts(newContactCnts,true);
    contactDebug=false;
    boolean contactBroken=checkForBrokenContact(contactCnts,newContactCnts);
    updateForces();
    energy=computeEnergy();
    forceSqr=computeForceSqr();
    if (debugLevel > 0) {
      System.out.println("String_Node_Str" + prevEnergy + "String_Node_Str"+ energy+ "String_Node_Str"+ ederiv);
    }
    double r1=forceDotDisp();
    DoubleHolder deriv=new DoubleHolder();
    double f1=func.eval(deriv,s);
    double df1=deriv.value;
    if (contactBroken) {
      saveDvecToVtmp();
      updateStiffness(0,dscale);
      factorAndSolve();
      double scale=1.0;
      for (int k=0; k < myNumKnots; k++) {
        WrapKnot knot=myKnots[k];
        int widx=knot.myPrevWrappableIdx;
        if (widx != -1 && newContactCnts[widx] != 0) {
          if (knot.myDvec.dot(knot.myVtmp) < 0) {
            double dist=knot.myDist;
            double prev=knot.myPrevDist;
            if (dist != Wrappable.OUTSIDE && dist > 0 && prev < 0) {
              double r=dist / (dist - prev);
              if (r < scale) {
                scale=r;
              }
            }
          }
        }
      }
      if (scale < 1.0) {
        if (myContactRescaling) {
          if (debugLevel > 0) {
            System.out.println("String_Node_Str" + (1 - scale));
          }
          advancePosByVtmp(1 - scale);
          s=1 - scale;
          updateContacts(contactCnts,true);
          updateForces();
          f1=computeEnergy();
          df1=-forceDotDisp();
        }
      }
    }
    double ltol=myLength * myLengthConvTol;
    if (!contactChanged) {
      double maxLatDisp=maxLateralDisplacement();
      if (debugLevel > 0) {
      }
      if (maxLatDisp / myLength < 1e-4 && Math.abs(prevLength - myLength) < ltol) {
        converged=true;
      }
    }
    if (!converged && myLineSearchP) {
      ResidualFunc rfunc=new ResidualFunc();
      double maxs=(contactChanged ? s : 3.0);
      if (df0 >= 0) {
        System.out.println("String_Node_Str" + df0);
        printStuckDebugInfo(maxs);
      }
 else {
        double snew=lineSearch(f0,df0,f1,df1,func,0.1,2.0,s,maxs);
        if (snew != s) {
          if (debugLevel > 0) {
            System.out.printf("String_Node_Str",snew);
          }
          rfunc.eval(snew);
          updateContacts(null,true);
          energy=computeEnergy();
          forceSqr=computeForceSqr();
        }
 else {
          rfunc.eval(s);
          updateContacts(null,true);
        }
      }
      if (false) {
      }
    }
    double newEnergy=computeEnergy();
    if (debugLevel > 0) {
      System.out.printf("String_Node_Str",(newEnergy - prevEnergy));
    }
    prevEnergy=energy;
    prevForceSqr=forceSqr;
    prevForce=forceNorm();
  }
 while (++icnt < maxIter && !converged);
  saveContactingKnotPositions();
  totalIterations+=icnt;
  totalCalls++;
  if (converged) {
    if (debugLevel > 0) {
      System.out.println("String_Node_Str" + icnt);
    }
  }
 else {
    if (debugLevel > 0) {
      System.out.println("String_Node_Str");
    }
    totalFails++;
  }
  if ((totalCalls % 100) == 0) {
  }
  myDscale=dscale;
}

Fixed version (ground truth):
/** 
 * Updates the knot points in this wrappable segment. This is done by iterating until the first order physics resulting from the attractive forces between adjacent knots and repulsive forces from contacting wrappables results in a stable configuration.
 */
protected int updateWrapStrand(int maxIter){
  int icnt=0;
  boolean converged=false;
  double dscale=myDscale;
  updateContactingKnotPositions();
  int[] contactCnts=getContactCnts();
  int[] newContactCnts=new int[myWrappables.size()];
  updateForces();
  double prevEnergy=computeEnergy();
  double prevForceSqr=computeForceSqr();
  double prevForce=forceNorm();
  boolean wroteR=false;
  boolean wroteRx=false;
  do {
    double prevLength=myLength;
    if (inContact()) {
    }
    updateStiffness(0,dscale);
    boolean clipped=(factorAndSolve() < 1.0);
    double r0=forceDotDisp();
    double denom=forceNorm() * computeDvecLength();
    double cos=r0 / denom;
    double mincos=0.1;
    if (cos < mincos) {
      double lam=(denom * (mincos - cos) / computeForceSqr());
      modifyDvec(lam);
      r0=forceDotDisp();
      if (debugLevel > 0) {
        System.out.println("String_Node_Str" + cos + "String_Node_Str"+ r0 / (forceNorm() * computeDvecLength()));
      }
    }
    double computedFSqr=computeForceSqrDeriv();
    savePosToPrev();
    LineSearchFunc func=new EnergyFunc();
    double f0, df0;
    if (func instanceof ForceSqrFunc) {
      f0=computeForceSqr();
      df0=computeForceSqrDeriv();
    }
 else {
      f0=computeEnergy();
      df0=-forceDotDisp();
    }
    double h=1e-8;
    prevEnergy=computeEnergy();
    advancePosByDvec(h);
    updateContacts(null,false);
    updateForces();
    double forceSqr=computeForceSqr();
    double energy=computeEnergy();
    double ederiv=(energy - prevEnergy) / h;
    double fsqrDeriv=(forceSqr - prevForceSqr) / h;
    double s=1.0;
    advancePosByDvec(s);
    contactDebug=(icnt == 0);
    boolean contactChanged=updateContacts(newContactCnts,true);
    contactDebug=false;
    boolean contactBroken=checkForBrokenContact(contactCnts,newContactCnts);
    updateForces();
    energy=computeEnergy();
    forceSqr=computeForceSqr();
    if (debugLevel > 0) {
      System.out.println("String_Node_Str" + prevEnergy + "String_Node_Str"+ energy+ "String_Node_Str"+ ederiv);
    }
    double r1=forceDotDisp();
    DoubleHolder deriv=new DoubleHolder();
    double f1=func.eval(deriv,s);
    double df1=deriv.value;
    if (contactBroken) {
      saveDvecToVtmp();
      updateStiffness(0,dscale);
      factorAndSolve();
      double scale=1.0;
      for (int k=0; k < myNumKnots; k++) {
        WrapKnot knot=myKnots[k];
        int widx=knot.myPrevWrappableIdx;
        if (widx != -1 && newContactCnts[widx] != 0) {
          if (knot.myDvec.dot(knot.myVtmp) < 0) {
            if (debugLevel > 0)             System.out.println("String_Node_Str");
            double dist=knot.myDist;
            double prev=knot.myPrevDist;
            if (dist != Wrappable.OUTSIDE && dist > 0 && prev < 0) {
              double r=dist / (dist - prev);
              if (r < scale) {
                scale=r;
              }
            }
          }
        }
      }
      if (scale < 1.0) {
        if (myContactRescaling) {
          if (debugLevel > 0) {
            System.out.println("String_Node_Str" + (1 - scale));
          }
          advancePosByVtmp(1 - scale);
          s=1 - scale;
          updateContacts(contactCnts,true);
          updateForces();
          f1=computeEnergy();
          df1=-forceDotDisp();
        }
      }
 else {
        restoreDvecFromVtmp();
      }
    }
    double ltol=myLength * myLengthConvTol;
    if (!contactChanged) {
      double maxLatDisp=maxLateralDisplacement();
      if (debugLevel > 0) {
      }
      if (maxLatDisp / myLength < 1e-4 && Math.abs(prevLength - myLength) < ltol) {
        converged=true;
      }
    }
    if (!converged && myLineSearchP) {
      ResidualFunc rfunc=new ResidualFunc();
      double maxs=(contactChanged ? s : 3.0);
      if (df0 >= 0) {
        System.out.println("String_Node_Str" + df0);
        printStuckDebugInfo(maxs);
      }
 else {
        double snew=lineSearch(f0,df0,f1,df1,func,0.1,2.0,s,maxs);
        if (snew != s) {
          if (debugLevel > 0) {
            System.out.printf("String_Node_Str",snew);
          }
          rfunc.eval(snew);
          updateContacts(null,true);
          energy=computeEnergy();
          forceSqr=computeForceSqr();
        }
 else {
          rfunc.eval(s);
          updateContacts(null,true);
        }
      }
      if (false) {
      }
    }
    double newEnergy=computeEnergy();
    if (debugLevel > 0) {
      System.out.printf("String_Node_Str",(newEnergy - prevEnergy));
    }
    prevEnergy=energy;
    prevForceSqr=forceSqr;
    prevForce=forceNorm();
  }
 while (++icnt < maxIter && !converged);
  saveContactingKnotPositions();
  totalIterations+=icnt;
  totalCalls++;
  if (converged) {
    if (debugLevel > 0) {
      System.out.println("String_Node_Str" + icnt);
    }
  }
 else {
    if (debugLevel > 0) {
      System.out.println("String_Node_Str");
    }
    totalFails++;
  }
  if ((totalCalls % 100) == 0) {
  }
  myDscale=dscale;
  return icnt;
}