12 #include "../fem/fem.hpp"
24 input >> Order >> NumOfControlPoints;
25 knot.Load(input, NumOfControlPoints + Order + 1);
32 NumOfControlPoints = NCP;
33 knot.SetSize(NumOfControlPoints + Order + 1);
54 " Parent KnotVector order higher than child");
56 int nOrder = Order + t;
59 for (
int i = 0; i <= nOrder; i++)
61 (*newkv)[i] = knot(0);
63 for (
int i = nOrder + 1; i < newkv->
GetNCP(); i++)
65 (*newkv)[i] = knot(i - t);
67 for (
int i = 0; i <= nOrder; i++)
69 (*newkv)[newkv->
GetNCP() + i] = knot(knot.Size()-1);
79 newknots.
SetSize(NumOfElements);
81 for (
int i = 0; i < knot.Size()-1; i++)
83 if (knot(i) != knot(i+1))
85 newknots(j) = 0.5*(knot(i) + knot(i+1));
94 for (
int i = Order; i < NumOfControlPoints; i++)
96 if (knot(i) != knot(i+1))
105 double apb = knot(0) + knot(knot.Size()-1);
107 int ns = (NumOfControlPoints - Order)/2;
108 for (
int i = 1; i <= ns; i++)
110 double tmp = apb - knot(Order + i);
111 knot(Order + i) = apb - knot(NumOfControlPoints - i);
112 knot(NumOfControlPoints - i) = tmp;
118 out << Order <<
' ' << NumOfControlPoints <<
' ';
119 knot.Print(out, knot.Size());
126 int ip = (i >= 0) ? (i + p) : (-1 - i + p);
127 double u = getKnotLocation((i >= 0) ? xi : 1. - xi, ip), saved, tmp;
128 double left[MaxOrder+1], right[MaxOrder+1];
132 mfem_error(
"KnotVector::CalcShape : Order > MaxOrder!");
136 for (
int j = 1; j <= p; ++j)
138 left[j] = u - knot(ip+1-j);
139 right[j] = knot(ip+j) - u;
141 for (
int r = 0; r < j; ++r)
143 tmp = shape(r)/(right[r+1] + left[j-r]);
144 shape(r) = saved + right[r+1]*tmp;
145 saved = left[j-r]*tmp;
154 int p = Order, rk, pk;
155 int ip = (i >= 0) ? (i + p) : (-1 - i + p);
156 double u = getKnotLocation((i >= 0) ? xi : 1. - xi, ip), temp, saved, d;
157 double ndu[MaxOrder+1][MaxOrder+1], left[MaxOrder+1], right[MaxOrder+1];
161 mfem_error(
"KnotVector::CalcDShape : Order > MaxOrder!");
165 for (
int j = 1; j <= p; j++)
167 left[j] = u - knot(ip-j+1);
168 right[j] = knot(ip+j) - u;
170 for (
int r = 0; r < j; r++)
172 ndu[j][r] = right[r+1] + left[j-r];
173 temp = ndu[r][j-1]/ndu[j][r];
174 ndu[r][j] = saved + right[r+1]*temp;
175 saved = left[j-r]*temp;
180 for (
int r = 0; r <= p; ++r)
187 d = ndu[rk][pk]/ndu[p][rk];
191 d -= ndu[r][pk]/ndu[p][r];
197 grad *= p*(knot(ip+1) - knot(ip));
199 grad *= p*(knot(ip) - knot(ip+1));
206 if (u == knot(NumOfControlPoints+Order))
208 mid = NumOfControlPoints;
213 high = NumOfControlPoints + 1;
214 mid = (low + high)/2;
215 while ( (u < knot(mid-1)) || (u > knot(mid)) )
225 mid = (low + high)/2;
236 " Can not compare knot vectors with different orders!");
239 int s = kv.
Size() - Size();
250 for (
int j = 0; j < kv.
Size(); j++)
252 if (knot(i) == kv[j])
272 ni = kv[0]->GetNCP();
273 nj = kv[1]->GetNCP();
276 data =
new double[ni*nj*Dim];
279 for (
int i = 0; i < ni*nj*Dim; i++)
283 else if (kv.Size() == 3)
285 ni = kv[0]->GetNCP();
286 nj = kv[1]->GetNCP();
287 nk = kv[2]->GetNCP();
289 data =
new double[ni*nj*nk*Dim];
292 for (
int i = 0; i < ni*nj*nk*Dim; i++)
298 mfem_error(
"NURBSPatch::init : Wrond dimension of knotvectors!");
304 int pdim, dim, size = 1;
307 input >> ws >> ident >> pdim;
309 for (
int i = 0; i < pdim; i++)
312 size *= kv[i]->GetNCP();
315 input >> ws >> ident >> dim;
318 input >> ws >> ident;
319 if (ident ==
"controlpoints" || ident ==
"controlpoints_homogeneous")
321 for (
int j = 0, i = 0; i < size; i++)
322 for (
int d = 0; d <= dim; d++, j++)
327 for (
int j = 0, i = 0; i < size; i++)
329 for (
int d = 0; d <= dim; d++)
331 for (
int d = 0; d < dim; d++)
332 data[j+d] *= data[j+dim];
358 kv.SetSize(kv_.
Size());
359 for (
int i = 0; i < kv.Size(); i++)
366 kv.SetSize(parent->
kv.Size());
367 for (
int i = 0; i < kv.Size(); i++)
380 for (
int i = 0; i < kv.Size(); i++)
382 if (kv[i])
delete kv[i];
404 for (
int i = 0; i < kv.Size(); i++)
406 if (kv[i])
delete kv[i];
414 out <<
"knotvectors\n" << kv.Size() <<
'\n';
415 for (
int i = 0; i < kv.Size(); i++)
418 size *= kv[i]->GetNCP();
421 out <<
"\ndimension\n" << Dim - 1
422 <<
"\n\ncontrolpoints\n";
423 for (
int j = 0, i = 0; i < size; i++)
426 for (
int d = 1; d < Dim; d++)
427 out <<
' ' << data[j++];
452 cerr <<
"NURBSPatch::SetLoopDirection :\n"
453 " Direction error in 2D patch, dir = " << dir <<
'\n';
482 cerr <<
"NURBSPatch::SetLoopDirection :\n"
483 " Direction error in 3D patch, dir = " << dir <<
'\n';
494 for (
int dir = 0; dir < kv.Size(); dir++)
496 kv[dir]->UniformRefinement(newknots);
497 KnotInsert(dir, newknots);
503 for (
int dir = 0; dir < kv.Size(); dir++)
505 KnotInsert(dir, *newkv[dir]);
511 if (dir >= kv.Size() || dir < 0)
512 mfem_error(
"NURBSPatch::KnotInsert : Incorrect direction!");
514 int t = newkv.
GetOrder() - kv[dir]->GetOrder();
518 DegreeElevate(dir, t);
522 mfem_error(
"NURBSPatch::KnotInsert : Incorrect order!");
526 GetKV(dir)->Difference(newkv, diff);
529 KnotInsert(dir, diff);
536 if (dir >= kv.Size() || dir < 0)
537 mfem_error(
"NURBSPatch::KnotInsert : Incorrect direction!");
548 if (size != newp.SetLoopDirection(dir))
549 mfem_error(
"NURBSPatch::KnotInsert : Size mismatch!");
551 int rr = knot.
Size() - 1;
557 for (
int j = 0; j <= a; j++)
561 for (
int j = b+pl; j <= ml+pl; j++)
563 newkv[j+rr+1] = oldkv[j];
565 for (
int k = 0; k <= (a-pl); k++)
567 for (
int ll = 0; ll < size; ll++)
568 newp(k,ll) = oldp(k,ll);
570 for (
int k = (b-1); k < ml; k++)
572 for (
int ll = 0; ll < size; ll++)
573 newp(k+rr+1,ll) = oldp(k,ll);
579 for (
int j = rr; j >= 0; j--)
581 while ( (knot(j) <= oldkv[i]) && (i > a) )
584 for (
int ll = 0; ll < size; ll++)
585 newp(k-pl-1,ll) = oldp(i-pl-1,ll);
591 for (
int ll = 0; ll < size; ll++)
592 newp(k-pl-1,ll) = newp(k-pl,ll);
594 for (
int l = 1; l <= pl; l++)
597 double alfa = newkv[k+l] - knot(j);
598 if (fabs(alfa) == 0.0)
600 for (
int ll = 0; ll < size; ll++)
601 newp(ind-1,ll) = newp(ind,ll);
605 alfa = alfa/(newkv[k+l] - oldkv[i-pl+l]);
606 for (
int ll = 0; ll < size; ll++)
607 newp(ind-1,ll) = alfa*newp(ind-1,ll) + (1.0-alfa)*newp(ind,ll);
622 for (
int dir = 0; dir < kv.Size(); dir++)
624 DegreeElevate(dir, t);
631 if (dir >= kv.Size() || dir < 0)
632 mfem_error(
"NURBSPatch::DegreeElevate : Incorrect direction!");
634 int i, j, k, kj, mpi, mul, mh, kind, cind, first, last;
635 int r, a, b, oldr, save, s, tr, lbz, rbz, l;
636 double inv, ua, ub, numer, alf, den, bet, gam;
647 if (size != newp.SetLoopDirection(dir))
648 mfem_error(
"NURBSPatch::DegreeElevate : Size mismatch!");
665 for (i = 0; i <= ph; i++)
667 binom(i,0) = binom(i,i) = 1;
668 for (j = 1; j < i; j++)
669 binom(i,j) = binom(i-1,j) + binom(i-1,j-1);
675 for (i = 1; i <= ph2; i++)
677 inv = 1.0/binom(ph,i);
679 for (j = max(0,i-t); j <= mpi; j++)
681 bezalfs(i,j) = inv*binom(p,j)*binom(t,i-j);
686 for (i = ph2+1; i < ph; i++)
689 for (j = max(0,i-t); j <= mpi; j++)
691 bezalfs(i,j) = bezalfs(ph-i,p-j);
702 for (l = 0; l < size; l++)
703 newp(0,l) = oldp(0,l);
704 for (i = 0; i <= ph; i++)
707 for (i = 0; i <= p; i++)
709 for (l = 0; l < size; l++)
710 bpts(i,l) = oldp(i,l);
716 while (b < m && oldkv[b] == oldkv[b+1]) b++;
724 if (oldr > 0) lbz = (oldr+2)/2;
727 if (r > 0) rbz = ph-(r+1)/2;
733 for (k = p ; k > mul; k--)
734 alphas[k-mul-1] = numer/(oldkv[a+k]-ua);
736 for (j = 1; j <= r; j++)
740 for (k = p; k >= s; k--)
742 for (l = 0; l < size; l++)
743 bpts(k,l) = (alphas[k-s]*bpts(k,l) +
744 (1.0-alphas[k-s])*bpts(k-1,l));
746 for (l = 0; l < size; l++)
747 nextbpts(save,l) = bpts(p,l);
751 for (i = lbz; i <= ph; i++)
753 for (l = 0; l < size; l++)
756 for (j = max(0,i-t); j <= mpi; j++)
758 for (l = 0; l < size; l++)
759 ebpts(i,l) += bezalfs(i,j)*bpts(j,l);
768 bet = (ub-newkv[kind-1])/den;
770 for (tr = 1; tr < oldr; tr++)
779 alf = (ub-newkv[i])/(ua-newkv[i]);
780 for (l = 0; l < size; l++)
781 newp(i,l) = alf*newp(i,l)-(1.0-alf)*newp(i-1,l);
785 if ((j-tr) <= (kind-ph+oldr))
787 gam = (ub-newkv[j-tr])/den;
788 for (l = 0; l < size; l++)
789 ebpts(kj,l) = gam*ebpts(kj,l) + (1.0-gam)*ebpts(kj+1,l);
793 for (l = 0; l < size; l++)
794 ebpts(kj,l) = bet*ebpts(kj,l) + (1.0-bet)*ebpts(kj+1,l);
808 for (i = 0; i < (ph-oldr); i++)
814 for (j = lbz; j <= rbz; j++)
816 for (l = 0; l < size; l++)
817 newp(cind,l) = ebpts(j,l);
823 for (j = 0; j <r; j++)
824 for (l = 0; l < size; l++)
825 bpts(j,l) = nextbpts(j,l);
827 for (j = r; j <= p; j++)
828 for (l = 0; l < size; l++)
829 bpts(j,l) = oldp(b-p+j,l);
837 for (i = 0; i <= ph; i++)
848 int size = SetLoopDirection(dir);
850 for (
int id = 0;
id < nd/2;
id++)
851 for (
int i = 0; i < size; i++)
852 Swap<double>((*
this)(
id,i), (*
this)(nd-1-
id,i));
858 if (abs(dir1-dir2) == 2)
860 " directions 0 and 2 are not supported!");
865 Swap<KnotVector *>(nkv[dir1], nkv[dir2]);
868 int size = SetLoopDirection(dir1);
869 newpatch->SetLoopDirection(dir2);
871 for (
int id = 0;
id < nd;
id++)
872 for (
int i = 0; i < size; i++)
873 (*newpatch)(id,i) = (*
this)(id,i);
882 double l2 = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];
885 if (fabs(angle) == M_PI_2)
887 s = r*copysign(1., angle);
891 else if (fabs(angle) == M_PI)
906 T(0,0) = (n[0]*n[0] + (n[1]*n[1] + n[2]*n[2])*c)/l2;
907 T(0,1) = -(n[0]*n[1]*c1)/l2 - (n[2]*s)/l;
908 T(0,2) = -(n[0]*n[2]*c1)/l2 + (n[1]*s)/l;
909 T(1,0) = -(n[0]*n[1]*c1)/l2 + (n[2]*s)/l;
910 T(1,1) = (n[1]*n[1] + (n[0]*n[0] + n[2]*n[2])*c)/l2;
911 T(1,2) = -(n[1]*n[2]*c1)/l2 - (n[0]*s)/l;
912 T(2,0) = -(n[0]*n[2]*c1)/l2 - (n[1]*s)/l;
913 T(2,1) = -(n[1]*n[2]*c1)/l2 + (n[0]*s)/l;
914 T(2,2) = (n[2]*n[2] + (n[0]*n[0] + n[1]*n[1])*c)/l2;
920 mfem_error(
"NURBSPatch::Rotate3D : not a NURBSPatch in 3D!");
925 Get3DRotationMatrix(n, angle, 1., T);
928 for (
int i = 0; i < kv.Size(); i++)
929 size *= kv[i]->GetNCP();
931 for (
int i = 0; i < size; i++)
943 for (
int dir = 0; dir < kv.Size(); dir++)
944 if (maxd < kv[dir]->GetOrder())
945 maxd = kv[dir]->GetOrder();
947 for (
int dir = 0; dir < kv.Size(); dir++)
948 if (maxd > kv[dir]->GetOrder())
949 DegreeElevate(dir, maxd - kv[dir]->GetOrder());
956 if (p1.
kv.Size() != p2.
kv.Size() || p1.
Dim != p2.
Dim)
957 mfem_error(
"Interpolate(NURBSPatch &, NURBSPatch &)");
959 int size = 1, dim = p1.
Dim;
962 for (
int i = 0; i < p1.
kv.Size(); i++)
964 if (p1.
kv[i]->GetOrder() < p2.
kv[i]->GetOrder())
975 size *= kv[i]->GetNCP();
980 nkv[0] = nkv[1] = 0.0;
981 nkv[2] = nkv[3] = 1.0;
987 for (
int i = 0; i < size; i++)
989 for (
int d = 0; d < dim; d++)
991 patch->
data[i*dim+d] = p1.
data[i*dim+d];
992 patch->
data[(i+size)*dim+d] = p2.
data[i*dim+d];
1002 mfem_error(
"Revolve3D(NURBSPatch &, double [], double)");
1007 for (
int i = 0; i < patch.
kv.Size(); i++)
1009 nkv[i] = patch.
kv[i];
1010 size *= nkv[i]->GetNCP();
1015 lkv[0] = lkv[1] = lkv[2] = 0.0;
1016 for (
int i = 1; i < times; i++)
1017 lkv[2*i+1] = lkv[2*i+2] = i;
1018 lkv[ns] = lkv[ns+1] = lkv[ns+2] = times;
1024 Vector u(NULL, 3), v(NULL, 3);
1027 double c = cos(ang/2);
1031 double *op = patch.
data, *np;
1032 for (
int i = 0; i < size; i++)
1034 np = newpatch->
data + 4*i;
1035 for (
int j = 0; j < 4; j++)
1037 for (
int j = 0; j < times; j++)
1060 patchTopo =
new Mesh;
1071 input >> ws >> ident;
1072 if (ident ==
"knotvectors")
1074 input >> NumOfKnotVectors;
1075 knotVectors.SetSize(NumOfKnotVectors);
1076 for (
int i = 0; i < NumOfKnotVectors; i++)
1079 if (knotVectors[i]->GetOrder() != knotVectors[0]->GetOrder())
1080 mfem_error(
"NURBSExtension::NURBSExtension :\n"
1081 " Variable orders are not supported!");
1083 Order = knotVectors[0]->GetOrder();
1085 else if (ident ==
"patches")
1087 patches.SetSize(GetNP());
1088 for (
int p = 0; p < patches.Size(); p++)
1094 NumOfKnotVectors = 0;
1095 for (
int i = 0; i < patchTopo->GetNEdges(); i++)
1096 if (NumOfKnotVectors < KnotInd(i))
1097 NumOfKnotVectors = KnotInd(i);
1099 knotVectors.SetSize(NumOfKnotVectors);
1103 for (
int p = 0; p < patches.Size(); p++)
1105 patchTopo->GetElementEdges(p, edges, oedge);
1106 if (Dimension() == 2)
1108 if (knotVectors[KnotInd(edges[0])] == NULL)
1109 knotVectors[KnotInd(edges[0])] =
1111 if (knotVectors[KnotInd(edges[1])] == NULL)
1112 knotVectors[KnotInd(edges[1])] =
1117 if (knotVectors[KnotInd(edges[0])] == NULL)
1118 knotVectors[KnotInd(edges[0])] =
1120 if (knotVectors[KnotInd(edges[3])] == NULL)
1121 knotVectors[KnotInd(edges[3])] =
1123 if (knotVectors[KnotInd(edges[8])] == NULL)
1124 knotVectors[KnotInd(edges[8])] =
1128 Order = knotVectors[0]->GetOrder();
1139 if (patches.Size() == 0)
1140 input >> ws >> ident;
1141 if (patches.Size() == 0 && ident ==
"mesh_elements")
1143 input >> NumOfActiveElems;
1144 activeElem.SetSize(GetGNE());
1147 for (
int i = 0; i < NumOfActiveElems; i++)
1150 activeElem[glob_elem] =
true;
1154 input >> ws >> ident;
1158 NumOfActiveElems = NumOfElements;
1159 activeElem.SetSize(NumOfElements);
1163 GenerateActiveVertices();
1164 GenerateElementDofTable();
1165 GenerateActiveBdrElems();
1166 GenerateBdrElementDofTable();
1168 if (patches.Size() == 0)
1171 if (ident ==
"weights")
1173 weights.Load(input, GetNDof());
1177 weights.SetSize(GetNDof());
1192 NumOfKnotVectors = parent->
GetNKV();
1193 knotVectors.SetSize(NumOfKnotVectors);
1194 for (
int i = 0; i < NumOfKnotVectors; i++)
1213 GenerateElementDofTable();
1214 GenerateBdrElementDofTable();
1216 weights.SetSize(GetNDof());
1225 mfem_error(
"NURBSExtension::NURBSExtension :\n"
1226 " parent does not own the patch topology!");
1235 NumOfKnotVectors = parent->
GetNKV();
1236 knotVectors.SetSize(NumOfKnotVectors);
1237 for (
int i = 0; i < NumOfKnotVectors; i++)
1247 NumOfActiveElems = NumOfElements;
1248 activeElem.SetSize(NumOfElements);
1251 GenerateActiveVertices();
1252 GenerateElementDofTable();
1253 GenerateActiveBdrElems();
1254 GenerateBdrElementDofTable();
1256 weights.SetSize(GetNDof());
1257 MergeWeights(mesh_array, num_pieces);
1265 for (
int i = 0; i < knotVectors.Size(); i++)
1266 delete knotVectors[i];
1268 for (
int i = 0; i < patches.Size(); i++)
1277 patchTopo->PrintTopo(out, edge_to_knot);
1278 out <<
"\nknotvectors\n" << NumOfKnotVectors <<
'\n';
1279 for (
int i = 0; i < NumOfKnotVectors; i++)
1281 knotVectors[i]->Print(out);
1284 if (NumOfActiveElems < NumOfElements)
1286 out <<
"\nmesh_elements\n" << NumOfActiveElems <<
'\n';
1287 for (
int i = 0; i < NumOfElements; i++)
1292 out <<
"\nweights\n";
1293 weights.Print(out, 1);
1299 "NURBS Mesh entity sizes:\n"
1300 "Dimension = " << Dimension() <<
"\n"
1301 "Order = " << GetOrder() <<
"\n"
1302 "NumOfKnotVectors = " << GetNKV() <<
"\n"
1303 "NumOfPatches = " << GetNP() <<
"\n"
1304 "NumOfBdrPatches = " << GetNBP() <<
"\n"
1305 "NumOfVertices = " << GetGNV() <<
"\n"
1306 "NumOfElements = " << GetGNE() <<
"\n"
1307 "NumOfBdrElements = " << GetGNBE() <<
"\n"
1308 "NumOfDofs = " << GetNTotalDof() <<
"\n"
1309 "NumOfActiveVertices = " << GetNV() <<
"\n"
1310 "NumOfActiveElems = " << GetNE() <<
"\n"
1311 "NumOfActiveBdrElems = " << GetNBE() <<
"\n"
1312 "NumOfActiveDofs = " << GetNDof() <<
'\n';
1313 for (
int i = 0; i < NumOfKnotVectors; i++)
1315 out <<
' ' << i + 1 <<
") ";
1316 knotVectors[i]->Print(out);
1323 int vert[8], nv, g_el, nx, ny, nz, dim = Dimension();
1329 activeVert.SetSize(GetGNV());
1331 for (
int p = 0; p < GetNP(); p++)
1337 nz = (dim == 3) ? p2g.
nz() : 1;
1339 for (
int k = 0; k < nz; k++)
1341 for (
int j = 0; j < ny; j++)
1343 for (
int i = 0; i < nx; i++)
1345 if (activeElem[g_el])
1349 vert[0] = p2g(i, j );
1350 vert[1] = p2g(i+1,j );
1351 vert[2] = p2g(i+1,j+1);
1352 vert[3] = p2g(i, j+1);
1357 vert[0] = p2g(i, j, k);
1358 vert[1] = p2g(i+1,j, k);
1359 vert[2] = p2g(i+1,j+1,k);
1360 vert[3] = p2g(i, j+1,k);
1362 vert[4] = p2g(i, j, k+1);
1363 vert[5] = p2g(i+1,j, k+1);
1364 vert[6] = p2g(i+1,j+1,k+1);
1365 vert[7] = p2g(i, j+1,k+1);
1369 for (
int v = 0; v < nv; v++)
1370 activeVert[vert[v]] = 1;
1378 NumOfActiveVertices = 0;
1379 for (
int i = 0; i < GetGNV(); i++)
1380 if (activeVert[i] == 1)
1381 activeVert[i] = NumOfActiveVertices++;
1386 int dim = Dimension();
1389 activeBdrElem.SetSize(GetGNBE());
1390 if (GetGNE() == GetNE())
1392 activeBdrElem =
true;
1393 NumOfActiveBdrElems = GetGNBE();
1396 activeBdrElem =
false;
1397 NumOfActiveBdrElems = 0;
1410 for (
int i = 0; i < num_pieces; i++)
1416 for (
int lel = 0; lel < lext->
GetNE(); lel++)
1418 int gel = lelem_elem[lel];
1420 int nd = el_dof->RowSize(gel);
1421 int *gdofs = el_dof->GetRow(gel);
1423 for (
int j = 0; j < nd; j++)
1424 weights(gdofs[j]) = lext->
weights(ldofs[j]);
1436 for (
int i = 0; i < num_pieces; i++)
1443 for (
int lel = 0; lel < lext->
GetNE(); lel++)
1459 for (
int p = 0; p < GetNP(); p++)
1461 patchTopo->GetElementEdges(p, edges, oedge);
1463 for (
int i = 0; i < edges.
Size(); i++)
1465 edges[i] = edge_to_knot[edges[i]];
1467 edges[i] = -1 - edges[i];
1470 if ((Dimension() == 2 &&
1471 (edges[0] != -1 - edges[2] || edges[1] != -1 - edges[3])) ||
1473 (Dimension() == 3 &&
1474 (edges[0] != edges[2] || edges[0] != edges[4] ||
1475 edges[0] != edges[6] || edges[1] != edges[3] ||
1476 edges[1] != edges[5] || edges[1] != edges[7] ||
1477 edges[8] != edges[9] || edges[8] != edges[10] ||
1478 edges[8] != edges[11])))
1480 cerr <<
"NURBSExtension::CheckPatch (patch = " << p
1481 <<
")\n Inconsistent edge-to-knot mapping!\n";
1485 if ((Dimension() == 2 &&
1486 (edges[0] < 0 || edges[1] < 0)) ||
1488 (Dimension() == 3 &&
1489 (edges[0] < 0 || edges[3] < 0 || edges[8] < 0)))
1491 cerr <<
"NURBSExtension::CheckPatch (patch = " << p
1492 <<
") : Bad orientation!\n";
1503 for (
int p = 0; p < GetNBP(); p++)
1505 patchTopo->GetBdrElementEdges(p, edges, oedge);
1507 for (
int i = 0; i < edges.
Size(); i++)
1509 edges[i] = edge_to_knot[edges[i]];
1511 edges[i] = -1 - edges[i];
1514 if ((Dimension() == 2 && (edges[0] < 0)) ||
1515 (Dimension() == 3 && (edges[0] < 0 || edges[1] < 0)))
1517 cerr <<
"NURBSExtension::CheckBdrPatch (boundary patch = "
1518 << p <<
") : Bad orientation!\n";
1530 patchTopo->GetElementEdges(p, edges, orient);
1532 if (Dimension() == 2)
1534 kv[0] = KnotVec(edges[0]);
1535 kv[1] = KnotVec(edges[1]);
1539 kv[0] = KnotVec(edges[0]);
1540 kv[1] = KnotVec(edges[3]);
1541 kv[2] = KnotVec(edges[8]);
1551 patchTopo->GetBdrElementEdges(p, edges, orient);
1553 if (Dimension() == 2)
1555 kv[0] = KnotVec(edges[0]);
1559 kv[0] = KnotVec(edges[0]);
1560 kv[1] = KnotVec(edges[1]);
1566 int nv = patchTopo->GetNV();
1567 int ne = patchTopo->GetNEdges();
1568 int nf = patchTopo->GetNFaces();
1569 int np = patchTopo->GetNE();
1570 int meshCounter, spaceCounter, dim = Dimension();
1576 e_meshOffsets.SetSize(ne);
1577 f_meshOffsets.SetSize(nf);
1578 p_meshOffsets.SetSize(np);
1580 v_spaceOffsets.SetSize(nv);
1581 e_spaceOffsets.SetSize(ne);
1582 f_spaceOffsets.SetSize(nf);
1583 p_spaceOffsets.SetSize(np);
1586 for (meshCounter = 0; meshCounter < nv; meshCounter++)
1588 v_meshOffsets[meshCounter] = meshCounter;
1589 v_spaceOffsets[meshCounter] = meshCounter;
1591 spaceCounter = meshCounter;
1594 for (
int e = 0; e < ne; e++)
1596 e_meshOffsets[e] = meshCounter;
1597 e_spaceOffsets[e] = spaceCounter;
1598 meshCounter += KnotVec(e)->GetNE() - 1;
1599 spaceCounter += KnotVec(e)->GetNCP() - 2;
1603 for (
int f = 0; f < nf; f++)
1605 f_meshOffsets[f] = meshCounter;
1606 f_spaceOffsets[f] = spaceCounter;
1608 patchTopo->GetFaceEdges(f, edges, orient);
1611 (KnotVec(edges[0])->GetNE() - 1) *
1612 (KnotVec(edges[1])->GetNE() - 1);
1614 (KnotVec(edges[0])->GetNCP() - 2) *
1615 (KnotVec(edges[1])->GetNCP() - 2);
1619 for (
int p = 0; p < np; p++)
1621 p_meshOffsets[p] = meshCounter;
1622 p_spaceOffsets[p] = spaceCounter;
1624 patchTopo->GetElementEdges(p, edges, orient);
1629 (KnotVec(edges[0])->GetNE() - 1) *
1630 (KnotVec(edges[1])->GetNE() - 1);
1632 (KnotVec(edges[0])->GetNCP() - 2) *
1633 (KnotVec(edges[1])->GetNCP() - 2);
1638 (KnotVec(edges[0])->GetNE() - 1) *
1639 (KnotVec(edges[3])->GetNE() - 1) *
1640 (KnotVec(edges[8])->GetNE() - 1);
1642 (KnotVec(edges[0])->GetNCP() - 2) *
1643 (KnotVec(edges[3])->GetNCP() - 2) *
1644 (KnotVec(edges[8])->GetNCP() - 2);
1647 NumOfVertices = meshCounter;
1648 NumOfDofs = spaceCounter;
1653 int dim = Dimension();
1657 for (
int p = 0; p < GetNP(); p++)
1659 GetPatchKnotVectors(p, kv);
1661 int ne = kv[0]->GetNE();
1662 for (
int d = 1; d < dim; d++)
1663 ne *= kv[d]->GetNE();
1665 NumOfElements += ne;
1671 int dim = Dimension() - 1;
1674 NumOfBdrElements = 0;
1675 for (
int p = 0; p < GetNBP(); p++)
1677 GetBdrPatchKnotVectors(p, kv);
1679 int ne = kv[0]->GetNE();
1680 for (
int d = 1; d < dim; d++)
1681 ne *= kv[d]->GetNE();
1683 NumOfBdrElements += ne;
1691 if (Dimension() == 2)
1693 Get2DElementTopo(elements);
1697 Get3DElementTopo(elements);
1709 for (
int p = 0; p < GetNP(); p++)
1715 int patch_attr = patchTopo->GetAttribute(p);
1717 for (
int j = 0; j < ny; j++)
1719 for (
int i = 0; i < nx; i++)
1723 ind[0] = activeVert[p2g(i, j )];
1724 ind[1] = activeVert[p2g(i+1,j )];
1725 ind[2] = activeVert[p2g(i+1,j+1)];
1726 ind[3] = activeVert[p2g(i, j+1)];
1745 for (
int p = 0; p < GetNP(); p++)
1752 int patch_attr = patchTopo->GetAttribute(p);
1754 for (
int k = 0; k < nz; k++)
1756 for (
int j = 0; j < ny; j++)
1758 for (
int i = 0; i < nx; i++)
1762 ind[0] = activeVert[p2g(i, j, k)];
1763 ind[1] = activeVert[p2g(i+1,j, k)];
1764 ind[2] = activeVert[p2g(i+1,j+1,k)];
1765 ind[3] = activeVert[p2g(i, j+1,k)];
1767 ind[4] = activeVert[p2g(i, j, k+1)];
1768 ind[5] = activeVert[p2g(i+1,j, k+1)];
1769 ind[6] = activeVert[p2g(i+1,j+1,k+1)];
1770 ind[7] = activeVert[p2g(i, j+1,k+1)];
1772 elements[el] =
new Hexahedron(ind, patch_attr);
1786 if (Dimension() == 2)
1788 Get2DBdrElementTopo(boundary);
1792 Get3DBdrElementTopo(boundary);
1804 for (
int b = 0; b < GetNBP(); b++)
1809 int bdr_patch_attr = patchTopo->GetBdrAttribute(b);
1811 for (
int i = 0; i < nx; i++)
1813 if (activeBdrElem[g_be])
1815 int _i = (okv[0] >= 0) ? i : (nx - 1 - i);
1816 ind[0] = activeVert[p2g[_i ]];
1817 ind[1] = activeVert[p2g[_i+1]];
1819 boundary[l_be] =
new Segment(ind, bdr_patch_attr);
1835 for (
int b = 0; b < GetNBP(); b++)
1841 int bdr_patch_attr = patchTopo->GetBdrAttribute(b);
1843 for (
int j = 0; j < ny; j++)
1845 int _j = (okv[1] >= 0) ? j : (ny - 1 - j);
1846 for (
int i = 0; i < nx; i++)
1848 if (activeBdrElem[g_be])
1850 int _i = (okv[0] >= 0) ? i : (nx - 1 - i);
1851 ind[0] = activeVert[p2g(_i, _j )];
1852 ind[1] = activeVert[p2g(_i+1,_j )];
1853 ind[2] = activeVert[p2g(_i+1,_j+1)];
1854 ind[3] = activeVert[p2g(_i, _j+1)];
1867 activeDof.SetSize(GetNTotalDof());
1870 if (Dimension() == 2)
1872 Generate2DElementDofTable();
1876 Generate3DElementDofTable();
1879 NumOfActiveDofs = 0;
1880 for (
int d = 0; d < GetNTotalDof(); d++)
1884 activeDof[d] = NumOfActiveDofs;
1887 int *dof = el_dof->GetJ();
1888 int ndof = el_dof->Size_of_connections();
1889 for (
int i = 0; i < ndof; i++)
1891 dof[i] = activeDof[dof[i]] - 1;
1902 el_dof =
new Table(NumOfActiveElems, (Order + 1)*(Order + 1));
1903 el_to_patch.SetSize(NumOfActiveElems);
1904 el_to_IJK.SetSize(NumOfActiveElems, 2);
1906 for (
int p = 0; p < GetNP(); p++)
1911 for (
int j = 0; j < kv[1]->
GetNKS(); j++)
1913 if (kv[1]->isElement(j))
1915 for (
int i = 0; i < kv[0]->
GetNKS(); i++)
1917 if (kv[0]->isElement(i))
1921 int *dofs = el_dof->GetRow(el);
1923 for (
int jj = 0; jj <= Order; jj++)
1925 for (
int ii = 0; ii <= Order; ii++)
1927 dofs[idx] = p2g(i+ii,j+jj);
1928 activeDof[dofs[idx]] = 1;
1932 el_to_patch[el] = p;
1933 el_to_IJK(el,0) = i;
1934 el_to_IJK(el,1) = j;
1954 el_dof =
new Table(NumOfActiveElems, (Order + 1)*(Order + 1)*(Order + 1));
1955 el_to_patch.SetSize(NumOfActiveElems);
1956 el_to_IJK.SetSize(NumOfActiveElems, 3);
1958 for (
int p = 0; p < GetNP(); p++)
1963 for (
int k = 0; k < kv[2]->
GetNKS(); k++)
1965 if (kv[2]->isElement(k))
1967 for (
int j = 0; j < kv[1]->
GetNKS(); j++)
1969 if (kv[1]->isElement(j))
1971 for (
int i = 0; i < kv[0]->
GetNKS(); i++)
1973 if (kv[0]->isElement(i))
1978 int *dofs = el_dof->GetRow(el);
1979 for (
int kk = 0; kk <= Order; kk++)
1981 for (
int jj = 0; jj <= Order; jj++)
1983 for (
int ii = 0; ii <= Order; ii++)
1985 dofs[idx] = p2g(i+ii,j+jj,k+kk);
1986 activeDof[dofs[idx]] = 1;
1992 el_to_patch[el] = p;
1993 el_to_IJK(el,0) = i;
1994 el_to_IJK(el,1) = j;
1995 el_to_IJK(el,2) = k;
2011 if (Dimension() == 2)
2013 Generate2DBdrElementDofTable();
2017 Generate3DBdrElementDofTable();
2020 int *dof = bel_dof->GetJ();
2021 int ndof = bel_dof->Size_of_connections();
2022 for (
int i = 0; i < ndof; i++)
2024 dof[i] = activeDof[dof[i]] - 1;
2031 int lbe = 0, okv[1];
2035 bel_dof =
new Table(NumOfActiveBdrElems, Order + 1);
2036 bel_to_patch.SetSize(NumOfActiveBdrElems);
2037 bel_to_IJK.SetSize(NumOfActiveBdrElems, 1);
2039 for (
int b = 0; b < GetNBP(); b++)
2045 int nks0 = kv[0]->
GetNKS();
2046 for (
int i = 0; i < nks0; i++)
2048 if (kv[0]->isElement(i))
2050 if (activeBdrElem[gbe])
2052 int *dofs = bel_dof->GetRow(lbe);
2054 for (
int ii = 0; ii <= Order; ii++)
2056 dofs[idx] = p2g[(okv[0] >= 0) ? (i+ii) : (nx-i-ii)];
2059 bel_to_patch[lbe] = b;
2060 bel_to_IJK(lbe,0) = (okv[0] >= 0) ? i : (-1-i);
2072 int lbe = 0, okv[2];
2076 bel_dof =
new Table(NumOfActiveBdrElems, (Order + 1)*(Order + 1));
2077 bel_to_patch.SetSize(NumOfActiveBdrElems);
2078 bel_to_IJK.SetSize(NumOfActiveBdrElems, 2);
2080 for (
int b = 0; b < GetNBP(); b++)
2087 int nks0 = kv[0]->
GetNKS();
2088 int nks1 = kv[1]->
GetNKS();
2089 for (
int j = 0; j < nks1; j++)
2091 if (kv[1]->isElement(j))
2093 for (
int i = 0; i < nks0; i++)
2095 if (kv[0]->isElement(i))
2097 if (activeBdrElem[gbe])
2099 int *dofs = bel_dof->GetRow(lbe);
2101 for (
int jj = 0; jj <= Order; jj++)
2103 int _jj = (okv[1] >= 0) ? (j+jj) : (ny-j-jj);
2104 for (
int ii = 0; ii <= Order; ii++)
2106 int _ii = (okv[0] >= 0) ? (i+ii) : (nx-i-ii);
2107 dofs[idx] = p2g(_ii,_jj);
2111 bel_to_patch[lbe] = b;
2112 bel_to_IJK(lbe,0) = (okv[0] >= 0) ? i : (-1-i);
2113 bel_to_IJK(lbe,1) = (okv[1] >= 0) ? j : (-1-j);
2127 for (
int gv = 0; gv < GetGNV(); gv++)
2128 if (activeVert[gv] >= 0)
2129 lvert_vert[activeVert[gv]] = gv;
2135 for (
int le = 0, ge = 0; ge < GetGNE(); ge++)
2137 lelem_elem[le++] = ge;
2148 NURBSFE->
SetIJK(el_to_IJK.GetRow(i));
2149 if (el_to_patch[i] != NURBSFE->
GetPatch())
2151 GetPatchKnotVectors(el_to_patch[i], NURBSFE->
KnotVectors());
2154 el_dof->GetRow(i, dofs);
2155 weights.GetSubVector(dofs, NURBSFE->
Weights());
2168 NURBSFE->
SetIJK(bel_to_IJK.GetRow(i));
2169 if (bel_to_patch[i] != NURBSFE->
GetPatch())
2171 GetBdrPatchKnotVectors(bel_to_patch[i], NURBSFE->
KnotVectors());
2172 NURBSFE->
SetPatch(bel_to_patch[i]);
2174 bel_dof->GetRow(i, dofs);
2175 weights.GetSubVector(dofs, NURBSFE->
Weights());
2185 if (patches.Size() == 0)
2186 GetPatchNets(Nodes);
2191 if (patches.Size() == 0)
return;
2193 SetSolutionVector(Nodes);
2199 if (patches.Size() == 0)
2200 mfem_error(
"NURBSExtension::SetKnotsFromPatches :"
2201 " No patches available!");
2205 for (
int p = 0; p < patches.Size(); p++)
2207 GetPatchKnotVectors(p, kv);
2209 for (
int i = 0; i < kv.
Size(); i++)
2210 *kv[i] = *patches[p]->GetKV(i);
2213 Order = knotVectors[0]->GetOrder();
2214 for (
int i = 0; i < NumOfKnotVectors; i++)
2216 if (Order != knotVectors[i]->GetOrder())
2218 " Variable orders are not supported!");
2226 NumOfActiveElems = NumOfElements;
2227 activeElem.SetSize(NumOfElements);
2230 GenerateActiveVertices();
2231 GenerateElementDofTable();
2232 GenerateActiveBdrElems();
2233 GenerateBdrElementDofTable();
2238 for (
int p = 0; p < patches.Size(); p++)
2240 patches[p]->DegreeElevate(t);
2246 for (
int p = 0; p < patches.Size(); p++)
2248 patches[p]->UniformRefinement();
2259 for (
int p = 0; p < patches.Size(); p++)
2261 patchTopo->GetElementEdges(p, edges, orient);
2265 pkv[0] = kv[KnotInd(edges[0])];
2266 pkv[1] = kv[KnotInd(edges[1])];
2270 pkv[0] = kv[KnotInd(edges[0])];
2271 pkv[1] = kv[KnotInd(edges[3])];
2272 pkv[2] = kv[KnotInd(edges[8])];
2275 patches[p]->KnotInsert(pkv);
2281 if (Dimension() == 2)
2283 Get2DPatchNets(coords);
2287 Get3DPatchNets(coords);
2296 patches.SetSize(GetNP());
2297 for (
int p = 0; p < GetNP(); p++)
2303 for (
int j = 0; j < kv[1]->GetNCP(); j++)
2305 for (
int i = 0; i < kv[0]->GetNCP(); i++)
2308 for (
int d = 0; d < 2; d++)
2310 Patch(i,j,d) = coords(l*2 + d)*weights(l);
2312 Patch(i,j,2) = weights(l);
2323 patches.SetSize(GetNP());
2324 for (
int p = 0; p < GetNP(); p++)
2330 for (
int k = 0; k < kv[2]->GetNCP(); k++)
2332 for (
int j = 0; j < kv[1]->GetNCP(); j++)
2334 for (
int i = 0; i < kv[0]->GetNCP(); i++)
2337 for (
int d = 0; d < 3; d++)
2339 Patch(i,j,k,d) = coords(l*3 + d)*weights(l);
2341 Patch(i,j,k,3) = weights(l);
2350 if (Dimension() == 2)
2352 Set2DSolutionVector(coords);
2356 Set3DSolutionVector(coords);
2365 weights.SetSize(GetNDof());
2366 for (
int p = 0; p < GetNP(); p++)
2371 for (
int j = 0; j < kv[1]->GetNCP(); j++)
2373 for (
int i = 0; i < kv[0]->GetNCP(); i++)
2376 for (
int d = 0; d < 2; d++)
2378 coords(l*2 + d) = Patch(i,j,d)/Patch(i,j,2);
2380 weights(l) = Patch(i,j,2);
2392 weights.SetSize(GetNDof());
2393 for (
int p = 0; p < GetNP(); p++)
2398 for (
int k = 0; k < kv[2]->GetNCP(); k++)
2400 for (
int j = 0; j < kv[1]->GetNCP(); j++)
2402 for (
int i = 0; i < kv[0]->GetNCP(); i++)
2405 for (
int d = 0; d < 3; d++)
2407 coords(l*3 + d) = Patch(i,j,k,d)/Patch(i,j,k,3);
2409 weights(l) = Patch(i,j,k,3);
2426 mfem_error(
"ParNURBSExtension::ParNURBSExtension :\n"
2427 " all elements in the parent must be active!");
2432 mfem_error(
"ParNURBSExtension::ParNURBSExtension :\n"
2433 " parent does not own the patch topology!");
2453 partitioning =
new int[
GetGNE()];
2454 for (
int i = 0; i <
GetGNE(); i++)
2455 partitioning[i] = part[i];
2456 SetActive(partitioning, active_bel);
2464 BuildGroups(partitioning, *serial_elem_dof);
2468 for (
int gel = 0, lel = 0; gel <
GetGNE(); gel++)
2474 int *gdofs = serial_elem_dof->
GetRow(gel);
2475 for (
int i = 0; i < ndofs; i++)
2484 : gtopo(par_parent->gtopo.GetComm())
2536 partitioning = NULL;
2539 if (par_parent->partitioning == NULL)
2540 mfem_error(
"ParNURBSExtension::ParNURBSExtension :\n"
2541 " parent ParNURBSExtension has no partitioning!");
2544 Table *serial_elem_dof = GetGlobalElementDofTable();
2545 BuildGroups(par_parent->partitioning, *serial_elem_dof);
2546 delete serial_elem_dof;
2549 Table *ParNURBSExtension::GetGlobalElementDofTable()
2552 return Get2DGlobalElementDofTable();
2554 return Get3DGlobalElementDofTable();
2557 Table *ParNURBSExtension::Get2DGlobalElementDofTable()
2565 for (
int p = 0; p <
GetNP(); p++)
2567 p2g.SetPatchDofMap(p, kv);
2570 for (
int j = 0; j < kv[1]->GetNKS(); j++)
2572 if (kv[1]->isElement(j))
2574 for (
int i = 0; i < kv[0]->GetNKS(); i++)
2576 if (kv[0]->isElement(i))
2578 int *dofs = gel_dof->GetRow(el);
2580 for (
int jj = 0; jj <=
Order; jj++)
2582 for (
int ii = 0; ii <=
Order; ii++)
2584 dofs[idx] = p2g(i+ii,j+jj);
2597 Table *ParNURBSExtension::Get3DGlobalElementDofTable()
2605 for (
int p = 0; p <
GetNP(); p++)
2607 p2g.SetPatchDofMap(p, kv);
2610 for (
int k = 0; k < kv[2]->GetNKS(); k++)
2612 if (kv[2]->isElement(k))
2614 for (
int j = 0; j < kv[1]->GetNKS(); j++)
2616 if (kv[1]->isElement(j))
2618 for (
int i = 0; i < kv[0]->GetNKS(); i++)
2620 if (kv[0]->isElement(i))
2622 int *dofs = gel_dof->GetRow(el);
2624 for (
int kk = 0; kk <=
Order; kk++)
2626 for (
int jj = 0; jj <=
Order; jj++)
2628 for (
int ii = 0; ii <=
Order; ii++)
2630 dofs[idx] = p2g(i+ii,j+jj,k+kk);
2646 void ParNURBSExtension::SetActive(
int *_partitioning,
2647 const Array<bool> &active_bel)
2653 for (
int i = 0; i <
GetGNE(); i++)
2654 if (_partitioning[i] == MyRank)
2662 for (
int i = 0; i <
GetGNBE(); i++)
2667 void ParNURBSExtension::BuildGroups(
int *_partitioning,
const Table &elem_dof)
2671 ListOfIntegerSets groups;
2676 for (
int i = 0; i < dof_proc.Size_of_connections(); i++)
2677 dof_proc.GetJ()[i] = _partitioning[dof_proc.GetJ()[i]];
2681 group.Recreate(1, &MyRank);
2682 groups.Insert(group);
2689 group.Recreate(dof_proc.RowSize(d), dof_proc.GetRow(d));
2700 void NURBSPatchMap::GetPatchKnotVectors(
int p, KnotVector *kv[])
2706 kv[0] = Ext->
KnotVec(edges[0]);
2707 kv[1] = Ext->
KnotVec(edges[1]);
2713 kv[0] = Ext->
KnotVec(edges[0]);
2714 kv[1] = Ext->
KnotVec(edges[3]);
2715 kv[2] = Ext->
KnotVec(edges[8]);
2720 void NURBSPatchMap::GetBdrPatchKnotVectors(
int p, KnotVector *kv[],
int *okv)
2724 kv[0] = Ext->
KnotVec(edges[0], oedge[0], &okv[0]);
2729 kv[1] = Ext->
KnotVec(edges[1], oedge[1], &okv[1]);
2737 GetPatchKnotVectors(p, kv);
2739 I = kv[0]->
GetNE() - 1;
2740 J = kv[1]->
GetNE() - 1;
2742 for (
int i = 0; i < verts.
Size(); i++)
2745 for (
int i = 0; i < edges.
Size(); i++)
2750 K = kv[2]->
GetNE() - 1;
2752 for (
int i = 0; i < faces.
Size(); i++)
2761 GetPatchKnotVectors(p, kv);
2766 for (
int i = 0; i < verts.
Size(); i++)
2769 for (
int i = 0; i < edges.
Size(); i++)
2776 for (
int i = 0; i < faces.
Size(); i++)
2785 GetBdrPatchKnotVectors(p, kv, okv);
2787 I = kv[0]->
GetNE() - 1;
2789 for (
int i = 0; i < verts.
Size(); i++)
2798 J = kv[1]->
GetNE() - 1;
2800 for (
int i = 0; i < edges.
Size(); i++)
2809 GetBdrPatchKnotVectors(p, kv, okv);
2813 for (
int i = 0; i < verts.
Size(); i++)
2824 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 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 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)
Resizes the vector if the new size is different.
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.
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 GetElementEdges(int i, Array< int > &, Array< int > &) const
Return the indices and the orientations of all edges of element i.
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)
friend void Mult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A = B * C.
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 GetBdrElementEdges(int i, Array< int > &, Array< int > &) const
Return the indices and the orientations of all edges of bdr element i.
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 > &)
Abstract finite element space.
Array< int > v_meshOffsets
void swap(Vector *v1, Vector *v2)
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)
void SetSubVector(const Array< int > &dofs, const Vector &elemvect)
Array< int > p_meshOffsets
KnotVector & operator=(const KnotVector &kv)
void GetElementVDofs(int i, Array< int > &dofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
void Set2DSolutionVector(Vector &Nodes)
Table * GetElementDofTable()
NURBSExtension * NURBSext
ParNURBSExtension(MPI_Comm comm, NURBSExtension *parent, int *partitioning, const Array< bool > &active_bel)
Array< KnotVector * > & KnotVectors() const
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 LoadBE(int i, const FiniteElement *BE)
void Print(std::ostream &out) const
void SetSize(int s)
If the matrix is not a square matrix of size s then recreate it.
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)