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
00099
00100
00101
00102 #include <stdlib.h>
00103 #include <math.h>
00104 #include "constrain.h"
00105 #include "rio.h"
00106
00107 typedef struct _curvedata
00108 {
00109 double jac[3][3];
00110 double ijac[3][3];
00111 } sCCurveData;
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 static double Tolerance = 1.0e+10;
00123
00124
00125
00126
00127 #ifndef ZERO
00128 #define ZERO(v) ((fabs(v)<Tolerance)?1:0)
00129 #endif
00130
00131
00132
00133
00134 #ifndef MIN
00135 #define MIN(a,b) ((a<b)?a:b)
00136 #endif
00137
00138
00139
00140
00141 #ifndef MAX
00142 #define MAX(a,b) ((a>b)?a:b)
00143 #endif
00144
00145
00146
00147
00148
00149
00150
00157 static void DiffVec( sCoord *in0, sCoord *in1, sCoord *out )
00158 {
00159 out->x = in0->x - in1->x;
00160 out->y = in0->y - in1->y;
00161 out->z = in0->z - in1->z;
00162 }
00163
00170 static double ProdEscalar( sCoord *in0, sCoord* in1 )
00171 {
00172 double prod;
00173 prod = (in0->x)*(in1->x) + (in0->y)*(in1->y) + (in0->z)*(in1->z);
00174
00175 return (prod);
00176 }
00177
00184 static void CrossProd( sCoord *in0, sCoord *in1, sCoord *out )
00185 {
00186 out->x = (in0->y * in1->z) - (in0->z * in1->y);
00187 out->y = (in0->z * in1->x) - (in0->x * in1->z);
00188 out->z = (in0->x * in1->y) - (in0->y * in1->x);
00189 }
00190
00194 static double VecLen( sCoord *vec )
00195 {
00196 return(sqrt((vec->x * vec->x) + (vec->y * vec->y) + (vec->z * vec->z)));
00197 }
00198
00202 static double Dist( sCoord *in0, sCoord *in1 )
00203 {
00204 sCoord tmp;
00205
00206 DiffVec(in1, in0, &tmp);
00207
00208 return(VecLen(&tmp));
00209 }
00210
00215 static void VecNormalize( sCoord *vec, sCoord *n )
00216 {
00217 double len;
00218
00219 len = VecLen(vec);
00220
00221 n->x = vec->x / len;
00222 n->y = vec->y / len;
00223 n->z = vec->z / len;
00224 }
00225
00230 static sCoord DirNormalize( sCoord* p1, sCoord* p2 )
00231 {
00232 sCoord dr;
00233 sCoord nrm;
00234
00235 dr.x = p2->x - p1->x;
00236 dr.y = p2->y - p1->y;
00237 dr.z = p2->z - p1->z;
00238
00239 VecNormalize(&dr,&nrm);
00240
00241 return nrm;
00242 }
00243
00253 static int LineBounds( sCoord *c, sCoord *pi, sCoord *pf )
00254 {
00255 double aux;
00256
00257 aux = MIN(pi->x, pf->x);
00258 if(c->x < aux) if(!ZERO(c->x - aux)) return(0);
00259 aux = MAX(pi->x, pf->x);
00260 if(c->x > aux) if(!ZERO(c->x - aux)) return(0);
00261
00262 aux = MIN(pi->y, pf->y);
00263 if(c->y < aux) if(!ZERO(c->y - aux)) return(0);
00264 aux = MAX(pi->y, pf->y);
00265 if(c->y > aux) if(!ZERO(c->y - aux)) return(0);
00266
00267 aux = MIN(pi->z, pf->z);
00268 if(c->z < aux) if(!ZERO(c->z - aux)) return(0);
00269 aux = MAX(pi->z, pf->z);
00270 if(c->z > aux) if(!ZERO(c->z - aux)) return(0);
00271
00272 return(1);
00273 }
00274
00282 static int Invert3x3( double a[3][3], double b[3][3] )
00283 {
00284 double det;
00285 int i, j;
00286
00287
00288 for(i = 0; i < 3; i++)
00289 for(j = 0; j < 3; j++)
00290 b[i][j] = 0.0 ;
00291
00292
00293 det = a[0][0] * (a[1][1] * a[2][2] - a[1][2] * a[2][1]) -
00294 a[0][1] * (a[1][0] * a[2][2] - a[1][2] * a[2][0]) +
00295 a[0][2] * (a[1][0] * a[2][1] - a[1][1] * a[2][0]) ;
00296
00297
00298 if(ZERO(det))
00299 return 0;
00300
00301
00302 b[0][0] = (a[1][1] * a[2][2] - a[1][2] * a[2][1]) / det ;
00303 b[0][1] = -(a[0][1] * a[2][2] - a[0][2] * a[2][1]) / det ;
00304 b[0][2] = (a[0][1] * a[1][2] - a[0][2] * a[1][1]) / det ;
00305 b[1][0] = -(a[1][0] * a[2][2] - a[1][2] * a[2][0]) / det ;
00306 b[1][1] = (a[0][0] * a[2][2] - a[0][2] * a[2][0]) / det ;
00307 b[1][2] = -(a[0][0] * a[1][2] - a[0][2] * a[1][0]) / det ;
00308 b[2][0] = (a[1][0] * a[2][1] - a[1][1] * a[2][0]) / det ;
00309 b[2][1] = -(a[0][0] * a[2][1] - a[0][1] * a[2][0]) / det ;
00310 b[2][2] = (a[0][0] * a[1][1] - a[0][1] * a[1][0]) / det ;
00311
00312 return 1;
00313 }
00314
00324 static int CheckPoint( sCoord *c, sCoord *pi, sCoord *pf )
00325 {
00326 sCoord du, dv, dw;
00327 double coef[3][3];
00328 double cinv[3][3];
00329
00330
00331 DiffVec(pf, pi, &du);
00332 DiffVec(c, pi, &dv);
00333
00334
00335 CrossProd(&du, &dv, &dw);
00336
00337
00338 coef[0][0] = du.x; coef[0][1] = dv.x; coef[0][2] = dw.x;
00339 coef[1][0] = du.y; coef[1][1] = dv.y; coef[1][2] = dw.y;
00340 coef[2][0] = du.z; coef[2][1] = dv.z; coef[2][2] = dw.z;
00341
00342
00343 if(!Invert3x3(coef, cinv))
00344 {
00345
00346
00347
00348
00349
00350 if(!LineBounds(c, pi, pf))
00351 return(0);
00352 else
00353 return(1);
00354 }
00355
00356 return(0);
00357 }
00358
00359
00360 static int _checkPointInExtrem(sConstrain *c, sCoord *p, int *id )
00361 {
00362 sCoord d, dp, n;
00363 double area;
00364 sCoord *pi;
00365 sCoord *pf;
00366 int inc[2];
00367 double TOL = 0.001;
00368
00369
00370
00371
00372
00373
00374
00375 ElmConnect(c->elems[0], inc);
00376 pi = &c->nodes[inc[0]-1].coord;
00377 pf = &c->nodes[inc[1]-1].coord;
00378 d = DirNormalize(pi, pf);
00379 dp = DirNormalize( p, pf );
00380
00381
00382 CrossProd(&d, &dp, &n);
00383 area = VecLen( &n );
00384
00385
00386 if( area < TOL )
00387 {
00388 if( ProdEscalar( &d, &dp ) > 0 )
00389 {
00390
00391 *id = 0;
00392 return( 1 );
00393 }
00394 }
00395
00396
00397
00398
00399
00400
00401 ElmConnect(c->elems[c->numElems-1], inc);
00402 pi = &c->nodes[inc[0]-1].coord;
00403 pf = &c->nodes[inc[1]-1].coord;
00404 d = DirNormalize(pf, pi);
00405 dp = DirNormalize( p, pi );
00406
00407
00408 CrossProd(&d, &dp, &n);
00409 area = VecLen( &n );
00410
00411 if( area < TOL )
00412 {
00413
00414 if( ProdEscalar( &d, &dp ) > 0 )
00415 {
00416
00417 *id = c->numElems-1;
00418 return( 1 );
00419 }
00420 }
00421 return( 0 );
00422 }
00423
00431 static int PolyInvSurf( sConstrain *c, sCoord *p, double *dist )
00432 {
00433 int flag = 0;
00434 int e;
00435 int inc[2];
00436 int id;
00437 double tol = 0.000001;
00438
00439
00440
00441 *dist = 0.0;
00442
00443
00444
00445 ElmConnect(c->elems[0], inc);
00446
00447 if((Dist(&c->nodes[inc[0]-1].coord, p)) < tol)
00448 {
00449 id = 0;
00450 *dist = 0.0;
00451 return(id);
00452 }
00453
00454
00455
00456
00457 for(e = 0; e < c->numElems; e++)
00458 {
00459 ElmConnect(c->elems[e], inc);
00460 if(CheckPoint(p, &c->nodes[inc[0]-1].coord, &c->nodes[inc[1]-1].coord))
00461 {
00462 id = e;
00463 flag = 1;
00464 *dist += Dist(&c->nodes[inc[0]-1].coord, p);
00465 break;
00466 }
00467 *dist += Dist(&c->nodes[inc[0]-1].coord, &c->nodes[inc[1]-1].coord);
00468 }
00469
00470
00471
00472 if(!flag)
00473 {
00474 flag = _checkPointInExtrem(c, p, &id );
00475
00476 if( !flag )
00477 {
00478 id = -1;
00479 *dist = 0.0;
00480 return(id);
00481 }
00482 ElmConnect(c->elems[id], inc);
00483
00484 if( id == 0 )
00485 *dist = 0.0;
00486 else
00487 *dist += Dist(&c->nodes[inc[1]-1].coord, p);
00488 }
00489
00490 return(id);
00491 }
00492
00500 static int _curvePolySlide( sConstrain *c, double dist, void **elm, sCoord *p )
00501 {
00502 double dist_pol = 0.0;
00503 int flag = 0;
00504 double D, Dx, Dy, Dz, d;
00505 int e;
00506 int inc[2];
00507 double tol = 0.000001;
00508 int first = 0;
00509
00510
00511
00512
00513 if(dist < 0.0)
00514 {
00515
00516
00517 ElmConnect(c->elems[0], inc);
00518 *elm = c->elems[0];
00519 first = 1;
00520 dist_pol = Dist(&c->nodes[inc[1]-1].coord, &c->nodes[inc[0]-1].coord);
00521 }
00522
00523
00524
00525
00526 if(fabs( dist ) < tol)
00527 {
00528
00529 ElmConnect(c->elems[0], inc);
00530 p->x = c->nodes[inc[0]-1].coord.x;
00531 p->y = c->nodes[inc[0]-1].coord.y;
00532 p->z = c->nodes[inc[0]-1].coord.z;
00533 *elm = c->elems[0];
00534
00535 return(0);
00536 }
00537 if( !first )
00538 {
00539
00540
00541 for(e = 0; e < c->numElems; e++)
00542 {
00543 ElmConnect(c->elems[e], inc);
00544 dist_pol += Dist(&c->nodes[inc[0]-1].coord, &c->nodes[inc[1]-1].coord);
00545 if((dist_pol > dist) || (fabs(dist_pol - dist)<0.00001))
00546 {
00547
00548 flag = 1;
00549 *elm = c->elems[e];
00550 break;
00551 }
00552 }
00553 }
00554
00555
00556
00557
00558 if( !first && !flag )
00559 {
00560
00561
00562 *elm = c->elems[c->numElems-1];
00563 ElmConnect(c->elems[c->numElems-1], inc);
00564 }
00565
00566 D = Dist(&c->nodes[inc[1]-1].coord, &c->nodes[inc[0]-1].coord);
00567 Dx = c->nodes[inc[1]-1].coord.x - c->nodes[inc[0]-1].coord.x;
00568 Dy = c->nodes[inc[1]-1].coord.y - c->nodes[inc[0]-1].coord.y;
00569 Dz = c->nodes[inc[1]-1].coord.z - c->nodes[inc[0]-1].coord.z;
00570 d = dist - dist_pol;
00571
00572 p->x = c->nodes[inc[1]-1].coord.x + (d * Dx) / D;
00573 p->y = c->nodes[inc[1]-1].coord.y + (d * Dy) / D;
00574 p->z = c->nodes[inc[1]-1].coord.z + (d * Dz) / D;
00575
00576 return(1);
00577 }
00578
00583 static void EvaluateTolerance( sConstrain *c )
00584 {
00585 int inc[3];
00586 double dist = 0.0;
00587 double auxTol = 0.0;
00588 int i;
00589
00590 for(i = 0; i < c->numElems; i++)
00591 {
00592 ElmConnect(c->elems[i],inc);
00593 dist = Dist(&c->nodes[inc[1]-1].coord, &c->nodes[inc[0]-1].coord);
00594 auxTol = dist * 0.1;
00595 if(auxTol < Tolerance)
00596 Tolerance = auxTol;
00597 }
00598
00599 }
00600
00604 static int _curveToLocal(sConstrain *c, sCoord *p, void **elm, double jac[3][3])
00605 {
00606 int e, i, j;
00607 int inc[2];
00608 double jace[3][3], ijace[3][3];
00609 int found = 0;
00610
00611 if( !(*elm) )
00612 {
00613 for(e = 0; e < c->numElems; e++)
00614 {
00615 ElmConnect(c->elems[e],inc);
00616 if(CheckPoint(p, &c->nodes[inc[0]-1].coord, &c->nodes[inc[1]-1].coord))
00617 {
00618 ElmJacobian(c->elems[e],jace,ijace);
00619 *elm = c->elems[e];
00620 found = 1;
00621 break;
00622 }
00623 }
00624
00625 if(!found)
00626 {
00627 found = _checkPointInExtrem(c, p, &e );
00628
00629 if( !found )
00630 {
00631 fprintf(stderr, "Could not find element(1).\n\n");
00632 *elm = NULL;
00633 return 0;
00634 }
00635 ElmJacobian(c->elems[e],jace,ijace);
00636 *elm = c->elems[e];
00637 }
00638 }
00639 else
00640 {
00641 sElement *_elm = (sElement*)(*elm);
00642
00643 ElmJacobian( _elm, jace, ijace );
00644 }
00645
00646 for( i = 0; i < 3; i++ )
00647 for( j = 0; j < 3; j++ )
00648 jac[i][j] = jace[i][j];
00649
00650 return 1;
00651
00652 }
00653
00657 static int _curveToGlobal( sConstrain *c, sCoord *p,
00658 void **elm, double ijac[3][3] )
00659 {
00660 int i, j;
00661 int inc[2];
00662 double jace[3][3], ijace[3][3];
00663 int found = 0;
00664
00665 if( !(*elm) )
00666 {
00667 for(i = 0; i < c->numElems; i++)
00668 {
00669 ElmConnect(c->elems[i],inc);
00670 if(CheckPoint(p, &c->nodes[inc[0]-1].coord, &c->nodes[inc[1]-1].coord))
00671 {
00672 ElmJacobian(c->elems[i],jace,ijace);
00673 *elm = c->elems[i];
00674 found = 1;
00675 break;
00676 }
00677 }
00678
00679 if(!found)
00680 {
00681 found = _checkPointInExtrem(c, p, &i );
00682
00683 if( !found )
00684 {
00685 fprintf(stderr, "Could not find element(2).\n\n");
00686 *elm = NULL;
00687 return 0;
00688 }
00689 ElmJacobian(c->elems[i],jace,ijace);
00690 *elm = c->elems[i];
00691 }
00692 }
00693 else
00694 {
00695 sElement *_elm = ((sElement*)(*elm));
00696
00697 ElmJacobian( _elm, jace, ijace );
00698 }
00699
00700 for( i = 0; i < 3; i++ )
00701 for( j = 0; j < 3; j++ )
00702 ijac[i][j] = ijace[i][j];
00703
00704 return 1;
00705
00706 }
00707
00711 static int _curveSlide( sConstrain *c, sCoord *p, void **elm, sCoord *d,
00712 double ijac[3][3], sCoord *pl )
00713 {
00714 int i, j;
00715 int inc[2];
00716 double jace[3][3], ijace[3][3];
00717 double dist_p;
00718 double dist_pl;
00719 int id_p;
00720 int status;
00721
00722
00723 id_p = PolyInvSurf(c, p, &dist_p);
00724 if(id_p == -1)
00725 {
00726 fprintf(stderr, "Could not find element(3).\n\n");
00727 return 0;
00728 }
00729
00730
00731 dist_pl = dist_p + d->x;
00732
00733
00734
00735
00736 status = _curvePolySlide(c, dist_pl, elm, pl);
00737 if(!status)
00738 {
00739 pl->x = p->x;
00740 pl->y = p->y;
00741 pl->z = p->z;
00742 }
00743
00744
00745 {
00746 sElement *_elm = (sElement*)(*elm);
00747
00748 ElmConnect( _elm, inc );
00749 ElmJacobian( _elm, jace, ijace );
00750 }
00751
00752 for(i = 0; i < 3; i++)
00753 for(j = 0; j < 3; j++)
00754 ijac[i][j] = ijace[i][j];
00755
00756 return 1;
00757
00758 }
00759
00760
00761
00762
00763
00764
00765
00766
00767 static void ConstCurveNew(int, int, int, sConstrain **, sConstrain **);
00768 static void ConstCurveFree(sConstrain *);
00769 static void ConstCurveRead(sConstrain *);
00770 static void ConstCurveBuild(sConstrain *);
00771
00775 static void ConstCurveNew( int label, int num_nodes, int num_elems,
00776 sConstrain **c, sConstrain **clst )
00777 {
00778 sCCurveData *data = NULL;
00779
00780
00781
00782
00783
00784
00785 num_nodes += 2;
00786 num_elems += 2;
00787
00788 data = (sCCurveData *)calloc(num_nodes, sizeof(sCCurveData));
00789
00790 (*c) = (sConstrain *)malloc(sizeof(sConstrain));
00791 (*c)->type = CURVE;
00792 (*c)->label = label;
00793 (*c)->numNodes = num_nodes;
00794 (*c)->numElems = num_elems;
00795 (*c)->nodes = (sNode *)calloc(num_nodes, sizeof(sNode));
00796 (*c)->elems = (sElement **)calloc(num_elems, sizeof(sElement *));
00797 (*c)->data = data;
00798
00799 clst[ContNumConstrainRead] = (*c);
00800 ContNumConstrainRead++;
00801
00802 }
00803
00807 static void ConstCurveFree(sConstrain *c)
00808 {
00809 int i;
00810
00811 if( c->data ) {
00812 free(c->data);
00813 }
00814
00815 if( c->numNodes != 0 ) {
00816 free(c->nodes);
00817 }
00818
00819 if( c->numElems != 0 ) {
00820 for( i = 0; i < c->numElems; i++ ) {
00821 ElmFree(c->elems[i]);
00822 }
00823 free(c->elems);
00824 }
00825 c->numNodes = 0;
00826 c->numElems = 0;
00827 c->nodes = NULL;
00828 c->elems = NULL;
00829 c->data = NULL;
00830
00831 }
00832
00836 static void ConstCurveRead(sConstrain *c)
00837 {
00838 int i, id;
00839 double x, y, z;
00840 int matid, tckid, ordid;
00841 sElement *elm = NULL;
00842
00843 #if 0
00844 static int first = 0;
00845 if(!first)
00846 {
00847 for( i = 0; i < c->numNodes; i++ )
00848 {
00849 fscanf(nf, "%d %lf %lf %lf", &id, &x, &y, &z);
00850 c->nodes[i].id = id;
00851 c->nodes[i].coord.x = x;
00852 c->nodes[i].coord.y = y;
00853 c->nodes[i].coord.z = z;
00854 c->nodes[i].dof.x = FORCE;
00855 c->nodes[i].dof.y = FORCE;
00856 c->nodes[i].dof.z = FORCE;
00857 c->nodes[i].dof.psi = 0.0;
00858 c->nodes[i].rezone = NONE;
00859 c->nodes[i].curve = 0;
00860 c->nodes[i].dspIteration = DSP_NO;
00861 c->nodes[i].dspTime = DSP_NO;
00862 }
00863
00864 for( i = 0; i < c->numElems; i++ )
00865 {
00866 fscanf(nf, "%d%d%d%d", &id, &matid, &tckid, &ordid);
00867 ElmNew(LINE2,id,matid,ordid,tckid,&elm,c->elems,c->nodes);
00868 ElmRead(elm);
00869 }
00870 first = 1;
00871 }
00872 else
00873 {
00874 #else
00875
00876
00877
00878
00879
00880
00881
00882
00883 for(i = 1; i < c->numNodes - 1; i++)
00884 {
00885 fscanf(nf, "%d %lf %lf %lf", &id, &x, &y, &z);
00886 c->nodes[i].id = id+1;
00887 c->nodes[i].coord.x = x;
00888 c->nodes[i].coord.y = y;
00889 c->nodes[i].coord.z = z;
00890 c->nodes[i].dof.x = FORCE;
00891 c->nodes[i].dof.y = FORCE;
00892 c->nodes[i].dof.z = FORCE;
00893 c->nodes[i].dof.psi = 0.0;
00894 c->nodes[i].rezone = NONE;
00895 c->nodes[i].curve = 0;
00896 c->nodes[i].dspIteration = DSP_NO;
00897 c->nodes[i].dspTime = DSP_NO;
00898 }
00899
00900
00901
00902 for(i = 1; i < c->numElems - 1; i++)
00903 {
00904 fscanf(nf, "%d%d%d%d", &id, &matid, &tckid, &ordid);
00905 ElmNew(LINE2, id+1, matid, ordid, tckid, &elm, c->elems, c->nodes);
00906 ElmRead(elm);
00907 }
00908
00909
00910
00911
00912 for(i = 1; i < c->numElems - 1; i++)
00913 {
00914 ElmUpdateConnect(c->elems[i]);
00915 }
00916
00917
00918
00919
00920
00921 {
00922 sCoord dirn;
00923 int inc[2];
00924 sCoord pe;
00925 double extension = 10.0;
00926 int lastElem;
00927 int lastNode;
00928
00929
00930
00931 ElmConnect(c->elems[1], inc);
00932 dirn = DirNormalize(&c->nodes[inc[1]-1].coord, &c->nodes[inc[0]-1].coord);
00933 pe.x = c->nodes[inc[0]-1].coord.x + extension * dirn.x;
00934 pe.y = c->nodes[inc[0]-1].coord.y + extension * dirn.y;
00935 pe.z = c->nodes[inc[0]-1].coord.z + extension * dirn.z;
00936 c->nodes[0].id = 1;
00937 c->nodes[0].coord.x = pe.x;
00938 c->nodes[0].coord.y = pe.y;
00939 c->nodes[0].coord.z = pe.z;
00940 c->nodes[0].dof.x = FORCE;
00941 c->nodes[0].dof.y = FORCE;
00942 c->nodes[0].dof.z = FORCE;
00943 c->nodes[0].dof.psi = 0.0;
00944 c->nodes[0].rezone = NONE;
00945 c->nodes[0].curve = 0;
00946 c->nodes[0].dspIteration = DSP_NO;
00947 c->nodes[0].dspTime = DSP_NO;
00948 ElmNew(LINE2, 1, 1, 1, 1, &elm, c->elems, c->nodes);
00949 inc[0] = 1;
00950 inc[1] = 2;
00951 ElmSetConnect(elm, inc);
00952
00953
00954
00955 lastElem = c->numElems - 1;
00956 lastNode = c->numNodes - 1;
00957 ElmConnect(c->elems[lastElem-1], inc);
00958 dirn = DirNormalize(&c->nodes[inc[0]-1].coord, &c->nodes[inc[1]-1].coord);
00959 pe.x = c->nodes[inc[1]-1].coord.x + extension * dirn.x;
00960 pe.y = c->nodes[inc[1]-1].coord.y + extension * dirn.y;
00961 pe.z = c->nodes[inc[1]-1].coord.z + extension * dirn.z;
00962 c->nodes[lastNode].id = c->numNodes;
00963 c->nodes[lastNode].coord.x = pe.x;
00964 c->nodes[lastNode].coord.y = pe.y;
00965 c->nodes[lastNode].coord.z = pe.z;
00966 c->nodes[lastNode].dof.x = FORCE;
00967 c->nodes[lastNode].dof.y = FORCE;
00968 c->nodes[lastNode].dof.z = FORCE;
00969 c->nodes[lastNode].dof.psi = 0.0;
00970 c->nodes[lastNode].rezone = NONE;
00971 c->nodes[lastNode].curve = 0;
00972 c->nodes[lastNode].dspIteration = DSP_NO;
00973 c->nodes[lastNode].dspTime = DSP_NO;
00974 ElmNew(LINE2, c->numElems, 1, 1, 1, &elm, c->elems, c->nodes);
00975 inc[0] = inc[0] + 1;
00976 inc[1] = inc[1] + 1;
00977 ElmSetConnect(elm, inc);
00978 }
00979 #endif
00980
00981 EvaluateTolerance(c);
00982
00983 }
00984
00988 static void ConstCurveBuild(sConstrain *c)
00989 {
00990 int i, j, n, k, l;
00991 int inc[3];
00992 double jac[3][3], ijac[3][3];
00993 int *count = NULL;
00994 sCCurveData *data = NULL;
00995
00996 count = (int *)calloc(c->numNodes, sizeof(int));
00997 data = (sCCurveData *)c->data;
00998
00999 for( i = 0; i < c->numElems; i++ ) {
01000 ElmNumNodes(c->elems[i],&n);
01001 ElmConnect(c->elems[i],inc);
01002 ElmJacobian(c->elems[i],jac,ijac);
01003 for( j = 0; j < n; j++ ) {
01004 for( k = 0; k < 3; k++ ) {
01005 for( l = 0; l < 3; l++ ) {
01006 data[inc[j]-1].jac[k][l] += jac[k][l];
01007 data[inc[j]-1].ijac[k][l] += ijac[k][l];
01008 }
01009 }
01010 count[inc[j]-1]++;
01011 }
01012 }
01013
01014 for( i = 0; i < c->numNodes; i++ ) {
01015 for( k = 0; k < 3; k++ ) {
01016 for( l = 0; l < 3; l++ ) {
01017 data[i].jac[k][l] /= count[i];
01018 data[i].ijac[k][l] /= count[i];
01019 }
01020 }
01021 }
01022
01023 free(count);
01024
01025 }
01026
01030 static int ConstCurveLocal(sConstrain *c, sCoord *p, void **elm,
01031 double *g, double *l)
01032 {
01033 int i, j;
01034 double jac[3][3];
01035
01036 if(!_curveToLocal(c, p, elm, jac))
01037 return 0;
01038
01039 for(i = 0; i < NDof; i++)
01040 {
01041 l[i] = 0.0;
01042 for(j = 0; j < NDof; j++)
01043 l[i] += jac[i][j] * g[j];
01044 }
01045
01046 return 1;
01047
01048 }
01049
01053 static int ConstCurveGlobal(sConstrain *c, sCoord *p, void **elm,
01054 double *l, double *g)
01055 {
01056 int i, j;
01057 double ijac[3][3];
01058
01059 if(!_curveToGlobal(c, p, elm, ijac))
01060 return 0;
01061
01062 for(i = 0; i < NDof; i++)
01063 {
01064 g[i] = 0.0;
01065 for( j = 0; j < NDof; j++ )
01066 g[i] += ijac[i][j] * l[j];
01067 }
01068
01069 return 1;
01070
01071 }
01072
01076 static int ConstCurveSlide( sConstrain *c, sCoord *p, void **elm, sCoord *d,
01077 double *l, double *g, sCoord *pl )
01078 {
01079 int i, j;
01080 double ijac[3][3];
01081
01082 if(!_curveSlide(c, p, elm, d, ijac, pl))
01083 return 0;
01084
01085 for(i = 0; i < NDof; i++)
01086 {
01087 g[i] = 0.0;
01088 for(j = 0; j < NDof; j++)
01089 g[i] += ijac[i][j] * l[j];
01090 }
01091
01092 return 1;
01093
01094 }
01095
01096
01097
01098
01099
01103 void ConstCurveInit(void);
01104 void ConstCurveInit(void)
01105 {
01106 ConstClass[CURVE].new = ConstCurveNew;
01107 ConstClass[CURVE].free = ConstCurveFree;
01108 ConstClass[CURVE].read = ConstCurveRead;
01109 ConstClass[CURVE].build = ConstCurveBuild;
01110 ConstClass[CURVE].local = ConstCurveLocal;
01111 ConstClass[CURVE].global = ConstCurveGlobal;
01112 ConstClass[CURVE].slide = ConstCurveSlide;
01113
01114 Tolerance = 1.0e+10;
01115
01116 }
01117
01118
01119
01120
01121
01122