avtVector
avtIVPNIMRODIntegrator::getBfield(const avtIVPField* field, avtVector y)
{
  // FIX THIS CODE - It would be preferable to use a dynamic cast but
  // because the field is passd down as a const it can not be used.
  avtIVPNIMRODField *m3dField = (avtIVPNIMRODField *)(field);

  double pt[3];

  pt[0] = y[0];
  pt[1] = y[1];
  pt[2] = y[2];

  double xieta[2];
  int    element;

  /* Find the element containing the point; get local coords xi,eta */
  if ((element = m3dField->get_tri_coords2D(pt, xieta)) < 0) 
  {
    return avtVector(0,0,0);
  }
  else 
  {
    float B[3];

    m3dField->interpBcomps(B, pt, element, xieta);
    
    return avtVector(B);
  }
}
Beispiel #2
0
avtIVPSolver::avtIVPSolver() : convertToCartesian(false),
                               convertToCylindrical(false),
                               order(1),
                               yCur(avtVector()), vCur(avtVector()),
                               h(1e-5), h_max(1e-5), tol(1e-8), t(0.0),
                               periodic_boundary_x(0.),
                               periodic_boundary_y(0.),
                               periodic_boundary_z(0.),
                               period(0), baseTime(0), maxTime(1),
                               direction(DIRECTION_BACKWARD)
{
}
bool SetupRational(avtPoincareIC *rational)
{
  if (2 <= RATIONAL_DEBUG)
    {
      std::vector<avtVector> puncturePoints;
      FieldlineLib fieldlib;
      fieldlib.getPunctures(rational->points, avtVector(0, 1, 0), puncturePoints);
      std::cerr << "LINE " << __LINE__ << "  " 
                << "Found an unsearched rational, ID: " 
                << rational->id << ", " << puncturePoints[0] << std::endl;
    }
  // Update rational's properties
  // The analysis method is Rational_Search for most of the process.
  
  // The Original_Rational is kept around mainly to help with
  // organization.
  rational->properties.analysisMethod = FieldlineProperties::RATIONAL_SEARCH;
  rational->properties.searchState  = FieldlineProperties::ORIGINAL_RATIONAL;
  
  // The Original_Rational has a list of each of the
  // seeds. These get swapped out with better curves over the
  // course of the minimization and this list is used to draw
  // the final curves
  rational->properties.children = new std::vector< avtPoincareIC* >();

  return true;
}
Beispiel #4
0
avtVector
avtMatrix::operator*(const avtVector &r) const
{
    double x,y,z,w;

    x = m[0][0] * r.x +
        m[0][1] * r.y +
        m[0][2] * r.z +
        m[0][3];
    y = m[1][0] * r.x +
        m[1][1] * r.y +
        m[1][2] * r.z +
        m[1][3];
    z = m[2][0] * r.x +
        m[2][1] * r.y +
        m[2][2] * r.z +
        m[2][3];
    w = m[3][0] * r.x +
        m[3][1] * r.y +
        m[3][2] * r.z +
        m[3][3];

    double iw = 1. / w;
    x *= iw;
    y *= iw;
    z *= iw;

    return avtVector(x,y,z);
}
double FindMinimizationDistance( avtPoincareIC* ic)
{
  if (4 <= RATIONAL_DEBUG)
    cerr << "Finding Minimization Distance...\n";

  std::vector<avtVector> puncturePoints;
  FieldlineLib fieldlib;
  fieldlib.getPunctures(ic->points, avtVector(0, 1, 0), puncturePoints);

  if (puncturePoints.size() < 2*ic->properties.toroidalWinding)
    {
      cerr << "Not enough puncture points to find correct Rational Surface Minimization distance. Failing.\n";
      cerr << "need "<<2*ic->properties.toroidalWinding<<" puncture pts at least.\n";
      return -1;
    }

  int ix = FindMinimizationIndex(ic);

  avtVector puncture1 = puncturePoints[ix];
  avtVector puncture2 = puncturePoints[ix + ic->properties.toroidalWinding];

  double dist = (puncture1 - puncture2).length();

  return dist;
}
void
VisitPointTool::UpdateTool()
{
    hotPoints[0].pt = avtVector((double*)Interface.GetPoint());

    if (proxy.GetFullFrameMode())
    {
        // 
        // Translate the hotPoints so they appear in the correct position
        // in full-frame mode. 
        // 
        double scale;
        int type;
        proxy.GetScaleFactorAndType(scale, type);
        if (type == 0 ) // x_axis
            hotPoints[0].pt.x *= scale;
        else            // x_axis
            hotPoints[0].pt.y *= scale;
    }
    double axisscale[3];
    if (proxy.Get3DAxisScalingFactors(axisscale))
    {
        hotPoints[0].pt.x *= axisscale[0];
        hotPoints[0].pt.y *= axisscale[1];
        hotPoints[0].pt.z *= axisscale[2];
    }

    UpdateSphere();
    UpdateText();
}
VisitPointTool::VisitPointTool(VisWindowToolProxy &p) : VisitInteractiveTool(p),
    Interface(p)
{
    window3D = false;
    addedBbox = false;
    addedGuide = false;
    axisTranslate = none;

    HotPoint h;
    h.radius = 1./60.; // See what a good value is.
    h.tool = this;

    //
    // Add the hotpoint
    //
    h.pt = avtVector(0., 0.,  0.);
    h.callback = TranslateCallback;
    hotPoints.push_back(h);

    guideActor = NULL;
    guideMapper = NULL;
    guideData = NULL;

    sphereActor = NULL;
    sphereMapper = NULL;
    sphereData = NULL;

    CreateTextActors();
    CreateGuide();
    CreateSphere();
}
//*******************
// To start the minimization, we need to define three points
// If the middle point ('b) is already lower than the
// other two we can go straight to
// minimization. Otherwise, we have to bracket the
// minimum.  First things first, setup the two new
// points (b & c) and send them off
bool PrepareToBracket(avtPoincareIC *seed,
                      avtVector &newA,
                      avtVector &newB,
                      avtVector &newC)
{
  if (5 <= RATIONAL_DEBUG)
    std::cerr<< "Line: " << __LINE__ <<" Preparing to bracket the minimum"<<std::endl;
  
  Vector xzplane(0,1,0);
  FieldlineLib fieldlib;
  
  std::vector<avtVector> seed_puncture_points;
  fieldlib.getPunctures( seed->points, xzplane,
                         seed_puncture_points);
  avtVector maxPuncture;
  avtVector origPt1 = seed->properties.rationalPt1;
  avtVector origPt2 = seed->properties.rationalPt2;
  int ix = FindMinimizationIndex(seed);
  if (1 <= RATIONAL_DEBUG)
    cerr <<"Line: "<<__LINE__<< " Bracketing inside Original Rational Pts:\n"<<VectorToString(origPt1)<<"\n"<<VectorToString(origPt2)<<std::endl;
  if (ix < 0)
    return false;  

  maxPuncture = seed_puncture_points[ix];
  
  avtVector origChord = origPt2 - origPt1;
  avtVector perpendicular = -origChord.cross(avtVector(0,1,0));

  double xa = (origPt1 - maxPuncture).dot(perpendicular);
  perpendicular.normalize();
  
  double minDist = 2 * MAX_SPACING;
  if (xa < minDist)
    xa = minDist;

  avtVector intersection = maxPuncture + xa * perpendicular;

  cerr << "Max Puncture: "<<VectorToString(maxPuncture)<<"\nxa: "<<xa<<"\nintersection: "<<VectorToString(intersection)<<"\n";
  
  avtVector newPt1 = intersection;
  avtVector newPt2 = maxPuncture + GOLD * (newPt1 - maxPuncture);

  newPt1[1] =  Z_OFFSET;
  newPt2[1] =  Z_OFFSET;
  
  newA = maxPuncture;
  newB = newPt1;
  newC = newPt2;

  if (1 <= RATIONAL_DEBUG)
    cerr<<"LINE "<<__LINE__<<"New A,B,C:\n"<< VectorToString(newA) <<"\n"<< VectorToString(newB) <<"\n"<< VectorToString(newC) <<"\n";

  seed->properties.analysisMethod = FieldlineProperties::RATIONAL_SEARCH;
  seed->properties.searchState = FieldlineProperties::MINIMIZING_A;
  
  return true;
}
Beispiel #9
0
void 
avtIVPRK4::Reset(const double& t_start,
                   const avtVector &y_start,
                   const avtVector &v_start)
{
    t = t_start;
    d = 0.0;
    numStep = 0;

    y = y_start;
    v = avtVector( 0, 0, 0 );
    h = h_max;
}
Beispiel #10
0
avtVector
avtMatrix::operator^(const avtVector &r) const
{
    double x,y,z;

    x = m[0][0] * r.x +
        m[0][1] * r.y +
        m[0][2] * r.z;
    y = m[1][0] * r.x +
        m[1][1] * r.y +
        m[1][2] * r.z;
    z = m[2][0] * r.x +
        m[2][1] * r.y +
        m[2][2] * r.z;

    // note -- could insert "normalize" in here
    return avtVector(x,y,z);
}
Beispiel #11
0
void 
avtIVPDopri5::Reset(const double& t_start,
                    const avtVector& y_start,
                    const avtVector& v_start)
{
    h = h_init = 0.0;
    
    n_accepted = n_rejected = n_steps = n_eval = 0;
    
    facold = 1e-4;
    hlamb  = 0.0;
    iasti  = 0;
    
    t = t_start;
    d = 0.0;
    numStep = 0;
    y = y_start;
    k1 = avtVector(0,0,0);
}
/**
 *
 * Takes in a curve, returns the index of puncture point contained
 * between pt0 and pt1.
 *
 **/
int FindMinimizationIndex( avtPoincareIC *ic )
{
  if (4 <= RATIONAL_DEBUG)
    cerr << "Finding Minimization Index...\n";

  std::vector<avtVector> puncturePoints;
  FieldlineLib fieldlib;
  fieldlib.getPunctures(ic->points, avtVector(0, 1, 0), puncturePoints);

  if (puncturePoints.size() < 2*ic->properties.toroidalWinding)
    {
      cerr << "Not enough puncture points to find correct Rational Surface Minimization index. Failing.\n";
      cerr << "need "<<2*ic->properties.toroidalWinding<<" puncture pts at least.\n";
      return -1;
    }

  avtVector seedPt = ic->properties.srcPt;
  double min = 99999999;
  int minix = -1;
  for (int i =0; i < ic->properties.toroidalWinding && i < puncturePoints.size(); i++)
    {
      avtVector puncture = puncturePoints[i];
      double dist = (seedPt - puncture).length();
      if (min > dist)
        {
          min = dist;
          minix = i;
        }
    }
  if (minix > -1 && 3 <= RATIONAL_DEBUG)
    cerr <<"LINE: "<<__LINE__<<"found " << minix <<", "<< min <<"\n";
  return minix;
  
  if (puncturePoints.size() > 0)
    return 0;
  else 
    return -1;
}
double MinRationalDistance( avtPoincareIC *ic,
                        unsigned int toroidalWinding,
                        unsigned int &index )
{
  
  double delta = 9999999999999.0;


  std::vector<avtVector> puncturePoints;
  FieldlineLib fieldlib;
  fieldlib.getPunctures(ic->points, avtVector(0, 1, 0), puncturePoints);

  for (unsigned int i=0; i+toroidalWinding < puncturePoints.size() && i < toroidalWinding; ++i)
    {      
      avtVector vec = puncturePoints[i] - puncturePoints[i+toroidalWinding];
      if( delta > vec.length() )
      {
        delta = vec.length();
        index = i;
      }
    }
  return delta;
}
bool
avtLCSFilter::SingleBlockIterativeCalc( vtkDataSet *in_ds,
                                        std::vector<avtIntegralCurve*> &ics,
                                        int &offset )
{
    int dims[3];

    if (in_ds->GetDataObjectType() == VTK_UNIFORM_GRID)
    {
      ((vtkUniformGrid*)in_ds)->GetDimensions(dims);
    }      
    else if (in_ds->GetDataObjectType() == VTK_RECTILINEAR_GRID)
    {
      ((vtkRectilinearGrid*)in_ds)->GetDimensions(dims);
    }      
    else if (in_ds->GetDataObjectType() == VTK_STRUCTURED_GRID)
    {
      ((vtkStructuredGrid*)in_ds)->GetDimensions(dims);
    }      
    else
    {
      EXCEPTION1(VisItException,
                 "Can only compute SingleBlockIterativeCalc on "
                 "imagedata, rectilinear grids, or structured grids. ");
    }

    // Variable name and number of points.
    std::string var = outVarRoot + outVarName;

    int nTuples = in_ds->GetNumberOfPoints();
    
    // Storage for the points and times
    std::vector<avtVector> remapPoints(nTuples);
    std::vector<double>    remapTimes(nTuples);

    // Zero out the points.
    for(size_t i = 0; i < remapPoints.size(); ++i)
    {
      remapPoints[i] = avtVector(0,0,0);
      remapTimes[i] = 0;
    }

    // ARS - This code does not nothing of use that I can see. The
    // remapPoints just need to be zeroed out.

    // if (GetInput()->GetInfo().GetAttributes().DataIsReplicatedOnAllProcessors())
    // {
    //     // The parallel synchronization for when data is replicated involves
    //     // a sum across all processors.  So we want remapPoints to have the
    //     // location of the particle on one processor, and zero on the rest.
    //     // Do that here.
    //     // Special care is needed for the case where the particle never
    //     // advected.  Then we need to put the initial location on just one
    //     // processor.  We do this on rank 0.
    //     std::vector<int> iHavePoint(nTuples, 0);
    //     std::vector<int> anyoneHasPoint;

    //     for (size_t idx = 0; idx < ics.size(); idx++)
    //     {
    //         size_t index = ics[idx]->id;
    //         size_t l = (index-offset);
    //         if(l < remapPoints.size()) ///l >= 0 is always true
    //         {
    //             iHavePoint[l] = 1;
    //         }
    //     }

    //     UnifyMaximumValue(iHavePoint, anyoneHasPoint);
    //     avtVector zero;
    //     zero.x = zero.y = zero.z = 0.;
    //     for (size_t i = 0; i < (size_t)nTuples; i++)
    //     {
    //         if (PAR_Rank() == 0 && !anyoneHasPoint[i])
    //         {
    //             remapPoints[i] = seedPoints.at(offset + i);
    //             remapTimes[i] = 0;
    //         }
    //         else
    //         {
    //             remapPoints[i] = zero;
    //             remapTimes[i] = 0;
    //         }
    //     }
    // }
    // else
    // {
    //     //copy the original seed points
    //     for(size_t i = 0; i < remapPoints.size(); ++i)
    //     {
    //         remapPoints[i] = seedPoints.at(offset + i);
    //         remapTimes[i] = 0;
    //     }
    // }

    for(size_t i = 0; i < ics.size(); ++i)
    {
        avtStreamlineIC * ic = (avtStreamlineIC *) ics[i];

        size_t index = ic->id;
        int l = (int)(index-offset);

        if(l >= 0 && l < (int)remapPoints.size())
        {
          remapPoints.at(l) = ic->GetEndPoint();

          if( doPathlines )
            remapTimes.at(l) = ic->GetTime() - seedTime0;
          else
            remapTimes.at(l) = ic->GetTime();
        }
    }

    // Get the stored data arrays
    vtkDataArray* jacobian[3];
    
    vtkDoubleArray *exponents = (vtkDoubleArray *)
      in_ds->GetPointData()->GetArray(var.c_str());
    vtkDoubleArray *component = (vtkDoubleArray *)
      in_ds->GetPointData()->GetArray("component");
    vtkDoubleArray *times = (vtkDoubleArray *)
      in_ds->GetPointData()->GetArray("times");

    //use static function in avtGradientExpression to calculate
    //gradients.  since this function only does scalar, break our
    //vectors into scalar components and calculate one at a time.

    // Note the mesh is uniform with all distances being one.
    for(int i = 0; i < 3; ++i)
    {
        for(size_t j = 0; j < (size_t)nTuples; ++j)
            component->SetTuple1(j, remapPoints[j][i]);

        if (GetInput()->GetInfo().GetAttributes().DataIsReplicatedOnAllProcessors())
        {
            float *newvals = new float[nTuples];
            float *origvals = (float *) component->GetVoidPointer(0);
            SumFloatArrayAcrossAllProcessors(origvals, newvals, nTuples);
            // copy newvals back into origvals
            memcpy(origvals, newvals, nTuples*sizeof(float));
            delete [] newvals;
        }

        jacobian[i] =
          avtGradientExpression::CalculateGradient(in_ds, var.c_str());
    }

    // Store the times for the exponent.
    for(size_t l = 0; l < (size_t)nTuples; ++l)
    {
      times->SetTuple1(l, remapTimes[l]);
    }

    for (int i = 0; i < nTuples; i++)
      component->SetTuple1(i, std::numeric_limits<double>::epsilon());

    //now have the jacobian - 3 arrays with 3 components.
    ComputeLyapunovExponent(jacobian, component);
    
    jacobian[0]->Delete();
    jacobian[1]->Delete();
    jacobian[2]->Delete();
    
    // Compute the FSLE
    ComputeFSLE( component, times, exponents );

    bool haveAllExponents = true;

    // For each integral curve check it's mask value to see it
    // additional integration is required.
    for(size_t i=0; i<ics.size(); ++i)
    {
      avtStreamlineIC * ic = (avtStreamlineIC *) ics[i];

      size_t index = ic->id;
      size_t l = (index-offset);

      int ms = ic->GetMaxSteps();

      if( ms < maxSteps )
      {
        ic->SetMaxSteps(ms+1);
        ic->status.ClearTerminationMet();
      }

      // Check to see if all exponents have been found.
      if( exponents->GetTuple1(l) == std::numeric_limits<double>::min() &&
          ms < maxSteps )
        haveAllExponents = false;
    }
    
    //done with offset, increment it for the next call to this
    //function.
    offset += nTuples;

    return haveAllExponents;
}
void
VisitPointTool::GetGuidePoints(avtVector *pts)
{
    int axis = FacingAxis();

    // Fill the return pts array.
    double bounds[6];
    proxy.GetBounds(bounds);
    double axisscale[3];
    if (proxy.Get3DAxisScalingFactors(axisscale))
    {
        bounds[0] *= axisscale[0];
        bounds[1] *= axisscale[0];
        bounds[2] *= axisscale[1];
        bounds[3] *= axisscale[1];
        bounds[4] *= axisscale[2];
        bounds[5] *= axisscale[2];
    }
    double xmin = bounds[0];
    double xmax = bounds[1];
    double ymin = bounds[2];
    double ymax = bounds[3];
    double zmin = bounds[4];
    double zmax = bounds[5];

    if(axis == 0 || axis == 1)
    {
        pts[0] = avtVector(hotPoints[0].pt.x, ymin, zmax);
        pts[1] = avtVector(hotPoints[0].pt.x, ymin, zmin);
        pts[2] = avtVector(hotPoints[0].pt.x, ymax, zmin);
        pts[3] = avtVector(hotPoints[0].pt.x, ymax, zmax);
        pts[4] = avtVector(hotPoints[0].pt.x, hotPoints[0].pt.y, zmax);
        pts[5] = avtVector(hotPoints[0].pt.x, hotPoints[0].pt.y, zmin);
        pts[6] = avtVector(hotPoints[0].pt.x, ymax, hotPoints[0].pt.z);
        pts[7] = avtVector(hotPoints[0].pt.x, hotPoints[0].pt.y, hotPoints[0].pt.z);
        pts[8] = avtVector(hotPoints[0].pt.x, ymin, hotPoints[0].pt.z);
    }
    else if(axis == 2 || axis == 3)
    {
        pts[0] = avtVector(xmin, hotPoints[0].pt.y, zmax);
        pts[1] = avtVector(xmax, hotPoints[0].pt.y, zmax);
        pts[2] = avtVector(xmax, hotPoints[0].pt.y, zmin);
        pts[3] = avtVector(xmin, hotPoints[0].pt.y, zmin);
        pts[4] = avtVector(xmin, hotPoints[0].pt.y, hotPoints[0].pt.z);
        pts[5] = avtVector(xmax, hotPoints[0].pt.y, hotPoints[0].pt.z);
        pts[6] = avtVector(hotPoints[0].pt.x, hotPoints[0].pt.y, zmin);
        pts[7] = avtVector(hotPoints[0].pt.x, hotPoints[0].pt.y, hotPoints[0].pt.z);
        pts[8] = avtVector(hotPoints[0].pt.x, hotPoints[0].pt.y, zmax);
    }
    else if(axis == 4 || axis == 5)
    {
        pts[0] = avtVector(xmin, ymin, hotPoints[0].pt.z);
        pts[1] = avtVector(xmax, ymin, hotPoints[0].pt.z);
        pts[2] = avtVector(xmax, ymax, hotPoints[0].pt.z);
        pts[3] = avtVector(xmin, ymax, hotPoints[0].pt.z);
        pts[4] = avtVector(xmin, hotPoints[0].pt.y, hotPoints[0].pt.z);
        pts[5] = avtVector(xmax, hotPoints[0].pt.y, hotPoints[0].pt.z);
        pts[6] = avtVector(hotPoints[0].pt.x, ymax, hotPoints[0].pt.z);
        pts[7] = avtVector(hotPoints[0].pt.x, hotPoints[0].pt.y, hotPoints[0].pt.z);
        pts[8] = avtVector(hotPoints[0].pt.x, ymin, hotPoints[0].pt.z);
    }
}
void
VisitPointTool::Translate(CB_ENUM e, int ctrl, int shift, int x, int y, int)
{
    if (axisTranslate == none)
    {
        if (shift && !ctrl)
            if (window3D)
                axisTranslate = inAndOut;
            else
                axisTranslate = none;
        else if (shift && ctrl)
            axisTranslate = leftAndRight;
        else if (ctrl)
            axisTranslate = upAndDown;
        else
            axisTranslate = none;
    }

    if(e == CB_START)
    {
        vtkRenderer *ren = proxy.GetCanvas();
        vtkCamera *camera = ren->GetActiveCamera();
        double ViewFocus[3];
        camera->GetFocalPoint(ViewFocus);
        ComputeWorldToDisplay(ViewFocus[0], ViewFocus[1],
                              ViewFocus[2], ViewFocus);
        // Store the focal depth.
        focalDepth = ViewFocus[2];

        if (axisTranslate != none)
        {
            translationDistance = ComputeTranslationDistance(axisTranslate);
        }

        // Make the right actors active.
        InitialActorSetup();
    }
    else if(e == CB_MIDDLE)
    {
        avtVector newPoint = ComputeDisplayToWorld(avtVector(x,y,focalDepth));
        //
        // Have to recalculate the old mouse point since the viewport has
        // moved, so we can't move it outside the loop
        //
        avtVector oldPoint = ComputeDisplayToWorld(avtVector(lastX,lastY,focalDepth));
        avtVector motion(newPoint - oldPoint);

        if (axisTranslate)
        {
            double delta;
            if (axisTranslate == leftAndRight)
                delta = x - lastX;
            else
                delta = y - lastY;
            motion = translationDistance * delta;
        }

        hotPoints[0].pt = (hotPoints[0].pt + motion);

        // Update the text actors.
        UpdateText();

        // Update the guide and the sphere.
        UpdateGuide();
        UpdateSphere();

        // Render the window
        proxy.Render();

        if (proxy.GetToolUpdateMode() == UPDATE_CONTINUOUS)
            CallCallback();
    }
    else
    {
        // Call the tool's callback.
        if (proxy.GetToolUpdateMode() != UPDATE_ONCLOSE)
            CallCallback();

        // Remove the right actors.
        FinalActorSetup();

        axisTranslate = none;
    }
}
avtVector
VisitPointTool::ComputeTranslationDistance(int direction)
{
    // This shouldn't happen, but just in case
    if (direction == none)
        return avtVector(0,0,0);

    if (direction == inAndOut)
        return ComputeDepthTranslationDistance();

    vtkCamera *camera = proxy.GetCanvas()->GetActiveCamera();
    
    int i;

    int *size = proxy.GetCanvas()->GetSize();
    double bounds[6];
    proxy.GetBounds(bounds);

    double dx = bounds[1] - bounds[0];
    double dy = bounds[3] - bounds[2];
    double dz = bounds[5] - bounds[4];
    
    std::vector<avtVector> axes;
    axes.push_back(avtVector(1., 0., 0.) * (dx / double(size[1])));
    axes.push_back(avtVector(-1., 0., 0.) * (dx / double(size[1])));
    axes.push_back(avtVector(0., 1., 0.) * (dy / double(size[1])));
    axes.push_back(avtVector(0., -1., 0.) * (dy / double(size[1])));
    axes.push_back(avtVector(0., 0., 1.) * (dz / double(size[1])));
    axes.push_back(avtVector(0., 0., -1.) * (dz / double(size[1])));
    
    avtVector camvec; // The vector to dot with

    const double *up = camera->GetViewUp();

    if (direction == upAndDown)
    {
        // Find what vector of {i,j,k,-i,-j,-k} best represents 'up'
        // The vector we want is the camera up vector.
        camvec.x = up[0];
        camvec.y = up[1];
        camvec.z = up[2];
    }
    else
    {
        // Find what vector best represents 'right'
        // The vector we want is the cross of the focus vector
        //  and the up vector.
        avtVector upVec(up[0], up[1], up[2]);
        const double *pos = camera->GetPosition();
        const double *focus = camera->GetFocalPoint();
        avtVector focusVec(focus[0]-pos[0],focus[1]-pos[1],focus[2]-pos[2]);
      
        camvec = focusVec % upVec;
    }
    
    camvec.normalize();
    
    double dots[6];
    for (i = 0; i < 6; ++i)
       dots[i] = camvec * axes[i]; 

    // Find the index of the largest dot product.
    int largestDotIndex = 0;
    for(i = 1; i < 6; ++i)
    {
        if(dots[i] > dots[largestDotIndex])
            largestDotIndex = i;
    }
    
    return axes[largestDotIndex];   
}
Beispiel #18
0
void
avtMatrix::MakeTrackball(double p1x,double p1y,  double p2x, double p2y,
                         bool lhs)
{
#define RADIUS       0.8        /* z value at x = y = 0.0  */
#define COMPRESSION  3.5        /* multipliers for x and y */
#define AR3 (RADIUS*RADIUS*RADIUS)

    double     q[4];   // quaternion
    avtVector  p1, p2; // pointer loactions on trackball
    avtVector  axis;   // axis of rotation
    double     phi;    // rotation angle (radians)
    double     t;

    // Check for zero mouse movement
    if (p1x==p2x && p1y==p2y)
    {
        MakeIdentity();
        return;
    }

    // Compute z-coordinates for projection of P1 and P2 onto
    // the trackball.
    p1 = avtVector(p1x, p1y, AR3/((p1x*p1x+p1y*p1y)*COMPRESSION+AR3));
    p2 = avtVector(p2x, p2y, AR3/((p2x*p2x+p2y*p2y)*COMPRESSION+AR3));

    // Compute the axis of rotation and temporarily store it
    // in the quaternion.
    axis = (p2 % p1).normalized();

    // Figure how much to rotate around that axis.
    t = (p2 - p1).norm();
    t = MIN(MAX(t, -1.0), 1.0);
    phi = -2.0*asin(t/(2.0*RADIUS));

    axis *= sin(phi/2.0);
    q[0]  = axis.x;
    q[1]  = axis.y;
    q[2]  = axis.z;
    q[3]  = cos(phi/2.0);

    // normalize quaternion to unit magnitude
    t =  1.0 / sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
    q[0] *= t;
    q[1] *= t;
    q[2] *= t;
    q[3] *= t;

    //  Handle LH coordinate systems.
    if (lhs)
    {
        q[2]*=-1;
    }

    // create the rotation matrix from the quaternion
    MakeIdentity();

    m[0][0] = 1.0 - 2.0 * (q[1]*q[1] + q[2]*q[2]);
    m[0][1] = 2.0 * (q[0]*q[1] + q[2]*q[3]);
    m[0][2] = (2.0 * (q[2]*q[0] - q[1]*q[3]) );

    m[1][0] = 2.0 * (q[0]*q[1] - q[2]*q[3]);
    m[1][1] = 1.0 - 2.0 * (q[2]*q[2] + q[0]*q[0]);
    m[1][2] = (2.0 * (q[1]*q[2] + q[0]*q[3]) );

    m[2][0] = (2.0 * (q[2]*q[0] + q[1]*q[3]) );
    m[2][1] = (2.0 * (q[1]*q[2] - q[0]*q[3]) );
    m[2][2] = (1.0 - 2.0 * (q[1]*q[1] + q[0]*q[0]) );
}
/**
 *
 * return a vector of seed points for the given rational
 *
 **/
std::vector<avtVector> GetSeeds( avtPoincareIC *poincare_ic,
                                 avtVector &point1,
                                 avtVector &point2,
                                 double maxDistance )
{
  std::vector<avtVector> puncturePoints;

  FieldlineLib fieldlib;
  fieldlib.getPunctures(poincare_ic->points, avtVector(0, 1, 0), puncturePoints);

  unsigned int toroidalWinding = poincare_ic->properties.toroidalWinding;
  unsigned int windingGroupOffset = poincare_ic->properties.windingGroupOffset;
  
  // Calculate angle size for each puncture point and find the one
  // that forms the largest angle (i.e. flattest portion of the
  // surface).
  int nSeeds = 0;
  double maxAngle = 0;
  unsigned int best_index = 0;

  unsigned int best_one_less;
  unsigned int best_one_more;

  bool twoPts = false;
  for( int i=0; i<toroidalWinding; ++i )
  {
    unsigned int one_less = (i-windingGroupOffset+toroidalWinding) % toroidalWinding;
    unsigned int one_more = (i+windingGroupOffset+toroidalWinding) % toroidalWinding;
    
    if (one_less == one_more)
      {
        best_index = i;
        best_one_more = one_more;
        twoPts = true;
        break;
      }
    
    if (3 <= RATIONAL_DEBUG)
      cerr << "Line: "<<__LINE__<<" wgo: "<<windingGroupOffset<<", ix-1: "<<one_less<<", ix: "<<i<<", ix+1: " <<one_more<<std::endl;

    avtVector pt0 = puncturePoints[one_less];
    avtVector pt1 = puncturePoints[i];
    avtVector pt2 = puncturePoints[one_more];

    // Save the maximum angle angle and the index of the puncture point.
    double angle = GetAngle( pt0, pt1, pt2 );
    if (maxAngle < angle)
    {     
      maxAngle = angle;
      best_index = i;

      best_one_less = one_less;
      best_one_more = one_more;
    }
  } 

 // Get circle equation 
  avtVector pt0,pt1,pt2;
  if (twoPts)
    {
       pt0 = puncturePoints[best_index];
       pt2 = puncturePoints[best_one_more];
       if (1 <= RATIONAL_DEBUG)
        cerr <<"Line: "<<__LINE__<< " 2 Rational Pts:\n"
             <<VectorToString(pt0)<<"\n"
             <<VectorToString(pt2)<<"\n";
       avtVector midpt = pt0 + 0.5 * (pt2-pt0);
       avtVector cx = (pt2-pt0).cross(avtVector(0,1,0));
       avtVector newpt = midpt + .5*cx;
       if (1 <= RATIONAL_DEBUG)
        cerr <<"Line: "<<__LINE__<< " 2 New Pts:\n"
             <<VectorToString(midpt)<<"\n"
             <<VectorToString(newpt)<<"\n";

       pt1 = newpt;
    }
  else
    {

      // Find the circle that intersects the three punctures points which
      // approximates the cross section of the surface.
      
      // Get circle equation 
      pt0 = puncturePoints[best_one_less];
      pt1 = puncturePoints[best_index];
      pt2 = puncturePoints[best_one_more];
      if (1 <= RATIONAL_DEBUG)
        cerr <<"Line: "<<__LINE__<< " Rational Pts:\n"
             <<VectorToString(pt0)<<"\n"
             <<VectorToString(pt1)<<"\n"
             <<VectorToString(pt2)<<"\n";
    }

  point1 = pt1; //for future reference
  point2 = pt2;
  
  if (1 <= RATIONAL_DEBUG)
    cerr <<"Line: "<<__LINE__<< " New seeds between:\n"
         <<VectorToString(point1)<<"\n"
         <<VectorToString(point2)<<"\n";
  
  // Center of the circle
  /////*********** Find The Circle Using Three Points******************///      
  double ax,ay,bx,by,cx,cy,x1,y11,dx1,dy1,x2,y2,dx2,dy2,ox,oy,dx,dy,radius;
  ax = pt0[0]; ay = pt0[2];
  bx = pt1[0]; by = pt1[2];
  cx = pt2[0]; cy = pt2[2];      
  x1 = (bx + ax) / 2;
  y11 = (by + ay) / 2;
  dy1 = bx - ax;
  dx1 = -(by - ay);      
  x2 = (cx + bx) / 2;
  y2 = (cy + by) / 2;
  dy2 = cx - bx;
  dx2 = -(cy - by);      
  ox = (y11 * dx1 * dx2 + x2 * dx1 * dy2 - x1 * dy1 * dx2 - y2 * dx1 * dx2)/ (dx1 * dy2 - dy1 * dx2);
  oy = (ox - x1) * dy1 / dx1 + y11;      
  dx = ox - ax;
  dy = oy - ay;
  radius = sqrt(dx * dx + dy * dy);     
  
  avtVector center(ox,0,oy);
  
  // Get the number of points needed to cover the range between the two
  // the puncture points.
  double dist = (pt2 - pt1).length();
  nSeeds = dist / maxDistance;
  if( dist > (double) nSeeds * maxDistance )
    ++nSeeds;
  double angle =GetAngle(point1, center, point2);
  
  // Add seeds stretching between two of the puncture points.
  std::vector<avtVector> seedPts;
  seedPts.resize( nSeeds );
  if (1 <= RATIONAL_DEBUG)
    std::cerr <<"Line: "<<__LINE__
              << " \ncenter: " << center 
              << " \nradius: " << radius
              << " \nnSeeds: " << nSeeds
              << " \nAngle: " << angle
              << std::endl;
  for( double i=0; i<nSeeds; ++i)
    {
      double t = i / nSeeds;
      avtVector X = center + (std::sin((1-t) * angle ) * (point1-center) + std::sin(t * angle) * (point2-center)) / std::sin(angle);
      X[1] = Z_OFFSET;
      
      seedPts[i] = X;
      
      if (3 <= RATIONAL_DEBUG)
        cerr << "New Seed: "<<VectorToString(X) << std::endl;
    }
  
  return seedPts;  
}
avtStateRecorderIntegralCurve::Sample
avtStateRecorderIntegralCurve::GetSample( size_t n ) const
{
    std::vector<double>::const_iterator m =
      history.begin() + n*GetSampleStride();

    Sample s;

    if( historyMask & SAMPLE_TIME )
        s.time = *(m++);
    else
        s.time = 0;

    if( historyMask & SAMPLE_POSITION )
    {
        s.position.x = *(m++);
        s.position.y = *(m++);
        s.position.z = *(m++);
    }
    else
        s.position = avtVector(0,0,0);

    if( historyMask & SAMPLE_VELOCITY )
    {
        s.velocity.x = *(m++);
        s.velocity.y = *(m++);
        s.velocity.z = *(m++);
    }
    else
        s.velocity = avtVector(0,0,0);

    if( historyMask & SAMPLE_VORTICITY )
        s.vorticity = *(m++);
    else
        s.vorticity = 0;

    if( historyMask & SAMPLE_ARCLENGTH )
        s.arclength = *(m++);
    else
        s.arclength = 0;

    if( historyMask & SAMPLE_VARIABLE )
        s.variable = *(m++);
    else
        s.variable = 0;

    if( historyMask & SAMPLE_SECONDARY0 ) 
        s.secondarys[0] = *(m++);
    else
        s.secondarys[0] = 0;

    if( historyMask & SAMPLE_SECONDARY1 )
        s.secondarys[1] = *(m++);
    else
        s.secondarys[1] = 0;

    if( historyMask & SAMPLE_SECONDARY2 )
        s.secondarys[2] = *(m++);
    else
        s.secondarys[2] = 0;

    if( historyMask & SAMPLE_SECONDARY3 ) 
        s.secondarys[3] = *(m++);
    else
        s.secondarys[3] = 0;

    if( historyMask & SAMPLE_SECONDARY4 )
        s.secondarys[4] = *(m++);
    else
        s.secondarys[4] = 0;

    if( historyMask & SAMPLE_SECONDARY5 )
        s.secondarys[5] = *(m++);
    else
        s.secondarys[5] = 0;

    return s;
}
vtkDataSet *
avtLegacyStreamlineFilter::ExecuteData(vtkDataSet *inDS, int, std::string)
{
    vtkPolyData        *outPD = NULL;
    vtkPolyData        *ballPD = NULL;
    vtkLineSource      *line = NULL;
    vtkPlaneSource     *plane = NULL;
    vtkSphereSource    *sphere = NULL;

    //
    // Create and initialize the streamline filter.
    //
    if(streamline != 0)
        streamline->Delete();
    streamline = vtkVisItStreamLine::New();
    streamline->SetIntegrationDirection(streamlineDirection);
    streamline->SetIntegrationStepLength(stepLength);
    streamline->SetStepLength(stepLength);
    streamline->SetSavePointInterval(stepLength);
    streamline->SetMaximumPropagationTime(maxTime);
    streamline->SetTerminalSpeed(0.01);
    vtkRungeKutta4 *integrator = vtkRungeKutta4::New();
    streamline->SetIntegrator(integrator);
    integrator->Delete();

    bool showTube = displayMethod == STREAMLINE_DISPLAY_TUBES;
    int spatialDim = GetInput()->GetInfo().GetAttributes().GetSpatialDimension();

    //
    // Create a source for the filter's streamline points.
    //
    if(sourceType == STREAMLINE_SOURCE_POINT)
    {
        double z0 = (spatialDim > 2) ? pointSource[2] : 0.;
        streamline->SetStartPosition(pointSource[0], pointSource[1], z0);
    }
    else if(sourceType == STREAMLINE_SOURCE_LINE)
    {
        line = vtkLineSource::New();
        double z0 = (spatialDim > 2) ? lineStart[2] : 0.;
        double z1 = (spatialDim > 2) ? lineEnd[2] : 0.;
        line->SetPoint1(lineStart[0], lineStart[1], z0);
        line->SetPoint2(lineEnd[0], lineEnd[1], z1);
        line->SetResolution(pointDensity);
        if(showTube && showStart)
            ballPD = line->GetOutput();

        streamline->SetSource(line->GetOutput());
    }
    else if(sourceType == STREAMLINE_SOURCE_PLANE)
    {
        plane = vtkPlaneSource::New();
        plane->SetXResolution(pointDensity);
        plane->SetYResolution(pointDensity);
        avtVector O(planeOrigin);
        avtVector U(planeUpAxis);
        avtVector N(planeNormal);
        U.normalize();
        N.normalize();
        if(spatialDim <= 2)
           N = avtVector(0.,0.,1.);
        // Determine the right vector.
        avtVector R(U % N);
        R.normalize();
        plane->SetOrigin(O.x, O.y, O.z);
        avtVector P1(U * (2./1.414214) * planeRadius + O);
        avtVector P2(R * (2./1.414214) * planeRadius + O);
        plane->SetPoint2(P1.x, P1.y, P1.z);
        plane->SetPoint1(P2.x, P2.y, P2.z);
        plane->SetNormal(N.x, N.y, N.z);
        plane->SetCenter(O.x, O.y, O.z);

        // Zero out the Z coordinate if the input dataset is only 2D.
        vtkPolyData *planePD = plane->GetOutput();
        if(spatialDim <= 2)
            SetZToZero(planePD);

        if(showTube && showStart)
            ballPD = planePD;

        streamline->SetSource(planePD);
    }
    else if(sourceType == STREAMLINE_SOURCE_SPHERE)
    {
        sphere = vtkSphereSource::New();
        sphere->SetCenter(sphereOrigin[0], sphereOrigin[1], sphereOrigin[2]);
        sphere->SetRadius(sphereRadius);
        sphere->SetLatLongTessellation(1);
        double t = double(30 - pointDensity) / 29.;
        double angle = t * 3. + (1. - t) * 30.;
        sphere->SetPhiResolution(int(angle));
        sphere->SetThetaResolution(int(angle));

        // Zero out the Z coordinate if the input dataset is only 2D.
        vtkPolyData *spherePD = sphere->GetOutput();
        if(spatialDim <= 2)
            SetZToZero(spherePD);

        if(showTube && showStart)
            ballPD = spherePD;

        streamline->SetSource(spherePD);
    }
    else if(sourceType == STREAMLINE_SOURCE_BOX)
    {
        //
        // Create polydata that contains the points that we want to streamline.
        //
        ballPD = vtkPolyData::New();
        vtkPoints *pts = vtkPoints::New();
        ballPD->SetPoints(pts);

        int npts = (pointDensity+1)*(pointDensity+1);
        int nZvals = 1;
        if(spatialDim > 2)
        {
            npts *= (pointDensity+1);
            nZvals = (pointDensity+1);
        }
        pts->SetNumberOfPoints(npts);

        float dX = boxExtents[1] - boxExtents[0];
        float dY = boxExtents[3] - boxExtents[2];
        float dZ = boxExtents[5] - boxExtents[4];
        int index = 0;
        for(int k = 0; k < nZvals; ++k)
        {
            float Z = 0.;
            if(spatialDim > 2)
                Z = (float(k) / float(pointDensity)) * dZ + boxExtents[4];
            for(int j = 0; j < pointDensity+1; ++j)
            {
                float Y = (float(j) / float(pointDensity)) * dY + boxExtents[2];
                for(int i = 0; i < pointDensity+1; ++i)
                {
                    float X = (float(i) / float(pointDensity)) * dX + boxExtents[0];
                    pts->SetPoint(index++, X, Y, Z);
                }
            }
        }
        pts->Delete();

        streamline->SetSource(ballPD);
    }

    bool doRibbons = displayMethod == STREAMLINE_DISPLAY_RIBBONS;
    if(coloringMethod == STREAMLINE_COLOR_SOLID)
    {
        // No variable coloring.
        streamline->SetSpeedScalars(1);  // hack
        streamline->SetVorticity(doRibbons?1:0);
    }
    else if(coloringMethod == STREAMLINE_COLOR_SPEED)
    {
        // Color by velocity magnitude.
        streamline->SetSpeedScalars(1);
        streamline->SetVorticity(doRibbons?1:0);
    }
    else
    {
        // Color by vorticity magnitude.
        streamline->SetSpeedScalars(0);
        streamline->SetVorticity(1);
    }

    // Set the input to the streamline filter and execute it.
    streamline->SetInput(inDS);
    streamline->Update();
    vtkPolyData *streams = streamline->GetOutput();
    if (coloringMethod == STREAMLINE_COLOR_SPEED)
        streams->GetPointData()->GetScalars()->SetName("colorVar");

    if(doRibbons)
    {
        //
        // If we're going to display the streamlines as ribbons, add the
        // streams to the ribbon filter and get the output.
        //
        if(ribbons != 0)
            ribbons->Delete();
        ribbons = vtkRibbonFilter::New();
        ribbons->SetWidth(2. * radius);
        ribbons->SetInput(streams);
        ribbons->Update();
        streams = ribbons->GetOutput();
    }

    // If we're coloring by vorticity magnitude, convert the vorticity to
    // vorticity magnitude and put it in the Scalars array.
    vtkDataArray *vorticity = streams->GetPointData()->GetVectors();
    if(vorticity != 0)
    {
        if(coloringMethod == STREAMLINE_COLOR_VORTICITY)
        {
            debug4 << "Computing vorticity magnitude." << endl;
            int n = vorticity->GetNumberOfTuples();
            vtkFloatArray *vortMag = vtkFloatArray::New();
            vortMag->SetName("colorVar");
            vortMag->SetNumberOfComponents(1);
            vortMag->SetNumberOfTuples(n);
            float *vm = (float *)vortMag->GetVoidPointer(0);
            for(int i = 0; i < n; ++i)
            {
                const double *val = vorticity->GetTuple3(i);
                *vm++ = (float)sqrt(val[0]*val[0] + val[1]*val[1] + val[2]*val[2]);
            }
            // If there is a scalar array, remove it.
            vtkDataArray *oldScalars = streams->GetPointData()->GetScalars();
            if(oldScalars != 0)
                streams->GetPointData()->RemoveArray(oldScalars->GetName());
            // Remove the vorticity array.
            streams->GetPointData()->RemoveArray(vorticity->GetName());

            // Make vorticity magnitude be the active scalar field.
            streams->GetPointData()->SetVectors(0);
            streams->GetPointData()->SetScalars(vortMag);
        }
        else
        {
            // Remove the vorticity array.
            streams->GetPointData()->RemoveArray(vorticity->GetName());
            streams->GetPointData()->SetVectors(0);
            debug4 << "Removed vorticity since we didn't need it." << endl;
        }
    }

    if(!doRibbons && showTube)
    {
        //
        // Create and initialize the tube filter.
        //
        if(tubes != 0)
            tubes->Delete();
        tubes = vtkTubeFilter::New();
        tubes->SetRadius(radius);
        tubes->SetNumberOfSides(8);
        tubes->SetRadiusFactor(2.);
        tubes->SetCapping(1);
        tubes->ReleaseDataFlagOn();

        if(showStart)
        {
            // Execute the tube filter.
            tubes->SetInput(streams);
            tubes->Update();
            vtkPolyData *tubeData = tubes->GetOutput();

            // Create an append filter that we'll use to add the start balls
            // to the tube poly data.
            vtkAppendPolyData *append = vtkAppendPolyData::New();
            append->AddInput(tubeData);
            vtkPolyData       **balls = NULL;
            int                 nballs = 0;

            // Add spheres to the start of the streamlines so we know where
            // they start.
            if(sourceType == STREAMLINE_SOURCE_POINT)
            {
                double pt[] = {pointSource[0], pointSource[1], 0.};
                if(spatialDim > 2) pt[2] = pointSource[2];
                vtkDataArray *arr = tubeData->GetPointData()->GetScalars();
                float val = arr->GetTuple1(0);
                balls = new vtkPolyData *[1];
                nballs = 1;
                balls[0] = AddStartSphere(tubeData, val, pt);
                append->AddInput(balls[0]);
            }
            else if(ballPD != NULL)
            {
                vtkCellArray *lines = streams->GetLines();
                if(lines != NULL && lines->GetNumberOfCells() > 0)
                {
                    lines->SetTraversalLocation(0);
                    nballs = ballPD->GetNumberOfPoints();
                    balls = new vtkPolyData*[nballs];
                    for(vtkIdType i = 0; i < nballs; ++i)
                    {
                        // Figure out the data value used to color the ball.
                        vtkIdType *pts = NULL, npts;
                        lines->GetNextCell(npts, pts);
                        if(pts != NULL)
                        {
                            vtkDataArray *arr = streams->GetPointData()->GetScalars();
                            double val = arr->GetTuple1(pts[0]);
                            balls[i] = AddStartSphere(tubeData, val, ballPD->GetPoint(i));
                        }
                        else
                        {
                            // There was no line for the point so add a ball 
                            // colored with zero speed.
                            balls[i] = AddStartSphere(tubeData, 0., ballPD->GetPoint(i));
                        }

                        // Add the ball to the append filter.
                        append->AddInput(balls[i]);
                    }
                }
            }

            append->Update();
            outPD = append->GetOutput();
            // Stash the polydata in the streamline filter since we keep it around for
            // the life of the filter. This keeps it from disappearing when we delete
            // the append filter.
            streamline->SetOutput(outPD);

            //
            // Delete the ball polydata.
            //
            append->Delete();
            if(nballs > 0)
            {
                for(int i = 0; i < nballs; ++i)
                    balls[i]->Delete();
                delete [] balls;
            }
        }
        else
        {
            tubes->SetInput(streams);
            tubes->Update();
            outPD = tubes->GetOutput();
        }
    }
    else
    {
        outPD = streams;
    }

    //
    // Delete any sources that we created.
    //
    if(line != NULL)
        line->Delete();
    if(plane != NULL)
        plane->Delete();
    if(sphere != NULL)
        sphere->Delete();

    return outPD;
}
avtVector 
avtIVPFlashField::ConvertToCylindrical(const avtVector& pt) const
{
  return avtVector(sqrt(pt[0]*pt[0]+pt[1]*pt[1]), atan2(pt[1], pt[0]), pt[2] );
}
Beispiel #23
0
// ****************************************************************************
//  Constructor:  avtTrackball::avtTrackball
//
//  Purpose:
//    Initialize the trackball.
//
//  Programmer:  Jeremy Meredith
//  Creation:    October  9, 2001
//
// ****************************************************************************
avtTrackball::avtTrackball()
{
    constrain = false;
    center = avtVector(0,0);
}
Beispiel #24
0
// ****************************************************************************
//  Method:  avtTrackball::Project
//
//  Purpose:
//    Project a point in unit screen space onto the trackball.
//
//  Arguments:
//    p          the 2d point in unit screen space
//
//  Programmer:  Jeremy Meredith
//  Creation:    October  9, 2001
//
// ****************************************************************************
avtVector
avtTrackball::Project(const avtVector &s)
{
    double z = double(AR3) / ((s.x*s.x + s.y*s.y) * COMPRESSION + AR3);
    return avtVector(s.x, s.y, z);
}