18 : mesh(mesh_), length(length_)
24 void 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,MPI_DOUBLE,MPI_MIN,pmesh->GetComm());
56 MPI_Allreduce(MPI_IN_PLACE,&dom_bdr(d,1),1,MPI_DOUBLE,MPI_MAX,pmesh->GetComm());
61 for (
int i = 0; i <
dim; i++)
63 comp_dom_bdr(i, 0) = dom_bdr(i, 0) + length(i, 0);
64 comp_dom_bdr(i, 1) = dom_bdr(i, 1) - length(i, 1);
71 int nrelem = mesh_->
GetNE();
74 for (
int i = 0; i < nrelem; ++i)
83 int nrvert = vertices.
Size();
85 for (
int iv = 0; iv < nrvert; ++iv)
87 int vert_idx = vertices[iv];
88 double *coords = mesh_->
GetVertex(vert_idx);
89 for (
int comp = 0; comp <
dim; ++comp)
91 if (coords[comp] > comp_dom_bdr(comp, 1) ||
92 coords[comp] < comp_dom_bdr(comp, 0))
112 *attrNonPML = 0; (*attrNonPML)[0] = 1;
129 std::vector<std::complex<double>> &dxs)
131 std::complex<double> zi = std::complex<double>(0., 1.);
138 for (
int i = 0; i <
dim; ++i)
141 if (x(i) >= comp_dom_bdr(i, 1))
143 coeff = n * c / k / pow(length(i, 1), n);
144 dxs[i] = 1.0 + zi * coeff * std::abs(pow(x(i) - comp_dom_bdr(i, 1), n - 1.0));
146 if (x(i) <= comp_dom_bdr(i, 0))
148 coeff = n * c / k / pow(length(i, 0), n);
149 dxs[i] = 1.0 + zi * coeff * std::abs(pow(x(i) - comp_dom_bdr(i, 0), n - 1.0));
159 std::vector<std::complex<double>> dxs(
dim);
160 std::complex<double> det(1.0,0.0);
162 for (
int i=0; i<
dim; ++i) { det *= dxs[i]; }
169 std::vector<std::complex<double>> dxs(
dim);
170 std::complex<double> det(1.0,0.0);
172 for (
int i=0; i<
dim; ++i) { det *= dxs[i]; }
179 std::vector<std::complex<double>> dxs(
dim);
180 std::complex<double> det(1.0,0.0);
182 for (
int i=0; i<
dim; ++i) { det *= dxs[i]; }
183 return det.imag()*det.imag() + det.real()*det.real();
191 std::vector<std::complex<double>> dxs(
dim);
192 std::complex<double> det(1.0,0.0);
194 for (
int i = 0; i<
dim; ++i) { det *= dxs[i]; }
197 for (
int i = 0; i<
dim; ++i)
199 M(i,i) = (pow(dxs[i], 2)/det).real();
207 std::vector<std::complex<double>> dxs(
dim);
208 std::complex<double> det = 1.0;
210 for (
int i = 0; i<
dim; ++i) { det *= dxs[i]; }
213 for (
int i = 0; i<
dim; ++i)
215 M(i,i) = (pow(dxs[i], 2)/det).imag();
223 std::vector<std::complex<double>> dxs(
dim);
224 std::complex<double> det = 1.0;
226 for (
int i = 0; i<
dim; ++i) { det *= dxs[i]; }
229 for (
int i = 0; i<
dim; ++i)
231 std::complex<double>
a = pow(dxs[i], 2)/det;
232 M(i,i) =
a.imag() *
a.imag() +
a.real() *
a.real();
242 std::vector<std::complex<double>> dxs(
dim);
243 std::complex<double> det(1.0, 0.0);
246 for (
int i = 0; i <
dim; ++i) { det *= dxs[i]; }
249 for (
int i = 0; i <
dim; ++i)
251 M(i, i) = (det / pow(dxs[i], 2)).real();
259 std::vector<std::complex<double>> dxs(
dim);
260 std::complex<double> det = 1.0;
263 for (
int i = 0; i <
dim; ++i) { det *= dxs[i]; }
266 for (
int i = 0; i <
dim; ++i)
268 M(i, i) = (det / pow(dxs[i], 2)).imag();
276 std::vector<std::complex<double>> dxs(
dim);
277 std::complex<double> det = 1.0;
280 for (
int i = 0; i <
dim; ++i) { det *= dxs[i]; }
283 for (
int i = 0; i <
dim; ++i)
285 std::complex<double>
a = det / pow(dxs[i], 2);
286 M(i, i) =
a.real()*
a.real() +
a.imag()*
a.imag();
virtual void GetVertices(Array< int > &v) const =0
Returns element's vertices.
int Dimension() const
Dimension of the reference space used within the elements.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
Data type dense matrix using column-major storage.
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.
void Jt_J_detJinv_i_function(const Vector &x, CartesianPML *pml, DenseMatrix &M)
void abs_detJ_Jt_J_inv_2_function(const Vector &x, CartesianPML *pml, DenseMatrix &M)
int GetNBE() const
Returns number of boundary elements.
void detJ_Jt_J_inv_r_function(const Vector &x, CartesianPML *pml, DenseMatrix &M)
double detJ_i_function(const Vector &x, CartesianPML *pml)
CartesianPML(Mesh *mesh_, const Array2D< double > &length_)
void SetSize(int m, int n)
virtual void SetAttributes()
Determine the sets of unique attribute values in domain and boundary elements.
void abs_Jt_J_detJinv_2_function(const Vector &x, CartesianPML *pml, DenseMatrix &M)
void SetAttributes(Mesh *mesh_, Array< int > *attrNonPML=nullptr, Array< int > *attrPML=nullptr)
Mark element in the PML region.
const double * GetVertex(int i) const
Return pointer to vertex i's coordinates.
double abs_detJ_2_function(const Vector &x, CartesianPML *pml)
void detJ_Jt_J_inv_i_function(const Vector &x, CartesianPML *pml, DenseMatrix &M)
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
double detJ_r_function(const Vector &x, CartesianPML *pml)
PML stretching functions: See https://doi.org/10.1006/jcph.1994.1159.
int GetNE() const
Returns number of elements.
Class for setting up a simple Cartesian PML region.
void Jt_J_detJinv_r_function(const Vector &x, CartesianPML *pml, DenseMatrix &M)
double infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
void SetAttribute(const int attr)
Set element's attribute.
int Size() const
Return the logical size of the array.
Abstract data type element.
void StretchFunction(const Vector &x, std::vector< std::complex< double >> &dxs)
PML complex stretching function.
Array< int > attributes
A list of all unique element attributes used by the Mesh.