Exemplo n.º 1
0
void Foam::steadyStateControl::maxTypeResidual
(
    const word& fieldName,
    ITstream& data,
    scalar& firstRes,
    scalar& lastRes
) const
{
    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
    if (mesh_.foundObject<fieldType>(fieldName))
    {
        //fieldType& pointVelocity = const_cast<fieldType&>(
        //  mesh_.objectRegistry::lookupObject<fieldType>( fieldName )
        //);
	fieldType& field = const_cast<fieldType&>(
		mesh_.lookupObject<fieldType>( fieldName )
	);

        const List<SolverPerformance<Type> > sp(data);

        int sz = field.size();
        reduce(sz, sumOp<int>());
        Type nF = gSumCmptProd( field, field ) / static_cast<double>(sz);

	//Type finiR = sp.first().initialResidual();
	//Type liniR = sp.last().initialResidual();
	//
	scalar norm = mag(nF);

	for (direction cmpt=0; cmpt < nF.size(); cmpt++){
	  nF[cmpt] = sqrt( nF[cmpt] );
	  //finiR[cmpt] *= tmpNF;
	  //liniR[cmpt] *= tmpNF;
	}
        nF = nF/norm;

	//finiR /= norm;
	//liniR /= norm;
	//firstRes = cmptMax(finiR);
	//lastRes = cmptMax(liniR);
	//
        firstRes = cmptMax( cmptMultiply(sp.first().initialResidual(), nF) );
        lastRes  = cmptMax( cmptMultiply(sp.last().initialResidual(),  nF) );

        //firstRes = cmptMax(sp.first().initialResidual());
        //lastRes = cmptMax(sp.last().initialResidual());
    }
}
Exemplo n.º 2
0
typename Foam::SolverPerformance<Type>
Foam::PCICG<Type, DType, LUType>::solve(Field<Type>& psi) const
{
    word preconditionerName(this->controlDict_.lookup("preconditioner"));

    // --- Setup class containing solver performance data
    SolverPerformance<Type> solverPerf
    (
        preconditionerName + typeName,
        this->fieldName_
    );

    label nCells = psi.size();

    Type* __restrict__ psiPtr = psi.begin();

    Field<Type> pA(nCells);
    Type* __restrict__ pAPtr = pA.begin();

    Field<Type> wA(nCells);
    Type* __restrict__ wAPtr = wA.begin();

    Type wArA = solverPerf.great_*pTraits<Type>::one;
    Type wArAold = wArA;

    // --- Calculate A.psi
    this->matrix_.Amul(wA, psi);

    // --- Calculate initial residual field
    Field<Type> rA(this->matrix_.source() - wA);
    Type* __restrict__ rAPtr = rA.begin();

    // --- Calculate normalisation factor
    Type normFactor = this->normFactor(psi, wA, pA);

    if (LduMatrix<Type, DType, LUType>::debug >= 2)
    {
        Info<< "   Normalisation factor = " << normFactor << endl;
    }

    // --- Calculate normalised residual norm
    solverPerf.initialResidual() = cmptDivide(gSumCmptMag(rA), normFactor);
    solverPerf.finalResidual() = solverPerf.initialResidual();

    // --- Check convergence, solve if not converged
    if
    (
        this->minIter_ > 0
     || !solverPerf.checkConvergence(this->tolerance_, this->relTol_)
    )
    {
        // --- Select and construct the preconditioner
        autoPtr<typename LduMatrix<Type, DType, LUType>::preconditioner>
        preconPtr = LduMatrix<Type, DType, LUType>::preconditioner::New
        (
            *this,
            this->controlDict_
        );

        // --- Solver iteration
        do
        {
            // --- Store previous wArA
            wArAold = wArA;

            // --- Precondition residual
            preconPtr->precondition(wA, rA);

            // --- Update search directions:
            wArA = gSumCmptProd(wA, rA);

            if (solverPerf.nIterations() == 0)
            {
                for (label cell=0; cell<nCells; cell++)
                {
                    pAPtr[cell] = wAPtr[cell];
                }
            }
            else
            {
                Type beta = cmptDivide
                (
                    wArA,
                    stabilise(wArAold, solverPerf.vsmall_)
                );

                for (label cell=0; cell<nCells; cell++)
                {
                    pAPtr[cell] = wAPtr[cell] + cmptMultiply(beta, pAPtr[cell]);
                }
            }


            // --- Update preconditioned residual
            this->matrix_.Amul(wA, pA);

            Type wApA = gSumCmptProd(wA, pA);


            // --- Test for singularity
            if
            (
                solverPerf.checkSingularity
                (
                    cmptDivide(cmptMag(wApA), normFactor)
                )
            )
            {
                break;
            }


            // --- Update solution and residual:

            Type alpha = cmptDivide
            (
                wArA,
                stabilise(wApA, solverPerf.vsmall_)
            );

            for (label cell=0; cell<nCells; cell++)
            {
                psiPtr[cell] += cmptMultiply(alpha, pAPtr[cell]);
                rAPtr[cell] -= cmptMultiply(alpha, wAPtr[cell]);
            }

            solverPerf.finalResidual() =
                cmptDivide(gSumCmptMag(rA), normFactor);

        } while
        (
            (
                solverPerf.nIterations()++ < this->maxIter_
            && !solverPerf.checkConvergence(this->tolerance_, this->relTol_)
            )
         || solverPerf.nIterations() < this->minIter_
        );
    }

    return solverPerf;
}
Exemplo n.º 3
0
Foam::SolverPerformance<Type>
Foam::PBiCICG<Type, DType, LUType>::solve(gpuField<Type>& psi) const
{
    word preconditionerName(this->controlDict_.lookup("preconditioner"));

    if(preconditionerName != "none")
        preconditionerName = "diagonal";

    // --- Setup class containing solver performance data
    SolverPerformance<Type> solverPerf
    (
        preconditionerName + typeName,
        this->fieldName_
    );

    register label nCells = psi.size();


    gpuField<Type> pA(nCells);

    gpuField<Type> pT(nCells, pTraits<Type>::zero);

    gpuField<Type> wA(nCells);

    gpuField<Type> wT(nCells);

    Type wArT = solverPerf.great_*pTraits<Type>::one;
    Type wArTold = wArT;

    // --- Calculate A.psi and T.psi
    this->matrix_.Amul(wA, psi);
    this->matrix_.Tmul(wT, psi);

    // --- Calculate initial residual and transpose residual fields
    gpuField<Type> rA(this->matrix_.source() - wA);
    gpuField<Type> rT(this->matrix_.source() - wT);

    // --- Calculate normalisation factor
    Type normFactor = this->normFactor(psi, wA, pA);

    if (LduMatrix<Type, DType, LUType>::debug >= 2)
    {
        Info<< "   Normalisation factor = " << normFactor << endl;
    }

    // --- Calculate normalised residual norm
    solverPerf.initialResidual() = cmptDivide(gSumCmptMag(rA), normFactor);
    solverPerf.finalResidual() = solverPerf.initialResidual();

    // --- Check convergence, solve if not converged
    if (!solverPerf.checkConvergence(this->tolerance_, this->relTol_))
    {
        // --- Select and construct the preconditioner
        autoPtr<typename LduMatrix<Type, DType, LUType>::preconditioner>
        preconPtr = LduMatrix<Type, DType, LUType>::preconditioner::New
        (
            *this,
            this->controlDict_
        );

        // --- Solver iteration
        do
        {
            // --- Store previous wArT
            wArTold = wArT;

            // --- Precondition residuals
            preconPtr->precondition(wA, rA);
            preconPtr->preconditionT(wT, rT);

            // --- Update search directions:
            wArT = gSumCmptProd(wA, rT);

            if (solverPerf.nIterations() == 0)
            {
                thrust::copy(wA.begin(),wA.end(),pA.begin());
                thrust::copy(wT.begin(),wT.end(),pT.begin());
            }
            else
            {
                Type beta = cmptDivide
                (
                    wArT,
                    stabilise(wArTold, solverPerf.vsmall_)
                );

               thrust::transform
               (
                   wA.begin(),
                   wA.end(),
                   thrust::make_transform_iterator
                   (
                       pA.begin(),
                       cmptMultiplyBinaryFunctionSFFunctor<Type,Type,Type>(beta)
                   ),
                   pA.begin(),
                   addOperatorFunctor<Type,Type,Type>()
               );

               thrust::transform
               (
                   wT.begin(),
                   wT.end(),
                   thrust::make_transform_iterator
                   (
                       pT.begin(),
                       cmptMultiplyBinaryFunctionSFFunctor<Type,Type,Type>(beta)
                   ),
                   pT.begin(),
                   addOperatorFunctor<Type,Type,Type>()
               );
            }


            // --- Update preconditioned residuals
            this->matrix_.Amul(wA, pA);
            this->matrix_.Tmul(wT, pT);

            Type wApT = gSumCmptProd(wA, pT);

            // --- Test for singularity
            if
            (
                solverPerf.checkSingularity
                (
                    cmptDivide(cmptMag(wApT), normFactor)
                )
            )
            {
                break;
            }


            // --- Update solution and residual:

            Type alpha = cmptDivide
            (
                wArT,
                stabilise(wApT, solverPerf.vsmall_)
            );

            thrust::transform
            (
                psi.begin(),
                psi.end(),
                thrust::make_transform_iterator
                (
                    pA.begin(),
                    cmptMultiplyBinaryFunctionSFFunctor<Type,Type,Type>(alpha)
                ),
                psi.begin(),
                addOperatorFunctor<Type,Type,Type>()
            );

            thrust::transform
            (
                rA.begin(),
                rA.end(),
                thrust::make_transform_iterator
                (
                    wA.begin(),
                    cmptMultiplyBinaryFunctionSFFunctor<Type,Type,Type>(alpha)
                ),
                rA.begin(),
                subtractOperatorFunctor<Type,Type,Type>()
            );

            thrust::transform
            (
                rT.begin(),
                rT.end(),
                thrust::make_transform_iterator
                (
                    wT.begin(),
                    cmptMultiplyBinaryFunctionSFFunctor<Type,Type,Type>(alpha)
                ),
                rT.begin(),
                subtractOperatorFunctor<Type,Type,Type>()
            );

            solverPerf.finalResidual() =
                cmptDivide(gSumCmptMag(rA), normFactor);

        } while
        (
            solverPerf.nIterations()++ < this->maxIter_
        && !(solverPerf.checkConvergence(this->tolerance_, this->relTol_))
        );
    }

    return solverPerf;
}