LCOV - code coverage report
Current view: top level - src/mesquite/Mesh - PatchData.hpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 102 150 68.0 %
Date: 2020-07-18 00:09:26 Functions: 31 38 81.6 %
Branches: 43 138 31.2 %

           Branch data     Line data    Source code
       1                 :            : /* *****************************************************************
       2                 :            :     MESQUITE -- The Mesh Quality Improvement Toolkit
       3                 :            : 
       4                 :            :     Copyright 2004 Sandia Corporation and Argonne National
       5                 :            :     Laboratory.  Under the terms of Contract DE-AC04-94AL85000
       6                 :            :     with Sandia Corporation, the U.S. Government retains certain
       7                 :            :     rights in this software.
       8                 :            : 
       9                 :            :     This library is free software; you can redistribute it and/or
      10                 :            :     modify it under the terms of the GNU Lesser General Public
      11                 :            :     License as published by the Free Software Foundation; either
      12                 :            :     version 2.1 of the License, or (at your option) any later version.
      13                 :            : 
      14                 :            :     This library is distributed in the hope that it will be useful,
      15                 :            :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16                 :            :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17                 :            :     Lesser General Public License for more details.
      18                 :            : 
      19                 :            :     You should have received a copy of the GNU Lesser General Public License
      20                 :            :     (lgpl.txt) along with this library; if not, write to the Free Software
      21                 :            :     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      22                 :            : 
      23                 :            :     [email protected], [email protected], [email protected],
      24                 :            :     [email protected], [email protected], [email protected]
      25                 :            : 
      26                 :            :   ***************************************************************** */
      27                 :            : #ifndef MESQUITE_PATCHDATA_HPP
      28                 :            : #define MESQUITE_PATCHDATA_HPP
      29                 :            : /*!
      30                 :            :   \file   PatchData.hpp
      31                 :            :   \brief    This file contains the PatchData class and its associated mementos.
      32                 :            : 
      33                 :            : 
      34                 :            :   The PatchData class provides the mesh information and functionality to Mesquite.
      35                 :            :   The PatchDataVerticesMemento class allows the state of a PatchData object to be saved
      36                 :            :   in order to later restore that object to its previous state.
      37                 :            : 
      38                 :            :   \author Thomas Leurent
      39                 :            :   \author Michael Brewer
      40                 :            :   \date   2002-01-17
      41                 :            : */
      42                 :            : 
      43                 :            : #include "Mesquite.hpp"
      44                 :            : #include "MsqVertex.hpp"
      45                 :            : #include "MsqMeshEntity.hpp"
      46                 :            : #include "MsqVertex.hpp"
      47                 :            : #include "MeshInterface.hpp"
      48                 :            : #include "MsqError.hpp"
      49                 :            : #include "Settings.hpp"
      50                 :            : #include "NodeSet.hpp"
      51                 :            : #include "MappingFunction.hpp"
      52                 :            : 
      53                 :            : #include <cstddef>
      54                 :            : #include <cstdlib>
      55                 :            : #include <map>
      56                 :            : #include <vector>
      57                 :            : #include <iosfwd>
      58                 :            : 
      59                 :            : namespace MBMesquite
      60                 :            : {
      61                 :            : class ExtraData;
      62                 :            : class PatchDataVerticesMemento;
      63                 :            : class Mesh;
      64                 :            : class Settings;
      65                 :            : 
      66                 :            : /*!
      67                 :            :   Contains all the mesh information necessary for
      68                 :            :   one iteration of the optimization algorithms over a
      69                 :            :   local mesh patch. */
      70                 :            : class PatchData
      71                 :            : {
      72                 :            :   public:
      73                 :            :     // Constructor/Destructor
      74                 :            :     MESQUITE_EXPORT PatchData();
      75                 :            :     MESQUITE_EXPORT ~PatchData();
      76                 :            : 
      77                 :       1239 :     MESQUITE_EXPORT void attach_settings( const Settings* p_settings )
      78                 :            :     {
      79                 :       1239 :         mSettings = p_settings;
      80                 :       1239 :     }
      81                 :            :     MESQUITE_EXPORT const Settings* settings() const
      82                 :            :     {
      83                 :            :         return mSettings;
      84                 :            :     }
      85                 :            : 
      86                 :            :     /**\brief For use by testing code -- create patch explicitly
      87                 :            :      *
      88                 :            :      * Create a patch containing elements of the same type and
      89                 :            :      * without any higher-order nodes.
      90                 :            :      *
      91                 :            :      *\param num_vertex   Number of vertices in patch
      92                 :            :      *\param vtx_coords   Array of vertex coords.  Length must be 3*num_vertex
      93                 :            :      *\param type         Element type
      94                 :            :      *\param connectivity Element connectivity, specified as a list
      95                 :            :      *                    of vertex numbers, beginning with zero.
      96                 :            :      *\param vertex_fixed_flags Optional array to specify which vertices
      97                 :            :      *                    are to be marked as fixed.  If not specified,
      98                 :            :      *                    no vertices are fixed.
      99                 :            :      */
     100                 :            :     MESQUITE_EXPORT
     101                 :            :     void fill( size_t num_vertex, const double* vtx_coords, size_t num_elem, EntityTopology type,
     102                 :            :                const size_t* connectivity, const bool* vertex_fixed_flags, MsqError& err );
     103                 :            : 
     104                 :            :     /**\brief For use by testing code -- create patch explicitly
     105                 :            :      *
     106                 :            :      * Create a patch containing elements without any higher-order nodes.
     107                 :            :      *
     108                 :            :      *\param num_vertex   Number of vertices in patch
     109                 :            :      *\param vtx_coords   Array of vertex coords.  Length must be 3*num_vertex
     110                 :            :      *\param elem_types   The type of each element
     111                 :            :      *\param connectivity Element connectivity, specified as a list
     112                 :            :      *                    of vertex numbers, beginning with zero.
     113                 :            :      *\param vertex_fixed_flags Optional array to specify which vertices
     114                 :            :      *                    are to be marked as fixed.  If NULL,
     115                 :            :      *                    no vertices are fixed.
     116                 :            :      */
     117                 :            :     MESQUITE_EXPORT
     118                 :            :     void fill( size_t num_vertex, const double* vtx_coords, size_t num_elem, const EntityTopology* elem_types,
     119                 :            :                const size_t* connectivity, const bool* vertex_fixed_flags, MsqError& err );
     120                 :            : 
     121                 :            :     /**\brief For use by testing code -- create patch explicitly
     122                 :            :      *
     123                 :            :      * Most general form of fill function.  Works for polygons,
     124                 :            :      * elements with higher-order nodes, etc.
     125                 :            :      *
     126                 :            :      *\param num_vertex   Number of vertices in patch
     127                 :            :      *\param vtx_coords   Array of vertex coords.  Length must be 3*num_vertex
     128                 :            :      *\param elem_types   The type of each element
     129                 :            :      *\param vertex_per_elem The length of the connectivity list for each element.
     130                 :            :      *\param connectivity Element connectivity, specified as a list
     131                 :            :      *                    of vertex numbers, beginning with zero.
     132                 :            :      *\param vertex_fixed_flags Optional array to specify which vertices
     133                 :            :      *                    are to be marked as fixed.  If NULL,
     134                 :            :      *                    no vertices are fixed.
     135                 :            :      */
     136                 :            :     MESQUITE_EXPORT
     137                 :            :     void fill( size_t num_vertex, const double* vtx_coords, size_t num_elem, const EntityTopology* elem_types,
     138                 :            :                const size_t* vertex_per_elem, const size_t* elem_connectivity, const bool* vertex_fixed_flags,
     139                 :            :                MsqError& err );
     140                 :            : 
     141                 :            :     /**\brief Create global patch
     142                 :            :      *
     143                 :            :      * Create a global patch - mesh should be initialized first.
     144                 :            :      */
     145                 :            :     MESQUITE_EXPORT
     146                 :            :     void fill_global_patch( MsqError& err );
     147                 :            : 
     148                 :            :     MESQUITE_EXPORT
     149                 :            :     void set_mesh_entities( std::vector< Mesh::ElementHandle >& patch_elems,
     150                 :            :                             std::vector< Mesh::VertexHandle >& free_vertices, MsqError& err );
     151                 :            : 
     152                 :            :   private:
     153                 :            :     //! Doesn't allow PatchData to be copied implicitly.
     154                 :            :     //! Mementos such as PatchDataVerticesMemento should be used when necessary.
     155                 :            :     PatchData( const PatchData& pd );
     156                 :            :     //! Doesn't allow a PatchData object to be assigned to another.
     157                 :            :     //! Mementos such as PatchDataVerticesMemento should be used when necessary.
     158                 :            :     PatchData& operator=( const PatchData& pd );
     159                 :            : 
     160                 :            :   public:
     161                 :            :     enum ComputedInfo
     162                 :            :     {
     163                 :            :         MIN_UNSIGNED_AREA = 0,  //!< minimum volume or area out of all elements in the patch
     164                 :            :         MAX_UNSIGNED_AREA,      //!< maximum volume or area out of all elements in the patch
     165                 :            :         MIN_EDGE_LENGTH,        //!< minimum edge length in the patch
     166                 :            :         MAX_EDGE_LENGTH,        //!< maximum edge length in the patch
     167                 :            :         MINMAX_SIGNED_DET2D,    //!< minimum and maximum corner area out of all elements in the patch
     168                 :            :         MINMAX_SIGNED_DET3D,    //!< minimum and maximum corner volume out of all elements in the
     169                 :            :                                 //!< patch
     170                 :            :         AVERAGE_DET3D,          //!< average corner determinant out of all elements in the patch
     171                 :            :         MAX_COMPUTED_INFO_ENUM
     172                 :            :     };
     173                 :            : 
     174                 :            :     //! This function clears the patch information such as maximum volume, etc ...
     175                 :            :     MESQUITE_EXPORT
     176                 :            :     void clear_computed_info()
     177                 :            :     {
     178                 :            :         haveComputedInfos = 0;
     179                 :            :     }
     180                 :            : 
     181                 :            :     MESQUITE_EXPORT
     182                 :          0 :     bool have_computed_info( ComputedInfo info ) const
     183                 :            :     {
     184                 :          0 :         return 0 != ( haveComputedInfos & ( 1 << info ) );
     185                 :            :     }
     186                 :            : 
     187                 :            :     //! Returns the maximum volume or area out of all the elements in the patch
     188                 :            :     //! This information is stored in the patch and should not decrease performance
     189                 :            :     //! when used properly. See also PatchData::clear_computed_info() .
     190                 :            :     MESQUITE_EXPORT
     191                 :            :     void get_minmax_element_unsigned_area( double& min, double& max, MsqError& err );
     192                 :            : 
     193                 :            :     MESQUITE_EXPORT
     194                 :            :     void get_minmax_edge_length( double& min, double& max ) const;
     195                 :            : 
     196                 :            :     //! Returns average corner determinant over all corners in the patch
     197                 :            :     //! This information is stored in the patch and should not decrease performance
     198                 :            :     //! when used properly. See also PatchData::clear_computed_info() .
     199                 :            :     //    double get_average_Lambda_3d(MsqError &err);
     200                 :            : 
     201                 :            :     //! Removes data
     202                 :            :     MESQUITE_EXPORT
     203                 :            :     void clear();
     204                 :            :     //! Reorders the mesh data
     205                 :            :     MESQUITE_EXPORT
     206                 :            :     void reorder();
     207                 :            : 
     208                 :            :     //! number of vertices in the patch.
     209                 :    9838453 :     MESQUITE_EXPORT size_t num_nodes() const
     210                 :            :     {
     211                 :    9838453 :         return vertexArray.size();
     212                 :            :     }
     213                 :   95744212 :     MESQUITE_EXPORT size_t num_free_vertices() const
     214                 :            :     {
     215                 :   95744212 :         return numFreeVertices;
     216                 :            :     }
     217                 :    1289796 :     MESQUITE_EXPORT size_t num_slave_vertices() const
     218                 :            :     {
     219                 :    1289796 :         return numSlaveVertices;
     220                 :            :     }
     221                 :            :     MESQUITE_EXPORT size_t num_fixed_vertices() const
     222                 :            :     {
     223                 :            :         return num_nodes() - num_free_vertices() - num_slave_vertices();
     224                 :            :     }
     225                 :            :     //! number of elements in the Patch.
     226                 :    2875356 :     MESQUITE_EXPORT size_t num_elements() const
     227                 :            :     {
     228                 :    2875356 :         return elementArray.size();
     229                 :            :     }
     230                 :            : 
     231                 :            :     MESQUITE_EXPORT bool is_vertex_free( size_t index ) const
     232                 :            :     {
     233                 :            :         return index < numFreeVertices;
     234                 :            :     }
     235                 :            :     MESQUITE_EXPORT bool is_vertex_not_free( size_t index ) const
     236                 :            :     {
     237                 :            :         return index >= numFreeVertices;
     238                 :            :     }
     239                 :      20574 :     MESQUITE_EXPORT bool is_vertex_slave( size_t index ) const
     240                 :            :     {
     241 [ +  + ][ +  + ]:      20574 :         return index >= numFreeVertices && ( index - numFreeVertices ) < numSlaveVertices;
     242                 :            :     }
     243                 :            :     MESQUITE_EXPORT bool is_vertex_fixed( size_t index ) const
     244                 :            :     {
     245                 :            :         return index >= numFreeVertices + numSlaveVertices;
     246                 :            :     }
     247                 :            : 
     248                 :            :     //! number of element corners (number of vertex uses) in patch
     249                 :            :     MESQUITE_EXPORT size_t num_corners() const;
     250                 :            : 
     251                 :            :     //! Returns a pointer to the start of the vertex array.
     252                 :            :     MESQUITE_EXPORT const MsqVertex* get_vertex_array( MsqError& err ) const;
     253                 :            :     // MsqVertex* get_vertex_array(MsqError &err);
     254                 :          0 :     MESQUITE_EXPORT const MsqVertex* get_vertex_array() const
     255                 :            :     {
     256                 :          0 :         return arrptr( vertexArray );
     257                 :            :     }
     258                 :            :     // MsqVertex* get_vertex_array()             { return arrptr(vertexArray); }
     259                 :            : 
     260                 :            :     //! Returns a pointer to the start of the element array.
     261                 :            :     MESQUITE_EXPORT const MsqMeshEntity* get_element_array( MsqError& err ) const;
     262                 :            :     MESQUITE_EXPORT MsqMeshEntity* get_element_array( MsqError& err );
     263                 :            : 
     264                 :          0 :     MESQUITE_EXPORT size_t* get_connectivity_array()
     265                 :            :     {
     266                 :          0 :         return arrptr( elemConnectivityArray );
     267                 :            :     }
     268                 :            : 
     269                 :     150306 :     MESQUITE_EXPORT Mesh::ElementHandle* get_element_handles_array()
     270                 :            :     {
     271                 :     150306 :         return arrptr( elementHandlesArray );
     272                 :            :     }
     273                 :            : 
     274                 :    6510181 :     MESQUITE_EXPORT Mesh::VertexHandle* get_vertex_handles_array()
     275                 :            :     {
     276                 :    6510181 :         return arrptr( vertexHandlesArray );
     277                 :            :     }
     278                 :            : 
     279                 :            :     //! Returns the start of the vertex->element array.
     280                 :            :     //! For each vertex in the patch, this array holds
     281                 :            :     //! the number of elements the vertex is attached to,
     282                 :            :     //! followed by the indices of those elements.
     283                 :            :     // const size_t* get_vertex_to_elem_array(MsqError &err);
     284                 :            :     //! Returns the start of the vertex->element offset
     285                 :            :     //! array (v2e_o).  For vertex i, v2e_o[i] is the
     286                 :            :     //! index into the vertex->element array (v2e) where
     287                 :            :     //! vertex i's data begins.  So, v2e[v2e_o[i]] gives
     288                 :            :     //! you the number of elements vertex i is attached
     289                 :            :     //! to, and v2e[v2e_o[i]+1] gives you the index of
     290                 :            :     //! the first element attached to vertex i.
     291                 :            :     // const size_t* get_vertex_to_elem_offset(MsqError &err);
     292                 :            : 
     293                 :            :     // MsqVertex& vertex_by_index(size_t index);
     294                 :            :     MESQUITE_EXPORT const MsqVertex& vertex_by_index( size_t index ) const;
     295                 :            :     MESQUITE_EXPORT MsqMeshEntity& element_by_index( size_t index );
     296                 :            :     MESQUITE_EXPORT const MsqMeshEntity& element_by_index( size_t index ) const;
     297                 :            :     MESQUITE_EXPORT size_t get_vertex_index( MsqVertex* vertex );
     298                 :            :     MESQUITE_EXPORT size_t get_element_index( MsqMeshEntity* element );
     299                 :            : 
     300                 :            :     //! Get the coordinates of vertices attached to the specified element
     301                 :            :     MESQUITE_EXPORT
     302                 :            :     void get_element_vertex_coordinates( size_t elem_index, std::vector< Vector3D >& coords, MsqError& err );
     303                 :            :     /*! Get the indices of vertices of specified element. !inefficient!*/
     304                 :            :     MESQUITE_EXPORT
     305                 :            :     void get_element_vertex_indices( size_t elem_index, std::vector< size_t >& vertex_indices, MsqError& err );
     306                 :            :     /*! Get the indices of the elements attached to the specified vertex. */
     307                 :            :     MESQUITE_EXPORT
     308                 :            :     void get_vertex_element_indices( size_t vertex_index, std::vector< size_t >& elem_indices, MsqError& err );
     309                 :            : 
     310                 :            :     /** Get the indices of elements adjacent to the specified vertex,
     311                 :            :      *  and having the specified dimension */
     312                 :            :     MESQUITE_EXPORT
     313                 :            :     void get_vertex_element_indices( size_t vertex_index, unsigned element_dimension,
     314                 :            :                                      std::vector< size_t >& elem_indices, MsqError& err );
     315                 :            : 
     316                 :            :     /*! Get indices of elements attached to specified vertex */
     317                 :            :     MESQUITE_EXPORT
     318                 :            :     const size_t* get_vertex_element_adjacencies( size_t vertex_index, size_t& array_len_out, MsqError& err );
     319                 :            : 
     320                 :            :     /*! Get the indices of vertices that are attached to vertex (given by
     321                 :            :       vertex_index) by an element edge.
     322                 :            :     */
     323                 :            :     MESQUITE_EXPORT
     324                 :            :     void get_adjacent_vertex_indices( size_t vertex_index, std::vector< size_t >& vert_indices, MsqError& err ) const;
     325                 :            : 
     326                 :            :     /*! \brief Get the indices of entities attached to entity
     327                 :            :   (given by ent_ind).
     328                 :            :       adj_ents is filled with the indices into the entity array of elements
     329                 :            :       adjacent to the given element via an n-dimensional entity.
     330                 :            : 
     331                 :            :     */
     332                 :            :     MESQUITE_EXPORT
     333                 :            :     void get_adjacent_entities_via_n_dim( int n, size_t ent_ind, std::vector< size_t >& adj_ents, MsqError& err );
     334                 :            : 
     335                 :            :     /*! Create the arrays that store which elements are attached
     336                 :            :       to each node.  If you know how many total vertex uses there are,
     337                 :            :       pass it in.  Otherwise the PatchData will calculate that number.
     338                 :            :     */
     339                 :            :     MESQUITE_EXPORT
     340                 :            :     void generate_vertex_to_element_data();
     341                 :            : 
     342                 :            :     /*!
     343                 :            :      */
     344                 :            :     MESQUITE_EXPORT
     345                 :            :     void set_vertex_coordinates( const Vector3D& coords, size_t index, MsqError& err );
     346                 :            :     /*! Add delta to the index-th free vertex in the patch
     347                 :            :      */
     348                 :            :     MESQUITE_EXPORT
     349                 :            :     void move_vertex( const Vector3D& delta, size_t index, MsqError& err );
     350                 :            : 
     351                 :            :     /*! Adjust the position of the specified vertex so that it
     352                 :            :         lies on its constraining domain.  The actual domain constraint
     353                 :            :         is managed by the MeshSet's MeshDomain object.
     354                 :            :     */
     355                 :            :     MESQUITE_EXPORT
     356                 :            :     void snap_vertex_to_domain( size_t vertex_index, MsqError& err );
     357                 :            : 
     358                 :            :     /*! Returns whether a domain is associated with the MeshSet from which
     359                 :            :         the Patch originates.
     360                 :            :         If false, you cannot ask for a surface normal. */
     361                 :            :     MESQUITE_EXPORT
     362                 :   30433203 :     bool domain_set() const
     363                 :            :     {
     364                 :   30433203 :         return 0 != myDomain;
     365                 :            :     }
     366                 :            : 
     367                 :            :     /*\brief Get domain normal at vertex location
     368                 :            :      *
     369                 :            :      * Get the normal of the domain associated with the passed
     370                 :            :      * element handle at the location of the specified vertex.
     371                 :            :      *\param vert_index  The index of the vertex in this PatchData
     372                 :            :      *\param elem_handle The handle of the element passed to the domain
     373                 :            :      *\param normal_out  The resulting domain normal
     374                 :            :      *\param err         Error flag.  Possible error conditions include:
     375                 :            :      *                   invalid input data, no domain associated with
     376                 :            :      *                   element, no domain at all, etc.
     377                 :            :      */
     378                 :            :     MESQUITE_EXPORT
     379                 :            :     void get_domain_normal_at_vertex( size_t vert_index, Mesh::ElementHandle element, Vector3D& normal_out,
     380                 :            :                                       MsqError& err );
     381                 :            : 
     382                 :            :     /*! Get the normal to the domain at the centroid (projected to the
     383                 :            :         domain) of a given element.
     384                 :            :         Normal is returned in Vector3D &surf_norm.  If the normal cannot
     385                 :            :         be determined, or if the underlying domain is not a surface,
     386                 :            :         the normal will be set to (0,0,0).
     387                 :            :         Check PatchData::domain_set() is not false first.
     388                 :            :     */
     389                 :            :     MESQUITE_EXPORT
     390                 :            :     void get_domain_normal_at_element( size_t elem_index, Vector3D& surf_norm, MsqError& err );
     391                 :            : 
     392                 :            :     /** Get surface normals at element corners.
     393                 :            :      *  normals_out must be of sufficient size to hold
     394                 :            :      *  the normals of all the corners.
     395                 :            :      **/
     396                 :            :     MESQUITE_EXPORT
     397                 :            :     void get_domain_normals_at_corners( size_t element_index, Vector3D normals_out[], MsqError& err );
     398                 :            : 
     399                 :            :     MESQUITE_EXPORT
     400                 :            :     void get_domain_normal_at_corner( size_t elemen_index, unsigned corner, Vector3D& normal, MsqError& err );
     401                 :            : 
     402                 :            :     MESQUITE_EXPORT
     403                 :            :     void get_domain_normal_at_mid_edge( size_t element_index, unsigned edge_number, Vector3D& normal, MsqError& err );
     404                 :            : 
     405                 :            :     //! Alternative signature. Same functionality.
     406                 :            :     MESQUITE_EXPORT
     407                 :      18784 :     void get_domain_normal_at_element( const MsqMeshEntity* elem_ptr, Vector3D& surf_norm, MsqError& err )
     408                 :            :     {
     409                 :      18784 :         get_domain_normal_at_element( size_t( elem_ptr - &( elementArray[0] ) ), surf_norm, err );
     410                 :      18784 :     }
     411                 :            : 
     412                 :            :     MESQUITE_EXPORT
     413                 :   12893064 :     void get_domain_normal_at_sample( size_t element_index, Sample location, Vector3D& surf_norm, MsqError& err )
     414                 :            :     {
     415   [ +  +  +  - ]:   12893064 :         switch( location.dimension )
     416                 :            :         {
     417                 :            :             case 0:
     418                 :   12680254 :                 get_domain_normal_at_corner( element_index, location.number, surf_norm, err );
     419                 :   12680254 :                 break;
     420                 :            :             case 1:
     421                 :      33686 :                 get_domain_normal_at_mid_edge( element_index, location.number, surf_norm, err );
     422                 :      33686 :                 break;
     423                 :            :             case 2:
     424         [ -  + ]:     179124 :                 assert( location.number == 0 );
     425                 :     179124 :                 get_domain_normal_at_element( element_index, surf_norm, err );
     426                 :     179124 :                 break;
     427                 :            :             default:
     428                 :            :                 MSQ_SETERR( err )
     429         [ #  # ]:          0 :                 ( "Invalid dimension for surface element subentity.\n", MsqError::INVALID_ARG );
     430                 :            :         }
     431                 :   12893064 :     }
     432                 :            : 
     433                 :            :     //! Moves free vertices and then snaps the free vertices to the domain.
     434                 :            :     /*\param dk an array of directions, ordered like the vertices in
     435                 :            :       the PatchData.
     436                 :            :       \param nb_vtx number of vertices.
     437                 :            :       \param step_size a scalar that multiplies the vectors given in dk.
     438                 :            :     */
     439                 :            :     MESQUITE_EXPORT
     440                 :            :     void move_free_vertices_constrained( Vector3D dk[], size_t nb_vtx, double step_size, MsqError& err );
     441                 :            : 
     442                 :            :     /*! Moves free vertices from a memento position along a certain direction
     443                 :            :       and then snaps the free vertices to the domain.
     444                 :            :       \param dk an array of directions, ordered like the vertices in
     445                 :            :       the PatchData.
     446                 :            :       \param nb_vtx number of vertices.
     447                 :            :       \param step_size a scalar that multiplies the vectors given in dk.
     448                 :            :     */
     449                 :            :     MESQUITE_EXPORT
     450                 :            :     void set_free_vertices_constrained( PatchDataVerticesMemento* memento, Vector3D dk[], size_t nb_vtx,
     451                 :            :                                         double step_size, MsqError& err );
     452                 :            : 
     453                 :            :     //! Project gradient vector terms onto geometric domain
     454                 :            :     MESQUITE_EXPORT
     455                 :            :     void project_gradient( std::vector< Vector3D >& gradient, MsqError& err );
     456                 :            : 
     457                 :            :     //! Calculates the distance each vertex has moved from its original
     458                 :            :     //! position as defined by the PatchDataVerticesMememnto.
     459                 :            :     MESQUITE_EXPORT
     460                 :            :     double get_max_vertex_movement_squared( PatchDataVerticesMemento* memento, MsqError& err );
     461                 :            : 
     462                 :            :     //! Updates the underlying mesh (the MBMesquite::Mesh implementation) with
     463                 :            :     //! new node coordinates and flag values.
     464                 :            :     //!\param tag If non-null, store vertex coords in tag rather than
     465                 :            :     //!           updating the coords in the mesh database.  Used for
     466                 :            :     //!           Jacobi optimizations.
     467                 :            :     MESQUITE_EXPORT
     468                 :            :     void update_mesh( MsqError& err, const TagHandle* tag = 0 );
     469                 :            : 
     470                 :            :     //! Calculate new location for all slave higher-order nodes using
     471                 :            :     //! mapping function.  Called by update_mesh().
     472                 :            :     MESQUITE_EXPORT
     473                 :            :     void update_slave_node_coordinates( MsqError& err );
     474                 :            :     MESQUITE_EXPORT
     475                 :            :     void update_slave_node_coordinates( const size_t* elem_indices, size_t num_elem, MsqError& err );
     476                 :            : 
     477                 :            :     //! Remove the soft_fixed flag from all vertices in the patch.
     478                 :            :     MESQUITE_EXPORT
     479                 :            :     void set_all_vertices_soft_free( MsqError& err );
     480                 :            :     //! Add a soft_fixed flag to all vertices in the patch.
     481                 :            :     MESQUITE_EXPORT
     482                 :            :     void set_all_vertices_soft_fixed( MsqError& err );
     483                 :            :     //! Add a soft_fixed flag to all free vertices in the patch.
     484                 :            :     MESQUITE_EXPORT
     485                 :            :     void set_free_vertices_soft_fixed( MsqError& err );
     486                 :            : 
     487                 :            :     //! Mark vertex as culled (soft fixed)
     488                 :            :     MESQUITE_EXPORT
     489                 :          0 :     void set_vertex_culled( size_t vtx_index )
     490                 :            :     {
     491                 :          0 :         vertexArray[vtx_index].flags() |= MsqVertex::MSQ_CULLED;
     492                 :          0 :     }
     493                 :            :     //! Mark vertex as culled (soft fixed)
     494                 :            :     MESQUITE_EXPORT
     495                 :            :     void clear_vertex_culled( size_t vtx_index )
     496                 :            :     {
     497                 :            :         vertexArray[vtx_index].flags() &= ~MsqVertex::MSQ_CULLED;
     498                 :            :     }
     499                 :            :     //! check if vertex is culled
     500                 :            :     MESQUITE_EXPORT
     501                 :            :     int check_vertex_culled( size_t vtx_index ) const
     502                 :            :     {
     503                 :            :         return vertexArray[vtx_index].get_flags() | MsqVertex::MSQ_CULLED;
     504                 :            :     }
     505                 :            : 
     506                 :            :     //! Fills a PatchData with the elements attached to a center vertex.
     507                 :            :     //! Note that all entities in the sub-patch are copies of the entities
     508                 :            :     //! in 'this' patch.  As such, moving a vertex in the sub-patch
     509                 :            :     //! won't move the corresponding vertex in the source patch.  Also,
     510                 :            :     //! calling 'update_mesh()' on the sub-patch WILL modify the TSTT
     511                 :            :     //! mesh, but the source patch won't see the changes.
     512                 :            :     MESQUITE_EXPORT
     513                 :            :     void get_subpatch( size_t center_vertex_index, unsigned num_adj_elem_layers, PatchData& pd_to_fill, MsqError& err );
     514                 :            : 
     515                 :            :     MESQUITE_EXPORT
     516                 :            :     void get_free_vertex_coordinates( std::vector< Vector3D >& coords_out ) const;
     517                 :            : 
     518                 :            :     //! Creates a memento that holds the current
     519                 :            :     //! state of the PatchData coordinates.
     520                 :            :     MESQUITE_EXPORT
     521                 :            :     PatchDataVerticesMemento* create_vertices_memento( MsqError& err );
     522                 :            : 
     523                 :            :     //! reinstantiates a memento to holds the current
     524                 :            :     //! state of the PatchData coordinates. Improves memory management.
     525                 :            :     MESQUITE_EXPORT
     526                 :            :     void recreate_vertices_memento( PatchDataVerticesMemento* memento, MsqError& err );
     527                 :            : 
     528                 :            :     //! Restore the PatchData coordinates to the state
     529                 :            :     //! contained in the memento.
     530                 :            :     MESQUITE_EXPORT
     531                 :            :     void set_to_vertices_memento( PatchDataVerticesMemento* memento, MsqError& err );
     532                 :            : 
     533                 :            :     //! Sets the originating meshSet. This is normally done in MeshSet::get_next_patch().
     534                 :            :     //! This function is only for tests purposes.
     535                 :            :     MESQUITE_EXPORT
     536                 :            :     void set_mesh( Mesh* ms );
     537                 :            : 
     538                 :            :     //! Returns the originating meshSet.
     539                 :            :     MESQUITE_EXPORT
     540                 :    5791592 :     Mesh* get_mesh() const
     541                 :            :     {
     542                 :    5791592 :         return myMesh;
     543                 :            :     }
     544                 :            : 
     545                 :            :     MESQUITE_EXPORT
     546                 :            :     void set_domain( MeshDomain* dm );
     547                 :            : 
     548                 :            :     MESQUITE_EXPORT
     549                 :    2364486 :     MeshDomain* get_domain() const
     550                 :            :     {
     551                 :    2364486 :         return myDomain;
     552                 :            :     }
     553                 :            : 
     554                 :            :     MESQUITE_EXPORT
     555                 :            :     const Settings* get_settings() const
     556                 :            :     {
     557                 :            :         return mSettings;
     558                 :            :     }
     559                 :            :     MESQUITE_EXPORT
     560                 :       6681 :     const MappingFunction* get_mapping_function( EntityTopology type ) const
     561                 :            :     {
     562                 :       6681 :         return mSettings->get_mapping_function( type );
     563                 :            :     }
     564                 :            :     MESQUITE_EXPORT
     565                 :   20205940 :     const MappingFunction2D* get_mapping_function_2D( EntityTopology type ) const
     566                 :            :     {
     567                 :   20205940 :         return mSettings->get_mapping_function_2D( type );
     568                 :            :     }
     569                 :            :     MESQUITE_EXPORT
     570                 :    7808570 :     const MappingFunction3D* get_mapping_function_3D( EntityTopology type ) const
     571                 :            :     {
     572                 :    7808570 :         return mSettings->get_mapping_function_3D( type );
     573                 :            :     }
     574                 :            : 
     575                 :            :     //! Get R^3 coordinates for logical sample location.
     576                 :            :     MESQUITE_EXPORT
     577                 :            :     void get_sample_location( size_t element_index, Sample sample, Vector3D& result, MsqError& err ) const;
     578                 :            : 
     579                 :            :     //! This function returns a NodeSet indicating which
     580                 :            :     //! nodes in the specified element are not slaved.
     581                 :            :     MESQUITE_EXPORT
     582                 :            :     NodeSet non_slave_node_set( size_t elem_idx ) const;
     583                 :            : 
     584                 :            :     MESQUITE_EXPORT
     585                 :    8118664 :     NodeSet get_samples( size_t element, NodeSet non_slave_nodes ) const
     586                 :            :     {
     587                 :            :         // If we have a mapping function, use it
     588                 :    8118664 :         const EntityTopology type = element_by_index( element ).get_element_type();
     589                 :            :         const MappingFunction* f;
     590 [ +  - ][ +  - ]:    8118664 :         if( mSettings && ( f = mSettings->get_mapping_function( type ) ) ) return f->sample_points( non_slave_nodes );
                 [ +  - ]
     591                 :            :         // Otherwise default to sampling at all non-slave nodes
     592                 :          0 :         non_slave_nodes.set_all_corner_nodes( type );
     593                 :          0 :         return non_slave_nodes;
     594                 :            :     }
     595                 :            : 
     596                 :            :     MESQUITE_EXPORT
     597                 :    8118664 :     NodeSet get_samples( size_t element ) const
     598                 :            :     {
     599                 :    8118664 :         return get_samples( element, non_slave_node_set( element ) );
     600                 :            :     }
     601                 :            : 
     602                 :            :     MESQUITE_EXPORT
     603                 :            :     void get_samples( size_t element, std::vector< Sample >& samples_out, MsqError& err ) const;
     604                 :            : 
     605                 :            :     //! Display the coordinates and connectivity information
     606                 :            :     friend std::ostream& operator<<( std::ostream&, const PatchData& );
     607                 :            : 
     608                 :            :   private:
     609                 :            :     /* allow access to the following to functions */
     610                 :            :     friend class MBMesquite::ExtraData;
     611                 :            :     /**\brief Attach an ExtraData object to this PatchData */
     612                 :            :     bool attach_extra_data( ExtraData* data );
     613                 :            :     /**\brief Remove an ExtraData object from this PatchData */
     614                 :            :     bool remove_extra_data( ExtraData* data );
     615                 :            : 
     616                 :            :     /**\brief notify all attached ExtraData instances that patch contents have changed */
     617                 :            :     void notify_new_patch();
     618                 :            :     /**\brief notify all attached ExtraData instances that a subpatch is being initalized
     619                 :            :      *\param sub_patch  The new, already populated subpatch
     620                 :            :      *\param vertex_index_map For the i-th vertex in the subpatch, the
     621                 :            :      *                  i-th entry in this list is the corresponding index in
     622                 :            :      *                  this patch.
     623                 :            :      *\param element_index_map For the i-th element in the subpatch, the
     624                 :            :      *                  i-th entry in this list is the corresponding index in
     625                 :            :      *                  this patch.
     626                 :            :      */
     627                 :            :     void notify_sub_patch( PatchData& sub_patch, const size_t* vertex_index_map, const size_t* element_index_map,
     628                 :            :                            MsqError& err );
     629                 :            :     /**\brief notify all attached ExtraData instances that this patch is being destroyed */
     630                 :            :     void notify_patch_destroyed();
     631                 :            : 
     632                 :            :     /** Call before initialize_data to change vertex_flags for
     633                 :            :      *  higher-order nodes to MSQ_DEPENDENT.
     634                 :            :      */
     635                 :            :     void enslave_higher_order_nodes( const size_t* element_offset_array, unsigned char* vertex_flags,
     636                 :            :                                      MsqError& err ) const;
     637                 :            : 
     638                 :            :     /** Call after filling vertex handle and connectivity arrays to
     639                 :            :      * finish initializing the PatchData.  Reorders vertex handles array
     640                 :            :      * such that all higher-order nodes are at end of array, updates
     641                 :            :      * element connectivity array appropriately, initalizes numCornerVertices,
     642                 :            :      * and per-element vertex and node counts.
     643                 :            :      *
     644                 :            :      * NOTE:  If the patch contains higher-order elements, this function
     645                 :            :      *        will re-order the nodes in the vertex array. Do *NOT* assume
     646                 :            :      *        vertex indices are the same after calling this function!
     647                 :            :      *
     648                 :            :      * NOTE:  This function expects the following data to be initalized:
     649                 :            :      *         vertexHandlesArray
     650                 :            :      *         elemConnectivityArray
     651                 :            :      *         the topology type for all elements in elementArray
     652                 :            :      *        The function assumes the following data has not been
     653                 :            :      *        initialized and therefore does not need to be updated:
     654                 :            :      *         vertexArray
     655                 :            :      *
     656                 :            :      * \param elem_offset_array Offset into connectivity array for each element
     657                 :            :      */
     658                 :            :     void initialize_data( size_t* elem_offset_array, unsigned char* vertex_flags, MsqError& err );
     659                 :            : 
     660                 :            :     /** Code common to misc. methods for populating patch data.
     661                 :            :      *  Remove duplicates from an array of handles.
     662                 :            :      *\param handles    The array of handles to uniquify.
     663                 :            :      *\param count      As input, the lenght of the #handles
     664                 :            :      *                  array.  As output, the number of unique
     665                 :            :      *                  handles remaining in the array.
     666                 :            :      *\param index_map  If non-null, this must be an array of the
     667                 :            :      *                  same length as the handles array.  If this
     668                 :            :      *                  array is passed, the entry cooresponding
     669                 :            :      *                  to each handle in the input #handles array will
     670                 :            :      *                  be set to the index of that handle in the output
     671                 :            :      *                  array.
     672                 :            :      */
     673                 :            :     static void make_handles_unique( Mesh::EntityHandle* handles, size_t& count, size_t* index_map = 0 );
     674                 :            : 
     675                 :            :     /*\brief Note that the passed info has been calculated and stored */
     676                 :          0 :     void note_have_info( ComputedInfo info )
     677                 :            :     {
     678                 :          0 :         haveComputedInfos |= ( 1 << info );
     679                 :          0 :     }
     680                 :            : 
     681                 :            :     /*\brief Update cached domain normal data */
     682                 :            :     void update_cached_normals( MsqError& );
     683                 :            : 
     684                 :            :     Mesh* myMesh;          //!< The Mesh used to fill this PatchData [may be NULL]
     685                 :            :     MeshDomain* myDomain;  //!< The geometric domain of the mesh [may be NULL]
     686                 :            : 
     687                 :            :     //! Cached data for vertices in PatchData::vertexHandlesArray,
     688                 :            :     //! or vertex data for a temporary patch.
     689                 :            :     std::vector< MsqVertex > vertexArray;
     690                 :            :     //! The list of handles for the vertices in this patch
     691                 :            :     //! May be empty if PatchData::myMesh is NULL
     692                 :            :     std::vector< Mesh::VertexHandle > vertexHandlesArray;
     693                 :            :     //! The number of vertices in PatchData::vertexArray that are
     694                 :            :     //! free vertices.  The vertex array is sorted such that
     695                 :            :     //! free vertices are first in the array.  This value
     696                 :            :     //! is therefore the offset at which slave vertices begin
     697                 :            :     //! in the array.
     698                 :            :     size_t numFreeVertices;
     699                 :            :     //! The number of slave vertices in vertexArray.  The
     700                 :            :     //! vertices are ordered such that all fixed vertices occur
     701                 :            :     //! after the slave vertices.  Therefore the offset at which
     702                 :            :     //! the fixed vertices begin is numFreeVertices+numSlaveVertices
     703                 :            :     size_t numSlaveVertices;
     704                 :            :     //! Cached data for elements in PatchData::elementHandlesArray
     705                 :            :     //! or element data for a temporary patch.
     706                 :            :     std::vector< MsqMeshEntity > elementArray;
     707                 :            :     //! The hist of handles for elements in this patch.
     708                 :            :     //! May be empty if PatchData::myMesh is NULL
     709                 :            :     std::vector< Mesh::ElementHandle > elementHandlesArray;
     710                 :            :     //! Element connectivity data.  The concatenation of the
     711                 :            :     //! connectivity list of each element in PatchData::elementArray.
     712                 :            :     //! Each element in PatchData::elementArray has a pointer into
     713                 :            :     //! this array at the correct offset for that element's connectivity data.
     714                 :            :     std::vector< size_t > elemConnectivityArray;
     715                 :            :     //! The concatenation of the adjacency lists of all the vertices
     716                 :            :     //! in PatchData::vertexArray.  Each value in the array is an index into
     717                 :            :     //! PatchData::elementArray indicating that the corresponding element uses
     718                 :            :     //! the vertex.  May be empty if vertex adjacency data has not been
     719                 :            :     //! requested.
     720                 :            :     std::vector< size_t > vertAdjacencyArray;
     721                 :            :     //! This array is indexed by vertex indices and specifies the
     722                 :            :     //! offset in \vertAdjacencyArray at which the adjacency list
     723                 :            :     //! for the corresponding vertex begins.  May be empty if vertex
     724                 :            :     //! adjacency data has not been requested.
     725                 :            :     std::vector< size_t > vertAdjacencyOffsets;
     726                 :            :     //! Index into normalData at which the normal for the corresponding
     727                 :            :     //! vertex index is located. Only vertices constrained to a single
     728                 :            :     //! domain with a topological dimension of 2 have a unique domain
     729                 :            :     //! normal.
     730                 :            :     std::vector< unsigned > vertexNormalIndices;
     731                 :            :     //! Storage space for cached domain normal data.  Pointers in
     732                 :            :     //! PatchData::vertexNormalPointers point into this list.
     733                 :            :     std::vector< Vector3D > normalData;
     734                 :            :     //! Storage space for cached domain DOF for vertices.  IF
     735                 :            :     //! a domain exists and PatchData::normalData is not empty, but
     736                 :            :     //! this array is, it may be assumed that all vertices have
     737                 :            :     //! have a DOF == 2.
     738                 :            :     std::vector< unsigned short > vertexDomainDOF;
     739                 :            : 
     740                 :            :     // Arrays in which to store temporary data
     741                 :            :     // (avoids reallocation of temp space)
     742                 :            :     std::vector< size_t > offsetArray;
     743                 :            :     std::vector< unsigned char > byteArray;
     744                 :            :     mutable std::vector< bool > bitMap;
     745                 :            : 
     746                 :            :     // Patch Computed Information (maxs, mins, etc ... )
     747                 :            :     double computedInfos[MAX_COMPUTED_INFO_ENUM];
     748                 :            :     // Bit map indicating which values in PatchData::computedInfos
     749                 :            :     // are valud (which values have been calculated.)
     750                 :            :     unsigned haveComputedInfos;
     751                 :            : 
     752                 :            :     ExtraData* dataList;
     753                 :            : 
     754                 :            :     const Settings* mSettings;
     755                 :            :     static const Settings defaultSettings;
     756                 :            : };
     757                 :            : 
     758                 :            : void print_patch_data( const PatchData& pd );
     759                 :            : 
     760                 :            : /*! \brief Contains a copy of the coordinates of a PatchData.
     761                 :            : 
     762                 :            :   Use PatchDataVerticesMemento when you want to change the coordinates
     763                 :            :   of a PatchData object but also have the option to restore them.
     764                 :            :   This class can only be instantiated through PatchData::create_vertices_memento().
     765                 :            : */
     766                 :     115908 : class PatchDataVerticesMemento
     767                 :            : {
     768                 :            :   public:
     769                 :            :     void clear()
     770                 :            :     {
     771                 :            :         originator = 0;
     772                 :            :         vertices.clear();
     773                 :            :         normalData.clear();
     774                 :            :     }
     775                 :            : 
     776                 :            :   private:
     777                 :            :     // Constructor accessible only to originator (i.e. PatchData)
     778                 :            :     friend class PatchData;
     779         [ +  - ]:      57976 :     PatchDataVerticesMemento() : originator( 0 ) {}
     780                 :            : 
     781                 :            :     PatchData* originator;  //!< PatchData whose state is kept
     782                 :            :     std::vector< MsqVertex > vertices;
     783                 :            :     std::vector< Vector3D > normalData;
     784                 :            : };
     785                 :            : 
     786                 :          0 : inline void PatchData::clear()
     787                 :            : {
     788                 :          0 :     vertexArray.clear();
     789                 :          0 :     vertexHandlesArray.clear();
     790                 :          0 :     elementArray.clear();
     791                 :          0 :     elementHandlesArray.clear();
     792                 :          0 :     elemConnectivityArray.clear();
     793                 :          0 :     vertAdjacencyArray.clear();
     794                 :          0 :     vertAdjacencyOffsets.clear();
     795                 :          0 :     vertexNormalIndices.clear();
     796                 :          0 :     normalData.clear();
     797                 :            :     // vertexDomainDOF.clear();
     798                 :          0 :     numFreeVertices   = 0;
     799                 :          0 :     numSlaveVertices  = 0;
     800                 :          0 :     haveComputedInfos = 0;
     801                 :          0 :     myMesh            = 0;
     802                 :          0 :     myDomain          = 0;
     803                 :          0 : }
     804                 :            : 
     805                 :            : /*! \brief Returns an array of all vertices in the PatchData.
     806                 :            :  */
     807                 :    5542006 : inline const MsqVertex* PatchData::get_vertex_array( MsqError& err ) const
     808                 :            : {
     809 [ -  + ][ #  # ]:    5542006 :     if( vertexArray.empty() ) MSQ_SETERR( err )( "No vertex array defined", MsqError::INVALID_STATE );
     810                 :    5542006 :     return arrptr( vertexArray );
     811                 :            : }
     812                 :            : 
     813                 :            : /*! \brief Returns the PatchData element array.
     814                 :            :  */
     815                 :            : inline const MsqMeshEntity* PatchData::get_element_array( MsqError& err ) const
     816                 :            : {
     817                 :            :     if( elementArray.empty() ) MSQ_SETERR( err )( "No element array defined", MsqError::INVALID_STATE );
     818                 :            :     return arrptr( elementArray );
     819                 :            : }
     820                 :         62 : inline MsqMeshEntity* PatchData::get_element_array( MsqError& err )
     821                 :            : {
     822 [ -  + ][ #  # ]:         62 :     if( elementArray.empty() ) MSQ_SETERR( err )( "No element array defined", MsqError::INVALID_STATE );
     823                 :         62 :     return arrptr( elementArray );
     824                 :            : }
     825                 :            : 
     826                 :            : /*! \brief set the coordinates of the index-th vertex in the raw array
     827                 :            :  */
     828                 :   14031558 : inline void PatchData::set_vertex_coordinates( const Vector3D& coords, size_t index, MsqError& err )
     829                 :            : {
     830         [ -  + ]:   14031558 :     if( index >= vertexArray.size() )
     831                 :            :     {
     832         [ #  # ]:          0 :         MSQ_SETERR( err )( "Index bigger than numVertices.", MsqError::INVALID_ARG );
     833                 :          0 :         return;
     834                 :            :     }
     835                 :            : 
     836                 :   14031558 :     vertexArray[index] = coords;
     837                 :            : 
     838         [ -  + ]:   14031558 :     if( numSlaveVertices )
     839                 :            :     {
     840                 :            :         size_t num_elem;
     841                 :            :         const size_t* indices;
     842 [ #  # ][ #  # ]:   14031558 :         indices = get_vertex_element_adjacencies( index, num_elem, err );MSQ_ERRRTN( err );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     843 [ #  # ][ #  # ]:          0 :         update_slave_node_coordinates( indices, num_elem, err );MSQ_ERRRTN( err );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     844                 :            :     }
     845                 :            : }
     846                 :            : /*! \brief increment the coordinates of the index-th vertex in the raw array
     847                 :            :  */
     848                 :      62926 : inline void PatchData::move_vertex( const Vector3D& delta, size_t index, MsqError& err )
     849                 :            : {
     850         [ -  + ]:      62926 :     if( index >= vertexArray.size() )
     851                 :            :     {
     852         [ #  # ]:          0 :         MSQ_SETERR( err )( "Index bigger than numVertices.", MsqError::INVALID_ARG );
     853                 :          0 :         return;
     854                 :            :     }
     855                 :            : 
     856                 :      62926 :     vertexArray[index] += delta;
     857                 :            : 
     858         [ -  + ]:      62926 :     if( numSlaveVertices )
     859                 :            :     {
     860                 :            :         size_t num_elem;
     861                 :            :         const size_t* indices;
     862 [ #  # ][ #  # ]:      62926 :         indices = get_vertex_element_adjacencies( index, num_elem, err );MSQ_ERRRTN( err );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     863 [ #  # ][ #  # ]:          0 :         update_slave_node_coordinates( indices, num_elem, err );MSQ_ERRRTN( err );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     864                 :            :     }
     865                 :            : }
     866                 :            : 
     867                 :            : // inline MsqVertex& PatchData::vertex_by_index(size_t index)
     868                 :            : //{
     869                 :            : //  return vertexArray[index];
     870                 :            : //}
     871                 :            : 
     872                 :  158285268 : inline const MsqVertex& PatchData::vertex_by_index( size_t index ) const
     873                 :            : {
     874         [ -  + ]:  158285268 :     assert( index < vertexArray.size() );
     875                 :  158285268 :     return vertexArray[index];
     876                 :            : }
     877                 :            : 
     878                 :   81306309 : inline MsqMeshEntity& PatchData::element_by_index( size_t index )
     879                 :            : {
     880         [ -  + ]:   81306309 :     assert( index < elementArray.size() );
     881                 :   81306309 :     return elementArray[index];
     882                 :            : }
     883                 :            : 
     884                 :   54609034 : inline const MsqMeshEntity& PatchData::element_by_index( size_t index ) const
     885                 :            : {
     886         [ -  + ]:   54609034 :     assert( index < elementArray.size() );
     887                 :   54609034 :     return elementArray[index];
     888                 :            : }
     889                 :            : 
     890                 :            : /*! gets the index of a vertex in the PatchData vertex array,
     891                 :            :   given a pointer to the vertex. */
     892                 :            : inline size_t PatchData::get_vertex_index( MsqVertex* vertex )
     893                 :            : {
     894                 :            :     return vertex - arrptr( vertexArray );
     895                 :            : }
     896                 :            : 
     897                 :    4578473 : inline size_t PatchData::get_element_index( MsqMeshEntity* element )
     898                 :            : {
     899                 :    4578473 :     return element - arrptr( elementArray );
     900                 :            : }
     901                 :            : 
     902                 :          0 : inline void PatchData::get_free_vertex_coordinates( std::vector< Vector3D >& coords_out ) const
     903                 :            : {
     904                 :          0 :     coords_out.resize( num_free_vertices() );
     905 [ #  # ][ #  # ]:          0 :     std::copy( vertexArray.begin(), vertexArray.begin() + num_free_vertices(), coords_out.begin() );
     906                 :          0 : }
     907                 :            : 
     908                 :            : /*!
     909                 :            :   This function instantiate PatchDataVerticesMemento object and returns a pointer to it.
     910                 :            :   The PatchDataVerticesMemento contains the current state of the PatchData coordinates.
     911                 :            :   It can be used to restore the same PatchData object to those coordinates.
     912                 :            : 
     913                 :            :   It is the responsibility of the caller to discard the PatchDataVerticesMemento
     914                 :            :   when not needed any more.
     915                 :            : */
     916                 :      57976 : inline PatchDataVerticesMemento* PatchData::create_vertices_memento( MsqError& err )
     917                 :            : {
     918         [ +  - ]:      57976 :     PatchDataVerticesMemento* memento = new PatchDataVerticesMemento;
     919                 :      57976 :     recreate_vertices_memento( memento, err );
     920 [ -  + ][ #  # ]:      57976 :     if( MSQ_CHKERR( err ) )
                 [ -  + ]
     921                 :            :     {
     922         [ #  # ]:          0 :         delete memento;
     923                 :          0 :         return 0;
     924                 :            :     }
     925                 :      57976 :     return memento;
     926                 :            : }
     927                 :            : 
     928                 :            : /*!
     929                 :            :   This function reuses an existing PatchDataVerticesMemento object.
     930                 :            :   The PatchDataVerticesMemento contains the current state of the PatchData coordinates.
     931                 :            :   It can be used to restore the same PatchData object to those coordinates.
     932                 :            : 
     933                 :            :   It is the responsibility of the caller to delete the PatchDataVerticesMemento
     934                 :            :   when it is no longer needed.
     935                 :            : */
     936                 :     946847 : inline void PatchData::recreate_vertices_memento( PatchDataVerticesMemento* memento, MsqError& /*err*/ )
     937                 :            : {
     938                 :     946847 :     memento->originator = this;
     939                 :            : 
     940                 :     946847 :     size_t num_vtx = num_free_vertices() + num_slave_vertices();
     941                 :            : 
     942                 :     946847 :     memento->vertices.resize( num_vtx );
     943 [ +  - ][ +  - ]:     946847 :     std::copy( vertexArray.begin(), vertexArray.begin() + num_vtx, memento->vertices.begin() );
     944                 :            : 
     945                 :            :     int num_normal;
     946         [ +  + ]:     946847 :     if( normalData.empty() )
     947                 :     773150 :         num_normal = 0;
     948         [ +  + ]:     173697 :     else if( vertexNormalIndices.empty() )
     949                 :     173646 :         num_normal = num_vtx;
     950                 :            :     else
     951                 :            :     {
     952                 :         51 :         num_normal = num_vtx;
     953 [ +  + ][ +  + ]:         92 :         while( num_normal != 0 && vertexNormalIndices[--num_normal] >= normalData.size() )
                 [ +  + ]
     954                 :            :             ;
     955         [ +  - ]:         51 :         if( num_normal == 0 )
     956                 :            :         {
     957         [ +  + ]:         51 :             if( vertexNormalIndices[0] < normalData.size() ) num_normal = vertexNormalIndices[0] + 1;
     958                 :            :         }
     959                 :            :         else
     960                 :          0 :             num_normal = vertexNormalIndices[num_normal] + 1;
     961                 :            :     }
     962                 :            : 
     963                 :     946847 :     memento->normalData.resize( num_normal );
     964 [ +  - ][ +  - ]:     946847 :     std::copy( normalData.begin(), normalData.begin() + num_normal, memento->normalData.begin() );
     965                 :     946847 : }
     966                 :            : 
     967                 :            : /*!
     968                 :            :   This function restores a PatchData object coordinates to a previous state hold in
     969                 :            :   a PatchDataVerticesMemento object (see create_vertices_memento() ).
     970                 :            : 
     971                 :            :   The function checks whether the memento originates from this particular PatchData object.
     972                 :            :   The function does not destroy the memento object: this is the caller responsibility.
     973                 :            : */
     974                 :     342584 : inline void PatchData::set_to_vertices_memento( PatchDataVerticesMemento* memento, MsqError& err )
     975                 :            : {
     976         [ -  + ]:     342584 :     if( memento->originator != this )
     977                 :            :     {
     978                 :            :         MSQ_SETERR( err )
     979                 :            :         ( "Memento may only be used to restore the PatchData "
     980                 :            :           "object from which it was created.",
     981         [ #  # ]:          0 :           MsqError::INVALID_ARG );
     982                 :          0 :         return;
     983                 :            :     }
     984                 :            : 
     985         [ -  + ]:     342584 :     if( memento->vertices.size() != num_free_vertices() + num_slave_vertices() )
     986                 :            :     {
     987                 :            :         MSQ_SETERR( err )
     988                 :            :         ( "Unable to restore patch coordinates.  Number of "
     989                 :            :           "vertices in PatchData has changed.",
     990         [ #  # ]:          0 :           MsqError::INVALID_STATE );
     991                 :          0 :         return;
     992                 :            :     }
     993                 :            : 
     994                 :            :     // copies the memento array into the PatchData array.
     995                 :     342584 :     std::copy( memento->vertices.begin(), memento->vertices.end(), vertexArray.begin() );
     996                 :     342584 :     std::copy( memento->normalData.begin(), memento->normalData.end(), normalData.begin() );
     997                 :            : }
     998                 :            : 
     999                 :            : }  // namespace MBMesquite
    1000                 :            : 
    1001                 :            : #endif

Generated by: LCOV version 1.11