MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
mtop_solvers.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 <memory>
13
14#include "mtop_solvers.hpp"
15
16using namespace mfem;
17
21
25
26///////////////////////////////////////////////////////////////////////////////
27/// \brief The QFunction struct defining the linear elasticity operator at
28/// integration points which is valid in 2D and 3D
29template <int DIM> struct QFunction
30{
31 using matd_t = tensor<real_t, DIM, DIM>;
32
33 struct Elasticity
34 {
35 MFEM_HOST_DEVICE inline auto operator()(const matd_t &dudxi,
36 const real_t &L, const real_t &M,
37 const matd_t &J,
38 const real_t &w) const
39 {
40 const matd_t JxW = transpose(inv(J)) * det(J) * w;
41 constexpr auto I = mfem::future::IsotropicIdentity<DIM>();
42 const auto eps = mfem::future::sym(dudxi * mfem::future::inv(J));
43 return tuple{(L * tr(eps) * I + 2.0 * M * eps) * JxW};
44 }
45 };
46};
47
49 bool pa, bool dfem):
50 pmesh(mesh),
51 pa(pa),
52 dfem(dfem),
53 dim(mesh->Dimension()),
54 spaceDim(mesh->SpaceDimension()),
55 vfec(new H1_FECollection(vorder, dim)),
56 vfes(new ParFiniteElementSpace(pmesh, vfec, dim,
57 // PA Elasticity only implemented for byNODES ordering
58 pa||dfem ? Ordering::byNODES : Ordering::byVDIM)),
59 sol(vfes->GetTrueVSize()),
60 adj(vfes->GetTrueVSize()),
61 rhs(vfes->GetTrueVSize()),
62 fdisp(vfes),
63 adisp(vfes),
64 prec(nullptr),
65 ls(nullptr),
66 lor_block_offsets(dim + 1),
67 lvforce(nullptr),
68 volforce(nullptr),
69 E(nullptr),
70 nu(nullptr),
71 lambda(nullptr),
72 mu(nullptr),
73 bf(nullptr),
74 fe(vfes->GetFE(0)),
75 nodes((pmesh->EnsureNodes(),
76 static_cast<ParGridFunction *>(pmesh->GetNodes()))),
77 mfes(nodes->ParFESpace()),
78 ir(IntRules.Get(fe->GetGeomType(),
79 fe->GetOrder() + fe->GetOrder() + fe->GetDim() - 1)),
80 qs(*pmesh, ir),
81 Lambda_ps(*pmesh, ir, 1),
82 Mu_ps(*pmesh, ir, 1),
83 lf(nullptr)
84{
85 MFEM_VERIFY(qs.GetSize() == Lambda_ps.GetTrueVSize(),
86 "QuadratureSpace and ParameterSpace size mismatch");
87
88 sol = 0.0;
89 rhs = 0.0;
90 adj = 0.0;
91
92 fdisp = 0.0;
93 adisp = 0.0;
94
96
99
100 lcsurf_load = std::make_unique<SurfaceLoad>(dim, load_coeff);
101 glsurf_load = std::make_unique<SurfaceLoad>(dim, surf_loads);
102
103 if (pmesh->attributes.Size() > 0)
104 {
105 domain_attributes.SetSize(pmesh->attributes.Max());
106 domain_attributes = 1;
107 }
108}
109
111{
112 delete prec;
113 delete ls;
114
115 delete bf;
116 delete lf;
117
118 delete vfes;
119 delete vfec;
120
121 delete lvforce;
122
123 for (auto it = load_coeff.begin(); it != load_coeff.end(); it++)
124 {
125 delete it->second;
126 }
127
128 delete lambda;
129 delete mu;
130}
131
133 real_t atol,
134 int miter)
135{
136 linear_rtol = rtol;
137 linear_atol = atol;
138 linear_iter = miter;
139}
140
142 real_t val)
143{
144 if (dir == 0)
145 {
146 bcx[id] = ConstantCoefficient(val);
147 AddDispBC(id, dir, bcx[id]);
148 }
149 else if (dir == 1)
150 {
151 bcy[id] = ConstantCoefficient(val);
152 AddDispBC(id, dir, bcy[id]);
153 }
154 else if (dir == 2)
155 {
156 bcz[id] = ConstantCoefficient(val);
157 AddDispBC(id, dir, bcz[id]);
158 }
159 else if (dir == -1)
160 {
161 bcx[id] = ConstantCoefficient(val);
162 bcy[id] = ConstantCoefficient(val);
163 bcz[id] = ConstantCoefficient(val);
164 AddDispBC(id, 0, bcx[id]);
165 AddDispBC(id, 1, bcy[id]);
166 AddDispBC(id, 2, bcz[id]);
167 }
168 else
169 {
170 MFEM_ABORT("Invalid BC direction: "
171 "0(x), 1(y), 2(z), or -1(all), got " << dir);
172 }
173}
174
176{
177 bccx.clear();
178 bccy.clear();
179 bccz.clear();
180
181 bcx.clear();
182 bcy.clear();
183 bcz.clear();
184
185 ess_tdofv.DeleteAll();
186}
187
189{
190 if (dir == 0) { bccx[id] = &val; }
191 else if (dir == 1) { bccy[id] = &val; }
192 else if (dir == 2) { bccz[id] = &val; }
193 else if (dir == -1)
194 {
195 bccx[id] = &val;
196 bccy[id] = &val;
197 bccz[id] = &val;
198 }
199 else
200 {
201 MFEM_ABORT("Invalid BC direction: "
202 "0(x), 1(y), 2(z), or -1(all), got " << dir);
203 }
204 if (pmesh->Dimension() == 2) { bccz.clear(); }
205}
206
208{
209 delete lvforce;
210 Vector ff(dim);
211 ff(0) = fx;
212 ff(1) = fy;
213 if (dim == 3) { ff(2) = fz; }
214 lvforce = new VectorConstantCoefficient(ff);
215 volforce = lvforce;
216}
217
219{
220 volforce = &fv;
221}
222
223
225 ParFiniteElementSpace& scalar_space,
226 Array<int> &ess_dofs)
227{
228 // Set the BC
229 ess_dofs.DeleteAll();
230
231 auto cbcc = &bccx;
232 if (j == 1) { cbcc = &bccy; }
233 else if (j == 2) { cbcc = &bccz; }
234
235 Array<int> ess_bdr(pmesh->bdr_attributes.Max()); ess_bdr = 0;
236
237 for (auto it = cbcc->begin(); it != cbcc->end(); it++)
238 {
239 ess_bdr[it->first - 1] = 1;
240 }
241 scalar_space.GetEssentialTrueDofs(ess_bdr,ess_dofs);
242}
243
244
246{
247 // Set the BC
248 ess_tdofv.DeleteAll();
249
250 Array<int> ess_tdofx, ess_tdofy, ess_tdofz;
251
252 for (auto it = bccx.begin(); it != bccx.end(); it++)
253 {
254 Array<int> ess_bdr(pmesh->bdr_attributes.Max());
255 ess_bdr = 0;
256 ess_bdr[it->first - 1] = 1;
257 Array<int> ess_tdof_list;
258 vfes->GetEssentialTrueDofs(ess_bdr, ess_tdof_list, 0);
259 ess_tdofx.Append(ess_tdof_list);
260
261 VectorArrayCoefficient pcoeff(dim);
262 pcoeff.Set(0, it->second, false);
263 fdisp.ProjectBdrCoefficient(pcoeff, ess_bdr);
264 }
265 // copy tdofsx from displacement grid function
266 {
267 Vector &vc = fdisp.GetTrueVector();
268 const int Net = ess_tdofx.Size();
269 const auto d_vc = vc.Read();
270 const auto d_ess_tdofx = ess_tdofx.Read();
271 auto d_bsol = bsol.ReadWrite();
272 mfem::forall(Net, [=] MFEM_HOST_DEVICE(int ii)
273 {
274 d_bsol[d_ess_tdofx[ii]] = d_vc[d_ess_tdofx[ii]];
275 });
276 }
277 ess_tdofx.HostReadWrite(), ess_dofs.HostReadWrite();
278 ess_dofs.Append(ess_tdofx);
279 ess_tdofx.DeleteAll();
280
281 for (auto it = bccy.begin(); it != bccy.end(); it++)
282 {
283 Array<int> ess_bdr(pmesh->bdr_attributes.Max());
284 ess_bdr = 0;
285 ess_bdr[it->first - 1] = 1;
286 Array<int> ess_tdof_list;
287 vfes->GetEssentialTrueDofs(ess_bdr, ess_tdof_list, 1);
288 ess_tdofy.Append(ess_tdof_list);
289
290 VectorArrayCoefficient pcoeff(dim);
291 pcoeff.Set(1, it->second, false);
292 fdisp.ProjectBdrCoefficient(pcoeff, ess_bdr);
293 }
294 // copy tdofsy from displacement grid function
295 {
296 Vector &vc = fdisp.GetTrueVector();
297 const int Net = ess_tdofy.Size();
298 const auto d_vc = vc.Read();
299 const auto d_ess_tdofy = ess_tdofy.Read();
300 auto d_bsol = bsol.ReadWrite();
301 mfem::forall(Net, [=] MFEM_HOST_DEVICE(int ii)
302 {
303 d_bsol[d_ess_tdofy[ii]] = d_vc[d_ess_tdofy[ii]];
304 });
305 ess_tdofy.HostReadWrite(), ess_dofs.HostReadWrite();
306 }
307 ess_dofs.Append(ess_tdofy);
308 ess_tdofy.DeleteAll();
309
310 if (dim == 3)
311 {
312 for (auto it = bccz.begin(); it != bccz.end(); it++)
313 {
314 Array<int> ess_bdr(pmesh->bdr_attributes.Max());
315 ess_bdr = 0;
316 ess_bdr[it->first - 1] = 1;
317 Array<int> ess_tdof_list;
318 vfes->GetEssentialTrueDofs(ess_bdr, ess_tdof_list, 2);
319 ess_tdofz.Append(ess_tdof_list);
320
321 VectorArrayCoefficient pcoeff(dim);
322 pcoeff.Set(2, it->second, false);
323 fdisp.ProjectBdrCoefficient(pcoeff, ess_bdr);
324 }
325
326 // copy tdofsz from displacement grid function
327 {
328 Vector &vc = fdisp.GetTrueVector();
329 for (int ii = 0; ii < ess_tdofz.Size(); ii++)
330 {
331 bsol[ess_tdofz[ii]] = vc[ess_tdofz[ii]];
332 }
333 }
334 ess_dofs.Append(ess_tdofz);
335 ess_tdofz.DeleteAll();
336 }
337}
338
340{
341 // the rhs x is assumed to have the contribution of the BC set in advance
342 // the BC values are not modified here
343 ls->Mult(x, y);
344
345 int N = ess_tdofv.Size();
346 real_t *yp = y.ReadWrite();
347 const real_t *sp = sol.Read();
348 const int *ep = ess_tdofv.Read();
349 mfem::forall(N, [=] MFEM_HOST_DEVICE(int i) { yp[ep[i]] = sp[ep[i]]; });
350}
351
353 Vector &y) const
354{
355 // the adjoint rhs is assumed to be corrected for the BC
356 // K is symmetric
357 ls->Mult(x, y);
358
359 int N = ess_tdofv.Size();
360 ess_tdofv.Read();
361
362 auto yp = y.Write();
363 const auto ep = ess_tdofv.Read();
364
365 mfem::forall(N, [=] MFEM_HOST_DEVICE(int i) { yp[ep[i]] = 0.0; });
366}
367
369{
370 delete bf; bf=nullptr;
371
372 if (dfem)
373 {
374#ifdef MFEM_USE_DOUBLE
375 // define the differentiable operator
376 dop = std::make_unique<mfem::future::DifferentiableOperator>(
377 std::vector<mfem::future::FieldDescriptor> {{ U, vfes }},
378 std::vector<mfem::future::FieldDescriptor>
379 {
380 { LCoeff, &Lambda_ps},
381 { MuCoeff, &Mu_ps},
382 { Coords, mfes }
383 },
384 *pmesh);
385
386 // sample lambda on the integration points
387 Lambda_cv = std::make_unique<CoefficientVector>(*lambda, qs);
388
389 // sample mu on the integration points
390 Mu_cv = std::make_unique<CoefficientVector>(*mu, qs);
391
392 // set the parameters of the differentiable operator
393 dop->SetParameters({ Lambda_cv.get(), Mu_cv.get(), nodes });
394
395 // define the q-function for dimensions 2 and 3
396 const auto inputs =
400 Weight{} };
401 const auto output = mfem::future::tuple{ Gradient<U>{} };
402 if (2 == spaceDim)
403 {
404 typename QFunction<2>::Elasticity e2qf;
405 dop->AddDomainIntegrator(e2qf, inputs, output, ir, domain_attributes);
406 }
407 else if (3 == spaceDim)
408 {
409 typename QFunction<3>::Elasticity e3qf;
410 dop->AddDomainIntegrator(e3qf, inputs, output, ir, domain_attributes);
411 }
412 else { MFEM_ABORT("Space dimension not supported"); }
413#else
414 MFEM_ABORT("Differentiable operator is only supported in double precision");
415#endif
416 }
417 else
418 {
419 // define standard bilinear form
420 bf = new mfem::ParBilinearForm(vfes);
421 bf->AddDomainIntegrator(new mfem::ElasticityIntegrator(*lambda, *mu));
423 }
424
425 // set BC
426 sol = real_t(0.0);
427 SetEssTDofs(sol, ess_tdofv);
428
429 if (pa)
430 {
431 bf->Assemble();
432 Operator *Kop;
433 bf->FormSystemOperator(ess_tdofv, Kop);
434 Kh = std::make_unique<OperatorHandle>(Kop);
435 Kc = dynamic_cast<mfem::ConstrainedOperator*>(Kop);
436 }
437 else if (dfem)
438 {
439 Operator *Kop;
440 dop->FormSystemOperator(ess_tdofv, Kop);
441 Kh = std::make_unique<OperatorHandle>(Kop);
442 Kc = dynamic_cast<mfem::ConstrainedOperator*>(Kop);
443 }
444 else
445 {
446 bf->Assemble(0);
447 bf->Finalize();
448 K.reset(bf->ParallelAssemble());
449 Ke.reset(K->EliminateRowsCols(ess_tdofv));
450 }
451
452 if (ls == nullptr)
453 {
454 ls = new CGSolver(pmesh->GetComm());
455 if (pa || dfem)
456 {
457 // PA LOR lor_disc & scalar_lor_fespace setup
458 lor_disc = std::make_unique<ParLORDiscretization>(*vfes);
459 ParFiniteElementSpace &lor_space = lor_disc->GetParFESpace();
460 const FiniteElementCollection &lor_fec = *lor_space.FEColl();
461 ParMesh &lor_mesh = *lor_space.GetParMesh();
462 lor_scalar_fespace = std::make_unique<ParFiniteElementSpace>(
463 &lor_mesh, &lor_fec, 1, Ordering::byNODES);
464 lor_block_offsets[0] = 0;
465 lor_integrator = std::make_unique<ElasticityIntegrator>(*lambda, *mu);
466 lor_integrator->AssemblePA(lor_disc->GetParFESpace());
467
468 for (int j = 0; j < dim; j++)
469 {
470 auto *block = new ElasticityComponentIntegrator(*lor_integrator, j, j);
471 // create the LOR matrix and corresponding AMG preconditioners.
472 lor_bilinear_forms.emplace_back(new ParBilinearForm(lor_scalar_fespace.get()));
473 lor_bilinear_forms[j]->SetAssemblyLevel(AssemblyLevel::FULL);
474 lor_bilinear_forms[j]->EnableSparseMatrixSorting(Device::IsEnabled());
475 lor_bilinear_forms[j]->AddDomainIntegrator(block);
476 lor_bilinear_forms[j]->Assemble();
477 // set the essential boundaries
478 Array<int> ess_tdof_list_block;
479 SetEssTDofs(j,*lor_scalar_fespace,ess_tdof_list_block);
480 lor_block.emplace_back(lor_bilinear_forms[j]->ParallelAssemble());
481 lor_block[j]->EliminateBC(ess_tdof_list_block,
482 Operator::DiagonalPolicy::DIAG_ONE);
483 lor_amg_blocks.emplace_back(new HypreBoomerAMG);
484 lor_amg_blocks[j]->SetStrengthThresh(0.25);
485 lor_amg_blocks[j]->SetRelaxType(16); // Chebyshev
486 lor_amg_blocks[j]->SetOperator(*lor_block[j]);
487 lor_block_offsets[j+1] = lor_amg_blocks[j]->Height();
488 }
489
490 lor_block_offsets.PartialSum();
491 lor_blockDiag =
492 std::make_unique<BlockDiagonalPreconditioner>(lor_block_offsets);
493 for (int i = 0; i < dim; i++)
494 {
495 lor_blockDiag->SetDiagonalBlock(i, lor_amg_blocks[i].get());
496 }
497 lor_pa_prec.reset(lor_blockDiag.release());
498 ls->SetPreconditioner(*lor_pa_prec);
499 }
500 else
501 {
502 prec = new HypreBoomerAMG();
503 // set the rigid body modes
504 prec->SetElasticityOptions(vfes);
505 ls->SetPreconditioner(*prec);
506 }
507 ls->SetOperator(((pa||dfem) ? *Kh->Ptr() : *K));
508 ls->SetPrintLevel(1);
509 }
510 else
511 {
512 ls->SetOperator((pa||dfem) ? *Kh->Ptr() : *K);
513 }
514}
515
517{
518 ls->SetAbsTol(linear_atol);
519 ls->SetRelTol(linear_rtol);
520 ls->SetMaxIter(linear_iter);
521
522 if (lf == nullptr)
523 {
524 lf = new ParLinearForm(vfes);
525 if (volforce != nullptr)
526 {
528 }
529 // add surface loads
531 }
532
533 (*lf) = real_t(0.0);
534
535 if (pa || dfem) { lf->UseFastAssembly(true); }
536 lf->Assemble();
537 lf->ParallelAssemble(rhs);
538
539 if (pa || dfem) { Kc->EliminateRHS(sol, rhs); }
540 else
541 {
542 K->EliminateBC(*Ke, ess_tdofv, sol, rhs);
543 }
544
545 ls->Mult(rhs, sol);
546
547 delete lf;
548 lf = nullptr;
549}
void SetEssTDofs(mfem::Vector &bsol, mfem::Array< int > &ess_dofs)
void AddDispBC(int id, int dir, real_t val)
Adds displacement BC in direction 0(x), 1(y), 2(z), or -1(all).
void FSolve()
Solves the forward problem.
void SetVolForce(real_t fx, real_t fy, real_t fz=0.0)
Set the values of the volumetric force.
void Mult(const mfem::Vector &x, mfem::Vector &y) const override
Forward solve with given RHS. x is the RHS vector.
void SetLinearSolver(real_t rtol=1e-8, real_t atol=1e-12, int miter=200)
IsoLinElasticSolver(mfem::ParMesh *mesh, int vorder=1, bool pa=false, bool dfem=false)
~IsoLinElasticSolver()
Destructor of the solver.
virtual void Assemble()
void MultTranspose(const mfem::Vector &x, mfem::Vector &y) const override
void DelDispBC()
Clear all displacement BC.
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 PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
Definition array.cpp:104
void DeleteAll()
Delete the whole array.
Definition array.hpp:1033
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Definition array.hpp:912
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:381
T * HostReadWrite()
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), false).
Definition array.hpp:401
void SetAssemblyLevel(AssemblyLevel assembly_level)
Set the desired assembly level.
void AddDomainIntegrator(BilinearFormIntegrator *bfi)
Adds new Domain Integrator. Assumes ownership of bfi.
void Finalize(int skip_zeros=1) override
Finalizes the matrix initialization if the AssemblyLevel is AssemblyLevel::LEGACY....
void SetDiagonalBlock(int iblock, Operator *op)
Add a square block op in the block-entry (iblock, iblock).
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...
A coefficient that is constant across space and time.
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
static bool IsEnabled()
Return true if any backend other than Backend::CPU is enabled.
Definition device.hpp:247
Integrator that computes the PA action of one of the blocks in an ElasticityIntegrator,...
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Definition fe_coll.hpp:27
const FiniteElementCollection * FEColl() const
Definition fespace.hpp:856
const Vector & GetTrueVector() const
Read only access to the (optional) internal true-dof Vector.
Definition gridfunc.hpp:134
Arbitrary order H1-conforming (continuous) finite elements.
Definition fe_coll.hpp:279
The BoomerAMG solver in hypre.
Definition hypre.hpp:1737
void SetElasticityOptions(ParFiniteElementSpace *fespace, bool interp_refine=true)
Definition hypre.cpp:5312
void EliminateRowsCols(const Array< int > &rows_cols, const HypreParVector &X, HypreParVector &B)
Definition hypre.cpp:2399
void EliminateBC(const HypreParMatrix &Ae, const Array< int > &ess_dof_list, const Vector &X, Vector &B) const
Eliminate essential BC specified by ess_dof_list from the solution X to the r.h.s....
Definition hypre.cpp:2451
void SetRelTol(real_t rtol)
Definition solvers.hpp:238
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Definition solvers.cpp:178
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 SetAbsTol(real_t atol)
Definition solvers.hpp:239
void AddDomainIntegrator(LinearFormIntegrator *lfi)
Adds new Domain Integrator. Assumes ownership of lfi.
void AddBoundaryIntegrator(LinearFormIntegrator *lfi)
Adds new Boundary Integrator. Assumes ownership of lfi.
void UseFastAssembly(bool use_fa)
Which assembly algorithm to use: the new device-compatible fast assembly (true), or the legacy CPU-on...
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Definition mesh.hpp:304
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1306
Array< int > attributes
A list of all unique element attributes used by the Mesh.
Definition mesh.hpp:302
Operator * Ptr() const
Access the underlying Operator pointer.
Definition handle.hpp:87
Abstract operator.
Definition operator.hpp:25
int width
Dimension of the input / number of columns in the matrix.
Definition operator.hpp:28
void FormSystemOperator(const Array< int > &ess_tdof_list, Operator *&A)
Return in A a parallel (on truedofs) version of this square operator.
Definition operator.cpp:227
int height
Dimension of the output / number of rows in the matrix.
Definition operator.hpp:27
The ordering method used when the number of unknowns per mesh node (vector dimension) is bigger than ...
Definition ordering.hpp:13
Class for parallel bilinear form.
HypreParMatrix * ParallelAssemble()
Returns the matrix assembled on the true dofs, i.e. P^t A P.
void Assemble(int skip_zeros=1)
Assemble the local matrix.
Abstract parallel finite element space.
Definition pfespace.hpp:31
void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1) const override
int GetTrueVSize() const override
Return the number of local vector true dofs.
Definition pfespace.hpp:353
ParMesh * GetParMesh() const
Definition pfespace.hpp:341
Class for parallel grid function.
Definition pgridfunc.hpp:50
void ProjectBdrCoefficient(Coefficient *coeff[], VectorCoefficient *vcoeff, const Array< int > &attr)
ParFiniteElementSpace & GetParFESpace() const
Return the LOR ParFiniteElementSpace.
Definition lor.cpp:528
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 GetSize() const
Return the total number of quadrature points.
Definition qspace.hpp:107
Vector coefficient defined by an array of scalar coefficients. Coefficients that are not set will eva...
void Set(int i, Coefficient *c, bool own=true)
Sets coefficient in the vector.
Base class for vector Coefficients that optionally depend on time and space.
Vector coefficient that is constant in space and time.
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
virtual real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:536
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:528
void SetParameters(std::vector< Vector * > p) const
Set the parameters for the operator.
Definition doperator.cpp:19
void AddDomainIntegrator(qfunc_t &qfunc, input_t inputs, output_t outputs, const IntegrationRule &integration_rule, const Array< int > &domain_attributes, derivative_ids_t derivative_ids=std::make_index_sequence< 0 > {})
Add a domain integrator to the operator.
Gradient FieldOperator.
Identity FieldOperator.
Weight FieldOperator.
int dim
Definition ex24.cpp:53
real_t mu
Definition ex25.cpp:140
mfem::real_t real_t
MFEM_HOST_DEVICE constexpr isotropic_tensor< real_t, m, m > IsotropicIdentity()
Definition tensor.hpp:2042
MFEM_HOST_DEVICE T det(const tensor< T, 1, 1 > &A)
Returns the determinant of a matrix.
Definition tensor.hpp:1406
MFEM_HOST_DEVICE T tr(const tensor< T, n, n > &A)
Returns the trace of a square matrix.
Definition tensor.hpp:1317
MFEM_HOST_DEVICE tensor< T, 1, 1 > inv(const tensor< T, 1, 1 > &A)
Inverts a matrix.
Definition tensor.hpp:1707
MFEM_HOST_DEVICE tensor< T, n, m > transpose(const tensor< T, m, n > &A)
Returns the transpose of the matrix.
Definition tensor.hpp:1388
MFEM_HOST_DEVICE tensor< T, n, n > sym(const tensor< T, n, n > &A)
Returns the symmetric part of a square matrix.
Definition tensor.hpp:1333
float real_t
Definition config.hpp:46
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
Dual number struct (value plus gradient)
Definition dual.hpp:36
This is a class that mimics most of std::tuple's interface, except that it is usable in CUDA kernels ...
Definition tuple.hpp:49
std::array< int, NCMesh::MaxFaceNodes > nodes