CRhinoCommand::result CCommandTestHistoryExample::RunCommand( const CRhinoCommandContext& context )
{
  CRhinoCommand::result rc  = CRhinoCommand::failure; 

  CRhinoGetObject go;
  go.SetCommandPrompt(L"Pick two curves");
  go.SetGeometryFilter(CRhinoGetObject::curve_object);
  go.GetObjects(2,2);
  if( go.Result()== CRhinoGet::object && 
      go.ObjectCount()==2)
  {
    CRhinoObjRef CObj0 = go.Object(0);
    CRhinoObjRef CObj1 = go.Object(1);
    const ON_Curve* c0 = CObj0.Curve();
    const ON_Curve* c1 = CObj1.Curve();
    if( c0 && c1)
    {
      ON_Surface* pSrf = MakeBilinearSurface( *c0, *c1);
      ON_Brep brep;
      if(pSrf && brep.Create(pSrf))
      {
        CRhinoHistory history(*this);
        WriteHistory(history,  CObj0, CObj1);
        context.m_doc.AddBrepObject(brep,NULL,&history);
        rc  = CRhinoCommand::success; 
      }
    }

  }

  return rc;
}
void CHandHistoryWriter::ResetOnMyTurn() {
  WriteHistory();
}
void CHandHistoryWriter::ResetOnHandreset() {
  //write_log(true, "######## Test ################\n");
  WriteHistory();
}
unsigned long CSysSolve::BCGSTAB_LinSolver(const CSysVector & b, CSysVector & x, CMatrixVectorProduct & mat_vec,
                                 CPreconditioner & precond, su2double tol, unsigned long m, su2double *residual, bool monitoring) {
	
  int rank = 0;
#ifdef HAVE_MPI
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#endif
  
  /*--- Check the subspace size ---*/
  
  if (m < 1) {
    if (rank == MASTER_NODE) cerr << "CSysSolve::BCGSTAB: illegal value for subspace size, m = " << m << endl;
#ifndef HAVE_MPI
    exit(EXIT_FAILURE);
#else
	MPI_Abort(MPI_COMM_WORLD,1);
    MPI_Finalize();
#endif
  }
	
  CSysVector r(b);
  CSysVector r_0(b);
  CSysVector p(b);
	CSysVector v(b);
  CSysVector s(b);
	CSysVector t(b);
	CSysVector phat(b);
	CSysVector shat(b);
  CSysVector A_x(b);
  
  /*--- Calculate the initial residual, compute norm, and check if system is already solved ---*/
  
	mat_vec(x, A_x);
  r -= A_x; r_0 = r; // recall, r holds b initially
  su2double norm_r = r.norm();
  su2double norm0 = b.norm();
  if ( (norm_r < tol*norm0) || (norm_r < eps) ) {
    if (rank == MASTER_NODE) cout << "CSysSolve::BCGSTAB(): system solved by initial guess." << endl;
    return 0;
  }
	
	/*--- Initialization ---*/
  
  su2double alpha = 1.0, beta = 1.0, omega = 1.0, rho = 1.0, rho_prime = 1.0;
	
  /*--- Set the norm to the initial initial residual value ---*/
  
  norm0 = norm_r;
  
  /*--- Output header information including initial residual ---*/
  
  int i = 0;
  if ((monitoring) && (rank == MASTER_NODE)) {
    WriteHeader("BCGSTAB", tol, norm_r);
    WriteHistory(i, norm_r, norm0);
  }
	
  /*---  Loop over all search directions ---*/
  
  for (i = 0; i < (int)m; i++) {
		
		/*--- Compute rho_prime ---*/
    
		rho_prime = rho;
		
		/*--- Compute rho_i ---*/
    
		rho = dotProd(r, r_0);
		
		/*--- Compute beta ---*/
    
		beta = (rho / rho_prime) * (alpha /omega);
		
		/*--- p_{i} = r_{i-1} + beta * p_{i-1} - beta * omega * v_{i-1} ---*/
    
		su2double beta_omega = -beta*omega;
		p.Equals_AX_Plus_BY(beta, p, beta_omega, v);
		p.Plus_AX(1.0, r);
		
		/*--- Preconditioning step ---*/
    
		precond(p, phat);
		mat_vec(phat, v);

		/*--- Calculate step-length alpha ---*/
    
    su2double r_0_v = dotProd(r_0, v);
    alpha = rho / r_0_v;
    
		/*--- s_{i} = r_{i-1} - alpha * v_{i} ---*/
    
		s.Equals_AX_Plus_BY(1.0, r, -alpha, v);
		
		/*--- Preconditioning step ---*/
    
		precond(s, shat);
		mat_vec(shat, t);
    
		/*--- Calculate step-length omega ---*/
    
    omega = dotProd(t, s) / dotProd(t, t);
    
		/*--- Update solution and residual: ---*/
    
    x.Plus_AX(alpha, phat); x.Plus_AX(omega, shat);
		r.Equals_AX_Plus_BY(1.0, s, -omega, t);
    
    /*--- Check if solution has converged, else output the relative residual if necessary ---*/
    
    norm_r = r.norm();
    if (norm_r < tol*norm0) break;
    if (((monitoring) && (rank == MASTER_NODE)) && ((i+1) % 50 == 0) && (rank == MASTER_NODE)) WriteHistory(i+1, norm_r, norm0);
    
  }
	  
  if ((monitoring) && (rank == MASTER_NODE)) {
    cout << "# BCGSTAB final (true) residual:" << endl;
    cout << "# Iteration = " << i << ": |res|/|res0| = "  << norm_r/norm0 << ".\n" << endl;
  }
	
//  /*--- Recalculate final residual (this should be optional) ---*/
//	mat_vec(x, A_x);
//  r = b; r -= A_x;
//  su2double true_res = r.norm();
//  
//  if ((fabs(true_res - norm_r) > tol*10.0) && (rank == MASTER_NODE)) {
//    cout << "# WARNING in CSysSolve::BCGSTAB(): " << endl;
//    cout << "# true residual norm and calculated residual norm do not agree." << endl;
//    cout << "# true_res - calc_res = " << true_res <<" "<< norm_r << endl;
//  }
	
  (*residual) = norm_r;
	return i;
}
unsigned long CSysSolve::FGMRES_LinSolver(const CSysVector & b, CSysVector & x, CMatrixVectorProduct & mat_vec,
                               CPreconditioner & precond, su2double tol, unsigned long m, su2double *residual, bool monitoring) {
	
int rank = 0;

#ifdef HAVE_MPI
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#endif
  
  /*---  Check the subspace size ---*/
  
  if (m < 1) {
    if (rank == MASTER_NODE) cerr << "CSysSolve::FGMRES: illegal value for subspace size, m = " << m << endl;
#ifndef HAVE_MPI
    exit(EXIT_FAILURE);
#else
	MPI_Abort(MPI_COMM_WORLD,1);
    MPI_Finalize();
#endif
  }

  /*---  Check the subspace size ---*/
  
  if (m > 1000) {
    if (rank == MASTER_NODE) cerr << "CSysSolve::FGMRES: illegal value for subspace size (too high), m = " << m << endl;
#ifndef HAVE_MPI
    exit(EXIT_FAILURE);
#else
	MPI_Abort(MPI_COMM_WORLD,1);
    MPI_Finalize();
#endif
  }
  
  /*---  Define various arrays
	 Note: elements in w and z are initialized to x to avoid creating
	 a temporary CSysVector object for the copy constructor ---*/
  
  vector<CSysVector> w(m+1, x);
  vector<CSysVector> z(m+1, x);
  vector<su2double> g(m+1, 0.0);
  vector<su2double> sn(m+1, 0.0);
  vector<su2double> cs(m+1, 0.0);
  vector<su2double> y(m, 0.0);
  vector<vector<su2double> > H(m+1, vector<su2double>(m, 0.0));
  
  /*---  Calculate the norm of the rhs vector ---*/
  
  su2double norm0 = b.norm();
  
  /*---  Calculate the initial residual (actually the negative residual)
	 and compute its norm ---*/
  
  mat_vec(x, w[0]);
  w[0] -= b;
  
  su2double beta = w[0].norm();
  
  if ( (beta < tol*norm0) || (beta < eps) ) {
    
    /*---  System is already solved ---*/
    
    if (rank == MASTER_NODE) cout << "CSysSolve::FGMRES(): system solved by initial guess." << endl;
    return 0;
  }
  
  /*---  Normalize residual to get w_{0} (the negative sign is because w[0]
	 holds the negative residual, as mentioned above) ---*/
  
  w[0] /= -beta;
  
  /*---  Initialize the RHS of the reduced system ---*/
  
  g[0] = beta;
  
  /*--- Set the norm to the initial residual value ---*/
  
  norm0 = beta;

  /*---  Output header information including initial residual ---*/
  
  int i = 0;
  if ((monitoring) && (rank == MASTER_NODE)) {
    WriteHeader("FGMRES", tol, beta);
    WriteHistory(i, beta, norm0);
  }
  
  /*---  Loop over all search directions ---*/
  
  for (i = 0; i < (int)m; i++) {
    
    /*---  Check if solution has converged ---*/
    
    if (beta < tol*norm0) break;
    
    /*---  Precondition the CSysVector w[i] and store result in z[i] ---*/
    
    precond(w[i], z[i]);
    
    /*---  Add to Krylov subspace ---*/
    
    mat_vec(z[i], w[i+1]);
    
    /*---  Modified Gram-Schmidt orthogonalization ---*/
    
    ModGramSchmidt(i, H, w);
    
    /*---  Apply old Givens rotations to new column of the Hessenberg matrix
		 then generate the new Givens rotation matrix and apply it to
		 the last two elements of H[:][i] and g ---*/
    
    for (int k = 0; k < i; k++)
      ApplyGivens(sn[k], cs[k], H[k][i], H[k+1][i]);
    GenerateGivens(H[i][i], H[i+1][i], sn[i], cs[i]);
    ApplyGivens(sn[i], cs[i], g[i], g[i+1]);
    
    /*---  Set L2 norm of residual and check if solution has converged ---*/
    
    beta = fabs(g[i+1]);
    
    /*---  Output the relative residual if necessary ---*/
    
    if ((((monitoring) && (rank == MASTER_NODE)) && ((i+1) % 50 == 0)) && (rank == MASTER_NODE)) WriteHistory(i+1, beta, norm0);
    
  }

  /*---  Solve the least-squares system and update solution ---*/
  
  SolveReduced(i, H, g, y);
  for (int k = 0; k < i; k++) {
    x.Plus_AX(y[k], z[k]);
  }
  
  if ((monitoring) && (rank == MASTER_NODE)) {
    cout << "# FGMRES final (true) residual:" << endl;
    cout << "# Iteration = " << i << ": |res|/|res0| = " << beta/norm0 << ".\n" << endl;
  }
  
//  /*---  Recalculate final (neg.) residual (this should be optional) ---*/
//  mat_vec(x, w[0]);
//  w[0] -= b;
//  su2double res = w[0].norm();
//
//  if (fabs(res - beta) > tol*10) {
//    if (rank == MASTER_NODE) {
//      cout << "# WARNING in CSysSolve::FGMRES(): " << endl;
//      cout << "# true residual norm and calculated residual norm do not agree." << endl;
//      cout << "# res - beta = " << res - beta << endl;
//    }
//  }
	
  (*residual) = beta;
	return i;
  
}
unsigned long CSysSolve::CG_LinSolver(const CSysVector & b, CSysVector & x, CMatrixVectorProduct & mat_vec,
                                           CPreconditioner & precond, su2double tol, unsigned long m, bool monitoring) {
	
int rank = 0;

#ifdef HAVE_MPI
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#endif
  
  /*--- Check the subspace size ---*/
  if (m < 1) {
    if (rank == MASTER_NODE) cerr << "CSysSolve::ConjugateGradient: illegal value for subspace size, m = " << m << endl;
#ifndef HAVE_MPI
    exit(EXIT_FAILURE);
#else
	MPI_Abort(MPI_COMM_WORLD,1);
    MPI_Finalize();
#endif
  }
  
  CSysVector r(b);
  CSysVector A_p(b);
  
  /*--- Calculate the initial residual, compute norm, and check if system is already solved ---*/
  mat_vec(x, A_p);
  
  r -= A_p; // recall, r holds b initially
  su2double norm_r = r.norm();
  su2double norm0 = b.norm();
  if ( (norm_r < tol*norm0) || (norm_r < eps) ) {
    if (rank == MASTER_NODE) cout << "CSysSolve::ConjugateGradient(): system solved by initial guess." << endl;
    return 0;
  }
  
  su2double alpha, beta, r_dot_z;
  CSysVector z(r);
  precond(r, z);
  CSysVector p(z);
  
  /*--- Set the norm to the initial initial residual value ---*/
  norm0 = norm_r;
  
  /*--- Output header information including initial residual ---*/
  int i = 0;
  if ((monitoring) && (rank == MASTER_NODE)) {
    WriteHeader("CG", tol, norm_r);
    WriteHistory(i, norm_r, norm0);
  }
  
  /*---  Loop over all search directions ---*/
  for (i = 0; i < (int)m; i++) {
    
    /*--- Apply matrix to p to build Krylov subspace ---*/
    mat_vec(p, A_p);
    
    /*--- Calculate step-length alpha ---*/
    r_dot_z = dotProd(r, z);
    alpha = dotProd(A_p, p);
    alpha = r_dot_z / alpha;
    
    /*--- Update solution and residual: ---*/
    x.Plus_AX(alpha, p);
    r.Plus_AX(-alpha, A_p);
    
    /*--- Check if solution has converged, else output the relative residual if necessary ---*/
    norm_r = r.norm();
    if (norm_r < tol*norm0) break;
    if (((monitoring) && (rank == MASTER_NODE)) && ((i+1) % 5 == 0)) WriteHistory(i+1, norm_r, norm0);
    
    precond(r, z);
    
    /*--- Calculate Gram-Schmidt coefficient beta,
		 beta = dotProd(r_{i+1}, z_{i+1}) / dotProd(r_{i}, z_{i}) ---*/
    beta = 1.0 / r_dot_z;
    r_dot_z = dotProd(r, z);
    beta *= r_dot_z;
    
    /*--- Gram-Schmidt orthogonalization; p = beta *p + z ---*/
    p.Equals_AX_Plus_BY(beta, p, 1.0, z);
  }
  

  
  if ((monitoring) && (rank == MASTER_NODE)) {
    cout << "# Conjugate Gradient final (true) residual:" << endl;
    cout << "# Iteration = " << i << ": |res|/|res0| = "  << norm_r/norm0 << ".\n" << endl;
  }
  
//  /*--- Recalculate final residual (this should be optional) ---*/
//  mat_vec(x, A_p);
//  r = b;
//  r -= A_p;
//  su2double true_res = r.norm();
//  
//  if (fabs(true_res - norm_r) > tol*10.0) {
//    if (rank == MASTER_NODE) {
//      cout << "# WARNING in CSysSolve::ConjugateGradient(): " << endl;
//      cout << "# true residual norm and calculated residual norm do not agree." << endl;
//      cout << "# true_res - calc_res = " << true_res - norm_r << endl;
//    }
//  }
	
	return i;
  
}
Beispiel #7
0
  /**
   * Mosaic Processing method, returns false if the cube is not inside the mosaic
   */
  bool ProcessMapMosaic::StartProcess(QString inputFile) {
    if (InputCubes.size() != 0) {
      QString msg = "Input cubes already exist; do not call SetInputCube when using ";
      msg += "ProcessMosaic::StartProcess(QString)";
      throw IException(IException::Programmer, msg, _FILEINFO_);
    }

    if (OutputCubes.size() == 0) {
      QString msg = "An output cube must be set before calling StartProcess";
      throw IException(IException::Programmer, msg, _FILEINFO_);
    }

    CubeAttributeInput inAtt(inputFile);
    Cube *inCube = ProcessMosaic::SetInputCube(inputFile, inAtt);

    Cube *mosaicCube = OutputCubes[0];
    Projection *iproj = inCube->projection();
    Projection *oproj = mosaicCube->projection();
    int nsMosaic = mosaicCube->sampleCount();
    int nlMosaic = mosaicCube->lineCount();

    if (*iproj != *oproj) {
      QString msg = "Mapping groups do not match between cube [" + inputFile + "] and mosaic";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    int outSample, outSampleEnd, outLine, outLineEnd;
    outSample = (int)(oproj->ToWorldX(iproj->ToProjectionX(1.0)) + 0.5);
    outLine   = (int)(oproj->ToWorldY(iproj->ToProjectionY(1.0)) + 0.5);

    int ins = InputCubes[0]->sampleCount();
    int inl =  InputCubes[0]->lineCount();
    outSampleEnd = outSample + ins;
    outLineEnd   = outLine + inl;

    bool wrapPossible = iproj->IsEquatorialCylindrical();
    int worldSize = 0;
    if (wrapPossible) {
      // Figure out how many samples 360 degrees is
      wrapPossible = wrapPossible && oproj->SetUniversalGround(0, 0);
      int worldStart = (int)(oproj->WorldX() + 0.5);
      wrapPossible = wrapPossible && oproj->SetUniversalGround(0, 180);
      int worldEnd = (int)(oproj->WorldX() + 0.5);

      worldSize = abs(worldEnd - worldStart) * 2;

      wrapPossible = wrapPossible && (worldSize > 0);

      // This is EquatorialCylindrical, so shift to the left all the way
      if (wrapPossible) {
        // While some data would still be put in the mosaic, move left
        //  >1 for end because 0 still means no data, whereas 1 means 1 line of data
        while (outSampleEnd - worldSize > 1) {
          outSample -= worldSize;
          outSampleEnd -= worldSize;
        }
        // Now we have the sample range to the furthest left
      }
    }

    // Check overlaps of input image along the mosaic edges before
    // calling ProcessMosaic::StartProcess
    // Left edge
    if (outSample < 1) {
      ins = ins + outSample - 1;
    }

    // Top edge
    if (outLine < 1) {
      inl = inl + outLine - 1;
    }

    // Right edge
    if ((outSample + ins - 1) > nsMosaic) {
      ins = nsMosaic - outSample + 1;
    }

    // Bottom edge
    if ((outLine + inl - 1) > nlMosaic) {
      inl = nlMosaic - outLine + 1;
    }

    if (outSampleEnd < 1 || outLineEnd < 1 || outSample > nsMosaic || outLine > nlMosaic || ins < 1 || inl < 1) {
      // Add a PvlKeyword naming which files are not included in output mosaic
      ClearInputCubes();
      return false;
    }
    else {
      // Place the input in the mosaic
      Progress()->SetText("Mosaicking " + FileName(inputFile).name());

      try {
        do {
          int outBand = 1;
          ProcessMosaic::StartProcess(outSample, outLine, outBand);

          // Increment for projections where occurrances may happen multiple times
          outSample += worldSize;
          outSampleEnd += worldSize;
        }
        while (wrapPossible && outSample < nsMosaic);
      }
      catch (IException &e) {
        QString msg = "Unable to mosaic cube [" + FileName(inputFile).name() + "]";
        throw IException(e, IException::User, msg, _FILEINFO_);
      }
    }

    WriteHistory(*mosaicCube);

    // Don't propagate any more histories now that we've done one
    p_propagateHistory = false;

    ClearInputCubes();

    return true;
  }