Reduced Lagrange Multipliers
 
Loading...
Searching...
No Matches
vtk_utils.h
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2024 by Luca Heltai
4//
5// This file is part of the reduced_lagrange_multipliers application, based on
6// the deal.II library.
7//
8// The reduced_lagrange_multipliers application is free software; you can use
9// it, redistribute it, and/or modify it under the terms of the Apache-2.0
10// License WITH LLVM-exception as published by the Free Software Foundation;
11// either version 3.0 of the License, or (at your option) any later version. The
12// full text of the license can be found in the file LICENSE.md at the top level
13// of the reduced_lagrange_multipliers distribution.
14//
15// ---------------------------------------------------------------------
16
17#ifndef rdl_vtk_utils_h
18#define rdl_vtk_utils_h
19
20#include <deal.II/base/config.h>
21
22#include <deal.II/base/mpi.h>
23#include <deal.II/base/point.h>
24
26
29
30#include <deal.II/fe/fe_q.h>
33
35#include <deal.II/grid/tria.h>
36
38#include <deal.II/lac/vector.h>
39
40#include <iostream>
41#include <map>
42#include <unordered_map>
43
44
45#ifdef DEAL_II_WITH_VTK
46
47# include <deal.II/grid/tria.h>
48
50# include <deal.II/lac/vector.h>
51
52using namespace dealii;
53
54namespace VTKUtils
79{
91 template <int dim, int spacedim>
92 void
93 read_vtk(const std::string &vtk_filename,
94 Triangulation<dim, spacedim> &tria,
95 const bool cleanup = true);
96
110 void
111 read_cell_data(const std::string &vtk_filename,
112 const std::string &cell_data_name,
113 Vector<double> &output_vector);
114
125 void
126 read_vertex_data(const std::string &vtk_filename,
127 const std::string &vertex_data_name,
128 Vector<double> &output_vector);
129
130
152 void
153 read_data(const std::string &vtk_filename, Vector<double> &output_vector);
154
171 template <int dim, int spacedim>
172 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>,
173 std::vector<std::string>>
174 vtk_to_finite_element(const std::string &vtk_filename);
175
191 template <int dim, int spacedim>
192 BlockIndices
193 get_block_indices(const FiniteElement<dim, spacedim> &fe);
194
214 template <int dim, int spacedim, typename VectorType>
215 void
216 data_to_dealii_vector(const Triangulation<dim, spacedim> &serial_tria,
217 const Vector<double> &data,
218 const DoFHandler<dim, spacedim> &dh,
219 VectorType &output_vector);
220
221
240 template <int dim, int spacedim>
241 void
242 read_vtk(const std::string &vtk_filename,
243 DoFHandler<dim, spacedim> &dof_handler,
244 Vector<double> &output_vector,
245 std::vector<std::string> &data_names);
246
260 template <int dim, int spacedim>
261 void
262 serial_vector_to_distributed_vector(
263 const DoFHandler<dim, spacedim> &serial_dh,
264 const DoFHandler<dim, spacedim> &parallel_dh,
265 const Vector<double> &serial_vec,
266 LinearAlgebra::distributed::Vector<double> &parallel_vec);
267
268
283 template <int dim, int spacedim>
284 std::vector<types::global_vertex_index>
285 distributed_to_serial_vertex_indices(
286 const Triangulation<dim, spacedim> &serial_tria,
287 const Triangulation<dim, spacedim> &parallel_tria);
288
289# ifndef DOXYGEN
290 // Explicit implementation of template functions
291
292 template <int dim, int spacedim, typename VectorType>
293 void
294 data_to_dealii_vector(const Triangulation<dim, spacedim> &serial_tria,
295 const Vector<double> &data,
296 const DoFHandler<dim, spacedim> &dh,
297 VectorType &output_vector)
298 {
299 AssertDimension(dh.n_dofs(), output_vector.size());
300 const auto &fe = dh.get_fe();
301
302 const auto dist_to_serial_vertices =
303 distributed_to_serial_vertex_indices(serial_tria, dh.get_triangulation());
304
305 const auto &locally_owned_dofs = dh.locally_owned_dofs();
306
307 types::global_dof_index dofs_offset = 0;
308 unsigned int vertex_comp_offset = 0;
309 unsigned int cell_comp_offset = 0;
310 for (unsigned int field = 0; field < fe.n_blocks(); ++field)
311 {
312 const auto &field_fe = fe.base_element(field);
313 const unsigned int n_comps = field_fe.n_components();
314 if (field_fe.n_dofs_per_vertex() > 0)
315 {
316 // This is a vertex data field
317 const types::global_dof_index n_local_dofs =
318 n_comps * serial_tria.n_vertices();
319 for (const auto &cell : dh.active_cell_iterators())
320 if (cell->is_locally_owned())
321 for (const auto v : cell->vertex_indices())
322 {
323 const types::global_dof_index serial_vertex_index =
324 dist_to_serial_vertices[cell->vertex_index(v)];
325 if (serial_vertex_index != numbers::invalid_unsigned_int)
326 for (unsigned int c = 0; c < n_comps; ++c)
327 {
328 const types::global_dof_index dof_index =
329 cell->vertex_dof_index(v, vertex_comp_offset + c);
330 Assert(locally_owned_dofs.is_element(dof_index),
331 ExcInternalError());
332 output_vector[dof_index] =
333 data[dofs_offset + n_comps * serial_vertex_index +
334 c];
335 }
336 }
337 dofs_offset += n_local_dofs;
338 vertex_comp_offset += n_comps;
339 }
340 else if (field_fe.template n_dofs_per_object<dim>() > 0)
341 {
342 // this is a cell data field
343 const types::global_dof_index n_local_dofs =
344 n_comps * serial_tria.n_global_active_cells();
345
346 // Assumption: serial and parallel meshes have the same ordering of
347 // cells.
348 auto serial_cell = serial_tria.begin_active();
349 auto parallel_cell = dh.begin_active();
350 for (; parallel_cell != dh.end(); ++parallel_cell)
351 if (parallel_cell->is_locally_owned())
352 {
353 // Advanced serial cell until we reach the same cell index of
354 // the parallel cell
355 while (serial_cell->id() < parallel_cell->id())
356 ++serial_cell;
357 const auto serial_cell_index =
358 serial_cell->global_active_cell_index();
359 for (unsigned int c = 0; c < n_comps; ++c)
360 {
361 const types::global_dof_index dof_index =
362 parallel_cell->dof_index(cell_comp_offset + c);
363 Assert(locally_owned_dofs.is_element(dof_index),
364 ExcInternalError());
365 output_vector[dof_index] =
366 data[dofs_offset + n_comps * serial_cell_index + c];
367 }
368 }
369 dofs_offset += n_local_dofs;
370 cell_comp_offset += n_comps;
371 }
372 }
373 }
374
375 template <int dim, int spacedim>
376 BlockIndices
377 get_block_indices(const FiniteElement<dim, spacedim> &fe)
378 {
379 BlockIndices block_indices;
380 for (unsigned int i = 0; i < fe.n_blocks(); ++i)
381 {
382 const auto &block_fe = fe.base_element(i);
383 block_indices.push_back(block_fe.n_components());
384 }
385 return block_indices;
386 };
387# endif
388} // namespace VTKUtils
389#endif // DEAL_II_WITH_VTK
390
391
392#endif
void push_back(const size_type size)
cell_iterator end() const
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
const Triangulation< dim, spacedim > & get_triangulation() const
const IndexSet & locally_owned_dofs() const
active_cell_iterator begin_active(const unsigned int level=0) const
types::global_dof_index n_dofs() const
unsigned int n_blocks() const
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
virtual types::global_cell_index n_global_active_cells() const
unsigned int n_vertices() const
active_cell_iterator begin_active(const unsigned int level=0) const
IteratorRange< active_cell_iterator > active_cell_iterators() const
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
std::vector< index_type > data
constexpr unsigned int invalid_unsigned_int
unsigned int global_dof_index