Ejemplo n.º 1
0
void
EigenExecutionerBase::inversePowerIteration(unsigned int min_iter,
                                            unsigned int max_iter,
                                            Real pfactor,
                                            bool cheb_on,
                                            Real tol_eig,
                                            Real tol_x,
                                            bool echo,
                                            bool output_convergence,
                                            Real time_base,
                                            Real & k,
                                            Real & initial_res)
{
  mooseAssert(max_iter>=min_iter, "Maximum number of power iterations must be greater than or equal to its minimum");
  mooseAssert(pfactor>0.0, "Invaid linear convergence tolerance");
  mooseAssert(tol_eig>0.0, "Invalid eigenvalue tolerance");
  mooseAssert(tol_x>0.0, "Invalid solution norm tolerance");
  if ( _bx_execflag != EXEC_TIMESTEP && _bx_execflag != EXEC_RESIDUAL)
    mooseError("rhs postprocessor for the power method has to be executed on timestep or residual");
  if ( _xdiff_execflag != EXEC_TIMESTEP && _xdiff_execflag != EXEC_RESIDUAL)
    mooseError("xdiff postprocessor for the power method has to be executed on timestep or residual");

  // not perform any iteration when max_iter==0
  if (max_iter==0) return;

  // turn off nonlinear flag so that RHS kernels opterate on previous solutions
  _eigen_sys.eigenKernelOnOld();

  // FIXME: currently power iteration use old and older solutions,
  // so save old and older solutions before they are changed by the power iteration
  _eigen_sys.saveOldSolutions();

  // _es.parameters.print(Moose::out);
  // save solver control parameters to be modified by the power iteration
  Real tol1 = _problem.es().parameters.get<Real> ("linear solver tolerance");
  unsigned int num1 = _problem.es().parameters.get<unsigned int>("nonlinear solver maximum iterations");

  // every power iteration is a linear solve, so set nonlinear iteration number to one
  _problem.es().parameters.set<Real> ("linear solver tolerance") = pfactor;
  _problem.es().parameters.set<unsigned int>("nonlinear solver maximum iterations") = 1;

  if (echo)
  {
    Moose::out << std::endl;
    Moose::out << " Power iterations starts" << std::endl;
    Moose::out << " ________________________________________________________________________________ " << std::endl;
  }

  // some iteration variables
  Real k_old = 0.0;

  std::vector<Real> keff_history;
  std::vector<Real> diff_history;

  unsigned int iter = 0;

  // power iteration loop...
  // Note: |Bx|/k will stay constant one!
  makeBXConsistent(k);
  while (true)
  {
    if (echo)  Moose::out << " Power iteration= "<< iter << std::endl;

    // important: solutions of aux system is also copied
    _problem.copyOldSolutions();
    _problem.updateMaterials();
    k_old = k;

    // FIXME: timestep needs to be changed to step
    _problem.onTimestepBegin(); // this will copy postprocessors to old
    _problem.timestepSetup();
    _problem.computeUserObjects(EXEC_TIMESTEP_BEGIN, UserObjectWarehouse::PRE_AUX);
    _problem.computeAuxiliaryKernels(EXEC_TIMESTEP_BEGIN);
    _problem.computeUserObjects(EXEC_TIMESTEP_BEGIN, UserObjectWarehouse::POST_AUX);

    preIteration();
    _problem.solve();
    postIteration();

    // FIXME: timestep needs to be changed to step
    _problem.computeUserObjects(EXEC_TIMESTEP, UserObjectWarehouse::PRE_AUX);
    _problem.computeAuxiliaryKernels(EXEC_TIMESTEP);
    _problem.computeUserObjects(EXEC_TIMESTEP, UserObjectWarehouse::POST_AUX);
    _problem.onTimestepEnd();

    // save the initial residual
    if (iter==0) initial_res = _eigen_sys._initial_residual;

    // update eigenvalue
    k = k_old * _source_integral / _source_integral_old;

    // synchronize _eigenvalue with |Bx| for output purpose
    // Note: if using MOOSE output system, eigenvalue output will be one iteration behind.
    //       Also this will affect EigenKernels with eigen=false.
    _eigenvalue = k;

    if (echo && (!output_convergence))
    {
      // output on screen the convergence history only when we want to and MOOSE output system is not used
      keff_history.push_back(k);
      if (_solution_diff) diff_history.push_back(*_solution_diff);

      std::ios_base::fmtflags flg = Moose::out.flags();
      std::streamsize pcs = Moose::out.precision();
      if (_solution_diff)
      {
        Moose::out << std::endl;
        Moose::out << " +================+=====================+=====================+\n";
        Moose::out << " | iteration      | eigenvalue          | solution_difference |\n";
        Moose::out << " +================+=====================+=====================+\n";
        unsigned int j = 0;
        if (keff_history.size()>10)
        {
          Moose::out << " :                :                     :                     :\n";
          j = keff_history.size()-10;
        }
        for (; j<keff_history.size(); j++)
          Moose::out << " | " << std::setw(14) << j
                     << " | " << std::setw(19) << std::scientific << std::setprecision(8) << keff_history[j]
                     << " | " << std::setw(19) << std::scientific << std::setprecision(8) << diff_history[j]
                     << " |\n";
        Moose::out << " +================+=====================+=====================+\n" << std::flush;
        Moose::out << std::endl;
      }
      else
      {
        Moose::out << std::endl;
        Moose::out << " +================+=====================+\n";
        Moose::out << " | iteration      | eigenvalue          |\n";
        Moose::out << " +================+=====================+\n";
        unsigned int j = 0;
        if (keff_history.size()>10)
        {
          Moose::out << " :                :                     :\n";
          j = keff_history.size()-10;
        }
        for (; j<keff_history.size(); j++)
          Moose::out << " | " << std::setw(14) << j
                     << " | " << std::setw(19) << std::scientific << std::setprecision(8) << keff_history[j]
                     << " |\n";
        Moose::out << " +================+=====================+\n" << std::flush;
        Moose::out << std::endl;
      }
      Moose::out.flags(flg);
      Moose::out.precision(pcs);
    }

    // increment iteration number here
    iter++;

    if (cheb_on)
    {
      chebyshev(iter);
      if (echo)
        Moose::out << " Chebyshev step: " << chebyshev_parameters.icheb << std::endl;
    }

    if (echo)
      Moose::out << " ________________________________________________________________________________ "
                 << std::endl;

    // not perform any convergence check when number of iterations is less than min_iter
    if (iter>=min_iter)
    {
      // no need to check convergence of the last iteration
      if (iter!=max_iter)
      {
        bool converged = true;
        Real keff_error = fabs(k_old-k)/k;
        if (keff_error>tol_eig) converged = false;
        if (_solution_diff)
          if (*_solution_diff > tol_x) converged = false;
        if (converged) break;
      }
      else
        break;
    }

    // use output system to dump iteration history
    if (output_convergence)
    {
      // we need to tempararily change system time to obtain the right output
      // FIXME: if 'step' capability is available, we will not need to do this.
      Real t = _problem.time();
      _problem.time() = time_base + Real(iter)/max_iter;
      _output_warehouse.outputStep();
      _problem.time() = t;
    }
  }

  // restore parameters changed by the executioner
  _problem.es().parameters.set<Real> ("linear solver tolerance") = tol1;
  _problem.es().parameters.set<unsigned int>("nonlinear solver maximum iterations") = num1;

  //FIXME: currently power iteration use old and older solutions, so restore them
  _eigen_sys.restoreOldSolutions();
}
Ejemplo n.º 2
0
void
EigenExecutionerBase::inversePowerIteration(unsigned int min_iter,
                                            unsigned int max_iter,
                                            Real pfactor,
                                            bool cheb_on,
                                            Real tol_eig,
                                            bool echo,
                                            PostprocessorName xdiff,
                                            Real tol_x,
                                            Real & k,
                                            Real & initial_res)
{
  mooseAssert(max_iter>=min_iter, "Maximum number of power iterations must be greater than or equal to its minimum");
  mooseAssert(pfactor>0.0, "Invaid linear convergence tolerance");
  mooseAssert(tol_eig>0.0, "Invalid eigenvalue tolerance");
  mooseAssert(tol_x>0.0, "Invalid solution norm tolerance");

  // obtain the solution diff
  const PostprocessorValue * solution_diff = NULL;
  if (xdiff != "")
  {
    solution_diff = &getPostprocessorValueByName(xdiff);
    ExecFlagType xdiff_execflag = _problem.getUserObject<UserObject>(xdiff).execBitFlags();
    if ((xdiff_execflag & EXEC_LINEAR) == EXEC_NONE)
      mooseError("Postprocessor "+xdiff+" requires execute_on = 'linear'");
  }

  // not perform any iteration when max_iter==0
  if (max_iter==0) return;

  // turn off nonlinear flag so that RHS kernels opterate on previous solutions
  _eigen_sys.eigenKernelOnOld();

  // FIXME: currently power iteration use old and older solutions,
  // so save old and older solutions before they are changed by the power iteration
  _eigen_sys.saveOldSolutions();

  // save solver control parameters to be modified by the power iteration
  Real tol1 = _problem.es().parameters.get<Real> ("linear solver tolerance");
  unsigned int num1 = _problem.es().parameters.get<unsigned int>("nonlinear solver maximum iterations");

  // every power iteration is a linear solve, so set nonlinear iteration number to one
  _problem.es().parameters.set<Real> ("linear solver tolerance") = pfactor;
  _problem.es().parameters.set<unsigned int>("nonlinear solver maximum iterations") = 1;

  if (echo)
  {
    _console << std::endl;
    _console << " Power iterations starts" << std::endl;
    _console << " ________________________________________________________________________________ " << std::endl;
  }

  // some iteration variables
  Real k_old = 0.0;
  Real & source_integral_old = getPostprocessorValueOld("bx_norm");
  Real saved_source_integral_old = source_integral_old;
  Chebyshev_Parameters chebyshev_parameters;

  std::vector<Real> keff_history;
  std::vector<Real> diff_history;

  unsigned int iter = 0;

  // power iteration loop...
  // Note: |Bx|/k will stay constant one!
  makeBXConsistent(k);
  while (true)
  {
    if (echo)
      _console << " Power iteration= "<< iter << std::endl;

    // important: solutions of aux system is also copied
    _problem.advanceState();
    k_old = k;
    source_integral_old = _source_integral;

    preIteration();
    _problem.solve();
    postIteration();

    // save the initial residual
    if (iter==0) initial_res = _eigen_sys._initial_residual_before_preset_bcs;

    // update eigenvalue
    k = k_old * _source_integral / source_integral_old;
    _eigenvalue = k;

    if (echo)
    {
      // output on screen the convergence history only when we want to and MOOSE output system is not used
      keff_history.push_back(k);
      if (solution_diff) diff_history.push_back(*solution_diff);

      std::stringstream ss;
      if (solution_diff)
      {
        ss << std::endl;
        ss << " +================+=====================+=====================+\n";
        ss << " | iteration      | eigenvalue          | solution_difference |\n";
        ss << " +================+=====================+=====================+\n";
        unsigned int j = 0;
        if (keff_history.size()>10)
        {
          ss << " :                :                     :                     :\n";
          j = keff_history.size()-10;
        }
        for (; j<keff_history.size(); j++)
          ss << " | " << std::setw(14) << j
             << " | " << std::setw(19) << std::scientific << std::setprecision(8) << keff_history[j]
             << " | " << std::setw(19) << std::scientific << std::setprecision(8) << diff_history[j]
             << " |\n";
        ss << " +================+=====================+=====================+\n" << std::flush;
      }
      else
      {
        ss << std::endl;
        ss << " +================+=====================+\n";
        ss << " | iteration      | eigenvalue          |\n";
        ss << " +================+=====================+\n";
        unsigned int j = 0;
        if (keff_history.size()>10)
        {
          ss << " :                :                     :\n";
          j = keff_history.size()-10;
        }
        for (; j<keff_history.size(); j++)
          ss << " | " << std::setw(14) << j
             << " | " << std::setw(19) << std::scientific << std::setprecision(8) << keff_history[j]
             << " |\n";
        ss << " +================+=====================+\n" << std::flush;
        ss << std::endl;
      }
      _console << ss.str() << std::endl;
    }

    // increment iteration number here
    iter++;

    if (cheb_on)
    {
      chebyshev(chebyshev_parameters, iter, solution_diff);
      if (echo)
        _console << " Chebyshev step: " << chebyshev_parameters.icheb << std::endl;
    }

    if (echo)
      _console << " ________________________________________________________________________________ "
               << std::endl;

    // not perform any convergence check when number of iterations is less than min_iter
    if (iter>=min_iter)
    {
      // no need to check convergence of the last iteration
      if (iter!=max_iter)
      {
        bool converged = true;
        Real keff_error = fabs(k_old-k)/k;
        if (keff_error>tol_eig) converged = false;
        if (solution_diff)
          if (*solution_diff > tol_x) converged = false;
        if (converged) break;
      }
      else
        break;
    }
  }
  source_integral_old = saved_source_integral_old;

  // restore parameters changed by the executioner
  _problem.es().parameters.set<Real> ("linear solver tolerance") = tol1;
  _problem.es().parameters.set<unsigned int>("nonlinear solver maximum iterations") = num1;

  //FIXME: currently power iteration use old and older solutions, so restore them
  _eigen_sys.restoreOldSolutions();
}
Ejemplo n.º 3
0
void az_lsp(float * a,		/* input : LP filter coefficients                     */
	    float * lsp,	/* output: Line spectral pairs (in the cosine domain) */
	    float * old_lsp	/* input : LSP vector from past frame                 */
    )
{
	int i, j, nf, ip;
	float xlow, ylow, xhigh, yhigh, xmid, ymid, xint;
	float *coef;

	float f1[NC + 1], f2[NC + 1];

    /*-------------------------------------------------------------*
    * find the sum and diff polynomials F1(z) and F2(z)           *
    *      F1(z) = [A(z) + z^11 A(z^-1)]/(1+z^-1)                 *
    *      F2(z) = [A(z) - z^11 A(z^-1)]/(1-z^-1)                 *
    *-------------------------------------------------------------*/
	f1[0] = (float) 1.0;
	f2[0] = (float) 1.0;
	for (i = 1, j = M; i <= NC; i++, j--) {
		f1[i] = a[i] + a[j] - f1[i - 1];
		f2[i] = a[i] - a[j] + f2[i - 1];
	}

    /*---------------------------------------------------------------------*
    * Find the LSPs (roots of F1(z) and F2(z) ) using the                 *
    * Chebyshev polynomial evaluation.                                    *
    * The roots of F1(z) and F2(z) are alternatively searched.            *
    * We start by finding the first root of F1(z) then we switch          *
    * to F2(z) then back to F1(z) and so on until all roots are found.    *
    *                                                                     *
    *  - Evaluate Chebyshev pol. at grid points and check for sign change.*
    *  - If sign change track the root by subdividing the interval        *
    *    NO_ITER times and ckecking sign change.                          *
    *---------------------------------------------------------------------*/
	nf = 0;			/* number of found frequencies */
	ip = 0;			/* flag to first polynomial   */

	coef = f1;		/* start with F1(z) */

	xlow = grid[0];
	ylow = chebyshev(xlow, coef, NC);

	j = 0;
	while ((nf < M) && (j < GRID_POINTS)) {
		j++;
		xhigh = xlow;
		yhigh = ylow;
		xlow = grid[j];
		ylow = chebyshev(xlow, coef, NC);

		if (ylow * yhigh <= (float) 0.0) {	/* if sign change new root exists */
			j--;

			/* divide the interval of sign change by 4 */

			for (i = 0; i < 4; i++) {
				xmid = (float) 0.5 *(xlow + xhigh);
				ymid = chebyshev(xmid, coef, NC);
				if (ylow * ymid <= (float) 0.0) {
					yhigh = ymid;
					xhigh = xmid;
				} else {
					ylow = ymid;
					xlow = xmid;
				}
			}

			/* linear interpolation for evaluating the root */

			xint = xlow - ylow * (xhigh - xlow) / (yhigh - ylow);

			lsp[nf] = xint;	/* new root */
			nf++;

			ip = 1 - ip;	/* flag to other polynomial    */
			coef = ip ? f2 : f1;	/* pointer to other polynomial */

			xlow = xint;
			ylow = chebyshev(xlow, coef, NC);
		}
	}

	/* Check if M roots found */
	/* if not use the LSPs from previous frame */

	if (nf < M) {
		for (i = 0; i < M; i++)
			lsp[i] = old_lsp[i];
	}
	return;
}