constshot.c

Go to the documentation of this file.
00001 /*
00002  *   
00003  * @file constshot.c
00004  * @author Juan Pablo Ibanez.
00005  * @date September 14, 2006
00006  *
00007  * Module created to support the use of SHOT constrain
00008  * (stolen from constcurve.c)
00009  *
00010  */
00011 
00012 /*
00013  * Global variables and symbols:
00014  */
00015 #include <stdlib.h>
00016 #include <math.h>
00017 #include "constrain.h"
00018 #include "rio.h"
00019 
00020 typedef struct _curvedata 
00021 {
00022   double jac[3][3];
00023   double ijac[3][3];
00024 } sCCurveData;
00025 
00026 sCoord* shotVector = NULL;
00027 
00028 /*
00029 ** ------------------------------------------------------------------------
00030 ** Local variables and symbols:
00031 */
00032 
00033 /*
00034 %K Tolerance definition
00035 */
00036 static double Tolerance = 1.0e+10;
00037 
00038 /*
00039 %K Zero definition
00040 */
00041 #ifndef ZERO
00042 #define ZERO(v)     ((fabs(v)<Tolerance)?1:0) 
00043 #endif
00044 
00045 /*
00046 %K Minimum definition
00047 */
00048 #ifndef MIN
00049 #define MIN(a,b)    ((a<b)?a:b)
00050 #endif
00051 
00052 /*
00053 %K Maximum definition
00054 */
00055 #ifndef MAX
00056 #define MAX(a,b)    ((a>b)?a:b)
00057 #endif
00058 
00059 
00060 /*
00061 ** ------------------------------------------------------------------------
00062 ** Local functions:
00063 */
00064 
00071 static void     DiffVec( sCoord *in0, sCoord *in1, sCoord *out )    
00072 {
00073   out->x = in0->x - in1->x;
00074   out->y = in0->y - in1->y;
00075   out->z = in0->z - in1->z;
00076 } 
00077 
00084 static double ProdEscalar( sCoord *in0, sCoord* in1 )
00085 {
00086   double prod;
00087   prod = (in0->x)*(in1->x) + (in0->y)*(in1->y) + (in0->z)*(in1->z); 
00088   
00089   return (prod);
00090 }
00091 
00098 static void CrossProd( sCoord *in0, sCoord *in1, sCoord *out )
00099 {
00100   out->x = (in0->y * in1->z) - (in0->z * in1->y); 
00101   out->y = (in0->z * in1->x) - (in0->x * in1->z); 
00102   out->z = (in0->x * in1->y) - (in0->y * in1->x); 
00103 }  
00104 
00108 static double VecLen( sCoord *vec )
00109 {
00110   return(sqrt((vec->x * vec->x) + (vec->y * vec->y) + (vec->z * vec->z)));
00111 }
00112 
00116 static double Dist( sCoord *in0, sCoord *in1 )
00117 {
00118   sCoord tmp;
00119 
00120   DiffVec(in1, in0, &tmp);
00121   
00122   return(VecLen(&tmp));
00123 }
00124 
00129 static void EvaluateTolerance( sConstrain *c )
00130 {
00131   int inc[3];
00132   double dist = 0.0;
00133   double auxTol = 0.0;
00134   int i;
00135 
00136   for(i = 0; i < c->numElems; i++)
00137   {
00138     ElmConnect(c->elems[i],inc);
00139     dist = Dist(&c->nodes[inc[1]-1].coord, &c->nodes[inc[0]-1].coord);
00140     auxTol = dist * 0.1;
00141     if(auxTol < Tolerance)
00142       Tolerance = auxTol;
00143   }
00144 
00145 } /* End of EvaluateTolerance */
00146 
00150 static void TranslateShot(sConstrain *c, sCoord* p)
00151 {
00152   int i;
00153   int sign;
00154   sCoord* vec = shotVector;
00155 
00156   /* aplly tranlation to shot constrain */
00157   /* p = current node */
00158   sign = -1;
00159   for(i = 0; i < c->numNodes; i++)
00160   {
00161     c->nodes[i].coord.x = p->x + sign*vec->x;
00162     c->nodes[i].coord.y = p->y + sign*vec->y;
00163     c->nodes[i].coord.z = p->z + sign*vec->z;
00164     sign += 2; 
00165   }
00166 
00167 } /* end of TranslateShot */
00168 
00169 /*
00170  * Subclass methods:
00171  */
00172 static void ConstShotNew   (int, int, int, sConstrain **, sConstrain **);
00173 static void ConstShotFree  (sConstrain *);
00174 static void ConstShotRead  (sConstrain *);
00175 static void ConstShotBuild (sConstrain *);
00176 
00180 static void ConstShotNew( int label, int num_nodes, int num_elems,
00181                            sConstrain **c, sConstrain **clst )
00182 {
00183  sCCurveData *data = NULL;
00184 
00185  data = (sCCurveData *)calloc(num_nodes, sizeof(sCCurveData));
00186 
00187  (*c) = (sConstrain *)malloc(sizeof(sConstrain));
00188  (*c)->type = SHOT;
00189  (*c)->label = label;
00190  (*c)->numNodes = num_nodes;
00191  (*c)->numElems = num_elems;
00192  (*c)->nodes = (sNode *)calloc(num_nodes, sizeof(sNode));
00193  (*c)->elems = (sElement **)calloc(num_elems, sizeof(sElement *));
00194  (*c)->data = data;
00195  clst[ContNumConstrainRead] = (*c);
00196  ContNumConstrainRead++;
00197 
00198 } /* End of ConstShotNew */
00199 
00203 static void ConstShotFree(sConstrain *c)
00204 {
00205  int i;
00206 
00207  if( c->data ) {
00208   free(c->data);
00209  }
00210 
00211  if( c->numNodes != 0 ) {
00212   free(c->nodes);
00213  }
00214 
00215  if( c->numElems != 0 ) {
00216   for( i = 0; i < c->numElems; i++ ) {
00217    ElmFree(c->elems[i]);
00218   }
00219   free(c->elems);
00220  }
00221  c->numNodes = 0;
00222  c->numElems = 0;
00223  c->nodes = NULL;
00224  c->elems = NULL;
00225  c->data = NULL;
00226 
00227 } /* End of ConstShotFree */
00228 
00232 static void ConstShotRead(sConstrain *c)
00233 {
00234  int i;
00235  int sign;
00236  sElement *elm = NULL;
00237  sCoord   *vec = NULL;    /* vetor unitario */
00238  int       inc[2];        /* Vetor auxiliar de incidencia dos segmentos. */
00239 
00240   /* Le as coordenadas do vetor unitario.
00241    */
00242    vec = (sCoord*)malloc(sizeof(sCoord));
00243    fscanf(nf, "%lf %lf %lf", &(vec->x), &(vec->y), &(vec->z));
00244    shotVector = vec;
00245     
00246   /* inicia informacao comum aos dois nos */
00247    for(i = 0; i < c->numNodes; i++)
00248    {  
00249      c->nodes[i].id = i+1;
00250      c->nodes[i].dof.x = FORCE;
00251      c->nodes[i].dof.y = FORCE;
00252      c->nodes[i].dof.z = FORCE;
00253      c->nodes[i].dof.psi = 0.0;
00254      c->nodes[i].rezone = NONE;
00255      c->nodes[i].curve = 0;
00256      c->nodes[i].dspIteration = DSP_NO;
00257      c->nodes[i].dspTime = DSP_NO;
00258    }
00259 
00260   /* seta coordenadas dos dois nos */
00261    sign = -1;
00262    for(i = 0; i < c->numNodes; i++)
00263    {
00264      c->nodes[i].coord.x = sign*vec->x;
00265      c->nodes[i].coord.y = sign*vec->y;
00266      c->nodes[i].coord.z = sign*vec->z;
00267      sign += 2;
00268    }
00269 
00270   /* Cria os segmentos.
00271    */
00272   for(i = 0; i < c->numElems; i++)
00273   {
00274     ElmNew(LINE2, i+1, 1, 1, 1, &elm, c->elems, c->nodes);
00275     inc[0] = i+1;
00276     inc[1] = i+2;
00277     ElmSetConnect(elm, inc);
00278   }
00279 
00280  EvaluateTolerance(c);
00281 
00282  /*for(i = 0; i < c->numNodes; i++) {
00283    printf("node = %d\tx = %f\ty = %f\n",
00284           i,c->nodes[i].coord.x,c->nodes[i].coord.y);
00285  }*/
00286 
00287 } /* End of ConstShotRead */
00288 
00292 static void ConstShotBuild(sConstrain *c)
00293 {
00294  int i, j, n, k, l;
00295  int inc[3];
00296  double jac[3][3], ijac[3][3];
00297  int *count = NULL;
00298  sCCurveData *data = NULL;
00299 
00300  count = (int *)calloc(c->numNodes, sizeof(int));
00301  data = (sCCurveData *)c->data;
00302 
00303  for( i = 0; i < c->numElems; i++ ) {
00304   ElmNumNodes(c->elems[i],&n);
00305   ElmConnect(c->elems[i],inc);
00306   ElmJacobian(c->elems[i],jac,ijac);
00307   for( j = 0; j < n; j++ ) {
00308    for( k = 0; k < 3; k++ ) {
00309     for( l = 0; l < 3; l++ ) {
00310      data[inc[j]-1].jac[k][l] += jac[k][l];
00311      data[inc[j]-1].ijac[k][l] += ijac[k][l];
00312     }
00313    }
00314    count[inc[j]-1]++;
00315   }
00316  }
00317 
00318  for( i = 0; i < c->numNodes; i++ ) {
00319   for( k = 0; k < 3; k++ ) {
00320    for( l = 0; l < 3; l++ ) {
00321     data[i].jac[k][l] /= count[i];
00322     data[i].ijac[k][l] /= count[i];
00323    }
00324   }
00325  }
00326  
00327  free(count);
00328 
00329 } /* End of ConstShotBuild */
00330 
00334 static int ConstShotLocal( sConstrain *c, sCoord *p, void **elm,
00335                            double *g, double *l )
00336 {
00337   int i, j;
00338   double jac[3][3];
00339   double ijac[3][3];
00340 
00341   /* update shot constrain */
00342   TranslateShot(c,p);
00343 
00344   ElmJacobian(c->elems[0],jac,ijac);
00345 
00346   *elm = c->elems[0];
00347 
00348   for(i = 0; i < NDof; i++) 
00349   {
00350     l[i] = 0.0;
00351     for(j = 0; j < NDof; j++) 
00352       l[i] += jac[i][j] * g[j];
00353   }
00354 
00355   return 1;
00356 
00357 } /* End of ConstShotLocal */
00358 
00362 static int ConstShotGlobal( sConstrain *c, sCoord *p, void **elm,
00363                             double *l, double *g )
00364 {
00365   int i, j;
00366   double  jac[3][3];
00367   double ijac[3][3];
00368 
00369   ElmJacobian(c->elems[0],jac,ijac);
00370 
00371   *elm = c->elems[0];
00372 
00373   for(i = 0; i < NDof; i++) 
00374   {
00375     g[i] = 0.0;
00376     for( j = 0; j < NDof; j++ )
00377       g[i] += ijac[i][j] * l[j];
00378   }
00379 
00380   return 1;
00381 
00382 } /* End of ConstShotGlobal */
00383 
00388 static int ConstShotSlide( sConstrain *c, sCoord *p, void **elm, sCoord *d,
00389                            double *l, double *g, sCoord *pl )
00390 {
00391   int      i, j;
00392   double   jace[3][3], ijace[3][3];
00393   double   d_gbl[3];
00394   double   d_local[3];
00395 
00396   d_local[0] = d->x;
00397   d_local[1] = 0.0;
00398   d_local[2] = 0.0;
00399       
00400   *elm = c->elems[0];
00401   ElmJacobian( ((sElement*)(*elm)), jace, ijace );
00402 
00403   /* Computes displacements in global coordinates */
00404   for(i = 0; i < NDof; i++)
00405   {
00406     d_gbl[i] = 0.0;
00407     for(j = 0; j < NDof; j++)
00408       d_gbl[i] += ijace[i][j] * d_local[j];
00409   }
00410 
00411   /* Computes new node coordinates in shot constrain. */
00412   pl->x = p->x + d_gbl[0]; 
00413   pl->y = p->y + d_gbl[1]; 
00414   if( NDof == 3 )
00415     pl->z = p->z + d_gbl[2]; 
00416 
00417   for(i = 0; i < NDof; i++)
00418   {
00419     g[i] = 0.0;
00420     for(j = 0; j < NDof; j++)
00421       g[i] += ijace[i][j] * l[j];
00422   }
00423 
00424   return 1;
00425 }
00426 
00427 /*
00428  * Public functions:
00429  */
00430 
00435 void ConstShotInit(void);
00436 void ConstShotInit(void)
00437 {
00438   ConstClass[SHOT].new    = ConstShotNew;
00439   ConstClass[SHOT].free   = ConstShotFree;
00440   ConstClass[SHOT].read   = ConstShotRead;
00441   ConstClass[SHOT].build  = ConstShotBuild;
00442   ConstClass[SHOT].local  = ConstShotLocal;
00443   ConstClass[SHOT].global = ConstShotGlobal;
00444   ConstClass[SHOT].slide  = ConstShotSlide;
00445 
00446   Tolerance = 1.0e+10;
00447 
00448 } /* End of ConstShotInit */
00449 
00450 
00451 /*
00452  * End of File.
00453  */
00454 
00455 

Generated on Tue Oct 23 11:23:29 2007 for Relax by  doxygen 1.5.3