00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 #include <stdio.h>
00098 #include <stdlib.h>
00099 #include <math.h>
00100
00101 #include "constrain.h"
00102 #include "load.h"
00103 #include "elm.h"
00104 #include "node.h"
00105 #include "alg.h"
00106 #include "xgplib.h"
00107 #include "fem.h"
00108 #include "csr.h"
00109 #include "pfs.h"
00110 #include "solversamg.h"
00111
00112
00113
00114
00115
00116
00117 #ifndef maxcor
00118 #define maxcor 30
00119 #endif
00120
00121 #ifndef maxiter
00122 #define maxiter 5000
00123 #endif
00124
00125 #ifndef cgtol
00126 #define cgtol 1.0e-10
00127 #endif
00128
00129 #ifndef ngr
00130 #define ngr 10e20
00131 #endif
00132
00133
00134
00135
00136
00137
00138 static void ElmKpr(double *);
00139 static void ElmKp(double *, double *);
00140 static void GCSolver(double *, double *);
00141 static void SearchDirection(int i, int k, double *vector, double **w, double **v);
00142
00143 static void ElmKpParalelo(int , int , int , int , double *, double *,
00144 double *, double *, double *, double *);
00145 static void ElmKprParalelo(int , int , int , int, double *,
00146 double *, double *, double *, double *,
00147 double *, double *);
00148 static void ContourParalelo(int , int , double *, double *);
00149 static void ContourKpParalelo(int , int , double *);
00150 static void ProdEscalarParalelo(int, int , double *, double *,
00151 double *, double *, double *, double *);
00152 static void UpDataParalelo(int , int , double *, double *, double ,
00153 double *, double *, double *, double *,
00154 double *, double *, double *);
00155 static void ResParalelo(int , int , double ,
00156 double *, double *, double *,
00157 double *, double *, double *);
00158 static void PreParalelo(int , int , double *, double *,
00159 double *, double *, double *,
00160 double *, double *);
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 static void SearchDirection(int i, int k, double *vector, double **w, double **v)
00171 {
00172
00173
00174
00175
00176 int n;
00177 int j;
00178 int m;
00179 double a;
00180 double *b;
00181 int matrix = 12;
00182 int iversion = 4;
00183 int nsys = 1;
00184 int npnt = 0;
00185
00186 n=0;
00187 a=0.0;
00188 m=k;
00189
00190 b = (double*)malloc(i*sizeof(double));
00191
00192 for (j = 0; j < i; j++){
00193 a += w[j][m]*vector[j];
00194 }
00195 for (j = 0; j < i; j++){
00196 b[j] = vector[j]+v[j][m]*a;
00197 }
00198 for (j = 0; j < i; j++){
00199 vector[j] = b[j];
00200 }
00201 while(m>0){
00202 m -=1;
00203 a=0.0;
00204 for (j = 0; j < i; j++){
00205 a += w[j][m]*vector[j];
00206 }
00207 for (j = 0; j < i; j++){
00208 b[j] = vector[j]+v[j][m]*a;
00209 }
00210 for (j = 0; j < i; j++){
00211 vector[j] = b[j];
00212 }
00213 }
00214
00215 if(Config.solver == 0){
00216
00217
00218
00219 GCSolver(b, vector);
00220
00221 }
00222 else{
00223
00224
00225
00226 SamgSolver( iversion, nna, nnu, matrix, nsys, npnt, ia, ja, avector, b, vector );
00227
00228 }
00229
00230 a=0.0;
00231 for (j = 0; j < i; j++){
00232 a += v[j][n]*vector[j];
00233 }
00234 for (j = 0; j < i; j++){
00235 b[j] = vector[j]+w[j][n]*a;
00236 }
00237 for (j = 0; j < i; j++){
00238 vector[j] = b[j];
00239 }
00240 while(n<k){
00241 n +=1;
00242 a=0.0;
00243 for (j = 0; j < i; j++){
00244 a += v[j][n]*vector[j];
00245 }
00246 for (j = 0; j < i; j++){
00247 b[j] = vector[j]+w[j][n]*a;
00248 }
00249 for (j = 0; j < i; j++){
00250 vector[j] = b[j];
00251 }
00252 }
00253 free ( b );
00254 }
00255
00256
00257
00258 static void ProdutoEscalar(int n, int nn, double *w, double *v, double *a )
00259 {
00260 int i;
00261
00262 *a = 0.0;
00263
00264 for (i = n; i < nn; i++){
00265 *a += w[i]*v[i];
00266 }
00267 }
00268
00269 static void SomaVector(int n, int nn, double *w, double *v, double *b, double a)
00270 {
00271 int i;
00272
00273 for (i = n; i < nn; i++){
00274 b[i] = w[i] + v[i]*a;
00275 v[i] = b[i];
00276 }
00277 }
00278
00279 static void SearchDirectionParalelo(int i, int k, double *vector, double **w, double **v,
00280 int ni[], int nf[], int gli[], int glf[])
00281 {
00282
00283
00284
00285
00286 int n;
00287 int j;
00288 int m;
00289 double a;
00290 double *b;
00291 int matrix = 12;
00292 int iversion = 4;
00293 int nsys = 1;
00294 int npnt = 0;
00295
00296 int nd = 10;
00297 int l;
00298 double ea;
00299 double *wi, *vi;
00300
00301 n=0;
00302 a=0.0;
00303 m=k;
00304
00305 b = (double*)malloc(i*sizeof(double));
00306 wi = (double*)malloc(i*sizeof(double));
00307 vi = (double*)malloc(i*sizeof(double));
00308
00309 for(j = 0; j < i; j++){
00310 wi[j] = w[j][m];
00311 vi[j] = v[j][m];
00312 }
00313
00314 ea = 0.0;
00315
00316 for (l = 0; l < nd; l++){
00317
00318 ProdutoEscalar(gli[l], glf[l], wi, vector, &a);
00319
00320 ea += a;
00321 }
00322
00323 for (l = 0; l < nd; l++){
00324
00325 SomaVector(gli[l], glf[l], vector, vi, b, ea);
00326
00327 }
00328
00329 while(m>0){
00330 m -=1;
00331 ea = 0.0;
00332
00333 for(j = 0; j < i; j++){
00334 wi[j] = w[j][m];
00335 vi[j] = v[j][m];
00336 }
00337
00338 for (l = 0; l < nd; l++){
00339
00340 ProdutoEscalar(gli[l], glf[l], wi, vector, &a);
00341
00342 ea += a;
00343 }
00344
00345 for (l = 0; l < nd; l++){
00346
00347 SomaVector(gli[l], glf[l], vector, vi, b, ea);
00348
00349 }
00350
00351 }
00352
00353 if(Config.solver == 0){
00354
00355
00356
00357 GCSolver(b, vector);
00358
00359 }
00360 else{
00361
00362
00363
00364 SamgSolver( iversion, nna, nnu, matrix, nsys, npnt, ia, ja, avector, b, vector );
00365
00366 }
00367
00368 ea = 0.0;
00369
00370 for(j = 0; j < i; j++){
00371 wi[j] = w[j][n];
00372 vi[j] = v[j][n];
00373 }
00374
00375 for (l = 0; l < nd; l++){
00376
00377 ProdutoEscalar(gli[l], glf[l], vi, vector, &a);
00378
00379 ea += a;
00380 }
00381
00382 for (l = 0; l < nd; l++){
00383
00384 SomaVector(gli[l], glf[l], vector, wi, b, ea);
00385
00386 }
00387
00388 while(n<k){
00389 n +=1;
00390 ea = 0.0;
00391
00392 for (l = 0; l < nd; l++){
00393
00394 ProdutoEscalar(gli[l], glf[l], vi, vector, &a);
00395
00396 ea += a;
00397 }
00398
00399 for (l = 0; l < nd; l++){
00400
00401 SomaVector(gli[l], glf[l], vector, wi, b, ea);
00402
00403 }
00404
00405 }
00406 free ( b );
00407 free ( vi );
00408 free ( wi );
00409 }
00410
00411
00412
00413 #if 0
00414
00415
00416
00417
00418 static void ElmKpr(double *Kp)
00419 {
00420 int i;
00421
00422 for( i = 0; i < NumNodes * NDof; i++ ){
00423 Kp[i] = avector[ia[i]];
00424 }
00425 }
00426
00427
00428
00429
00430 static void ElmKp(double *d, double *p)
00431 {
00432 int i,j,k,l,m;
00433
00434 for( i = 0; i < NumNodes * NDof; i++ ){
00435 j = ia[i];
00436 l = ia[i+1];
00437 for (k = j; k < l; k++){
00438 m=ja[k];
00439 d[i] += avector[k] * p[m];
00440 }
00441 }
00442 }
00443
00444
00445
00446
00447 static void GCSolver(double *R, double *u)
00448 {
00449 int i,j,m;
00450 double alpha,beta,a,b;
00451 double *rn,*p,*d,*Kp,*z;
00452 double error;
00453 int iter;
00454
00455 m = NumNodes * NDof;
00456
00457 rn = (double*)malloc(m*sizeof(double));
00458 p = (double*)malloc(m*sizeof(double));
00459 d = (double*)malloc(m*sizeof(double));
00460 Kp = (double*)malloc(m*sizeof(double));
00461 z = (double*)malloc(m*sizeof(double));
00462
00463 for( i = 0; i < m; i++ ){
00464 Kp[i] = 0.0;
00465 }
00466
00467
00468
00469 ElmKpr(Kp);
00470
00471 for( i = 0; i < NumNodes; i++ ){
00472 if( NodeVector[i].dof.x == DISPLACEMENT ){
00473 Kp[NDof*i]+= ngr;
00474 }
00475 if( NodeVector[i].dof.y == DISPLACEMENT ){
00476 Kp[NDof*i+1]+= ngr;
00477 }
00478 if( NDof == 3 ) {
00479 if( NodeVector[i].dof.z == DISPLACEMENT ){
00480 Kp[NDof*i+2]+= ngr;
00481 }
00482 }
00483 }
00484
00485 for( j = 0; j < m; j++ ){
00486 if(Kp[j] != 0.0){
00487 Kp[j] = 1.0/Kp[j];
00488 }
00489 else{
00490 Kp[j] = 1.0;
00491 }
00492 rn[j] = R[j];
00493 z[j] = p[j] = Kp[j]*rn[j];
00494 d[j] = u[j] = 0.0;
00495 }
00496
00497 error = 1.0; iter = 0;
00498
00499 while((error>=cgtol)&&(iter<maxiter)){
00500 iter ++;
00501
00502 error = 0.0;
00503
00504 ElmKp(d,p);
00505
00506 for( i = 0; i < NumNodes; i++ ){
00507 if( NodeVector[i].dof.x == DISPLACEMENT ){
00508 d[NDof*i] = ngr*p[NDof*i];
00509 }
00510 if( NodeVector[i].dof.y == DISPLACEMENT ){
00511 d[NDof*i+1] = ngr*p[NDof*i+1];
00512 }
00513 if( NDof == 3 ) {
00514 if( NodeVector[i].dof.z == DISPLACEMENT ){
00515 d[NDof*i+2] = ngr*p[NDof*i+2];
00516 }
00517 }
00518 }
00519
00520 a = b = 0.0;
00521
00522 for (j = 0; j < m; j++){
00523 a+= z[j]*rn[j];
00524 b+= p[j]*d[j];
00525 }
00526
00527 alpha = a/b;
00528 a = b = 0.0;
00529
00530 for( j = 0; j < m; j++ ){
00531 u[j]+= alpha*p[j];
00532 rn[j]= R[j]-alpha*d[j];
00533 b+= z[j]*R[j];
00534 z[j]= Kp[j]*rn[j];
00535 a+= z[j]*rn[j];
00536 }
00537
00538 beta=a/b;
00539
00540 for( j = 0; j < m; j++ ){
00541 p[j]= z[j]+beta*p[j];
00542 R[j]= rn[j];
00543 d[j]= 0.0;
00544 error+= rn[j]*rn[j];
00545 }
00546
00547 error=sqrt(error);
00548
00549 }
00550
00551 free ( rn );
00552 free ( p );
00553 free ( d );
00554 free ( Kp );
00555 free ( z );
00556 }
00557
00558 #else
00559
00560
00561
00562
00563
00564 static void ElmKprParalelo(int n, int nn, int m, int mm, double *Kp,
00565 double *d, double *p, double *z, double *rn,
00566 double *u, double *R)
00567 {
00568 int i;
00569
00570 for( i = n; i < nn; i++ ){
00571 Kp[i] = avector[ia[i]];
00572 }
00573
00574 ContourKpParalelo(m, mm, Kp);
00575
00576 PreParalelo(n, nn, Kp, d, p, z, rn, u, R);
00577
00578 }
00579
00580
00581
00582
00583 static void ElmKpParalelo(int n, int nn, int ni, int nf, double *d, double *p,
00584 double *z, double *rn, double *a, double *b)
00585 {
00586 int i,j,k,l,m;
00587
00588 for( i = n; i < nn; i++ ){
00589 j = ia[i];
00590 l = ia[i+1];
00591 for (k = j; k < l; k++){
00592 m=ja[k];
00593 d[i] += avector[k] * p[m];
00594 }
00595 }
00596
00597 ContourParalelo(ni, nf, d, p);
00598
00599 ProdEscalarParalelo(n, nn, a, b, d, p, z, rn);
00600
00601 }
00602
00603 static void ContourParalelo(int n, int nn, double *d, double *p)
00604 {
00605 int i;
00606
00607 for( i = n; i < nn; i++ ){
00608 if( NodeVector[i].dof.x == DISPLACEMENT ){
00609 d[NDof*i] = ngr*p[NDof*i];
00610 }
00611 if( NodeVector[i].dof.y == DISPLACEMENT ){
00612 d[NDof*i+1] = ngr*p[NDof*i+1];
00613 }
00614 if( NDof == 3 ) {
00615 if( NodeVector[i].dof.z == DISPLACEMENT ){
00616 d[NDof*i+2] = ngr*p[NDof*i+2];
00617 }
00618 }
00619 }
00620
00621 }
00622
00623 static void ContourKpParalelo(int n, int nn, double *Kp)
00624 {
00625 int i;
00626
00627 for( i = n; i < nn; i++ ){
00628 if( NodeVector[i].dof.x == DISPLACEMENT ){
00629 Kp[NDof*i]+= ngr;
00630 }
00631 if( NodeVector[i].dof.y == DISPLACEMENT ){
00632 Kp[NDof*i+1]+= ngr;
00633 }
00634 if( NDof == 3 ) {
00635 if( NodeVector[i].dof.z == DISPLACEMENT ){
00636 Kp[NDof*i+2]+= ngr;
00637 }
00638 }
00639 }
00640
00641 }
00642
00643 static void ProdEscalarParalelo(int n, int nn, double *a, double *b,
00644 double *d, double *p, double *z, double *rn)
00645 {
00646 int i;
00647
00648 *a = *b = 0.0;
00649
00650 for (i = n; i < nn; i++){
00651 *a += z[i]*rn[i];
00652 *b += p[i]*d[i];
00653 }
00654
00655 }
00656
00657 static void UpDataParalelo(int n, int nn, double *a, double *b, double alpha,
00658 double *u, double *d, double *p, double *z,
00659 double *rn, double *R, double *Kp)
00660
00661 {
00662 int i;
00663
00664 *a = *b = 0.0;
00665
00666 for (i = n; i < nn; i++){
00667 u[i]+= alpha*p[i];
00668 rn[i]= R[i]-alpha*d[i];
00669 *b += z[i]*R[i];
00670 z[i]= Kp[i]*rn[i];
00671 *a += z[i]*rn[i];
00672 }
00673
00674 }
00675
00676 static void ResParalelo(int n, int nn, double beta,
00677 double *d, double *p, double *z,
00678 double *rn, double *R, double *error)
00679 {
00680 int i;
00681
00682 for( i = n; i < nn; i++ ){
00683 p[i]= z[i]+beta*p[i];
00684 R[i]= rn[i];
00685 d[i]= 0.0;
00686 *error+= rn[i]*rn[i];
00687 }
00688
00689 }
00690
00691 static void PreParalelo(int n, int nn, double *Kp, double *d,
00692 double *p, double *z, double *rn,
00693 double *u, double *R)
00694 {
00695 int i;
00696
00697 for( i = n; i < nn; i++ ){
00698 if(Kp[i] != 0.0){
00699 Kp[i] = 1.0/Kp[i];
00700 }
00701 else{
00702 Kp[i] = 1.0;
00703 }
00704 rn[i] = R[i];
00705 z[i] = p[i] = Kp[i]*rn[i];
00706 d[i] = u[i] = 0.0;
00707 }
00708
00709 }
00710
00711
00712
00713
00714
00715
00716 static void GCSolver(double *R, double *u)
00717 {
00718 int i,m;
00719 double alpha,beta;
00720 double *rn,*p,*d,*Kp,*z;
00721 double error;
00722 int iter;
00723 int gli[10], glf[10];
00724 int ni[10], nf[10];
00725 double ea, eb;
00726 double a, b;
00727 int nno;
00728
00729
00730 int nd = 10;
00731
00732
00733 nno = NumNodes/nd;
00734
00735 ni[0] = 0;
00736 nf[0] = nno;
00737 for( i = 1; i < nd-1; i++ ){
00738 ni[i] = nf[i-1] + 1;
00739 nf[i] = nf[i-1] + nno;
00740 }
00741 ni[nd-1] = nf[nd-2] + 1;
00742 nf[nd-1] = NumNodes - 1;
00743
00744
00745 gli[0] = 0;
00746 glf[0] = nf[0] * NDof;
00747 for( i = 1; i < nd-1; i++ ){
00748 gli[i] = glf[i-1];
00749 glf[i] = nf[i] * NDof;
00750 }
00751 gli[nd-1] = glf[nd-2];
00752 glf[nd-1] = nf[nd-1] * NDof + NDof;
00753
00754
00755 m = NumNodes * NDof;
00756
00757 rn = (double*)malloc(m*sizeof(double));
00758 p = (double*)malloc(m*sizeof(double));
00759 d = (double*)malloc(m*sizeof(double));
00760 Kp = (double*)malloc(m*sizeof(double));
00761 z = (double*)malloc(m*sizeof(double));
00762
00763
00764
00765 for(i = 0; i < nd; i++){
00766
00767 ElmKprParalelo(gli[i], glf[i], ni[i], nf[i], Kp, d, p, z, rn, u, R);
00768
00769 }
00770
00771
00772 error = 1.0; iter = 0;
00773
00774 while((error>=cgtol)&&(iter<maxiter)){
00775
00776 iter ++;
00777
00778 error = ea = eb = 0.0;
00779
00780
00781 for(i = 0; i < nd; i++){
00782
00783 ElmKpParalelo(gli[i], glf[i], ni[i], nf[i], d, p, z, rn, &a, &b);
00784
00785 ea += a;
00786 eb += b;
00787
00788 }
00789
00790 alpha = ea/eb;
00791 ea = eb = 0.0;
00792
00793
00794 for(i = 0; i < nd; i++){
00795
00796 UpDataParalelo(gli[i], glf[i], &a, &b, alpha, u, d, p, z, rn, R, Kp);
00797
00798 ea += a;
00799 eb += b;
00800
00801 }
00802
00803 beta = ea/eb;
00804
00805
00806 for(i = 0; i < nd; i++){
00807
00808 ResParalelo(gli[i], glf[i], beta, d, p, z, rn, R, &error);
00809
00810 }
00811 error = sqrt(error);
00812 }
00813
00814 free ( rn );
00815 free ( p );
00816 free ( d );
00817 free ( Kp );
00818 free ( z );
00819 }
00820
00821
00822 #endif
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832 void BuildAVector( void )
00833 {
00834 int i,j,k,l,elm;
00835 double ke[24][24];
00836 int u[24];
00837 int index;
00838
00839
00840
00841
00842 for( elm = 0; elm < NumElements; elm++ ){
00843
00844
00845 ElmGetDof(ElmList[elm], u, &index);
00846
00847
00848 ElmKMatrix(ElmList[elm], ke);
00849
00850
00851
00852 for(i = 0; i < index; i++){
00853 for(j = 0; j < index; j++){
00854 k = u[i];
00855 l = u[j];
00856 BuildaVector(k,l,ke[i][j]);
00857 }
00858 }
00859 }
00860
00861
00862 for( i = 0; i < NumNodes; i++ ){
00863 if( NodeVector[i].dof.x == DISPLACEMENT ){
00864 avector[ia[NDof*i]]+= ngr;
00865 }
00866 if( NodeVector[i].dof.y == DISPLACEMENT ){
00867 avector[ia[NDof*i+1]]+= ngr;
00868 }
00869 if( NDof == 3 ) {
00870 if( NodeVector[i].dof.z == DISPLACEMENT ){
00871 avector[ia[NDof*i+2]]+= ngr;
00872 }
00873 }
00874 }
00875 }
00876
00877
00878
00879
00880
00881 void BFGS(double dtime, double *F, double *U, double *V,
00882 int *iteration, double *error, double error0, int loadstep )
00883 {
00884
00885
00886
00887
00888 int i,j,k,n;
00889 double vp[3];
00890 eRestType dof[3];
00891 double b, c;
00892 double *q, *F0;
00893 double **w, **v;
00894 int needite;
00895 int stop = 0;
00896 int matrix = 12;
00897 int iversion = 4;
00898 int nsys = 1;
00899 int npnt = 0;
00900
00901 n = NumNodes*NDof;
00902
00903 q = (double*)malloc(n*sizeof(double));
00904 F0 = (double*)malloc(n*sizeof(double));
00905 w = (double**)malloc(n*sizeof(double*));
00906 v = (double**)malloc(n*sizeof(double*));
00907 for(i=0; i < n; i++){
00908 w[i] = (double*)malloc(maxcor*sizeof(double));
00909 v[i] = (double*)malloc(maxcor*sizeof(double));
00910 }
00911
00912 for( i = 0; i < NumNodes; i++ ) {
00913 dof[0] = NodeVector[i].dof.x;
00914 dof[1] = NodeVector[i].dof.y;
00915 dof[2] = NodeVector[i].dof.z;
00916 vp[0] = NodeVector[i].dof.vpx;
00917 vp[1] = NodeVector[i].dof.vpy;
00918 vp[2] = NodeVector[i].dof.vpz;
00919 for( j = 0; j < NDof; j++ ) {
00920
00921
00922 if(dof[j] == DISPLACEMENT){
00923 U[NDof*i+j] = vp[j] * Config.loadfactor;
00924 }
00925 }
00926 }
00927
00928
00929
00930 InternalForces( dtime, F, U, V );
00931
00932 for( j = 0; j < n; j++ ){
00933 q[j] = F0[j] = V[j] = F[j];
00934 }
00935 k=0;
00936
00937
00938
00939 if(Config.solver == 0){
00940
00941
00942
00943 GCSolver(F, V);
00944
00945 }
00946 else{
00947
00948
00949 SamgSolver( iversion, nna, nnu, matrix, nsys, npnt, ia, ja, avector, F, V );
00950 }
00951
00952 *error = Config.tolerance; needite = 0;
00953
00954 do {
00955
00956
00957 for( i = 0; i < NumNodes; i++ ) {
00958 U[NDof*i] += V[NDof*i];
00959 U[NDof*i+1] += V[NDof*i+1];
00960 if( NDof == 3 ) {
00961 U[NDof*i+2] += V[NDof*i+2];
00962 }
00963 }
00964
00965
00966
00967 InternalForces( dtime, F, U, V);
00968
00969 *error = ComputeError( F, V, error0 );
00970
00971 if( _count_it != NULL )
00972 (*_count_it) ( *iteration, *error, loadstep);
00973
00974 if( _fstop != NULL )
00975 (*_fstop) ( &stop );
00976
00977
00978
00979 needite = NeedIteration( error, iteration, stop );
00980
00981 printf( "\tStep: %d Error: %5.3E\r", *iteration, *error );
00982
00983 if(!needite) break;
00984 if(*error < Config.tolerance) break;
00985
00986 b=c=0.0;
00987 for (j = 0; j < n; j++){
00988 q[j] -= F[j];
00989 b += V[j]*q[j];
00990 c += V[j]*F0[j];
00991 }
00992 for (j = 0; j < n; j++){
00993 v[j][k]= -(pow(fabs(b/c),0.5))*F0[j]-q[j];
00994 w[j][k]= V[j]/b;
00995 V[j] = q[j] = F0[j] = F[j];
00996 }
00997
00998 SearchDirection(n, k, V, w, v);
00999 k ++;
01000 if( k == maxcor ) k = 0;
01001 }while( needite);
01002
01003 free ( q );
01004 free ( F0 );
01005 for(i=0; i < n; i++){
01006 free( w[i] );
01007 free( v[i] );
01008 }
01009 free( w );
01010 free( v );
01011
01012 }
01013
01014
01015
01016
01017 void NRM(double dtime, double *F, double *U, double *V,
01018 int *iteration, double *error, double error0, int loadstep )
01019 {
01020
01021
01022
01023
01024 int i,j,n;
01025 double vp[3];
01026 eRestType dof[3];
01027 int needite = 0;
01028 int stop = 0;
01029 int matrix = 12;
01030 int iversion = 4;
01031 int nsys = 1;
01032 int npnt = 0;
01033
01034 n = NumNodes*NDof;
01035
01036 do {
01037
01038 for( i = 0; i < NumNodes; i++ ) {
01039 dof[0] = NodeVector[i].dof.x;
01040 dof[1] = NodeVector[i].dof.y;
01041 dof[2] = NodeVector[i].dof.z;
01042 vp[0] = NodeVector[i].dof.vpx;
01043 vp[1] = NodeVector[i].dof.vpy;
01044 vp[2] = NodeVector[i].dof.vpz;
01045 for( j = 0; j < NDof; j++ ) {
01046
01047
01048 if(dof[j] == DISPLACEMENT){
01049 U[NDof*i+j] = vp[j] * Config.loadfactor;
01050 }
01051 }
01052 }
01053
01054
01055
01056 InternalForces( dtime, F, U, V );
01057
01058 for( j = 0; j < n; j++ ){
01059 V[j] = F[j];
01060 }
01061
01062
01063
01064 if(Config.solver == 0){
01065
01066
01067
01068 GCSolver(F, V);
01069
01070 }
01071 else{
01072
01073
01074 SamgSolver( iversion, nna, nnu, matrix, nsys, npnt, ia, ja, avector, F, V );
01075
01076 }
01077
01078
01079
01080 for( i = 0; i < NumNodes; i++ ) {
01081 U[NDof*i] += V[NDof*i];
01082 U[NDof*i+1] += V[NDof*i+1];
01083 if( NDof == 3 ) {
01084 U[NDof*i+2] += V[NDof*i+2];
01085 }
01086 }
01087
01088
01089
01090 InternalForces( dtime, F, U, V);
01091
01092 *error = ComputeError( F, V, error0 );
01093
01094 if( _count_it != NULL )
01095 (*_count_it) ( *iteration, *error, loadstep);
01096
01097 if( _fstop != NULL )
01098 (*_fstop) ( &stop );
01099
01100
01101
01102 needite = NeedIteration( error, iteration, stop );
01103
01104 printf( "\tStep: %d Error: %5.3E\r", *iteration, *error );
01105
01106 }while(needite);
01107
01108 }
01109
01110
01111
01112
01113 void LINEAR(double dtime, double *F, double *U, double *V,
01114 int *iteration, double *error, double error0, int loadstep )
01115 {
01116 int i,j;
01117 double vp[3];
01118 eRestType dof[3];
01119 int stop = 0;
01120 int matrix = 12;
01121 int iversion = 4;
01122 int nsys = 1;
01123 int npnt = 0;
01124
01125 for( i = 0; i < NumNodes; i++ ) {
01126 dof[0] = NodeVector[i].dof.x;
01127 dof[1] = NodeVector[i].dof.y;
01128 dof[2] = NodeVector[i].dof.z;
01129 vp[0] = NodeVector[i].dof.vpx;
01130 vp[1] = NodeVector[i].dof.vpy;
01131 vp[2] = NodeVector[i].dof.vpz;
01132 for( j = 0; j < NDof; j++ ) {
01133
01134
01135 if(dof[j] == DISPLACEMENT){
01136 U[NDof*i+j] = vp[j] * Config.loadfactor;
01137 }
01138 }
01139 }
01140
01141
01142
01143 InternalForces( dtime, F, U, V );
01144
01145 for( j = 0; j < NumNodes*NDof; j++ ){
01146 V[j] = F[j];
01147 }
01148
01149
01150
01151 if(Config.solver == 0){
01152
01153
01154
01155 GCSolver(F, V);
01156
01157 }
01158 else{
01159
01160
01161 SamgSolver( iversion, nna, nnu, matrix, nsys, npnt, ia, ja, avector, F, V );
01162 }
01163
01164
01165
01166 for( i = 0; i < NumNodes; i++ ) {
01167 U[NDof*i] += V[NDof*i];
01168 U[NDof*i+1] += V[NDof*i+1];
01169 if( NDof == 3 ) {
01170 U[NDof*i+2] += V[NDof*i+2];
01171 }
01172 }
01173
01174
01175
01176 InternalForces( dtime, F, U, V);
01177
01178 *error = ComputeError( F, V, error0 );
01179
01180 if( _count_it != NULL )
01181 (*_count_it) ( *iteration, *error, loadstep);
01182
01183 if( _fstop != NULL )
01184 (*_fstop) ( &stop );
01185
01186 }
01187
01188
01189
01190 #if 0
01191
01192
01193
01194 void InternalForces( double dtime, double *F, double *U, double *V )
01195 {
01196 int i;
01197 sTensor stress[8], strain[8];
01198 double iforce[24];
01199
01200
01201
01202 for( i = 0; i < NumNodes; i++ ) {
01203 if( NodeVector[i].rezone == NONE ) {
01204 if( NodeVector[i].dof.x == FORCE ) F[NDof*i] = NodeVector[i].dof.vpx * Config.loadfactor;
01205 else F[NDof*i] = 0.0;
01206
01207 if( NodeVector[i].dof.y == FORCE ) F[NDof*i+1] = NodeVector[i].dof.vpy * Config.loadfactor;
01208 else F[NDof*i+1] = 0.0;
01209
01210 if( NDof == 3 ) {
01211 if( NodeVector[i].dof.z == FORCE ) F[NDof*i+2] = NodeVector[i].dof.vpz * Config.loadfactor;
01212 else F[NDof*i+2] = 0.0;
01213 }
01214 }
01215 }
01216
01217
01218
01219 for( i = 0; i < NumElements; i++ ) {
01220
01221
01222 if( ElmList[i]->rezone != NONE )
01223 continue;
01224
01225
01226
01227 ElmStressStrain( ElmList[i], dtime, U, 0L, stress, strain );
01228
01229
01230
01231 if( IsGeomNonLinear && (ElmList[i]->rezone != DONE) )
01232 ElmUpdateStress( ElmList[i], dtime, V, stress );
01233
01234
01235
01236 ElmInterForce( ElmList[i], stress, iforce );
01237
01238
01239
01240 ElmAssVector( ElmList[i], F, iforce );
01241 }
01242
01243 }
01244
01245 #else
01246
01247
01248
01249
01250 void InternalForces( double dtime, double *F, double *U, double *V )
01251 {
01252 int i,j;
01253 sTensor stress[8], strain[8];
01254 double iforce[24];
01255
01256 int nd = 10;
01257 int ei[10], ef[10];
01258 int nelm;
01259 double *Faux;
01260
01261 nelm = NumElements/nd;
01262
01263
01264 ei[0] = 0;
01265 ef[0] = nelm;
01266
01267 for(i = 1; i < (nd-1); i++){
01268 ei[i] = ef[i-1];
01269 ef[i] = ei[i] + nelm;
01270 }
01271 ei[nd-1] = ef[nd-2];
01272 ef[nd-1] = NumElements;
01273
01274
01275 Faux = (double *)calloc( NDof*NumNodes, sizeof(double) );
01276
01277
01278
01279 for( i = 0; i < NumNodes; i++ ) {
01280 if( NodeVector[i].rezone == NONE ) {
01281 if( NodeVector[i].dof.x == FORCE ) F[NDof*i] = NodeVector[i].dof.vpx * Config.loadfactor;
01282 else F[NDof*i] = 0.0;
01283
01284 if( NodeVector[i].dof.y == FORCE ) F[NDof*i+1] = NodeVector[i].dof.vpy * Config.loadfactor;
01285 else F[NDof*i+1] = 0.0;
01286
01287 if( NDof == 3 ) {
01288 if( NodeVector[i].dof.z == FORCE ) F[NDof*i+2] = NodeVector[i].dof.vpz * Config.loadfactor;
01289 else F[NDof*i+2] = 0.0;
01290 }
01291 }
01292 }
01293
01294 for( j = 0; j < nd; j++ ) {
01295
01296 for( i = 0; i < NDof*NumNodes; i++ ) {
01297 Faux[i] = 0.0;
01298 }
01299
01300 for( i = ei[j]; i < ef[j]; i++ ) {
01301
01302
01303
01304
01305 if( ElmList[i]->rezone != NONE )
01306 continue;
01307
01308
01309
01310 ElmStressStrain( ElmList[i], dtime, U, 0L, stress, strain );
01311
01312
01313
01314 if( IsGeomNonLinear && (ElmList[i]->rezone != DONE) )
01315 ElmUpdateStress( ElmList[i], dtime, V, stress );
01316
01317
01318
01319 ElmInterForce( ElmList[i], stress, iforce );
01320
01321
01322
01323 ElmAssVector( ElmList[i], Faux, iforce );
01324 }
01325
01326 for( i = 0; i < NDof*NumNodes; i++ ) {
01327 F[i] += Faux[i];
01328 }
01329
01330 }
01331
01332 free(Faux);
01333
01334
01335 }
01336
01337 #endif
01338
01339
01340
01341
01342 int DisplacementVelocity( int iteration, double alpha, double dtime,
01343 double *FVector, double *VVector,
01344 double *UVector, double *MVector )
01345 {
01346 int i, j;
01347 double a, b, df, disp, veloc;
01348 double vp[3];
01349 eRestType dof[3];
01350
01351
01352
01353 a = 2.0 - (alpha * dtime);
01354 b = 2.0 + (alpha * dtime);
01355
01356 pfs_iter = iteration;
01357
01358
01359
01360 for( i = 0; i < NumNodes; i++ )
01361 {
01362 pfs_node = i;
01363
01364
01365 if( NodeVector[i].rezone != NONE )
01366 continue;
01367
01368
01369
01370 dof[0] = NodeVector[i].dof.x;
01371 dof[1] = NodeVector[i].dof.y;
01372 dof[2] = NodeVector[i].dof.z;
01373 vp[0] = NodeVector[i].dof.vpx;
01374 vp[1] = NodeVector[i].dof.vpy;
01375 vp[2] = NodeVector[i].dof.vpz;
01376
01377
01378
01379 disp = 0.0;
01380 veloc = 0.0;
01381
01382
01383 if((dof[0] == OBJECT) || (dof[1] == OBJECT) || (dof[2] == OBJECT))
01384 {
01385
01386 int idNodeConst = NodeVector[i].constrain.id - 1;
01387
01388 void* ConstrElm = &(NodeVector[i].constrain.curr_elm);
01389
01390 double fl[3];
01391 double vl[3];
01392 double ml = MVector[NDof*i];
01393
01394 sCoord p;
01395
01396 if( iteration == 0 )
01397 {
01398 if( !ConstToLocal(ConstList[idNodeConst], &NodeVector[i].coord,
01399 ConstrElm, vp, fl) )
01400 {
01401 return 0;
01402 }
01403
01404 for(j = 0; j < NDof; j++)
01405 vl[j] = 0.01 * dtime * (fl[j] / (2.0 * ml));
01406
01407 if( !ConstToGlobal(ConstList[idNodeConst], &NodeVector[i].coord,
01408 ConstrElm, vl, &VVector[NDof*i]) )
01409 return 0;
01410
01411
01412 for(j = 0; j < NDof; j++)
01413 UVector[NDof*i+j] += dtime * VVector[NDof*i+j];
01414 }
01415 else
01416 {
01417
01418
01419
01420 p.x = NodeVector[i].coord.x + UVector[NDof*i];
01421 p.y = NodeVector[i].coord.y + UVector[NDof*i+1];
01422 if(NDof == 3)
01423 p.z = NodeVector[i].coord.z + UVector[NDof*i+2];
01424 else
01425 p.z = 0.0;
01426 if( !ConstToLocal(ConstList[idNodeConst], &p, ConstrElm,
01427 &FVector[NDof*i], fl) ) return 0;
01428 if( !ConstToLocal(ConstList[idNodeConst], &p, ConstrElm,
01429 &VVector[NDof*i], vl) ) return 0;
01430
01431
01432 for(j = 0; j < NDof; j++)
01433 vl[j] = ((a / b) * vl[j]) + (2.0 * dtime * (fl[j] / (b * ml)));
01434
01435
01436
01437 fl[2] = vl[2] = 0.0;
01438 if(NDof <= 2)
01439 fl[1] = vl[1] = 0.0;
01440
01441 {
01442 double UVecPrev[3];
01443 sCoord pl;
01444 sCoord delta_u;
01445
01446
01447
01448 delta_u.x = dtime * vl[0];
01449
01450 if(NDof == 3)
01451 delta_u.y = dtime * vl[1];
01452 else
01453 delta_u.y = 0.0;
01454
01455 delta_u.z = 0.0;
01456
01457 if( !ConstSlide(ConstList[idNodeConst], &p, ConstrElm,
01458 &delta_u, vl, &VVector[NDof*i], &pl) )
01459 {
01460
01461 printf( "DisplacementVelocity: Node didn't slide\n" );
01462
01463 }
01464
01465
01466
01467
01468 for(j = 0; j < NDof; j++)
01469 UVecPrev[j] = UVector[NDof*i+j];
01470
01471
01472
01473 UVector[NDof*i] = pl.x - NodeVector[i].coord.x;
01474 UVector[NDof*i+1] = pl.y - NodeVector[i].coord.y;
01475 if(NDof == 3)
01476 UVector[NDof*i+2] = pl.z - NodeVector[i].coord.z;
01477
01478
01479
01480 for(j = 0; j < NDof; j++)
01481 VVector[NDof*i+j] = (UVector[NDof*i+j] - UVecPrev[j]) / dtime;
01482 }
01483 }
01484 }
01485
01486
01487
01488 for( j = 0; j < NDof; j++ ) {
01489
01490
01491 if(MVector[NDof*i+j] != 0.0){
01492
01493 switch( dof[j] ) {
01494 case FORCE:
01495 if( iteration == 0 )
01496 df = vp[j];
01497 else
01498 df = FVector[NDof*i+j];
01499
01500 if( iteration == 0 )
01501 VVector[NDof*i+j] = 0.01 * dtime * (df / (2.0 * MVector[NDof*i+j]));
01502 else
01503 VVector[NDof*i+j] = ((a / b) * VVector[NDof*i+j]) +
01504 (2.0 * dtime * (df / (b * MVector[NDof*i+j])));
01505
01506 UVector[NDof*i+j] += dtime * VVector[NDof*i+j];
01507 break;
01508
01509 case DISPLACEMENT:
01510 VVector[NDof*i+j] = 0.0;
01511 UVector[NDof*i+j] = vp[j] * Config.loadfactor;
01512
01513 if(iteration == 0)
01514 {
01515
01516
01517 if(NodeVector[i].constrain.id)
01518 {
01519
01520
01521 if(!NodeVector[i].pilot)
01522 {
01523 NodeVector[i].dof.x = OBJECT;
01524 NodeVector[i].dof.y = OBJECT;
01525 NodeVector[i].dof.z = OBJECT;
01526 }
01527 }
01528 }
01529 break;
01530
01531 case VELOCITY:
01532 VVector[NDof*i+j] = vp[j];
01533 UVector[NDof*i+j] += dtime * VVector[NDof*i+j];
01534 break;
01535
01536 default:
01537 break;
01538 }
01539 }
01540
01541 if( (NodeVector[i].dspIteration == DSP_YES) && (GpType == 0) )
01542 disp += (UVector[NDof*i+j] * UVector[NDof*i+j]);
01543 else if( (NodeVector[i].dspIteration == DSP_YES) && (GpType == 1) )
01544 veloc += (VVector[NDof*i+j] * VVector[NDof*i+j]);
01545 }
01546
01547 if( (NodeVector[i].dspIteration == DSP_YES) && (GpType == 0) )
01548 XGPSendPoint( NodeVector[i].curve, (double)iteration, sqrt( disp ) );
01549 else if( (NodeVector[i].dspIteration == DSP_YES) && (GpType == 1) )
01550 XGPSendPoint( NodeVector[i].curve, (double)iteration, sqrt( veloc ) );
01551 }
01552 return 1;
01553 }
01554
01555
01556
01557
01558
01559 void MassVector( double *MVector )
01560 {
01561 int i;
01562 double mass[24];
01563
01564
01565
01566 for( i = 0; i < NDof*NumNodes; i++ )
01567 MVector[i] = 0.0;
01568
01569
01570
01571 for( i = 0; i < NumElements; i++ ) {
01572
01573
01574 if( ElmList[i]->rezone == DONE )
01575 continue;
01576
01577
01578
01579 ElmMass( ElmList[i], mass );
01580
01581
01582
01583 ElmAssVector( ElmList[i], MVector, mass );
01584 }
01585
01586 }
01587
01588
01589
01590
01591
01592 int DoRezone( int step, double *FVector )
01593 {
01594 int i, j, id, numnodes;
01595 int inc[8];
01596
01597
01598
01599 if( Rezone == 0L )
01600 return( 0 );
01601
01602
01603
01604 for( i = 0; i < Rezone[step-1].numelm; i++ ) {
01605 id = Rezone[step-1].elm[i] - 1;
01606 if( ElmList[id]->rezone == NONE ) ElmList[id]->rezone = TODO;
01607 else ElmList[id]->rezone = DONE;
01608 }
01609
01610
01611
01612 for( i = 0; i < NumNodes; i++ )
01613 NodeVector[i].rezone = DONE;
01614
01615 for( i = 0; i < NumElements; i++ ) {
01616 if( ElmList[i]->rezone == NONE ) {
01617 ElmConnect( ElmList[i], inc );
01618 ElmNumNodes( ElmList[i], &numnodes );
01619 for( j = 0; j < numnodes; j++ )
01620 NodeVector[inc[j]-1].rezone = NONE;
01621 }
01622 }
01623
01624
01625
01626 UpdatePrescribedValues( FVector );
01627
01628
01629
01630 for( i = 0; i < NumElements; i++ )
01631 if( ElmList[i]->rezone == TODO )
01632 ElmList[i]->rezone = DONE;
01633
01634 return( 1 );
01635
01636 }
01637
01638
01639
01640
01641
01642 void PercolationForces( double *F )
01643 {
01644 int i;
01645 double pforce[24];
01646
01647
01648
01649 for( i = 0; i < NumElements; i++ ) {
01650
01651
01652 if( ElmList[i]->rezone != NONE )
01653 continue;
01654
01655
01656
01657 ElmPercForce( ElmList[i], pforce );
01658
01659
01660
01661 ElmAssVector( ElmList[i], F, pforce );
01662 }
01663
01664 }
01665
01666
01667
01668