00001
00034
00035
00036
00037 #include <stdlib.h>
00038 #include <math.h>
00039 #include "constrain.h"
00040 #include "rio.h"
00041
00042 #include "geo.h"
00043 #include "pfs.h"
00044
00045 typedef struct _surfacedata
00046 {
00047 void *pfsSurface;
00048 } sCSurfaceData;
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 static double Tolerance = 1.0e+10;
00059
00060
00061
00062
00063 #ifndef ZERO
00064 #define ZERO(v) ((fabs(v)<Tolerance)?1:0)
00065 #endif
00066
00067
00068
00069
00070 #ifndef MIN
00071 #define MIN(a,b) ((a<b)?a:b)
00072 #endif
00073
00074
00075
00076
00077 #ifndef MAX
00078 #define MAX(a,b) ((a>b)?a:b)
00079 #endif
00080
00081
00082
00083
00084
00085
00086
00090 static void Inverse( double m[3][3], double d[3][3] )
00091 {
00092 double det = m[0][0] * ((m[1][1] * m[2][2]) - (m[1][2] * m[2][1])) -
00093 m[0][1] * ((m[1][0] * m[2][2]) - (m[1][2] * m[2][0])) +
00094 m[0][2] * ((m[1][0] * m[2][1]) - (m[1][1] * m[2][0]));
00095
00096 d[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / det;
00097 d[0][1] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1]) / det;
00098 d[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / det;
00099 d[1][0] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0]) / det;
00100 d[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / det;
00101 d[1][2] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0]) / det;
00102 d[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / det;
00103 d[2][1] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0]) / det;
00104 d[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / det;
00105
00106 }
00107
00111 static double VecLen( sCoord *vec )
00112 {
00113 return(sqrt((vec->x * vec->x) + (vec->y * vec->y) + (vec->z * vec->z)));
00114 }
00115
00119 static double Dist( sCoord *in0, sCoord *in1 )
00120 {
00121 sCoord tmp;
00122
00123 tmp.x = in1->x - in0->x;
00124 tmp.y = in1->y - in0->y;
00125 tmp.y = in1->z - in0->z;
00126
00127 return(VecLen(&tmp));
00128 }
00129
00134 static void EvaluateTolerance( sConstrain *c )
00135 {
00136 int inc[3];
00137 sCSurfaceData *data = NULL;
00138 double dist1 = 0.0;
00139 double dist2 = 0.0;
00140 double dist3 = 0.0;
00141 double auxTol1 = 0.0;
00142 double auxTol2 = 0.0;
00143 double auxTol3 = 0.0;
00144 int i;
00145
00146 data = (sCSurfaceData *)c->data;
00147
00148 for(i = 0; i < c->numElems; i++)
00149 {
00150 ElmConnect(c->elems[i],inc);
00151 dist1 = Dist(&c->nodes[inc[1]-1].coord, &c->nodes[inc[0]-1].coord);
00152 dist2 = Dist(&c->nodes[inc[2]-1].coord, &c->nodes[inc[1]-1].coord);
00153 dist3 = Dist(&c->nodes[inc[0]-1].coord, &c->nodes[inc[2]-1].coord);
00154 auxTol1 = dist1 * 0.1;
00155 auxTol2 = dist2 * 0.1;
00156 auxTol3 = dist3 * 0.1;
00157 if(auxTol1 < Tolerance)
00158 Tolerance = auxTol1;
00159 if(auxTol2 < Tolerance)
00160 Tolerance = auxTol2;
00161 if(auxTol3 < Tolerance)
00162 Tolerance = auxTol3;
00163 }
00164
00165 }
00166
00171
00178 static int _surfaceCurrElemTransfMtx( double transf[3][3] )
00179 {
00180 int i;
00181 int nnode = 3;
00182 PFSGeoPoint pn[3], n[3];
00183
00184 for(i = 0; i < nnode; i++)
00185 {
00186 int id;
00187 pfsRItrElemNode( &id );
00188 pfsRItrNodeCoords(id, &(pn[i].x), &(pn[i].y), &(pn[i].z));
00189 }
00190
00191
00192
00193 PFSGeoDiffVec(&(pn[1]), &(pn[0]), &(n[0]));
00194
00195
00196
00197 pfsRItrElemNormal(&(n[2].x), &(n[2].y), &(n[2].z));
00198
00199
00200
00201 PFSGeoCrossProd(&n[2], &n[0], &n[1]);
00202
00203
00204
00205 PFSGeoVecNormalize(&n[0], &n[0]);
00206 PFSGeoVecNormalize(&n[1], &n[1]);
00207 PFSGeoVecNormalize(&n[2], &n[2]);
00208
00209
00210
00211 for(i=0; i<nnode; ++i)
00212 {
00213 transf[i][0] = n[i].x;
00214 transf[i][1] = n[i].y;
00215 transf[i][2] = n[i].z;
00216 }
00217
00218 return 1;
00219 }
00220
00221 static int _surfaceToLocal( sConstrain *c, sCoord *p,
00222 void **elm, double transf[3][3] )
00223 {
00224 int found = 0;
00225 sCSurfaceData *data = (sCSurfaceData *)c->data;
00226
00227 pfsRActivateSurf(data->pfsSurface);
00228
00229 if( !(*elm) )
00230 {
00231
00232 found = pfsRGetElem( p->x, p->y, p->z, elm );
00233
00234 if(!found)
00235 {
00236
00237
00238 found = pfsRGetLoopElem( p->x, p->y, p->z, elm );
00239 if( !found )
00240 {
00241 fprintf(stderr, "Could not find element(ToLocal).\n\n");
00242 *elm = NULL;
00243 return 0;
00244 }
00245 }
00246 }
00247
00248
00249 pfsRSetCurrElem( *elm );
00250
00251
00252 _surfaceCurrElemTransfMtx( transf );
00253
00254 return 1;
00255 }
00260 static void _invertMtx( double m[3][3], double i[3][3] )
00261 {
00262 double det = m[0][0] * ((m[1][1] * m[2][2]) - (m[1][2] * m[2][1])) -
00263 m[0][1] * ((m[1][0] * m[2][2]) - (m[1][2] * m[2][0])) +
00264 m[0][2] * ((m[1][0] * m[2][1]) - (m[1][1] * m[2][0]));
00265
00266 i[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / det;
00267 i[0][1] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1]) / det;
00268 i[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / det;
00269 i[1][0] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0]) / det;
00270 i[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / det;
00271 i[1][2] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0]) / det;
00272 i[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / det;
00273 i[2][1] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0]) / det;
00274 i[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / det;
00275
00276 }
00277
00278 static int _surfaceToGlobal( sConstrain *c, sCoord *p,
00279 void **elm, double itransf[3][3] )
00280 {
00281 int found = 0;
00282 double transf[3][3];
00283 sCSurfaceData *data = (sCSurfaceData *)c->data;
00284
00285 pfsRActivateSurf(data->pfsSurface);
00286
00287 if( !(*elm) )
00288 {
00289
00290 found = pfsRGetElem( p->x, p->y, p->z, elm );
00291
00292 if(!found)
00293 {
00294
00295
00296 found = pfsRGetLoopElem( p->x, p->y, p->z, elm );
00297 if( !found )
00298 {
00299 fprintf(stderr, "Could not find element(ToGlobal).\n\n");
00300 *elm = NULL;
00301 return 0;
00302 }
00303 }
00304 }
00305
00306
00307 pfsRSetCurrElem( *elm );
00308
00309
00310 _surfaceCurrElemTransfMtx( transf );
00311
00312
00313 _invertMtx( transf, itransf );
00314
00315 return 1;
00316 }
00317
00318
00319
00320
00321 static void _surfaceLocalT3Coord( int inc[3], sCoord coord[3], double jac[3][3] )
00322 {
00323 const int nnode = 3;
00324 int i;
00325 PFSGeoPoint tmp;
00326 PFSGeoPoint pn[3], n[3];
00327
00328 for(i = 0; i < nnode; i++)
00329 {
00330 pfsRItrNodeCoords(inc[i], &(pn[i].x), &(pn[i].y), &(pn[i].z));
00331 }
00332
00333
00334
00335 PFSGeoDiffVec(&(pn[1]), &(pn[0]), &(n[0]));
00336
00337
00338
00339 pfsRItrElemNormal(&(n[2].x), &(n[2].y), &(n[2].z));
00340
00341
00342
00343 PFSGeoCrossProd(&n[2], &n[0], &n[1]);
00344
00345
00346
00347 for(i=0;i<nnode;++i)
00348 {
00349 PFSGeoVecNormalize(&n[i], &n[i]);
00350 }
00351
00352
00353 coord[0].x = 0.0;
00354 coord[0].y = 0.0;
00355 coord[0].z = 0.0;
00356
00357
00358 PFSGeoDiffVec(&(pn[1]), &(pn[0]), &tmp);
00359 coord[1].x = PFSGeoVecLen(&tmp);
00360 coord[1].y = 0.0;
00361 coord[1].z = 0.0;
00362
00363
00364 PFSGeoDiffVec(&(pn[2]), &(pn[0]), &tmp);
00365 coord[2].x = PFSGeoDotProd(&n[0], &tmp);
00366 coord[2].y = PFSGeoDotProd(&n[1], &tmp);
00367 coord[2].z = 0.0;
00368
00369
00370
00371
00372 for( i=0; i<3; i++ )
00373 {
00374 jac[i][0] = n[i].x;
00375 jac[i][1] = n[i].y;
00376 jac[i][2] = n[i].z;
00377 }
00378 }
00379
00380 static int _surfaceLocalTri2PFS( sCoord coord[3],
00381 double u1, double v1,
00382 double u2, double v2,
00383 double u3, double v3, double jacinv[2][2] )
00384 {
00385 double x1 = coord[0].x; double y1 = coord[0].y;
00386 double x2 = coord[1].x; double y2 = coord[1].y;
00387 double x3 = coord[2].x; double y3 = coord[2].y;
00388
00389 double dt;
00390 double dudx;
00391 double dudy;
00392 double dvdx;
00393 double dvdy;
00394
00395 dt = (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1);
00396
00397 if( dt < 1e-8 )
00398 return( 0 );
00399
00400 dudx = (y2 - y3)*u1 + (y3 - y1)*u2 + (y1 - y2)*u3;
00401 dudy = (x3 - x2)*u1 + (x1 - x3)*u2 + (x2 - x1)*u3;
00402 dvdx = (y2 - y3)*v1 + (y3 - y1)*v2 + (y1 - y2)*v3;
00403 dvdy = (x3 - x2)*v1 + (x1 - x3)*v2 + (x2 - x1)*v3;
00404
00405 jacinv[0][0] = dudx / dt;
00406 jacinv[0][1] = dudy / dt;
00407 jacinv[1][0] = dvdx / dt;
00408 jacinv[1][1] = dvdy / dt;
00409
00410 return( 1 );
00411 }
00415 static int _surfaceSlide( sConstrain *c, sCoord *p, void **elm, sCoord *d,
00416 double ijac[3][3], sCoord *pl )
00417 {
00418 int i;
00419 int nnode = 3;
00420 int nodeid[3];
00421 double du_pfs, dv_pfs;
00422 double u[3], v[3];
00423 double jac[3][3];
00424
00425 double local2pfs[2][2];
00426
00427 double path_len;
00428 sCoord localT3Coord[3];
00429 int status;
00430
00431 sCSurfaceData *data = (sCSurfaceData *)c->data;
00432
00433 if( !(*elm) )
00434 {
00435
00436 int found = pfsRGetElem( p->x, p->y, p->z, elm );
00437
00438 if( !found )
00439 {
00440
00441
00442 found = pfsRGetLoopElem( p->x, p->y, p->z, elm );
00443 if( !found )
00444 {
00445 fprintf(stderr, "Could not find element(Slide).\n\n");
00446 *elm = NULL;
00447 return 0;
00448 }
00449 }
00450 }
00451
00452
00453
00454 pfsRActivateSurf(data->pfsSurface);
00455
00456
00457 pfsRSetCurrElem(*elm);
00458
00459
00460
00461
00462
00463 for( i=0; i< nnode; ++i )
00464 {
00465 pfsRItrElemNode(&nodeid[i]);
00466 pfsRItrNodeParVals(nodeid[i], &u[i], &v[i]);
00467 }
00468
00469
00470 _surfaceLocalT3Coord( nodeid, localT3Coord, jac );
00471
00472 Inverse( jac, ijac );
00473
00474
00475 _surfaceLocalTri2PFS( localT3Coord, u[0], v[0],
00476 u[1], v[1],
00477 u[2], v[2], local2pfs );
00478
00479 du_pfs = local2pfs[0][0]*d->x + local2pfs[0][1]*d->y;
00480 dv_pfs = local2pfs[1][0]*d->x + local2pfs[1][1]*d->y;
00481
00482 path_len = sqrt( d->x*d->x + d->y*d->y );
00483
00484 status = pfsRShot( *elm, p->x, p->y, p->z,
00485 du_pfs, dv_pfs, path_len,
00486 elm, &pl->x, &pl->y, &pl->z );
00487
00488 if( !status )
00489 {
00490 pl->x = p->x;
00491 pl->y = p->y;
00492 pl->z = p->z;
00493 }
00494 return 1;
00495 }
00496
00497
00498
00499
00500 static void ConstSurfaceNew(int, int, int, sConstrain **, sConstrain **);
00501 static void ConstSurfaceFree(sConstrain *);
00502 static void ConstSurfaceRead(sConstrain *);
00503 static void ConstSurfaceBuild(sConstrain *);
00504
00508 static void ConstSurfaceNew( int label, int num_nodes, int num_elems,
00509 sConstrain **c, sConstrain **clst)
00510 {
00511 sCSurfaceData *data = NULL;
00512
00513 data = (sCSurfaceData *)calloc(num_nodes, sizeof(sCSurfaceData));
00514
00515 (*c) = (sConstrain *)calloc(1, sizeof(sConstrain));
00516 (*c)->type = SURFACE;
00517 (*c)->label = label;
00518 (*c)->numNodes = num_nodes;
00519 (*c)->numElems = num_elems;
00520 (*c)->nodes = (sNode *)calloc(num_nodes, sizeof(sNode));
00521 (*c)->elems = (sElement **)calloc(num_elems, sizeof(sElement *));
00522 (*c)->data = data;
00523
00524
00525
00526
00527 clst[ContNumConstrainRead] = (*c);
00528 ContNumConstrainRead++;
00529
00530 }
00531
00535 static void ConstSurfaceFree( sConstrain *c )
00536 {
00537 int i;
00538
00539 if(c->data)
00540 free(c->data);
00541
00542 if(c->numNodes != 0)
00543 free(c->nodes);
00544
00545 if(c->numElems != 0)
00546 {
00547 for(i = 0; i < c->numElems; i++)
00548 {
00549 ElmFree(c->elems[i]);
00550 }
00551 free(c->elems);
00552 }
00553 c->numNodes = 0;
00554 c->numElems = 0;
00555 c->nodes = NULL;
00556 c->elems = NULL;
00557 c->data = NULL;
00558
00559 }
00560
00564 static void ConstSurfaceRead( sConstrain *c )
00565 {
00566 int i, id;
00567 double x, y, z;
00568 int matid, tckid, ordid;
00569 sElement *elm = NULL;
00570
00571
00572
00573 for(i = 0; i < c->numNodes; i++)
00574 {
00575 fscanf(nf, "%d %lf %lf %lf", &id, &x, &y, &z);
00576 c->nodes[i].id = id;
00577 c->nodes[i].coord.x = x;
00578 c->nodes[i].coord.y = y;
00579 c->nodes[i].coord.z = z;
00580 c->nodes[i].dof.x = FORCE;
00581 c->nodes[i].dof.y = FORCE;
00582 c->nodes[i].dof.z = FORCE;
00583 c->nodes[i].dof.psi = 0.0;
00584 c->nodes[i].rezone = NONE;
00585 c->nodes[i].curve = 0;
00586 c->nodes[i].dspIteration = DSP_NO;
00587 c->nodes[i].dspTime = DSP_NO;
00588 }
00589
00590
00591
00592 for(i = 0; i < c->numElems; i++)
00593 {
00594 fscanf(nf, "%d%d%d%d", &id, &matid, &tckid, &ordid);
00595 ElmNew(T3, id, matid, ordid, tckid, &elm, c->elems, c->nodes);
00596 ElmRead(elm);
00597 }
00598
00599 EvaluateTolerance(c);
00600
00601 }
00602
00607 static void ConstSurfaceBuild( sConstrain *c )
00608 {
00609 sCSurfaceData *data = NULL;
00610 int inc[3];
00611 int i;
00612
00613 data = (sCSurfaceData *)c->data;
00614
00615
00616
00617 data->pfsSurface = pfsRInitSurf(c->numNodes, c->numElems);
00618
00619
00620
00621 pfsRActivateSurf(data->pfsSurface);
00622
00623
00624
00625 for(i = 0; i < c->numNodes; i++)
00626 pfsRAddNode(c->nodes[i].coord.x, c->nodes[i].coord.y, c->nodes[i].coord.z);
00627
00628
00629
00630
00631 for(i = 0; i < c->numElems; i++)
00632 {
00633
00634
00635 ElmConnect(c->elems[i],inc);
00636
00637
00638
00639 pfsRAddElem(inc[0]-1, inc[1]-1, inc[2]-1);
00640 }
00641
00642
00643
00644
00645 pfsRCompleteSurf();
00646
00647
00648
00649
00650 pfsRSolveSurfPar(0);
00651
00652
00653
00654
00655 pfsCompleteParSpace();
00656
00657 }
00658
00662 static int ConstSurfaceLocal( sConstrain *c, sCoord *p, void **elm,
00663 double *g, double *l )
00664 {
00665 int i, j;
00666 double transf[3][3];
00667
00668 if(!_surfaceToLocal(c, p, elm, transf))
00669 {
00670 return 0;
00671 }
00672
00673 for(i = 0; i < NDof; i++)
00674 {
00675 l[i] = 0.0;
00676 for(j = 0; j < NDof; j++)
00677 {
00678 l[i] += transf[i][j] * g[j];
00679 }
00680 }
00681
00682 return 1;
00683
00684 }
00685
00689 static int ConstSurfaceGlobal( sConstrain *c, sCoord *p, void **elm,
00690 double *l, double *g )
00691 {
00692 int i, j;
00693 double itransf[3][3];
00694
00695 if(!_surfaceToGlobal(c, p, elm, itransf))
00696 return 0;
00697
00698 for( i = 0; i < NDof; i++ )
00699 {
00700 g[i] = 0.0;
00701 for( j = 0; j < NDof; j++ )
00702 {
00703 g[i] += itransf[i][j] * l[j];
00704 }
00705 }
00706
00707 return 1;
00708
00709 }
00710
00714 static int ConstSurfaceSlide( sConstrain *c, sCoord *p, void **elm, sCoord *d,
00715 double *l, double *g, sCoord *pl )
00716 {
00717 int i, j;
00718 double ijac[3][3];
00719
00720 if(!_surfaceSlide(c, p, elm, d, ijac, pl))
00721 return 0;
00722
00723 for(i = 0; i < NDof; i++)
00724 {
00725 g[i] = 0.0;
00726 for(j = 0; j < NDof; j++)
00727 {
00728 g[i] += ijac[i][j] * l[j];
00729 }
00730 }
00731
00732 return 1;
00733
00734 }
00735
00736
00737
00738
00739
00743 void ConstSurfaceInit(void);
00744 void ConstSurfaceInit(void)
00745 {
00746 ConstClass[SURFACE].new = ConstSurfaceNew;
00747 ConstClass[SURFACE].free = ConstSurfaceFree;
00748 ConstClass[SURFACE].read = ConstSurfaceRead;
00749 ConstClass[SURFACE].build = ConstSurfaceBuild;
00750 ConstClass[SURFACE].local = ConstSurfaceLocal;
00751 ConstClass[SURFACE].global = ConstSurfaceGlobal;
00752 ConstClass[SURFACE].slide = ConstSurfaceSlide;
00753
00754 Tolerance = 1.0e+10;
00755
00756 }
00757
00758
00759
00760
00761
00762