1#ifndef VIENNASHE_UTIL_GENERATE_DEVICE_HPP
2#define VIENNASHE_UTIL_GENERATE_DEVICE_HPP
26#include "viennagrid/mesh/mesh.hpp"
27#include "viennagrid/mesh/element_creation.hpp"
28#include "viennagrid/topology/line.hpp"
29#include "viennagrid/topology/quadrilateral.hpp"
75 points_y_(points_y) {}
93 unsigned long points_x_;
94 unsigned long points_y_;
99 void clear() { segment_descs_.clear(); }
107 double start_y,
double len_y,
unsigned long points_y)
117 std::size_t
size()
const {
return segment_descs_.size(); }
121 std::vector<segment_description> segment_descs_;
136 template <
typename MeshT,
typename SegmentationT>
138 SegmentationT & segmentation,
140 viennagrid::simplex_tag<1>
143 typedef typename viennagrid::result_of::point<MeshT>::type PointType;
144 typedef typename viennagrid::result_of::vertex<MeshT>::type VertexType;
145 typedef typename viennagrid::result_of::cell<MeshT>::type CellType;
147 typedef typename viennagrid::result_of::cell_tag<MeshT>::type CellTag;
149 typedef typename viennagrid::result_of::handle<MeshT, viennagrid::vertex_tag>::type VertexHandleType;
157 std::vector<PointType> segment_boundary_points;
159 std::size_t total_points = 1;
160 for (std::size_t i=0; i<conf.
size(); ++i)
162 SegmentDescriptionType
const & seg_desc = conf.
at(i);
164 assert(seg_desc.get_points_x() > 1 &&
bool(
"Logic error: Not enough points in x-direction provided for segment"));
165 assert(seg_desc.get_points_y() == 1 &&
bool(
"Logic error: Provided two-dimensional grid description for one-dimensional mesh"));
166 assert(seg_desc.get_length_x() > 0.0 &&
bool(
"Logic error: x-coordinate is degenerate in device generation."));
168 double distance_tolerance = 1e-10 * seg_desc.get_length_x();
170 PointType p0(seg_desc.get_start_x());
171 PointType p1(seg_desc.get_start_x() + seg_desc.get_length_x());
173 bool insert_p0 =
true;
174 bool insert_p1 =
true;
176 for (std::size_t j=0; j<segment_boundary_points.size(); ++j)
185 segment_boundary_points.push_back(p0);
187 segment_boundary_points.push_back(p1);
189 total_points += seg_desc.get_points_x() - 1;
195 log::info<log_generate_device>() <<
"* generate_device(): Setting up vertices..." << std::endl;
197 std::vector<int> segment_boundary_ids(segment_boundary_points.size(), -1);
199 std::vector< std::vector<int> > segment_vertex_ids(conf.
size());
201 int vertex_counter = 0;
204 for (std::size_t i=0; i<conf.
size(); ++i)
206 SegmentDescriptionType
const & seg_desc = conf.
at(i);
208 segment_vertex_ids[i].resize(seg_desc.get_points_x());
210 double distance_tolerance = 1e-10 * seg_desc.
get_length_x();
213 for (std::size_t j = 0; j<seg_desc.get_points_x(); ++j)
215 PointType candidate_point(seg_desc.get_start_x() + seg_desc.get_length_x() *
static_cast<double>(j) / (
static_cast<double>(seg_desc.get_points_x()) - 1.0));
218 if (j == 0 || j == seg_desc.get_points_x() - 1)
222 for (std::size_t k=0; k<segment_boundary_points.size(); ++k)
224 if (
viennagrid::norm_2(candidate_point - segment_boundary_points[k]) < distance_tolerance )
226 if (segment_boundary_ids[k] == -1)
228 viennagrid::make_vertex_with_id(mesh,
typename VertexType::id_type(vertex_counter), candidate_point);
229 segment_boundary_ids[k] = vertex_counter++;
231 segment_vertex_ids[i][j] = segment_boundary_ids[k];
236 assert(found &&
bool(
"Logic error: Could not find matching boundary point"));
241 viennagrid::make_vertex_with_id(mesh,
typename VertexType::id_type(vertex_counter), candidate_point);
242 segment_vertex_ids[i][j] = vertex_counter++;
251 log::info<log_generate_device>() <<
"* generate_device(): Setting up cells..." << std::endl;
252 viennagrid::static_array<VertexHandleType, viennagrid::boundary_elements<CellTag, viennagrid::vertex_tag>::num> cell_vertex_handles;
254 for (std::size_t i=0; i<conf.
size(); ++i)
256 SegmentDescriptionType
const & seg_desc = conf.
at(i);
258 for (std::size_t j = 0; j<seg_desc.get_points_x() - 1; ++j)
260 cell_vertex_handles[0] = viennagrid::vertices(mesh).handle_at(
static_cast<std::size_t
>(segment_vertex_ids[i][j]));
261 cell_vertex_handles[1] = viennagrid::vertices(mesh).handle_at(
static_cast<std::size_t
>(segment_vertex_ids[i][j+1]));
263 viennagrid::make_element_with_id<CellType>(segmentation[
static_cast<int>(i)],
264 cell_vertex_handles.begin(),
265 cell_vertex_handles.end(),
266 typename CellType::id_type(cell_id++));
270 log::info<log_generate_device>() <<
"* generate_device(): DONE" << std::endl;
275 template <
typename MeshType>
278 viennagrid::hypercube_tag<1>
295 template <
typename MeshT,
typename SegmentationT>
297 SegmentationT & segmentation,
299 viennagrid::quadrilateral_tag
302 typedef typename viennagrid::result_of::point<MeshT>::type PointType;
303 typedef typename viennagrid::result_of::vertex<MeshT>::type VertexType;
304 typedef typename viennagrid::result_of::cell<MeshT>::type CellType;
306 typedef typename viennagrid::result_of::cell_tag<MeshT>::type CellTag;
308 typedef typename viennagrid::result_of::handle<MeshT, viennagrid::vertex_tag>::type VertexHandleType;
316 std::vector<PointType> segment_boundary_points;
318 for (std::size_t seg_idx=0; seg_idx<conf.
size(); ++seg_idx)
320 SegmentDescriptionType
const & seg_desc = conf.
at(seg_idx);
322 assert(seg_desc.get_points_x() > 1 &&
bool(
"Logic error: Not enough points in x-direction provided for segment"));
323 assert(seg_desc.get_points_y() > 1 &&
bool(
"Logic error: Not enough points in y-direction provided for segment"));
324 assert(seg_desc.get_length_x() > 0.0 &&
bool(
"Logic error: x-coordinate is degenerate in device generation."));
325 assert(seg_desc.get_length_y() > 0.0 &&
bool(
"Logic error: y-coordinate is degenerate in device generation."));
327 double distance_tolerance = 1e-10 * std::min(seg_desc.get_length_x(), seg_desc.get_length_y());
329 for (std::size_t j=0; j<seg_desc.get_points_y(); ++j)
331 for (std::size_t i=0; i<seg_desc.get_points_x(); ++i)
333 if (i == 0 || j == 0 || i == seg_desc.get_points_x() - 1 || j == seg_desc.get_points_y() - 1)
335 double inc_x = seg_desc.get_length_x() /
static_cast<double>(seg_desc.get_points_x() - 1);
336 double inc_y = seg_desc.get_length_y() /
static_cast<double>(seg_desc.get_points_y() - 1);
338 PointType p(seg_desc.get_start_x() + i * inc_x,
339 seg_desc.get_start_y() + j * inc_y);
341 bool insert_p =
true;
343 for (std::size_t k=0; k<segment_boundary_points.size(); ++k)
353 segment_boundary_points.push_back(p);
362 log::info<log_generate_device>() <<
"* generate_device(): Setting up vertices..." << std::endl;
364 std::vector<long> segment_boundary_ids(segment_boundary_points.size(), -1);
366 std::vector< std::vector< std::vector<long> > > segment_vertex_ids(conf.
size());
368 int vertex_counter = 0;
371 for (std::size_t seg_idx=0; seg_idx<conf.
size(); ++seg_idx)
373 SegmentDescriptionType
const & seg_desc = conf.
at(seg_idx);
375 segment_vertex_ids[seg_idx].resize(seg_desc.get_points_x());
377 double distance_tolerance = 1e-10 * seg_desc.
get_length_x();
379 for (std::size_t i = 0; i<seg_desc.get_points_x(); ++i)
380 segment_vertex_ids[seg_idx][i].resize(seg_desc.get_points_y());
383 double inc_x = seg_desc.get_length_x() /
static_cast<double>(seg_desc.get_points_x() - 1);
384 double inc_y = seg_desc.get_length_y() /
static_cast<double>(seg_desc.get_points_y() - 1);
386 for (std::size_t j = 0; j<seg_desc.get_points_y(); ++j)
388 for (std::size_t i = 0; i<seg_desc.get_points_x(); ++i)
390 PointType p(seg_desc.get_start_x() + i * inc_x,
391 seg_desc.get_start_y() + j * inc_y);
394 if (i == 0 || j == 0 || i == seg_desc.get_points_x() - 1 || j == seg_desc.get_points_y() - 1)
398 for (std::size_t k=0; k<segment_boundary_points.size(); ++k)
402 if (segment_boundary_ids[k] == -1)
404 viennagrid::make_vertex_with_id(mesh,
typename VertexType::id_type(vertex_counter), p);
405 segment_boundary_ids[k] = vertex_counter++;
407 segment_vertex_ids[seg_idx][i][j] = segment_boundary_ids[k];
412 assert(found &&
bool(
"Logic error: Could not find matching boundary point"));
417 viennagrid::make_vertex_with_id(mesh,
typename VertexType::id_type(vertex_counter), p);
418 segment_vertex_ids[seg_idx][i][j] = vertex_counter++;
428 log::info<log_generate_device>() <<
"* generate_device(): Setting up cells..." << std::endl;
429 viennagrid::static_array<VertexHandleType, viennagrid::boundary_elements<CellTag, viennagrid::vertex_tag>::num> cell_vertex_handles;
431 for (std::size_t seg_idx=0; seg_idx<conf.
size(); ++seg_idx)
433 SegmentDescriptionType
const & seg_desc = conf.
at(seg_idx);
435 for (std::size_t j = 0; j<seg_desc.get_points_y() - 1; ++j)
437 for (std::size_t i = 0; i<seg_desc.get_points_x() - 1; ++i)
439 cell_vertex_handles[0] = viennagrid::vertices(mesh).handle_at(std::size_t(segment_vertex_ids[seg_idx][i][j]));
440 cell_vertex_handles[1] = viennagrid::vertices(mesh).handle_at(std::size_t(segment_vertex_ids[seg_idx][i+1][j]));
441 cell_vertex_handles[2] = viennagrid::vertices(mesh).handle_at(std::size_t(segment_vertex_ids[seg_idx][i][j+1]));
442 cell_vertex_handles[3] = viennagrid::vertices(mesh).handle_at(std::size_t(segment_vertex_ids[seg_idx][i+1][j+1]));
444 viennagrid::make_element_with_id<CellType>(segmentation[
static_cast<int>(seg_idx)],
445 cell_vertex_handles.begin(),
446 cell_vertex_handles.end(),
447 typename CellType::id_type(cell_id++));
452 log::info<log_generate_device>() <<
"* generate_device(): DONE" << std::endl;
468 template <
typename MeshT,
typename SegmentationT>
481 template <
typename IndexT =
unsigned long>
486 IndexT * segmentation,
489 : vertices_(vertices), cells_(cells), segmentation_(segmentation),
490 num_vertices_(num_vertices), num_cells_(
num_cells)
494 template <
typename MeshT,
typename SegmentationT >
497 typedef typename viennagrid::result_of::point<MeshT>::type PointType;
498 typedef typename viennagrid::result_of::vertex<MeshT>::type VertexType;
499 typedef typename viennagrid::result_of::cell<MeshT>::type CellType;
501 typedef typename viennagrid::result_of::cell_tag<MeshT>::type CellTag;
503 typedef typename viennagrid::result_of::handle<MeshT, viennagrid::vertex_tag>::type VertexHandleType;
505 for (
int i = 0; i < static_cast<int>(num_vertices_); ++i)
508 for (std::size_t j = 0; j < (std::size_t )PointType::dim; ++j)
509 p[j] = vertices_[i][j];
511 viennagrid::make_vertex_with_id( mesh,
typename VertexType::id_type(i), p );
514 for (
int i = 0; i < static_cast<int>(num_cells_); ++i )
516 viennagrid::static_array<VertexHandleType, viennagrid::boundary_elements<CellTag, viennagrid::vertex_tag>::num> cell_vertex_handles;
517 for (std::size_t j=0; j < (std::size_t )viennagrid::boundary_elements<CellTag, viennagrid::vertex_tag>::num; ++j)
519 cell_vertex_handles[j] = viennagrid::vertices(mesh).handle_at(cells_[i][j]);
522 IndexT seg_id = segmentation_[i];
523 if (segmentation_ != 0) seg_id = segmentation_[i];
525 viennagrid::make_element_with_id<CellType>(seg[
static_cast<int>(seg_id)],
526 cell_vertex_handles.begin(),
527 cell_vertex_handles.end(),
528 typename CellType::id_type(i));
535 IndexT * segmentation_;
536 IndexT num_vertices_;
548 template <
typename IndexT =
unsigned long>
553 IndexT * segmentation,
556 : vertices_(vertices), cells_(cells), segmentation_(segmentation),
557 num_vertices_(num_vertices), num_cells_(
num_cells)
561 template <
typename MeshT,
typename SegmentationT >
564 typedef typename viennagrid::result_of::point<MeshT>::type PointType;
565 typedef typename viennagrid::result_of::vertex<MeshT>::type VertexType;
566 typedef typename viennagrid::result_of::cell<MeshT>::type CellType;
568 typedef typename viennagrid::result_of::cell_tag<MeshT>::type CellTag;
570 typedef typename viennagrid::result_of::handle<MeshT, viennagrid::vertex_tag>::type VertexHandleType;
572 const std::size_t dim = (std::size_t )PointType::dim;
573 for (
int i = 0; i < static_cast<int>(num_vertices_); ++i)
576 for (std::size_t j = 0; j < dim; ++j)
577 p[j] = vertices_[std::size_t(i)*dim + j];
579 viennagrid::make_vertex_with_id( mesh,
typename VertexType::id_type(i), p );
582 for (
int i = 0; i < static_cast<int>(num_cells_); ++i )
584 const std::size_t nen = viennagrid::boundary_elements<CellTag, viennagrid::vertex_tag>::num;
586 viennagrid::static_array<VertexHandleType, viennagrid::boundary_elements<CellTag, viennagrid::vertex_tag>::num> cell_vertex_handles;
587 for (std::size_t j = 0; j < nen; ++j)
589 cell_vertex_handles[j] = viennagrid::vertices(mesh).handle_at(cells_[std::size_t(i)*nen + j]);
593 if (segmentation_ != 0) seg_id = segmentation_[i];
595 viennagrid::make_element_with_id<CellType>(seg[
int(seg_id)],
596 cell_vertex_handles.begin(),
597 cell_vertex_handles.end(),
598 typename CellType::id_type(i));
605 IndexT * segmentation_;
606 IndexT num_vertices_;
double get_length_y() const
double get_length_x() const
segment_description(double start_x, double len_x, unsigned long points_x)
double get_start_x() const
segment_description(double start_x, double start_y, double len_x, double len_y, unsigned long points_x, unsigned long points_y)
unsigned long get_points_y() const
double get_start_y() const
unsigned long get_points_x() const
Configuration class for the simple mesh generator.
void add_segment(double start_x, double start_y, double len_x, double len_y, unsigned long points_x, unsigned long points_y)
segment_description segment_description_type
segment_description const & at(std::size_t i) const
void add_segment(double start_x, double len_x, unsigned long points_x)
void add_segment(double start_x, double len_x, unsigned long points_x, double start_y, double len_y, unsigned long points_y)
A logging facility providing fine-grained control over logging in ViennaSHE.
VectorType::value_type norm_2(VectorType const &v)
void generate_device_impl(MeshT &mesh, SegmentationT &segmentation, device_generation_config const &conf, viennagrid::simplex_tag< 1 >)
Implementation of a simple one-dimensional 'mesh' generation. Fills a ViennaGrid mesh.
void generate_device(MeshT &mesh, SegmentationT &seg, device_generation_config const &conf)
Public interface for mesh generation of simple one- or two-dimensional meshes. Device must be rectang...
The main ViennaSHE namespace. All functionality resides inside this namespace.
A device generator to generate a device from C-Arrays (DOES NOT TAKE OWNERSHIP)
device_from_array_generator(double **vertices, IndexT **cells, IndexT *segmentation, IndexT num_vertices, IndexT num_cells)
void operator()(MeshT &mesh, SegmentationT &seg) const
Functor interface. The mesh and the segmentation need to be given.
A device generator to generate a device from flat C-Arrays (DOES NOT TAKE OWNERSHIP)
device_from_flat_array_generator(double *vertices, IndexT *cells, IndexT *segmentation, IndexT num_vertices, IndexT num_cells)
void operator()(MeshT &mesh, SegmentationT &seg) const
Functor interface. The mesh and the segmentation need to be given.
Defines the log keys used within the viennashe::util namespace.