Revised fvMatrix::setReference

This commit is contained in:
Henrik Rusche 2013-07-10 00:58:16 +02:00
parent 3915b701f7
commit 1e32d23da1

View file

@ -519,37 +519,40 @@ void Foam::fvMatrix<Type>::setReference
const bool forceReference const bool forceReference
) )
{ {
if (celli >= 0 && (psi_.needReference() || forceReference)) if ((forceReference || psi_.needReference()) && celli >= 0)
{ {
// Bug fix: force reference only on master for parallel runs // HR, 9/Jul/2013
// HJ, 12/Feb/2010 // Very early versions could produce memory violations if celli is read
if (Pstream::parRun()) // from dictionary, however, the proposed fix produced unpredictable
{ // results in parallel. Keeping in mind that topologically changing
// Parallel run: // meshes will complicate the matter to level that cannot possibly be
// - only set reference on master processor: one place is enough // dealt with at this point, we will simply raise an error if celli
// - make sure that cellI is not out of range // is out of bound.
if (Pstream::master())
{
label parCelli = celli;
while (parCelli >= diag().size()) // In essence: The user of this function needs to make sure that celli
// is set only on one processor and that it is updated if the mesh
// changes. We should be doing better than this! Consider mesh object
// to hold reference cell and associated data.
if (celli >= diag().size())
{ {
// Out of range, pick a local cell FatalErrorIn
parCelli /= Pstream::nProcs(); (
"fvMatrix<Type>::setReference"
"("
"const label celli, "
"const Type& value, "
"const bool forceReference"
")"
)
<< "celli out of bound"
<< abort(FatalError);
} }
source()[parCelli] += diag()[parCelli]*value;
diag()[parCelli] += diag()[parCelli];
}
}
else
{
// Serial run, standard practice
source()[celli] += diag()[celli]*value; source()[celli] += diag()[celli]*value;
diag()[celli] += diag()[celli]; diag()[celli] += diag()[celli];
} }
} }
}
template<class Type> template<class Type>