21 : mesh(mesh_), length(length_)
27void CartesianPML::SetBoundaries()
32 for (
int i = 0; i <
dim; i++)
38 for (
int i = 0; i < mesh->
GetNBE(); i++)
40 Array<int> bdr_vertices;
42 for (
int j = 0; j < bdr_vertices.Size(); j++)
44 for (
int k = 0; k <
dim; k++)
46 dom_bdr(k, 0) = std::min(dom_bdr(k, 0), mesh->
GetVertex(bdr_vertices[j])[k]);
47 dom_bdr(k, 1) = std::max(dom_bdr(k, 1), mesh->
GetVertex(bdr_vertices[j])[k]);
53 ParMesh * pmesh =
dynamic_cast<ParMesh *
>(mesh);
56 for (
int d=0; d<
dim; d++)
58 MPI_Allreduce(MPI_IN_PLACE, &dom_bdr(d,0), 1,
59 MPITypeMap<real_t>::mpi_type, MPI_MIN,pmesh->GetComm());
60 MPI_Allreduce(MPI_IN_PLACE, &dom_bdr(d,1), 1,
61 MPITypeMap<real_t>::mpi_type, MPI_MAX, pmesh->GetComm());
66 for (
int i = 0; i <
dim; i++)
68 comp_dom_bdr(i, 0) = dom_bdr(i, 0) + length(i, 0);
69 comp_dom_bdr(i, 1) = dom_bdr(i, 1) - length(i, 1);
76 int nrelem = mesh_->
GetNE();
79 for (
int i = 0; i < nrelem; ++i)
88 int nrvert = vertices.
Size();
90 for (
int iv = 0; iv < nrvert; ++iv)
92 int vert_idx = vertices[iv];
94 for (
int comp = 0; comp <
dim; ++comp)
96 if (coords[comp] > comp_dom_bdr(comp, 1) ||
97 coords[comp] < comp_dom_bdr(comp, 0))
117 *attrNonPML = 0; (*attrNonPML)[0] = 1;
134 std::vector<std::complex<real_t>> &dxs)
136 std::complex<real_t> zi = std::complex<real_t>(0., 1.);
143 for (
int i = 0; i <
dim; ++i)
146 if (x(i) >= comp_dom_bdr(i, 1))
148 coeff = n * c / k / pow(length(i, 1), n);
149 dxs[i] =
real_t(1.0) + zi *
real_t(coeff * std::abs(pow(x(i) - comp_dom_bdr(i,
152 if (x(i) <= comp_dom_bdr(i, 0))
154 coeff = n * c / k / pow(length(i, 0), n);
155 dxs[i] =
real_t(1.0) + zi *
real_t(coeff * std::abs(pow(x(i) - comp_dom_bdr(i,
166 std::vector<std::complex<real_t>> dxs(
dim);
167 std::complex<real_t> det(1.0,0.0);
169 for (
int i=0; i<
dim; ++i) { det *= dxs[i]; }
176 std::vector<std::complex<real_t>> dxs(
dim);
177 std::complex<real_t> det(1.0,0.0);
179 for (
int i=0; i<
dim; ++i) { det *= dxs[i]; }
186 std::vector<std::complex<real_t>> dxs(
dim);
187 std::complex<real_t> det(1.0,0.0);
189 for (
int i=0; i<
dim; ++i) { det *= dxs[i]; }
190 return det.imag()*det.imag() + det.real()*det.real();
198 std::vector<std::complex<real_t>> dxs(
dim);
199 std::complex<real_t> det(1.0,0.0);
201 for (
int i = 0; i<
dim; ++i) { det *= dxs[i]; }
204 for (
int i = 0; i<
dim; ++i)
206 M(i,i) = (pow(dxs[i],
real_t(2))/det).real();
214 std::vector<std::complex<real_t>> dxs(
dim);
215 std::complex<real_t> det = 1.0;
217 for (
int i = 0; i<
dim; ++i) { det *= dxs[i]; }
220 for (
int i = 0; i<
dim; ++i)
222 M(i,i) = (pow(dxs[i],
real_t(2))/det).imag();
230 std::vector<std::complex<real_t>> dxs(
dim);
231 std::complex<real_t> det = 1.0;
233 for (
int i = 0; i<
dim; ++i) { det *= dxs[i]; }
236 for (
int i = 0; i<
dim; ++i)
238 std::complex<real_t>
a = pow(dxs[i],
real_t(2))/det;
239 M(i,i) =
a.imag() *
a.imag() +
a.real() *
a.real();
249 std::vector<std::complex<real_t>> dxs(
dim);
250 std::complex<real_t> det(1.0, 0.0);
253 for (
int i = 0; i <
dim; ++i) { det *= dxs[i]; }
256 for (
int i = 0; i <
dim; ++i)
258 M(i, i) = (det / pow(dxs[i],
real_t(2))).real();
266 std::vector<std::complex<real_t>> dxs(
dim);
267 std::complex<real_t> det = 1.0;
270 for (
int i = 0; i <
dim; ++i) { det *= dxs[i]; }
273 for (
int i = 0; i <
dim; ++i)
275 M(i, i) = (det / pow(dxs[i],
real_t(2))).imag();
283 std::vector<std::complex<real_t>> dxs(
dim);
284 std::complex<real_t> det = 1.0;
287 for (
int i = 0; i <
dim; ++i) { det *= dxs[i]; }
290 for (
int i = 0; i <
dim; ++i)
292 std::complex<real_t>
a = det / pow(dxs[i],
real_t(2));
293 M(i, i) =
a.real()*
a.real() +
a.imag()*
a.imag();
Dynamic 2D array using row-major layout.
void SetSize(int m, int n)
Set the 2D array size to m x n.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
Class for setting up a simple Cartesian PML region.
void SetAttributes(Mesh *mesh_, Array< int > *attrNonPML=nullptr, Array< int > *attrPML=nullptr)
Mark element in the PML region.
void StretchFunction(const Vector &x, std::vector< std::complex< real_t > > &dxs)
PML complex stretching function.
CartesianPML(Mesh *mesh_, const Array2D< real_t > &length_)
Data type dense matrix using column-major storage.
Abstract data type element.
virtual void GetVertices(Array< int > &v) const =0
Get the indices defining the vertices.
void SetAttribute(const int attr)
Set element's attribute.
void GetBdrElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of boundary element i.
const Element * GetElement(int i) const
Return pointer to the i'th element object.
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
virtual void SetAttributes(bool elem_attrs_changed=true, bool bdr_face_attrs_changed=true)
Determine the sets of unique attribute values in domain if elem_attrs_changed and boundary elements i...
int GetNBE() const
Returns number of boundary elements.
Array< int > attributes
A list of all unique element attributes used by the Mesh.
const real_t * GetVertex(int i) const
Return pointer to vertex i's coordinates.
real_t detJ_r_function(const Vector &x, CartesianPML *pml)
PML stretching functions: See https://doi.org/10.1006/jcph.1994.1159.
void Jt_J_detJinv_r_function(const Vector &x, CartesianPML *pml, DenseMatrix &M)
void abs_Jt_J_detJinv_2_function(const Vector &x, CartesianPML *pml, DenseMatrix &M)
void detJ_Jt_J_inv_r_function(const Vector &x, CartesianPML *pml, DenseMatrix &M)
void Jt_J_detJinv_i_function(const Vector &x, CartesianPML *pml, DenseMatrix &M)
real_t abs_detJ_2_function(const Vector &x, CartesianPML *pml)
real_t detJ_i_function(const Vector &x, CartesianPML *pml)
void abs_detJ_Jt_J_inv_2_function(const Vector &x, CartesianPML *pml, DenseMatrix &M)
constexpr real_t infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
void detJ_Jt_J_inv_i_function(const Vector &x, CartesianPML *pml, DenseMatrix &M)