Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
compute_curvature.C
Go to the documentation of this file.
1 /* *******************************************************************
2  * Rocstar Simulation Suite *
3  * Copyright@2015, Illinois Rocstar LLC. All rights reserved. *
4  * *
5  * Illinois Rocstar LLC *
6  * Champaign, IL *
7  * www.illinoisrocstar.com *
8  * sales@illinoisrocstar.com *
9  * *
10  * License: See LICENSE file in top level of distribution package or *
11  * http://opensource.org/licenses/NCSA *
12  *********************************************************************/
13 /* *******************************************************************
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
16  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
17  * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR *
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
21  * USE OR OTHER DEALINGS WITH THE SOFTWARE. *
22  *********************************************************************/
23 // $Id: compute_curvature.C,v 1.6 2008/12/06 08:43:23 mtcampbe Exp $
24 
25 #include "Manifold_2.h"
26 #include "Generic_element_2.h"
27 #include "../Rocblas/include/Rocblas.h"
28 
30 
31 static inline double sign(double x) {
32  return (x>=0) ? 1 : -1;
33 }
34 
35 // Helper function for compute_nodal_mcn.
36 // Compute weights of LB-operator about the first vertex of a given
37 // quadrilateral. Also returns the area of the element.
38 static double
40  ws[0] = ws[1] = ws[2] = 0.;
41 
42  Generic_element_2 e(4);
43  int size = e.get_num_gp();
44 
45  double area = 0;
46  for (int i=0; i<size; i++){
47  // Compute tangents at quadrature points.
48  Vector_2<Real> nc;
49  e.get_gp_nat_coor(i, nc);
50 
51  const Real &xi=nc[0], &eta=nc[1];
52 
53  const Vector_3<Real> u = (1-eta)*(ps[1]-ps[0])+eta*(ps[2]-ps[3]);
54  const Vector_3<Real> v = (1-xi)* (ps[3]-ps[0])+xi* (ps[2]-ps[1]);
55 
56  // Obtain the weights and local area of quadrature point
57  const Real weight = e.get_gp_weight( i);
58 
59  // Evaluate the weights for Laplace-Beltrami operator
60  const Real jacobi_det = u.cross_product(u,v).norm();
61  const Real uv = u*v;
62 
63  const Real su = weight * ((1-eta)*uv-(1-xi)*(u*u))/jacobi_det;
64  const Real sv = weight * ((1-xi)*uv-(1-eta)*(v*v))/jacobi_det;
65 
66  ws[0] += (1-eta)*sv -xi*su;
67  ws[1] += xi*su + eta*sv;
68  ws[2] += (1-xi)*su - eta*sv;;
69  area += weight * jacobi_det;
70  }
71 
72  return area;
73 }
74 
75 // Compute mean-curvature normals and their Laplace-Beltrami operator.
76 // Algorithm based on Y. Zhang, C. Bajaj, and G. Xu, "Surface Smoothing
77 // and quality improvement of quadrilateral/hexahedral meshes with
78 // geometric flow", International Meshing Roundtable, 2005.
80 compute_mcn( COM::Attribute *mcn_in, COM::Attribute *lbmcn_in) {
81 
82  COM_assertion( mcn_in != NULL && mcn_in ->size_of_components() == 3 &&
83  mcn_in->is_nodal());
84  COM_assertion( lbmcn_in != NULL && lbmcn_in->size_of_components() == 3 &&
85  lbmcn_in->is_nodal());
86 
87  COM::Attribute *mcn, *lbmcn;
88  // Inherit mcn and lbmcn onto buffer window
89  if ( mcn_in->window() != _buf_window)
90  mcn = _buf_window->inherit( mcn_in, "mcn__MCNTEMP",
91  false, true, NULL, 0);
92  else
93  mcn = mcn_in;
94 
95  if ( lbmcn_in->window() != _buf_window)
96  lbmcn = _buf_window->inherit( lbmcn_in, "lbmcn__MCNTEMP",
97  false, true, NULL, 0);
98  else
99  lbmcn = lbmcn_in;
100 
101  // Allocate buffer spaces for weights and areas
102  COM::Attribute *areas=NULL, *weights=NULL;
103  areas = _buf_window->new_attribute( "areas__MCNTEMP", 'n',
104  COM_DOUBLE, 1, "");
105  _buf_window->resize_array( areas, NULL);
106 
107  weights = _buf_window->new_attribute( "weights__MCNTEMP", 'e',
108  COM_DOUBLE, 12, "");
109  _buf_window->resize_array( weights, NULL);
110  _buf_window->init_done( false);
111 
112  // Initialize attributes to 0s
113  double zero = 0.;
114  Rocblas::copy_scalar( &zero, mcn);
115  Rocblas::copy_scalar( &zero, areas);
116  Rocblas::copy_scalar( &zero, weights);
117 
118  std::vector< COM::Pane*> panes;
119  mcn->window()->panes( panes);
120  Point_3<Real> ps[4];
121 
122  std::vector< COM::Pane*>::const_iterator it = panes.begin();
123 
124  // First, compute the mean-curvature normal, and save the weights
125  // for Laplace-Beltrami operator.
126  for (int i=0, local_npanes = panes.size(); i<local_npanes; ++i, ++it){
127  const COM::Pane &pane = **it;
128 
129  const Point_3<Real> *pnts =
130  reinterpret_cast<const Point_3<Real>*>(pane.coordinates());
131  Vector_3<Real> *mcn_ptr = (Vector_3<Real> *)
132  (pane.attribute( mcn->id())->pointer());
133  Vector_3<Real> *ws_ptr = (Vector_3<Real> *)
134  (pane.attribute( weights->id())->pointer());
135  Real *area_ptr = (Real *)(pane.attribute( areas->id())->pointer());
136 
137  // Loop through elements of the pane
138  Element_node_enumerator ene( &pane, 1);
139 
140  for ( int j=0, jsize=pane.size_of_elements(); j<jsize; ++j, ene.next()) {
141  Point_3<Real> cnt(0,0,0);
142  int ne=ene.size_of_edges();
143  for ( int kk=0; kk<ne; ++kk)
144  (Vector_3<Real>&)cnt += (const Vector_3<Real>&)pnts[ene[kk]-1];
145  (Vector_3<Real>&)cnt /= ne;
146 
147  // Loop through each vertex
148  for ( int k=0; k<ne; ++k) {
149  // Assign points for the quadrilateral.
150  ps[0] = pnts[ene[k]-1];
151  ps[1] = ps[0]+0.5*(pnts[ene[(k+1)%ne]-1]-ps[0]);
152  ps[2] = cnt;
153  ps[3] = ps[0]+0.5*(pnts[ene[(k+ne-1)%ne]-1]-ps[0]);
154 
155  // Compute weights of LB-operator for the first vertex and
156  // increment the area.
157  Vector_3<Real> &ws = ws_ptr[4*j+k];
158  area_ptr[ ene[k]-1] += compute_lbop_weights( ps, &ws[0]);
159 
160  Vector_3<Real> dA = (ws[0]*(ps[1]-ps[0])+ws[1]*(ps[2]-ps[0])+
161  ws[2]*(ps[3]-ps[0]));
162 
163  mcn_ptr[ ene[k]-1] += dA;
164  }
165  }
166  }
167 
168  // Reduce on the area and mcn and divide mcn by areas.
171  Rocblas::div( mcn, areas, mcn);
172 
173  // Second, compute the Laplace-Beltrami of the mean-curvature.
174  Rocblas::copy_scalar( &zero, lbmcn);
175 
176  it = panes.begin();
177  for (int i=0, local_npanes = panes.size(); i<local_npanes; ++i, ++it) {
178  const COM::Pane &pane = **it;
179 
180  const Vector_3<Real> *mcn_ptr = (const Vector_3<Real> *)
181  (pane.attribute( mcn->id())->pointer());
182  const Vector_3<Real> *ws_ptr = (const Vector_3<Real> *)
183  (pane.attribute( weights->id())->pointer());
184 
185  Vector_3<Real> *lbmcn_ptr = (Vector_3<Real> *)
186  (pane.attribute( lbmcn->id())->pointer());
187 
188  // Loop through elements of the pane
189  Element_node_enumerator ene( &pane, 1);
190  double fs[4];
191 
192  for ( int j=0, jsize=pane.size_of_elements(); j<jsize; ++j, ene.next()) {
193  int ne=ene.size_of_edges();
194 
195  // Loop through each vertex
196  for ( int k=0; k<ne; ++k) {
197 
198  // Compute the magnitude and vector of current vertex
199  int ii0=ene[k]-1;
200  fs[0] = mcn_ptr[ii0].norm();
201  Vector_3<Real> vec=(mcn_ptr[ii0]); if (fs[0]>0) vec/=fs[0];
202 
203  // Compute length of other vertices mcn corresponding to the
204  // direction of mcn at the current vertex
205  for ( int kk=1; kk<ne; ++kk) {
206  int ii=ene[(k+kk)%ne]-1;
207 
208  fs[kk] = sign(mcn_ptr[ii]*vec)*mcn_ptr[ii].norm();
209  }
210 
211  const Vector_3<Real> &ws = ws_ptr[4*j+k];
212  lbmcn_ptr[ ene[k]-1] += 4.*(ws[0]*(fs[1]-fs[0])+ws[1]*(fs[2]-fs[0])+
213  ws[2]*(fs[3]-fs[0]))*vec;
214  }
215  }
216  }
217 
218  // Reduce on lbmcn and divide it by areas.
220  Rocblas::div( lbmcn, areas, lbmcn);
221 
222  // Delete buffer space in reverse order
223  _buf_window->delete_attribute( weights->name());
224  _buf_window->delete_attribute( areas->name());
225  if ( lbmcn_in->window() != _buf_window)
226  _buf_window->delete_attribute( lbmcn->name());
227  if ( mcn_in->window() != _buf_window)
228  _buf_window->delete_attribute( mcn->name());
229 
230  _buf_window->init_done(false);
231 }
232 
234 
235 
236 
237 
238 
239 
#define COM_assertion(EX)
Error checking utility similar to the assert macro of the C language.
static SURF_BEGIN_NAMESPACE double sign(double x)
An adaptor for enumerating node IDs of an element.
j indices k indices k
Definition: Indexing.h:6
COM::Window * _buf_window
Definition: Manifold_2.h:360
static double compute_lbop_weights(Point_3< Real > *ps, Real *ws)
#define SURF_END_NAMESPACE
Definition: surfbasic.h:29
void get_gp_nat_coor(const Size i, Nat_coor &nc, const Size doa=0) const
Get the natrual coordinate associated with a Gauss point.
Encapsulation of the element-wise computations for two-dimensional elements.
Real get_gp_weight(const Size i, const Size doa=0) const
Get the weight associated with a Gauss point.
double Real
Definition: mapbasic.h:322
*********************************************************************Illinois Open Source License ****University of Illinois NCSA **Open Source License University of Illinois All rights reserved ****Developed free of to any person **obtaining a copy of this software and associated documentation to deal with the Software without including without limitation the rights to and or **sell copies of the and to permit persons to whom the **Software is furnished to do subject to the following this list of conditions and the following disclaimers ****Redistributions in binary form must reproduce the above **copyright this list of conditions and the following **disclaimers in the documentation and or other materials **provided with the distribution ****Neither the names of the Center for Simulation of Advanced the University of nor the names of its **contributors may be used to endorse or promote products derived **from this Software without specific prior written permission ****THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY **EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES **OF FITNESS FOR A PARTICULAR PURPOSE AND **NONINFRINGEMENT IN NO EVENT SHALL THE CONTRIBUTORS OR **COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN AN ACTION OF TORT OR **ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE **USE OR OTHER DEALINGS WITH THE SOFTWARE v
Definition: roccomf90.h:20
#define SURF_BEGIN_NAMESPACE
Definition: surfbasic.h:28
void reduce_on_shared_nodes(COM::Attribute *attr, MPI_Op op)
Perform reduction over a given nodal attributes.
Definition: Manifold_2.C:1105
int size_of_edges() const
Number of edges per element.
blockLoc i
Definition: read.cpp:79
void int int REAL * x
Definition: read.cpp:74
static void div(const Attribute *x, const Attribute *y, Attribute *z)
Operation wrapper for division.
Definition: op3args.C:269
static Vector_3 cross_product(const Vector_3 &v, const Vector_3 &w)
Definition: mapbasic.h:104
static void copy_scalar(const void *x, Attribute *y)
Operation wrapper for copy (x is a scalar pointer).
Definition: op2args.C:583
j indices j
Definition: Indexing.h:6
void compute_mcn(COM::Attribute *mcn_in, COM::Attribute *lbmcn_in)
Size get_num_gp(const Size doa=0) const
Get the number of Gauss points.
void next()
Go to the next element within the connectivity tables of a pane.
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_SUM
Type norm() const
Definition: mapbasic.h:112