*/
unsigned int memory_consumption () const;
+ /**
+ * Value for no neighbor.
+ */
+ static const unsigned int no_neighbor = static_cast<unsigned int>(-1);
+
/**
* Exception
*/
*/
struct DXFlags
{
- private:
/**
- * Dummy entry to suppress compiler
- * warnings when copying an empty
- * structure. Remove this member
- * when adding the first flag to
- * this structure (and remove the
- * @p{private} as well).
+ * Write in multigrid format.
+ * This will be necessary to
+ * get streamlines right on
+ * locally refined grids.
*/
- int dummy;
-
- public:
+ bool write_multigrid;
+ /**
+ * Write neighbor information.
+ */
+ bool write_neighbors;
+ /**
+ * Constructor.
+ */
+ DXFlags (const bool write_multigrid = false,
+ const bool write_neighbors = false);
+public:
/**
* Declare all flags with name
* and type as offered by this
static void
write_gmv_reorder_data_vectors (const typename std::vector<Patch<dim,spacedim> > &patches,
std::vector<std::vector<double> > &data_vectors);
+
};
template <int dim, int spacedim>
DataOutBase::Patch<dim,spacedim>::Patch () :
+ me(no_neighbor),
n_subdivisions (1)
+
// all the other data has a
// constructor of its own
{
+ for (unsigned int i=0;i<GeometryInfo<dim>::faces_per_cell;++i)
+ neighbors[i] = no_neighbor;
+
Assert (dim<=spacedim, ExcInvalidCombinationOfDimensions(dim,spacedim));
Assert (spacedim<=3, ExcNotImplemented());
};
template <int dim, int spacedim>
void DataOutBase::write_dx (const typename std::vector<Patch<dim,spacedim> > &patches,
const std::vector<std::string> &data_names,
- const DXFlags &/*flags*/,
+ const DXFlags &flags,
std::ostream &out)
{
AssertThrow (out, ExcIO());
Assert (false, ExcNotImplemented());
};
- // start with vertices
- out << "object 1 class array type float rank 1 shape " << spacedim << " items " << n_nodes << " data follows"
+ // start with vertices order is
+ // lexicographical, x varying
+ // fastest
+ out << "object \"vertices\" class array type float rank 1 shape " << spacedim << " items " << n_nodes << " data follows"
<< std::endl;
///////////////////////////////
/////////////////////////////////////////
// write cells
- out << "object 2 class array type int rank 1 shape " << GeometryInfo<dim>::vertices_per_cell
+ out << "object \"cells\" class array type int rank 1 shape " << GeometryInfo<dim>::vertices_per_cell
<< " items " << n_cells << " data follows"
<< std::endl;
for (unsigned int j=0; j<n_subdivisions; ++j)
{
out << first_vertex_of_patch+i*(n_subdivisions+1)+j << '\t'
- << first_vertex_of_patch+(i+1)*(n_subdivisions+1)+j << '\t'
<< first_vertex_of_patch+i*(n_subdivisions+1)+j+1 << '\t'
+ << first_vertex_of_patch+(i+1)*(n_subdivisions+1)+j << '\t'
<< first_vertex_of_patch+(i+1)*(n_subdivisions+1)+j+1
<< std::endl;
};
if (dim==3) out << "cubes";
out << "\"" << std::endl
<< "attribute \"ref\" string \"positions\"" << std::endl;
-
+
+//TODO:[GK] Patches must be of same size!
+ /////////////////////////////
+ // write neighbor information
+ if (flags.write_neighbors)
+ {
+ out << "object \"neighbors\" class array type int rank 1 shape "
+ << GeometryInfo<dim>::faces_per_cell
+ << " items " << n_cells
+ << " data follows";
+
+ for (typename std::vector<Patch<dim,spacedim> >::const_iterator
+ patch=patches.begin();
+ patch!=patches.end(); ++patch)
+ {
+ const unsigned int n = patch->n_subdivisions;
+ const unsigned int cells_per_patch
+ = n
+ * ((dim>1) ? n : 1)
+ * ((dim>2) ? n : 1);
+ const unsigned int patch_start = patch->me * cells_per_patch;
+
+ for (unsigned int ix=0;ix<n;++ix)
+ for (unsigned int iy=0;iy<((dim>1) ? n : 1);++iy)
+ for (unsigned int iz=0;iz<((dim>2) ? n : 1);++iz)
+ {
+ const unsigned int nx = ix*n;
+ const unsigned int ny = iy;
+ const unsigned int nz = iz*n*n;
+
+ out << std::endl;
+ // Direction -x
+ // Last cell in row
+ // of other patch
+ if (ix==0)
+ {
+ const unsigned int nn = patch->neighbors[0];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+ny+nz+n*(n-1));
+ else
+ out << "-1";
+ } else {
+ out << '\t'
+ << patch_start+nx-n+ny+nz;
+ }
+ // Direction +x
+ // First cell in row
+ // of other patch
+ if (ix == n-1)
+ {
+ const unsigned int nn = patch->neighbors[1];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+ny+nz);
+ else
+ out << "-1";
+ } else {
+ out << '\t'
+ << patch_start+nx+n+ny+nz;
+ }
+ if (dim<2)
+ continue;
+ // Direction -y
+ if (iy==0)
+ {
+ const unsigned int nn = patch->neighbors[2];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+nx+nz+1*(n-1));
+ else
+ out << "-1";
+ } else {
+ out << '\t'
+ << patch_start+nx+ny-1+nz;
+ }
+ // Direction +y
+ if (iy == n-1)
+ {
+ const unsigned int nn = patch->neighbors[3];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+nx+nz);
+ else
+ out << "-1";
+ } else {
+ out << '\t'
+ << patch_start+nx+ny+1+nz;
+ }
+ if (dim<3)
+ continue;
+
+ // Direction -z
+ if (iz==0)
+ {
+ const unsigned int nn = patch->neighbors[4];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+nx+ny+n*n*(n-1));
+ else
+ out << "-1";
+ } else {
+ out << '\t'
+ << patch_start+nx+ny+nz-n*n;
+ }
+ // Direction +z
+ if (iz == n-1)
+ {
+ const unsigned int nn = patch->neighbors[4];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+nx+ny);
+ else
+ out << "-1";
+ } else {
+ out << '\t'
+ << patch_start+nx+ny+nz+n*n;
+ }
+ }
+ out << std::endl;
+ }
+ }
/////////////////////////////
// now write data
if (n_data_sets != 0)
{
- out << "object 3 class array type float rank 1 shape " << n_data_sets
+ out << "object \"data\" class array type float rank 1 shape "
+ << n_data_sets
<< " items " << n_nodes << " data follows" << std::endl;
// loop over all patches
};
out << "attribute \"dep\" string \"positions\"" << std::endl;
} else {
- out << "object 3 class constantarray type float rank 0 items " << n_nodes << " data follows"
+ out << "object \"data\" class constantarray type float rank 0 items " << n_nodes << " data follows"
<< std::endl << '0' << std::endl;
}
// no model data
out << "object \"deal data\" class field" << std::endl
- << "component \"positions\" value 1" << std::endl
- << "component \"connections\" value 2" << std::endl
- << "component \"data\" value 3" << std::endl;
+ << "component \"positions\" value \"vertices\"" << std::endl
+ << "component \"connections\" value \"cells\"" << std::endl
+ << "component \"data\" value \"data\"" << std::endl;
+
+ if (flags.write_neighbors)
+ out << "component \"neighbors\" value \"neighbors\"" << std::endl;
if (true)
{
for (;cell != dofs->end();)
{
Assert (patch != patches.end(), ExcInternalError());
+
+ // Insert cell-patch pair into
+ // map for neighbors
+ data.patch_map->insert(typename PatchMap::value_type(cell, patch));
for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
patch->vertices[vertex] = cell->vertex(vertex);
// clear the patches array
if (true)
{
- std::vector<DataOutBase::Patch<dim> > dummy;
+ typename std::vector<DataOutBase::Patch<dim> > dummy;
patches.swap (dummy);
};
cell = next_cell(cell))
++n_patches;
+
+ PatchMap patch_map;
+
std::vector<Data> thread_data(n_threads);
// init data for the threads
thread_data[i].n_components = n_components;
thread_data[i].n_datasets = n_datasets;
thread_data[i].n_subdivisions = n_subdivisions;
+ thread_data[i].patch_map = &patch_map;
thread_data[i].patch_values.resize (n_q_points);
thread_data[i].patch_values_system.resize (n_q_points);
#else
build_some_patches(thread_data[0]);
#endif
+//TODO: New code for neighbors: Parallelize?
+
+ // First, number patches
+ // consecutively.
+ unsigned int patch_no = 0;
+ typename std::vector<typename DataOutBase::Patch<dim> >::iterator patch;
+ for (patch = patches.begin(); patch != patches.end(); ++patch)
+ patch->me = patch_no++;
+
+ // Traverse the map of cells
+ // created in build_some_patches
+ // and enter numbers of neighboring
+ // patches on the same level.
+ typename PatchMap::iterator map_entry;
+ for (map_entry = patch_map.begin(); map_entry != patch_map.end(); ++map_entry)
+ {
+ typename DoFHandler<dim>::cell_iterator cell = map_entry->first;
+ patch = map_entry->second;
+
+ for (unsigned int i=0;i<GeometryInfo<dim>::faces_per_cell;++i)
+ {
+ if (cell->at_boundary(i))
+ continue;
+ typename DoFHandler<dim>::cell_iterator
+ neighbor = cell->neighbor(i);
+ if (cell->level() != neighbor->level())
+ continue;
+ typename PatchMap::iterator
+ neighbor_entry = patch_map.find(neighbor);
+ if (neighbor_entry == patch_map.end())
+ continue;
+ typename std::vector<typename DataOutBase::Patch<dim> >::iterator
+ neighbor_patch = neighbor_entry->second;
+
+ switch (dim)
+ {
+ case 2:
+ switch (i)
+ {
+ case 0: patch->neighbors[2] = neighbor_patch->me; break;
+ case 1: patch->neighbors[1] = neighbor_patch->me; break;
+ case 2: patch->neighbors[3] = neighbor_patch->me; break;
+ case 3: patch->neighbors[0] = neighbor_patch->me; break;
+ }
+ break;
+ case 3:
+ switch (i)
+ {
+ case 0: patch->neighbors[2] = neighbor_patch->me; break;
+ case 1: patch->neighbors[3] = neighbor_patch->me; break;
+ case 2: patch->neighbors[4] = neighbor_patch->me; break;
+ case 3: patch->neighbors[1] = neighbor_patch->me; break;
+ case 4: patch->neighbors[5] = neighbor_patch->me; break;
+ case 5: patch->neighbors[0] = neighbor_patch->me; break;
+ }
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
+ }
+ }
};