00001 #include "partop.h"
00002 #include <string.h>
00003 #include <math.h>
00004 #include <time.h>
00005 #include <float.h>
00006 #include <limits.h>
00007 #include <stdlib.h>
00008 #include "galias.h"
00009 #include "intp.h"
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 partop::partop(int np,int mr,long nd,meshdescription meshd,char *nameproc, int nl)
00024 {
00025
00026 nproc=np;
00027
00028 myrank=mr;
00029
00030 md = meshd;
00031
00032
00033 nn=0;
00034
00035 ndof=0;
00036
00037 ncdof=0;
00038
00039 nbcdof=0;
00040
00041
00042 maxnn=0;
00043
00044
00045 nin=0;
00046
00047 nbn=0;
00048
00049 maxnbn = 0;
00050
00051 tnbn=0;
00052
00053 tnnp=0;
00054
00055
00056 maxndof=0;
00057
00058 bltg = NULL;
00059
00060 lnindom = NULL;
00061
00062 lnbndom = NULL;
00063
00064
00065 nodmultip = NULL;
00066
00067 icnbn = NULL;
00068
00069 gnbndom = NULL;
00070
00071 nind = NULL;
00072
00073
00074 if (myrank==0){
00075
00076 nnsd = NULL;
00077
00078 bmultip = NULL;
00079
00080 amultip = NULL;
00081
00082 nbnd = NULL;
00083
00084 allnodes = NULL;
00085
00086 bnodes = NULL;
00087
00088 coupdof = NULL;
00089
00090 coupdofmas = NULL;
00091
00092 nalldof = NULL;
00093
00094 ndofnmas = NULL;
00095
00096 dofindmas = NULL;
00097
00098 dofind = NULL;
00099
00100 icnbnmas = NULL;
00101
00102 icmultip = NULL;
00103
00104 gnbn = NULL;
00105
00106 gnin = NULL;
00107
00108 gnbncn = NULL;
00109
00110 sid = NULL;
00111
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 ndom=nd;
00124
00125 strcpy (procName,nameproc);
00126 nameLength=nl;
00127
00128
00129
00130 ne=0;
00131
00132
00133 lnbn = NULL;
00134
00135 lnin = NULL;
00136
00137 lgnbn = NULL;
00138
00139 dofmultip = NULL;
00140
00141 if (myrank==0){
00142 multip = NULL;
00143 cnbn = NULL;
00144 nbdofnd = NULL;
00145 nbdofd = NULL;
00146 lbcn = NULL;
00147 bnmultip = NULL;
00148 llnbn = NULL;
00149 ldn = NULL;
00150
00151
00152
00153
00154 gcnbn = NULL;
00155
00156 }
00157
00158 }
00159
00160
00161
00162
00163
00164
00165 partop::~partop()
00166 {
00167 long i;
00168
00169 delete [] bltg;
00170 delete [] lnindom;
00171 delete [] lnbndom;
00172
00173 delete [] nodmultip;
00174 delete [] icnbn;
00175 delete [] gnbndom;
00176
00177 delete [] lnbn;
00178 delete [] lnin;
00179 delete [] lgnbn;
00180 delete [] dofmultip;
00181 delete [] nind;
00182
00183 if (myrank==0){
00184 delete [] nnsd;
00185 delete [] bmultip;
00186 delete [] amultip;
00187 delete [] nbnd;
00188
00189 for (i=0;i<nproc;i++){
00190 if (allnodes)
00191 delete [] allnodes[i];
00192 if (bnodes)
00193 delete [] bnodes[i];
00194 if (coupdof)
00195 delete [] coupdof[i];
00196 }
00197 delete [] allnodes;
00198 delete [] bnodes;
00199 delete [] coupdof;
00200
00201 delete [] coupdofmas;
00202
00203 delete [] nalldof;
00204
00205 delete [] ndofnmas;
00206
00207 for (i=0;i<tnnp;i++){
00208 if (dofindmas)
00209 delete [] dofindmas[i];
00210 if (dofind)
00211 delete [] dofind[i];
00212 }
00213 delete [] dofindmas;
00214 delete [] dofind;
00215
00216 if (icnbnmas)
00217 {
00218 for (i=0;i<nproc;i++){
00219 delete [] icnbnmas[i];
00220 }
00221 }
00222 delete [] icnbnmas;
00223
00224 delete [] icmultip;
00225
00226 for (i=0;i<nproc;i++){
00227 if (gnbn)
00228 delete [] gnbn[i];
00229 if (gnin)
00230 delete [] gnin[i];
00231 }
00232 delete [] gnbn;
00233 delete [] gnin;
00234
00235 for (i=0;i<tnbn;i++){
00236 if (gnbncn)
00237 delete [] gnbncn[i];
00238 if (sid)
00239 delete [] sid[i];
00240 }
00241 delete [] gnbncn;
00242 delete [] sid;
00243
00244 delete [] multip;
00245
00246 for (i=0;i<nproc;i++){
00247 if (cnbn)
00248 delete [] cnbn[i];
00249 if (nbdofnd)
00250 delete [] nbdofnd[i];
00251 }
00252 delete [] cnbn;
00253 delete [] nbdofnd;
00254
00255 delete [] nbdofd;
00256
00257 delete [] bnmultip;
00258
00259 for (i=0;i<tnbn;i++){
00260 if (llnbn)
00261 delete [] llnbn[i];
00262 if (ldn)
00263 delete [] ldn[i];
00264 }
00265 delete [] llnbn;
00266 delete [] ldn;
00267
00268
00269
00270
00271
00272
00273
00274 }
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 void partop::initiation (gtopology *top,long *ltg)
00287 {
00288 long i;
00289
00290
00291 nn = top->nn;
00292
00293 ne = top->ne;
00294
00295
00296 switch (md){
00297 case all_nodes:{
00298 for (i=0;i<nn;i++){
00299 top->gnodes[i].ai = ltg[i];
00300 }
00301 break;
00302 }
00303 case bound_nodes:{
00304 for (i=0;i<nn;i++){
00305 top->gnodes[i].ai = ltg[i];
00306 }
00307 break;
00308 }
00309 case neg_bound_nodes:{
00310 for (i=0;i<nn;i++){
00311 top->gnodes[i].ai = ltg[i];
00312 }
00313 break;
00314 }
00315 default:{
00316 par_print_err(myrank,"unknown type of mesh description", __FILE__, __LINE__, __func__);
00317 }
00318 }
00319
00320
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 void partop::compute_multiplicity (long *ltg,long *domproc,FILE *out)
00358 {
00359 long i,j,k,buffsize;
00360 long *buff;
00361 MPI_Status stat;
00362
00363 if (maxnn==0){
00364 fprintf (stderr,"\n\n maximum number of nodes on one subdomain is equal to zero,\n");
00365 fprintf (stderr,"\n function numbers_of_all_nodes_on_subdomains has to be called first,\n");
00366 abort ();
00367 }
00368
00369 switch (md){
00370 case bound_nodes:{
00371
00372 buffsize=2;
00373 buff = new long [buffsize];
00374
00375
00376 nbn=0;
00377 maxnbn = 0;
00378 tnbn=0;
00379 for (i=0;i<nn;i++){
00380 if (tnbn<ltg[i])
00381 tnbn=ltg[i];
00382 if (ltg[i]>-1)
00383 nbn++;
00384 }
00385
00386 buff[0]=tnbn;
00387 buff[1]=nbn;
00388
00389 if (myrank==0){
00390
00391 if (nbnd != NULL)
00392 delete [] nbnd;
00393 nbnd = new long [nproc];
00394 memset(nbnd, 0, sizeof(*nbnd)*nproc);
00395
00396
00397 j=domproc[0];
00398 if (tnbn<buff[0]) tnbn=buff[0];
00399 if (maxnbn<buff[1]) maxnbn=buff[1];
00400 nbnd[j]=buff[1];
00401
00402 for (i=1;i<nproc;i++){
00403 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
00404 j=domproc[stat.MPI_TAG];
00405
00406 if (tnbn<buff[0])
00407 tnbn=buff[0];
00408 if (maxnbn<buff[1])
00409 maxnbn=buff[1];
00410 nbnd[j]=buff[1];
00411 }
00412 tnbn++;
00413
00414 buff[0]=tnbn;
00415 buff[1]=maxnbn;
00416
00417 for (i=1;i<nproc;i++){
00418 MPI_Send (buff,buffsize,MPI_LONG,i,myrank,MPI_COMM_WORLD);
00419 }
00420 }
00421 else{
00422 MPI_Send (buff,buffsize,MPI_LONG,0,myrank,MPI_COMM_WORLD);
00423 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
00424 }
00425 MPI_Barrier (MPI_COMM_WORLD);
00426
00427 tnbn=buff[0];
00428 maxnbn=buff[1];
00429
00430 delete [] buff;
00431
00432 buffsize = maxnbn;
00433 buff = new long [buffsize];
00434 for (i=0;i<maxnbn;i++){
00435 buff[i]=-1;
00436 }
00437
00438 j=0;
00439 for(i=0;i<nn;i++){
00440 if (ltg[i]>-1){
00441 buff[j] = ltg[i];
00442 j++;
00443 }
00444 }
00445
00446
00447 if(myrank == 0){
00448 if (multip!=NULL){
00449 delete [] multip;
00450 }
00451 multip = new long [tnbn];
00452 for(i=0;i<tnbn;i++){
00453 multip[i]=0;
00454 }
00455
00456
00457 for(j=0;j<maxnbn;j++){
00458 if (buff[j]>-1){
00459 multip[buff[j]]++;
00460 }
00461 }
00462
00463
00464 for (i=1;i<nproc;i++){
00465 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
00466 for(j=0;j<maxnbn;j++){
00467 if (buff[j]>-1){
00468 multip[buff[j]]++;
00469 }
00470 }
00471 }
00472
00473 }
00474 else{
00475 MPI_Send (buff,buffsize,MPI_LONG,0,myrank,MPI_COMM_WORLD);
00476 }
00477 MPI_Barrier (MPI_COMM_WORLD);
00478 delete [] buff;
00479
00480 buffsize=tnbn;
00481 buff = new long [buffsize];
00482
00483 if (myrank==0){
00484 for (i=0;i<tnbn;i++){
00485 buff[i]=multip[i];
00486 }
00487
00488 for (i=1;i<nproc;i++){
00489 MPI_Send (buff,buffsize,MPI_LONG,i,myrank,MPI_COMM_WORLD);
00490 }
00491 }
00492 else{
00493 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
00494 }
00495 MPI_Barrier (MPI_COMM_WORLD);
00496
00497 if (nodmultip!=NULL)
00498 delete [] nodmultip;
00499 nodmultip = new long [nn];
00500
00501 for (i=0;i<nn;i++){
00502 if (ltg[i]>-1){
00503 nodmultip[i]=buff[ltg[i]];
00504 }
00505 else{
00506 nodmultip[i]=1;
00507 }
00508 }
00509
00510 delete [] buff;
00511
00512 break;
00513 }
00514
00515
00516
00517
00518 case all_nodes:
00519 case neg_bound_nodes:{
00520
00521 buffsize=maxnn+1;
00522 buff = new long [buffsize];
00523 tnnp=0;
00524 for (i=0;i<nn;i++){
00525 buff[i]=ltg[i];
00526 if (tnnp<ltg[i])
00527 tnnp=ltg[i];
00528 }
00529 buff[maxnn]=tnnp;
00530
00531
00532
00533
00534 if (myrank==0){
00535 if (allnodes != NULL){
00536 for (i=0;i<nproc;i++){
00537 delete [] allnodes[i];
00538 }
00539 delete [] allnodes;
00540 }
00541 allnodes = new long* [nproc];
00542 for (i=0;i<nproc;i++){
00543 allnodes[i] = new long [nnsd[i]];
00544 }
00545
00546
00547 k=domproc[0];
00548 for (j=0;j<nnsd[k];j++){
00549 allnodes[k][j]=buff[j];
00550 }
00551 if (tnnp<buff[maxnn])
00552 tnnp=buff[maxnn];
00553
00554
00555 for (i=1;i<nproc;i++){
00556 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
00557
00558 k=domproc[stat.MPI_TAG];
00559 for (j=0;j<nnsd[k];j++){
00560 allnodes[k][j]=buff[j];
00561 }
00562 if (tnnp<buff[maxnn])
00563 tnnp=buff[maxnn];
00564 }
00565 }
00566
00567
00568
00569
00570 else{
00571 MPI_Send (buff,buffsize,MPI_LONG,0,myrank,MPI_COMM_WORLD);
00572 }
00573
00574 if (myrank==0){
00575
00576
00577
00578
00579 tnnp++;
00580
00581 fprintf (out,"\n\n\n total number of nodes on whole problem %ld\n",tnnp);
00582 if (multip != NULL)
00583 delete [] multip;
00584 multip = new long [tnnp];
00585 for (i=0;i<tnnp;i++){
00586 multip[i]=0;
00587 }
00588
00589
00590 for (i=0;i<nproc;i++){
00591 for (j=0;j<nnsd[i];j++){
00592 multip[allnodes[i][j]]++;
00593 }
00594 }
00595 }
00596
00597
00598 if (myrank==0){
00599 for (i=1;i<nproc;i++){
00600 k=domproc[i];
00601 for (j=0;j<nnsd[k];j++){
00602 buff[j]=multip[allnodes[k][j]];
00603 }
00604 MPI_Send (buff,buffsize,MPI_LONG,i,myrank,MPI_COMM_WORLD);
00605 }
00606
00607 k=domproc[0];
00608 for (j=0;j<nnsd[k];j++){
00609 buff[j]=multip[allnodes[k][j]];
00610 }
00611 }
00612 else{
00613 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
00614 }
00615
00616
00617 if (nodmultip != NULL)
00618 delete [] nodmultip;
00619 nodmultip = new long [nn];
00620 for (i=0;i<nn;i++){
00621 nodmultip[i] = buff[i];
00622 }
00623
00624 delete [] buff;
00625
00626 if (myrank==0){
00627
00628 tnbn=0;
00629 for (i=0;i<tnnp;i++){
00630 if (multip[i]!=1) tnbn++;
00631 }
00632
00633
00634 if (nbnd != NULL)
00635 delete [] nbnd;
00636 nbnd = new long [nproc];
00637
00638 maxnbn=0;
00639 for (i=0;i<nproc;i++){
00640 k=0;
00641 for (j=0;j<nnsd[i];j++){
00642 if (multip[allnodes[i][j]]>1) k++;
00643 }
00644 if (maxnbn<k) maxnbn=k;
00645 nbnd[i]=k;
00646 }
00647
00648 for (i=1;i<nproc;i++){
00649 MPI_Send (&maxnbn,1,MPI_LONG,i,myrank,MPI_COMM_WORLD);
00650 }
00651 }
00652 else{
00653 MPI_Recv (&maxnbn,1,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
00654 }
00655
00656
00657
00658 nbn=0;
00659 for (i=0;i<nn;i++){
00660 if (nodmultip[i]>1)
00661 nbn++;
00662 }
00663
00664 break;
00665 }
00666 default:{
00667 fprintf (stderr,"\n\n unknown type of mesh description is required in");
00668 fprintf (stderr,"\n function compute_multiplicity (file %s, line %d)\n",__FILE__,__LINE__);
00669 }
00670 }
00671 MPI_Barrier (MPI_COMM_WORLD);
00672
00673
00674 fprintf(out,"\n\n\n Multiplicity of nodes on subdomain\n\n");
00675 for (i=0;i<nn;i++)
00676 fprintf(out,"%ld %ld\n",i,nodmultip[i]);
00677
00678
00679 fprintf(out,"\n\n\n total number of boundary nodes in whole problem is %ld\n\n",tnbn);
00680 fprintf (out,"\n\n\n maximum number of boundary nodes on subdomain is %ld\n\n",maxnbn);
00681 if (myrank==0){
00682 fprintf (out,"\n\n\n numbers of boundary nodes on each subdomain \n\n");
00683 for (i=0;i<nproc;i++){
00684 fprintf (out,"\n %ld",nbnd[i]);
00685 }
00686 }
00687 fprintf(out,"\n\n\n total number of boundary nodes in whole problem is %ld\n\n",tnbn);
00688 fprintf (out,"\n\n\n maximum number of boundary nodes on subdomain is %ld\n\n",maxnbn);
00689 if (myrank==0){
00690 fprintf (out,"\n\n\n numbers of boundary nodes on each subdomain \n\n");
00691 for (i=0;i<nproc;i++){
00692 fprintf (out,"\n %ld",nbnd[i]);
00693 }
00694 }
00695
00696 }
00697
00698
00699
00700
00701
00702
00703
00704
00705 void partop::dof_multiplicity (gtopology *top,FILE *out)
00706 {
00707 long i,j,k,nm;
00708 long ndofn;
00709
00710 ndof = 0;
00711 for (i=0;i<nn;i++){
00712 ndofn=top->give_ndofn (i);
00713 for (j=0;j<ndofn;j++){
00714 k=top->give_dof (i,j);
00715 if (k>0){
00716 ndof++;
00717 }
00718 }
00719 }
00720
00721
00722
00723
00724 dofmultip = new long [ndof];
00725
00726 for (i=0;i<nn;i++){
00727 ndofn=top->give_ndofn (i);
00728 nm=nodmultip[i];
00729 for (j=0;j<ndofn;j++){
00730 k=top->give_dof (i,j);
00731 if (k>0){
00732 dofmultip[k-1]=nm;
00733 }
00734 }
00735 }
00736
00737
00738
00739
00740
00741
00742
00743 }
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768 void partop::find_boundary_nodes (long *ltg,long *domproc,FILE *out)
00769 {
00770 long i,j,k,l,buffsize;
00771 long *buff;
00772 MPI_Status stat;
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899 buffsize=maxnbn;
00900 buff = new long [buffsize];
00901
00902 switch (md){
00903 case bound_nodes:{
00904
00905
00906 if (lgnbn!=NULL)
00907 delete [] lgnbn;
00908 lgnbn = new long [nbn];
00909
00910 j=0;
00911 for (i=0;i<nn;i++){
00912 if (ltg[i]>-1){
00913 lgnbn[j]=ltg[i];
00914 j++;
00915 }
00916 }
00917 break;
00918 }
00919 case all_nodes:
00920 case neg_bound_nodes:{
00921
00922 if (myrank==0){
00923 for (i=1;i<nproc;i++){
00924 k=domproc[i];
00925 l=0;
00926 for (j=0;j<nnsd[k];j++){
00927 if (multip[allnodes[k][j]]>1){
00928 buff[l]=allnodes[k][j];
00929 l++;
00930 }
00931 }
00932
00933 MPI_Send (buff,buffsize,MPI_LONG,i,myrank,MPI_COMM_WORLD);
00934 }
00935
00936 k=domproc[0];
00937 l=0;
00938 for (j=0;j<nnsd[k];j++){
00939 if (multip[allnodes[k][j]]>1){
00940 buff[l]=allnodes[k][j];
00941 l++;
00942 }
00943 }
00944
00945 }
00946 else{
00947 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
00948 }
00949
00950
00951 if (lgnbn!=NULL)
00952 delete [] lgnbn;
00953 lgnbn = new long [nbn];
00954
00955 for (i=0;i<nbn;i++){
00956 lgnbn[i]=buff[i];
00957 }
00958
00959 break;
00960 }
00961 default:{
00962 fprintf (stderr,"\n\n unknown type of mesh description is required in");
00963 fprintf (stderr,"\n function find_boundary_nodes (file %s, line %d)\n",__FILE__,__LINE__);
00964 }
00965 }
00966
00967
00968 delete [] buff;
00969
00970
00971
00972
00973
00974
00975 if (lnbn != NULL)
00976 delete [] lnbn;
00977 lnbn = new long [nbn];
00978
00979 switch (md){
00980 case all_nodes:
00981 case neg_bound_nodes:{
00982 j=0;
00983 for (i=0;i<nn;i++){
00984 if (nodmultip[i]>1){
00985 lnbn[j]=i;
00986 j++;
00987 }
00988 }
00989
00990 break;
00991 }
00992
00993 case bound_nodes:{
00994 j=0;
00995 for (i=0;i<nn;i++){
00996 if (ltg[i]>-1){
00997 lnbn[j]=i;
00998 j++;
00999 }
01000 }
01001 break;
01002 }
01003 default:{
01004 fprintf (stderr,"\n\n unknown type of mesh description is required in");
01005 fprintf (stderr,"\n function find_boundary_nodes (file %s, line %d)\n",__FILE__,__LINE__);
01006 }
01007 }
01008
01009
01010
01011 nin = nn-nbn;
01012
01013
01014 if (lnin != NULL)
01015 delete [] lnin;
01016 lnin = new long [nin];
01017
01018 buff = new long [nn];
01019 for (i=0;i<nn;i++){
01020 buff[i]=0;
01021 }
01022
01023 for (i=0;i<nbn;i++){
01024 j=lnbn[i];
01025 buff[j]=1;
01026 }
01027
01028 j=0;
01029 for (i=0;i<nn;i++){
01030 if (buff[i]==0){
01031 lnin[j]=i;
01032 j++;
01033 }
01034 }
01035
01036 delete [] buff;
01037
01038 MPI_Barrier (MPI_COMM_WORLD);
01039
01040
01041 if (myrank==0){
01042 fprintf (out,"\n\n\n numbers of boundary nodes on each subdomain \n\n");
01043 for (i=0;i<nproc;i++){
01044 fprintf (out,"\n %ld",nbnd[i]);
01045 }
01046 }
01047
01048 fprintf (out,"\n\n\n numbers of boundary nodes on subdomain \n\n");
01049 fprintf (out,"\n %ld",nbn);
01050 fprintf (out,"\n\n\n local numbers of boundary nodes on subdomain");
01051 for (i=0;i<nbn;i++){
01052 fprintf (out,"\n %ld %ld",i,lnbn[i]);
01053 }
01054
01055 fprintf (out,"\n\n\n numbers of internal nodes on subdomain \n\n");
01056 fprintf (out,"\n %ld",nin);
01057 fprintf (out,"\n\n\n local numbers of internal nodes on subdomain");
01058 for (i=0;i<nin;i++){
01059 fprintf (out,"\n %ld %ld",i,lnin[i]);
01060 }
01061
01062
01063 }
01064
01065
01066
01067
01068
01069
01070 void partop::rewrite_ltg (long *ltg)
01071 {
01072 long i;
01073
01074 for (i=0;i<nn;i++){
01075 ltg[i]=-1;
01076 }
01077 for (i=0;i<nbn;i++){
01078 ltg[lnbn[i]]=lgnbn[i];
01079 }
01080 }
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102 void partop::boundary_nodes_on_master (gtopology *top,long *domproc,FILE *out)
01103 {
01104 long i,j,k,m,buffsize;
01105 long *buff;
01106 MPI_Status stat;
01107
01108 if (myrank==0){
01109 if (nbnd==NULL){
01110 fprintf (stderr,"\n\n array containing numbers of boundary nodes on subdomains is not allocated,\n");
01111 fprintf (stderr,"\n function find_boundary_nodes has to be called first (file %s, line %d),\n",__FILE__,__LINE__);
01112 }
01113 }
01114
01115
01116 if (myrank==0){
01117 if (cnbn != NULL){
01118 for (i=0;i<nproc;i++){
01119 delete [] cnbn[i];
01120 }
01121 delete [] cnbn;
01122 }
01123 cnbn = new long* [nproc];
01124 for (i=0;i<nproc;i++){
01125 cnbn[i] = new long [nbnd[i]];
01126 }
01127 }
01128
01129 switch (md){
01130 case all_nodes:
01131 case neg_bound_nodes:{
01132
01133 if (myrank==0){
01134 if (gcnbn != NULL)
01135 delete [] gcnbn;
01136 gcnbn = new long [tnnp];
01137
01138 j=0;
01139 for (i=0;i<tnnp;i++){
01140 if (multip[i]>1){
01141 gcnbn[i]=j;
01142 j++;
01143 }
01144 else{
01145 gcnbn[i]=-1;
01146 }
01147 }
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157 if (j!=tnbn){
01158 fprintf (stderr,"\n\n total number of boundary nodes computed in function boundary_nodes_on_master");
01159 fprintf (stderr,"\n differs from the number computed in function find_boundary_nodes (file %s, line %d),\n",__FILE__,__LINE__);
01160 }
01161
01162 for (i=0;i<nproc;i++){
01163 m=0;
01164 for (j=0;j<nnsd[i];j++){
01165 k=allnodes[i][j];
01166 if (gcnbn[k]>-1){
01167 cnbn[i][m]=gcnbn[k];
01168 m++;
01169 }
01170 }
01171 }
01172 delete [] gcnbn;
01173 gcnbn = NULL;
01174 }
01175
01176 break;
01177 }
01178
01179 case bound_nodes:{
01180
01181 if (maxnbn==0){
01182 fprintf (stderr,"\n\n maximum number of boundary nodes on one subdomain is equal to zero,");
01183 fprintf (stderr,"\n function find_boundary_nodes should be called first (file %s, line %d),\n",__FILE__,__LINE__);
01184 }
01185
01186 buffsize=maxnbn;
01187 buff = new long [buffsize];
01188
01189
01190 j=0;
01191 for (i=0;i<nn;i++){
01192 if (top->gnodes[i].ai>-1){
01193 buff[j]=top->gnodes[i].ai;
01194 j++;
01195 }
01196 }
01197
01198 if (myrank==0){
01199
01200
01201 k=domproc[0];
01202 for (j=0;j<nbnd[k];j++){
01203 cnbn[k][j]=buff[j];
01204 }
01205
01206 for (i=1;i<nproc;i++){
01207 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
01208
01209
01210 k=domproc[stat.MPI_TAG];
01211 for (j=0;j<nbnd[k];j++){
01212 cnbn[k][j]=buff[j];
01213 }
01214
01215 }
01216
01217 }
01218 else{
01219 MPI_Send (buff,buffsize,MPI_LONG,0,myrank,MPI_COMM_WORLD);
01220 }
01221
01222 delete [] buff;
01223 break;
01224 }
01225 default:{
01226 fprintf (stderr,"\n\n unknown type of mesh description is required in");
01227 fprintf (stderr,"\n function boundary_nodes_on_master (file %s, line %d)\n",__FILE__,__LINE__);
01228 }
01229 }
01230
01231
01232 MPI_Barrier (MPI_COMM_WORLD);
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246 }
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261 void partop::coarse_local_nodes ()
01262 {
01263 long i,j,k,m;
01264
01265 if (myrank==0){
01266
01267 bnmultip = new long [tnbn];
01268 for (i=0;i<tnbn;i++){
01269 bnmultip[i]=0;
01270 }
01271
01272 if (md == all_nodes){
01273 j=0;
01274 for (i=0;i<tnnp;i++){
01275 if (multip[i]>1){
01276 bnmultip[j]=multip[i];
01277 j++;
01278 }
01279 }
01280 }
01281
01282 if (md == bound_nodes){
01283 for (i=0;i<nproc;i++){
01284 for (j=0;j<nbnd[i];j++){
01285 bnmultip[cnbn[i][j]]++;
01286 }
01287 }
01288 }
01289
01290 llnbn = new long* [tnbn];
01291 ldn = new long* [tnbn];
01292 for (i=0;i<tnbn;i++){
01293 llnbn[i] = new long [bnmultip[i]];
01294 ldn[i] = new long [bnmultip[i]];
01295 bnmultip[i]=0;
01296 }
01297
01298 for (i=0;i<nproc;i++){
01299 for (j=0;j<nbnd[i];j++){
01300 k=cnbn[i][j];
01301 m=bnmultip[k];
01302 llnbn[k][m]=j;
01303 ldn[k][m]=i;
01304 bnmultip[k]++;
01305 }
01306 }
01307 }
01308 }
01309
01310
01311
01312
01313
01314
01315
01316
01317 void partop::sort_nodes (FILE *out)
01318 {
01319 long i,j,k,m,n,min;
01320
01321 if (myrank==0){
01322 for (i=0;i<tnbn;i++){
01323 for (j=0;j<bnmultip[i];j++){
01324 min=nproc;
01325 for (k=j;k<bnmultip[i];k++){
01326 if (ldn[i][k]<min){
01327 min=ldn[i][k];
01328 m=k;
01329 }
01330 }
01331 n=ldn[i][j];
01332 ldn[i][j]=ldn[i][m];
01333 ldn[i][m]=n;
01334
01335 n=llnbn[i][j];
01336 llnbn[i][j]=llnbn[i][m];
01337 llnbn[i][m]=n;
01338 }
01339 }
01340 }
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367 }
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391 void partop::number_of_bdofs_on_nodes (gtopology *top,long *domproc,FILE *out)
01392 {
01393 long i,j,k,buffsize;
01394 long *buff;
01395 MPI_Status stat;
01396
01397 if (lnbn==NULL){
01398 fprintf (stderr,"\n\n array containing local numbers of boundary nodes is not allocated,\n");
01399 fprintf (stderr,"\n function find_boundary_nodes has to be called first (file %s, line %d),\n",__FILE__,__LINE__);
01400 }
01401
01402 buffsize = maxnbn;
01403 buff = new long [buffsize];
01404
01405
01406 for (i=0;i<nbn;i++){
01407 j=lnbn[i];
01408 buff[i]=top->give_ndofn (j);
01409 }
01410
01411 if (myrank==0){
01412 if (nbdofnd != NULL){
01413 for (i=0;i<nproc;i++){
01414 delete [] nbdofnd[i];
01415 }
01416 delete [] nbdofnd;
01417 }
01418 nbdofnd = new long* [nproc];
01419 for (i=0;i<nproc;i++){
01420 nbdofnd[i] = new long [nbnd[i]];
01421 }
01422
01423
01424 k=domproc[0];
01425 for (j=0;j<nbnd[k];j++){
01426 nbdofnd[k][j]=buff[j];
01427 }
01428
01429 for (i=1;i<nproc;i++){
01430 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
01431
01432
01433 k=domproc[stat.MPI_TAG];
01434 for (j=0;j<nbnd[k];j++){
01435 nbdofnd[k][j]=buff[j];
01436 }
01437
01438 }
01439 }
01440 else{
01441 MPI_Send (buff,buffsize,MPI_LONG,0,myrank,MPI_COMM_WORLD);
01442 }
01443 MPI_Barrier (MPI_COMM_WORLD);
01444
01445 delete [] buff;
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458 }
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485 void partop::code_numbers_on_master (gtopology *top,long *domproc,FILE *out)
01486 {
01487 long i,j,k,m,l,ndofn,buffsize;
01488 long *buff;
01489 MPI_Status stat;
01490
01491 if (myrank==0){
01492 if (nbdofnd==NULL){
01493 fprintf (stderr,"\n\n array ndofnd is not allocated in function code_numbers_on_master,\n");
01494 fprintf (stderr,"\n function number_of_dofs_on_nodes has to be called first (file %s, line %d),\n",__FILE__,__LINE__);
01495 }
01496 }
01497
01498
01499 if (myrank==0){
01500 if (nbdofd != NULL)
01501 delete [] nbdofd;
01502 nbdofd = new long [nproc];
01503
01504 maxnbdof=0;
01505 for (i=0;i<nproc;i++){
01506 nbdofd[i]=0;
01507 for (j=0;j<nbnd[i];j++){
01508 nbdofd[i]+=nbdofnd[i][j];
01509 }
01510 if (maxnbdof<nbdofd[i])
01511 maxnbdof=nbdofd[i];
01512 }
01513
01514 for (i=1;i<nproc;i++){
01515 MPI_Send (&maxnbdof,1,MPI_LONG,i,myrank,MPI_COMM_WORLD);
01516 }
01517 }
01518 else{
01519 MPI_Recv (&maxnbdof,1,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
01520 }
01521
01522 buffsize = maxnbdof;
01523 buff = new long [buffsize];
01524
01525 m=0;
01526 for (i=0;i<nbn;i++){
01527 k=lnbn[i];
01528 ndofn = top->give_ndofn (k);
01529 for (j=0;j<ndofn;j++){
01530 buff[m]=top->give_dof (k,j);
01531 m++;
01532 }
01533 }
01534
01535 if (myrank==0){
01536 if (lbcn != NULL){
01537 for (i=0;i<nproc;i++){
01538 for (j=0;j<nbnd[i];j++){
01539 delete [] lbcn[i][j];
01540 }
01541 delete [] lbcn[i];
01542 }
01543 delete [] lbcn;
01544 }
01545 lbcn = new long** [nproc];
01546 for (i=0;i<nproc;i++){
01547 lbcn[i] = new long* [nbnd[i]];
01548 for (j=0;j<nbnd[i];j++){
01549 lbcn[i][j] = new long [nbdofnd[i][j]];
01550 }
01551 }
01552
01553
01554 l=0;
01555 m=domproc[0];
01556 for (j=0;j<nbnd[m];j++){
01557 for (k=0;k<nbdofnd[m][j];k++){
01558 lbcn[m][j][k]=buff[l];
01559 l++;
01560 }
01561 }
01562
01563 for (i=1;i<nproc;i++){
01564 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
01565
01566
01567 l=0;
01568 m=domproc[stat.MPI_TAG];
01569 for (j=0;j<nbnd[m];j++){
01570 for (k=0;k<nbdofnd[m][j];k++){
01571 lbcn[m][j][k]=buff[l];
01572 l++;
01573 }
01574 }
01575
01576 }
01577 }
01578 else{
01579 MPI_Send (buff,buffsize,MPI_LONG,0,myrank,MPI_COMM_WORLD);
01580 }
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599 MPI_Barrier (MPI_COMM_WORLD);
01600
01601 }
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658 void partop::numbers_of_all_nodes_on_subdomains (long *domproc,FILE *out)
01659 {
01660 long i,j,k;
01661 MPI_Status stat;
01662
01663
01664 maxnn=nn;
01665
01666
01667
01668
01669 if (myrank==0){
01670
01671 if (nnsd!=NULL)
01672 delete [] nnsd;
01673 nnsd = new long [nproc];
01674
01675
01676 j=domproc[0];
01677 nnsd[j]=maxnn;
01678
01679 for (i=1;i<nproc;i++){
01680 MPI_Recv (&k,1,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
01681
01682
01683 j=domproc[stat.MPI_TAG];
01684 if (maxnn<k) maxnn=k;
01685 nnsd[j]=k;
01686 }
01687
01688 for (i=1;i<nproc;i++){
01689 MPI_Send (&maxnn,1,MPI_LONG,i,myrank,MPI_COMM_WORLD);
01690 }
01691 }
01692
01693
01694
01695 else{
01696 MPI_Send (&nn,1,MPI_LONG,0,myrank,MPI_COMM_WORLD);
01697 MPI_Recv (&maxnn,1,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
01698 }
01699 MPI_Barrier (MPI_COMM_WORLD);
01700
01701
01702 if (myrank==0){
01703 fprintf (out,"\n\n\n partop::numbers_of_all_nodes_on_subdomains");
01704 fprintf (out,"\n\n the maximum number of nodes on subdomains (maxnn) %ld",maxnn);
01705 fprintf (out,"\n\n array nnsd");
01706 for (i=0;i<nproc;i++){
01707 fprintf (out,"\n %ld",nnsd[i]);
01708 }
01709 }
01710
01711 }
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741 void partop::assemble_multip (long *ltg,long *domproc,FILE *out,char *proc_name)
01742 {
01743 long i,j,k,buffsize;
01744 long *buff;
01745 MPI_Status stat;
01746
01747 if (maxnn==0){
01748 par_print_err(myrank,proc_name,"maximum number of nodes on one subdomain is equal to zero",__FILE__, __LINE__, __func__);
01749 par_print_err(myrank,proc_name,"function numbers_of_all_nodes_on_subdomains has to be called first",__FILE__, __LINE__, __func__);
01750 }
01751 if (myrank==0){
01752 if (nnsd==NULL){
01753 par_print_err(myrank,proc_name,"array nnsd (number of nodes on subdomains) is not assembled",__FILE__, __LINE__, __func__);
01754 par_print_err(myrank,proc_name,"function numbers_of_all_nodes_on_subdomains has to be called first",__FILE__, __LINE__, __func__);
01755 }
01756 }
01757
01758 switch (md){
01759 case bound_nodes:{
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827 buffsize=2;
01828 buff = new long [buffsize];
01829
01830
01831 maxnbn = 0;
01832
01833 nbn = 0;
01834
01835 tnbn = 0;
01836
01837
01838 for (i=0;i<nn;i++){
01839 if (tnbn<ltg[i])
01840 tnbn=ltg[i];
01841 if (ltg[i]>-1)
01842 nbn++;
01843 }
01844
01845 buff[0]=tnbn;
01846 buff[1]=nbn;
01847
01848 if (myrank==0){
01849
01850 j=domproc[0];
01851 if (tnbn<buff[0]) tnbn=buff[0];
01852 if (maxnbn<buff[1]) maxnbn=buff[1];
01853
01854 for (i=1;i<nproc;i++){
01855 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
01856 j=domproc[stat.MPI_TAG];
01857
01858 if (tnbn<buff[0])
01859 tnbn=buff[0];
01860 if (maxnbn<buff[1])
01861 maxnbn=buff[1];
01862 }
01863 tnbn++;
01864
01865 buff[0]=tnbn;
01866 buff[1]=maxnbn;
01867
01868 for (i=1;i<nproc;i++){
01869 MPI_Send (buff,buffsize,MPI_LONG,i,myrank,MPI_COMM_WORLD);
01870 }
01871 }
01872 else{
01873 MPI_Send (buff,buffsize,MPI_LONG,0,myrank,MPI_COMM_WORLD);
01874 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
01875 }
01876 MPI_Barrier (MPI_COMM_WORLD);
01877
01878 tnbn=buff[0];
01879 maxnbn=buff[1];
01880
01881 delete [] buff;
01882
01883
01884
01885 buffsize = maxnn;
01886 buff = new long [buffsize];
01887 for (i=0;i<maxnn;i++){
01888 buff[i]=-1;
01889 }
01890
01891 for(i=0;i<nn;i++){
01892 buff[i] = ltg[i];
01893 }
01894
01895
01896 if(myrank == 0){
01897
01898 if (bnodes != NULL){
01899 for (i=0;i<nproc;i++){
01900 delete [] bnodes[i];
01901 }
01902 delete [] bnodes;
01903 }
01904 bnodes = new long* [nproc];
01905 for (i=0;i<nproc;i++){
01906 bnodes[i] = new long [nnsd[i]];
01907 }
01908
01909 if (bmultip!=NULL){
01910 delete [] bmultip;
01911 }
01912 bmultip = new long [tnbn];
01913 for(i=0;i<tnbn;i++){
01914 bmultip[i]=0;
01915 }
01916
01917
01918 k=domproc[0];
01919 for(j=0;j<nnsd[k];j++){
01920 bnodes[k][j]=buff[j];
01921 if (buff[j]>-1){
01922 bmultip[buff[j]]++;
01923 }
01924 }
01925
01926
01927 for (i=1;i<nproc;i++){
01928 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
01929
01930 k=domproc[stat.MPI_TAG];
01931 for(j=0;j<nnsd[k];j++){
01932 bnodes[k][j]=buff[j];
01933 if (buff[j]>-1){
01934 bmultip[buff[j]]++;
01935 }
01936 }
01937 }
01938
01939 }
01940 else{
01941 MPI_Send (buff,buffsize,MPI_LONG,0,myrank,MPI_COMM_WORLD);
01942 }
01943 MPI_Barrier (MPI_COMM_WORLD);
01944 delete [] buff;
01945
01946 buffsize=tnbn;
01947 buff = new long [buffsize];
01948
01949 if (myrank==0){
01950 for (i=0;i<tnbn;i++){
01951 buff[i]=bmultip[i];
01952 }
01953
01954 for (i=1;i<nproc;i++){
01955 MPI_Send (buff,buffsize,MPI_LONG,i,myrank,MPI_COMM_WORLD);
01956 }
01957 }
01958 else{
01959 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
01960 }
01961 MPI_Barrier (MPI_COMM_WORLD);
01962
01963 delete [] buff;
01964
01965 break;
01966 }
01967
01968
01969
01970 case all_nodes:
01971 case neg_bound_nodes:{
01972
01973 buffsize=maxnn+1;
01974 buff = new long [buffsize];
01975
01976
01977 tnnp=0;
01978
01979 for (i=0;i<nn;i++){
01980 buff[i]=ltg[i];
01981 if (tnnp<ltg[i])
01982 tnnp=ltg[i];
01983 }
01984 buff[maxnn]=tnnp;
01985
01986
01987
01988
01989 if (myrank==0){
01990 if (allnodes != NULL){
01991 for (i=0;i<nproc;i++){
01992 delete [] allnodes[i];
01993 }
01994 delete [] allnodes;
01995 }
01996 allnodes = new long* [nproc];
01997 for (i=0;i<nproc;i++){
01998 allnodes[i] = new long [nnsd[i]];
01999 }
02000
02001
02002 k=domproc[0];
02003 for (j=0;j<nnsd[k];j++){
02004 allnodes[k][j]=buff[j];
02005 }
02006 if (tnnp<buff[maxnn])
02007 tnnp=buff[maxnn];
02008
02009
02010 for (i=1;i<nproc;i++){
02011 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
02012
02013 k=domproc[stat.MPI_TAG];
02014 for (j=0;j<nnsd[k];j++){
02015 allnodes[k][j]=buff[j];
02016 }
02017 if (tnnp<buff[maxnn])
02018 tnnp=buff[maxnn];
02019 }
02020 }
02021
02022
02023
02024
02025 else{
02026 MPI_Send (buff,buffsize,MPI_LONG,0,myrank,MPI_COMM_WORLD);
02027 }
02028
02029 if (myrank==0){
02030
02031
02032
02033
02034 tnnp++;
02035
02036 if (amultip != NULL)
02037 delete [] amultip;
02038 amultip = new long [tnnp];
02039 for (i=0;i<tnnp;i++){
02040 amultip[i]=0;
02041 }
02042
02043
02044 for (i=0;i<nproc;i++){
02045 for (j=0;j<nnsd[i];j++){
02046 amultip[allnodes[i][j]]++;
02047 }
02048 }
02049 }
02050 delete [] buff;
02051 break;
02052 }
02053 default:{
02054 par_print_err(myrank,proc_name,"unknown type of mesh description",__FILE__, __LINE__, __func__);
02055 }
02056 }
02057 MPI_Barrier (MPI_COMM_WORLD);
02058
02059
02060
02061
02062
02063 if (myrank==0){
02064 if (allnodes!=NULL){
02065 fprintf (out,"\n\n array allnodes \n");
02066 for (i=0;i<nproc;i++){
02067 fprintf (out,"\n");
02068 for (j=0;j<nnsd[i];j++){
02069 fprintf (out,"\n nproc %3ld node %6ld allnode %6ld",i,j,allnodes[i][j]);
02070 }
02071 }
02072 }
02073 if (amultip!=NULL){
02074 fprintf(out,"\n\n\n tnnp - total number of nodes in whole problem is %ld\n\n",tnnp);
02075 for (i=0;i<tnnp;i++){
02076 fprintf (out,"\n node %6ld amultip %3ld",i,amultip[i]);
02077 }
02078 }
02079 if (bmultip!=NULL){
02080 for (i=0;i<tnbn;i++){
02081 fprintf (out,"\n boundary/interface node %6ld bmultip %3ld",i,bmultip[i]);
02082 }
02083 }
02084
02085 if (bnodes!=NULL){
02086 fprintf(out,"\n\n\n array bnodes \n\n");
02087 for (i=0;i<nproc;i++){
02088 fprintf (out,"\n domain %ld\n",i);
02089 for (j=0;j<nnsd[i];j++){
02090 fprintf (out,"\n bnodes %6ld %6ld",j,bnodes[i][j]);
02091 }
02092 }
02093 }
02094
02095 fprintf(out,"\n\n\n total number of boundary/interface nodes in whole problem (tnbn) is %ld\n\n",tnbn);
02096 fprintf (out,"\n\n\n maximum number of boundary/interface nodes on subdomain (maxnbn) is %ld\n\n",maxnbn);
02097 }
02098
02099 }
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119 void partop::coupled_dofs (gtopology *top,long *domproc,FILE *out)
02120 {
02121 long i,j,k,l,ndofn;
02122 long *buff,buffsize;
02123 MPI_Status stat;
02124
02125
02126
02127 ncdof=0;
02128
02129
02130 for (i=0;i<nn;i++){
02131
02132 ndofn=top->give_ndofn (i);
02133
02134 for (j=0;j<ndofn;j++){
02135 k=top->give_dof (i,j);
02136 if (k>1){
02137 if (ncdof<k)
02138 ncdof=k;
02139 }
02140 }
02141 }
02142
02143
02144
02145
02146
02147 if (myrank==0){
02148
02149 for (i=1;i<nproc;i++){
02150 MPI_Recv (&k,1,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
02151
02152 if (ncdof<k) ncdof=k;
02153
02154 }
02155
02156
02157 for (i=1;i<nproc;i++){
02158 MPI_Send (&ncdof,1,MPI_LONG,i,myrank,MPI_COMM_WORLD);
02159 }
02160
02161 }
02162
02163
02164
02165 else{
02166 MPI_Send (&ncdof,1,MPI_LONG,0,myrank,MPI_COMM_WORLD);
02167 MPI_Recv (&ncdof,1,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
02168 }
02169 MPI_Barrier (MPI_COMM_WORLD);
02170
02171 buffsize=ncdof;
02172 buff=new long [buffsize];
02173 for (i=0;i<buffsize;i++){
02174 buff[i]=0;
02175 }
02176
02177
02178 for (i=0;i<nn;i++){
02179
02180 ndofn=top->give_ndofn (i);
02181
02182 for (j=0;j<ndofn;j++){
02183 k=top->give_dof (i,j);
02184 if (k>1){
02185 buff[k-1]=k;
02186 }
02187 }
02188 }
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199 if (myrank==0){
02200
02201
02202
02203
02204 if (coupdof!=NULL){
02205 for (i=0;i<nproc;i++){
02206 delete [] coupdof[i];
02207 }
02208 delete [] coupdof;
02209 }
02210 coupdof = new long* [nproc];
02211 for (i=0;i<nproc;i++){
02212 coupdof[i] = new long [ncdof];
02213 for (j=0;j<ncdof;j++){
02214 coupdof[i][j]=0;
02215 }
02216 }
02217
02218
02219 k=domproc[0];
02220 for (j=0;j<ncdof;j++){
02221 l=buff[j];
02222 if (l>1)
02223 coupdof[k][l-1]++;
02224 }
02225
02226
02227 for (i=1;i<nproc;i++){
02228 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
02229
02230 k=domproc[stat.MPI_TAG];
02231 for (j=0;j<ncdof;j++){
02232 l=buff[j];
02233 if (l>1)
02234 coupdof[k][l-1]++;
02235 }
02236 }
02237
02238
02239 if (coupdofmas!=NULL){
02240 delete [] coupdofmas;
02241 }
02242 coupdofmas = new long [ncdof];
02243 for (i=0;i<ncdof;i++){
02244 coupdofmas[i]=0;
02245 }
02246
02247
02248 for (i=0;i<ncdof;i++){
02249 k=0;
02250
02251 for (j=0;j<nproc;j++){
02252 if (coupdof[j][i]>0)
02253 k++;
02254 }
02255 if (k>1){
02256
02257
02258 coupdofmas[i]=1;
02259 }
02260 }
02261
02262
02263 nbcdof=0;
02264 for (i=0;i<ncdof;i++){
02265 if (coupdofmas[i]==1)
02266 nbcdof++;
02267 }
02268
02269 }
02270
02271
02272
02273 else{
02274 MPI_Send (buff,buffsize,MPI_LONG,0,myrank,MPI_COMM_WORLD);
02275 }
02276 MPI_Barrier (MPI_COMM_WORLD);
02277
02278
02279
02280
02281
02282 if (myrank==0){
02283
02284 for (i=1;i<nproc;i++){
02285 MPI_Send (&nbcdof,1,MPI_LONG,i,myrank,MPI_COMM_WORLD);
02286 }
02287 }
02288
02289
02290
02291 else
02292 {
02293 MPI_Recv (&nbcdof,1,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
02294 }
02295 MPI_Barrier (MPI_COMM_WORLD);
02296
02297
02298
02299
02300 if (myrank==0){
02301 fprintf (out,"\n\n\n partop::coupled_dofs");
02302 fprintf (out,"\n\n ncdof - the number of coupled DOFs %ld",ncdof);
02303 fprintf (out,"\n nbcdof - the number of boundary/interface coupled DOFs %ld",nbcdof);
02304 fprintf (out,"\n\n array coupdof");
02305 for (i=0;i<nproc;i++){
02306 for (j=0;j<ncdof;j++){
02307 fprintf (out,"\n coupdof %3ld %3ld %ld",i,j,coupdof[i][j]);
02308 }
02309 }
02310 fprintf (out,"\n\n");
02311 for (i=0;i<ncdof;i++){
02312 fprintf (out,"\n coupdofmas %6ld %ld",i,coupdofmas[i]);
02313 }
02314 }
02315 delete [] buff;
02316 }
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340 void partop::numbers_of_all_dofs_on_subdomains (gtopology *top,long *domproc,FILE *out)
02341 {
02342 long i,j,k;
02343 MPI_Status stat;
02344
02345
02346 maxndof=0;
02347 for (i=0;i<nn;i++){
02348 maxndof+=top->give_ndofn (i);
02349 }
02350
02351
02352
02353
02354 if (myrank==0){
02355
02356 if (nalldof!=NULL)
02357 delete [] nalldof;
02358 nalldof = new long [nproc];
02359
02360
02361 j=domproc[0];
02362 nalldof[j]=maxndof;
02363
02364 for (i=1;i<nproc;i++){
02365 MPI_Recv (&k,1,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
02366
02367
02368 j=domproc[stat.MPI_TAG];
02369 if (maxndof<k) maxndof=k;
02370 nalldof[j]=k;
02371 }
02372
02373 for (i=1;i<nproc;i++){
02374 MPI_Send (&maxndof,1,MPI_LONG,i,myrank,MPI_COMM_WORLD);
02375 }
02376 }
02377
02378
02379
02380 else{
02381 MPI_Send (&maxndof,1,MPI_LONG,0,myrank,MPI_COMM_WORLD);
02382 MPI_Recv (&maxndof,1,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
02383 }
02384 MPI_Barrier (MPI_COMM_WORLD);
02385
02386
02387 if (myrank==0){
02388 fprintf (out,"\n\n\n the maximum number of DOFs on subdomain (maxndof) %ld\n",maxndof);
02389 fprintf (out,"\n\n\n the numbers of all DOFs on each subdomain (alldof)\n\n");
02390 for (i=0;i<nproc;i++){
02391 fprintf (out,"\n %ld",nalldof[i]);
02392 }
02393 }
02394
02395 }
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408 void partop::ndofn_master (gtopology *top,long *domproc,FILE *out,char *proc_name)
02409 {
02410 long i,j,k,l,ndofn;
02411 long *buff,buffsize;
02412 MPI_Status stat;
02413
02414
02415
02416
02417
02418
02419
02420
02421 if (maxnn==0){
02422 par_print_err(myrank,proc_name,"maximum number of nodes on one subdomain is equal to zero",__FILE__, __LINE__, __func__);
02423 par_print_err(myrank,proc_name,"function numbers_of_all_nodes_on_subdomains has to be called first",__FILE__, __LINE__, __func__);
02424 abort ();
02425 }
02426
02427 buffsize=maxnn;
02428 buff = new long [buffsize];
02429
02430
02431 for (i=0;i<nn;i++){
02432
02433 buff[i] = top->give_ndofn (i);
02434 }
02435
02436
02437
02438
02439 if (myrank==0){
02440
02441 if (tnnp==0){
02442 par_print_err(myrank,proc_name,"total number of nodes in the problem (tnnp) is zero",__FILE__, __LINE__, __func__);
02443 par_print_err(myrank,proc_name,"function partop::assemble_multip has to be called first",__FILE__, __LINE__, __func__);
02444 }
02445 if (nnsd==NULL){
02446 par_print_err(myrank,proc_name,"array nnsd (number of nodes on subdomains) is not assembled",__FILE__, __LINE__, __func__);
02447 par_print_err(myrank,proc_name,"function partop::numbers_of_all_nodes_on_subdomains has to be called first",__FILE__, __LINE__, __func__);
02448 }
02449 if (allnodes==NULL){
02450 par_print_err(myrank,proc_name,"array allnodes is not assembled",__FILE__, __LINE__, __func__);
02451 par_print_err(myrank,proc_name,"function partop::assemble_multip has to be called first",__FILE__, __LINE__, __func__);
02452 }
02453
02454
02455 if (ndofnmas!=NULL){
02456 delete [] ndofnmas;
02457 }
02458 ndofnmas = new long [tnnp];
02459 memset(ndofnmas, 0, sizeof(*ndofnmas)*tnnp);
02460
02461
02462
02463
02464 k=domproc[0];
02465
02466 for (j=0;j<nnsd[k];j++){
02467
02468 l=allnodes[k][j];
02469
02470 ndofnmas[l]=buff[j];
02471 }
02472
02473 for (i=1;i<nproc;i++){
02474 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
02475
02476
02477
02478
02479 k=domproc[stat.MPI_TAG];
02480
02481 for (j=0;j<nnsd[k];j++){
02482
02483 l=allnodes[k][j];
02484
02485 ndofnmas[l]=buff[j];
02486 }
02487
02488 }
02489
02490 }
02491
02492
02493
02494 else{
02495 MPI_Send (buff,buffsize,MPI_LONG,0,myrank,MPI_COMM_WORLD);
02496 }
02497 MPI_Barrier (MPI_COMM_WORLD);
02498
02499
02500
02501
02502 if (myrank==0){
02503 fprintf(out,"\n\n\n the numbers of DOFs on nodes (ndofnmas)\n\n");
02504 for (i=0;i<tnnp;i++){
02505 fprintf (out,"\n node %6ld ndofnmas %3ld",i,ndofnmas[i]);
02506 }
02507 }
02508
02509 delete [] buff;
02510 }
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526 void partop::dofind_master (gtopology *top,long *domproc,FILE *out,char *proc_name)
02527 {
02528 long i,j,k,l,m,ii,ndofn;
02529 long *buff,buffsize;
02530 MPI_Status stat;
02531
02532
02533
02534
02535
02536
02537
02538
02539 if (maxndof==0){
02540 par_print_err(myrank,proc_name,"maximum number of DOFs is zero",__FILE__, __LINE__, __func__);
02541 par_print_err(myrank,proc_name,"function partop::numbers_of_all_dofs_on_subdomains has to be called first",__FILE__, __LINE__, __func__);
02542 }
02543
02544 buffsize=maxndof;
02545 buff = new long [buffsize];
02546
02547
02548 k=0;
02549
02550 for (i=0;i<nn;i++){
02551
02552 ndofn = top->give_ndofn (i);
02553
02554 for (j=0;j<ndofn;j++){
02555 buff[k]=top->give_dof (i,j);
02556 k++;
02557 }
02558 }
02559
02560
02561
02562
02563 if (myrank==0){
02564
02565
02566 if (dofindmas!=NULL){
02567 for (i=0;i<tnnp;i++){
02568 delete [] dofindmas[i];
02569 }
02570 delete [] dofindmas;
02571 }
02572 dofindmas = new long* [tnnp];
02573 for (i=0;i<tnnp;i++){
02574 dofindmas[i] = new long [ndofnmas[i]];
02575 }
02576
02577
02578
02579
02580 ii=0;
02581
02582 k=domproc[0];
02583
02584 for (j=0;j<nnsd[k];j++){
02585
02586 l=allnodes[k][j];
02587
02588 for (m=0;m<ndofnmas[l];m++){
02589 dofindmas[l][m]=buff[ii];
02590 ii++;
02591 }
02592 }
02593
02594
02595
02596 for (i=1;i<nproc;i++){
02597 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
02598
02599
02600
02601 ii=0;
02602
02603 k=domproc[stat.MPI_TAG];
02604
02605 for (j=0;j<nnsd[k];j++){
02606
02607 l=allnodes[k][j];
02608
02609 for (m=0;m<ndofnmas[l];m++){
02610 dofindmas[l][m]=buff[ii];
02611 ii++;
02612 }
02613 }
02614
02615 }
02616
02617 }
02618
02619
02620
02621 else{
02622 MPI_Send (buff,buffsize,MPI_LONG,0,myrank,MPI_COMM_WORLD);
02623 }
02624 MPI_Barrier (MPI_COMM_WORLD);
02625
02626
02627
02628
02629 if (myrank==0){
02630 fprintf(out,"\n\n\n DOF id (dofindmas)\n\n");
02631 for (i=0;i<tnnp;i++){
02632 fprintf (out,"\n node %6ld ",i);
02633 for (j=0;j<ndofnmas[i];j++){
02634 fprintf (out," dofindmas %3ld",dofindmas[i][j]);
02635 }
02636 }
02637 fprintf (out,"\n\n");
02638 }
02639 delete [] buff;
02640 }
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661 void partop::update_multip (gtopology *top,FILE *out,char *proc_name)
02662 {
02663 long i,j,k,l,ndofn,dofid;
02664
02665
02666
02667
02668
02669
02670
02671
02672 if (myrank==0){
02673
02674
02675 if (dofind!=NULL){
02676 for (i=0;i<tnnp;i++){
02677 delete [] dofind[i];
02678 }
02679 delete [] dofind;
02680 }
02681 dofind = new long* [tnnp];
02682 for (i=0;i<tnnp;i++){
02683 dofind[i] = new long [ndofnmas[i]];
02684 for (j=0;j<ndofnmas[i];j++){
02685 dofind[i][j]=0;
02686 }
02687 }
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707 for (i=0;i<nproc;i++){
02708
02709 for (j=0;j<nnsd[i];j++){
02710
02711 l=allnodes[i][j];
02712
02713 ndofn = ndofnmas[l];
02714
02715 for (k=0;k<ndofn;k++){
02716
02717 dofid=dofindmas[l][k];
02718 if (amultip[l]>1){
02719
02720 dofind[l][k]=1;
02721 if (dofid>1){
02722
02723
02724
02725 if (coupdofmas[dofid-1]==0)
02726 coupdofmas[dofid-1]=1;
02727 }
02728 }
02729 if (dofid>1){
02730
02731
02732 if (coupdofmas[dofid-1]==1){
02733
02734
02735 dofind[l][k]=1;
02736 }
02737
02738 }
02739 }
02740 }
02741 }
02742
02743 fprintf (out,"\n\n\n");
02744 for (i=0;i<tnnp;i++){
02745 fprintf (out,"\n dofind %6ld ",i);
02746 for (j=0;j<ndofnmas[i];j++){
02747 fprintf (out," %3ld",dofind[i][j]);
02748 }
02749 }
02750
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761 tnbn=0;
02762
02763 for (i=0;i<nproc;i++){
02764
02765 for (j=0;j<nnsd[i];j++){
02766
02767 l=allnodes[i][j];
02768
02769 ndofn = ndofnmas[l];
02770
02771 for (k=0;k<ndofn;k++){
02772 if (dofind[l][k]==1){
02773
02774 if (amultip[l]==1){
02775
02776
02777 amultip[l]=2;
02778 }
02779 }
02780 }
02781 }
02782 }
02783
02784
02785
02786
02787 }
02788
02789
02790
02791
02792 if (myrank==0){
02793 if (amultip!=NULL){
02794 fprintf(out,"\n\n\n modified array amultip with respect to the coupled DOFs\n");
02795 for (i=0;i<tnnp;i++){
02796 fprintf (out,"\n node %6ld amultip %3ld",i,amultip[i]);
02797 }
02798 }
02799 fprintf(out,"\n\n\n DOF id (dofind)\n\n");
02800 for (i=0;i<tnnp;i++){
02801 fprintf (out,"\n node %6ld ",i);
02802 for (j=0;j<ndofnmas[i];j++){
02803 fprintf (out," dofind %3ld",dofind[i][j]);
02804 }
02805 }
02806 fprintf (out,"\n\n");
02807 }
02808
02809 }
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838 void partop::assemble_nbnd_nind (long *ltg,long *domproc,FILE *out,char *proc_name)
02839 {
02840 long i,j,k;
02841 long *buff,buffsize;
02842 MPI_Status stat;
02843
02844 switch (md){
02845 case bound_nodes:{
02846
02847 if (maxnn==0){
02848 par_print_err(myrank,proc_name,"maximum number of nodes on one subdomain is equal to zero",__FILE__, __LINE__, __func__);
02849 par_print_err(myrank,proc_name,"function numbers_of_all_nodes_on_subdomains has to be called first",__FILE__, __LINE__, __func__);
02850 }
02851
02852
02853 nbn=0;
02854 for (i=0;i<nn;i++){
02855 if (ltg[i]>-1)
02856 nbn++;
02857 }
02858
02859 if (myrank==0){
02860
02861 if (nbnd != NULL)
02862 delete [] nbnd;
02863 nbnd = new long [nproc];
02864
02865 maxnbn=0;
02866
02867
02868 j=domproc[0];
02869 nbnd[j]=nbn;
02870 if (maxnbn<nbn)
02871 maxnbn=nbn;
02872
02873 for (i=1;i<nproc;i++){
02874 MPI_Recv (&k,1,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
02875
02876
02877 j=domproc[stat.MPI_TAG];
02878 nbnd[j]=k;
02879 if (maxnbn<k)
02880 maxnbn=nbnd[j];
02881
02882 }
02883 }
02884 else{
02885 MPI_Send (&nbn,1,MPI_LONG,0,myrank,MPI_COMM_WORLD);
02886 }
02887 MPI_Barrier (MPI_COMM_WORLD);
02888
02889 if (myrank==0){
02890 for (i=1;i<nproc;i++){
02891 MPI_Send (&maxnbn,1,MPI_LONG,i,myrank,MPI_COMM_WORLD);
02892 }
02893 }
02894 else
02895 MPI_Recv (&maxnbn,1,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
02896
02897 MPI_Barrier (MPI_COMM_WORLD);
02898
02899 break;
02900 }
02901
02902
02903
02904
02905 case all_nodes:
02906 case neg_bound_nodes:{
02907
02908 buffsize=2;
02909 buff = new long [buffsize];
02910
02911
02912
02913
02914 if (myrank==0){
02915
02916 if (nnsd==NULL){
02917 par_print_err(myrank,proc_name,"array nnsd is not assembled",__FILE__, __LINE__, __func__);
02918 par_print_err(myrank,proc_name,"function partop::numbers_of_all_nodes_on_subdomains has to be called first",__FILE__, __LINE__, __func__);
02919 }
02920 if (amultip==NULL){
02921 par_print_err(myrank,proc_name,"array amultip is not assembled",__FILE__, __LINE__, __func__);
02922 par_print_err(myrank,proc_name,"function partop::assemble_multip has to be called first",__FILE__, __LINE__, __func__);
02923 }
02924 if (allnodes==NULL){
02925 par_print_err(myrank,proc_name,"array allnodes is not assembled",__FILE__, __LINE__, __func__);
02926 par_print_err(myrank,proc_name,"function partop::assemble_multip has to be called first",__FILE__, __LINE__, __func__);
02927 }
02928
02929
02930 if (nbnd != NULL)
02931 delete [] nbnd;
02932 nbnd = new long [nproc];
02933
02934
02935 maxnbn=0;
02936 for (i=0;i<nproc;i++){
02937 k=0;
02938 for (j=0;j<nnsd[i];j++){
02939 if (amultip[allnodes[i][j]]>1) k++;
02940 }
02941 nbnd[i]=k;
02942 if (maxnbn<nbnd[i])
02943 maxnbn=nbnd[i];
02944 }
02945
02946
02947
02948
02949 tnbn=0;
02950 for (i=0;i<tnnp;i++){
02951 if (amultip[i]!=1) tnbn++;
02952 }
02953
02954
02955 for (i=1;i<nproc;i++){
02956 k=domproc[i];
02957 buff[0]=nbnd[k];
02958 buff[1]=maxnbn;
02959 MPI_Send (buff,buffsize,MPI_LONG,i,myrank,MPI_COMM_WORLD);
02960 }
02961
02962 k=domproc[0];
02963 nbn=nbnd[k];
02964 }
02965 else{
02966 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
02967
02968 nbn = buff[0];
02969 maxnbn = buff[1];
02970 }
02971 MPI_Barrier (MPI_COMM_WORLD);
02972
02973 delete [] buff;
02974
02975 break;
02976 }
02977 default:{
02978 par_print_err(myrank,proc_name,"unknown type of mesh description is required",__FILE__, __LINE__, __func__);
02979 }
02980 }
02981 MPI_Barrier (MPI_COMM_WORLD);
02982
02983
02984 nin = nn - nbn;
02985
02986 if (nind != NULL)
02987 delete [] nind;
02988 nind = new long [nproc];
02989 tnin = 0;
02990 buff = new long[nproc+1];
02991 if (myrank==0){
02992
02993 for (i=0;i<nproc;i++){
02994 nind[i]=nnsd[i]-nbnd[i];
02995 tnin += nind[i];
02996 buff[i] = nind[i];
02997 }
02998 buff[nproc] = tnin;
02999 for (i=1;i<nproc;i++){
03000 MPI_Send(buff,nproc+1,MPI_LONG,i,myrank,MPI_COMM_WORLD);
03001 }
03002 }
03003 else{
03004 MPI_Recv(buff,nproc+1,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
03005 for (i=0;i<nproc;i++)
03006 nind[i] = buff[i];
03007 tnin = buff[nproc];
03008 }
03009 MPI_Barrier (MPI_COMM_WORLD);
03010
03011 delete [] buff;
03012
03013
03014
03015
03016 fprintf (out,"\n\n\n the number of boundary/interface nodes on subdomain (nbn) %ld\n",nbn);
03017 fprintf (out,"\n the number of internal nodes on subdomain (nin) %ld\n",nin);
03018 fprintf (out,"\n the number of all nodes on subdomain (nn) %ld\n",nn);
03019 fprintf (out,"\n the maximum number of all nodes on subdomain (maxnn) %ld\n",maxnn);
03020 fprintf (out,"\n the maximum number of boundary/interface nodes on subdomain (maxnbn) %ld\n",maxnbn);
03021 if (myrank==0){
03022 fprintf (out,"\n\n\n the numbers of boundary/interface nodes on each subdomain (nbnd)\n\n");
03023 for (i=0;i<nproc;i++){
03024 fprintf (out,"\n %ld",nbnd[i]);
03025 }
03026 fprintf (out,"\n\n\n the numbers of internal nodes on each subdomain (nind)\n\n");
03027 for (i=0;i<nproc;i++){
03028 fprintf (out,"\n %ld",nind[i]);
03029 }
03030 }
03031
03032 }
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050 void partop::assemble_nodmultip (long *ltg,long *domproc,FILE *out,char *proc_name)
03051 {
03052 long i,j,k,buffsize;
03053 long *buff;
03054 MPI_Status stat;
03055
03056 switch (md){
03057 case bound_nodes:{
03058
03059
03060
03061 buffsize=tnbn;
03062 buff = new long [buffsize];
03063
03064 if (myrank==0){
03065 for (i=0;i<tnbn;i++){
03066 buff[i]=bmultip[i];
03067 }
03068
03069 for (i=1;i<nproc;i++){
03070 MPI_Send (buff,buffsize,MPI_LONG,i,myrank,MPI_COMM_WORLD);
03071 }
03072 }
03073 else{
03074 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
03075 }
03076 MPI_Barrier (MPI_COMM_WORLD);
03077
03078 if (nodmultip!=NULL)
03079 delete [] nodmultip;
03080 nodmultip = new long [nn];
03081
03082 for (i=0;i<nn;i++){
03083 if (ltg[i]>-1){
03084 nodmultip[i]=buff[ltg[i]];
03085 }
03086 else{
03087 nodmultip[i]=1;
03088 }
03089 }
03090
03091 delete [] buff;
03092
03093 break;
03094 }
03095
03096
03097
03098 case all_nodes:
03099 case neg_bound_nodes:{
03100
03101 if (maxnn==0){
03102 par_print_err(myrank,proc_name,"maximum number of nodes on one subdomain is equal to zero",__FILE__, __LINE__, __func__);
03103 par_print_err(myrank,proc_name,"function numbers_of_all_nodes_on_subdomains has to be called first",__FILE__, __LINE__, __func__);
03104 abort ();
03105 }
03106 if (myrank==0){
03107 if (nnsd==NULL){
03108 par_print_err(myrank,proc_name,"array nnsd is not assembled",__FILE__, __LINE__, __func__);
03109 par_print_err(myrank,proc_name,"function partop::numbers_of_all_nodes_on_subdomains has to be called first",__FILE__, __LINE__, __func__);
03110 }
03111 if (amultip==NULL){
03112 par_print_err(myrank,proc_name,"array amultip is not assembled",__FILE__, __LINE__, __func__);
03113 par_print_err(myrank,proc_name,"function partop::assemble_multip has to be called first",__FILE__, __LINE__, __func__);
03114 }
03115 if (allnodes==NULL){
03116 par_print_err(myrank,proc_name,"array allnodes is not assembled",__FILE__, __LINE__, __func__);
03117 par_print_err(myrank,proc_name,"function partop::assemble_multip has to be called first",__FILE__, __LINE__, __func__);
03118 }
03119 }
03120
03121 buffsize=maxnn;
03122 buff = new long [buffsize];
03123
03124 if (myrank==0){
03125 for (i=1;i<nproc;i++){
03126 k=domproc[i];
03127 for (j=0;j<nnsd[k];j++){
03128 buff[j]=amultip[allnodes[k][j]];
03129 }
03130 MPI_Send (buff,buffsize,MPI_LONG,i,myrank,MPI_COMM_WORLD);
03131 }
03132
03133 k=domproc[0];
03134 for (j=0;j<nnsd[k];j++){
03135 buff[j]=amultip[allnodes[k][j]];
03136 }
03137 }
03138 else{
03139 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
03140 }
03141
03142
03143 if (nodmultip != NULL)
03144 delete [] nodmultip;
03145 nodmultip = new long [nn];
03146 for (i=0;i<nn;i++){
03147 nodmultip[i] = buff[i];
03148 }
03149
03150 delete [] buff;
03151
03152 break;
03153 }
03154 default:{
03155 par_print_err(myrank,proc_name,"unknown type of mesh description is required",__FILE__, __LINE__, __func__);
03156 }
03157 }
03158 MPI_Barrier (MPI_COMM_WORLD);
03159
03160
03161
03162
03163
03164 fprintf(out,"\n\n\n Multiplicity of nodes on subdomain (nodmultip)\n\n");
03165 for (i=0;i<nn;i++){
03166 fprintf(out,"%ld %ld\n",i,nodmultip[i]);
03167 }
03168
03169
03170 }
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188 void partop::node_global_numbers (long *domproc,FILE *out,char *proc_name)
03189 {
03190 long i,j,k,ii,jj,kk;
03191 long *buff,buffsize;
03192 MPI_Status stat;
03193
03194 if (myrank==0){
03195
03196 if (gnin != NULL){
03197 for (i=0;i<nproc;i++){
03198 delete [] gnin[i];
03199 }
03200 delete [] gnin;
03201 }
03202 gnin = new long* [nproc];
03203 for (i=0;i<nproc;i++){
03204 gnin[i] = new long [nind[i]];
03205 memset(gnin[i], 0, sizeof(*gnin[i])*nind[i]);
03206 }
03207
03208 if (gnbn != NULL){
03209 for (i=0;i<nproc;i++){
03210 delete [] gnbn[i];
03211 }
03212 delete [] gnbn;
03213 }
03214 gnbn = new long* [nproc];
03215 for (i=0;i<nproc;i++){
03216 gnbn[i] = new long [nbnd[i]];
03217 memset(gnbn[i], 0, sizeof(*gnbn[i])*nbnd[i]);
03218 }
03219 }
03220
03221
03222 if (gnbndom != NULL){
03223 delete [] gnbndom;
03224 }
03225 gnbndom = new long [nbn];
03226 memset(gnbndom, 0, sizeof(*gnbndom)*nbn);
03227
03228 switch (md){
03229 case bound_nodes:{
03230 par_print_err(myrank,proc_name,"mesh description bound_nodes cannot be used",__FILE__, __LINE__, __func__);
03231 break;
03232 }
03233 case metis:
03234 case all_nodes:{
03235
03236 if (myrank==0){
03237
03238 if (nnsd==NULL){
03239 par_print_err(myrank,proc_name,"array nnsd is not assembled",__FILE__, __LINE__, __func__);
03240 par_print_err(myrank,proc_name,"function partop::numbers_of_all_nodes_on_subdomains has to be called first",__FILE__, __LINE__, __func__);
03241 }
03242 if (amultip==NULL){
03243 par_print_err(myrank,proc_name,"array amultip is not assembled",__FILE__, __LINE__, __func__);
03244 par_print_err(myrank,proc_name,"function partop::assemble_multip has to be called first",__FILE__, __LINE__, __func__);
03245 }
03246 if (allnodes==NULL){
03247 par_print_err(myrank,proc_name,"array allnodes is not assembled",__FILE__, __LINE__, __func__);
03248 par_print_err(myrank,proc_name,"function partop::assemble_multip has to be called first",__FILE__, __LINE__, __func__);
03249 }
03250
03251
03252 for (i=0;i<nproc;i++){
03253
03254 ii=0;
03255
03256 jj=0;
03257
03258 for (j=0;j<nnsd[i];j++){
03259 if (amultip[allnodes[i][j]]>1){
03260
03261
03262
03263 gnbn[i][ii]=allnodes[i][j];
03264 ii++;
03265 }
03266 if (amultip[allnodes[i][j]]==1){
03267
03268
03269
03270 gnin[i][jj]=allnodes[i][j];
03271 jj++;
03272 }
03273
03274 }
03275
03276 }
03277
03278 }
03279 break;
03280 }
03281 case neg_bound_nodes:{
03282
03283 if (myrank==0){
03284
03285 if (nnsd==NULL){
03286 par_print_err(myrank,proc_name,"array nnsd is not assembled",__FILE__, __LINE__, __func__);
03287 par_print_err(myrank,proc_name,"function partop::numbers_of_all_nodes_on_subdomains has to be called first",__FILE__, __LINE__, __func__);
03288 }
03289 if (allnodes==NULL){
03290 par_print_err(myrank,proc_name,"array allnodes is not assembled",__FILE__, __LINE__, __func__);
03291 par_print_err(myrank,proc_name,"function partop::assemble_multip has to be called first",__FILE__, __LINE__, __func__);
03292 }
03293
03294
03295 for (i=0;i<nproc;i++){
03296
03297 ii=0;
03298
03299 jj=0;
03300
03301 for (j=0;j<nnsd[i];j++){
03302 if (allnodes[i][j]<0){
03303
03304 gnbn[i][ii]=0-allnodes[i][j]-2;
03305 ii++;
03306 }
03307 if (allnodes[i][j]>-1){
03308
03309 gnin[i][jj]=allnodes[i][j];
03310 jj++;
03311 }
03312 }
03313 }
03314 }
03315
03316 break;
03317 }
03318 default:{
03319 par_print_err(myrank,proc_name,"unknown type of mesh description is required",__FILE__, __LINE__, __func__);
03320 }
03321 }
03322
03323 buffsize=maxnbn;
03324 buff = new long [buffsize];
03325
03326 if (myrank==0){
03327
03328
03329 for (i=1;i<nproc;i++){
03330
03331 k=domproc[i];
03332
03333 for (j=0;j<nbnd[k];j++){
03334 buff[j]=gnbn[k][j];
03335 }
03336 MPI_Send (buff,buffsize,MPI_LONG,i,myrank,MPI_COMM_WORLD);
03337 }
03338
03339
03340 k=domproc[0];
03341
03342 for (j=0;j<nbnd[k];j++){
03343 buff[j]=gnbn[k][j];
03344 }
03345
03346 }
03347 else{
03348 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
03349 }
03350 MPI_Barrier (MPI_COMM_WORLD);
03351
03352 for (i=0;i<nbn;i++){
03353 gnbndom[i]=buff[i];
03354 }
03355
03356 delete [] buff;
03357
03358
03359
03360
03361
03362 fprintf (out,"\n\n\n global numbers of interface/boundary nodes on subdomain (gnbndom)");
03363 for (i=0;i<nbn;i++){
03364 fprintf (out,"\n %6ld %6ld",i,gnbndom[i]);
03365 }
03366 if (myrank==0){
03367 fprintf (out,"\n\n\n global numbers of interface/boundary nodes on subdomain (gnbn)");
03368 for (i=0;i<nproc;i++){
03369 fprintf (out,"\n\n domain %ld",i);
03370 for (j=0;j<nbnd[i];j++){
03371 fprintf (out,"\n %6ld %6ld",j,gnbn[i][j]);
03372 }
03373 }
03374
03375 fprintf (out,"\n\n\n global numbers of internal nodes on subdomain (gnin)");
03376 for (i=0;i<nproc;i++){
03377 fprintf (out,"\n\n domain %ld",i);
03378 for (j=0;j<nind[i];j++){
03379 fprintf (out,"\n %6ld %6ld",j,gnin[i][j]);
03380 }
03381 }
03382 }
03383
03384 }
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398 void partop::node_local_numbers (FILE *out)
03399 {
03400 long i,j,k,ii,jj,kk;
03401 long *buff,buffsize;
03402 MPI_Status stat;
03403
03404
03405 if (lnindom != NULL){
03406 delete [] lnindom;
03407 }
03408 lnindom = new long [nin];
03409
03410 if (lnbndom != NULL){
03411 delete [] lnbndom;
03412 }
03413 lnbndom = new long [nbn];
03414
03415 j=0;
03416 for (i=0;i<nn;i++){
03417 if (nodmultip[i]>1){
03418 lnbndom[j]=i;
03419 j++;
03420 }
03421 }
03422 j=0;
03423 for (i=0;i<nn;i++){
03424 if (nodmultip[i]==1){
03425 lnindom[j]=i;
03426 j++;
03427 }
03428 }
03429
03430
03431
03432
03433
03434 fprintf (out,"\n\n\n local numbers of interface/boundary nodes on subdomain (lnbndom)");
03435 for (i=0;i<nbn;i++){
03436 fprintf (out,"\n %6ld %6ld",i,lnbndom[i]);
03437 }
03438 fprintf (out,"\n\n\n local numbers of internal nodes on subdomain (lnindom)");
03439 for (i=0;i<nin;i++){
03440 fprintf (out,"\n %6ld %6ld",i,lnindom[i]);
03441 }
03442
03443 }
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461 void partop::node_coarse_numbers (long *domproc,FILE *out,char *proc_name)
03462 {
03463 long i,j,k,l,ii,jj,ln,cn,buffsize;
03464 long *av,*buff;
03465 av=NULL;
03466 MPI_Status stat;
03467
03468 if (myrank==0){
03469
03470
03471
03472 if (icnbnmas != NULL){
03473 for (i=0;i<nproc;i++){
03474 delete [] icnbnmas[i];
03475 }
03476 delete [] icnbnmas;
03477 }
03478 icnbnmas = new long* [nproc];
03479 for (i=0;i<nproc;i++){
03480 icnbnmas[i] = new long [nbnd[i]];
03481 memset(icnbnmas[i], 0, sizeof(*icnbnmas[i])*nbnd[i]);
03482 }
03483
03484
03485 switch (md){
03486 case bound_nodes:{
03487
03488 if (nnsd==NULL){
03489 par_print_err(myrank,proc_name,"array nnsd is not assembled",__FILE__, __LINE__, __func__);
03490 par_print_err(myrank,proc_name,"function partop::numbers_of_all_nodes_on_subdomains has to be called first",__FILE__, __LINE__, __func__);
03491 }
03492 if (bnodes==NULL){
03493 par_print_err(myrank,proc_name,"array bnodes is not assembled",__FILE__, __LINE__, __func__);
03494 par_print_err(myrank,proc_name,"function partop::assemble_multip has to be called first",__FILE__, __LINE__, __func__);
03495 }
03496
03497
03498 for (i=0;i<nproc;i++){
03499
03500 l=0;
03501
03502 for (j=0;j<nnsd[i];j++){
03503 k=bnodes[i][j];
03504 if (k>-1){
03505 icnbnmas[i][l]=k;
03506 l++;
03507 }
03508 }
03509 }
03510
03511 break;
03512 }
03513 case metis:
03514 case all_nodes:
03515 case neg_bound_nodes:{
03516
03517 if (tnnp==0){
03518 par_print_err(myrank,proc_name,"total number of nodes in the problem (tnnp) is zero",__FILE__, __LINE__, __func__);
03519 par_print_err(myrank,proc_name,"function partop::assemble_multip has to be called first",__FILE__, __LINE__, __func__);
03520 }
03521 if (amultip==NULL){
03522 par_print_err(myrank,proc_name,"array amultip is not assembled",__FILE__, __LINE__, __func__);
03523 par_print_err(myrank,proc_name,"function partop::assemble_multip has to be called first",__FILE__, __LINE__, __func__);
03524 }
03525 if (allnodes==NULL){
03526 par_print_err(myrank,proc_name,"array allnodes is not assembled",__FILE__, __LINE__, __func__);
03527 par_print_err(myrank,proc_name,"function partop::assemble_multip has to be called first",__FILE__, __LINE__, __func__);
03528 }
03529
03530 j=0;
03531 av = new long [tnnp];
03532 for (i=0;i<tnnp;i++){
03533 av[i]=amultip[i];
03534 if (av[i]==1)
03535 av[i]=-1;
03536 if (av[i]>1){
03537 av[i]=j;
03538 j++;
03539 }
03540 }
03541 break;
03542 }
03543 default:{
03544 print_err("unknown type of mesh description is required", __FILE__, __LINE__, __func__);
03545 }
03546 }
03547
03548 switch (md){
03549 case bound_nodes:{
03550 break;
03551 }
03552 case metis:
03553 case all_nodes:{
03554
03555 for (i=0;i<nproc;i++){
03556
03557 l=0;
03558
03559 for (j=0;j<nnsd[i];j++){
03560 k=allnodes[i][j];
03561 if (av[k]>-1){
03562 icnbnmas[i][l]=av[k];
03563 l++;
03564 }
03565 }
03566 }
03567 break;
03568 }
03569 case neg_bound_nodes:{
03570
03571 for (i=0;i<nproc;i++){
03572
03573 l=0;
03574
03575 for (j=0;j<nnsd[i];j++){
03576 k=allnodes[i][j];
03577 if (k<0){
03578 k=0-k-2;
03579 icnbnmas[i][j]=av[k];
03580 l++;
03581 }
03582 }
03583 }
03584 break;
03585 }
03586 default:{
03587 print_err("unknown type of mesh description is required", __FILE__, __LINE__, __func__);
03588 }
03589 }
03590
03591
03592
03593 if (icmultip!=NULL){
03594 delete [] icmultip;
03595 }
03596 icmultip = new long [tnbn];
03597 for (i=0;i<tnbn;i++){
03598 icmultip[i]=0;
03599 }
03600
03601
03602 for (i=0;i<nproc;i++){
03603
03604 for (j=0;j<nbnd[i];j++){
03605 icmultip[icnbnmas[i][j]]++;
03606 }
03607 }
03608
03609 if (av!=NULL)
03610 delete [] av;
03611 }
03612
03613 buffsize=maxnbn;
03614 buff = new long [buffsize];
03615
03616
03617 if (icnbn!=NULL){
03618 delete [] icnbn;
03619 }
03620 icnbn = new long [nbn];
03621
03622 if (myrank==0){
03623
03624
03625 for (i=1;i<nproc;i++){
03626
03627 k=domproc[i];
03628
03629 for (j=0;j<nbnd[k];j++){
03630 buff[j]=icnbnmas[k][j];
03631 }
03632 MPI_Send (buff,buffsize,MPI_LONG,i,myrank,MPI_COMM_WORLD);
03633 }
03634
03635
03636 k=domproc[0];
03637
03638 for (j=0;j<nbnd[k];j++){
03639 buff[j]=icnbnmas[k][j];
03640 }
03641
03642 }
03643 else{
03644 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
03645 }
03646 MPI_Barrier (MPI_COMM_WORLD);
03647
03648 for (i=0;i<nbn;i++){
03649 icnbn[i]=buff[i];
03650 }
03651
03652 delete [] buff;
03653
03654
03655
03656
03657
03658 if (myrank==0){
03659 fprintf (out,"\n\n\n coarse numbers of interface/boundary nodes on subdomain");
03660 for (i=0;i<nproc;i++){
03661 fprintf (out,"\n\n domain %ld",i);
03662 for (j=0;j<nbnd[i];j++){
03663 fprintf (out,"\n %6ld %6ld",j,icnbnmas[i][j]);
03664 }
03665 }
03666
03667 fprintf (out,"\n\n\n coarse-local correspondence \n");
03668 for (i=0;i<tnbn;i++){
03669 fprintf (out,"\n coarse node %6ld, number of nodes %2ld",i,icmultip[i]);
03670 }
03671 }
03672 fprintf (out,"\n\n\n coarse numbers of interface/boundary nodes on subdomain");
03673 for (i=0;i<nbn;i++){
03674 fprintf (out,"\n %6ld %6ld",i,icnbn[i]);
03675 }
03676
03677 }
03678
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692
03693
03694 void partop::node_coarse_global_map (FILE *out,char *proc_name)
03695 {
03696 long i,j,k,ii,jj,ln,cn;
03697
03698 if (myrank==0){
03699
03700 if (tnbn==0){
03701 par_print_err(myrank,proc_name,"total number of boundary/interface nodes (tnbn) is zero",__FILE__, __LINE__, __func__);
03702 par_print_err(myrank,proc_name,"function partop::assemble_nbnd_nind or partop::update_multip or partop::assemble_multip has to be called first",__FILE__, __LINE__, __func__);
03703 }
03704 if (icmultip==NULL){
03705 par_print_err(myrank,proc_name,"array icmultip is not assembled",__FILE__, __LINE__, __func__);
03706 par_print_err(myrank,proc_name,"function partop::node_coarse_numbers has to be called first",__FILE__, __LINE__, __func__);
03707 }
03708 if (icnbnmas==NULL){
03709 par_print_err(myrank,proc_name,"array icnbnmas is not assembled",__FILE__, __LINE__, __func__);
03710 par_print_err(myrank,proc_name,"function partop::node_coarse_numbers has to be called first",__FILE__, __LINE__, __func__);
03711 }
03712 if (gnbn==NULL){
03713 par_print_err(myrank,proc_name,"array gnbn is not assembled",__FILE__, __LINE__, __func__);
03714 par_print_err(myrank,proc_name,"function partop::node_global_numbers has to be called first",__FILE__, __LINE__, __func__);
03715 }
03716
03717
03718 if (gnbncn!=NULL){
03719 for (i=0;i<tnbn;i++){
03720 delete [] gnbncn[i];
03721 }
03722 delete [] gnbncn;
03723 }
03724 gnbncn = new long* [tnbn];
03725 for (i=0;i<tnbn;i++){
03726 gnbncn[i]=new long [icmultip[i]];
03727 }
03728
03729 if (sid!=NULL){
03730 for (i=0;i<tnbn;i++){
03731 delete [] sid[i];
03732 }
03733 delete [] sid;
03734 }
03735 sid = new long* [tnbn];
03736 for (i=0;i<tnbn;i++){
03737 sid[i] = new long [icmultip[i]];
03738 }
03739
03740
03741 for (i=0;i<tnbn;i++){
03742 icmultip[i]=0;
03743 }
03744
03745
03746 for (i=0;i<nproc;i++){
03747
03748 for (j=0;j<nbnd[i];j++){
03749
03750 cn=icnbnmas[i][j];
03751
03752 ln=gnbn[i][j];
03753
03754
03755 gnbncn[cn][icmultip[cn]]=ln;
03756
03757 sid[cn][icmultip[cn]]=i;
03758 icmultip[cn]++;
03759 }
03760 }
03761 }
03762
03763
03764
03765
03766 if (myrank==0){
03767 fprintf (out,"\n\n\n coarse-global correspondence \n");
03768 for (i=0;i<tnbn;i++){
03769 fprintf (out,"\n coarse node %6ld, number of nodes %2ld",i,icmultip[i]);
03770 for (j=0;j<icmultip[i];j++){
03771 fprintf (out," node %ld, global number %6ld, subdomain id %4ld",j,gnbncn[i][j],sid[i][j]);
03772 }
03773 }
03774 fprintf (out,"\n\n\n coarse-global correspondence \n");
03775 for (i=0;i<tnbn;i++){
03776 fprintf (out,"\n coarse node %6ld",i);
03777 for (j=0;j<icmultip[i];j++){
03778 fprintf (out," ggn %6ld, sub.%4ld",gnbncn[i][j],sid[i][j]);
03779 }
03780 }
03781 }
03782
03783 }
03784
03785
03786
03787
03788
03789
03790
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807 long partop::schur_ordering (gtopology *top,long *domproc,FILE *out,char *proc_name)
03808 {
03809 long i,j,k,l,m,ndofn,nid,ncdof,buffsize;
03810 long *aux,**auxdofind,*buff;
03811 MPI_Status stat;
03812
03813 switch (md){
03814 case bound_nodes:{
03815
03816
03817
03818
03819 ndof=1;
03820 for (i=0;i<nin;i++){
03821
03822 nid=lnindom[i];
03823
03824 ndofn = top->give_ndofn (nid);
03825
03826 for (j=0;j<ndofn;j++){
03827 k=top->give_dof (nid,j);
03828 if (k>0){
03829 top->save_dof (nid,j,ndof);
03830 ndof++;
03831 }
03832 }
03833 }
03834
03835 nidof = ndof-1;
03836
03837
03838
03839
03840
03841 for (i=0;i<nbn;i++){
03842
03843 nid=lnbndom[i];
03844
03845 ndofn = top->give_ndofn (nid);
03846
03847 for (j=0;j<ndofn;j++){
03848 k=top->give_dof (nid,j);
03849 if (k>0){
03850 top->save_dof (nid,j,ndof);
03851 ndof++;
03852 }
03853 }
03854 }
03855 ndof--;
03856
03857
03858
03859 for (i=0;i<top->ne;i++){
03860 if (top->give_cne (i)==1){
03861 for (j=0;j<top->give_ndofe(i);j++){
03862 if (top->give_dof (i,j)>ndof) ndof=top->give_dof (i,j);
03863 }
03864 }
03865 }
03866
03867
03868 nbdof = ndof-nidof;
03869
03870 break;
03871 }
03872 case metis:
03873 case all_nodes:{
03874
03875
03876
03877
03878 if (maxndof==0){
03879 par_print_err(myrank,proc_name,"maximum number of DOFs on one subdomain is equal to zero",__FILE__, __LINE__, __func__);
03880 par_print_err(myrank,proc_name,"function numbers_of_all_dofs_on_subdomains has to be called first",__FILE__, __LINE__, __func__);
03881 }
03882
03883 buffsize=maxndof;
03884 buff = new long [buffsize];
03885 for (i=0;i<buffsize;i++){
03886 buff[i]=0;
03887 }
03888
03889 if (myrank==0){
03890
03891 if (nnsd==NULL){
03892 par_print_err(myrank,proc_name,"array nnsd is not assembled",__FILE__, __LINE__, __func__);
03893 par_print_err(myrank,proc_name,"function partop::numbers_of_all_nodes_on_subdomains has to be called first",__FILE__, __LINE__, __func__);
03894 }
03895 if (allnodes==NULL){
03896 par_print_err(myrank,proc_name,"array allnodes is not assembled",__FILE__, __LINE__, __func__);
03897 par_print_err(myrank,proc_name,"function partop::assemble_multip has to be called first",__FILE__, __LINE__, __func__);
03898 }
03899 if (ndofnmas==NULL){
03900 par_print_err(myrank,proc_name,"array ndofnmas is not assembled",__FILE__, __LINE__, __func__);
03901 par_print_err(myrank,proc_name,"function partop::ndofn_master has to be called first",__FILE__, __LINE__, __func__);
03902 }
03903 if (dofind==NULL){
03904 par_print_err(myrank,proc_name,"array dofind is not assembled",__FILE__, __LINE__, __func__);
03905 par_print_err(myrank,proc_name,"function partop::update_multip has to be called first",__FILE__, __LINE__, __func__);
03906 }
03907
03908
03909
03910 for (i=1;i<nproc;i++){
03911
03912 k=domproc[i];
03913
03914
03915 m=0;
03916
03917 for (j=0;j<nnsd[k];j++){
03918
03919 nid=allnodes[k][j];
03920
03921
03922 ndofn=ndofnmas[nid];
03923
03924 for (l=0;l<ndofn;l++){
03925 buff[m]=dofind[nid][l];
03926 m++;
03927 }
03928 }
03929
03930
03931 MPI_Send (buff,buffsize,MPI_LONG,i,myrank,MPI_COMM_WORLD);
03932 }
03933
03934
03935
03936 k=domproc[0];
03937
03938
03939 m=0;
03940
03941 for (j=0;j<nnsd[k];j++){
03942
03943 nid=allnodes[k][j];
03944
03945 ndofn=ndofnmas[nid];
03946
03947 for (l=0;l<ndofn;l++){
03948 buff[m]=dofind[nid][l];
03949 m++;
03950 }
03951 }
03952
03953 }
03954 else{
03955 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
03956 }
03957 MPI_Barrier (MPI_COMM_WORLD);
03958
03959 auxdofind = new long* [nn];
03960 for (i=0;i<nn;i++){
03961 auxdofind[i] = new long [top->give_ndofn(i)];
03962 }
03963
03964
03965 k=0;
03966
03967 for (i=0;i<nn;i++){
03968
03969 ndofn=top->give_ndofn(i);
03970
03971 for (j=0;j<ndofn;j++){
03972 auxdofind[i][j]=buff[k];
03973 k++;
03974 }
03975 }
03976
03977 delete [] buff;
03978
03979
03980
03981
03982
03983
03984 ndof=0;
03985
03986 for (i=0;i<nn;i++){
03987
03988 ndofn=top->give_ndofn (i);
03989
03990 for (j=0;j<ndofn;j++){
03991 k=top->give_dof (i,j);
03992 if (k>ndof) ndof=k;
03993 }
03994 }
03995 ndof--;
03996 if (ndof<0) ndof=0;
03997 aux = new long [ndof];
03998 for (i=0;i<ndof;i++){
03999 aux[i]=-1;
04000 }
04001
04002
04003
04004
04005 ndof=1;
04006
04007
04008
04009
04010
04011
04012 for (j=0;j<nn;j++){
04013
04014 ndofn=top->give_ndofn (j);
04015
04016 for (l=0;l<ndofn;l++){
04017 if (auxdofind[j][l]==0){
04018
04019
04020 k=top->give_dof (j,l);
04021 if (k<0) continue;
04022 if (k==0) continue;
04023 if (k==1){
04024 top->gnodes[j].cn[l]=ndof; ndof++;
04025 }
04026 if (k>1){
04027 if (aux[k-2]==-1){
04028 top->gnodes[j].cn[l]=ndof;
04029 aux[k-2]=ndof;
04030 ndof++;
04031 }
04032 else{
04033 top->gnodes[j].cn[l]=aux[k-2];
04034 }
04035 }
04036 }
04037 }
04038 }
04039
04040
04041 nidof=ndof-1;
04042
04043
04044
04045
04046
04047
04048 for (j=0;j<nn;j++){
04049
04050 ndofn=top->give_ndofn (j);
04051
04052 for (l=0;l<ndofn;l++){
04053 if (auxdofind[j][l]==1){
04054
04055
04056 k=top->give_dof (j,l);
04057 if (k<0) continue;
04058 if (k==0) continue;
04059 if (k==1){
04060 top->gnodes[j].cn[l]=ndof; ndof++;
04061 }
04062 if (k>1){
04063 if (aux[k-2]==-1){
04064 top->gnodes[j].cn[l]=ndof;
04065 aux[k-2]=ndof;
04066 ndof++;
04067 }
04068 else{
04069 top->gnodes[j].cn[l]=aux[k-2];
04070 }
04071 }
04072 }
04073 }
04074 }
04075 ndof--;
04076
04077
04078 nbdof = ndof-nidof;
04079
04080 if (aux != NULL)
04081 delete [] aux;
04082
04083 for (i=0;i<nn;i++){
04084 delete [] auxdofind[i];
04085 }
04086 delete [] auxdofind;
04087
04088 break;
04089 }
04090 default:{
04091 print_err("unknown type of mesh description is required", __FILE__, __LINE__, __func__);
04092 }
04093 }
04094
04095
04096
04097 top->cnstate=1;
04098
04099
04100
04101
04102
04103 fprintf (out,"\n\n nidof %6ld",nidof);
04104 fprintf (out,"\n\n nbdof %6ld",nbdof);
04105 fprintf (out,"\n\n ndof %6ld",ndof);
04106 fprintf (out,"\n\n\n kontrola kodovych cisel \n\n");
04107
04108 for (j=0;j<nn;j++){
04109 fprintf (out,"\n node %6ld ",j);
04110
04111 ndofn=top->give_ndofn (j);
04112
04113 for (l=0;l<ndofn;l++){
04114 fprintf (out," %6ld",top->gnodes[j].cn[l]);
04115 }
04116 }
04117
04118
04119 return ndof;
04120 }
04121
04122
04123
04124
04125
04126
04127
04128
04129
04130
04131
04132
04133
04134 void partop::prepare_data (long *domproc,long *ltg,gtopology *top,FILE *out,char *proc_name)
04135 {
04136 long i, k, delta;
04137
04138 initiation (top,ltg);
04139 numbers_of_all_nodes_on_subdomains (domproc,out);
04140 coupled_dofs (top,domproc,out);
04141 if ((md==bound_nodes) && nbcdof!=0)
04142 {
04143 fprintf(stdout, "\n Coupled dofs detected on boundary/interface nodes\n");
04144 fprintf(stdout, " Global node numbers will be regenerated\n");
04145 assemble_nbnd_nind(ltg,domproc,out,proc_name);
04146 delta = 0;
04147 for(i=0; i<ndom; i++)
04148 delta += nind[i];
04149 k = delta;
04150 bltg = new long[top->nn];
04151 for(i=0; i< top->nn; i++)
04152 bltg[i] = ltg[i];
04153 for(i=0; i< top->nn; i++)
04154 {
04155 if (ltg[i]<0)
04156 {
04157 ltg[i] = k;
04158 k++;
04159 }
04160 else
04161 ltg[i] += tnin;
04162 }
04163 md = all_nodes;
04164 initiation (top,ltg);
04165 fprintf(out, "\n\n\n Coupled dofs on boundary/interface nodes were detected");
04166 fprintf(out, "\n global node numbers (ltg) has been regenerated");
04167 fprintf(out, "\n mesh description changed to all_nodes, delta=%ld\n", delta);
04168 for(i=0; i< top->nn; i++)
04169 fprintf(out, "%ld %ld %ld\n", i+1, bltg[i], ltg[i]);
04170 }
04171
04172 assemble_multip (ltg,domproc,out,proc_name);
04173 numbers_of_all_dofs_on_subdomains (top,domproc,out);
04174
04175
04176
04177
04178
04179
04180
04181
04182
04183
04184 long j,buffsize,*buff;
04185 buffsize=maxnbn;
04186 buff = new long [buffsize];
04187
04188
04189
04190
04191
04192
04193 if (lnbn != NULL)
04194 delete [] lnbn;
04195 lnbn = new long [nbn];
04196
04197 switch (md){
04198 case bound_nodes:{
04199 j=0;
04200 for (i=0;i<nn;i++){
04201 if (ltg[i]>-1){
04202 lnbn[j]=i;
04203 j++;
04204 }
04205 }
04206 break;
04207 }
04208 default:{
04209 fprintf (stderr,"\n\n unknown type of mesh description is required in");
04210 fprintf (stderr,"\n function find_boundary_nodes (file %s, line %d)\n",__FILE__,__LINE__);
04211 }
04212 }
04213
04214
04215
04216 nin = nn-nbn;
04217
04218
04219 if (lnin != NULL)
04220 delete [] lnin;
04221 lnin = new long [nin];
04222
04223 j=0;
04224 for (i=0;i<nn;i++){
04225 if (ltg[i]==-1){
04226 lnin[j]=i;
04227 j++;
04228 }
04229 }
04230
04231 MPI_Barrier (MPI_COMM_WORLD);
04232
04233
04234
04235
04236
04237
04238
04239
04240
04241
04242
04243
04244
04245
04246
04247
04248
04249
04250
04251
04252
04253
04254
04255
04256
04257
04258
04259
04260
04261
04262
04263
04264
04265
04266
04267 if (md==all_nodes || md==neg_bound_nodes){
04268 ndofn_master (top,domproc,out,proc_name);
04269 dofind_master (top,domproc,out,proc_name);
04270 update_multip (top,out,proc_name);
04271 }
04272
04273 assemble_nbnd_nind (ltg,domproc,out,proc_name);
04274 assemble_nodmultip (ltg,domproc,out,proc_name);
04275 if (md==all_nodes || md==neg_bound_nodes){
04276 node_global_numbers (domproc,out,proc_name);
04277 }
04278 node_local_numbers (out);
04279
04280 node_coarse_numbers (domproc,out,proc_name);
04281
04282 if (md==all_nodes || md==neg_bound_nodes){
04283 node_coarse_global_map (out,proc_name);
04284 }
04285
04286 }
04287
04288
04289
04290
04291
04292
04293
04294
04295
04296
04297
04298
04299
04300
04301
04302
04303
04304 void partop::assemble_gcnd(gtopology *top,long *domproc,FILE *out)
04305 {
04306 long i,j,k,ii,m;
04307 long a,b,buffsize;
04308 long adr,ndofn;
04309 long *buff;
04310 long *gnn;
04311 long *pgcn;
04312 MPI_Status stat;
04313
04314 if (md==bound_nodes){
04315
04316
04317 buffsize = maxnbn;
04318 buff = new long [buffsize];
04319
04320 for(i = 0; i < nbn; i++){
04321 buff[i] = lnbndom[i];
04322 }
04323
04324
04325
04326
04327
04328
04329
04330 if(myrank == 0){
04331 if (allnodes != NULL){
04332 for (i=0;i<nproc;i++){
04333 delete [] allnodes[i];
04334 }
04335 delete [] allnodes;
04336 }
04337 allnodes = new long *[nproc];
04338
04339 for(i = 0; i< nproc; i++){
04340 allnodes[i] = new long [nnsd[i]];
04341 for(j = 0; j < nnsd[i]; j++){
04342 allnodes[i][j] = -1;
04343 }
04344 }
04345
04346
04347 for(k = 0; k < nbnd[0]; k++){
04348 allnodes[0][buff[k]]=icnbnmas[0][k];
04349 }
04350 a = tnbn;
04351 for(k = 0; k < nnsd[0]; k++){
04352 if(allnodes[0][k] == -1){
04353 allnodes[0][k] = a;
04354 a++;
04355 }
04356 }
04357
04358
04359
04360 for (i=1;i<nproc;i++){
04361 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
04362 j=domproc[stat.MPI_TAG];
04363 for(k = 0; k < nbnd[0]; k++){
04364 allnodes[j][buff[k]]=icnbnmas[j][k];
04365 }
04366 for(k = 0; k < nnsd[j]; k++){
04367 if(allnodes[j][k] == -1){
04368 allnodes[j][k] = a;
04369 a++;
04370 }
04371 }
04372 }
04373 for (i=0;i<nproc;i++){
04374 fprintf(out,"\n\nDomain number %ld\n",i+1);
04375 for(j = 0; j < nnsd[i]; j++){
04376 fprintf(out,"%ld %ld\n",j+1,allnodes[i][j]+1);
04377 }
04378 }
04379 tnnp = a;
04380 fprintf(out,"tnnp is %ld\n",tnnp);
04381
04382 }
04383 else{
04384 MPI_Send (buff,buffsize,MPI_LONG,0,myrank,MPI_COMM_WORLD);
04385 }
04386 MPI_Barrier (MPI_COMM_WORLD);
04387 delete []buff;
04388 }
04389
04390
04391 buffsize = maxnn;
04392 buff = new long [buffsize];
04393
04394
04395 for (i=0;i<nn;i++){
04396 buff[i]=top -> give_ndofn(i);
04397 }
04398
04399 if (myrank==0){
04400
04401
04402 if (gnn == NULL)
04403 gnn = new long[tnnp+1];
04404
04405 for(i = 0; i < tnnp+1; i++)
04406 gnn[i] = -10;
04407
04408
04409 k = domproc[0];
04410 for (i = 0;i < nnsd[k]; i++){
04411 gnn[allnodes[k][i]] = buff[i];
04412 }
04413
04414 for (i= 1 ;i < nproc; i++){
04415 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
04416
04417
04418 k=domproc[stat.MPI_TAG];
04419 for (j = 0; j < nnsd[k]; j++){
04420 if(gnn[allnodes[k][j]] == -10){
04421 gnn[allnodes[k][j]] = buff[j];
04422 }
04423 else{
04424 if (gnn[allnodes[k][j]] != buff[j]){
04425 fprintf (stderr,"\n different numbers of DOFs on the %ld-th domain in the %ld-th node",k,j);
04426 fprintf (stderr,"\n in function assemble_gnn (file %s, line %d)\n",__FILE__,__LINE__);
04427 }
04428 }
04429 }
04430 }
04431 }
04432 else{
04433 MPI_Send (buff,buffsize,MPI_LONG,0,myrank,MPI_COMM_WORLD);
04434 }
04435 MPI_Barrier (MPI_COMM_WORLD);
04436
04437 delete [] buff;
04438
04439 if (myrank == 0){
04440
04441
04442
04443
04444
04445
04446
04447
04448 a = gnn[0];
04449 gnn[0] = 0;
04450 for(i = 1; i < tnnp+1; i++){
04451 b = gnn[i];
04452 gnn[i] = gnn[i-1] + a;
04453 a = b;
04454 }
04455 tndof = gnn[tnnp];
04456
04457
04458 fprintf(out,"\n\n\ngnn array\n\n");
04459 for(i = 0; i < tnnp+1; i++){
04460 fprintf(out,"%ld %ld\n",i+1,gnn[i]);
04461 }
04462 }
04463
04464
04465 buffsize = maxndof;
04466 buff = new long [buffsize];
04467
04468 m = 0;
04469 for (i = 0;i < nn; i++){
04470 ndofn = top->give_ndofn (i);
04471 for (j = 0; j < ndofn; j++){
04472 buff[m] = top -> give_dof (i,j);
04473 m++;
04474 }
04475 }
04476
04477
04478 if (myrank==0){
04479
04480
04481
04482
04483
04484
04485
04486 if (pgcn == NULL){
04487 pgcn = new long[tndof];
04488 }
04489
04490
04491 for(i = 0; i < tndof; i++) pgcn[i] = -10;
04492
04493
04494 k = domproc[0];
04495 m = 0;
04496 for (i = 0;i < nnsd[k]; i++){
04497 adr = gnn[allnodes[k][i]];
04498
04499 ndofn = gnn[allnodes[k][i]+1] - adr;
04500
04501 for (j = 0;j < ndofn; j++){
04502 pgcn[adr+j] = buff[m];
04503 m++;
04504 }
04505 }
04506
04507
04508 for (i= 1 ;i < nproc; i++){
04509 MPI_Recv (buff,buffsize,MPI_LONG,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
04510
04511 k = domproc[stat.MPI_TAG];
04512 m = 0;
04513 for (ii = 0;ii< nnsd[k]; ii++){
04514 adr = gnn[allnodes[k][ii]];
04515 ndofn = gnn[allnodes[k][ii]+1] - adr;
04516 for (j = 0;j < ndofn; j++){
04517 pgcn[adr+j] = buff[m];
04518 m++;
04519 }
04520 }
04521 }
04522 }
04523 else{
04524 MPI_Send (buff,buffsize,MPI_LONG,0,myrank,MPI_COMM_WORLD);
04525 }
04526 MPI_Barrier (MPI_COMM_WORLD);
04527
04528 delete []buff;
04529
04530
04531
04532
04533
04534
04535
04536
04537
04538
04539
04540
04541
04542 if(myrank == 0){
04543 m = 1;
04544 for(i = 0; i < tndof; i++){
04545 if(pgcn[i] > 0){
04546 pgcn[i] = m;
04547 m++;
04548 }
04549 }
04550
04551 fprintf(out,"\n\n\n Global code numbers\n\n");
04552 for(i = 0; i < tndof; i++){
04553 fprintf(out,"%ld %ld\n",i,pgcn[i]);
04554 }
04555 tndof = m-1;
04556 fprintf(out,"\n\n\n number of DOFs on whole problem %ld\n\n",tndof);
04557 }
04558
04559
04560
04561 if(myrank == 0){
04562
04563 nud = new long[nproc];
04564 for(i = 0; i < nproc; i++){
04565 nud[i]=0;
04566 for(j = 0; j < nnsd[i]; j++){
04567 adr = gnn[allnodes[i][j]];
04568 ndofn = gnn[allnodes[i][j]+1] - adr;
04569 for (k = 0;k < ndofn; k++){
04570 if(pgcn[adr+k] > 0){
04571 nud[i]++;
04572 }
04573 }
04574 }
04575 }
04576
04577 fprintf(out,"\n\n\n Number of unknowns on subdomain\n");
04578 for(i = 0; i < nproc; i++){
04579 fprintf(out,"Domain %ld %ld\n",i+1,nud[i]);
04580 }
04581
04582 gcnd = new long*[nproc];
04583 for(i = 0;i < nproc; i++){
04584 gcnd[i] = new long[nud[i]];
04585 m = 0;
04586 for(j = 0; j < nnsd[i]; j++){
04587 adr = gnn[allnodes[i][j]];
04588 ndofn = gnn[allnodes[i][j]+1] - adr;
04589 for (k = 0;k < ndofn; k++){
04590 if(pgcn[adr+k] > 0){
04591 gcnd[i][m] = pgcn[adr+k] ;
04592 m++;
04593 }
04594 }
04595 }
04596 }
04597
04598
04599 fprintf(out,"\n\n\n Unknowns on subdomain gcnd\n");
04600 for(i = 0;i < nproc; i++){
04601 fprintf(out,"Domain %ld\n",i+1);
04602 for(j = 0; j < nud[i]; j++){
04603 fprintf(out,"%ld %ld\n",j,gcnd[i][j]);
04604 }
04605 }
04606 delete []gnn;
04607 delete []pgcn;
04608 }
04609
04610 }