13 #include "../fem/fem.hpp"
14 #include "../general/text.hpp"
17 #if defined(_MSC_VER) && (_MSC_VER < 1800)
19 #define copysign _copysign
31 input >> Order >> NumOfControlPoints;
32 knot.Load(input, NumOfControlPoints + Order + 1);
39 NumOfControlPoints = NCP;
40 knot.SetSize(NumOfControlPoints + Order + 1);
61 " Parent KnotVector order higher than child");
63 int nOrder = Order + t;
66 for (
int i = 0; i <= nOrder; i++)
68 (*newkv)[i] = knot(0);
70 for (
int i = nOrder + 1; i < newkv->
GetNCP(); i++)
72 (*newkv)[i] = knot(i - t);
74 for (
int i = 0; i <= nOrder; i++)
76 (*newkv)[newkv->
GetNCP() + i] = knot(knot.Size()-1);
86 newknots.
SetSize(NumOfElements);
88 for (
int i = 0; i < knot.Size()-1; i++)
90 if (knot(i) != knot(i+1))
92 newknots(j) = 0.5*(knot(i) + knot(i+1));
101 for (
int i = Order; i < NumOfControlPoints; i++)
103 if (knot(i) != knot(i+1))
112 double apb = knot(0) + knot(knot.Size()-1);
114 int ns = (NumOfControlPoints - Order)/2;
115 for (
int i = 1; i <= ns; i++)
117 double tmp = apb - knot(Order + i);
118 knot(Order + i) = apb - knot(NumOfControlPoints - i);
119 knot(NumOfControlPoints - i) = tmp;
125 out << Order <<
' ' << NumOfControlPoints <<
' ';
126 knot.Print(out, knot.Size());
133 int ip = (i >= 0) ? (i + p) : (-1 - i + p);
134 double u = getKnotLocation((i >= 0) ? xi : 1. - xi, ip), saved, tmp;
135 double left[MaxOrder+1], right[MaxOrder+1];
140 mfem_error(
"KnotVector::CalcShape : Order > MaxOrder!");
145 for (
int j = 1; j <= p; ++j)
147 left[j] = u - knot(ip+1-j);
148 right[j] = knot(ip+j) - u;
150 for (
int r = 0; r < j; ++r)
152 tmp = shape(r)/(right[r+1] + left[j-r]);
153 shape(r) = saved + right[r+1]*tmp;
154 saved = left[j-r]*tmp;
163 int p = Order, rk, pk;
164 int ip = (i >= 0) ? (i + p) : (-1 - i + p);
165 double u = getKnotLocation((i >= 0) ? xi : 1. - xi, ip), temp, saved, d;
166 double ndu[MaxOrder+1][MaxOrder+1], left[MaxOrder+1], right[MaxOrder+1];
171 mfem_error(
"KnotVector::CalcDShape : Order > MaxOrder!");
176 for (
int j = 1; j <= p; j++)
178 left[j] = u - knot(ip-j+1);
179 right[j] = knot(ip+j) - u;
181 for (
int r = 0; r < j; r++)
183 ndu[j][r] = right[r+1] + left[j-r];
184 temp = ndu[r][j-1]/ndu[j][r];
185 ndu[r][j] = saved + right[r+1]*temp;
186 saved = left[j-r]*temp;
191 for (
int r = 0; r <= p; ++r)
198 d = ndu[rk][pk]/ndu[p][rk];
202 d -= ndu[r][pk]/ndu[p][r];
209 grad *= p*(knot(ip+1) - knot(ip));
213 grad *= p*(knot(ip) - knot(ip+1));
221 if (u == knot(NumOfControlPoints+Order))
223 mid = NumOfControlPoints;
228 high = NumOfControlPoints + 1;
229 mid = (low + high)/2;
230 while ( (u < knot(mid-1)) || (u > knot(mid)) )
240 mid = (low + high)/2;
251 " Can not compare knot vectors with different orders!");
254 int s = kv.
Size() - Size();
265 for (
int j = 0; j < kv.
Size(); j++)
267 if (knot(i) == kv[j])
287 ni = kv[0]->GetNCP();
288 nj = kv[1]->GetNCP();
291 data =
new double[ni*nj*Dim];
294 for (
int i = 0; i < ni*nj*Dim; i++)
300 else if (kv.Size() == 3)
302 ni = kv[0]->GetNCP();
303 nj = kv[1]->GetNCP();
304 nk = kv[2]->GetNCP();
306 data =
new double[ni*nj*nk*Dim];
309 for (
int i = 0; i < ni*nj*nk*Dim; i++)
317 mfem_error(
"NURBSPatch::init : Wrond dimension of knotvectors!");
323 int pdim,
dim, size = 1;
326 input >> ws >> ident >> pdim;
328 for (
int i = 0; i < pdim; i++)
331 size *= kv[i]->GetNCP();
334 input >> ws >> ident >>
dim;
337 input >> ws >> ident;
338 if (ident ==
"controlpoints" || ident ==
"controlpoints_homogeneous")
340 for (
int j = 0, i = 0; i < size; i++)
341 for (
int d = 0; d <=
dim; d++, j++)
348 for (
int j = 0, i = 0; i < size; i++)
350 for (
int d = 0; d <=
dim; d++)
354 for (
int d = 0; d <
dim; d++)
356 data[j+d] *= data[j+
dim];
383 kv.SetSize(kv_.
Size());
384 for (
int i = 0; i < kv.Size(); i++)
393 kv.SetSize(parent->
kv.Size());
394 for (
int i = 0; i < kv.Size(); i++)
413 for (
int i = 0; i < kv.Size(); i++)
415 if (kv[i]) {
delete kv[i]; }
439 for (
int i = 0; i < kv.Size(); i++)
441 if (kv[i]) {
delete kv[i]; }
449 out <<
"knotvectors\n" << kv.Size() <<
'\n';
450 for (
int i = 0; i < kv.Size(); i++)
453 size *= kv[i]->GetNCP();
456 out <<
"\ndimension\n" << Dim - 1
457 <<
"\n\ncontrolpoints\n";
458 for (
int j = 0, i = 0; i < size; i++)
461 for (
int d = 1; d < Dim; d++)
463 out <<
' ' << data[j++];
489 cerr <<
"NURBSPatch::SetLoopDirection :\n"
490 " Direction error in 2D patch, dir = " << dir <<
'\n';
519 cerr <<
"NURBSPatch::SetLoopDirection :\n"
520 " Direction error in 3D patch, dir = " << dir <<
'\n';
531 for (
int dir = 0; dir < kv.Size(); dir++)
533 kv[dir]->UniformRefinement(newknots);
534 KnotInsert(dir, newknots);
540 for (
int dir = 0; dir < kv.Size(); dir++)
542 KnotInsert(dir, *newkv[dir]);
548 if (dir >= kv.Size() || dir < 0)
550 mfem_error(
"NURBSPatch::KnotInsert : Incorrect direction!");
553 int t = newkv.
GetOrder() - kv[dir]->GetOrder();
557 DegreeElevate(dir, t);
561 mfem_error(
"NURBSPatch::KnotInsert : Incorrect order!");
565 GetKV(dir)->Difference(newkv, diff);
568 KnotInsert(dir, diff);
575 if (dir >= kv.Size() || dir < 0)
577 mfem_error(
"NURBSPatch::KnotInsert : Incorrect direction!");
589 if (size != newp.SetLoopDirection(dir))
591 mfem_error(
"NURBSPatch::KnotInsert : Size mismatch!");
594 int rr = knot.
Size() - 1;
600 for (
int j = 0; j <= a; j++)
604 for (
int j = b+pl; j <= ml+pl; j++)
606 newkv[j+rr+1] = oldkv[j];
608 for (
int k = 0; k <= (a-pl); k++)
610 for (
int ll = 0; ll < size; ll++)
612 newp(k,ll) = oldp(k,ll);
615 for (
int k = (b-1); k < ml; k++)
617 for (
int ll = 0; ll < size; ll++)
619 newp(k+rr+1,ll) = oldp(k,ll);
626 for (
int j = rr; j >= 0; j--)
628 while ( (knot(j) <= oldkv[i]) && (i > a) )
631 for (
int ll = 0; ll < size; ll++)
633 newp(k-pl-1,ll) = oldp(i-pl-1,ll);
640 for (
int ll = 0; ll < size; ll++)
642 newp(k-pl-1,ll) = newp(k-pl,ll);
645 for (
int l = 1; l <= pl; l++)
648 double alfa = newkv[k+l] - knot(j);
649 if (fabs(alfa) == 0.0)
651 for (
int ll = 0; ll < size; ll++)
653 newp(ind-1,ll) = newp(ind,ll);
658 alfa = alfa/(newkv[k+l] - oldkv[i-pl+l]);
659 for (
int ll = 0; ll < size; ll++)
661 newp(ind-1,ll) = alfa*newp(ind-1,ll) + (1.0-alfa)*newp(ind,ll);
677 for (
int dir = 0; dir < kv.Size(); dir++)
679 DegreeElevate(dir, t);
686 if (dir >= kv.Size() || dir < 0)
688 mfem_error(
"NURBSPatch::DegreeElevate : Incorrect direction!");
691 int i, j, k, kj, mpi, mul, mh, kind, cind, first, last;
692 int r, a, b, oldr, save, s, tr, lbz, rbz, l;
693 double inv, ua, ub, numer, alf, den, bet, gam;
704 if (size != newp.SetLoopDirection(dir))
706 mfem_error(
"NURBSPatch::DegreeElevate : Size mismatch!");
724 for (i = 0; i <= ph; i++)
726 binom(i,0) = binom(i,i) = 1;
727 for (j = 1; j < i; j++)
729 binom(i,j) = binom(i-1,j) + binom(i-1,j-1);
736 for (i = 1; i <= ph2; i++)
738 inv = 1.0/binom(ph,i);
740 for (j = max(0,i-t); j <= mpi; j++)
742 bezalfs(i,j) = inv*binom(p,j)*binom(t,i-j);
747 for (i = ph2+1; i < ph; i++)
750 for (j = max(0,i-t); j <= mpi; j++)
752 bezalfs(i,j) = bezalfs(ph-i,p-j);
763 for (l = 0; l < size; l++)
765 newp(0,l) = oldp(0,l);
767 for (i = 0; i <= ph; i++)
772 for (i = 0; i <= p; i++)
774 for (l = 0; l < size; l++)
776 bpts(i,l) = oldp(i,l);
783 while (b < m && oldkv[b] == oldkv[b+1]) { b++; }
791 if (oldr > 0) { lbz = (oldr+2)/2; }
794 if (r > 0) { rbz = ph-(r+1)/2; }
800 for (k = p ; k > mul; k--)
802 alphas[k-mul-1] = numer/(oldkv[a+k]-ua);
805 for (j = 1; j <= r; j++)
809 for (k = p; k >= s; k--)
811 for (l = 0; l < size; l++)
812 bpts(k,l) = (alphas[k-s]*bpts(k,l) +
813 (1.0-alphas[k-s])*bpts(k-1,l));
815 for (l = 0; l < size; l++)
817 nextbpts(save,l) = bpts(p,l);
822 for (i = lbz; i <= ph; i++)
824 for (l = 0; l < size; l++)
829 for (j = max(0,i-t); j <= mpi; j++)
831 for (l = 0; l < size; l++)
833 ebpts(i,l) += bezalfs(i,j)*bpts(j,l);
843 bet = (ub-newkv[kind-1])/den;
845 for (tr = 1; tr < oldr; tr++)
854 alf = (ub-newkv[i])/(ua-newkv[i]);
855 for (l = 0; l < size; l++)
857 newp(i,l) = alf*newp(i,l)-(1.0-alf)*newp(i-1,l);
862 if ((j-tr) <= (kind-ph+oldr))
864 gam = (ub-newkv[j-tr])/den;
865 for (l = 0; l < size; l++)
867 ebpts(kj,l) = gam*ebpts(kj,l) + (1.0-gam)*ebpts(kj+1,l);
872 for (l = 0; l < size; l++)
874 ebpts(kj,l) = bet*ebpts(kj,l) + (1.0-bet)*ebpts(kj+1,l);
889 for (i = 0; i < (ph-oldr); i++)
895 for (j = lbz; j <= rbz; j++)
897 for (l = 0; l < size; l++)
899 newp(cind,l) = ebpts(j,l);
906 for (j = 0; j <r; j++)
907 for (l = 0; l < size; l++)
909 bpts(j,l) = nextbpts(j,l);
912 for (j = r; j <= p; j++)
913 for (l = 0; l < size; l++)
915 bpts(j,l) = oldp(b-p+j,l);
924 for (i = 0; i <= ph; i++)
937 int size = SetLoopDirection(dir);
939 for (
int id = 0;
id < nd/2;
id++)
940 for (
int i = 0; i < size; i++)
942 Swap<double>((*this)(id,i), (*
this)(nd-1-id,i));
949 if (abs(dir1-dir2) == 2)
951 " directions 0 and 2 are not supported!");
956 Swap<KnotVector *>(nkv[dir1], nkv[dir2]);
959 int size = SetLoopDirection(dir1);
960 newpatch->SetLoopDirection(dir2);
962 for (
int id = 0;
id < nd;
id++)
963 for (
int i = 0; i < size; i++)
965 (*newpatch)(id,i) = (*
this)(id,i);
975 double l2 = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];
978 if (fabs(angle) == M_PI_2)
980 s = r*copysign(1., angle);
984 else if (fabs(angle) == M_PI)
999 T(0,0) = (n[0]*n[0] + (n[1]*n[1] + n[2]*n[2])*c)/l2;
1000 T(0,1) = -(n[0]*n[1]*c1)/l2 - (n[2]*s)/l;
1001 T(0,2) = -(n[0]*n[2]*c1)/l2 + (n[1]*s)/l;
1002 T(1,0) = -(n[0]*n[1]*c1)/l2 + (n[2]*s)/l;
1003 T(1,1) = (n[1]*n[1] + (n[0]*n[0] + n[2]*n[2])*c)/l2;
1004 T(1,2) = -(n[1]*n[2]*c1)/l2 - (n[0]*s)/l;
1005 T(2,0) = -(n[0]*n[2]*c1)/l2 - (n[1]*s)/l;
1006 T(2,1) = -(n[1]*n[2]*c1)/l2 + (n[0]*s)/l;
1007 T(2,2) = (n[2]*n[2] + (n[0]*n[0] + n[1]*n[1])*c)/l2;
1014 mfem_error(
"NURBSPatch::Rotate3D : not a NURBSPatch in 3D!");
1020 Get3DRotationMatrix(n, angle, 1., T);
1023 for (
int i = 0; i < kv.Size(); i++)
1025 size *= kv[i]->GetNCP();
1028 for (
int i = 0; i < size; i++)
1040 for (
int dir = 0; dir < kv.Size(); dir++)
1041 if (maxd < kv[dir]->GetOrder())
1043 maxd = kv[dir]->GetOrder();
1046 for (
int dir = 0; dir < kv.Size(); dir++)
1047 if (maxd > kv[dir]->GetOrder())
1049 DegreeElevate(dir, maxd - kv[dir]->GetOrder());
1057 if (p1.
kv.Size() != p2.
kv.Size() || p1.
Dim != p2.
Dim)
1059 mfem_error(
"Interpolate(NURBSPatch &, NURBSPatch &)");
1062 int size = 1,
dim = p1.
Dim;
1065 for (
int i = 0; i < p1.
kv.Size(); i++)
1067 if (p1.
kv[i]->GetOrder() < p2.
kv[i]->GetOrder())
1078 size *= kv[i]->GetNCP();
1083 nkv[0] = nkv[1] = 0.0;
1084 nkv[2] = nkv[3] = 1.0;
1090 for (
int i = 0; i < size; i++)
1092 for (
int d = 0; d <
dim; d++)
1094 patch->
data[i*dim+d] = p1.
data[i*dim+d];
1095 patch->
data[(i+size)*dim+d] = p2.
data[i*dim+d];
1106 mfem_error(
"Revolve3D(NURBSPatch &, double [], double)");
1112 for (
int i = 0; i < patch.
kv.Size(); i++)
1114 nkv[i] = patch.
kv[i];
1115 size *= nkv[i]->GetNCP();
1120 lkv[0] = lkv[1] = lkv[2] = 0.0;
1121 for (
int i = 1; i < times; i++)
1123 lkv[2*i+1] = lkv[2*i+2] = i;
1125 lkv[ns] = lkv[ns+1] = lkv[ns+2] = times;
1131 Vector u(NULL, 3), v(NULL, 3);
1134 double c = cos(ang/2);
1138 double *op = patch.
data, *np;
1139 for (
int i = 0; i < size; i++)
1141 np = newpatch->
data + 4*i;
1142 for (
int j = 0; j < 4; j++)
1146 for (
int j = 0; j < times; j++)
1166 patchTopo =
new Mesh;
1177 input >> ws >> ident;
1178 if (ident ==
"knotvectors")
1180 input >> NumOfKnotVectors;
1181 knotVectors.SetSize(NumOfKnotVectors);
1182 for (
int i = 0; i < NumOfKnotVectors; i++)
1185 if (knotVectors[i]->GetOrder() != knotVectors[0]->GetOrder())
1186 mfem_error(
"NURBSExtension::NURBSExtension :\n"
1187 " Variable orders are not supported!");
1189 Order = knotVectors[0]->GetOrder();
1191 else if (ident ==
"patches")
1193 patches.SetSize(GetNP());
1194 for (
int p = 0; p < patches.Size(); p++)
1200 NumOfKnotVectors = 0;
1201 for (
int i = 0; i < patchTopo->GetNEdges(); i++)
1202 if (NumOfKnotVectors < KnotInd(i))
1204 NumOfKnotVectors = KnotInd(i);
1207 knotVectors.SetSize(NumOfKnotVectors);
1211 for (
int p = 0; p < patches.Size(); p++)
1213 patchTopo->GetElementEdges(p, edges, oedge);
1214 if (Dimension() == 2)
1216 if (knotVectors[KnotInd(edges[0])] == NULL)
1217 knotVectors[KnotInd(edges[0])] =
1219 if (knotVectors[KnotInd(edges[1])] == NULL)
1220 knotVectors[KnotInd(edges[1])] =
1225 if (knotVectors[KnotInd(edges[0])] == NULL)
1226 knotVectors[KnotInd(edges[0])] =
1228 if (knotVectors[KnotInd(edges[3])] == NULL)
1229 knotVectors[KnotInd(edges[3])] =
1231 if (knotVectors[KnotInd(edges[8])] == NULL)
1232 knotVectors[KnotInd(edges[8])] =
1236 Order = knotVectors[0]->GetOrder();
1247 if (patches.Size() == 0)
1249 input >> ws >> ident;
1251 if (patches.Size() == 0 && ident ==
"mesh_elements")
1253 input >> NumOfActiveElems;
1254 activeElem.SetSize(GetGNE());
1257 for (
int i = 0; i < NumOfActiveElems; i++)
1260 activeElem[glob_elem] =
true;
1264 input >> ws >> ident;
1268 NumOfActiveElems = NumOfElements;
1269 activeElem.SetSize(NumOfElements);
1273 GenerateActiveVertices();
1274 GenerateElementDofTable();
1275 GenerateActiveBdrElems();
1276 GenerateBdrElementDofTable();
1278 if (patches.Size() == 0)
1281 if (ident ==
"weights")
1283 weights.Load(input, GetNDof());
1287 weights.SetSize(GetNDof());
1302 NumOfKnotVectors = parent->
GetNKV();
1303 knotVectors.SetSize(NumOfKnotVectors);
1304 for (
int i = 0; i < NumOfKnotVectors; i++)
1323 GenerateElementDofTable();
1324 GenerateBdrElementDofTable();
1326 weights.SetSize(GetNDof());
1335 mfem_error(
"NURBSExtension::NURBSExtension :\n"
1336 " parent does not own the patch topology!");
1345 NumOfKnotVectors = parent->
GetNKV();
1346 knotVectors.SetSize(NumOfKnotVectors);
1347 for (
int i = 0; i < NumOfKnotVectors; i++)
1357 NumOfActiveElems = NumOfElements;
1358 activeElem.SetSize(NumOfElements);
1361 GenerateActiveVertices();
1362 GenerateElementDofTable();
1363 GenerateActiveBdrElems();
1364 GenerateBdrElementDofTable();
1366 weights.SetSize(GetNDof());
1367 MergeWeights(mesh_array, num_pieces);
1372 if (patches.Size() == 0)
1378 for (
int i = 0; i < knotVectors.Size(); i++)
1380 delete knotVectors[i];
1383 for (
int i = 0; i < patches.Size(); i++)
1396 patchTopo->PrintTopo(out, edge_to_knot);
1397 if (patches.Size() == 0)
1399 out <<
"\nknotvectors\n" << NumOfKnotVectors <<
'\n';
1400 for (
int i = 0; i < NumOfKnotVectors; i++)
1402 knotVectors[i]->Print(out);
1405 if (NumOfActiveElems < NumOfElements)
1407 out <<
"\nmesh_elements\n" << NumOfActiveElems <<
'\n';
1408 for (
int i = 0; i < NumOfElements; i++)
1415 out <<
"\nweights\n";
1416 weights.Print(out, 1);
1420 out <<
"\npatches\n";
1421 for (
int p = 0; p < patches.Size(); p++)
1423 out <<
"\n# patch " << p <<
"\n\n";
1424 patches[p]->Print(out);
1432 "NURBS Mesh entity sizes:\n"
1433 "Dimension = " << Dimension() <<
"\n"
1434 "Order = " << GetOrder() <<
"\n"
1435 "NumOfKnotVectors = " << GetNKV() <<
"\n"
1436 "NumOfPatches = " << GetNP() <<
"\n"
1437 "NumOfBdrPatches = " << GetNBP() <<
"\n"
1438 "NumOfVertices = " << GetGNV() <<
"\n"
1439 "NumOfElements = " << GetGNE() <<
"\n"
1440 "NumOfBdrElements = " << GetGNBE() <<
"\n"
1441 "NumOfDofs = " << GetNTotalDof() <<
"\n"
1442 "NumOfActiveVertices = " << GetNV() <<
"\n"
1443 "NumOfActiveElems = " << GetNE() <<
"\n"
1444 "NumOfActiveBdrElems = " << GetNBE() <<
"\n"
1445 "NumOfActiveDofs = " << GetNDof() <<
'\n';
1446 for (
int i = 0; i < NumOfKnotVectors; i++)
1448 out <<
' ' << i + 1 <<
") ";
1449 knotVectors[i]->Print(out);
1456 int vert[8], nv, g_el, nx, ny, nz,
dim = Dimension();
1462 activeVert.SetSize(GetGNV());
1464 for (
int p = 0; p < GetNP(); p++)
1470 nz = (dim == 3) ? p2g.
nz() : 1;
1472 for (
int k = 0; k < nz; k++)
1474 for (
int j = 0; j < ny; j++)
1476 for (
int i = 0; i < nx; i++)
1478 if (activeElem[g_el])
1482 vert[0] = p2g(i, j );
1483 vert[1] = p2g(i+1,j );
1484 vert[2] = p2g(i+1,j+1);
1485 vert[3] = p2g(i, j+1);
1490 vert[0] = p2g(i, j, k);
1491 vert[1] = p2g(i+1,j, k);
1492 vert[2] = p2g(i+1,j+1,k);
1493 vert[3] = p2g(i, j+1,k);
1495 vert[4] = p2g(i, j, k+1);
1496 vert[5] = p2g(i+1,j, k+1);
1497 vert[6] = p2g(i+1,j+1,k+1);
1498 vert[7] = p2g(i, j+1,k+1);
1502 for (
int v = 0; v < nv; v++)
1504 activeVert[vert[v]] = 1;
1513 NumOfActiveVertices = 0;
1514 for (
int i = 0; i < GetGNV(); i++)
1515 if (activeVert[i] == 1)
1517 activeVert[i] = NumOfActiveVertices++;
1523 int dim = Dimension();
1526 activeBdrElem.SetSize(GetGNBE());
1527 if (GetGNE() == GetNE())
1529 activeBdrElem =
true;
1530 NumOfActiveBdrElems = GetGNBE();
1533 activeBdrElem =
false;
1534 NumOfActiveBdrElems = 0;
1547 for (
int i = 0; i < num_pieces; i++)
1553 for (
int lel = 0; lel < lext->
GetNE(); lel++)
1555 int gel = lelem_elem[lel];
1557 int nd = el_dof->RowSize(gel);
1558 int *gdofs = el_dof->GetRow(gel);
1560 for (
int j = 0; j < nd; j++)
1562 weights(gdofs[j]) = lext->
weights(ldofs[j]);
1575 for (
int i = 0; i < num_pieces; i++)
1582 for (
int lel = 0; lel < lext->
GetNE(); lel++)
1598 for (
int p = 0; p < GetNP(); p++)
1600 patchTopo->GetElementEdges(p, edges, oedge);
1602 for (
int i = 0; i < edges.
Size(); i++)
1604 edges[i] = edge_to_knot[edges[i]];
1607 edges[i] = -1 - edges[i];
1611 if ((Dimension() == 2 &&
1612 (edges[0] != -1 - edges[2] || edges[1] != -1 - edges[3])) ||
1614 (Dimension() == 3 &&
1615 (edges[0] != edges[2] || edges[0] != edges[4] ||
1616 edges[0] != edges[6] || edges[1] != edges[3] ||
1617 edges[1] != edges[5] || edges[1] != edges[7] ||
1618 edges[8] != edges[9] || edges[8] != edges[10] ||
1619 edges[8] != edges[11])))
1621 cerr <<
"NURBSExtension::CheckPatch (patch = " << p
1622 <<
")\n Inconsistent edge-to-knot mapping!\n";
1626 if ((Dimension() == 2 &&
1627 (edges[0] < 0 || edges[1] < 0)) ||
1629 (Dimension() == 3 &&
1630 (edges[0] < 0 || edges[3] < 0 || edges[8] < 0)))
1632 cerr <<
"NURBSExtension::CheckPatch (patch = " << p
1633 <<
") : Bad orientation!\n";
1644 for (
int p = 0; p < GetNBP(); p++)
1646 patchTopo->GetBdrElementEdges(p, edges, oedge);
1648 for (
int i = 0; i < edges.
Size(); i++)
1650 edges[i] = edge_to_knot[edges[i]];
1653 edges[i] = -1 - edges[i];
1657 if ((Dimension() == 2 && (edges[0] < 0)) ||
1658 (Dimension() == 3 && (edges[0] < 0 || edges[1] < 0)))
1660 cerr <<
"NURBSExtension::CheckBdrPatch (boundary patch = "
1661 << p <<
") : Bad orientation!\n";
1673 patchTopo->GetElementEdges(p, edges, orient);
1675 if (Dimension() == 2)
1677 kv[0] = KnotVec(edges[0]);
1678 kv[1] = KnotVec(edges[1]);
1682 kv[0] = KnotVec(edges[0]);
1683 kv[1] = KnotVec(edges[3]);
1684 kv[2] = KnotVec(edges[8]);
1694 patchTopo->GetBdrElementEdges(p, edges, orient);
1696 if (Dimension() == 2)
1698 kv[0] = KnotVec(edges[0]);
1702 kv[0] = KnotVec(edges[0]);
1703 kv[1] = KnotVec(edges[1]);
1709 int nv = patchTopo->GetNV();
1710 int ne = patchTopo->GetNEdges();
1711 int nf = patchTopo->GetNFaces();
1712 int np = patchTopo->GetNE();
1713 int meshCounter, spaceCounter,
dim = Dimension();
1719 e_meshOffsets.SetSize(ne);
1720 f_meshOffsets.SetSize(nf);
1721 p_meshOffsets.SetSize(np);
1723 v_spaceOffsets.SetSize(nv);
1724 e_spaceOffsets.SetSize(ne);
1725 f_spaceOffsets.SetSize(nf);
1726 p_spaceOffsets.SetSize(np);
1729 for (meshCounter = 0; meshCounter < nv; meshCounter++)
1731 v_meshOffsets[meshCounter] = meshCounter;
1732 v_spaceOffsets[meshCounter] = meshCounter;
1734 spaceCounter = meshCounter;
1737 for (
int e = 0; e < ne; e++)
1739 e_meshOffsets[e] = meshCounter;
1740 e_spaceOffsets[e] = spaceCounter;
1741 meshCounter += KnotVec(e)->GetNE() - 1;
1742 spaceCounter += KnotVec(e)->GetNCP() - 2;
1746 for (
int f = 0; f < nf; f++)
1748 f_meshOffsets[f] = meshCounter;
1749 f_spaceOffsets[f] = spaceCounter;
1751 patchTopo->GetFaceEdges(f, edges, orient);
1754 (KnotVec(edges[0])->GetNE() - 1) *
1755 (KnotVec(edges[1])->GetNE() - 1);
1757 (KnotVec(edges[0])->GetNCP() - 2) *
1758 (KnotVec(edges[1])->GetNCP() - 2);
1762 for (
int p = 0; p < np; p++)
1764 p_meshOffsets[p] = meshCounter;
1765 p_spaceOffsets[p] = spaceCounter;
1767 patchTopo->GetElementEdges(p, edges, orient);
1772 (KnotVec(edges[0])->GetNE() - 1) *
1773 (KnotVec(edges[1])->GetNE() - 1);
1775 (KnotVec(edges[0])->GetNCP() - 2) *
1776 (KnotVec(edges[1])->GetNCP() - 2);
1781 (KnotVec(edges[0])->GetNE() - 1) *
1782 (KnotVec(edges[3])->GetNE() - 1) *
1783 (KnotVec(edges[8])->GetNE() - 1);
1785 (KnotVec(edges[0])->GetNCP() - 2) *
1786 (KnotVec(edges[3])->GetNCP() - 2) *
1787 (KnotVec(edges[8])->GetNCP() - 2);
1790 NumOfVertices = meshCounter;
1791 NumOfDofs = spaceCounter;
1796 int dim = Dimension();
1800 for (
int p = 0; p < GetNP(); p++)
1802 GetPatchKnotVectors(p, kv);
1804 int ne = kv[0]->GetNE();
1805 for (
int d = 1; d <
dim; d++)
1807 ne *= kv[d]->GetNE();
1810 NumOfElements += ne;
1816 int dim = Dimension() - 1;
1819 NumOfBdrElements = 0;
1820 for (
int p = 0; p < GetNBP(); p++)
1822 GetBdrPatchKnotVectors(p, kv);
1824 int ne = kv[0]->GetNE();
1825 for (
int d = 1; d <
dim; d++)
1827 ne *= kv[d]->GetNE();
1830 NumOfBdrElements += ne;
1838 if (Dimension() == 2)
1840 Get2DElementTopo(elements);
1844 Get3DElementTopo(elements);
1856 for (
int p = 0; p < GetNP(); p++)
1862 int patch_attr = patchTopo->GetAttribute(p);
1864 for (
int j = 0; j < ny; j++)
1866 for (
int i = 0; i < nx; i++)
1870 ind[0] = activeVert[p2g(i, j )];
1871 ind[1] = activeVert[p2g(i+1,j )];
1872 ind[2] = activeVert[p2g(i+1,j+1)];
1873 ind[3] = activeVert[p2g(i, j+1)];
1892 for (
int p = 0; p < GetNP(); p++)
1899 int patch_attr = patchTopo->GetAttribute(p);
1901 for (
int k = 0; k < nz; k++)
1903 for (
int j = 0; j < ny; j++)
1905 for (
int i = 0; i < nx; i++)
1909 ind[0] = activeVert[p2g(i, j, k)];
1910 ind[1] = activeVert[p2g(i+1,j, k)];
1911 ind[2] = activeVert[p2g(i+1,j+1,k)];
1912 ind[3] = activeVert[p2g(i, j+1,k)];
1914 ind[4] = activeVert[p2g(i, j, k+1)];
1915 ind[5] = activeVert[p2g(i+1,j, k+1)];
1916 ind[6] = activeVert[p2g(i+1,j+1,k+1)];
1917 ind[7] = activeVert[p2g(i, j+1,k+1)];
1919 elements[el] =
new Hexahedron(ind, patch_attr);
1933 if (Dimension() == 2)
1935 Get2DBdrElementTopo(boundary);
1939 Get3DBdrElementTopo(boundary);
1951 for (
int b = 0; b < GetNBP(); b++)
1956 int bdr_patch_attr = patchTopo->GetBdrAttribute(b);
1958 for (
int i = 0; i < nx; i++)
1960 if (activeBdrElem[g_be])
1962 int _i = (okv[0] >= 0) ? i : (nx - 1 - i);
1963 ind[0] = activeVert[p2g[_i ]];
1964 ind[1] = activeVert[p2g[_i+1]];
1966 boundary[l_be] =
new Segment(ind, bdr_patch_attr);
1982 for (
int b = 0; b < GetNBP(); b++)
1988 int bdr_patch_attr = patchTopo->GetBdrAttribute(b);
1990 for (
int j = 0; j < ny; j++)
1992 int _j = (okv[1] >= 0) ? j : (ny - 1 - j);
1993 for (
int i = 0; i < nx; i++)
1995 if (activeBdrElem[g_be])
1997 int _i = (okv[0] >= 0) ? i : (nx - 1 - i);
1998 ind[0] = activeVert[p2g(_i, _j )];
1999 ind[1] = activeVert[p2g(_i+1,_j )];
2000 ind[2] = activeVert[p2g(_i+1,_j+1)];
2001 ind[3] = activeVert[p2g(_i, _j+1)];
2014 activeDof.SetSize(GetNTotalDof());
2017 if (Dimension() == 2)
2019 Generate2DElementDofTable();
2023 Generate3DElementDofTable();
2026 NumOfActiveDofs = 0;
2027 for (
int d = 0; d < GetNTotalDof(); d++)
2031 activeDof[d] = NumOfActiveDofs;
2034 int *dof = el_dof->GetJ();
2035 int ndof = el_dof->Size_of_connections();
2036 for (
int i = 0; i < ndof; i++)
2038 dof[i] = activeDof[dof[i]] - 1;
2049 el_dof =
new Table(NumOfActiveElems, (Order + 1)*(Order + 1));
2050 el_to_patch.SetSize(NumOfActiveElems);
2051 el_to_IJK.SetSize(NumOfActiveElems, 2);
2053 for (
int p = 0; p < GetNP(); p++)
2058 for (
int j = 0; j < kv[1]->
GetNKS(); j++)
2060 if (kv[1]->isElement(j))
2062 for (
int i = 0; i < kv[0]->
GetNKS(); i++)
2064 if (kv[0]->isElement(i))
2068 int *dofs = el_dof->GetRow(el);
2070 for (
int jj = 0; jj <= Order; jj++)
2072 for (
int ii = 0; ii <= Order; ii++)
2074 dofs[idx] = p2g(i+ii,j+jj);
2075 activeDof[dofs[idx]] = 1;
2079 el_to_patch[el] = p;
2080 el_to_IJK(el,0) = i;
2081 el_to_IJK(el,1) = j;
2101 el_dof =
new Table(NumOfActiveElems, (Order + 1)*(Order + 1)*(Order + 1));
2102 el_to_patch.SetSize(NumOfActiveElems);
2103 el_to_IJK.SetSize(NumOfActiveElems, 3);
2105 for (
int p = 0; p < GetNP(); p++)
2110 for (
int k = 0; k < kv[2]->
GetNKS(); k++)
2112 if (kv[2]->isElement(k))
2114 for (
int j = 0; j < kv[1]->
GetNKS(); j++)
2116 if (kv[1]->isElement(j))
2118 for (
int i = 0; i < kv[0]->
GetNKS(); i++)
2120 if (kv[0]->isElement(i))
2125 int *dofs = el_dof->GetRow(el);
2126 for (
int kk = 0; kk <= Order; kk++)
2128 for (
int jj = 0; jj <= Order; jj++)
2130 for (
int ii = 0; ii <= Order; ii++)
2132 dofs[idx] = p2g(i+ii,j+jj,k+kk);
2133 activeDof[dofs[idx]] = 1;
2139 el_to_patch[el] = p;
2140 el_to_IJK(el,0) = i;
2141 el_to_IJK(el,1) = j;
2142 el_to_IJK(el,2) = k;
2158 if (Dimension() == 2)
2160 Generate2DBdrElementDofTable();
2164 Generate3DBdrElementDofTable();
2167 int *dof = bel_dof->GetJ();
2168 int ndof = bel_dof->Size_of_connections();
2169 for (
int i = 0; i < ndof; i++)
2171 dof[i] = activeDof[dof[i]] - 1;
2178 int lbe = 0, okv[1];
2182 bel_dof =
new Table(NumOfActiveBdrElems, Order + 1);
2183 bel_to_patch.SetSize(NumOfActiveBdrElems);
2184 bel_to_IJK.SetSize(NumOfActiveBdrElems, 1);
2186 for (
int b = 0; b < GetNBP(); b++)
2192 int nks0 = kv[0]->
GetNKS();
2193 for (
int i = 0; i < nks0; i++)
2195 if (kv[0]->isElement(i))
2197 if (activeBdrElem[gbe])
2199 int *dofs = bel_dof->GetRow(lbe);
2201 for (
int ii = 0; ii <= Order; ii++)
2203 dofs[idx] = p2g[(okv[0] >= 0) ? (i+ii) : (nx-i-ii)];
2206 bel_to_patch[lbe] = b;
2207 bel_to_IJK(lbe,0) = (okv[0] >= 0) ? i : (-1-i);
2219 int lbe = 0, okv[2];
2223 bel_dof =
new Table(NumOfActiveBdrElems, (Order + 1)*(Order + 1));
2224 bel_to_patch.SetSize(NumOfActiveBdrElems);
2225 bel_to_IJK.SetSize(NumOfActiveBdrElems, 2);
2227 for (
int b = 0; b < GetNBP(); b++)
2234 int nks0 = kv[0]->
GetNKS();
2235 int nks1 = kv[1]->
GetNKS();
2236 for (
int j = 0; j < nks1; j++)
2238 if (kv[1]->isElement(j))
2240 for (
int i = 0; i < nks0; i++)
2242 if (kv[0]->isElement(i))
2244 if (activeBdrElem[gbe])
2246 int *dofs = bel_dof->GetRow(lbe);
2248 for (
int jj = 0; jj <= Order; jj++)
2250 int _jj = (okv[1] >= 0) ? (j+jj) : (ny-j-jj);
2251 for (
int ii = 0; ii <= Order; ii++)
2253 int _ii = (okv[0] >= 0) ? (i+ii) : (nx-i-ii);
2254 dofs[idx] = p2g(_ii,_jj);
2258 bel_to_patch[lbe] = b;
2259 bel_to_IJK(lbe,0) = (okv[0] >= 0) ? i : (-1-i);
2260 bel_to_IJK(lbe,1) = (okv[1] >= 0) ? j : (-1-j);
2274 for (
int gv = 0; gv < GetGNV(); gv++)
2275 if (activeVert[gv] >= 0)
2277 lvert_vert[activeVert[gv]] = gv;
2284 for (
int le = 0, ge = 0; ge < GetGNE(); ge++)
2287 lelem_elem[le++] = ge;
2299 NURBSFE->
SetIJK(el_to_IJK.GetRow(i));
2300 if (el_to_patch[i] != NURBSFE->
GetPatch())
2302 GetPatchKnotVectors(el_to_patch[i], NURBSFE->
KnotVectors());
2305 el_dof->GetRow(i, dofs);
2306 weights.GetSubVector(dofs, NURBSFE->
Weights());
2319 NURBSFE->
SetIJK(bel_to_IJK.GetRow(i));
2320 if (bel_to_patch[i] != NURBSFE->
GetPatch())
2322 GetBdrPatchKnotVectors(bel_to_patch[i], NURBSFE->
KnotVectors());
2323 NURBSFE->
SetPatch(bel_to_patch[i]);
2325 bel_dof->GetRow(i, dofs);
2326 weights.GetSubVector(dofs, NURBSFE->
Weights());
2336 if (patches.Size() == 0)
2338 GetPatchNets(Nodes);
2344 if (patches.Size() == 0) {
return; }
2346 SetSolutionVector(Nodes);
2352 if (patches.Size() == 0)
2353 mfem_error(
"NURBSExtension::SetKnotsFromPatches :"
2354 " No patches available!");
2358 for (
int p = 0; p < patches.Size(); p++)
2360 GetPatchKnotVectors(p, kv);
2362 for (
int i = 0; i < kv.
Size(); i++)
2364 *kv[i] = *patches[p]->GetKV(i);
2368 Order = knotVectors[0]->GetOrder();
2369 for (
int i = 0; i < NumOfKnotVectors; i++)
2371 if (Order != knotVectors[i]->GetOrder())
2373 " Variable orders are not supported!");
2381 NumOfActiveElems = NumOfElements;
2382 activeElem.SetSize(NumOfElements);
2385 GenerateActiveVertices();
2386 GenerateElementDofTable();
2387 GenerateActiveBdrElems();
2388 GenerateBdrElementDofTable();
2393 for (
int p = 0; p < patches.Size(); p++)
2395 patches[p]->DegreeElevate(t);
2401 for (
int p = 0; p < patches.Size(); p++)
2403 patches[p]->UniformRefinement();
2414 for (
int p = 0; p < patches.Size(); p++)
2416 patchTopo->GetElementEdges(p, edges, orient);
2420 pkv[0] = kv[KnotInd(edges[0])];
2421 pkv[1] = kv[KnotInd(edges[1])];
2425 pkv[0] = kv[KnotInd(edges[0])];
2426 pkv[1] = kv[KnotInd(edges[3])];
2427 pkv[2] = kv[KnotInd(edges[8])];
2430 patches[p]->KnotInsert(pkv);
2436 if (Dimension() == 2)
2438 Get2DPatchNets(coords);
2442 Get3DPatchNets(coords);
2451 patches.SetSize(GetNP());
2452 for (
int p = 0; p < GetNP(); p++)
2458 for (
int j = 0; j < kv[1]->GetNCP(); j++)
2460 for (
int i = 0; i < kv[0]->GetNCP(); i++)
2463 for (
int d = 0; d < 2; d++)
2465 Patch(i,j,d) = coords(l*2 + d)*weights(l);
2467 Patch(i,j,2) = weights(l);
2478 patches.SetSize(GetNP());
2479 for (
int p = 0; p < GetNP(); p++)
2485 for (
int k = 0; k < kv[2]->GetNCP(); k++)
2487 for (
int j = 0; j < kv[1]->GetNCP(); j++)
2489 for (
int i = 0; i < kv[0]->GetNCP(); i++)
2492 for (
int d = 0; d < 3; d++)
2494 Patch(i,j,k,d) = coords(l*3 + d)*weights(l);
2496 Patch(i,j,k,3) = weights(l);
2505 if (Dimension() == 2)
2507 Set2DSolutionVector(coords);
2511 Set3DSolutionVector(coords);
2520 weights.SetSize(GetNDof());
2521 for (
int p = 0; p < GetNP(); p++)
2526 for (
int j = 0; j < kv[1]->GetNCP(); j++)
2528 for (
int i = 0; i < kv[0]->GetNCP(); i++)
2531 for (
int d = 0; d < 2; d++)
2533 coords(l*2 + d) = Patch(i,j,d)/Patch(i,j,2);
2535 weights(l) = Patch(i,j,2);
2547 weights.SetSize(GetNDof());
2548 for (
int p = 0; p < GetNP(); p++)
2553 for (
int k = 0; k < kv[2]->GetNCP(); k++)
2555 for (
int j = 0; j < kv[1]->GetNCP(); j++)
2557 for (
int i = 0; i < kv[0]->GetNCP(); i++)
2560 for (
int d = 0; d < 3; d++)
2562 coords(l*3 + d) = Patch(i,j,k,d)/Patch(i,j,k,3);
2564 weights(l) = Patch(i,j,k,3);
2581 mfem_error(
"ParNURBSExtension::ParNURBSExtension :\n"
2582 " all elements in the parent must be active!");
2587 mfem_error(
"ParNURBSExtension::ParNURBSExtension :\n"
2588 " parent does not own the patch topology!");
2608 partitioning =
new int[
GetGNE()];
2609 for (
int i = 0; i <
GetGNE(); i++)
2611 partitioning[i] = part[i];
2613 SetActive(partitioning, active_bel);
2621 BuildGroups(partitioning, *serial_elem_dof);
2625 for (
int gel = 0, lel = 0; gel <
GetGNE(); gel++)
2631 int *gdofs = serial_elem_dof->
GetRow(gel);
2632 for (
int i = 0; i < ndofs; i++)
2643 : gtopo(par_parent->gtopo.GetComm())
2695 partitioning = NULL;
2698 if (par_parent->partitioning == NULL)
2699 mfem_error(
"ParNURBSExtension::ParNURBSExtension :\n"
2700 " parent ParNURBSExtension has no partitioning!");
2703 Table *serial_elem_dof = GetGlobalElementDofTable();
2704 BuildGroups(par_parent->partitioning, *serial_elem_dof);
2705 delete serial_elem_dof;
2708 Table *ParNURBSExtension::GetGlobalElementDofTable()
2712 return Get2DGlobalElementDofTable();
2716 return Get3DGlobalElementDofTable();
2720 Table *ParNURBSExtension::Get2DGlobalElementDofTable()
2728 for (
int p = 0; p <
GetNP(); p++)
2730 p2g.SetPatchDofMap(p, kv);
2733 for (
int j = 0; j < kv[1]->GetNKS(); j++)
2735 if (kv[1]->isElement(j))
2737 for (
int i = 0; i < kv[0]->GetNKS(); i++)
2739 if (kv[0]->isElement(i))
2741 int *dofs = gel_dof->GetRow(el);
2743 for (
int jj = 0; jj <=
Order; jj++)
2745 for (
int ii = 0; ii <=
Order; ii++)
2747 dofs[idx] = p2g(i+ii,j+jj);
2760 Table *ParNURBSExtension::Get3DGlobalElementDofTable()
2768 for (
int p = 0; p <
GetNP(); p++)
2770 p2g.SetPatchDofMap(p, kv);
2773 for (
int k = 0; k < kv[2]->GetNKS(); k++)
2775 if (kv[2]->isElement(k))
2777 for (
int j = 0; j < kv[1]->GetNKS(); j++)
2779 if (kv[1]->isElement(j))
2781 for (
int i = 0; i < kv[0]->GetNKS(); i++)
2783 if (kv[0]->isElement(i))
2785 int *dofs = gel_dof->GetRow(el);
2787 for (
int kk = 0; kk <=
Order; kk++)
2789 for (
int jj = 0; jj <=
Order; jj++)
2791 for (
int ii = 0; ii <=
Order; ii++)
2793 dofs[idx] = p2g(i+ii,j+jj,k+kk);
2809 void ParNURBSExtension::SetActive(
int *_partitioning,
2810 const Array<bool> &active_bel)
2816 for (
int i = 0; i <
GetGNE(); i++)
2817 if (_partitioning[i] == MyRank)
2825 for (
int i = 0; i <
GetGNBE(); i++)
2832 void ParNURBSExtension::BuildGroups(
int *_partitioning,
const Table &elem_dof)
2836 ListOfIntegerSets groups;
2841 for (
int i = 0; i < dof_proc.Size_of_connections(); i++)
2843 dof_proc.GetJ()[i] = _partitioning[dof_proc.GetJ()[i]];
2848 group.Recreate(1, &MyRank);
2849 groups.Insert(group);
2856 group.Recreate(dof_proc.RowSize(d), dof_proc.GetRow(d));
2867 void NURBSPatchMap::GetPatchKnotVectors(
int p, KnotVector *kv[])
2873 kv[0] = Ext->
KnotVec(edges[0]);
2874 kv[1] = Ext->
KnotVec(edges[1]);
2880 kv[0] = Ext->
KnotVec(edges[0]);
2881 kv[1] = Ext->
KnotVec(edges[3]);
2882 kv[2] = Ext->
KnotVec(edges[8]);
2887 void NURBSPatchMap::GetBdrPatchKnotVectors(
int p, KnotVector *kv[],
int *okv)
2891 kv[0] = Ext->
KnotVec(edges[0], oedge[0], &okv[0]);
2896 kv[1] = Ext->
KnotVec(edges[1], oedge[1], &okv[1]);
2906 GetPatchKnotVectors(p, kv);
2908 I = kv[0]->
GetNE() - 1;
2909 J = kv[1]->
GetNE() - 1;
2911 for (
int i = 0; i < verts.
Size(); i++)
2916 for (
int i = 0; i < edges.
Size(); i++)
2923 K = kv[2]->
GetNE() - 1;
2925 for (
int i = 0; i < faces.
Size(); i++)
2936 GetPatchKnotVectors(p, kv);
2941 for (
int i = 0; i < verts.
Size(); i++)
2946 for (
int i = 0; i < edges.
Size(); i++)
2955 for (
int i = 0; i < faces.
Size(); i++)
2966 GetBdrPatchKnotVectors(p, kv, okv);
2968 I = kv[0]->
GetNE() - 1;
2970 for (
int i = 0; i < verts.
Size(); i++)
2981 J = kv[1]->
GetNE() - 1;
2983 for (
int i = 0; i < edges.
Size(); i++)
2994 GetBdrPatchKnotVectors(p, kv, okv);
2998 for (
int i = 0; i < verts.
Size(); i++)
3011 for (
int i = 0; i < edges.
Size(); i++)
Array< KnotVector * > knotVectors
Abstract class for Finite Elements.
Array< int > f_meshOffsets
KnotVector * DegreeElevate(int t) const
void Get3DPatchNets(const Vector &Nodes)
void Set3DSolutionVector(Vector &Nodes)
void Create(ListOfIntegerSets &groups, int mpitag)
NURBSPatch(NURBSPatch *parent, int dir, int Order, int NCP)
Array2D< int > bel_to_IJK
int Size() const
Logical size of the array.
void SetSubVector(const Array< int > &dofs, const double value)
Set the entries listed in dofs to the given value.
void SetCoordsFromPatches(Vector &Nodes)
KnotVector * KnotVec(int edge)
void swap(NURBSPatch *np)
void Get2DBdrElementTopo(Array< Element * > &boundary)
Class for grid function - Vector with associated FE space.
void GetBdrElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of bdr element i.
void DegreeElevate(int dir, int t)
NURBSPatch * Interpolate(NURBSPatch &p1, NURBSPatch &p2)
void SetPatchDofMap(int p, KnotVector *kv[])
void Generate2DElementDofTable()
void MergeGridFunctions(GridFunction *gf_array[], int num_pieces, GridFunction &merged)
void Generate3DElementDofTable()
void KnotInsert(int dir, const KnotVector &knot)
void MergeWeights(Mesh *mesh_array[], int num_pieces)
void SetSize(int s)
Resize the vector to size s.
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
void GetElementFaces(int i, Array< int > &, Array< int > &) const
Return the indices and the orientations of all faces of element i.
void Print(std::ostream &out)
void Copy(Array ©) const
Create a copy of the current array.
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
void Rotate3D(double normal[], double angle)
Array< int > e_meshOffsets
void GetElements()
Count the number of elements.
Data type dense matrix using column-major storage.
int Size() const
Returns the size of the vector.
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
void GetPatchNets(const Vector &Nodes)
void Generate3DBdrElementDofTable()
Array< int > e_spaceOffsets
void GenerateBdrElementDofTable()
void GetElementVertices(int i, Array< int > &dofs) const
Returns the indices of the dofs of element i.
const KnotVector * GetKnotVector(int i) const
void Get2DElementTopo(Array< Element * > &elements)
void GetElementLocalToGlobal(Array< int > &lelem_elem)
Data type quadrilateral element.
Array< int > edge_to_knot
void GenerateActiveVertices()
void GetVertexLocalToGlobal(Array< int > &lvert_vert)
void skip_comment_lines(std::istream &is, const char comment_char)
void SetBdrPatchVertexMap(int p, KnotVector *kv[], int *okv)
void SwapDirections(int dir1, int dir2)
friend class NURBSPatchMap
void Get3DElementTopo(Array< Element * > &elements)
KnotVector()
Create KnotVector.
void Get3DBdrElementTopo(Array< Element * > &boundary)
static const int MaxOrder
Array< int > v_spaceOffsets
void UniformRefinement(Vector &newknots) const
void LoadFE(int i, const FiniteElement *FE)
void GetBdrElementTopo(Array< Element * > &boundary)
void GetElementTopo(Array< Element * > &elements)
void Generate2DBdrElementDofTable()
Data type hexahedron element.
void SetPatch(int p) const
void GetPatchKnotVectors(int p, Array< KnotVector * > &kv)
void GenerateActiveBdrElems()
Mesh * GetMesh() const
Returns the mesh.
void LoadPatchTopo(std::istream &input, Array< int > &edge_to_knot)
Read NURBS patch/macro-element mesh.
virtual ~NURBSExtension()
Destroy a NURBSExtension.
void Transpose(const Table &A, Table &At, int _ncols_A)
Transpose a Table.
static void Get3DRotationMatrix(double n[], double angle, double r, DenseMatrix &T)
void SetKnotsFromPatches()
void CalcShape(Vector &shape, int i, double xi)
Array< int > f_spaceOffsets
Array< bool > activeBdrElem
FiniteElementSpace * FESpace()
void SetElement(int e) const
void GetBdrElementFace(int i, int *, int *) const
Return the index and the orientation of the face of bdr element i. (3D)
void Swap(Array< T > &, Array< T > &)
Array< int > v_meshOffsets
void mfem_error(const char *msg)
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
void GetBdrPatchKnotVectors(int p, Array< KnotVector * > &kv)
Array< int > p_meshOffsets
KnotVector & operator=(const KnotVector &kv)
void Set2DSolutionVector(Vector &Nodes)
Table * GetElementDofTable()
NURBSExtension * NURBSext
Optional NURBS mesh extension.
ParNURBSExtension(MPI_Comm comm, NURBSExtension *parent, int *partitioning, const Array< bool > &active_bel)
Array< KnotVector * > & KnotVectors() const
void GetElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of element i.
NURBSPatch * Revolve3D(NURBSPatch &patch, double n[], double ang, int times)
Array< int > p_spaceOffsets
int findKnotSpan(double u) const
void GenerateElementDofTable()
void GetBdrElementVertices(int i, Array< int > &dofs) const
Returns the indices of the dofs of boundary element i.
void SetIJK(int *IJK) const
void SetBdrPatchDofMap(int p, KnotVector *kv[], int *okv)
void Difference(const KnotVector &kv, Vector &diff) const
void CalcDShape(Vector &grad, int i, double xi)
void DegreeElevate(int t)
void Get2DPatchNets(const Vector &Nodes)
void Mult(const double *x, double *y) const
Matrix vector multiplication.
void LoadBE(int i, const FiniteElement *BE)
void Print(std::ostream &out) const
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
void PrintCharacteristics(std::ostream &out)
void SetPatchVertexMap(int p, KnotVector *kv[])
void FlipDirection(int dir)
void SetSolutionVector(Vector &Nodes)
Data type line segment element.
Array< int > bel_to_patch
void ConvertToPatches(const Vector &Nodes)
void KnotInsert(Array< KnotVector * > &kv)
void Print(std::ostream &out) const
int SetLoopDirection(int dir)