bool
avtLCSIC::CheckForTermination(avtIVPStep& step, avtIVPField *field)
{
    bool shouldTerminate = false;

    // Check for termination.
    if( doTime )
    {
        if( (direction == DIRECTION_FORWARD  && step.GetT1() >= maxTime) ||
            (direction == DIRECTION_BACKWARD && step.GetT1() <= maxTime) )
            shouldTerminate = true;
    }
    if( doDistance )
    {
        double Lstep = step.GetLength();
        double Ltogo = std::abs(maxDistance) - distance;

        if( Lstep > Ltogo )
        {
            step.ClampToLength( Ltogo );
            shouldTerminate = true;
        }
        else if (field->VelocityIsInstantaneous() &&
                 (Lstep / std::abs(step.t1 - step.t0) < 1e-8))
        {
            {
                // Above condition ensures that the curve makes progress 
                // w.r.t. distance to avoid infinite integration into a 
                // critical point.
                //
                // FIXME: I don't like the above hardcoded threshold -
                // this should probably be something like 
                // Lstep / Lmax < 1e-6 ?
                //
                // FIXME: Also, this should only be tested in the stationary 
                // case, since in a time-varying scenario, the critical point
                // might move.
                shouldTerminate = true;
            }
        }
    }

    if( !shouldTerminate && numSteps >= maxSteps )
    {
        terminatedBecauseOfMaxSteps = true;
        shouldTerminate = true;
    }

    // Update other termination criteria.
    numSteps += 1;

    return shouldTerminate;
}
// ****************************************************************************
//  Method: avtLCSIC::AnalyzeStep
//
//  Purpose:
//      Analyzes the current step.
//
//  Programmer: Allen Sanderson
//  Creation:   August 14, 2013
//
//  Modifications:
//
// ****************************************************************************
void avtLCSIC::AnalyzeStep( avtIVPStep &step,
                            avtIVPField *field)
{
    if (CheckForTermination(step, field))
        status.SetTerminationMet();

    // These must be called after CheckForTermination, because 
    // CheckForTermination will modify the step if it goes beyond the
    // termination criteria.  (Example: streamlines will split a step if it
    // is terminating by distance.)
    p_end = step.GetP1();

    time = step.GetT1();
    arcLength += step.GetLength();
    distance  += step.GetLength();

    summation0 += (p_start - p_end).length();
    summation1  = (p_start - p_end).length();
}
    virtual void AnalyzeStep( avtIVPStep &step, avtIVPField *field)
    {
        avtVector p = step.GetP1();
        dist += sqrt((p.x-last_loc[0])*(p.x-last_loc[0])+
                     (p.y-last_loc[1])*(p.y-last_loc[1]));
        last_loc[0] = p.x;
        last_loc[1] = p.y;
        if (numSteps++ >= 1000)
            status = STATUS_FINISHED;

    }
void
avtStateRecorderIntegralCurve::AnalyzeStep( avtIVPStep& step, 
                                            avtIVPField* field )
{
    if (history.size() == 0)
    {
        // Record the first position of the step.
        RecordStep( field, step, step.GetT0() );
    }

    if (CheckForTermination(step, field))
        status.SetTerminationMet();

    // These must be called after CheckForTermination, because 
    // CheckForTermination will modify the step if it goes beyond the
    // termination criteria.  (Example: streamlines will split a step if it
    // is terminating by distance.)

    time = step.GetT1();
    distance += step.GetLength();

    RecordStep( field, step, step.GetT1() );
}
void avtStateRecorderIntegralCurve::RecordStep(const avtIVPField* field,
                                               const avtIVPStep& step,
                                               double t)
{
    avtVector p = step.GetP(t);

    /*
    //If the step is within tolerance of the previous step, just overwrite the last step
    //with this step.
    size_t nSamp = GetNumberOfSamples();
    if (nSamp > 1)
    {
        Sample prevSamp = GetSample(nSamp-1);
        if ((p-prevSamp.position).length2() < epsilon)
        {
            std::vector<double>::iterator m = history.begin() + (nSamp-1)*GetSampleStride();
            history.erase(m, history.end());
        }
    }
    */

    if( historyMask & SAMPLE_TIME )
        history.push_back( t );

    if( historyMask & SAMPLE_POSITION )
    {
        history.push_back( p.x );
        history.push_back( p.y );
        history.push_back( p.z );
    }
        
    if( historyMask & SAMPLE_VELOCITY )
    {
        avtVector v = step.GetV( t );
        history.push_back( v.x );
        history.push_back( v.y );
        history.push_back( v.z );
    }
        
    if( historyMask & SAMPLE_VORTICITY )
        history.push_back( field->ComputeVorticity( t, p ) );
        
    if( historyMask & SAMPLE_ARCLENGTH )
        history.push_back( distance );
        
    if( historyMask & SAMPLE_VARIABLE )
        history.push_back( field->ComputeScalarVariable( variableIndex, t, p ) );

    if( historyMask & SAMPLE_SECONDARY0 )
        history.push_back( field->ComputeScalarVariable( 0, t, p ) );
        
    if( historyMask & SAMPLE_SECONDARY1 )
        history.push_back( field->ComputeScalarVariable( 1, t, p ) );

    if( historyMask & SAMPLE_SECONDARY2 )
        history.push_back( field->ComputeScalarVariable( 2, t, p ) );

    if( historyMask & SAMPLE_SECONDARY3 )
        history.push_back( field->ComputeScalarVariable( 3, t, p ) );
        
    if( historyMask & SAMPLE_SECONDARY4 )
        history.push_back( field->ComputeScalarVariable( 4, t, p ) );

    if( historyMask & SAMPLE_SECONDARY5 )
        history.push_back( field->ComputeScalarVariable( 5, t, p ) );
}