[1] | 1 | /*
|
---|
[22498] | 2 | * TriangleUtils: mesh manipulation routines:
|
---|
[1] | 3 | */
|
---|
| 4 |
|
---|
[3252] | 5 | #include <stdio.h>
|
---|
| 6 |
|
---|
[22498] | 7 | #include "./triangle.h"
|
---|
[3335] | 8 | #include "../Exceptions/exceptions.h"
|
---|
[14904] | 9 | #include "../MemOps/MemOps.h"
|
---|
[1] | 10 |
|
---|
[6748] | 11 | #define RIFTPENALTYPAIRSWIDTH 8
|
---|
[18063] | 12 | int IsGridOnRift(int* riftsegments, int nriftsegs, int node){/*{{{*/
|
---|
[1] | 13 |
|
---|
[8301] | 14 | /*Does this node belong to 4 elements, or just 2? If it belongs to 4 elements, it is inside a rift,
|
---|
[1] | 15 | *if it belongs to 2 elements, it is on the tip of a rift, or it has already been split across the rift (see below).*/
|
---|
[13622] | 16 |
|
---|
[1] | 17 | int i;
|
---|
| 18 | int j;
|
---|
| 19 | int count;
|
---|
| 20 |
|
---|
| 21 | count=0;
|
---|
| 22 | for (i=0;i<nriftsegs;i++){
|
---|
| 23 | for (j=0;j<2;j++){
|
---|
[8301] | 24 | if ((*(riftsegments+4*i+2+j))==node) count++;
|
---|
[1] | 25 | }
|
---|
| 26 | }
|
---|
| 27 | if (count==2){
|
---|
| 28 | return 1;
|
---|
| 29 | }
|
---|
| 30 | else{
|
---|
| 31 | return 0;
|
---|
| 32 | }
|
---|
[12080] | 33 | }/*}}}*/
|
---|
[18063] | 34 | int GridElementsList(int** pGridElements, int* pNumGridElements,int node,int* index,int nel){/*{{{*/
|
---|
[1] | 35 |
|
---|
[8301] | 36 | /*From a node, recover all the elements that are connected to it: */
|
---|
[1] | 37 | int i,j;
|
---|
| 38 | int noerr=1;
|
---|
| 39 |
|
---|
| 40 | int max_number_elements=12;
|
---|
| 41 | int current_size;
|
---|
| 42 | int NumGridElements;
|
---|
| 43 | int* GridElements=NULL;
|
---|
| 44 | int* GridElementsRealloc=NULL;
|
---|
| 45 |
|
---|
| 46 | /*From a mesh with 30 degrees minimum angle, we get 12 possible elements that own
|
---|
[8301] | 47 | * the node. We start by allocating GridElements with that size, and realloc
|
---|
[1] | 48 | * more if needed.*/
|
---|
| 49 |
|
---|
| 50 | current_size=max_number_elements;
|
---|
| 51 | NumGridElements=0;
|
---|
[12436] | 52 | GridElements=xNew<int>(max_number_elements);
|
---|
[1] | 53 |
|
---|
| 54 | for (i=0;i<nel;i++){
|
---|
| 55 | for (j=0;j<3;j++){
|
---|
[14222] | 56 | if (index[3*i+j]==node){
|
---|
[1] | 57 | if (NumGridElements<=(current_size-1)){
|
---|
| 58 | GridElements[NumGridElements]=i;
|
---|
| 59 | NumGridElements++;
|
---|
| 60 | break;
|
---|
| 61 | }
|
---|
| 62 | else{
|
---|
| 63 | /*Reallocate another max_number_elements slots in the GridElements: */
|
---|
[12447] | 64 | GridElementsRealloc=xReNew<int>(GridElements,current_size,(current_size+max_number_elements));
|
---|
[1] | 65 | if (!GridElementsRealloc){
|
---|
| 66 | noerr=0;
|
---|
| 67 | goto cleanup_and_return;
|
---|
| 68 | }
|
---|
| 69 | current_size+=max_number_elements;
|
---|
| 70 | GridElements=GridElementsRealloc;
|
---|
| 71 | GridElements[NumGridElements]=i;
|
---|
| 72 | NumGridElements++;
|
---|
| 73 | break;
|
---|
| 74 | }
|
---|
| 75 | }
|
---|
| 76 | }
|
---|
| 77 | }
|
---|
| 78 | cleanup_and_return:
|
---|
| 79 | if(!noerr){
|
---|
[12436] | 80 | xDelete<int>(GridElements);
|
---|
[1] | 81 | }
|
---|
| 82 | /*Allocate return pointers: */
|
---|
| 83 | *pGridElements=GridElements;
|
---|
| 84 | *pNumGridElements=NumGridElements;
|
---|
| 85 | return noerr;
|
---|
[12080] | 86 | }/*}}}*/
|
---|
[18063] | 87 | int IsNeighbor(int el1,int el2,int* index){/*{{{*/
|
---|
[8301] | 88 | /*From a triangulation held in index, figure out if elements 1 and 2 have two nodes in common: */
|
---|
[1] | 89 | int i,j;
|
---|
| 90 | int count=0;
|
---|
| 91 | for (i=0;i<3;i++){
|
---|
| 92 | for (j=0;j<3;j++){
|
---|
[14222] | 93 | if (index[3*el1+i]==index[3*el2+j])count++;
|
---|
[1] | 94 | }
|
---|
| 95 | }
|
---|
| 96 | if (count==2){
|
---|
| 97 | return 1;
|
---|
| 98 | }
|
---|
| 99 | else{
|
---|
| 100 | return 0;
|
---|
| 101 | }
|
---|
[12080] | 102 | }/*}}}*/
|
---|
[18063] | 103 | int IsOnRift(int el,int nriftsegs,int* riftsegments){/*{{{*/
|
---|
[1] | 104 | /*From a list of elements segments, figure out if el belongs to it: */
|
---|
| 105 | int i;
|
---|
| 106 | for (i=0;i<nriftsegs;i++){
|
---|
[16218] | 107 | if ((*(riftsegments+4*i+0)==el) || (*(riftsegments+4*i+1)==el)){
|
---|
[1] | 108 | return 1;
|
---|
| 109 | }
|
---|
| 110 | }
|
---|
| 111 | return 0;
|
---|
[12080] | 112 | }/*}}}*/
|
---|
[18063] | 113 | void RiftSegmentsFromSegments(int* pnriftsegs, int** priftsegments, int nel,int* index,int nsegs,int* segments){/*{{{*/
|
---|
[13622] | 114 |
|
---|
[1] | 115 | int i,counter;
|
---|
| 116 | int el,el2;
|
---|
[13622] | 117 |
|
---|
[1] | 118 | int nriftsegs;
|
---|
| 119 | int* riftsegments=NULL;
|
---|
| 120 | int* riftsegments_uncompressed=NULL;
|
---|
[14222] | 121 | int element_nodes[3];
|
---|
[1] | 122 |
|
---|
| 123 | /*Allocate segmentflags: */
|
---|
[12446] | 124 | riftsegments_uncompressed=xNewZeroInit<int>(nsegs*5);
|
---|
[1] | 125 |
|
---|
| 126 | /*Find the segments that belong to a rift: they are the ones that see two elements. The other ones belong to a boundary
|
---|
| 127 | *or a hole: */
|
---|
| 128 | nriftsegs=0;
|
---|
| 129 | for (i=0;i<nsegs;i++){
|
---|
| 130 | el=(int)*(segments+3*i+2)-1; //element found in AssociateSegmentToElements
|
---|
[8301] | 131 | /*Temporarily set nodes belonging to the segments to -1 in the triangulation index, and
|
---|
[1] | 132 | *then proceed to find another element that owns the segment. If we don't find it, we know
|
---|
| 133 | *we are dealing with a boundary or hole, otherwise, we are dealing with a rift: */
|
---|
[8301] | 134 | element_nodes[0]=*(index+3*el+0);
|
---|
| 135 | element_nodes[1]=*(index+3*el+1);
|
---|
| 136 | element_nodes[2]=*(index+3*el+2);
|
---|
[1] | 137 |
|
---|
[14222] | 138 | index[3*el+0]=-1;
|
---|
| 139 | index[3*el+1]=-1;
|
---|
| 140 | index[3*el+2]=-1;
|
---|
[1] | 141 |
|
---|
| 142 | el2=FindElement(*(segments+3*i+0),*(segments+3*i+1),index,nel);
|
---|
| 143 |
|
---|
| 144 | /*Restore index: */
|
---|
[14222] | 145 | index[3*el+0]=element_nodes[0];
|
---|
| 146 | index[3*el+1]=element_nodes[1];
|
---|
| 147 | index[3*el+2]=element_nodes[2];
|
---|
[1] | 148 |
|
---|
| 149 | if (el2!=-1){
|
---|
| 150 | /*el and el2 are on a segment rift, facing one another, plug them into riftsegments_uncompressed: */
|
---|
[14222] | 151 | riftsegments_uncompressed[5*i+0]=1;
|
---|
| 152 | riftsegments_uncompressed[5*i+1]=el;
|
---|
| 153 | riftsegments_uncompressed[5*i+2]=el2;
|
---|
| 154 | riftsegments_uncompressed[5*i+3]=segments[3*i+0];
|
---|
| 155 | riftsegments_uncompressed[5*i+4]=segments[3*i+1];
|
---|
| 156 | nriftsegs++;
|
---|
[1] | 157 | }
|
---|
| 158 | }
|
---|
| 159 |
|
---|
| 160 | /*Compress riftsegments_uncompressed:*/
|
---|
[12436] | 161 | riftsegments=xNew<int>(nriftsegs*4);
|
---|
[1] | 162 | counter=0;
|
---|
| 163 | for (i=0;i<nsegs;i++){
|
---|
[14222] | 164 | if (riftsegments_uncompressed[5*i+0]){
|
---|
| 165 | riftsegments[counter*4+0]=riftsegments_uncompressed[5*i+1];
|
---|
| 166 | riftsegments[counter*4+1]=riftsegments_uncompressed[5*i+2];
|
---|
| 167 | riftsegments[counter*4+2]=riftsegments_uncompressed[5*i+3];
|
---|
| 168 | riftsegments[counter*4+3]=riftsegments_uncompressed[5*i+4];
|
---|
[1] | 169 | counter++;
|
---|
| 170 | }
|
---|
| 171 | }
|
---|
[12436] | 172 | xDelete<int>(riftsegments_uncompressed);
|
---|
[13622] | 173 |
|
---|
[1] | 174 | /*Assign output pointers: */
|
---|
| 175 | *priftsegments=riftsegments;
|
---|
| 176 | *pnriftsegs=nriftsegs;
|
---|
[12080] | 177 | }/*}}}*/
|
---|
[18063] | 178 | int DetermineGridElementListOnOneSideOfRift(int* pNumGridElementListOnOneSideOfRift, int** pGridElementListOnOneSideOfRift, int segmentnumber, int nriftsegs, int* riftsegments, int node,int* index,int nel){/*{{{*/
|
---|
[1] | 179 |
|
---|
| 180 | int noerr=1;
|
---|
| 181 | int k,l,counter;
|
---|
| 182 | int newel;
|
---|
| 183 |
|
---|
| 184 | int* GridElements=NULL;
|
---|
| 185 | int NumGridElements;
|
---|
| 186 |
|
---|
| 187 | /*Output: */
|
---|
| 188 | int NumGridElementListOnOneSideOfRift;
|
---|
| 189 | int* GridElementListOnOneSideOfRift=NULL;
|
---|
| 190 |
|
---|
[8301] | 191 | /*Build a list of all the elements connected to this node: */
|
---|
| 192 | GridElementsList(&GridElements,&NumGridElements,node,index,nel);
|
---|
[3595] | 193 |
|
---|
[1] | 194 | /*Figure out the list of elements that are on the same side of the rift. To do so, we start from one
|
---|
| 195 | * side of the rift and keep rotating in the same direction:*/
|
---|
[12436] | 196 | GridElementListOnOneSideOfRift=xNew<int>(NumGridElements);
|
---|
[1] | 197 | //bootstrap the GridElementListOnOneSideOfRift by filling elements from riftsegments: */
|
---|
| 198 | GridElementListOnOneSideOfRift[0]=*(riftsegments+4*segmentnumber+0); /*this one does not belong to the same side, but is just there
|
---|
| 199 | for a rotation direction, we 'll take it out when we are
|
---|
| 200 | done rotating*/
|
---|
| 201 | GridElementListOnOneSideOfRift[1]=*(riftsegments+4*segmentnumber+1);
|
---|
| 202 | counter=1;
|
---|
| 203 | for (;;){
|
---|
| 204 | /*Find neighbour of element GridElementListOnOneSideOfRift[counter], not
|
---|
| 205 | * equal to GridElementListOnOneSideOfRift[counter-1]*/
|
---|
| 206 | for (k=0;k<NumGridElements;k++){
|
---|
| 207 | if(IsNeighbor(GridElements[k],GridElementListOnOneSideOfRift[counter],index)){
|
---|
| 208 | /*Verify this element is not already in our list of element on the same side of the rift: */
|
---|
| 209 | newel=1;
|
---|
| 210 | for (l=0;l<=counter;l++){
|
---|
| 211 | if (GridElements[k]==GridElementListOnOneSideOfRift[l]){
|
---|
| 212 | newel=0;
|
---|
| 213 | break;
|
---|
| 214 | }
|
---|
| 215 | }
|
---|
| 216 | if (newel){
|
---|
| 217 | counter++;
|
---|
| 218 | GridElementListOnOneSideOfRift[counter]=GridElements[k];
|
---|
| 219 | if (IsOnRift(GridElements[k],nriftsegs,riftsegments)){
|
---|
| 220 | break;
|
---|
| 221 | }
|
---|
| 222 | k=-1;
|
---|
| 223 | }
|
---|
| 224 | }
|
---|
| 225 | }
|
---|
| 226 | /*Reduce counter by 1 and get rift of first element in GridElementListOnOneSideOfRift:*/
|
---|
| 227 | NumGridElementListOnOneSideOfRift=counter;
|
---|
| 228 | for (l=0;l<NumGridElementListOnOneSideOfRift;l++){
|
---|
| 229 | GridElementListOnOneSideOfRift[l]=GridElementListOnOneSideOfRift[l+1];
|
---|
| 230 | }
|
---|
| 231 | break;
|
---|
| 232 | }// for (;;)
|
---|
| 233 |
|
---|
[27232] | 234 | /*Free resources: */
|
---|
[12436] | 235 | xDelete<int>(GridElements);
|
---|
[1] | 236 | /*Assign output pointers: */
|
---|
| 237 | *pNumGridElementListOnOneSideOfRift=NumGridElementListOnOneSideOfRift;
|
---|
| 238 | *pGridElementListOnOneSideOfRift=GridElementListOnOneSideOfRift;
|
---|
| 239 | return noerr;
|
---|
[12080] | 240 | }/*}}}*/
|
---|
[18063] | 241 | int UpdateSegments(int** psegments,int** psegmentmarkerlist, int* pnsegs,int* index, double* x,double* y,int* riftsegments,int nriftsegs,int nods,int nel){/*{{{*/
|
---|
[1] | 242 |
|
---|
| 243 | int noerr=1;
|
---|
| 244 | int i,j,k;
|
---|
| 245 | int el1,el2;
|
---|
| 246 |
|
---|
[14222] | 247 | int *segments = NULL;
|
---|
| 248 | int *segmentmarkerlist = NULL;
|
---|
| 249 | int nsegs;
|
---|
[1] | 250 |
|
---|
| 251 | /*Recover input: */
|
---|
[13363] | 252 | segments = *psegments;
|
---|
| 253 | segmentmarkerlist = *psegmentmarkerlist;
|
---|
| 254 | nsegs = *pnsegs;
|
---|
[1] | 255 |
|
---|
| 256 | /*Reallocate segments: */
|
---|
[14222] | 257 | segments =xReNew<int>(segments, nsegs*3,(nsegs+nriftsegs)*3);
|
---|
| 258 | segmentmarkerlist=xReNew<int>(segmentmarkerlist,nsegs,(nsegs+nriftsegs));
|
---|
[1] | 259 |
|
---|
[8301] | 260 | /*First, update the existing segments to the new nodes :*/
|
---|
[1] | 261 | for (i=0;i<nriftsegs;i++){
|
---|
[12080] | 262 | el1=riftsegments[4*i+0];
|
---|
| 263 | el2=riftsegments[4*i+1];
|
---|
[1] | 264 | for (j=0;j<nsegs;j++){
|
---|
[12080] | 265 | if (segments[3*j+2]==(el1+1)){
|
---|
[1] | 266 | /*segment j is the same as rift segment i.Let's update segments[j][:] using element el1 and the corresponding rift segment.
|
---|
| 267 | *Because riftsegments does not represent a list of rift segments anymore (it got heavily modified in SplitElementsForRifts,
|
---|
[8301] | 268 | *we can only rely on the position (x,y) of the rift nodes to create a segment:*/
|
---|
[1] | 269 | for (k=0;k<3;k++){
|
---|
[14222] | 270 | if ((x[*(index+el1*3+k)-1]==x[*(segments+3*j+0)-1]) && (y[*(index+el1*3+k)-1]==y[*(segments+3*j+0)-1])){
|
---|
[12086] | 271 | *(segments+3*j+0)=*(index+el1*3+k); _assert_(segments[3*j+0]<nods+1);
|
---|
[1] | 272 | break;
|
---|
| 273 | }
|
---|
| 274 | }
|
---|
| 275 | for (k=0;k<3;k++){
|
---|
[14222] | 276 | if ((x[*(index+el1*3+k)-1]==x[*(segments+3*j+1)-1]) && (y[*(index+el1*3+k)-1]==y[*(segments+3*j+1)-1])){
|
---|
[12086] | 277 | *(segments+3*j+1)=*(index+el1*3+k); _assert_(segments[3*j+1]<nods+1);
|
---|
[1] | 278 | break;
|
---|
| 279 | }
|
---|
| 280 | }
|
---|
| 281 | /*Deal with el2: */
|
---|
| 282 | *(segments+3*(nsegs+i)+2)=el2+1;
|
---|
| 283 | *(segmentmarkerlist+(nsegs+i))=*(segmentmarkerlist+j);
|
---|
| 284 | for (k=0;k<3;k++){
|
---|
[14222] | 285 | if ((x[*(index+el2*3+k)-1]==x[*(segments+3*j+0)-1]) && (y[*(index+el2*3+k)-1]==y[*(segments+3*j+0)-1])){
|
---|
[12086] | 286 | *(segments+3*(nsegs+i)+0)=*(index+el2*3+k); _assert_(segments[3*(nsegs+i)+0]<nods+1);
|
---|
[1] | 287 | break;
|
---|
| 288 | }
|
---|
| 289 | }
|
---|
| 290 | for (k=0;k<3;k++){
|
---|
[14222] | 291 | if ((x[*(index+el2*3+k)-1]==x[*(segments+3*j+1)-1]) && (y[*(index+el2*3+k)-1]==y[*(segments+3*j+1)-1])){
|
---|
[12086] | 292 | *(segments+3*(nsegs+i)+1)=*(index+el2*3+k); _assert_(segments[3*(nsegs+i)+1]<nods+1);
|
---|
[1] | 293 | break;
|
---|
| 294 | }
|
---|
| 295 | }
|
---|
| 296 | }
|
---|
| 297 | if (*(segments+3*j+2)==(el2+1)){
|
---|
| 298 | /*segment j is the same as rift segment i.*/
|
---|
| 299 | /*Let's update segments[j][:] using element el2 and the corresponding rift segment: */
|
---|
| 300 | for (k=0;k<3;k++){
|
---|
[14222] | 301 | if ((x[*(index+el2*3+k)-1]==x[*(segments+3*j+0)-1]) && (y[*(index+el2*3+k)-1]==y[*(segments+3*j+0)-1])){
|
---|
[12086] | 302 | *(segments+3*j+0)=*(index+el2*3+k); _assert_(segments[3*j+0]<nods+1);
|
---|
[1] | 303 | break;
|
---|
| 304 | }
|
---|
| 305 | }
|
---|
| 306 | for (k=0;k<3;k++){
|
---|
[14222] | 307 | if ((x[*(index+el2*3+k)-1]==x[*(segments+3*j+1)-1]) && (y[*(index+el2*3+k)-1]==y[*(segments+3*j+1)-1])){
|
---|
[12086] | 308 | *(segments+3*j+1)=*(index+el2*3+k);_assert_(segments[3*j+1]<nods+1);
|
---|
[1] | 309 | break;
|
---|
| 310 | }
|
---|
| 311 | }
|
---|
| 312 | /*Deal with el1: */
|
---|
| 313 | *(segments+3*(nsegs+i)+2)=el1+1;
|
---|
| 314 | *(segmentmarkerlist+(nsegs+i))=*(segmentmarkerlist+j);
|
---|
| 315 | for (k=0;k<3;k++){
|
---|
[14222] | 316 | if ((x[*(index+el1*3+k)-1]==x[*(segments+3*j+0)-1]) && (y[*(index+el1*3+k)-1]==y[*(segments+3*j+0)-1])){
|
---|
[12086] | 317 | *(segments+3*(nsegs+i)+0)=*(index+el1*3+k);_assert_(segments[3*(nsegs+i)+0]<nods+1);
|
---|
[1] | 318 | break;
|
---|
| 319 | }
|
---|
| 320 | }
|
---|
| 321 | for (k=0;k<3;k++){
|
---|
[14222] | 322 | if ((x[*(index+el1*3+k)-1]==x[*(segments+3*j+1)-1]) && (y[*(index+el1*3+k)-1]==y[*(segments+3*j+1)-1])){
|
---|
[12086] | 323 | *(segments+3*(nsegs+i)+1)=*(index+el1*3+k);_assert_(segments[3*(nsegs+i)+1]<nods+1);
|
---|
[1] | 324 | break;
|
---|
| 325 | }
|
---|
| 326 | }
|
---|
| 327 | }
|
---|
| 328 | }
|
---|
| 329 | }
|
---|
| 330 | nsegs+=nriftsegs;
|
---|
| 331 |
|
---|
| 332 | /*Assign output pointers: */
|
---|
| 333 | *psegments=segments;
|
---|
| 334 | *psegmentmarkerlist=segmentmarkerlist;
|
---|
| 335 | *pnsegs=nsegs;
|
---|
[13622] | 336 |
|
---|
[1] | 337 | return noerr;
|
---|
[12080] | 338 | }/*}}}*/
|
---|
[18063] | 339 | int FindElement(int A,int B,int* index,int nel){/*{{{*/
|
---|
[1] | 340 |
|
---|
| 341 | int el=-1;
|
---|
[14222] | 342 | for (int n=0;n<nel;n++){
|
---|
| 343 | if(((index[3*n+0]==A) || (index[3*n+1]==A) || (index[3*n+2]==A)) && ((index[3*n+0]==B) || (index[3*n+1]==B) || (index[3*n+2]==B))){
|
---|
[1] | 344 | el=n;
|
---|
| 345 | break;
|
---|
| 346 | }
|
---|
| 347 | }
|
---|
| 348 | return el;
|
---|
[12080] | 349 | }/*}}}*/
|
---|
[18063] | 350 | int SplitRiftSegments(int** psegments,int** psegmentmarkerlist, int* pnumsegs, int* pnumrifts,int** priftsnumsegs,int*** priftssegments,int numrifts,int nods,int nel){/*{{{*/
|
---|
[1] | 351 |
|
---|
| 352 | /*Using segment markers, wring out the rift segments from the segments. Rift markers are
|
---|
| 353 | *of the form 2+i where i=0 to number of rifts */
|
---|
| 354 |
|
---|
| 355 | int noerr=1;
|
---|
| 356 | int i,j,counter;
|
---|
| 357 |
|
---|
| 358 | /*input: */
|
---|
[14222] | 359 | int *segments = NULL;
|
---|
| 360 | int *segmentmarkerlist = NULL;
|
---|
[1] | 361 | int numsegs;
|
---|
[13622] | 362 |
|
---|
[1] | 363 | /*output: */
|
---|
[14222] | 364 | int new_numsegs;
|
---|
| 365 | int *riftsnumsegs = NULL;
|
---|
| 366 | int **riftssegments = NULL;
|
---|
| 367 | int *new_segments = NULL;
|
---|
| 368 | int *new_segmentmarkers = NULL;
|
---|
[1] | 369 |
|
---|
| 370 | /*intermediary: */
|
---|
[14222] | 371 | int* riftsegment=NULL;
|
---|
[1] | 372 |
|
---|
| 373 | /*Recover input arguments: */
|
---|
[14222] | 374 | segments = *psegments;
|
---|
| 375 | numsegs = *pnumsegs;
|
---|
| 376 | segmentmarkerlist = *psegmentmarkerlist;
|
---|
[1] | 377 |
|
---|
| 378 | /*First, figure out how many segments will be left in 'segments': */
|
---|
| 379 | counter=0;
|
---|
| 380 | for (i=0;i<numsegs;i++){
|
---|
| 381 | if (segmentmarkerlist[i]==1)counter++; //1 is default marker for non-rifts;
|
---|
| 382 | }
|
---|
| 383 | /*Allocate new segments: */
|
---|
| 384 | new_numsegs=counter;
|
---|
[14222] | 385 | new_segments=xNew<int>(new_numsegs*3);
|
---|
| 386 | new_segmentmarkers=xNew<int>(new_numsegs);
|
---|
[1] | 387 |
|
---|
| 388 | /*Copy new segments info : */
|
---|
| 389 | counter=0;
|
---|
| 390 | for (i=0;i<numsegs;i++){
|
---|
| 391 | if (segmentmarkerlist[i]==1){
|
---|
[12080] | 392 | new_segments[3*counter+0]=segments[3*i+0];
|
---|
| 393 | new_segments[3*counter+1]=segments[3*i+1];
|
---|
| 394 | new_segments[3*counter+2]=segments[3*i+2];
|
---|
[1] | 395 | new_segmentmarkers[counter]=segmentmarkerlist[i];
|
---|
| 396 | counter++;
|
---|
| 397 | }
|
---|
| 398 | }
|
---|
| 399 |
|
---|
| 400 | /*Now deal with rift segments: */
|
---|
[12436] | 401 | riftsnumsegs=xNew<int>(numrifts);
|
---|
[14222] | 402 | riftssegments=xNew<int*>(numrifts);
|
---|
[1] | 403 | for (i=0;i<numrifts;i++){
|
---|
| 404 | /*Figure out how many segments for rift i: */
|
---|
| 405 | counter=0;
|
---|
| 406 | for (j=0;j<numsegs;j++){
|
---|
| 407 | if (segmentmarkerlist[j]==2+i)counter++;
|
---|
| 408 | }
|
---|
| 409 | riftsnumsegs[i]=counter;
|
---|
[14222] | 410 | riftsegment=xNew<int>(counter*3);
|
---|
[1] | 411 | /*Copy new segments info :*/
|
---|
| 412 | counter=0;
|
---|
| 413 | for (j=0;j<numsegs;j++){
|
---|
| 414 | if (segmentmarkerlist[j]==(2+i)){
|
---|
[12086] | 415 | riftsegment[3*counter+0]=segments[3*j+0];_assert_(riftsegment[3*counter+0]<nods+1);
|
---|
| 416 | riftsegment[3*counter+1]=segments[3*j+1];_assert_(riftsegment[3*counter+1]<nods+1);
|
---|
| 417 | riftsegment[3*counter+2]=segments[3*j+2];_assert_(riftsegment[3*counter+2]<nel+1);
|
---|
[1] | 418 | counter++;
|
---|
| 419 | }
|
---|
| 420 | }
|
---|
| 421 | *(riftssegments+i)=riftsegment;
|
---|
| 422 | }
|
---|
| 423 |
|
---|
[27232] | 424 | /*Free resources: */
|
---|
[14222] | 425 | xDelete<int>(segments);
|
---|
[1] | 426 |
|
---|
| 427 | /*Assign output pointers: */
|
---|
| 428 | *psegments=new_segments;
|
---|
| 429 | *psegmentmarkerlist=new_segmentmarkers;
|
---|
| 430 | *pnumsegs=new_numsegs;
|
---|
| 431 | *pnumrifts=numrifts;
|
---|
| 432 | *priftssegments=riftssegments;
|
---|
| 433 | *priftsnumsegs=riftsnumsegs;
|
---|
| 434 | return noerr;
|
---|
[12080] | 435 | }/*}}}*/
|
---|
[18063] | 436 | int PairRiftElements(int** priftsnumpairs,int*** priftspairs,int numrifts,int* riftsnumsegments,int** riftssegments,double* x,double* y){/*{{{*/
|
---|
[1] | 437 |
|
---|
| 438 | int noerr=1;
|
---|
| 439 | int i,j,k;
|
---|
| 440 |
|
---|
| 441 | /*output: */
|
---|
[14222] | 442 | int *riftsnumpairs = NULL;
|
---|
| 443 | int **riftspairs = NULL;
|
---|
[1] | 444 |
|
---|
| 445 | /*intermediary :*/
|
---|
[14222] | 446 | int numsegs;
|
---|
| 447 | int* segments=NULL;
|
---|
| 448 | int* pairs=NULL;
|
---|
| 449 | int node1,node2,node3,node4;
|
---|
[1] | 450 |
|
---|
[12436] | 451 | riftsnumpairs=xNew<int>(numrifts);
|
---|
[14222] | 452 | riftspairs=xNew<int*>(numrifts);
|
---|
[1] | 453 | for (i=0;i<numrifts;i++){
|
---|
| 454 | segments=riftssegments[i];
|
---|
[14222] | 455 | numsegs =riftsnumsegments[i];
|
---|
[1] | 456 | riftsnumpairs[i]=numsegs;
|
---|
[14222] | 457 | pairs=xNew<int>(2*numsegs);
|
---|
[1] | 458 | for (j=0;j<numsegs;j++){
|
---|
[14222] | 459 | pairs[2*j+0]=segments[3*j+2]; //retrieve element to which this segment belongs.
|
---|
| 460 | node1=segments[3*j+0]-1; node2=segments[3*j+1]-1;
|
---|
[1] | 461 | /*Find element facing on other side of rift: */
|
---|
| 462 | for (k=0;k<numsegs;k++){
|
---|
| 463 | if (k==j)continue;
|
---|
[14222] | 464 | node3=segments[3*k+0]-1; node4=segments[3*k+1]-1;
|
---|
[8301] | 465 | /*We are trying to find 2 elements, where position of node3 == position of node1, and position of node4 == position of node2*/
|
---|
[16521] | 466 | if ( ((x[node3]==x[node1]) && (y[node3]==y[node1]) && (x[node4]==x[node2]) && (y[node4]==y[node2]))
|
---|
| 467 | || ((x[node3]==x[node2]) && (y[node3]==y[node2]) && (x[node4]==x[node1]) && (y[node4]==y[node1])) ){
|
---|
[1] | 468 | /*We found the corresponding element: */
|
---|
[14222] | 469 | pairs[2*j+1]=segments[3*k+2];
|
---|
[1] | 470 | break;
|
---|
| 471 | }
|
---|
| 472 | }
|
---|
| 473 | }
|
---|
| 474 | riftspairs[i]=pairs;
|
---|
| 475 | }
|
---|
| 476 |
|
---|
| 477 | /*Assign output pointers: */
|
---|
| 478 | *priftsnumpairs=riftsnumpairs;
|
---|
| 479 | *priftspairs=riftspairs;
|
---|
| 480 | return noerr;
|
---|
[12080] | 481 | }/*}}}*/
|
---|
[18063] | 482 | int IsRiftPresent(int* priftflag,int* pnumrifts,int* segmentmarkerlist,int nsegs){/*{{{*/
|
---|
[1] | 483 |
|
---|
| 484 | int i;
|
---|
| 485 | int noerr=1;
|
---|
[13622] | 486 |
|
---|
[1] | 487 | /*output: */
|
---|
| 488 | int riftflag=0;
|
---|
| 489 | int numrifts=0;
|
---|
| 490 |
|
---|
[14222] | 491 | int maxmark=1; //default marker for regular segments
|
---|
[1] | 492 |
|
---|
| 493 | /*Any marker >=2 indicates a certain rift: */
|
---|
| 494 | numrifts=0;
|
---|
| 495 | for (i=0;i<nsegs;i++){
|
---|
| 496 | if (segmentmarkerlist[i]>maxmark){
|
---|
| 497 | numrifts++;
|
---|
| 498 | maxmark=segmentmarkerlist[i];
|
---|
| 499 | }
|
---|
| 500 | }
|
---|
[14222] | 501 | if(numrifts)riftflag=1;
|
---|
[1] | 502 |
|
---|
| 503 | /*Assign output pointers:*/
|
---|
| 504 | *priftflag=riftflag;
|
---|
| 505 | *pnumrifts=numrifts;
|
---|
| 506 | return noerr;
|
---|
[12080] | 507 | }/*}}}*/
|
---|
[18063] | 508 | int OrderRifts(int** priftstips,int** riftssegments,int** riftspairs,int numrifts,int* riftsnumsegments,double* x,double* y,int nods,int nels){/*{{{*/
|
---|
[13622] | 509 |
|
---|
[1] | 510 | int noerr=1;
|
---|
| 511 | int i,j,k,counter;
|
---|
| 512 |
|
---|
| 513 | /*intermediary: */
|
---|
[14222] | 514 | int *riftsegments = NULL;
|
---|
| 515 | int *riftpairs = NULL;
|
---|
[1] | 516 | int numsegs;
|
---|
| 517 |
|
---|
| 518 | /*ordering and copy: */
|
---|
[14222] | 519 | int *order = NULL;
|
---|
| 520 | int *riftsegments_copy = NULL;
|
---|
| 521 | int *riftpairs_copy = NULL;
|
---|
[1] | 522 |
|
---|
[8301] | 523 | /*node and element manipulation: */
|
---|
[14222] | 524 | int node1,node2,node3,node4,temp_node,tip1,tip2,node;
|
---|
| 525 | int el2;
|
---|
| 526 | int already_ordered=0;
|
---|
[1] | 527 |
|
---|
| 528 | /*output: */
|
---|
[14222] | 529 | int* riftstips=NULL;
|
---|
[1] | 530 |
|
---|
| 531 | /*Allocate byproduct of this routine, riftstips: */
|
---|
[14222] | 532 | riftstips=xNew<int>(numrifts*2);
|
---|
[1] | 533 |
|
---|
| 534 | /*Go through all rifts: */
|
---|
| 535 | for (i=0;i<numrifts;i++){
|
---|
[14222] | 536 | riftsegments = riftssegments[i];
|
---|
| 537 | riftpairs = riftspairs[i];
|
---|
| 538 | numsegs = riftsnumsegments[i];
|
---|
[13622] | 539 |
|
---|
[1] | 540 | /*Allocate copy of riftsegments and riftpairs,
|
---|
| 541 | *as well as ordering vector: */
|
---|
[14222] | 542 | riftsegments_copy=xNew<int>(numsegs*3);
|
---|
| 543 | riftpairs_copy=xNew<int>(numsegs*2);
|
---|
[12436] | 544 | order=xNew<int>(numsegs);
|
---|
[1] | 545 |
|
---|
[8301] | 546 | /*First find the tips, using the pairs. If a pair of elements has one node in common, this node is a rift tip: */
|
---|
[1] | 547 | tip1=-1;
|
---|
| 548 | tip2=-1;
|
---|
| 549 |
|
---|
| 550 | for (j=0;j<numsegs;j++){
|
---|
| 551 | el2=*(riftpairs+2*j+1);
|
---|
[14222] | 552 | node1=*(riftsegments+3*j+0);
|
---|
| 553 | node2=*(riftsegments+3*j+1);
|
---|
[8301] | 554 | /*Summary, el1 and el2 are facing one another across the rift. node1 and node2 belong to el1 and
|
---|
| 555 | *are located on the rift. Find node3 and node4, nodes belonging to el2 and located on the rift: */
|
---|
[1] | 556 | for (k=0;k<numsegs;k++){
|
---|
| 557 | if (*(riftsegments+3*k+2)==el2){
|
---|
[14222] | 558 | node3=*(riftsegments+3*k+0);
|
---|
| 559 | node4=*(riftsegments+3*k+1);
|
---|
[1] | 560 | break;
|
---|
| 561 | }
|
---|
| 562 | }
|
---|
[8301] | 563 | /* Make sure node3 faces node1 and node4 faces node2: */
|
---|
[12086] | 564 | _assert_(node1<nods+1 && node4<nods+1);
|
---|
| 565 | _assert_(node1>0 && node4>0);
|
---|
| 566 | if ((x[node1-1]==x[node4-1]) && (y[node1-1]==y[node4-1])){
|
---|
[8301] | 567 | /*Swap node3 and node4:*/
|
---|
| 568 | temp_node=node3;
|
---|
| 569 | node3=node4;
|
---|
| 570 | node4=temp_node;
|
---|
[1] | 571 | }
|
---|
| 572 |
|
---|
| 573 | /*Figure out if a tip is on this element: */
|
---|
[8301] | 574 | if (node3==node1){
|
---|
| 575 | /*node1 is a tip*/
|
---|
[1] | 576 | if (tip1==-1) {
|
---|
[8301] | 577 | tip1=node1;
|
---|
[1] | 578 | continue;
|
---|
| 579 | }
|
---|
[8301] | 580 | if ((tip2==-1) && (node1!=tip1)){
|
---|
| 581 | tip2=node1;
|
---|
[1] | 582 | break;
|
---|
| 583 | }
|
---|
| 584 | }
|
---|
[13622] | 585 |
|
---|
[8301] | 586 | if (node4==node2){
|
---|
| 587 | /*node2 is a tip*/
|
---|
[1] | 588 | if (tip1==-1){
|
---|
[8301] | 589 | tip1=node2;
|
---|
[1] | 590 | continue;
|
---|
| 591 | }
|
---|
[8301] | 592 | if ((tip2==-1) && (node2!=tip1)){
|
---|
| 593 | tip2=node2;
|
---|
[1] | 594 | break;
|
---|
| 595 | }
|
---|
| 596 | }
|
---|
| 597 | }
|
---|
| 598 |
|
---|
| 599 | /*Record tips in riftstips: */
|
---|
[14222] | 600 | *(riftstips+2*i+0)=tip1;
|
---|
| 601 | *(riftstips+2*i+1)=tip2;
|
---|
[1] | 602 |
|
---|
| 603 | /*We have the two tips for this rift. Go from tip1 to tip2, and figure out the order in which segments are sequential.
|
---|
| 604 | *Because two elements are connected to tip1, we chose one first, which defines the direction we are rotating along the rift. */
|
---|
[8301] | 605 | node=tip1;
|
---|
[1] | 606 | for (counter=0;counter<numsegs;counter++){
|
---|
| 607 | for (j=0;j<numsegs;j++){
|
---|
[14222] | 608 | node1=*(riftsegments+3*j+0);
|
---|
| 609 | node2=*(riftsegments+3*j+1);
|
---|
[13622] | 610 |
|
---|
[8301] | 611 | if ((node1==node) || (node2==node)){
|
---|
| 612 | /*Ok, this segment is connected to node, plug its index into order, unless we already plugged it before: */
|
---|
[1] | 613 | already_ordered=0;
|
---|
| 614 | for (k=0;k<counter;k++){
|
---|
| 615 | if(order[k]==j){
|
---|
| 616 | already_ordered=1;
|
---|
| 617 | break;
|
---|
| 618 | }
|
---|
| 619 | }
|
---|
| 620 | if (!already_ordered){
|
---|
| 621 | order[counter]=j;
|
---|
[8301] | 622 | if(node1==node){
|
---|
| 623 | node=node2;
|
---|
[1] | 624 | }
|
---|
[8301] | 625 | else if(node2==node){
|
---|
| 626 | node=node1;
|
---|
[1] | 627 | }
|
---|
| 628 | break;
|
---|
| 629 | }
|
---|
| 630 | }
|
---|
| 631 | }
|
---|
| 632 | }
|
---|
| 633 |
|
---|
| 634 | /*Using the order vector, and the riftsegments_copy and riftspairs_copy, reorder the segments and the pairs: */
|
---|
| 635 | for (j=0;j<numsegs;j++){
|
---|
[6412] | 636 | _assert_(order[j]<numsegs);
|
---|
[1] | 637 | *(riftsegments_copy+3*j+0)=*(riftsegments+3*order[j]+0);
|
---|
| 638 | *(riftsegments_copy+3*j+1)=*(riftsegments+3*order[j]+1);
|
---|
| 639 | *(riftsegments_copy+3*j+2)=*(riftsegments+3*order[j]+2);
|
---|
| 640 | *(riftpairs_copy+2*j+0)=*(riftpairs+2*order[j]+0);
|
---|
| 641 | *(riftpairs_copy+2*j+1)=*(riftpairs+2*order[j]+1);
|
---|
| 642 | }
|
---|
[13622] | 643 |
|
---|
[1] | 644 | for (j=0;j<numsegs;j++){
|
---|
| 645 | *(riftsegments+3*j+0)=*(riftsegments_copy+3*j+0);
|
---|
| 646 | *(riftsegments+3*j+1)=*(riftsegments_copy+3*j+1);
|
---|
| 647 | *(riftsegments+3*j+2)=*(riftsegments_copy+3*j+2);
|
---|
| 648 | *(riftpairs+2*j+0)=*(riftpairs_copy+2*j+0);
|
---|
| 649 | *(riftpairs+2*j+1)=*(riftpairs_copy+2*j+1);
|
---|
| 650 | }
|
---|
| 651 |
|
---|
[12436] | 652 | xDelete<int>(order);
|
---|
[14222] | 653 | xDelete<int>(riftsegments_copy);
|
---|
| 654 | xDelete<int>(riftpairs_copy);
|
---|
[1] | 655 |
|
---|
| 656 | }
|
---|
| 657 |
|
---|
| 658 | /*Assign output pointer:*/
|
---|
| 659 | *priftstips=riftstips;
|
---|
| 660 | return noerr;
|
---|
[12080] | 661 | }/*}}}*/
|
---|
[18063] | 662 | int PenaltyPairs(double*** priftspenaltypairs,int** priftsnumpenaltypairs,int numrifts,int** riftssegments,/*{{{*/
|
---|
[14222] | 663 | int* riftsnumsegs,int** riftspairs,int* riftstips,double* x,double* y){
|
---|
[1] | 664 |
|
---|
| 665 | int noerr=1;
|
---|
| 666 | int i,j,k,k0;
|
---|
| 667 |
|
---|
[8301] | 668 | double el1,el2,node1,node2,node3,node4;
|
---|
[9320] | 669 | double temp_node;
|
---|
[1] | 670 |
|
---|
| 671 | /*output: */
|
---|
[12436] | 672 | double **riftspenaltypairs = NULL;
|
---|
| 673 | double *riftpenaltypairs = NULL;
|
---|
| 674 | int *riftsnumpenaltypairs = NULL;
|
---|
[1] | 675 |
|
---|
| 676 | /*intermediary: */
|
---|
| 677 | int numsegs;
|
---|
[14222] | 678 | int* riftsegments=NULL;
|
---|
| 679 | int* riftpairs=NULL;
|
---|
[1] | 680 | int counter;
|
---|
| 681 | double normal[2];
|
---|
| 682 | double length;
|
---|
| 683 | int k1,k2;
|
---|
| 684 |
|
---|
| 685 | /*Allocate: */
|
---|
[12436] | 686 | riftspenaltypairs=xNew<double*>(numrifts);
|
---|
| 687 | riftsnumpenaltypairs=xNew<int>(numrifts);
|
---|
[1] | 688 |
|
---|
| 689 | for(i=0;i<numrifts;i++){
|
---|
| 690 | numsegs=riftsnumsegs[i];
|
---|
| 691 | riftsegments=riftssegments[i];
|
---|
| 692 | riftpairs=riftspairs[i];
|
---|
| 693 |
|
---|
| 694 | /*allocate riftpenaltypairs, and riftnumpenaltypairs: */
|
---|
[12446] | 695 | if((numsegs/2-1)!=0)riftpenaltypairs=xNewZeroInit<double>((numsegs/2-1)*RIFTPENALTYPAIRSWIDTH);
|
---|
[13622] | 696 |
|
---|
[1] | 697 | /*Go through only one flank of the rifts, not counting the tips: */
|
---|
| 698 | counter=0;
|
---|
| 699 | for(j=0;j<(numsegs/2);j++){
|
---|
| 700 | el1=*(riftpairs+2*j+0);
|
---|
| 701 | el2=*(riftpairs+2*j+1);
|
---|
[8301] | 702 | node1=*(riftsegments+3*j+0);
|
---|
| 703 | node2=*(riftsegments+3*j+1);
|
---|
| 704 | /*Find segment index to recover node3 and node4, facing node1 and node2: */
|
---|
[1] | 705 | k0=-1;
|
---|
| 706 | for(k=0;k<numsegs;k++){
|
---|
| 707 | if(*(riftsegments+3*k+2)==el2){
|
---|
| 708 | k0=k;
|
---|
| 709 | break;
|
---|
| 710 | }
|
---|
| 711 | }
|
---|
[8301] | 712 | node3=*(riftsegments+3*k0+0);
|
---|
| 713 | node4=*(riftsegments+3*k0+1);
|
---|
[1] | 714 |
|
---|
[8301] | 715 | /* Make sure node3 faces node1 and node4 faces node2: */
|
---|
| 716 | if ((x[(int)node1-1]==x[(int)node4-1]) && (y[(int)node1-1]==y[(int)node4-1])){
|
---|
| 717 | /*Swap node3 and node4:*/
|
---|
| 718 | temp_node=node3;
|
---|
| 719 | node3=node4;
|
---|
| 720 | node4=temp_node;
|
---|
[1] | 721 | }
|
---|
[8301] | 722 | /*Ok, we have node1 facing node3, and node2 facing node4. Compute the normal to
|
---|
[1] | 723 | *this segment, and its length: */
|
---|
[8301] | 724 | normal[0]=cos(atan2(x[(int)node1-1]-x[(int)node2-1],y[(int)node2-1]-y[(int)node1-1]));
|
---|
| 725 | normal[1]=sin(atan2(x[(int)node1-1]-x[(int)node2-1],y[(int)node2-1]-y[(int)node1-1]));
|
---|
| 726 | length=sqrt(pow(x[(int)node2-1]-x[(int)node1-1],(double)2)+pow(y[(int)node2-1]-y[(int)node1-1],(double)2));
|
---|
[1] | 727 |
|
---|
[8301] | 728 | /*Be careful here, we want penalty loads on each node, not on each segment. This means we cannot plug node1,
|
---|
| 729 | * node2, node3 and node4 directly into riftpenaltypairs. We need to include node1, node2, node3 and node4,
|
---|
[1] | 730 | * only once. We'll add the normals and the lengths : */
|
---|
| 731 |
|
---|
[8301] | 732 | if(node1!=node3){ //exclude tips from loads
|
---|
[1] | 733 | k1=-1;
|
---|
| 734 | for(k=0;k<counter;k++){
|
---|
[8301] | 735 | if( (*(riftpenaltypairs+k*7+0))==node1){
|
---|
[1] | 736 | k1=k;
|
---|
| 737 | break;
|
---|
| 738 | }
|
---|
| 739 | }
|
---|
| 740 | if(k1==-1){
|
---|
[8301] | 741 | *(riftpenaltypairs+counter*7+0)=node1;
|
---|
| 742 | *(riftpenaltypairs+counter*7+1)=node3;
|
---|
[1] | 743 | *(riftpenaltypairs+counter*7+2)=el1;
|
---|
| 744 | *(riftpenaltypairs+counter*7+3)=el2;
|
---|
| 745 | *(riftpenaltypairs+counter*7+4)=normal[0];
|
---|
| 746 | *(riftpenaltypairs+counter*7+5)=normal[1];
|
---|
| 747 | *(riftpenaltypairs+counter*7+6)=length/2;
|
---|
| 748 | counter++;
|
---|
| 749 | }
|
---|
| 750 | else{
|
---|
| 751 | *(riftpenaltypairs+k1*7+4)+=normal[0];
|
---|
| 752 | *(riftpenaltypairs+k1*7+5)+=normal[1];
|
---|
| 753 | *(riftpenaltypairs+k1*7+6)+=length/2;
|
---|
| 754 | }
|
---|
| 755 | }
|
---|
[8301] | 756 | if(node2!=node4){
|
---|
[1] | 757 | k2=-1;
|
---|
| 758 | for(k=0;k<counter;k++){
|
---|
[8301] | 759 | if( (*(riftpenaltypairs+k*7+0))==node2){
|
---|
[1] | 760 | k2=k;
|
---|
| 761 | break;
|
---|
| 762 | }
|
---|
| 763 | }
|
---|
| 764 | if(k2==-1){
|
---|
[8301] | 765 | *(riftpenaltypairs+counter*7+0)=node2;
|
---|
| 766 | *(riftpenaltypairs+counter*7+1)=node4;
|
---|
[1] | 767 | *(riftpenaltypairs+counter*7+2)=el1;
|
---|
| 768 | *(riftpenaltypairs+counter*7+3)=el2;
|
---|
| 769 | *(riftpenaltypairs+counter*7+4)=normal[0];
|
---|
| 770 | *(riftpenaltypairs+counter*7+5)=normal[1];
|
---|
| 771 | *(riftpenaltypairs+counter*7+6)=length/2;
|
---|
| 772 | counter++;
|
---|
| 773 | }
|
---|
| 774 | else{
|
---|
| 775 | *(riftpenaltypairs+k2*7+4)+=normal[0];
|
---|
| 776 | *(riftpenaltypairs+k2*7+5)+=normal[1];
|
---|
| 777 | *(riftpenaltypairs+k2*7+6)+=length/2;
|
---|
| 778 | }
|
---|
| 779 | }
|
---|
| 780 | }
|
---|
| 781 | /*Renormalize normals: */
|
---|
| 782 | for(j=0;j<counter;j++){
|
---|
[14222] | 783 | double magnitude=sqrt(pow( double(riftpenaltypairs[j*7+4]),2) + pow( double(riftpenaltypairs[j*7+5]),2) );
|
---|
[1] | 784 | *(riftpenaltypairs+j*7+4)=*(riftpenaltypairs+j*7+4)/magnitude;
|
---|
| 785 | *(riftpenaltypairs+j*7+5)=*(riftpenaltypairs+j*7+5)/magnitude;
|
---|
| 786 | }
|
---|
[13622] | 787 |
|
---|
[1] | 788 | riftspenaltypairs[i]=riftpenaltypairs;
|
---|
| 789 | riftsnumpenaltypairs[i]=(numsegs/2-1);
|
---|
| 790 | }
|
---|
| 791 |
|
---|
| 792 | /*Assign output pointers: */
|
---|
| 793 | *priftspenaltypairs=riftspenaltypairs;
|
---|
| 794 | *priftsnumpenaltypairs=riftsnumpenaltypairs;
|
---|
| 795 | return noerr;
|
---|
[14222] | 796 | }/*}}}*/
|
---|
| 797 | int RemoveCornersFromRifts(int** pindex,int* pnel,double** px,double** py,int* pnods,int* segments,int* segmentmarkers,int num_seg){/*{{{*/
|
---|
[1] | 798 |
|
---|
| 799 | int noerr=1;
|
---|
| 800 | int i,j,k;
|
---|
[14222] | 801 | int node1,node2,node3;
|
---|
[1] | 802 | int el;
|
---|
| 803 | double pair[2];
|
---|
| 804 | int pair_count=0;
|
---|
| 805 | int triple=0;
|
---|
| 806 |
|
---|
| 807 | /*Recover input: */
|
---|
[14222] | 808 | int *index = *pindex;
|
---|
| 809 | int nel = *pnel;
|
---|
| 810 | double *x = *px;
|
---|
| 811 | double *y = *py;
|
---|
| 812 | int nods = *pnods;
|
---|
[1] | 813 |
|
---|
| 814 | for (i=0;i<num_seg;i++){
|
---|
[8301] | 815 | node1=*(segments+3*i+0);
|
---|
| 816 | node2=*(segments+3*i+1);
|
---|
| 817 | /*Find all elements connected to [node1 node2]: */
|
---|
[1] | 818 | pair_count=0;
|
---|
| 819 | for (j=0;j<nel;j++){
|
---|
[8301] | 820 | if (*(index+3*j+0)==node1){
|
---|
| 821 | if ((*(index+3*j+1)==node2) || (*(index+3*j+2)==node2)){
|
---|
[1] | 822 | pair[pair_count]=j;
|
---|
| 823 | pair_count++;
|
---|
| 824 | }
|
---|
| 825 | }
|
---|
[8301] | 826 | if (*(index+3*j+1)==node1){
|
---|
| 827 | if ((*(index+3*j+0)==node2) || (*(index+3*j+2)==node2)){
|
---|
[1] | 828 | pair[pair_count]=j;
|
---|
| 829 | pair_count++;
|
---|
| 830 | }
|
---|
| 831 | }
|
---|
[8301] | 832 | if (*(index+3*j+2)==node1){
|
---|
| 833 | if ((*(index+3*j+0)==node2) || (*(index+3*j+1)==node2)){
|
---|
[1] | 834 | pair[pair_count]=j;
|
---|
| 835 | pair_count++;
|
---|
| 836 | }
|
---|
| 837 | }
|
---|
| 838 | }
|
---|
| 839 | /*Ok, we have pair_count elements connected to this segment. For each of these elements,
|
---|
[8301] | 840 | *figure out if the third node also belongs to a segment: */
|
---|
[1] | 841 | if ((pair_count==0) || (pair_count==1)){ //we only select the rift segments, which belong to 2 elements
|
---|
| 842 | continue;
|
---|
| 843 | }
|
---|
| 844 | else{
|
---|
| 845 | for (j=0;j<pair_count;j++){
|
---|
| 846 | el=(int)pair[j];
|
---|
| 847 | triple=0;
|
---|
[8301] | 848 | /*First find node3: */
|
---|
| 849 | if (*(index+3*el+0)==node1){
|
---|
| 850 | if (*(index+3*el+1)==node2)node3=*(index+3*el+2);
|
---|
| 851 | else node3=*(index+3*el+1);
|
---|
[1] | 852 | }
|
---|
[8301] | 853 | if (*(index+3*el+1)==node1){
|
---|
| 854 | if (*(index+3*el+0)==node2)node3=*(index+3*el+2);
|
---|
| 855 | else node3=*(index+3*el+0);
|
---|
[1] | 856 | }
|
---|
[8301] | 857 | if (*(index+3*el+2)==node1){
|
---|
| 858 | if (*(index+3*el+0)==node2)node3=*(index+3*el+1);
|
---|
| 859 | else node3=*(index+3*el+0);
|
---|
[1] | 860 | }
|
---|
[8301] | 861 | /*Ok, we have node3. Does node3 belong to a segment? : */
|
---|
[1] | 862 | for (k=0;k<num_seg;k++){
|
---|
[8301] | 863 | if ((node3==*(segments+3*k+0)) || (node3==*(segments+3*k+1))){
|
---|
[1] | 864 | triple=1;
|
---|
| 865 | break;
|
---|
| 866 | }
|
---|
| 867 | }
|
---|
| 868 | if(triple==1){
|
---|
| 869 | /*el is a corner element: we need to split it in 3 triangles: */
|
---|
[13248] | 870 | x=xReNew<double>(x,nods,nods+1);
|
---|
| 871 | y=xReNew<double>(y,nods,nods+1);
|
---|
[8301] | 872 | x[nods]=(x[(int)node1-1]+x[(int)node2-1]+x[(int)node3-1])/3;
|
---|
| 873 | y[nods]=(y[(int)node1-1]+y[(int)node2-1]+y[(int)node3-1])/3;
|
---|
[14222] | 874 | index=xReNew<int>(index,nel*3,(nel+2*3));
|
---|
[1] | 875 | /*First, reassign element el: */
|
---|
[8301] | 876 | *(index+3*el+0)=node1;
|
---|
| 877 | *(index+3*el+1)=node2;
|
---|
[1] | 878 | *(index+3*el+2)=nods+1;
|
---|
| 879 | /*Other two elements: */
|
---|
[8301] | 880 | *(index+3*nel+0)=node2;
|
---|
| 881 | *(index+3*nel+1)=node3;
|
---|
[1] | 882 | *(index+3*nel+2)=nods+1;
|
---|
| 883 |
|
---|
[8301] | 884 | *(index+3*(nel+1)+0)=node3;
|
---|
| 885 | *(index+3*(nel+1)+1)=node1;
|
---|
[1] | 886 | *(index+3*(nel+1)+2)=nods+1;
|
---|
| 887 | /*we need to change the segment elements corresponding to el: */
|
---|
| 888 | for (k=0;k<num_seg;k++){
|
---|
[14222] | 889 | if (*(segments+3*k+2)==(el+1)){
|
---|
[14235] | 890 | if ( ((*(segments+3*k+0)==node1) && (*(segments+3*k+1)==node2)) || ((*(segments+3*k+0)==node2) && (*(segments+3*k+1)==node1))) *(segments+3*k+2)=el+1;
|
---|
| 891 | if ( ((*(segments+3*k+0)==node2) && (*(segments+3*k+1)==node3)) || ((*(segments+3*k+0)==node3) && (*(segments+3*k+1)==node2))) *(segments+3*k+2)=nel+1;
|
---|
| 892 | if ( ((*(segments+3*k+0)==node3) && (*(segments+3*k+1)==node1)) || ((*(segments+3*k+0)==node1) && (*(segments+3*k+1)==node3))) *(segments+3*k+2)=nel+2;
|
---|
[1] | 893 | }
|
---|
| 894 | }
|
---|
| 895 |
|
---|
| 896 | nods=nods+1;
|
---|
| 897 | nel=nel+2;
|
---|
| 898 | i=0;
|
---|
| 899 | break;
|
---|
| 900 | }
|
---|
| 901 | } //for (j=0;j<pair_count;j++)
|
---|
| 902 | }
|
---|
| 903 | }// for (i=0;i<num_seg;i++)
|
---|
| 904 |
|
---|
| 905 | /*Assign output pointers: */
|
---|
| 906 | *pindex=index;
|
---|
| 907 | *pnel=nel;
|
---|
| 908 | *px=x;
|
---|
| 909 | *py=y;
|
---|
| 910 | *pnods=nods;
|
---|
| 911 | return noerr;
|
---|
[14222] | 912 | }/*}}}*/
|
---|