Branch data Line data Source code
1 : : #ifndef AMR_tet_store_h
2 : : #define AMR_tet_store_h
3 : :
4 : : #include <unordered_set>
5 : : #include <vector>
6 : :
7 : : #include "AMR_types.hpp"
8 : : #include "active_element_store.hpp"
9 : : #include "master_element_store.hpp"
10 : : #include "marked_refinements_store.hpp"
11 : : #include "edge_store.hpp"
12 : : #include "util.hpp"
13 : : #include "id_generator.hpp"
14 : :
15 : : namespace AMR {
16 : :
17 : : class tet_store_t {
18 : : public:
19 : : // FIXME: Remove this (center_tets) data structure!
20 : : // This is a horrendous code abuse, and I'm sorry. I'm fairly
21 : : // certain we'll be re-writing how this detection is done and just
22 : : // wanted a quick-fix so I could move on :(
23 : : std::set<size_t> center_tets; // Store for 1:4 centers
24 : :
25 : : std::set<size_t> delete_list; // For marking deletions in deref
26 : :
27 : : AMR::active_element_store_t active_elements;
28 : : AMR::master_element_store_t master_elements;
29 : :
30 : : std::vector< std::size_t > active_tetinpoel;
31 : : std::set< std::size_t > active_nodes;
32 : :
33 : : AMR::id_generator_t id_generator;
34 : :
35 : : std::unordered_set<size_t> intermediate_list;
36 : : // Public so it can be trivially grabbed for looping over.
37 : : std::vector< std::size_t > active_id_mapping;
38 : :
39 : : tet_list_t tets;
40 : : AMR::edge_store_t edge_store;
41 : :
42 : : // TODO: Make this (and others) private at some point
43 : : AMR::marked_refinements_store_t<AMR::Refinement_Case> marked_refinements;
44 : : AMR::marked_refinements_store_t<AMR::Derefinement_Case> marked_derefinements;
45 : :
46 : : /**
47 : : * @brief function to return the number of tets stored
48 : : *
49 : : * @return Num of tets
50 : : */
51 : 0 : size_t size() {
52 : 0 : return tets.size();
53 : : }
54 : :
55 : : /**
56 : : * @brief Helper to check if an given tet is active
57 : : *
58 : : * @param id id of the tool to check
59 : : *
60 : : * @return active status of tet
61 : : */
62 : 0 : bool is_active(size_t id)
63 : : {
64 : 0 : return active_elements.exists(id);
65 : : }
66 : :
67 : : /**
68 : : * @brief Return refinement case for a given id
69 : : *
70 : : * @param id id to get case for
71 : : *
72 : : * @return Refinement case for id
73 : : */
74 : 0 : Refinement_Case get_refinement_case(size_t id)
75 : : {
76 : 0 : return data(id).refinement_case;
77 : : }
78 : :
79 : : /**
80 : : * @brief Set value of normal
81 : : *
82 : : * @param id Id to set
83 : : * @param val true/false to set
84 : : */
85 : 0 : void set_normal(size_t id, bool val)
86 : : {
87 : 0 : data(id).normal = val;
88 : 0 : }
89 : :
90 : : /**
91 : : * @brief Get normal value for given id
92 : : *
93 : : * @param id Id of tet to check
94 : : *
95 : : * @return true/false of normal value
96 : : */
97 : 0 : bool is_normal(size_t id)
98 : : {
99 : : // should the underlying type be bool?
100 : 0 : return data(id).normal;
101 : : }
102 : :
103 : : /**
104 : : * @brief set a tet as normal
105 : : *
106 : : * @param id id to set
107 : : */
108 : 0 : void mark_normal(size_t id)
109 : : {
110 : 0 : set_normal(id, true);
111 : 0 : }
112 : :
113 : : /**
114 : : * @brief get data for a tet from master element
115 : : *
116 : : * @param id id of tet to get
117 : : *
118 : : * @return state of the tet
119 : : */
120 : 0 : Refinement_State& data(size_t id)
121 : : {
122 : 0 : return master_elements.get(id);
123 : : }
124 : :
125 : : const Refinement_State& data(size_t id) const
126 : : {
127 : : return master_elements.get(id);
128 : : }
129 : :
130 : : /**
131 : : * @brief Method to insert tet into the tet store, so the
132 : : * underlying data structure doesn't have to be interfaced with
133 : : * directly
134 : : *
135 : : * @param id Id of the added tet
136 : : * @param t The tet element
137 : : */
138 : 0 : void insert(size_t id, tet_t t)
139 : : {
140 : : // cppcheck-suppress assertWithSideEffect
141 [ - - ]: 0 : assert( !exists(id) );
142 [ - - ]: 0 : tets.insert( std::pair<size_t, tet_t>(id, t));
143 : 0 : }
144 : :
145 : : /**
146 : : * @brief Getter for tet element
147 : : *
148 : : * @param id Id of tet to get
149 : : *
150 : : * @return Copy of the tet
151 : : */
152 : 0 : tet_t get( size_t id )
153 : : {
154 : : // cppcheck-suppress assertWithSideEffect
155 [ - - ]: 0 : assert( exists(id) );
156 : 0 : return tets.at(id);
157 : : }
158 : :
159 : : /**
160 : : * @brief Function to check if a tet exists. Useful for debugging
161 : : * access to invalid tets, or trying to re-create a tet which
162 : : * already exists
163 : : *
164 : : * @param id Id of the tet to check
165 : : *
166 : : * @return Bool stating if the tet already exists
167 : : */
168 : 0 : bool exists(size_t id)
169 : : {
170 [ - - ]: 0 : auto f = tets.find(id);
171 [ - - ]: 0 : if (f != tets.end())
172 : : {
173 : : //trace_out << "tet " << id << " exists." << std::endl;
174 : 0 : return true;
175 : : }
176 : 0 : return false;
177 : : }
178 : :
179 : : /**
180 : : * @brief Function to store a tet from a list of nodes
181 : : *
182 : : * @param id The ID of the tetrahedron to insert
183 : : * @param nodes The node ids which make up the tet
184 : : */
185 : 0 : void store_tet(size_t id, tet_t nodes) {
186 : :
187 : 0 : insert(id, nodes);
188 : :
189 : : // Sanity check the storage ids
190 : : // (this is probably better in a function/2d loop)
191 [ - - ]: 0 : assert( nodes[0] != nodes[1] );
192 [ - - ]: 0 : assert( nodes[0] != nodes[2] );
193 [ - - ]: 0 : assert( nodes[0] != nodes[3] );
194 [ - - ]: 0 : assert( nodes[1] != nodes[2] );
195 [ - - ]: 0 : assert( nodes[1] != nodes[3] );
196 [ - - ]: 0 : assert( nodes[2] != nodes[3] );
197 : 0 : }
198 : :
199 : : /**
200 : : * @brief Convenience function to store a tet without first building
201 : : * a list
202 : : *
203 : : * @param id The ID of the tetrahedron to store
204 : : * @param first First Node
205 : : * @param second Second Node
206 : : * @param third Third Node
207 : : * @param forth Forth Node
208 : : */
209 : : void store_tet(
210 : : size_t id,
211 : : size_t first,
212 : : size_t second,
213 : : size_t third,
214 : : size_t forth
215 : : )
216 : : {
217 : : store_tet( id, { {first, second, third, forth} } );
218 : : }
219 : :
220 : 0 : void add(
221 : : size_t id,
222 : : const tet_t& nodes,
223 : : Refinement_Case refinement_case,
224 : : size_t parent_id
225 : : )
226 : : {
227 : :
228 : : //std::cout << "id " << id << " parent " << parent_id << std::endl;
229 : :
230 : 0 : add_to_master(id, nodes, refinement_case, parent_id, true);
231 : :
232 : 0 : master_elements.get(id).refinement_level =
233 : 0 : master_elements.get(parent_id).refinement_level+1;
234 : :
235 : : // Deal with updating parent
236 : 0 : master_elements.add_child(parent_id, id);
237 : :
238 : : trace_out << "Added child " << id << std::endl;
239 : 0 : }
240 : :
241 : : /**
242 : : * @brief Convenience function to add a tet to the master_elements
243 : : * and active_elements store
244 : : *
245 : : * @param id The ID of the tetrahedron to add
246 : : * @param nodes A list of the nodes which form th etet
247 : : * @param refinement_case The refinement case which caused this tet
248 : : * to be generated
249 : : * @param parent_id The ID of the parent tetrahedron
250 : : * @param has_parent True if element has a parent
251 : : */
252 : 0 : void add_to_master(size_t id, const tet_t& nodes,
253 : : Refinement_Case refinement_case, size_t parent_id=0,
254 : : bool has_parent=false)
255 : : {
256 : 0 : store_tet(id, nodes);
257 : :
258 : 0 : size_t refinement_level = 0;
259 : :
260 : : // Add to master list
261 : 0 : master_elements.add(id, refinement_case, refinement_level, parent_id, has_parent);
262 : :
263 : : // The new master element should start as active
264 : 0 : active_elements.add(id);
265 : 0 : }
266 : :
267 : : /**
268 : : * @brief Interface to add a tet from the original mesh (no parent)
269 : : */
270 : 0 : void add(const tet_t& nodes, Refinement_Case refinement_case)
271 : : {
272 : 0 : size_t id = id_generator.get_next_tet_id();
273 : 0 : add_to_master(id, nodes, refinement_case);
274 : 0 : }
275 : :
276 : 0 : void add(
277 : : size_t id,
278 : : size_t first,
279 : : size_t second,
280 : : size_t third,
281 : : size_t forth,
282 : : Refinement_Case refinement_case,
283 : : size_t parent_id
284 : : )
285 : : {
286 [ - - ]: 0 : return add(
287 : : id,
288 : : { {first, second, third, forth} },
289 : : refinement_case,
290 : : parent_id
291 : 0 : );
292 : :
293 : : }
294 : :
295 : : // NOTE: this does *not* deal with edges
296 : : /**
297 : : * @brief Function to delete a tet from the tet store (useful in
298 : : * derefinement)
299 : : *
300 : : * @param id id of the tet to delete
301 : : */
302 : 0 : void erase(size_t id)
303 : : {
304 : 0 : deactivate(id);
305 : 0 : master_elements.erase(id);
306 : 0 : tets.erase(id);
307 : : // TODO: Should this update the number of children here rather than at the call site?
308 : 0 : }
309 : :
310 : : /**
311 : : * @brief Function to remove a tet from the active tet list
312 : : *
313 : : * @param id The id of the tet to deactivate
314 : : */
315 : 0 : void deactivate(size_t id) {
316 : 0 : active_elements.erase(id);
317 : : // TODO: For safety, should we also mark it's edges as not
318 : : // needing to be refined?
319 : 0 : }
320 : :
321 : 0 : void activate(size_t id) {
322 [ - - ]: 0 : if (!is_active(id) )
323 : : {
324 : 0 : active_elements.add(id);
325 : : }
326 : 0 : }
327 : :
328 : : /**
329 : : * @brief Function to add a tet to a list which maintains what is a
330 : : * center tet. (The need to maintain a list could be replaced by a
331 : : * geometric check on the tet itself)
332 : : *
333 : : * @param id Id of the tet to add
334 : : */
335 : 0 : void add_center(size_t id)
336 : : {
337 : : // cppcheck-suppress assertWithSideEffect
338 [ - - ]: 0 : assert( !is_center(id) );
339 : 0 : center_tets.insert(id);
340 : 0 : }
341 : :
342 : : /**
343 : : * @brief function to check if a tet is a center tet in a 1:4
344 : : *
345 : : * @param id Id of the tet to check
346 : : *
347 : : * @return Bool stating if it's a center tet or not
348 : : */
349 : 0 : bool is_center(size_t id)
350 : : {
351 [ - - ][ - - ]: 0 : if (center_tets.find(id) != center_tets.end())
352 : : {
353 : 0 : return true;
354 : : }
355 : 0 : return false;
356 : : }
357 : :
358 : : /**
359 : : * @brief Function to get a list of refinement levels, useful for
360 : : * vis
361 : : *
362 : : * @return Vector containing refinement levels of tets
363 : : */
364 : : std::vector< real_t > get_refinement_level_list() const
365 : : {
366 : : std::vector<real_t> refinement_level_list;
367 : :
368 : : for (const auto& kv : tets)
369 : : {
370 : : size_t element_id = kv.first;
371 : : if (active_elements.exists( element_id )) {
372 : : real_t val = static_cast< tk::real >(
373 : : master_elements.get(element_id).refinement_level );
374 : : refinement_level_list.push_back(val);
375 : : }
376 : : }
377 : :
378 : : trace_out << "Made refinement level list of len " << refinement_level_list.size() << std::endl;
379 : : return refinement_level_list;
380 : : }
381 : :
382 : : /**
383 : : * @brief Function to return a list of cell types, useful when
384 : : * invoking the vis to do coloring by cell type
385 : : *
386 : : * @return Vector listening the types of cells
387 : : */
388 : : std::vector< real_t > get_cell_type_list() const
389 : : {
390 : : std::vector<real_t> cell_type_list;
391 : :
392 : : for (const auto& kv : tets)
393 : : {
394 : : size_t element_id = kv.first;
395 : :
396 : : if (active_elements.exists( element_id )) {
397 : :
398 : : real_t val = 0.0;
399 : :
400 : : // Be a good citizen, make this enum human readable
401 : : switch (master_elements.get(element_id).refinement_case)
402 : : {
403 : : case Refinement_Case::one_to_two:
404 : : val = 2.0;
405 : : break;
406 : : case Refinement_Case::one_to_four:
407 : : val = 4.0;
408 : : break;
409 : : case Refinement_Case::one_to_eight:
410 : : val = 8.0;
411 : : break;
412 : : case Refinement_Case::initial_grid:
413 : : val = 1.0;
414 : : break;
415 : : // TODO: this will never actually happen, as a 2:8 currently views
416 : : // itself as a 1:8 (as it did a 2:1, and a 1:8)
417 : : case Refinement_Case::two_to_eight:
418 : : val = 2.8;
419 : : break;
420 : : case Refinement_Case::four_to_eight:
421 : : val = 4.8;
422 : : break;
423 : : case Refinement_Case::none:
424 : : val = 0.0;
425 : : break;
426 : : }
427 : : cell_type_list.push_back(val);
428 : : }
429 : : }
430 : :
431 : : trace_out << "Made cell type list of len " << cell_type_list.size() << std::endl;
432 : : return cell_type_list;
433 : : }
434 : :
435 : : /**
436 : : * @brief The function gives a way to go back from active_inpoel to
437 : : * real AMR id
438 : : *
439 : : * @return A vector which hold the AMR ids of the active inpoel
440 : : */
441 : : std::vector< std::size_t >& get_active_id_mapping()
442 : : {
443 : : active_id_mapping.clear();
444 : :
445 : : for (const auto& kv : tets)
446 : : {
447 : : size_t element_id = kv.first;
448 : :
449 : : if (is_active( element_id )) {
450 : : active_id_mapping.push_back( element_id );
451 : : }
452 : : }
453 : :
454 : : return active_id_mapping;
455 : : }
456 : :
457 : : /**
458 : : * @brief Function to extract only the active elements from tetinpeol
459 : : *
460 : : * @return List of only active elements
461 : : */
462 : : // TODO: need equiv for m_x/m_y/m_z? Otherwise there will be
463 : : // useless nodes in m_x etc? (Although that's functionally fine)
464 : 0 : std::vector< std::size_t >& get_active_inpoel()
465 : : {
466 : 0 : active_tetinpoel.clear();
467 : 0 : active_nodes.clear();
468 : :
469 [ - - ]: 0 : for (const auto& kv : tets)
470 : : {
471 : :
472 : 0 : size_t element_id = kv.first;
473 : 0 : auto t = kv.second;
474 : :
475 [ - - ][ - - ]: 0 : if (is_active( element_id )) {
476 [ - - ]: 0 : active_tetinpoel.push_back( t[0] );
477 [ - - ]: 0 : active_tetinpoel.push_back( t[1] );
478 [ - - ]: 0 : active_tetinpoel.push_back( t[2] );
479 [ - - ]: 0 : active_tetinpoel.push_back( t[3] );
480 : :
481 [ - - ]: 0 : active_nodes.insert( t[0] );
482 [ - - ]: 0 : active_nodes.insert( t[1] );
483 [ - - ]: 0 : active_nodes.insert( t[2] );
484 [ - - ]: 0 : active_nodes.insert( t[3] );
485 : : }
486 : : }
487 : :
488 : 0 : return active_tetinpoel;
489 : : }
490 : :
491 : : // TODO: These mark methods can probably be a single one to which a
492 : : // Refinement_Case is passed, depending on how extra edges are marked
493 : : /**
494 : : * @brief Function to mark a given tet as needing a 1:2 refinement
495 : : *
496 : : * @param tet_id The tet to mark
497 : : */
498 : 0 : void mark_one_to_two(size_t tet_id)
499 : : {
500 : : // TODO: If none of these methods need extra markings, then
501 : : // change them into a single method
502 : : trace_out << "Mark " << tet_id << " as 1:2" << std::endl;
503 : 0 : marked_refinements.add(tet_id, Refinement_Case::one_to_two);
504 : 0 : }
505 : :
506 : : /**
507 : : * @brief Mark a given tet as needing a 1:4 refinement
508 : : *
509 : : * @param tet_id The tet to mark
510 : : */
511 : 0 : void mark_one_to_four(size_t tet_id)
512 : : {
513 : : trace_out << "Mark " << tet_id << " as 1:4" << std::endl;
514 : 0 : marked_refinements.add(tet_id, Refinement_Case::one_to_four);
515 : 0 : }
516 : :
517 : : /**
518 : : * @brief Mark a given tet as needing a 2:8 refinement
519 : : *
520 : : * @param tet_id id of tet to mark
521 : : */
522 : 0 : void mark_two_to_eight(size_t tet_id)
523 : : {
524 : : trace_out << "Mark " << tet_id << " as 2:8" << std::endl;
525 : 0 : marked_refinements.add(tet_id, Refinement_Case::two_to_eight);
526 : 0 : }
527 : :
528 : : /**
529 : : * @brief Mark a given tet as needing a 4:8 refinement
530 : : *
531 : : * @param tet_id id of tet to mark
532 : : */
533 : 0 : void mark_four_to_eight(size_t tet_id)
534 : : {
535 : : trace_out << "Mark " << tet_id << " as 4:8" << std::endl;
536 : 0 : marked_refinements.add(tet_id, Refinement_Case::four_to_eight);
537 : 0 : }
538 : :
539 : : /**
540 : : * @brief Function to mark a given tet as needing a 1:8 refinement
541 : : *
542 : : * @param tet_id The tet to mark
543 : : */
544 : 0 : void mark_one_to_eight(size_t tet_id)
545 : : {
546 : : trace_out << "Mark " << tet_id << " as 1:8" << std::endl;
547 : 0 : marked_refinements.add(tet_id, Refinement_Case::one_to_eight);
548 : 0 : }
549 : :
550 : 0 : bool has_refinement_decision(size_t id)
551 : : {
552 : 0 : return marked_refinements.exists(id);
553 : : }
554 : :
555 : : /**
556 : : * @brief Helper debug function to print tet information
557 : : */
558 : 0 : void print_tets() {
559 [ - - ]: 0 : for (const auto& kv : tets)
560 : : {
561 : 0 : tet_t tet = kv.second;
562 : :
563 : : trace_out << "Tet " << kv.first << " has edges :" <<
564 : : tet[0] << ", " <<
565 : : tet[1] << ", " <<
566 : : tet[2] << ", " <<
567 : : tet[3] << ", " <<
568 : : std::endl;
569 : : }
570 : 0 : }
571 : :
572 : : void print_edges()
573 : : {
574 : : edge_store.print();
575 : : }
576 : :
577 : 0 : void print_node_types()
578 : : {
579 : :
580 : 0 : int initial_grid = 0;
581 : 0 : int one_to_two = 0;
582 : 0 : int one_to_four = 0;
583 : 0 : int one_to_eight = 0;
584 : 0 : int other = 0;
585 : :
586 [ - - ]: 0 : for (const auto& kv : tets)
587 : : {
588 : 0 : size_t tet_id = kv.first;
589 [ - - ][ - - ]: 0 : if (is_active(tet_id))
590 : : {
591 [ - - ][ - - ]: 0 : switch(get_refinement_case(tet_id))
[ - - ][ - - ]
[ - - ]
592 : : {
593 : 0 : case Refinement_Case::one_to_two:
594 : 0 : one_to_two++;
595 : 0 : break;
596 : 0 : case Refinement_Case::one_to_four:
597 : 0 : one_to_four++;
598 : 0 : break;
599 : 0 : case Refinement_Case::one_to_eight:
600 : 0 : one_to_eight++;
601 : 0 : break;
602 : 0 : case Refinement_Case::initial_grid:
603 : 0 : initial_grid++;
604 : 0 : break;
605 : 0 : case Refinement_Case::two_to_eight:
606 : : // Don't care (yet)
607 : 0 : other++;
608 : 0 : break;
609 : 0 : case Refinement_Case::four_to_eight:
610 : : // Don't care (yet)
611 : 0 : other++;
612 : 0 : break;
613 : 0 : case Refinement_Case::none:
614 : : // Don't care (yet)
615 : 0 : other++;
616 : 0 : break;
617 : : }
618 : :
619 : : }
620 : : }
621 : :
622 : : //std::cout << "Active Totals:" << std::endl;
623 : : //std::cout << " --> Initial = " << initial_grid << std::endl;
624 : : //std::cout << " --> 1:2 = " << one_to_two << std::endl;
625 : : //std::cout << " --> 1:4 = " << one_to_four << std::endl;
626 : : //std::cout << " --> 1:8 = " << one_to_eight << std::endl;
627 : 0 : }
628 : :
629 : 0 : edge_list_t generate_edge_keys(size_t tet_id)
630 : : {
631 [ - - ]: 0 : tet_t tet = get(tet_id);
632 [ - - ]: 0 : return edge_store.generate_keys(tet);
633 : : }
634 : :
635 : 0 : void generate_edges(size_t i) {
636 : : // For tet ABCD, edges are:
637 : : // AB, AC, AD, BC, BD, CD
638 : : //
639 [ - - ]: 0 : edge_list_t edge_list = generate_edge_keys(i);
640 : :
641 [ - - ]: 0 : for (size_t j = 0; j < NUM_TET_EDGES; j++)
642 : : {
643 : 0 : edge_t edge = edge_list[j];
644 : :
645 : 0 : size_t A = edge.first();
646 : 0 : size_t B = edge.second();
647 : :
648 : : Edge_Refinement er = Edge_Refinement(A, B, false,
649 : 0 : false, Edge_Lock_Case::unlocked);
650 : :
651 [ - - ]: 0 : edge_store.add(edge, er);
652 : : }
653 : 0 : }
654 : :
655 : : /**
656 : : * @brief function to take a tet_id, finds it's nodes, and
657 : : * expresses them as faces
658 : : *
659 : : * Take tet ABCD, generate faces {ABC, ABD, ACD, BCD}
660 : : *
661 : : * @param tet_id The tet to generate faces for
662 : : *
663 : : * @return A list of faces making this tet
664 : : */
665 : 0 : face_list_t generate_face_lists(size_t tet_id)
666 : : {
667 : : // Hard code this for now...
668 [ - - ]: 0 : tet_t tet = get(tet_id);
669 : :
670 : : trace_out << "Tet has nodes " <<
671 : : tet[0] << ", " <<
672 : : tet[1] << ", " <<
673 : : tet[2] << ", " <<
674 : : tet[3] << ", " <<
675 : : std::endl;
676 : :
677 : : face_list_t face_list;
678 : :
679 : : // ABC
680 : 0 : face_list[0][0] = tet[0];
681 : 0 : face_list[0][1] = tet[1];
682 : 0 : face_list[0][2] = tet[2];
683 : :
684 : : // ABD
685 : 0 : face_list[1][0] = tet[0];
686 : 0 : face_list[1][1] = tet[3];
687 : 0 : face_list[1][2] = tet[1];
688 : :
689 : : // ACD
690 : 0 : face_list[2][0] = tet[0];
691 : 0 : face_list[2][1] = tet[2];
692 : 0 : face_list[2][2] = tet[3];
693 : :
694 : : // BCD
695 : 0 : face_list[3][0] = tet[1];
696 : 0 : face_list[3][1] = tet[3];
697 : 0 : face_list[3][2] = tet[2];
698 : :
699 : 0 : return face_list;
700 : : }
701 : :
702 : : /**
703 : : * @brief Function which marks all edges in a given tet as needing
704 : : * to be refined
705 : : *
706 : : * @param tet_id ID of the tet to mark
707 : : */
708 : 0 : void mark_edges_for_refinement(size_t tet_id)
709 : : {
710 [ - - ]: 0 : edge_list_t edge_list = generate_edge_keys(tet_id);
711 [ - - ]: 0 : for (size_t k = 0; k < NUM_TET_EDGES; k++)
712 : : {
713 : 0 : edge_t edge = edge_list[k];
714 [ - - ]: 0 : edge_store.mark_for_refinement(edge);
715 : : trace_out << "Marking edge " << edge << " for refine " << std::endl;
716 : : }
717 : 0 : }
718 : :
719 : : /**
720 : : * @brief Delete existing edges. Iterate over the tets, and add them to
721 : : * the edge store.
722 : : */
723 : : // FIXME: Better name for this?
724 : : void generate_edges() {
725 : :
726 : : // Go over tets, and generate all known edges
727 : : edge_store.edges.clear();
728 : :
729 : : // Jump over tets
730 : : for (const auto& kv : tets)
731 : : {
732 : : size_t tet_id = kv.first;
733 : : generate_edges(tet_id);
734 : : }
735 : : }
736 : :
737 : 0 : void unset_marked_children(size_t parent_id)
738 : : {
739 : 0 : Refinement_State& parent = data(parent_id);
740 [ - - ]: 0 : for (auto c : parent.children)
741 : : {
742 [ - - ]: 0 : marked_refinements.erase(c);
743 : : }
744 : 0 : }
745 : :
746 : 0 : child_id_list_t generate_child_ids(size_t parent_id, size_t count = MAX_CHILDREN)
747 : : {
748 : 0 : return id_generator.generate_child_ids(parent_id, count);
749 : : }
750 : : size_t get_child_id(size_t parent_id, size_t offset) const
751 : : {
752 : : return master_elements.get_child_id(parent_id, offset);
753 : : }
754 : :
755 : 0 : size_t get_parent_id(size_t id) const
756 : : {
757 : 0 : return master_elements.get_parent(id);
758 : : }
759 : :
760 : : // Deref
761 : 0 : void process_delete_list()
762 : : {
763 : : trace_out << "process_delete_list " << delete_list.size() << std::endl;
764 : 0 : size_t original_size = size();
765 [ - - ]: 0 : for(auto f : delete_list) {
766 [ - - ]: 0 : erase(f);
767 : : }
768 : :
769 : 0 : size_t end_size = size();
770 : : trace_out << "Deleted " << original_size-end_size << std::endl;
771 : :
772 : 0 : delete_list.clear();
773 : 0 : }
774 : : /**
775 : : * @brief Function to mark a given tet as a specific Derefinement_Case
776 : : *
777 : : * @param tet_id The tet to mark
778 : : * @param decision The Derefinement_case to set
779 : : */
780 : 0 : void mark_derefinement_decision(size_t tet_id, AMR::Derefinement_Case decision)
781 : : {
782 : : trace_out << "MARKING_DEREF_DECISION" << std::endl;
783 : 0 : marked_derefinements.add(tet_id, decision);
784 : 0 : }
785 : 0 : bool has_derefinement_decision(size_t id)
786 : : {
787 : 0 : return marked_derefinements.exists(id);
788 : : }
789 : :
790 : : };
791 : : }
792 : :
793 : : #endif // guard
|