void Foam::pamgPolicy::calcChild() { // Algorithm: // 1) Create temporary equation addressing using a double-pass algorithm. // to create the offset table. // 2) Loop through all equations and for each equation find the best fit // neighbour. If all neighbours are grouped, add equation to best group // Get addressing const label nEqns = matrix_.lduAddr().size(); const unallocLabelList& upperAddr = matrix_.lduAddr().upperAddr(); const unallocLabelList& lowerAddr = matrix_.lduAddr().lowerAddr(); // Get off-diagonal matrix coefficients const scalarField& upper = matrix_.upper(); // For each equation calculate coeffs labelList cols(upperAddr.size() + lowerAddr.size()); labelList rowOffsets(nEqns + 1); // Memory management { labelList nNbrs(nEqns, 0); forAll (upperAddr, coeffI) { nNbrs[upperAddr[coeffI]]++; } forAll (lowerAddr, coeffI) { nNbrs[lowerAddr[coeffI]]++; } rowOffsets[0] = 0; forAll (nNbrs, eqnI) { rowOffsets[eqnI + 1] = rowOffsets[eqnI] + nNbrs[eqnI]; } // Reset the list to use as counter nNbrs = 0; forAll (upperAddr, coeffI) { cols [ rowOffsets[upperAddr[coeffI]] + nNbrs[upperAddr[coeffI]] ] = coeffI; nNbrs[upperAddr[coeffI]]++; }
Foam::tmp<Foam::labelField> Foam::pairGAMGAgglomeration::agglomerate ( label& nCoarseCells, const lduAddressing& fineMatrixAddressing, const scalarField& faceWeights ) { const label nFineCells = fineMatrixAddressing.size(); const labelUList& upperAddr = fineMatrixAddressing.upperAddr(); const labelUList& lowerAddr = fineMatrixAddressing.lowerAddr(); // For each cell calculate faces labelList cellFaces(upperAddr.size() + lowerAddr.size()); labelList cellFaceOffsets(nFineCells + 1); // memory management { labelList nNbrs(nFineCells, 0); forAll(upperAddr, facei) { nNbrs[upperAddr[facei]]++; } forAll(lowerAddr, facei) { nNbrs[lowerAddr[facei]]++; } cellFaceOffsets[0] = 0; forAll(nNbrs, celli) { cellFaceOffsets[celli+1] = cellFaceOffsets[celli] + nNbrs[celli]; } // reset the whole list to use as counter nNbrs = 0; forAll(upperAddr, facei) { cellFaces [ cellFaceOffsets[upperAddr[facei]] + nNbrs[upperAddr[facei]] ] = facei; nNbrs[upperAddr[facei]]++; }
void Foam::MGridGenGAMGAgglomeration:: makeCompactCellFaceAddressingAndFaceWeights ( const lduAddressing& fineAddressing, List<idxtype>& cellCells, List<idxtype>& cellCellOffsets, const scalarField& magSi, List<scalar>& faceWeights ) { const label nFineCells = fineAddressing.size(); const label nFineFaces = fineAddressing.upperAddr().size(); const labelUList& upperAddr = fineAddressing.upperAddr(); const labelUList& lowerAddr = fineAddressing.lowerAddr(); // Number of neighbours for each cell labelList nNbrs(nFineCells, 0); forAll(upperAddr, facei) { nNbrs[upperAddr[facei]]++; } forAll(lowerAddr, facei) { nNbrs[lowerAddr[facei]]++; } // Set the sizes of the addressing and faceWeights arrays cellCellOffsets.setSize(nFineCells + 1); cellCells.setSize(2*nFineFaces); faceWeights.setSize(2*nFineFaces); cellCellOffsets[0] = 0; forAll(nNbrs, celli) { cellCellOffsets[celli+1] = cellCellOffsets[celli] + nNbrs[celli]; }
Foam::labelListList Foam::GAMGProcAgglomeration::globalCellCells ( const lduMesh& mesh ) { const lduAddressing& addr = mesh.lduAddr(); lduInterfacePtrsList interfaces = mesh.interfaces(); const label myProcID = Pstream::myProcNo(mesh.comm()); globalIndex globalNumbering ( addr.size(), Pstream::msgType(), mesh.comm(), Pstream::parRun() ); labelList globalIndices ( identity ( globalNumbering.localSize(myProcID), globalNumbering.localStart(myProcID) ) ); // Get the interface cells PtrList<labelList> nbrGlobalCells(interfaces.size()); { // Initialise transfer of restrict addressing on the interface forAll(interfaces, inti) { if (interfaces.set(inti)) { interfaces[inti].initInternalFieldTransfer ( Pstream::commsTypes::nonBlocking, globalIndices ); } } if (Pstream::parRun()) { Pstream::waitRequests(); } forAll(interfaces, inti) { if (interfaces.set(inti)) { nbrGlobalCells.set ( inti, new labelList ( interfaces[inti].internalFieldTransfer ( Pstream::commsTypes::nonBlocking, globalIndices ) ) ); } } } // Scan the neighbour list to find out how many times the cell // appears as a neighbour of the face. Done this way to avoid guessing // and resizing list labelList nNbrs(addr.size(), 1); const labelUList& nbr = addr.upperAddr(); const labelUList& own = addr.lowerAddr(); { forAll(nbr, facei) { nNbrs[nbr[facei]]++; nNbrs[own[facei]]++; } forAll(interfaces, inti) { if (interfaces.set(inti)) { const labelUList& faceCells = interfaces[inti].faceCells(); forAll(faceCells, i) { nNbrs[faceCells[i]]++; } } } }
double getTPSAAtomContribs(const ROMol &mol, std::vector<double> &Vi, bool force) { TEST_ASSERT(Vi.size() >= mol.getNumAtoms()); double res = 0; if (!force && mol.hasProp(common_properties::_tpsaAtomContribs)) { mol.getProp(common_properties::_tpsaAtomContribs, Vi); mol.getProp(common_properties::_tpsa, res); return res; } unsigned int nAtoms = mol.getNumAtoms(); std::vector<int> nNbrs(nAtoms, 0), nSing(nAtoms, 0), nDoub(nAtoms, 0), nTrip(nAtoms, 0), nArom(nAtoms, 0), nHs(nAtoms, 0); for (ROMol::ConstBondIterator bIt = mol.beginBonds(); bIt != mol.endBonds(); ++bIt) { const Bond *bnd = (*bIt); if (bnd->getBeginAtom()->getAtomicNum() == 1) { nNbrs[bnd->getEndAtomIdx()] -= 1; nHs[bnd->getEndAtomIdx()] += 1; } else if (bnd->getEndAtom()->getAtomicNum() == 1) { nNbrs[bnd->getBeginAtomIdx()] -= 1; nHs[bnd->getBeginAtomIdx()] += 1; } else if (bnd->getIsAromatic()) { nArom[bnd->getBeginAtomIdx()] += 1; nArom[bnd->getEndAtomIdx()] += 1; } else { switch (bnd->getBondType()) { case Bond::SINGLE: nSing[bnd->getBeginAtomIdx()] += 1; nSing[bnd->getEndAtomIdx()] += 1; break; case Bond::DOUBLE: nDoub[bnd->getBeginAtomIdx()] += 1; nDoub[bnd->getEndAtomIdx()] += 1; break; case Bond::TRIPLE: nTrip[bnd->getBeginAtomIdx()] += 1; nTrip[bnd->getEndAtomIdx()] += 1; break; default: break; } } } for (unsigned int i = 0; i < nAtoms; ++i) { const Atom *atom = mol.getAtomWithIdx(i); int atNum = atom->getAtomicNum(); if (atNum != 7 && atNum != 8) continue; nHs[i] += atom->getTotalNumHs(); int chg = atom->getFormalCharge(); bool in3Ring = mol.getRingInfo()->isAtomInRingOfSize(i, 3); nNbrs[i] += atom->getDegree(); double tmp = -1; if (atNum == 7) { switch (nNbrs[i]) { case 1: if (nHs[i] == 0 && chg == 0 && nTrip[i] == 1) tmp = 23.79; else if (nHs[i] == 1 && chg == 0 && nDoub[i] == 1) tmp = 23.85; else if (nHs[i] == 2 && chg == 0 && nSing[i] == 1) tmp = 26.02; else if (nHs[i] == 2 && chg == 1 && nDoub[i] == 1) tmp = 25.59; else if (nHs[i] == 3 && chg == 1 && nSing[i] == 1) tmp = 27.64; break; case 2: if (nHs[i] == 0 && chg == 0 && nSing[i] == 1 && nDoub[i] == 1) tmp = 12.36; else if (nHs[i] == 0 && chg == 0 && nTrip[i] == 1 && nDoub[i] == 1) tmp = 13.60; else if (nHs[i] == 1 && chg == 0 && nSing[i] == 2 && in3Ring) tmp = 21.94; else if (nHs[i] == 1 && chg == 0 && nSing[i] == 2 && !in3Ring) tmp = 12.03; else if (nHs[i] == 0 && chg == 1 && nTrip[i] == 1 && nSing[i] == 1) tmp = 4.36; else if (nHs[i] == 1 && chg == 1 && nDoub[i] == 1 && nSing[i] == 1) tmp = 13.97; else if (nHs[i] == 2 && chg == 1 && nSing[i] == 2) tmp = 16.61; else if (nHs[i] == 0 && chg == 0 && nArom[i] == 2) tmp = 12.89; else if (nHs[i] == 1 && chg == 0 && nArom[i] == 2) tmp = 15.79; else if (nHs[i] == 1 && chg == 1 && nArom[i] == 2) tmp = 14.14; break; case 3: if (nHs[i] == 0 && chg == 0 && nSing[i] == 3 && in3Ring) tmp = 3.01; else if (nHs[i] == 0 && chg == 0 && nSing[i] == 3 && !in3Ring) tmp = 3.24; else if (nHs[i] == 0 && chg == 0 && nSing[i] == 1 && nDoub[i] == 2) tmp = 11.68; else if (nHs[i] == 0 && chg == 1 && nSing[i] == 2 && nDoub[i] == 1) tmp = 3.01; else if (nHs[i] == 1 && chg == 1 && nSing[i] == 3) tmp = 4.44; else if (nHs[i] == 0 && chg == 0 && nArom[i] == 3) tmp = 4.41; else if (nHs[i] == 0 && chg == 0 && nSing[i] == 1 && nArom[i] == 2) tmp = 4.93; else if (nHs[i] == 0 && chg == 0 && nDoub[i] == 1 && nArom[i] == 2) tmp = 8.39; else if (nHs[i] == 0 && chg == 1 && nArom[i] == 3) tmp = 4.10; else if (nHs[i] == 0 && chg == 1 && nSing[i] == 1 && nArom[i] == 2) tmp = 3.88; break; case 4: if (nHs[i] == 0 && nSing[i] == 4 && chg == 1) tmp = 0.0; break; } if (tmp < 0.0) { tmp = 30.5 - nNbrs[i] * 8.2 + nHs[i] * 1.5; if (tmp < 0) tmp = 0.0; } } else if (atNum == 8) { switch (nNbrs[i]) { case 1: if (nHs[i] == 0 && chg == 0 && nDoub[i] == 1) tmp = 17.07; else if (nHs[i] == 1 && chg == 0 && nSing[i] == 1) tmp = 20.23; else if (nHs[i] == 0 && chg == -1 && nSing[i] == 1) tmp = 23.06; break; case 2: if (nHs[i] == 0 && chg == 0 && nSing[i] == 2 && in3Ring) tmp = 12.53; else if (nHs[i] == 0 && chg == 0 && nSing[i] == 2 && !in3Ring) tmp = 9.23; else if (nHs[i] == 0 && chg == 0 && nArom[i] == 2) tmp = 13.14; break; } if (tmp < 0.0) { tmp = 28.5 - nNbrs[i] * 8.6 + nHs[i] * 1.5; if (tmp < 0) tmp = 0.0; } } Vi[i] = tmp; res += tmp; } mol.setProp(common_properties::_tpsaAtomContribs, Vi, true); mol.setProp(common_properties::_tpsa, res, true); return res; }