619 lines
18 KiB
C++
619 lines
18 KiB
C++
#include "Utilities.hpp"
|
|
|
|
Sweep::Sweep(int dim_) : dim(dim_)
|
|
{
|
|
nsweeps = pow(2,dim);
|
|
sweeps.resize(nsweeps);
|
|
|
|
for (int is = 0; is<nsweeps; is++)
|
|
{
|
|
sweeps[is].SetSize(dim);
|
|
}
|
|
|
|
switch(dim)
|
|
{
|
|
case 1:
|
|
sweeps[0][0] = 1;
|
|
sweeps[1][0] = -1;
|
|
break;
|
|
case 2:
|
|
sweeps[0][0] = 1; sweeps[0][1] = 1;
|
|
sweeps[1][0] = -1; sweeps[1][1] = 1;
|
|
sweeps[2][0] = 1; sweeps[2][1] = -1;
|
|
sweeps[3][0] = -1; sweeps[3][1] = -1;
|
|
break;
|
|
default:
|
|
sweeps[0][0] = 1; sweeps[0][1] = 1; sweeps[0][2] = 1;
|
|
sweeps[1][0] = -1; sweeps[1][1] = 1; sweeps[1][2] = 1;
|
|
sweeps[2][0] = 1; sweeps[2][1] = -1; sweeps[2][2] = 1;
|
|
sweeps[3][0] = -1; sweeps[3][1] = -1; sweeps[3][2] = 1;
|
|
sweeps[4][0] = 1; sweeps[4][1] = 1; sweeps[4][2] = -1;
|
|
sweeps[5][0] = -1; sweeps[5][1] = 1; sweeps[5][2] = -1;
|
|
sweeps[6][0] = 1; sweeps[6][1] = -1; sweeps[6][2] = -1;
|
|
sweeps[7][0] = -1; sweeps[7][1] = -1; sweeps[7][2] = -1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Sweep::~Sweep()
|
|
{
|
|
for (int i = 0; i<nsweeps; i++)
|
|
{
|
|
sweeps[i].DeleteAll();
|
|
}
|
|
}
|
|
|
|
|
|
double CutOffFncn(const Vector &x, const Vector & pmin, const Vector & pmax, const Array2D<double> & h_)
|
|
{
|
|
int dim = pmin.Size();
|
|
Vector h0(dim);
|
|
Vector h1(dim);
|
|
for (int i=0; i<dim; i++)
|
|
{
|
|
h0(i) = h_[i][0];
|
|
h1(i) = h_[i][1];
|
|
}
|
|
Vector x0(dim);
|
|
Vector x1(dim);
|
|
x0 = pmin; x0+=h0;
|
|
x1 = pmax; x1-=h1;
|
|
|
|
double f = 1.0;
|
|
for (int i = 0; i<dim; i++)
|
|
{
|
|
double val = 1.0;
|
|
if( x(i) >= pmax(i) || x(i) <= pmin(i))
|
|
{
|
|
val = 0.0;
|
|
}
|
|
else if (x(i) < pmax(i) && x(i) >= x1(i))
|
|
{
|
|
if(h1(i) != 0.0)
|
|
// val = (x(i)-pmax(i))/(x1(i)-pmax(i));
|
|
val = pow((x(i)-pmax(i))/(x1(i)-pmax(i)),1.0);
|
|
}
|
|
else if (x(i) > pmin(i) && x(i) <= x0(i))
|
|
{
|
|
if (h0(i) != 0.0)
|
|
// val = (x(i)-pmin(i))/(x0(i)-pmin(i));
|
|
val = pow((x(i)-pmin(i))/(x0(i)-pmin(i)),1.0);
|
|
}
|
|
|
|
if (h0(i) == 0 && x(i) <= x1(i))
|
|
{
|
|
val = 1.0;
|
|
}
|
|
if (h1(i) == 0 && x(i) >= x0(i))
|
|
{
|
|
val = 1.0;
|
|
}
|
|
f *= val;
|
|
}
|
|
return f;
|
|
}
|
|
|
|
double ChiFncn(const Vector &x, const Vector & pmin, const Vector & pmax, const Array2D<double> & h_)
|
|
{
|
|
int dim = pmin.Size();
|
|
Vector h0(dim);
|
|
Vector h1(dim);
|
|
for (int i=0; i<dim; i++)
|
|
{
|
|
h0(i) = h_[i][0];
|
|
h1(i) = h_[i][1];
|
|
}
|
|
Vector x0(dim);
|
|
Vector x1(dim);
|
|
x0 = pmin; x0+=h0;
|
|
x1 = pmax; x1-=h1;
|
|
|
|
double f = 1.0;
|
|
for (int i = 0; i<dim; i++)
|
|
{
|
|
double val = 1.0;
|
|
if( x(i) >= pmax(i) || x(i) <= pmin(i))
|
|
{
|
|
val = 0.0;
|
|
}
|
|
else if (x(i) < pmax(i) && x(i) >= x1(i))
|
|
{
|
|
if(h1(i) != 0.0)
|
|
val = (x(i)-pmax(i))/(x1(i)-pmax(i));
|
|
// This function has to be changed to smth more reasonable
|
|
// val = pow((x(i)-pmax(i))/(x1(i)-pmax(i)),100.0);
|
|
}
|
|
else if (x(i) > pmin(i) && x(i) <= x0(i))
|
|
{
|
|
if (h0(i) != 0.0)
|
|
val = (x(i)-pmin(i))/(x0(i)-pmin(i));
|
|
// val = pow((x(i)-pmin(i))/(x0(i)-pmin(i)),100.0);
|
|
}
|
|
|
|
if (h0(i) == 0 && x(i) <= x1(i))
|
|
{
|
|
val = 1.0;
|
|
}
|
|
if (h1(i) == 0 && x(i) >= x0(i))
|
|
{
|
|
val = 1.0;
|
|
}
|
|
f *= val;
|
|
}
|
|
return f;
|
|
}
|
|
|
|
|
|
DofMap::DofMap(FiniteElementSpace * fes , MeshPartition * partition)
|
|
{
|
|
const FiniteElementCollection * fec = fes->FEColl();
|
|
nrpatch = partition->nrpatch;
|
|
|
|
fespaces.SetSize(nrpatch);
|
|
|
|
Dof2GlobalDof.resize(nrpatch);
|
|
|
|
for (int ip=0; ip<nrpatch; ++ip)
|
|
{
|
|
// create finite element spaces for each patch
|
|
fespaces[ip] = new FiniteElementSpace(partition->patch_mesh[ip],fec);
|
|
|
|
// construct the patch tdof to global tdof map
|
|
int nrdof = fespaces[ip]->GetTrueVSize();
|
|
Dof2GlobalDof[ip].SetSize(2*nrdof);
|
|
|
|
// loop through the elements in the patch
|
|
for (int iel = 0; iel<partition->element_map[ip].Size(); ++iel)
|
|
{
|
|
// index in the global mesh
|
|
int iel_idx = partition->element_map[ip][iel];
|
|
// get the dofs of this element
|
|
Array<int> ElemDofs;
|
|
Array<int> GlobalElemDofs;
|
|
fespaces[ip]->GetElementDofs(iel,ElemDofs);
|
|
fes->GetElementDofs(iel_idx,GlobalElemDofs);
|
|
// the sizes have to match
|
|
MFEM_VERIFY(ElemDofs.Size() == GlobalElemDofs.Size(),
|
|
"Size inconsistency");
|
|
// loop through the dofs and take into account the signs;
|
|
int ndof = ElemDofs.Size();
|
|
for (int i = 0; i<ndof; ++i)
|
|
{
|
|
int pdof_ = ElemDofs[i];
|
|
int gdof_ = GlobalElemDofs[i];
|
|
int pdof = (pdof_ >= 0) ? pdof_ : abs(pdof_) - 1;
|
|
int gdof = (gdof_ >= 0) ? gdof_ : abs(gdof_) - 1;
|
|
Dof2GlobalDof[ip][pdof] = gdof;
|
|
Dof2GlobalDof[ip][pdof+nrdof] = gdof+fes->GetTrueVSize();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
DofMap::DofMap(FiniteElementSpace * fes , MeshPartition * partition, int nrlayers)
|
|
{
|
|
|
|
nx = partition->nxyz[0];
|
|
ny = partition->nxyz[1];
|
|
nz = partition->nxyz[2];
|
|
|
|
int partition_kind = partition->partition_kind;
|
|
// Mesh * mesh = fespace->GetMesh();
|
|
const FiniteElementCollection * fec = fes->FEColl();
|
|
nrpatch = partition->nrpatch;
|
|
|
|
fespaces.SetSize(nrpatch);
|
|
PmlMeshes.SetSize(nrpatch);
|
|
// Extend patch meshes to include pml
|
|
|
|
for (int ip = 0; ip<nrpatch; ip++)
|
|
{
|
|
int k = ip/(nx*ny);
|
|
int j = (ip-k*nx*ny)/nx;
|
|
int i = (ip-k*nx*ny)%nx;
|
|
|
|
Array<int> directions;
|
|
if (i > 0)
|
|
{
|
|
for (int i=0; i<nrlayers; i++)
|
|
{
|
|
directions.Append(-1);
|
|
}
|
|
}
|
|
if (j > 0)
|
|
{
|
|
for (int i=0; i<nrlayers; i++)
|
|
{
|
|
directions.Append(-2);
|
|
}
|
|
}
|
|
if (k > 0)
|
|
{
|
|
for (int i=0; i<nrlayers; i++)
|
|
{
|
|
directions.Append(-3);
|
|
}
|
|
}
|
|
if (i < nx-1)
|
|
{
|
|
for (int i=0; i<nrlayers; i++)
|
|
{
|
|
if (partition_kind == 3 || partition_kind == 2) directions.Append(1);
|
|
}
|
|
}
|
|
if (j < ny-1)
|
|
{
|
|
for (int i=0; i<nrlayers; i++)
|
|
{
|
|
if (partition_kind == 3 || partition_kind == 2) directions.Append(2);
|
|
}
|
|
}
|
|
if (k < nz-1)
|
|
{
|
|
for (int i=0; i<nrlayers; i++)
|
|
{
|
|
if (partition_kind == 3 || partition_kind == 2) directions.Append(1);
|
|
}
|
|
}
|
|
PmlMeshes[ip] = ExtendMesh(partition->patch_mesh[ip],directions);
|
|
}
|
|
|
|
// Save PML_meshes
|
|
string meshpath;
|
|
string solpath;
|
|
if (partition_kind == 3 || partition_kind == 2)
|
|
{
|
|
meshpath = "output/mesh_ovlp_pml.";
|
|
solpath = "output/sol_ovlp_pml.";
|
|
}
|
|
else if (partition_kind == 4)
|
|
{
|
|
meshpath = "output/mesh_novlp_pml.";
|
|
solpath = "output/sol_novlp_pml.";
|
|
}
|
|
else
|
|
{
|
|
MFEM_ABORT("This partition kind not supported yet");
|
|
}
|
|
|
|
// SaveMeshPartition(PmlMeshes, meshpath, solpath);
|
|
|
|
PmlFespaces.SetSize(nrpatch);
|
|
Dof2GlobalDof.resize(nrpatch);
|
|
Dof2PmlDof.resize(nrpatch);
|
|
|
|
for (int ip=0; ip<nrpatch; ++ip)
|
|
{
|
|
// create finite element spaces for each patch
|
|
fespaces[ip] = new FiniteElementSpace(partition->patch_mesh[ip],fec);
|
|
PmlFespaces[ip] = new FiniteElementSpace(PmlMeshes[ip],fec);
|
|
|
|
// construct the patch tdof to global tdof map
|
|
int nrdof = fespaces[ip]->GetTrueVSize();
|
|
Dof2GlobalDof[ip].SetSize(2*nrdof);
|
|
Dof2PmlDof[ip].SetSize(2*nrdof);
|
|
|
|
// build dof maps between patch and extended patch
|
|
// loop through the patch elements and constract the dof map
|
|
// The same elements in the extended mesh have the same ordering (but not the dofs)
|
|
|
|
// loop through the elements in the patch
|
|
for (int iel = 0; iel<partition->element_map[ip].Size(); ++iel)
|
|
{
|
|
// index in the global mesh
|
|
int iel_idx = partition->element_map[ip][iel];
|
|
// get the dofs of this element
|
|
Array<int> ElemDofs;
|
|
Array<int> PmlElemDofs;
|
|
Array<int> GlobalElemDofs;
|
|
fespaces[ip]->GetElementDofs(iel,ElemDofs);
|
|
PmlFespaces[ip]->GetElementDofs(iel,PmlElemDofs);
|
|
fes->GetElementDofs(iel_idx,GlobalElemDofs);
|
|
// the sizes have to match
|
|
MFEM_VERIFY(ElemDofs.Size() == GlobalElemDofs.Size(),
|
|
"Size inconsistency");
|
|
MFEM_VERIFY(ElemDofs.Size() == PmlElemDofs.Size(),
|
|
"Size inconsistency");
|
|
// loop through the dofs and take into account the signs;
|
|
int ndof = ElemDofs.Size();
|
|
for (int i = 0; i<ndof; ++i)
|
|
{
|
|
int pdof_ = ElemDofs[i];
|
|
int gdof_ = GlobalElemDofs[i];
|
|
int pmldof_ = PmlElemDofs[i];
|
|
int pdof = (pdof_ >= 0) ? pdof_ : abs(pdof_) - 1;
|
|
int gdof = (gdof_ >= 0) ? gdof_ : abs(gdof_) - 1;
|
|
int pmldof = (pmldof_ >= 0) ? pmldof_ : abs(pmldof_) - 1;
|
|
|
|
Dof2GlobalDof[ip][pdof] = gdof;
|
|
Dof2GlobalDof[ip][pdof+nrdof] = gdof+fes->GetTrueVSize();
|
|
Dof2PmlDof[ip][pdof] = pmldof;
|
|
Dof2PmlDof[ip][pdof+nrdof] = pmldof+PmlFespaces[ip]->GetTrueVSize();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
LocalDofMap::LocalDofMap(const FiniteElementCollection * fec_, MeshPartition * part1_,
|
|
MeshPartition * part2_):fec(fec_), part1(part1_), part2(part2_)
|
|
{
|
|
// Each overlapping patch has 2 non-overlapping subdomains
|
|
// Thre are n non-overlapping and and n-1 overlapping subdomains
|
|
int nrpatch = part2->nrpatch;
|
|
MFEM_VERIFY(part1->nrpatch-1 == part2->nrpatch, "Check number of subdomains");
|
|
|
|
cout << "Constructing local dof maps" << endl;
|
|
map1.resize(nrpatch);
|
|
map2.resize(nrpatch);
|
|
for (int ip=0; ip<nrpatch; ip++)
|
|
{
|
|
// Get the 3 meshes involved
|
|
Mesh * mesh = part2->patch_mesh[ip];
|
|
Mesh * mesh1 = part1->patch_mesh[ip];
|
|
Mesh * mesh2 = part1->patch_mesh[ip+1];
|
|
|
|
// Define the fespaces
|
|
FiniteElementSpace fespace(mesh, fec);
|
|
FiniteElementSpace fespace1(mesh1, fec);
|
|
FiniteElementSpace fespace2(mesh2, fec);
|
|
|
|
int ndof1 = fespace1.GetTrueVSize();
|
|
int ndof2 = fespace2.GetTrueVSize();
|
|
|
|
map1[ip].SetSize(2*ndof1); // times 2 because it's complex
|
|
map2[ip].SetSize(2*ndof2); // times 2 because it's complex
|
|
|
|
// loop through the elements in the patches
|
|
// map 1 is constructed by the first half of elements
|
|
// map 2 is constructed by the second half of elements
|
|
|
|
for (int iel = 0; iel<part1->element_map[ip].Size(); ++iel)
|
|
{
|
|
// index in the overlapping mesh
|
|
int iel_idx = iel;
|
|
Array<int> ElemDofs;
|
|
Array<int> GlobalElemDofs;
|
|
fespace1.GetElementDofs(iel,ElemDofs);
|
|
fespace.GetElementDofs(iel_idx,GlobalElemDofs);
|
|
// the sizes have to match
|
|
MFEM_VERIFY(ElemDofs.Size() == GlobalElemDofs.Size(),
|
|
"Size inconsistency");
|
|
// loop through the dofs and take into account the signs;
|
|
int ndof = ElemDofs.Size();
|
|
for (int i = 0; i<ndof; ++i)
|
|
{
|
|
int pdof_ = ElemDofs[i];
|
|
int gdof_ = GlobalElemDofs[i];
|
|
int pdof = (pdof_ >= 0) ? pdof_ : abs(pdof_) - 1;
|
|
int gdof = (gdof_ >= 0) ? gdof_ : abs(gdof_) - 1;
|
|
map1[ip][pdof] = gdof;
|
|
map1[ip][pdof+ndof1] = gdof+fespace.GetTrueVSize();
|
|
}
|
|
}
|
|
for (int iel = 0; iel<part1->element_map[ip+1].Size(); ++iel)
|
|
{
|
|
// index in the overlapping mesh
|
|
int k = part1->element_map[ip].Size();
|
|
int iel_idx = iel+k;
|
|
Array<int> ElemDofs;
|
|
Array<int> GlobalElemDofs;
|
|
fespace2.GetElementDofs(iel,ElemDofs);
|
|
fespace.GetElementDofs(iel_idx,GlobalElemDofs);
|
|
// the sizes have to match
|
|
MFEM_VERIFY(ElemDofs.Size() == GlobalElemDofs.Size(),
|
|
"Size inconsistency");
|
|
// loop through the dofs and take into account the signs;
|
|
int ndof = ElemDofs.Size();
|
|
for (int i = 0; i<ndof; ++i)
|
|
{
|
|
int pdof_ = ElemDofs[i];
|
|
int gdof_ = GlobalElemDofs[i];
|
|
int pdof = (pdof_ >= 0) ? pdof_ : abs(pdof_) - 1;
|
|
int gdof = (gdof_ >= 0) ? gdof_ : abs(gdof_) - 1;
|
|
map2[ip][pdof] = gdof;
|
|
map2[ip][pdof+ndof2] = gdof+fespace.GetTrueVSize();
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
NeighborDofMaps::NeighborDofMaps(MeshPartition * part_, FiniteElementSpace * fes_,
|
|
DofMap * dmap_,
|
|
int ovlp_layers_) : part(part_), fes(fes_),
|
|
dmap(dmap_),
|
|
ovlp_layers(ovlp_layers_)
|
|
{
|
|
|
|
nrsubdomains = part->nrpatch;
|
|
nxyz.SetSize(3);
|
|
mesh = fes->GetMesh();
|
|
dim = mesh->Dimension();
|
|
for (int d=0; d<3; d++) nxyz[d] = part->nxyz[d];
|
|
MarkOvlpElements();
|
|
ComputeNeighborDofMaps();
|
|
}
|
|
|
|
void NeighborDofMaps::MarkOvlpElements()
|
|
{
|
|
// Lists of elements
|
|
// x,y,z = +/- 1 ovlp
|
|
OvlpElems.resize(nrsubdomains);
|
|
|
|
for (int ip = 0; ip<nrsubdomains; ip++)
|
|
{
|
|
int i0,j0,k0;
|
|
Getijk(ip,i0,j0,k0);
|
|
int ijk[dim]; ijk[0] = i0; ijk[1]=j0;
|
|
if (dim==3) ijk[2] = k0;
|
|
|
|
FiniteElementSpace * sub_fes = dmap->fespaces[ip];
|
|
Mesh * sub_mesh = sub_fes->GetMesh();
|
|
// OvlpElems[ip].resize(2*dim);
|
|
OvlpElems[ip].resize(pow(3,dim));
|
|
|
|
Vector pmin, pmax;
|
|
sub_mesh->GetBoundingBox(pmin,pmax);
|
|
double h = part->MeshSize;
|
|
// Loop through elements
|
|
for (int iel=0; iel<sub_mesh->GetNE(); iel++)
|
|
{
|
|
// Get element center
|
|
Vector center(dim);
|
|
int geom = sub_mesh->GetElementBaseGeometry(iel);
|
|
ElementTransformation * tr = sub_mesh->GetElementTransformation(iel);
|
|
tr->Transform(Geometries.GetCenter(geom),center);
|
|
|
|
// loop through dimensions
|
|
Array<bool> pos(dim); pos = 0;
|
|
Array<bool> neg(dim); neg = 0;
|
|
|
|
for (int d=0;d<dim; d++)
|
|
{
|
|
if (ijk[d]>0 && center[d] < pmin[d]+2.0*h*ovlp_layers)
|
|
{
|
|
neg[d] = true;
|
|
}
|
|
|
|
if (ijk[d]<nxyz[d]-1 && center[d] > pmax[d]-2.0*h*ovlp_layers)
|
|
{
|
|
pos[d] = true;
|
|
}
|
|
}
|
|
SetElementToOverlap(ip,iel,neg,pos);
|
|
}
|
|
}
|
|
}
|
|
|
|
void NeighborDofMaps::ComputeNeighborDofMaps()
|
|
{
|
|
OvlpDofMaps.resize(nrsubdomains);
|
|
|
|
// Array<UniqueIndexGen * > Gen(nrsubdomains);
|
|
// // construct unique number generator for the elements of a patch
|
|
// for (int ip = 0; ip<nrsubdomains; ip++)
|
|
// {
|
|
// Gen[ip] = new UniqueIndexGen;
|
|
// // register the elements
|
|
// int nel = part->element_map[ip].Size();
|
|
// for (int iel=0; iel<nel; iel++)
|
|
// {
|
|
// int iel_idx = part->element_map[ip][iel];
|
|
// Gen[ip]->Set(iel_idx);
|
|
// }
|
|
// }
|
|
|
|
// construct dof maps
|
|
int nrneighbors = pow(3,dim); // including its self
|
|
|
|
for (int ip0 = 0; ip0<nrsubdomains; ip0++)
|
|
{
|
|
OvlpDofMaps[ip0].resize(nrneighbors);
|
|
|
|
FiniteElementSpace * fes0 = dmap->fespaces[ip0];
|
|
int tdofs0 = fes0->GetTrueVSize();
|
|
Array<int> marker0(tdofs0); marker0 = 0;
|
|
int i0, j0, k0;
|
|
Array<int> ijk(dim);
|
|
Getijk(ip0, i0,j0,k0);
|
|
|
|
int kbeg = (dim == 2) ? 0 : -1;
|
|
int kend = (dim == 2) ? 1 : 2;
|
|
for (int k=kbeg; k<kend; k++)
|
|
{
|
|
int k1 = k0 + k;
|
|
if (k1 <0 || k1>=nxyz[2]) continue;
|
|
int kk = (dim == 2) ? -1 : k;
|
|
for (int j=-1; j<2; j++)
|
|
{
|
|
int j1 = j0 + j;
|
|
if (j1 <0 || j1>=nxyz[1]) continue;
|
|
for (int i=-1; i<2; i++)
|
|
{
|
|
int i1 = i0 + i;
|
|
if (i1 <0 || i1>=nxyz[0]) continue;
|
|
|
|
Array<int> ip0list; marker0 = 0;
|
|
int directionId = GetDirectionId(i,j,kk);
|
|
|
|
Array<int> Elems = OvlpElems[ip0][directionId];
|
|
int nel = Elems.Size();
|
|
|
|
for (int iel = 0; iel<nel; ++iel)
|
|
{
|
|
int iel0 = Elems[iel];
|
|
Array<int> ElemDofs0;
|
|
|
|
fes0->GetElementDofs(iel0,ElemDofs0);
|
|
int ndof = ElemDofs0.Size();
|
|
// since the elements are added to the subdomain meshes
|
|
// in the same ordered fashion (as they come from the
|
|
// original mesh) then the ordering of elements in each
|
|
// subdomain is the same. Hence the dof ovlp lists
|
|
// can be computed for each subdomain independendly
|
|
for (int l = 0; l<ndof; ++l)
|
|
{
|
|
int dof0_ = ElemDofs0[l];
|
|
int dof0 = (dof0_ >= 0) ? dof0_ : abs(dof0_) - 1;
|
|
if (!marker0[dof0])
|
|
{
|
|
ip0list.Append(dof0); // dofs of ip0 in ovlp
|
|
marker0[dof0] = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
OvlpDofMaps[ip0][directionId].Append(ip0list);
|
|
int tsize = fes0->GetTrueVSize();
|
|
// Imaginary part
|
|
for (int l=0;l<ip0list.Size(); l++) { ip0list[l] += tsize; }
|
|
OvlpDofMaps[ip0][directionId].Append(ip0list);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void NeighborDofMaps::GetNeighborDofMap(const int ip,
|
|
const Array<int> & directions,
|
|
Array<int> & dofmap)
|
|
{
|
|
int k = (dim == 2) ? -1 : directions[2];
|
|
int directionid = GetDirectionId(directions[0],directions[1],k);
|
|
dofmap = OvlpDofMaps[ip][directionid];
|
|
}
|
|
|
|
|
|
void NeighborDofMaps::SetElementToOverlap(int ip, int iel,
|
|
const Array<bool> & neg,
|
|
const Array<bool> & pos)
|
|
{
|
|
int kbeg = (dim == 2) ? 0 : -1;
|
|
int kend = (dim == 2) ? 0 : 1;
|
|
for (int k = kbeg; k<=kend; k++)
|
|
{
|
|
if (dim == 3)
|
|
{
|
|
if (k == -1 && !neg[2]) continue;
|
|
if (k == 1 && !pos[2]) continue;
|
|
}
|
|
for (int j = -1; j<=1; j++)
|
|
{
|
|
if (j== -1 && !neg[1]) continue;
|
|
if (j== 1 && !pos[1]) continue;
|
|
for (int i = -1; i<=1; i++)
|
|
{
|
|
// cases to skip
|
|
if (i==-1 && !neg[0]) continue;
|
|
if (i== 1 && !pos[0]) continue;
|
|
|
|
if (i==0 && j==0 && k == 0) continue;
|
|
int kk = (dim==2)?-1 : k;
|
|
int DirId = GetDirectionId(i,j,kk);
|
|
OvlpElems[ip][DirId].Append(iel);
|
|
}
|
|
}
|
|
}
|
|
} |