58 for(i=0;i<nodesd2;i++) {
59 indi = ind[i] = data->
topology[element][i];
60 globalcoord[i] = data->
x[indi];
61 globalcoord[i+nodesd2] = data->
y[indi];
63 (*material) = data->
material[element];
70 switch (elementtype / 100) {
88 printf(
"GetElementDimension: unknown elementtype %d\n",elementtype);
103 return(maxelementtype);
109 int i,minelementtype;
116 return(minelementtype);
122 int maxelementtype,elemdim;
139 int i,j,elemtype,*elemind,sides,ind2[
MAXNODESD2];
143 sides = elemtype/100;
145 if(side < 0 && sides > 4)
153 ind[0] = elemind[side];
159 ind[0] = elemind[side];
160 ind[1] = elemind[(side+1)%3];
162 else if( side < 6 ) {
164 ind[0] = elemind[side-3];
171 ind[0] = elemind[side];
172 ind[1] = elemind[(side+1)%3];
173 ind[2] = elemind[side+3];
175 else if( side < 9 ) {
177 ind[0] = elemind[side-3];
184 ind[0] = elemind[side];
185 ind[1] = elemind[(side+1)%3];
186 ind[2] = elemind[2*side+3];
187 ind[3] = elemind[2*side+4];
189 else if( side < 13) {
191 ind[0] = elemind[side-3];
198 ind[0] = elemind[side];
199 ind[1] = elemind[(side+1)%4];
203 ind[0] = elemind[side-4];
210 ind[0] = elemind[side];
211 ind[1] = elemind[(side+1)%4];
215 ind[0] = elemind[side-4];
223 ind[0] = elemind[side];
224 ind[1] = elemind[(side+1)%4];
225 ind[2] = elemind[side+4];
229 ind[0] = elemind[side-4];
236 ind[0] = elemind[side];
237 ind[1] = elemind[(side+1)%4];
238 ind[2] = elemind[side+4];
242 ind[0] = elemind[side-4];
249 ind[0] = elemind[side];
250 ind[1] = elemind[(side+1)%4];
251 ind[2] = elemind[2*side+4];
252 ind[3] = elemind[2*side+5];
256 ind[0] = elemind[side-4];
263 ind[0] = elemind[side];
264 ind[1] = elemind[(side+1)%4];
265 ind[2] = elemind[2*side+4];
266 ind[3] = elemind[2*side+5];
270 ind[0] = elemind[side-4];
278 ind[0] = elemind[side];
279 ind[1] = elemind[(side+1)%3];
291 ind[0] = elemind[side-4];
295 ind[0] = elemind[side-7];
296 ind[1] = elemind[(side-6)%3];
301 ind[0] = elemind[side-10];
310 ind[0] = elemind[side];
311 ind[1] = elemind[(side+1)%3];
313 ind[3] = elemind[4+side];
314 ind[4] = elemind[7+(side+1)%3];
315 ind[5] = elemind[7+side];
329 ind[0] = elemind[side-4];
331 ind[2] = elemind[side+3];
334 ind[0] = elemind[side-7];
335 ind[1] = elemind[(side-6)%3];
336 ind[2] = elemind[side-3];
341 ind[0] = elemind[side-10];
349 ind[0] = elemind[side];
350 ind[1] = elemind[(side+1)%3];
351 ind[2] = elemind[(side+1)%3+3];
352 ind[3] = elemind[side+3];
357 ind[i] = elemind[3*(side-3)+i];
362 ind[0] = elemind[side-5];
363 ind[1] = elemind[(side-4)%3];
366 ind[0] = elemind[3+side-8];
367 ind[1] = elemind[3+(side-7)%3];
370 ind[0] = elemind[side-11];
371 ind[1] = elemind[3+side-11];
374 else if (side < 20) {
376 ind[0] = elemind[side-14];
384 ind[0] = elemind[side];
386 ind[2] = elemind[(side+1)%4];
396 ind[0] = elemind[side-5];
397 ind[1] = elemind[(side-4)%4];
400 ind[0] = elemind[side-9];
406 ind[0] = elemind[side-13];
413 ind[0] = elemind[side];
414 ind[1] = elemind[(side+1)%4];
417 ind[3] = elemind[side+5];
418 ind[4] = elemind[(side+1)%4+9];
419 ind[5] = elemind[side%4+9];
421 else if (side == 4) {
426 ind[i+4] = elemind[i+5];
431 ind[0] = elemind[(side-5)];
432 ind[1] = elemind[(side-4)%4];
433 ind[2] = elemind[side];
436 ind[0] = elemind[side-9];
438 ind[2] = elemind[side];
443 ind[0] = elemind[side-13];
451 ind[0] = elemind[side];
452 ind[1] = elemind[(side+1)%4];
453 ind[2] = elemind[(side+1)%4+4];
454 ind[3] = elemind[side+4];
458 ind[i] = elemind[4*(side-4)+i];
464 ind[0] = elemind[side-6];
465 ind[1] = elemind[(side-5)%4];
468 ind[0] = elemind[side-6];
469 ind[1] = elemind[(side-9)%4+4];
472 ind[0] = elemind[side-14];
473 ind[1] = elemind[side-14+4];
478 ind[0] = elemind[side-18];
485 ind[0] = elemind[side];
486 ind[1] = elemind[(side+1)%4];
487 ind[2] = elemind[(side+1)%4+4];
488 ind[3] = elemind[side+4];
489 ind[4] = elemind[8+side];
490 ind[5] = elemind[12+(side+1)%4];
491 ind[6] = elemind[16+side];
492 ind[7] = elemind[12+side];
496 ind[i] = elemind[4*(side-4)+i];
498 ind[i+4] = elemind[8*(side-4)+8+i];
505 ind[0] = elemind[side];
506 ind[1] = elemind[(side+1)%4];
507 ind[2] = elemind[(side+1)%4+4];
508 ind[3] = elemind[side+4];
509 ind[4] = elemind[8+side];
510 ind[5] = elemind[12+(side+1)%4];
511 ind[6] = elemind[16+side];
512 ind[7] = elemind[12+side];
513 ind[8] = elemind[20+side];
517 ind[i] = elemind[4*(side-4)+i];
519 ind[i+4] = elemind[8*(side-4)+8+i];
520 ind[8] = elemind[20+side];
525 printf(
"GetElementSide: unknown elementtype %d (elem=%d,side=%d)\n",elemtype,element,side);
529 if(*sideelemtype == 202 || *sideelemtype == 203 || *sideelemtype == 303 || *sideelemtype == 404) {
530 j = *sideelemtype/100-1;
537 else if(normal != 1) {
538 printf(
"GetElementSide: unknown option (normal=%d)\n",normal);
548 int elemtype,basetype,elemnodes,*elemind,hit,evenodd,quadratic,side;
551 basetype = elemtype / 100;
552 elemnodes = elemtype % 100;
553 quadratic = (elemnodes > basetype);
573 ind[0] = elemind[side];
574 ind[1] = elemind[(side+1)%3];
579 ind[0] = elemind[side];
580 ind[1] = elemind[(side+1)%4];
585 ind[0] = elemind[side];
586 ind[1] = elemind[(side+1)%3];
589 ind[0] = elemind[side-3];
595 ind[0] = elemind[side];
596 ind[1] = elemind[(side+1)%4];
599 ind[0] = elemind[side-4];
605 ind[0] = elemind[side];
606 ind[1] = elemind[(side+1)%3];
609 ind[0] = elemind[side-3];
610 ind[1] = elemind[side];
613 ind[0] = elemind[side-3];
614 ind[1] = elemind[3+(side+1)%3];
619 ind[0] = elemind[side];
620 ind[1] = elemind[(side+1)%4];
623 ind[0] = elemind[side-4];
624 ind[1] = elemind[side];
627 ind[0] = elemind[side-4];
628 ind[1] = elemind[4+(side+1)%4];
633 hit = (ind[0] || ind[1]);
636 if(hit && quadratic) {
637 evenodd = edge - 2*side;
641 ind[evenodd] = elemind[2];
645 ind[evenodd] = elemind[side+3];
649 ind[evenodd] = elemind[side+4];
653 ind[evenodd] = elemind[side+4];
657 ind[evenodd] = elemind[side+5];
661 ind[evenodd] = elemind[side+6];
665 ind[evenodd] = elemind[side+8];
679 int imax,imin,element;
685 for(element=1; element <= data->
noelements; element++) {
691 if(indxis) ind = indx[ind];
692 if(ind == 0)
continue;
693 if(ind > imax) imax = ind;
694 if(ind < imin) imin = ind;
696 if(imax-imin > indexwidth)
697 indexwidth = imax-imin;
741 sprintf(data->
bodyname[i],
"body%d",i);
768 data->
x[i] = data->
y[i] = data->
z[i] = 0.0;
773 printf(
"Allocated for %d %d-node elements resulting to %d nodes\n",
785 r2 = fabs(lim[1]-lim[0]);
786 if(r2 > fabs(lim[2]-lim[1]))
787 r2 = fabs(lim[2]-lim[1]);
789 for(i=0;i<points/2;i++) {
791 r1 = fabs(coords[2*i+1]);
793 if(fabs(x0) >= r2)
continue;
794 y0 = y-(lim[1]+coords[2*i+1]);
795 if(y0 < 0 && lim[0] > lim[1])
continue;
796 if(y0 > 0 && lim[2] < lim[1])
continue;
797 if(fabs(y0) >=
r2)
continue;
798 r = sqrt(x0*x0+y0*y0);
799 if(r < 1.0
e-50)
continue;
801 if(fabs(x0) > fabs(y0)) {
802 p = fabs(x0)/r - 1.0;
807 else if(fabs(x0) <= r2) {
808 *dx += p*x0*(r2-fabs(x0))/(r2-r1);
809 *dy += p*y0*(r2-fabs(x0))/(r2-r1);
813 p = fabs(y0)/r - 1.0;
818 else if(fabs(y0) <= r2) {
819 *dx += p*x0*(r2-fabs(y0))/(r2-r1);
820 *dy += p*y0*(r2-fabs(y0))/(r2-r1);
834 if(y > lim[0] && y < lim[2]) {
840 else if(x >= coords[points-2]) {
841 d = coords[points-1];
845 while(x > coords[2*i] && i < points/2-1) i++;
846 c = (coords[2*i+1]-coords[2*i-1])/(coords[2*i]-coords[2*i-2]);
847 d = coords[2*i-1] + c*(x-coords[2*i-2]);
851 *dy += d*(y-lim[0])/(lim[1]-lim[0]);
853 *dy += d*(lim[2]-
y)/(lim[2]-lim[1]);
867 if(y > lim[0] && y < lim[2]) {
873 while(x > coords[2*i] && i <= points/2-1) {
874 x1 = x1 +
cos(degs*coords[2*i-1])*(coords[2*i]-coords[2*i-2]);
875 z1 = z1 + sin(degs*coords[2*i-1])*(coords[2*i]-coords[2*i-2]);
878 x1 = x1 +
cos(degs*coords[2*i-1])*(x-coords[2*i-2]);
879 z1 = z1 + sin(degs*coords[2*i-1])*(x-coords[2*i-2]);
883 *dx += (x1-
x)*(y-lim[0])/(lim[1]-lim[0]);
884 *dz += z1*(y-lim[0])/(lim[1]-lim[0]);
887 *dx += (x1-
x)*(lim[2]-y)/(lim[2]-lim[1]);
888 *dz += z1*(lim[2]-
y)/(lim[2]-lim[1]);
899 if(y > lim[0] && y < lim[2]) {
904 else if(x >= coords[1]) {
905 d = coords[3]*sin(coords[2]*2.*
FM_PI);
908 c = coords[2]*2.*
FM_PI/(coords[1]-coords[0]);
909 d = coords[3]*sin(c*(x-coords[0]));
913 *dy += d*(y-lim[0])/(lim[1]-lim[0]);
915 *dy += d*(lim[2]-
y)/(lim[2]-lim[1]);
927 if(y > lim[0] && y < lim[2]) {
929 if(coords[1] > coords[0]) {
930 if(t<coords[0]) t = coords[0];
931 if(t>coords[1]) t = coords[1];
934 if(t>coords[0]) t = coords[0];
935 if(t<coords[1]) t = coords[1];
939 u = (t - coords[0])/(coords[1]-coords[0]);
943 d += coords[i+2] * pow(u,i);
947 *dy += d*(y-lim[0])/(lim[1]-lim[0]);
950 *dy += d*(lim[2]-
y)/(lim[2]-lim[1]);
962 if(y > lim[0] && y < lim[2]) {
964 if(coords[1] > coords[0]) {
965 if(t<coords[0]) t = coords[0];
966 if(t>coords[1]) t = coords[1];
969 if(t>coords[0]) t = coords[0];
970 if(t<coords[1]) t = coords[1];
974 u = (t - coords[0])/(coords[1]-coords[0]);
979 if(n>=1) d += u * coords[3];
986 d += coords[i+2] *
e;
990 *dy += d*(y-lim[0])/(lim[1]-lim[0]);
993 *dy += d*(lim[2]-
y)/(lim[2]-lim[1]);
1006 if(y > lim[0] && y < lim[2]) {
1007 if(x <= coords[0]) {
1010 else if(x >= coords[points-2]) {
1011 d = coords[points-1];
1015 while(x > coords[3*i] && i < points/3-1) i++;
1016 c = (coords[3*i+1]-coords[3*i-2])/pow((coords[3*i]-coords[3*i-3]),coords[3*i-1]);
1017 d = coords[3*i-2] + c*pow((x-coords[3*i-3]),coords[3*i-1]);
1021 *dy += d*(y-lim[0])/(lim[1]-lim[0]);
1023 *dy += d*(lim[2]-
y)/(lim[2]-lim[1]);
1032 Real sx,sy,ss,r,rat,
d,x0,y0;
1034 if(y > lim[0] && y < lim[2]) {
1035 if(x <= coords[0]) {
1038 else if(x >= coords[points-2]) {
1039 d = coords[points-1];
1043 while(x > coords[3*i] && i < points/3-1) i++;
1044 sx = 0.5*(coords[3*i]-coords[3*i-3]);
1045 sy = 0.5*(coords[3*i+1]-coords[3*i-2]);
1048 rat = sqrt(1.0/ss-1.0/(r*r))*r;
1049 x0 = coords[3*i-3] + sx - sy * rat;
1050 y0 = coords[3*i-2] + sy + sx * rat;
1051 d = y0-sqrt(r*r-(x-x0)*(x-x0))*r/fabs(r);
1055 *dy += d*(y-lim[0])/(lim[1]-lim[0]);
1057 *dy += d*(lim[2]-
y)/(lim[2]-lim[1]);
1073 int mode = 0,level,maplevel,
dim;
1100 elemtype = grid->
nonodes + 200;
1102 elemtype = grid->
nonodes + 400;
1108 for(cellj=1;cellj<= grid->
ycells ;cellj++) {
1109 for(j=1; j<=grid->
yelems[cellj]; j++)
1110 for(celli=1;celli<= grid->
xcells; celli++)
1111 if(k=grid->
numbered[cellj][celli]) {
1113 for(i=1; i<=grid->
xelems[celli]; i++) {
1119 data->
topology[elemind][l] = ind[l];
1120 data->
x[ind[l]] = globalcoord[l];
1121 data->
y[ind[l]] = globalcoord[l+
nonodes];
1134 maplim[3*k+1] = grid->
y[j];
1136 maplim[3*k+1] = grid->
x[j];
1146 for(level=0;level<10;level++) {
1151 if(maplevel ==
FALSE)
continue;
1153 if(level >= 5) data->
dim = 3;
1155 for(i=1;i<=data->
noknots;i++) {
1236 if(mode == 8 || mode == -8) {
1241 else if(level >= 5) {
1242 data->
z[i] += dx +
dy;
1257 dx = globalcoord[0]-globalcoord[1];
1258 dy = globalcoord[
nonodes]-globalcoord[nonodes+1];
1260 if(size < minsize) minsize = size;
1261 if(size > maxsize) maxsize = size;
1262 dx = globalcoord[0]-globalcoord[nonodes-1];
1263 dy = globalcoord[
nonodes]-globalcoord[2*nonodes-1];
1265 if(size < minsize) minsize = size;
1266 if(size > maxsize) maxsize = size;
1269 data->
maxsize = sqrt(maxsize);
1270 data->
minsize = sqrt(minsize);
1272 if(info)
printf(
"Maximum elementsize is %.3le and minimum %.3le.\n",
1280 Real value,
const char *dofname,
int eorder)
1286 if(variable == 0)
return(0);
1289 if(info)
printf(
"CreateVariable: Knots must first be created!\n");
1293 if(timesteps < 1) timesteps = 1;
1295 if(data->
edofs[variable] == 0) {
1298 data->
edofs[variable] = unknowns;
1301 if(info)
printf(
"Created variable %s with %d dofs.\n",
1302 dofname,data->
alldofs[variable]);
1303 for(i=1;i<=data->
alldofs[variable]*timesteps;i++)
1304 data->
dofs[variable][i] = value;
1306 else if (data->
edofs[variable] == unknowns) {
1307 if(info)
printf(
"CreateVariable: Variable %d exists with correct number of dofs!\n",
1311 if(info)
printf(
"CreateVariable: Variable %d exists with wrong number of dofs!\n",
1316 strcpy(data->
dofname[variable],dofname);
1331 if(data->
edofs[i] != 0) {
1332 if(data->
edofs[i] > 0)
1353 int sideelem,
int sideelemtype,
int *sideind)
1355 int i,j,sideelemtype2,elemind,parent,normal;
1356 int elemsides = 0,side,sidenodes,nohits,hit,noparent, bulknodes;
1361 for(parent=1;parent<=2;parent++) {
1363 elemind = bound->
parent[sideelem];
1364 noparent = (parent < 1);
1367 elemind = bound->
parent2[sideelem];
1373 if(elemsides == 8) elemsides = 6;
1374 else if(elemsides == 6) elemsides = 5;
1375 else if(elemsides == 5) elemsides = 4;
1377 for(normal=1;normal >= -1;normal -= 2) {
1379 for(side=0;side<elemsides;side++) {
1381 GetElementSide(elemind,side,normal,data,&sideind2[0],&sideelemtype2);
1383 if(sideelemtype2 < 300 && sideelemtype > 300)
break;
1384 if(sideelemtype2 < 200 && sideelemtype > 200)
break;
1385 if(sideelemtype != sideelemtype2)
continue;
1387 sidenodes = sideelemtype % 100;
1389 for(j=0;j<sidenodes;j++) {
1391 for(i=0;i<sidenodes;i++)
1392 if(sideind[(i+j)%sidenodes] != sideind2[i]) hit =
FALSE;
1396 bound->
side[sideelem] = side;
1397 bound->
normal[sideelem] = normal;
1400 bound->
side2[sideelem] = side;
1413 for(side=0;;side++) {
1415 GetElementSide(elemind,side,normal,data,&sideind2[0],&sideelemtype2);
1417 if(sideelemtype2 < 300 && sideelemtype > 300)
break;
1418 if(sideelemtype2 < 200 && sideelemtype > 200)
break;
1419 if(sideelemtype != sideelemtype2)
continue;
1421 sidenodes = sideelemtype % 100;
1424 for(j=0;j<sidenodes;j++)
1425 for(i=0;i<sidenodes;i++)
1426 if(sideind[i] == sideind2[j]) nohits++;
1427 if(nohits == sidenodes) {
1430 bound->
side[sideelem] = side;
1433 bound->
side2[sideelem] = side;
1442 printf(
"FindParentSide: unsuccesfull (elemtype=%d elemsides=%d parent=%d)\n",
1443 sideelemtype,elemsides,parent);
1448 for(i=0;i<sideelemtype%100;i++)
1449 printf(
" %d ",sideind[i]);
1453 for(i=0;i<elemsides;i++)
1467 struct BoundaryType *bound,
int material1,
int material2,
1468 int solidmat,
int boundarytype,
int info)
1480 int side,more,elem,elemind[2],nosides,no,times;
1481 int sidemat,thismat,size,setpoint,dimsides,cellside;
1489 printf(
"CreateBoundary: You tried to recreate the boundary!\n");
1493 printf(
"CreateBoundary: You tried to create a boundary before the knots were made.");
1496 if(material1 < 0 && material2 < 0) {
1497 printf(
"CreateBoundary: the material arguments are both negative");
1505 if(solidmat >= 2) solidmat -= 2;
1515 for(no=1; no <= data->
nocells; no++)
1516 for(side=0; side < dimsides; side++) {
1519 cellside = 3-2*side;
1524 sidemat = cell[no].
boundary[cellside];
1531 if( material1 >= 0 && material1 != sidemat)
continue;
1532 if( material2 >= 0 && material2 != thismat)
continue;
1534 if( material2 == -((side+2)%4+1) && sidemat == material1 &&
1535 sidemat != thismat) setpoint =
TRUE;
1536 if( material1 == -(side+1) && thismat == material2 &&
1537 sidemat != thismat) setpoint =
TRUE;
1539 if( material1 ==
MAT_BIGGER && sidemat > material2 ) setpoint =
TRUE;
1540 if( material1 ==
MAT_SMALLER && sidemat < material2 ) setpoint =
TRUE;
1542 if( material2 ==
MAT_BIGGER && thismat > material1 ) setpoint =
TRUE;
1543 if( material2 ==
MAT_SMALLER && thismat < material1 ) setpoint =
TRUE;
1545 if( sidemat == material1 && thismat == material2 ) setpoint =
TRUE;
1547 if(setpoint ==
TRUE) {
1560 bound->
parent[nosides] = elemind[0];
1561 bound->
parent2[nosides] = elemind[1];
1563 bound->
side[nosides] = side;
1564 bound->
side2[nosides] = (side+dimsides/2)%dimsides;
1566 bound->
types[nosides] = boundarytype;
1569 if(solidmat==
FIRST) {
1570 bound->
material[nosides] = sidemat;
1571 bound->
normal[nosides] = 1;
1574 bound->
material[nosides] = thismat;
1575 bound->
normal[nosides] = -1;
1585 printf(
"No boundary between materials %d and %d exists.\n",
1586 material1,material2);
1597 bound->
nosides = size = nosides;
1611 if(info)
printf(
"%d element sides between materials %d and %d were located to type %d.\n",
1612 nosides,material1,material2,boundarytype);
1622 int i,j,side,more,elem,elemind[2],nosides,no,times;
1623 int sidemat,thismat,size,setpoint,dimsides,cellside;
1624 int boundarytype,prevsidemat,prevthismat;
1625 int **bctypes,minmat,maxmat,maxtype;
1634 printf(
"CreateBoundary: You tried to recreate the boundary!\n");
1638 printf(
"CreateBoundary: You tried to create a boundary before the knots were made.");
1648 maxmat = minmat = 0;
1650 for(no=1; no <= data->
nocells; no++) {
1651 for(side=0; side < dimsides; side++) {
1653 cellside = 3-2*side;
1657 sidemat = cell[no].
boundary[cellside];
1664 maxmat =
MAX(maxmat,thismat);
1665 maxmat =
MAX(maxmat,sidemat);
1666 minmat =
MIN(minmat,thismat);
1667 minmat =
MIN(minmat,sidemat);
1671 bctypes =
Imatrix(minmat,maxmat,minmat,maxmat);
1672 for(i=minmat;i<=maxmat;i++)
1673 for(j=minmat;j<=maxmat;j++)
1677 for(no=1; no <= data->
nocells; no++) {
1678 for(side=0; side < dimsides; side++) {
1680 cellside = 3-2*side;
1684 sidemat = cell[no].
boundary[cellside];
1687 if(sidemat == thismat)
continue;
1689 if(bctypes[thismat][sidemat] == 0) {
1691 bctypes[thismat][sidemat] = boundarytype;
1692 if(0)
printf(
"type[%d %d] = %d\n",thismat,sidemat,boundarytype);
1696 maxtype = boundarytype;
1707 for(no=1; no <= data->
nocells; no++)
1708 for(side=0; side < dimsides; side++) {
1711 cellside = 3-2*side;
1716 sidemat = cell[no].
boundary[cellside];
1719 if(sidemat == thismat)
continue;
1720 boundarytype = bctypes[thismat][sidemat];
1730 bound->
parent[nosides] = elemind[0];
1731 bound->
parent2[nosides] = elemind[1];
1733 bound->
side[nosides] = side;
1734 bound->
side2[nosides] = (side+dimsides/2)%dimsides;
1736 bound->
types[nosides] = boundarytype;
1737 bound->
normal[nosides] = 1;
1741 prevsidemat = sidemat;
1742 prevthismat = thismat;
1745 if(nosides == 0)
return(0);
1754 bound->
nosides = size = nosides;
1770 if(info)
printf(
"%d boundary elements with %d types were automatically created\n",nosides,maxtype);
1782 printf(
"AllocateBoundary: You tried to recreate the boundary!\n");
1798 for(i=1;i<=size;i++) {
1801 bound->
side2[i] = 0;
1804 bound->
types[i] = 0;
1842 printf(
"%d element sides were destroyed.\n",nosides);
1852 int param1,
int param2,
int pointmode,
int pointtype,
int info)
1854 int size,i,no,corner,times,elem = 0,node;
1864 if(pointmode == 4) {
1865 for(no=1; no <= data->
nocells; no++)
1868 for(corner=0; corner < 4; corner++)
1869 if(cell[no].boundary[4+corner] == param1) {
1875 bound->
types[i] = pointtype;
1876 bound->
side[i] = 4 + corner;
1893 if(pointmode == 5) {
1895 for(no=1; no <= data->
nocells && corner <0; no++) {
1896 if(cell[no].xind-1 == param1 && cell[no].yind-1 == param2)
1898 else if(cell[no].xind == param1 && cell[no].yind-1 == param2)
1900 else if(cell[no].xind == param1 && cell[no].yind == param2)
1902 else if(cell[no].xind-1 == param1 && cell[no].yind == param2)
1911 bound->
types[i] = pointtype;
1912 bound->
side[i] = 4 + corner;
1924 node = data->
topology[elem][corner];
1925 printf(
"Found node %d at (%.3lg, %.3lg)\n",node,data->
x[node],data->
y[node]);
1930 if(times == 0 && size > 0) {
1936 if(info)
printf(
"Created %d new points of type %d in the corner of materials %d and %d.\n",
1937 size,pointtype,param1,param2);
1946 int i,j,
k,l,lmax,ind;
1953 if(info)
printf(
"Creating %d new nodes for discoutinuous boundary.\n",newknots);
1956 newsize = noknots+newknots;
1961 neworder =
Ivector(1,newsize);
1972 newx[j] = data->
x[i];
1973 newy[j] = data->
y[i];
1974 newz[j] = data->
z[i];
1977 if(lmax = data->
edofs[k])
1978 for(l=1;l<=lmax;l++)
1979 newdofs[k][lmax*(j-1)+l] = data->
dofs[
k][lmax*(i-1)+l];
1985 newx[j] = data->
x[i];
1986 newy[j] = data->
y[i];
1987 newz[j] = data->
z[i];
1989 if(lmax = data->
edofs[k])
1990 for(l=1;l<=lmax;l++)
1991 newdofs[k][lmax*(j-1)+l] = data->
dofs[
k][lmax*(i-1)+l];
1997 for(i=1;i<=newsize;i++)
1998 if(neworder[i] > 0) {
1999 if(order[neworder[i]] < 0)
2000 order[neworder[i]] = -i;
2002 order[neworder[i]] = i;
2010 if(data->
material[i] == material && order[ind] < 0)
2031 if(data->
edofs[k]) {
2032 data->
dofs[
k] = newdofs[
k];
2049 int side,parent,newknots,doublesides,maxtype,newbc;
2052 int mat1,mat2,par1,par2,mat1old,mat2old,
material;
2053 static int hitsexist=
FALSE,hitslength,*hits;
2063 mat1old = mat2old = 0;
2068 if(bound[bc].created ==
FALSE)
continue;
2071 for(i=1;i<=bound[bc].
nosides;i++) {
2072 if(bound[bc].
types[i] == boundtype) {
2073 par1 = bound[bc].
parent[i];
2079 if(!mat1old) mat1old = mat1;
2080 else if(mat1old != mat1) mat1old = -mat1;
2081 if(!mat2old) mat2old = mat2;
2082 else if(mat2old != mat2) mat2old = -mat2;
2090 if(!doublesides)
return(1);
2092 if(mat1old > 0) material = mat1old;
2093 else if(mat2old > 0) material = mat2old;
2095 printf(
"SetDiscontinuousBoundary: impossible to make the boundary of several materials\n");
2106 hitslength = (int) (1.1*data->
noknots);
2110 else if(hitslength <= data->
noknots) {
2112 hitslength = (int) (1.1*data->
noknots);
2130 for(i=1;i<=bound[bc].
nosides;i++) {
2131 maxtype =
MAX(maxtype, bound[bc].
types[i]);
2132 if(bound[bc].ediscont) maxtype =
MAX(maxtype, bound[bc].discont[i]);
2135 disconttype = maxtype + 1;
2136 if(info)
printf(
"Type of the other side of discontinous boundary set to %d.\n",disconttype);
2149 for(i=1;i<=bound[bc].
nosides;i++) {
2151 if(bound[bc].
types[i] != boundtype)
continue;
2153 if(!bound[bc].ediscont) {
2155 for(j=1;j<=bound[bc].
nosides;j++)
2156 bound[bc].discont[j] = 0;
2160 parent = bound[bc].
parent2[i];
2161 if(parent == 0)
continue;
2162 side = bound[bc].
side2[i];
2164 sidenodes = sideelemtype%100;
2166 bound[bc].
discont[i] = disconttype;
2168 for(j=0;j<sidenodes;j++) {
2169 ind =
abs(sideind[j]);
2172 if(order[ind] > 0) {
2174 order[ind] = -newknots;
2177 else if(endnodes == 0) {
2180 else if(order[ind] == 0) {
2182 order[ind] = -newknots;
2185 else if(endnodes == 1) {
2186 if(order[ind] > 0) {
2189 order[ind] = -newknots;
2194 else if(order[ind] == 0) {
2196 order[ind] = -newknots;
2203 if(endnodes == 0 || endnodes == 1) {
2210 if(newknots == 0)
return(3);
2219 int boundary1,
int boundary2,
int info)
2225 int parent,elemtype;
2226 int minp[2],maxp[2],bounds[2],dp[2],sumsides[2];
2229 printf(
"SetDiscontinuousBoundary: The boundary does not exist!\n");
2232 if(!bound->
nosides)
return(0);
2235 bounds[0] = boundary1;
2236 bounds[1] = boundary2;
2237 minp[0] = minp[1] = data->
noknots+1;
2238 maxp[0] = maxp[1] = 0;
2240 sumsides[0] = sumsides[1] = 0;
2244 for(i=1; i <= bound[j].
nosides; i++) {
2247 if(bound[j].
types[i] == bounds[k]) {
2250 if(bound[j].parent[i] > maxp[k]) maxp[
k] = bound[j].
parent[i];
2251 if(bound[j].parent[i] < minp[k]) minp[
k] = bound[j].
parent[i];
2257 for (k=0;k<=1;k++) {
2258 dp[
k] = maxp[
k] - minp[
k];
2259 if(info)
printf(
"Parents of boundary %d are on the interval [%d, %d]\n",
2260 bounds[k],minp[k],maxp[k]);
2263 if(dp[0] != dp[1] || sumsides[0] != sumsides[1]) {
2264 printf(
"FindPeriodicBoundary: The simple scheme cannot handle these boundaries!\n");
2265 printf(
"dp=[%d %d] sumsides=[%d %d]\n",dp[0],dp[1],sumsides[0],sumsides[1]);
2272 for(i=1; i <= bound[j].
nosides; i++) {
2275 if(bound[j].
types[i] == bounds[k]) {
2276 parent = bound[j].
parent[i];
2277 bound[j].
parent2[i] = bound[j].
parent[i] - minp[
k] + minp[(k+1)%2];
2279 if(!bound[j].ediscont) {
2281 for(l=1; l <= bound[j].
nosides; l++)
2282 bound[j].discont[l] = 0;
2288 if(elemtype%100 == 4) {
2289 bound[j].
side2[i] = (bound[j].
side[i] + 2) % 4;
2291 else if(elemtype%100 == 8) {
2292 if(bound[j].side[i] < 4) bound[j].
side2[i] = (bound[j].
side[i] + 2) % 4;
2293 if(bound[j].side[i] >= 4) bound[j].
side2[i] = 4 + (5 - bound[j].
side[i]);
2300 if(info)
printf(
"Periodic boundaries were set with a simple scheme\n");
2308 int bctype,
int connecttype,
int info)
2311 int i,j,
k,bc,sideelemtype,sidenodes;
2316 if(bound[bc].created ==
FALSE)
continue;
2317 if(bound[bc].nosides == 0)
continue;
2319 for(i=1;i<=bound[bc].
nosides;i++) {
2320 if(bound[bc].
types[i] != bctype)
continue;
2329 GetElementSide(bound[bc].parent[i],bound[bc].side[i],bound[bc].normal[i],
2330 data,sideind,&sideelemtype);
2331 sidenodes = sideelemtype%100;
2333 for(j=0;j<sidenodes;j++) {
2351 int i,j,
k,l,side = 0,elem,i1,isum = 0,sideelemtype;
2353 int **newtopo = NULL,*newmaterial = NULL,*newelementtypes = NULL,newnodes,*needed,*divisions,*division1;
2355 int allocated,maxanglej,evenodd,newelem;
2356 Real dx1,dx2,dy1,dy2,ds1,ds2;
2369 for(j=0;j<nonodes;j++)
2373 divisions =
Ivector(1,noelements);
2374 division1 =
Ivector(1,noelements);
2376 divisions[i] = division1[i] = 0;
2397 ds1 = sqrt(dx1*dx1+dy1*dy1);
2398 ds2 = sqrt(dx2*dx2+dy2*dy2);
2399 angles[j] = (180.0/
FM_PI) * acos((dx1*dx2+dy1*dy2)/(ds1*ds2));
2403 if(needed[data->
topology[i][j]] == 1) angles[j] *= 1.001;
2405 if(
abs(angles[j] > maxangle)) {
2406 maxangle = fabs(angles[j]);
2410 evenodd = maxanglej % 2;
2414 if( maxangle < critangle ) {
2416 newtype = elementtype;
2417 newnodes = elementtype % 100;
2420 switch(elementtype) {
2442 printf(
"ElementsToTriangles: not implemented for elementtype %d\n",elementtype);
2447 newmaxnodes =
MAX( newnodes, newmaxnodes );
2451 divisions[i] = triangles;
2452 division1[i] = newelements;
2453 newelements += triangles;
2457 for(j=division1[i]+1;j<=division1[i]+divisions[i];j++) {
2458 newelementtypes[j] = newtype;
2459 newmaterial[j] = data->
material[i];
2462 newelem = division1[i]+1;
2463 if(triangles == 1) {
2464 for(j=0;j<newnodes;j++)
2465 newtopo[newelem][j] = data->
topology[i][j];
2468 if(elementtype == 404 || elementtype == 409 || elementtype == 416) {
2470 newtopo[newelem][0] = data->
topology[i][0];
2471 newtopo[newelem][1] = data->
topology[i][1];
2472 newtopo[newelem][2] = data->
topology[i][3];
2473 newtopo[newelem+1][0] = data->
topology[i][2];
2474 newtopo[newelem+1][1] = data->
topology[i][3];
2475 newtopo[newelem+1][2] = data->
topology[i][1];
2478 newtopo[newelem][0] = data->
topology[i][1];
2479 newtopo[newelem][1] = data->
topology[i][2];
2480 newtopo[newelem][2] = data->
topology[i][0];
2481 newtopo[newelem+1][0] = data->
topology[i][3];
2482 newtopo[newelem+1][1] = data->
topology[i][0];
2483 newtopo[newelem+1][2] = data->
topology[i][2];
2486 if(elementtype == 409) {
2488 newtopo[newelem][3] = data->
topology[i][4];
2489 newtopo[newelem][4] = data->
topology[i][8];
2490 newtopo[newelem][5] = data->
topology[i][7];
2491 newtopo[newelem+1][3] = data->
topology[i][6];
2492 newtopo[newelem+1][4] = data->
topology[i][8];
2493 newtopo[newelem+1][5] = data->
topology[i][5];
2496 newtopo[newelem][3] = data->
topology[i][5];
2497 newtopo[newelem][4] = data->
topology[i][8];
2498 newtopo[newelem][5] = data->
topology[i][4];
2499 newtopo[newelem+1][3] = data->
topology[i][7];
2500 newtopo[newelem+1][4] = data->
topology[i][8];
2501 newtopo[newelem+1][5] = data->
topology[i][6];
2504 if(elementtype == 416) {
2506 newtopo[newelem][3] = data->
topology[i][4];
2507 newtopo[newelem][4] = data->
topology[i][5];
2508 newtopo[newelem][5] = data->
topology[i][13];
2509 newtopo[newelem][6] = data->
topology[i][15];
2510 newtopo[newelem][7] = data->
topology[i][10];
2511 newtopo[newelem][8] = data->
topology[i][11];
2512 newtopo[newelem][9] = data->
topology[i][12];
2514 newtopo[newelem+1][3] = data->
topology[i][8];
2515 newtopo[newelem+1][4] = data->
topology[i][9];
2516 newtopo[newelem+1][5] = data->
topology[i][15];
2517 newtopo[newelem+1][6] = data->
topology[i][13];
2518 newtopo[newelem+1][7] = data->
topology[i][6];
2519 newtopo[newelem+1][8] = data->
topology[i][7];
2520 newtopo[newelem+1][9] = data->
topology[i][14];
2523 newtopo[newelem][3] = data->
topology[i][6];
2524 newtopo[newelem][4] = data->
topology[i][7];
2525 newtopo[newelem][5] = data->
topology[i][14];
2526 newtopo[newelem][6] = data->
topology[i][12];
2527 newtopo[newelem][7] = data->
topology[i][4];
2528 newtopo[newelem][8] = data->
topology[i][5];
2529 newtopo[newelem][9] = data->
topology[i][13];
2531 newtopo[newelem+1][3] = data->
topology[i][10];
2532 newtopo[newelem+1][4] = data->
topology[i][11];
2533 newtopo[newelem+1][5] = data->
topology[i][12];
2534 newtopo[newelem+1][6] = data->
topology[i][14];
2535 newtopo[newelem+1][7] = data->
topology[i][8];
2536 newtopo[newelem+1][8] = data->
topology[i][9];
2537 newtopo[newelem+1][9] = data->
topology[i][15];
2540 else if(elementtype == 405) {
2541 newtopo[newelem][0] = data->
topology[i][0];
2542 newtopo[newelem][1] = data->
topology[i][1];
2543 newtopo[newelem][2] = data->
topology[i][4];
2544 newtopo[newelem+1][0] = data->
topology[i][1];
2545 newtopo[newelem+1][1] = data->
topology[i][2];
2546 newtopo[newelem+1][2] = data->
topology[i][4];
2547 newtopo[newelem+2][0] = data->
topology[i][2];
2548 newtopo[newelem+2][1] = data->
topology[i][3];
2549 newtopo[newelem+2][2] = data->
topology[i][4];
2550 newtopo[newelem+3][0] = data->
topology[i][3];
2551 newtopo[newelem+3][1] = data->
topology[i][0];
2552 newtopo[newelem+3][2] = data->
topology[i][4];
2560 newtopo =
Imatrix(1,newelements,0,newmaxnodes-1);
2561 newmaterial =
Ivector(1,newelements);
2562 newelementtypes =
Ivector(1,newelements);
2579 if(!bound[j].
created)
continue;
2581 for(i=1; i <= bound[j].
nosides; i++) {
2589 if(k == 0)
continue;
2593 GetElementSide(bound[j].parent[i],bound[j].side[i],bound[j].normal[i],
2594 data,sideind,&sideelemtype);
2596 GetElementSide(bound[j].parent2[i],bound[j].side2[i],bound[j].normal[i],
2597 data,sideind,&sideelemtype);
2599 if(sideelemtype/100 != 2) {
2600 printf(
"ElementsToTriangles: implemeted only for BCs 202 and 203\n");
2604 if(divisions[k] == 1) {
2605 elem = division1[
k]+1;
2606 side = bound[j].
side[i];
2612 for(elem=division1[k]+1;elem<=division1[
k]+divisions[
k];elem++) {
2614 for(i1=0;i1<3;i1++) {
2615 if(newtopo[elem][i1] == sideind[0]) isum++;
2616 if(newtopo[elem][i1] == sideind[1]) isum++;
2619 if(isum != 2)
continue;
2621 for(side=0;side<3;side++) {
2623 &data2,sideind2,&sideelemtype);
2625 for(i1=0;i1<2;i1++) {
2626 if(sideind2[i1] == sideind[0]) isum++;
2627 if(sideind2[i1] == sideind[1]) isum++;
2630 if(isum == 2)
goto nextparent;
2637 bound[j].
parent[i] = elem;
2638 bound[j].
side[i] = side;
2642 bound[j].
side2[i] = side;
2646 printf(
"Failed to find parent for side %d of %d (parent %d)\n",i,j,k);
2666 if(info)
printf(
"There are %d elements after triangularization (was %d)\n",
2667 newelements,noelements);
2678 for(i=1;i<=data->
noknots;i++) {
2680 fii =
FM_PI/180.0 * data->
y[i];
2684 data->
x[i] = (rad+dr) *
cos(fii);
2685 data->
y[i] = (rad+dr) * sin(fii);
2688 if(info)
printf(
"Making coordinate transformation from polar to cartesian\n");
2699 for(i=1;i<=data->
noknots;i++) {
2701 fii =
FM_PI/180.0 * data->
y[i];
2703 data->
x[i] = rad *
cos(fii);
2704 data->
y[i] = rad * sin(fii);
2707 if(info)
printf(
"Making coordinate transformation from cylindrical to cartesian\n");
2720 int **newtopo,*newmaterial,*newelementtypes,
maxnodes;
2721 Real *newx,*newy,*newz;
2729 if(0)
printf(
"Uniting two meshes to %d nodes and %d elements.\n",noknots,noelements);
2732 if(!bound2[j].
created)
continue;
2735 if(!bound1[k].created)
break;
2738 printf(
"k=%d j=%d\n",k,j);
2755 for(i=1; i <= bound1[
k].
nosides; i++) {
2757 if(bound1[k].parent2[i])
2763 newtopo =
Imatrix(1,noelements,0,maxnodes-1);
2764 newmaterial =
Ivector(1,noelements);
2765 newelementtypes =
Ivector(1,noelements);
2769 for(i=1;i<=data1->
noknots;i++) {
2770 newx[i] = data1->
x[i];
2771 newy[i] = data1->
y[i];
2772 newz[i] = data1->
z[i];
2774 for(i=1;i<=data2->
noknots;i++) {
2775 newx[i+data1->
noknots] = data2->
x[i];
2776 newy[i+data1->
noknots] = data2->
y[i];
2777 newz[i+data1->
noknots] = data2->
z[i];
2781 newmaterial[i] = data1->
material[i];
2783 nonodes = newelementtypes[i]%100;
2784 for(j=0;j<nonodes;j++)
2785 newtopo[i][j] = data1->
topology[i][j];
2790 nonodes = newelementtypes[i+data1->
noelements]%100;
2791 for(j=0;j<nonodes;j++)
2814 if(info)
printf(
"Two meshes were united to one with %d nodes and %d elements.\n",
2815 noknots,noelements);
2822 int *ncopies,
Real *meshsize,
int diffmats,
int info)
2827 int **newtopo,*newmaterial,*newelementtypes,
maxnodes;
2828 int maxmaterial,maxtype,ncopy,bndr,nosides;
2829 Real *newx,*newy,*newz;
2830 Real maxcoord[3],mincoord[3];
2832 int *vparent,*vparent2,*vside,*vside2,*vtypes,*vmaterial,*vnormal,*vdiscont = NULL;
2834 printf(
"CloneMeshes: copying the mesh to a matrix\n");
2835 if(diffmats) diffmats = 1;
2838 for(i=0;i<data->
dim;i++) {
2839 if(ncopies[i] > 1) totcopies *= ncopies[i];
2841 if(data->
dim == 2) ncopies[2] = 1;
2843 maxcoord[0] = mincoord[0] = data->
x[1];
2844 maxcoord[1] = mincoord[1] = data->
y[1];
2845 maxcoord[2] = mincoord[2] = data->
z[1];
2847 for(i=1;i<=data->
noknots;i++) {
2848 if(data->
x[i] > maxcoord[0]) maxcoord[0] = data->
x[i];
2849 if(data->
x[i] < mincoord[0]) mincoord[0] = data->
x[i];
2850 if(data->
y[i] > maxcoord[1]) maxcoord[1] = data->
y[i];
2851 if(data->
y[i] < mincoord[1]) mincoord[1] = data->
y[i];
2852 if(data->
z[i] > maxcoord[2]) maxcoord[2] = data->
z[i];
2853 if(data->
z[i] < mincoord[2]) mincoord[2] = data->
z[i];
2856 for(i=0;i<data->
dim;i++) {
2857 if(maxcoord[i]-mincoord[i] > meshsize[i]) meshsize[i] = maxcoord[i]-mincoord[i];
2860 noknots = totcopies * data->
noknots;
2864 printf(
"Copying the mesh to %d identical domains.\n",totcopies);
2867 newtopo =
Imatrix(1,noelements,0,maxnodes-1);
2868 newmaterial =
Ivector(1,noelements);
2869 newelementtypes =
Ivector(1,noelements);
2875 for(l=0;l<ncopies[2];l++) {
2876 for(k=0;k<ncopies[1];k++) {
2877 for(j=0;j<ncopies[0];j++) {
2878 for(i=1;i<=data->
noknots;i++) {
2879 ncopy = j+k*ncopies[0]+k*l*ncopies[1];
2880 ind = i + ncopy*data->
noknots;
2882 newx[ind] = data->
x[i] + j*meshsize[0];
2883 newy[ind] = data->
y[i] + k*meshsize[1];
2884 newz[ind] = data->
z[i] + l*meshsize[2];
2894 for(l=0;l<ncopies[2];l++) {
2895 for(k=0;k<ncopies[1];k++) {
2896 for(j=0;j<ncopies[0];j++) {
2898 ncopy = j+k*ncopies[0]+k*l*ncopies[1];
2901 newmaterial[ind] = data->
material[i] + diffmats*maxmaterial*ncopy;
2904 nonodes = newelementtypes[i]%100;
2905 for(m=0;m<nonodes;m++)
2914 if(!bound[j].
created)
continue;
2915 for(i=1; i <= bound[j].
nosides; i++)
2916 if(maxtype < bound[j].
types[i]) maxtype = bound[j].
types[i];
2921 if(!bound[bndr].
created)
continue;
2922 nosides = totcopies * bound[bndr].
nosides;
2924 vparent =
Ivector(1, nosides);
2925 vparent2 =
Ivector(1, nosides);
2928 vmaterial =
Ivector(1, nosides);
2930 vnormal =
Ivector(1, nosides);
2932 if(bound[bndr].ediscont) {
2933 vdiscont =
Ivector(1, nosides);
2934 for(i=1; i <= nosides; i++)
2938 for(l=0;l<ncopies[2];l++) {
2939 for(k=0;k<ncopies[1];k++) {
2940 for(j=0;j<ncopies[0];j++) {
2941 for(i=1; i <= bound[bndr].
nosides; i++) {
2943 ncopy = j+k*ncopies[0]+k*l*ncopies[1];
2944 ind = i + ncopy * bound[bndr].
nosides;
2947 vside[ind] = bound[bndr].
side[i];
2949 if(bound[bndr].parent2[i]) {
2951 vside2[ind] = bound[bndr].
side2[i];
2958 vnormal[ind] = bound[bndr].
normal[i];
2960 if(bound[bndr].ediscont)
2961 vdiscont[ind] = bound[bndr].
discont[i];
2963 vtypes[ind] = bound[bndr].
types[i] + diffmats * ncopy * maxtype;
2965 vmaterial[ind] = bound[bndr].
material[i] + ncopy * maxmaterial;
2971 bound[bndr].
nosides = nosides;
2972 bound[bndr].
side = vside;
2974 bound[bndr].
side2 = vside2;
2975 bound[bndr].
parent = vparent;
2976 bound[bndr].
parent2 = vparent2;
2977 bound[bndr].
types = vtypes;
2979 if(bound[bndr].ediscont)
2980 bound[bndr].
discont = vdiscont;
2998 if(info)
printf(
"The mesh was copied to several identical meshes\n");
3005 int *symmaxis,
int diffmats,
Real *meshsize,
int symmbound,
int info)
3010 int **newtopo,*newmaterial,*newelementtypes,
maxnodes;
3011 int maxtype,bndr,nosides;
3012 Real *newx,*newy,*newz;
3013 Real maxcoord[3],mincoord[3];
3014 int ind0,elem0,axis1,axis2,axis3,symmcount;
3016 int *vparent,*vparent2,*vside,*vside2,*vtypes,*vmaterial,*vnormal,*vdiscont = NULL;
3018 printf(
"MirrorMeshes: making a symmetric mapping of the mesh\n");
3020 if(symmaxis[0]) symmaxis[0] = 1;
3021 if(symmaxis[1]) symmaxis[1] = 1;
3022 if(symmaxis[2]) symmaxis[2] = 1;
3023 if(data->
dim < 3) symmaxis[2] = 0;
3025 maxcoord[0] = mincoord[0] = data->
x[1];
3026 maxcoord[1] = mincoord[1] = data->
y[1];
3027 maxcoord[2] = mincoord[2] = data->
z[1];
3029 for(i=1;i<=data->
noknots;i++) {
3030 if(data->
x[i] > maxcoord[0]) maxcoord[0] = data->
x[i];
3031 if(data->
x[i] < mincoord[0]) mincoord[0] = data->
x[i];
3032 if(data->
y[i] > maxcoord[1]) maxcoord[1] = data->
y[i];
3033 if(data->
y[i] < mincoord[1]) mincoord[1] = data->
y[i];
3034 if(data->
z[i] > maxcoord[2]) maxcoord[2] = data->
z[i];
3035 if(data->
z[i] < mincoord[2]) mincoord[2] = data->
z[i];
3038 for(i=0;i<data->
dim;i++) {
3039 if(maxcoord[i]-mincoord[i] > meshsize[i]) meshsize[i] = maxcoord[i]-mincoord[i];
3042 if(diffmats) diffmats = 1;
3045 for(i=0;i<data->
dim;i++)
3046 if(symmaxis[i]) totcopies *= 2;
3048 noknots = totcopies * data->
noknots;
3052 printf(
"Mirroring the mesh to %d symmetrical domains.\n",totcopies);
3055 newtopo =
Imatrix(1,noelements,0,maxnodes-1);
3056 newmaterial =
Ivector(1,noelements);
3057 newelementtypes =
Ivector(1,noelements);
3065 for(axis1=0;axis1 <= symmaxis[0];axis1++) {
3066 for(axis2=0;axis2 <= symmaxis[1];axis2++) {
3067 for(axis3=0;axis3 <= symmaxis[2];axis3++) {
3069 for(i=1;i<=data->
noknots;i++) {
3072 newx[ind] = (1-2*axis1) * data->
x[i];
3073 newy[ind] = (1-2*axis2) * data->
y[i];
3074 newz[ind] = (1-2*axis3)*data->
z[i];
3076 newmaterial[ind] = data->
material[i];
3087 for(axis1=0;axis1 <= symmaxis[0];axis1++) {
3088 for(axis2=0;axis2 <= symmaxis[1];axis2++) {
3089 for(axis3=0;axis3 <= symmaxis[2];axis3++) {
3093 newmaterial[ind] = data->
material[i];
3095 nonodes = newelementtypes[i]%100;
3096 for(m=0;m<nonodes;m++)
3097 newtopo[ind][m] = data->
topology[i][m] + ind0;
3102 printf(
"elem0=%d ind0=%d\n",elem0,ind0);
3109 if(!bound[j].
created)
continue;
3110 for(i=1; i <= bound[j].
nosides; i++)
3111 if(maxtype < bound[j].
types[i]) maxtype = bound[j].
types[i];
3116 if(!bound[bndr].
created)
continue;
3117 nosides = totcopies * bound[bndr].
nosides;
3120 vparent =
Ivector(1, nosides);
3121 vparent2 =
Ivector(1, nosides);
3124 vmaterial =
Ivector(1, nosides);
3126 vnormal =
Ivector(1, nosides);
3128 if(bound[bndr].ediscont) {
3129 vdiscont =
Ivector(1, nosides);
3130 for(i=1;i<=nosides;i++)
3138 for(axis1=0;axis1 <= symmaxis[0];axis1++) {
3139 for(axis2=0;axis2 <= symmaxis[1];axis2++) {
3140 for(axis3=0;axis3 <= symmaxis[2];axis3++) {
3142 for(i=1; i <= bound[bndr].
nosides; i++) {
3144 if(bound[bndr].
types[i] == symmbound)
continue;
3147 vparent[ind] = bound[bndr].
parent[i] + elem0;
3148 vparent2[ind] = bound[bndr].
parent2[i] + elem0;
3149 vside[ind] = bound[bndr].
side[i];
3150 vside2[ind] = bound[bndr].
side2[i];
3152 vnormal[ind] = bound[bndr].
normal[i];
3154 if(bound[bndr].ediscont)
3155 vdiscont[ind] = bound[bndr].
discont[i];
3157 vtypes[ind] = bound[bndr].
types[i] + diffmats * symmcount * maxtype;
3159 vmaterial[ind] = bound[bndr].
material[i];
3169 bound[bndr].
nosides = nosides;
3170 bound[bndr].
side = vside;
3171 bound[bndr].
side2 = vside2;
3172 bound[bndr].
parent = vparent;
3173 bound[bndr].
parent2 = vparent2;
3174 bound[bndr].
types = vtypes;
3176 if(bound[bndr].ediscont)
3177 bound[bndr].
discont = vdiscont;
3195 if(info)
printf(
"The mesh was copied to several identical meshes\n");
3203 int *origindx,
Real corder[],
int info)
3206 int **neighbours,*newrank,*newindx,*oldrank,*oldindx;
3207 int nocands = 0,*cands,ind,ind2,cantdo;
3208 int elemtype,indready,iter,*localorder,*localtmp,nolocal;
3221 if(elemtype != 404 && elemtype != 303 && elemtype != 808) cantdo = elemtype;
3224 printf(
"Automatic reordering not specified for elementtype %d\n",cantdo);
3228 printf(
"Allocating...\n");
3231 localorder =
Ivector(1,maxnodes);
3232 localtmp =
Ivector(1,maxnodes);
3233 localdist =
Rvector(1,maxnodes);
3235 neighbours =
Imatrix(1,noknots,1,maxnodes);
3242 oldindx[i] = origindx[i];
3245 oldrank[origindx[i]] = i;
3248 if(info)
printf(
"Indexwidth of the initial node order is %d.\n",minwidth);
3252 neighbours[j][i] = 0;
3255 if(info)
printf(
"Initializing neighbours\n");
3259 nonodes = elemtype%100;
3261 for(i=0;i<nonodes;i++) {
3264 if(elemtype == 404 || elemtype == 303) {
3266 cands[1] = (i+1)%nonodes;
3267 cands[2] = (i+nonodes-1)%nonodes;
3269 else if(elemtype == 808) {
3277 cands[1] = (i-4+1)%4+4;
3278 cands[2] = (i-4+3)%4+4;
3283 for(k=1;k<=nocands;k++) {
3286 if(neighbours[ind][l] == 0)
break;
3287 if(neighbours[ind][l] == ind2) ind2 = 0;
3289 if(ind2) neighbours[ind][l] = ind2;
3296 printf(
"neigbourds[%d]= ",j);
3298 printf(
"%d ",neighbours[j][l]);
3303 if(info)
printf(
"Reordering neighbours table\n");
3311 if(ind = neighbours[j][l]) {
3314 dx = data->
x[l] - data->
x[ind];
3315 dy = data->
y[l] - data->
y[ind];
3316 if(data->
dim == 3) dz = data->
z[l] - data->
z[ind];
3317 localdist[l] = corder[0]*fabs(dx) + corder[1]*fabs(dy) + corder[2]*fabs(dz);
3321 SortIndex(nolocal,localdist,localorder);
3323 for(l=1;l<=nolocal;l++)
3324 neighbours[j][l] = localtmp[localorder[l]];
3327 for(l=1;l<=nolocal;l++)
3328 printf(
"j=%d l=%d dist=%.3le order=%d %d\n",
3329 j,l,localdist[l],localorder[l],neighbours[j][l]);
3335 for(iter=1;iter<=iterations;iter++) {
3337 if(info)
printf(
"Optimal topology testing %d\n",iter);
3346 if(indready > ind) {
3347 for(l=noknots;l>=1;l--)
3348 if(j = oldindx[l])
break;
3349 if(info)
printf(
"Starting over from node %d when ind=%d indready=%d\n",j,ind,indready);
3352 j = newindx[indready] ;
3355 for(l=1;ind2 = neighbours[j][l];l++) {
3357 if(!newrank[ind2]) {
3359 newrank[ind2] = ind;
3360 newindx[ind] = ind2;
3361 oldindx[oldrank[ind2]] = 0;
3368 }
while(ind < noknots);
3371 if(info)
printf(
"Indexwidth of the suggested node order is %d.\n",indexwidth);
3374 oldrank[i] = newrank[i];
3377 oldindx[i] = newindx[i];
3379 if(indexwidth < minwidth) {
3381 origindx[i] = newindx[i];
3406 int **newtopology,*newmaterial,*newelementtypes;
3407 int *indx,*revindx,*elemindx,*revelemindx;
3408 int oldnoknots, oldnoelements;
3409 Real *newx,*newy,*newz,*arrange;
3412 noelements = oldnoelements = data->
noelements;
3413 noknots = oldnoknots = data->
noknots;
3415 if(info)
printf(
"Reordering %d knots and %d elements in %d-dimensions.\n",
3416 noknots,noelements,data->
dim);
3418 if(noelements > noknots)
3426 elemindx =
Ivector(1,noelements);
3427 revelemindx =
Ivector(1,noelements);
3436 xmin = xmax = data->
x[1];
3437 ymin = ymax = data->
y[1];
3438 if(data->
dim == 3) zmin = zmax = data->
z[1];
3439 for(i=1;i<=data->
noknots;i++) {
3440 if(xmin > data->
x[i]) xmin = data->
x[i];
3441 if(xmax < data->
x[i]) xmax = data->
x[i];
3442 if(ymin > data->
y[i]) ymin = data->
y[i];
3443 if(ymax < data->
y[i]) ymax = data->
y[i];
3444 if(data->
dim == 3) {
3445 if(zmin > data->
z[i]) zmin = data->
z[i];
3446 if(zmax < data->
z[i]) zmax = data->
z[i];
3451 if(data->
dim == 3) dz = zmax-zmin;
3460 cx = pow(cbase,1.0*(dx>dy)+1.0*(dx>dz));
3461 cy = pow(cbase,1.0*(dy>dx)+1.0*(dy>dz));
3462 cz = pow(cbase,1.0*(dz>dx)+1.0*(dz>dx));
3469 if(info)
printf(
"Ordering with (%.3lg*x + %.3lg*y + %.3lg*z)\n",cx,cy,cz);
3471 arrange[i] = cx*data->
x[i] + cy*data->
y[i];
3472 if(data->
dim == 3) arrange[i] += cz*data->
z[i];
3479 revindx[indx[i]] = i;
3485 for(i=0;i<nonodes;i++) {
3487 arrange[j] += cx*data->
x[
k] + cy*data->
y[
k];
3488 if(data->
dim == 3) arrange[j] += cz*data->
z[
k];
3494 revelemindx[elemindx[i]] = i;
3499 printf(
"i=%d indx=%d revi=%d f=%.2lg\n",
3500 i,indx[i],revindx[i],arrange[indx[i]]);
3503 if(info)
printf(
"Moving knots to new positions\n");
3508 for(i=1;i<=data->
noknots;i++) {
3509 newx[i] = data->
x[indx[i]];
3510 newy[i] = data->
y[indx[i]];
3511 newz[i] = data->
z[indx[i]];
3522 if(info)
printf(
"Moving the elements to new positions\n");
3525 newmaterial =
Ivector(1,noelements);
3526 newelementtypes =
Ivector(1,noelements);
3529 newmaterial[j] = data->
material[elemindx[j]];
3531 nonodes = newelementtypes[j]%100;
3532 for(i=0;i<nonodes;i++) {
3533 k = data->
topology[elemindx[j]][i];
3534 newtopology[j][i] = revindx[
k];
3543 printf(
"Moving the parents of the boundary nodes.\n");
3546 if(!bound[j].
created)
continue;
3548 for(i=1; i <= bound[j].
nosides; i++) {
3552 if(bound[j].parent2[i])
3558 printf(
"Indexwidth of the new node order is %d.\n",i);
3579 for(i=1;i<=
noknots;i++) indx[i] = 0;
3583 for(i=0;i<nonodes;i++)
3591 indx[i] = activeknots;
3595 if( noknots == activeknots) {
3596 if(info)
printf(
"All %d nodes were used by the mesh elements\n",noknots);
3600 if(info)
printf(
"Removing %d unused nodes (out of %d) from the mesh\n",noknots-activeknots,noknots);
3604 for(i=0;i<nonodes;i++)
3611 data->
x[j] = data->
x[i];
3612 data->
y[j] = data->
y[i];
3613 data->
z[j] = data->
z[i];
3625 int renumber,
int bcoffset,
int info)
3628 int minbc=0,maxbc=0,*mapbc;
3629 int elemdim=0,elemtype=0,*mapdim,sideind[
MAXNODESD1];
3632 if(0)
printf(
"Renumbering boundary types\n");
3636 if(!bound[j].
created)
continue;
3638 for(i=1;i<=bound[j].
nosides;i++) {
3640 maxbc = minbc = bound[j].
types[i];
3643 maxbc =
MAX(maxbc,bound[j].
types[i]);
3644 minbc =
MIN(minbc,bound[j].
types[i]);
3650 mapdim =
Ivector(minbc,maxbc);
3651 for(i=minbc;i<=maxbc;i++) mapbc[i] = mapdim[i] = 0;
3654 if(!bound[j].
created)
continue;
3655 for(i=1;i<=bound[j].
nosides;i++) {
3656 GetElementSide(bound[j].parent[i],bound[j].side[i],bound[j].normal[i],data,sideind,&elemtype);
3659 mapdim[bound[j].
types[i]] = elemdim;
3665 for(elemdim==2;elemdim>=0;elemdim--) {
3666 for(i=minbc;i<=maxbc;i++) {
3667 if(mapdim[i] != elemdim)
continue;
3675 if(maxbc - minbc >= j || minbc != 1) {
3676 if(info)
printf(
"Mapping boundary types from [%d %d] to [%d %d]\n",minbc,maxbc,1,j);
3679 if(!bound[j].
created)
continue;
3680 for(i=1;i<=bound[j].
nosides;i++) {
3681 bound[j].
types[i] = mapbc[bound[j].
types[i]];
3695 if(info)
printf(
"Adding offset of %d to the BCs\n",bcoffset);
3697 if(!bound[j].
created)
continue;
3698 for(i=1;i<=bound[j].
nosides;i++)
3699 bound[j].
types[i] += bcoffset;
3702 for(j=MAXBOUNDARIES-bcoffset-1;j>=0;j--) {
3714 int minmat=0,maxmat=0,*mapmat;
3716 if(0)
printf(
"Setting new material types\n");
3719 if(noelements < 1) {
3720 printf(
"There are no elements to set!\n");
3727 maxmat = minmat = data->
material[j];
3734 mapmat =
Ivector(minmat,maxmat);
3735 for(i=minmat;i<=maxmat;i++) mapmat[i] = 0;
3741 for(i=minmat;i<=maxmat;i++)
3742 if(mapmat[i]) mapmat[i] = ++j;
3744 if(maxmat - minmat >= j || minmat != 1) {
3745 if(info)
printf(
"Mapping material types from [%d %d] to [%d %d]\n",
3758 if(info)
printf(
"Materials ordered continously between %d and %d\n",minmat,maxmat);
3768 int maxelemtype,maxelemdim,elemdim;
3769 int parent, side, sideind[
MAXNODESD1],sideelemtype;
3770 int nosides, oldnosides,newnosides;
3772 if(info)
printf(
"Removing lower dimensional boundaries\n");
3775 if(noelements < 1)
return(1);
3780 if(info)
printf(
"Maximum elementtype is %d and dimension %d\n",maxelemtype,maxelemdim);
3781 if(maxelemdim < 2)
return(2);
3787 if(!bound[j].
created)
continue;
3788 for(i=1;i<=bound[j].
nosides;i++) {
3791 parent = bound[j].
parent[i];
3792 side = bound[j].
side[i];
3795 if(sideelemtype > 300)
3797 else if(sideelemtype > 200)
3802 if(maxelemdim - elemdim > 1)
continue;
3805 if(nosides == i)
continue;
3809 bound[j].
side[nosides] = bound[j].
side[i];
3814 newnosides += nosides;
3817 if(info)
printf(
"Removed %d (out of %d) less than %dD boundary elements\n",
3818 oldnosides-newnosides,oldnosides,maxelemdim);
3828 int i,j,side,identical,element;
3829 int noknots,nomaterials,nosides,newbound;
3830 int maxelementtype,maxedgenodes,elemedges,maxelemedges,edge,dosides;
3831 int **edgetable,sideind[
MAXNODESD1],sideelemtype,allocated;
3839 printf(
"FindEdges: Finding edges of bulk elements of type %d\n",material);
3842 if(maxelementtype/100 > 4) {
3843 printf(
"FindEdges: Implemented only for 2D elements!\n");
3848 if(maxelementtype/100 <= 2) maxedgenodes = 1;
3849 else if(maxelementtype/100 <= 4) maxedgenodes = 2;
3850 maxelemedges = maxelementtype/100;
3852 edgetable =
Imatrix(1,maxelemedges*nomaterials,0,maxedgenodes+1);
3853 for(i=1;i<=maxelemedges*nomaterials;i++)
3854 for(j=0;j<=maxedgenodes+1;j++)
3855 edgetable[i][j] = 0;
3858 for(element=1;element<=data->
noelements;element++) {
3859 if(data->
material[element] != material)
continue;
3863 for(side=0;side<elemedges;side++) {
3867 edgetable[edge][maxedgenodes] = element;
3868 edgetable[edge][maxedgenodes+1] = side;
3870 if(maxedgenodes == 1)
3871 edgetable[edge][0] = sideind[0];
3872 else if(maxedgenodes == 2) {
3873 if(sideind[0] > sideind[1]) {
3874 edgetable[edge][0] = sideind[0];
3875 edgetable[edge][1] = sideind[1];
3878 edgetable[edge][1] = sideind[0];
3879 edgetable[edge][0] = sideind[1];
3890 arrange[i] = edgetable[i][0];
3896 printf(
"noknots = %d\n",noknots);
3898 printf(
"indx[%d]=%d edge=%d arrange[%d] = %lg arrange[indx[%d]] = %lg\n",
3899 i,indx[i],edgetable[i][0],i,arrange[i],i,arrange[indx[i]]);
3904 revindx[indx[i]] = i;
3914 if(maxedgenodes == 1) {
3915 for(j=i+1;j<=noknots && edgetable[indx[i]][0] == edgetable[indx[j]][0];j++)
3917 for(j=i-1;j>=1 && edgetable[indx[i]][0] == edgetable[indx[j]][0];j--)
3920 else if(maxedgenodes == 2) {
3921 for(j=i+1;j<=noknots && edgetable[indx[i]][0] == edgetable[indx[j]][0];j++)
3922 if(edgetable[indx[i]][1] == edgetable[indx[j]][1])
3924 for(j=i-1;j>=1 && edgetable[indx[i]][0] == edgetable[indx[j]][0];j--)
3925 if(edgetable[indx[i]][1] == edgetable[indx[j]][1])
3929 if(identical)
continue;
3932 bound[newbound].
parent[nosides] = edgetable[indx[i]][maxedgenodes];
3933 bound[newbound].
parent2[nosides] = 0;
3934 bound[newbound].
side[nosides] = edgetable[indx[i]][maxedgenodes+1];
3935 bound[newbound].
side2[nosides] = 0;
3936 bound[newbound].
types[nosides] = sidetype;
3945 if(info)
printf(
"Created boundary %d of type %d and size %d for material %d\n",
3946 newbound,sidetype,nosides,material);
3952 free_Imatrix(edgetable,1,maxelemedges*nomaterials,0,maxedgenodes+1);
3958 int i,j,same,nosides,hits;
3961 nosides = elemtype / 100;
3962 for(i=0;i<nosides;i++)
3963 for(j=0;j<nosides;j++)
3964 if(ind1[i] == ind2[j]) hits++;
3966 same = (hits == nosides);
3973 int *boundnodes,
int suggesttype,
int dimred,
int info)
3975 int i,j,side,identical,element,lowerdim,
dim,minedge = 0,maxedge = 0;
3976 int nonodes,nosides,newbound = 0;
3978 int noboundnodes,sameside,newtype = 0,elemtype;
3983 lowerdim = dim - dimred;
3989 if(boundnodes[i]) noboundnodes++;
3991 printf(
"FindNewBoundaries: no nonzero entries in boundnodes vector!\n");
3995 if(info)
printf(
"There are %d nonzero entries in boundnodes vector!\n",noboundnodes);
4001 for(element=1;element<=data->
noelements;element++) {
4006 maxedge = elemtype/100 -1;
4011 maxedge = elemtype/100 -1;
4013 else if(lowerdim == 0) {
4014 minedge = elemtype/100;
4015 maxedge = minedge + 1;
4021 if(elemtype/100 == 5) maxedge = 3;
4022 else if(elemtype/100 == 6 || elemtype/100 == 7) maxedge = 4;
4023 else if(elemtype/100 == 8) maxedge = 5;
4025 else if(lowerdim == 1) {
4026 if(elemtype/100 == 8) {
4030 else if(elemtype/100 == 5) {
4035 printf(
"FindNewBoundaries: not implemented for all 3d boundaries\n");
4037 else if(lowerdim == 0) {
4038 if(elemtype/100 == 8) {
4045 for(side=minedge;side<=maxedge;side++) {
4049 nonodes = sideelemtype % 100;
4051 for(i=0;i<nonodes;i++)
4052 if(!boundnodes[sideind[i]]) identical =
FALSE;
4054 if(!identical)
continue;
4058 for(i=1;i<nosides;i++) {
4059 if(bound[newbound].parent2[i])
continue;
4061 GetElementSide(bound[newbound].parent[i],bound[newbound].side[i],
4062 1,data,sideind0,&sideelemtype0);
4063 if(sideelemtype0 != sideelemtype)
continue;
4066 bound[newbound].
parent2[i] = element;
4067 bound[newbound].
side2[i] = side;
4073 bound[newbound].
types[nosides] = newtype;
4074 bound[newbound].
parent[nosides] = element;
4075 bound[newbound].
side[nosides] = side;
4076 bound[newbound].
types[nosides] = newtype;
4086 newtype = suggesttype;
4089 if(suggesttype)
continue;
4090 for(i=1;i<=bound[j].
nosides;i++)
4091 if(bound[j].
types[i] > newtype) newtype = bound[j].
types[i];
4094 if(!suggesttype) newtype++;
4098 if(info)
printf(
"Allocating for %d sides of boundary %d\n",nosides,newtype);
4102 bound[newbound].
nosides = nosides;
4103 if(info)
printf(
"Found %d sides of dim %d to define boundary %d\n",nosides,lowerdim,newtype);
4105 for(i=1;i<=nosides;i++) {
4106 if(j = bound[newbound].parent2[i]) {
4107 if(bound[newbound].parent[i] > bound[newbound].parent2[i]) {
4109 bound[newbound].
parent[i] = j;
4110 j = bound[newbound].
side2[i];
4111 bound[newbound].
side2[i] = bound[newbound].
side[i];
4112 bound[newbound].
side[i] = j;
4119 printf(
"The nodes do not form a boundary!\n");
4124 printf(
"The nodes do not form a boundary, trying with %d-dimensional elements.\n",lowerdim);
4135 int *boundnodes,
int *noboundnodes,
int info)
4140 int *visited,elemdim,*ind;
4141 Real *anglesum,dx1,dx2,dy1,dy2,dz1,
dz2,ds1,ds2,dotprod;
4146 if(mat1 < 1 && mat2 < 1) {
4147 printf(
"FindBulkBoundaty: Either of the materials must be positive\n");
4155 if(info)
printf(
"Finding nodes between bulk elements of material %d and %d\n",mat1,mat2);
4167 if(material == mat1) {
4170 if(k > elemdim) elemdim =
k;
4172 for(j=0;j<nonodes;j++) {
4178 maxnodes = minnodes = visited[1];
4179 for(i=1;i<=data->
noknots;i++) {
4180 if(visited[i] > maxnodes) maxnodes = visited[i];
4181 if(visited[i] < minnodes) minnodes = visited[i];
4184 if(elemdim == 3 || elemdim == 4) {
4191 if(material == mat1) {
4195 if(nonodes == 3 || nonodes == 4) {
4196 for(k=0;k<nonodes;k++) {
4197 dx1 = data->
x[ind[(k+1)%nonodes]] - data->
x[ind[k]];
4198 dy1 = data->
y[ind[(k+1)%nonodes]] - data->
y[ind[
k]];
4199 dz1 = data->
z[ind[(k+1)%nonodes]] - data->
z[ind[k]];
4200 dx2 = data->
x[ind[(k+nonodes-1)%nonodes]] - data->
x[ind[
k]];
4201 dy2 = data->
y[ind[(k+nonodes-1)%nonodes]] - data->
y[ind[k]];
4202 dz2 = data->
z[ind[(k+nonodes-1)%nonodes]] - data->
z[ind[
k]];
4203 ds1 = sqrt(dx1*dx1+dy1*dy1+dz1*dz1);
4204 ds2 = sqrt(dx2*dx2+dy2*dy2+dz2*dz2);
4205 dotprod = dx1*dx2 + dy1*dy2 + dz1*
dz2;
4207 anglesum[ind[
k]] += acos(dotprod / (ds1*ds2));
4214 for(i=1;i<=data->
noknots;i++) {
4215 anglesum[i] /= 2.0 *
FM_PI;
4216 if(anglesum[i] > 0.99) visited[i] = 0;
4217 if(anglesum[i] > 1.01)
printf(
"FindBulkBoundary: surpricingly large angle %.3le in node %d\n",anglesum[i],i);
4220 if(0)
printf(
"There are %d boundary node candidates\n",j);
4226 if(visited[i] == maxnodes) visited[i] = 0;
4229 printf(
"FindBulkBoundary: Nodes must belong to more than %d elements.\n",maxnodes);
4237 if(material == mat1)
continue;
4240 for(j=0;j<nonodes;j++) {
4245 for(k=1;k<=data->
noknots;k++) {
4248 else if(visited[k] < boundnodes[k])
4250 else if(visited[k] + boundnodes[k] < maxnodes)
4256 else if(mat2 == -10) {
4258 if(visited[i]) boundnodes[i] = 1;
4260 else if(mat2 == -11 || mat2 == -12 || mat2 > 0) {
4264 if(material == mat1)
continue;
4265 if(mat2 > 0 && material != mat2)
continue;
4266 if(mat2 == -11 && material < mat1)
continue;
4267 if(mat2 == -12 && material > mat1)
continue;
4270 for(j=0;j<nonodes;j++) {
4272 if(visited[k]) boundnodes[
k] = 1;
4276 else if(mat2 >= -2*data->
dim && mat2 <= -1) {
4282 xmax = xmin = data->
x[
k];
4284 if(data->
dim >= 3) zmax = zmin = data->
z[
k];
4289 if(data->
x[i] < xmin) xmin = data->
x[i];
4290 if(data->
dim >= 2) {
4294 if(data->
dim >= 3) {
4295 if(data->
z[i] > zmax) zmax = data->
z[i];
4296 if(data->
z[i] < zmin) zmin = data->
z[i];
4303 if(data->
dim >= 3) ds += (zmax-zmin)*(zmax-zmin);
4310 if(visited[i] < maxnodes && visited[i]) {
4312 if(data->
dim == 1) {
4313 if(mat2 == -1 && fabs(data->
x[i]-xmin) <
eps) boundnodes[i] = 1;
4314 else if(mat2 == -2 && fabs(data->
x[i]-
xmax) <
eps) boundnodes[i] = 1;
4316 if(data->
dim >= 2) {
4317 if(mat2 == -1 && (fabs(data->
y[i]-
ymin) <
eps)) boundnodes[i] = 1;
4318 else if(mat2 == -3 && (fabs(data->
y[i]-
ymax) <
eps)) boundnodes[i] = 1;
4319 else if(mat2 == -4 && (fabs(data->
x[i]-xmin) <
eps)) boundnodes[i] = 1;
4320 else if(mat2 == -2 && (fabs(data->
x[i]-
xmax) <
eps)) boundnodes[i] = 1;
4322 if(data->
dim >= 3) {
4323 if(mat2 == -5 && fabs(data->
z[i]-zmin) <
eps) boundnodes[i] = 1;
4324 else if(mat2 == -6 && fabs(data->
z[i]-zmax) <
eps) boundnodes[i] = 1;
4330 printf(
"FindBulkBoundary: unknown option %d for finding a side\n",mat2);
4337 if(boundnodes[i]) *noboundnodes += 1;
4339 if(info)
printf(
"Located %d nodes at the interval between materials %d and %d\n",
4340 *noboundnodes,mat1,mat2);
4349 int *boundnodes,
int *noboundnodes,
int info)
4353 Real ds,
xmin,
xmax,
ymin = 0,
ymax = 0,zmin = 0,zmax = 0,
eps,dx1,dx2,dy1,dy2,dz1,
dz2,ds1,ds2,dotprod;
4354 Real *anglesum = NULL;
4360 if(mat1 < 1 && mat2 < 1) {
4361 printf(
"FindBoundaryBoundaty: Either of the boundaries must be positive\n");
4369 if(info)
printf(
"Finding nodes between boundary elements of type %d and %d\n",mat1,mat2);
4381 if(!bound[j].
created)
continue;
4382 for(i=1; i <= bound[j].
nosides; i++) {
4384 if(bound[j].
types[i] == mat1) {
4385 GetElementSide(bound[j].parent[i],bound[j].side[i],bound[j].normal[i],
4386 data,sideind,&elemtype);
4388 nonodes = elemtype % 100;
4389 nocorners = elemtype / 100;
4391 for(k=0;k<nocorners;k++)
4392 visited[sideind[k]] += 1;
4393 for(k=nocorners;k<nonodes;k++)
4394 visited[sideind[k]] -= 1;
4396 if(nocorners == 3 || nocorners == 4) {
4403 nonodes = nocorners;
4404 for(k=0;k<nonodes;k++) {
4405 dx1 = data->
x[sideind[(k+1)%nonodes]] - data->
x[sideind[k]];
4406 dy1 = data->
y[sideind[(k+1)%nonodes]] - data->
y[sideind[
k]];
4407 dz1 = data->
z[sideind[(k+1)%nonodes]] - data->
z[sideind[k]];
4408 dx2 = data->
x[sideind[(k+nonodes-1)%nonodes]] - data->
x[sideind[
k]];
4409 dy2 = data->
y[sideind[(k+nonodes-1)%nonodes]] - data->
y[sideind[k]];
4410 dz2 = data->
z[sideind[(k+nonodes-1)%nonodes]] - data->
z[sideind[
k]];
4411 ds1 = sqrt(dx1*dx1+dy1*dy1+dz1*dz1);
4412 ds2 = sqrt(dx2*dx2+dy2*dy2+dz2*dz2);
4413 dotprod = dx1*dx2 + dy1*dy2 + dz1*
dz2;
4415 anglesum[sideind[
k]] += acos(dotprod / (ds1*ds2));
4423 maxnodes = minnodes =
abs(visited[1]);
4424 for(i=1;i<=data->
noknots;i++) {
4425 j =
abs( visited[i] );
4426 maxnodes =
MAX( j, maxnodes );
4427 minnodes =
MIN( j, minnodes );
4429 if(info)
printf(
"There are from %d to %d hits per node\n",minnodes,maxnodes);
4431 printf(
"FindBulkBoundary: Nodes must belong to more than %d elements.\n",maxnodes);
4437 for(i=1;i<=data->
noknots;i++) {
4438 anglesum[i] /= 2.0 *
FM_PI;
4439 if(anglesum[i] > 0.99) visited[i] = 0;
4440 if(anglesum[i] > 1.01)
printf(
"FindBulkBoundary: surpricingly large angle %.3le in node %d\n",anglesum[i],i);
4446 for(i=1;i<=data->
noknots;i++) {
4447 if(visited[i] == -1)
4449 else if(visited[i] < -1) {
4454 if(k && info)
printf(
"Removed %d potential higher order side nodes from the list.\n",k);
4458 if(visited[i] == maxnodes || visited[i] < 0) visited[i] = 0;
4468 else if(mat2 == -11 || mat2 == -12 || mat2 == -10 || mat2 > 0) {
4470 if(!bound[j].
created)
continue;
4471 for(i=1; i <= bound[j].
nosides; i++) {
4473 material = bound[j].
types[i];
4475 if(material == mat1)
continue;
4476 if(mat2 > 0 && material != mat2)
continue;
4477 if(mat2 == -11 && material < mat1)
continue;
4478 if(mat2 == -12 && material > mat1)
continue;
4480 GetElementSide(bound[j].parent[i],bound[j].side[i],bound[j].normal[i],
4481 data,sideind,&elemtype);
4482 nonodes = elemtype%100;
4483 for(k=0;k<nonodes;k++) {
4485 if(visited[l]) boundnodes[l] = 1;
4492 else if(mat2 >= -2*data->
dim && mat2 <= -1) {
4495 if(!bound[j].
created)
continue;
4496 for(i=1; i <= bound[j].
nosides; i++) {
4498 material = bound[j].
types[i];
4499 if(material != mat1)
continue;
4501 GetElementSide(bound[j].parent[i],bound[j].side[i],bound[j].normal[i],
4502 data,sideind,&elemtype);
4503 nonodes = elemtype%100;
4506 for(k=0;k<nonodes;k++) {
4508 if(visited[l] < maxnodes) hits++;
4513 xmax = xmin = data->
x[l];
4514 if(data->
dim >= 2)
ymax = ymin = data->
y[l];
4515 if(data->
dim >= 3) zmax = zmin = data->
z[l];
4517 for(k=1;k<nonodes;k++) {
4519 if(data->
x[l] > xmax) xmax = data->
x[l];
4520 if(data->
x[l] < xmin) xmin = data->
x[l];
4521 if(data->
dim >= 2) {
4523 if(data->
y[l] < ymin) ymin = data->
y[l];
4525 if(data->
dim >= 3) {
4526 if(data->
z[l] > zmax) zmax = data->
z[l];
4527 if(data->
z[l] < zmin) zmin = data->
z[l];
4531 ds = (xmax-
xmin)*(xmax-xmin);
4533 if(data->
dim >= 3) ds += (zmax-zmin)*(zmax-zmin);
4537 for(k=0;k<nonodes;k++) {
4540 if(!visited[l])
continue;
4542 if(data->
dim == 1) {
4543 if(mat2 == -1 && fabs(data->
x[l]-xmin) <
eps) boundnodes[l] = 1;
4544 else if(mat2 == -2 && fabs(data->
x[l]-xmax) <
eps) boundnodes[l] = 1;
4546 if(data->
dim >= 2) {
4547 if(mat2 == -1 && (fabs(data->
y[l]-ymin) <
eps)) elemind[l] = 1;
4548 else if(mat2 == -3 && (fabs(data->
y[l]-
ymax) <
eps)) elemind[l] = 1;
4549 else if(mat2 == -4 && (fabs(data->
x[l]-xmin) <
eps)) elemind[l] = 1;
4550 else if(mat2 == -2 && (fabs(data->
x[l]-xmax) <
eps)) elemind[l] = 1;
4552 if(data->
dim >= 3) {
4553 if(mat2 == -5 && fabs(data->
z[l]-zmin) <
eps) elemind[l] = 1;
4554 else if(mat2 == -6 && fabs(data->
z[l]-zmax) <
eps) elemind[l] = 1;
4560 for(k=0;k<nonodes;k++)
4563 if(hits > 1)
for(k=0;k<nonodes;k++)
4564 if(elemind[k]) boundnodes[sideind[
k]] = 1;
4570 printf(
"FindBoundaryBoundary: unknown option %d for finding a side\n",mat2);
4577 if(boundnodes[i]) *noboundnodes += 1;
4579 if(info)
printf(
"Located %d nodes at the interval between boundaries %d and %d\n",
4580 *noboundnodes,mat1,mat2);
4590 int i,j,side,element,maxcon,con,newknots,ind,ind2;
4592 int **newnodetable,inds[2],**newtopo;
4593 Real *newx,*newy,*newz;
4595 if(info)
printf(
"Trying to increase the element order of current elements\n");
4603 newnodetable =
Imatrix(0,maxcon-1,1,noknots);
4605 for(j=0;j<maxcon;j++)
4606 newnodetable[j][i] = 0;
4610 for(j=0;j<maxcon;j++) {
4614 newnodetable[j][i] = noknots + newknots;
4619 if(info)
printf(
"There will be %d new nodes in the elements\n",newknots);
4621 newx =
Rvector(1,noknots+newknots);
4622 newy =
Rvector(1,noknots+newknots);
4623 newz =
Rvector(1,noknots+newknots);
4627 newx[i] = data->
x[i];
4628 newy[i] = data->
y[i];
4629 newz[i] = data->
z[i];
4632 for(j=0;j<maxcon;j++) {
4634 ind = newnodetable[j][i];
4636 newx[ind] = 0.5*(data->
x[i] + data->
x[con]);
4637 newy[ind] = 0.5*(data->
y[i] + data->
y[con]);
4638 newz[ind] = 0.5*(data->
z[i] + data->
z[con]);
4646 if(maxelemtype <= 303)
4648 else if(maxelemtype == 404)
4650 else if(maxelemtype == 504)
4652 else if(maxelemtype == 605)
4654 else if(maxelemtype == 706)
4656 else if(maxelemtype == 808)
4659 printf(
"Not implemented for elementtype %d\n",maxelemtype);
4660 bigerror(
"IncreaseElementOrder: Cant continue the subroutine");
4663 if(info)
printf(
"New leading elementtype is %d\n",100*(maxelemtype/100)+maxnodes);
4665 newtopo =
Imatrix(1,noelements,0,maxnodes-1);
4667 for(element=1;element<=
noelements;element++) {
4669 for(i=0;i<elemtype%100;i++)
4670 newtopo[element][i] = data->
topology[element][i];
4674 for(element=1;element<=data->
noelements;element++) {
4678 for(side=0;;side++) {
4682 if(inds[0] > inds[1]) {
4690 for(j=0;j<maxcon;j++) {
4694 node = newnodetable[j][ind];
4695 newtopo[element][nonodes+side] = node;
4700 elemtype = 100*(elemtype/100)+nonodes+side;
4720 if(info)
printf(
"Increased the element order from 1 to 2\n");
4732 int i,j,j2,ind1,ind2,nonodes1;
4733 Real x,
y,r,f,
z,q,
x2,y2,
z2,
dx,
dy,
dz,
eps,mult;
4734 int hits,trials,tests;
4735 int candidates,*candidatelist,*indx;
4738 printf(
"Rectangular geometry with r1=%.4lg for %d nodes.\n",
4742 printf(
"Cylindrical geometry with r1=%.4lg r2=%.4lg for %d nodes.\n",
4747 for(i=1;i<=data->
noknots;i++) {
4755 data->
x[i] =
cos(f)*r;
4756 data->
y[i] = sin(f)*r;
4770 if(f <= 0.25*
FM_PI) {
4774 else if(f <= 0.75*
FM_PI) {
4778 else if(f <= 1.25*
FM_PI) {
4782 else if(f <= 1.75*
FM_PI){
4791 if(!rectangle && q > 0.0) {
4792 data->
x[i] = (1-q)*data->
x[i] + q*
cos(f)*
r2;
4793 data->
y[i] = (1-q)*data->
y[i] + q*sin(f)*
r2;
4795 else if(rectangle && mult > 1.0) {
4813 for(i=0;i<nonodes1;i++) {
4820 for(i=1;i<=data->
noknots;i++) {
4821 if(!indx[i])
continue;
4825 if(fabs(y) > r1+eps)
continue;
4826 if((fabs(x) > r1+eps) && (fabs(y) > eps) )
continue;
4827 if((fabs(x) > eps) && (fabs(y) > eps) &&
4828 (fabs(fabs(x)-r1) > eps) && (fabs(fabs(y)-r1) > eps))
continue;
4831 candidatelist[candidates] = i;
4833 printf(
"%d/%d candidates for duplicate nodes.\n",candidates,data->
noknots);
4835 hits = tests = trials = 0;
4836 for(j=1;j<=candidates;j++) {
4837 ind1 = indx[candidatelist[j]];
4842 for(j2=j+1;j2<=candidates;j2++) {
4843 ind2 = indx[candidatelist[j2]];
4854 if(dx*dx + dy*dy + dz*dz < eps*eps) {
4856 indx[candidatelist[j2]] = ind1;
4862 printf(
"Found %d double nodes in %d tests.\n",hits,tests);
4866 for(i=0;i<nonodes1;i++) {
4868 if(ind2 != indx[ind2]) {
4877 printf(
"Eliminated %d nodes from topology.\n",trials);
4887 printf(
"Cylindrical coordinate for r1=%.4lg and r2=%.4lg.\n",r1,r2);
4891 cmin = 1.0/(3.0-sqrt(3.));
4894 if(factor > 1.0) factor=1.0;
4895 else if(factor < 0.0) factor=0.0;
4897 c = cmin+(cmax-cmin)*factor;
4899 if(fabs(c-1.0) <
eps)
return;
4901 printf(
"Improving cylindrical mesh quality r1=%.4lg, r2=%.4lg and c=%.4lg\n",r1,r2,c);
4903 for(i=1;i<=data->
noknots;i++) {
4908 if(r >= r2)
continue;
4909 if(r < eps)
continue;
4911 if(fabs(x) <= r1+eps && fabs(y) <= r1+eps) {
4912 if(fabs(x) < fabs(y)) {
4914 data->
x[i] = (c*q+(1.-q))*
x;
4915 data->
y[i] = (c*q+(1.-q))*
y;
4919 data->
x[i] = (c*q+(1.-q))*
x;
4920 data->
y[i] = (c*q+(1.-q))*
y;
4924 if(fabs(x) < fabs(y)) {
4926 q2 = (fabs(y)-
r1)/(r2*fabs(y/r)-
r1);
4927 data->
x[i] = (c*q+(1.-q)) *x*(1-q2) + q2*x;
4928 data->
y[i] = (c*q+(1.-q)) *(1-q2)*y + q2*y;
4932 q2 = (fabs(x)-
r1)/(r2*fabs(x/r)-
r1);
4933 data->
x[i] = (c*q+(1.-q))*(1-q2)*x + q2*x;
4934 data->
y[i] = (c*q+(1.-q))*y*(1-q2) + q2*y;
4948 printf(
"Cylindrical coordinate curve, zet=%.3lg rad=%.3lg angle=%.3lg\n",
4952 f0 =
FM_PI*(angle/180.);
4956 for(i=1;i<=data->
noknots;i++) {
4961 if(z <= z0)
continue;
4964 z2 = z0 + sin(f0)*(r0+
x) +
cos(f0)*(z-
z1);
4965 x2 = (
cos(f0)-1.0)*r0 +
cos(f0)*x - sin(f0)*(z-
z1);
4971 z2 = z0 + sin(f)*(r0+
x);
4972 x2 = (
cos(f)-1.0)*r0 +
cos(f)*
x;
4983 int i,j,
k,l,type,maxtype,addtype,elemsides,totsides,used,hit;
4985 Real x,
y,
z,sx,sy,sz,sxx,syy,szz,
dx,
dy,
dz;
4993 if(!bound[j].
created)
continue;
4994 if(!bound[j].nosides)
continue;
4996 for(i=1;i<=bound[j].
nosides;i++) {
4998 for(k=1;k<=bound[j].
nosides;k++)
4999 if(maxtype < bound[j].
types[k]) maxtype = bound[j].
types[
k];
5004 printf(
"Maximum boundary type is %d\n",maxtype);
5005 printf(
"Number of boundaries is %d\n",totsides);
5009 for(type=1;type<=maxtype;type++) {
5014 bc[i] = bcdim[i] = 0;
5019 if(!bound[j].
created)
continue;
5020 if(!bound[j].nosides)
continue;
5022 for(k=1;k<=bound[j].
nosides;k++) {
5024 if(bound[j].
types[k] != type)
continue;
5025 GetElementSide(bound[j].parent[k],bound[j].side[k],bound[j].normal[k],
5026 data,sideind,&sideelemtype);
5029 sxx = syy = szz = 0.0;
5030 elemsides = sideelemtype%100;
5033 for(l=0;l<elemsides;l++) {
5034 x = data->
x[sideind[l]];
5035 y = data->
y[sideind[l]];
5036 z = data->
z[sideind[l]];
5050 dx = sqrt(sxx-sx*sx);
5051 dy = sqrt(syy-sy*sy);
5052 dz = sqrt(szz-sz*sz);
5054 if(sideelemtype < 300 && dz < eps) {
5058 for(i=0;i<MAXBOUNDARIES && bcdim[i];i++) {
5059 if(bcdim[i] == 1 && fabs(bclim[i]-sx) < eps*fabs(dy)) {
5060 bound[j].
types[
k] = bc[i];
5069 printf(
"Adding new BC %d in Y-direction\n",addtype);
5071 bound[j].
types[
k] = bc[i];
5074 bc[i] = bound[j].
types[
k];
5084 for(i=0;i<MAXBOUNDARIES && bcdim[i];i++) {
5085 if(bcdim[i] == 2 && fabs(bclim[i]-sy) < eps*fabs(dx)) {
5086 bound[j].
types[
k] = bc[i];
5094 printf(
"Adding new BC %d in X-direction\n",addtype);
5096 bound[j].
types[
k] = bc[i];
5099 bc[i] = bound[j].
types[
k];
5108 if(dx < eps*dy && dx < eps*dz) {
5110 else if(dy < eps*dx && dy < eps*dz) {
5123 int i,j,
k,l,maxtype,addtype = 0,elemsides;
5125 int axistype[4],axishit[4],axissum,axismax,done;
5126 Real x,
y,
z,sx,sy,sz,sxx,syy,szz,
dx,
dy,
dz;
5132 if(!bound[j].
created)
continue;
5133 if(!bound[j].nosides)
continue;
5135 for(i=1;i<=bound[j].
nosides;i++) {
5136 for(k=1;k<=bound[j].
nosides;k++)
5137 if(maxtype < bound[j].
types[k]) maxtype = bound[j].
types[
k];
5140 printf(
"Maximum boundary type is %d\n",maxtype);
5144 if(!bound[j].
created)
continue;
5145 if(!bound[j].nosides)
continue;
5148 for(k=1;k<=bound[j].
nosides;k++)
5149 bound[j].
types[k] = bound[j].type;
5156 if(!bound[j].
created)
continue;
5157 if(!bound[j].nosides)
continue;
5159 for(k=0;k<4;k++) axishit[k] = 0;
5165 for(k=1;k<=bound[j].
nosides;k++) {
5167 GetElementSide(bound[j].parent[k],bound[j].side[k],bound[j].normal[k],
5168 data,sideind,&sideelemtype);
5171 sxx = syy = szz = 0.0;
5172 elemsides = sideelemtype%100;
5175 for(l=0;l<elemsides;l++) {
5176 x = data->
x[sideind[l]];
5177 y = data->
y[sideind[l]];
5178 z = data->
z[sideind[l]];
5192 dx = sqrt(sxx-sx*sx);
5193 dy = sqrt(syy-sy*sy);
5194 dz = sqrt(szz-sz*sz);
5196 if(dx < eps*dy && dx < eps*dz) {
5199 if(axistype[0]) bound[j].
types[
k] = maxtype + axistype[0];
5206 if(axistype[1]) bound[j].
types[
k] = maxtype + axistype[1];
5212 else if(dy < eps*dx && dy < eps*dz) {
5215 if(axistype[2]) bound[j].
types[
k] = maxtype + axistype[2];
5222 if(axistype[3]) bound[j].
types[
k] = maxtype + axistype[3];
5237 axissum += axishit[
k];
5238 if(axishit[k]) addtype++;
5245 if(axishit[l] > axishit[axismax])
5248 axistype[axismax] = k+1;
5249 axishit[axismax] = -(k+1);
5252 if(axissum == bound[j].nosides) {
5259 printf(
"Separating %d rectangular boundaries from boundary %d.\n",addtype,j);
5276 int i,j,
k,l,
m,
n,knot0,knot1,knot2 = 0,elem0,size,kmax,
noknots,origtype;
5277 int nonodes3d,nonodes2d;
5278 int cellk,element,level,side,parent,parent2,layers,elemtype;
5279 int material,material2,ind1,ind2,*indx,*topo;
5280 int sideelemtype,sideind[
MAXNODESD1],sidetype,maxsidetype,newbounds;
5281 int refmaterial1[10],refmaterial2[10],refsidetype[10],indxlength;
5282 Real z,*newx,*newy,*newz,corder[3];
5290 printf(
"CreateKnotsExtruded: unknown option!\n");
5302 else if(origtype == 404)
5304 else if(origtype == 408)
5306 else if(origtype == 409)
5309 printf(
"CreateKnotsExtruded: not implemented for elementtypes %d!\n",origtype);
5312 if(info)
printf(
"Elementtype %d extruded to type %d.\n",origtype,elemtype);
5314 nonodes2d = origtype%100;
5315 data->
maxnodes = nonodes3d = elemtype%100;
5335 for(i=0;i<=indxlength;i++)
5340 newbounds = grid->
zcells+1;
5350 if(!boundxy[j].
created)
continue;
5352 if(0) bound[j] = boundxy[j];
5369 for(i=1;i<=size;i++) {
5370 bound[j].
types[i] = 0;
5371 bound[j].
side[i] = 0;
5372 bound[j].
side2[i] = 0;
5381 knot1 = layers*dataxy->
noknots;
5382 if(layers == 2) knot2 = dataxy->
noknots;
5387 for(cellk=1;cellk <= grid->
zcells ;cellk++) {
5389 kmax = grid->
zelems[cellk];
5391 for(k=1;k<=kmax; k++) {
5393 if(0)
printf(
"elem0=%d knot0=%d knot1=%d\n",elem0,knot0,knot1);
5396 for(element=1;element <= dataxy->
noelements;element++) {
5402 for(i=0;i<nonodes2d;i++)
5403 meanx += dataxy->
x[dataxy->
topology[element][i]];
5404 meanx = fabs(meanx/nonodes2d);
5406 if(grid->
rotate && meanx < 0.0)
continue;
5407 if(grid->
rotate && cellk%2==0 && meanx < grid->rotateradius1)
continue;
5411 indx[(level-1)*dataxy->
noelements+element] = elem0;
5420 if(elemtype == 706) {
5426 else if(elemtype == 808) {
5432 if(elemtype == 820 || elemtype == 827) {
5441 if(elemtype == 827) {
5449 knot0 += layers*dataxy->
noknots;
5450 knot1 += layers*dataxy->
noknots;
5451 knot2 += layers*dataxy->
noknots;
5455 if(info)
printf(
"Extruded mesh has %d elements in %d levels.\n",elem0,level);
5460 for(cellk=1;cellk <= grid->
zcells ;cellk++) {
5464 for(;k<=grid->
zelems[cellk]; k++) {
5467 z = grid->
z[cellk-1] + k*grid->
dz[cellk];
5469 else if(grid->
zexpand[cellk] > 0.0) {
5470 z = grid->
z[cellk-1] + grid->
dz[cellk] *
5473 else if(grid->
zelems[cellk] <= 2) {
5474 z = grid->
z[cellk-1] + k*grid->
dz[cellk];
5477 if(k<=grid->zelems[cellk]/2) {
5478 z = grid->
z[cellk-1] + grid->
dz[cellk] *
5482 z = grid->
z[cellk] - grid->
dz[cellk] *
5487 for(i=1;i <= dataxy->
noknots;i++) {
5488 data->
x[i+knot0] = dataxy->
x[i];
5489 data->
y[i+knot0] = dataxy->
y[i];
5490 data->
z[i+knot0] =
z;
5492 knot0 += layers * dataxy->
noknots;
5499 if(elemtype == 820 || elemtype == 827) {
5500 for(element=1;element <= data->
noelements;element++) {
5503 data->
x[topo[i+12]] = 0.5*(data->
x[topo[i]]+data->
x[topo[i+4]]);
5504 data->
y[topo[i+12]] = 0.5*(data->
y[topo[i]]+data->
y[topo[i+4]]);
5505 data->
z[topo[i+12]] = 0.5*(data->
z[topo[i]]+data->
z[topo[i+4]]);
5507 if(elemtype == 827) {
5509 data->
x[topo[i+20]] = 0.5*(data->
x[topo[12+i]]+data->
x[topo[12+(i+1)%4]]);
5510 data->
y[topo[i+20]] = 0.5*(data->
y[topo[12+i]]+data->
y[topo[12+(i+1)%4]]);
5511 data->
z[topo[i+20]] = 0.5*(data->
z[topo[12+i]]+data->
z[topo[12+(i+1)%4]]);
5513 data->
x[topo[26]] = 0.5*(data->
x[topo[0]]+data->
x[topo[6]]);
5514 data->
y[topo[26]] = 0.5*(data->
y[topo[0]]+data->
y[topo[6]]);
5515 data->
z[topo[26]] = 0.5*(data->
z[topo[0]]+data->
z[topo[6]]);
5532 if(!bound[j].
created)
continue;
5536 for(cellk=1;cellk <= grid->
zcells ;cellk++) {
5537 for(k=1;k<=grid->
zelems[cellk]; k++) {
5541 printf(
"level=%d j=%d side=%d\n",level,j,side);
5544 for(i=1;i<=boundxy[j].
nosides;i++){
5547 parent = indx[ind1];
5549 if(parent) material = data->
material[parent];
5552 if(boundxy[j].parent2[i]) {
5554 parent2 = indx[ind2];
5559 if(parent2) material2 = data->
material[parent2];
5563 printf(
"ind=[%d %d] parent=[%d %d] material=[%d %d]\n",
5564 ind1,ind2,parent,parent2,material,material2);
5567 if((parent || parent2) && (material != material2)) {
5570 sidetype = boundxy[j].
types[i];
5571 bound[j].
types[side] = sidetype;
5574 bound[j].
parent[side] = parent;
5575 bound[j].
parent2[side] = parent2;
5576 bound[j].
side[side] = boundxy[j].
side[i];
5581 bound[j].
parent[side] = parent2;
5582 bound[j].
parent2[side] = parent;
5583 bound[j].
side[side] = boundxy[j].
side2[i];
5584 bound[j].
side2[side] = boundxy[j].
side[i];
5585 bound[j].
material[side] = material2;
5592 if(sidetype > maxsidetype) maxsidetype = sidetype;
5593 printf(
"Extruded BC %d of type %d was created with %d sides.\n",
5606 for(cellk=1;cellk <= grid->
zcells ;cellk++) {
5612 for(k=1;k<=grid->
zelems[cellk]; k++) {
5614 if(!(k == 1) && !(cellk == grid->
zcells && k==grid->
zelems[cellk]))
continue;
5616 if(cellk == grid->
zcells && k == grid->
zelems[cellk]) {
5617 if(grid->
zelems[cellk] == 1)
5627 refmaterial1[i] = 0;
5628 refmaterial2[i] = 0;
5640 parent = indx[ind1];
5643 if(ind2 > indxlength)
5646 parent2 = indx[ind2];
5648 if(parent == 0 && parent2 != 0) {
5656 if(!parent)
continue;
5660 material2 = data->
material[parent2];
5665 printf(
"level=%d ind=[%d %d] parent=[%d %d] material=[%d %d] swap=%d\n",
5666 level,ind1,ind2,parent,parent2,material,material2,swap);
5670 if(origtype == 303)
GetElementSide(parent,4-swap,1,data,sideind,&sideelemtype);
5672 meanx = meany = 0.0;
5674 for(l=0;l<sideelemtype%100;l++) {
5675 meanx += data->
y[sideind[l]];
5676 meany += data->
z[sideind[l]];
5680 for(l=0;l<sideelemtype%100;l++) {
5681 meanx += data->
x[sideind[l]];
5682 meany += data->
z[sideind[l]];
5685 meanx = fabs(meanx)/(sideelemtype%100);
5686 meany = fabs(meany)/(sideelemtype%100);
5692 for(m=0;m<grid->
xcells && grid->
x[
m]+1.0e-12 < meanx;m++);
5693 for(n=0;n<grid->
ycells && grid->
y[
n]+1.0e-12 < meany;n++);
5697 printf(
"cellk=%d meanx=%.3lg meany=%.3lg material2=%d m=%d n=%d\n",
5698 cellk,meanx,meany,material2,m,n);
5703 if(material != material2) {
5707 bound[j].
parent[side] = parent;
5708 bound[j].
parent2[side] = parent2;
5711 if(origtype == 303) {
5721 if(refmaterial1[m] == material && refmaterial2[m] == material2) {
5724 else if(refmaterial1[m] == 0 && refmaterial2[m] == 0) {
5726 refmaterial2[
m] = material2;
5728 refsidetype[
m] = sidetype;
5732 printf(
"Layer includes more than 9 new BCs!\n");
5735 bound[j].
types[side] = refsidetype[
m];
5739 printf(
"BC %d on layer %d was created with %d sides.\n",j,level,side);
5740 if(sidetype > maxsidetype) maxsidetype = sidetype;
5742 if(redo ==
TRUE)
goto redolayer;
5759 for(element=1;element<=data->
noelements;element++) {
5760 int blocks, maxradi = 0,addtype;
5761 Real eps,fii,
rad,meanrad,maxrad,xc,yc,dfii,fii0,rads[4],fiis[4];
5766 for(side=0;side<6;side++) {
5773 xc = data->
x[sideind[i]];
5774 yc = data->
y[sideind[i]];
5776 rad = sqrt(yc*yc+xc*xc);
5778 fii = 2*atan2(yc,xc)/
FM_PI;
5787 meanrad += 0.25 *
rad;
5790 fii0 = fiis[maxradi];
5793 if(rads[i] > eps * maxrad) {
5794 if( fabs(fiis[i]-fii0) > dfii) dfii = fabs(fiis[i]-fii0);
5798 if(dfii > eps)
continue;
5803 if(fabs(fii0) < eps) {
5805 if(meanrad < grid->rotateradius2)
5811 else if(fabs(fii0-blocks) < eps) {
5813 if(meanrad < grid->rotateradius2)
5822 bound[j+addtype].
side[
k] = side;
5823 bound[j+addtype].
parent[
k] = element;
5824 bound[j+addtype].
types[
k] = sidetype+addtype+1;
5829 printf(
"Symmetry BCs [%d %d %d %d] have [%d %d %d %d] sides.\n",
5830 j,j+1,j+2,j+3,bound[j].nosides,bound[j+1].nosides,
5831 bound[j+2].nosides,bound[j+3].nosides);
5833 if(bound[j+l].nosides == 0)
5844 for(i=0;i<j+4;i++) {
5845 if(bound[i].nosides) k=bound[i].
types[bound[i].
nosides];
5846 printf(
"bnd=%d types[1]=%d types[max]=%d nosides=%d type=%d\n",
5847 i,bound[i].
types[1],k,bound[i].nosides,bound[i].type);
5858 for(element=1;element<=data->
noelements;element++) {
5860 for(i=0;i<nonodes3d;i++)
5861 indx[data->
topology[element][i]] = 1;
5869 if(j < data->noknots) {
5870 printf(
"%d original nodes moved to %d new ones.\n",data->
noknots,j);
5873 newx[indx[i]] = data->
x[i];
5877 for(i=1;i<=data->noknots;i++)
5878 newy[indx[i]] = data->
y[i];
5883 newz[indx[i]] = data->
z[i];
5889 for(element=1;element<=data->
noelements;element++) {
5891 for(i=0;i<nonodes3d;i++)
5910 printf(
"Created %d elements and %d nodes by rotation of %d degrees.\n",
5914 if(info)
printf(
"Created %d elements and %d nodes by extruding the 2D geometry\n",
5925 int i,j,element,
material,elemcode1,elemcode2,maxnode,*indx,reduced;
5926 Real *newx,*newy,*newz;
5933 for(element=1;element<=data->
noelements;element++) {
5935 material = data->
material[element];
5936 elemcode2 = elemcode1;
5937 if(material >= matmin && material <= matmax)
5938 elemcode2 = 101*(elemcode1/100);
5939 if(elemcode2 == 505) elemcode2 = 504;
5941 printf(
"element=%d codes=[%d,%d]\n",element,elemcode1,elemcode2);
5942 printf(
"mat=%d interval=[%d,%d]\n",material,matmin,matmax);
5944 if(elemcode2 < elemcode1)
5946 maxnode = elemcode2%100;
5947 for(i=0;i<maxnode;i++)
5948 indx[data->
topology[element][i]] = 1;
5952 printf(
"The element order is reduced in %d elements at interval [%d,%d]\n",
5953 reduced,matmin,matmax);
5960 printf(
"%d original nodes moved to %d new ones.\n",data->
noknots,j);
5966 for(i=1;i<=data->
noknots;i++) {
5967 newx[indx[i]] = data->
x[i];
5968 newy[indx[i]] = data->
y[i];
5969 newz[indx[i]] = data->
z[i];
5981 for(element=1;element<=data->
noelements;element++) {
5983 for(i=0;i<maxnode;i++)
5996 int *mergeindx,*doubles;
5997 Real *newx,*newy,*newz;
6010 cdist = sqrt(cx*cx+cy*cy+cz*cz);
6019 mergeindx =
Ivector(1,noknots);
6027 if(info)
printf(
"Merging nodes close (%.3lg) to one another.\n",eps);
6031 if(mergeindx[i])
continue;
6034 if(mergeindx[j])
continue;
6036 dx = data->
x[i] - data->
x[j];
6037 dy = data->
y[i] - data->
y[j];
6038 dz = data->
z[i] - data->
z[j];
6039 if(fabs(cx*dx+cy*dy+cz*dz) > eps)
break;
6041 dist = dx*dx + dy*dy + dz*
dz;
6043 if(dist < eps*eps) {
6044 doubles[i] = doubles[j] =
TRUE;
6056 if(mergeindx[i] == 0)
6060 if(mergeindx[i] < 0)
6061 mergeindx[i] = mergeindx[-mergeindx[i]];
6064 printf(
"%d original nodes merged to %d new nodes.\n",
6065 noknots,newnoknots);
6072 newx[mergeindx[i]] = data->
x[i];
6073 newy[mergeindx[i]] = data->
y[i];
6074 newz[mergeindx[i]] = data->
z[i];
6079 printf(
"i=%d indx=%d merge=%d\n",i,indx[i],mergeindx[i]);
6091 if(info)
printf(
"Merging the topologies.\n");
6097 for(i=0;i<nonodes;i++) {
6106 if(info)
printf(
"Merging of nodes is complete.\n");
6113 int i,i2,j,
k,l,totsides,newsides,sidenodes,sideelemtype,side;
6119 if(info)
printf(
"Eliminating boundaries at joined nodes\n");
6122 if(!bound[j].
created)
continue;
6123 if(!bound[j].nosides)
continue;
6126 for(i=1;i<=bound[j].
nosides;i++) {
6128 parent = bound[j].
parent[i];
6129 side = bound[j].
side[i];
6132 sidenodes = sideelemtype % 100;
6135 for(k=0;k<sidenodes;k++)
6136 if(doubles[sideind[k]]) l++;
6144 bound[j].
side[i2] = bound[j].
side[i];
6158 if(info)
printf(
"Eliminated %d boundaries from orinal set of %d.\n",totsides-newsides,totsides);
6168 int i,j,
k,l,sideelemtype,sideelemtype2,elemind,elemind2,parent,sideelem,sameelem;
6170 int sidenodes,sidenodes2,maxelemtype,elemtype,elemdim,sideelements,
material;
6171 int *moveelement,*parentorder,*possible,**
invtopo;
6173 int debug,unmoved,removed,elemhits;
6174 int notfound,*notfounds;
6177 if(info)
printf(
"Making elements to boundary conditions\n");
6182 bound[j].nosides = 0;
6188 if(info)
printf(
"Leading bulk elementtype is %d\n",maxelemtype);
6191 if(info)
printf(
"Trailing bulk elementtype is %d\n",minelemtype);
6196 moveelement =
Ivector(1,noelements);
6206 moveelement[i] =
FALSE;
6211 else if(elemsides > 2)
6213 else if(elemsides > 1)
6215 else if(elemsides == 1)
6218 moveelement[i] = elemdim - sideelemdim;
6219 if(moveelement[i]) sideelements++;
6221 if(info)
printf(
"There are %d (out of %d) lower dimensional elements.\n",
6222 sideelements,noelements);
6223 if(sideelements == 0)
return;
6227 possible =
Ivector(1,noknots);
6228 for(i=1;i<=
noknots;i++) possible[i] = 0;
6229 for(elemind=1;elemind <= data->
noelements;elemind++) {
6230 if(moveelement[elemind])
continue;
6238 maxpossible = possible[1];
6240 if(maxpossible < possible[i]) {
6241 maxpossible = possible[i];
6244 if(info)
printf(
"Node %d belongs to maximum of %d elements\n",j,maxpossible);
6248 invtopo =
Imatrix(1,noknots,1,maxpossible);
6250 for(j=1;j<=maxpossible;j++)
6253 for(elemind=1;elemind <= data->
noelements;elemind++) {
6254 if(moveelement[elemind])
continue;
6256 for(i=0;i<elemtype%100;i++) {
6258 for(l=1;invtopo[
k][l];l++);
6259 invtopo[
k][l] = elemind;
6269 for(elemind=1;elemind <= data->
noelements;elemind++) {
6271 if(!moveelement[elemind])
continue;
6276 sidenodes = sideelemtype % 100;
6277 for(i=0;i<sidenodes;i++)
6278 sideind[i] = data->
topology[elemind][i];
6281 for(l=1;l<=maxpossible;l++) {
6282 elemind2 = invtopo[sideind[0]][l];
6284 if(!elemind2)
continue;
6288 for(i=0;i<sidenodes;i++)
6289 for(j=0;j<elemtype%100;j++)
6290 if(sideind[i] == data->
topology[elemind2][j]) hit++;
6292 if(hit < sidenodes)
continue;
6294 if(hit > sidenodes)
printf(
"Strange: elemhits %d vs. elemnodes %d\n",hit,sidenodes);
6295 if(hit >= sidenodes) elemhits++;
6297 for(side=0;side<=100;side++) {
6299 if(debug)
printf(
"elem1=%d l=%d elem2=%d side=%d\n",elemind,l,elemind2,side);
6301 GetElementSide(elemind2,side,1,data,&sideind2[0],&sideelemtype2);
6303 if(debug)
printf(
"elemtype=%d sidelemtype=%d %d\n",
6304 elemtype,sideelemtype,sideelemtype2);
6306 if(sideelemtype2 == 0 )
break;
6307 if(sideelemtype2 < 300 && sideelemtype > 300)
break;
6308 if(sideelemtype2 < 200 && sideelemtype > 200)
break;
6310 sidenodes2 = sideelemtype2 % 100;
6311 if(sidenodes != sidenodes2)
continue;
6312 if(sidenodes2 == 1 && sidenodes > 1)
break;
6315 for(i=0;i<sidenodes;i++)
6316 for(j=0;j<sidenodes2;j++)
6317 if(sideind[i] == sideind2[j]) hit++;
6319 if(debug)
printf(
"%d hits in element %d\n",hit,sideelemtype2);
6320 if(hit < sidenodes)
continue;
6322 if(sideelemtype != sideelemtype2) {
6323 printf(
"Hits in element after mismatch: %d vs. %d\n",sideelemtype,sideelemtype2);
6329 bound->
parent2[sideelem] = elemind2;
6330 bound->
side2[sideelem] = side;
6336 if(debug)
printf(
"sideelem=%d %d %d\n",sideelem,side,elemind2);
6337 bound->
parent[sideelem] = elemind2;
6338 bound->
side[sideelem] = side;
6340 bound->
side2[sideelem] = 0;
6341 material = data->
material[elemind];
6343 if(sidenodes == 2) {
6344 if((sideind[0]-sideind[1])*(sideind2[0]-sideind2[1])<0)
6345 bound->
normal[sideelem] = -1;
6349 if(material <
MAXBODIES && material < MAXBOUNDARIES)
6355 if(moveelement[elemind] > 1)
goto foundtwo;
6363 printf(
"element: index = %d type = %d nodes = %d elemhits = %d\n",
6364 elemind,sideelemtype,sidenodes,elemhits);
6366 for(i=0;i<sidenodes;i++)
6367 printf(
" %d ",sideind[i]);
6372 if(retainorphans && moveelement[elemind] == 1) {
6374 notfounds =
Ivector(1,noelements);
6376 notfounds[i] =
FALSE;
6379 notfounds[elemind] =
TRUE;
6382 moveelement[elemind] = -1;
6392 if(twiceelem)
printf(
"Found %d sides that were multiply given\n",twiceelem);
6393 if(sameelem)
printf(
"Found %d side elements that have two parents.\n",sameelem);
6396 if(sideelem == sideelements) {
6397 printf(
"Found correctly %d side elements.\n",sideelem);
6400 printf(
"Found %d side elements, could have found %d\n",sideelem,sideelements);
6401 printf(
"Removing %d lower dimensional elements from the element list\n",removed);
6403 printf(
"************************** WARNING **********************\n");
6405 printf(
"Adding %d elements to boundary without parent information\n",notfound);
6408 for(i=sideelem+1;i<=sideelements;i++) bound->
elementtypes[i] = 0;
6412 for(elemind=1;elemind <= data->
noelements;elemind++) {
6413 if(!notfounds[elemind])
continue;
6417 for(i=0;i<j%100;i++)
6425 printf(
"Removing %d lower dimensional elements without parent information\n",notfound);
6435 parentorder =
Ivector(1,noelements);
6438 if(moveelement[i] == 0) {
6446 for(l=0;l<k%100;l++)
6453 if(info)
printf(
"Parent elements were reordered up to indx %d.\n",j);
6457 for(i=1;i<=bound->
nosides;i++) {
6463 if(info)
printf(
"Moved %d elements (out of %d) to new positions\n",j,noelements);
6472 if(info)
printf(
"All done\n");
6482 int noknots,hit,tothits,dimvisited;
6483 int *topbot = NULL,*indxper;
6484 int botn,topn,*revindtop,*revindbot;
6486 Real *coord = NULL,*toparr,*botarr,epsmin;
6489 if(data->
dim < 3) periodicdim[2] = 0;
6490 if(!periodicdim[0] && !periodicdim[1] && !periodicdim[2])
return(1);
6493 printf(
"FindPeriodicNodes: Subroutine is called for second time¡\n");
6508 for(dim=1;dim<=3;dim++) {
6509 if(!periodicdim[dim-1])
continue;
6511 if(info)
printf(
"Finding periodic nodes in dim=%d\n",dim);
6513 if(dim==1) coord = data->
x;
6514 else if(dim==2) coord = data->
y;
6515 else if(dim==3) coord = data->
z;
6517 coordmax = coordmin = coord[1];
6519 for(i=1;i<=data->
noknots;i++) {
6520 if(coordmax < coord[i]) coordmax = coord[i];
6521 if(coordmin > coord[i]) coordmin = coord[i];
6524 if(info)
printf(
"Coordinate in dimension %d is at the interval [%.3lg, %.3lg]\n",
6525 dim,coordmin,coordmax);
6527 if(coordmax-coordmin < 1.0
e-10)
continue;
6532 eps = 1.0e-5 * (coordmax-coordmin);
6535 for(i=1;i<=data->
noknots;i++) {
6536 if(fabs(coord[i]-coordmax) <
eps) {
6540 else if(fabs(coord[i] - coordmin) <
eps) {
6550 printf(
"There should be equal number of top and bottom nodes (%d vs. %d)!\n",topn,botn);
6554 if(info)
printf(
"Looking for %d periodic nodes\n",topn);
6567 revindtop[topn] = i;
6572 revindbot[botn] = i;
6577 if(data->
dim == 2) {
6578 for(i=1;i<=botn;i++) {
6581 for(i2=1;i2<=topn;i2++) {
6583 if(dim == 1) dist = fabs(data->
y[j] - data->
y[j2]);
6584 else if(dim == 2) dist = fabs(data->
x[j] - data->
x[j2]);
6593 if(indxper[j] == j) indxper[j2] = j;
6594 else if(indxper[indxper[j]]==indxper[j]) {
6596 printf(
"case2: j=[%d %d] i=[%d %d]\n",j,j2,i,i2);
6598 indxper[j2] = indxper[j];
6601 printf(
"unknown 2d case!\n");
6605 printf(
"Couldn't find a periodic counterpart for node %d at [%.3lg %.3lg]]\n",
6606 j,data->
x[j],data->
y[j]);
6612 if(data->
dim == 3) {
6613 for(i=1;i<=botn;i++) {
6616 epsmin = coordmax - coordmin;
6618 for(i2=1;i2<=topn;i2++) {
6621 dy = data->
y[j] - data->
y[j2];
6622 dz = data->
z[j] - data->
z[j2];
6625 dx = data->
x[j] - data->
x[j2];
6626 dz = data->
z[j] - data->
z[j2];
6629 dx = data->
x[j] - data->
x[j2];
6630 dy = data->
y[j] - data->
y[j2];
6632 if(
dx*
dx+dy*dy+dz*dz < eps*eps) {
6642 if(indxper[j] == j) indxper[j2] = j;
6643 else if(indxper[indxper[j]]==indxper[j]) {
6644 indxper[j2] = indxper[j];
6646 else if(indxper[indxper[indxper[j]]]==indxper[indxper[j]]) {
6647 indxper[j2] = indxper[indxper[j]];
6650 printf(
"unknown 3d case!\n");
6654 printf(
"The periodic counterpart for node %d was not found!\n",j);
6662 if(info)
printf(
"Found all in all %d periodic nodes.\n",tothits);
6667 if(i!=indxper[i])
printf(
"i=%d per=%d\n",i,indxper[i]);
6679 int nolayers,
int *layerbounds,
int *layernumber,
6680 Real *layerratios,
Real *layerthickness,
int *layerparents,
6681 int maxfilters,
Real layereps,
int info)
6685 int i,j,
k,l,
m,
n,i2,i3,nonodes,maxbc,newbc = 0;
6687 int oldnoknots,oldnoelements,maxelemtype,oldmaxnodes;
6688 int nonewnodes,nonewelements,dolayer,
dim,order = 0,midpoints = 0;
6689 int checkmaterials,parent,parent2,use2,second;
6691 Real *newx,*newy,*newz,*oldx,*oldy,*elemwidth;
6692 Real e1x,e1y,e2x,e2y;
6694 int *layernode,*newelementtypes,**newtopo,**oldtopo;
6695 int *topomap,*newmaterial,*herit,*inside,*nonlin = NULL;
6696 int endbcs, *endparents = NULL, *endtypes = NULL, *endnodes = NULL, *endnodes2 = NULL, *endneighbours = NULL;
6698 if(maxfilters == 1) maxfilters = 1000;
6699 if(layereps > 0.1) layereps = 0.001;
6700 if(layereps < 1.0
e-8) layereps = 0.001;
6706 if(maxelemtype > 409) {
6707 printf(
"Subroutine implemented only up to 2nd degree!\n");
6711 if(info)
printf(
"Largest elementtype is %d\n",maxelemtype);
6714 checkmaterials =
FALSE;
6715 for(k=0;k<nolayers;k++)
6716 if(layerparents[k]) checkmaterials =
TRUE;
6721 oldnoelements = noelements = data->
noelements;
6722 oldnoknots = noknots = data->
noknots;
6725 layernode =
Ivector(1,oldnoknots);
6726 for(i=1;i<=oldnoknots;i++) layernode[i] = 0;
6737 if(!bound[j].
created)
continue;
6739 for(i=1;i<=bound[j].
nosides;i++) {
6741 parent = bound[j].
parent[i];
6743 if(bound[j].
types[i] > maxbc) maxbc = bound[j].
types[i];
6745 for(k=0;k<nolayers;k++) {
6747 if(bound[j].
types[i] == layerbounds[k]) {
6748 if(checkmaterials) {
6749 if(layerparents[k] < 0)
continue;
6751 if(data->
material[parent] == layerparents[k])
6753 else if(parent = bound[j].parent2[i]) {
6754 if(data->
material[parent] == layerparents[k]) {
6766 if(!dolayer)
continue;
6771 GetElementSide(bound[j].parent2[i],bound[j].side2[i],bound[j].normal[i],
6772 data,ind,&sideelemtype);
6775 data,ind,&sideelemtype);
6777 nonewelements += layernumber[dolayer-1];
6780 if(sideelemtype == 202) {
6783 else if(sideelemtype == 203) {
6785 if(maxelemtype > 408) midpoints =
TRUE;
6788 for(l=0;l<sideelemtype%100;l++) {
6791 if(!layernode[ind[l]]) {
6793 layernode[ind[l]] = -(noknots + nonewnodes);
6795 if(l < sideelemtype/100 || midpoints)
6796 nonewnodes += order * layernumber[dolayer-1];
6798 nonewnodes += layernumber[dolayer-1];
6801 layernode[ind[l]] =
abs(layernode[ind[l]]);
6807 if(!nonewelements) {
6808 if(info)
printf(
"Found no active boundary layers!\n");
6813 if(maxelemtype%100 > 4) {
6816 for(i=elemtype/100;i<elemtype%100;i++) {
6818 layernode[
k] =
abs(layernode[k]);
6827 if(layernode[i] < 0) endbcs++;
6830 endparents =
Ivector(1,endbcs);
6833 endnodes2 =
Ivector(1,endbcs);
6835 endneighbours =
Ivector(1,2*endbcs);
6836 for(i=1;i<=endbcs;i++)
6837 endparents[i] = endtypes[i] = endnodes[i] = endnodes2[i] = 0;
6841 if(layernode[i] < 0) {
6843 endparents[endbcs] = i;
6851 for(i2=1;i2<=endbcs;i2++) {
6853 if(!bound[j].
created)
continue;
6855 for(i=1;i<=bound[j].
nosides;i++) {
6857 GetElementSide(bound[j].parent[i],bound[j].side[i],bound[j].normal[i],
6858 data,ind,&sideelemtype);
6862 for(i3=0;i3<sideelemtype%100;i3++)
6863 if(ind[i3] == endparents[i2]) {
6867 if(!dolayer)
continue;
6871 if(checkmaterials) {
6872 for(k=0;k<nolayers;k++) {
6873 if(layerparents[k] < 0)
continue;
6874 parent = bound[j].
parent[i];
6875 if(data->
material[parent] == layerparents[k])
6877 else if(parent = bound[j].parent2[i]) {
6878 if(data->
material[parent] == layerparents[k]) {
6884 if(!dolayer)
continue;
6888 for(k=0;k<nolayers;k++) {
6889 if(layerparents[k] < 0)
continue;
6890 if(bound[j].
types[i] == layerbounds[k]) dolayer =
TRUE;
6893 endneighbours[2*i2-1] = ind[1-i3];
6897 endtypes[i2] = bound[j].
types[i];
6898 dx = fabs(data->
x[ind[0]] - data->
x[ind[1]]);
6899 dy = fabs(data->
y[ind[0]] - data->
y[ind[1]]);
6901 if(dx < rectfactor *
dy &&
dy < rectfactor * dx) {
6902 endnodes[i2] = ind[i3];
6903 if(sideelemtype%100 > 2) endnodes2[i2] = ind[2];
6904 endneighbours[2*i2] = ind[1-i3];
6907 if(info)
printf(
"Found an existing boundary %d for the single node %d %d\n",
6908 bound[j].
types[i],endparents[i2],endnodes[i2]);
6918 endtypes[i2] = maxbc;
6933 for(k=0;k<nolayers;k++)
6934 if(layernumber[k] > i) i = layernumber[
k];
6938 printf(
"Allocating for additional %d boundary elements into bc %d.\n",
6939 bound[newbc].nosides,newbc);
6948 noknots = data->
noknots + nonewnodes;
6949 noelements = data->
noelements + nonewelements;
6955 printf(
"Creating additional %d elements and %d nodes.\n",nonewelements,nonewnodes);
6956 printf(
"Boundary layer mesh has %d elements and %d nodes.\n",noelements,noknots);
6960 if(maxelemtype <= 303)
6962 else if(maxelemtype == 306)
6967 newmaterial =
Ivector(1,noelements);
6968 newelementtypes =
Ivector(1,noelements);
6972 for(i=1;i<=
noknots;i++) newz[i] = 0.0;
6974 elemwidth =
Rvector(1,nonewelements);
6975 for(i=1;i<=nonewelements;i++) elemwidth[i] = 0.0;
6978 for(i=1;i<=oldnoknots;i++) herit[i] = i;
6979 for(i=oldnoknots+1;i<=
noknots;i++) herit[i] = 0;
6984 newmaterial[j] = data->
material[j];
6987 newtopo[j][i] = data->
topology[j][i];
6991 for(i=1;i<=data->
noknots;i++) {
6992 newx[i] = data->
x[i];
6993 newy[i] = data->
y[i];
6997 for(i=1;i<=
noknots;i++) topomap[i] = i;
6999 inside =
Ivector(1,noelements);
7005 if(!bound[j].created)
continue;
7007 for(i=1;i<=bound[j].
nosides;i++) {
7010 parent = bound[j].
parent[i];
7011 parent2 = bound[j].
parent2[i];
7014 for(k=0;k<nolayers;k++) {
7015 if(bound[j].
types[i] == layerbounds[k]) {
7016 if(checkmaterials) {
7017 if(layerparents[k] < 0)
continue;
7019 if(data->
material[parent] == layerparents[k]) {
7026 if(data->
material[parent] == layerparents[k]) {
7032 else dolayer = k + 1;
7037 if(!dolayer)
continue;
7040 GetElementSide(bound[j].parent2[i],bound[j].side2[i],bound[j].normal[i],
7041 data,ind,&sideelemtype);
7043 GetElementSide(bound[j].parent[i],bound[j].side[i],bound[j].normal[i],
7044 data,ind,&sideelemtype);
7048 if(sideelemtype == 202)
7050 else if(sideelemtype == 203)
7054 for(i2=0;i2<sideelemtype%100;i2++) {
7056 if(i2 < 2 && layernode[ind[i2]] < 0) {
7057 layernode[ind[i2]] =
abs(layernode[ind[i2]]);
7063 dy = -(data->
x[ind[1]] - data->
x[ind[0]]);
7064 dx = data->
y[ind[1]] - data->
y[ind[0]];
7065 ds = sqrt(dx*dx+
dy*
dy);
7069 n = layernumber[dolayer-1];
7070 ds = -layerthickness[dolayer-1];
7072 for(l=0;l <
n;l++) {
7075 newmaterial[elemindx] = data->
material[parent];
7076 inside[elemindx] = 1;
7078 if(n <= 1 || fabs(layerratios[dolayer-1]-1.0) < 0.001) {
7080 elemwidth[elemindx-oldnoelements] = ds /
n;
7083 ratio = pow(layerratios[dolayer-1],-1./(n-1.));
7084 q = (1.- pow(ratio,(
Real)(l+1))) / (1.-pow(ratio,(
Real)(n)));
7085 p = (1.- pow(ratio,(
Real)(l))) / (1.-pow(ratio,(
Real)(n)));
7086 elemwidth[elemindx-oldnoelements] = (q-
p) * ds;
7090 for(m=0;m<sideelemtype%100;m++) {
7097 bound[newbc].
parent[i2] = elemindx;
7099 bound[newbc].
side[i2] = 3 - 2*
m;
7100 bound[newbc].
side2[i2] = 0;
7102 for(i3=1;i3<=endbcs;i3++)
7103 if(ind[m] == endparents[i3]) {
7104 bound[newbc].
types[i2] = endtypes[i3];
7105 endneighbours[2*i3-1] = layernode[ind[
m]] + 1;
7112 nodeindx = layernode[ind[
m]] + order*(l+1);
7115 nodeindx = layernode[ind[
m]] + (1+midpoints)*(l+1);
7121 if(herit[nodeindx] != 0) {
7123 e2x = newx[nodeindx] - data->
x[ind[
m]];
7124 e2y = newy[nodeindx] - data->
y[ind[
m]];
7126 p = (e1x*e2x + e1y*e2y)/(sqrt(e1x*e1x+e1y*e1y)*sqrt(e2x*e2x+e2y*e2y));
7128 newx[nodeindx] += e1x - p * e2x;
7129 newy[nodeindx] += e1y - p * e2y;
7132 herit[nodeindx] = ind[
m];
7133 newx[nodeindx] = data->
x[ind[
m]] + e1x;
7134 newy[nodeindx] = data->
y[ind[
m]] + e1y;
7140 newtopo[elemindx][3] = ind[0];
7141 newtopo[elemindx][2] = ind[1];
7142 if(order == 2) newtopo[elemindx][6] = ind[2];
7145 newtopo[elemindx][3] = layernode[ind[0]] + order*l;
7146 newtopo[elemindx][2] = layernode[ind[1]] + order*l;
7147 if(order == 2) newtopo[elemindx][6] = layernode[ind[2]] + (midpoints+1)*l;
7149 newtopo[elemindx][0] = layernode[ind[0]] + order*(l+1);
7150 newtopo[elemindx][1] = layernode[ind[1]] + order*(l+1);
7153 newtopo[elemindx][7] = layernode[ind[0]] + order*l+1;
7154 newtopo[elemindx][5] = layernode[ind[1]] + order*l+1;
7155 newtopo[elemindx][4] = layernode[ind[2]] + (midpoints+1)*(l+1);
7156 if(midpoints) newtopo[elemindx][8] = layernode[ind[2]] + 2*l+1;
7160 newelementtypes[elemindx] = 404;
7162 else if(midpoints) {
7163 newelementtypes[elemindx] = 409;
7166 newelementtypes[elemindx] = 408;
7170 if(l == n-1 && parent2) {
7173 inside[parent2] = 2;
7175 for(i2=0;i2<elemtype%100;i2++) {
7176 for(i3=0;i3<sideelemtype%100;i3++) {
7177 if(data->
topology[parent2][i2] == ind[i3]) {
7179 topomap[ind[i3]] = layernode[ind[i3]] + order *
n;
7182 topomap[ind[i3]] = layernode[ind[i3]] + (midpoints+1) * n;
7192 bound[j].
side2[i] = 0;
7193 bound[j].
parent2[i] = elemindx;
7196 bound[j].
side[i] = 0;
7197 bound[j].
parent[i] = elemindx;
7206 for(i=1;i<=
noknots;i++) inside2[i] = 0;
7210 if(inside[j] == 2) {
7212 for(i=0;i<elemtype/100;i++) {
7213 inside2[newtopo[j][i]] =
TRUE;
7223 for(i=0;i<elemtype/100;i++)
7224 if(inside2[newtopo[j][i]]) k++;
7225 if(k > 1) inside[j] = 2;
7232 if(checkmaterials) {
7233 for(j=1;j<=oldnoelements;j++) {
7235 for(k=0;k<nolayers;k++)
7236 if(data->
material[j] == layerparents[k]) dolayer =
TRUE;
7239 if(inside[j] == 1)
printf(
"Element %d of material %d should be in the inside\n",
7248 if(inside[j] == 2) {
7250 for(i=0;i<elemtype%100;i++)
7251 newtopo[j][i] = topomap[data->
topology[j][i]];
7281 if(maxelemtype%100 > 4) {
7282 if(info)
printf(
"Marking the higher order nodes\n");
7289 for(i=elemtype/100;i<elemtype%100;i++) {
7299 int ind1,ind2,ind3,*fixedx,*fixedy;
7300 Real *aidx,*aidy,*weights;
7301 Real maxerror = 0,minds,dx2 = 0,dy2 = 0,ds2,fii;
7307 if(info)
printf(
"Filtering the mesh to meet the original geometry\n");
7316 for(i=1;i<=
noknots;i++) fixedx[i] = fixedy[i] = 0;
7319 if(checkmaterials) {
7324 for(k=0;k<nolayers;k++)
7325 if(data->
material[j] == layerparents[k]) dolayer =
TRUE;
7327 for(i=0;i<elemtype/100;i++) {
7329 if(dolayer && fixedx[ind1]%2 == 0)
7331 if(!dolayer && fixedx[ind1] < 2)
7345 if(!bound[j].created)
continue;
7347 for(i=1;i<=bound[j].
nosides;i++) {
7349 GetElementSide(bound[j].parent[i],bound[j].side[i],bound[j].normal[i],
7350 data,ind,&sideelemtype);
7352 dx = fabs(newx[ind[0]] - newx[ind[1]]);
7353 dy = fabs(newy[ind[0]] - newy[ind[1]]);
7354 if(dx > rectfactor *
dy) {
7355 for(l=0;l<sideelemtype%100;l++) {
7356 fixedy[ind[l]] =
TRUE;
7359 else if(dy > rectfactor * dx) {
7360 for(l=0;l<sideelemtype%100;l++) {
7361 fixedx[ind[l]] =
TRUE;
7365 for(l=0;l<sideelemtype%100;l++) {
7366 fixedy[ind[l]] =
TRUE;
7367 fixedx[ind[l]] =
TRUE;
7376 if(!bound[j].created)
continue;
7378 for(i=1;i<=bound[j].
nosides;i++) {
7381 parent = bound[j].
parent[i];
7382 parent2 = bound[j].
parent2[i];
7385 GetElementSide(bound[j].parent[i],bound[j].side[i],bound[j].normal[i],
7386 data,ind,&sideelemtype);
7388 for(k=0;k<nolayers;k++) {
7389 if(bound[j].
types[i] == layerbounds[k]) {
7390 if(checkmaterials) {
7391 if(layerparents[k] < 0)
continue;
7393 if(data->
material[parent] == layerparents[k]) {
7400 if(data->
material[parent] == layerparents[k]) {
7406 else dolayer = k + 1;
7411 for(l=0;l<sideelemtype%100;l++) {
7412 fixedy[ind[l]] =
TRUE;
7413 fixedx[ind[l]] =
TRUE;
7420 for(j=1;j<=endbcs;j++) {
7437 for(i=1;i<=
noknots;i++)
if(fixedx[i]) j += 1;
7438 if(info)
printf(
"Number of fixed nodes in x-direction is %d\n",j);
7441 for(i=1;i<=
noknots;i++)
if(fixedy[i]) j += 1;
7442 if(info)
printf(
"Number of fixed nodes in y-direction is %d\n",j);
7448 newx[j] = aidx[j] = oldx[j];
7450 newx[j] = aidx[j] = oldx[herit[j]];
7454 newy[j] = aidy[j] = oldy[j];
7456 newy[j] = aidy[j] = oldy[herit[j]];
7461 for(iter=1;iter<=maxfilters;iter++) {
7481 nonodes = elemtype / 100;
7483 for(i=0;i<nonodes;i++) {
7492 if(j<=oldnoelements) {
7493 dx = oldx[oldtopo[j][i2]] - oldx[oldtopo[j][i]];
7494 dy = oldy[oldtopo[j][i2]] - oldy[oldtopo[j][i]];
7495 ds = sqrt(dx*dx+
dy*
dy);
7498 ds = fabs(elemwidth[j-oldnoelements]);
7500 if(ds < minds) minds = ds;
7503 if(j<=oldnoelements) {
7504 dx2 = oldx[oldtopo[j][i2]] - oldx[oldtopo[j][i3]];
7505 dy2 = oldy[oldtopo[j][i2]] - oldy[oldtopo[j][i3]];
7506 ds2 = sqrt(dx2*dx2+dy2*dy2);
7509 ds2 = fabs(elemwidth[j-oldnoelements]);
7512 if(j <= oldnoelements && ds * ds2 < 1.0
e-50) {
7513 printf(
"problem elem %d and nodes %d (%d %d)\n",j,i2,i,i3);
7514 printf(
"dist ds=%.3le ds2=%.3le\n",ds,ds2);
7515 printf(
"coord: %.3le %.3le\n",oldx[oldtopo[j][i2]], oldy[oldtopo[j][i2]]);
7519 if(
abs(method) == 2 && j<=oldnoelements) {
7520 fii = acos((dx*dx2+
dy*dy2)/(ds*ds2)) / (
FM_PI/2.0);
7522 else if(
abs(method) == 3 && j<=oldnoelements) {
7523 fii = acos((dx*dx2+
dy*dy2)/(ds*ds2));
7533 for(k=1;k<=endbcs;k++)
7534 if(ind2 == endnodes[k]) dolayer =
k;
7538 if(endneighbours[2*(dolayer-1)+k] == ind1) {
7539 weights[ind2] += fii / ds;
7540 if(!fixedx[ind2]) newx[ind2] += aidx[ind1] * fii / ds;
7541 if(!fixedy[ind2]) newy[ind2] += aidy[ind1] * fii / ds;
7545 if(endneighbours[2*(dolayer-1)+k] == ind3) {
7546 weights[ind2] += fii / ds2;
7547 if(!fixedx[ind2]) newx[ind2] += aidx[ind3] * fii / ds2;
7548 if(!fixedy[ind2]) newy[ind2] += aidy[ind3] * fii / ds2;
7553 if(ind2 <= oldnoknots || herit[ind1] == herit[ind2]) {
7554 weights[ind2] += fii / ds;
7555 if(!fixedx[ind2]) newx[ind2] += aidx[ind1] * fii / ds;
7556 if(!fixedy[ind2]) newy[ind2] += aidy[ind1] * fii / ds;
7559 if(ind2 <= oldnoknots || herit[ind3] == herit[ind2]) {
7560 weights[ind2] += fii / ds2;
7561 if(!fixedx[ind2]) newx[ind2] += aidx[ind3] * fii / ds2;
7562 if(!fixedy[ind2]) newy[ind2] += aidy[ind3] * fii / ds2;
7568 if(maxelemtype%100 > 4) {
7570 if(nonlin[j])
continue;
7572 if(weights[j] > 1.0
e-50) {
7573 if(!fixedx[j]) newx[j] /= weights[j];
7574 if(!fixedy[j]) newy[j] /= weights[j];
7577 printf(
"no weight for index %d\n",j);
7580 dx = newx[j] - aidx[j];
7581 dy = newy[j] - aidy[j];
7584 if(ds > maxerror) maxerror = ds;
7589 if(!fixedx[j]) newx[j] /= weights[j];
7590 if(!fixedy[j]) newy[j] /= weights[j];
7592 dx = newx[j]-aidx[j];
7593 dy = newy[j]-aidy[j];
7596 if(ds > maxerror) maxerror = ds;
7600 maxerror = sqrt(maxerror) / minds;
7601 if(maxerror < layereps)
break;
7605 printf(
"Filtered the new node coordinates %d times with final error %.3le.\n",
7613 if(maxelemtype%100 > 4) {
7616 if(elemtype%100 <= elemtype/100)
continue;
7618 if(elemtype == 306) {
7620 if(!fixedx[newtopo[j][k+3]]) {
7621 newx[newtopo[j][k+3]] = 0.5 * (newx[newtopo[j][
k]] + newx[newtopo[j][(k+1)%3]]);
7623 if(!fixedy[newtopo[j][k+3]]) {
7624 newy[newtopo[j][k+3]] = 0.5 * (newy[newtopo[j][
k]] + newy[newtopo[j][(k+1)%3]]);
7629 else if(elemtype == 408 || elemtype == 409) {
7631 if(elemtype == 409) {
7632 newx[newtopo[j][8]] = 0.0;
7633 newy[newtopo[j][8]] = 0.0;
7637 if(!fixedx[newtopo[j][k+4]]) {
7638 newx[newtopo[j][k+4]] = 0.5 * (newx[newtopo[j][
k]] + newx[newtopo[j][(k+1)%4]]);
7640 if(!fixedy[newtopo[j][k+4]]) {
7641 newy[newtopo[j][k+4]] = 0.5 * (newy[newtopo[j][
k]] + newy[newtopo[j][(k+1)%4]]);
7643 if(elemtype == 409) {
7644 newx[newtopo[j][8]] += 0.25 * newx[newtopo[j][
k]];
7645 newy[newtopo[j][8]] += 0.25 * newy[newtopo[j][
k]];
7650 printf(
"Unknown elementtype %d\n",elemtype);
7663 if(bound[newbc].nosides > 0)
7671 if(!maxfilters && maxelemtype%100 > 4) {
7672 if(info)
printf(
"Making the higher order nodes to lie in between\n");
7677 if(elemtype%100 <= elemtype/100)
continue;
7679 if(elemtype == 408 || elemtype == 409) {
7681 if(elemtype == 409) {
7682 newx[newtopo[j][8]] = 0.0;
7683 newy[newtopo[j][8]] = 0.0;
7687 newx[newtopo[j][k+4]] = 0.5 * (newx[newtopo[j][
k]] + newx[newtopo[j][(k+1)%4]]);
7688 newy[newtopo[j][k+4]] = 0.5 * (newy[newtopo[j][
k]] + newy[newtopo[j][(k+1)%4]]);
7690 if(elemtype == 409) {
7691 newx[newtopo[j][8]] += 0.25 * newx[newtopo[j][
k]];
7692 newy[newtopo[j][8]] += 0.25 * newy[newtopo[j][
k]];
7709 if(info)
printf(
"Boundary layers created successfully.\n");
7711 if(checkmaterials && !second) {
7712 for(k=0;k<nolayers;k++) {
7713 if(layerparents[k] < 0) second =
TRUE;
7714 layerparents[
k] = -layerparents[
k];
7717 if(info)
printf(
"\nPerforming boundary layer generation again for negative materials\n");
7730 int nolayers,
int *layerbounds,
int *layernumber,
7731 Real *layerratios,
Real *layerthickness,
int *layerparents,
7737 int i,j,
k,l,
dim,maxbc,maxelemtype,dolayer,parent,nlayer = 0,sideelemtype,elemind,side;
7738 int noelements,
noknots,oldnoknots,oldnoelements,oldmaxnodes,nonewnodes,nonewelements;
7739 int maxcon,elemsides,elemdone,midpoints,order,bcnodes,elemhits,elemtype,goforit;
7740 int ind[
MAXNODESD2],baseind[2],topnode[2],basenode[2];
7741 int *layernode,*newelementtypes,**newtopo,**oldtopo,*newmaterial,**edgepairs,*sharednode;
7743 Real *newx,*newy,*newz,*oldx,*oldy,*oldz;
7750 if(maxelemtype > 409) {
7751 printf(
"Subroutine implemented only up to 2nd degree!\n");
7755 if(info)
printf(
"Largest elementtype is %d\n",maxelemtype);
7758 oldnoelements = noelements = data->
noelements;
7759 oldnoknots = noknots = data->
noknots;
7762 layernode =
Ivector(1,oldnoknots);
7763 for(i=1;i<=oldnoknots;i++)
7766 sharednode =
Ivector(1,oldnoknots);
7767 for(i=1;i<=oldnoknots;i++)
7778 if(!bound[j].
created)
continue;
7780 for(i=1;i<=bound[j].
nosides;i++) {
7782 parent = bound[j].
parent[i];
7783 if(bound[j].
types[i] > maxbc) maxbc = bound[j].
types[i];
7785 for(k=0;k<nolayers;k++) {
7786 if(bound[j].
types[i] == layerbounds[k]) {
7787 nlayer = layernumber[
k];
7788 slayer = layerthickness[
k];
7789 qlayer = layerratios[
k];
7793 if(!dolayer)
continue;
7797 data,ind,&sideelemtype);
7800 if(sideelemtype == 202) {
7803 else if(sideelemtype == 203) {
7805 if(maxelemtype > 408) midpoints =
TRUE;
7808 for(l=0;l<sideelemtype%100;l++)
7809 layernode[ind[l]] += 1;
7813 if(slayer > 1.0 || slayer < 1.0
e-20)
7818 for(i=1;i<=data->
noknots;i++) {
7819 if(layernode[i]) bcnodes++;
7820 maxcon =
MAX(maxcon, layernode[i]);
7823 if(info)
printf(
"Found %d new nodes in the boundary layers!\n",bcnodes);
7824 if(!bcnodes)
return(0);
7825 if(info)
printf(
"There are %d connections at maximum\n",maxcon);
7828 if(maxelemtype <= 303)
7830 else if(maxelemtype == 306)
7838 for(i=0;i<elemtype%100;i++) {
7846 nonewelements += nlayer ;
7847 if(elemhits != 2) nonewelements += nlayer + 1;
7850 printf(
"There will %d new elemenets\n",nonewelements);
7853 nonewnodes = 2*nonewelements;
7855 edgepairs =
Imatrix(1,nonewnodes,1,3);
7856 for(j=1;j<=nonewnodes;j++)
7857 edgepairs[j][1] = edgepairs[j][2] = edgepairs[j][3] = 0;
7868 noknots = oldnoknots + nonewnodes;
7869 noelements = oldnoelements + nonewelements;
7872 printf(
"Creating additional %d elements and %d nodes.\n",nonewelements,nonewnodes);
7873 printf(
"Boundary layer mesh has at maximum %d elements and %d nodes.\n",noelements,noknots);
7878 newmaterial =
Ivector(1,noelements);
7879 newelementtypes =
Ivector(1,noelements);
7886 newmaterial[j] = data->
material[j];
7889 newtopo[j][i] = data->
topology[j][i];
7893 for(i=1;i<=data->
noknots;i++) {
7894 newx[i] = data->
x[i];
7895 newy[i] = data->
y[i];
7896 newz[i] = data->
z[i];
7907 elemsides = elemtype % 100;
7908 for(i=0;i<elemsides;i++)
7909 if( layernode[ data->
topology[j][i] ]) elemhits++;
7910 if(!elemhits)
continue;
7912 if(elemtype == 404) {
7915 for(side=0;side<elemsides;side++) {
7918 if(elemhits == 2 || elemhits == 3)
7919 if(layernode[oldtopo[j][side]] && layernode[oldtopo[j][(side+1)%elemsides]]) goforit =
TRUE;
7921 if(layernode[oldtopo[j][side]]) goforit =
TRUE;
7922 if(!goforit)
continue;
7928 if(!layernode[oldtopo[j][k]])
break;
7929 if(0)
printf(
"Special node %d in corner %d\n",oldtopo[j][k],k);
7931 basenode[0] = oldtopo[j][side];
7932 basenode[1] = oldtopo[j][(side+1)%elemsides];
7933 topnode[0] = oldtopo[j][
k];
7934 topnode[1] = oldtopo[j][
k];
7936 else if(elemhits == 2) {
7937 basenode[0] = oldtopo[j][side];
7938 basenode[1] = oldtopo[j][(side+1)%elemsides];
7939 topnode[0] = oldtopo[j][(side+3)%elemsides];
7940 topnode[1] = oldtopo[j][(side+2)%elemsides];
7942 else if(elemhits == 1) {
7943 basenode[0] = oldtopo[j][side];
7944 basenode[1] = basenode[0];
7945 topnode[0] = oldtopo[j][(side+3)%elemsides];
7946 topnode[1] = oldtopo[j][(side+1)%elemsides];
7950 for(i=1;i<=nonewnodes;i++) {
7951 if(!edgepairs[i][1])
break;
7952 if(basenode[k] == edgepairs[i][1] && topnode[k] == edgepairs[i][2])
break;
7954 if(!edgepairs[i][1]) {
7955 edgepairs[i][1] = basenode[
k];
7956 edgepairs[i][2] = topnode[
k];
7958 edgepairs[i][3] = baseind[
k];
7962 if(0)
printf(
"Using existing nodes\n");
7963 baseind[
k] = edgepairs[i][3];
7965 x0[
k] = oldx[basenode[
k]];
7966 y0[
k] = oldy[basenode[
k]];
7967 dx[
k] = oldx[topnode[
k]] - x0[
k];
7968 dy[
k] = oldy[topnode[
k]] - y0[
k];
7970 for(i=1;i<=nlayer;i++) {
7971 if(nlayer <= 1 || fabs(qlayer-1.0) < 0.001) {
7972 q = (1.0*i) / (nlayer+1);
7975 ratio = pow(qlayer,1.0/nlayer);
7976 q = (1.- pow(
ratio,1.0*i)) / (1.- pow(
ratio,1.0+nlayer));
7979 newx[baseind[
k]+i] = x0[
k] + q * dx[
k];
7980 newy[baseind[
k]+i] = y0[
k] + q * dy[
k];
7986 newelementtypes[j] = 303;
7987 newtopo[j][0] = basenode[0];
7988 newtopo[j][1] = baseind[1] + 1;
7989 newtopo[j][2] = baseind[0] + 1;
7991 else if(elemhits == 3 && elemdone) {
7993 newelementtypes[elemind] = 404;
7994 newmaterial[elemind] = newmaterial[j];
7995 newtopo[elemind][side] = basenode[0];
7996 newtopo[elemind][(side+1)%elemsides] = basenode[1];
7997 newtopo[elemind][(side+2)%elemsides] = baseind[1] + 1;
7998 newtopo[elemind][(side+3)%elemsides] = baseind[0] + 1;
8001 newtopo[j][(side+2)%elemsides] = baseind[1] + 1;
8002 newtopo[j][(side+3)%elemsides] = baseind[0] + 1;
8005 for(i=1;i<nlayer;i++) {
8007 newelementtypes[elemind] = 404;
8008 newmaterial[elemind] = newmaterial[j];
8009 newtopo[elemind][0] = baseind[0] + i;
8010 newtopo[elemind][1] = baseind[1] + i;
8011 newtopo[elemind][2] = baseind[1] + i+1;
8012 newtopo[elemind][3] = baseind[0] + i+1;
8018 newelementtypes[elemind] = 303;
8019 newmaterial[elemind] = newmaterial[j];
8020 newtopo[elemind][0] = baseind[0] + nlayer;
8021 newtopo[elemind][1] = baseind[1] + nlayer;
8022 newtopo[elemind][2] = topnode[0];
8024 else if(elemhits == 2 || elemhits == 1) {
8026 newelementtypes[elemind] = 404;
8027 newmaterial[elemind] = newmaterial[j];
8028 newtopo[elemind][0] = baseind[0] + nlayer;
8029 newtopo[elemind][1] = baseind[1] + nlayer;
8030 newtopo[elemind][2] = topnode[1];
8031 newtopo[elemind][3] = topnode[0];
8036 newelementtypes[elemind] = 303;
8037 newmaterial[elemind] = newmaterial[j];
8038 newtopo[elemind][0] = topnode[1];
8039 newtopo[elemind][1] = oldtopo[j][(side+2)%elemsides];
8040 newtopo[elemind][2] = topnode[0];
8046 printf(
"cannot handle quadrilaterals with %d hits\n",elemhits);
8050 else if(elemtype == 303) {
8053 for(side=0;side<elemsides;side++) {
8057 if(layernode[oldtopo[j][side]] && layernode[oldtopo[j][(side+1)%elemsides]]) goforit =
TRUE;
8059 else if(elemhits == 1) {
8060 if(layernode[oldtopo[j][side]]) goforit =
TRUE;
8062 else if(elemhits == 3) {
8063 if(sharednode[oldtopo[j][side]] == 1) goforit =
TRUE;
8065 printf(
"The boundary layer creation for certain corner triangles is omitted\n");
8068 if(!goforit)
continue;
8071 if(1)
printf(
"Special node %d in corner %d\n",oldtopo[j][side],side);
8072 basenode[0] = oldtopo[j][side];
8073 basenode[1] = basenode[0];
8074 topnode[0] = oldtopo[j][(side+2)%elemsides];
8075 topnode[1] = oldtopo[j][(side+1)%elemsides];
8077 else if(elemhits == 2) {
8078 basenode[0] = oldtopo[j][side];
8079 basenode[1] = oldtopo[j][(side+1)%elemsides];
8080 topnode[0] = oldtopo[j][(side+2)%elemsides];
8081 topnode[1] = topnode[0];
8083 else if(elemhits == 1) {
8084 basenode[0] = oldtopo[j][side];
8085 basenode[1] = basenode[0];
8086 topnode[0] = oldtopo[j][(side+2)%elemsides];
8087 topnode[1] = oldtopo[j][(side+1)%elemsides];
8091 for(i=1;i<=nonewnodes;i++) {
8092 if(!edgepairs[i][1])
break;
8093 if(basenode[k] == edgepairs[i][1] && topnode[k] == edgepairs[i][2])
break;
8095 if(!edgepairs[i][1]) {
8096 edgepairs[i][1] = basenode[
k];
8097 edgepairs[i][2] = topnode[
k];
8099 edgepairs[i][3] = baseind[
k];
8103 if(0)
printf(
"Using existing nodes\n");
8104 baseind[
k] = edgepairs[i][3];
8107 x0[
k] = oldx[basenode[
k]];
8108 y0[
k] = oldy[basenode[
k]];
8109 dx[
k] = oldx[topnode[
k]] - x0[
k];
8110 dy[
k] = oldy[topnode[
k]] - y0[
k];
8112 for(i=1;i<=nlayer;i++) {
8113 if(nlayer <= 1 || fabs(qlayer-1.0) < 0.001) {
8114 q = (1.0*i) / (nlayer+1);
8117 ratio = pow(qlayer,1.0/nlayer);
8118 q = (1.- pow(
ratio,1.0*i)) / (1.- pow(
ratio,1.0*nlayer));
8121 newx[baseind[
k]+i] = x0[
k] + q * dx[
k];
8122 newy[baseind[
k]+i] = y0[
k] + q * dy[
k];
8127 if(elemhits == 1 || elemhits == 3) {
8128 newelementtypes[j] = 303;
8129 newtopo[j][0] = basenode[0];
8130 newtopo[j][1] = baseind[1] + 1;
8131 newtopo[j][2] = baseind[0] + 1;
8133 else if(elemhits == 2) {
8134 newelementtypes[j] = 404;
8135 newtopo[j][side] = basenode[0];
8136 newtopo[j][(side+1)%4] = basenode[1];
8137 newtopo[j][(side+2)%4] = baseind[1] + 1;
8138 newtopo[j][(side+3)%4] = baseind[0] + 1;
8141 for(i=1;i<nlayer;i++) {
8143 newelementtypes[elemind] = 404;
8144 newmaterial[elemind] = newmaterial[j];
8145 newtopo[elemind][0] = baseind[0] + i;
8146 newtopo[elemind][1] = baseind[1] + i;
8147 newtopo[elemind][2] = baseind[1] + i+1;
8148 newtopo[elemind][3] = baseind[0] + i+1;
8152 if(elemhits == 1 || elemhits == 3) {
8154 newelementtypes[elemind] = 404;
8155 newmaterial[elemind] = newmaterial[j];
8156 newtopo[elemind][0] = baseind[0] + nlayer;
8157 newtopo[elemind][1] = baseind[1] + nlayer;
8158 newtopo[elemind][2] = topnode[1];
8159 newtopo[elemind][3] = topnode[0];
8161 else if(elemhits == 2) {
8163 newelementtypes[elemind] = 303;
8164 newmaterial[elemind] = newmaterial[j];
8165 newtopo[elemind][0] = baseind[0] + nlayer;
8166 newtopo[elemind][1] = baseind[1] + nlayer;
8167 newtopo[elemind][2] = topnode[1];
8172 printf(
"cannot handle triangles with %d hits\n",elemhits);
8176 printf(
"Not implemented for element %d\n",elemtype);
8179 noelements = elemind;
8189 printf(
"The created boundary layer mesh has at %d elements and %d nodes.\n",noelements,noknots);
8199 Real x,
y,
z,xz,yz,yx,zx,zy,xy,cx,cy,cz = 0;
8203 if(info)
printf(
"Scaling mesh with vector [%.3lg %.3lg %.3lg]\n",
8205 for(i=1;i<=data->
noknots;i++) {
8208 if(data->
dim == 3) data->
z[i] *= eg->
cscale[2];
8210 if(0)
printf(
"Scaling of mesh finished.\n");
8214 if(info)
printf(
"Rotating mesh with degrees [%.3lg %.3lg %.3lg]\n",
8220 for(i=1;i<=data->
noknots;i++) {
8223 if(data->
dim >= 2) y = data->
y[i];
8225 if(data->
dim >= 3) z = data->
z[i];
8228 xz = x*
cos(cz) + y*sin(cz);
8229 yz = -x*sin(cz) + y*
cos(cz);
8231 if(data->
dim == 3) {
8232 yx = yz*
cos(cx) + z*sin(cx);
8233 zx = -yz*sin(cx) + z*
cos(cx);
8235 zy = zx*
cos(cy) + xz*sin(cy);
8236 xy = -zx*sin(cy) + xz*
cos(cy);
8247 if(0)
printf(
"Rotation of mesh finished.\n");
8251 if(info)
printf(
"Translating the mesh with vector [%.3lg %.3lg %.3lg]\n",
8253 for(i=1;i<=data->
noknots;i++) {
8258 if(0)
printf(
"Translation of mesh finished.\n");
8262 xmin = xmax = data->
x[1];
8263 ymin = ymax = data->
y[1];
8264 if(data->
dim == 3) zmin = zmax = data->
z[1];
8266 for(i=1;i<=data->
noknots;i++) {
8267 xmax =
MAX( xmax, data->
x[i] );
8268 xmin =
MIN( xmin, data->
x[i] );
8269 ymax =
MAX( ymax, data->
y[i] );
8270 ymin =
MIN( ymin, data->
y[i] );
8271 if(data->
dim == 3) {
8272 zmax =
MAX( zmax, data->
z[i] );
8273 zmin =
MIN( zmin, data->
z[i] );
8276 cx = 0.5 * (xmin +
xmax);
8277 cy = 0.5 * (ymin +
ymax);
8278 if(data->
dim == 3) cz = 0.5 * (zmin + zmax);
8280 if(info)
printf(
"Setting new center to %.3le %.3le %.3le\n",cx,cy,cz);
8282 for(i=1;i<=data->
noknots;i++) {
8285 if(data->
dim == 3) data->
z[i] -= cz;
8296 int i,j,
k,l,
m,totcon,
noelements,
noknots,elemtype,nonodes,hit,ind,ind2;
8297 int maxcon,percon,edge;
8299 printf(
"Creating a dual graph of the finite element mesh\n");
8302 printf(
"The dual graph already exists! You shoule remove the old graph!\n");
8316 for(edge=0;;edge++) {
8323 for(l=0;l<maxcon;l++) {
8339 for(l=0;l<maxcon;l++) {
8341 if(data->
dualgraph[l][ind2] == 0)
break;
8358 for(j=0;j<nonodes;j++) {
8360 for(k=0;k<nonodes;k++) {
8362 if(ind == ind2)
continue;
8365 for(l=0;l<maxcon;l++) {
8386 for(ind=1;ind<=
noknots;ind++) {
8388 if(ind == ind2)
continue;
8391 for(l=0;l<maxcon;l++) {
8412 if(info)
printf(
"There are at maximum %d connections in dual graph.\n",maxcon);
8413 if(info)
printf(
"There are at all in all %d connections in dual graph.\n",totcon);
8414 if(info && percon)
printf(
"There are %d periodic connections in dual graph.\n",percon);
8425 printf(
"You tried to destroy a non-existing dual graph\n");
8432 for(i=0;i<maxcon;i++)
8438 if(info)
printf(
"The dual graph was destroyed\n");
8447 int *neededby,minneeded,maxneeded;
8449 printf(
"Creating an inverse topology of the finite element mesh\n");
8452 printf(
"The inverse topology already exists!\n");
8460 neededby =
Ivector(1,noknots);
8468 for(j=0;j<nonodes;j++) {
8484 minneeded = maxneeded = neededby[1];
8486 minneeded =
MIN( minneeded, neededby[i]);
8487 maxneeded =
MAX( maxneeded, neededby[i]);
8491 if(info)
printf(
"There are from %d to %d connections in the inverse topology.\n",minneeded,maxneeded);
8502 int i,elemtype,maxelemtype,minelemtype,*elemtypes;
8508 maxelemtype =
MAX( maxelemtype, elemtype );
8509 minelemtype =
MIN( minelemtype, elemtype );
8512 elemtypes =
Ivector(minelemtype,maxelemtype);
8513 for(i=minelemtype;i<=maxelemtype;i++)
8518 elemtypes[elemtype] += 1;
8522 printf(
"Number of different elementtypes\n");
8523 for(i=minelemtype;i<=maxelemtype;i++)
8524 if(elemtypes[i])
printf(
"\t%d\t%d\n",i,elemtypes[i]);
8536 int i,j,l,currenttype;
8541 if(info)
printf(
"Setting boundary types between %d and %d to %d\n",
8545 if(!bound[j].
created)
continue;
8547 for(i=1; i <= bound[j].
nosides; i++) {
8548 if(currenttype = bound[j].
types[i]) {
8550 if(currenttype >= eg->
sidemap[3*l] && currenttype <= eg->sidemap[3*l+1]) {
8558 if(info)
printf(
"Renumbering boundary types finished\n");
8563 if(info)
printf(
"Setting material types between %d and %d to %d\n",
8568 if(currenttype >= eg->
bulkmap[3*l] && currenttype <= eg->bulkmap[3*l+1]) {
8574 if(info)
printf(
"Renumbering material indexes finished\n");
8584 int *boundnodes,noboundnodes;
8590 boundnodes,&noboundnodes,info);
8597 boundnodes,&noboundnodes,info);