12 #include "../config/config.hpp" 28 FmsBasisTypeToMfemBasis(FmsBasisType
b)
33 case FMS_NODAL_GAUSS_OPEN:
36 case FMS_NODAL_GAUSS_CLOSED:
42 case FMS_NODAL_UNIFORM_OPEN:
45 case FMS_NODAL_UNIFORM_CLOSED:
48 case FMS_NODAL_CHEBYSHEV_OPEN:
49 case FMS_NODAL_CHEBYSHEV_CLOSED:
51 "FMS_NODAL_CHEBYSHEV_OPEN, FMS_NODAL_CHEBYSHEV_CLOSED need conversion to MFEM types." 65 FmsFieldGetOrderAndLayout(FmsField
f, FmsInt *f_order, FmsLayoutType *f_layout)
68 FmsFieldDescriptor fd;
70 FmsScalarType data_type;
71 const void *data =
nullptr;
74 FmsFieldGet(
f, &fd, NULL, &layout, &data_type,
77 FmsFieldDescriptorType f_fd_type;
78 FmsFieldDescriptorGetType(fd, &f_fd_type);
79 if (f_fd_type != FMS_FIXED_ORDER)
85 FmsFieldType field_type;
86 FmsBasisType basis_type;
87 FmsFieldDescriptorGetFixedOrder(fd, &field_type,
105 template <
typename DataType>
115 FmsInt
dim, n_elem, space_dim;
120 FmsMeshGetNumComponents(fms_mesh, &num_comp);
121 FmsComponent main_comp = NULL;
122 FmsField coords = NULL;
123 for (FmsInt comp_id = 0; comp_id < num_comp; comp_id++)
126 FmsMeshGetComponent(fms_mesh, comp_id, &comp);
127 FmsComponentGetCoordinates(comp, &coords);
128 if (coords) { main_comp = comp;
break; }
130 if (!main_comp) {
return 1; }
131 FmsComponentGetDimension(main_comp, &
dim);
132 FmsComponentGetNumEntities(main_comp, &n_elem);
133 FmsInt n_ents[FMS_NUM_ENTITY_TYPES];
135 FmsComponentGetNumParts(main_comp, &n_main_parts);
136 for (FmsInt et = FMS_VERTEX; et < FMS_NUM_ENTITY_TYPES; et++)
139 for (FmsInt part_id = 0; part_id < n_main_parts; part_id++)
142 FmsComponentGetPart(main_comp, part_id, (FmsEntityType)et, NULL, NULL,
143 NULL, NULL, &num_ents);
144 n_ents[et] += num_ents;
150 FmsFieldDescriptor f_fd;
151 FmsLayoutType f_layout;
152 FmsScalarType f_data_type;
154 FmsFieldGet(
f, &f_fd, &space_dim, &f_layout, &f_data_type,
159 FmsFieldDescriptorGetNumDofs(f_fd, &f_num_dofs);
162 auto src_data =
reinterpret_cast<const DataType *
>(f_data);
164 FmsFieldDescriptorType f_fd_type;
165 FmsFieldDescriptorGetType(f_fd, &f_fd_type);
166 if (f_fd_type != FMS_FIXED_ORDER)
170 FmsFieldType f_field_type;
171 FmsBasisType f_basis_type;
173 FmsFieldDescriptorGetFixedOrder(f_fd, &f_field_type,
174 &f_basis_type, &f_order);
176 if (f_field_type != FMS_CONTINUOUS && f_field_type != FMS_DISCONTINUOUS &&
177 f_field_type != FMS_HDIV)
182 int btype = FmsBasisTypeToMfemBasis(f_basis_type);
196 switch (f_field_type)
198 case FMS_DISCONTINUOUS:
208 case FMS_DISCONTINUOUS_WEIGHTED:
209 MFEM_ABORT(
"Field types FMS_HCURL and FMS_DISCONTINUOUS_WEIGHTED" 210 " are not supported yet.");
219 const FmsInt nstride = (f_layout == FMS_BY_VDIM) ? space_dim : 1;
220 const FmsInt vstride = (f_layout == FMS_BY_VDIM) ? 1 : f_num_dofs;
223 if ((FmsInt)(func.
Size()) != f_num_dofs*space_dim)
229 const int vdim = fes->
GetVDim();
237 int ent_dofs[FMS_NUM_ENTITY_TYPES];
238 ent_dofs[FMS_VERTEX] = vert_dofs;
239 ent_dofs[FMS_EDGE] = edge_dofs;
240 ent_dofs[FMS_TRIANGLE] = tri_dofs;
241 ent_dofs[FMS_QUADRILATERAL] = quad_dofs;
242 ent_dofs[FMS_TETRAHEDRON] = tet_dofs;
243 ent_dofs[FMS_HEXAHEDRON] = hex_dofs;
244 FmsInt fms_dof_offset = 0;
245 int mfem_ent_cnt[4] = {0,0,0,0};
246 int mfem_last_vert_cnt = 0;
249 if (
dim >= 2 && edge_dofs > 0)
252 for (
int i = 0; i < mesh->
GetNEdges(); i++)
255 int id = mfem_edge.
GetId(ev[0], ev[1]);
256 if (
id != i) {
return 13; }
260 ((n_ents[FMS_TRIANGLE] > 0 && tri_dofs > 0) ||
261 (n_ents[FMS_QUADRILATERAL] > 0 && quad_dofs > 0)))
264 for (
int i = 0; i < mesh->
GetNFaces(); i++)
269 int id = mfem_face.
GetId(fv[0], fv[1], fv[2], fv[3]);
270 if (
id != i) {
return 14; }
275 for (FmsInt part_id = 0; part_id < n_main_parts; part_id++)
278 for (FmsInt et = FMS_VERTEX; et < FMS_NUM_ENTITY_TYPES; et++)
281 FmsIntType ent_id_type;
283 const FmsOrientation *ents_ori;
285 FmsComponentGetPart(main_comp, part_id, (FmsEntityType)et, &domain,
286 &ent_id_type, &ents, &ents_ori, &num_ents);
287 if (num_ents == 0) {
continue; }
288 if (ent_dofs[et] == 0)
290 if (et == FMS_VERTEX) { mfem_last_vert_cnt = mfem_ent_cnt[et]; }
291 mfem_ent_cnt[FmsEntityDim[et]] += num_ents;
296 (ent_id_type != FMS_INT32 && ent_id_type != FMS_UINT32))
300 if (ents_ori != NULL)
305 if (et == FMS_VERTEX)
307 const int mfem_dof_offset = mfem_ent_cnt[0]*vert_dofs;
308 for (FmsInt i = 0; i < num_ents*vert_dofs; i++)
310 for (
int j = 0; j < vdim; j++)
312 const int idx = i*nstride+j*vstride;
313 func(mfem_dof_offset*nstride+idx) =
314 static_cast<double>(src_data[fms_dof_offset*nstride+idx]);
317 fms_dof_offset += num_ents*vert_dofs;
318 mfem_last_vert_cnt = mfem_ent_cnt[et];
319 mfem_ent_cnt[0] += num_ents;
323 if (FmsEntityDim[et] ==
dim)
325 for (FmsInt e = 0; e < num_ents; e++)
328 for (
int i = 0; i < ent_dofs[et]; i++, fms_dof_offset++)
330 for (
int j = 0; j < vdim; j++)
333 static_cast<double>(src_data[fms_dof_offset*nstride+j*vstride]);
337 mfem_ent_cnt[
dim] += num_ents;
340 const FmsInt nv = FmsEntityNumVerts[et];
342 const int *ei = (
const int *)ents;
345 FmsDomainGetEntitiesVerts(domain, (FmsEntityType)et, NULL, FMS_INT32,
346 0, ents_verts.GetData(), num_ents);
350 for (FmsInt i = 0; i < num_ents; i++)
352 FmsDomainGetEntitiesVerts(domain, (FmsEntityType)et, NULL,
353 FMS_INT32, ei[i], &ents_verts[i*nv], 1);
356 for (
int i = 0; i < ents_verts.Size(); i++)
358 ents_verts[i] += mfem_last_vert_cnt;
361 switch ((FmsEntityType)et)
365 for (FmsInt part_ent_id = 0; part_ent_id < num_ents; part_ent_id++)
367 const int *ev = &ents_verts[2*part_ent_id];
368 int mfem_edge_id = mfem_edge.
FindId(ev[0], ev[1]);
369 if (mfem_edge_id < 0)
374 int ori = (ev[0] == m_ev[0]) ? 0 : 1;
377 for (
int i = 0; i < edge_dofs; i++)
379 for (
int j = 0; j < vdim; j++)
382 static_cast<double>(src_data[(fms_dof_offset+perm[i])*nstride+j*vstride]);
385 fms_dof_offset += edge_dofs;
391 for (FmsInt part_ent_id = 0; part_ent_id < num_ents; part_ent_id++)
393 const int *tv = &ents_verts[3*part_ent_id];
394 int mfem_face_id = mfem_face.
FindId(tv[0], tv[1], tv[2], INT_MAX);
395 if (mfem_face_id < 0)
401 while (tv[ori] != m_ev[0]) { ori++; }
402 ori = (tv[(ori+1)%3] == m_ev[1]) ? 2*ori : 2*ori+1;
405 for (
int i = 0; i < tri_dofs; i++)
407 for (
int j = 0; j < vdim; j++)
410 static_cast<double>(src_data[(fms_dof_offset+perm[i])*nstride+j*vstride]);
413 fms_dof_offset += tri_dofs;
417 case FMS_QUADRILATERAL:
419 for (FmsInt part_ent_id = 0; part_ent_id < num_ents; part_ent_id++)
421 const int *qv = &ents_verts[4*part_ent_id];
422 int mfem_face_id = mfem_face.
FindId(qv[0], qv[1], qv[2], qv[3]);
423 if (mfem_face_id < 0) {
return 19; }
426 while (qv[ori] != m_ev[0]) { ori++; }
427 ori = (qv[(ori+1)%4] == m_ev[1]) ? 2*ori : 2*ori+1;
430 for (
int i = 0; i < quad_dofs; i++)
432 for (
int j = 0; j < vdim; j++)
435 static_cast<double>(src_data[(fms_dof_offset+perm[i])*nstride+j*vstride]);
438 fms_dof_offset += quad_dofs;
444 mfem_ent_cnt[FmsEntityDim[et]] += num_ents;
454 FmsInt
dim, n_vert, n_elem, n_bdr_elem, space_dim;
459 FmsMeshGetNumComponents(fms_mesh, &num_comp);
460 FmsComponent main_comp = NULL;
461 FmsField coords = NULL;
462 for (FmsInt comp_id = 0; comp_id < num_comp; comp_id++)
465 FmsMeshGetComponent(fms_mesh, comp_id, &comp);
466 FmsComponentGetCoordinates(comp, &coords);
467 if (coords) { main_comp = comp;
break; }
469 if (!main_comp) {
return 1; }
470 FmsComponentGetDimension(main_comp, &
dim);
471 FmsComponentGetNumEntities(main_comp, &n_elem);
472 FmsInt n_ents[FMS_NUM_ENTITY_TYPES];
474 FmsComponentGetNumParts(main_comp, &n_main_parts);
476 #define RENUMBER_ENTITIES 477 #ifdef RENUMBER_ENTITIES 486 int *verts_per_part =
new int[n_main_parts];
490 for (FmsInt et = FMS_VERTEX; et < FMS_NUM_ENTITY_TYPES; et++)
493 for (FmsInt part_id = 0; part_id < n_main_parts; part_id++)
496 FmsComponentGetPart(main_comp, part_id, (FmsEntityType)et, NULL, NULL,
497 NULL, NULL, &num_ents);
498 n_ents[et] += num_ents;
499 #ifdef RENUMBER_ENTITIES 500 if (et == FMS_VERTEX)
502 verts_per_part[part_id] = num_ents;
507 n_vert = n_ents[FMS_VERTEX];
509 #ifdef RENUMBER_ENTITIES 510 int *verts_start =
new int[n_main_parts];
512 for (FmsInt i = 1; i < n_main_parts; ++i)
514 verts_start[i] = verts_start[i-1] + verts_per_part[i-1];
520 FmsComponent bdr_comp = NULL;
521 FmsInt num_rel_comps;
522 const FmsInt *rel_comp_ids;
523 FmsComponentGetRelations(main_comp, &rel_comp_ids, &num_rel_comps);
524 for (FmsInt i = 0; i < num_rel_comps; i++)
527 FmsMeshGetComponent(fms_mesh, rel_comp_ids[i], &comp);
529 FmsComponentGetDimension(comp, &comp_dim);
530 if (comp_dim ==
dim-1) { bdr_comp = comp;
break; }
534 FmsComponentGetNumEntities(bdr_comp, &n_bdr_elem);
541 FmsFieldGet(coords, NULL, &space_dim, NULL, NULL, NULL);
543 Mesh *mesh =
nullptr;
544 mesh =
new Mesh(
dim, n_vert, n_elem, n_bdr_elem, space_dim);
548 FmsMeshGetNumTags(fms_mesh, &num_tags);
549 FmsTag elem_tag = NULL, bdr_tag = NULL;
550 for (FmsInt tag_id = 0; tag_id < num_tags; tag_id++)
553 FmsMeshGetTag(fms_mesh, tag_id, &tag);
555 FmsTagGetComponent(tag, &comp);
556 if (!elem_tag && comp == main_comp)
559 const char *tn = NULL;
560 FmsTagGetName(tag, &tn);
561 mfem::out <<
"Found element tag " << tn << std::endl;
565 else if (!bdr_tag && comp == bdr_comp)
568 const char *tn = NULL;
569 FmsTagGetName(tag, &tn);
570 mfem::out <<
"Found boundary tag " << tn << std::endl;
575 FmsIntType attr_type;
576 const void *v_attr, *v_bdr_attr;
582 FmsTagGet(elem_tag, &attr_type, &v_attr, &num_attr);
583 if (attr_type == FMS_UINT8)
588 else if (attr_type == FMS_INT32 || attr_type == FMS_UINT32)
590 attr.
MakeRef((
int*)v_attr, num_attr);
601 FmsTagGet(bdr_tag, &attr_type, &v_bdr_attr, &num_attr);
602 if (attr_type == FMS_UINT8)
607 else if (attr_type == FMS_INT32 || attr_type == FMS_UINT32)
609 bdr_attr.
MakeRef((
int*)v_bdr_attr, num_attr);
619 for (FmsInt part_id = 0; part_id < n_main_parts; part_id++)
621 for (
int et = FMS_VERTEX; et < FMS_NUM_ENTITY_TYPES; et++)
623 if (FmsEntityDim[et] !=
dim) {
continue; }
626 FmsIntType elem_id_type;
627 const void *elem_ids;
628 const FmsOrientation *elem_ori;
630 FmsComponentGetPart(main_comp, part_id, (FmsEntityType)et, &domain,
631 &elem_id_type, &elem_ids, &elem_ori, &num_elems);
633 if (num_elems == 0) {
continue; }
635 if (elem_ids != NULL &&
636 (elem_id_type != FMS_INT32 && elem_id_type != FMS_UINT32))
638 err = 3;
goto func_exit;
640 if (elem_ori != NULL)
642 err = 4;
goto func_exit;
645 const FmsInt nv = FmsEntityNumVerts[et];
647 if (elem_ids == NULL)
649 FmsDomainGetEntitiesVerts(domain, (FmsEntityType)et, NULL, FMS_INT32,
650 0, ents_verts.
GetData(), num_elems);
654 const int *ei = (
const int *)elem_ids;
655 for (FmsInt i = 0; i < num_elems; i++)
657 FmsDomainGetEntitiesVerts(domain, (FmsEntityType)et, NULL, FMS_INT32,
658 ei[i], &ents_verts[i*nv], 1);
661 const int elem_offset = mesh->
GetNE();
662 switch ((FmsEntityType)et)
669 #ifdef RENUMBER_ENTITIES 673 for (FmsInt i = 0; i < num_elems*3; i++)
675 ents_verts[i] += verts_start[part_id];
679 for (FmsInt i = 0; i < num_elems; i++)
682 &ents_verts[3*i], elem_tag ? attr[elem_offset+i] : 1);
685 case FMS_QUADRILATERAL:
686 #ifdef RENUMBER_ENTITIES 687 for (FmsInt i = 0; i < num_elems*4; i++)
689 ents_verts[i] += verts_start[part_id];
692 for (FmsInt i = 0; i < num_elems; i++)
694 mesh->
AddQuad(&ents_verts[4*i], elem_tag ? attr[elem_offset+i] : 1);
697 case FMS_TETRAHEDRON:
698 #ifdef RENUMBER_ENTITIES 699 for (FmsInt i = 0; i < num_elems*4; i++)
701 ents_verts[i] += verts_start[part_id];
704 for (FmsInt i = 0; i < num_elems; i++)
706 mesh->
AddTet(&ents_verts[4*i], elem_tag ? attr[elem_offset+i] : 1);
714 #ifdef RENUMBER_ENTITIES 715 for (FmsInt i = 0; i < num_elems*8; i++)
717 ents_verts[i] += verts_start[part_id];
721 for (FmsInt i = 0; i < num_elems; i++)
723 const int *hex_verts = &ents_verts[8*i];
725 const int reorder[8] = {0, 1, 2, 3, 5, 4, 6, 7};
726 const int new_verts[8] = {hex_verts[reorder[0]],
727 hex_verts[reorder[1]],
728 hex_verts[reorder[2]],
729 hex_verts[reorder[3]],
730 hex_verts[reorder[4]],
731 hex_verts[reorder[5]],
732 hex_verts[reorder[6]],
733 hex_verts[reorder[7]]
735 hex_verts = new_verts;
737 mesh->
AddHex(hex_verts, elem_tag ? attr[elem_offset+i] : 1);
747 if (bdr_comp && n_bdr_elem > 0)
750 FmsComponentGetNumParts(bdr_comp, &n_bdr_parts);
752 for (FmsInt part_id = 0; part_id < n_bdr_parts; part_id++)
754 for (
int et = FMS_VERTEX; et < FMS_NUM_ENTITY_TYPES; et++)
756 if (FmsEntityDim[et] !=
dim-1) {
continue; }
759 FmsIntType elem_id_type;
760 const void *elem_ids;
761 const FmsOrientation *elem_ori;
763 FmsComponentGetPart(bdr_comp, part_id, (FmsEntityType)et, &domain,
764 &elem_id_type, &elem_ids, &elem_ori, &num_elems);
765 if (num_elems == 0) {
continue; }
767 if (elem_ids != NULL &&
768 (elem_id_type != FMS_INT32 && elem_id_type != FMS_UINT32))
770 err = 6;
goto func_exit;
772 if (elem_ori != NULL)
774 err = 7;
goto func_exit;
777 const FmsInt nv = FmsEntityNumVerts[et];
779 if (elem_ids == NULL)
781 FmsDomainGetEntitiesVerts(domain, (FmsEntityType)et, NULL, FMS_INT32,
782 0, ents_verts.
GetData(), num_elems);
786 const int *ei = (
const int *)elem_ids;
787 for (FmsInt i = 0; i < num_elems; i++)
789 FmsDomainGetEntitiesVerts(domain, (FmsEntityType)et, NULL,
790 FMS_INT32, ei[i], &ents_verts[i*nv], 1);
793 const int elem_offset = mesh->
GetNBE();
794 switch ((FmsEntityType)et)
797 for (FmsInt i = 0; i < num_elems; i++)
800 &ents_verts[2*i], bdr_tag ? bdr_attr[elem_offset+i] : 1);
804 for (FmsInt i = 0; i < num_elems; i++)
807 &ents_verts[3*i], bdr_tag ? bdr_attr[elem_offset+i] : 1);
810 case FMS_QUADRILATERAL:
811 for (FmsInt i = 0; i < num_elems; i++)
814 &ents_verts[4*i], bdr_tag ? bdr_attr[elem_offset+i] : 1);
824 #ifdef RENUMBER_ENTITIES 825 delete [] verts_per_part;
826 delete [] verts_start;
832 const double origin[3] = {0.,0.,0.};
833 for (FmsInt vi = 0; vi < n_vert; vi++)
841 FmsFieldDescriptor coords_fd = NULL;
842 FmsLayoutType coords_layout;
843 FmsFieldGet(coords, &coords_fd, NULL, &coords_layout, NULL, NULL);
846 mfem::err <<
"Error reading the FMS mesh coords' FieldDescriptor." << std::endl;
850 FmsInt coords_order = 0;
851 FmsBasisType coords_btype = FMS_NODAL_GAUSS_CLOSED;
852 FmsFieldType coords_ftype = FMS_CONTINUOUS;
853 FmsFieldDescriptorGetFixedOrder(coords_fd, &coords_ftype, &coords_btype,
857 if (coords_btype != FMS_NODAL_GAUSS_CLOSED)
859 mfem::err <<
"Error reading FMS mesh coords." << std::endl;
865 const bool discont = (coords_ftype == FMS_DISCONTINUOUS);
867 (coords_layout == FMS_BY_VDIM) ?
875 FmsFieldToGridFunction<double>(fms_mesh, coords, mesh, nodes,
false);
899 btype = FMS_NODAL_GAUSS_OPEN;
904 btype = FMS_NODAL_GAUSS_CLOSED;
909 btype = FMS_POSITIVE;
914 btype = FMS_NODAL_UNIFORM_OPEN;
919 btype = FMS_NODAL_UNIFORM_CLOSED;
950 const std::string &fd_name,
951 const std::string &field_name,
956 if (!dc) {
return 1; }
957 if (!comp) {
return 2; }
958 if (!mesh) {
return 3; }
959 if (!gf) {
return 4; }
960 if (!outfield) {
return 5; }
967 #ifdef DEBUG_MFEM_FMS 968 mfem::out <<
"Adding FMS field for " << field_name <<
"..." << endl;
976 FmsFieldType ftype = FMS_CONTINUOUS;
977 FmsBasisType btype = FMS_NODAL_GAUSS_CLOSED;
982 ftype = FMS_CONTINUOUS;
983 order =
static_cast<FmsInt
>(fespace->
GetOrder(0));
990 mfem::err <<
"Error converting MFEM basis type to FMS for" 991 " FMS_CONTINUOUS." << std::endl;
999 ftype = FMS_DISCONTINUOUS;
1000 order =
static_cast<FmsInt
>(fespace->
GetOrder(0));
1007 mfem::err <<
"Error converting MFEM basis type to FMS for" 1008 " FMS_DISCONTINUOUS." << std::endl;
1016 mfem::out <<
"Warning, unsupported ContType (TANGENTIAL) for " 1017 << field_name <<
". Using FMS_CONTINUOUS." << std::endl;
1029 if (sscanf(fecoll->
Name(),
"RT_%dD_P%d", &idim, &iorder) == 2)
1031 order = (FmsInt)iorder;
1035 order =
static_cast<FmsInt
>(fespace->
GetOrder(0));
1045 mfem::out <<
"Warning, unsupported ContType for field " << field_name
1046 <<
". Using FMS_CONTINUOUS." << std::endl;
1047 ftype = FMS_CONTINUOUS;
1052 FmsFieldDescriptor fd = NULL;
1054 FmsDataCollectionAddFieldDescriptor(dc, fd_name.c_str(), &fd);
1055 FmsDataCollectionAddField(dc, field_name.c_str(), &
f);
1059 FmsFieldDescriptorSetComponent(fd, comp);
1060 FmsFieldDescriptorSetFixedOrder(fd, ftype, btype, order);
1063 FmsFieldDescriptorGetNumDofs(fd, &ndofs);
1065 const char *name = NULL;
1066 FmsFieldGetName(
f, &name);
1068 FMS_BY_VDIM : FMS_BY_NODES;
1070 #ifdef DEBUG_MFEM_FMS 1073 case FMS_CONTINUOUS:
1074 mfem::out <<
"\tFMS_CONTINUOUS" << std::endl;
1076 case FMS_DISCONTINUOUS:
1077 mfem::out <<
"\tFMS_DISCONTINUOUS" << std::endl;
1083 mfem::out <<
"\tField is order " << order <<
" with vdim " << vdim <<
1084 " and nDoFs " << ndofs << std::endl;
1085 mfem::out <<
"\tgf->size() " << gf->
Size() <<
" ndofs * vdim " << ndofs * vdim
1087 mfem::out <<
"\tlayout " << layout <<
" (0 = BY_NODES, 1 = BY_VDIM)" <<
1091 if (FmsFieldSet(
f, fd, vdim, layout, FMS_DOUBLE, c))
1093 mfem::err <<
"Error setting field " << field_name <<
" in FMS." << std::endl;
1102 if (!mdc) {
return false; }
1103 if (!fdc) {
return false; }
1106 double *time = NULL, *timestep = NULL;
1107 FmsMetaData top_level = NULL;
1108 FmsMetaData *cycle_time_timestep = NULL;
1110 mdata_err = FmsDataCollectionAttachMetaData(fdc, &top_level);
1111 if (!top_level || mdata_err)
1113 mfem::err <<
"Failed to attach metadata to the FmsDataCollection" << std::endl;
1117 mdata_err = FmsMetaDataSetMetaData(top_level,
"MetaData", 3,
1118 &cycle_time_timestep);
1119 if (!cycle_time_timestep || mdata_err)
1121 mfem::err <<
"Failed to acquire FmsMetaData array" << std::endl;
1125 if (!cycle_time_timestep[0])
1127 mfem::err <<
"The MetaData pointer for cycle is NULL" << std::endl;
1130 mdata_err = FmsMetaDataSetIntegers(cycle_time_timestep[0],
"cycle",
1131 FMS_INT32, 1, (
void**)&cycle);
1132 if (!cycle || mdata_err)
1134 mfem::err <<
"The data pointer for cycle is NULL" << std::endl;
1139 if (!cycle_time_timestep[1])
1141 mfem::err <<
"The FmsMetaData pointer for time is NULL" << std::endl;
1144 mdata_err = FmsMetaDataSetScalars(cycle_time_timestep[1],
"time", FMS_DOUBLE,
1146 if (!time || mdata_err)
1148 mfem::err <<
"The data pointer for time is NULL." << std::endl;
1153 if (!cycle_time_timestep[2])
1155 mfem::err <<
"The FmsMetData pointer for timestep is NULL" << std::endl;
1158 mdata_err = FmsMetaDataSetScalars(cycle_time_timestep[2],
"timestep",
1159 FMS_DOUBLE, 1, (
void**)×tep);
1160 if (!timestep || mdata_err)
1162 mfem::err <<
"The data pointer for timestep is NULL" << std::endl;
1173 std::vector<int> &values)
1175 if (!mdata) {
return false; }
1177 bool retval =
false;
1178 FmsMetaDataType type;
1179 FmsIntType int_type;
1181 FmsMetaData *children =
nullptr;
1182 const void *data =
nullptr;
1183 const char *mdata_name =
nullptr;
1184 if (FmsMetaDataGetType(mdata, &type) == 0)
1189 if (FmsMetaDataGetIntegers(mdata, &mdata_name, &int_type, &size, &data) == 0)
1191 if (strcasecmp(key.c_str(), mdata_name) == 0)
1199 for (i = 0; i < size; i++)
1201 values.push_back(static_cast<int>(reinterpret_cast<const int8_t*>(data)[i]));
1205 for (i = 0; i < size; i++)
1207 values.push_back(static_cast<int>(reinterpret_cast<const int16_t*>(data)[i]));
1211 for (i = 0; i < size; i++)
1213 values.push_back(static_cast<int>(reinterpret_cast<const int32_t*>(data)[i]));
1217 for (i = 0; i < size; i++)
1219 values.push_back(static_cast<int>(reinterpret_cast<const int64_t*>(data)[i]));
1223 for (i = 0; i < size; i++)
1225 values.push_back(static_cast<int>(reinterpret_cast<const uint8_t*>(data)[i]));
1229 for (i = 0; i < size; i++)
1231 values.push_back(static_cast<int>(reinterpret_cast<const uint16_t*>(data)[i]));
1235 for (i = 0; i < size; i++)
1237 values.push_back(static_cast<int>(reinterpret_cast<const uint32_t*>(data)[i]));
1241 for (i = 0; i < size; i++)
1243 values.push_back(static_cast<int>(reinterpret_cast<const uint64_t*>(data)[i]));
1254 if (FmsMetaDataGetMetaData(mdata, &mdata_name, &size, &children) == 0)
1257 for (i = 0; i < size && !retval; i++)
1274 std::vector<double> &values)
1276 if (!mdata) {
return false; }
1278 bool retval =
false;
1279 FmsMetaDataType type;
1280 FmsScalarType scal_type;
1282 FmsMetaData *children =
nullptr;
1283 const void *data =
nullptr;
1284 const char *mdata_name =
nullptr;
1285 if (FmsMetaDataGetType(mdata, &type) == 0)
1290 if (FmsMetaDataGetScalars(mdata, &mdata_name, &scal_type, &size, &data) == 0)
1292 if (strcasecmp(key.c_str(), mdata_name) == 0)
1300 for (i = 0; i < size; i++)
1302 values.push_back(static_cast<double>(reinterpret_cast<const float*>(data)[i]));
1306 for (i = 0; i < size; i++)
1308 values.push_back(reinterpret_cast<const double*>(data)[i]);
1319 if (FmsMetaDataGetMetaData(mdata, &mdata_name, &size, &children) == 0)
1322 for (i = 0; i < size && !retval; i++)
1341 if (!mdata) {
return false; }
1343 bool retval =
false;
1344 FmsMetaDataType type;
1346 FmsMetaData *children =
nullptr;
1347 const char *mdata_name =
nullptr;
1348 const char *str_value =
nullptr;
1350 if (FmsMetaDataGetType(mdata, &type) == 0)
1357 if (strcasecmp(key.c_str(), mdata_name) == 0)
1365 if (FmsMetaDataGetMetaData(mdata, &mdata_name, &size, &children) == 0)
1368 for (i = 0; i < size && !retval; i++)
1391 FmsDataCollectionGetMesh(dc, &fms_mesh);
1395 Mesh *mesh =
nullptr;
1399 std::string collection_name(
"collection");
1400 const char *cn =
nullptr;
1401 FmsDataCollectionGetName(dc, &cn);
1404 collection_name = cn;
1412 FmsField *fields =
nullptr;
1413 FmsInt num_fields = 0;
1414 if (FmsDataCollectionGetFields(dc, &fields, &num_fields) == 0)
1416 for (FmsInt i = 0; i < num_fields; ++i)
1418 const char *name =
nullptr;
1419 FmsFieldGetName(fields[i], &name);
1424 FmsFieldDescriptor f_fd;
1425 FmsLayoutType f_layout;
1426 FmsScalarType f_data_type;
1428 FmsFieldGet(fields[i], &f_fd, NULL, &f_layout, &f_data_type,
1433 switch (f_data_type)
1436 err = FmsFieldToGridFunction<float>(fms_mesh, fields[i], mesh, *gf,
true);
1439 err = FmsFieldToGridFunction<double>(fms_mesh, fields[i], mesh, *gf,
true);
1441 case FMS_COMPLEX_FLOAT:
1442 case FMS_COMPLEX_DOUBLE:
1455 mfem::out <<
"There was an error converting " << name <<
" code: " <<
err <<
1460 const char *fname = NULL;
1461 FmsFieldGetName(fields[i], &fname);
1466 FmsMetaData mdata = NULL;
1467 FmsDataCollectionGetMetaData(dc, &mdata);
1470 std::vector<int> ivalues;
1471 std::vector<double> dvalues;
1475 if (!ivalues.empty())
1482 if (!dvalues.empty())
1489 if (!dvalues.empty())
1500 mfem::out <<
"FmsDataCollectionToDataCollection: mesh failed to convert. err=" 1512 const auto &fields = (*mfem_dc)->GetFieldMap();
1513 for (
const auto &field : fields)
1533 if (!mmesh) {
return 1; }
1534 if (!fmesh) {
return 2; }
1535 if (!volume) {
return 3; }
1539 const int num_verticies = mmesh->
GetNV();
1540 #ifdef DEBUG_MFEM_FMS 1541 const int num_edges = mmesh->
GetNEdges();
1543 const int num_faces = mmesh->
GetNFaces();
1544 const int num_elements = mmesh->
GetNE();
1546 #ifdef DEBUG_MFEM_FMS 1547 mfem::out <<
"nverts: " << num_verticies << std::endl;
1548 mfem::out <<
"nedges: " << num_edges << std::endl;
1549 mfem::out <<
"nfaces: " << num_faces << std::endl;
1550 mfem::out <<
"nele: " << num_elements << std::endl;
1553 FmsMeshConstruct(fmesh);
1554 FmsMeshSetPartitionId(*fmesh, 0, 1);
1556 FmsDomain *domains = NULL;
1557 FmsMeshAddDomains(*fmesh,
"Domain", 1, &domains);
1558 FmsDomainSetNumVertices(domains[0], num_verticies);
1560 const int edge_reorder[2] = {1, 0};
1561 const int quad_reorder[4] = {0,1,2,3};
1562 const int tet_reorder[4] = {3,2,1,0};
1563 const int hex_reorder[6] = {0,5,1,3,4,2};
1564 const int *reorder[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
1565 reorder[FMS_EDGE] = edge_reorder;
1566 reorder[FMS_QUADRILATERAL] = quad_reorder;
1567 reorder[FMS_TETRAHEDRON] = tet_reorder;
1568 reorder[FMS_HEXAHEDRON] = hex_reorder;
1573 mfem::err <<
"Error, mesh has no edges." << std::endl;
1577 if (!faces && num_faces > 0)
1580 "Error, mesh contains faces but the \"GetFaceEdgeTable\" returned NULL." <<
1586 std::vector<int> edge_verts(edges->
Size() * 2);
1587 for (
int i = 0; i < edges->
Size(); i++)
1591 for (
int j = 0; j < 2; j++)
1593 edge_verts[i*2 + j] = nids[j];
1598 FmsDomainSetNumEntities(domains[0], FMS_EDGE, FMS_INT32, edge_verts.size() / 2);
1599 FmsDomainAddEntities(domains[0], FMS_EDGE, reorder, FMS_INT32,
1600 edge_verts.data(), edge_verts.size() / 2);
1601 #ifdef DEBUG_MFEM_FMS 1603 for (
int i = 0; i < edge_verts.size(); i++)
1605 if (i % 2 == 0) {
mfem::out << std::endl <<
"\t" << i/2 <<
": "; }
1616 int rowsize = faces->
RowSize(0);
1617 std::vector<int> face_edges(faces->
Size() * rowsize);
1618 for (
int i = 0; i < faces->
Size(); i++)
1622 for (
int j = 0; j < rowsize; j++)
1624 face_edges[i*rowsize + j] = eids[j];
1627 FmsEntityType ent_type = (rowsize == 3) ? FMS_TRIANGLE : FMS_QUADRILATERAL;
1628 FmsDomainSetNumEntities(domains[0], ent_type, FMS_INT32,
1629 face_edges.size() / rowsize);
1630 FmsDomainAddEntities(domains[0], ent_type, NULL, FMS_INT32, face_edges.data(),
1631 face_edges.size() / rowsize);
1632 #ifdef DEBUG_MFEM_FMS 1634 for (
int i = 0; i < face_edges.size(); i++)
1636 if (i % rowsize == 0) {
mfem::out << std::endl <<
"\t" << i/rowsize <<
": "; }
1637 mfem::out <<
"(" << edge_verts[face_edges[i]*2] <<
", " <<
1638 edge_verts[face_edges[i]*2+1] <<
") ";
1645 std::vector<int> tags;
1646 std::vector<int> tris;
1647 std::vector<int> quads;
1648 std::vector<int> tets;
1649 std::vector<int> hexes;
1650 for (
int i = 0; i < num_elements; i++)
1670 for (
int e = 0; e < 3; e++)
1672 tris.push_back(eids[e]);
1680 for (
int e = 0; e < 4; e++)
1682 quads.push_back(eids[e]);
1690 for (
int f = 0;
f < 4;
f++)
1692 tets.push_back(fids[
f]);
1700 for (
int f = 0;
f < 6;
f++)
1702 hexes.push_back(fids[
f]);
1707 mfem::err <<
"Error, element not implemented." << std::endl;
1714 FmsDomainSetNumEntities(domains[0], FMS_TRIANGLE, FMS_INT32, tris.size() / 3);
1715 FmsDomainAddEntities(domains[0], FMS_TRIANGLE, reorder, FMS_INT32, tris.data(),
1717 #ifdef DEBUG_MFEM_FMS 1719 for (
int i = 0; i < tris.size(); i++)
1721 if (i % 3 == 0) {
mfem::out << std::endl <<
"\t" << i/3 <<
": "; }
1732 FmsDomainSetNumEntities(domains[0], FMS_QUADRILATERAL, FMS_INT32,
1734 FmsDomainAddEntities(domains[0], FMS_QUADRILATERAL, reorder, FMS_INT32,
1735 quads.data(), quads.size() / 4);
1736 #ifdef DEBUG_MFEM_FMS 1738 for (
int i = 0; i < quads.size(); i++)
1740 if (i % 4 == 0) {
mfem::out << std::endl <<
"\t" << i/4 <<
": "; }
1749 FmsDomainSetNumEntities(domains[0], FMS_TETRAHEDRON, FMS_INT32,
1751 FmsDomainAddEntities(domains[0], FMS_TETRAHEDRON, reorder, FMS_INT32,
1752 tets.data(), tets.size() / 4);
1753 #ifdef DEBUG_MFEM_FMS 1755 for (
int i = 0; i < tets.size(); i++)
1757 if (i % 4 == 0) {
mfem::out << std::endl <<
"\t" << i/4 <<
": "; }
1766 FmsDomainSetNumEntities(domains[0], FMS_HEXAHEDRON, FMS_INT32,
1768 FmsDomainAddEntities(domains[0], FMS_HEXAHEDRON, reorder, FMS_INT32,
1769 hexes.data(), hexes.size() / 6);
1770 #ifdef DEBUG_MFEM_FMS 1772 for (
int i = 0; i < hexes.size(); i++)
1774 if (i % 6 == 0) {
mfem::out << std::endl <<
"\t" << i/6 <<
": "; }
1781 err = FmsMeshFinalize(*fmesh);
1784 mfem::err <<
"FmsMeshFinalize returned error code " <<
err << std::endl;
1788 err = FmsMeshValidate(*fmesh);
1791 mfem::err <<
"FmsMeshValidate returned error code " <<
err << std::endl;
1795 FmsComponent v = NULL;
1796 FmsMeshAddComponent(*fmesh,
"volume", &v);
1797 FmsComponentAddDomain(v, domains[0]);
1800 FmsMeshAddTag(*fmesh,
"element_attribute", &tag);
1801 FmsTagSetComponent(tag, v);
1802 FmsTagSet(tag, FMS_INT32, FMS_INT32, tags.data(), tags.size());
1805 std::vector<int> bdr_eles[FMS_NUM_ENTITY_TYPES];
1806 std::vector<int> bdr_attributes;
1807 const int NBE = mmesh->
GetNBE();
1808 for (
int i = 0; i < NBE; i++)
1833 MFEM_WARNING(
"Unsupported boundary element " << betype <<
" at boundary index " 1841 FmsComponent boundary = NULL;
1842 FmsMeshAddComponent(*fmesh,
"boundary", &boundary);
1844 FmsComponentAddPart(boundary, domains[0], &part_id);
1845 for (
int i = FMS_NUM_ENTITY_TYPES - 1; i > 0; i--)
1847 if (bdr_eles[i].size())
1849 FmsComponentAddPartEntities(boundary, part_id, (FmsEntityType)i,
1850 FMS_INT32, FMS_INT32, FMS_INT32, NULL,
1852 NULL, bdr_eles[i].size());
1856 FmsComponentAddRelation(v, 1);
1857 FmsTag boundary_tag = NULL;
1858 FmsMeshAddTag(*fmesh,
"boundary_attribute", &boundary_tag);
1859 FmsTagSetComponent(boundary_tag, boundary);
1860 FmsTagSet(boundary_tag, FMS_INT32, FMS_INT32, bdr_attributes.data(),
1861 bdr_attributes.size());
1869 FmsDataCollection *dc)
1875 FmsMesh fmesh = NULL;
1876 FmsComponent volume = NULL;
1878 if (!fmesh || !volume ||
err)
1880 mfem::err <<
"Error converting mesh topology from MFEM to FMS" << std::endl;
1883 FmsMeshDestroy(&fmesh);
1891 mfem::err <<
"There was an error creating the FMS data collection." <<
1893 FmsMeshDestroy(&fmesh);
1896 FmsDataCollectionDestroy(dc);
1905 FmsField fcoords = NULL;
1908 err |= FmsComponentSetCoordinates(volume, fcoords);
1915 FmsFieldDescriptor fdcoords = NULL;
1916 FmsField fcoords = NULL;
1917 err = FmsDataCollectionAddFieldDescriptor(*dc,
"CoordsDescriptor", &fdcoords);
1918 err |= FmsFieldDescriptorSetComponent(fdcoords, volume);
1919 err |= FmsFieldDescriptorSetFixedOrder(fdcoords, FMS_CONTINUOUS,
1920 FMS_NODAL_GAUSS_CLOSED, 1);
1921 err |= FmsDataCollectionAddField(*dc,
"Coords", &fcoords);
1924 err |= FmsComponentSetCoordinates(volume, fcoords);
1929 mfem::err <<
"There was an error setting the mesh coordinates." << std::endl;
1930 FmsMeshDestroy(&fmesh);
1931 FmsDataCollectionDestroy(dc);
1936 for (
const auto &pair : fields)
1938 std::string fd_name(pair.first +
"Descriptor");
1941 pair.second, &field);
1944 mfem::err <<
"WARNING: There was an error adding the " << pair.first <<
1945 " field. Continuing..." << std::endl;
bool FmsMetaDataGetInteger(FmsMetaData mdata, const std::string &key, std::vector< int > &values)
void GetEdgeInteriorDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the interior of the specified edge.
Table * GetEdgeVertexTable() const
Class for grid function - Vector with associated FE space.
void GetElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of element i.
int AddQuad(int v1, int v2, int v3, int v4, int attr=1)
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
int GetBdrElementEdgeIndex(int i) const
Field is discontinuous across element interfaces.
virtual int GetContType() const =0
bool FmsMetaDataGetScalar(FmsMetaData mdata, const std::string &key, std::vector< double > &values)
virtual const double * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
Normal component of vector field.
Element::Type GetBdrElementType(int i) const
Returns the type of boundary element i.
bool MfemMetaDataToFmsMetaData(DataCollection *mdc, FmsDataCollection fdc)
T * GetData()
Returns the data.
int AddTriangle(int v1, int v2, int v3, int attr=1)
int Size() const
Returns the size of the vector.
int GetNEdges() const
Return the number of edges.
static const char * Name(int b_type)
Check and convert a BasisType constant to a string identifier.
int GetCycle() const
Get time cycle (for time-dependent simulations)
int FmsMeshToMesh(FmsMesh fms_mesh, Mesh **mfem_mesh)
bool FmsMetaDataGetString(FmsMetaData mdata, const std::string &key, std::string &value)
int GetNBE() const
Returns number of boundary elements.
virtual int DofForGeometry(Geometry::Type GeomType) const =0
std::function< double(const Vector &)> f(double mass_coeff)
int AddBdrTriangle(int v1, int v2, int v3, int attr=1)
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
int GetAttribute(int i) const
Return the attribute of element i.
int AddVertex(double x, double y=0.0, double z=0.0)
Nodes: x_i = (i+1/2)/n, i=0,...,n-1.
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
void GetElementFaces(int i, Array< int > &faces, Array< int > &ori) const
Return the indices and the orientations of all faces of element i.
void GetVertices(Vector &vert_coord) const
int Append(const T &el)
Append element 'el' to array, resize if necessary.
const FiniteElementCollection * FEColl() const
int AddTet(int v1, int v2, int v3, int v4, int attr=1)
Data collection with VisIt I/O routines.
virtual void SetCurvature(int order, bool discont=false, int space_dim=-1, int ordering=1)
Set the curvature of the mesh nodes using the given polynomial degree.
void GetEdgeVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of edge i.
double GetTimeStep() const
Get the simulation time step (for time-dependent simulations)
void GetFaceVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of face i.
Type
Constants for the classes derived from Element.
virtual const char * Name() const
int AddBdrSegment(int v1, int v2, int attr=1)
int DataCollectionToFmsDataCollection(DataCollection *mfem_dc, FmsDataCollection *dc)
int FmsDataCollectionToDataCollection(FmsDataCollection dc, DataCollection **mfem_dc)
FiniteElementSpace * FESpace()
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
void SetTime(double t)
Set physical time (for time-dependent simulations)
Tangential components of vector field.
void GetFaceInteriorDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the interior of the specified face.
const FieldMapType & GetFieldMap() const
Get a const reference to the internal field map.
Table * GetFaceEdgeTable() const
double * GetData() const
Return a pointer to the beginning of the Vector data.
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
void SetOwnData(bool o)
Set the ownership of collection data.
int GetVDim() const
Returns vector dimension.
int GetBdrAttribute(int i) const
Return the attribute of boundary element i.
virtual const int * DofOrderForOrientation(Geometry::Type GeomType, int Or) const =0
Returns an array, say p, that maps a local permuted index i to a local base index: base_i = p[i]...
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
virtual void Save() override
Save the collection and a VisIt root file.
int AddHex(int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8, int attr=1)
void FinalizeTopology(bool generate_bdr=true)
Finalize the construction of the secondary topology (connectivity) data of a Mesh.
int GetOrder(int i) const
Returns the polynomial degree of the i'th finite element.
int AddBdrQuad(int v1, int v2, int v3, int v4, int attr=1)
int GridFunctionToFmsField(FmsDataCollection dc, FmsComponent comp, const std::string &fd_name, const std::string &field_name, const Mesh *mesh, const GridFunction *gf, FmsField *outfield)
Serendipity basis (squares / cubes)
Nodes: x_i = (i+1)/(n+1), i=0,...,n-1.
bool BasisTypeToFmsBasisType(int bt, FmsBasisType &btype)
int SpaceDimension() const
Dimension of the physical space containing the mesh.
int GetNE() const
Returns number of elements.
void SetTimeStep(double ts)
Set the simulation time step (for time-dependent simulations)
Element::Type GetElementType(int i) const
Returns the type of element i.
int MeshToFmsMesh(const Mesh *mmesh, FmsMesh *fmesh, FmsComponent *volume)
int Size() const
Returns the number of TYPE I elements.
Ordering::Type GetOrdering() const
Return the ordering method.
virtual void Finalize(bool refine=false, bool fix_orientation=false)
Finalize the construction of a general Mesh.
int FindId(int p1, int p2) const
Find id of item whose parents are p1, p2... Return -1 if it doesn't exist.
virtual void SetSpace(FiniteElementSpace *f)
Associate a new FiniteElementSpace with the GridFunction.
int Size() const
Return the logical size of the array.
Mesh * GetMesh()
Get a pointer to the mesh in the collection.
void MakeRef(T *, int)
Make this Array a reference to a pointer.
int DofToVDof(int dof, int vd, int ndofs=-1) const
Compute a single vdof corresponding to the index dof and the vector index vd.
Nodes: x_i = i/(n-1), i=0,...,n-1.
int GetNFaces() const
Return the number of faces in a 3D mesh.
int GetId(int p1, int p2)
Get id of item whose parents are p1, p2... Create it if it doesn't exist.
Arbitrary order H1-conforming (continuous) finite elements.
void GetNodes(Vector &node_coord) const
void GetElementInteriorDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the interior of the specified element.
Field is continuous across element interfaces.
const std::string & GetCollectionName() const
Get the name of the collection.
int FmsFieldToGridFunction(FmsMesh fms_mesh, FmsField f, Mesh *mesh, GridFunction &func, bool setFE)
This function converts an FmsField to an MFEM GridFunction.
Arbitrary order "L2-conforming" discontinuous finite elements.
virtual void RegisterField(const std::string &field_name, GridFunction *gf) override
Add a grid function to the collection and update the root file.
double GetTime() const
Get physical time (for time-dependent simulations)