tmp<scalarField> faMatrix<scalar>::residual() const { scalarField boundaryDiag(psi_.size(), 0.0); addBoundaryDiag(boundaryDiag, 0); // Make a copy of interfaces: no longer a reference // HJ, 20/Nov/2007 lduInterfaceFieldPtrsList interfaces = psi_.boundaryField().interfaces(); tmp<scalarField> tres ( lduMatrix::residual ( psi_.internalField(), source_ - boundaryDiag*psi_.internalField(), boundaryCoeffs_, interfaces, 0 ) ); addBoundarySource(tres()); return tres; }
Foam::SolverPerformance<Type> Foam::fvMatrix<Type>::solveCoupled ( const dictionary& solverControls ) { if (debug) { Info.masterStream(this->mesh().comm()) << "fvMatrix<Type>::solveCoupled" "(const dictionary& solverControls) : " "solving fvMatrix<Type>" << endl; } GeometricField<Type, fvPatchField, volMesh>& psi = const_cast<GeometricField<Type, fvPatchField, volMesh>&>(psi_); LduMatrix<Type, scalar, scalar> coupledMatrix(psi.mesh()); coupledMatrix.diag() = diag(); coupledMatrix.upper() = upper(); coupledMatrix.lower() = lower(); coupledMatrix.source() = source(); addBoundaryDiag(coupledMatrix.diag(), 0); addBoundarySource(coupledMatrix.source(), false); coupledMatrix.interfaces() = psi.boundaryField().interfaces(); coupledMatrix.interfacesUpper() = boundaryCoeffs().component(0); coupledMatrix.interfacesLower() = internalCoeffs().component(0); autoPtr<typename LduMatrix<Type, scalar, scalar>::solver> coupledMatrixSolver ( LduMatrix<Type, scalar, scalar>::solver::New ( psi.name(), coupledMatrix, solverControls ) ); SolverPerformance<Type> solverPerf ( coupledMatrixSolver->solve(psi) ); if (SolverPerformance<Type>::debug) { solverPerf.print(Info.masterStream(this->mesh().comm())); } psi.correctBoundaryConditions(); psi.mesh().setSolverPerformance(psi.name(), solverPerf); return solverPerf; }
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::tmp<Foam::Field<Type> > Foam::fvMatrix<Type>::residual() const { // Complete matrix assembly. HJ, 17/Apr/2012 fvMatrix& m = const_cast<fvMatrix&>(*this); m.completeAssembly(); // Bug fix: Creating a tmp out of a const reference will change the field // HJ, 15/Apr/2011 tmp<Field<Type> > tres(new Field<Type>(source_)); Field<Type>& res = tres(); addBoundarySource(res); // Make a copy of interfaces: no longer a reference // HJ, 20/Nov/2007 lduInterfaceFieldPtrsList interfaces = psi_.boundaryField().interfaces(); // Loop over field components for (direction cmpt = 0; cmpt < Type::nComponents; cmpt++) { scalarField psiCmpt = psi_.internalField().component(cmpt); scalarField boundaryDiagCmpt(psi_.size(), 0); addBoundaryDiag(boundaryDiagCmpt, cmpt); FieldField<Field, scalar> bouCoeffsCmpt ( boundaryCoeffs_.component(cmpt) ); res.replace ( cmpt, lduMatrix::residual ( psiCmpt, res.component(cmpt) - boundaryDiagCmpt*psiCmpt, bouCoeffsCmpt, interfaces, cmpt ) ); } return tres; }
lduSolverPerformance faMatrix<scalar>::solve ( const dictionary& solverControls ) { if (debug) { Info<< "faMatrix<scalar>::solve(const dictionary&) : " "solving faMatrix<scalar>" << endl; } scalarField saveDiag = diag(); addBoundaryDiag(diag(), 0); scalarField totalSource = source_; addBoundarySource(totalSource, 0); // Make a copy of interfaces: no longer a reference // HJ, 20/Nov/2007 lduInterfaceFieldPtrsList interfaces = psi_.boundaryField().interfaces(); // Solver call lduSolverPerformance solverPerf = lduSolver::New ( psi_.name(), *this, boundaryCoeffs_, internalCoeffs_, interfaces, solverControls )->solve(psi_.internalField(), totalSource); solverPerf.print(); diag() = saveDiag; psi_.correctBoundaryConditions(); return solverPerf; }
Foam::tmp<Foam::scalarField> Foam::fvMatrix<Foam::scalar>::residual() const { scalarField boundaryDiag(psi_.size(), 0.0); addBoundaryDiag(boundaryDiag, 0); tmp<scalarField> tres ( lduMatrix::residual ( psi_.primitiveField(), source_ - boundaryDiag*psi_.primitiveField(), boundaryCoeffs_, psi_.boundaryField().scalarInterfaces(), 0 ) ); addBoundarySource(tres.ref()); return tres; }
autoPtr<faMatrix<scalar>::faSolver> faMatrix<scalar>::solver ( const dictionary& solverControls ) { if (debug) { Info<< "faMatrix<scalar>::solver(const dictionary&) : " "solver for faMatrix<scalar>" << endl; } scalarField saveDiag = diag(); addBoundaryDiag(diag(), 0); // Make a copy of interfaces: no longer a reference // HJ, 20/Nov/2007 lduInterfaceFieldPtrsList interfaces = psi_.boundaryField().interfaces(); autoPtr<faMatrix<scalar>::faSolver> solverPtr ( new faMatrix<scalar>::faSolver ( *this, lduSolver::New ( psi_.name(), *this, boundaryCoeffs_, internalCoeffs_, interfaces, solverControls ) ) ); diag() = saveDiag; return solverPtr; }
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::tmp<Foam::Field<Type>> Foam::fvMatrix<Type>::residual() const { tmp<Field<Type>> tres(new Field<Type>(source_)); Field<Type>& res = tres(); addBoundarySource(res); // Loop over field components for (direction cmpt=0; cmpt<Type::nComponents; cmpt++) { scalarField psiCmpt(psi_.internalField().component(cmpt)); scalarField boundaryDiagCmpt(psi_.size(), 0.0); addBoundaryDiag(boundaryDiagCmpt, cmpt); FieldField<Field, scalar> bouCoeffsCmpt ( boundaryCoeffs_.component(cmpt) ); res.replace ( cmpt, lduMatrix::residual ( psiCmpt, res.component(cmpt) - boundaryDiagCmpt*psiCmpt, bouCoeffsCmpt, psi_.boundaryField().scalarInterfaces(), cmpt ) ); } return tres; }
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<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; }
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; }