12 #ifdef MFEM_USE_MESQUITE
16 #include "../fem/fem.hpp"
35 void MesquiteMesh::MeshTags::clear()
37 for (std::vector<TagData*>::iterator iter = tagList.begin();
38 iter != tagList.end(); ++iter)
45 size_t MesquiteMesh::MeshTags::size_from_tag_type( Mesh::TagType type )
48 case Mesh::BYTE:
return 1;
49 case Mesh::BOOL:
return sizeof(bool);
50 case Mesh::DOUBLE:
return sizeof(double);
51 case Mesh::INT:
return sizeof(int);
52 case Mesh::HANDLE:
return sizeof(
void*);
53 case Mesh::LONG_LONG:
return sizeof(
long long);
54 default: assert(0);
return 0;
58 size_t MesquiteMesh::MeshTags::create(
const std::string& name,
64 size_t h = handle( name, err );
67 MSQ_SETERR(err)(name, MsqError::TAG_ALREADY_EXISTS);
71 if (length == 0 || size_from_tag_type(type) == 0)
73 MSQ_SETERR(err)(MsqError::INVALID_ARG);
77 TagData* tag =
new TagData( name, type, length );
79 tagList.push_back(tag);
83 tag->defaultValue = malloc( tag->desc.size );
84 memcpy( tag->defaultValue, defval, tag->desc.size );
90 size_t MesquiteMesh::MeshTags::create(
const MfemTagDescription& desc,
94 size_t h = handle( desc.name.c_str(), err );
97 MSQ_SETERR(err)(desc.name.c_str(), MsqError::TAG_ALREADY_EXISTS);
102 if (desc.size == 0 || (desc.size % size_from_tag_type(desc.type)) != 0)
104 MSQ_SETERR(err)(MsqError::INVALID_ARG);
108 TagData* tag =
new TagData( desc );
110 tagList.push_back(tag);
114 tag->defaultValue = malloc( tag->desc.size );
115 memcpy( tag->defaultValue, defval, tag->desc.size );
121 void MesquiteMesh::MeshTags::destroy(
size_t tag_index, MsqError& err )
124 if (tag_index >= tagList.size() || 0 == tagList[tag_index])
126 MSQ_SETERR(err)(MsqError::TAG_NOT_FOUND);
130 delete tagList[tag_index];
131 tagList[tag_index] = 0;
134 size_t MesquiteMesh::MeshTags::handle(
const std::string& name, MsqError& err )
const
136 for (
size_t i = 0; i < tagList.size(); ++i)
137 if (tagList[i] && tagList[i]->desc.name == name)
143 const MesquiteMesh::MfemTagDescription& MesquiteMesh::MeshTags::properties(
size_t tag_index, MsqError& err )
const
145 static MfemTagDescription dummy_desc;
148 if (tag_index >= tagList.size() || !tagList[tag_index])
150 MSQ_SETERR(err)(
"Invalid tag handle", MsqError::INVALID_ARG);
154 return tagList[tag_index]->desc;
158 void MesquiteMesh::MeshTags::set_element_data(
size_t tag_index,
160 const size_t* index_array,
167 if (tag_index >= tagList.size() || !tagList[tag_index])
169 MSQ_SETERR(err)(
"Invalid tag handle", MsqError::INVALID_ARG);
173 TagData* tag = tagList[tag_index];
176 size_t total = tag->elementCount;
177 for (i = 0; i < num_indices; ++i)
178 if (index_array[i] >= total)
179 total = index_array[i] + 1;
182 if (total > tag->elementCount)
185 tag->elementData = realloc( tag->elementData, tag->desc.size * total );
187 if (tag->defaultValue)
189 data = ((
char*)tag->elementData) + tag->elementCount * tag->desc.size;
190 for (i = tag->elementCount; i < total; ++i)
192 memcpy( data, tag->defaultValue, tag->desc.size );
193 data += tag->desc.size;
198 memset( (
char*)tag->elementData + tag->elementCount * tag->desc.size, 0,
199 (total - tag->elementCount) * tag->desc.size );
201 tag->elementCount = total;
205 data = (
char*)tag->elementData;
206 const char* iter = (
const char*)values;
207 for (i = 0; i < num_indices; ++i)
209 memcpy( data + index_array[i]*tag->desc.size, iter, tag->desc.size );
210 iter += tag->desc.size;
214 void MesquiteMesh::MeshTags::get_element_data(
size_t tag_index,
216 const size_t* index_array,
218 MsqError& err )
const
221 if (tag_index >= tagList.size() || !tagList[tag_index])
223 MSQ_SETERR(err)(
"Invalid tag handle", MsqError::INVALID_ARG);
227 TagData* tag = tagList[tag_index];
229 char* iter = (
char*)values;
230 const char* data = (
const char*)tag->elementData;
232 for (
size_t i = 0; i < num_indices; ++i)
235 size_t index = index_array[i];
236 if (index >= tag->elementCount)
238 ptr = tag->defaultValue;
241 MSQ_SETERR(err)(MsqError::TAG_NOT_FOUND);
247 ptr = data + index * tag->desc.size;
250 memcpy( iter, ptr, tag->desc.size );
251 iter += tag->desc.size;
255 void MesquiteMesh::MeshTags::set_vertex_data(
size_t tag_index,
257 const size_t* index_array,
264 if (tag_index >= tagList.size() || !tagList[tag_index])
266 MSQ_SETERR(err)(
"Invalid tag handle", MsqError::INVALID_ARG);
270 TagData* tag = tagList[tag_index];
273 size_t total = tag->vertexCount;
274 for (i = 0; i < num_indices; ++i)
275 if (index_array[i] >= total)
276 total = index_array[i] + 1;
279 if (total > tag->vertexCount)
282 tag->vertexData = realloc( tag->vertexData, tag->desc.size * total );
284 if (tag->defaultValue)
286 data = ((
char*)tag->vertexData) + tag->vertexCount * tag->desc.size;
287 for (i = tag->vertexCount; i < total; ++i)
289 memcpy( data, tag->defaultValue, tag->desc.size );
290 data += tag->desc.size;
295 memset( (
char*)tag->vertexData + tag->vertexCount * tag->desc.size, 0,
296 (total - tag->vertexCount) * tag->desc.size );
298 tag->vertexCount = total;
302 data = (
char*)tag->vertexData;
303 const char* iter = (
const char*)values;
304 for (i = 0; i < num_indices; ++i)
306 memcpy( data + index_array[i]*tag->desc.size, iter, tag->desc.size );
307 iter += tag->desc.size;
311 void MesquiteMesh::MeshTags::get_vertex_data(
size_t tag_index,
313 const size_t* index_array,
315 MsqError& err )
const
318 if (tag_index >= tagList.size() || !tagList[tag_index])
320 MSQ_SETERR(err)(
"Invalid tag handle", MsqError::INVALID_ARG);
324 TagData* tag = tagList[tag_index];
326 char* iter = (
char*)values;
327 const char* data = (
const char*)tag->vertexData;
329 for (
size_t i = 0; i < num_indices; ++i)
332 size_t index = index_array[i];
333 if (index >= tag->vertexCount)
335 ptr = tag->defaultValue;
338 MSQ_SETERR(err)(MsqError::TAG_NOT_FOUND);
344 ptr = data + index * tag->desc.size;
347 memcpy( iter, ptr, tag->desc.size );
348 iter += tag->desc.size;
352 bool MesquiteMesh::MeshTags::tag_has_vertex_data(
size_t tag_index, MsqError& err )
355 if (tag_index >= tagList.size() || !tagList[tag_index])
357 MSQ_SETERR(err)(
"Invalid tag handle", MsqError::INVALID_ARG);
361 TagData* tag = tagList[tag_index];
362 return 0 != tag->vertexData || tag->defaultValue;
365 bool MesquiteMesh::MeshTags::tag_has_element_data(
size_t tag_index, MsqError& err )
368 if (tag_index >= tagList.size() || !tagList[tag_index])
370 MSQ_SETERR(err)(
"Invalid tag handle", MsqError::INVALID_ARG);
374 TagData* tag = tagList[tag_index];
375 return 0 != tag->elementData || tag->defaultValue;
378 MesquiteMesh::MeshTags::TagIterator MesquiteMesh::MeshTags::tag_begin()
381 while (index < tagList.size() && tagList[index] == NULL)
383 return TagIterator(
this, index );
389 while (index < tags->tagList.size() && NULL == tags->tagList[index])
397 while (index < tags->tagList.size() && NULL == tags->tagList[index])
406 while (index < tags->tagList.size() && NULL == tags->tagList[index])
415 while (index < tags->tagList.size() && NULL == tags->tagList[index])
424 : myTags( new MeshTags )
427 nelems = mesh->
GetNE();
436 dof_elem =
new Table;
441 ndofs = mesh->
GetNV();
445 mByte = vector<char>(ndofs);
446 mFixed = vector<bool>(ndofs,
false);
450 for (
int i = 0; i < mesh->
GetNBE(); i++)
456 for (
int j = 0; j < bdofs.Size(); j++)
457 mFixed[bdofs[j]] =
true;
468 Mesquite::MsqError& err)
470 elements.resize(nelems);
471 for (
int i = 0; i < nelems; i++)
472 elements[i] = (ElementHandle) i;
476 Mesquite::MsqError& err)
478 vertices.resize(ndofs);
479 for (
int i = 0; i < ndofs; i++)
480 vertices[i] = (VertexHandle) i;
484 MsqVertex* coordinates,
489 const size_t *indices = (
const size_t*) vert_array;
491 for (
int i = 0; i < num_vtx; i++)
493 mesh->
GetNode(indices[i], coords);
494 coordinates[i].x(coords[0]);
495 coordinates[i].y(coords[1]);
497 coordinates[i].z(coords[2]);
499 coordinates[i].z(0.0);
504 const Vector3D &coordinates,
508 coords[0] = coordinates.x();
509 coords[1] = coordinates.y();
510 coords[2] = coordinates.z();
511 mesh->
SetNode((
size_t) vertex, coords);
518 size_t index = (size_t) vertex;
523 const unsigned char *byte_array,
527 const size_t* indices = (
const size_t*) vert_array;
528 for (
int i = 0; i < array_size; i++)
529 mByte[indices[i]] = byte_array[i];
536 *byte = mByte[(
const size_t) vertex];
540 unsigned char *byte_array,
544 const size_t* indices = (
const size_t*) vertex;
545 for (
int i = 0; i < array_size; i++)
546 byte_array[i] = mByte[indices[i]];
550 std::vector<bool>& fixed_flag_array,
554 fixed_flag_array.resize(num_vtx + 1);
555 const size_t* indices = (
const size_t*) vert_array;
556 for (
int i = 0; i < num_vtx; i++)
557 fixed_flag_array[i] = mFixed[indices[i]];
561 const std::vector< bool > &fixed_flag_array,
565 const size_t* indices = (
const size_t*) vert_array;
566 for (
int i = 0; i < num_vtx; i++)
567 mFixed[indices[i]] = fixed_flag_array[i];
572 std::vector<VertexHandle>& vert_handles,
573 std::vector<size_t>& offsets,
576 const size_t* indices = (
const size_t*) elem_handles;
577 vert_handles.clear();
578 offsets.resize(num_elems + 1);
582 for (
int i = 0; i < num_elems; i++)
584 offsets[i] = vert_handles.size();
591 for (
int j = 0; j < elem_dofs.
Size(); j++)
595 vert_handles.push_back( (VertexHandle) elem_dofs[j] );
598 offsets[num_elems] = vert_handles.size();
603 std::vector<ElementHandle>& elements,
604 std::vector<size_t>& offsets,
607 const size_t* indices = (
const size_t*) vertex_array;
609 offsets.resize(num_vertex + 1);
611 for (
int i = 0; i < num_vertex; i++)
613 offsets[i] = elements.size();
614 int* vertex_elems = dof_elem->
GetRow(indices[i]);
615 for (
int j = 0; j < dof_elem->
RowSize(indices[i]); j++)
616 elements.push_back( (ElementHandle) vertex_elems[j] );
618 offsets[num_vertex] = elements.size();
622 EntityTopology *element_topologies,
643 int mfem_to_mesquite[9] = {0,0,8,9,11,12,0,0,0};
644 const size_t* indices = (
const size_t*) element_handle_array;
645 for (
int i = 0; i < num_elements; i++)
646 element_topologies[i] = (EntityTopology) mfem_to_mesquite[mesh->
GetElementType(indices[i])];
651 MsqPrintError err(cerr);
663 TagHandle attributeTagHandle =
tag_create(
"material", Mesh::INT, 1, 0, err );
665 int *materialValues =
new int[nelems];
666 for(
int i=0;i<nelems;i++)
674 std::vector<ElementHandle> elements;
678 (
const void*)(materialValues), err );
680 delete materialValues;
690 size_t size = MeshTags::size_from_tag_type( type );
691 MfemTagDescription desc( name, type, length*size );
692 size_t index = myTags->create( desc, defval, err ); MSQ_ERRZERO(err);
693 return (TagHandle)index;
698 myTags->destroy( (
size_t)handle, err ); MSQ_CHKERR(err);
703 size_t index = myTags->handle( name, err ); MSQ_ERRZERO(err);
705 MSQ_SETERR(err)( MsqError::TAG_NOT_FOUND,
"could not find tag \"%s\"", name.c_str() );
706 return (TagHandle)index;
715 const MfemTagDescription& desc
716 = myTags->properties( (
size_t)handle, err ); MSQ_ERRRTN(err);
720 length = (unsigned)(desc.size / MeshTags::size_from_tag_type( desc.type ));
726 const ElementHandle* elem_array,
730 myTags->set_element_data( (
size_t)handle,
732 (
const size_t*)elem_array,
734 err ); MSQ_CHKERR(err);
739 const ElementHandle* elem_array,
743 myTags->get_element_data( (
size_t)handle,
745 (
const size_t*)elem_array,
747 err ); MSQ_CHKERR(err);
752 const VertexHandle* elem_array,
756 myTags->set_vertex_data( (
size_t)handle,
758 (
const size_t*)elem_array,
760 err ); MSQ_CHKERR(err);
765 const VertexHandle* elem_array,
769 myTags->get_vertex_data( (
size_t)handle,
771 (
const size_t*)elem_array,
773 err ); MSQ_CHKERR(err);
780 MsqPrintError err(cerr);
783 int mNumInterfaceSmoothIters = 5;
784 bool mFixBndryInInterfaceSmooth =
true;
785 bool project_gradient=
false;
786 double cos_crease_angle=0.2;
789 std::vector<Mesquite::Mesh::VertexHandle> vertices;
791 if (MSQ_CHKERR(err)) {std::cout << err << std::endl; exit(EXIT_FAILURE);}
792 int num_vertices = vertices.size();
795 std::vector<bool> app_fixed(num_vertices);
798 if (MSQ_CHKERR(err)) {std::cout << err << std::endl; exit(EXIT_FAILURE);}
799 int num_app_fixed = 0;
801 for (
int i = 0; i < num_vertices; i++)
803 if (app_fixed[i]) num_app_fixed++;
806 std::cout <<
"mesh has " << num_vertices <<
" vertices and " << num_app_fixed <<
" are app fixed. ";
809 Mesquite::PlanarDomain geom( PlanarDomain::XY );
815 Mesquite::MeshBoundaryDomain2D* mesh_domain =
new Mesquite::MeshBoundaryDomain2D( MeshBoundaryDomain2D::XY, 0.0, project_gradient,
816 Mesquite::MeshBoundaryDomain2D::QUADRATIC);
817 mesh_domain->skin_area_mesh(&mesh,cos_crease_angle,
"material");
819 std::vector<Mesquite::Mesh::VertexHandle> theBoundaryVertices;
820 mesh_domain->get_boundary_vertices( theBoundaryVertices );
822 int num_boundary_vertices = theBoundaryVertices.size();
824 std::vector<Mesquite::Mesh::VertexHandle> theBoundaryEdges;
825 mesh_domain->get_boundary_edges( theBoundaryEdges );
828 std::vector<bool> fixed_flags_boundary(num_boundary_vertices);
831 std::vector<bool> app_fixed_boundary(num_boundary_vertices);
834 int num_app_fixed_boundary = 0;
835 for (
int i = 0; i < num_boundary_vertices; i++)
837 if (app_fixed_boundary[i]) num_app_fixed_boundary++;
840 std::cout <<
"mesh has " << num_boundary_vertices <<
" boundary vertices and " << num_app_fixed_boundary <<
" are app fixed" << std::endl;
844 int num_fixed_boundary_flags = 0;
846 std::vector<Mesquite::Mesh::VertexHandle> theCornerVertices;
847 mesh_domain->get_corner_vertices( theCornerVertices );
851 for (
int i = 0; i < num_boundary_vertices; i++)
853 if (!mFixBndryInInterfaceSmooth)
854 fixed_flags_boundary[i] =
false;
856 fixed_flags_boundary[i] = app_fixed_boundary[i];
858 for (
int j = 0; j < theCornerVertices.size(); j++)
861 if (theCornerVertices[j] == theBoundaryVertices[i])
863 fixed_flags_boundary[i] =
true;
864 num_fixed_boundary_flags++;
869 printf(
"fixed %d of %d boundary vertices (those classified corner)\n", num_fixed_boundary_flags, num_boundary_vertices);
873 Mesquite::InstructionQueue boundary_queue;
874 Mesquite::InstructionQueue interior_queue;
877 boundary_queue.set_slaved_ho_node_mode(Settings::SLAVE_ALL);
878 interior_queue.set_slaved_ho_node_mode(Settings::SLAVE_ALL);
880 TShapeB1 targetMetric;
884 TQualityMetric metric( &tc, &targetMetric );
886 Mesquite::LPtoPTemplate* obj_func =
new Mesquite::LPtoPTemplate(&metric, pOrder, err);
887 if (MSQ_CHKERR(err)) {std::cout << err << std::endl; exit(EXIT_FAILURE);}
889 Mesquite::QuasiNewton* boundary_alg =
new Mesquite::QuasiNewton( obj_func);
890 boundary_alg->use_element_on_vertex_patch();
892 Mesquite::QuasiNewton* interior_alg =
new Mesquite::QuasiNewton( obj_func );
893 interior_alg->use_global_patch();
896 double grad_norm = 1e-5;
897 double successiveEps = 1e-5;
898 int boundary_outer = 5;
899 int boundary_inner = 3;
902 Mesquite::TerminationCriterion* boundaryTermInner =
new Mesquite::TerminationCriterion();
903 Mesquite::TerminationCriterion* boundaryTermOuter =
new Mesquite::TerminationCriterion();
906 boundaryTermOuter->add_relative_successive_improvement(successiveEps);
907 boundaryTermOuter->add_iteration_limit(boundary_outer);
908 boundaryTermInner->add_iteration_limit(boundary_inner);
910 ostringstream bndryStream;
911 bndryStream<<
"boundary_"<<targetMetric.get_name()<<
"_p"<<pOrder;
912 boundaryTermOuter->write_mesh_steps(bndryStream.str().c_str());
913 boundary_alg->set_outer_termination_criterion(boundaryTermOuter);
914 boundary_alg->set_inner_termination_criterion(boundaryTermInner);
917 Mesquite::TerminationCriterion* interiorTermInner =
new Mesquite::TerminationCriterion();
918 Mesquite::TerminationCriterion* interiorTermOuter =
new Mesquite::TerminationCriterion();
919 interiorTermInner->add_absolute_gradient_L2_norm(grad_norm);
920 interiorTermInner->add_relative_successive_improvement(successiveEps);
922 interiorTermInner->add_iteration_limit(100);
924 ostringstream interiorStream;
925 interiorStream<<
"interior_"<<targetMetric.get_name()<<
"_p"<<pOrder;
926 interiorTermOuter->write_mesh_steps(interiorStream.str().c_str());
927 interiorTermOuter->add_iteration_limit(1);
928 interior_alg->set_outer_termination_criterion(interiorTermOuter);
929 interior_alg->set_inner_termination_criterion(interiorTermInner);
943 boundary_queue.set_master_quality_improver(boundary_alg, err);
945 if (MSQ_CHKERR(err)) {std::cout << err << std::endl; exit(EXIT_FAILURE);}
949 interior_queue.set_master_quality_improver(interior_alg, err);
951 if (MSQ_CHKERR(err)) {std::cout << err << std::endl; exit(EXIT_FAILURE);}
955 std::vector<bool> fixed_flags(num_vertices);
957 for (
int j=0; j<mNumInterfaceSmoothIters; j++) {
959 cout<<
" Boundary + Interior smoothing pass "<< j<<
"....."<<endl;
962 for (
int i = 0; i < num_vertices; i++) fixed_flags[i] =
true;
964 if (MSQ_CHKERR(err)) {std::cout << err << std::endl; exit(EXIT_FAILURE);}
967 if (MSQ_CHKERR(err)) {std::cout << err << std::endl; exit(EXIT_FAILURE);}
973 if (MSQ_CHKERR(err)) {std::cout << err << std::endl; exit(EXIT_FAILURE);}
975 for (
int i = 0; i < num_vertices; i++)
977 if (fixed_flags[i]) num_fixed++;
980 std::cout <<
" For Boundary smooth, mesh has " << num_vertices <<
" vertices and " << num_fixed <<
" are fixed. "<<endl;
986 boundary_queue.run_instructions(&mesh, mesh_domain, err);
987 if (MSQ_CHKERR(err)) {std::cout << err << std::endl; exit(EXIT_FAILURE);}
988 cout<<
" boundary smooth completed in "<<boundaryTermOuter->get_iteration_count()<<
" outer and "<<boundaryTermInner->get_iteration_count()<<
" inner iterations."<<endl;
993 if (!mFixBndryInInterfaceSmooth)
998 for (
int i = 0; i < num_vertices; i++) fixed_flags[i] =
false;
1008 if (MSQ_CHKERR(err)) {std::cout << err << std::endl; exit(EXIT_FAILURE);}
1009 for (
int i = 0; i < num_boundary_vertices; i++) fixed_flags[i] =
true;
1012 if (MSQ_CHKERR(err)) {std::cout << err << std::endl; exit(EXIT_FAILURE);}
1018 if (MSQ_CHKERR(err)) {std::cout << err << std::endl; exit(EXIT_FAILURE);}
1020 for (
int i = 0; i < num_vertices; i++)
1022 if (fixed_flags[i]) num_fixed++;
1025 std::cout <<
" For Interior smooth, mesh has " << num_vertices <<
" vertices and " << num_fixed <<
" are fixed. "<<endl;
1030 interior_queue.run_instructions(&mesh, &geom, err);
1031 if (MSQ_CHKERR(err)) {std::cout << err << std::endl; exit(EXIT_FAILURE);}
1032 cout<<
" interior smooth completed in "<<interiorTermOuter->get_iteration_count()<<
" outer and "<<interiorTermInner->get_iteration_count()<<
" inner iterations."<<endl;
1038 delete interiorTermOuter;
1039 delete interiorTermInner;
1040 delete boundaryTermOuter;
1041 delete boundaryTermInner;
1042 delete interior_alg;
1043 delete boundary_alg;
1054 MsqDebug::enable(1);
1055 MsqPrintError err(cerr);
1059 const double vert_move_tol = 1e-3;
1061 switch (mesquite_option)
1063 case 0: method =
new LaplaceWrapper();
break;
1064 case 1: method =
new UntangleWrapper();
break;
1065 case 2: method =
new ShapeImprover();
break;
1066 case 3: method =
new PaverMinEdgeLengthWrapper(vert_move_tol);
break;
1069 if( mesquite_option < 4 )
1072 method->set_slaved_ho_node_mode(Settings::SLAVE_NONE);
1074 if( this->Dimension() == 3 )
1075 method->run_instructions(&msq_mesh, err);
1078 Vector3D normal(0,0,1);
1079 Vector3D point(0,0,0);
1080 PlanarDomain mesh_plane(normal, point);
1082 method->run_instructions(&msq_mesh, &mesh_plane, err);
1088 BoundaryPreservingOptimization( msq_mesh );
void vertices_set_byte(const VertexHandle *vert_array, const unsigned char *byte_array, size_t array_size, MsqError &err)
void get_all_vertices(std::vector< VertexHandle > &vertices, MsqError &err)
void vertices_set_fixed_flag(const VertexHandle vert_array[], const std::vector< bool > &fixed_flag_array, size_t num_vtx, MsqError &err)
TagHandle tag_create(const std::string &tag_name, TagType type, unsigned length, const void *default_value, MsqError &err)
void vertex_set_coordinates(VertexHandle vertex, const Vector3D &coordinates, MsqError &err)
int Size() const
Logical size of the array.
int GetNDofs() const
Returns number of degrees of freedom.
virtual void GetVertices(Array< int > &v) const =0
Returns element's vertices.
int GetNBE() const
Returns number of boundary elements.
MesquiteMesh(mfem::Mesh *mfem_mesh)
void BuildElementToDofTable()
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
void tag_get_element_data(TagHandle handle, size_t num_elems, const ElementHandle *elem_array, void *tag_data, MsqError &err)
int GetNE() const
Returns number of elements.
void get_all_elements(std::vector< ElementHandle > &elements, MsqError &err)
void vertices_get_coordinates(const VertexHandle vert_array[], MsqVertex *coordinates, size_t num_vtx, MsqError &err)
void tag_properties(TagHandle handle, std::string &name_out, TagType &type_out, unsigned &length_out, MsqError &err)
void vertex_set_byte(VertexHandle vertex, unsigned char byte, MsqError &err)
void MesquiteSmooth(const int mesquite_option=0)
void vertices_get_attached_elements(const VertexHandle *vertex_array, size_t num_vertex, std::vector< ElementHandle > &elements, std::vector< size_t > &offsets, MsqError &err)
void tag_get_vertex_data(TagHandle handle, size_t num_elems, const VertexHandle *node_array, void *tag_data, MsqError &err)
void vertices_get_fixed_flag(const VertexHandle vert_array[], std::vector< bool > &fixed_flag_array, size_t num_vtx, MsqError &err)
virtual void GetElementDofs(int i, Array< int > &dofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
void tag_set_vertex_data(TagHandle handle, size_t num_elems, const VertexHandle *node_array, const void *tag_data, MsqError &err)
void tag_delete(TagHandle handle, MsqError &err)
void Transpose(const Table &A, Table &At, int _ncols_A)
Transpose a Table.
int GetElementType(int i) const
Returns the type of element i.
const Element * GetElement(int i) const
FiniteElementSpace * FESpace()
void vertices_get_byte(const VertexHandle *vertex, unsigned char *byte_array, size_t array_size, MsqError &err)
virtual void GetBdrElementDofs(int i, Array< int > &dofs) const
Returns indexes of degrees of freedom for i'th boundary element.
void GetBdrElementVertices(int i, Array< int > &dofs) const
Returns the indices of the dofs of boundary element i.
void vertex_get_byte(const VertexHandle vertex, unsigned char *byte, MsqError &err)
void elements_get_topologies(const ElementHandle *element_handle_array, EntityTopology *element_topologies, size_t num_elements, MsqError &err)
void GetNodes(Vector &node_coord) const
void SetNode(int i, const double *coord)
void GetNode(int i, double *coord)
const Table & GetElementToDofTable() const
TagHandle tag_get(const std::string &name, MsqError &err)
void tag_set_element_data(TagHandle handle, size_t num_elems, const ElementHandle *elem_array, const void *tag_data, MsqError &err)
int GetAttribute(int i) const
Return the attribute of element i.
void elements_get_attached_vertices(const ElementHandle *elem_handles, size_t num_elems, std::vector< VertexHandle > &vert_handles, std::vector< size_t > &offsets, MsqError &err)
int get_geometric_dimension(MsqError &err)
Table * GetVertexToElementTable()
The returned Table must be destroyed by the caller.