PLaSK library

Loading...
Searching...
No Matches
mesh.hpp
Go to the documentation of this file.
1/*
2 * This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3 * Copyright (c) 2022 Lodz University of Technology
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#ifndef PLASK__MESH_H
15#define PLASK__MESH_H
16
103#include <map>
104
105#include <plask/config.hpp>
106#include <plask/memory.hpp>
107
108#include "../vec.hpp"
109#include "../geometry/object.hpp"
110#include "../utils/iterators.hpp"
111#include "../utils/cache.hpp"
112#include "../utils/xml.hpp"
113
114#include <boost/signals2.hpp>
115#include "../utils/event.hpp"
116
117 namespace plask {
118
120 struct PLASK_API MeshBase {
121 virtual ~MeshBase() {}
122};
123
134 struct PLASK_API Mesh: public Printable, MeshBase {
135
141 struct Event: public EventWithSourceAndFlags<Mesh> {
142
144 enum Flags {
145 EVENT_DELETE = 1,
146 EVENT_RESIZE = 1<<1,
147 EVENT_USER_DEFINED = 1<<2
148 };
149
155 bool hasFlag(Flags flag) const { return hasAnyFlag(flag); }
156
161 bool isDelete() const { return hasFlag(EVENT_DELETE); }
162
167 bool isResize() const { return hasFlag(EVENT_RESIZE); }
168
174 explicit Event(Mesh* source, unsigned char flags = 0): EventWithSourceAndFlags<Mesh>(source, flags) {}
175 };
176
178 boost::signals2::signal<void(Event&)> changed;
179
187 template <typename ClassT, typename methodT>
188 boost::signals2::connection changedConnectMethod(ClassT* obj, methodT method, boost::signals2::connect_position at = boost::signals2::at_back) {
189 return changed.connect(boost::bind(method, obj, _1), at);
190 }
191
192 template <typename ClassT, typename methodT>
193 void changedDisconnectMethod(ClassT* obj, methodT method) {
194 changed.disconnect(boost::bind(method, obj, _1));
195 }
196
201 template<typename EventT = Event, typename ...Args>
202 void fireChanged(Args&&... event_constructor_params_without_source) {
203 EventT evt(this, std::forward<Args>(event_constructor_params_without_source)...);
204 onChange(evt);
205 changed(evt);
206 }
207
209 void fireResized() { fireChanged(Event::EVENT_RESIZE); }
210
212 virtual std::size_t size() const = 0;
213
215 virtual bool empty() const { return size() == 0; }
216
221 virtual void writeXML(XMLElement& object) const;
222
223 virtual ~Mesh() { fireChanged(Event::EVENT_DELETE); }
224
225 protected:
226
231 virtual void onChange(const Event& evt);
232
233};
234
238 template <int dimension>
239 struct PLASK_API MeshD: public Mesh {
240
242 enum { DIM = dimension };
243
245 typedef typename Primitive<DIM>::DVec LocalCoords;
246
252 virtual LocalCoords at(std::size_t index) const = 0;
253
259 LocalCoords operator[](std::size_t index) const { return at(index); }
260
265 typedef IndexedIterator< const MeshD<dimension>, LocalCoords > const_iterator;
266 typedef const_iterator iterator;
267 typedef const_iterator Iterator;
268
270 const_iterator begin() const { return const_iterator(this, 0); }
271
273 const_iterator end() const { return const_iterator(this, this->size()); }
274
279 MeshD(const MeshD& PLASK_UNUSED(to_copy)) {}
280
281 MeshD() {}
282
287 MeshD& operator=(const MeshD& PLASK_UNUSED(to_copy)) { return *this; }
288
294 bool operator==(const MeshD& to_compare) const {
295 if (this == &to_compare) return true;
296 return hasSameNodes(to_compare);
297 }
298
304 bool operator!=(const MeshD& to_compare) const { return ! (*this == to_compare); }
305
306 void print(std::ostream& out) const override;
307
308 protected:
309
318 virtual bool hasSameNodes(const MeshD<dimension>& to_compare) const;
319
320};
321
322 PLASK_API_EXTERN_TEMPLATE_STRUCT(MeshD<1>)
323 PLASK_API_EXTERN_TEMPLATE_STRUCT(MeshD<2>)
324 PLASK_API_EXTERN_TEMPLATE_STRUCT(MeshD<3>)
325
326
327 class PLASK_API MeshGenerator: public MeshBase {
328 public:
329
331 typedef EventWithSourceAndFlags<MeshGenerator> Event;
332
334 boost::signals2::signal<void(Event&)> changed;
335
343 template <typename ClassT, typename methodT>
344 void changedConnectMethod(ClassT* obj, methodT method, boost::signals2::connect_position at = boost::signals2::at_back) {
345 changed.connect(boost::bind(method, obj, _1), at);
346 }
347
348 template <typename ClassT, typename methodT>
349 void changedDisconnectMethod(ClassT* obj, methodT method) {
350 changed.disconnect(boost::bind(method, obj, _1));
351 }
352
357 template<typename EventT = Event, typename ...Args>
358 void fireChanged(Args&&... event_constructor_params_without_source) {
359 EventT evt(this, std::forward<Args>(event_constructor_params_without_source)...);
360 onChange(evt);
361 changed(evt);
362 }
363
364 virtual ~MeshGenerator() {}
365
366 protected:
367
372 virtual void onChange(const Event& evt);
373
374};
375
377 template <int MESH_DIM>
378 class PLASK_API MeshGeneratorD: public MeshGenerator
379{
380 public:
382 typedef MeshD<MESH_DIM> MeshType;
383
385 enum { DIM = (MESH_DIM < 2) ? 2 : MESH_DIM };
386
387 protected:
388 WeakCache<GeometryObject, MeshType, CacheRemoveOnEachChange> cache;
389
390 void onChange(const Event&) override { clearCache(); }
391
392 template <typename RequiredType>
393 static shared_ptr<RequiredType> cast(const shared_ptr<MeshType>& res) {
394 auto finall_res = dynamic_pointer_cast<RequiredType>(res);
395 if (res && !finall_res) throw Exception("wrong type of generated {0}D mesh.", MESH_DIM);
396 return finall_res;
397 }
398
399 public:
400
401 typedef shared_ptr<GeometryObjectD<DIM>> GeometryPtr;
402
408 virtual shared_ptr<MeshType> generate(const GeometryPtr& geometry) = 0;
409
414 inline void clearCache() {
415 cache.clear();
416 }
417
419 shared_ptr<MeshType> operator()(const GeometryPtr& geometry);
420
421 template <typename RequiredType>
422 shared_ptr<RequiredType> get(const shared_ptr<GeometryObjectD<DIM>>& geometry) {
423 return cast<RequiredType> ( this->operator ()(geometry) );
424 }
425
426 template <typename RequiredType>
427 shared_ptr<RequiredType> generate_t(const shared_ptr<GeometryObjectD<DIM>>& geometry) {
428 return cast<RequiredType> ( this->generate(geometry) );
429 }
430
431};
432
433 PLASK_API_EXTERN_TEMPLATE_CLASS(MeshGeneratorD<1>)
434 PLASK_API_EXTERN_TEMPLATE_CLASS(MeshGeneratorD<2>)
435 PLASK_API_EXTERN_TEMPLATE_CLASS(MeshGeneratorD<3>)
436
437
441 struct PLASK_API RegisterMeshReader {
442 typedef std::function<shared_ptr<Mesh>(XMLReader&)> ReadingFunction;
443 RegisterMeshReader(const std::string& tag_name, ReadingFunction fun);
444 static std::map<std::string, ReadingFunction>& getReaders();
445 static ReadingFunction getReader(const std::string& name);
446};
447
448 struct Manager;
449
454 struct PLASK_API RegisterMeshGeneratorReader {
455 typedef std::function<shared_ptr<MeshGenerator>(XMLReader&, Manager&)> ReadingFunction;
456 RegisterMeshGeneratorReader(const std::string& tag_name, ReadingFunction fun);
457 static std::map<std::string, ReadingFunction>& getReaders();
458 static ReadingFunction getReader(const std::string& name);
459};
460
461
462} // namespace plask
463
464#endif //PLASK__MESH_H