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 : 204 : size_t size() {
52 : 204 : 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 : 5103015 : bool is_active(size_t id)
63 : : {
64 : 5103015 : 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 : 911156 : Refinement_Case get_refinement_case(size_t id)
75 : : {
76 : 911156 : 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 : 586526 : void set_normal(size_t id, bool val)
86 : : {
87 : 586526 : data(id).normal = val;
88 : 586526 : }
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 : 143522 : bool is_normal(size_t id)
98 : : {
99 : : // should the underlying type be bool?
100 : 143522 : return data(id).normal;
101 : : }
102 : :
103 : : /**
104 : : * @brief set a tet as normal
105 : : *
106 : : * @param id id to set
107 : : */
108 : 318 : void mark_normal(size_t id)
109 : : {
110 : 318 : set_normal(id, true);
111 : 318 : }
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 : 2478616 : Refinement_State& data(size_t id)
121 : : {
122 : 2478616 : return master_elements.get(id);
123 : : }
124 : :
125 : 439502 : const Refinement_State& data(size_t id) const
126 : : {
127 : 439502 : 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 : 852136 : void insert(size_t id, tet_t t)
139 : : {
140 : : // cppcheck-suppress assertWithSideEffect
141 [ - + ]: 852136 : assert( !exists(id) );
142 [ + - ]: 852136 : tets.insert( std::pair<size_t, tet_t>(id, t));
143 : 852136 : }
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 : 5234070 : tet_t get( size_t id )
153 : : {
154 : : // cppcheck-suppress assertWithSideEffect
155 [ - + ]: 5234070 : assert( exists(id) );
156 : 5234070 : 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 : 6086206 : bool exists(size_t id)
169 : : {
170 [ + - ]: 6086206 : auto f = tets.find(id);
171 [ + + ]: 6086206 : if (f != tets.end())
172 : : {
173 : : //trace_out << "tet " << id << " exists." << std::endl;
174 : 5234070 : return true;
175 : : }
176 : 852136 : 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 : 852136 : void store_tet(size_t id, tet_t nodes) {
186 : :
187 : 852136 : insert(id, nodes);
188 : :
189 : : // Sanity check the storage ids
190 : : // (this is probably better in a function/2d loop)
191 [ - + ]: 852136 : assert( nodes[0] != nodes[1] );
192 [ - + ]: 852136 : assert( nodes[0] != nodes[2] );
193 [ - + ]: 852136 : assert( nodes[0] != nodes[3] );
194 [ - + ]: 852136 : assert( nodes[1] != nodes[2] );
195 [ - + ]: 852136 : assert( nodes[1] != nodes[3] );
196 [ - + ]: 852136 : assert( nodes[2] != nodes[3] );
197 : 852136 : }
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 : 350030 : 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 : 350030 : add_to_master(id, nodes, refinement_case, parent_id, true);
231 : :
232 : 700060 : master_elements.get(id).refinement_level =
233 : 350030 : master_elements.get(parent_id).refinement_level+1;
234 : :
235 : : // Deal with updating parent
236 : 350030 : master_elements.add_child(parent_id, id);
237 : :
238 : : trace_out << "Added child " << id << std::endl;
239 : 350030 : }
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 : 852136 : 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 : 852136 : store_tet(id, nodes);
257 : :
258 : 852136 : size_t refinement_level = 0;
259 : :
260 : : // Add to master list
261 : 852136 : master_elements.add(id, refinement_case, refinement_level, parent_id, has_parent);
262 : :
263 : : // The new master element should start as active
264 : 852136 : active_elements.add(id);
265 : 852136 : }
266 : :
267 : : /**
268 : : * @brief Interface to add a tet from the original mesh (no parent)
269 : : */
270 : 502106 : void add(const tet_t& nodes, Refinement_Case refinement_case)
271 : : {
272 : 502106 : size_t id = id_generator.get_next_tet_id();
273 : 502106 : add_to_master(id, nodes, refinement_case);
274 : 502106 : }
275 : :
276 : : // NOTE: this does *not* deal with edges
277 : : /**
278 : : * @brief Function to delete a tet from the tet store (useful in
279 : : * derefinement)
280 : : *
281 : : * @param id id of the tet to delete
282 : : */
283 : 237192 : void erase(size_t id)
284 : : {
285 : 237192 : deactivate(id);
286 : 237192 : master_elements.erase(id);
287 : 237192 : tets.erase(id);
288 : : // TODO: Should this update the number of children here rather than at the call site?
289 : 237192 : }
290 : :
291 : : /**
292 : : * @brief Function to remove a tet from the active tet list
293 : : *
294 : : * @param id The id of the tet to deactivate
295 : : */
296 : 281189 : void deactivate(size_t id) {
297 : 281189 : active_elements.erase(id);
298 : : // TODO: For safety, should we also mark it's edges as not
299 : : // needing to be refined?
300 : 281189 : }
301 : :
302 : 29649 : void activate(size_t id) {
303 [ + - ]: 29649 : if (!is_active(id) )
304 : : {
305 : 29649 : active_elements.add(id);
306 : : }
307 : 29649 : }
308 : :
309 : : /**
310 : : * @brief Function to add a tet to a list which maintains what is a
311 : : * center tet. (The need to maintain a list could be replaced by a
312 : : * geometric check on the tet itself)
313 : : *
314 : : * @param id Id of the tet to add
315 : : */
316 : 77 : void add_center(size_t id)
317 : : {
318 : : // cppcheck-suppress assertWithSideEffect
319 [ - + ]: 77 : assert( !is_center(id) );
320 : 77 : center_tets.insert(id);
321 : 77 : }
322 : :
323 : : /**
324 : : * @brief function to check if a tet is a center tet in a 1:4
325 : : *
326 : : * @param id Id of the tet to check
327 : : *
328 : : * @return Bool stating if it's a center tet or not
329 : : */
330 : 345 : bool is_center(size_t id)
331 : : {
332 [ + - ][ + + ]: 345 : if (center_tets.find(id) != center_tets.end())
333 : : {
334 : 67 : return true;
335 : : }
336 : 278 : return false;
337 : : }
338 : :
339 : : /**
340 : : * @brief Function to get a list of refinement levels, useful for
341 : : * vis
342 : : *
343 : : * @return Vector containing refinement levels of tets
344 : : */
345 : 149 : std::vector< real_t > get_refinement_level_list() const
346 : : {
347 : 149 : std::vector<real_t> refinement_level_list;
348 : :
349 [ + + ]: 254083 : for (const auto& kv : tets)
350 : : {
351 : 253934 : size_t element_id = kv.first;
352 [ + - ][ + + ]: 253934 : if (active_elements.exists( element_id )) {
353 : 226606 : real_t val = static_cast< tk::real >(
354 [ + - ]: 226606 : master_elements.get(element_id).refinement_level );
355 [ + - ]: 226606 : refinement_level_list.push_back(val);
356 : : }
357 : : }
358 : :
359 : : trace_out << "Made refinement level list of len " << refinement_level_list.size() << std::endl;
360 : 149 : return refinement_level_list;
361 : : }
362 : :
363 : : /**
364 : : * @brief Function to return a list of cell types, useful when
365 : : * invoking the vis to do coloring by cell type
366 : : *
367 : : * @return Vector listening the types of cells
368 : : */
369 : 149 : std::vector< real_t > get_cell_type_list() const
370 : : {
371 : 149 : std::vector<real_t> cell_type_list;
372 : :
373 [ + + ]: 254083 : for (const auto& kv : tets)
374 : : {
375 : 253934 : size_t element_id = kv.first;
376 : :
377 [ + - ][ + + ]: 253934 : if (active_elements.exists( element_id )) {
378 : :
379 : 226606 : real_t val = 0.0;
380 : :
381 : : // Be a good citizen, make this enum human readable
382 [ + - ][ + + ]: 226606 : switch (master_elements.get(element_id).refinement_case)
[ + + ][ - - ]
[ - - ]
383 : : {
384 : 654 : case Refinement_Case::one_to_two:
385 : 654 : val = 2.0;
386 : 654 : break;
387 : 580 : case Refinement_Case::one_to_four:
388 : 580 : val = 4.0;
389 : 580 : break;
390 : 206726 : case Refinement_Case::one_to_eight:
391 : 206726 : val = 8.0;
392 : 206726 : break;
393 : 18646 : case Refinement_Case::initial_grid:
394 : 18646 : val = 1.0;
395 : 18646 : break;
396 : : // TODO: this will never actually happen, as a 2:8 currently views
397 : : // itself as a 1:8 (as it did a 2:1, and a 1:8)
398 : 0 : case Refinement_Case::two_to_eight:
399 : 0 : val = 2.8;
400 : 0 : break;
401 : 0 : case Refinement_Case::four_to_eight:
402 : 0 : val = 4.8;
403 : 0 : break;
404 : 0 : case Refinement_Case::none:
405 : 0 : val = 0.0;
406 : 0 : break;
407 : : }
408 [ + - ]: 226606 : cell_type_list.push_back(val);
409 : : }
410 : : }
411 : :
412 : : trace_out << "Made cell type list of len " << cell_type_list.size() << std::endl;
413 : 149 : return cell_type_list;
414 : : }
415 : :
416 : : /**
417 : : * @brief The function gives a way to go back from active_inpoel to
418 : : * real AMR id
419 : : *
420 : : * @return A vector which hold the AMR ids of the active inpoel
421 : : */
422 : : std::vector< std::size_t >& get_active_id_mapping()
423 : : {
424 : : active_id_mapping.clear();
425 : :
426 : : for (const auto& kv : tets)
427 : : {
428 : : size_t element_id = kv.first;
429 : :
430 : : if (is_active( element_id )) {
431 : : active_id_mapping.push_back( element_id );
432 : : }
433 : : }
434 : :
435 : : return active_id_mapping;
436 : : }
437 : :
438 : : /**
439 : : * @brief Function to extract only the active elements from tetinpeol
440 : : *
441 : : * @return List of only active elements
442 : : */
443 : : // TODO: need equiv for m_x/m_y/m_z? Otherwise there will be
444 : : // useless nodes in m_x etc? (Although that's functionally fine)
445 : 921 : std::vector< std::size_t >& get_active_inpoel()
446 : : {
447 : 921 : active_tetinpoel.clear();
448 : 921 : active_nodes.clear();
449 : :
450 [ + + ]: 1924961 : for (const auto& kv : tets)
451 : : {
452 : :
453 : 1924040 : size_t element_id = kv.first;
454 : 1924040 : auto t = kv.second;
455 : :
456 [ + - ][ + + ]: 1924040 : if (is_active( element_id )) {
457 [ + - ]: 1721714 : active_tetinpoel.push_back( t[0] );
458 [ + - ]: 1721714 : active_tetinpoel.push_back( t[1] );
459 [ + - ]: 1721714 : active_tetinpoel.push_back( t[2] );
460 [ + - ]: 1721714 : active_tetinpoel.push_back( t[3] );
461 : :
462 [ + - ]: 1721714 : active_nodes.insert( t[0] );
463 [ + - ]: 1721714 : active_nodes.insert( t[1] );
464 [ + - ]: 1721714 : active_nodes.insert( t[2] );
465 [ + - ]: 1721714 : active_nodes.insert( t[3] );
466 : : }
467 : : }
468 : :
469 : 921 : return active_tetinpoel;
470 : : }
471 : :
472 : : // TODO: These mark methods can probably be a single one to which a
473 : : // Refinement_Case is passed, depending on how extra edges are marked
474 : : /**
475 : : * @brief Function to mark a given tet as needing a 1:2 refinement
476 : : *
477 : : * @param tet_id The tet to mark
478 : : */
479 : 2945 : void mark_one_to_two(size_t tet_id)
480 : : {
481 : : // TODO: If none of these methods need extra markings, then
482 : : // change them into a single method
483 : : trace_out << "Mark " << tet_id << " as 1:2" << std::endl;
484 : 2945 : marked_refinements.add(tet_id, Refinement_Case::one_to_two);
485 : 2945 : }
486 : :
487 : : /**
488 : : * @brief Mark a given tet as needing a 1:4 refinement
489 : : *
490 : : * @param tet_id The tet to mark
491 : : */
492 : 1915 : void mark_one_to_four(size_t tet_id)
493 : : {
494 : : trace_out << "Mark " << tet_id << " as 1:4" << std::endl;
495 : 1915 : marked_refinements.add(tet_id, Refinement_Case::one_to_four);
496 : 1915 : }
497 : :
498 : : /**
499 : : * @brief Mark a given tet as needing a 2:8 refinement
500 : : *
501 : : * @param tet_id id of tet to mark
502 : : */
503 : 0 : void mark_two_to_eight(size_t tet_id)
504 : : {
505 : : trace_out << "Mark " << tet_id << " as 2:8" << std::endl;
506 : 0 : marked_refinements.add(tet_id, Refinement_Case::two_to_eight);
507 : 0 : }
508 : :
509 : : /**
510 : : * @brief Mark a given tet as needing a 4:8 refinement
511 : : *
512 : : * @param tet_id id of tet to mark
513 : : */
514 : 0 : void mark_four_to_eight(size_t tet_id)
515 : : {
516 : : trace_out << "Mark " << tet_id << " as 4:8" << std::endl;
517 : 0 : marked_refinements.add(tet_id, Refinement_Case::four_to_eight);
518 : 0 : }
519 : :
520 : : /**
521 : : * @brief Function to mark a given tet as needing a 1:8 refinement
522 : : *
523 : : * @param tet_id The tet to mark
524 : : */
525 : 112757 : void mark_one_to_eight(size_t tet_id)
526 : : {
527 : : trace_out << "Mark " << tet_id << " as 1:8" << std::endl;
528 : 112757 : marked_refinements.add(tet_id, Refinement_Case::one_to_eight);
529 : 112757 : }
530 : :
531 : 586208 : bool has_refinement_decision(size_t id)
532 : : {
533 : 586208 : return marked_refinements.exists(id);
534 : : }
535 : :
536 : : /**
537 : : * @brief Helper debug function to print tet information
538 : : */
539 : 141 : void print_tets() {
540 [ + + ]: 586349 : for (const auto& kv : tets)
541 : : {
542 : 586208 : tet_t tet = kv.second;
543 : :
544 : : trace_out << "Tet " << kv.first << " has edges :" <<
545 : : tet[0] << ", " <<
546 : : tet[1] << ", " <<
547 : : tet[2] << ", " <<
548 : : tet[3] << ", " <<
549 : : std::endl;
550 : : }
551 : 141 : }
552 : :
553 : : void print_edges()
554 : : {
555 : : edge_store.print();
556 : : }
557 : :
558 : 243 : void print_node_types()
559 : : {
560 : :
561 : 243 : int initial_grid = 0;
562 : 243 : int one_to_two = 0;
563 : 243 : int one_to_four = 0;
564 : 243 : int one_to_eight = 0;
565 : 243 : int other = 0;
566 : :
567 [ + + ]: 794147 : for (const auto& kv : tets)
568 : : {
569 : 793904 : size_t tet_id = kv.first;
570 [ + - ][ + + ]: 793904 : if (is_active(tet_id))
571 : : {
572 [ + - ][ + + ]: 707509 : switch(get_refinement_case(tet_id))
[ + + ][ - - ]
[ - - ]
573 : : {
574 : 654 : case Refinement_Case::one_to_two:
575 : 654 : one_to_two++;
576 : 654 : break;
577 : 580 : case Refinement_Case::one_to_four:
578 : 580 : one_to_four++;
579 : 580 : break;
580 : 679262 : case Refinement_Case::one_to_eight:
581 : 679262 : one_to_eight++;
582 : 679262 : break;
583 : 27013 : case Refinement_Case::initial_grid:
584 : 27013 : initial_grid++;
585 : 27013 : break;
586 : 0 : case Refinement_Case::two_to_eight:
587 : : // Don't care (yet)
588 : 0 : other++;
589 : 0 : break;
590 : 0 : case Refinement_Case::four_to_eight:
591 : : // Don't care (yet)
592 : 0 : other++;
593 : 0 : break;
594 : 0 : case Refinement_Case::none:
595 : : // Don't care (yet)
596 : 0 : other++;
597 : 0 : break;
598 : : }
599 : :
600 : : }
601 : : }
602 : :
603 : : //std::cout << "Active Totals:" << std::endl;
604 : : //std::cout << " --> Initial = " << initial_grid << std::endl;
605 : : //std::cout << " --> 1:2 = " << one_to_two << std::endl;
606 : : //std::cout << " --> 1:4 = " << one_to_four << std::endl;
607 : : //std::cout << " --> 1:8 = " << one_to_eight << std::endl;
608 : 243 : }
609 : :
610 : 4102424 : edge_list_t generate_edge_keys(size_t tet_id)
611 : : {
612 [ + - ]: 4102424 : tet_t tet = get(tet_id);
613 [ + - ]: 8204848 : return edge_store.generate_keys(tet);
614 : : }
615 : :
616 : 502379 : void generate_edges(size_t i) {
617 : : // For tet ABCD, edges are:
618 : : // AB, AC, AD, BC, BD, CD
619 : : //
620 [ + - ]: 502379 : edge_list_t edge_list = generate_edge_keys(i);
621 : :
622 [ + + ]: 3516653 : for (size_t j = 0; j < NUM_TET_EDGES; j++)
623 : : {
624 : 3014274 : edge_t edge = edge_list[j];
625 : :
626 : 3014274 : size_t A = edge.first();
627 : 3014274 : size_t B = edge.second();
628 : :
629 : : Edge_Refinement er = Edge_Refinement(A, B, false,
630 : 3014274 : false, Edge_Lock_Case::unlocked);
631 : :
632 [ + - ]: 3014274 : edge_store.add(edge, er);
633 : : }
634 : 502379 : }
635 : :
636 : : /**
637 : : * @brief function to take a tet_id, finds it's nodes, and
638 : : * expresses them as faces
639 : : *
640 : : * Take tet ABCD, generate faces {ABC, ABD, ACD, BCD}
641 : : *
642 : : * @param tet_id The tet to generate faces for
643 : : *
644 : : * @return A list of faces making this tet
645 : : */
646 : 6147 : face_list_t generate_face_lists(size_t tet_id)
647 : : {
648 : : // Hard code this for now...
649 [ + - ]: 6147 : tet_t tet = get(tet_id);
650 : :
651 : : trace_out << "Tet has nodes " <<
652 : : tet[0] << ", " <<
653 : : tet[1] << ", " <<
654 : : tet[2] << ", " <<
655 : : tet[3] << ", " <<
656 : : std::endl;
657 : :
658 : : face_list_t face_list;
659 : :
660 : : // ABC
661 : 6147 : face_list[0][0] = tet[0];
662 : 6147 : face_list[0][1] = tet[1];
663 : 6147 : face_list[0][2] = tet[2];
664 : :
665 : : // ABD
666 : 6147 : face_list[1][0] = tet[0];
667 : 6147 : face_list[1][1] = tet[3];
668 : 6147 : face_list[1][2] = tet[1];
669 : :
670 : : // ACD
671 : 6147 : face_list[2][0] = tet[0];
672 : 6147 : face_list[2][1] = tet[2];
673 : 6147 : face_list[2][2] = tet[3];
674 : :
675 : : // BCD
676 : 6147 : face_list[3][0] = tet[1];
677 : 6147 : face_list[3][1] = tet[3];
678 : 6147 : face_list[3][2] = tet[2];
679 : :
680 : 12294 : return face_list;
681 : : }
682 : :
683 : : /**
684 : : * @brief Function which marks all edges in a given tet as needing
685 : : * to be refined
686 : : *
687 : : * @param tet_id ID of the tet to mark
688 : : */
689 : 112757 : void mark_edges_for_refinement(size_t tet_id)
690 : : {
691 [ + - ]: 112757 : edge_list_t edge_list = generate_edge_keys(tet_id);
692 [ + + ]: 789299 : for (size_t k = 0; k < NUM_TET_EDGES; k++)
693 : : {
694 : 676542 : edge_t edge = edge_list[k];
695 [ + - ]: 676542 : edge_store.mark_for_refinement(edge);
696 : : trace_out << "Marking edge " << edge << " for refine " << std::endl;
697 : : }
698 : 112757 : }
699 : :
700 : : /**
701 : : * @brief Delete existing edges. Iterate over the tets, and add them to
702 : : * the edge store.
703 : : */
704 : : // FIXME: Better name for this?
705 : 2005 : void generate_edges() {
706 : :
707 : : // Go over tets, and generate all known edges
708 : 2005 : edge_store.edges.clear();
709 : :
710 : : // Jump over tets
711 [ + + ]: 504111 : for (const auto& kv : tets)
712 : : {
713 : 502106 : size_t tet_id = kv.first;
714 [ + - ]: 502106 : generate_edges(tet_id);
715 : : }
716 : 2005 : }
717 : :
718 : 0 : void unset_marked_children(size_t parent_id)
719 : : {
720 : 0 : Refinement_State& parent = data(parent_id);
721 [ - - ]: 0 : for (auto c : parent.children)
722 : : {
723 [ - - ]: 0 : marked_refinements.erase(c);
724 : : }
725 : 0 : }
726 : :
727 : 43997 : child_id_list_t generate_child_ids(size_t parent_id, size_t count = MAX_CHILDREN)
728 : : {
729 : 43997 : return id_generator.generate_child_ids(parent_id, count);
730 : : }
731 : 373594 : size_t get_child_id(size_t parent_id, size_t offset) const
732 : : {
733 : 373594 : return master_elements.get_child_id(parent_id, offset);
734 : : }
735 : :
736 : 92 : size_t get_parent_id(size_t id) const
737 : : {
738 : 92 : return master_elements.get_parent(id);
739 : : }
740 : :
741 : : // Deref
742 : 102 : void process_delete_list()
743 : : {
744 : : trace_out << "process_delete_list " << delete_list.size() << std::endl;
745 : 102 : size_t original_size = size();
746 [ - + ]: 102 : for(auto f : delete_list) {
747 [ - - ]: 0 : erase(f);
748 : : }
749 : :
750 : 102 : size_t end_size = size();
751 : : trace_out << "Deleted " << original_size-end_size << std::endl;
752 : :
753 : 102 : delete_list.clear();
754 : 102 : }
755 : : /**
756 : : * @brief Function to mark a given tet as a specific Derefinement_Case
757 : : *
758 : : * @param tet_id The tet to mark
759 : : * @param decision The Derefinement_case to set
760 : : */
761 : 60379 : void mark_derefinement_decision(size_t tet_id, AMR::Derefinement_Case decision)
762 : : {
763 : : trace_out << "MARKING_DEREF_DECISION" << std::endl;
764 : 60379 : marked_derefinements.add(tet_id, decision);
765 : 60379 : }
766 : 207696 : bool has_derefinement_decision(size_t id)
767 : : {
768 : 207696 : return marked_derefinements.exists(id);
769 : : }
770 : :
771 : : };
772 : : }
773 : :
774 : : #endif // guard
|