46 std::vector<bool> flags;
59 for (
int i=0,
n=ene.size_of_nodes();
i<
n; ++
i) flags[ene[
i]] =
true;
72 {
if ( count >= nnodes)
break;
else continue; }
76 if ( !flags[pvid_trg])
continue;
79 if ( !p_src || p_src->
id()!=SVID_src.
pane_id)
82 int svid_src = SVID_src.
node_id;
107 switch ( ene.size_of_nodes()) {
109 f[3] = 0.5*(f[0]+f[1]);
110 f[4] = 0.5*(f[1]+f[2]);
111 f[5] = 0.5*(f[2]+f[0]);
114 f[8] = 0.25*(f[0]+f[1]+f[2]+f[3]);
116 f[4] = 0.5*(f[0]+f[1]);
117 f[5] = 0.5*(f[1]+f[2]);
118 f[6] = 0.5*(f[2]+f[3]);
119 f[7] = 0.5*(f[3]+f[0]);
131 std:: cout <<
"RFACE: Interpolation done in "
132 <<
get_wtime()-t0 <<
" seconds." << std::endl;
137 template <
class _Data,
class _Po
ints,
class _Loads,
class Tag>
142 const _Points &pnts_s,
143 const _Points &pnts_t,
155 const unsigned int n = e_t.size_of_nodes();
161 Point_3 ps_s[Generic_element::MAX_SIZE];
162 Point_3 ps_t[Generic_element::MAX_SIZE];
163 for (
int i=0;
i<sne; ++
i) e_t.interpolate( pnts_t, ncs_t[
i], &ps_t[i]);
165 for (
int i=0; i<sne; ++
i) e_s.interpolate( pnts_s, ncs_s[i], &ps_s[i]);
169 {
if ( doa == 0) doa =
std::max(e_t.order(), e_s.order())==1? 2 : 4; }
174 Real emm[Generic_element::MAX_SIZE*Generic_element::MAX_SIZE];
176 if ( compute_mass) std::fill(emm, emm+n*n, 0.);
180 std::vector<Real> esf(n*n,0.);
181 std::vector<Vector_n> l_t(n,
Vector_n(data_s.dimension(),0));
185 Real N[Generic_element::MAX_SIZE];
187 for (
int i=0,
ni=sub_e.get_num_gp(doa); i <
ni; ++
i) {
188 sub_e.get_gp_nat_coor( i, sub_nc, doa);
189 sub_e.interpolate( ncs_s, sub_nc, &nc_s);
195 Real a_t=sub_e.get_gp_weight(i, doa), a_s=a_t;
196 a_t *= sub_e.Jacobian_det( ps_t, sub_nc);
199 if ( alpha!=1.) a_s *= sub_e.Jacobian_det( ps_s, sub_nc);
203 sub_e.interpolate( ncs_t, sub_nc, &nc_t);
204 e_t.shape_func( nc_t, N);
207 Vector_3 grads_t[Generic_element::MAX_SIZE];
208 e_t.gradients( pnts_t, nc_t, grads_t);
210 std::vector<Vector_3> load_prime( data_s.dimension(),
NULL_VECTOR);
212 Vector_3 grads_s[Generic_element::MAX_SIZE];
214 e_s.gradients( pnts_s, nc_s, grads_s);
220 for (
unsigned int j=0;
j<
n; ++
j) {
221 loads[
j] += N[
j] *
v;
223 for (
unsigned int k=0;
k<=
j; ++
k)
224 emm[
j*n+
k] += N[
j]*N[
k]*a_t;
227 for (
unsigned int k=0;
k<data_s.dimension(); ++
k)
228 l_t[
j][
k] += grads_t[
j]*load_prime[
k]*area;
230 if ( !lump && compute_mass) {
231 for (
unsigned int k=0;
k<=
j; ++
k) {
233 esf[
j*n+
k] += grads_t[
j]*grads_t[
k]*area;
242 if ( mu<0 && !lump && compute_mass) {
245 for (
unsigned int j=0;
j<
n; ++
j) {
246 for (
unsigned int k=0;
k<
j; ++
k) {
247 t1 += emm[j*n+
k]*esf[j*n+
k]; t2 += esf[j*n+
k]*esf[j*n+
k];
255 for (
unsigned int j=0;
j<
n; ++
j) {
256 loads[
j] += mu * l_t[
j];
259 for (
unsigned int k=0;
k<=
j; ++
k) {
260 emm[
j*n+
k] += mu*esf[
j*n+
k];
269 for (
unsigned int j=0;
j<
n; ++
j) {
273 for (
unsigned int k=0;
k<
n; ++
k)
277 diag[
j][0] += emm[
j*n+
j];
283 for (
unsigned int j=0;
j<
n; ++
j)
284 for (
unsigned int k=0;
k<
n; ++
k)
290 template <
class _SDF>
310 Point_2 ncs_src[3], ncs_trg[3];
311 for (
int i=0;
i<3; ++
i) {
332 e_src, e_trg, pnts_s, pnts_t, ncs_src, ncs_trg,
339 template <
class _SDF>
352 Real *p = (*pit)->pointer( rhs.
id());
353 std::fill( p, p+(*pit)->size_of_nodes()*rhs.
dimension(),
Real(0));
356 p = (*pit)->pointer( diag.
id());
357 std::fill( p, p+(*pit)->size_of_nodes()*diag.
dimension(),
Real(0));
363 ENE ene_src, ene_trg;
367 for (
int i=1, size=(*pit)->size_of_subfaces();
i<=size; ++
i) {
369 if ( !(*pit)->need_recv( ene_trg.
id()))
continue;
371 const Face_ID &fid = (*pit)->get_subface_counterpart(
i);
377 fid.
face_id,
i, alpha, rhs, diag, doa, lump);
385 template <
class _SDF>
388 Real *tol,
int *iter,
int doa,
bool verbose)
402 bool needs_source_coor = alpha!=1.;
406 bool lump = *iter<=0;
423 int ierr=
pcg( tDF, b, p,
q, r,
s,
z, diag, tol, iter);
426 std::cerr <<
"***RFACE: WARNING: PCG did not converge after "
427 << *iter <<
" iterations and relative error is "
428 << *tol << std::endl;
443 std:: cout <<
"RFACE: Transfer to nodes done in "
446 std:: cout <<
" with relative error "
447 << *tol <<
" after " << *iter <<
" iterators"
450 std:: cout <<
"." << std::endl;
457 Real *tol,
int *iter,
int doa,
bool verbose)
464 Real *tol,
int *iter,
int doa,
bool verbose)
485 std:: cout <<
"RFACE: Interpolation done in "
486 <<
get_wtime()-t0 <<
" seconds." << std::endl;
491 template <
class _SDF>
494 const int order,
bool verbose)
502 bool needs_source_coor = alpha!=1.;
513 std:: cout <<
"RFACE: Load transfer done in "
514 <<
get_wtime()-t0 <<
" seconds." << std::endl;
520 const Real alpha,
const int order,
bool verbose)
527 const Real alpha,
const int order,
bool verbose)
void loadtransfer(const _SDF &vS, Nodal_data &vT, const Real alpha, const int order, bool verb)
Computes the load vector.
void transfer(const Nodal_data_const &sf, Nodal_data &tf, const Real alpha, Real *t, int *iter, int doa, bool ver)
The main entry to the data transfer algorithm.
int node_id
the local id within the pane starting from 1.
void replicate_data(const Facial_data_const &data, bool replicate_coor)
Replicate the given data from remote processes onto local process.
void compute_load_vector_wra(const RFC_Pane_transfer *p_src, RFC_Pane_transfer *p_dst, const _SDF &sDF, ENE &ene_src, ENE &ene_trg, int sfid_src, int sfid_trg, const Real alpha, Nodal_data &rhs, Nodal_data &diag, int doa, bool lump)
Computes the element-wise load vector, and also computes mass matrix if diag has a nonnegative ID...
void transfer_2n(const _SDF &sDF, Nodal_data &tDF, const Real alpha, Real *tol, int *iter, int doa, bool verb)
template function for transfering from nodes/faces to nodes.
An adaptor for enumerating node IDs of an element.
const RFC_Pane_transfer * get_src_pane(int i)
int face_id
the local id within the pane starting from 1.
const Real * coordinates() const
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.
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)
int pane_id
the id of the owner pane.
const Node_ID & get_subnode_counterpart(int i) const
void compute_load_prime(const Generic_element &e_s, const _Data &data_s, const Vector_3 *grads_s, Vector_3 *load_prime, Tag_nodal)
void barrier() const
Block until all processes of the window have reached here.
SURF::Generic_element_2 Generic_element
int parent_type_of_subnode(int) const
Determine the parent type of a subnode of given tyep.
int size_of_faces() const
The total number of faces in the pane.
int size_of_isolated_nodes() const
int id() const
Get the local id of the element within the pane.
int size_of_subnodes() const
The total number of nodes in the subdivision of the pane.
*********************************************************************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
void element_load_vector(const _Data &data_s, const Generic_element &e_s, const Generic_element &e_t, const _Points &pnts_s, const _Points &pnts_t, const Point_2 *ncs_s, const Point_2 *ncs_t, const Real alpha, const int sne, const Tag &tag, _Loads loads, _Loads diag, Real *emm, int doa, bool lump)
Computes the element-wise load vector, and also computes mass matrix if emm is not NULL...
#define RFC_END_NAME_SPACE
*********************************************************************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 ** copy
void clear_replicated_data()
Clear all the replicate data but keep metadata.
int pane_id
the id of the owner pane.
void reduce_maxabs_to_all(Nodal_data &)
int get_parent_node(int) const
Get the local parent node id of a given subnode.
void int int int REAL REAL REAL * z
void delete_nodal_buffers()
void get_host_element_of_subnode(int i, Element_node_enumerator &ene, Point_2 &nc) const
int size_of_nodes() const
The total number of nodes in the pane.
int size_of_edges() const
Number of edges per element.
RFC_Window_transfer & trg
#define RFC_BEGIN_NAME_SPACE
void get_nat_coor_in_element(const int eid, const int lid, Point_2 &nc) const
Take a subface id and a local subnode id, return the natual coordinates of the subnode within the par...
Value_nonconst get_value(RFC_Pane_transfer *p, int v)
int size_of_nodes() const
Number of nodes per element.
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)
Nodal_data nodal_buffer(int)
bool is_nodal(Tag_nodal) const
void interpolate(const Generic_element &e, const Element_var_const values, const Generic_element::Nat_coor &nc, _Value &v)
Element_node_enumerator ENE
void init_nodal_buffers(const Nodal_data &nd, int n, bool init_emm)
Vector_n min(const Array_n_const &v1, const Array_n_const &v2)
void init_load_vector(const _SDF &vS, const Real alpha, Nodal_data &ld, Nodal_data &diag, int doa, bool lump)
Initialize load vector and the diagonal of the mass matrix.
void get_host_element_of_subface(int i, Element_node_enumerator &ene) const
void precondition_Jacobi(const Nodal_data_const &rhs, const Nodal_data_const &diag, Nodal_data &x)
Diagonal (Jacobi) preconditioner.
An const adaptor for accessing nodal coordinates of a pane.
void interpolate_fe(const _SDF &sDF, Nodal_data &tDF, bool verb)
Perform finite-element interpolation (non-conservative), assuming source data has been replicated...
bool is_quadratic() const
Does this pane contain quadratic elements?
void int int REAL REAL REAL *z blockDim dim * ni
Some basic geometric data types.
RFC_Window_transfer & src
void transfer(const Facial_data_const &sf, Nodal_data &tf, const Real alpha, Real *tol, int *iter, int doa, bool verb)
The main entry to the data transfer algorithm.
RFC_BEGIN_NAME_SPACE double get_wtime()
void comp_loads(const Facial_data_const &sf, Nodal_data &tf, const Real alpha, const int order, bool verb)
Compute the nodal load vector.
void transfer(const Nodal_data_const &sf, Nodal_data &tf, bool verb)
The main entry to the data transfer algorithm.
bool need_recv(int i) const
void reduce_to_all(Nodal_data &, MPI_Op)
bool is_root() const
Check whether the process has rank 0.
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 comp_loads(const Nodal_data_const &sf, Nodal_data &tf, const Real alpha, const int doa, bool verb)
Compute the nodal load vector.
std::vector< RFC_Pane_transfer * >::iterator Pane_iterator