Merge branch 'master' into bugfix/submesh-issue-4107
This commit is contained in:
@@ -1585,9 +1585,10 @@ void MixedBilinearForm::Assemble(int skip_zeros)
|
||||
ftr = mesh->GetBdrFaceTransformations(i);
|
||||
if (ftr)
|
||||
{
|
||||
trial_fes->GetFaceVDofs(ftr->ElementNo, trial_vdofs);
|
||||
const int iface = mesh->GetBdrElementFaceIndex(i);
|
||||
trial_fes->GetFaceVDofs(iface, trial_vdofs);
|
||||
test_fes->GetElementVDofs(ftr->Elem1No, test_vdofs);
|
||||
trial_face_fe = trial_fes->GetFaceElement(ftr->ElementNo);
|
||||
trial_face_fe = trial_fes->GetFaceElement(iface);
|
||||
test_fe1 = test_fes->GetFE(ftr->Elem1No);
|
||||
// The test_fe2 object is really a dummy and not used on the
|
||||
// boundaries, but we can't dereference a NULL pointer, and we don't
|
||||
|
||||
+5
-5
@@ -2949,16 +2949,16 @@ void VectorDiffusionIntegrator::AssembleElementVector(
|
||||
}
|
||||
|
||||
dshape.SetSize(dof, dim);
|
||||
dshapedxt.SetSize(dof, dim);
|
||||
// pelmat.SetSize(dim);
|
||||
dshapedxt.SetSize(dof, sdim);
|
||||
pelmat.SetSize(dof);
|
||||
|
||||
elvect.SetSize(dim*dof);
|
||||
elvect.SetSize(vdim*dof);
|
||||
|
||||
// NOTE: DenseMatrix is in column-major order. This is consistent with
|
||||
// vectors ordered byNODES. In the resulting DenseMatrix, each column
|
||||
// corresponds to a particular vdim.
|
||||
DenseMatrix mat_in(elfun.GetData(), dof, dim);
|
||||
DenseMatrix mat_out(elvect.GetData(), dof, dim);
|
||||
DenseMatrix mat_in(elfun.GetData(), dof, vdim);
|
||||
DenseMatrix mat_out(elvect.GetData(), dof, vdim);
|
||||
|
||||
const IntegrationRule *ir = IntRule;
|
||||
if (ir == NULL)
|
||||
|
||||
+2
-2
@@ -1568,7 +1568,7 @@ double ComputeGlobalLpNorm(double p, VectorCoefficient &coeff, ParMesh &pmesh,
|
||||
#endif
|
||||
|
||||
VectorQuadratureFunctionCoefficient::VectorQuadratureFunctionCoefficient(
|
||||
QuadratureFunction &qf)
|
||||
const QuadratureFunction &qf)
|
||||
: VectorCoefficient(qf.GetVDim()), QuadF(qf), index(0) { }
|
||||
|
||||
void VectorQuadratureFunctionCoefficient::SetComponent(int index_, int length_)
|
||||
@@ -1622,7 +1622,7 @@ void VectorQuadratureFunctionCoefficient::Project(QuadratureFunction &qf)
|
||||
}
|
||||
|
||||
QuadratureFunctionCoefficient::QuadratureFunctionCoefficient(
|
||||
QuadratureFunction &qf) : QuadF(qf)
|
||||
const QuadratureFunction &qf) : QuadF(qf)
|
||||
{
|
||||
MFEM_VERIFY(qf.GetVDim() == 1, "QuadratureFunction's vdim must be 1");
|
||||
}
|
||||
|
||||
+2
-2
@@ -2245,7 +2245,7 @@ private:
|
||||
|
||||
public:
|
||||
/// Constructor with a quadrature function as input
|
||||
VectorQuadratureFunctionCoefficient(QuadratureFunction &qf);
|
||||
VectorQuadratureFunctionCoefficient(const QuadratureFunction &qf);
|
||||
|
||||
/** Set the starting index within the QuadFunc that'll be used to project
|
||||
outwards as well as the corresponding length. The projected length should
|
||||
@@ -2273,7 +2273,7 @@ private:
|
||||
|
||||
public:
|
||||
/// Constructor with a quadrature function as input
|
||||
QuadratureFunctionCoefficient(QuadratureFunction &qf);
|
||||
QuadratureFunctionCoefficient(const QuadratureFunction &qf);
|
||||
|
||||
const QuadratureFunction& GetQuadFunction() const { return QuadF; }
|
||||
|
||||
|
||||
+7
-4
@@ -170,12 +170,13 @@ public:
|
||||
virtual int GetSpaceDim() const = 0;
|
||||
|
||||
/** @brief Transform a point @a pt from physical space to a point @a ip in
|
||||
reference space. */
|
||||
reference space and optionally can set a solver tolerance using @a phys_tol. */
|
||||
/** Attempt to find the IntegrationPoint that is transformed into the given
|
||||
point in physical space. If the inversion fails a non-zero value is
|
||||
returned. This method is not 100 percent reliable for non-linear
|
||||
transformations. */
|
||||
virtual int TransformBack(const Vector &pt, IntegrationPoint &ip) = 0;
|
||||
virtual int TransformBack(const Vector &pt, IntegrationPoint &ip,
|
||||
const double phys_tol = 1e-15) = 0;
|
||||
|
||||
virtual ~ElementTransformation() { }
|
||||
};
|
||||
@@ -442,14 +443,16 @@ public:
|
||||
virtual int GetSpaceDim() const { return PointMat.Height(); }
|
||||
|
||||
/** @brief Transform a point @a pt from physical space to a point @a ip in
|
||||
reference space. */
|
||||
reference space and optionally can set a solver tolerance using @a phys_tol. */
|
||||
/** Attempt to find the IntegrationPoint that is transformed into the given
|
||||
point in physical space. If the inversion fails a non-zero value is
|
||||
returned. This method is not 100 percent reliable for non-linear
|
||||
transformations. */
|
||||
virtual int TransformBack(const Vector & v, IntegrationPoint & ip)
|
||||
virtual int TransformBack(const Vector & v, IntegrationPoint & ip,
|
||||
const double phys_rel_tol = 1e-15)
|
||||
{
|
||||
InverseElementTransformation inv_tr(this);
|
||||
inv_tr.SetPhysicalRelTol(phys_rel_tol);
|
||||
return inv_tr.Transform(v, ip);
|
||||
}
|
||||
|
||||
|
||||
+9
-8
@@ -2058,7 +2058,7 @@ void GridFunction::AccumulateAndCountZones(VectorCoefficient &vcoeff,
|
||||
}
|
||||
|
||||
void GridFunction::AccumulateAndCountBdrValues(
|
||||
Coefficient *coeff[], VectorCoefficient *vcoeff, Array<int> &attr,
|
||||
Coefficient *coeff[], VectorCoefficient *vcoeff, const Array<int> &attr,
|
||||
Array<int> &values_counter)
|
||||
{
|
||||
int i, j, fdof, d, ind, vdim;
|
||||
@@ -2200,7 +2200,7 @@ static void accumulate_dofs(const Array<int> &dofs, const Vector &vals,
|
||||
}
|
||||
|
||||
void GridFunction::AccumulateAndCountBdrTangentValues(
|
||||
VectorCoefficient &vcoeff, Array<int> &bdr_attr,
|
||||
VectorCoefficient &vcoeff, const Array<int> &bdr_attr,
|
||||
Array<int> &values_counter)
|
||||
{
|
||||
const FiniteElement *fe;
|
||||
@@ -2576,7 +2576,7 @@ void GridFunction::ProjectDiscCoefficient(VectorCoefficient &coeff,
|
||||
}
|
||||
|
||||
void GridFunction::ProjectBdrCoefficient(VectorCoefficient &vcoeff,
|
||||
Array<int> &attr)
|
||||
const Array<int> &attr)
|
||||
{
|
||||
Array<int> values_counter;
|
||||
AccumulateAndCountBdrValues(NULL, &vcoeff, attr, values_counter);
|
||||
@@ -2593,7 +2593,8 @@ void GridFunction::ProjectBdrCoefficient(VectorCoefficient &vcoeff,
|
||||
#endif
|
||||
}
|
||||
|
||||
void GridFunction::ProjectBdrCoefficient(Coefficient *coeff[], Array<int> &attr)
|
||||
void GridFunction::ProjectBdrCoefficient(Coefficient *coeff[],
|
||||
const Array<int> &attr)
|
||||
{
|
||||
Array<int> values_counter;
|
||||
// this->HostReadWrite(); // done inside the next call
|
||||
@@ -2623,7 +2624,7 @@ void GridFunction::ProjectBdrCoefficient(Coefficient *coeff[], Array<int> &attr)
|
||||
}
|
||||
|
||||
void GridFunction::ProjectBdrCoefficientNormal(
|
||||
VectorCoefficient &vcoeff, Array<int> &bdr_attr)
|
||||
VectorCoefficient &vcoeff, const Array<int> &bdr_attr)
|
||||
{
|
||||
#if 0
|
||||
// implementation for the case when the face dofs are integrals of the
|
||||
@@ -2698,7 +2699,7 @@ void GridFunction::ProjectBdrCoefficientNormal(
|
||||
}
|
||||
|
||||
void GridFunction::ProjectBdrCoefficientTangent(
|
||||
VectorCoefficient &vcoeff, Array<int> &bdr_attr)
|
||||
VectorCoefficient &vcoeff, const Array<int> &bdr_attr)
|
||||
{
|
||||
Array<int> values_counter;
|
||||
AccumulateAndCountBdrTangentValues(vcoeff, bdr_attr, values_counter);
|
||||
@@ -2746,7 +2747,8 @@ double GridFunction::ComputeL2Error(
|
||||
for (j = 0; j < ir->GetNPoints(); j++)
|
||||
{
|
||||
const IntegrationPoint &ip = ir->IntPoint(j);
|
||||
fe->CalcShape(ip, shape);
|
||||
transf->SetIntPoint(&ip);
|
||||
fe->CalcPhysShape(*transf, shape);
|
||||
for (d = 0; d < fes->GetVDim(); d++)
|
||||
{
|
||||
a = 0;
|
||||
@@ -2759,7 +2761,6 @@ double GridFunction::ComputeL2Error(
|
||||
{
|
||||
a -= (*this)(-1-vdofs[fdof*d+k]) * shape(k);
|
||||
}
|
||||
transf->SetIntPoint(&ip);
|
||||
a -= exsol[d]->Eval(*transf, ip);
|
||||
error += ip.weight * transf->Weight() * a * a;
|
||||
}
|
||||
|
||||
+9
-7
@@ -446,11 +446,12 @@ protected:
|
||||
Array<int> &zones_per_dof);
|
||||
|
||||
void AccumulateAndCountBdrValues(Coefficient *coeff[],
|
||||
VectorCoefficient *vcoeff, Array<int> &attr,
|
||||
VectorCoefficient *vcoeff,
|
||||
const Array<int> &attr,
|
||||
Array<int> &values_counter);
|
||||
|
||||
void AccumulateAndCountBdrTangentValues(VectorCoefficient &vcoeff,
|
||||
Array<int> &bdr_attr,
|
||||
const Array<int> &bdr_attr,
|
||||
Array<int> &values_counter);
|
||||
|
||||
// Complete the computation of averages; called e.g. after
|
||||
@@ -465,7 +466,7 @@ public:
|
||||
/** @brief Project a Coefficient on the GridFunction, modifying only DOFs on
|
||||
the boundary associated with the boundary attributes marked in the
|
||||
@a attr array. */
|
||||
void ProjectBdrCoefficient(Coefficient &coeff, Array<int> &attr)
|
||||
void ProjectBdrCoefficient(Coefficient &coeff, const Array<int> &attr)
|
||||
{
|
||||
Coefficient *coeff_p = &coeff;
|
||||
ProjectBdrCoefficient(&coeff_p, attr);
|
||||
@@ -475,26 +476,27 @@ public:
|
||||
DOFs on the boundary associated with the boundary attributes marked in
|
||||
the @a attr array. */
|
||||
virtual void ProjectBdrCoefficient(VectorCoefficient &vcoeff,
|
||||
Array<int> &attr);
|
||||
const Array<int> &attr);
|
||||
|
||||
/** @brief Project a set of Coefficient%s on the components of the
|
||||
GridFunction, modifying only DOFs on the boundary associated with the
|
||||
boundary attributed marked in the @a attr array. */
|
||||
/** If a Coefficient pointer in the array @a coeff is NULL, that component
|
||||
will not be touched. */
|
||||
virtual void ProjectBdrCoefficient(Coefficient *coeff[], Array<int> &attr);
|
||||
virtual void ProjectBdrCoefficient(Coefficient *coeff[],
|
||||
const Array<int> &attr);
|
||||
|
||||
/** Project the normal component of the given VectorCoefficient on
|
||||
the boundary. Only boundary attributes that are marked in
|
||||
'bdr_attr' are projected. Assumes RT-type VectorFE GridFunction. */
|
||||
void ProjectBdrCoefficientNormal(VectorCoefficient &vcoeff,
|
||||
Array<int> &bdr_attr);
|
||||
const Array<int> &bdr_attr);
|
||||
|
||||
/** @brief Project the tangential components of the given VectorCoefficient
|
||||
on the boundary. Only boundary attributes that are marked in @a bdr_attr
|
||||
are projected. Assumes ND-type VectorFE GridFunction. */
|
||||
virtual void ProjectBdrCoefficientTangent(VectorCoefficient &vcoeff,
|
||||
Array<int> &bdr_attr);
|
||||
const Array<int> &bdr_attr);
|
||||
|
||||
virtual double ComputeL2Error(Coefficient *exsol[],
|
||||
const IntegrationRule *irs[] = NULL,
|
||||
|
||||
@@ -917,6 +917,7 @@ int Quadrature1D::CheckClosed(int type)
|
||||
{
|
||||
case GaussLobatto:
|
||||
case ClosedUniform:
|
||||
case ClosedGL:
|
||||
return type;
|
||||
default:
|
||||
return Invalid;
|
||||
|
||||
+2
-2
@@ -728,7 +728,7 @@ private:
|
||||
|
||||
public:
|
||||
VectorQuadratureLFIntegrator(VectorQuadratureFunctionCoefficient &vqfc,
|
||||
const IntegrationRule *ir)
|
||||
const IntegrationRule *ir = NULL)
|
||||
: LinearFormIntegrator(ir), vqfc(vqfc)
|
||||
{
|
||||
if (ir)
|
||||
@@ -760,7 +760,7 @@ private:
|
||||
|
||||
public:
|
||||
QuadratureLFIntegrator(QuadratureFunctionCoefficient &qfc,
|
||||
const IntegrationRule *ir)
|
||||
const IntegrationRule *ir = NULL)
|
||||
: LinearFormIntegrator(ir), qfc(qfc)
|
||||
{
|
||||
if (ir)
|
||||
|
||||
+2
-2
@@ -666,7 +666,7 @@ void ParGridFunction::ProjectDiscCoefficient(VectorCoefficient &vcoeff,
|
||||
}
|
||||
|
||||
void ParGridFunction::ProjectBdrCoefficient(
|
||||
Coefficient *coeff[], VectorCoefficient *vcoeff, Array<int> &attr)
|
||||
Coefficient *coeff[], VectorCoefficient *vcoeff, const Array<int> &attr)
|
||||
{
|
||||
Array<int> values_counter;
|
||||
AccumulateAndCountBdrValues(coeff, vcoeff, attr, values_counter);
|
||||
@@ -720,7 +720,7 @@ void ParGridFunction::ProjectBdrCoefficient(
|
||||
}
|
||||
|
||||
void ParGridFunction::ProjectBdrCoefficientTangent(VectorCoefficient &vcoeff,
|
||||
Array<int> &bdr_attr)
|
||||
const Array<int> &bdr_attr)
|
||||
{
|
||||
Array<int> values_counter;
|
||||
AccumulateAndCountBdrTangentValues(vcoeff, bdr_attr, values_counter);
|
||||
|
||||
+5
-4
@@ -44,7 +44,7 @@ protected:
|
||||
Vector send_data;
|
||||
|
||||
void ProjectBdrCoefficient(Coefficient *coeff[], VectorCoefficient *vcoeff,
|
||||
Array<int> &attr);
|
||||
const Array<int> &attr);
|
||||
|
||||
public:
|
||||
ParGridFunction() { pfes = NULL; }
|
||||
@@ -256,16 +256,17 @@ public:
|
||||
|
||||
// Only the values in the master are guaranteed to be correct!
|
||||
void ProjectBdrCoefficient(VectorCoefficient &vcoeff,
|
||||
Array<int> &attr) override
|
||||
const Array<int> &attr) override
|
||||
{ ProjectBdrCoefficient(NULL, &vcoeff, attr); }
|
||||
|
||||
// Only the values in the master are guaranteed to be correct!
|
||||
void ProjectBdrCoefficient(Coefficient *coeff[], Array<int> &attr) override
|
||||
void ProjectBdrCoefficient(Coefficient *coeff[],
|
||||
const Array<int> &attr) override
|
||||
{ ProjectBdrCoefficient(coeff, NULL, attr); }
|
||||
|
||||
// Only the values in the master are guaranteed to be correct!
|
||||
void ProjectBdrCoefficientTangent(VectorCoefficient &vcoeff,
|
||||
Array<int> &bdr_attr) override;
|
||||
const Array<int> &bdr_attr) override;
|
||||
|
||||
double ComputeL1Error(Coefficient *exsol[],
|
||||
const IntegrationRule *irs[] = NULL) const override
|
||||
|
||||
+42
-12
@@ -1420,14 +1420,20 @@ void Prolongation2D(const int NE, const int D1D, const int Q1D,
|
||||
const Array<double>& B, const Vector& mask)
|
||||
{
|
||||
auto x_ = Reshape(localL.Read(), D1D, D1D, NE);
|
||||
auto y_ = Reshape(localH.ReadWrite(), Q1D, Q1D, NE);
|
||||
auto y_ = Reshape(localH.Write(), Q1D, Q1D, NE);
|
||||
auto B_ = Reshape(B.Read(), Q1D, D1D);
|
||||
auto m_ = Reshape(mask.Read(), Q1D, Q1D, NE);
|
||||
|
||||
localH = 0.0;
|
||||
|
||||
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
|
||||
{
|
||||
for (int qy = 0; qy < Q1D; ++qy)
|
||||
{
|
||||
for (int qx = 0; qx < Q1D; ++qx)
|
||||
{
|
||||
y_(qx, qy, e) = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
for (int dy = 0; dy < D1D; ++dy)
|
||||
{
|
||||
double sol_x[DofQuadLimits::MAX_Q1D];
|
||||
@@ -1467,14 +1473,23 @@ void Prolongation3D(const int NE, const int D1D, const int Q1D,
|
||||
const Array<double>& B, const Vector& mask)
|
||||
{
|
||||
auto x_ = Reshape(localL.Read(), D1D, D1D, D1D, NE);
|
||||
auto y_ = Reshape(localH.ReadWrite(), Q1D, Q1D, Q1D, NE);
|
||||
auto y_ = Reshape(localH.Write(), Q1D, Q1D, Q1D, NE);
|
||||
auto B_ = Reshape(B.Read(), Q1D, D1D);
|
||||
auto m_ = Reshape(mask.Read(), Q1D, Q1D, Q1D, NE);
|
||||
|
||||
localH = 0.0;
|
||||
|
||||
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
|
||||
{
|
||||
for (int qz = 0; qz < Q1D; ++qz)
|
||||
{
|
||||
for (int qy = 0; qy < Q1D; ++qy)
|
||||
{
|
||||
for (int qx = 0; qx < Q1D; ++qx)
|
||||
{
|
||||
y_(qx, qy, qz, e) = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int dz = 0; dz < D1D; ++dz)
|
||||
{
|
||||
double sol_xy[DofQuadLimits::MAX_Q1D][DofQuadLimits::MAX_Q1D];
|
||||
@@ -1539,14 +1554,20 @@ void Restriction2D(const int NE, const int D1D, const int Q1D,
|
||||
const Array<double>& Bt, const Vector& mask)
|
||||
{
|
||||
auto x_ = Reshape(localH.Read(), Q1D, Q1D, NE);
|
||||
auto y_ = Reshape(localL.ReadWrite(), D1D, D1D, NE);
|
||||
auto y_ = Reshape(localL.Write(), D1D, D1D, NE);
|
||||
auto Bt_ = Reshape(Bt.Read(), D1D, Q1D);
|
||||
auto m_ = Reshape(mask.Read(), Q1D, Q1D, NE);
|
||||
|
||||
localL = 0.0;
|
||||
|
||||
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
|
||||
{
|
||||
for (int dy = 0; dy < D1D; ++dy)
|
||||
{
|
||||
for (int dx = 0; dx < D1D; ++dx)
|
||||
{
|
||||
y_(dx, dy, e) = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
for (int qy = 0; qy < Q1D; ++qy)
|
||||
{
|
||||
double sol_x[DofQuadLimits::MAX_D1D];
|
||||
@@ -1578,14 +1599,23 @@ void Restriction3D(const int NE, const int D1D, const int Q1D,
|
||||
const Array<double>& Bt, const Vector& mask)
|
||||
{
|
||||
auto x_ = Reshape(localH.Read(), Q1D, Q1D, Q1D, NE);
|
||||
auto y_ = Reshape(localL.ReadWrite(), D1D, D1D, D1D, NE);
|
||||
auto y_ = Reshape(localL.Write(), D1D, D1D, D1D, NE);
|
||||
auto Bt_ = Reshape(Bt.Read(), D1D, Q1D);
|
||||
auto m_ = Reshape(mask.Read(), Q1D, Q1D, Q1D, NE);
|
||||
|
||||
localL = 0.0;
|
||||
|
||||
mfem::forall(NE, [=] MFEM_HOST_DEVICE (int e)
|
||||
{
|
||||
for (int dz = 0; dz < D1D; ++dz)
|
||||
{
|
||||
for (int dy = 0; dy < D1D; ++dy)
|
||||
{
|
||||
for (int dx = 0; dx < D1D; ++dx)
|
||||
{
|
||||
y_(dx, dy, dz, e) = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int qz = 0; qz < Q1D; ++qz)
|
||||
{
|
||||
double sol_xy[DofQuadLimits::MAX_D1D][DofQuadLimits::MAX_D1D];
|
||||
|
||||
@@ -45,12 +45,12 @@ BlockOperator::BlockOperator(const Array<int> & row_offsets_,
|
||||
op = static_cast<Operator *>(NULL);
|
||||
}
|
||||
|
||||
void BlockOperator::SetDiagonalBlock(int iblock, Operator *opt, double c)
|
||||
void BlockOperator::SetDiagonalBlock(int iblock, const Operator *opt, double c)
|
||||
{
|
||||
SetBlock(iblock, iblock, opt, c);
|
||||
}
|
||||
|
||||
void BlockOperator::SetBlock(int iRow, int iCol, Operator *opt, double c)
|
||||
void BlockOperator::SetBlock(int iRow, int iCol, const Operator *opt, double c)
|
||||
{
|
||||
if (owns_blocks && op(iRow, iCol))
|
||||
{
|
||||
|
||||
@@ -61,14 +61,14 @@ public:
|
||||
* op: the Operator to be inserted.
|
||||
* c: optional scalar multiple for this block.
|
||||
*/
|
||||
void SetDiagonalBlock(int iblock, Operator *op, double c = 1.0);
|
||||
void SetDiagonalBlock(int iblock, const Operator *op, double c = 1.0);
|
||||
//! Add a block op in the block-entry (iblock, jblock).
|
||||
/**
|
||||
* irow, icol: The block will be inserted in location (irow, icol).
|
||||
* op: the Operator to be inserted.
|
||||
* c: optional scalar multiple for this block.
|
||||
*/
|
||||
void SetBlock(int iRow, int iCol, Operator *op, double c = 1.0);
|
||||
void SetBlock(int iRow, int iCol, const Operator *op, double c = 1.0);
|
||||
|
||||
//! Return the number of row blocks
|
||||
int NumRowBlocks() const { return nRowBlocks; }
|
||||
@@ -78,9 +78,6 @@ public:
|
||||
//! Check if block (i,j) is a zero block
|
||||
int IsZeroBlock(int i, int j) const { return (op(i,j)==NULL) ? 1 : 0; }
|
||||
//! Return a reference to block i,j
|
||||
Operator & GetBlock(int i, int j)
|
||||
{ MFEM_VERIFY(op(i,j), ""); return *op(i,j); }
|
||||
//! Return a reference to block i,j (const version)
|
||||
const Operator & GetBlock(int i, int j) const
|
||||
{ MFEM_VERIFY(op(i,j), ""); return *op(i,j); }
|
||||
//! Return the coefficient for block i,j
|
||||
@@ -123,7 +120,7 @@ private:
|
||||
//! Column offsets for the starting position of each block
|
||||
Array<int> col_offsets;
|
||||
//! 2D array that stores each block of the operator.
|
||||
Array2D<Operator *> op;
|
||||
Array2D<const Operator *> op;
|
||||
//! 2D array that stores a coefficient for each block of the operator.
|
||||
Array2D<double> coef;
|
||||
|
||||
|
||||
+10
-4
@@ -481,7 +481,8 @@ ConstrainedOperator::ConstrainedOperator(Operator *A, const Array<int> &list,
|
||||
MemoryType mem_type = GetMemoryType(mem_class);
|
||||
list.Read(); // TODO: just ensure 'list' is registered, no need to copy it
|
||||
constraint_list.MakeRef(list);
|
||||
// typically z and w are large vectors, so store them on the device
|
||||
// typically z and w are large vectors, so use the device (GPU) to perform
|
||||
// operations on them
|
||||
z.SetSize(height, mem_type); z.UseDevice(true);
|
||||
w.SetSize(height, mem_type); w.UseDevice(true);
|
||||
}
|
||||
@@ -591,6 +592,13 @@ void ConstrainedOperator::Mult(const Vector &x, Vector &y) const
|
||||
}
|
||||
}
|
||||
|
||||
void ConstrainedOperator::AddMult(const Vector &x, Vector &y,
|
||||
const double a) const
|
||||
{
|
||||
Mult(x, w);
|
||||
y.Add(a, w);
|
||||
}
|
||||
|
||||
RectangularConstrainedOperator::RectangularConstrainedOperator(
|
||||
Operator *A,
|
||||
const Array<int> &trial_list,
|
||||
@@ -625,9 +633,7 @@ void RectangularConstrainedOperator::EliminateRHS(const Vector &x,
|
||||
d_w[id] = d_x[id];
|
||||
});
|
||||
|
||||
// A.AddMult(w, b, -1.0); // if available to all Operators
|
||||
A->Mult(w, z);
|
||||
b -= z;
|
||||
A->AddMult(w, b, -1.0);
|
||||
|
||||
const int test_csz = test_constraints.Size();
|
||||
auto test_idx = test_constraints.Read();
|
||||
|
||||
+6
-4
@@ -892,14 +892,14 @@ public:
|
||||
DiagonalPolicy diag_policy = DIAG_ONE);
|
||||
|
||||
/// Returns the type of memory in which the solution and temporaries are stored.
|
||||
virtual MemoryClass GetMemoryClass() const { return mem_class; }
|
||||
MemoryClass GetMemoryClass() const override { return mem_class; }
|
||||
|
||||
/// Set the diagonal policy for the constrained operator.
|
||||
void SetDiagonalPolicy(const DiagonalPolicy diag_policy_)
|
||||
{ diag_policy = diag_policy_; }
|
||||
|
||||
/// Diagonal of A, modified according to the used DiagonalPolicy.
|
||||
virtual void AssembleDiagonal(Vector &diag) const;
|
||||
void AssembleDiagonal(Vector &diag) const override;
|
||||
|
||||
/** @brief Eliminate "essential boundary condition" values specified in @a x
|
||||
from the given right-hand side @a b.
|
||||
@@ -922,10 +922,12 @@ public:
|
||||
|
||||
where the "_b" subscripts denote the essential (boundary) indices/dofs of
|
||||
the vectors, and "_i" -- the rest of the entries. */
|
||||
virtual void Mult(const Vector &x, Vector &y) const;
|
||||
void Mult(const Vector &x, Vector &y) const override;
|
||||
|
||||
void AddMult(const Vector &x, Vector &y, const double a = 1.0) const override;
|
||||
|
||||
/// Destructor: destroys the unconstrained Operator, if owned.
|
||||
virtual ~ConstrainedOperator() { if (own_A) { delete A; } }
|
||||
~ConstrainedOperator() override { if (own_A) { delete A; } }
|
||||
};
|
||||
|
||||
/** @brief Rectangular Operator for imposing essential boundary conditions on
|
||||
|
||||
@@ -1767,6 +1767,7 @@ void SparseMatrix::EliminateCol(int col, DiagonalPolicy dpolicy)
|
||||
if (aux->Column == col)
|
||||
{
|
||||
aux->Value = 0.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,6 +491,10 @@ public:
|
||||
void GenerateOffsets(int N, HYPRE_BigInt loc_sizes[],
|
||||
Array<HYPRE_BigInt> *offsets[]) const;
|
||||
|
||||
/** Return true if the face is interior or shared. In parallel, this
|
||||
method only works if the face neighbor data is exchanged. */
|
||||
inline bool FaceIsTrueInterior(int FaceNo) const { return Mesh::FaceIsTrueInterior(FaceNo); }
|
||||
|
||||
void ExchangeFaceNbrData();
|
||||
void ExchangeFaceNbrNodes();
|
||||
|
||||
|
||||
@@ -314,7 +314,8 @@ void SaddleSchwarzSmoother::Mult(const Vector & x, Vector & y) const
|
||||
blk_y.GetBlock(1) -= coarse_l2_projection;
|
||||
}
|
||||
|
||||
BDPMinresSolver::BDPMinresSolver(HypreParMatrix& M, HypreParMatrix& B,
|
||||
BDPMinresSolver::BDPMinresSolver(const HypreParMatrix& M,
|
||||
const HypreParMatrix& B,
|
||||
IterSolveParameters param)
|
||||
: DarcySolver(M.NumRows(), B.NumRows()), op_(offsets_), prec_(offsets_),
|
||||
BT_(B.Transpose()), solver_(M.GetComm())
|
||||
@@ -360,8 +361,8 @@ DivFreeSolver::DivFreeSolver(const HypreParMatrix &M, const HypreParMatrix& B,
|
||||
|
||||
for (int l = data.P_l2.size(); l >= 0; --l)
|
||||
{
|
||||
auto& M_f = static_cast<HypreParMatrix&>(ops_[l]->GetBlock(0, 0));
|
||||
auto& B_f = static_cast<HypreParMatrix&>(ops_[l]->GetBlock(1, 0));
|
||||
auto& M_f = static_cast<const HypreParMatrix&>(ops_[l]->GetBlock(0, 0));
|
||||
auto& B_f = static_cast<const HypreParMatrix&>(ops_[l]->GetBlock(1, 0));
|
||||
|
||||
if (l == 0)
|
||||
{
|
||||
@@ -586,7 +587,7 @@ void DivFreeSolver::Mult(const Vector & x, Vector & y) const
|
||||
ch.Clear();
|
||||
ch.Start();
|
||||
|
||||
auto M = dynamic_cast<HypreParMatrix&>(ops_.Last()->GetBlock(0, 0));
|
||||
auto& M = dynamic_cast<const HypreParMatrix&>(ops_.Last()->GetBlock(0, 0));
|
||||
M.Mult(-1.0, correction.GetBlock(0), 1.0, resid.GetBlock(0));
|
||||
SolvePotential(resid.GetBlock(0), correction.GetBlock(1));
|
||||
blk_y.GetBlock(1) += correction.GetBlock(1);
|
||||
|
||||
@@ -190,7 +190,7 @@ class BDPMinresSolver : public DarcySolver
|
||||
MINRESSolver solver_;
|
||||
Array<int> ess_zero_dofs_;
|
||||
public:
|
||||
BDPMinresSolver(HypreParMatrix& M, HypreParMatrix& B,
|
||||
BDPMinresSolver(const HypreParMatrix& M, const HypreParMatrix& B,
|
||||
IterSolveParameters param);
|
||||
virtual void Mult(const Vector & x, Vector & y) const;
|
||||
virtual void SetOperator(const Operator &op) { }
|
||||
|
||||
Reference in New Issue
Block a user