36 #include <boost/algorithm/string.hpp>
71 int expdim =
m_graph->GetMeshDimension();
79 ASSERTL0(
false,
"Last field is defined as pressure but this is not suitable for this solver, please remove this field as it is implicitly defined");
88 ASSERTL0(
m_fields.num_elements() > 2,
"Expect to have three at least three components of velocity variables");
105 for(i =0 ; i <
m_velocity.num_elements(); ++i)
116 ASSERTL0(nz <=2 ,
"For single mode calculation can only have nz <= 2");
117 if(
m_session->DefinesSolverInfo(
"BetaZero"))
136 for(i = 2; i < nz; ++i)
143 else if (expdim == 3)
146 ASSERTL0(
false,
"Setup mapping aray");
150 ASSERTL0(
false,
"Exp dimension not recognised");
156 std::string vExtrapolation =
"Standard";
158 if (
m_session->DefinesSolverInfo(
"Extrapolation"))
160 vExtrapolation =
m_session->GetSolverInfo(
"Extrapolation");
196 ASSERTL1(
m_npointsZ <=2,
"Only expected a maxmimum of two planes in single mode linear NS solver");
227 for(n = 1; n < nz; ++n)
423 for(n = 0; n < nel; ++n)
427 nsize_bndry_p1[n] = nsize_bndry[n]+nz_loc;
428 nsize_int [n] = (nvel*
m_fields[
m_velocity[0]]->GetExp(eid)->GetNcoeffs()*nz_loc - nsize_bndry[n]);
429 nsize_p[n] =
m_pressure->GetExp(eid)->GetNcoeffs()*nz_loc;
430 nsize_p_m1[n] = nsize_p[n]-nz_loc;
460 for(n = 0; n < nel; ++n)
463 nbndry = nsize_bndry[n];
465 k = nsize_bndry_p1[n];
480 locExp->GetBoundaryMap(bmap);
481 locExp->GetInteriorMap(imap);
485 locExp->DetShapeType(),
492 int nbmap = bmap.num_elements();
493 int nimap = imap.num_elements();
497 int psize =
m_pressure->GetExp(eid)->GetNcoeffs();
498 int pqsize =
m_pressure->GetExp(eid)->GetTotPoints();
503 if(AddAdvectionTerms ==
false)
509 CondMat = locExp->GetLocStaticCondMatrix(helmkey);
511 for(k = 0; k < nvel*nz_loc; ++k)
514 rows = SubBlock.GetRows();
515 cols = SubBlock.GetColumns();
516 for(i = 0; i < rows; ++i)
518 for(j = 0; j < cols; ++j)
520 (*Ah)(i+k*rows,j+k*cols) =
m_kinvis*SubBlock(i,j);
525 for(k = 0; k < nvel*nz_loc; ++k)
529 rows = SubBlock.GetRows();
530 cols = SubBlock.GetColumns();
531 for(i = 0; i < rows; ++i)
533 for(j = 0; j < cols; ++j)
535 (*B)(i+k*rows,j+k*cols) = SubBlock(i,j);
536 (*C)(i+k*rows,j+k*cols) =
m_kinvis*SubBlock1(j,i);
541 for(k = 0; k < nvel*nz_loc; ++k)
545 rows = SubBlock.GetRows();
546 cols = SubBlock.GetColumns();
547 for(i = 0; i < rows; ++i)
549 for(j = 0; j < cols; ++j)
551 (*D)(i+k*rows,j+k*cols) = inv_kinvis*SubBlock(i,j);
558 for(i = 0; i < bmap.num_elements(); ++i)
562 coeffs[bmap[i]] = 1.0;
566 for(j = 0; j < nvel; ++j)
568 if( (nz_loc == 2)&&(j == 2))
574 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
576 Blas::Dcopy(psize,&(pcoeffs)[0],1,
578 ((nz_loc*j+1)*bmap.num_elements()+i)*nsize_p[n],1);
581 Blas::Dcopy(psize,&(pcoeffs)[0],1,
583 ((nz_loc*j)*bmap.num_elements()+i)*nsize_p[n]+psize,1);
591 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
593 for(k = 0; k < nz_loc; ++k)
595 Blas::Dcopy(psize,&(pcoeffs)[0],1,
597 ((nz_loc*j+k)*bmap.num_elements()+i)*nsize_p[n]+ k*psize,1);
604 for(i = 0; i < imap.num_elements(); ++i)
608 coeffs[imap[i]] = 1.0;
612 for(j = 0; j < nvel; ++j)
614 if( (nz_loc == 2)&&(j == 2))
620 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
622 Blas::Dcopy(psize,&(pcoeffs)[0],1,
624 ((nz_loc*j+1)*imap.num_elements()+i)*nsize_p[n],1);
627 Blas::Dcopy(psize,&(pcoeffs)[0],1,
629 ((nz_loc*j)*imap.num_elements()+i)*nsize_p[n]+psize,1);
639 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
642 for(k = 0; k < nz_loc; ++k)
644 Blas::Dcopy(psize,&(pcoeffs)[0],1,
646 ((nz_loc*j+k)*imap.num_elements()+i)*nsize_p[n]+ k*psize,1);
660 ->GetLocMatrix(helmkey));
664 NekDouble HelmMatScale = HelmMat.Scale();
665 int HelmMatRows = HelmMat.GetRows();
670 locExp->DetShapeType(),
673 ->GetLocMatrix(masskey);
682 int npoints = locExp->GetTotPoints();
685 if(IsLinearNSEquation)
690 for(nv = 0; nv < nvel; ++nv)
692 for(nv1 = 0; nv1 < nvel; ++nv1)
694 if(cnt < nvel*nvel-1)
696 AdvDeriv[cnt+1] = AdvDeriv[cnt] + npoints;
713 for(i = 0; i < nbmap; ++i)
718 coeffs[bmap[i]] = 1.0;
719 locExp->BwdTrans(coeffs,phys);
721 for(k = 0; k < nvel*nz_loc; ++k)
723 for(j = 0; j < nbmap; ++j)
726 Ah_data[i+k*nbmap + (j+k*nbmap)*AhRows] +=
m_kinvis*HelmMatScale*HelmMat_data[bmap[i] + HelmMatRows*bmap[j]];
729 for(j = 0; j < nimap; ++j)
731 B_data[i+k*nbmap + (j+k*nimap)*nbndry] +=
m_kinvis*HelmMatScale*HelmMat_data[bmap[i]+HelmMatRows*imap[j]];
737 for(k = 0; k < nvel; ++k)
739 for(j = 0; j < nbmap; ++j)
741 Ah_data[i+2*k*nbmap + (j+(2*k+1)*nbmap)*AhRows] -= lambda_imag*(*MassMat)(bmap[i],bmap[j]);
744 for(j = 0; j < nbmap; ++j)
746 Ah_data[i+(2*k+1)*nbmap + (j+2*k*nbmap)*AhRows] += lambda_imag*(*MassMat)(bmap[i],bmap[j]);
749 for(j = 0; j < nimap; ++j)
751 B_data[i+2*k*nbmap + (j+(2*k+1)*nimap)*nbndry] -= lambda_imag*(*MassMat)(bmap[i],imap[j]);
754 for(j = 0; j < nimap; ++j)
756 B_data[i+(2*k+1)*nbmap + (j+2*k*nimap)*nbndry] += lambda_imag*(*MassMat)(bmap[i],imap[j]);
764 for(k = 0; k < nvel; ++k)
766 if((nz_loc == 2)&&(k == 2))
773 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
774 Blas::Dcopy(psize,&(pcoeffs)[0],1,
776 ((nz_loc*k+1)*bmap.num_elements()+i)*nsize_p[n],1);
780 Blas::Dcopy(psize,&(pcoeffs)[0],1,
782 ((nz_loc*k)*bmap.num_elements()+i)*nsize_p[n]+psize,1);
786 Advtmp = Advfield[k] + phys_offset,
787 1,deriv,1,tmpphys,1);
789 locExp->IProductWRTBase(tmpphys,coeffs);
793 for(nv = 0; nv < nvel; ++nv)
795 for(j = 0; j < nbmap; ++j)
797 Ah_data[j+2*nv*nbmap + (i+(2*nv+1)*nbmap)*AhRows] +=
801 for(j = 0; j < nimap; ++j)
803 C_data[i+(2*nv+1)*nbmap + (j+2*nv*nimap)*nbndry] +=
810 for(nv = 0; nv < nvel; ++nv)
812 for(j = 0; j < nbmap; ++j)
814 Ah_data[j+(2*nv+1)*nbmap + (i+2*nv*nbmap)*AhRows] +=
818 for(j = 0; j < nimap; ++j)
820 C_data[i+2*nv*nbmap + (j+(2*nv+1)*nimap)*nbndry] +=
831 Advtmp = Advfield[k] + phys_offset,
832 1,deriv,1,tmpphys,1);
833 locExp->IProductWRTBase(tmpphys,coeffs);
836 for(nv = 0; nv < nvel*nz_loc; ++nv)
838 for(j = 0; j < nbmap; ++j)
840 Ah_data[j+nv*nbmap + (i+nv*nbmap)*AhRows] +=
844 for(j = 0; j < nimap; ++j)
846 C_data[i+nv*nbmap + (j+nv*nimap)*nbndry] +=
852 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
853 for(j = 0; j < nz_loc; ++j)
855 Blas::Dcopy(psize,&(pcoeffs)[0],1,
857 ((nz_loc*k+j)*bmap.num_elements() + i)*nsize_p[n]+ j*psize,1);
862 if(IsLinearNSEquation)
864 for(nv = 0; nv < nvel; ++nv)
870 locExp->IProductWRTBase(tmpphys,coeffs);
872 for(
int n1 = 0; n1 < nz_loc; ++n1)
874 for(j = 0; j < nbmap; ++j)
876 Ah_data[j+(k*nz_loc+n1)*nbmap +
877 (i+(nv*nz_loc+n1)*nbmap)*AhRows] +=
881 for(j = 0; j < nimap; ++j)
883 C_data[i+(nv*nz_loc+n1)*nbmap +
884 (j+(k*nz_loc+n1)*nimap)*nbndry] +=
894 for(i = 0; i < nimap; ++i)
898 coeffs[imap[i]] = 1.0;
899 locExp->BwdTrans(coeffs,phys);
901 for(k = 0; k < nvel*nz_loc; ++k)
903 for(j = 0; j < nbmap; ++j)
905 C_data[j+k*nbmap + (i+k*nimap)*nbndry] +=
m_kinvis*HelmMatScale*HelmMat_data[imap[i]+HelmMatRows*bmap[j]];
908 for(j = 0; j < nimap; ++j)
910 D_data[i+k*nimap + (j+k*nimap)*nint] +=
m_kinvis*HelmMatScale*HelmMat_data[imap[i]+HelmMatRows*imap[j]];
916 for(k = 0; k < nvel; ++k)
918 for(j = 0; j < nbmap; ++j)
920 C_data[j+2*k*nbmap + (i+(2*k+1)*nimap)*nbndry] += lambda_imag*(*MassMat)(bmap[j],imap[i]);
923 for(j = 0; j < nbmap; ++j)
925 C_data[j+(2*k+1)*nbmap + (i+2*k*nimap)*nbndry] -= lambda_imag*(*MassMat)(bmap[j],imap[i]);
928 for(j = 0; j < nimap; ++j)
930 D_data[i+2*k*nimap + (j+(2*k+1)*nimap)*nint] -= lambda_imag*(*MassMat)(imap[i],imap[j]);
933 for(j = 0; j < nimap; ++j)
935 D_data[i+(2*k+1)*nimap + (j+2*k*nimap)*nint] += lambda_imag*(*MassMat)(imap[i],imap[j]);
941 for(k = 0; k < nvel; ++k)
943 if((nz_loc == 2)&&(k == 2))
949 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
950 Blas::Dcopy(psize,&(pcoeffs)[0],1,
952 ((nz_loc*k+1)*imap.num_elements()+i)*nsize_p[n],1);
955 Blas::Dcopy(psize,&(pcoeffs)[0],1,
957 ((nz_loc*k)*imap.num_elements()+i)*nsize_p[n]+psize,1);
961 Vmath::Vmul(npoints, Advtmp = Advfield[k] + phys_offset,1,deriv,1,tmpphys,1);
962 locExp->IProductWRTBase(tmpphys,coeffs);
965 for(nv = 0; nv < nvel; ++nv)
967 for(j = 0; j < nbmap; ++j)
969 B_data[j+2*nv*nbmap + (i+(2*nv+1)*nimap)*nbndry] +=
973 for(j = 0; j < nimap; ++j)
975 D_data[j+2*nv*nimap + (i+(2*nv+1)*nimap)*nint] +=
981 for(nv = 0; nv < nvel; ++nv)
983 for(j = 0; j < nbmap; ++j)
985 B_data[j+(2*nv+1)*nbmap + (i+2*nv*nimap)*nbndry] +=
989 for(j = 0; j < nimap; ++j)
991 D_data[j+(2*nv+1)*nimap + (i+2*nv*nimap)*nint] +=
1005 Advtmp = Advfield[k] + phys_offset,
1006 1,deriv,1,tmpphys,1);
1007 locExp->IProductWRTBase(tmpphys,coeffs);
1010 for(nv = 0; nv < nvel*nz_loc; ++nv)
1012 for(j = 0; j < nbmap; ++j)
1014 B_data[j+nv*nbmap + (i+nv*nimap)*nbndry] +=
1018 for(j = 0; j < nimap; ++j)
1020 D_data[j+nv*nimap + (i+nv*nimap)*nint] +=
1025 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
1026 for(j = 0; j < nz_loc; ++j)
1028 Blas::Dcopy(psize,&(pcoeffs)[0],1,
1030 ((nz_loc*k+j)*imap.num_elements() + i)*nsize_p[n]+j*psize,1);
1035 if(IsLinearNSEquation)
1038 for(nv = 0; nv < nvel; ++nv)
1042 AdvDeriv[k*nvel+nv],
1044 locExp->IProductWRTBase(tmpphys,coeffs);
1046 for(n1 = 0; n1 < nz_loc; ++n1)
1048 for(j = 0; j < nbmap; ++j)
1050 B_data[j+(k*nz_loc+n1)*nbmap +
1051 (i+(nv*nz_loc+n1)*nimap)*nbndry] +=
1055 for(j = 0; j < nimap; ++j)
1057 D_data[j+(k*nz_loc+n1)*nimap +
1058 (i+(nv*nz_loc+n1)*nimap)*nint] +=
1075 Blas::Dgemm(
'N',
'T', B->GetRows(), C->GetRows(),
1076 B->GetColumns(), -1.0, B->GetRawPtr(),
1077 B->GetRows(), C->GetRawPtr(),
1079 Ah->GetRawPtr(), Ah->GetRows());
1092 DNekMat DintCinvDTint, BCinvDTint_m_DTbnd, DintCinvBTtilde_m_Dbnd;
1098 DintCinvDTint = (*Dint)*(*Cinv)*
Transpose(*Dint);
1102 DintCinvBTtilde_m_Dbnd = (*Dint)*(*Cinv)*
Transpose(*Btilde) - (*Dbnd);
1112 for(n1 = 0; n1 < nz_loc; ++n1)
1114 for(i = 0; i < psize-1; ++i)
1116 for(n2 = 0; n2 < nz_loc; ++n2)
1118 for(j = 0; j < psize-1; ++j)
1122 Dh_data[(i+n1*(psize-1)) + (j+n2*(psize-1))*Dh->GetRows()] =
1123 -DintCinvDTint(i+1+n1*psize,j+1+n2*psize);
1129 for(n1 = 0; n1 < nz_loc; ++n1)
1131 for(i = 0; i < nsize_bndry_p1[n]-nz_loc; ++i)
1133 (*Ah)(i,nsize_bndry_p1[n]-nz_loc+n1) = BCinvDTint_m_DTbnd(i,n1*psize);
1134 (*Ah)(nsize_bndry_p1[n]-nz_loc+n1,i) = DintCinvBTtilde_m_Dbnd(n1*psize,i);
1138 for(n1 = 0; n1 < nz_loc; ++n1)
1140 for(n2 = 0; n2 < nz_loc; ++n2)
1142 (*Ah)(nsize_bndry_p1[n]-nz_loc+n1,nsize_bndry_p1[n]-nz_loc+n2) =
1143 -DintCinvDTint(n1*psize,n2*psize);
1147 for(n1 = 0; n1 < nz_loc; ++n1)
1149 for(j = 0; j < psize-1; ++j)
1151 for(i = 0; i < nsize_bndry_p1[n]-nz_loc; ++i)
1153 (*Bh)(i,j+n1*(psize-1)) = BCinvDTint_m_DTbnd(i,j+1+n1*psize);
1154 (*Ch)(j+n1*(psize-1),i) = DintCinvBTtilde_m_Dbnd(j+1+n1*psize,i);
1159 for(n1 = 0; n1 < nz_loc; ++n1)
1161 for(n2 = 0; n2 < nz_loc; ++n2)
1163 for(j = 0; j < psize-1; ++j)
1165 (*Bh)(nsize_bndry_p1[n]-nz_loc+n1,j+n2*(psize-1)) = -DintCinvDTint(n1*psize,j+1+n2*psize);
1166 (*Ch)(j+n2*(psize-1),nsize_bndry_p1[n]-nz_loc+n1) = -DintCinvDTint(j+1+n2*psize,n1*psize);
1173 (*Bh) = (*Bh)*(*Dh);
1175 Blas::Dgemm(
'N',
'N', Bh->GetRows(), Ch->GetColumns(), Bh->GetColumns(), -1.0,
1176 Bh->GetRawPtr(), Bh->GetRows(), Ch->GetRawPtr(), Ch->GetRows(),
1177 1.0, Ah->GetRawPtr(), Ah->GetRows());
1187 cout <<
"Matrix Setup Costs: " << timer.
TimePerTest(1) << endl;
1199 cout <<
"Multilevel condensation: " << timer.
TimePerTest(1) << endl;
1247 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1253 "Advection Velocity section must be defined in "
1256 std::vector<std::string> fieldStr;
1257 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1281 "Restart section must be defined in session file.");
1284 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1288 std::vector<std::string> fieldStr;
1289 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1295 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1299 cout <<
"Saving the RESTART file for m_kinvis = "<<
m_kinvis <<
" (<=> Re = " << 1/
m_kinvis <<
")" <<endl;
1318 cout <<
"Saving the Stokes Flow for m_kinvis = "<<
m_kinvis <<
" (<=> Re = " << 1/
m_kinvis <<
")" <<endl;
1327 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1333 "Advection Velocity section must be defined in "
1336 std::vector<std::string> fieldStr;
1337 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1348 ASSERTL0(
false,
"Unknown or undefined equation type for CoupledLinearNS");
1359 std::vector<SolverUtils::ForcingSharedPtr>::const_iterator x;
1362 (*x)->Apply(
m_fields, outarray, outarray, time);
1377 if(fabs(lambda_store - lambda) > 1e-10)
1379 cout <<
"Setting up Stokes matrix problem [.";
1382 cout <<
"]" << endl;
1383 lambda_store = lambda;
1387 for(i = 0; i <
m_velocity.num_elements(); ++i)
1399 for(i = 0; i <
m_velocity.num_elements(); ++i)
1408 int nfields =
m_fields.num_elements();
1409 for (
int k=0 ; k < nfields; ++k)
1420 int nfields =
m_fields.num_elements();
1421 for (
int k=0 ; k < nfields; ++k)
1449 Generaltimer.
Start();
1457 cout<<
"We execute INITIALLY SolveSteadyNavierStokes for m_kinvis = "<<
m_kinvis<<
" (<=> Re = "<<1/
m_kinvis<<
")"<<endl;
1464 cout<<
"We execute SolveSteadyNavierStokes for m_kinvis = "<<
m_kinvis<<
" (<=> Re = "<<1/
m_kinvis<<
")"<<endl;
1474 cout<<
"We execute SolveSteadyNavierStokes for m_kinvis = "<<
m_kinvis<<
" (<=> Re = "<<1/
m_kinvis<<
")"<<endl;
1482 Generaltimer.
Stop();
1483 cout<<
"\nThe total calculation time is : " << Generaltimer.
TimePerTest(1)/60 <<
" minute(s). \n\n";
1489 ASSERTL0(
false,
"Unknown or undefined equation type for CoupledLinearNS");
1506 const unsigned int ncmpt =
m_velocity.num_elements();
1510 for(
int i = 0; i < ncmpt; ++i)
1516 std::vector<SolverUtils::ForcingSharedPtr>::const_iterator x;
1520 (*x)->Apply(
m_fields, forcing_phys, forcing_phys, time);
1522 for (
unsigned int i = 0; i < ncmpt; ++i)
1526 m_fields[i]->IProductWRTBase(forcing_phys[i], forcing[i]);
1527 m_fields[i]->SetWaveSpace(waveSpace);
1538 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1544 if(
m_session->DefinesFunction(
"ForcingTerm"))
1546 std::vector<std::string> fieldStr;
1547 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1552 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1559 cout <<
"'ForcingTerm' section has not been defined in the input file => forcing=0" << endl;
1566 Newtontimer.
Start();
1575 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1583 L2Norm(delta_velocity_Phys, L2_norm);
1586 while(max(L2_norm[0], L2_norm[1]) >
m_tol)
1594 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1600 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1622 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1628 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1630 Vmath::Vadd(Velocity_Phys[i].num_elements(),Velocity_Phys[i], 1, delta_velocity_Phys[i], 1,
1631 Velocity_Phys[i], 1);
1635 L2Norm(delta_velocity_Phys, L2_norm);
1637 if(max(Inf_norm[0], Inf_norm[1]) > 100)
1639 cout<<
"\nThe Newton method has failed at m_kinvis = "<<
m_kinvis<<
" (<=> Re = " << 1/
m_kinvis <<
")"<< endl;
1640 ASSERTL0(0,
"The Newton method has failed... \n");
1650 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1657 cout<<
"We have done "<<
m_counter-1 <<
" iteration(s) in " << Newtontimer.
TimePerTest(1)/60 <<
" minute(s). \n\n";
1668 cout <<
"We apply the continuation method: " <<endl;
1670 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1690 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1697 Vmath::Vadd(u_star[i].num_elements(), u_star[i], 1, u_N[i], 1, u_star[i], 1);
1709 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1712 for(
int j = 0; j < inarray[i].num_elements(); ++j)
1714 if(inarray[i][j] > outarray[i])
1716 outarray[i] = inarray[i][j];
1719 cout <<
"InfNorm["<<i<<
"] = "<< outarray[i] <<endl;
1726 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1729 for(
int j = 0; j < inarray[i].num_elements(); ++j)
1731 outarray[i] += inarray[i][j]*inarray[i][j];
1733 outarray[i]=sqrt(outarray[i]);
1734 cout <<
"L2Norm["<<i<<
"] = "<< outarray[i] <<endl;
1748 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1765 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1774 Vmath::Vsub(outarray[i].num_elements(), outarray[i], 1, AdvTerm[i], 1, outarray[i], 1);
1775 Vmath::Vsub(outarray[i].num_elements(), outarray[i], 1, ViscTerm[i], 1, outarray[i], 1);
1777 Vmath::Vadd(outarray[i].num_elements(), outarray[i], 1, Forc[i], 1, outarray[i], 1);
1790 SpatialDomains::ExpansionMap::const_iterator expMapIter;
1793 for (expMapIter = VelExp.begin(); expMapIter != VelExp.end(); ++expMapIter)
1797 for(i = 0; i < expMapIter->second->m_basisKeyVector.size(); ++i)
1801 ASSERTL0(nummodes > 3,
"Velocity polynomial space not sufficiently high (>= 4)");
1804 BasisVec.push_back(newB);
1810 (*returnval)[expMapIter->first] = expansionElementShPtr;
1814 m_graph->SetExpansions(
"p",returnval);
1895 for(i = 0; i <
m_velocity.num_elements(); ++i)
1899 force[i] = forcing[i] + 2*n*ncoeffsplane;
1904 for(i = 0; i <
m_velocity.num_elements(); ++i)
1912 for(i = 0; i <
m_velocity.num_elements(); ++i)
1916 force[i] = forcing[i];
1924 int i,j,k,n,eid,cnt,cnt1;
1925 int nbnd,nint,offset;
1927 int nel = fields[0]->GetNumElmts();
1936 int nplanecoeffs = fields[
m_velocity[0]]->GetNcoeffs();
1954 for(i = 0; i < fields.num_elements(); ++i)
1958 Vmath::Zero(2*pressure->GetNcoeffs(),pressure->UpdateCoeffs(),1);
1965 for(i = 0; i < nel; ++i)
1968 fields[
m_velocity[0]]->GetExp(eid)->GetBoundaryMap(bmap);
1969 fields[
m_velocity[0]]->GetExp(eid)->GetInteriorMap(imap);
1970 nbnd = bmap.num_elements();
1971 nint = imap.num_elements();
1972 offset = fields[
m_velocity[0]]->GetCoeff_Offset(eid);
1974 for(j = 0; j < nvel; ++j)
1976 for(n = 0; n < nz_loc; ++n)
1978 for(k = 0; k < nbnd; ++k)
1980 f_bnd[cnt+k] = forcing[j][n*nplanecoeffs +
1983 for(k = 0; k < nint; ++k)
1985 f_int[cnt1+k] = forcing[j][n*nplanecoeffs +
1999 F_bnd = F_bnd - (*
m_mat[mode].m_BCinv)*F_int;
2000 F_p_tmp = (*
m_mat[mode].m_Cinv)*F_int;
2001 F_p = (*
m_mat[mode].m_D_int) * F_p_tmp;
2013 for(i = 0; i < nel; ++i)
2016 nbnd = nz_loc*fields[0]->GetExp(eid)->NumBndryCoeffs();
2018 for(j = 0; j < nvel; ++j)
2020 for(k = 0; k < nbnd; ++k)
2022 fh_bnd[loctoglomap[offset+j*nbnd+k]] +=
2023 loctoglosign[offset+j*nbnd+k]*f_bnd[cnt+k];
2028 nint = pressure->GetExp(eid)->GetNcoeffs();
2029 offset += nvel*nbnd + nint*nz_loc;
2033 for(i = 0; i < nel; ++i)
2036 nbnd = nz_loc*fields[0]->GetExp(eid)->NumBndryCoeffs();
2037 nint = pressure->GetExp(eid)->GetNcoeffs();
2039 for(n = 0; n < nz_loc; ++n)
2041 for(j = 0; j < nint; ++j)
2043 fh_bnd[loctoglomap[offset + nvel*nbnd + n*nint+j]] = f_p[cnt1+j];
2047 offset += nvel*nbnd + nz_loc*nint;
2058 for(k = 0; k < nvel; ++k)
2064 bndCondExp =
m_fields[k]->GetPlane(2*mode)->GetBndCondExpansions();
2068 bndCondExp =
m_fields[k]->GetBndCondExpansions();
2071 for(i = 0; i < bndCondExp.num_elements(); ++i)
2075 for(n = 0; n < nz_loc; ++n)
2077 if(bndConds[i]->GetBoundaryConditionType()
2080 for(j = 0; j < (bndCondExp[i])->
GetNcoeffs(); j++)
2086 bnd[bndmap[bndcnt++]] = 0;
2090 bnd[bndmap[bndcnt++]] = bndCondCoeffs[cnt++];
2096 for(j = 0; j < (bndCondExp[i])->
GetNcoeffs(); j++)
2098 fh_bnd[bndmap[bndcnt++]]
2099 += bndCondCoeffs[cnt++];
2110 int totpcoeffs = pressure->GetNcoeffs();
2112 for(i = 0; i < nel; ++i)
2115 nbnd = nz_loc*fields[0]->GetExp(eid)->NumBndryCoeffs();
2116 nint = pressure->GetExp(eid)->GetNcoeffs();
2118 for(j = 0; j < nvel; ++j)
2120 for(k = 0; k < nbnd; ++k)
2122 f_bnd[cnt+k] = loctoglosign[offset+j*nbnd+k]*bnd[loctoglomap[offset + j*nbnd + k]];
2126 offset += nvel*nbnd + nint*nz_loc;
2129 pressure->SetPhysState(
false);
2131 offset = cnt = cnt1 = 0;
2132 for(i = 0; i < nel; ++i)
2135 nint = pressure->GetExp(eid)->GetNcoeffs();
2136 nbnd = fields[0]->GetExp(eid)->NumBndryCoeffs();
2137 cnt1 = pressure->GetCoeff_Offset(eid);
2139 for(n = 0; n < nz_loc; ++n)
2141 for(j = 0; j < nint; ++j)
2143 p_coeffs[n*totpcoeffs + cnt1+j] =
2144 f_p[cnt+j] = bnd[loctoglomap[offset +
2145 (nvel*nz_loc)*nbnd +
2150 offset += (nvel*nbnd + nint)*nz_loc;
2157 F_int = (*
m_mat[mode].m_Cinv)*F_int;
2161 for(i = 0; i < nel; ++i)
2164 fields[0]->GetExp(eid)->GetBoundaryMap(bmap);
2165 fields[0]->GetExp(eid)->GetInteriorMap(imap);
2166 nbnd = bmap.num_elements();
2167 nint = imap.num_elements();
2168 offset = fields[0]->GetCoeff_Offset(eid);
2170 for(j = 0; j < nvel; ++j)
2172 for(n = 0; n < nz_loc; ++n)
2174 for(k = 0; k < nbnd; ++k)
2176 fields[j]->SetCoeff(n*nplanecoeffs +
2181 for(k = 0; k < nint; ++k)
2183 fields[j]->SetCoeff(n*nplanecoeffs +
2193 for(j = 0; j < nvel; ++j)
2195 fields[j]->SetPhysState(
false);
2201 std::vector<Array<OneD, NekDouble> > fieldcoeffs(
m_fields.num_elements()+1);
2202 std::vector<std::string> variables(
m_fields.num_elements()+1);
2205 for(i = 0; i <
m_fields.num_elements(); ++i)
2207 fieldcoeffs[i] =
m_fields[i]->UpdateCoeffs();
2218 m_fields[0]->GetPlane(0)->FwdTrans_IterPerExp(
m_pressure->GetPlane(0)->GetPhys(),fieldcoeffs[i]);
2219 m_fields[0]->GetPlane(1)->FwdTrans_IterPerExp(
m_pressure->GetPlane(1)->GetPhys(),tmpfieldcoeffs);
2220 for(
int e=0; e<
m_fields[0]->GetNcoeffs()/2; e++)
2222 fieldcoeffs[i][e+
m_fields[0]->GetNcoeffs()/2] = tmpfieldcoeffs[e];
2239 return m_session->GetVariables().size();
virtual SOLVER_UTILS_EXPORT void v_DoSolve()
Solves an unsteady problem.
EquationType m_equationType
equation type;
bool m_singleMode
Flag to determine if single homogeneous mode is used.
DNekScalBlkMatSharedPtr m_Btilde
Interior-boundary Laplacian plus linearised convective terms .
#define ASSERTL0(condition, msg)
DNekScalBlkMatSharedPtr m_D_bnd
Inner product of pressure system with divergence of the boundary velocity space . ...
boost::shared_ptr< CoupledLocalToGlobalC0ContMap > CoupledLocalToGlobalC0ContMapSharedPtr
SolverUtils::AdvectionSharedPtr m_advObject
Advection term.
tBaseSharedPtr CreateInstance(tKey idKey BOOST_PP_COMMA_IF(MAX_PARAM) BOOST_PP_ENUM_BINARY_PARAMS(MAX_PARAM, tParam, x))
Create an instance of the class referred to by idKey.
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
NekDouble m_kinvis
Kinematic viscosity.
void DefineImplicitSolve(FuncPointerT func, ObjectPointerT obj)
ExtrapolateFactory & GetExtrapolateFactory()
LibUtilities::TimeIntegrationSchemeOperators m_ode
The time integration scheme operators to use.
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
std::vector< std::pair< std::string, std::string > > SummaryList
NekDouble m_lambda
Lambda constant in real system if one required.
NekDouble m_LhomZ
physical length in Z direction (if homogeneous)
virtual void v_Output(void)
BasisType GetBasisType() const
Return type of expansion basis.
const SpatialDomains::ExpansionMap & GenPressureExp(const SpatialDomains::ExpansionMap &VelExp)
Array< OneD, int > m_velocity
int which identifies which components of m_fields contains the velocity (u,v,w);
SOLVER_UTILS_EXPORT void Checkpoint_Output(const int n)
Write checkpoint file of m_fields.
Array< OneD, Array< OneD, NekDouble > > m_ForcingTerm
ExtrapolateSharedPtr m_extrapolation
Array< OneD, CoupledSolverMatrices > m_mat
bool m_useFFT
Flag to determine if FFT is used for homogeneous transform.
void EvaluateAdvectionTerms(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
std::map< ConstFactorType, NekDouble > ConstFactorMap
virtual bool v_NegatedOp(void)
void L2Norm(Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, NekDouble > &outarray)
int m_npointsZ
number of points in Z direction (if homogeneous)
std::string m_sessionName
Name of the session.
boost::shared_ptr< DNekMat > DNekMatSharedPtr
int m_nConvectiveFields
Number of fields to be convected;.
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
virtual void v_TransCoeffToPhys(void)
Virtual function for transformation to physical space.
boost::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
SOLVER_UTILS_EXPORT int GetTotPoints()
void EvaluateNewtonRHS(Array< OneD, Array< OneD, NekDouble > > &Velocity, Array< OneD, Array< OneD, NekDouble > > &outarray)
DNekScalBlkMatSharedPtr m_D_int
Inner product of pressure system with divergence of the interior velocity space . ...
virtual void v_InitObject()
Init object for UnsteadySystem class.
void SolveSteadyNavierStokes(void)
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*y.
void DefineOdeRhs(FuncPointerT func, ObjectPointerT obj)
boost::shared_ptr< ExpansionMap > ExpansionMapShPtr
void SolveLinearNS(const Array< OneD, Array< OneD, NekDouble > > &forcing)
std::vector< SolverUtils::ForcingSharedPtr > m_forcing
Forcing terms.
Base class for unsteady solvers.
Array< OneD, Array< OneD, NekDouble > > m_ForcingTerm_Coeffs
void AddSummaryItem(SummaryList &l, const std::string &name, const std::string &value)
Adds a summary item to the summary info list.
virtual void v_DoInitialise(void)
Sets up initial conditions.
boost::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
SpatialDomains::BoundaryConditionsSharedPtr m_boundaryConditions
Pointer to boundary conditions object.
boost::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
void DefineForcingTerm(void)
virtual void v_GenerateSummary(SolverUtils::SummaryList &s)
Print a summary of time stepping parameters.
void InfNorm(Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, NekDouble > &outarray)
void Neg(int n, T *x, const int incx)
Negate x = -x.
std::vector< BasisKey > BasisKeyVector
Name for a vector of BasisKeys.
void SetUpCoupledMatrix(const NekDouble lambda=0.0, const Array< OneD, Array< OneD, NekDouble > > &Advfield=NullNekDoubleArrayofArray, bool IsLinearNSEquation=true)
virtual int v_GetForceDimension(void)
SOLVER_UTILS_EXPORT void EvaluateFunction(Array< OneD, Array< OneD, NekDouble > > &pArray, std::string pFunctionName, const NekDouble pTime=0.0, const int domain=0)
Evaluates a function as specified in the session file.
static const NekDouble kNekUnsetDouble
Describe a linear system.
bool m_homogen_dealiasing
Flag to determine if dealiasing is used for homogeneous simulations.
EquationSystemFactory & GetEquationSystemFactory()
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
MultiRegions::Direction const DirCartesianMap[]
DNekScalBlkMatSharedPtr m_Cinv
Interior-Interior Laplaican plus linearised convective terms inverted, i.e. the inverse of ...
SOLVER_UTILS_EXPORT void WriteFld(const std::string &outname)
Write field data to the given filename.
Array< OneD, CoupledLocalToGlobalC0ContMapSharedPtr > m_locToGloMap
NekDouble m_KinvisPercentage
virtual void v_TransPhysToCoeff(void)
Virtual function for transformation to coefficient space.
PointsKey GetPointsKey() const
Return distribution of points.
void EvaluateAdvection(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
boost::shared_ptr< Expansion > ExpansionShPtr
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
SOLVER_UTILS_EXPORT int GetNcoeffs()
bool m_zeroMode
Id to identify when single mode is mean mode (i.e. beta=0);.
This class is the base class for Navier Stokes problems.
SpatialDomains::MeshGraphSharedPtr m_graph
Pointer to graph defining mesh.
SOLVER_UTILS_EXPORT void SetInitialConditions(NekDouble initialtime=0.0, bool dumpInitialConditions=true, const int domain=0)
Initialise the data in the dependent fields.
virtual void v_DoSolve(void)
Solves an unsteady problem.
MultiRegions::ExpListSharedPtr m_pressure
Pointer to field holding pressure field.
int GetNumModes() const
Returns the order of the basis.
static Array< OneD, Array< OneD, NekDouble > > NullNekDoubleArrayofArray
void Zero(int n, T *x, const int incx)
Zero vector.
void SolveUnsteadyStokesSystem(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time, const NekDouble a_iixDt)
boost::shared_ptr< StdExpansion > StdExpansionSharedPtr
NekDouble TimePerTest(unsigned int n)
Returns amount of seconds per iteration in a test with n iterations.
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
virtual void v_InitObject()
Init object for UnsteadySystem class.
Describes the specification for a Basis.
enum HomogeneousType m_HomogeneousType
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
std::map< int, ExpansionShPtr > ExpansionMap
DNekScalBlkMatSharedPtr m_BCinv
Boundary-interior Laplacian plus linearised convective terms pre-multiplying Cinv: ...
MultiRegions::GlobalLinSysSharedPtr m_CoupledBndSys
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.