00001 #ifndef PARTOP_H 00002 #define PARTOP_H 00003 00004 #include <stdio.h> 00005 #include <mpi.h> 00006 #include "../GEFEL/gtopology.h" 00007 #include "../GEFEL/gmatrix.h" 00008 #include "pgalias.h" 00009 #include "../GEFEL/galias.h" 00010 #include "../GEFEL/intp.h" 00011 00012 /** 00013 class deals with topology in parallel computations 00014 it is superior class to the class gtopology which is used 00015 for particular subdomains 00016 the class partop manages several classes gtopology 00017 00018 00019 notation: 00020 00021 node multiplicity - number of subdomains which share the node 00022 00023 internal node - node with multiplicity 1, (node inside a subdomain, 00024 node not lying on inter-subdomain boundary) 00025 00026 boundary node - node with multiplicity at least 2, (node lying 00027 on inter-subdomain boundary) 00028 00029 coarse node - artificial node defined on master which collects appropriate 00030 boundary nodes 00031 00032 00033 global ordering - node ordering before mesh partitioning 00034 global node numbers - node numbers used in undecomposed mesh 00035 (node numbers used before decomposition/partitioning) 00036 00037 local ordering - ordering of subdomains (without respect to remaining subdomains) 00038 local node numbers - node numbers used in decomposed mesh 00039 (node numbers used after decomposition/partitioning) 00040 00041 coarse ordering - ordering of boundary (interface) nodes only 00042 coarse node number - node numbers of boundary nodes only, ordering 00043 of all boundary nodes in coarse problem 00044 00045 group ordering - ordering of selected nodes only 00046 group node number - only selected nodes are ordered on the whole problem, it is similar to 00047 the coarse ordering 00048 00049 00050 mesh description: 00051 md = 1 - all nodes have their global node number 00052 md = 2 - only boundary nodes have coarse number, internal nodes are denoted by -1 00053 md = 3 - all nodes have their global node number, boundary nodes have their global number multiplied by -1 00054 00055 JK 00056 */ 00057 class partop 00058 { 00059 public: 00060 partop(int np,int mr,long nd,meshdescription meshd,char *nameproc, int nl); 00061 ~partop (); 00062 void initiation (gtopology *top,long *ltg); 00063 00064 00065 00066 00067 // function computes nodal multiplicity 00068 void compute_multiplicity (long *ltg,long *domproc,FILE *out); 00069 // tnnp is established 00070 // multip is assmebled 00071 // nodmultip is assembled 00072 // allnodes is assembled 00073 // nbnd is assembled 00074 // maxnbn is established 00075 // tnbn is established 00076 00077 00078 void dof_multiplicity (gtopology *top,FILE *out); 00079 // dofmultip is assembled 00080 00081 00082 void rewrite_ltg (long *ltg); 00083 00084 00085 void find_boundary_nodes (long *ltg,long *domproc,FILE *out); 00086 // lgnbn is assembled 00087 // lnbn is assembled 00088 // nin is established 00089 // lnin is assembled 00090 00091 00092 void boundary_nodes_on_master (gtopology *top,long *domproc,FILE *out); 00093 // cnbn is assembled 00094 00095 00096 void coarse_local_nodes (); 00097 void sort_nodes (FILE *out); 00098 00099 00100 void number_of_bdofs_on_nodes (gtopology *top,long *domproc,FILE *out); 00101 // nbdofnd is assembled 00102 00103 00104 void code_numbers_on_master (gtopology *top,long *domproc,FILE *out); 00105 // maxnbdof is established 00106 // lbcn is assembled 00107 00108 00109 // ******************************************* 00110 // ******************************************* 00111 00112 void nodesplit_allnodes (gtopology *top,long *domproc); 00113 void nodesplit_bnodes (gtopology *top,long *domproc,FILE *out); 00114 void gcnprep (gtopology *top,long *domproc); 00115 void corner_nodes (gtopology *top, FILE *out); 00116 00117 void dof_incidence (gtopology *top,long nbdof); 00118 void corner_nodes2d (gtopology *top,FILE *out); 00119 void corner_nodes3d (gtopology *top,FILE *out); 00120 00121 00122 00123 00124 00125 // ************************************************* 00126 // VARIABLES AND ARRAYS DEFINED ON ALL PROCESSORS 00127 // ************************************************* 00128 00129 /// name of processor 00130 char procName[MPI_MAX_PROCESSOR_NAME]; 00131 /// 00132 int nameLength; 00133 /// number of domain attached to the processor 00134 long ndom; 00135 /// number of elements on subdomain 00136 long ne; 00137 00138 00139 00140 00141 /// maximum number of boundary DOFs on one subdomain 00142 /// variable is defined in function code_numbers_on_master 00143 long maxnbdof; 00144 00145 00146 00147 00148 00149 00150 /// array containing number of subdomains which share the degree of freedom 00151 /// it contains ndof components 00152 /// nodmultip[i]=j - the i-th dof belongs to j subdomains 00153 /// array is allocated in function dof_multiplicity 00154 long *dofmultip; 00155 00156 /// array containing numbers of boundary nodes 00157 /// it contains nbn components 00158 /// lnbn[i]=j - the i-th boundary node has local number j 00159 /// array is allocated in function find_boundary_nodes 00160 long *lnbn; 00161 00162 /// array containing numbers of internal nodes 00163 /// it contains nin components 00164 /// lnin[i]=j - the i-th internal node has local number j 00165 /// array is allocated in function find_boundary_nodes 00166 long *lnin; 00167 00168 /// array containing list of global numbers of boundary nodes 00169 /// lgnbn[i]=j - the i-th boundary node has global number k 00170 long *lgnbn; 00171 00172 00173 00174 00175 // ******************************************************** 00176 // VARIABLES AND ARRAYS DEFINED ONLY ON MASTER PROCESSOR 00177 // ******************************************************** 00178 00179 00180 /// total number of DOFs in the whole problem 00181 long tndof; 00182 00183 00184 /// number of DOFs in coarse (reduced) problem 00185 long ndofcp; 00186 00187 00188 00189 00190 /// array containing number of subdomains which each boundary node belongs to 00191 /// it contains tnnp components 00192 /// multip[i]=j - the i-th node belongs to j subdomains 00193 /// array is allocated in function compute_multiplicity 00194 long *multip; 00195 00196 00197 00198 /// array containing correspondence between global and coarse node numbers 00199 /// it contains tnnp components 00200 /// gcnbn[i]=j - the i-th node is the j-th boundary node, j=-1 for internal nodes 00201 /// array is allocated and deallocated in function boundary_nodes_on_master 00202 long *gcnbn; 00203 00204 /// array containing coarse node numbers of boundary nodes 00205 /// it contains nproc rows and nbnd[i] columns 00206 /// cnbn[i][j]=k - the j-th boundary node on the i-th subdomain has coarse node number k 00207 /// array is allocated in function boundary_nodes_on_master 00208 long **cnbn; 00209 00210 /// array containing numbers of DOFs on boundary nodes 00211 /// it contains nproc rows and nbnd[i] columns 00212 /// nbdofnd[i][j]=k - the j-th boundary node on the i-th subdomain contains k degrees of freedom 00213 /// array is allocated in function number_of_bdofs_on_nodes 00214 long **nbdofnd; 00215 00216 00217 00218 /// array containing numbers of boundary DOFs on subdomains 00219 /// it contains nproc components 00220 /// ndofd[i]=j - the i-th domain contains j degrees of freedom on boundary 00221 /// array is allocated in function code_numbers_on_master 00222 long *nbdofd; 00223 00224 /// array containing local boundary code numbers 00225 /// lbcn[i][j][k]=m - the k-th DOF on the j-th boundary node on the i-th subdomain has number m 00226 /// array is allocated in function code_numbers_on_master 00227 long ***lbcn; 00228 00229 /// array containing multiplicity of boundary nodes 00230 /// it is different array from array multip which is defined for all nodes in problem 00231 /// it contains tnbn components 00232 /// bnmultip[i]=j - the i-th boundary node has multiplicity j 00233 /// the i-th boundary node is shared by j subdomains 00234 /// array is allocated in function coarse_local_nodes 00235 long *bnmultip; 00236 00237 /// array containing local numbers of boundary nodes belonging to coarse nodes 00238 /// it contains tnbn rows and bnmultip[i] columns 00239 /// llnbn[i][j]=k - the j-th node belonging to the i-th coarse node has number k 00240 /// array is allocated in function 00241 long **llnbn; 00242 00243 /// array containing numbers of subdomain to which coarse nodes belong to 00244 /// it contains tnbn rows and bnmultip[i] columns 00245 /// ldn[i][j]=k - the j-th node belonging to the i-th coarse node belongs to the k-th domain 00246 /// array is allocated in function 00247 long **ldn; 00248 00249 /// array containing numbers of DOFs at coarse nodes 00250 /// it contains tnbn components 00251 /// ndofncn[i]=j - the i-th coarse node contains j DOFs 00252 /// array is allocated in function schurordering 00253 //long *ndofncn; 00254 00255 /// array containing code numbers at coarse nodes 00256 /// it contains tnbn rows and ndofncn[i] columns 00257 /// cncn[i][j]=k - the j-th unknown at the i-th coarse node has number k 00258 /// array is allocated in function schurordering 00259 //long **cncn; 00260 00261 00262 00263 00264 00265 00266 00267 00268 /// array containing global code numbers 00269 /// gcn[i][j]=k - the j-th component of the i-th boundary node (the i is the global number of node) is equal to the k 00270 long **gcn; 00271 00272 00273 00274 /* 00275 ZACATEK ROZSAHLYCH UPRAV 00276 27.7.2009 00277 */ 00278 00279 // function collects numbers of all nodes on subdomains 00280 void numbers_of_all_nodes_on_subdomains (long *domproc,FILE *out); 00281 // maxnn is established 00282 // nnsd is assembled 00283 00284 // function assembles node multiplicity 00285 void assemble_multip (long *ltg,long *domproc,FILE *out,char *proc_name); 00286 // array bmultip or amultip is assembled 00287 // tnbn is determined 00288 // tnnp is determined if appropriate node ordering is used 00289 // maxnbn is determined if appropriate node ordering is used 00290 // allnodes is allocated and assembled if appropriate node ordering is used 00291 00292 00293 void coupled_dofs (gtopology *top,long *domproc,FILE *out); 00294 // ncdof is determined 00295 // coupdof is allocated and assembled 00296 // coupdofmas is allocated and assembled 00297 00298 // function collects the numbers of all degrees of freedom on subdomains 00299 // supports and constraints are added as DOFs 00300 void numbers_of_all_dofs_on_subdomains (gtopology *top,long *domproc,FILE *out); 00301 // maxndof is established 00302 // nalldof is assembled 00303 00304 // function assembles array containing the numbers of DOFs on nodes 00305 void ndofn_master (gtopology *top,long *domproc,FILE *out,char *proc_name); 00306 // ndofnmas is allocated and assembled 00307 00308 // function collects id of DOFs on the master 00309 void dofind_master (gtopology *top,long *domproc,FILE *out,char *proc_name); 00310 // dofindmas is allocated and assembled 00311 00312 00313 // function updates node multiplicity 00314 void update_multip (gtopology *top,FILE *out,char *proc_name); 00315 // dofind is allocated and assembled 00316 00317 00318 // function assembles the arrays nbnd a nind 00319 void assemble_nbnd_nind (long *ltg,long *domproc,FILE *out,char *proc_name); 00320 // nbnd is allocated and assembled 00321 // nind is allocated and assembled 00322 00323 00324 // function assembles the array nodmultip 00325 void assemble_nodmultip (long *ltg,long *domproc,FILE *out,char *proc_name); 00326 // nodmultip is allocated and assembled 00327 00328 00329 // function assembles global numbers of nodes 00330 void node_global_numbers (long *domproc,FILE *out,char *proc_name); 00331 // gnin is allocated and assembled 00332 // gnbn is allocated and assembled 00333 00334 // function assembles local numbers of nodes 00335 void node_local_numbers (FILE *out); 00336 // lnindom is allocated and assembled 00337 // lnbndom is allocated and assembled 00338 00339 // function assembles coarse numbers of boundary/interface nodes 00340 void node_coarse_numbers (long *domproc,FILE *out,char *proc_name); 00341 // icnbnmas is allocated and assembled 00342 // icmultip is allocated and assembled 00343 00344 00345 // function assembles coarse - global numbers map 00346 void node_coarse_global_map (FILE *out,char *proc_name); 00347 // gnbncn is allocated and assembled 00348 // sid is allocated and assembled 00349 00350 // function generates the Schur complement ordering on subdomains 00351 // it takes into account the coupled DOFs 00352 long schur_ordering (gtopology *top,long *domproc,FILE *out,char *proc_name); 00353 00354 00355 void prepare_data (long *domproc,long *ltg,gtopology *top,FILE *out,char *proc_name); 00356 00357 //function assembles global code numbers on master processor 00358 // for using of class parcongrad 00359 void assemble_gcnd(gtopology *top,long *domproc,FILE *out); 00360 // gcnd is assembled 00361 00362 00363 /// the number of processors 00364 int nproc; 00365 /// rank of processor 00366 int myrank; 00367 /// mesh description 00368 meshdescription md; 00369 /// the number of nodes on subdomain 00370 long nn; 00371 /// the number of DOFs on subdomain 00372 long ndof; 00373 /// the number of internal DOFs on subdomain 00374 long nidof; 00375 /// the number of boundary/interface DOFs on subdomain 00376 long nbdof; 00377 00378 00379 00380 /// the number of coupled DOFs 00381 /// if two or more DOFs are coupled, it means that they have the same 00382 /// code number, they will be localized into one position in vectors and matrices 00383 /// such DOFs are aggregated into one DOF 00384 /// therefore, ncdof is the number of aggregates 00385 /// it is determined in the function coupled_dofs 00386 long ncdof; 00387 00388 /// the number of boundary/interface coupled DOFs 00389 /// it is determined in the function coupled_dofs 00390 long nbcdof; 00391 00392 /// the maximum number of nodes on one subdomain 00393 /// variable is determined in function numbers_of_all_nodes_on_subdomains 00394 long maxnn; 00395 00396 // master 00397 /// array containing the numbers of nodes on subdomains 00398 /// it contains nproc components 00399 /// nnsd[i]=j - j nodes are defined on the i-th subdomain 00400 /// array is allocated in function numbers_of_all_nodes_on_subdomains 00401 long *nnsd; 00402 00403 // master 00404 /// array containing number of subdomains which each boundary/interface node belongs to 00405 /// it contains tnbn components, 00406 /// multip[i]=j - the i-th interface/boundary node belongs to j subdomains 00407 /// array is assembled in the function assemble_multip (FILE *out) 00408 long *bmultip; 00409 00410 // master 00411 /// array containing number of subdomains which each node belongs to 00412 /// it contains tnnp components, 00413 /// multip[i]=j - the i-th node belongs to j subdomains 00414 /// array is assembled in the function assemble_multip (FILE *out) 00415 long *amultip; 00416 00417 /// the number of internal nodes 00418 /// variable is defined in function find_boundary_nodes 00419 long nin; 00420 00421 /// the number of boundary/interface nodes on subdomain 00422 /// variable is determined in function assemble_multip 00423 long nbn; 00424 00425 /// the maximum number of boundary/interface nodes on one subdomain 00426 /// variable is defined in function assemble_multip 00427 long maxnbn; 00428 00429 /// the total number of boundary/interface nodes 00430 /// variable is defined in function assemble_multip 00431 long tnbn; 00432 00433 /// the total number of internal nodes 00434 /// variable is defined in function assemble_multip 00435 long tnin; 00436 00437 // master 00438 /// the total number of nodes in the whole problem 00439 /// variable is defined in function compute_multiplicity 00440 long tnnp; 00441 00442 // master 00443 /// array containing the numbers of boundary/interface nodes on subdomains 00444 /// it contains nproc components 00445 /// nbnd[i]=j - the i-th domain contains j boundary/interface nodes 00446 /// array is allocated in function assemble_nbnd_nind 00447 long *nbnd; 00448 00449 /// array containing the numbers of internal nodes on subdomains 00450 /// it contains nproc components 00451 /// nind[i]=j - the i-th domain contains j internal nodes 00452 /// array is allocated in function assemble_nbnd_nind 00453 long *nind; 00454 00455 /// array containing numbers of subdomains which share the nodes 00456 /// it contains nn components 00457 /// nodmultip[i]=j - the i-th node belongs to j subdomains 00458 /// array is allocated in function assemble_multip 00459 long *nodmultip; 00460 00461 // master 00462 /// array containing global node numbers 00463 /// this array is assembled for mesh description = all_nodes 00464 /// it contains nproc rows and nn[i] columns 00465 /// allnodes[i][j]=k - the j-th node on the i-th subdomain has global number k 00466 /// array is allocated in function assemble_multip 00467 long **allnodes; 00468 00469 // master 00470 /// array containing coarse node numbers 00471 /// this array is assembled for mesh description = bound_nodes 00472 /// it contains nproc rows and nn[i] columns 00473 /// bnodes[i][j]=k - the j-th node on the i-th subdomain has coarse number k 00474 /// if k=-1, the node is internal 00475 /// array is allocated in function assemble_multip 00476 long **bnodes; 00477 00478 // master 00479 /// array containing indicators of coupled DOFs 00480 /// it has ns, ncdof components 00481 /// coupdof[i][j]=k - the j-th coupled DOFs on the i-th subdomain is shared by k nodes 00482 /// array is allocated in the function coupled_dofs 00483 long **coupdof; 00484 00485 // master 00486 /// array containing suspicious indicators of coupled DOFs 00487 /// it has ncdof components 00488 /// coupdofmas[i]=0 - the i-th coupled DOF is not a boundary/interface DOF 00489 /// coupdofmas[i]=1 - the i-th coupled DOF is a boundary/interface DOF 00490 /// array is allocated in the function coupled_dofs 00491 long *coupdofmas; 00492 00493 // master 00494 /// array containing numbers of all degrees of freedom on subdomains 00495 /// nalldof[i]=j - the i-th subdomain contains j degrees of freedom 00496 /// array is allocated in function numbers_of_all_dofs_on_subdomains 00497 long *nalldof; 00498 00499 /// the maximum number of all DOFs on one subdomain 00500 /// variable is determined in function numbers_of_all_dofs_on_subdomains 00501 long maxndof; 00502 00503 // master 00504 /// array containing the numbers of DOF on nodes 00505 /// it contains tnnp components 00506 /// ndofnmas[i]=j - the i-th node (in the global ordering) contains j DOFs 00507 /// array is allocated and assembled in the function ndofn_master 00508 long *ndofnmas; 00509 00510 /// array containing DOF indicators 00511 /// indicators are used for code number generation 00512 /// it has tnnp, ndofnmas[i] components 00513 /// dofindmas[i][j]=k - the j-th DOF in the i-th node has indicator k 00514 /// array is allocated in the function dofind_master 00515 long **dofindmas; 00516 00517 /// array containing DOF indicators 00518 /// if there are coupled DOFs, it is not enough to deal with nodes 00519 /// DOFs have to be split to internal and boundary/interface 00520 /// it has tnnp, ndofnmas[i] components 00521 /// dofind[i][j]=0 - the j-th DOF in the i-th node is internal 00522 /// dofind[i][j]=1 - the j-th DOF in the i-th node is boundary/interface 00523 /// array is allocated in the function update_multip 00524 long **dofind; 00525 00526 /// array containing coarse numbers of interface/boundary nodes 00527 /// it contains ns, nbnd[i] components 00528 /// icnbnmas[i][j]=k - the j-th boundary node on the i-th subdomain has coarse number k 00529 /// array is allocated in the function node_coarse_numbers 00530 long **icnbnmas; 00531 00532 /// array containing coarse numbers of interface/boundary nodes on one subdomain 00533 /// it contains nbn components 00534 /// icnbn[i]=j - the i-th boundary node has coarse number j 00535 /// array is allocated in the function node_coarse_numbers 00536 long *icnbn; 00537 00538 /// array containing node multiplicity of boundary/interface nodes 00539 /// it contains tnbn components 00540 /// icmultip[i]=j - the i-th boundary/interface node belongs to j subdomains 00541 /// array is allocated in the function node_coarse_numbers 00542 long *icmultip; 00543 00544 /// global numbers of boundary/interface nodes on the master 00545 /// it contains nproc, nbn components 00546 /// gnbn[i][j]=k - the j-th boundary/interface node on the i-th subdomain has global number k 00547 /// array is allocated and assembled in the function node_global_numbers 00548 long **gnbn; 00549 00550 /// global numbers of internal nodes on the master 00551 /// it contains nproc, nin components 00552 /// gnin[i][j]=k - the j-th internal node on the i-th subdomain has global number k 00553 /// array is allocated and assembled in the function node_global_numbers 00554 long **gnin; 00555 00556 /// global numbers of boundary/interface nodes on subdomains 00557 /// it contains nbn components 00558 /// gnbndom[i]=j - the i-th boundary/interface node has global number j 00559 /// array is allocated and assembled in the function node_global_numbers 00560 long *gnbndom; 00561 00562 /// local numbers of boundary/interface nodes on subdomains 00563 /// it contains nbn components 00564 /// lnbndom[i]=j - the i-th boundary/interface node has local number j 00565 /// array is allocated and assembled in the function node_local_numbers 00566 long *lnbndom; 00567 00568 /// local numbers of internal nodes on subdomains 00569 /// it contains nin components 00570 /// lnindom[i]=j - the i-th internal node has local number j 00571 /// array is allocated and assembled in the function node_local_numbers 00572 long *lnindom; 00573 00574 /// global numbers of boundary/interface nodes appropriate to coarse node 00575 /// it contains global numbers of boundary/interafce nodes of each coarse node 00576 /// it contains tnbn rows and icmultip[i] columns 00577 /// gnbncn[i][j]=k - the j-th node shared by the i-th coarse node has global number k 00578 /// aray is allocated in the function node_coarse_global_map 00579 long **gnbncn; 00580 00581 /// subdomain id of interface/boundary nodes appropriate to coarse node 00582 /// it contains tnbn rows and icmultip[i] columns 00583 /// sid[i][j]=k - the j-th node shared by the i-th coarse node belongs to the k-th subdomain 00584 /// array is allocated in the function node_coarse_local_map or node_coarse_global_map 00585 long **sid; 00586 00587 /// master 00588 /// nud[i]=j - the i-th domain contains j unknowns (degrees of freedom) 00589 long *nud; 00590 00591 /// master 00592 /// gcnd[i][j]=k - the j-th unknown on the i-th subdomain has global number k 00593 /// gcnd[i] is a pointer to array with code numbers of the i-th subdomain 00594 /// it is similar to arrays cn on elements, the subdomain plays a role of a superelement 00595 long **gcnd; 00596 00597 00598 00599 00600 00601 00602 00603 00604 // backup of ltg from psolver (used in Temelin) 00605 long *bltg; 00606 00607 00608 00609 00610 00611 00612 00613 00614 00615 }; 00616 00617 00618 #endif