rewrite the mechanism to enforce constraint degrees of freedom

- the residual now does not consider constraints anymore
- instead, the central place for constraints is the linearizer:
  - it gets a constraintsMap() method which is analogous to residual()
    but it stores (DOF index, constraints vector) pairs because
    typically only very few DOFs need to be constraint.
- the newton method consults the linearizer's constraint map to update
  the error and the current iterative solution. the primary variables
  for constraint degrees of freedom are now directly copied from the
  'Constraints' object to correctly handle pseudo primary variables.
- the abilility to specify partial constraints is removed, i.e., it is
  no longer possible to constrain some equations/primary variables of
  a degree of freedom without having to specify all of them. The
  reason is that is AFAICS with partial constraint DOFs it is
  impossible to specify the pseudo primary variables for models which
  require them (PVS, black-oil).

  because of this, the reference solution for the Navier-Stokes test
  is updated. the test still oscillates like hell, but fixing this
  would require to implement spatial discretizations that are either
  better in general (e.g., DG methods) or adapted to Navier-Stokes
  problems (e.g., staggered grid FV methods). since both of these are
  currently quite low on my list of priorities, let's just accept the
  osscillations for now.
This commit is contained in:
Andreas Lauser 2015-12-31 13:20:24 +01:00
parent c0f8fc274d
commit f6c835298a
11 changed files with 6868 additions and 17351 deletions

View File

@ -394,11 +394,11 @@ public:
const GlobalPosition &pos = context.pos(spaceIdx, timeIdx);
if (onUpperBoundary_(pos) && !onInlet_(pos)) {
constraints.setAllConstraint();
constraints.setActive(true);
constraints.assignNaive(initialFluidState_);
}
else if (onLowerBoundary_(pos)) {
constraints.setAllConstraint();
constraints.setActive(true);
constraints.assignNaive(initialFluidState_);
}
}

View File

@ -512,7 +512,7 @@ public:
+ (pCFracture[nonWettingPhaseIdx]
- pCFracture[wettingPhaseIdx]));
constraints.setAllConstraint();
constraints.setActive(true);
constraints.assignNaiveFromFracture(fractureFluidState,
matrixMaterialParams_);
}

View File

@ -236,12 +236,12 @@ public:
const auto &pos = context.pos(spaceIdx, timeIdx);
if (onUpperBoundary_(pos)) {
constraints.setActive(true);
// lid moves from left to right
const Scalar lidVelocity = 1.0;
constraints.setConstraint(momentum0EqIdx, velocity0Idx + 0,
lidVelocity);
constraints.setConstraint(momentum0EqIdx + 1, velocity0Idx + 1, 0);
constraints.setConstraint(conti0EqIdx, pressureIdx, 1e5);
constraints[velocity0Idx + 0] = lidVelocity;
constraints[velocity0Idx + 1] = 0.0;
constraints[pressureIdx + 1] = 1e5;
}
}

View File

@ -511,7 +511,7 @@ public:
fs.setMoleFraction(waterPhaseIdx, waterCompIdx, 1.0);
constraints.setAllConstraint();
constraints.setActive(true);
constraints.assignNaive(fs);
}
else if (width / 2 - 1 < x && x < width / 2 + 1 && y > height / 2) {
@ -533,7 +533,7 @@ public:
initialFluidState_.moleFraction(phaseIdx,
compIdx));
constraints.setAllConstraint();
constraints.setActive(true);
constraints.assignNaive(fs);
}
}

View File

@ -281,18 +281,8 @@ public:
const auto &pos = context.pos(spaceIdx, timeIdx);
if (onUpperBoundary_(pos)) {
PrimaryVariables initCond;
initial(initCond, context, spaceIdx, timeIdx);
constraints.setConstraint(pressureIdx, conti0EqIdx,
initCond[pressureIdx]);
;
constraints.setConstraint(moleFrac1Idx, conti0EqIdx + 1,
initCond[moleFrac1Idx]);
for (unsigned axisIdx = 0; axisIdx < dimWorld; ++axisIdx)
constraints.setConstraint(velocity0Idx + axisIdx,
momentum0EqIdx + axisIdx,
initCond[velocity0Idx + axisIdx]);
constraints.setActive(true);
initial(constraints, context, spaceIdx, timeIdx);
}
}
//! \}

View File

@ -291,21 +291,8 @@ public:
const auto &pos = context.pos(spaceIdx, timeIdx);
if (onLowerBoundary_(pos) || onUpperBoundary_(pos)) {
PrimaryVariables initCond;
initial(initCond, context, spaceIdx, timeIdx);
constraints.setConstraint(temperatureIdx, energyEqIdx,
initCond[temperatureIdx]);
;
constraints.setConstraint(pressureIdx, conti0EqIdx,
initCond[pressureIdx]);
constraints.setConstraint(moleFrac1Idx, conti0EqIdx + 1,
initCond[moleFrac1Idx]);
;
for (unsigned axisIdx = 0; axisIdx < dimWorld; ++axisIdx)
constraints.setConstraint(velocity0Idx + axisIdx,
momentum0EqIdx + axisIdx,
initCond[momentum0EqIdx + axisIdx]);
constraints.setActive(true);
initial(constraints, context, spaceIdx, timeIdx);
}
}

View File

@ -280,16 +280,8 @@ public:
const auto &pos = context.pos(spaceIdx, timeIdx);
if (onLeftBoundary_(pos) || onRightBoundary_(pos)) {
PrimaryVariables initCond;
initial(initCond, context, spaceIdx, timeIdx);
constraints.setConstraint(pressureIdx, conti0EqIdx,
initCond[pressureIdx]);
;
for (unsigned axisIdx = 0; axisIdx < dimWorld; ++axisIdx)
constraints.setConstraint(velocity0Idx + axisIdx,
momentum0EqIdx + axisIdx,
initCond[velocity0Idx + axisIdx]);
constraints.setActive(true);
initial(constraints, context, spaceIdx, timeIdx);
}
}

View File

@ -103,9 +103,6 @@ SET_TYPE_PROP(WaterAirBaseProblem, FluidSystem,
// Enable gravity
SET_BOOL_PROP(WaterAirBaseProblem, EnableGravity, true);
// Enable constraints
SET_BOOL_PROP(WaterAirBaseProblem, EnableConstraints, true);
// Use forward differences instead of central differences
SET_INT_PROP(WaterAirBaseProblem, NumericDifferenceMethod, +1);
@ -442,24 +439,6 @@ public:
values.assignMassConservative(fs, matParams, /*inEquilibrium=*/true);
}
/*!
* \copydoc FvBaseProblem::constraints
*
* In this problem, constraints are used to keep the temperature of the degrees of
* freedom which are closest to the inlet constant.
*/
template <class Context>
void constraints(Constraints &constraints,
const Context &context,
unsigned spaceIdx, unsigned timeIdx) const
{
const auto &pos = context.pos(spaceIdx, timeIdx);
if (onInlet_(pos)) {
constraints.setConstraint(temperatureIdx, energyEqIdx, 380);
}
}
/*!
* \copydoc FvBaseProblem::source
*

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff