/** * The current network state is gathered from the network. * * @param factory powerflow factory * @param network network controlled by @c factory * * @return */ PFSolverHelper(PFFactory& factory, boost::shared_ptr<PFNetwork> network) : p_factory(factory), p_network(network), Xold(), Xdelta() { p_factory.setMode(State); mapper::BusVectorMap<PFNetwork> vMap(p_network); Xold = vMap.mapToVector(); // Xold->print(); X.reset(Xold->clone()); Xdelta.reset(Xold->clone()); Xdelta->zero(); p_factory.setMode(Jacobian); mapper::FullMatrixMap<PFNetwork> jMap(p_network); J = jMap.mapToMatrix(); }
/** * This is called by the nonlinear solver each iteration to build * the Jacobian from the current network state. * * @param Xcur current state estimate * @param J Jacobian */ void operator() (const math::Vector& Xcur, math::Matrix& theJ) { // In both the Netwon-Raphson and PETSc nonlinear solver (some // methods) implementations, the RHS function builder is called // before this, so we may be able to count on the current solution // being on the netork when here. // X.print(); // update(Xcur); // Set to build Jacobian p_factory.setMode(Jacobian); mapper::FullMatrixMap<PFNetwork> jMap(p_network); // build the Jacobian jMap.mapToMatrix(theJ); }
/** * Execute the iterative solve portion of the application using a * hand-coded Newton-Raphson solver * @return false if an error was encountered in the solution */ bool gridpack::powerflow::PFAppModule::solve() { bool ret = true; gridpack::utility::CoarseTimer *timer = gridpack::utility::CoarseTimer::instance(); int t_total = timer->createCategory("Powerflow: Total Application"); timer->start(t_total); // set YBus components so that you can create Y matrix int t_fact = timer->createCategory("Powerflow: Factory Operations"); timer->start(t_fact); p_factory->setYBus(); timer->stop(t_fact); int t_cmap = timer->createCategory("Powerflow: Create Mappers"); timer->start(t_cmap); p_factory->setMode(YBus); #if 0 gridpack::mapper::FullMatrixMap<PFNetwork> mMap(p_network); #endif timer->stop(t_cmap); int t_mmap = timer->createCategory("Powerflow: Map to Matrix"); timer->start(t_mmap); #if 0 boost::shared_ptr<gridpack::math::Matrix> Y = mMap.mapToMatrix(); p_busIO->header("\nY-matrix values\n"); Y->print(); // Y->save("Ybus.m"); #endif timer->stop(t_mmap); timer->start(t_fact); p_factory->setMode(S_Cal); timer->stop(t_fact); timer->start(t_cmap); gridpack::mapper::BusVectorMap<PFNetwork> vvMap(p_network); timer->stop(t_cmap); int t_vmap = timer->createCategory("Powerflow: Map to Vector"); // make Sbus components to create S vector timer->start(t_fact); p_factory->setSBus(); timer->stop(t_fact); // p_busIO->header("\nIteration 0\n"); // Set PQ timer->start(t_cmap); p_factory->setMode(RHS); gridpack::mapper::BusVectorMap<PFNetwork> vMap(p_network); timer->stop(t_cmap); timer->start(t_vmap); #ifdef USE_REAL_VALUES boost::shared_ptr<gridpack::math::RealVector> PQ = vMap.mapToRealVector(); #else boost::shared_ptr<gridpack::math::Vector> PQ = vMap.mapToVector(); #endif timer->stop(t_vmap); // PQ->print(); timer->start(t_cmap); p_factory->setMode(Jacobian); gridpack::mapper::FullMatrixMap<PFNetwork> jMap(p_network); timer->stop(t_cmap); timer->start(t_mmap); #ifdef USE_REAL_VALUES boost::shared_ptr<gridpack::math::RealMatrix> J = jMap.mapToRealMatrix(); #else boost::shared_ptr<gridpack::math::Matrix> J = jMap.mapToMatrix(); #endif timer->stop(t_mmap); // p_busIO->header("\nJacobian values\n"); // J->print(); // Create X vector by cloning PQ #ifdef USE_REAL_VALUES boost::shared_ptr<gridpack::math::RealVector> X(PQ->clone()); #else boost::shared_ptr<gridpack::math::Vector> X(PQ->clone()); #endif gridpack::utility::Configuration::CursorPtr cursor; cursor = p_config->getCursor("Configuration.Powerflow"); // Create linear solver int t_csolv = timer->createCategory("Powerflow: Create Linear Solver"); timer->start(t_csolv); #ifdef USE_REAL_VALUES gridpack::math::RealLinearSolver solver(*J); #else gridpack::math::LinearSolver solver(*J); #endif solver.configure(cursor); timer->stop(t_csolv); gridpack::ComplexType tol = 2.0*p_tolerance; int iter = 0; // First iteration X->zero(); //might not need to do this //p_busIO->header("\nCalling solver\n"); int t_lsolv = timer->createCategory("Powerflow: Solve Linear Equation"); timer->start(t_lsolv); // char dbgfile[32]; // sprintf(dbgfile,"j0.bin"); // J->saveBinary(dbgfile); // sprintf(dbgfile,"pq0.bin"); // PQ->saveBinary(dbgfile); try { solver.solve(*PQ, *X); } catch (const gridpack::Exception e) { p_busIO->header("Solver failure\n\n"); timer->stop(t_lsolv); return false; } timer->stop(t_lsolv); tol = PQ->normInfinity(); // Create timer for map to bus int t_bmap = timer->createCategory("Powerflow: Map to Bus"); int t_updt = timer->createCategory("Powerflow: Bus Update"); char ioBuf[128]; while (real(tol) > p_tolerance && iter < p_max_iteration) { // Push current values in X vector back into network components // Need to implement setValues method in PFBus class in order for this to // work timer->start(t_bmap); p_factory->setMode(RHS); vMap.mapToBus(X); timer->stop(t_bmap); // Exchange data between ghost buses (I don't think we need to exchange data // between branches) timer->start(t_updt); p_network->updateBuses(); timer->stop(t_updt); // Create new versions of Jacobian and PQ vector timer->start(t_vmap); #ifdef USE_REAL_VALUES vMap.mapToRealVector(PQ); #else vMap.mapToVector(PQ); #endif // p_busIO->header("\nnew PQ vector\n"); // PQ->print(); timer->stop(t_vmap); timer->start(t_mmap); p_factory->setMode(Jacobian); #ifdef USE_REAL_VALUES jMap.mapToRealMatrix(J); #else jMap.mapToMatrix(J); #endif timer->stop(t_mmap); // Create linear solver timer->start(t_lsolv); X->zero(); //might not need to do this // sprintf(dbgfile,"j%d.bin",iter+1); // J->saveBinary(dbgfile); // sprintf(dbgfile,"pq%d.bin",iter+1); // PQ->saveBinary(dbgfile); try { solver.solve(*PQ, *X); } catch (const gridpack::Exception e) { p_busIO->header("Solver failure\n\n"); timer->stop(t_lsolv); return false; } timer->stop(t_lsolv); tol = PQ->normInfinity(); sprintf(ioBuf,"\nIteration %d Tol: %12.6e\n",iter+1,real(tol)); p_busIO->header(ioBuf); iter++; } if (iter >= p_max_iteration) ret = false; // Push final result back onto buses timer->start(t_bmap); p_factory->setMode(RHS); vMap.mapToBus(X); timer->stop(t_bmap); // Make sure that ghost buses have up-to-date values before printing out // results timer->start(t_updt); p_network->updateBuses(); timer->stop(t_updt); timer->stop(t_total); return ret; }