18 : mesh(mesh_), length(length_)
24void CartesianPML::SetBoundaries()
29 for (
int i = 0; i <
dim; i++)
35 for (
int i = 0; i < mesh->
GetNBE(); i++)
37 Array<int> bdr_vertices;
39 for (
int j = 0; j < bdr_vertices.Size(); j++)
41 for (
int k = 0; k <
dim; k++)
43 dom_bdr(k, 0) = std::min(dom_bdr(k, 0), mesh->
GetVertex(bdr_vertices[j])[k]);
44 dom_bdr(k, 1) = std::max(dom_bdr(k, 1), mesh->
GetVertex(bdr_vertices[j])[k]);
50 ParMesh * pmesh =
dynamic_cast<ParMesh *
>(mesh);
53 for (
int d=0; d<
dim; d++)
55 MPI_Allreduce(MPI_IN_PLACE, &dom_bdr(d,0), 1,
56 MPITypeMap<real_t>::mpi_type, MPI_MIN,pmesh->GetComm());
57 MPI_Allreduce(MPI_IN_PLACE, &dom_bdr(d,1), 1,
58 MPITypeMap<real_t>::mpi_type, MPI_MAX, pmesh->GetComm());
63 for (
int i = 0; i <
dim; i++)
65 comp_dom_bdr(i, 0) = dom_bdr(i, 0) + length(i, 0);
66 comp_dom_bdr(i, 1) = dom_bdr(i, 1) - length(i, 1);
73 int nrelem = mesh_->
GetNE();
76 for (
int i = 0; i < nrelem; ++i)
85 int nrvert = vertices.
Size();
87 for (
int iv = 0; iv < nrvert; ++iv)
89 int vert_idx = vertices[iv];
91 for (
int comp = 0; comp <
dim; ++comp)
93 if (coords[comp] > comp_dom_bdr(comp, 1) ||
94 coords[comp] < comp_dom_bdr(comp, 0))
114 *attrNonPML = 0; (*attrNonPML)[0] = 1;
131 std::vector<std::complex<real_t>> &dxs)
133 std::complex<real_t> zi = std::complex<real_t>(0., 1.);
140 for (
int i = 0; i <
dim; ++i)
143 if (x(i) >= comp_dom_bdr(i, 1))
145 coeff = n * c / k / pow(length(i, 1), n);
146 dxs[i] =
real_t(1.0) + zi *
real_t(coeff * std::abs(pow(x(i) - comp_dom_bdr(i,
149 if (x(i) <= comp_dom_bdr(i, 0))
151 coeff = n * c / k / pow(length(i, 0), n);
152 dxs[i] =
real_t(1.0) + zi *
real_t(coeff * std::abs(pow(x(i) - comp_dom_bdr(i,
163 std::vector<std::complex<real_t>> dxs(
dim);
164 std::complex<real_t> det(1.0,0.0);
166 for (
int i=0; i<
dim; ++i) { det *= dxs[i]; }
173 std::vector<std::complex<real_t>> dxs(
dim);
174 std::complex<real_t> det(1.0,0.0);
176 for (
int i=0; i<
dim; ++i) { det *= dxs[i]; }
183 std::vector<std::complex<real_t>> dxs(
dim);
184 std::complex<real_t> det(1.0,0.0);
186 for (
int i=0; i<
dim; ++i) { det *= dxs[i]; }
187 return det.imag()*det.imag() + det.real()*det.real();
195 std::vector<std::complex<real_t>> dxs(
dim);
196 std::complex<real_t> det(1.0,0.0);
198 for (
int i = 0; i<
dim; ++i) { det *= dxs[i]; }
201 for (
int i = 0; i<
dim; ++i)
203 M(i,i) = (pow(dxs[i],
real_t(2))/det).real();
211 std::vector<std::complex<real_t>> dxs(
dim);
212 std::complex<real_t> det = 1.0;
214 for (
int i = 0; i<
dim; ++i) { det *= dxs[i]; }
217 for (
int i = 0; i<
dim; ++i)
219 M(i,i) = (pow(dxs[i],
real_t(2))/det).imag();
227 std::vector<std::complex<real_t>> dxs(
dim);
228 std::complex<real_t> det = 1.0;
230 for (
int i = 0; i<
dim; ++i) { det *= dxs[i]; }
233 for (
int i = 0; i<
dim; ++i)
235 std::complex<real_t>
a = pow(dxs[i],
real_t(2))/det;
236 M(i,i) =
a.imag() *
a.imag() +
a.real() *
a.real();
246 std::vector<std::complex<real_t>> dxs(
dim);
247 std::complex<real_t> det(1.0, 0.0);
250 for (
int i = 0; i <
dim; ++i) { det *= dxs[i]; }
253 for (
int i = 0; i <
dim; ++i)
255 M(i, i) = (det / pow(dxs[i],
real_t(2))).real();
263 std::vector<std::complex<real_t>> dxs(
dim);
264 std::complex<real_t> det = 1.0;
267 for (
int i = 0; i <
dim; ++i) { det *= dxs[i]; }
270 for (
int i = 0; i <
dim; ++i)
272 M(i, i) = (det / pow(dxs[i],
real_t(2))).imag();
280 std::vector<std::complex<real_t>> dxs(
dim);
281 std::complex<real_t> det = 1.0;
284 for (
int i = 0; i <
dim; ++i) { det *= dxs[i]; }
287 for (
int i = 0; i <
dim; ++i)
289 std::complex<real_t>
a = det / pow(dxs[i],
real_t(2));
290 M(i, i) =
a.real()*
a.real() +
a.imag()*
a.imag();
Dynamic 2D array using row-major layout.
void SetSize(int m, int 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.
int GetNBE() const
Returns number of boundary elements.
Array< int > attributes
A list of all unique element attributes used by the Mesh.
virtual void SetAttributes()
Determine the sets of unique attribute values in domain and boundary elements.
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.
real_t infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
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)
void detJ_Jt_J_inv_i_function(const Vector &x, CartesianPML *pml, DenseMatrix &M)