MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
navier_solver.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, 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 <iomanip>
14
15using namespace mfem;
16using namespace navier;
17
19{
21 for (int i = 0; i < bffis->Size(); ++i)
22 {
23 dst->AddDomainIntegrator((*bffis)[i]);
24 }
25}
26
27NavierSolver::NavierSolver(ParMesh *mesh, int order, real_t kin_vis)
28 : pmesh(mesh), order(order), kin_vis(kin_vis),
29 gll_rules(0, Quadrature1D::GaussLobatto)
30{
35
36 // Check if fully periodic mesh
37 if (!(pmesh->bdr_attributes.Size() == 0))
38 {
40 vel_ess_attr = 0;
41
43 pres_ess_attr = 0;
44 }
45
46 int vfes_truevsize = vfes->GetTrueVSize();
47 int pfes_truevsize = pfes->GetTrueVSize();
48
49 un.SetSize(vfes_truevsize);
50 un = 0.0;
51 un_next.SetSize(vfes_truevsize);
52 un_next = 0.0;
53 unm1.SetSize(vfes_truevsize);
54 unm1 = 0.0;
55 unm2.SetSize(vfes_truevsize);
56 unm2 = 0.0;
57 fn.SetSize(vfes_truevsize);
58 Nun.SetSize(vfes_truevsize);
59 Nun = 0.0;
60 Nunm1.SetSize(vfes_truevsize);
61 Nunm1 = 0.0;
62 Nunm2.SetSize(vfes_truevsize);
63 Nunm2 = 0.0;
64 Fext.SetSize(vfes_truevsize);
65 FText.SetSize(vfes_truevsize);
66 Lext.SetSize(vfes_truevsize);
67 resu.SetSize(vfes_truevsize);
68
69 tmp1.SetSize(vfes_truevsize);
70
71 pn.SetSize(pfes_truevsize);
72 pn = 0.0;
73 resp.SetSize(pfes_truevsize);
74 resp = 0.0;
75 FText_bdr.SetSize(pfes_truevsize);
76 g_bdr.SetSize(pfes_truevsize);
77
79 un_gf = 0.0;
81 un_next_gf = 0.0;
82
88
90 pn_gf = 0.0;
92
93 cur_step = 0;
94
95 PrintInfo();
96}
97
99{
100 if (verbose && pmesh->GetMyRank() == 0)
101 {
102 mfem::out << "Setup" << std::endl;
104 {
105 mfem::out << "Using Partial Assembly" << std::endl;
106 }
107 else
108 {
109 mfem::out << "Using Full Assembly" << std::endl;
110 }
111 }
112
113 sw_setup.Start();
114
117
118 Array<int> empty;
119
120 // GLL integration rule (Numerical Integration)
122 2 * order - 1);
123
124 nlcoeff.constant = -1.0;
125 N = new ParNonlinearForm(vfes);
126 auto *nlc_nlfi = new VectorConvectionNLFIntegrator(nlcoeff);
127 if (numerical_integ)
128 {
129 nlc_nlfi->SetIntRule(&ir_ni);
130 }
131 N->AddDomainIntegrator(nlc_nlfi);
133 {
135 N->Setup();
136 }
137
139 auto *mv_blfi = new VectorMassIntegrator;
140 if (numerical_integ)
141 {
142 mv_blfi->SetIntRule(&ir_ni);
143 }
146 {
148 }
149 Mv_form->Assemble();
150 Mv_form->FormSystemMatrix(empty, Mv);
151
153 auto *sp_blfi = new DiffusionIntegrator;
154 if (numerical_integ)
155 {
156 sp_blfi->SetIntRule(&ir_ni);
157 }
160 {
162 }
163 Sp_form->Assemble();
165
167 auto *vd_mblfi = new VectorDivergenceIntegrator();
168 if (numerical_integ)
169 {
170 vd_mblfi->SetIntRule(&ir_ni);
171 }
172 D_form->AddDomainIntegrator(vd_mblfi);
174 {
176 }
177 D_form->Assemble();
178 D_form->FormRectangularSystemMatrix(empty, empty, D);
179
181 auto *g_mblfi = new GradientIntegrator();
182 if (numerical_integ)
183 {
184 g_mblfi->SetIntRule(&ir_ni);
185 }
186 G_form->AddDomainIntegrator(g_mblfi);
188 {
190 }
191 G_form->Assemble();
192 G_form->FormRectangularSystemMatrix(empty, empty, G);
193
195 H_bdfcoeff.constant = 1.0 / dt;
197 auto *hmv_blfi = new VectorMassIntegrator(H_bdfcoeff);
198 auto *hdv_blfi = new VectorDiffusionIntegrator(H_lincoeff);
199 if (numerical_integ)
200 {
201 hmv_blfi->SetIntRule(&ir_ni);
202 hdv_blfi->SetIntRule(&ir_ni);
203 }
204 H_form->AddDomainIntegrator(hmv_blfi);
205 H_form->AddDomainIntegrator(hdv_blfi);
207 {
209 }
210 H_form->Assemble();
212
215 auto *ftext_bnlfi = new BoundaryNormalLFIntegrator(*FText_gfcoeff);
216 if (numerical_integ)
217 {
218 ftext_bnlfi->SetIntRule(&ir_ni);
219 }
221
223 for (auto &vel_dbc : vel_dbcs)
224 {
225 auto *gbdr_bnlfi = new BoundaryNormalLFIntegrator(*vel_dbc.coeff);
226 if (numerical_integ)
227 {
228 gbdr_bnlfi->SetIntRule(&ir_ni);
229 }
230 g_bdr_form->AddBoundaryIntegrator(gbdr_bnlfi, vel_dbc.attr);
231 }
232
234 for (auto &accel_term : accel_terms)
235 {
236 auto *vdlfi = new VectorDomainLFIntegrator(*accel_term.coeff);
237 // @TODO: This order should always be the same as the nonlinear forms one!
238 // const IntegrationRule &ir = IntRules.Get(pmesh->GetTypicalElementGeometry(),
239 // 4 * order);
240 // vdlfi->SetIntRule(&ir);
241 if (numerical_integ)
242 {
243 vdlfi->SetIntRule(&ir_ni);
244 }
246 }
247
249 {
250 Vector diag_pa(vfes->GetTrueVSize());
251 Mv_form->AssembleDiagonal(diag_pa);
252 MvInvPC = new OperatorJacobiSmoother(diag_pa, empty);
253 }
254 else
255 {
257 dynamic_cast<HypreSmoother *>(MvInvPC)->SetType(HypreSmoother::Jacobi, 1);
258 }
259 MvInv = new CGSolver(vfes->GetComm());
260 MvInv->iterative_mode = false;
265 MvInv->SetMaxIter(200);
266
268 {
272 SpInvPC->Mult(resp, pn);
275 }
276 else
277 {
282 }
283 SpInv = new CGSolver(vfes->GetComm());
284 SpInv->iterative_mode = true;
286 if (pres_dbcs.empty())
287 {
289 }
290 else
291 {
293 }
296 SpInv->SetMaxIter(200);
297
299 {
300 Vector diag_pa(vfes->GetTrueVSize());
301 H_form->AssembleDiagonal(diag_pa);
303 }
304 else
305 {
307 dynamic_cast<HypreSmoother *>(HInvPC)->SetType(HypreSmoother::Jacobi, 1);
308 }
309 HInv = new CGSolver(vfes->GetComm());
310 HInv->iterative_mode = true;
311 HInv->SetOperator(*H);
315 HInv->SetMaxIter(200);
316
317 // If the initial condition was set, it has to be aligned with dependent
318 // Vectors and GridFunctions
320 un_next = un;
322
323 // Set initial time step in the history array
324 dthist[0] = dt;
325
326 if (filter_alpha != 0.0)
327 {
329 pmesh->Dimension());
332 pmesh->Dimension());
333
335 un_NM1_gf = 0.0;
336
338 un_filtered_gf = 0.0;
339 }
340
341 sw_setup.Stop();
342}
343
345{
346 // Rotate values in time step history
347 dthist[2] = dthist[1];
348 dthist[1] = dthist[0];
349 dthist[0] = dt;
350
351 // Rotate values in nonlinear extrapolation history
352 Nunm2 = Nunm1;
353 Nunm1 = Nun;
354
355 // Rotate values in solution history
356 unm2 = unm1;
357 unm1 = un;
358
359 // Update the current solution and corresponding GridFunction
361 un = un_next;
363}
364
365void NavierSolver::Step(real_t &time, real_t dt, int current_step,
366 bool provisional)
367{
368 sw_step.Start();
369
370 SetTimeIntegrationCoefficients(current_step);
371
372 // Set current time for velocity Dirichlet boundary conditions.
373 for (auto &vel_dbc : vel_dbcs)
374 {
375 vel_dbc.coeff->SetTime(time + dt);
376 }
377
378 // Set current time for pressure Dirichlet boundary conditions.
379 for (auto &pres_dbc : pres_dbcs)
380 {
381 pres_dbc.coeff->SetTime(time + dt);
382 }
383
384 H_bdfcoeff.constant = bd0 / dt;
385 H_form->Update();
386 H_form->Assemble();
388
389 HInv->SetOperator(*H);
391 {
392 delete HInvPC;
393 Vector diag_pa(vfes->GetTrueVSize());
394 H_form->AssembleDiagonal(diag_pa);
397 }
398
399 // Extrapolated f^{n+1}.
400 for (auto &accel_term : accel_terms)
401 {
402 accel_term.coeff->SetTime(time + dt);
403 }
404
405 f_form->Assemble();
407
408 // Nonlinear extrapolated terms.
410
411 N->Mult(un, Nun);
412 N->Mult(unm1, Nunm1);
413 N->Mult(unm2, Nunm2);
414
415 {
416 const auto d_Nun = Nun.Read();
417 const auto d_Nunm1 = Nunm1.Read();
418 const auto d_Nunm2 = Nunm2.Read();
419 auto d_Fext = Fext.Write();
420 const auto ab1_ = ab1;
421 const auto ab2_ = ab2;
422 const auto ab3_ = ab3;
423 mfem::forall(Fext.Size(), [=] MFEM_HOST_DEVICE (int i)
424 {
425 d_Fext[i] = ab1_ * d_Nun[i] +
426 ab2_ * d_Nunm1[i] +
427 ab3_ * d_Nunm2[i];
428 });
429 }
430
431 Fext.Add(1.0, fn);
432
433 // Fext = M^{-1} (F(u^{n}) + f^{n+1})
434 MvInv->Mult(Fext, tmp1);
437 Fext.Set(1.0, tmp1);
438
439 // Compute BDF terms.
440 {
441 const real_t bd1idt = -bd1 / dt;
442 const real_t bd2idt = -bd2 / dt;
443 const real_t bd3idt = -bd3 / dt;
444 const auto d_un = un.Read();
445 const auto d_unm1 = unm1.Read();
446 const auto d_unm2 = unm2.Read();
447 auto d_Fext = Fext.ReadWrite();
448 mfem::forall(Fext.Size(), [=] MFEM_HOST_DEVICE (int i)
449 {
450 d_Fext[i] += bd1idt * d_un[i] +
451 bd2idt * d_unm1[i] +
452 bd3idt * d_unm2[i];
453 });
454 }
455
456 sw_extrap.Stop();
457
458 // Pressure Poisson.
460 {
461 const auto d_un = un.Read();
462 const auto d_unm1 = unm1.Read();
463 const auto d_unm2 = unm2.Read();
464 auto d_Lext = Lext.Write();
465 const auto ab1_ = ab1;
466 const auto ab2_ = ab2;
467 const auto ab3_ = ab3;
468 mfem::forall(Lext.Size(), [=] MFEM_HOST_DEVICE (int i)
469 {
470 d_Lext[i] = ab1_ * d_un[i] +
471 ab2_ * d_unm1[i] +
472 ab3_ * d_unm2[i];
473 });
474 }
475
477 if (pmesh->Dimension() == 2)
478 {
481 }
482 else
483 {
486 }
487
489 Lext *= kin_vis;
490
492
493 // \tilde{F} = F - \nu CurlCurl(u)
494 FText.Set(-1.0, Lext);
495 FText.Add(1.0, Fext);
496
497 // p_r = \nabla \cdot FText
498 D->Mult(FText, resp);
499 resp.Neg();
500
501 // Add boundary terms.
505
508 resp.Add(1.0, FText_bdr);
509 resp.Add(-bd0 / dt, g_bdr);
510
511 if (pres_dbcs.empty())
512 {
514 }
515
516 for (auto &pres_dbc : pres_dbcs)
517 {
518 pn_gf.ProjectBdrCoefficient(*pres_dbc.coeff, pres_dbc.attr);
519 }
520
522
523 Vector X1, B1;
525 {
526 auto *SpC = Sp.As<ConstrainedOperator>();
527 EliminateRHS(*Sp_form, *SpC, pres_ess_tdof, pn_gf, resp_gf, X1, B1, 1);
528 }
529 else
530 {
532 }
534 SpInv->Mult(B1, X1);
539
540 // If the boundary conditions on the pressure are pure Neumann remove the
541 // nullspace by removing the mean of the pressure solution. This is also
542 // ensured by the OrthoSolver wrapper for the preconditioner which removes
543 // the nullspace after every application.
544 if (pres_dbcs.empty())
545 {
547 }
548
550
551 // Project velocity.
552 G->Mult(pn, resu);
553 resu.Neg();
554 Mv->Mult(Fext, tmp1);
555 resu.Add(1.0, tmp1);
556
557 // un_next_gf = un_gf;
558
559 for (auto &vel_dbc : vel_dbcs)
560 {
562 }
563
565
566 Vector X2, B2;
568 {
569 auto *HC = H.As<ConstrainedOperator>();
571 }
572 else
573 {
575 }
577 HInv->Mult(B2, X2);
578 sw_hsolve.Stop();
582
584
585 // If the current time step is not provisional, accept the computed solution
586 // and update the time step history by default.
587 if (!provisional)
588 {
590 time += dt;
591 }
592
593 if (filter_alpha != 0.0)
594 {
597 const auto d_un_filtered_gf = un_filtered_gf.Read();
598 auto d_un_gf = un_gf.ReadWrite();
599 const auto filter_alpha_ = filter_alpha;
600 mfem::forall(un_gf.Size(), [=] MFEM_HOST_DEVICE (int i)
601 {
602 d_un_gf[i] = (1.0 - filter_alpha_) * d_un_gf[i]
603 + filter_alpha_ * d_un_filtered_gf[i];
604 });
605 }
606
607 sw_step.Stop();
608
609 if (verbose && pmesh->GetMyRank() == 0)
610 {
611 mfem::out << std::setw(7) << "" << std::setw(3) << "It" << std::setw(8)
612 << "Resid" << std::setw(12) << "Reltol"
613 << "\n";
614 // If numerical integration is active, there is no solve (thus no
615 // iterations), on the inverse velocity mass application.
616 if (!numerical_integ)
617 {
618 mfem::out << std::setw(5) << "MVIN " << std::setw(5) << std::fixed
619 << iter_mvsolve << " " << std::setw(3)
620 << std::setprecision(2) << std::scientific << res_mvsolve
621 << " " << rtol_mvsolve << "\n";
622 }
623 mfem::out << std::setw(5) << "PRES " << std::setw(5) << std::fixed
624 << iter_spsolve << " " << std::setw(3) << std::setprecision(2)
625 << std::scientific << res_spsolve << " " << rtol_spsolve
626 << "\n";
627 mfem::out << std::setw(5) << "HELM " << std::setw(5) << std::fixed
628 << iter_hsolve << " " << std::setw(3) << std::setprecision(2)
629 << std::scientific << res_hsolve << " " << rtol_hsolve
630 << "\n";
631 mfem::out << std::setprecision(8);
632 mfem::out << std::scientific;
633 }
634}
635
637{
638 // Make sure not to recompute the inner product linear form every
639 // application.
640 if (mass_lf == nullptr)
641 {
642 onecoeff.constant = 1.0;
644 auto *dlfi = new DomainLFIntegrator(onecoeff);
645 if (numerical_integ)
646 {
648 2 * order - 1);
649 dlfi->SetIntRule(&ir_ni);
650 }
652 mass_lf->Assemble();
653
654 ParGridFunction one_gf(v.ParFESpace());
656
657 volume = mass_lf->operator()(one_gf);
658 }
659
660 real_t integ = mass_lf->operator()(v);
661
662 v -= integ / volume;
663}
664
666 ConstrainedOperator &constrainedA,
667 const Array<int> &ess_tdof_list,
668 Vector &x,
669 Vector &b,
670 Vector &X,
671 Vector &B,
672 int copy_interior)
673{
674 const Operator *Po = A.GetOutputProlongation();
675 const Operator *Pi = A.GetProlongation();
676 const Operator *Ri = A.GetRestriction();
677 A.InitTVectors(Po, Ri, Pi, x, b, X, B);
678 if (!copy_interior)
679 {
680 X.SetSubVectorComplement(ess_tdof_list, 0.0);
681 }
682 constrainedA.EliminateRHS(X, B);
683}
684
686{
687 real_t loc_sum = v.Sum();
688 real_t global_sum = 0.0;
689 int loc_size = v.Size();
690 int global_size = 0;
691
692 MPI_Allreduce(&loc_sum, &global_sum, 1, MPITypeMap<real_t>::mpi_type, MPI_SUM,
693 pfes->GetComm());
694 MPI_Allreduce(&loc_size, &global_size, 1, MPI_INT, MPI_SUM, pfes->GetComm());
695
696 v -= global_sum / static_cast<real_t>(global_size);
697}
698
700{
701 FiniteElementSpace *fes = u.FESpace();
702
703 // AccumulateAndCountZones.
704 Array<int> zones_per_vdof;
705 zones_per_vdof.SetSize(fes->GetVSize());
706 zones_per_vdof = 0;
707
708 cu = 0.0;
709
710 // Local interpolation.
711 int elndofs;
712 Array<int> vdofs;
713 Vector vals;
714 Vector loc_data;
715 int vdim = fes->GetVDim();
716 DenseMatrix grad_hat;
717 DenseMatrix dshape;
718 DenseMatrix grad;
719 Vector curl;
720
721 for (int e = 0; e < fes->GetNE(); ++e)
722 {
723 fes->GetElementVDofs(e, vdofs);
724 u.GetSubVector(vdofs, loc_data);
725 vals.SetSize(vdofs.Size());
727 const FiniteElement *el = fes->GetFE(e);
728 elndofs = el->GetDof();
729 int dim = el->GetDim();
730 dshape.SetSize(elndofs, dim);
731
732 for (int dof = 0; dof < elndofs; ++dof)
733 {
734 // Project.
735 const IntegrationPoint &ip = el->GetNodes().IntPoint(dof);
736 tr->SetIntPoint(&ip);
737
738 // Eval and GetVectorGradientHat.
739 el->CalcDShape(tr->GetIntPoint(), dshape);
740 grad_hat.SetSize(vdim, dim);
741 DenseMatrix loc_data_mat(loc_data.GetData(), elndofs, vdim);
742 MultAtB(loc_data_mat, dshape, grad_hat);
743
744 const DenseMatrix &Jinv = tr->InverseJacobian();
745 grad.SetSize(grad_hat.Height(), Jinv.Width());
746 Mult(grad_hat, Jinv, grad);
747
748 curl.SetSize(3);
749 curl(0) = grad(2, 1) - grad(1, 2);
750 curl(1) = grad(0, 2) - grad(2, 0);
751 curl(2) = grad(1, 0) - grad(0, 1);
752
753 for (int j = 0; j < curl.Size(); ++j)
754 {
755 vals(elndofs * j + dof) = curl(j);
756 }
757 }
758
759 // Accumulate values in all dofs, count the zones.
760 for (int j = 0; j < vdofs.Size(); j++)
761 {
762 int ldof = vdofs[j];
763 cu(ldof) += vals[j];
764 zones_per_vdof[ldof]++;
765 }
766 }
767
768 // Communication
769
770 // Count the zones globally.
771 GroupCommunicator &gcomm = u.ParFESpace()->GroupComm();
772 gcomm.Reduce<int>(zones_per_vdof, GroupCommunicator::Sum);
773 gcomm.Bcast(zones_per_vdof);
774
775 // Accumulate for all vdofs.
777 gcomm.Bcast<real_t>(cu.GetData());
778
779 // Compute means.
780 for (int i = 0; i < cu.Size(); i++)
781 {
782 const int nz = zones_per_vdof[i];
783 if (nz)
784 {
785 cu(i) /= nz;
786 }
787 }
788}
789
791 ParGridFunction &cu,
792 bool assume_scalar)
793{
794 FiniteElementSpace *fes = u.FESpace();
795
796 // AccumulateAndCountZones.
797 Array<int> zones_per_vdof;
798 zones_per_vdof.SetSize(fes->GetVSize());
799 zones_per_vdof = 0;
800
801 cu = 0.0;
802
803 // Local interpolation.
804 int elndofs;
805 Array<int> vdofs;
806 Vector vals;
807 Vector loc_data;
808 int vdim = fes->GetVDim();
809 DenseMatrix grad_hat;
810 DenseMatrix dshape;
811 DenseMatrix grad;
812 Vector curl;
813
814 for (int e = 0; e < fes->GetNE(); ++e)
815 {
816 fes->GetElementVDofs(e, vdofs);
817 u.GetSubVector(vdofs, loc_data);
818 vals.SetSize(vdofs.Size());
820 const FiniteElement *el = fes->GetFE(e);
821 elndofs = el->GetDof();
822 int dim = el->GetDim();
823 dshape.SetSize(elndofs, dim);
824
825 for (int dof = 0; dof < elndofs; ++dof)
826 {
827 // Project.
828 const IntegrationPoint &ip = el->GetNodes().IntPoint(dof);
829 tr->SetIntPoint(&ip);
830
831 // Eval and GetVectorGradientHat.
832 el->CalcDShape(tr->GetIntPoint(), dshape);
833 grad_hat.SetSize(vdim, dim);
834 DenseMatrix loc_data_mat(loc_data.GetData(), elndofs, vdim);
835 MultAtB(loc_data_mat, dshape, grad_hat);
836
837 const DenseMatrix &Jinv = tr->InverseJacobian();
838 grad.SetSize(grad_hat.Height(), Jinv.Width());
839 Mult(grad_hat, Jinv, grad);
840
841 if (assume_scalar)
842 {
843 curl.SetSize(2);
844 curl(0) = grad(0, 1);
845 curl(1) = -grad(0, 0);
846 }
847 else
848 {
849 curl.SetSize(2);
850 curl(0) = grad(1, 0) - grad(0, 1);
851 curl(1) = 0.0;
852 }
853
854 for (int j = 0; j < curl.Size(); ++j)
855 {
856 vals(elndofs * j + dof) = curl(j);
857 }
858 }
859
860 // Accumulate values in all dofs, count the zones.
861 for (int j = 0; j < vdofs.Size(); j++)
862 {
863 int ldof = vdofs[j];
864 cu(ldof) += vals[j];
865 zones_per_vdof[ldof]++;
866 }
867 }
868
869 // Communication.
870
871 // Count the zones globally.
872 GroupCommunicator &gcomm = u.ParFESpace()->GroupComm();
873 gcomm.Reduce<int>(zones_per_vdof, GroupCommunicator::Sum);
874 gcomm.Bcast(zones_per_vdof);
875
876 // Accumulate for all vdofs.
878 gcomm.Bcast<real_t>(cu.GetData());
879
880 // Compute means.
881 for (int i = 0; i < cu.Size(); i++)
882 {
883 const int nz = zones_per_vdof[i];
884 if (nz)
885 {
886 cu(i) /= nz;
887 }
888 }
889}
890
892{
893 ParMesh *pmesh_u = u.ParFESpace()->GetParMesh();
894 FiniteElementSpace *fes = u.FESpace();
895 int vdim = fes->GetVDim();
896
897 Vector ux, uy, uz;
898 Vector ur, us, ut;
899 real_t cflx = 0.0;
900 real_t cfly = 0.0;
901 real_t cflz = 0.0;
902 real_t cflm = 0.0;
903 real_t cflmax = 0.0;
904
905 for (int e = 0; e < fes->GetNE(); ++e)
906 {
907 const FiniteElement *fe = fes->GetFE(e);
908 const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(),
909 fe->GetOrder());
911
912 u.GetValues(e, ir, ux, 1);
913 ur.SetSize(ux.Size());
914 u.GetValues(e, ir, uy, 2);
915 us.SetSize(uy.Size());
916 if (vdim == 3)
917 {
918 u.GetValues(e, ir, uz, 3);
919 ut.SetSize(uz.Size());
920 }
921
922 real_t hmin = pmesh_u->GetElementSize(e, 1) /
923 (real_t) fes->GetElementOrder(0);
924
925 for (int i = 0; i < ir.GetNPoints(); ++i)
926 {
927 const IntegrationPoint &ip = ir.IntPoint(i);
928 tr->SetIntPoint(&ip);
929 const DenseMatrix &invJ = tr->InverseJacobian();
930 const real_t detJinv = 1.0 / tr->Jacobian().Det();
931
932 if (vdim == 2)
933 {
934 ur(i) = (ux(i) * invJ(0, 0) + uy(i) * invJ(1, 0)) * detJinv;
935 us(i) = (ux(i) * invJ(0, 1) + uy(i) * invJ(1, 1)) * detJinv;
936 }
937 else if (vdim == 3)
938 {
939 ur(i) = (ux(i) * invJ(0, 0) + uy(i) * invJ(1, 0)
940 + uz(i) * invJ(2, 0))
941 * detJinv;
942 us(i) = (ux(i) * invJ(0, 1) + uy(i) * invJ(1, 1)
943 + uz(i) * invJ(2, 1))
944 * detJinv;
945 ut(i) = (ux(i) * invJ(0, 2) + uy(i) * invJ(1, 2)
946 + uz(i) * invJ(2, 2))
947 * detJinv;
948 }
949
950 cflx = fabs(dt * ux(i) / hmin);
951 cfly = fabs(dt * uy(i) / hmin);
952 if (vdim == 3)
953 {
954 cflz = fabs(dt * uz(i) / hmin);
955 }
956 cflm = cflx + cfly + cflz;
957 cflmax = fmax(cflmax, cflm);
958 }
959 }
960
961 real_t cflmax_global = 0.0;
962 MPI_Allreduce(&cflmax,
963 &cflmax_global,
964 1,
966 MPI_MAX,
967 pmesh_u->GetComm());
968
969 return cflmax_global;
970}
971
973{
974 vel_dbcs.emplace_back(attr, coeff);
975
976 if (verbose && pmesh->GetMyRank() == 0)
977 {
978 mfem::out << "Adding Velocity Dirichlet BC to attributes ";
979 for (int i = 0; i < attr.Size(); ++i)
980 {
981 if (attr[i] == 1)
982 {
983 mfem::out << i << " ";
984 }
985 }
986 mfem::out << std::endl;
987 }
988
989 for (int i = 0; i < attr.Size(); ++i)
990 {
991 MFEM_ASSERT((vel_ess_attr[i] && attr[i]) == 0,
992 "Duplicate boundary definition deteceted.");
993 if (attr[i] == 1)
994 {
995 vel_ess_attr[i] = 1;
996 }
997 }
998}
999
1004
1006{
1007 pres_dbcs.emplace_back(attr, coeff);
1008
1009 if (verbose && pmesh->GetMyRank() == 0)
1010 {
1011 mfem::out << "Adding Pressure Dirichlet BC to attributes ";
1012 for (int i = 0; i < attr.Size(); ++i)
1013 {
1014 if (attr[i] == 1)
1015 {
1016 mfem::out << i << " ";
1017 }
1018 }
1019 mfem::out << std::endl;
1020 }
1021
1022 for (int i = 0; i < attr.Size(); ++i)
1023 {
1024 MFEM_ASSERT((pres_ess_attr[i] && attr[i]) == 0,
1025 "Duplicate boundary definition deteceted.");
1026 if (attr[i] == 1)
1027 {
1028 pres_ess_attr[i] = 1;
1029 }
1030 }
1031}
1032
1037
1039{
1040 accel_terms.emplace_back(attr, coeff);
1041
1042 if (verbose && pmesh->GetMyRank() == 0)
1043 {
1044 mfem::out << "Adding Acceleration term to attributes ";
1045 for (int i = 0; i < attr.Size(); ++i)
1046 {
1047 if (attr[i] == 1)
1048 {
1049 mfem::out << i << " ";
1050 }
1051 }
1052 mfem::out << std::endl;
1053 }
1054}
1055
1060
1062{
1063 // Maximum BDF order to use at current time step
1064 // step + 1 <= order <= max_bdf_order
1065 int bdf_order = std::min(step + 1, max_bdf_order);
1066
1067 // Ratio of time step history at dt(t_{n}) - dt(t_{n-1})
1068 real_t rho1 = 0.0;
1069
1070 // Ratio of time step history at dt(t_{n-1}) - dt(t_{n-2})
1071 real_t rho2 = 0.0;
1072
1073 rho1 = dthist[0] / dthist[1];
1074
1075 if (bdf_order == 3)
1076 {
1077 rho2 = dthist[1] / dthist[2];
1078 }
1079
1080 if (step == 0 && bdf_order == 1)
1081 {
1082 bd0 = 1.0;
1083 bd1 = -1.0;
1084 bd2 = 0.0;
1085 bd3 = 0.0;
1086 ab1 = 1.0;
1087 ab2 = 0.0;
1088 ab3 = 0.0;
1089 }
1090 else if (step >= 1 && bdf_order == 2)
1091 {
1092 bd0 = (1.0 + 2.0 * rho1) / (1.0 + rho1);
1093 bd1 = -(1.0 + rho1);
1094 bd2 = pow(rho1, 2.0) / (1.0 + rho1);
1095 bd3 = 0.0;
1096 ab1 = 1.0 + rho1;
1097 ab2 = -rho1;
1098 ab3 = 0.0;
1099 }
1100 else if (step >= 2 && bdf_order == 3)
1101 {
1102 bd0 = 1.0 + rho1 / (1.0 + rho1)
1103 + (rho2 * rho1) / (1.0 + rho2 * (1 + rho1));
1104 bd1 = -1.0 - rho1 - (rho2 * rho1 * (1.0 + rho1)) / (1.0 + rho2);
1105 bd2 = pow(rho1, 2.0) * (rho2 + 1.0 / (1.0 + rho1));
1106 bd3 = -(pow(rho2, 3.0) * pow(rho1, 2.0) * (1.0 + rho1))
1107 / ((1.0 + rho2) * (1.0 + rho2 + rho2 * rho1));
1108 ab1 = ((1.0 + rho1) * (1.0 + rho2 * (1.0 + rho1))) / (1.0 + rho2);
1109 ab2 = -rho1 * (1.0 + rho2 * (1.0 + rho1));
1110 ab3 = (pow(rho2, 2.0) * rho1 * (1.0 + rho1)) / (1.0 + rho2);
1111 }
1112}
1113
1115{
1116 real_t my_rt[6], rt_max[6];
1117
1118 my_rt[0] = sw_setup.RealTime();
1119 my_rt[1] = sw_step.RealTime();
1120 my_rt[2] = sw_extrap.RealTime();
1121 my_rt[3] = sw_curlcurl.RealTime();
1122 my_rt[4] = sw_spsolve.RealTime();
1123 my_rt[5] = sw_hsolve.RealTime();
1124
1125 MPI_Reduce(my_rt, rt_max, 6, MPITypeMap<real_t>::mpi_type, MPI_MAX, 0,
1126 pmesh->GetComm());
1127
1128 if (pmesh->GetMyRank() == 0)
1129 {
1130 mfem::out << std::setw(10) << "SETUP" << std::setw(10) << "STEP"
1131 << std::setw(10) << "EXTRAP" << std::setw(10) << "CURLCURL"
1132 << std::setw(10) << "PSOLVE" << std::setw(10) << "HSOLVE"
1133 << "\n";
1134
1135 mfem::out << std::setprecision(3) << std::setw(10) << my_rt[0]
1136 << std::setw(10) << my_rt[1] << std::setw(10) << my_rt[2]
1137 << std::setw(10) << my_rt[3] << std::setw(10) << my_rt[4]
1138 << std::setw(10) << my_rt[5] << "\n";
1139
1140 mfem::out << std::setprecision(3) << std::setw(10) << " " << std::setw(10)
1141 << my_rt[1] / my_rt[1] << std::setw(10) << my_rt[2] / my_rt[1]
1142 << std::setw(10) << my_rt[3] / my_rt[1] << std::setw(10)
1143 << my_rt[4] / my_rt[1] << std::setw(10) << my_rt[5] / my_rt[1]
1144 << "\n";
1145
1146 mfem::out << std::setprecision(8);
1147 }
1148}
1149
1151{
1152 int fes_size0 = vfes->GlobalVSize();
1153 int fes_size1 = pfes->GlobalVSize();
1154
1155 if (pmesh->GetMyRank() == 0)
1156 {
1157 mfem::out << "NAVIER version: " << NAVIER_VERSION << std::endl
1158 << "MFEM version: " << MFEM_VERSION << std::endl
1159 << "MFEM GIT: " << MFEM_GIT_STRING << std::endl
1160 << "Velocity #DOFs: " << fes_size0 << std::endl
1161 << "Pressure #DOFs: " << fes_size1 << std::endl;
1162 }
1163}
1164
1166{
1167 delete FText_gfcoeff;
1168 delete g_bdr_form;
1169 delete FText_bdr_form;
1170 delete mass_lf;
1171 delete Mv_form;
1172 delete N;
1173 delete Sp_form;
1174 delete D_form;
1175 delete G_form;
1176 delete HInvPC;
1177 delete HInv;
1178 delete H_form;
1179 delete SpInv;
1180 delete MvInvPC;
1181 delete SpInvOrthoPC;
1182 delete SpInvPC;
1183 delete lor;
1184 delete f_form;
1185 delete MvInv;
1186 delete vfec;
1187 delete pfec;
1188 delete vfes;
1189 delete pfes;
1190 delete vfec_filter;
1191 delete vfes_filter;
1192}
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
Definition array.cpp:69
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition array.hpp:840
int Size() const
Return the logical size of the array.
Definition array.hpp:166
void SetAssemblyLevel(AssemblyLevel assembly_level)
Set the desired assembly level.
void AddDomainIntegrator(BilinearFormIntegrator *bfi)
Adds new Domain Integrator. Assumes ownership of bfi.
Array< BilinearFormIntegrator * > * GetDBFI()
Access all the integrators added with AddDomainIntegrator().
Class for boundary integration .
Definition lininteg.hpp:224
Conjugate gradient method.
Definition solvers.hpp:627
void Mult(const Vector &b, Vector &x) const override
Iterative solution of the linear system using the Conjugate Gradient method.
Definition solvers.cpp:869
void SetOperator(const Operator &op) override
Set/update the solver for the given operator.
Definition solvers.hpp:640
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
Square Operator for imposing essential boundary conditions using only the action, Mult(),...
void EliminateRHS(const Vector &x, Vector &b) const
Eliminate "essential boundary condition" values specified in x from the given right-hand side b.
Definition operator.cpp:559
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition densemat.hpp:116
Class for domain integration .
Definition lininteg.hpp:108
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:208
ElementTransformation * GetElementTransformation(int i) const
Definition fespace.hpp:905
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for the i'th element. The returned indices are offsets into an ...
Definition fespace.cpp:304
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
Definition fespace.cpp:3824
int GetNE() const
Returns number of elements in the mesh.
Definition fespace.hpp:869
int GetElementOrder(int i) const
Returns the order of the i'th finite element.
Definition fespace.cpp:193
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
Definition fespace.hpp:826
int GetVDim() const
Returns the vector dimension of the finite element space.
Definition fespace.hpp:819
Abstract class for all finite elements.
Definition fe_base.hpp:247
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
Definition fe_base.hpp:341
int GetDim() const
Returns the reference space dimension for the finite element.
Definition fe_base.hpp:324
const IntegrationRule & GetNodes() const
Get a const reference to the nodes of the element.
Definition fe_base.hpp:403
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...
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition fe_base.hpp:334
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition fe_base.hpp:337
A general function coefficient.
void ProjectGridFunction(const GridFunction &src)
Project the src GridFunction to this GridFunction, both of which must be on the same mesh.
Communicator performing operations within groups defined by a GroupTopology with arbitrary-size data ...
void Reduce(T *ldata, void(*Op)(OpData< T >)) const
Reduce within each group where the master is the root.
static void Sum(OpData< T >)
Reduce operation Sum, instantiated for int and double.
void Bcast(T *ldata, int layout) const
Broadcast within each group where the master is the root.
Arbitrary order H1-conforming (continuous) finite elements.
Definition fe_coll.hpp:279
The BoomerAMG solver in hypre.
Definition hypre.hpp:1737
void SetPrintLevel(int print_level)
Definition hypre.hpp:1817
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve the linear system Ax=b.
Definition hypre.cpp:4121
Wrapper for hypre's ParCSR matrix class.
Definition hypre.hpp:419
Parallel smoothers in hypre.
Definition hypre.hpp:1066
Class for integration point with weight.
Definition intrules.hpp:35
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:100
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition intrules.hpp:256
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition intrules.hpp:259
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
virtual void SetIntRule(const IntegrationRule *ir)
Prescribe a fixed IntegrationRule to use, or set to null to let the integrator choose an appropriate ...
real_t GetFinalNorm() const
Returns the final residual norm after termination of the solver during the last call to Mult().
Definition solvers.hpp:304
void SetRelTol(real_t rtol)
Definition solvers.hpp:238
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Definition solvers.cpp:178
int GetNumIterations() const
Returns the number of iterations taken during the last call to Mult()
Definition solvers.hpp:289
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
Definition solvers.cpp:76
void SetMaxIter(int max_it)
Definition solvers.hpp:240
void AddDomainIntegrator(LinearFormIntegrator *lfi)
Adds new Domain Integrator. Assumes ownership of lfi.
void AddBoundaryIntegrator(LinearFormIntegrator *lfi)
Adds new Boundary Integrator. Assumes ownership of lfi.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Definition mesh.hpp:304
Geometry::Type GetTypicalElementGeometry() const
If the local mesh is not empty, return GetElementGeometry(0); otherwise, return a typical Geometry pr...
Definition mesh.cpp:1628
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1306
real_t GetElementSize(int i, int type=0)
Get the size of the i-th element relative to the perfect reference element.
Definition mesh.cpp:110
void SetAssemblyLevel(AssemblyLevel assembly_level)
Set the desired assembly level. The default is AssemblyLevel::LEGACY.
void AddDomainIntegrator(BilinearFormIntegrator *bfi)
Adds a domain integrator. Assumes ownership of bfi.
void AddDomainIntegrator(NonlinearFormIntegrator *nlfi)
Adds new Domain Integrator.
void SetAssemblyLevel(AssemblyLevel assembly_level)
Set the desired assembly level. The default is AssemblyLevel::LEGACY.
virtual void Setup()
Setup the NonlinearForm: based on the current AssemblyLevel and the current mesh, optionally,...
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get().
Definition handle.hpp:104
Jacobi smoothing for a given bilinear form (no matrix necessary).
Definition solvers.hpp:422
Abstract operator.
Definition operator.hpp:25
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition operator.hpp:66
virtual const Operator * GetRestriction() const
Restriction operator from input vectors for the operator to linear algebra (linear system) vectors....
Definition operator.hpp:155
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition operator.hpp:72
virtual const Operator * GetOutputProlongation() const
Prolongation operator from linear algebra (linear system) vectors, to output vectors for the operator...
Definition operator.hpp:159
virtual const Operator * GetProlongation() const
Prolongation operator from linear algebra (linear system) vectors, to input vectors for the operator....
Definition operator.hpp:151
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
Solver wrapper which orthogonalizes the input and output vector.
Definition solvers.hpp:1332
void SetSolver(Solver &s)
Set the solver used by the OrthoSolver.
Definition solvers.cpp:3702
Class for parallel bilinear form.
void RecoverFEMSolution(const Vector &X, const Vector &b, Vector &x) override
void Assemble(int skip_zeros=1)
Assemble the local matrix.
void FormSystemMatrix(const Array< int > &ess_tdof_list, OperatorHandle &A) override
Form the linear system matrix A, see FormLinearSystem() for details.
void Update(FiniteElementSpace *nfes=NULL) override
Update the FiniteElementSpace and delete all data associated with the old one.
void AssembleDiagonal(Vector &diag) const override
Assemble the diagonal of the bilinear form into diag. Note that diag is a true-dof Vector.
void FormLinearSystem(const Array< int > &ess_tdof_list, Vector &x, Vector &b, OperatorHandle &A, Vector &X, Vector &B, int copy_interior=0) override
Form the linear system A X = B, corresponding to this bilinear form and the linear form b(....
Abstract parallel finite element space.
Definition pfespace.hpp:31
MPI_Comm GetComm() const
Definition pfespace.hpp:337
void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1) const override
HYPRE_BigInt GlobalVSize() const
Definition pfespace.hpp:347
int GetTrueVSize() const override
Return the number of local vector true dofs.
Definition pfespace.hpp:353
const SparseMatrix * GetRestrictionMatrix() const override
Get the R matrix which restricts a local dof vector to true dof vector.
Definition pfespace.hpp:470
Class for parallel grid function.
Definition pgridfunc.hpp:50
HypreParVector * GetTrueDofs() const
Returns the true dofs in a new HypreParVector.
void SetFromTrueDofs(const Vector &tv) override
Set the GridFunction from the given true-dof vector.
void ProjectBdrCoefficient(Coefficient *coeff[], VectorCoefficient *vcoeff, const Array< int > &attr)
ParFiniteElementSpace * ParFESpace() const
void ProjectCoefficient(Coefficient &coeff) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
void SetSpace(FiniteElementSpace *f) override
Associate a new FiniteElementSpace with the ParGridFunction.
Definition pgridfunc.cpp:91
Create and assemble a low-order refined version of a ParBilinearForm.
Definition lor.hpp:166
HypreParMatrix & GetAssembledMatrix() const
Return the assembled LOR operator as a HypreParMatrix.
Definition lor.cpp:522
Class for parallel linear form.
void ParallelAssemble(Vector &tv)
Assemble the vector on the true dofs, i.e. P^t v.
void Assemble()
Assembles the ParLinearForm i.e. sums over all domain/bdr integrators.
Class for parallel meshes.
Definition pmesh.hpp:34
MPI_Comm GetComm() const
Definition pmesh.hpp:405
int GetMyRank() const
Definition pmesh.hpp:407
Class for parallel bilinear form using different test and trial FE spaces.
void Assemble(int skip_zeros=1)
Assemble the local matrix.
void FormRectangularSystemMatrix(const Array< int > &trial_tdof_list, const Array< int > &test_tdof_list, OperatorHandle &A) override
Return in A a parallel (on truedofs) version of this operator.
Parallel non-linear operator on the true dofs.
void Mult(const Vector &x, Vector &y) const override
Evaluate the action of the NonlinearForm.
A class container for 1D quadrature type constants.
Definition intrules.hpp:400
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
Definition operator.hpp:795
void MultTranspose(const Vector &x, Vector &y) const override
Multiply a vector with the transposed matrix. y = At * x.
double RealTime()
Return the number of real seconds elapsed since the stopwatch was started.
Definition tic_toc.cpp:432
void Start()
Start the stopwatch. The elapsed time is not cleared.
Definition tic_toc.cpp:411
void Stop()
Stop the stopwatch.
Definition tic_toc.cpp:422
Base class for vector Coefficients that optionally depend on time and space.
A general vector function coefficient.
Vector coefficient defined by a vector GridFunction.
Vector data type.
Definition vector.hpp:82
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:520
void Neg()
(*this) = -(*this)
Definition vector.cpp:376
virtual real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:536
Vector & Set(const real_t a, const Vector &x)
(*this) = a * x
Definition vector.cpp:341
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
real_t Sum() const
Return the sum of the vector entries.
Definition vector.cpp:1246
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:584
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
Definition vector.hpp:243
void SetSubVectorComplement(const Array< int > &dofs, const real_t val)
Set all vector entries NOT in the dofs Array to the given val.
Definition vector.cpp:854
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:528
Vector & Add(const real_t a, const Vector &Va)
(*this) += a * Va
Definition vector.cpp:326
void Setup(real_t dt)
Initialize forms, solvers and preconditioners.
ParFiniteElementSpace * vfes_filter
real_t kin_vis
Kinematic viscosity (dimensionless).
real_t ComputeCFL(ParGridFunction &u, real_t dt)
Compute CFL.
ParLORDiscretization * lor
bool verbose
Enable/disable verbose output.
void AddVelDirichletBC(VectorCoefficient *coeff, Array< int > &attr)
Add a Dirichlet boundary condition to the velocity field.
FiniteElementCollection * vfec
Velocity finite element collection.
std::vector< PresDirichletBC_T > pres_dbcs
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.
VectorGridFunctionCoefficient * FText_gfcoeff
int order
The order of the velocity and pressure space.
bool partial_assembly
Enable/disable partial assembly of forms.
void PrintTimingData()
Print timing summary of the solving routine.
void AddPresDirichletBC(Coefficient *coeff, Array< int > &attr)
Add a Dirichlet boundary condition to the pressure field.
FiniteElementCollection * vfec_filter
ConstantCoefficient onecoeff
ParFiniteElementSpace * pfes
Pressure finite element space.
ConstantCoefficient nlcoeff
void PrintInfo()
Print information about the Navier version.
std::vector< AccelTerm_T > accel_terms
void MeanZero(ParGridFunction &v)
Remove the mean from a ParGridFunction.
void ComputeCurl2D(ParGridFunction &u, ParGridFunction &cu, bool assume_scalar=false)
Compute for .
bool numerical_integ
Enable/disable numerical integration rules of forms.
ParMixedBilinearForm * D_form
void UpdateTimestepHistory(real_t dt)
Rotate entries in the time step and solution history arrays.
ParLinearForm * mass_lf
Linear form to compute the mass matrix in various subroutines.
ConstantCoefficient H_lincoeff
ParMesh * pmesh
The parallel mesh.
ConstantCoefficient H_bdfcoeff
void AddAccelTerm(VectorCoefficient *coeff, Array< int > &attr)
Add an acceleration term to the RHS of the equation.
std::vector< VelDirichletBC_T > vel_dbcs
void Step(real_t &time, real_t dt, int cur_step, bool provisional=false)
Compute solution at the next time step t+dt.
ParMixedBilinearForm * G_form
FiniteElementCollection * pfec
Pressure finite element collection.
void SetTimeIntegrationCoefficients(int step)
Update the EXTk/BDF time integration coefficient.
void Orthogonalize(Vector &v)
Remove mean from a Vector.
ParFiniteElementSpace * vfes
Velocity finite element space.
void ComputeCurl3D(ParGridFunction &u, ParGridFunction &cu)
Compute for .
NavierSolver(ParMesh *mesh, int order, real_t kin_vis)
Initialize data structures, set FE space order and kinematic viscosity.
std::vector< real_t > dthist
int dim
Definition ex24.cpp:53
real_t b
Definition lissajous.cpp:42
real_t(const Vector &x, real_t t) ScalarFuncT
void(const Vector &x, real_t t, Vector &u) VecFuncT
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition table.cpp:505
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
ComplexDenseMatrix * MultAtB(const ComplexDenseMatrix &A, const ComplexDenseMatrix &B)
Multiply the complex conjugate transpose of a matrix A with a matrix B. A^H*B.
float real_t
Definition config.hpp:46
std::function< real_t(const Vector &)> f(real_t mass_coeff)
Definition lor_mms.hpp:30
void forall(int N, lambda &&body)
Definition forall.hpp:839
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition intrules.hpp:492
void vel_dbc(const Vector &x, real_t t, Vector &u)
Fluid data.
void CopyDBFIntegrators(ParBilinearForm *src, ParBilinearForm *dst)
Helper struct to convert a C++ type to an MPI type.