78 m_equ[0]->PrintSummary(out);
81 if (
m_comm->GetRank() == 0)
83 out <<
"\tArnoldi solver type : Modified Arnoldi" << endl;
103 int nq =
m_equ[0]->UpdateFields()[0]->GetNcoeffs();
108 std::string evlFile =
m_session->GetSessionName() +
".evl";
110 if (
m_comm->GetRank() == 0)
112 evlout.open(evlFile.c_str());
116 Array<OneD, NekDouble> alpha = Array<OneD, NekDouble> (
m_kdim+1, 0.0);
117 Array<OneD, NekDouble> wr = Array<OneD, NekDouble> (
m_kdim, 0.0);
118 Array<OneD, NekDouble> wi = Array<OneD, NekDouble> (
m_kdim, 0.0);
119 Array<OneD, NekDouble> zvec = Array<OneD, NekDouble> (m_kdim*
m_kdim, 0.0);
121 Array<OneD, Array<OneD, NekDouble> > Kseq
122 = Array<OneD, Array<OneD, NekDouble> > (m_kdim + 1);
123 Array<OneD, Array<OneD, NekDouble> > Tseq
124 = Array<OneD, Array<OneD, NekDouble> > (m_kdim + 1);
125 for (i = 0; i < m_kdim + 1; ++i)
127 Kseq[i] = Array<OneD, NekDouble>(ntot, 0.0);
128 Tseq[i] = Array<OneD, NekDouble>(ntot, 0.0);
132 if(
m_session->DefinesFunction(
"InitialConditions"))
134 if (
m_comm->GetRank() == 0)
136 out <<
"\tInital vector : specified in input file " << endl;
138 m_equ[0]->SetInitialConditions(0.0,
false);
144 if (
m_comm->GetRank() == 0)
146 out <<
"\tInital vector : random " << endl;
156 if (
m_comm->GetRank() == 0)
158 out <<
"Iteration: " << 0 << endl;
162 alpha[0] =
Blas::Ddot(ntot, &Kseq[0][0], 1, &Kseq[0][0], 1);
164 alpha[0] = std::sqrt(alpha[0]);
165 Vmath::Smul(ntot, 1.0/alpha[0], Kseq[0], 1, Kseq[0], 1);
169 for (i = 1; !converged && i <=
m_kdim; ++i)
175 alpha[i] =
Blas::Ddot(ntot, &Kseq[i][0], 1, &Kseq[i][0], 1);
177 alpha[i] = std::sqrt(alpha[i]);
180 Vmath::Smul(ntot, 1.0/alpha[i], Kseq[i], 1, Kseq[i], 1);
183 for (
int k = 0; k < i + 1; ++k)
189 EV_small(Tseq, ntot, alpha, i, zvec, wr, wi, resnorm);
192 converged =
EV_test(i, i, zvec, wr, wi, resnorm,
193 std::min(i,
m_nvec), evlout, resid0);
194 converged = max (converged, 0);
196 if (
m_comm->GetRank() == 0)
198 out <<
"Iteration: " << i <<
" (residual : " << resid0
206 for (i = m_kdim + 1; !converged && i <=
m_nits; ++i)
210 for (
int j = 1; j <=
m_kdim; ++j)
212 alpha[j-1] = alpha[j];
217 EV_update(Kseq[m_kdim - 1], Kseq[m_kdim]);
221 &Kseq[m_kdim][0], 1);
222 m_comm->AllReduce(alpha[m_kdim],
224 alpha[
m_kdim] = std::sqrt(alpha[m_kdim]);
225 Vmath::Smul(ntot, 1.0/alpha[m_kdim], Kseq[m_kdim], 1,
229 for (
int k = 0; k < m_kdim + 1; ++k)
235 EV_small(Tseq, ntot, alpha, m_kdim, zvec, wr, wi, resnorm);
238 converged =
EV_test(i, m_kdim, zvec, wr, wi, resnorm,
241 if (
m_comm->GetRank() == 0)
243 out <<
"Iteration: " << i <<
" (residual : "
244 << resid0 <<
")" <<endl;
255 for(j = 0; j <
m_equ[0]->GetNvariables(); ++j)
259 if (
m_comm->GetRank() == 0)
261 out <<
"L 2 error (variable " <<
m_equ[0]->GetVariable(j)
262 <<
") : " << vL2Error << endl;
263 out <<
"L inf error (variable " <<
m_equ[0]->GetVariable(j)
264 <<
") : " << vLinfError << endl;
269 EV_post(Tseq, Kseq, ntot, min(--i, m_kdim),
m_nvec, zvec, wr, wi,
277 if (
m_comm->GetRank() == 0)
288 Array<OneD, NekDouble> &src,
289 Array<OneD, NekDouble> &tgt)
293 m_equ[0]->TransCoeffToPhys();
299 Array<OneD, MultiRegions::ExpListSharedPtr> fields;
300 fields =
m_equ[0]->UpdateFields();
304 m_equ[1]->TransCoeffToPhys();
318 Array<
OneD, Array<OneD, NekDouble> > &Kseq,
320 const Array<OneD, NekDouble> &alpha,
322 Array<OneD, NekDouble> &zvec,
323 Array<OneD, NekDouble> &wr,
324 Array<OneD, NekDouble> &wi,
327 int kdimp = kdim + 1;
330 Array<OneD, NekDouble> R(kdimp * kdimp, 0.0);
331 Array<OneD, NekDouble> H(kdimp * kdim, 0.0);
332 Array<OneD, NekDouble> rwork(lwork, 0.0);
335 for (
int i = 0; i < kdimp; ++i)
339 gsc = std::sqrt(gsc);
340 ASSERTL0(gsc != 0.0,
"Vectors are linearly independent.");
343 Vmath::Smul(ntot, 1.0/gsc, Kseq[i], 1, Kseq[i], 1);
345 for (
int j = i + 1; j < kdimp; ++j)
347 gsc =
Blas::Ddot(ntot, &Kseq[i][0], 1, &Kseq[j][0], 1);
349 Vmath::Svtvp(ntot, -gsc, Kseq[i], 1, Kseq[j], 1, Kseq[j], 1);
355 for (
int i = 0; i < kdim; ++i)
357 for (
int j = 0; j < kdim; ++j)
359 H[j*kdim+i] = alpha[j+1] * R[(j+1)*kdimp+i]
360 -
Vmath::Dot(j, &H[0] + i, kdim, &R[0] + j*kdimp, 1);
361 H[j*kdim+i] /= R[j*kdimp+j];
365 H[(kdim-1)*kdim+kdim] = alpha[kdim]
366 * std::fabs(R[kdim*kdimp+kdim] / R[(kdim-1)*kdimp + kdim-1]);
368 Lapack::dgeev_(
'N',
'V', kdim, &H[0], kdim, &wr[0], &wi[0], 0, 1,
369 &zvec[0], kdim, &rwork[0], lwork, ier);
373 resnorm = H[(kdim-1)*kdim + kdim];
383 Array<OneD, NekDouble> &zvec,
384 Array<OneD, NekDouble> &wr,
385 Array<OneD, NekDouble> &wi,
394 Array<OneD, NekDouble> resid(kdim);
395 for (
int i = 0; i < kdim; ++i)
398 &zvec[0] + i*kdim, 1));
399 resid[i] = resnorm * std::fabs(zvec[kdim - 1 + i*kdim]) / tmp;
402 resid[i-1] = resid[i] = hypot(resid[i-1], resid[i]);
406 EV_sort(zvec, wr, wi, resid, kdim);
413 if (
m_comm->GetRank() == 0)
415 evlout <<
"-- Iteration = " << itrn <<
", H(k+1, k) = "
418 evlout.setf(ios::scientific, ios::floatfield);
421 evlout <<
"EV Magnitude Angle Growth "
422 <<
"Frequency Residual" << endl;
426 evlout <<
"EV Real Imaginary inverse real "
427 <<
"inverse imag Residual" << endl;
430 for (
int i = 0; i < kdim; i++)
432 WriteEvs(evlout,i,wr[i],wi[i],resid[i]);
436 resid0 = resid[nvec-1];
445 Array<OneD, NekDouble> &evec,
446 Array<OneD, NekDouble> &wr,
447 Array<OneD, NekDouble> &wi,
448 Array<OneD, NekDouble> &test,
451 Array<OneD, NekDouble> z_tmp(dim,0.0);
453 for (
int j = 1; j < dim; ++j)
460 while (i >= 0 && test[i] > te_tmp)
465 Vmath::Vcopy(dim, &evec[0] + i*dim, 1, &evec[0] + (i+1)*dim, 1);
471 Vmath::Vcopy(dim, &z_tmp[0], 1, &evec[0] + (i+1)*dim, 1);
480 Array<
OneD, Array<OneD, NekDouble> > &Tseq,
481 Array<
OneD, Array<OneD, NekDouble> > &Kseq,
485 Array<OneD, NekDouble> &zvec,
486 Array<OneD, NekDouble> &wr,
487 Array<OneD, NekDouble> &wi,
493 ASSERTL0(
false,
"Convergence was not achieved within the "
494 "prescribed number of iterations.");
499 ASSERTL0(
false,
"Minimum residual reached.");
501 else if (icon == nvec)
504 EV_big(Tseq, Kseq, ntot, kdim, icon, zvec, wr, wi);
505 Array<OneD, MultiRegions::ExpListSharedPtr> fields
506 =
m_equ[0]->UpdateFields();
508 for (
int j = 0; j < icon; ++j)
510 std::string file =
m_session->GetSessionName() +
"_eig_"
511 + boost::lexical_cast<std::string>(j);
519 ASSERTL0(
false,
"Unrecognised value.");
528 Array<
OneD, Array<OneD, NekDouble> > &bvecs,
529 Array<
OneD, Array<OneD, NekDouble> > &evecs,
533 Array<OneD, NekDouble> &zvec,
534 Array<OneD, NekDouble> &wr,
535 Array<OneD, NekDouble> &wi)
540 for (
int j = 0; j < nvec; ++j)
543 for (
int i = 0; i < kdim; ++i)
545 wgt = zvec[i + j*kdim];
546 Vmath::Svtvp(ntot, wgt, bvecs[i], 1, evecs[j], 1, evecs[j], 1);
551 for (
int i = 0; i < nvec; ++i)
555 norm =
Blas::Ddot(ntot, &evecs[i][0], 1, &evecs[i][0], 1);
557 norm = std::sqrt(norm);
558 Vmath::Smul(ntot, 1.0/norm, evecs[i], 1, evecs[i], 1);
562 norm =
Blas::Ddot(ntot, &evecs[i][0], 1, &evecs[i][0], 1);
563 norm +=
Blas::Ddot(ntot, &evecs[i+1][0], 1, &evecs[i+1][0], 1);
565 norm = std::sqrt(norm);
567 Vmath::Smul(ntot, 1.0/norm, evecs[i], 1, evecs[i], 1);
568 Vmath::Smul(ntot, 1.0/norm, evecs[i+1], 1, evecs[i+1], 1);