MFEM  v4.3.0
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
navier_solver.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #include "navier_solver.hpp"
13 #include "../../general/forall.hpp"
14 #include <fstream>
15 #include <iomanip>
16 
17 using namespace mfem;
18 using namespace navier;
19 
21 {
23  for (int i = 0; i < bffis->Size(); ++i)
24  {
25  dst->AddDomainIntegrator((*bffis)[i]);
26  }
27 }
28 
29 NavierSolver::NavierSolver(ParMesh *mesh, int order, double kin_vis)
30  : pmesh(mesh), order(order), kin_vis(kin_vis)
31 {
32  vfec = new H1_FECollection(order, pmesh->Dimension());
33  pfec = new H1_FECollection(order);
35  pfes = new ParFiniteElementSpace(pmesh, pfec);
36 
37  // Check if fully periodic mesh
38  if (!(pmesh->bdr_attributes.Size() == 0))
39  {
41  vel_ess_attr = 0;
42 
44  pres_ess_attr = 0;
45  }
46 
47  int vfes_truevsize = vfes->GetTrueVSize();
48  int pfes_truevsize = pfes->GetTrueVSize();
49 
50  un.SetSize(vfes_truevsize);
51  un = 0.0;
52  un_next.SetSize(vfes_truevsize);
53  un_next = 0.0;
54  unm1.SetSize(vfes_truevsize);
55  unm1 = 0.0;
56  unm2.SetSize(vfes_truevsize);
57  unm2 = 0.0;
58  fn.SetSize(vfes_truevsize);
59  Nun.SetSize(vfes_truevsize);
60  Nun = 0.0;
61  Nunm1.SetSize(vfes_truevsize);
62  Nunm1 = 0.0;
63  Nunm2.SetSize(vfes_truevsize);
64  Nunm2 = 0.0;
65  Fext.SetSize(vfes_truevsize);
66  FText.SetSize(vfes_truevsize);
67  Lext.SetSize(vfes_truevsize);
68  resu.SetSize(vfes_truevsize);
69 
70  tmp1.SetSize(vfes_truevsize);
71 
72  pn.SetSize(pfes_truevsize);
73  pn = 0.0;
74  resp.SetSize(pfes_truevsize);
75  resp = 0.0;
76  FText_bdr.SetSize(pfes_truevsize);
77  g_bdr.SetSize(pfes_truevsize);
78 
80  un_gf = 0.0;
82  un_next_gf = 0.0;
83 
89 
90  pn_gf.SetSpace(pfes);
91  pn_gf = 0.0;
92  resp_gf.SetSpace(pfes);
93 
94  cur_step = 0;
95 
96  PrintInfo();
97 }
98 
99 void NavierSolver::Setup(double dt)
100 {
101  if (verbose && pmesh->GetMyRank() == 0)
102  {
103  mfem::out << "Setup" << std::endl;
104  if (partial_assembly)
105  {
106  mfem::out << "Using Partial Assembly" << std::endl;
107  }
108  else
109  {
110  mfem::out << "Using Full Assembly" << std::endl;
111  }
112  }
113 
114  sw_setup.Start();
115 
116  pmesh_lor = new ParMesh(
118  pfec_lor = new H1_FECollection(1);
120 
123 
124  Array<int> empty;
125 
126  // GLL integration rule (Numerical Integration)
128  const IntegrationRule &ir_ni = rules_ni.Get(vfes->GetFE(0)->GetGeomType(),
129  2 * order - 1);
130 
131  nlcoeff.constant = -1.0;
132  N = new ParNonlinearForm(vfes);
134  if (partial_assembly)
135  {
137  N->Setup();
138  }
139 
142  if (numerical_integ)
143  {
144  mv_blfi->SetIntRule(&ir_ni);
145  }
146  Mv_form->AddDomainIntegrator(mv_blfi);
147  if (partial_assembly)
148  {
150  }
151  Mv_form->Assemble();
152  Mv_form->FormSystemMatrix(empty, Mv);
153 
156  if (numerical_integ)
157  {
158  // blfi->SetIntRule(&ir_ni);
159  }
160  Sp_form->AddDomainIntegrator(sp_blfi);
161  if (partial_assembly)
162  {
164  }
165  Sp_form->Assemble();
167 
170  if (partial_assembly)
171  {
173  }
174  D_form->Assemble();
175  D_form->FormRectangularSystemMatrix(empty, empty, D);
176 
179  if (partial_assembly)
180  {
182  }
183  G_form->Assemble();
184  G_form->FormRectangularSystemMatrix(empty, empty, G);
185 
187  H_bdfcoeff.constant = 1.0 / dt;
188  H_form = new ParBilinearForm(vfes);
191  if (partial_assembly)
192  {
194  }
195  H_form->Assemble();
197 
201  *FText_gfcoeff),
202  vel_ess_attr);
203 
205  for (auto &vel_dbc : vel_dbcs)
206  {
208  *vel_dbc.coeff),
209  vel_dbc.attr);
210  }
211 
212  f_form = new ParLinearForm(vfes);
213  for (auto &accel_term : accel_terms)
214  {
215  auto *vdlfi = new VectorDomainLFIntegrator(*accel_term.coeff);
216  // @TODO: This order should always be the same as the nonlinear forms one!
217  // const IntegrationRule &ir = IntRules.Get(vfes->GetFE(0)->GetGeomType(),
218  // 4 * order);
219  // vdlfi->SetIntRule(&ir);
220  f_form->AddDomainIntegrator(vdlfi);
221  }
222 
223  if (partial_assembly)
224  {
225  Vector diag_pa(vfes->GetTrueVSize());
226  Mv_form->AssembleDiagonal(diag_pa);
227  MvInvPC = new OperatorJacobiSmoother(diag_pa, empty);
228  }
229  else
230  {
232  dynamic_cast<HypreSmoother *>(MvInvPC)->SetType(HypreSmoother::Jacobi, 1);
233  }
234  MvInv = new CGSolver(vfes->GetComm());
235  MvInv->iterative_mode = false;
236  MvInv->SetOperator(*Mv);
239  MvInv->SetRelTol(1e-12);
240  MvInv->SetMaxIter(200);
241 
242  if (partial_assembly)
243  {
251  SpInvPC->Mult(resp, pn);
254  }
255  else
256  {
261  }
262  SpInv = new CGSolver(vfes->GetComm());
263  SpInv->iterative_mode = true;
264  SpInv->SetOperator(*Sp);
265  if (pres_dbcs.empty())
266  {
268  }
269  else
270  {
272  }
275  SpInv->SetMaxIter(200);
276 
277  if (partial_assembly)
278  {
279  Vector diag_pa(vfes->GetTrueVSize());
280  H_form->AssembleDiagonal(diag_pa);
282  }
283  else
284  {
286  dynamic_cast<HypreSmoother *>(HInvPC)->SetType(HypreSmoother::Jacobi, 1);
287  }
288  HInv = new CGSolver(vfes->GetComm());
289  HInv->iterative_mode = true;
290  HInv->SetOperator(*H);
294  HInv->SetMaxIter(200);
295 
296  // If the initial condition was set, it has to be aligned with dependent
297  // Vectors and GridFunctions
299  un_next = un;
301 
302  // Set initial time step in the history array
303  dthist[0] = dt;
304 
305  if (filter_alpha != 0.0)
306  {
308  pmesh->Dimension());
310  vfec_filter,
311  pmesh->Dimension());
312 
313  un_NM1_gf.SetSpace(vfes_filter);
314  un_NM1_gf = 0.0;
315 
317  un_filtered_gf = 0.0;
318  }
319 
320  sw_setup.Stop();
321 }
322 
324 {
325  // Rotate values in time step history
326  dthist[2] = dthist[1];
327  dthist[1] = dthist[0];
328  dthist[0] = dt;
329 
330  // Rotate values in nonlinear extrapolation history
331  Nunm2 = Nunm1;
332  Nunm1 = Nun;
333 
334  // Rotate values in solution history
335  unm2 = unm1;
336  unm1 = un;
337 
338  // Update the current solution and corresponding GridFunction
340  un = un_next;
342 }
343 
344 void NavierSolver::Step(double &time, double dt, int cur_step, bool provisional)
345 {
346  sw_step.Start();
347 
349 
350  // Set current time for velocity Dirichlet boundary conditions.
351  for (auto &vel_dbc : vel_dbcs)
352  {
353  vel_dbc.coeff->SetTime(time + dt);
354  }
355 
356  // Set current time for pressure Dirichlet boundary conditions.
357  for (auto &pres_dbc : pres_dbcs)
358  {
359  pres_dbc.coeff->SetTime(time + dt);
360  }
361 
362  H_bdfcoeff.constant = bd0 / dt;
363  H_form->Update();
364  H_form->Assemble();
366 
367  HInv->SetOperator(*H);
368  if (partial_assembly)
369  {
370  delete HInvPC;
371  Vector diag_pa(vfes->GetTrueVSize());
372  H_form->AssembleDiagonal(diag_pa);
375  }
376 
377  // Extrapolated f^{n+1}.
378  for (auto &accel_term : accel_terms)
379  {
380  accel_term.coeff->SetTime(time + dt);
381  }
382 
383  f_form->Assemble();
385 
386  // Nonlinear extrapolated terms.
387  sw_extrap.Start();
388 
389  N->Mult(un, Nun);
390  Nun.Add(1.0, fn);
391 
392  {
393  const auto d_Nun = Nun.Read();
394  const auto d_Nunm1 = Nunm1.Read();
395  const auto d_Nunm2 = Nunm2.Read();
396  auto d_Fext = Fext.Write();
397  const auto ab1_ = ab1;
398  const auto ab2_ = ab2;
399  const auto ab3_ = ab3;
400  MFEM_FORALL(i, Fext.Size(),
401  d_Fext[i] = ab1_ * d_Nun[i] +
402  ab2_ * d_Nunm1[i] +
403  ab3_ * d_Nunm2[i];);
404  }
405 
406  // Fext = M^{-1} (F(u^{n}) + f^{n+1})
407  MvInv->Mult(Fext, tmp1);
410  Fext.Set(1.0, tmp1);
411 
412  // Compute BDF terms.
413  {
414  const double bd1idt = -bd1 / dt;
415  const double bd2idt = -bd2 / dt;
416  const double bd3idt = -bd3 / dt;
417  const auto d_un = un.Read();
418  const auto d_unm1 = unm1.Read();
419  const auto d_unm2 = unm2.Read();
420  auto d_Fext = Fext.ReadWrite();
421  MFEM_FORALL(i, Fext.Size(),
422  d_Fext[i] += bd1idt * d_un[i] +
423  bd2idt * d_unm1[i] +
424  bd3idt * d_unm2[i];);
425  }
426 
427  sw_extrap.Stop();
428 
429  // Pressure Poisson.
430  sw_curlcurl.Start();
431  {
432  const auto d_un = un.Read();
433  const auto d_unm1 = unm1.Read();
434  const auto d_unm2 = unm2.Read();
435  auto d_Lext = Lext.Write();
436  const auto ab1_ = ab1;
437  const auto ab2_ = ab2;
438  const auto ab3_ = ab3;
439  MFEM_FORALL(i, Lext.Size(),
440  d_Lext[i] = ab1_ * d_un[i] +
441  ab2_ * d_unm1[i] +
442  ab3_ * d_unm2[i];);
443  }
444 
446  if (pmesh->Dimension() == 2)
447  {
450  }
451  else
452  {
455  }
456 
458  Lext *= kin_vis;
459 
460  sw_curlcurl.Stop();
461 
462  // \tilde{F} = F - \nu CurlCurl(u)
463  FText.Set(-1.0, Lext);
464  FText.Add(1.0, Fext);
465 
466  // p_r = \nabla \cdot FText
467  D->Mult(FText, resp);
468  resp.Neg();
469 
470  // Add boundary terms.
474 
475  g_bdr_form->Assemble();
477  resp.Add(1.0, FText_bdr);
478  resp.Add(-bd0 / dt, g_bdr);
479 
480  if (pres_dbcs.empty())
481  {
483  }
484 
485  for (auto &pres_dbc : pres_dbcs)
486  {
487  pn_gf.ProjectBdrCoefficient(*pres_dbc.coeff, pres_dbc.attr);
488  }
489 
491 
492  Vector X1, B1;
493  if (partial_assembly)
494  {
495  auto *SpC = Sp.As<ConstrainedOperator>();
496  EliminateRHS(*Sp_form, *SpC, pres_ess_tdof, pn_gf, resp_gf, X1, B1, 1);
497  }
498  else
499  {
501  }
502  sw_spsolve.Start();
503  SpInv->Mult(B1, X1);
504  sw_spsolve.Stop();
508 
509  // If the boundary conditions on the pressure are pure Neumann remove the
510  // nullspace by removing the mean of the pressure solution. This is also
511  // ensured by the OrthoSolver wrapper for the preconditioner which removes
512  // the nullspace after every application.
513  if (pres_dbcs.empty())
514  {
515  MeanZero(pn_gf);
516  }
517 
519 
520  // Project velocity.
521  G->Mult(pn, resu);
522  resu.Neg();
523  Mv->Mult(Fext, tmp1);
524  resu.Add(1.0, tmp1);
525 
526  // un_next_gf = un_gf;
527 
528  for (auto &vel_dbc : vel_dbcs)
529  {
531  }
532 
534 
535  Vector X2, B2;
536  if (partial_assembly)
537  {
538  auto *HC = H.As<ConstrainedOperator>();
539  EliminateRHS(*H_form, *HC, vel_ess_tdof, un_next_gf, resu_gf, X2, B2, 1);
540  }
541  else
542  {
544  }
545  sw_hsolve.Start();
546  HInv->Mult(B2, X2);
547  sw_hsolve.Stop();
551 
553 
554  // If the current time step is not provisional, accept the computed solution
555  // and update the time step history by default.
556  if (!provisional)
557  {
559  time += dt;
560  }
561 
562  if (filter_alpha != 0.0)
563  {
566  const auto d_un_filtered_gf = un_filtered_gf.Read();
567  auto d_un_gf = un_gf.ReadWrite();
568  const auto filter_alpha_ = filter_alpha;
569  MFEM_FORALL(i,
570  un_gf.Size(),
571  d_un_gf[i] = (1.0 - filter_alpha_) * d_un_gf[i]
572  + filter_alpha_ * d_un_filtered_gf[i];);
573  }
574 
575  sw_step.Stop();
576 
577  if (verbose && pmesh->GetMyRank() == 0)
578  {
579  mfem::out << std::setw(7) << "" << std::setw(3) << "It" << std::setw(8)
580  << "Resid" << std::setw(12) << "Reltol"
581  << "\n";
582  // If numerical integration is active, there is no solve (thus no
583  // iterations), on the inverse velocity mass application.
584  if (!numerical_integ)
585  {
586  mfem::out << std::setw(5) << "MVIN " << std::setw(5) << std::fixed
587  << iter_mvsolve << " " << std::setw(3)
588  << std::setprecision(2) << std::scientific << res_mvsolve
589  << " " << 1e-12 << "\n";
590  }
591  mfem::out << std::setw(5) << "PRES " << std::setw(5) << std::fixed
592  << iter_spsolve << " " << std::setw(3) << std::setprecision(2)
593  << std::scientific << res_spsolve << " " << rtol_spsolve
594  << "\n";
595  mfem::out << std::setw(5) << "HELM " << std::setw(5) << std::fixed
596  << iter_hsolve << " " << std::setw(3) << std::setprecision(2)
597  << std::scientific << res_hsolve << " " << rtol_hsolve
598  << "\n";
599  mfem::out << std::setprecision(8);
600  mfem::out << std::fixed;
601  }
602 }
603 
605 {
606  // Make sure not to recompute the inner product linear form every
607  // application.
608  if (mass_lf == nullptr)
609  {
610  onecoeff.constant = 1.0;
611  mass_lf = new ParLinearForm(v.ParFESpace());
613  mass_lf->Assemble();
614 
615  ParGridFunction one_gf(v.ParFESpace());
617 
618  volume = mass_lf->operator()(one_gf);
619  }
620 
621  double integ = mass_lf->operator()(v);
622 
623  v -= integ / volume;
624 }
625 
627  ConstrainedOperator &constrainedA,
628  const Array<int> &ess_tdof_list,
629  Vector &x,
630  Vector &b,
631  Vector &X,
632  Vector &B,
633  int copy_interior)
634 {
635  const Operator *Po = A.GetOutputProlongation();
636  const Operator *Pi = A.GetProlongation();
637  const Operator *Ri = A.GetRestriction();
638  A.InitTVectors(Po, Ri, Pi, x, b, X, B);
639  if (!copy_interior)
640  {
641  X.SetSubVectorComplement(ess_tdof_list, 0.0);
642  }
643  constrainedA.EliminateRHS(X, B);
644 }
645 
647 {
648  double loc_sum = v.Sum();
649  double global_sum = 0.0;
650  int loc_size = v.Size();
651  int global_size = 0;
652 
653  MPI_Allreduce(&loc_sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, pfes->GetComm());
654  MPI_Allreduce(&loc_size, &global_size, 1, MPI_INT, MPI_SUM, pfes->GetComm());
655 
656  v -= global_sum / static_cast<double>(global_size);
657 }
658 
660 {
661  FiniteElementSpace *fes = u.FESpace();
662 
663  // AccumulateAndCountZones.
664  Array<int> zones_per_vdof;
665  zones_per_vdof.SetSize(fes->GetVSize());
666  zones_per_vdof = 0;
667 
668  cu = 0.0;
669 
670  // Local interpolation.
671  int elndofs;
672  Array<int> vdofs;
673  Vector vals;
674  Vector loc_data;
675  int vdim = fes->GetVDim();
676  DenseMatrix grad_hat;
677  DenseMatrix dshape;
678  DenseMatrix grad;
679  Vector curl;
680 
681  for (int e = 0; e < fes->GetNE(); ++e)
682  {
683  fes->GetElementVDofs(e, vdofs);
684  u.GetSubVector(vdofs, loc_data);
685  vals.SetSize(vdofs.Size());
687  const FiniteElement *el = fes->GetFE(e);
688  elndofs = el->GetDof();
689  int dim = el->GetDim();
690  dshape.SetSize(elndofs, dim);
691 
692  for (int dof = 0; dof < elndofs; ++dof)
693  {
694  // Project.
695  const IntegrationPoint &ip = el->GetNodes().IntPoint(dof);
696  tr->SetIntPoint(&ip);
697 
698  // Eval and GetVectorGradientHat.
699  el->CalcDShape(tr->GetIntPoint(), dshape);
700  grad_hat.SetSize(vdim, dim);
701  DenseMatrix loc_data_mat(loc_data.GetData(), elndofs, vdim);
702  MultAtB(loc_data_mat, dshape, grad_hat);
703 
704  const DenseMatrix &Jinv = tr->InverseJacobian();
705  grad.SetSize(grad_hat.Height(), Jinv.Width());
706  Mult(grad_hat, Jinv, grad);
707 
708  curl.SetSize(3);
709  curl(0) = grad(2, 1) - grad(1, 2);
710  curl(1) = grad(0, 2) - grad(2, 0);
711  curl(2) = grad(1, 0) - grad(0, 1);
712 
713  for (int j = 0; j < curl.Size(); ++j)
714  {
715  vals(elndofs * j + dof) = curl(j);
716  }
717  }
718 
719  // Accumulate values in all dofs, count the zones.
720  for (int j = 0; j < vdofs.Size(); j++)
721  {
722  int ldof = vdofs[j];
723  cu(ldof) += vals[j];
724  zones_per_vdof[ldof]++;
725  }
726  }
727 
728  // Communication
729 
730  // Count the zones globally.
731  GroupCommunicator &gcomm = u.ParFESpace()->GroupComm();
732  gcomm.Reduce<int>(zones_per_vdof, GroupCommunicator::Sum);
733  gcomm.Bcast(zones_per_vdof);
734 
735  // Accumulate for all vdofs.
736  gcomm.Reduce<double>(cu.GetData(), GroupCommunicator::Sum);
737  gcomm.Bcast<double>(cu.GetData());
738 
739  // Compute means.
740  for (int i = 0; i < cu.Size(); i++)
741  {
742  const int nz = zones_per_vdof[i];
743  if (nz)
744  {
745  cu(i) /= nz;
746  }
747  }
748 }
749 
751  ParGridFunction &cu,
752  bool assume_scalar)
753 {
754  FiniteElementSpace *fes = u.FESpace();
755 
756  // AccumulateAndCountZones.
757  Array<int> zones_per_vdof;
758  zones_per_vdof.SetSize(fes->GetVSize());
759  zones_per_vdof = 0;
760 
761  cu = 0.0;
762 
763  // Local interpolation.
764  int elndofs;
765  Array<int> vdofs;
766  Vector vals;
767  Vector loc_data;
768  int vdim = fes->GetVDim();
769  DenseMatrix grad_hat;
770  DenseMatrix dshape;
771  DenseMatrix grad;
772  Vector curl;
773 
774  for (int e = 0; e < fes->GetNE(); ++e)
775  {
776  fes->GetElementVDofs(e, vdofs);
777  u.GetSubVector(vdofs, loc_data);
778  vals.SetSize(vdofs.Size());
780  const FiniteElement *el = fes->GetFE(e);
781  elndofs = el->GetDof();
782  int dim = el->GetDim();
783  dshape.SetSize(elndofs, dim);
784 
785  for (int dof = 0; dof < elndofs; ++dof)
786  {
787  // Project.
788  const IntegrationPoint &ip = el->GetNodes().IntPoint(dof);
789  tr->SetIntPoint(&ip);
790 
791  // Eval and GetVectorGradientHat.
792  el->CalcDShape(tr->GetIntPoint(), dshape);
793  grad_hat.SetSize(vdim, dim);
794  DenseMatrix loc_data_mat(loc_data.GetData(), elndofs, vdim);
795  MultAtB(loc_data_mat, dshape, grad_hat);
796 
797  const DenseMatrix &Jinv = tr->InverseJacobian();
798  grad.SetSize(grad_hat.Height(), Jinv.Width());
799  Mult(grad_hat, Jinv, grad);
800 
801  if (assume_scalar)
802  {
803  curl.SetSize(2);
804  curl(0) = grad(0, 1);
805  curl(1) = -grad(0, 0);
806  }
807  else
808  {
809  curl.SetSize(2);
810  curl(0) = grad(1, 0) - grad(0, 1);
811  curl(1) = 0.0;
812  }
813 
814  for (int j = 0; j < curl.Size(); ++j)
815  {
816  vals(elndofs * j + dof) = curl(j);
817  }
818  }
819 
820  // Accumulate values in all dofs, count the zones.
821  for (int j = 0; j < vdofs.Size(); j++)
822  {
823  int ldof = vdofs[j];
824  cu(ldof) += vals[j];
825  zones_per_vdof[ldof]++;
826  }
827  }
828 
829  // Communication.
830 
831  // Count the zones globally.
832  GroupCommunicator &gcomm = u.ParFESpace()->GroupComm();
833  gcomm.Reduce<int>(zones_per_vdof, GroupCommunicator::Sum);
834  gcomm.Bcast(zones_per_vdof);
835 
836  // Accumulate for all vdofs.
837  gcomm.Reduce<double>(cu.GetData(), GroupCommunicator::Sum);
838  gcomm.Bcast<double>(cu.GetData());
839 
840  // Compute means.
841  for (int i = 0; i < cu.Size(); i++)
842  {
843  const int nz = zones_per_vdof[i];
844  if (nz)
845  {
846  cu(i) /= nz;
847  }
848  }
849 }
850 
852 {
854  FiniteElementSpace *fes = u.FESpace();
855  int vdim = fes->GetVDim();
856 
857  Vector ux, uy, uz;
858  Vector ur, us, ut;
859  double cflx = 0.0;
860  double cfly = 0.0;
861  double cflz = 0.0;
862  double cflm = 0.0;
863  double cflmax = 0.0;
864 
865  for (int e = 0; e < fes->GetNE(); ++e)
866  {
867  const FiniteElement *fe = fes->GetFE(e);
868  const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(),
869  fe->GetOrder());
871 
872  u.GetValues(e, ir, ux, 1);
873  ur.SetSize(ux.Size());
874  u.GetValues(e, ir, uy, 2);
875  us.SetSize(uy.Size());
876  if (vdim == 3)
877  {
878  u.GetValues(e, ir, uz, 3);
879  ut.SetSize(uz.Size());
880  }
881 
882  double hmin = pmesh->GetElementSize(e, 1) /
883  (double) fes->GetElementOrder(0);
884 
885  for (int i = 0; i < ir.GetNPoints(); ++i)
886  {
887  const IntegrationPoint &ip = ir.IntPoint(i);
888  tr->SetIntPoint(&ip);
889  const DenseMatrix &invJ = tr->InverseJacobian();
890  const double detJinv = 1.0 / tr->Jacobian().Det();
891 
892  if (vdim == 2)
893  {
894  ur(i) = (ux(i) * invJ(0, 0) + uy(i) * invJ(1, 0)) * detJinv;
895  us(i) = (ux(i) * invJ(0, 1) + uy(i) * invJ(1, 1)) * detJinv;
896  }
897  else if (vdim == 3)
898  {
899  ur(i) = (ux(i) * invJ(0, 0) + uy(i) * invJ(1, 0)
900  + uz(i) * invJ(2, 0))
901  * detJinv;
902  us(i) = (ux(i) * invJ(0, 1) + uy(i) * invJ(1, 1)
903  + uz(i) * invJ(2, 1))
904  * detJinv;
905  ut(i) = (ux(i) * invJ(0, 2) + uy(i) * invJ(1, 2)
906  + uz(i) * invJ(2, 2))
907  * detJinv;
908  }
909 
910  cflx = fabs(dt * ux(i) / hmin);
911  cfly = fabs(dt * uy(i) / hmin);
912  if (vdim == 3)
913  {
914  cflz = fabs(dt * uz(i) / hmin);
915  }
916  cflm = cflx + cfly + cflz;
917  cflmax = fmax(cflmax, cflm);
918  }
919  }
920 
921  double cflmax_global = 0.0;
922  MPI_Allreduce(&cflmax,
923  &cflmax_global,
924  1,
925  MPI_DOUBLE,
926  MPI_MAX,
927  pmesh->GetComm());
928 
929  return cflmax_global;
930 }
931 
933 {
934  vel_dbcs.emplace_back(attr, coeff);
935 
936  if (verbose && pmesh->GetMyRank() == 0)
937  {
938  mfem::out << "Adding Velocity Dirichlet BC to attributes ";
939  for (int i = 0; i < attr.Size(); ++i)
940  {
941  if (attr[i] == 1)
942  {
943  mfem::out << i << " ";
944  }
945  }
946  mfem::out << std::endl;
947  }
948 
949  for (int i = 0; i < attr.Size(); ++i)
950  {
951  MFEM_ASSERT((vel_ess_attr[i] && attr[i]) == 0,
952  "Duplicate boundary definition deteceted.");
953  if (attr[i] == 1)
954  {
955  vel_ess_attr[i] = 1;
956  }
957  }
958 }
959 
961 {
963 }
964 
966 {
967  pres_dbcs.emplace_back(attr, coeff);
968 
969  if (verbose && pmesh->GetMyRank() == 0)
970  {
971  mfem::out << "Adding Pressure Dirichlet BC to attributes ";
972  for (int i = 0; i < attr.Size(); ++i)
973  {
974  if (attr[i] == 1)
975  {
976  mfem::out << i << " ";
977  }
978  }
979  mfem::out << std::endl;
980  }
981 
982  for (int i = 0; i < attr.Size(); ++i)
983  {
984  MFEM_ASSERT((pres_ess_attr[i] && attr[i]) == 0,
985  "Duplicate boundary definition deteceted.");
986  if (attr[i] == 1)
987  {
988  pres_ess_attr[i] = 1;
989  }
990  }
991 }
992 
994 {
996 }
997 
999 {
1000  accel_terms.emplace_back(attr, coeff);
1001 
1002  if (verbose && pmesh->GetMyRank() == 0)
1003  {
1004  mfem::out << "Adding Acceleration term to attributes ";
1005  for (int i = 0; i < attr.Size(); ++i)
1006  {
1007  if (attr[i] == 1)
1008  {
1009  mfem::out << i << " ";
1010  }
1011  }
1012  mfem::out << std::endl;
1013  }
1014 }
1015 
1017 {
1019 }
1020 
1022 {
1023  // Maximum BDF order to use at current time step
1024  // step + 1 <= order <= max_bdf_order
1025  int bdf_order = std::min(step + 1, max_bdf_order);
1026 
1027  // Ratio of time step history at dt(t_{n}) - dt(t_{n-1})
1028  double rho1 = 0.0;
1029 
1030  // Ratio of time step history at dt(t_{n-1}) - dt(t_{n-2})
1031  double rho2 = 0.0;
1032 
1033  rho1 = dthist[0] / dthist[1];
1034 
1035  if (bdf_order == 3)
1036  {
1037  rho2 = dthist[1] / dthist[2];
1038  }
1039 
1040  if (step == 0 && bdf_order == 1)
1041  {
1042  bd0 = 1.0;
1043  bd1 = -1.0;
1044  bd2 = 0.0;
1045  bd3 = 0.0;
1046  ab1 = 1.0;
1047  ab2 = 0.0;
1048  ab3 = 0.0;
1049  }
1050  else if (step >= 1 && bdf_order == 2)
1051  {
1052  bd0 = (1.0 + 2.0 * rho1) / (1.0 + rho1);
1053  bd1 = -(1.0 + rho1);
1054  bd2 = pow(rho1, 2.0) / (1.0 + rho1);
1055  bd3 = 0.0;
1056  ab1 = 1.0 + rho1;
1057  ab2 = -rho1;
1058  ab3 = 0.0;
1059  }
1060  else if (step >= 2 && bdf_order == 3)
1061  {
1062  bd0 = 1.0 + rho1 / (1.0 + rho1)
1063  + (rho2 * rho1) / (1.0 + rho2 * (1 + rho1));
1064  bd1 = -1.0 - rho1 - (rho2 * rho1 * (1.0 + rho1)) / (1.0 + rho2);
1065  bd2 = pow(rho1, 2.0) * (rho2 + 1.0 / (1.0 + rho1));
1066  bd3 = -(pow(rho2, 3.0) * pow(rho1, 2.0) * (1.0 + rho1))
1067  / ((1.0 + rho2) * (1.0 + rho2 + rho2 * rho1));
1068  ab1 = ((1.0 + rho1) * (1.0 + rho2 * (1.0 + rho1))) / (1.0 + rho2);
1069  ab2 = -rho1 * (1.0 + rho2 * (1.0 + rho1));
1070  ab3 = (pow(rho2, 2.0) * rho1 * (1.0 + rho1)) / (1.0 + rho2);
1071  }
1072 }
1073 
1075 {
1076  double my_rt[6], rt_max[6];
1077 
1078  my_rt[0] = sw_setup.RealTime();
1079  my_rt[1] = sw_step.RealTime();
1080  my_rt[2] = sw_extrap.RealTime();
1081  my_rt[3] = sw_curlcurl.RealTime();
1082  my_rt[4] = sw_spsolve.RealTime();
1083  my_rt[5] = sw_hsolve.RealTime();
1084 
1085  MPI_Reduce(my_rt, rt_max, 6, MPI_DOUBLE, MPI_MAX, 0, pmesh->GetComm());
1086 
1087  if (pmesh->GetMyRank() == 0)
1088  {
1089  mfem::out << std::setw(10) << "SETUP" << std::setw(10) << "STEP"
1090  << std::setw(10) << "EXTRAP" << std::setw(10) << "CURLCURL"
1091  << std::setw(10) << "PSOLVE" << std::setw(10) << "HSOLVE"
1092  << "\n";
1093 
1094  mfem::out << std::setprecision(3) << std::setw(10) << my_rt[0]
1095  << std::setw(10) << my_rt[1] << std::setw(10) << my_rt[2]
1096  << std::setw(10) << my_rt[3] << std::setw(10) << my_rt[4]
1097  << std::setw(10) << my_rt[5] << "\n";
1098 
1099  mfem::out << std::setprecision(3) << std::setw(10) << " " << std::setw(10)
1100  << my_rt[1] / my_rt[1] << std::setw(10) << my_rt[2] / my_rt[1]
1101  << std::setw(10) << my_rt[3] / my_rt[1] << std::setw(10)
1102  << my_rt[4] / my_rt[1] << std::setw(10) << my_rt[5] / my_rt[1]
1103  << "\n";
1104 
1105  mfem::out << std::setprecision(8);
1106  }
1107 }
1108 
1110 {
1111  int fes_size0 = vfes->GlobalVSize();
1112  int fes_size1 = pfes->GlobalVSize();
1113 
1114  if (pmesh->GetMyRank() == 0)
1115  {
1116  mfem::out << "NAVIER version: " << NAVIER_VERSION << std::endl
1117  << "MFEM version: " << MFEM_VERSION << std::endl
1118  << "MFEM GIT: " << MFEM_GIT_STRING << std::endl
1119  << "Velocity #DOFs: " << fes_size0 << std::endl
1120  << "Pressure #DOFs: " << fes_size1 << std::endl;
1121  }
1122 }
1123 
1125 {
1126  delete FText_gfcoeff;
1127  delete g_bdr_form;
1128  delete FText_bdr_form;
1129  delete mass_lf;
1130  delete Mv_form;
1131  delete N;
1132  delete Sp_form;
1133  delete D_form;
1134  delete G_form;
1135  delete HInvPC;
1136  delete HInv;
1137  delete H_form;
1138  delete SpInv;
1139  delete MvInvPC;
1140  delete Sp_form_lor;
1141  delete SpInvOrthoPC;
1142  delete SpInvPC;
1143  delete f_form;
1144  delete pfes_lor;
1145  delete pfec_lor;
1146  delete pmesh_lor;
1147  delete MvInv;
1148  delete vfec;
1149  delete pfec;
1150  delete vfes;
1151  delete pfes;
1152  delete vfec_filter;
1153  delete vfes_filter;
1154 }
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition: intrules.hpp:247
Abstract class for all finite elements.
Definition: fe.hpp:243
FiniteElementCollection * vfec_filter
void PrintTimingData()
Print timing summary of the solving routine.
int Size() const
Return the logical size of the array.
Definition: array.hpp:134
void Orthogonalize(Vector &v)
Remove mean from a Vector.
Class for domain integration L(v) := (f, v)
Definition: lininteg.hpp:97
void Reduce(T *ldata, void(*Op)(OpData< T >)) const
Reduce within each group where the master is the root.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
Definition: fespace.hpp:540
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1)
Definition: pfespace.cpp:790
Conjugate gradient method.
Definition: solvers.hpp:316
int GetDim() const
Returns the reference space dimension for the finite element.
Definition: fe.hpp:317
FiniteElementCollection * pfec
Pressure finite element collection.
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
Definition: handle.hpp:99
Class for an integration rule - an Array of IntegrationPoint.
Definition: intrules.hpp:90
void EliminateRHS(Operator &A, ConstrainedOperator &constrainedA, const Array< int > &ess_tdof_list, Vector &x, Vector &b, Vector &X, Vector &B, int copy_interior=0)
Eliminate essential BCs in an Operator and apply to RHS.
virtual void AssembleDiagonal(Vector &diag) const
Assemble the diagonal of the bilinear form into diag. Note that diag is a true-dof Vector...
void Bcast(T *ldata, int layout) const
Broadcast within each group where the master is the root.
int GetNumIterations() const
Definition: solvers.hpp:103
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Definition: intrules.cpp:920
ParMesh * GetParMesh() const
Definition: pfespace.hpp:267
Base class for vector Coefficients that optionally depend on time and space.
virtual void FormLinearSystem(const Array< int > &ess_tdof_list, Vector &x, Vector &b, OperatorHandle &A, Vector &X, Vector &B, int copy_interior=0)
Form the linear system A X = B, corresponding to this bilinear form and the linear form b(...
void PrintInfo()
Print information about the Navier version.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:616
static ParMesh MakeRefined(ParMesh &orig_mesh, int ref_factor, int ref_type)
Create a uniformly refined (by any factor) version of orig_mesh.
Definition: pmesh.cpp:1361
Array< BilinearFormIntegrator * > * GetDBFI()
Access all the integrators added with AddDomainIntegrator().
FiniteElementCollection * pfec_lor
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:513
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i&#39;th element.
Definition: fespace.cpp:262
virtual void Setup()
Setup the NonlinearForm: based on the current AssemblyLevel and the current mesh, optionally...
double Det() const
Definition: densemat.cpp:451
ConstantCoefficient nlcoeff
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:476
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition: operator.hpp:72
void AddDomainIntegrator(NonlinearFormIntegrator *nlfi)
Adds new Domain Integrator.
void(const Vector &x, double t, Vector &u) VecFuncT
void SetIntPoint(const IntegrationPoint *ip)
Set the integration point ip that weights and Jacobians will be evaluated at.
Definition: eltrans.hpp:85
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
Definition: vector.cpp:525
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
Definition: fe.hpp:327
Container class for integration rules.
Definition: intrules.hpp:311
Data type dense matrix using column-major storage.
Definition: densemat.hpp:23
ParGridFunction un_filtered_gf
int Size() const
Returns the size of the vector.
Definition: vector.hpp:190
Parallel non-linear operator on the true dofs.
virtual const Operator * GetOutputProlongation() const
Prolongation operator from linear algebra (linear system) vectors, to output vectors for the operator...
Definition: operator.hpp:121
int GetElementOrder(int i) const
Returns the order of the i&#39;th finite element.
Definition: fespace.cpp:160
virtual void SetIntRule(const IntegrationRule *ir)
Prescribe a fixed IntegrationRule to use (when ir != NULL) or let the integrator choose (when ir == N...
Definition: nonlininteg.hpp:43
double(const Vector &x, double t) ScalarFuncT
ParLinearForm * FText_bdr_form
std::vector< PresDirichletBC_T > pres_dbcs
const DenseMatrix & InverseJacobian()
Return the inverse of the Jacobian matrix of the transformation at the currently set IntegrationPoint...
Definition: eltrans.hpp:132
bool numerical_integ
Enable/disable numerical integration rules of forms.
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
void SetAssemblyLevel(AssemblyLevel assembly_level)
Set the desired assembly level.
double RealTime()
Definition: tic_toc.cpp:426
virtual void SetSpace(FiniteElementSpace *f)
Associate a new FiniteElementSpace with the ParGridFunction.
Definition: pgridfunc.cpp:87
Abstract parallel finite element space.
Definition: pfespace.hpp:28
ConstantCoefficient H_lincoeff
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
Definition: pgridfunc.cpp:493
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
Definition: operator.hpp:652
const IntegrationPoint & GetIntPoint()
Get a const reference to the currently set integration point. This will return NULL if no integration...
Definition: eltrans.hpp:90
double * GetData() const
Return a pointer to the beginning of the Vector data.
Definition: vector.hpp:199
NavierSolver(ParMesh *mesh, int order, double kin_vis)
Initialize data structures, set FE space order and kinematic viscosity.
ParMixedBilinearForm * G_form
virtual void Update(FiniteElementSpace *nfes=NULL)
Update the FiniteElementSpace and delete all data associated with the old one.
double GetFinalNorm() const
Definition: solvers.hpp:105
void Setup(double dt)
Initialize forms, solvers and preconditioners.
void MeanZero(ParGridFunction &v)
Remove the mean from a ParGridFunction.
virtual int GetTrueVSize() const
Return the number of local vector true dofs.
Definition: pfespace.hpp:279
void Stop()
Stop the stopwatch.
Definition: tic_toc.cpp:416
bool partial_assembly
Enable/disable partial assembly of forms.
void AddDomainIntegrator(BilinearFormIntegrator *bfi)
Adds a domain integrator. Assumes ownership of bfi.
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition: fe.hpp:320
virtual const Operator * GetProlongation() const
Prolongation operator from linear algebra (linear system) vectors, to input vectors for the operator...
Definition: operator.hpp:115
int GetNE() const
Returns number of elements in the mesh.
Definition: fespace.hpp:567
The BoomerAMG solver in hypre.
Definition: hypre.hpp:1387
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition: intrules.hpp:250
void ComputeCurl3D(ParGridFunction &u, ParGridFunction &cu)
Compute for .
Class for parallel linear form.
Definition: plinearform.hpp:26
HYPRE_BigInt GlobalVSize() const
Definition: pfespace.hpp:273
Communicator performing operations within groups defined by a GroupTopology with arbitrary-size data ...
void SetPrintLevel(int print_lvl)
Definition: solvers.cpp:71
FiniteElementCollection * vfec
Velocity finite element collection.
MPI_Comm GetComm() const
Definition: pfespace.hpp:263
double f(const Vector &xvec)
Definition: lor_mms.hpp:32
double GetElementSize(ElementTransformation *T, int type=0)
Definition: mesh.cpp:76
virtual const FiniteElement * GetFE(int i) const
Definition: pfespace.cpp:511
ParFiniteElementSpace * pfes_lor
static void Sum(OpData< T >)
Reduce operation Sum, instantiated for int and double.
virtual void SetFromTrueDofs(const Vector &tv)
Set the GridFunction from the given true-dof vector.
Definition: pgridfunc.hpp:164
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:66
double ComputeCFL(ParGridFunction &u, double dt)
Compute CFL.
Class for boundary integration .
Definition: lininteg.hpp:178
virtual double * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
Definition: vector.hpp:434
Jacobi smoothing for a given bilinear form (no matrix necessary).
Definition: solvers.hpp:130
double b
Definition: lissajous.cpp:42
void SetPrintLevel(int print_level)
Definition: hypre.hpp:1467
const DenseMatrix & Jacobian()
Return the Jacobian matrix of the transformation at the currently set IntegrationPoint, using the method SetIntPoint().
Definition: eltrans.hpp:111
void SetMaxIter(int max_it)
Definition: solvers.hpp:100
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve the linear system Ax=b.
Definition: hypre.cpp:3414
ConstantCoefficient onecoeff
T Max() const
Find the maximal element in the array, using the comparison operator &lt; for class T.
Definition: array.cpp:68
void Assemble(int skip_zeros=1)
void Assemble(int skip_zeros=1)
Assemble the local matrix.
virtual void Mult(const Vector &x, Vector &y) const
Evaluate the action of the NonlinearForm.
const IntegrationRule & GetNodes() const
Get a const reference to the nodes of the element.
Definition: fe.hpp:390
std::vector< double > dthist
void SetTimeIntegrationCoefficients(int step)
Update the EXTk/BDF time integration coefficient.
virtual void FormRectangularSystemMatrix(const Array< int > &trial_tdof_list, const Array< int > &test_tdof_list, OperatorHandle &A)
Return in A a parallel (on truedofs) version of this operator.
ParBilinearForm * Sp_form_lor
void AddVelDirichletBC(VectorCoefficient *coeff, Array< int > &attr)
Add a Dirichlet boundary condition to the velocity field.
Parallel smoothers in hypre.
Definition: hypre.hpp:840
void GetValues(int i, const IntegrationRule &ir, Vector &vals, int vdim=1) const
Definition: gridfunc.cpp:466
int GetVDim() const
Returns vector dimension.
Definition: fespace.hpp:534
virtual const Operator * GetRestriction() const
Restriction operator from input vectors for the operator to linear algebra (linear system) vectors...
Definition: operator.hpp:118
FiniteElementSpace * FESpace()
Definition: gridfunc.hpp:629
void AddBoundaryIntegrator(LinearFormIntegrator *lfi)
Adds new Boundary Integrator. Assumes ownership of lfi.
Definition: linearform.cpp:70
int Dimension() const
Definition: mesh.hpp:911
void ComputeCurl2D(ParGridFunction &u, ParGridFunction &cu, bool assume_scalar=false)
Compute for .
void SetAssemblyLevel(AssemblyLevel assembly_level)
Set the desired assembly level. The default is AssemblyLevel::LEGACY.
void Start()
Clear the elapsed time and start the stopwatch.
Definition: tic_toc.cpp:411
void SetSubVectorComplement(const Array< int > &dofs, const double val)
Set all vector entries NOT in the dofs Array to the given val.
Definition: vector.cpp:686
A general vector function coefficient.
void SetAssemblyLevel(AssemblyLevel assembly_level)
Set the desired assembly level. The default is AssemblyLevel::LEGACY.
void UseExternalIntegrators()
Indicate that integrators are not owned by the BilinearForm.
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i-th element.
Definition: fespace.hpp:600
void AddDomainIntegrator(LinearFormIntegrator *lfi)
Adds new Domain Integrator. Assumes ownership of lfi.
Definition: linearform.cpp:39
Abstract base class BilinearFormIntegrator.
Definition: bilininteg.hpp:34
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Definition: mesh.hpp:204
int GetMyRank() const
Definition: pmesh.hpp:278
void SetRelTol(double rtol)
Definition: solvers.hpp:98
ParFiniteElementSpace * vfes
Velocity finite element space.
MPI_Comm GetComm() const
Definition: pmesh.hpp:276
void ProjectBdrCoefficient(Coefficient *coeff[], VectorCoefficient *vcoeff, Array< int > &attr)
Definition: pgridfunc.cpp:601
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition: fespace.hpp:87
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition: fe.hpp:323
ParLinearForm * mass_lf
Linear form to compute the mass matrix in various subroutines.
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
Definition: coefficient.hpp:39
void ProjectGridFunction(const GridFunction &src)
Project the src GridFunction to this GridFunction, both of which must be on the same mesh...
Definition: gridfunc.cpp:1760
void InitTVectors(const Operator *Po, const Operator *Ri, const Operator *Pi, Vector &x, Vector &b, Vector &X, Vector &B) const
Initializes memory for true vectors of linear system.
Definition: operator.cpp:22
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition: array.hpp:674
GroupCommunicator & GroupComm()
Return a reference to the internal GroupCommunicator (on VDofs)
Definition: pfespace.hpp:328
Vector & Set(const double a, const Vector &x)
(*this) = a * x
Definition: vector.cpp:258
std::vector< AccelTerm_T > accel_terms
virtual void RecoverFEMSolution(const Vector &X, const Vector &b, Vector &x)
bool verbose
Enable/disable verbose output.
virtual void FormSystemMatrix(const Array< int > &ess_tdof_list, OperatorHandle &A)
Form the linear system matrix A, see FormLinearSystem() for details.
virtual double * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
Definition: vector.hpp:442
Vector & Add(const double a, const Vector &Va)
(*this) += a * Va
Definition: vector.cpp:243
double kin_vis
Kinematic viscosity (dimensionless).
Class for integration point with weight.
Definition: intrules.hpp:25
Class for parallel bilinear form using different test and trial FE spaces.
std::vector< VelDirichletBC_T > vel_dbcs
void EliminateRHS(const Vector &x, Vector &b) const
Eliminate &quot;essential boundary condition&quot; values specified in x from the given right-hand side b...
Definition: operator.cpp:452
virtual const SparseMatrix * GetRestrictionMatrix() const
Get the R matrix which restricts a local dof vector to true dof vector.
Definition: pfespace.hpp:379
VectorGridFunctionCoefficient * FText_gfcoeff
void UpdateTimestepHistory(double dt)
Rotate entries in the time step and solution history arrays.
ParFiniteElementSpace * pfes
Pressure finite element space.
int dim
Definition: ex24.cpp:53
void MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
Definition: sparsemat.cpp:770
void AddDomainIntegrator(BilinearFormIntegrator *bfi)
Adds new Domain Integrator. Assumes ownership of bfi.
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i&#39;th element in t...
Definition: fespace.cpp:2388
HypreParVector * GetTrueDofs() const
Returns the true dofs in a new HypreParVector.
Definition: pgridfunc.cpp:143
Class for parallel bilinear form.
ParMixedBilinearForm * D_form
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.hpp:330
A general function coefficient.
void MultAtB(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB)
Multiply the transpose of a matrix A with a matrix B: At*B.
Definition: densemat.cpp:2648
Vector data type.
Definition: vector.hpp:60
Vector coefficient defined by a vector GridFunction.
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Definition: solvers.cpp:92
Arbitrary order H1-conforming (continuous) finite elements.
Definition: fe_coll.hpp:216
void Step(double &time, double dt, int cur_step, bool provisional=false)
Compute solution at the next time step t+dt.
ParFiniteElementSpace * vfes_filter
void AddPresDirichletBC(Coefficient *coeff, Array< int > &attr)
Add a Dirichlet boundary condition to the pressure field.
double u(const Vector &xvec)
Definition: lor_mms.hpp:24
Class for parallel grid function.
Definition: pgridfunc.hpp:32
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition: densemat.hpp:105
Square Operator for imposing essential boundary conditions using only the action, Mult()...
Definition: operator.hpp:834
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition: globals.hpp:66
Abstract operator.
Definition: operator.hpp:24
Wrapper for hypre&#39;s ParCSR matrix class.
Definition: hypre.hpp:277
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const =0
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Class for parallel meshes.
Definition: pmesh.hpp:32
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition: intrules.hpp:377
Solver wrapper which orthogonalizes the input and output vector.
double Sum() const
Return the sum of the vector entries.
Definition: vector.cpp:891
virtual const double * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
Definition: vector.hpp:426
void ParallelAssemble(Vector &tv)
Assemble the vector on the true dofs, i.e. P^t v.
Definition: plinearform.cpp:87
ParMesh * pmesh
The parallel mesh.
void AddAccelTerm(VectorCoefficient *coeff, Array< int > &attr)
Add an acceleration term to the RHS of the equation.
int order
The order of the velocity and pressure space.
ConstantCoefficient H_bdfcoeff
void Neg()
(*this) = -(*this)
Definition: vector.cpp:283
ParFiniteElementSpace * ParFESpace() const
Definition: pgridfunc.hpp:108