Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
moab::LloydSmoother Class Reference

#include <LloydSmoother.hpp>

+ Collaboration diagram for moab::LloydSmoother:

Public Member Functions

 LloydSmoother (Interface *impl)
 
 LloydSmoother (Interface *impl, ParallelComm *pc, Range &elems, Tag cds_tag=0, Tag fixed_tag=0, double abs_tol=-1.0, double rel_tol=1.0e-6)
 
 ~LloydSmoother ()
 
ErrorCode perform_smooth ()
 
Interfacemb_impl ()
 
ParallelCommpcomm ()
 
void pcomm (ParallelComm *pc)
 
Rangeelems ()
 
const Rangeelems () const
 
Tag fixed_tag ()
 
void fixed_tag (Tag fixed)
 
Tag coords_tag ()
 
void coords_tag (Tag coords)
 
double abs_tol ()
 
void abs_tol (double tol)
 
double rel_tol ()
 
void rel_tol (double tol)
 
int num_its ()
 
void num_its (int num)
 
int report_its ()
 
void report_its (int num)
 

Private Member Functions

ErrorCode initialize ()
 

Private Attributes

InterfacembImpl
 
ParallelCommmyPcomm
 
Range myElems
 
Tag coordsTag
 
Tag fixedTag
 
double absTol
 
double relTol
 
int reportIts
 
int numIts
 
bool iCreatedTag
 

Detailed Description

Examples
OptimizeMeshMesquite.cpp.

Definition at line 26 of file LloydSmoother.hpp.

Constructor & Destructor Documentation

◆ LloydSmoother() [1/2]

moab::LloydSmoother::LloydSmoother ( Interface impl)

◆ LloydSmoother() [2/2]

LloydSmoother::LloydSmoother ( Interface impl,
ParallelComm pc,
Range elems,
Tag  cds_tag = 0,
Tag  fixed_tag = 0,
double  abs_tol = -1.0,
double  rel_tol = 1.0e-6 
)

Definition at line 17 of file LloydSmoother.cpp.

18  : mbImpl( impl ), myPcomm( pc ), myElems( elms ), coordsTag( ctag ), fixedTag( ftag ), absTol( at ), relTol( rt ),
19  reportIts( 0 ), numIts( 0 ), iCreatedTag( false )
20 {
21 }

◆ ~LloydSmoother()

LloydSmoother::~LloydSmoother ( )

Definition at line 23 of file LloydSmoother.cpp.

24 {
25  if( iCreatedTag && fixedTag )
26  {
28  MB_CHK_SET_ERR_RET( rval, "Failed to delete the fixed tag" );
29  }
30 }

References ErrorCode, fixedTag, iCreatedTag, MB_CHK_SET_ERR_RET, mbImpl, and moab::Interface::tag_delete().

Member Function Documentation

◆ abs_tol() [1/2]

double moab::LloydSmoother::abs_tol ( )
inline

Definition at line 127 of file LloydSmoother.hpp.

128  {
129  return absTol;
130  }

References absTol.

◆ abs_tol() [2/2]

void moab::LloydSmoother::abs_tol ( double  tol)
inline

Definition at line 134 of file LloydSmoother.hpp.

135  {
136  absTol = tol;
137  }

References absTol.

◆ coords_tag() [1/2]

Tag moab::LloydSmoother::coords_tag ( )
inline

Definition at line 113 of file LloydSmoother.hpp.

114  {
115  return coordsTag;
116  }

References coordsTag.

◆ coords_tag() [2/2]

void moab::LloydSmoother::coords_tag ( Tag  coords)
inline

Definition at line 120 of file LloydSmoother.hpp.

121  {
122  coordsTag = coords;
123  }

References coordsTag.

◆ elems() [1/2]

Range& moab::LloydSmoother::elems ( )
inline

Definition at line 85 of file LloydSmoother.hpp.

86  {
87  return myElems;
88  }

References myElems.

◆ elems() [2/2]

const Range& moab::LloydSmoother::elems ( ) const
inline

Definition at line 92 of file LloydSmoother.hpp.

93  {
94  return myElems;
95  }

References myElems.

◆ fixed_tag() [1/2]

Tag moab::LloydSmoother::fixed_tag ( )
inline

Definition at line 99 of file LloydSmoother.hpp.

100  {
101  return fixedTag;
102  }

References fixedTag.

◆ fixed_tag() [2/2]

void moab::LloydSmoother::fixed_tag ( Tag  fixed)
inline

Definition at line 106 of file LloydSmoother.hpp.

107  {
108  fixedTag = fixed;
109  }

References fixedTag.

◆ initialize()

ErrorCode LloydSmoother::initialize ( )
private

Definition at line 214 of file LloydSmoother.cpp.

215 {
216  // first, check for tag; if we don't have it, make one and mark skin as fixed
217  if( !fixedTag )
218  {
219  unsigned char fixed = 0x0;
221  "Trouble making fixed tag" );
222  iCreatedTag = true;
223 
224  // get the skin; get facets, because we might need to filter on shared entities
225  Skinner skinner( mbImpl );
226  Range skin, skin_verts;
227  MB_CHK_SET_ERR( skinner.find_skin( 0, myElems, false, skin ), "Unable to find skin" );
228 
229 #ifdef MOAB_HAVE_MPI
230  // need to do a little extra if we're working in parallel
231  if( myPcomm )
232  {
233  // filter out ghost and interface facets
235  "Failed to filter on shared status" );
236  }
237 #endif
238  // get the vertices from those entities
239  MB_CHK_SET_ERR( mbImpl->get_adjacencies( skin, 0, false, skin_verts, Interface::UNION ),
240  "Trouble getting vertices" );
241 
242  // mark them fixed
243  std::vector< unsigned char > marks( skin_verts.size(), 0x1 );
244  MB_CHK_SET_ERR( mbImpl->tag_set_data( fixedTag, skin_verts, &marks[0] ), "Unable to set tag on skin" );
245  }
246 
247  return MB_SUCCESS;
248 }

References moab::ParallelComm::filter_pstatus(), moab::Skinner::find_skin(), fixedTag, moab::Interface::get_adjacencies(), iCreatedTag, MB_CHK_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_OPAQUE, mbImpl, myElems, myPcomm, PSTATUS_GHOST, PSTATUS_INTERFACE, PSTATUS_NOT, moab::Range::size(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), and moab::Interface::UNION.

Referenced by perform_smooth().

◆ mb_impl()

Interface* moab::LloydSmoother::mb_impl ( )
inline

Definition at line 64 of file LloydSmoother.hpp.

65  {
66  return mbImpl;
67  }

References mbImpl.

◆ num_its() [1/2]

int moab::LloydSmoother::num_its ( )
inline

Definition at line 155 of file LloydSmoother.hpp.

156  {
157  return numIts;
158  }

References numIts.

Referenced by DeformMeshRemap::execute().

◆ num_its() [2/2]

void moab::LloydSmoother::num_its ( int  num)
inline

Definition at line 159 of file LloydSmoother.hpp.

160  {
161  numIts = num;
162  }

References numIts.

◆ pcomm() [1/2]

ParallelComm* moab::LloydSmoother::pcomm ( )
inline

Definition at line 71 of file LloydSmoother.hpp.

72  {
73  return myPcomm;
74  }

References myPcomm.

◆ pcomm() [2/2]

void moab::LloydSmoother::pcomm ( ParallelComm pc)
inline

Definition at line 78 of file LloydSmoother.hpp.

79  {
80  myPcomm = pc;
81  }

References myPcomm.

◆ perform_smooth()

ErrorCode LloydSmoother::perform_smooth ( )

Definition at line 32 of file LloydSmoother.cpp.

33 {
34  if( myElems.empty() )
35  {
36  MB_SET_ERR( MB_FAILURE, "No elements specified to Lloyd smoother" );
37  }
39  {
40  MB_SET_ERR( MB_FAILURE, "Elements of unequal dimension specified to Lloyd smoother" );
41  }
42 
43  int dim = mbImpl->dimension_from_handle( *myElems.begin() );
44 
45  // first figure out tolerance to use
46  if( 0 > absTol )
47  {
48  // no tolerance set - get one relative to bounding box around elements
49  BoundBox bb;
50  MB_CHK_SET_ERR( bb.update( *mbImpl, myElems ), "Failed to compute bounding box around elements" );
51  absTol = relTol * bb.diagonal_length();
52  }
53 
54  // initialize if we need to
55  MB_CHK_SET_ERR( initialize(), "Failed to initialize" );
56 
57  // get all vertices
58  Range verts;
60  "Failed to get all vertices" );
61 
62  // perform Lloyd relaxation:
63  // 1. setup: set vertex centroids from vertex coords; filter to owned verts; get fixed tags
64 
65  // get all verts coords into tag; don't need to worry about filtering out fixed verts,
66  // we'll just be setting to their fixed coords
67  std::vector< double > vcentroids( 3 * verts.size() );
68  if( !coordsTag )
69  {
70  MB_CHK_SET_ERR( mbImpl->get_coords( verts, &vcentroids[0] ), "Failed to get vert coords" );
71  }
72  else
73  {
74  MB_CHK_SET_ERR( mbImpl->tag_get_data( coordsTag, verts, &vcentroids[0] ),
75  "Failed to get vert coords tag values" );
76  }
77 
78  Tag centroid;
80  "Couldn't get tag handle" );
81  MB_CHK_SET_ERR( mbImpl->tag_set_data( centroid, verts, &vcentroids[0] ), "Failed setting centroid tag" );
82 
83  Range owned_verts, shared_owned_verts;
84 #ifdef MOAB_HAVE_MPI
85  // filter verts down to owned ones and get fixed tag for them
86  if( myPcomm && myPcomm->size() > 1 )
87  {
88  MB_CHK_SET_ERR( myPcomm->filter_pstatus( verts, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, &owned_verts ),
89  "Failed to filter on pstatus" );
90  // get shared owned verts, for exchanging tags
91  MB_CHK_SET_ERR( myPcomm->filter_pstatus( owned_verts, PSTATUS_SHARED, PSTATUS_AND, -1, &shared_owned_verts ),
92  "Failed to filter for shared owned" );
93  // workaround: if no shared owned verts, put a non-shared one in the list, to prevent
94  // exchanging tags for all shared entities
95  if( shared_owned_verts.empty() ) shared_owned_verts.insert( *verts.begin() );
96  }
97  else
98  owned_verts = verts;
99 #else
100  owned_verts = verts;
101 #endif
102 
103  std::vector< unsigned char > fix_tag( owned_verts.size() );
104  MB_CHK_SET_ERR( mbImpl->tag_get_data( fixedTag, owned_verts, &fix_tag[0] ), "Failed to get fixed tag" );
105 
106  // now fill vcentroids array with positions of just owned vertices, since those are the ones
107  // we're actually computing
108  vcentroids.resize( 3 * owned_verts.size() );
109  MB_CHK_SET_ERR( mbImpl->tag_get_data( centroid, owned_verts, &vcentroids[0] ), "Failed to get centroid tag" );
110 
111  // some declarations for later iterations
112  std::vector< double > fcentroids( 3 * myElems.size() ); // fcentroids for element centroids
113  std::vector< double > ctag(
114  3 * CN::MAX_NODES_PER_ELEMENT ); // temporary coordinate storage for verts bounding an element
115  const EntityHandle* conn; // const ptr & size to elem connectivity
116  int nconn;
117  Range::iterator eit, vit; // for iterating over elems, verts
118  int e, v; // for indexing into centroid vectors
119  std::vector< EntityHandle > adj_elems; // used in vertex iteration
120 
121  // 2. while !converged
122  double resid = DBL_MAX;
123  numIts = 0;
124  while( resid > absTol )
125  {
126  numIts++;
127  resid = 0.0;
128 
129  // 2a. foreach elem: centroid = sum(vertex centroids)/num_verts_in_cell
130  for( eit = myElems.begin(), e = 0; eit != myElems.end(); ++eit, e++ )
131  {
132  // get verts for this elem
133  MB_CHK_SET_ERR( mbImpl->get_connectivity( *eit, conn, nconn ), "Failed to get connectivity" );
134  // get centroid tags for those verts
135  MB_CHK_SET_ERR( mbImpl->tag_get_data( centroid, conn, nconn, &ctag[0] ), "Failed to get centroid" );
136  fcentroids[3 * e + 0] = fcentroids[3 * e + 1] = fcentroids[3 * e + 2] = 0.0;
137  for( v = 0; v < nconn; v++ )
138  {
139  fcentroids[3 * e + 0] += ctag[3 * v + 0];
140  fcentroids[3 * e + 1] += ctag[3 * v + 1];
141  fcentroids[3 * e + 2] += ctag[3 * v + 2];
142  }
143  for( v = 0; v < 3; v++ )
144  fcentroids[3 * e + v] /= nconn;
145  }
146  MB_CHK_SET_ERR( mbImpl->tag_set_data( centroid, myElems, &fcentroids[0] ), "Failed to set elem centroid" );
147 
148  // 2b. foreach owned vertex:
149  for( vit = owned_verts.begin(), v = 0; vit != owned_verts.end(); ++vit, v++ )
150  {
151  // if !fixed
152  if( fix_tag[v] ) continue;
153  // vertex centroid = sum(cell centroids)/ncells
154  adj_elems.clear();
155  MB_CHK_SET_ERR( mbImpl->get_adjacencies( &( *vit ), 1, dim, false, adj_elems ), "Failed getting adjs" );
156  MB_CHK_SET_ERR( mbImpl->tag_get_data( centroid, &adj_elems[0], adj_elems.size(), &fcentroids[0] ),
157  "Failed to get elem centroid" );
158  double vnew[] = { 0.0, 0.0, 0.0 };
159  for( e = 0; e < (int)adj_elems.size(); e++ )
160  {
161  vnew[0] += fcentroids[3 * e + 0];
162  vnew[1] += fcentroids[3 * e + 1];
163  vnew[2] += fcentroids[3 * e + 2];
164  }
165  for( e = 0; e < 3; e++ )
166  vnew[e] /= adj_elems.size();
167  double delta = ( CartVect( vnew ) - CartVect( &vcentroids[3 * v] ) ).length();
168  resid = ( v ? std::max( resid, delta ) : delta );
169  for( e = 0; e < 3; e++ )
170  vcentroids[3 * v + e] = vnew[e];
171  }
172 
173  // set the centroid tag; having them only in vcentroids array isn't enough, as vertex
174  // centroids are accessed randomly in loop over faces
175  MB_CHK_SET_ERR( mbImpl->tag_set_data( centroid, owned_verts, &vcentroids[0] ),
176  "Failed to set vertex centroid" );
177 
178 #ifdef MOAB_HAVE_MPI
179  // 2c. exchange tags on owned verts
180  if( myPcomm && myPcomm->size() > 1 )
181  {
182  MB_CHK_SET_ERR( myPcomm->exchange_tags( centroid, shared_owned_verts ), "Failed to exchange tags" );
183  }
184 #endif
185 
186  if( reportIts && !( numIts % reportIts ) )
187  {
188  double global_max = resid;
189 #ifdef MOAB_HAVE_MPI
190  // global reduce for maximum delta, then report it
191  if( myPcomm && myPcomm->size() > 1 )
192  MPI_Reduce( &resid, &global_max, 1, MPI_DOUBLE, MPI_MAX, 0, myPcomm->comm() );
193  if( !myPcomm || !myPcomm->rank() )
194 #endif
195  std::cout << "Max residual = " << global_max << std::endl;
196  }
197 
198  } // end while
199 
200  // write the tag back onto vertex coordinates
201  if( !coordsTag )
202  {
203  MB_CHK_SET_ERR( mbImpl->set_coords( owned_verts, &vcentroids[0] ), "Failed to set vertex coords" );
204  }
205  else
206  {
207  MB_CHK_SET_ERR( mbImpl->tag_set_data( coordsTag, owned_verts, &vcentroids[0] ),
208  "Failed to set vert coords tag values" );
209  }
210 
211  return MB_SUCCESS;
212 }

References absTol, moab::Range::begin(), moab::ParallelComm::comm(), coordsTag, moab::BoundBox::diagonal_length(), moab::Interface::dimension_from_handle(), moab::Range::empty(), moab::Range::end(), moab::ParallelComm::exchange_tags(), moab::ParallelComm::filter_pstatus(), fixedTag, moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), moab::Interface::get_coords(), initialize(), moab::Range::insert(), length(), moab::CN::MAX_NODES_PER_ELEMENT, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_DOUBLE, mbImpl, myElems, myPcomm, numIts, PSTATUS_AND, PSTATUS_NOT, PSTATUS_NOT_OWNED, PSTATUS_SHARED, moab::ParallelComm::rank(), moab::Range::rbegin(), relTol, reportIts, moab::Interface::set_coords(), moab::Range::size(), moab::ParallelComm::size(), moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), moab::Interface::UNION, and moab::BoundBox::update().

Referenced by DeformMeshRemap::execute(), and run_local_smoother().

◆ rel_tol() [1/2]

double moab::LloydSmoother::rel_tol ( )
inline

Definition at line 141 of file LloydSmoother.hpp.

142  {
143  return relTol;
144  }

References relTol.

◆ rel_tol() [2/2]

void moab::LloydSmoother::rel_tol ( double  tol)
inline

Definition at line 148 of file LloydSmoother.hpp.

149  {
150  relTol = tol;
151  }

References relTol.

◆ report_its() [1/2]

int moab::LloydSmoother::report_its ( )
inline

Definition at line 166 of file LloydSmoother.hpp.

167  {
168  return reportIts;
169  }

References reportIts.

◆ report_its() [2/2]

void moab::LloydSmoother::report_its ( int  num)
inline

Definition at line 170 of file LloydSmoother.hpp.

171  {
172  reportIts = num;
173  }

References reportIts.

Member Data Documentation

◆ absTol

double moab::LloydSmoother::absTol
private

Definition at line 195 of file LloydSmoother.hpp.

Referenced by abs_tol(), and perform_smooth().

◆ coordsTag

Tag moab::LloydSmoother::coordsTag
private

Definition at line 189 of file LloydSmoother.hpp.

Referenced by coords_tag(), and perform_smooth().

◆ fixedTag

Tag moab::LloydSmoother::fixedTag
private

Definition at line 192 of file LloydSmoother.hpp.

Referenced by fixed_tag(), initialize(), perform_smooth(), and ~LloydSmoother().

◆ iCreatedTag

bool moab::LloydSmoother::iCreatedTag
private

Definition at line 204 of file LloydSmoother.hpp.

Referenced by initialize(), and ~LloydSmoother().

◆ mbImpl

Interface* moab::LloydSmoother::mbImpl
private

Definition at line 180 of file LloydSmoother.hpp.

Referenced by initialize(), mb_impl(), perform_smooth(), and ~LloydSmoother().

◆ myElems

Range moab::LloydSmoother::myElems
private

Definition at line 186 of file LloydSmoother.hpp.

Referenced by elems(), initialize(), and perform_smooth().

◆ myPcomm

ParallelComm* moab::LloydSmoother::myPcomm
private

Definition at line 183 of file LloydSmoother.hpp.

Referenced by initialize(), pcomm(), and perform_smooth().

◆ numIts

int moab::LloydSmoother::numIts
private

Definition at line 201 of file LloydSmoother.hpp.

Referenced by num_its(), and perform_smooth().

◆ relTol

double moab::LloydSmoother::relTol
private

Definition at line 195 of file LloydSmoother.hpp.

Referenced by perform_smooth(), and rel_tol().

◆ reportIts

int moab::LloydSmoother::reportIts
private

Definition at line 198 of file LloydSmoother.hpp.

Referenced by perform_smooth(), and report_its().


The documentation for this class was generated from the following files: