19 #include "libmesh/libmesh_config.h"
20 #include "libmesh/libmesh_logging.h"
21 #include "libmesh/dof_map.h"
22 #include "libmesh/elem.h"
23 #include "libmesh/dyna_io.h"
24 #include "libmesh/mesh_base.h"
25 #include "libmesh/int_range.h"
62 for (
unsigned int i=1; i != 2; ++i)
75 {0, 4, 1, 7, 8, 5, 3, 6, 2}));
78 {0, 1, 3, 2, 4, 5, 7, 6}));
80 { 0, 8, 1, 11, 20, 9, 3, 10, 2,
81 12, 21, 13, 24, 26, 22, 15, 23, 14,
82 4, 16, 5, 19, 25, 17, 7, 18, 6}));
96 dyna_type(dyna_type_in),
102 std::iota(nodes.begin(), nodes.end(), 0);
111 std::vector<unsigned int> && nodes_in) :
113 dyna_type(dyna_type_in),
123 constraint_rows_broadcast (false)
131 std::ifstream in (
name.c_str());
164 ELEM_SUBBLOCK_HEADER,
178 FileSection section = FILE_HEADER;
183 std::vector<dyna_int_type>
190 std::vector<dyna_int_type>
191 n_coef_vecs_in_subblock, n_coef_comp;
192 unsigned char weight_index = 0;
194 n_elem_blocks_read = 0,
196 n_elem_nodes_read = 0,
197 n_elem_cvids_read = 0,
198 n_coef_headers_read = 0,
199 n_coef_blocks_read = 0,
200 n_coef_comp_read = 0,
201 n_coef_vecs_read = 0;
208 std::vector<Real> spline_weights;
213 std::vector<std::vector<std::vector<dof_id_type>>> elem_global_nodes;
220 std::vector<std::vector<std::vector<Real>>> dense_constraint_vecs;
224 std::vector<std::vector<std::vector<dof_id_type>>> elem_constraint_rows;
235 if (s.find(
"B E X T 2.0") == static_cast<std::string::size_type>(0))
237 libmesh_assert_equal_to(section, FILE_HEADER);
238 section = PATCH_HEADER;
243 if (s.find(
"$#") == static_cast<std::string::size_type>(0))
247 if (s.find_first_not_of(
" \t") == std::string::npos)
251 std::stringstream stream(s);
255 stream >> n_spline_nodes;
257 stream >> n_coef_vec;
258 stream >> weight_control_flag;
260 libmesh_error_msg(
"Failure to parse patch header\n");
263 spline_weights.resize(n_spline_nodes);
265 if (weight_control_flag)
267 weight_index = cast_int<unsigned char>
273 section = NODE_LINES;
277 std::array<dyna_fp_type, 4> xyzw;
283 if (weight_control_flag)
284 spline_weights[n_nodes_read] = xyzw[3];
298 libmesh_error_msg(
"Failure to parse node line\n");
300 if (n_nodes_read >= n_spline_nodes)
301 section = N_ELEM_SUBBLOCKS;
303 case N_ELEM_SUBBLOCKS:
304 stream >> n_elem_blocks;
306 libmesh_error_msg(
"Failure to parse n_elem_blocks\n");
308 block_elem_type.resize(n_elem_blocks);
309 block_n_elem.resize(n_elem_blocks);
310 block_n_nodes.resize(n_elem_blocks);
311 block_n_coef_vec.resize(n_elem_blocks);
312 block_p.resize(n_elem_blocks);
313 block_dim.resize(n_elem_blocks);
315 elem_global_nodes.resize(n_elem_blocks);
316 elem_constraint_rows.resize(n_elem_blocks);
318 n_elem_blocks_read = 0;
319 section = ELEM_SUBBLOCK_HEADER;
321 case ELEM_SUBBLOCK_HEADER:
322 stream >> block_elem_type[n_elem_blocks_read];
323 stream >> block_n_elem[n_elem_blocks_read];
324 stream >> block_n_nodes[n_elem_blocks_read];
325 stream >> block_n_coef_vec[n_elem_blocks_read];
326 stream >> block_p[n_elem_blocks_read];
329 libmesh_error_msg(
"Failure to parse elem block\n");
331 block_dim[n_elem_blocks_read] = 1;
334 stream >> block_other_p;
337 block_dim[n_elem_blocks_read] = 2;
339 if (block_other_p != block_p[n_elem_blocks_read])
340 libmesh_not_implemented();
342 stream >> block_other_p;
345 block_dim[n_elem_blocks_read] = 3;
347 if (block_other_p != block_p[n_elem_blocks_read])
348 libmesh_not_implemented();
353 auto & block_global_nodes = elem_global_nodes[n_elem_blocks_read];
354 auto & block_constraint_rows = elem_constraint_rows[n_elem_blocks_read];
356 block_global_nodes.resize(block_n_elem[n_elem_blocks_read]);
357 block_constraint_rows.resize(block_n_elem[n_elem_blocks_read]);
360 (0, block_n_elem[n_elem_blocks_read]))
362 block_global_nodes[e].resize(block_n_nodes[n_elem_blocks_read]);
363 block_constraint_rows[e].resize(block_n_coef_vec[n_elem_blocks_read]);
367 n_elem_blocks_read++;
368 if (n_elem_blocks_read == n_elem_blocks)
370 n_elem_blocks_read = 0;
372 section = ELEM_NODES_LINES;
375 case ELEM_NODES_LINES:
377 const int end_node_to_read =
378 std::min(block_n_nodes[n_elem_blocks_read], n_elem_nodes_read +
max_ints_per_line);
379 for (; n_elem_nodes_read != end_node_to_read; ++n_elem_nodes_read)
384 elem_global_nodes[n_elem_blocks_read][n_elems_read][n_elem_nodes_read] = node_id;
390 libmesh_error_msg(
"Failure to parse elem nodes\n");
393 if (n_elem_nodes_read == block_n_nodes[n_elem_blocks_read])
395 n_elem_nodes_read = 0;
396 section = ELEM_COEF_VEC_IDS;
400 case ELEM_COEF_VEC_IDS:
402 const int end_cvid_to_read =
403 std::min(block_n_coef_vec[n_elem_blocks_read], n_elem_cvids_read +
max_ints_per_line);
404 for (; n_elem_cvids_read != end_cvid_to_read; ++n_elem_cvids_read)
410 elem_constraint_rows[n_elem_blocks_read][n_elems_read][n_elem_cvids_read] = node_cvid;
416 libmesh_error_msg(
"Failure to parse elem cvids\n");
418 if (n_elem_cvids_read == block_n_nodes[n_elem_blocks_read])
420 n_elem_cvids_read = 0;
422 section = ELEM_NODES_LINES;
423 if (n_elems_read == block_n_elem[n_elem_blocks_read])
426 n_elem_blocks_read++;
427 if (n_elem_blocks_read == n_elem_blocks)
428 section = N_COEF_BLOCKS;
435 stream >> n_dense_coef_vec_blocks;
437 stream >> n_sparse_coef_vec_blocks;
440 libmesh_error_msg(
"Failure to parse n_*_coef_vec_blocks\n");
442 if (n_sparse_coef_vec_blocks != 0)
443 libmesh_not_implemented();
445 dense_constraint_vecs.resize(n_dense_coef_vec_blocks);
446 n_coef_vecs_in_subblock.resize(n_dense_coef_vec_blocks);
447 n_coef_comp.resize(n_dense_coef_vec_blocks);
449 section = N_VECS_PER_BLOCK;
452 case N_VECS_PER_BLOCK:
453 stream >> n_coef_vecs_in_subblock[n_coef_headers_read];
454 stream >> n_coef_comp[n_coef_headers_read];
457 libmesh_error_msg(
"Failure to parse dense coef subblock header\n");
459 dense_constraint_vecs[n_coef_headers_read].resize
460 (n_coef_vecs_in_subblock[n_coef_headers_read]);
462 for (
auto & vec : dense_constraint_vecs[n_coef_headers_read])
463 vec.resize(n_coef_comp[n_coef_headers_read]);
465 n_coef_headers_read++;
466 if (n_coef_headers_read == n_dense_coef_vec_blocks)
468 n_coef_headers_read = 0;
469 section = COEF_VEC_COMPONENTS;
472 case COEF_VEC_COMPONENTS:
475 dense_constraint_vecs[n_coef_blocks_read][n_coef_vecs_read];
477 const int end_coef_to_read =
478 std::min(n_coef_comp[n_coef_blocks_read],
480 for (; n_coef_comp_read != end_coef_to_read; ++n_coef_comp_read)
485 current_vec[n_coef_comp_read] = coef_comp;
491 libmesh_error_msg(
"Failure to parse coefficients\n");
493 if (n_coef_comp_read == n_coef_comp[n_coef_blocks_read])
495 n_coef_comp_read = 0;
497 if (n_coef_vecs_read == n_coef_vecs_in_subblock[n_coef_blocks_read])
499 n_coef_vecs_read = 0;
500 n_coef_blocks_read++;
501 if (n_coef_blocks_read == n_dense_coef_vec_blocks)
502 section = END_OF_FILE;
511 if (section == END_OF_FILE)
515 libmesh_error_msg(
"Premature end of file");
517 libmesh_error_msg(
"Input stream failure! Perhaps the file does not exist?");
521 for (
auto coef_vec_block :
524 auto & dcv0 = dense_constraint_vecs[0];
525 auto & dcvi = dense_constraint_vecs[coef_vec_block];
526 dcv0.insert(dcv0.end(),
527 std::make_move_iterator(dcvi.begin()),
528 std::make_move_iterator(dcvi.end()));
530 dense_constraint_vecs.resize(1);
534 std::vector<std::vector<std::vector<std::vector<Real>>>> elem_constraint_mat(n_elem_blocks);
540 std::map<std::vector<std::pair<dof_id_type, Real>>,
Node *> local_nodes;
544 elem_constraint_mat[block_num].resize(block_n_elem[block_num]);
552 block_dim[block_num],
553 block_p[block_num]));
558 (
"Element of type " << block_elem_type[block_num] <<
559 " dim " << block_dim[block_num] <<
560 " degree " << block_p[block_num] <<
" not found!");
564 libmesh_assert_equal_to(elem->
dim(), block_dim[block_num]);
566 auto & my_constraint_rows = elem_constraint_rows[block_num][elem_num];
567 auto & my_global_nodes = elem_global_nodes[block_num][elem_num];
568 auto & my_constraint_mat = elem_constraint_mat[block_num][elem_num];
570 my_constraint_mat.resize(block_n_coef_vec[block_num]);
571 for (
auto spline_node_index :
573 my_constraint_mat[spline_node_index].resize(elem->
n_nodes());
575 for (
auto spline_node_index :
580 my_constraint_rows[spline_node_index];
584 for (; elem_coef_vec_index >= first_block_coef_vec &&
585 coef_block_num != n_dense_coef_vec_blocks; ++coef_block_num)
587 first_block_coef_vec += n_coef_vecs_in_subblock[coef_block_num];
591 if (coef_block_num == n_dense_coef_vec_blocks &&
592 first_block_coef_vec <= elem_coef_vec_index)
593 libmesh_error_msg(
"Can't find valid constraint coef vector");
598 n_coef_comp[coef_block_num])
599 libmesh_error_msg(
"Found " <<
600 n_coef_comp[coef_block_num] <<
601 " constraint coef vectors for " <<
604 for (
auto elem_node_index :
606 my_constraint_mat[spline_node_index][elem_node_index] =
607 dense_constraint_vecs[0][elem_coef_vec_index][elem_node_index];
610 for (
auto elem_node_index :
618 std::vector<std::pair<dof_id_type, Real>> key;
620 for (
auto spline_node_index :
624 my_constraint_rows[spline_node_index];
627 dense_constraint_vecs[0][elem_coef_vec_index][elem_node_index];
631 libmesh_assert_greater(my_global_nodes[spline_node_index],
633 global_node_idx = my_global_nodes[spline_node_index];
636 key.push_back(std::make_pair(global_node_idx, coef));
639 auto local_node_it = local_nodes.find(key);
641 if (local_node_it != local_nodes.end())
643 local_node_it->second;
648 std::vector<std::pair<dof_id_type, Real>> constraint_row;
650 for (
auto spline_node_index :
654 my_global_nodes[spline_node_index];
657 my_constraint_rows[spline_node_index];
662 dense_constraint_vecs[0][elem_coef_vec_index][elem_node_index];
664 w += coef * spline_weights[my_node_idx];
666 constraint_row.push_back(std::make_pair(spline_node->
id(), coef));
670 if (weight_control_flag)
672 local_nodes[key] = n;
686 unsigned int sys_num,
687 unsigned int var_num)
689 #ifdef LIBMESH_ENABLE_CONSTRAINTS
696 libmesh_not_implemented();
714 for (
auto pr : node_row.second)
719 dc_row[spline_dof_id] = pr.second;
725 libmesh_not_implemented();