35 #include "PatchData.hpp"
36 #include "MsqMeshEntity.hpp"
37 #include "MsqFreeVertexIndexIterator.hpp"
38 #include "MeshSet.hpp"
39 #include "MsqTimer.hpp"
40 #include "MsqDebug.hpp"
41 #include "TargetMatrix.hpp"
42 #include "TargetCalculator.hpp"
44 #ifdef MSQ_USE_OLD_STD_HEADERS
57 #ifdef MSQ_USE_OLD_IO_HEADERS
58 # include <iostream.h>
68 : targetMatrices(
"MSQ_TARGET_MATRIX",
Mesh::DOUBLE ),
72 mType(UNDEFINED_PATCH_TYPE),
94 for (
size_t i=0;
i<count; ++
i) {
129 for (
size_t i=0;
i<count; ++
i) {
134 for (
size_t j=0;
j<nve; ++
j) {
135 min =
det(A[
j]) < min ?
det(A[
j]) : min;
136 max =
det(A[j]) > max ?
det(A[j]) : max;
149 result = (min<=
MSQ_MIN) ? 0.001 * max : 0;
168 int total_num_corners =0;
174 total_num_corners += nve;
175 for (
int c=0; c<nve; ++c) {
181 avg = avg / total_num_corners;
204 size_t *sta =
new size_t[numv + 1];
206 size_t *ord =
new size_t[numv];
207 size_t *per =
new size_t[numv];
209 size_t *que1 =
new size_t[numv];
210 size_t *que2 =
new size_t[numv];
240 memset(sta, 0, (numv+1)*
sizeof(
size_t));
241 for (i = 0; i < nume; ++
i) {
245 for (j = 0; j < vtc; ++
j) {
255 for (i = 1; i <= numv; ++
i) {
261 vte =
new size_t[toc];
265 for (i = 0; i < nume; ++
i) {
269 for (j = 0; j < vtc; ++
j) {
270 vte[sta[vtx[
j]]++] =
i;
274 for (i = numv; i > 0; --
i) {
285 for (i = 0; i < numv; ++
i) {
295 memset(per, 0, numv*
sizeof(
size_t));
322 for (j = 0; j < vtc; ++
j) {
349 for (i = 0; i < numv; ++
i) {
365 pel =
new size_t[nume];
366 for (i = 0; i < nume; ++
i) {
371 for (i = 0; i < numv; ++
i) {
380 if (nume == pel[loc]) {
395 for (i = 0; i < numv; ++
i) {
402 PatchDataMem<Vector3D> v2n(numv);
403 for (i = 0; i < numv; ++
i) {
421 for (i = 0; i < nume; ++
i) {
425 for (j = 0; j < vtc; ++
j) {
426 vtx[
j] = per[vtx[
j]];
463 for (
size_t i = 0; i < count; ++
i)
474 for (
size_t i = 0; i < count; ++
i)
581 double step_size, MsqError &err)
585 MSQ_SETERR(err)(
"The directional vector must be of length numVertices.",
590 MsqFreeVertexIndexIterator free_iter(
this, err);
592 while (free_iter.next())
594 vertexArray[free_iter.value()] += (step_size * dk[free_iter.value()]);
605 && dk[m] != -zero_3d )
607 MSQ_DBGOUT(3) <<
"dk["<<m<<
"]: " << dk[m] << endl;
608 MSQ_DBGOUT(3) <<
"moving a fixed vertex." << endl;
636 if (nb_vtx != memento->numVertices)
643 MsqFreeVertexIndexIterator free_iter(
this, err);
646 while (free_iter.next())
649 vertexArray[m] = memento->vertices[m] + (step_size * dk[m]);
660 && ( dk[m] != zero_3d && dk[m] != -zero_3d) )
662 MSQ_DBGOUT(3) <<
"dk["<<m<<
"]: " << dk[m] << endl;
663 MSQ_DBGOUT(3) <<
"moving a fixed vertex." << endl;
685 double temp_dist=0.0;
687 MsqFreeVertexIndexIterator free_iter(
this, err);
MSQ_ERRZERO(err);
689 while (free_iter.next())
693 temp_dist=temp_vec.length_squared();
694 if(temp_dist>max_dist)
736 vector<Vector3D> &coords,
744 const size_t *vertex_indices =
elementArray[elem_index].get_vertex_index_array();
747 size_t num_verts =
elementArray[elem_index].vertex_count();
748 coords.reserve(coords.size() + num_verts);
749 for (
size_t i = 0; i < num_verts; i++)
760 vector<size_t> &vertex_indices,
764 elementArray[elem_index].get_vertex_indices(vertex_indices);
769 vector<size_t> &elem_indices,
774 elem_indices.resize( count );
775 memcpy( &elem_indices[0], ptr, count *
sizeof(
size_t) );
779 size_t& array_len_out,
790 array_len_out = end - begin;
804 vector<size_t> &vert_indices,
808 vector<size_t> elem_indices;
809 vector<size_t> temp_vert_indices;
810 msq_std::vector<size_t>::iterator iter;
818 while(!elem_indices.empty()){
819 elems[elem_indices.back()].get_connected_vertices(vertex_index, temp_vert_indices,err);
821 elem_indices.pop_back();
824 while(!temp_vert_indices.empty()){
825 cur_vert=temp_vert_indices.back();
826 temp_vert_indices.pop_back();
827 iter=vert_indices.begin();
829 while(iter!=vert_indices.end() && !found){
830 if(*(iter)==cur_vert)
835 vert_indices.push_back(cur_vert);
851 vector<size_t> &adj_ents,
857 vector<size_t> verts;
864 int num_vert=verts.size();
867 for(i=0;i<num_vert;++
i){
871 length_elem_on_vert[
i]=elem_on_vert[
i].size();
883 while(j<length_elem_on_vert[i]){
885 this_ent=elem_on_vert[
i][
j];
887 if(this_ent!=ent_ind){
897 while(k2<length_elem_on_vert[k1]){
899 if(elem_on_vert[k1][k2]==this_ent){
902 elem_on_vert[k1][k2]=ent_ind;
905 k2+=length_elem_on_vert[k1];
915 if(counter>n && this_ent!=ent_ind){
916 adj_ents.push_back(this_ent);
957 PatchDataMem<MsqMeshEntity>::iterator elem_iter;
958 const PatchDataMem<MsqMeshEntity>::iterator elem_end =
elementArray.end();
959 for (elem_iter =
elementArray.begin(); elem_iter != elem_end; ++elem_iter)
961 size_t* conn_iter = elem_iter->get_vertex_index_array();
962 const size_t* conn_end = conn_iter + elem_iter->node_count();
963 for ( ; conn_iter != conn_end; ++conn_iter )
974 size_t prev = *off_iter;
976 for ( ; off_iter != off_end; ++off_iter)
994 size_t* conn_iter =
elementArray[
i].get_vertex_index_array();
995 const size_t* conn_end = conn_iter +
elementArray[
i].node_count();
996 for ( ; conn_iter != conn_end; ++conn_iter )
1009 PatchData &subpatch,
1020 msq_std::map<size_t, size_t> vertex_index_map;
1023 const size_t* vertex_adjacencies;
1029 size_t which_elem, which_vert, vertex_count = 0;
1030 size_t vertex_uses = 0;
1031 for (which_elem = 0; which_elem < num_elems; ++which_elem )
1033 size_t elem_index = vertex_adjacencies[which_elem];
1035 for (which_vert = elem.node_count(); which_vert--; )
1037 size_t vert_index = elem.get_vertex_index(which_vert);
1038 if (vertex_index_map.find(vert_index) != vertex_index_map.end())
1039 vertex_index_map[vert_index] = vertex_count++;
1041 vertex_uses += elem.node_count();
1045 subpatch.vertexHandlesArray.resize( vertex_count );
1046 subpatch.elementArray.resize( num_elems );
1047 subpatch.elementHandlesArray.resize( num_elems );
1048 subpatch.elemConnectivityArray.resize( vertex_uses );
1055 msq_std::map<size_t,size_t>::iterator iter;
1056 for (iter = vertex_index_map.begin(); iter != vertex_index_map.end(); ++iter)
1060 msq_std::vector<size_t> elem_conn_offsets(vertex_uses);
1061 size_t* elem_connectivity = &(subpatch.elemConnectivityArray[0]);
1062 size_t elem_conn_index = 0;
1063 for (which_elem = 0; which_elem < num_elems; ++which_elem)
1065 size_t elem_index = vertex_adjacencies[which_elem];
1067 elem_conn_offsets[which_elem] = elem_conn_index;
1068 for (which_vert = 0; which_vert < elem.node_count(); which_vert++ )
1070 size_t vert_index = elem.get_vertex_index(which_vert);
1073 elem_connectivity[elem_conn_index++] = vertex_index_map[vert_index];
1075 subpatch.elementArray[which_elem].set_element_type( elem.get_element_type() );
1079 subpatch.initialize_data( &elem_conn_offsets[0], err );
MSQ_ERRRTN(err);
1083 subpatch.vertexArray.resize( vertex_count );
1084 for (which_vert = 0; which_vert < vertex_count; ++which_vert)
1086 size_t vert_index = (size_t)(subpatch.vertexHandlesArray[which_vert]);
1088 subpatch.vertexArray[which_vert] =
vertexArray[vert_index];
1147 surf_norm.normalize();
1186 MsqError &err)
const
1190 elementArray[elem_index].get_centroid(surf_norm, *
this, err);
1226 const unsigned count = elem.vertex_count();
1227 const size_t*
const vertex_indices = elem.get_vertex_index_array();
1238 for (
unsigned i = 0; i < count; ++
i)
1243 for (
unsigned i = 0; i < count; ++
i)
1256 for (
unsigned i = 0; i < count; ++
i)
1257 normals_out[i] =
vertexArray[ vertex_indices[i] ];
1268 if (ms->get_domain_constraint()!=NULL)
domainSet =
true; }
1270 ostream&
operator<<( ostream& stream,
const PatchData& pd )
1274 stream <<
"Vertices: " << endl;
1275 for (i = 0; i < pd.num_nodes(); ++
i)
1277 if (i == pd.num_vertices())
1278 stream <<
"Higher-Order Nodes: " << endl;
1280 stream << i <<
". ("
1281 << pd.vertexArray[
i].x() <<
","
1282 << pd.vertexArray[
i].y() <<
","
1283 << pd.vertexArray[
i].z()
1292 if (pd.vertAdjacencyArray.size())
1294 size_t j = pd.vertAdjacencyOffsets[
i];
1295 size_t end = pd.vertAdjacencyOffsets[i+1];
1296 for ( ; j < end; ++
j )
1297 stream <<
" " << pd.vertAdjacencyArray[j];
1303 stream <<
"Elements: " << endl;
1304 for (i = 0; i < pd.num_elements(); ++
i)
1306 stream << i <<
". ";
1307 switch (pd.elementArray[i].get_element_type()) {
1308 case POLYGON: stream <<
"Polygon";
break;
1309 case TRIANGLE: stream <<
"Tri";
break;
1311 case POLYHEDRON: stream <<
"Polyhedron";
break;
1314 case PRISM: stream <<
"Wedge";
break;
1315 case PYRAMID: stream <<
"Pyr";
break;
1316 default: stream <<
"Unknown";
break;
1318 stream << pd.elementArray[
i].node_count() <<
": ";
1319 for (
size_t j = 0; j < pd.elementArray[
i].node_count(); ++
j)
1320 stream << pd.elementArray[i].get_vertex_index_array()[
j] <<
" ";
1325 stream <<
"MeshSet: " << (pd.meshSet?
"yes":
"no") << endl;
1326 stream <<
"domainSet: " << (pd.domainSet?
"true":
"false") << endl;
1331 if (pd.haveComputedInfos)
1333 stream <<
"ComputedInfos:" << endl;
1350 return stream << endl;
1376 bool higher_order =
false;
1379 size_t start = elem_offset_array[
i];
1380 size_t conn_len = elem_offset_array[i+1] - start;
1381 assert(conn_len > 0);
1384 higher_order =
true;
1405 size_t* conn_array = elem.get_vertex_index_array();
1409 vertex_index_map[ conn_array[j] ] = 0;
1411 vertex_index_map[ conn_array[j] ] = 1;
1422 if (!vertex_index_map[i])
1425 vertex_index_map[
i] =
i;
1428 else if (vertex_index_map[j])
1431 vertex_index_map[
j] =
j;
1440 vertex_index_map[
i] =
j;
1441 vertex_index_map[
j] =
i;
1457 if (vertex_index_map[i])
1461 vertex_index_map[
i] =
i;
1472 size_t element_count,
1473 size_t vertex_use_count,
void update_mesh(MsqError &err)
Updates the underlying mesh (the Mesquite::Mesh implementation) with new node coordinates and flag va...
void set_free_vertices_soft_fixed(MsqError &err)
Add a soft_fixed flag to all free vertices in the patch.
void swap(int &a, int &b)
#define MSQ_ERRZERO(err)
Return zero/NULL on error.
#define MSQ_DBG(flag)
Check if a debug flag is activated - evaluates to a bool.
double get_max_vertex_movement_squared(PatchDataVerticesMemento *memento, MsqError &err)
Calculates the distance each vertex has moved from its original position as defined by the PatchDataV...
PatchDataMem< MsqVertex > vertexArray
void set_all_vertices_soft_free(MsqError &err)
Remove the soft_fixed flag from all vertices in the patch.
void resize(size_t new_size)
MsqVertex & vertex_by_index(size_t index)
Returns the start of the vertex->element array.
Mesquite::MeshDomain * get_domain_constraint()
Returns the domain associated with the MeshSet from which the Patch originates.
CornerTag< TargetMatrix > targetMatrices
Target matrix data.
virtual void closest_point(Mesh::EntityHandle handle, const Vector3D &position, Vector3D &closest, Vector3D &normal, MsqError &err) const =0
evaluate closest point and normal
void get_domain_normals_at_corners(size_t element_index, Vector3D normals_out[], MsqError &err)
Get surface normal at a point where the surface is the domain of an element and the point is the loca...
Vector_n max(const Array_n_const &v1, const Array_n_const &v2)
EntityHandle VertexHandle
vertex is fixed. This flag can be set on and off.
void allocate_storage(size_t vertex_count, size_t element_count, size_t vertex_use_count, MsqError &err)
Used by test code when creating a PatchData directly.
void get_vertex_element_indices(size_t vertex_index, msq_std::vector< size_t > &elem_indices, MsqError &err)
Class Mesh is the main class that holds all information to describe the current state of the mesh...
const int MSQ_MAX_NUM_VERT_PER_ENT
void note_have_info(ComputedInfo info)
PatchDataMem< size_t > elemConnectivityArray
int num_free_vertices(MsqError &err) const
Returns the number of elements in the current patch who are free to move.
double computedInfos[MAX_COMPUTED_INFO_ENUM]
static double compute_Lambda(const Matrix3D &A, MsqError &err)
Note that this function is static, i.e. it can be used independently of an object.
T norm(const NVec< DIM, T > &v)
void initialize_data(size_t *elem_offset_array, MsqError &err)
Call after filling vertex handle and connectivity arrays to finish initializing the PatchData...
void update_mesh(const PatchData &pd, MsqError &err)
Updates the coordinates in the underlying mesh with the coordinates stored in PatchData.
void get_minmax_element_unsigned_area(double &min, double &max, MsqError &err)
Returns the maximum volume or area out of all the elements in the patch This information is stored in...
void generate_vertex_to_element_data()
average corner determinant out of all elements in the patch
void get_adjacent_entities_via_n_dim(int n, size_t ent_ind, msq_std::vector< size_t > &adj_ents, MsqError &err)
Get the indices of entities attached to entity (given by ent_ind). adj_ents is filled with the indice...
void get_domain_normal_at_element(size_t elem_index, Vector3D &surf_norm, MsqError &err) const
invalid function argument passed
size_t num_elements() const
number of elements in the Patch.
NVec< 3, double > Vector3D
void get_subpatch(size_t center_vertex_index, PatchData &pd_to_fill, MsqError &err)
Fills a PatchData with the elements attached to a center vertex.
double get_barrier_delta(MsqError &err)
Returns delta based on the minimum and maximum corner determinant over all elements in the patch This...
#define MSQ_CHKERR(err)
Mesquite's Error Checking macro.
bool have_computed_info(ComputedInfo info) const
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
virtual void snap_to(Mesh::EntityHandle entity_handle, Vector3D &coordinate) const =0
Modifies "coordinate" so that it lies on the domain to which "entity_handle" is constrained.
minimum and maximum corner area out of all elements in the patch
void snap_vertex_to_domain(size_t vertex_index, MsqError &err)
Adjust the position of the specified vertex so that it lies on its constraining domain.
void get_element_vertex_indices(size_t elem_index, msq_std::vector< size_t > &vertex_indices, MsqError &err)
void get_adjacent_vertex_indices(size_t vertex_index, msq_std::vector< size_t > &vert_indices, MsqError &err)
void update_cached_normals(MsqError &)
size_t num_nodes() const
Get number of nodes (vertex + higher-order nodes)
PatchDataMem< Vector3D > vertexNormals
double get_average_Lambda_3d(MsqError &err)
Returns average corner determinant over all corners in the patch This information is stored in the pa...
maximum edge length in the patch
size_t num_vertices() const
number of vertices in the patch.
PatchDataMem< size_t > vertAdjacencyOffsets
double det(const Matrix3D &A)
size_t num_corners()
number of elements corners in the Patch.
PatchDataMem< MsqMeshEntity > elementArray
void move_free_vertices_constrained(Vector3D dk[], size_t nb_vtx, double step_size, MsqError &err)
Moves free vertices and then snaps the free vertices to the domain.
Vector_n min(const Array_n_const &v1, const Array_n_const &v2)
void set_free_vertices_constrained(PatchDataVerticesMemento *memento, Vector3D dk[], size_t nb_vtx, double step_size, MsqError &err)
void get_domain_normal_at_vertex(size_t vertex_index, bool normalize, Vector3D &surf_norm, MsqError &err)
vertex is always fixed. This can only be set on and never off.
object is in an invalid state
#define MSQ_FUNCTION_TIMER(NAME)
void reorder()
Reorders the mesh data.
PatchDataMem< Mesh::ElementHandle > elementHandlesArray
msq_stdio::ostream & operator<<(msq_stdio::ostream &s, const Matrix3D &A)
PatchDataMem< Mesh::VertexHandle > vertexHandlesArray
#define MSQ_DBGOUT(flag)
Check debug flag and return ostream associated with flag.
const MsqMeshEntity * get_element_array(MsqError &err) const
Returns a pointer to the start of the element array.
virtual void normal_at(Mesh::EntityHandle entity_handle, Vector3D &coordinate) const =0
Returns the normal of the domain to which "entity_handle" is constrained.
minimum and maximum corner volume out of all elements in the patch
minimum volume or area out of all elements in the patch
size_t * get_vertex_element_adjacencies(size_t vertex_index, size_t &array_len_out, MsqError &err)
#define MSQ_ERRRTN(err)
If passed error is true, return from a void function.
maximum volume or area out of all elements in the patch
void set_all_vertices_soft_fixed(MsqError &err)
Add a soft_fixed flag to all vertices in the patch.
PatchDataMem< size_t > vertAdjacencyArray
void set_mesh_set(MeshSet *ms)
Sets the originating meshSet.
minimum edge length in the patch
void get_element_vertex_coordinates(size_t elem_index, msq_std::vector< Vector3D > &coords, MsqError &err)
Get the coordinates of vertices attached to the specified element.
unsigned num_free_nodes(MsqError &err) const