MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
mesh_extras.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2026, 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#ifndef MFEM_MESH_EXTRAS
13#define MFEM_MESH_EXTRAS
14
15#include "mfem.hpp"
16#include <sstream>
17
18namespace mfem
19{
20
21namespace common
22{
23
24class ElementMeshStream : public std::stringstream
25{
26public:
28};
29
30/// Merges vertices which lie at the same location
31void MergeMeshNodes(Mesh * mesh, int logging);
32
33/// Convert a set of attribute numbers to a marker array
34/** The marker array will be of size max_attr and it will contain only zeroes
35 and ones. Ones indicate which attribute numbers are present in the attrs
36 array. In the special case when attrs has an entry equal to -1 the marker
37 array will contain all ones. */
38inline
39void AttrToMarker(int max_attr, const Array<int> &attrs, Array<int> &marker)
40{
41 if (attrs.Find(-1) != -1) { (marker = Array<int>(max_attr)) = 1; }
42 else { marker = AttributeSets::AttrToMarker(max_attr, attrs); }
43}
44
45/// Transform a mesh according to an arbitrary affine transformation
46/// y = A x + b
47/// Where A is a spaceDim x spaceDim matrix and b is a vector of size spaceDim.
48/// If A is of size zero the transformation will be y = b.
49/// If b is of size zero the transformation will be y = A x.
50///
51/// Note that no error checking related to the determinant of A is performed.
52/// If A has a non-positive determinant it is likely to produce an invalid
53/// transformed mesh.
55{
56private:
58 Vector b;
59 Vector x;
60
61public:
62 AffineTransformation(int dim_, const DenseMatrix &A_, const Vector & b_)
63 : VectorCoefficient(dim_), A(A_), b(b_), x(dim_)
64 {
65 MFEM_VERIFY((A.Height() == dim_ && A.Width() == dim_) ||
66 (A.Height() == 0 && A.Width() == 0),
67 "Affine transformation given an invalid matrix");
68 MFEM_VERIFY(b.Size() == dim_ || b.Size() == 0,
69 "Affine transformation given an invalid vector");
70 }
71
73 const IntegrationPoint &ip) override;
74
76};
77
78/// Generalized Kershaw mesh transformation in 2D and 3D, see D. Kershaw,
79/// "Differencing of the diffusion equation in Lagrangian hydrodynamic codes",
80/// JCP, 39:375–395, 1981.
81/** The input mesh should be Cartesian nx x ny x nz with nx divisible by 6 and
82 ny, nz divisible by 2.
83 The parameters @a epsy and @a epsz must be in (0, 1].
84 Uniform mesh is recovered for epsy=epsz=1.
85 The @a smooth parameter controls the transition between different layers. */
86// Usage:
87// common::KershawTransformation kershawT(pmesh->Dimension(), 0.3, 0.3, 2);
88// pmesh->Transform(kershawT);
90{
91private:
92 int dim;
93 real_t epsy, epsz;
94 int smooth;
95
96public:
97 KershawTransformation(const int dim_, real_t epsy_ = 0.3,
98 real_t epsz_ = 0.3, int smooth_ = 1)
99 : VectorCoefficient(dim_), dim(dim_), epsy(epsy_),
100 epsz(epsz_), smooth(smooth_)
101 {
102 MFEM_VERIFY(dim > 1,"Kershaw transformation only works for 2D and 3D"
103 "meshes.");
104 MFEM_VERIFY(smooth >= 1 && smooth <= 3,
105 "Kershaw parameter smooth must be in [1, 3]");
106 MFEM_VERIFY(epsy > 0 && epsy <=1,
107 "Kershaw parameter epsy must be in (0, 1].");
108 if (dim == 3)
109 {
110 MFEM_VERIFY(epsz > 0 && epsz <=1,
111 "Kershaw parameter epsz must be in (0, 1].");
112 }
113 }
114
115 // 1D transformation at the right boundary.
116 real_t right(const real_t eps, const real_t x)
117 {
118 return (x <= 0.5) ? (2-eps) * x : 1 + eps*(x-1);
119 }
120
121 // 1D transformation at the left boundary
122 real_t left(const real_t eps, const real_t x)
123 {
124 return 1-right(eps,1-x);
125 }
126
127 // Transition from a value of "a" for x=0, to a value of "b" for x=1.
128 // Controlled through "smooth" parameter.
129 real_t step(const real_t a, const real_t b, real_t x)
130 {
131 if (x <= 0) { return a; }
132 if (x >= 1) { return b; }
133 if (smooth == 1) { return a + (b-a) * (x); }
134 else if (smooth == 2) { return a + (b-a) * (x*x*(3-2*x)); }
135 else { return a + (b-a) * (x*x*x*(x*(6*x-15)+10)); }
136 }
137
139 const IntegrationPoint &ip) override;
140
142};
143
144/// Transform a [0,1]^D mesh into a spiral. The parameters are:
145/// @a turns - number of turns around the origin,
146/// @a width - for D >= 2, the width of the spiral arm,
147/// @ gap - gap between adjacent spiral arms at the end of each turn,
148/// @ height - for D = 3, the maximum height of the spiral.
149// Usage:
150// common::SpiralTransformation spiralT(spaceDim, 2.4, 0.1, 0.05, 1.0);
151// pmesh->Transform(spiralT);
153{
154private:
155 real_t dim, turns, width, gap, height;
156
157public:
158 SpiralTransformation(int dim_, real_t turns_ = 1.0, real_t width_ = 0.1,
159 real_t gap_ = 0.05, real_t height_ = 1.0)
160 : VectorCoefficient(dim_), dim(dim_),
161 turns(turns_), width(width_), gap(gap_), height(height_)
162 {
163 MFEM_VERIFY(turns > 0 && width > 0 && gap > 0 && height > 0,
164 "Spiral transformation requires positive parameters: turns, "
165 " width, gap, and height.");
166 }
167
169 const IntegrationPoint &ip) override;
170
172};
173
174
175} // namespace common
176
177} // namespace mfem
178
179#endif
int Find(const T &el) const
Return the first index where 'el' is found; return -1 if not found.
Definition array.hpp:1000
static Array< int > AttrToMarker(int max_attr, const Array< int > &attrs)
Prepares a marker array corresponding to an array of element attributes.
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
Type
Constants for the classes derived from Element.
Definition element.hpp:41
Class for integration point with weight.
Definition intrules.hpp:35
Mesh data type.
Definition mesh.hpp:67
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition operator.hpp:68
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition operator.hpp:74
Base class for vector Coefficients that optionally depend on time and space.
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the vector coefficient in the element described by T at the point ip, storing the result in ...
Vector data type.
Definition vector.hpp:82
AffineTransformation(int dim_, const DenseMatrix &A_, const Vector &b_)
void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip) override
Evaluate the vector coefficient in the element described by T at the point ip, storing the result in ...
real_t right(const real_t eps, const real_t x)
void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip) override
Evaluate the vector coefficient in the element described by T at the point ip, storing the result in ...
KershawTransformation(const int dim_, real_t epsy_=0.3, real_t epsz_=0.3, int smooth_=1)
real_t step(const real_t a, const real_t b, real_t x)
real_t left(const real_t eps, const real_t x)
void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip) override
Evaluate the vector coefficient in the element described by T at the point ip, storing the result in ...
SpiralTransformation(int dim_, real_t turns_=1.0, real_t width_=0.1, real_t gap_=0.05, real_t height_=1.0)
int dim
Definition ex24.cpp:53
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
void MergeMeshNodes(Mesh *mesh, int logging)
Merges vertices which lie at the same location.
void AttrToMarker(int max_attr, const Array< int > &attrs, Array< int > &marker)
Convert a set of attribute numbers to a marker array.
float real_t
Definition config.hpp:46