예제 #1
0
파일: PFCal.cpp 프로젝트: MoleRock/PFCT
//************************************
// Method:    SolvePFC
// FullName:  PFCal::PFC::SolvePFC
// Access:    public 
// Returns:   PF_RESULT
// Qualifier: 潮流计算模板函数,构造各种方法求解线性方程组
//************************************
PFVoid PFC::Solve(){
	PFDouble opml(0.0);
	Eigen::SparseLU<PFCore::PFSMatrixXD, PFCore::PFCOLAMDOrdering> solver;
	PFCIter = 0;
	//0. 初始化计算矩阵及向量大小
	this->_InitPFCalMatrix();

	do {
		//1. 求解功率失配量
		cout << "QG DISPATCH..." << endl;
		_MakeDPQVector();
		//2. 如果达到收敛条件,退出
		cout << "MAXDISPATCH\t" << PFCIter << "\t" << dPFCPQ.cwiseAbs().maxCoeff() << endl;
		if (dPFCPQ.cwiseAbs().maxCoeff() <  PFCEpsm){
			this->PFCResult = PF_RESULT_CONVERG;
			return;
		}
		//3. 计算雅可比阵
		_MakeJacoMatrix();
		//4. 计算电压偏差
		solver.compute(PFCJaco);
		if (solver.info() != Eigen::Success){
			cout << "Solving<stage_1> Failed!" << endl;
			this->PFCResult = PF_RESULT_DIVERGE_FAILURE;
			return;
		}
		dPFCVA = solver.solve(dPFCPQ);
		if (solver.info() != Eigen::Success){
			cout << "Solving<stage_2> Failed!" << endl;
			this->PFCResult = PF_RESULT_DIVERGE_FAILURE;
			return;
		}
		//5. 检测是否出现NAN
		if(dPFCVA.hasNaN()){
			this->PFCResult = PF_RESULT_DIVERGE_NAN;
			return;
		}
		//6. 更新状态量
		cout << "VOL DISPATCH..." << endl;
		opml = _CalOptimalMultiplier();
		dPFCVA *= opml;
		_UpdateSysState();
		//7. 迭代次数增加
		++PFCIter;
	} while (PFCIter <= PFCMaxIter);
	//迭代次数越限
	if (PFCIter > PFCMaxIter){
		this->PFCResult = PF_RESULT_DIVERGE_OVER_ITER;
		return;
	}
	this->PFCResult = PF_RESULT_DIVERGE;
	return;
}
예제 #2
0
    void ReliefGeneration::CompressHeightField(std::vector<double>& heightField, int resX, int resY)
    {
        double bbScale = 2;
        double alpha = bbScale * 300.0;
        double threthold = bbScale * 0.05;
        int vertNum = (resX + 1) * (resY + 1);
        std::vector<MagicMath::Vector3> DeltaVector(vertNum);
        for (int xid = 0; xid < resX; xid++)
        {
            for (int yid = 0; yid < resY; yid++)
            {
                int index = xid * (resY + 1) + yid;
                MagicMath::Vector3 deltaT(0, 0, 0);
                deltaT[0] = heightField.at(index + resY + 1) - heightField.at(index);
                deltaT[1] = heightField.at(index + 1) - heightField.at(index);
                double deltaMag = deltaT.Normalise();
                if (deltaMag > threthold)
                {
                    deltaMag = 0;
                }
                else
                {
                    deltaMag = log(1 + alpha * deltaMag) / alpha;
                }
                DeltaVector.at(index) = deltaT * deltaMag;
            }
        }
        std::vector<double> LaplaceField(vertNum);
        for (int xid = 1; xid < resX; xid++)
        {
            for (int yid = 1; yid < resY; yid++)
            {
                int index = xid * (resY + 1) + yid;
                LaplaceField.at(index) = DeltaVector.at(index)[0] - DeltaVector.at(index - resY - 1)[0] + 
                    DeltaVector.at(index)[1] - DeltaVector.at(index - 1)[1];

            }
        }
        DebugLog << "Relief: Construct Matrix" << std::endl;
        std::vector< Eigen::Triplet<double> > tripletList;
        Eigen::VectorXd b(vertNum, 1);
        for (int xid = 0; xid < resX + 1; xid++)
        {
            for (int yid = 0; yid < resY + 1; yid++)
            {
                int index = xid * (resY + 1) + yid;
                if (xid == 0 || xid == resX || yid == 0 || yid == resY)
                {
                    tripletList.push_back( Eigen::Triplet<double>(index, index, 1) );
                    b(index) = 0;
                }
                else
                {
                    tripletList.push_back( Eigen::Triplet<double>(index, index, -4.0) );
                    tripletList.push_back( Eigen::Triplet<double>(index, index + 1, 1.0) );
                    tripletList.push_back( Eigen::Triplet<double>(index, index - 1, 1.0) );
                    tripletList.push_back( Eigen::Triplet<double>(index, index + resY + 1, 1.0) );
                    tripletList.push_back( Eigen::Triplet<double>(index, index - resY - 1, 1.0) );
                    b(index) = LaplaceField.at(index);
                }
            }
        }
        DebugLog << "Relief: Solve Matrix" << std::endl;
        Eigen::SparseMatrix<double, Eigen::ColMajor> matA(vertNum,vertNum);
        matA.setFromTriplets(tripletList.begin(), tripletList.end());
        Eigen::SparseLU<Eigen::SparseMatrix<double, Eigen::ColMajor> > solver;
        solver.compute(matA);
        if(solver.info()!= Eigen::Success) 
        {
            DebugLog << "Relief: SuperLU Failed" << std::endl;
        }
        Eigen::VectorXd res = solver.solve(b);
        //Copy results
        for (int i = 0; i < vertNum; i++)
        {
            heightField.at(i) = res(i);
        }
    }
예제 #3
0
IGL_INLINE void igl::PolyVectorFieldFinder<DerivedV, DerivedF>::
minQuadWithKnownMini(const Eigen::SparseMatrix<std::complex<typename DerivedV::Scalar> > &Q,
                          const Eigen::SparseMatrix<std::complex<typename DerivedV::Scalar> > &f,
                     const Eigen::VectorXi isConstrained,
                          const Eigen::Matrix<std::complex<typename DerivedV::Scalar>, Eigen::Dynamic, 1> &xknown,
                          Eigen::Matrix<std::complex<typename DerivedV::Scalar>, Eigen::Dynamic, 1> &x)
{
  int N = Q.rows();

  int nc = xknown.rows();
  Eigen::VectorXi known; known.setZero(nc,1);
  Eigen::VectorXi unknown; unknown.setZero(N-nc,1);

  int indk = 0, indu = 0;
  for (int i = 0; i<N; ++i)
    if (isConstrained[i])
    {
      known[indk] = i;
      indk++;
    }
    else
    {
      unknown[indu] = i;
      indu++;
    }

  Eigen::SparseMatrix<std::complex<typename DerivedV::Scalar>> Quu, Quk;

  igl::slice(Q,unknown, unknown, Quu);
  igl::slice(Q,unknown, known, Quk);


  std::vector<typename Eigen::Triplet<std::complex<typename DerivedV::Scalar> > > tripletList;

  Eigen::SparseMatrix<std::complex<typename DerivedV::Scalar> > fu(N-nc,1);

  igl::slice(f,unknown, Eigen::VectorXi::Zero(1,1), fu);

  Eigen::SparseMatrix<std::complex<typename DerivedV::Scalar> > rhs = (Quk*xknown).sparseView()+.5*fu;

  Eigen::SparseLU< Eigen::SparseMatrix<std::complex<typename DerivedV::Scalar>>> solver;
  solver.compute(-Quu);
  if(solver.info()!=Eigen::Success)
  {
    std::cerr<<"Decomposition failed!"<<std::endl;
    return;
  }
  Eigen::SparseMatrix<std::complex<typename DerivedV::Scalar>>  b  = solver.solve(rhs);
  if(solver.info()!=Eigen::Success)
  {
    std::cerr<<"Solving failed!"<<std::endl;
    return;
  }

  indk = 0, indu = 0;
  x.setZero(N,1);
  for (int i = 0; i<N; ++i)
    if (isConstrained[i])
      x[i] = xknown[indk++];
    else
      x[i] = b.coeff(indu++,0);

}