Foam::lduMatrix::solverPerformance Foam::fvMatrix<Type>::solve ( const dictionary& solverControls ) { if (debug) { Info<< "fvMatrix<Type>::solve(const dictionary&) : " "solving fvMatrix<Type>" << endl; } lduSolverPerformance solverPerfVec ( "fvMatrix<Type>::solve", 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 implicit part by updateMatrixInterfaces within // the component loop. addBoundarySource(source); typename Type::labelType validComponents ( pow ( psi_.mesh().solutionD(), pTraits<typename powProduct<Vector<label>, Type::rank>::type>::zero ) ); // Make a copy of interfaces: no longer a reference // HJ, 20/Nov/2007 lduInterfaceFieldPtrsList interfaces = psi_.boundaryField().interfaces(); 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) ); // 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 ); lduMatrix::solverPerformance solverPerf; // Solver call solverPerf = lduMatrix::solver::New ( psi_.name() + pTraits<Type>::componentNames[cmpt], *this, bouCoeffsCmpt, intCoeffsCmpt, interfaces, solverControls )->solve(psiCmpt, sourceCmpt, cmpt); solverPerf.print(); if ( solverPerf.initialResidual() > solverPerfVec.initialResidual() && !solverPerf.singular() ) { solverPerfVec = solverPerf; } psi_.internalField().replace(cmpt, psiCmpt); diag() = saveDiag; } psi_.correctBoundaryConditions(); return solverPerfVec; }
Foam::lduMatrix::solverPerformance Foam::fvMatrix<Type>::solve ( const dictionary& solverControls ) { profilingTrigger profSolve("fvMatrix::solve_" + psi_.name()); if (debug) { Info<< "fvMatrix<Type>::solve(const dictionary&) : " "solving fvMatrix<Type>" << endl; } // Complete matrix assembly. HJ, 17/Apr/2012 this->completeAssembly(); lduSolverPerformance solverPerfVec ( "fvMatrix<Type>::solve", 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 implicit part by correctCmptBoundarySource // within the component loop. // Note: this is related to non-parallel coupled implicit boundaries // such as cyclic or cyclicGGI, which include transformation. // See also correctImplicitBoundarySource below. // HJ, 31/May/2013 addBoundarySource(source); typename Type::labelType validComponents ( pow ( psi_.mesh().solutionD(), pTraits<typename powProduct<Vector<label>, Type::rank>::type>::zero ) ); // Make a copy of interfaces: no longer a reference // HJ, 20/Nov/2007 lduInterfaceFieldPtrsList interfaces = psi_.boundaryField().interfaces(); 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) ); // Correct component boundary source for the explicit part of the // coupled boundary conditions. At the moment, the whole // coefficient-field product hass been added into the source, // but the implicit part for the current element needs to be taken out // (because it is implicit). // HJ, 31/May/2013 correctImplicitBoundarySource ( bouCoeffsCmpt, sourceCmpt, cmpt ); lduMatrix::solverPerformance solverPerf; // Solver call solverPerf = lduMatrix::solver::New ( psi_.name() + pTraits<Type>::componentNames[cmpt], *this, bouCoeffsCmpt, intCoeffsCmpt, interfaces, solverControls )->solve(psiCmpt, sourceCmpt, cmpt); solverPerf.print(); if ( solverPerf.initialResidual() > solverPerfVec.initialResidual() && !solverPerf.singular() ) { solverPerfVec = solverPerf; } psi_.internalField().replace(cmpt, psiCmpt); diag() = saveDiag; } psi_.correctBoundaryConditions(); return solverPerfVec; }
Foam::solverPerformance Foam::fvMatrix<Type>::solveSegregated ( const dictionary& solverControls ) { if (debug) { Info<< "fvMatrix<Type>::solveSegregated" "(const dictionary& solverControls) : " "solving fvMatrix<Type>" << endl; } GeometricField<Type, fvPatchField, volMesh>& psi = const_cast<GeometricField<Type, fvPatchField, volMesh>&>(psi_); solverPerformance 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 ( pow ( psi.mesh().solutionD(), pTraits<typename powProduct<Vector<label>, Type::rank>::type>::zero ) ); 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); solverPerf.print(Info); solverPerfVec = max(solverPerfVec, solverPerf); solverPerfVec.solverName() = solverPerf.solverName(); psi.internalField().replace(cmpt, psiCmpt); diag() = saveDiag; } psi.correctBoundaryConditions(); psi.mesh().setSolverPerformance(psi.name(), solverPerfVec); return solverPerfVec; }