MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
mesh-optimizer.hpp
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// MFEM Mesh Optimizer Miniapp - Serial/Parallel Shared Code
13
14#include "mfem.hpp"
15#include <fstream>
16#include <iostream>
17
18using namespace mfem;
19using namespace std;
20
22{
23 // semi-circle
24 const real_t xc = x(0) - 0.0, yc = x(1) - 0.5,
25 zc = (x.Size() == 3) ? x(2) - 0.5 : 0.0;
26 const real_t r = sqrt(xc*xc + yc*yc + zc*zc);
27 real_t r1 = 0.45; real_t r2 = 0.55; real_t sf=30.0;
28 real_t val = 0.5*(1+std::tanh(sf*(r-r1))) - 0.5*(1+std::tanh(sf*(r-r2)));
29
30 val = std::max((real_t) 0.,val);
31 val = std::min((real_t) 1.,val);
32 return val;
33}
34
36{
37 // top right
38 real_t xc = x(0) - 0.75, yc = x(1) - 0.75,
39 zc = (x.Size() == 3) ? x(2) - 0.0 : 0.0;
40 real_t r = sqrt(xc*xc + yc*yc + zc*zc);
41 real_t r1 = 0.45; real_t r2 = 0.55; real_t sf=30.0;
42 real_t val = 0.5*(1+std::tanh(sf*(r-r1))) - 0.5*(1+std::tanh(sf*(r-r2)));
43 val = std::max((real_t) 0.,val);
44 val = std::min((real_t) 1.,val);
45
46 // bottom right
47 xc = x(0) - 0.75; yc = x(1) + 1.25;
48 zc = (x.Size() == 3) ? x(2) - 0.0 : 0.0;
49 r = sqrt(xc*xc + yc*yc + zc*zc);
50 r1 = 0.45; r2 = 0.55; sf=30.0;
51 real_t val1 = 0.5*(1+std::tanh(sf*(r-r1))) - 0.5*(1+std::tanh(sf*(r-r2)));
52 val = std::max(val, val1);
53
54 // top left
55 xc = x(0) + 1.25; yc = x(1) - 0.75;
56 zc = (x.Size() == 3) ? x(2) - 0.0 : 0.0;
57 r = sqrt(xc*xc + yc*yc + zc*zc);
58 r1 = 0.45; r2 = 0.55; sf=30.0;
59 real_t val2 = 0.5*(1+std::tanh(sf*(r-r1))) - 0.5*(1+std::tanh(sf*(r-r2)));
60 val = std::max(val, val2);
61
62 // bottom left
63 xc = x(0) + 1.25; yc = x(1) + 1.25;
64 zc = (x.Size() == 3) ? x(2) - 0.0 : 0.0;
65 r = sqrt(xc*xc + yc*yc + zc*zc);
66 r1 = 0.45; r2 = 0.55; sf=30.0;
67 real_t val3 = 0.5*(1+std::tanh(sf*(r-r1))) - 0.5*(1+std::tanh(sf*(r-r2)));
68 val = std::max(val, val3);
69
70 return val;
71}
72
73void calc_mass_volume(const GridFunction &g, real_t &mass, real_t &vol)
74{
75 Mesh &mesh = *g.FESpace()->GetMesh();
76 const int NE = mesh.GetNE();
77 Vector g_vals;
78 mass = 0.0, vol = 0.0;
79 for (int e = 0; e < NE; e++)
80 {
83 Tr.OrderJ());
84 g.GetValues(Tr, ir, g_vals);
85 for (int j = 0; j < ir.GetNPoints(); j++)
86 {
87 const IntegrationPoint &ip = ir.IntPoint(j);
88 Tr.SetIntPoint(&ip);
89 mass += g_vals(j) * ip.weight * Tr.Weight();
90 vol += ip.weight * Tr.Weight();
91 }
92 }
93
94#ifdef MFEM_USE_MPI
95 auto gp = dynamic_cast<const ParGridFunction *>(&g);
96 if (gp)
97 {
98 MPI_Comm comm = gp->ParFESpace()->GetComm();
99 MPI_Allreduce(MPI_IN_PLACE, &mass, 1, MPITypeMap<real_t>::mpi_type,
100 MPI_SUM, comm);
101 MPI_Allreduce(MPI_IN_PLACE, &vol, 1, MPITypeMap<real_t>::mpi_type,
102 MPI_SUM, comm);
103 }
104#endif
105}
106
108{
109 const bool per = size.FESpace()->GetMesh()->GetNodalFESpace()->IsDGSpace();
110
111 // Indicator for small (value -> 1) or big (value -> 0) elements.
112 if (per)
113 {
115 size.ProjectCoefficient(size_ind_coeff);
116 }
117 else
118 {
119 FunctionCoefficient size_ind_coeff(size_indicator);
120 size.ProjectCoefficient(size_ind_coeff);
121 }
122
123 // Determine small/big target sizes based on the total number of
124 // elements and the volume occupied by small elements.
125 real_t volume_ind, volume;
126 calc_mass_volume(size, volume_ind, volume);
127 Mesh &mesh = *size.FESpace()->GetMesh();
128 int NE = mesh.GetNE();
129#ifdef MFEM_USE_MPI
130 auto size_p = dynamic_cast<const ParGridFunction *>(&size);
131 if (size_p) { NE = size_p->ParFESpace()->GetParMesh()->GetGlobalNE(); }
132#endif
133 NCMesh *ncmesh = mesh.ncmesh;
134 // For parallel NC meshes, all tasks have all root elements.
135 NE = (ncmesh) ? ncmesh->GetNumRootElements() : NE;
136 const real_t size_ratio = (mesh.Dimension() == 2) ? 9 : 27;
137 const real_t small_el_size = volume_ind / NE +
138 (volume - volume_ind) / (size_ratio * NE);
139 const real_t big_el_size = size_ratio * small_el_size;
140 for (int i = 0; i < size.Size(); i++)
141 {
142 size(i) = size(i) * small_el_size + (1.0 - size(i)) * big_el_size;
143 }
144}
145
147{
148 real_t xc = x(0)-0.5, yc = x(1)-0.5;
149 real_t th = 22.5*M_PI/180.;
150 real_t xn = cos(th)*xc + sin(th)*yc;
151 real_t yn = -sin(th)*xc + cos(th)*yc;
152 real_t th2 = (th > 45.*M_PI/180) ? M_PI/2 - th : th;
153 real_t stretch = 1/cos(th2);
154 xc = xn/stretch; yc = yn/stretch;
155 real_t tfac = 20;
156 real_t s1 = 3;
157 real_t s2 = 3;
158 real_t wgt = std::tanh((tfac*(yc) + s2*std::sin(s1*M_PI*xc)) + 1);
159 if (wgt > 1) { wgt = 1; }
160 if (wgt < 0) { wgt = 0; }
161 return wgt;
162}
163
165{
166 return M_PI * x(1) * (1.0 - x(1)) * cos(2 * M_PI * x(0));
167}
168
170{
171 int dim = x.Size();
172 v.SetSize(dim);
173 real_t l1, l2, l3;
174 l1 = 1.;
175 l2 = 1. + 5*x(1);
176 l3 = 1. + 10*x(2);
177 v[0] = l1/pow(l2*l3,0.5);
178 v[1] = l2/pow(l1*l3,0.5);
179 v[2] = l3/pow(l2*l1,0.5);
180}
181
183{
184private:
185 int metric;
186
187public:
188 HessianCoefficient(int dim, int metric_id)
189 : TMOPMatrixCoefficient(dim), metric(metric_id) { }
190
192 const IntegrationPoint &ip) override
193 {
194 Vector pos(3);
195 T.Transform(ip, pos);
196 if (metric != 14 && metric != 36 && metric != 85)
197 {
198 const real_t xc = pos(0) - 0.5, yc = pos(1) - 0.5;
199 const real_t r = sqrt(xc*xc + yc*yc);
200 real_t r1 = 0.15; real_t r2 = 0.35; real_t sf=30.0;
201 const real_t eps = 0.5;
202
203 const real_t tan1 = std::tanh(sf*(r-r1)),
204 tan2 = std::tanh(sf*(r-r2));
205
206 K(0, 0) = eps + 1.0 * (tan1 - tan2);
207 K(0, 1) = 0.0;
208 K(1, 0) = 0.0;
209 K(1, 1) = 1.0;
210 }
211 else if (metric == 14 || metric == 36) // Size + Alignment
212 {
213 const real_t xc = pos(0), yc = pos(1);
214 real_t theta = M_PI * yc * (1.0 - yc) * cos(2 * M_PI * xc);
215 real_t alpha_bar = 0.1;
216
217 K(0, 0) = cos(theta);
218 K(1, 0) = sin(theta);
219 K(0, 1) = -sin(theta);
220 K(1, 1) = cos(theta);
221
222 K *= alpha_bar;
223 }
224 else if (metric == 85) // Shape + Alignment
225 {
226 Vector x = pos;
227 real_t xc = x(0)-0.5, yc = x(1)-0.5;
228 real_t th = 22.5*M_PI/180.;
229 real_t xn = cos(th)*xc + sin(th)*yc;
230 real_t yn = -sin(th)*xc + cos(th)*yc;
231 xc = xn; yc=yn;
232
233 real_t tfac = 20;
234 real_t s1 = 3;
235 real_t s2 = 2;
236 real_t wgt = std::tanh((tfac*(yc) + s2*std::sin(s1*M_PI*xc)) + 1)
237 - std::tanh((tfac*(yc) + s2*std::sin(s1*M_PI*xc)) - 1);
238 if (wgt > 1) { wgt = 1; }
239 if (wgt < 0) { wgt = 0; }
240
241 xc = pos(0), yc = pos(1);
242 real_t theta = M_PI * (yc) * (1.0 - yc) * cos(2 * M_PI * xc);
243
244 K(0, 0) = cos(theta);
245 K(1, 0) = sin(theta);
246 K(0, 1) = -sin(theta);
247 K(1, 1) = cos(theta);
248
249 real_t asp_ratio_tar = 0.1 + 1*(1-wgt)*(1-wgt);
250
251 K(0, 0) *= 1/pow(asp_ratio_tar,0.5);
252 K(1, 0) *= 1/pow(asp_ratio_tar,0.5);
253 K(0, 1) *= pow(asp_ratio_tar,0.5);
254 K(1, 1) *= pow(asp_ratio_tar,0.5);
255 }
256 }
257
259 const IntegrationPoint &ip, int comp) override
260 {
261 Vector pos(3);
262 T.Transform(ip, pos);
263 K = 0.;
264 if (metric != 14 && metric != 85)
265 {
266 const real_t xc = pos(0) - 0.5, yc = pos(1) - 0.5;
267 const real_t r = sqrt(xc*xc + yc*yc);
268 real_t r1 = 0.15; real_t r2 = 0.35; real_t sf=30.0;
269
270 const real_t tan1 = std::tanh(sf*(r-r1)),
271 tan2 = std::tanh(sf*(r-r2));
272 real_t tan1d = 0., tan2d = 0.;
273 if (r > 0.001)
274 {
275 tan1d = (1.-tan1*tan1)*(sf)/r,
276 tan2d = (1.-tan2*tan2)*(sf)/r;
277 }
278
279 K(0, 1) = 0.0;
280 K(1, 0) = 0.0;
281 K(1, 1) = 1.0;
282 if (comp == 0) { K(0, 0) = tan1d*xc - tan2d*xc; }
283 else if (comp == 1) { K(0, 0) = tan1d*yc - tan2d*yc; }
284 }
285 }
286};
287
289{
290private:
291 int dim;
292 // 0 - size target in an annular region,
293 // 1 - size+aspect-ratio in an annular region,
294 // 2 - size+aspect-ratio target for a rotate sine wave.
295 int hr_target_type;
296
297public:
298 HRHessianCoefficient(int dim_, int hr_target_type_ = 0)
299 : TMOPMatrixCoefficient(dim_), dim(dim_),
300 hr_target_type(hr_target_type_) { }
301
303 const IntegrationPoint &ip) override
304 {
305 Vector pos(3);
306 T.Transform(ip, pos);
307 if (hr_target_type == 0) // size only circle
308 {
309 real_t small = 0.001, big = 0.01;
310 if (dim == 3) { small = 0.005, big = 0.1; }
311 const real_t xc = pos(0) - 0.5, yc = pos(1) - 0.5;
312 real_t r;
313 if (dim == 2)
314 {
315 r = sqrt(xc*xc + yc*yc);
316 }
317 else
318 {
319 const real_t zc = pos(2) - 0.5;
320 r = sqrt(xc*xc + yc*yc + zc*zc);
321 }
322 real_t r1 = 0.15; real_t r2 = 0.35; real_t sf=30.0;
323
324 const real_t tan1 = std::tanh(sf*(r-r1)),
325 tan2 = std::tanh(sf*(r-r2));
326
327 real_t ind = (tan1 - tan2);
328 if (ind > 1.0) {ind = 1.;}
329 if (ind < 0.0) {ind = 0.;}
330 real_t val = ind * small + (1.0 - ind) * big;
331 K = 0.0;
332 K(0, 0) = 1.0;
333 K(0, 1) = 0.0;
334 K(1, 0) = 0.0;
335 K(1, 1) = 1.0;
336 K(0, 0) *= pow(val,0.5);
337 K(1, 1) *= pow(val,0.5);
338 if (dim == 3) { K(2, 2) = pow(val,0.5); }
339 }
340 else if (hr_target_type == 1) // circle with size and AR
341 {
342 const real_t small = 0.001, big = 0.01;
343 const real_t xc = pos(0)-0.5, yc = pos(1)-0.5;
344 const real_t rv = xc*xc + yc*yc;
345 real_t r = 0;
346 if (rv>0.) {r = sqrt(rv);}
347
348 real_t r1 = 0.2; real_t r2 = 0.3; real_t sf=30.0;
349 const real_t szfac = 1;
350 const real_t asfac = 4;
351 const real_t eps2 = szfac/asfac;
352 const real_t eps1 = szfac;
353
354 real_t tan1 = std::tanh(sf*(r-r1)+1),
355 tan2 = std::tanh(sf*(r-r2)-1);
356 real_t wgt = 0.5*(tan1-tan2);
357
358 tan1 = std::tanh(sf*(r-r1)),
359 tan2 = std::tanh(sf*(r-r2));
360
361 real_t ind = (tan1 - tan2);
362 if (ind > 1.0) {ind = 1.;}
363 if (ind < 0.0) {ind = 0.;}
364 real_t szval = ind * small + (1.0 - ind) * big;
365
366 real_t th = std::atan2(yc,xc)*180./M_PI;
367 if (wgt > 1) { wgt = 1; }
368 if (wgt < 0) { wgt = 0; }
369
370 real_t maxval = eps2 + eps1*(1-wgt)*(1-wgt);
371 real_t minval = eps1;
372 real_t avgval = 0.5*(maxval+minval);
373 real_t ampval = 0.5*(maxval-minval);
374 real_t val1 = avgval + ampval*sin(2.*th*M_PI/180.+90*M_PI/180.);
375 real_t val2 = avgval + ampval*sin(2.*th*M_PI/180.-90*M_PI/180.);
376
377 K(0,1) = 0.0;
378 K(1,0) = 0.0;
379 K(0,0) = val1;
380 K(1,1) = val2;
381
382 K(0,0) *= pow(szval,0.5);
383 K(1,1) *= pow(szval,0.5);
384 }
385 else if (hr_target_type == 2) // sharp rotated sine wave
386 {
387 real_t xc = pos(0)-0.5, yc = pos(1)-0.5;
388 real_t th = 15.5*M_PI/180.;
389 real_t xn = cos(th)*xc + sin(th)*yc;
390 real_t yn = -sin(th)*xc + cos(th)*yc;
391 real_t th2 = (th > 45.*M_PI/180) ? M_PI/2 - th : th;
392 real_t stretch = 1/cos(th2);
393 xc = xn/stretch;
394 yc = yn;
395 real_t tfac = 20;
396 real_t s1 = 3;
397 real_t s2 = 2;
398 real_t yl1 = -0.025;
399 real_t yl2 = 0.025;
400 real_t wgt = std::tanh((tfac*(yc-yl1) + s2*std::sin(s1*M_PI*xc)) + 1) -
401 std::tanh((tfac*(yc-yl2) + s2*std::sin(s1*M_PI*xc)) - 1);
402 if (wgt > 1) { wgt = 1; }
403 if (wgt < 0) { wgt = 0; }
404
405 const real_t eps2 = 25;
406 const real_t eps1 = 1;
407 K(1,1) = eps1/eps2 + eps1*(1-wgt)*(1-wgt);
408 K(0,0) = eps1;
409 K(0,1) = 0.0;
410 K(1,0) = 0.0;
411 }
412 else { MFEM_ABORT("Unsupported option / wrong input."); }
413 }
414
416 const IntegrationPoint &ip, int comp) override
417 {
418 K = 0.;
419 }
420};
421
422// Additional IntegrationRules that can be used with the --quad-type option.
425
426// Defined with respect to the icf mesh.
428{
429 const real_t r = sqrt(x(0)*x(0) + x(1)*x(1) + 1e-12);
430 const real_t den = 0.002;
431 real_t l2 = 0.2 + 0.5*std::tanh((r-0.16)/den) - 0.5*std::tanh((r-0.17)/den)
432 + 0.5*std::tanh((r-0.23)/den) - 0.5*std::tanh((r-0.24)/den);
433 return l2;
434}
435
436// Used for the adaptive limiting examples.
438{
439 const real_t xc = x(0) - 0.1, yc = x(1) - 0.2;
440 const real_t r = sqrt(xc*xc + yc*yc);
441 real_t r1 = 0.45; real_t r2 = 0.55; real_t sf=30.0;
442 real_t val = 0.5*(1+std::tanh(sf*(r-r1))) - 0.5*(1+std::tanh(sf*(r-r2)));
443
444 val = std::max((real_t) 0.,val);
445 val = std::min((real_t) 1.,val);
446 return val;
447}
448
449// Used for exact surface alignment
451{
452 const int type = 1;
453
454 const int dim = x.Size();
455 if (type == 0)
456 {
457 const real_t sine = 0.25 * std::sin(4 * M_PI * x(0));
458 return (x(1) >= sine + 0.5) ? 1.0 : -1.0;
459 }
460 else
461 {
462 if (dim == 2)
463 {
464 const real_t xc = x(0) - 0.5, yc = x(1) - 0.5;
465 const real_t r = sqrt(xc*xc + yc*yc);
466 return r-0.3;
467 }
468 else
469 {
470 const real_t xc = x(0) - 0.5, yc = x(1) - 0.5, zc = x(2) - 0.5;
471 const real_t r = sqrt(xc*xc + yc*yc + zc*zc);
472 return r-0.3;
473 }
474 }
475}
476
477int material_id(int el_id, const GridFunction &g)
478{
479 const FiniteElementSpace *fes = g.FESpace();
480 const FiniteElement *fe = fes->GetFE(el_id);
481 Vector g_vals;
482 const IntegrationRule &ir =
483 IntRules.Get(fe->GetGeomType(), fes->GetOrder(el_id) + 2);
484
485 real_t integral = 0.0;
486 g.GetValues(el_id, ir, g_vals);
488 int approach = 1;
489 if (approach == 0) // integral based
490 {
491 for (int q = 0; q < ir.GetNPoints(); q++)
492 {
493 const IntegrationPoint &ip = ir.IntPoint(q);
494 Tr->SetIntPoint(&ip);
495 integral += ip.weight * g_vals(q) * Tr->Weight();
496 }
497 return (integral > 0.0) ? 1.0 : 0.0;
498 }
499 else if (approach == 1) // minimum value based
500 {
501 real_t minval = g_vals.Min();
502 return minval > 0.0 ? 1.0 : 0.0;
503 }
504 return 0.0;
505}
506
507void DiffuseField(GridFunction &field, int smooth_steps)
508{
509 // Setup the Laplacian operator
510 BilinearForm *Lap = new BilinearForm(field.FESpace());
512 Lap->Assemble();
513 Lap->Finalize();
514
515 // Setup the smoothing operator
516 DSmoother *S = new DSmoother(0,1.0,smooth_steps);
517 S->iterative_mode = true;
518 S->SetOperator(Lap->SpMat());
519
520 Vector tmp(field.Size());
521 tmp = 0.0;
522 S->Mult(tmp, field);
523
524 delete S;
525 delete Lap;
526}
527
528#ifdef MFEM_USE_MPI
529void DiffuseField(ParGridFunction &field, int smooth_steps)
530{
531 // Setup the Laplacian operator
532 ParBilinearForm *Lap = new ParBilinearForm(field.ParFESpace());
534 Lap->Assemble();
535 Lap->Finalize();
537
538 HypreSmoother *S = new HypreSmoother(*A,0,smooth_steps);
539 S->iterative_mode = true;
540
541 Vector tmp(A->Width());
542 field.SetTrueVector();
543 Vector fieldtrue = field.GetTrueVector();
544 tmp = 0.0;
545 S->Mult(tmp, fieldtrue);
546
547 field.SetFromTrueDofs(fieldtrue);
548
549 delete S;
550 delete A;
551 delete Lap;
552}
553#endif
void EvalGrad(DenseMatrix &K, ElementTransformation &T, const IntegrationPoint &ip, int comp) override
Evaluate the derivative of the matrix coefficient with respect to comp in the element described by T ...
void Eval(DenseMatrix &K, ElementTransformation &T, const IntegrationPoint &ip) override
Evaluate the matrix coefficient in the element described by T at the point ip, storing the result in ...
HRHessianCoefficient(int dim_, int hr_target_type_=0)
void Eval(DenseMatrix &K, ElementTransformation &T, const IntegrationPoint &ip) override
Evaluate the matrix coefficient in the element described by T at the point ip, storing the result in ...
HessianCoefficient(int dim, int metric_id)
void EvalGrad(DenseMatrix &K, ElementTransformation &T, const IntegrationPoint &ip, int comp) override
Evaluate the derivative of the matrix coefficient with respect to comp in the element described by T ...
A "square matrix" operator for the associated FE space and BLFIntegrators The sum of all the BLFInteg...
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 Assemble(int skip_zeros=1)
Assembles the form i.e. sums over all domain/bdr integrators.
const SparseMatrix & SpMat() const
Returns a const reference to the sparse matrix: .
Data type for scaled Jacobi-type smoother of sparse matrix.
void Mult(const Vector &x, Vector &y) const override
Matrix vector multiplication with Jacobi smoother.
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
real_t Weight()
Return the weight of the Jacobian matrix of the transformation at the currently set IntegrationPoint....
Definition eltrans.hpp:144
virtual int OrderJ() const =0
Return the order of the elements of the Jacobian of the transformation.
void SetIntPoint(const IntegrationPoint *ip)
Set the integration point ip that weights and Jacobians will be evaluated at.
Definition eltrans.hpp:106
virtual void Transform(const IntegrationPoint &, Vector &)=0
Transform integration point from reference coordinates to physical coordinates and store them in the ...
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:244
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:3835
int GetOrder(int i) const
Returns the polynomial degree of the i'th finite element.
Definition fespace.hpp:829
Mesh * GetMesh() const
Returns the mesh.
Definition fespace.hpp:679
bool IsDGSpace() const
Return whether or not the space is discontinuous (L2)
Definition fespace.hpp:1510
Abstract class for all finite elements.
Definition fe_base.hpp:244
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition fe_base.hpp:331
A general function coefficient.
Class for grid function - Vector with associated FE space.
Definition gridfunc.hpp:31
void GetValues(int i, const IntegrationRule &ir, Vector &vals, int vdim=1) const
Definition gridfunc.cpp:518
void SetTrueVector()
Shortcut for calling GetTrueDofs() with GetTrueVector() as argument.
Definition gridfunc.hpp:147
const Vector & GetTrueVector() const
Read only access to the (optional) internal true-dof Vector.
Definition gridfunc.hpp:133
FiniteElementSpace * FESpace()
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
Wrapper for hypre's ParCSR matrix class.
Definition hypre.hpp:408
Parallel smoothers in hypre.
Definition hypre.hpp:1046
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Relax the linear system Ax=b.
Definition hypre.cpp:3835
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
Container class for integration rules.
Definition intrules.hpp:422
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Mesh data type.
Definition mesh.hpp:64
const FiniteElementSpace * GetNodalFESpace() const
Definition mesh.cpp:6479
int GetNE() const
Returns number of elements.
Definition mesh.hpp:1282
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1216
void GetElementTransformation(int i, IsoparametricTransformation *ElTr) const
Builds the transformation defining the i-th element in ElTr. ElTr must be allocated in advance and wi...
Definition mesh.cpp:357
long long GetGlobalNE() const
Return the total (global) number of elements.
Definition mesh.hpp:1311
NCMesh * ncmesh
Optional nonconforming mesh extension.
Definition mesh.hpp:299
Geometry::Type GetElementBaseGeometry(int i) const
Definition mesh.hpp:1455
A class for non-conforming AMR. The class is not used directly by the user, rather it is an extension...
Definition ncmesh.hpp:140
int GetNumRootElements()
Return the number of root elements.
Definition ncmesh.hpp:450
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition operator.hpp:72
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.
MPI_Comm GetComm() const
Definition pfespace.hpp:334
ParMesh * GetParMesh() const
Definition pfespace.hpp:338
Class for parallel grid function.
Definition pgridfunc.hpp:50
void SetFromTrueDofs(const Vector &tv) override
Set the GridFunction from the given true-dof vector.
ParFiniteElementSpace * ParFESpace() const
@ ClosedUniform
aka closed Newton-Cotes
Definition intrules.hpp:408
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
Definition operator.hpp:783
void SetOperator(const Operator &a) override
Set/update the solver for the given operator.
Vector data type.
Definition vector.hpp:82
int Size() const
Returns the size of the vector.
Definition vector.hpp:226
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:558
real_t Min() const
Returns the minimal element of the vector.
Definition vector.cpp:1123
int dim
Definition ex24.cpp:53
real_t size_indicator(const Vector &x)
int material_id(int el_id, const GridFunction &g)
real_t surface_level_set(const Vector &x)
real_t adapt_lim_fun(const Vector &x)
real_t size_indicator_periodic(const Vector &x)
IntegrationRules IntRulesCU(0, Quadrature1D::ClosedUniform)
real_t weight_fun(const Vector &x)
real_t material_indicator_2d(const Vector &x)
IntegrationRules IntRulesLo(0, Quadrature1D::GaussLobatto)
void ConstructSizeGF(GridFunction &size)
void calc_mass_volume(const GridFunction &g, real_t &mass, real_t &vol)
real_t discrete_ori_2d(const Vector &x)
void discrete_aspr_3d(const Vector &x, Vector &v)
void DiffuseField(ParGridFunction &field, int smooth_steps)
float real_t
Definition config.hpp:43
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition intrules.hpp:492
Helper struct to convert a C++ type to an MPI type.