vtkPolyData* Foam::vtkPV4Foam::lagrangianVTKMesh ( const fvMesh& mesh, const word& cloudName ) { vtkPolyData* vtkmesh = NULL; if (debug) { Info<< "<beg> Foam::vtkPV4Foam::lagrangianVTKMesh - timePath " << mesh.time().timePath()/cloud::prefix/cloudName << endl; printMemory(); } // the region name is already in the mesh db IOobjectList sprayObjs ( mesh, mesh.time().timeName(), cloud::prefix/cloudName ); IOobject* positionsPtr = sprayObjs.lookup(word("positions")); if (positionsPtr) { Cloud<passiveParticle> parcels(mesh, cloudName, false); if (debug) { Info<< "cloud with " << parcels.size() << " parcels" << endl; } vtkmesh = vtkPolyData::New(); vtkPoints* vtkpoints = vtkPoints::New(); vtkCellArray* vtkcells = vtkCellArray::New(); vtkpoints->Allocate(parcels.size()); vtkcells->Allocate(parcels.size()); vtkIdType particleId = 0; forAllConstIter(Cloud<passiveParticle>, parcels, iter) { vtkInsertNextOpenFOAMPoint(vtkpoints, iter().position()); vtkcells->InsertNextCell(1, &particleId); particleId++; } vtkmesh->SetPoints(vtkpoints); vtkpoints->Delete(); vtkmesh->SetVerts(vtkcells); vtkcells->Delete(); }
void mapLagrangian(const meshToMesh& interp) { // Determine which particles are in meshTarget // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ const polyMesh& meshSource = interp.srcRegion(); const polyMesh& meshTarget = interp.tgtRegion(); const labelListList& sourceToTarget = interp.srcToTgtCellAddr(); const pointField& targetCc = meshTarget.cellCentres(); fileNameList cloudDirs ( readDir ( meshSource.time().timePath()/cloud::prefix, fileName::DIRECTORY ) ); forAll(cloudDirs, cloudI) { // Search for list of lagrangian objects for this time IOobjectList objects ( meshSource, meshSource.time().timeName(), cloud::prefix/cloudDirs[cloudI] ); IOobject* positionsPtr = objects.lookup(word("positions")); if (positionsPtr) { Info<< nl << " processing cloud " << cloudDirs[cloudI] << endl; // Read positions & cell passiveParticleCloud sourceParcels ( meshSource, cloudDirs[cloudI], false ); Info<< " read " << sourceParcels.size() << " parcels from source mesh." << endl; // Construct empty target cloud passiveParticleCloud targetParcels ( meshTarget, cloudDirs[cloudI], IDLList<passiveParticle>() ); particle::TrackingData<passiveParticleCloud> td(targetParcels); label sourceParticleI = 0; // Indices of source particles that get added to targetParcels DynamicList<label> addParticles(sourceParcels.size()); // Unmapped particles labelHashSet unmappedSource(sourceParcels.size()); // Initial: track from fine-mesh cell centre to particle position // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // This requires there to be no boundary in the way. forAllConstIter(Cloud<passiveParticle>, sourceParcels, iter) { bool foundCell = false; // Assume that cell from read parcel is the correct one... if (iter().cell() >= 0) { const labelList& targetCells = sourceToTarget[iter().cell()]; // Particle probably in one of the targetcells. Try // all by tracking from their cell centre to the parcel // position. forAll(targetCells, i) { // Track from its cellcentre to position to make sure. autoPtr<passiveParticle> newPtr ( new passiveParticle ( meshTarget, targetCc[targetCells[i]], targetCells[i] ) ); passiveParticle& newP = newPtr(); label facei = newP.track(iter().position(), td); if (facei < 0 && newP.cell() >= 0) { // Hit position. foundCell = true; addParticles.append(sourceParticleI); targetParcels.addParticle(newPtr.ptr()); break; } } } if (!foundCell) { // Store for closer analysis unmappedSource.insert(sourceParticleI); } sourceParticleI++; }