36 #include <boost/algorithm/string.hpp>
58 UnsteadySystem(pSession),
69 int expdim =
m_graph->GetMeshDimension();
77 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");
86 ASSERTL0(
m_fields.num_elements() > 2,
"Expect to have three at least three components of velocity variables");
103 for(i =0 ; i <
m_velocity.num_elements(); ++i)
114 ASSERTL0(nz <=2 ,
"For single mode calculation can only have nz <= 2");
115 if(
m_session->DefinesSolverInfo(
"BetaZero"))
134 for(i = 2; i < nz; ++i)
141 else if (expdim == 3)
144 ASSERTL0(
false,
"Setup mapping aray");
148 ASSERTL0(
false,
"Exp dimension not recognised");
154 std::string vExtrapolation =
"Standard";
156 if (
m_session->DefinesSolverInfo(
"Extrapolation"))
158 vExtrapolation =
m_session->GetSolverInfo(
"Extrapolation");
194 ASSERTL1(
m_npointsZ <=2,
"Only expected a maxmimum of two planes in single mode linear NS solver");
225 for(n = 1; n < nz; ++n)
421 for(n = 0; n < nel; ++n)
425 nsize_bndry_p1[n] = nsize_bndry[n]+nz_loc;
426 nsize_int [n] = (nvel*
m_fields[
m_velocity[0]]->GetExp(eid)->GetNcoeffs()*nz_loc - nsize_bndry[n]);
427 nsize_p[n] =
m_pressure->GetExp(eid)->GetNcoeffs()*nz_loc;
428 nsize_p_m1[n] = nsize_p[n]-nz_loc;
458 for(n = 0; n < nel; ++n)
461 nbndry = nsize_bndry[n];
463 k = nsize_bndry_p1[n];
478 locExp->GetBoundaryMap(bmap);
479 locExp->GetInteriorMap(imap);
483 locExp->DetShapeType(),
490 int nbmap = bmap.num_elements();
491 int nimap = imap.num_elements();
495 int psize =
m_pressure->GetExp(eid)->GetNcoeffs();
496 int pqsize =
m_pressure->GetExp(eid)->GetTotPoints();
501 if(AddAdvectionTerms ==
false)
507 CondMat = locExp->GetLocStaticCondMatrix(helmkey);
509 for(k = 0; k < nvel*nz_loc; ++k)
512 rows = SubBlock.GetRows();
513 cols = SubBlock.GetColumns();
514 for(i = 0; i < rows; ++i)
516 for(j = 0; j < cols; ++j)
518 (*Ah)(i+k*rows,j+k*cols) =
m_kinvis*SubBlock(i,j);
523 for(k = 0; k < nvel*nz_loc; ++k)
527 rows = SubBlock.GetRows();
528 cols = SubBlock.GetColumns();
529 for(i = 0; i < rows; ++i)
531 for(j = 0; j < cols; ++j)
533 (*B)(i+k*rows,j+k*cols) = SubBlock(i,j);
534 (*C)(i+k*rows,j+k*cols) =
m_kinvis*SubBlock1(j,i);
539 for(k = 0; k < nvel*nz_loc; ++k)
543 rows = SubBlock.GetRows();
544 cols = SubBlock.GetColumns();
545 for(i = 0; i < rows; ++i)
547 for(j = 0; j < cols; ++j)
549 (*D)(i+k*rows,j+k*cols) = inv_kinvis*SubBlock(i,j);
556 for(i = 0; i < bmap.num_elements(); ++i)
560 coeffs[bmap[i]] = 1.0;
564 for(j = 0; j < nvel; ++j)
566 if( (nz_loc == 2)&&(j == 2))
572 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
574 Blas::Dcopy(psize,&(pcoeffs)[0],1,
576 ((nz_loc*j+1)*bmap.num_elements()+i)*nsize_p[n],1);
579 Blas::Dcopy(psize,&(pcoeffs)[0],1,
581 ((nz_loc*j)*bmap.num_elements()+i)*nsize_p[n]+psize,1);
589 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
591 for(k = 0; k < nz_loc; ++k)
593 Blas::Dcopy(psize,&(pcoeffs)[0],1,
595 ((nz_loc*j+k)*bmap.num_elements()+i)*nsize_p[n]+ k*psize,1);
602 for(i = 0; i < imap.num_elements(); ++i)
606 coeffs[imap[i]] = 1.0;
610 for(j = 0; j < nvel; ++j)
612 if( (nz_loc == 2)&&(j == 2))
618 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
620 Blas::Dcopy(psize,&(pcoeffs)[0],1,
622 ((nz_loc*j+1)*imap.num_elements()+i)*nsize_p[n],1);
625 Blas::Dcopy(psize,&(pcoeffs)[0],1,
627 ((nz_loc*j)*imap.num_elements()+i)*nsize_p[n]+psize,1);
637 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
640 for(k = 0; k < nz_loc; ++k)
642 Blas::Dcopy(psize,&(pcoeffs)[0],1,
644 ((nz_loc*j+k)*imap.num_elements()+i)*nsize_p[n]+ k*psize,1);
658 ->GetLocMatrix(helmkey));
662 NekDouble HelmMatScale = HelmMat.Scale();
663 int HelmMatRows = HelmMat.GetRows();
668 locExp->DetShapeType(),
671 ->GetLocMatrix(masskey);
680 int npoints = locExp->GetTotPoints();
683 if(IsLinearNSEquation)
688 for(nv = 0; nv < nvel; ++nv)
690 for(nv1 = 0; nv1 < nvel; ++nv1)
692 if(cnt < nvel*nvel-1)
694 AdvDeriv[cnt+1] = AdvDeriv[cnt] + npoints;
711 for(i = 0; i < nbmap; ++i)
716 coeffs[bmap[i]] = 1.0;
717 locExp->BwdTrans(coeffs,phys);
719 for(k = 0; k < nvel*nz_loc; ++k)
721 for(j = 0; j < nbmap; ++j)
724 Ah_data[i+k*nbmap + (j+k*nbmap)*AhRows] +=
m_kinvis*HelmMatScale*HelmMat_data[bmap[i] + HelmMatRows*bmap[j]];
727 for(j = 0; j < nimap; ++j)
729 B_data[i+k*nbmap + (j+k*nimap)*nbndry] +=
m_kinvis*HelmMatScale*HelmMat_data[bmap[i]+HelmMatRows*imap[j]];
735 for(k = 0; k < nvel; ++k)
737 for(j = 0; j < nbmap; ++j)
739 Ah_data[i+2*k*nbmap + (j+(2*k+1)*nbmap)*AhRows] -= lambda_imag*(*MassMat)(bmap[i],bmap[j]);
742 for(j = 0; j < nbmap; ++j)
744 Ah_data[i+(2*k+1)*nbmap + (j+2*k*nbmap)*AhRows] += lambda_imag*(*MassMat)(bmap[i],bmap[j]);
747 for(j = 0; j < nimap; ++j)
749 B_data[i+2*k*nbmap + (j+(2*k+1)*nimap)*nbndry] -= lambda_imag*(*MassMat)(bmap[i],imap[j]);
752 for(j = 0; j < nimap; ++j)
754 B_data[i+(2*k+1)*nbmap + (j+2*k*nimap)*nbndry] += lambda_imag*(*MassMat)(bmap[i],imap[j]);
762 for(k = 0; k < nvel; ++k)
764 if((nz_loc == 2)&&(k == 2))
771 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
772 Blas::Dcopy(psize,&(pcoeffs)[0],1,
774 ((nz_loc*k+1)*bmap.num_elements()+i)*nsize_p[n],1);
778 Blas::Dcopy(psize,&(pcoeffs)[0],1,
780 ((nz_loc*k)*bmap.num_elements()+i)*nsize_p[n]+psize,1);
784 Advtmp = Advfield[k] + phys_offset,
785 1,deriv,1,tmpphys,1);
787 locExp->IProductWRTBase(tmpphys,coeffs);
791 for(nv = 0; nv < nvel; ++nv)
793 for(j = 0; j < nbmap; ++j)
795 Ah_data[j+2*nv*nbmap + (i+(2*nv+1)*nbmap)*AhRows] +=
799 for(j = 0; j < nimap; ++j)
801 C_data[i+(2*nv+1)*nbmap + (j+2*nv*nimap)*nbndry] +=
808 for(nv = 0; nv < nvel; ++nv)
810 for(j = 0; j < nbmap; ++j)
812 Ah_data[j+(2*nv+1)*nbmap + (i+2*nv*nbmap)*AhRows] +=
816 for(j = 0; j < nimap; ++j)
818 C_data[i+2*nv*nbmap + (j+(2*nv+1)*nimap)*nbndry] +=
829 Advtmp = Advfield[k] + phys_offset,
830 1,deriv,1,tmpphys,1);
831 locExp->IProductWRTBase(tmpphys,coeffs);
834 for(nv = 0; nv < nvel*nz_loc; ++nv)
836 for(j = 0; j < nbmap; ++j)
838 Ah_data[j+nv*nbmap + (i+nv*nbmap)*AhRows] +=
842 for(j = 0; j < nimap; ++j)
844 C_data[i+nv*nbmap + (j+nv*nimap)*nbndry] +=
850 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
851 for(j = 0; j < nz_loc; ++j)
853 Blas::Dcopy(psize,&(pcoeffs)[0],1,
855 ((nz_loc*k+j)*bmap.num_elements() + i)*nsize_p[n]+ j*psize,1);
860 if(IsLinearNSEquation)
862 for(nv = 0; nv < nvel; ++nv)
868 locExp->IProductWRTBase(tmpphys,coeffs);
870 for(
int n1 = 0; n1 < nz_loc; ++n1)
872 for(j = 0; j < nbmap; ++j)
874 Ah_data[j+(k*nz_loc+n1)*nbmap +
875 (i+(nv*nz_loc+n1)*nbmap)*AhRows] +=
879 for(j = 0; j < nimap; ++j)
881 C_data[i+(nv*nz_loc+n1)*nbmap +
882 (j+(k*nz_loc+n1)*nimap)*nbndry] +=
892 for(i = 0; i < nimap; ++i)
896 coeffs[imap[i]] = 1.0;
897 locExp->BwdTrans(coeffs,phys);
899 for(k = 0; k < nvel*nz_loc; ++k)
901 for(j = 0; j < nbmap; ++j)
903 C_data[j+k*nbmap + (i+k*nimap)*nbndry] +=
m_kinvis*HelmMatScale*HelmMat_data[imap[i]+HelmMatRows*bmap[j]];
906 for(j = 0; j < nimap; ++j)
908 D_data[i+k*nimap + (j+k*nimap)*nint] +=
m_kinvis*HelmMatScale*HelmMat_data[imap[i]+HelmMatRows*imap[j]];
914 for(k = 0; k < nvel; ++k)
916 for(j = 0; j < nbmap; ++j)
918 C_data[j+2*k*nbmap + (i+(2*k+1)*nimap)*nbndry] += lambda_imag*(*MassMat)(bmap[j],imap[i]);
921 for(j = 0; j < nbmap; ++j)
923 C_data[j+(2*k+1)*nbmap + (i+2*k*nimap)*nbndry] -= lambda_imag*(*MassMat)(bmap[j],imap[i]);
926 for(j = 0; j < nimap; ++j)
928 D_data[i+2*k*nimap + (j+(2*k+1)*nimap)*nint] -= lambda_imag*(*MassMat)(imap[i],imap[j]);
931 for(j = 0; j < nimap; ++j)
933 D_data[i+(2*k+1)*nimap + (j+2*k*nimap)*nint] += lambda_imag*(*MassMat)(imap[i],imap[j]);
939 for(k = 0; k < nvel; ++k)
941 if((nz_loc == 2)&&(k == 2))
947 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
948 Blas::Dcopy(psize,&(pcoeffs)[0],1,
950 ((nz_loc*k+1)*imap.num_elements()+i)*nsize_p[n],1);
953 Blas::Dcopy(psize,&(pcoeffs)[0],1,
955 ((nz_loc*k)*imap.num_elements()+i)*nsize_p[n]+psize,1);
959 Vmath::Vmul(npoints, Advtmp = Advfield[k] + phys_offset,1,deriv,1,tmpphys,1);
960 locExp->IProductWRTBase(tmpphys,coeffs);
963 for(nv = 0; nv < nvel; ++nv)
965 for(j = 0; j < nbmap; ++j)
967 B_data[j+2*nv*nbmap + (i+(2*nv+1)*nimap)*nbndry] +=
971 for(j = 0; j < nimap; ++j)
973 D_data[j+2*nv*nimap + (i+(2*nv+1)*nimap)*nint] +=
979 for(nv = 0; nv < nvel; ++nv)
981 for(j = 0; j < nbmap; ++j)
983 B_data[j+(2*nv+1)*nbmap + (i+2*nv*nimap)*nbndry] +=
987 for(j = 0; j < nimap; ++j)
989 D_data[j+(2*nv+1)*nimap + (i+2*nv*nimap)*nint] +=
1003 Advtmp = Advfield[k] + phys_offset,
1004 1,deriv,1,tmpphys,1);
1005 locExp->IProductWRTBase(tmpphys,coeffs);
1008 for(nv = 0; nv < nvel*nz_loc; ++nv)
1010 for(j = 0; j < nbmap; ++j)
1012 B_data[j+nv*nbmap + (i+nv*nimap)*nbndry] +=
1016 for(j = 0; j < nimap; ++j)
1018 D_data[j+nv*nimap + (i+nv*nimap)*nint] +=
1023 m_pressure->GetExp(eid)->IProductWRTBase(deriv,pcoeffs);
1024 for(j = 0; j < nz_loc; ++j)
1026 Blas::Dcopy(psize,&(pcoeffs)[0],1,
1028 ((nz_loc*k+j)*imap.num_elements() + i)*nsize_p[n]+j*psize,1);
1033 if(IsLinearNSEquation)
1036 for(nv = 0; nv < nvel; ++nv)
1040 AdvDeriv[k*nvel+nv],
1042 locExp->IProductWRTBase(tmpphys,coeffs);
1044 for(n1 = 0; n1 < nz_loc; ++n1)
1046 for(j = 0; j < nbmap; ++j)
1048 B_data[j+(k*nz_loc+n1)*nbmap +
1049 (i+(nv*nz_loc+n1)*nimap)*nbndry] +=
1053 for(j = 0; j < nimap; ++j)
1055 D_data[j+(k*nz_loc+n1)*nimap +
1056 (i+(nv*nz_loc+n1)*nimap)*nint] +=
1073 Blas::Dgemm(
'N',
'T', B->GetRows(), C->GetRows(),
1074 B->GetColumns(), -1.0, B->GetRawPtr(),
1075 B->GetRows(), C->GetRawPtr(),
1077 Ah->GetRawPtr(), Ah->GetRows());
1090 DNekMat DintCinvDTint, BCinvDTint_m_DTbnd, DintCinvBTtilde_m_Dbnd;
1096 DintCinvDTint = (*Dint)*(*Cinv)*
Transpose(*Dint);
1100 DintCinvBTtilde_m_Dbnd = (*Dint)*(*Cinv)*
Transpose(*Btilde) - (*Dbnd);
1110 for(n1 = 0; n1 < nz_loc; ++n1)
1112 for(i = 0; i < psize-1; ++i)
1114 for(n2 = 0; n2 < nz_loc; ++n2)
1116 for(j = 0; j < psize-1; ++j)
1120 Dh_data[(i+n1*(psize-1)) + (j+n2*(psize-1))*Dh->GetRows()] =
1121 -DintCinvDTint(i+1+n1*psize,j+1+n2*psize);
1127 for(n1 = 0; n1 < nz_loc; ++n1)
1129 for(i = 0; i < nsize_bndry_p1[n]-nz_loc; ++i)
1131 (*Ah)(i,nsize_bndry_p1[n]-nz_loc+n1) = BCinvDTint_m_DTbnd(i,n1*psize);
1132 (*Ah)(nsize_bndry_p1[n]-nz_loc+n1,i) = DintCinvBTtilde_m_Dbnd(n1*psize,i);
1136 for(n1 = 0; n1 < nz_loc; ++n1)
1138 for(n2 = 0; n2 < nz_loc; ++n2)
1140 (*Ah)(nsize_bndry_p1[n]-nz_loc+n1,nsize_bndry_p1[n]-nz_loc+n2) =
1141 -DintCinvDTint(n1*psize,n2*psize);
1145 for(n1 = 0; n1 < nz_loc; ++n1)
1147 for(j = 0; j < psize-1; ++j)
1149 for(i = 0; i < nsize_bndry_p1[n]-nz_loc; ++i)
1151 (*Bh)(i,j+n1*(psize-1)) = BCinvDTint_m_DTbnd(i,j+1+n1*psize);
1152 (*Ch)(j+n1*(psize-1),i) = DintCinvBTtilde_m_Dbnd(j+1+n1*psize,i);
1157 for(n1 = 0; n1 < nz_loc; ++n1)
1159 for(n2 = 0; n2 < nz_loc; ++n2)
1161 for(j = 0; j < psize-1; ++j)
1163 (*Bh)(nsize_bndry_p1[n]-nz_loc+n1,j+n2*(psize-1)) = -DintCinvDTint(n1*psize,j+1+n2*psize);
1164 (*Ch)(j+n2*(psize-1),nsize_bndry_p1[n]-nz_loc+n1) = -DintCinvDTint(j+1+n2*psize,n1*psize);
1171 (*Bh) = (*Bh)*(*Dh);
1173 Blas::Dgemm(
'N',
'N', Bh->GetRows(), Ch->GetColumns(), Bh->GetColumns(), -1.0,
1174 Bh->GetRawPtr(), Bh->GetRows(), Ch->GetRawPtr(), Ch->GetRows(),
1175 1.0, Ah->GetRawPtr(), Ah->GetRows());
1185 cout <<
"Matrix Setup Costs: " << timer.
TimePerTest(1) << endl;
1197 cout <<
"Multilevel condensation: " << timer.
TimePerTest(1) << endl;
1245 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1251 "Advection Velocity section must be defined in "
1254 std::vector<std::string> fieldStr;
1255 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1279 "Restart section must be defined in session file.");
1282 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1286 std::vector<std::string> fieldStr;
1287 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1293 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1297 cout <<
"Saving the RESTART file for m_kinvis = "<<
m_kinvis <<
" (<=> Re = " << 1/
m_kinvis <<
")" <<endl;
1316 cout <<
"Saving the Stokes Flow for m_kinvis = "<<
m_kinvis <<
" (<=> Re = " << 1/
m_kinvis <<
")" <<endl;
1325 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1331 "Advection Velocity section must be defined in "
1334 std::vector<std::string> fieldStr;
1335 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1346 ASSERTL0(
false,
"Unknown or undefined equation type for CoupledLinearNS");
1357 std::vector<SolverUtils::ForcingSharedPtr>::const_iterator x;
1360 (*x)->Apply(
m_fields, outarray, outarray, time);
1375 if(fabs(lambda_store - lambda) > 1e-10)
1377 cout <<
"Setting up Stokes matrix problem [.";
1380 cout <<
"]" << endl;
1381 lambda_store = lambda;
1387 for(i = 0; i <
m_velocity.num_elements(); ++i)
1396 for(i = 0; i <
m_velocity.num_elements(); ++i)
1405 int nfields =
m_fields.num_elements();
1406 for (
int k=0 ; k < nfields; ++k)
1417 int nfields =
m_fields.num_elements();
1418 for (
int k=0 ; k < nfields; ++k)
1434 UnsteadySystem::v_DoSolve();
1446 Generaltimer.
Start();
1454 cout<<
"We execute INITIALLY SolveSteadyNavierStokes for m_kinvis = "<<
m_kinvis<<
" (<=> Re = "<<1/
m_kinvis<<
")"<<endl;
1461 cout<<
"We execute SolveSteadyNavierStokes for m_kinvis = "<<
m_kinvis<<
" (<=> Re = "<<1/
m_kinvis<<
")"<<endl;
1471 cout<<
"We execute SolveSteadyNavierStokes for m_kinvis = "<<
m_kinvis<<
" (<=> Re = "<<1/
m_kinvis<<
")"<<endl;
1479 Generaltimer.
Stop();
1480 cout<<
"\nThe total calculation time is : " << Generaltimer.
TimePerTest(1)/60 <<
" minute(s). \n\n";
1486 ASSERTL0(
false,
"Unknown or undefined equation type for CoupledLinearNS");
1503 const unsigned int ncmpt =
m_velocity.num_elements();
1507 for(
int i = 0; i < ncmpt; ++i)
1513 std::vector<SolverUtils::ForcingSharedPtr>::const_iterator x;
1517 (*x)->Apply(
m_fields, forcing_phys, forcing_phys, time);
1519 for (
unsigned int i = 0; i < ncmpt; ++i)
1521 m_fields[i]->IProductWRTBase(forcing_phys[i], forcing[i]);
1532 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1538 if(
m_session->DefinesFunction(
"ForcingTerm"))
1540 std::vector<std::string> fieldStr;
1541 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1546 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1553 cout <<
"'ForcingTerm' section has not been defined in the input file => forcing=0" << endl;
1560 Newtontimer.
Start();
1569 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1577 L2Norm(delta_velocity_Phys, L2_norm);
1580 while(max(L2_norm[0], L2_norm[1]) >
m_tol)
1588 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1594 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1616 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1622 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1624 Vmath::Vadd(Velocity_Phys[i].num_elements(),Velocity_Phys[i], 1, delta_velocity_Phys[i], 1,
1625 Velocity_Phys[i], 1);
1629 L2Norm(delta_velocity_Phys, L2_norm);
1631 if(max(Inf_norm[0], Inf_norm[1]) > 100)
1633 cout<<
"\nThe Newton method has failed at m_kinvis = "<<
m_kinvis<<
" (<=> Re = " << 1/
m_kinvis <<
")"<< endl;
1634 ASSERTL0(0,
"The Newton method has failed... \n");
1644 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1651 cout<<
"We have done "<<
m_counter-1 <<
" iteration(s) in " << Newtontimer.
TimePerTest(1)/60 <<
" minute(s). \n\n";
1662 cout <<
"We apply the continuation method: " <<endl;
1664 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1681 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1688 Vmath::Vadd(u_star[i].num_elements(), u_star[i], 1, u_N[i], 1, u_star[i], 1);
1700 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1703 for(
int j = 0; j < inarray[i].num_elements(); ++j)
1705 if(inarray[i][j] > outarray[i])
1707 outarray[i] = inarray[i][j];
1710 cout <<
"InfNorm["<<i<<
"] = "<< outarray[i] <<endl;
1717 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1720 for(
int j = 0; j < inarray[i].num_elements(); ++j)
1722 outarray[i] += inarray[i][j]*inarray[i][j];
1724 outarray[i]=sqrt(outarray[i]);
1725 cout <<
"L2Norm["<<i<<
"] = "<< outarray[i] <<endl;
1739 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1756 for(
int i = 0; i <
m_velocity.num_elements(); ++i)
1762 Vmath::Vsub(outarray[i].num_elements(), outarray[i], 1, AdvTerm[i], 1, outarray[i], 1);
1763 Vmath::Vsub(outarray[i].num_elements(), outarray[i], 1, ViscTerm[i], 1, outarray[i], 1);
1765 Vmath::Vadd(outarray[i].num_elements(), outarray[i], 1, Forc[i], 1, outarray[i], 1);
1778 SpatialDomains::ExpansionMap::const_iterator expMapIter;
1781 for (expMapIter = VelExp.begin(); expMapIter != VelExp.end(); ++expMapIter)
1785 for(i = 0; i < expMapIter->second->m_basisKeyVector.size(); ++i)
1789 ASSERTL0(nummodes > 3,
"Velocity polynomial space not sufficiently high (>= 4)");
1792 BasisVec.push_back(newB);
1798 (*returnval)[expMapIter->first] = expansionElementShPtr;
1802 m_graph->SetExpansions(
"p",returnval);
1883 for(i = 0; i <
m_velocity.num_elements(); ++i)
1887 force[i] = forcing[i] + 2*n*ncoeffsplane;
1892 for(i = 0; i <
m_velocity.num_elements(); ++i)
1900 for(i = 0; i <
m_velocity.num_elements(); ++i)
1904 force[i] = forcing[i];
1912 int i,j,k,n,eid,cnt,cnt1;
1913 int nbnd,nint,offset;
1915 int nel = fields[0]->GetNumElmts();
1924 int nplanecoeffs = fields[
m_velocity[0]]->GetNcoeffs();
1942 for(i = 0; i < fields.num_elements(); ++i)
1946 Vmath::Zero(2*pressure->GetNcoeffs(),pressure->UpdateCoeffs(),1);
1953 for(i = 0; i < nel; ++i)
1955 eid = fields[
m_velocity[0]]->GetOffset_Elmt_Id(i);
1956 fields[
m_velocity[0]]->GetExp(eid)->GetBoundaryMap(bmap);
1957 fields[
m_velocity[0]]->GetExp(eid)->GetInteriorMap(imap);
1958 nbnd = bmap.num_elements();
1959 nint = imap.num_elements();
1960 offset = fields[
m_velocity[0]]->GetCoeff_Offset(eid);
1962 for(j = 0; j < nvel; ++j)
1964 for(n = 0; n < nz_loc; ++n)
1966 for(k = 0; k < nbnd; ++k)
1968 f_bnd[cnt+k] = forcing[j][n*nplanecoeffs +
1971 for(k = 0; k < nint; ++k)
1973 f_int[cnt1+k] = forcing[j][n*nplanecoeffs +
1987 F_bnd = F_bnd - (*
m_mat[mode].m_BCinv)*F_int;
1988 F_p_tmp = (*
m_mat[mode].m_Cinv)*F_int;
1989 F_p = (*
m_mat[mode].m_D_int) * F_p_tmp;
2001 for(i = 0; i < nel; ++i)
2003 eid = fields[0]->GetOffset_Elmt_Id(i);
2004 nbnd = nz_loc*fields[0]->GetExp(eid)->NumBndryCoeffs();
2006 for(j = 0; j < nvel; ++j)
2008 for(k = 0; k < nbnd; ++k)
2010 fh_bnd[loctoglomap[offset+j*nbnd+k]] +=
2011 loctoglosign[offset+j*nbnd+k]*f_bnd[cnt+k];
2016 nint = pressure->GetExp(eid)->GetNcoeffs();
2017 offset += nvel*nbnd + nint*nz_loc;
2021 for(i = 0; i < nel; ++i)
2023 eid = fields[0]->GetOffset_Elmt_Id(i);
2024 nbnd = nz_loc*fields[0]->GetExp(eid)->NumBndryCoeffs();
2025 nint = pressure->GetExp(eid)->GetNcoeffs();
2027 for(n = 0; n < nz_loc; ++n)
2029 for(j = 0; j < nint; ++j)
2031 fh_bnd[loctoglomap[offset + nvel*nbnd + n*nint+j]] = f_p[cnt1+j];
2035 offset += nvel*nbnd + nz_loc*nint;
2046 for(k = 0; k < nvel; ++k)
2052 bndCondExp =
m_fields[k]->GetPlane(2*mode)->GetBndCondExpansions();
2056 bndCondExp =
m_fields[k]->GetBndCondExpansions();
2059 for(i = 0; i < bndCondExp.num_elements(); ++i)
2063 for(n = 0; n < nz_loc; ++n)
2065 if(bndConds[i]->GetBoundaryConditionType()
2068 for(j = 0; j < (bndCondExp[i])->
GetNcoeffs(); j++)
2074 bnd[bndmap[bndcnt++]] = 0;
2078 bnd[bndmap[bndcnt++]] = bndCondCoeffs[cnt++];
2084 for(j = 0; j < (bndCondExp[i])->
GetNcoeffs(); j++)
2086 fh_bnd[bndmap[bndcnt++]]
2087 += bndCondCoeffs[cnt++];
2098 int totpcoeffs = pressure->GetNcoeffs();
2100 for(i = 0; i < nel; ++i)
2102 eid = fields[0]->GetOffset_Elmt_Id(i);
2103 nbnd = nz_loc*fields[0]->GetExp(eid)->NumBndryCoeffs();
2104 nint = pressure->GetExp(eid)->GetNcoeffs();
2106 for(j = 0; j < nvel; ++j)
2108 for(k = 0; k < nbnd; ++k)
2110 f_bnd[cnt+k] = loctoglosign[offset+j*nbnd+k]*bnd[loctoglomap[offset + j*nbnd + k]];
2114 offset += nvel*nbnd + nint*nz_loc;
2117 pressure->SetPhysState(
false);
2119 offset = cnt = cnt1 = 0;
2120 for(i = 0; i < nel; ++i)
2122 eid = fields[0]->GetOffset_Elmt_Id(i);
2123 nint = pressure->GetExp(eid)->GetNcoeffs();
2124 nbnd = fields[0]->GetExp(eid)->NumBndryCoeffs();
2125 cnt1 = pressure->GetCoeff_Offset(eid);
2127 for(n = 0; n < nz_loc; ++n)
2129 for(j = 0; j < nint; ++j)
2131 p_coeffs[n*totpcoeffs + cnt1+j] =
2132 f_p[cnt+j] = bnd[loctoglomap[offset +
2133 (nvel*nz_loc)*nbnd +
2138 offset += (nvel*nbnd + nint)*nz_loc;
2145 F_int = (*
m_mat[mode].m_Cinv)*F_int;
2149 for(i = 0; i < nel; ++i)
2151 eid = fields[
m_velocity[0]]->GetOffset_Elmt_Id(i);
2152 fields[0]->GetExp(eid)->GetBoundaryMap(bmap);
2153 fields[0]->GetExp(eid)->GetInteriorMap(imap);
2154 nbnd = bmap.num_elements();
2155 nint = imap.num_elements();
2156 offset = fields[0]->GetCoeff_Offset(eid);
2158 for(j = 0; j < nvel; ++j)
2160 for(n = 0; n < nz_loc; ++n)
2162 for(k = 0; k < nbnd; ++k)
2164 fields[j]->SetCoeff(n*nplanecoeffs +
2169 for(k = 0; k < nint; ++k)
2171 fields[j]->SetCoeff(n*nplanecoeffs +
2181 for(j = 0; j < nvel; ++j)
2183 fields[j]->SetPhysState(
false);
2189 std::vector<Array<OneD, NekDouble> > fieldcoeffs(
m_fields.num_elements()+1);
2190 std::vector<std::string> variables(
m_fields.num_elements()+1);
2193 for(i = 0; i <
m_fields.num_elements(); ++i)
2195 fieldcoeffs[i] =
m_fields[i]->UpdateCoeffs();
2206 m_fields[0]->GetPlane(0)->FwdTrans_IterPerExp(
m_pressure->GetPlane(0)->GetPhys(),fieldcoeffs[i]);
2207 m_fields[0]->GetPlane(1)->FwdTrans_IterPerExp(
m_pressure->GetPlane(1)->GetPhys(),tmpfieldcoeffs);
2208 for(
int e=0; e<
m_fields[0]->GetNcoeffs()/2; e++)
2210 fieldcoeffs[i][e+
m_fields[0]->GetNcoeffs()/2] = tmpfieldcoeffs[e];
2227 return m_session->GetVariables().size();
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)
void SetBoundaryConditions(NekDouble time)
time dependent boundary conditions updating
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.
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.
boost::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
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.
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()
static std::string className
Name of class.
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
void EvaluateAdvectionTerms(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, Array< OneD, NekDouble > &wk=NullNekDouble1DArray)
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()
static SolverUtils::EquationSystemSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession)
Creates an instance of this class.
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: ...
CoupledLinearNS(const LibUtilities::SessionReaderSharedPtr &pSesssion)
MultiRegions::GlobalLinSysSharedPtr m_CoupledBndSys
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.