Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Transfer_base.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: Transfer_base.C,v 1.23 2008/12/06 08:43:29 mtcampbe Exp $
24 
25 //=====================================================================
26 // This file contains the implementation of Transfer_base for
27 // overlay-based data transfer algorithms.
28 //
29 // Author: Xiangmin Jiao
30 // Revision: June 16, 2001
31 //=====================================================================
32 
33 #include "Transfer_base.h"
34 #include <iostream>
35 
37 
38 // This function solves the linear system A*x=b.
39 int
42  Nodal_data &z, Nodal_data &di, Real *tol, int *iter ) {
43  Real resid, alpha, beta, rho, rho_1=0, sigma=0;
44 
45  Real normb = norm2(b);
46  Real tol_sq = *tol * *tol;
47 
48  // r = b - A*x
50  saxpy( Real(1), b, Real(-1), r);
51 
52  if (normb < 1.e-15) normb = Real(1);
53 
54  if ( (resid = norm2(r) / normb) <= tol_sq) {
55  *tol = sqrt(resid);
56  *iter = 0;
57  return 0;
58  }
59 
60  for (int i = 1; i <= *iter; i++) {
61  precondition_Jacobi( r, di, z);
63 
64  // rho = dot(r, z); sigma = dot(z, s);
65  Real gsums[2];
66 
67  dot2(r, z, z, s, Array_n(gsums,2));
68  rho = gsums[0];
69 
70  if (i==1) {
71  copy_vec( z, p);
72  copy_vec( s, q);
73  sigma = gsums[1];
74  }
75  else {
76  beta = rho / rho_1;
77  // p = z + beta * p;
78  saxpy( Real(1), z, beta, p);
79 
80  // q = s + beta * q; i.e., q = A*p;
81  saxpy( Real(1), s, beta, q);
82  sigma = gsums[1] - beta * beta * sigma;
83  }
84  alpha = rho / sigma;
85 
86  // x += alpha * p;
87  saxpy( alpha, p, Real(1), x);
88  // r -= alpha * q;
89  saxpy( -alpha, q, Real(1), r);
90 
91  if ( (resid = norm2(r) / normb) <= tol_sq) {
92  *tol = sqrt(resid);
93  *iter = i;
94  return 0;
95  }
96 
97  rho_1 = rho;
98  }
99 
100  *tol = sqrt(resid);
101  return 1;
102 }
103 
104 void
106  const Nodal_data_const &diag,
107  Nodal_data &x) {
108  copy_vec( rhs, x); // Copy value from rhs to x
109 
110  // Divide x by diag.
111  for (Pane_iterator pit=trg_ps.begin(); pit!=trg_ps.end(); ++pit) {
112  Real *p = (*pit)->pointer( x.id());
113  const Real *q = (*pit)->pointer( diag.id());
114 
115  // Loop through the nodes of each pane.
116  for ( int i=1, size=(*pit)->size_of_nodes(); i<=size; ++i)
117  x.get_value( p, i) /= diag.get_value( q, i)[0];
118  }
119 }
120 
121 // This function evaluates a matrix-vector multiplication.
122 void
124  Nodal_data &y) {
125  // Loop through the elements of the target window to integrate
126  // \int_e N_iN_j de.
127  for ( Pane_iterator pit=trg_ps.begin(); pit!=trg_ps.end(); ++pit) {
128  RFC_Pane_transfer *p_trg = *pit;
129  Real *py = p_trg->pointer(y.id());
130  const Real *px = p_trg->pointer(x.id());
131 
132  // Initialize y by setting all its entries to 0.
133  Real *p = p_trg->pointer( y.id());
134  std::fill( p, p+(*pit)->size_of_nodes()*y.dimension(), Real(0));
135 
136  // Loop through the faces of each pane.
137  ENE ene( p_trg->base(), 1);
138  for ( int k=1, size=p_trg->size_of_faces(); k<=size; ++k, ene.next()) {
139  if ( !p_trg->need_recv(k)) continue;
140  Real *emm = p_trg->get_emm( k);
141  Element_var fy( y, py, ene);
142  Element_var_const fx( x, px, ene);
143 
144  // Add the submatrix onto the global matrix.
145  for ( int i=0, n=ene.size_of_nodes(); i<n; ++i) {
146  Array_n t = fy[i];
147  for ( int j=0; j<n; ++j, ++emm) t += (*emm) * fx[j];
148  }
149  }
150  }
151 
153 }
154 
155 Real
157  Real nrm(0);
158 
159  for ( Pane_iterator_const pit=trg_ps.begin(); pit!=trg_ps.end(); ++pit) {
160  const Real *p = (*pit)->pointer( x.id());
161  // Loop through the nodes of each pane.
162  for ( int i=1, size=(*pit)->size_of_nodes(); i<=size; ++i)
163  if ( (*pit)->is_primary_node( i))
164  nrm += square( x.get_value( p, i));
165  }
166  trg.allreduce( &nrm, MPI_SUM);
167  return nrm;
168 }
169 
170 Real
172  const Nodal_data_const &y) const {
173  Real prod(0);
174 
175  for ( Pane_iterator_const pit=trg_ps.begin(); pit!=trg_ps.end(); ++pit) {
176  const Real *px = (*pit)->pointer( x.id());
177  const Real *py = (*pit)->pointer( y.id());
178  // Loop through the nodes of each pane.
179  for ( int i=1, size=(*pit)->size_of_nodes(); i<=size; ++i)
180  if ( (*pit)->is_primary_node( i))
181  prod += x.get_value( px, i) * y.get_value( py, i);
182  }
183 
184  trg.allreduce( &prod, MPI_SUM);
185  return prod;
186 }
187 
188 // Comput the products x1*y1 and x2*y2 and assign to prod[0] and prod[1].
189 void
191  const Nodal_data_const &y1,
192  const Nodal_data_const &x2,
193  const Nodal_data_const &y2,
194  Array_n prods) const {
195  prods[0] = prods[1] = 0;
196  for ( Pane_iterator_const pit=trg_ps.begin(); pit!=trg_ps.end(); ++pit) {
197  const Real *px1 = (*pit)->pointer( x1.id());
198  const Real *py1 = (*pit)->pointer( y1.id());
199  const Real *px2 = (*pit)->pointer( x2.id());
200  const Real *py2 = (*pit)->pointer( y2.id());
201  // Loop through the nodes of each pane.
202  for ( int i=1, size=(*pit)->size_of_nodes(); i<=size; ++i)
203  if ( (*pit)->is_primary_node( i)) {
204  prods[0] += x1.get_value( px1, i) * y1.get_value( py1, i);
205  prods[1] += x2.get_value( px2, i) * y2.get_value( py2, i);
206  }
207  }
208 
209  trg.allreduce( prods, MPI_SUM);
210 }
211 
212 void
214  const Real &b, Nodal_data &y) {
215  for ( Pane_iterator pit=trg_ps.begin(); pit!=trg_ps.end(); ++pit) {
216  Real *px = (*pit)->pointer( x.id());
217  Real *py = (*pit)->pointer( y.id());
218  // Loop through the nodes of each pane.
219  for ( int i=1, size=(*pit)->size_of_nodes(); i<=size; ++i)
220  (y.get_value( py, i)*=b) += a*x.get_value( px, i);
221  }
222 }
223 
224 // This function computes x = a*x
225 void
227  for ( Pane_iterator pit=trg_ps.begin(); pit!=trg_ps.end(); ++pit) {
228  Real *px = (*pit)->pointer( x.id());
229  // Loop through the nodes of each pane.
230  for ( int i=1, size=(*pit)->size_of_nodes(); i<=size; ++i)
231  x.get_value( px, i) *= a;
232  }
233 }
234 
235 // This function computes x = 1 / x
236 void
238  for ( Pane_iterator pit=trg_ps.begin(); pit!=trg_ps.end(); ++pit) {
239  Real *px = (*pit)->pointer( x.id());
240  // Loop through the nodes of each pane.
241  for ( int i=1, size=(*pit)->size_of_nodes(); i<=size; ++i)
242  x.get_value( px, i).invert();
243  }
244 }
245 
246 // This function computes y = a*x + b*y
247 void
249  for ( Pane_iterator pit=trg_ps.begin(); pit!=trg_ps.end(); ++pit) {
250  Real *px = (*pit)->pointer( x.id());
251  Real *py = (*pit)->pointer( y.id());
252 
253  // Loop through the nodes of each pane.
254  for ( int i=1, size=(*pit)->size_of_nodes(); i<=size; ++i)
255  y.set_value( py, i, x.get_value( px, i));
256  }
257 }
258 
259 //============== The following functions for transfering to faces
260 void
262  const Nodal_data_const &sDF,
263  Array_n &min_v,
264  Array_n &max_v) {
265 
266  min_v = Vector_n( sDF.dimension(), HUGE_VAL);
267  max_v = Vector_n( sDF.dimension(), -HUGE_VAL);
268 
269  std::vector<const RFC_Pane_transfer*> ps;
270  win.panes( ps);
271 
272  for (std::vector<const RFC_Pane_transfer*>::iterator
273  pit=ps.begin(); pit!=ps.end(); ++pit) {
274  const Real *p = (*pit)->pointer( sDF.id());
275  // Loop through the nodes of each pane.
276  for ( int i=1, size=(*pit)->size_of_nodes(); i<=size; ++i) {
277  Array_n_const t = sDF.get_value( p, i);
278  for ( unsigned int k=0; k<t.dimension(); ++k) {
279  if ( !isfinite(t[k])) {
280  std::cerr << "ERROR: ****Invalid number "
281  << t[k] << " in " << win.name() << "["
282  << i-1 << "][" << k << "] (C Convention). Aborting..." << std::endl;
283  RFC_assertion( isfinite(t[k])); MPI_Abort( MPI_COMM_WORLD, -1);
284  }
285  }
286  min_v = min( min_v, t);
287  max_v = max( max_v, t);
288  }
289  }
290 
291  // Perform global reduction
292  win.allreduce( min_v, MPI_MIN);
293  win.allreduce( max_v, MPI_MAX);
294 }
295 
296 void
298  const Facial_data_const &sDF,
299  Array_n &min_v,
300  Array_n &max_v) {
301  min_v = Vector_n( sDF.dimension(), HUGE_VAL);
302  max_v = Vector_n( sDF.dimension(), -HUGE_VAL);
303 
304  std::vector<const RFC_Pane_transfer*> ps;
305  win.panes( ps);
306 
307  for (std::vector<const RFC_Pane_transfer*>::iterator
308  pit=ps.begin(); pit!=ps.end(); ++pit) {
309  const Real *p = (*pit)->pointer( sDF.id());
310  // Loop through the nodes of each pane.
311  for ( int i=1, size=(*pit)->size_of_faces(); i<=size; ++i) {
312  Array_n_const t = sDF.get_value( p, i);
313  for ( unsigned int k=0; k<t.dimension(); ++k) {
314  if ( !isfinite(t[k])) {
315  std::cerr << "ERROR: ****Invalid number "
316  << t[k] << " in " << win.name() << "["
317  << i-1 << "][" << k << "] (C Convention). Aborting..." << std::endl;
318  RFC_assertion( isfinite(t[k])); MPI_Abort( MPI_COMM_WORLD, -1);
319  }
320  }
321  min_v = min( min_v, t);
322  max_v = max( max_v, t);
323  }
324  }
325 
326  // Perform global reduction
327  win.allreduce( min_v, MPI_MIN);
328  win.allreduce( max_v, MPI_MAX);
329 }
330 
331 // Integrate the values over the surface.
332 void
334  const Facial_data_const &sDF,
335  Array_n &integral,
336  const int doa) {
337  integral = Vector_n( sDF.dimension(), 0);
338 
339  std::vector<const RFC_Pane_transfer*> ps;
340  win.panes( ps);
341 
342  Vector_n vt(sDF.dimension(), 0); Array_n t( vt.begin(), vt.end());
343 
344  Point_2 nc;
345  for (std::vector<const RFC_Pane_transfer*>::iterator
346  pit=ps.begin(); pit!=ps.end(); ++pit) {
347  ENE ene( (*pit)->base(), 1);
348  // Loop through the nodes of each pane.
349  for ( int i=1, size=(*pit)->size_of_faces(); i<=size; ++i, ene.next()) {
350  Generic_element e( ene.size_of_edges(), ene.size_of_nodes());
351 
352  Nodal_coor_const coors;
353  Element_coor_const pnts( coors, (*pit)->coordinates(), ene);
354 
355  for ( int i=0, n = e.get_num_gp(doa); i<n; ++i) {
356  e.get_gp_nat_coor( i, nc, doa);
357 
358  t = make_field( sDF, *pit, ene);
359  Real a=e.get_gp_weight(i, doa) * e.Jacobian_det( pnts, nc);
360  t *= a;
361  integral += t;
362  }
363  }
364  }
365 
366  // Perform global reduction
367  win.allreduce( integral, MPI_SUM);
368 }
369 
370 // Integrate the values over the surface.
371 void
373  const Nodal_data_const &sDF,
374  Array_n &integral,
375  const int doa) {
376  integral = Vector_n( sDF.dimension(), 0);
377 
378  std::vector<const RFC_Pane_transfer*> ps;
379  win.panes( ps);
380 
381  Vector_n vt(sDF.dimension(), 0); Array_n t( vt.begin(), vt.end());
382 
383  Point_2 nc;
384  for (std::vector<const RFC_Pane_transfer*>::iterator
385  pit=ps.begin(); pit!=ps.end(); ++pit) {
386  ENE ene( (*pit)->base(), 1);
387  // Loop through the nodes of each pane.
388  for ( int i=1, size=(*pit)->size_of_faces(); i<=size; ++i, ene.next()) {
389  Generic_element e( ene.size_of_edges(), ene.size_of_nodes());
390 
391  Nodal_coor_const coors;
392  Element_coor_const pnts( coors, (*pit)->coordinates(), ene);
393 
394  for ( int i=0, n = e.get_num_gp(doa); i<n; ++i) {
395  e.get_gp_nat_coor( i, nc, doa);
396 
397  interpolate( e, make_field( sDF, *pit, ene), nc, t);
398  Real a=e.get_gp_weight(i, doa) * e.Jacobian_det( pnts, nc);
399  t *= a;
400  integral += t;
401  }
402  }
403  }
404 
405  // Perform global reduction
406  win.allreduce( integral, MPI_SUM);
407 }
408 
409 
411 
412 
413 
414 
415 
416 
std::string name() const
The name of the window.
void dot2(const Nodal_data_const &x1, const Nodal_data_const &y1, const Nodal_data_const &x2, const Nodal_data_const &y2, Array_n prod) const
Real square(const Array_n_const &x) const
void invert(Nodal_data &x)
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_COMM_WORLD
An adaptor for enumerating node IDs of an element.
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_MAX
Size dimension() const
j indices k indices k
Definition: Indexing.h:6
void int int REAL REAL * y
Definition: read.cpp:74
Element_var_const make_field(const Nodal_data_const &d, const RFC_Pane_transfer *pn, const ENE &ene)
Construct a element-wise accessor from nodal data and pointers.
NT rhs
double s
Definition: blastest.C:80
std::vector< RFC_Pane_transfer * > trg_ps
Base * base()
The id of its base COM::Pane object.
Adpator for element-wise data container.
Vector_n max(const Array_n_const &v1, const Array_n_const &v2)
Definition: Vector_n.h:354
Size dimension() const
Definition: Vector_n.h:79
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_MIN
Value_const get_value(const RFC_Pane_transfer *p, int v) const
void saxpy(const Real &a, const Nodal_data_const &x, const Real &b, Nodal_data &y)
double Real
Definition: mapbasic.h:322
double sqrt(double d)
Definition: double.h:73
SURF::Generic_element_2 Generic_element
Definition: rfc_basic.h:46
bool isfinite(Real x)
int size_of_faces() const
The total number of faces in the pane.
void panes(std::vector< Pane * > &ps)
Get a vector of local panes contained in the window.
#define RFC_END_NAME_SPACE
Definition: rfc_basic.h:29
void scale(const Real &a, Nodal_data &x)
void int int int REAL REAL REAL * z
Definition: write.cpp:76
RFC_Window_transfer & trg
blockLoc i
Definition: read.cpp:79
#define RFC_BEGIN_NAME_SPACE
Definition: rfc_basic.h:28
void int int REAL * x
Definition: read.cpp:74
void set_value(RFC_Pane_transfer *p, int v, const Value_const &vec)
Value_nonconst get_value(RFC_Pane_transfer *p, int v)
int pcg(Nodal_data &x, Nodal_data &b, Nodal_data &p, Nodal_data &q, Nodal_data &r, Nodal_data &s, Nodal_data &z, Nodal_data &di, Real *tol, int *max_iter)
Definition: Transfer_base.C:40
const NT & n
void interpolate(const Generic_element &e, const Element_var_const values, const Generic_element::Nat_coor &nc, _Value &v)
Vector_n min(const Array_n_const &v1, const Array_n_const &v2)
Definition: Vector_n.h:346
void integrate(const RFC_Window_transfer &win, const Nodal_data_const &sDF, Array_n &intergral, const int doa)
j indices j
Definition: Indexing.h:6
void copy_vec(const Nodal_data_const &x, Nodal_data &y)
NT q
std::vector< RFC_Pane_transfer * >::const_iterator Pane_iterator_const
Definition: Transfer_base.h:55
void precondition_Jacobi(const Nodal_data_const &rhs, const Nodal_data_const &diag, Nodal_data &x)
Diagonal (Jacobi) preconditioner.
Real dot(const Nodal_data_const &x, const Nodal_data_const &y) const
An const adaptor for accessing nodal coordinates of a pane.
void multiply_mass_mat_and_x(const Nodal_data_const &x, Nodal_data &y)
Self & invert()
Definition: Vector_n.h:175
void minmax(const RFC_Window_transfer &win, const Facial_data_const &sDF, Array_n &min_v, Array_n &max_v)
#define RFC_assertion
Definition: rfc_basic.h:65
bool need_recv(int i) const
void reduce_to_all(Nodal_data &, MPI_Op)
Real norm2(const Nodal_data_const &x) const
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
void allreduce(Array_n &arr, MPI_Op op) const
std::vector< RFC_Pane_transfer * >::iterator Pane_iterator
Definition: Transfer_base.h:54