示例#1
0
// FIND CELL
//-------------------------------------------------------------------------
Index RectilinearGrid::findCell(const Vector &point, int flags) const {

    const bool acceptGhost = flags&AcceptGhost;

    for (int c=0; c<3; ++c) {
        if (point[c] < m_coords[c][0])
            return InvalidIndex;
        if (point[c] > m_coords[c][m_numDivisions[c]-1])
            return InvalidIndex;
    }

    Index n[3] = {0, 0, 0};
    for (int c=0; c<3; ++c) {
        for (Index i=0; i<m_numDivisions[c]; ++i) {
            if (m_coords[c][i] >= point[c])
                break;
            n[c] = i;
        }
    }

    Index el = cellIndex(n, m_numDivisions);
    if (acceptGhost || !isGhostCell(el))
        return el;
    return InvalidIndex;

}
示例#2
0
// FIND CELL
//-------------------------------------------------------------------------
Index UniformGrid::findCell(const Vector &point, int flags) const {

    const bool acceptGhost = flags&AcceptGhost;

    for (int c=0; c<3; ++c) {
        if (point[c] < m_min[c])
            return InvalidIndex;
        if (point[c] > m_max[c])
            return InvalidIndex;
    }

    Index n[3];
    for (int c=0; c<3; ++c) {
        n[c] = (point[c]-m_min[c])/m_dist[c];
        if (n[c] >= m_numDivisions[c]-1)
            n[c] = m_numDivisions[c]-2;
    }

    Index el = cellIndex(n, m_numDivisions);
    assert(inside(el, point));
    if (acceptGhost || !isGhostCell(el))
        return el;
    return InvalidIndex;
}
示例#3
0
void
ExporterVTK<MeshType,N>::saveNodeData( typename timeset_type::step_ptrtype step, Iterator __var, Iterator en, vtkSmartPointer<vtkout_type> out ) const
{
    while ( __var != en )
    {
        if ( !__var->second.worldComm().isActive() ) return;

        /* handle faces data */
#if 0
        if ( boption( _name="exporter.ensightgold.save-face" ) )
        {
            BOOST_FOREACH( auto m, __mesh->markerNames() )
            {
                if ( m.second[1] != __mesh->nDim-1 )
                    continue;
                VLOG(1) << "writing face with marker " << m.first << " with id " << m.second[0];
                auto pairit = __mesh->facesWithMarker( m.second[0], this->worldComm().localRank() );
                auto fit = pairit.first;
                auto fen = pairit.second;

                Feel::detail::MeshPoints<float> mp( __mesh.get(), this->worldComm(), fit, fen, true, true, true );
                int __ne = std::distance( fit, fen );

                int nverts = fit->numLocalVertices;
                DVLOG(2) << "Faces : " << __ne << "\n";

                if( this->worldComm().isMasterRank() )
                {
                    size = sizeof(buffer);
                }
                else
                {
                    size = 0;
                }
                memset(buffer, '\0', sizeof(buffer));
                strcpy( buffer, "part" );
                MPI_File_write_ordered(fh, buffer, size, MPI_CHAR, &status);

                int32_t partid = m.second[0];
                if( this->worldComm().isMasterRank() )
                {
                    size = 1;
                }
                else
                {
                    size = 0;
                }
                MPI_File_write_ordered(fh, &partid, size, MPI_INT32_T, &status);

                if( this->worldComm().isMasterRank() )
                {
                    size = sizeof(buffer);
                }
                else
                {
                    size = 0;
                }
                memset(buffer, '\0', sizeof(buffer));
                strcpy( buffer, "coordinates" );
                MPI_File_write_ordered(fh, buffer, size, MPI_CHAR, &status);

                // write values
                fit = pairit.first;
                fen = pairit.second;

                uint16_type nComponents = __var->second.nComponents;
                if ( __var->second.is_vectorial )
                    nComponents = 3;

                int nfaces = mp.ids.size();
                std::vector<float> field( nComponents*nfaces, 0.0 );
                for( ; fit != fen; ++fit )
                {
                    for ( uint16_type c = 0; c < nComponents; ++c )
                    {
                        for ( size_type j = 0; j < nverts; j++ )
                        {
                            size_type pid = mp.old2new[fit->point( j ).id()]-1;
                            size_type global_node_id = nfaces*c + pid ;
                            if ( c < __var->second.nComponents )
                            {
                                size_type thedof =  __var->second.start() +
                                                    boost::get<0>(__var->second.functionSpace()->dof()->faceLocalToGlobal( fit->id(), j, c ));

                                field[global_node_id] = __var->second.globalValue( thedof );
                            }
                            else
                            {
                                field[global_node_id] = 0;
                            }
                        }
                    }
                }
                /* Write each component separately */
                for ( uint16_type c = 0; c < __var->second.nComponents; ++c )
                {
                    MPI_File_write_ordered(fh, field.data() + nfaces * c, nfaces, MPI_FLOAT, &status);
                }
            } // boundaries loop
        }
#endif
        /* handle elements */
        uint16_type nComponents = __var->second.nComponents;

        VLOG(1) << "nComponents field: " << nComponents;
        if ( __var->second.is_vectorial )
        {
            nComponents = 3;
            VLOG(1) << "nComponents field(is_vectorial): " << nComponents;
        }

        /* we get that from the local processor */
        /* We do not need the renumbered global index */
        //auto r = markedelements(__mesh, M_markersToWrite[i], EntityProcessType::ALL);
        auto r = elements( step->mesh() );
        auto elt_it = r.template get<1>();
        auto elt_en = r.template get<2>();

        Feel::detail::MeshPoints<float> mp( step->mesh().get(), this->worldComm(), elt_it, elt_en, false, true, true, 0 );

        // previous implementation
        //size_type __field_size = mp.ids.size();
        //int nelts = std::distance(elt_it, elt_en);
        int npts = mp.ids.size();
        size_type __field_size = npts;
        if ( __var->second.is_vectorial )
            __field_size *= 3;
        std::vector<float> __field( __field_size, 0.0 );
        size_type e = 0;
        VLOG(1) << "field size=" << __field_size;
        if ( !__var->second.areGlobalValuesUpdated() )
            __var->second.updateGlobalValues();

        vtkSmartPointer<vtkFloatArray> da = vtkSmartPointer<vtkFloatArray>::New();
        da->SetName(__var->first.c_str());

        /* set array parameters */
        /* no need for preallocation if we are using Insert* methods */
        da->SetNumberOfComponents(nComponents);
        da->SetNumberOfTuples(npts);

        /*
           std::cout << this->worldComm().rank() << " nbPts:" << npts << " nComp:" << nComponents
           << " __var->second.nComponents:" << __var->second.nComponents << std::endl;
        */

        /*
           std::cout << this->worldComm().rank() << " marker=" << *mit << " nbPts:" << npts << " nComp:" << nComponents
           << " __evar->second.nComponents:" << __var->second.nComponents << std::endl;
           */

        /* loop on the elements */
        int index = 0;
        for ( ; elt_it != elt_en; ++elt_it )
        {
            VLOG(3) << "is ghost cell " << elt_it->isGhostCell();
            /* looop on the ccomponents is outside of the loop on the vertices */
            for ( uint16_type c = 0; c < nComponents; ++c )
            {
                for ( uint16_type p = 0; p < step->mesh()->numLocalVertices(); ++p, ++e )
                {
                    size_type ptid = mp.old2new[elt_it->point( p ).id()];
                    size_type global_node_id = ptid * nComponents + c;
                    //size_type global_node_id = mp.ids.size()*c + ptid ;
                    //LOG(INFO) << elt_it->get().point( p ).id() << " " << ptid << " " << global_node_id << std::endl;
                    DCHECK( ptid < step->mesh()->numPoints() ) << "Invalid point id " << ptid << " element: " << elt_it->id()
                            << " local pt:" << p
                            << " mesh numPoints: " << step->mesh()->numPoints();
                    DCHECK( global_node_id < __field_size ) << "Invalid dof id : " << global_node_id << " max size : " << __field_size;

                    if ( c < __var->second.nComponents )
                    {
                        size_type dof_id = boost::get<0>( __var->second.functionSpace()->dof()->localToGlobal( elt_it->id(), p, c ) );

                        __field[global_node_id] = __var->second.globalValue( dof_id );
                        //__field[npts*c + index] = __var->second.globalValue( dof_id );
                        //DVLOG(3) << "v[" << global_node_id << "]=" << __var->second.globalValue( dof_id ) << "  dof_id:" << dof_id;
                        DVLOG(3) << "v[" << (npts*c + index) << "]=" << __var->second.globalValue( dof_id ) << "  dof_id:" << dof_id;
                    }
                    else
                    {
                        __field[global_node_id] = 0.0;
                        //__field[npts*c + index] = 0.0;
                    }
                }
            }

            /* increment index of vertex */
            index++;
        }

        /* insert data into array */
        for(int i = 0; i < npts; i++)
        {
            da->SetTuple(mp.ids[i], __field.data() + i * nComponents);
        }

        /* add data array into the vtk object */
        out->GetPointData()->AddArray(da);

        /* Set the first scalar/vector/tensor data, we process as active */
        if( __var->second.is_scalar && !(out->GetPointData()->GetScalars()))
        {
            out->GetPointData()->SetActiveScalars(da->GetName());
        }
        if( __var->second.is_vectorial && !(out->GetPointData()->GetVectors()))
        {
            out->GetPointData()->SetActiveVectors(da->GetName());
        }
        if( __var->second.is_tensor2 && !(out->GetPointData()->GetTensors()))
        {
            out->GetPointData()->SetActiveTensors(da->GetName());
        }

        DVLOG(2) << "[ExporterVTK::saveNodal] saving " << __var->first << "done\n";

        ++__var;
    }
}
示例#4
0
/******************************************************************************
* Generates the tessellation.
******************************************************************************/
bool DelaunayTessellation::generateTessellation(const SimulationCell& simCell, const Point3* positions, size_t numPoints, FloatType ghostLayerSize, FutureInterfaceBase* progress)
{
	if(progress) progress->setProgressRange(0);
	std::vector<DT::Point> cgalPoints;

	// Set up random number generator to generate random perturbations.
	std::mt19937 rng;
	rng.seed(1);
	std::uniform_real_distribution<double> displacement(-1e-8, +1e-8);

	// Insert the original points first.
	cgalPoints.reserve(numPoints);
	for(size_t i = 0; i < numPoints; i++, ++positions) {

		// Add a small random perturbation to the particle positions to make the Delaunay triangulation more robust
		// against singular input data, e.g. particles forming an ideal crystal lattice.
		Point3 wp = simCell.wrapPoint(*positions);
		double coords[3];
		coords[0] = (double)wp.x() + displacement(rng);
		coords[1] = (double)wp.y() + displacement(rng);
		coords[2] = (double)wp.z() + displacement(rng);

		cgalPoints.push_back(Point3WithIndex(coords[0], coords[1], coords[2], i, false));
	}

	int vertexCount = numPoints;

	Vector3I stencilCount;
	FloatType cuts[3][2];
	Vector3 cellNormals[3];
	for(size_t dim = 0; dim < 3; dim++) {
		cellNormals[dim] = simCell.cellNormalVector(dim);
		cuts[dim][0] = cellNormals[dim].dot(simCell.reducedToAbsolute(Point3(0,0,0)) - Point3::Origin());
		cuts[dim][1] = cellNormals[dim].dot(simCell.reducedToAbsolute(Point3(1,1,1)) - Point3::Origin());

		if(simCell.pbcFlags()[dim]) {
			stencilCount[dim] = (int)ceil(ghostLayerSize / simCell.matrix().column(dim).dot(cellNormals[dim]));
			cuts[dim][0] -= ghostLayerSize;
			cuts[dim][1] += ghostLayerSize;
		}
		else {
			stencilCount[dim] = 0;
			cuts[dim][0] -= ghostLayerSize;
			cuts[dim][1] += ghostLayerSize;
		}
	}

	// Create ghost images of input vertices.
	for(int ix = -stencilCount[0]; ix <= +stencilCount[0]; ix++) {
		for(int iy = -stencilCount[1]; iy <= +stencilCount[1]; iy++) {
			for(int iz = -stencilCount[2]; iz <= +stencilCount[2]; iz++) {
				if(ix == 0 && iy == 0 && iz == 0) continue;

				if(progress && progress->isCanceled())
					return false;

				Vector3 shift = simCell.reducedToAbsolute(Vector3(ix,iy,iz));
				Vector_3<double> shiftd = (Vector_3<double>)shift;
				for(int vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) {
					Point3 pimage = (Point3)cgalPoints[vertexIndex] + shift;
					bool isClipped = false;
					for(size_t dim = 0; dim < 3; dim++) {
						FloatType d = cellNormals[dim].dot(pimage - Point3::Origin());
						if(d < cuts[dim][0] || d > cuts[dim][1]) {
							isClipped = true;
							break;
						}
					}
					if(!isClipped) {
						cgalPoints.push_back(Point3WithIndex(cgalPoints[vertexIndex].x() + shift.x(),
								cgalPoints[vertexIndex].y() + shift.y(), cgalPoints[vertexIndex].z() + shift.z(), vertexIndex, true));
					}
				}
			}
		}
	}

	if(progress && progress->isCanceled())
		return false;

	CGAL::spatial_sort(cgalPoints.begin(), cgalPoints.end(), _dt.geom_traits());

	if(progress) {
		if(progress->isCanceled()) return false;
		progress->setProgressRange(cgalPoints.size());
		progress->setProgressValue(0);
	}

	DT::Vertex_handle hint;
	for(auto p = cgalPoints.begin(); p != cgalPoints.end(); ++p) {
		hint = _dt.insert(*p, hint);

		if(progress && ((p - cgalPoints.begin()) % 4096) == 0) {
			if(progress->isCanceled()) return false;
			progress->incrementProgressValue(4096);
		}
	}
	progress->setProgressValue(cgalPoints.size());

	// Classify tessellation cells as ghost or local cells.
	for(CellIterator cell = begin_cells(); cell != end_cells(); ++cell) {
		cell->info().isGhost = isGhostCell(cell);
	}

	return true;
}