Foam::solverPerformance Foam::fvMatrix<Foam::scalar>::solveSegregated ( const dictionary& solverControls ) { if (debug) { Info.masterStream(this->mesh().comm()) << "fvMatrix<scalar>::solveSegregated" "(const dictionary& solverControls) : " "solving fvMatrix<scalar>" << endl; } GeometricField<scalar, fvPatchField, volMesh>& psi = const_cast<GeometricField<scalar, fvPatchField, volMesh>&>(psi_); scalarField saveDiag(diag()); addBoundaryDiag(diag(), 0); scalarField totalSource(source_); addBoundarySource(totalSource, false); // Solver call solverPerformance solverPerf = lduMatrix::solver::New ( psi.name(), *this, boundaryCoeffs_, internalCoeffs_, psi_.boundaryField().scalarInterfaces(), solverControls )->solve(psi.primitiveFieldRef(), totalSource); if (solverPerformance::debug) { solverPerf.print(Info.masterStream(mesh().comm())); } diag() = saveDiag; psi.correctBoundaryConditions(); psi.mesh().setSolverPerformance(psi.name(), solverPerf); return solverPerf; }
Foam::autoPtr<Foam::fvMatrix<Foam::scalar>::fvSolver> Foam::fvMatrix<Foam::scalar>::solver ( const dictionary& solverControls ) { if (debug) { Info.masterStream(this->mesh().comm()) << "fvMatrix<scalar>::solver(const dictionary& solverControls) : " "solver for fvMatrix<scalar>" << endl; } scalarField saveDiag(diag()); addBoundaryDiag(diag(), 0); autoPtr<fvMatrix<scalar>::fvSolver> solverPtr ( new fvMatrix<scalar>::fvSolver ( *this, lduMatrix::solver::New ( psi_.name(), *this, boundaryCoeffs_, internalCoeffs_, psi_.boundaryField().scalarInterfaces(), solverControls ) ) ); diag() = saveDiag; return solverPtr; }
Foam::solverPerformance Foam::fvMatrix<Foam::scalar>::fvSolver::solve ( const dictionary& solverControls ) { GeometricField<scalar, fvPatchField, volMesh>& psi = const_cast<GeometricField<scalar, fvPatchField, volMesh>&> (fvMat_.psi()); scalarField saveDiag(fvMat_.diag()); fvMat_.addBoundaryDiag(fvMat_.diag(), 0); scalarField totalSource(fvMat_.source()); fvMat_.addBoundarySource(totalSource, false); // assign new solver controls solver_->read(solverControls); solverPerformance solverPerf = solver_->solve ( psi.primitiveFieldRef(), totalSource ); if (solverPerformance::debug) { solverPerf.print(Info.masterStream(fvMat_.mesh().comm())); } fvMat_.diag() = saveDiag; psi.correctBoundaryConditions(); psi.mesh().setSolverPerformance(psi.name(), solverPerf); return solverPerf; }
Foam::SolverPerformance<Type> Foam::fvMatrix<Type>::solveSegregated ( const dictionary& solverControls ) { if (debug) { Info.masterStream(this->mesh().comm()) << "fvMatrix<Type>::solveSegregated" "(const dictionary& solverControls) : " "solving fvMatrix<Type>" << endl; } GeometricField<Type, fvPatchField, volMesh>& psi = const_cast<GeometricField<Type, fvPatchField, volMesh>&>(psi_); SolverPerformance<Type> solverPerfVec ( "fvMatrix<Type>::solveSegregated", psi.name() ); scalarField saveDiag(diag()); Field<Type> source(source_); // At this point include the boundary source from the coupled boundaries. // This is corrected for the implict part by updateMatrixInterfaces within // the component loop. addBoundarySource(source); typename Type::labelType validComponents ( psi.mesh().template validComponents<Type>() ); for (direction cmpt=0; cmpt<Type::nComponents; cmpt++) { if (validComponents[cmpt] == -1) continue; // copy field and source scalarField psiCmpt(psi.internalField().component(cmpt)); addBoundaryDiag(diag(), cmpt); scalarField sourceCmpt(source.component(cmpt)); FieldField<Field, scalar> bouCoeffsCmpt ( boundaryCoeffs_.component(cmpt) ); FieldField<Field, scalar> intCoeffsCmpt ( internalCoeffs_.component(cmpt) ); lduInterfaceFieldPtrsList interfaces = psi.boundaryField().scalarInterfaces(); // Use the initMatrixInterfaces and updateMatrixInterfaces to correct // bouCoeffsCmpt for the explicit part of the coupled boundary // conditions initMatrixInterfaces ( bouCoeffsCmpt, interfaces, psiCmpt, sourceCmpt, cmpt ); updateMatrixInterfaces ( bouCoeffsCmpt, interfaces, psiCmpt, sourceCmpt, cmpt ); solverPerformance solverPerf; // Solver call solverPerf = lduMatrix::solver::New ( psi.name() + pTraits<Type>::componentNames[cmpt], *this, bouCoeffsCmpt, intCoeffsCmpt, interfaces, solverControls )->solve(psiCmpt, sourceCmpt, cmpt); if (SolverPerformance<Type>::debug) { solverPerf.print(Info.masterStream(this->mesh().comm())); } solverPerfVec.replace(cmpt, solverPerf); psi.internalField().replace(cmpt, psiCmpt); diag() = saveDiag; } psi.correctBoundaryConditions(); psi.mesh().setSolverPerformance(psi.name(), solverPerfVec); return solverPerfVec; }
void fvBlockMatrix<Type>::insertDiagSource ( const direction dir, fvMatrix<matrixType>& matrix ) { matrix.completeAssembly(); // Save a copy for different components scalarField& diag = matrix.diag(); scalarField saveDiag(diag); // Add source boundary contribution Field<matrixType>& source = matrix.source(); matrix.addBoundarySource(source, false); const direction nCmpts = pTraits<matrixType>::nComponents; direction localDir = dir; // Get reference to this source field of block system Field<Type>& b = this->source(); if ( // This is needed if the matrixType is <vector>, then you need to grab // coeffs as linear. Consider doing a matrixType check also. // VV, 17/March/2014 this->diag().activeType() != blockCoeffBase::SQUARE ) { typename CoeffField<Type>::linearTypeField& blockDiag = this->diag().asLinear(); for (direction cmptI = 0; cmptI < nCmpts; cmptI++) { matrix.addBoundaryDiag(diag, cmptI); scalarField sourceCmpt(source.component(cmptI)); // FieldField<Field, scalar> bouCoeffsCmpt // ( // matrix.boundaryCoeffs().component(cmptI) // ); // Possible problem for coupled non-aligned boundaries. // VV, 14/May/2014. // matrix.correctImplicitBoundarySource // ( // bouCoeffsCmpt, // sourceCmpt, // cmptI // ); forAll (diag, cellI) { blockDiag[cellI](localDir) = diag[cellI]; b[cellI](localDir) += sourceCmpt[cellI]; } localDir++; // Reset diagonal diag = saveDiag; }
coupledSolverPerformance coupledFvMatrix<scalar>::solve ( const dictionary& solverControls ) { if (debug) { InfoIn("coupledFvMatrix<Type>::solve(const dictionary)") << "solving coupledFvMatrix<Type>" << endl; } typedef FieldField<Field, scalar> scalarFieldField; PtrList<lduMatrix>& matrices = *this; // Make a copy of the diagonal and complete the source scalarFieldField saveDiag(this->size()); scalarFieldField psi(this->size()); FieldField<Field, scalar> source(this->size()); lduInterfaceFieldPtrsListList interfaces(this->size()); PtrList<FieldField<Field, scalar> > bouCoeffs(this->size()); PtrList<FieldField<Field, scalar> > intCoeffs(this->size()); // Prepare block solution forAll (matrices, rowI) { fvScalarMatrix& curMatrix = static_cast<fvScalarMatrix&>(matrices[rowI]); saveDiag.set(rowI, new scalarField(curMatrix.diag())); // HR 17/Feb/2013 // Need to be able to compare references to support hacks such as in jumpCyclic // psi.set(rowI, new scalarField(curMatrix.psi())); psi.set(rowI, &curMatrix.psi()); source.set(rowI, new scalarField(curMatrix.source())); curMatrix.addBoundarySource(source[rowI], 0); interfaces[rowI] = curMatrix.psi().boundaryField().interfaces(); curMatrix.addBoundaryDiag(curMatrix.diag(), 0); bouCoeffs.set ( rowI, new FieldField<Field, scalar> ( curMatrix.boundaryCoeffs() ) ); intCoeffs.set ( rowI, new FieldField<Field, scalar> ( curMatrix.internalCoeffs().component(0) ) ); }