├── .DS_Store ├── Beam ├── .DS_Store ├── Function Files │ ├── .DS_Store │ ├── FindSpanPS.m │ ├── Thumbs.db │ ├── applyLaGrangeBC.m │ ├── applyLaGrangeBC2D.m │ ├── buildConnectivityPS.m │ ├── computeInternalF.m │ ├── computeK_Lin.m │ ├── computeNonLinearK.m │ ├── computeStrain.m │ ├── computeTanK.m │ ├── displacement.m │ ├── displacement_control_Master.m │ ├── displacement_control_Master2.m │ ├── displacement_control_Master_SnapThrough.m │ ├── findIndexJoel.m │ ├── getConnectivity.m │ ├── getDisp.m │ ├── getDispForce.m │ ├── getFinternal.m │ ├── getFreeDofs.m │ ├── getGeometry.m │ ├── getSctr.m │ ├── initK.m │ ├── partK.m │ └── updateGeometry.m ├── Gifs │ ├── .DS_Store │ ├── DR_Faster.gif │ ├── DR_Slow.gif │ ├── Elastica1.gif │ ├── Elastica2.gif │ ├── Gif_Homogeneous.gif │ ├── Gif_Homogeneous_Outwards.gif │ ├── Gif_StiffEnds.gif │ ├── Gif_VaryingStiffness.gif │ ├── LoadAndUnload1.gif │ └── LoadAndUnload2.gif └── Master Files │ ├── Master_Forward_Euler.m │ └── Master_beam_Joel.m ├── KL Shell ├── .DS_Store ├── Function Files │ ├── .DS_Store │ ├── BasisFunctionsEvaluate.m │ ├── applyKinematicConstraints.m │ ├── assembleSequentialK.m │ ├── checkEq.m │ ├── computeContravariant.m │ ├── computeCouplingConstraints.m │ ├── computeMetricC.m │ ├── computePatchInternalForces.m │ ├── computePatchStress.m │ ├── computeReactionForces.m │ ├── computeStress.m │ ├── getEvalPts.m │ ├── getPatchK.m │ ├── getPatchKLinear.m │ ├── getPatchStress.m │ ├── removeZeroCols.m │ ├── shiftBase2D.m │ ├── shiftBase2DVoigth.m │ └── solveEquations.m └── Resources │ ├── .DS_Store │ ├── NotEndBend.gif │ ├── Surface_e11.gif │ └── testSurface.gif ├── LICENSE ├── README.md └── Util ├── C_files ├── BSPLINE2DBasisDers.c ├── BSPLINE2DBasisDers.mexa64 ├── BSPLINE2DBasisDers.mexmaci64 ├── BSPLINE2DBasisDers.mexw64 ├── FindSpan.c ├── NURBS.c ├── NURBS.h ├── NURBS1DBasis2ndDers.c ├── NURBS1DBasis2ndDers.mexa64 ├── NURBS1DBasis2ndDers.mexmaci64 ├── NURBS1DBasis2ndDers.mexw64 ├── NURBS1DBasisDers.c ├── NURBS1DBasisDers.mexa64 ├── NURBS1DBasisDers.mexmaci64 ├── NURBS1DBasisDers.mexw64 ├── NURBS2DBasis2ndDers.c ├── NURBS2DBasis2ndDers.mexa64 ├── NURBS2DBasis2ndDers.mexmaci64 ├── NURBS2DBasis2ndDers.mexw64 ├── NURBS2DBasisDers.c ├── NURBS2DBasisDers.mexa64 ├── NURBS2DBasisDers.mexmaci64 ├── NURBS2DBasisDers.mexw64 ├── NURBS2DBasisDersSpecial.c ├── NURBS2DBasisDersSpecial.c~ ├── NURBS2DBasisDersSpecial.mexa64 ├── NURBS2DBasisDersSpecial.mexmaci64 ├── NURBS2DBasisDersSpecial.mexw64 ├── NURBS2Dders.c ├── NURBS2Dders.mexa64 ├── NURBS2Dders.mexmaci64 ├── NURBS2Dders.mexw64 ├── NURBS3DBasisDers.c ├── NURBS3DBasisDers.mexa64 ├── NURBS3DBasisDers.mexmaci64 ├── NURBS3DBasisDers.mexw64 ├── NURBS3DBasisDersSpecial.c ├── NURBS3DBasisDersSpecial.mexa64 ├── NURBS3DBasisDersSpecial.mexmaci64 ├── NURBS3DBasisDersSpecial.mexw64 ├── NURBSBasis_Ccode.c ├── NURBSbasis.c ├── NURBSbasis.log ├── NURBSbasis.mexa64 ├── NURBSbasis.mexmaci64 ├── NURBSbasis.mexw64 ├── NURBSfdfd2fInterpolation.c ├── NURBSfdfd2fInterpolation.mexa64 ├── NURBSfdfd2fInterpolation.mexmaci64 ├── NURBSfdfd2fInterpolation.mexw64 ├── NURBSinterpolation.c ├── NURBSinterpolation.mexa64 ├── NURBSinterpolation.mexmaci64 ├── NURBSinterpolation.mexw64 ├── NURBSinterpolation2d.c ├── NURBSplotter.m ├── SimpleSplinePlotter.m └── _NURBSbasis.c.swp ├── C_files_win ├── BSPLINE2DBasisDers.cpp ├── BSPLINE2DBasisDers.mexa64 ├── BSPLINE2DBasisDers.mexmaci64 ├── FindSpan.cpp ├── NURBS.cpp ├── NURBS.h ├── NURBS1DBasis2ndDers.cpp ├── NURBS1DBasis2ndDers.mexa64 ├── NURBS1DBasis2ndDers.mexmaci64 ├── NURBS1DBasisDers.cpp ├── NURBS1DBasisDers.mexa64 ├── NURBS1DBasisDers.mexmaci64 ├── NURBS2DBasis2ndDers.cpp ├── NURBS2DBasis2ndDers.mexa64 ├── NURBS2DBasis2ndDers.mexmaci64 ├── NURBS2DBasisDers.cpp ├── NURBS2DBasisDers.mexa64 ├── NURBS2DBasisDers.mexmaci64 ├── NURBS2DBasisDersSpecial.cpp ├── NURBS2DBasisDersSpecial.c~ ├── NURBS2DBasisDersSpecial.mexa64 ├── NURBS2DBasisDersSpecial.mexmaci64 ├── NURBS2Dders.cpp ├── NURBS2Dders.mexa64 ├── NURBS2Dders.mexmaci64 ├── NURBS3DBasisDers.cpp ├── NURBS3DBasisDers.mexa64 ├── NURBS3DBasisDers.mexmaci64 ├── NURBS3DBasisDersSpecial.cpp ├── NURBS3DBasisDersSpecial.mexa64 ├── NURBS3DBasisDersSpecial.mexmaci64 ├── NURBSBasis_Ccode.cpp ├── NURBSbasis.cpp ├── NURBSbasis.log ├── NURBSbasis.mexa64 ├── NURBSbasis.mexmaci64 ├── NURBSfdfd2fInterpolation.cpp ├── NURBSfdfd2fInterpolation.mexa64 ├── NURBSfdfd2fInterpolation.mexmaci64 ├── NURBSinterpolation.cpp ├── NURBSinterpolation.mexa64 ├── NURBSinterpolation.mexmaci64 ├── NURBSinterpolation2d.cpp ├── NURBSplotter.m ├── SimpleSplinePlotter.m └── _NURBSbasis.c.swp ├── README.md └── nurbs-util ├── BasisFun.m ├── Der1BasisFun.m ├── FindSpan.m ├── RefineKnotVectCurve.m ├── bezierExtraction.m ├── bezierExtraction2D.m ├── bezierExtractionExample.m ├── bsplineBasisDers.m ├── c.txt ├── convert2DNurbs.m ├── convert2DNurbsToPatch.m ├── convert3DNurbs.m ├── dersbasisfuns.m ├── feaplyc2.m ├── gbeam.m ├── genGP_GW.m ├── getNewKnots.m ├── hRefineNURBS.m ├── hRefinement2d.m ├── hRefinement2dUniform.m ├── inverseMapping1DNURBS.m ├── inverseQ4Mapping.m ├── jacobianPaMapping.m ├── jacobianPaPaMapping.m ├── jacobianPaPaMapping3d.m ├── l2err.m ├── nurb2proj.m ├── nurbedge.m ├── nurbshaped.m ├── parent2ParametricSpace.m ├── plotBoundary.m ├── proj2nurbs.m └── visualize.m /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/.DS_Store -------------------------------------------------------------------------------- /Beam/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Beam/.DS_Store -------------------------------------------------------------------------------- /Beam/Function Files/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Beam/Function Files/.DS_Store -------------------------------------------------------------------------------- /Beam/Function Files/FindSpanPS.m: -------------------------------------------------------------------------------- 1 | function knotSpanIndex = FindSpanPS(n,p,u,U) 2 | % knotSpanIndex = FindSpan(n,p,u,U) 3 | %------------------------------------------------------------- 4 | % PURPOSE: 5 | % find the knot span index for one variable u, NURBS-Book 6 | % (algorithm A2.1) 7 | % 8 | % INPUT: n = number of basis function - 1 9 | % p = degree of the basis functions 10 | % u = evaluation point 11 | % U = knot vector (row vector) 12 | % 13 | % OUTPUT: knotSpanIndex = index of knot span 14 | %------------------------------------------------------------- 15 | 16 | if (u == U(n+2)) 17 | knotSpanIndex= n-1; 18 | return 19 | end 20 | low = p; 21 | high = n+1; 22 | mid = floor((low + high)/2); 23 | while (u = U(mid+2) ) 24 | if( u < U(mid+1)) 25 | high = mid; 26 | else 27 | low = mid; 28 | end 29 | mid = floor((low+high)/2); 30 | end 31 | knotSpanIndex = mid; 32 | end -------------------------------------------------------------------------------- /Beam/Function Files/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Beam/Function Files/Thumbs.db -------------------------------------------------------------------------------- /Beam/Function Files/applyLaGrangeBC.m: -------------------------------------------------------------------------------- 1 | function [K_mod,f_mod] = applyLaGrangeBC(Xi_b,Xi_dof,Xi_b_val,p,Xi,Eta,Weights,K,f) 2 | 3 | N = zeros(length(f),length(Xi_b)); 4 | 5 | for i = 1:length(Xi_b) 6 | 7 | Xi_b_temp = Xi_b(i); 8 | Xi_dof_temp = Xi_dof(i); 9 | 10 | 11 | %spanIndex = FindSpanPS(numCpts-1,p,Xi_b_temp,Xi)+1; 12 | 13 | for j = 1:length(Weights) 14 | 15 | if Xi_dof_temp == 1 16 | N(2*j-1,i) = NURBSbasis(j, p, Xi_b_temp, Xi, Weights); 17 | elseif Xi_dof_temp == 2 18 | N(2*j,i) = NURBSbasis(j, p, Xi_b_temp, Xi, Weights); 19 | elseif Xi_dof_temp == 3 20 | 21 | end 22 | 23 | end 24 | 25 | end 26 | 27 | K_mod = [K N; 28 | N' zeros(length(Xi_b))]; 29 | f_mod = [f; 30 | Xi_b_val']; 31 | 32 | 33 | 34 | 35 | end -------------------------------------------------------------------------------- /Beam/Function Files/applyLaGrangeBC2D.m: -------------------------------------------------------------------------------- 1 | function [B,lambda] = applyLaGrangeBC2D(param,Xi_dof,Xi_b_val,n,m,p,q,Xi,Eta,index,element,weights,numDofs) 2 | 3 | 4 | B = zeros(numDofs,size(param,1)); 5 | 6 | 7 | 8 | for i = 1:length(param) 9 | 10 | tempXi = param(i,1); 11 | tempEta = param(i,2); 12 | tempDof = Xi_dof(i); 13 | 14 | % Find element of span 15 | % Xi/Eta span 16 | spanXi = FindSpanPS(n,p,tempXi,Xi)-(p-1); 17 | spanEta = FindSpanPS(m,q,tempEta,Eta)-(q-1); 18 | 19 | for j = 1:length(index) 20 | if index(j,1) == spanXi && index(j,2) == spanEta 21 | e = j; 22 | break 23 | end 24 | end 25 | 26 | ptsInd = element(e,:); 27 | 28 | 29 | % Get dofs/locations for values in stiffness matrix 30 | 31 | currentDofs = zeros(length(ptsInd),1); 32 | 33 | for j = 1:size(element,2) 34 | 35 | if tempDof == 1 36 | currentDofs(j) = 3*ptsInd(j)-2; 37 | elseif tempDof == 2 38 | currentDofs(j) = 3*ptsInd(j)-1; 39 | elseif tempDof == 3 40 | currentDofs(j) = 3*ptsInd(j); 41 | end 42 | 43 | end 44 | 45 | 46 | [R, ~, ~, ~, ~, ~] = NURBS2DBasis2ndDers(... 47 | [tempXi,tempEta], p, q, Xi,Eta, weights); 48 | 49 | B(currentDofs,i) = R'; 50 | lambda = Xi_b_val; 51 | 52 | 53 | end 54 | 55 | 56 | end -------------------------------------------------------------------------------- /Beam/Function Files/buildConnectivityPS.m: -------------------------------------------------------------------------------- 1 | function [elRange,elConn] = buildConnectivityPS(p,knotVec,noElems) 2 | % compute connectivity of 1D NURBS (for one direction) 3 | % also define the element ranges i.e. [xi1,xi2] 4 | % Adapted from the IGABEM code of Robert Simpson, Cardiff, UK 5 | % Vinh Phu Nguyen 6 | % Delft University of Technology, The Netherlands 7 | 8 | elRange = zeros(noElems,2); 9 | elKnotIndices = zeros(noElems,2); 10 | elConn = zeros(noElems,p+1); 11 | ne = length(unique(knotVec))-1; % number of elements 12 | 13 | element = 1; 14 | previousKnotVal = 0; 15 | 16 | for i=1:length(knotVec) 17 | currentKnotVal=knotVec(i); 18 | if knotVec(i)~=previousKnotVal 19 | elRange(element,:)=[previousKnotVal currentKnotVal]; 20 | elKnotIndices(element,:)=[i-1 i]; 21 | element=element+1; 22 | end 23 | previousKnotVal=currentKnotVal; 24 | end 25 | 26 | numRepeatedKnots=0; 27 | 28 | for e=1:ne 29 | indices=(elKnotIndices(e,1)-p+1):elKnotIndices(e,1); 30 | previousKnotVals=knotVec(indices); 31 | currentKnotVals=ones(1,p)*knotVec(elKnotIndices(e,1)); 32 | if isequal(previousKnotVals,currentKnotVals) && length(nonzeros(previousKnotVals))>1; 33 | numRepeatedKnots=numRepeatedKnots+1; 34 | end 35 | elConn(e,:)=(elKnotIndices(e,1)-p):elKnotIndices(e,1); 36 | end -------------------------------------------------------------------------------- /Beam/Function Files/computeInternalF.m: -------------------------------------------------------------------------------- 1 | function [fm,fb] = computeInternalF(ngp,Ex,Ey,defEx,defEy,numDofsPerNode,xiE,Xi,p,Weights,E,A,I,t_pts,t_knot,t_p) 2 | varyingT = 1; 3 | [Q,W] = GetIntegrationConstants(ngp); 4 | 5 | if varyingT == 0 6 | memStiff = E*A; 7 | benStiff = E*I; 8 | end 9 | 10 | elemPts = [Ex Ey]; 11 | defElemPts = [defEx defEy]; 12 | 13 | 14 | fm = zeros(numDofsPerNode*length(Ex),1); 15 | fb = zeros(numDofsPerNode*length(Ex),1); 16 | 17 | for i = 1:ngp 18 | 19 | Q1 = Q(i); 20 | W1 = W(i); 21 | XiCoord = parent2ParametricSpace(xiE, Q1); 22 | 23 | if varyingT == 1 24 | 25 | N_t = zeros(1,length(t_pts)); 26 | 27 | t_weights = ones(1,length(t_pts)); 28 | 29 | for j = 1:length(t_pts) 30 | 31 | N_t(1,j) = NURBSbasis(j, t_p, XiCoord, t_knot, t_weights); 32 | 33 | 34 | end 35 | 36 | t = N_t*t_pts(:,2); 37 | 38 | At = A*t; % A doubles as width in this case 39 | It = A*t^3/12; 40 | 41 | memStiff = E*At; 42 | benStiff = E*It; 43 | 44 | 45 | end 46 | 47 | J1 = jacobianPaMapping(xiE); 48 | 49 | [R, dRdxi, dR2dxi] = NURBS1DBasis2ndDers(XiCoord,p,Xi,Weights); 50 | 51 | jacob1 = dRdxi * defElemPts; 52 | jacob2 = dR2dxi * defElemPts; 53 | 54 | JACOB1 = dRdxi * elemPts; 55 | JACOB2 = dR2dxi * elemPts; 56 | 57 | % Base Vector 58 | 59 | a1 = jacob1; 60 | A1 = JACOB1; 61 | 62 | a3 = [-a1(2),a1(1)]; 63 | A3 = [-A1(2),A1(1)]; 64 | 65 | norma1 = norm(a1); 66 | norma3 = norm(a3); 67 | 68 | normA1 = norm(A1); 69 | normA3 = norm(A3); 70 | 71 | a3 = a3/norma3; 72 | A3 = A3/normA3; 73 | J2 = normA1; 74 | 75 | % C "MATRIX" 76 | 77 | a11 = dot(a1,a1); 78 | A11 = dot(A1,A1); 79 | 80 | b11 = dot(jacob2,a3); 81 | B11 = dot(JACOB2,A3); 82 | 83 | C = 1/A11^2; 84 | 85 | %Compute Strains 86 | 87 | epsilon = 1/2*(a11 - A11); 88 | kappa = B11 - b11; 89 | 90 | noBasis = length(R); 91 | Bm = zeros(1,noBasis*numDofsPerNode)'; 92 | Bb = zeros(1,noBasis*numDofsPerNode)'; 93 | 94 | for k = 1:noBasis 95 | 96 | dRIdx = dRdxi(k); 97 | dRI2dx = dR2dxi(k); 98 | 99 | id = [(2*k)-1 2*k]; 100 | 101 | Bm(id) = [dRIdx*a1(1) dRIdx*a1(2)]; 102 | Bb(id) = [-dRI2dx*a3(1)+1/normA3*jacob2(2)*dRIdx -dRI2dx*a3(2)+1/normA3*jacob2(1)*dRIdx]; 103 | 104 | end 105 | 106 | fm = fm + memStiff * epsilon * C * Bm * J1 * J2 * W1; 107 | fb = fb + benStiff * kappa * C * Bb * J1 * J2 * W1; 108 | end 109 | 110 | 111 | 112 | end 113 | -------------------------------------------------------------------------------- /Beam/Function Files/computeK_Lin.m: -------------------------------------------------------------------------------- 1 | function [Km,Kb] = computeK_Lin(ngp,Ex,Ey,numDofsPerNode,xiE,Xi,p,Weights,E,A,I,t_pts,t_knot,t_p) 2 | 3 | varyingT = 1; 4 | 5 | [Q,W] = GetIntegrationConstants(ngp); 6 | 7 | if varyingT == 0 8 | memStiff = E*A; 9 | benStiff = E*I; 10 | end 11 | 12 | elemPts = [Ex Ey]; 13 | Km = zeros(numDofsPerNode*length(Ex),numDofsPerNode*length(Ex)); 14 | Kb = zeros(numDofsPerNode*length(Ex),numDofsPerNode*length(Ex)); 15 | fb = zeros(numDofsPerNode*length(Ex),1); 16 | 17 | for i = 1:ngp 18 | 19 | Q1 = Q(i); 20 | W1 = W(i); 21 | XiCoord = parent2ParametricSpace(xiE, Q1); 22 | 23 | if varyingT == 1 24 | 25 | N_t = zeros(1,length(t_pts)); 26 | 27 | t_weights = ones(1,length(t_pts)); 28 | 29 | for j = 1:length(t_pts) 30 | 31 | N_t(1,j) = NURBSbasis(j, t_p, XiCoord, t_knot, t_weights); 32 | 33 | 34 | end 35 | 36 | t = N_t*t_pts(:,2); 37 | 38 | At = A*t; % A doubles as width in this case 39 | It = A*t^3/12; 40 | 41 | memStiff = E*At; 42 | benStiff = E*It; 43 | 44 | 45 | end 46 | 47 | J1 = jacobianPaMapping(xiE); 48 | 49 | [R, dRdxi, dR2dxi] = NURBS1DBasis2ndDers(XiCoord,p,Xi,Weights); 50 | 51 | jacob1 = dRdxi * elemPts; 52 | jacob2 = dR2dxi * elemPts; 53 | 54 | % Base Vector 55 | 56 | a1 = jacob1; 57 | 58 | a3 = [-a1(2),a1(1)]; 59 | 60 | norma1 = norm(a1); 61 | norma3 = norm(a3); 62 | 63 | a3 = a3/norma3; 64 | J2 = norma1; 65 | 66 | % C "MATRIX" 67 | 68 | a11 = dot(a1,a1); 69 | 70 | C = 1/a11^2; 71 | 72 | noBasis = length(R); 73 | Bm = zeros(1,noBasis*numDofsPerNode); 74 | Bb = zeros(1,noBasis*numDofsPerNode); 75 | 76 | for k = 1:noBasis 77 | 78 | dRIdx = dRdxi(k); 79 | dRI2dx = dR2dxi(k); 80 | 81 | id = [(2*k)-1 2*k]; 82 | 83 | Bm(1,id) = [dRIdx*a1(1) dRIdx*a1(2)]; 84 | Bb(1,id) = [-dRI2dx*a3(1)+1/norma3*jacob2(2)*dRIdx -dRI2dx*a3(2)+1/norma3*jacob2(1)*dRIdx]; 85 | 86 | end 87 | 88 | Km = Km + memStiff * Bm' * C * Bm * J1 * J2 * W1; 89 | Kb = Kb + benStiff * Bb' * C * Bb * J1 * J2 * W1; 90 | end 91 | 92 | end -------------------------------------------------------------------------------- /Beam/Function Files/computeNonLinearK.m: -------------------------------------------------------------------------------- 1 | function [KmNL,KbNL] = computeNonLinearK(ngp,Ex,Ey,refEx,refEy,numDofsPerNode,xiE,Xi,p,Weights,E,A,I,t_pts,t_knot,t_p) 2 | 3 | varyingT = 1; 4 | 5 | [Q,W] = GetIntegrationConstants(ngp); 6 | 7 | if varyingT == 0 8 | memStiff = E*A; 9 | benStiff = E*I; 10 | end 11 | 12 | elemPts = [refEx refEy]; 13 | defElemPts = [Ex Ey]; 14 | 15 | 16 | KmNL = zeros(numDofsPerNode*length(Ex),numDofsPerNode*length(Ex)); 17 | KbNL = zeros(numDofsPerNode*length(Ex),numDofsPerNode*length(Ex)); 18 | 19 | for i = 1:ngp 20 | 21 | Q1 = Q(i); 22 | W1 = W(i); 23 | XiCoord = parent2ParametricSpace(xiE, Q1); 24 | 25 | if varyingT == 1 26 | 27 | N_t = zeros(1,length(t_pts)); 28 | 29 | t_weights = ones(1,length(t_pts)); 30 | 31 | for j = 1:length(t_pts) 32 | 33 | N_t(1,j) = NURBSbasis(j, t_p, XiCoord, t_knot, t_weights); 34 | 35 | 36 | end 37 | 38 | t = N_t*t_pts(:,2); 39 | 40 | At = A*t; % A doubles as width in this case 41 | It = A*t^3/12; 42 | 43 | memStiff = E*At; 44 | benStiff = E*It; 45 | 46 | 47 | end 48 | 49 | J1 = jacobianPaMapping(xiE); 50 | 51 | [R, dRdxi, dR2dxi] = NURBS1DBasis2ndDers(XiCoord,p,Xi,Weights); 52 | 53 | jacob1 = dRdxi * defElemPts; 54 | jacob2 = dR2dxi * defElemPts; 55 | 56 | JACOB1 = dRdxi * elemPts; 57 | JACOB2 = dR2dxi * elemPts; 58 | 59 | % Base Vector 60 | 61 | a1 = jacob1; 62 | A1 = JACOB1; 63 | 64 | a3 = [-a1(2),a1(1)]; 65 | A3 = [-A1(2),A1(1)]; 66 | 67 | norma1 = norm(a1); 68 | norma3 = norm(a3); 69 | 70 | normA1 = norm(A1); 71 | normA3 = norm(A3); 72 | 73 | a3 = a3/norma3; 74 | A3 = A3/normA3; 75 | J2 = normA1; 76 | 77 | % C "MATRIX" 78 | 79 | a11 = dot(a1,a1); 80 | A11 = dot(A1,A1); 81 | 82 | b11 = dot(jacob2,a3); 83 | B11 = dot(JACOB2,A3); 84 | 85 | C = 1/A11^2; 86 | 87 | %Compute Strains 88 | 89 | epsilon = 1/2*(a11 - A11); 90 | kappa = B11 - b11; 91 | 92 | noBasis = length(R); 93 | Bm_vecNL = zeros(2,noBasis*numDofsPerNode); 94 | Bb_vecNL_1 = zeros(2,noBasis*numDofsPerNode); 95 | Bb_vecNL_2 = zeros(2,noBasis*numDofsPerNode); 96 | 97 | for k = 1:noBasis 98 | 99 | dRIdx = dRdxi(k); 100 | dRI2dx = dR2dxi(k); 101 | 102 | id = [(2*k)-1 2*k]; 103 | 104 | Bm_vecNL(1:2,id) = [dRIdx 0; 105 | 0 dRIdx]; 106 | 107 | % FIX 108 | Bb_vecNL_1(1:2,id) = 1/norma3*[dRI2dx 0; 109 | 0 dRI2dx]; 110 | 111 | Bb_vecNL_2(1:2,id) = 1/norma3*[0 -dRIdx; 112 | dRIdx 0]; 113 | 114 | 115 | 116 | end 117 | 118 | BmNL = Bm_vecNL'*Bm_vecNL; 119 | Bb_vec_partNL = Bb_vecNL_1'*Bb_vecNL_2; 120 | 121 | BbNL = Bb_vec_partNL+Bb_vec_partNL'; 122 | 123 | KmNL = KmNL + memStiff * epsilon * C * BmNL * J1 * J2 * W1; 124 | KbNL = KbNL + benStiff * kappa * C * (BbNL) * J1 * J2 * W1; %Sign on BbNL? 125 | end 126 | 127 | end -------------------------------------------------------------------------------- /Beam/Function Files/computeStrain.m: -------------------------------------------------------------------------------- 1 | function [kappa_xi,epsilon_x,nVecRef,nVecDef,A_pos,a_pos] = computeStrain(xi_coord,numCpts,p,Xi,Weights,refPts,currentPts) 2 | % Normal Strain 3 | 4 | %Evaluate Derivatives 5 | 6 | dNdxi = zeros(length(xi_coord),numCpts); 7 | dN2dxi = zeros(length(xi_coord),numCpts); 8 | N = zeros(length(xi_coord),numCpts); 9 | 10 | ind = 1; 11 | 12 | for i = 1:length(xi_coord) 13 | 14 | xi_p = xi_coord(i); 15 | 16 | span_ind = FindSpan(numCpts-1,p,xi_p,Xi); 17 | 18 | [R, dRdxi, dR2dxi] = NURBS1DBasis2ndDers(xi_p,p,Xi,Weights); 19 | dN2dxi(ind,span_ind-p+1:span_ind+1) = dR2dxi; 20 | dNdxi(ind,span_ind-p+1:span_ind+1) = dRdxi; 21 | N(ind,span_ind-p+1:span_ind+1) = R; 22 | 23 | ind = ind + 1; 24 | end 25 | 26 | A_pos = N*refPts; 27 | a_pos = N*currentPts; 28 | 29 | A_xi = dNdxi*refPts; 30 | a_xi = dNdxi*currentPts; 31 | 32 | dot_Axi = zeros(length(A_xi),1); 33 | dot_axi = zeros(length(A_xi),1); 34 | 35 | A_xixi = dN2dxi*refPts; 36 | a_xixi = dN2dxi*currentPts; 37 | 38 | A3_ = [-A_xi(:,2),A_xi(:,1)]; 39 | a3_ = [-a_xi(:,2),a_xi(:,1)]; 40 | 41 | A3_norm = normr(A3_); 42 | a3_norm = normr(a3_); 43 | 44 | nVecDef = a3_norm; 45 | nVecRef = A3_norm; 46 | 47 | b_xi = zeros(length(A_xixi),1); 48 | B_xi = zeros(length(A_xixi),1); 49 | 50 | for i = 1:length(A_xi) 51 | 52 | dot_Axi_temp = (A_xi(i,1)*A_xi(i,1)+A_xi(i,2)*A_xi(i,2)); 53 | dot_axi_temp = (a_xi(i,1)*a_xi(i,1)+a_xi(i,2)*a_xi(i,2)); 54 | 55 | dot_Axi(i) = dot_Axi_temp/dot_Axi_temp; 56 | dot_axi(i) = dot_axi_temp/dot_Axi_temp; 57 | 58 | b_xi_temp = a_xixi(i,1)*a3_norm(i,1) + a_xixi(i,2)*a3_norm(i,2); 59 | B_xi_temp = A_xixi(i,1)*A3_norm(i,1) + A_xixi(i,2)*A3_norm(i,2); 60 | 61 | b_xi(i) = b_xi_temp/dot_Axi_temp; 62 | B_xi(i) = B_xi_temp/dot_Axi_temp; 63 | end 64 | 65 | epsilon_x = 1/2*(dot_axi - dot_Axi); 66 | 67 | kappa_xi = B_xi - b_xi; -------------------------------------------------------------------------------- /Beam/Function Files/computeTanK.m: -------------------------------------------------------------------------------- 1 | function [K,KNL] = computeTanK(ngp,pts,refPts,numDofsPerNode,Xi,p,Weights,E,A,I,elRange,elConn,numElems,sctr,K,KNL,t) 2 | 3 | %Prepare Height Map. 4 | 5 | t_val = cell2mat(t(1)); 6 | t_knot = cell2mat(t(2)); 7 | t_p = cell2mat(t(3)); 8 | 9 | t_pts = zeros(length(t_val),2); 10 | 11 | t_step = 1/(length(t_val)-1); 12 | 13 | for j = 1:length(t_val) 14 | 15 | t_pts(j,:) = [(j-1)*t_step t_val(j)]; 16 | 17 | end 18 | 19 | 20 | for e = 1 : numElems 21 | 22 | xiE = elRange(e,:); 23 | 24 | conn = elConn(e,:); 25 | Ex = pts(conn,1); 26 | Ey = pts(conn,2); 27 | 28 | refEx = refPts(conn,1); 29 | refEy = refPts(conn,2); 30 | 31 | %Compute Linear K 32 | 33 | [Km,Kb] = computeK_Lin(ngp,Ex,Ey,numDofsPerNode,xiE,Xi,p,Weights,E,A,I,t_pts,t_knot,t_p); 34 | 35 | % Compute Non Linear K. 36 | 37 | [KmNL,KbNL] = computeNonLinearK(ngp,Ex,Ey,refEx,refEy,numDofsPerNode,xiE,Xi,p,Weights,E,A,I,t_pts,t_knot,t_p); 38 | 39 | KeL = Km + Kb; 40 | KeNL = KmNL + KbNL; 41 | 42 | Ke = KeL;% + KeNL; 43 | 44 | K(sctr(e,:),sctr(e,:)) = K(sctr(e,:),sctr(e,:)) + Ke; 45 | KNL(sctr(e,:),sctr(e,:)) = KNL(sctr(e,:),sctr(e,:)) + KeNL; 46 | 47 | end -------------------------------------------------------------------------------- /Beam/Function Files/displacement.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Beam/Function Files/displacement.m -------------------------------------------------------------------------------- /Beam/Function Files/findIndexJoel.m: -------------------------------------------------------------------------------- 1 | function index = findIndexJoel(vec,dof) 2 | lenVec = length(vec); 3 | 4 | for i = 1:lenVec 5 | dofVec = vec(i); 6 | if abs(dof - dofVec) < 0.0001 7 | index = i; 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /Beam/Function Files/getConnectivity.m: -------------------------------------------------------------------------------- 1 | function [elRange,elConn,index,numElems] = getConnectivity(Xi,p) 2 | 3 | uniqueXiKnots = unique(Xi); 4 | numElems = length(uniqueXiKnots)-1; 5 | 6 | [elRange,elConn] = buildConnectivityPS(p,Xi,numElems); 7 | 8 | index = zeros(numElems,1); 9 | 10 | for i = 1:numElems 11 | index(i,1) = i; 12 | end 13 | 14 | 15 | end -------------------------------------------------------------------------------- /Beam/Function Files/getDisp.m: -------------------------------------------------------------------------------- 1 | function [a,ax,ay] = getDispForce(a_temp,r_temp,f_temp,numDofs) 2 | 3 | a = a_temp(1:numDofs); 4 | a = a_temp(1:numDofs); 5 | 6 | numCpts = numDofs/2; 7 | 8 | ax = zeros(numCpts,1); 9 | ay = zeros(numCpts,1); 10 | 11 | j = 1; 12 | for i = 1:2:length(a) 13 | 14 | ax(j) = a(i); 15 | ay(j) = a(i+1); 16 | 17 | j = j + 1; 18 | end 19 | 20 | 21 | end -------------------------------------------------------------------------------- /Beam/Function Files/getDispForce.m: -------------------------------------------------------------------------------- 1 | function [a,ax,ay,r,f] = getDispForce(a_temp,r_temp,f_temp,numDofs) 2 | 3 | a = a_temp(1:numDofs); 4 | r = r_temp(1:numDofs); 5 | f = f_temp(1:numDofs); 6 | 7 | numCpts = numDofs/2; 8 | 9 | ax = zeros(numCpts,1); 10 | ay = zeros(numCpts,1); 11 | 12 | j = 1; 13 | for i = 1:2:length(a) 14 | 15 | ax(j) = a(i); 16 | ay(j) = a(i+1); 17 | 18 | j = j + 1; 19 | end 20 | 21 | 22 | end -------------------------------------------------------------------------------- /Beam/Function Files/getFinternal.m: -------------------------------------------------------------------------------- 1 | function [fi_current] = getFinternal(ngp,pts,refPts,numDofsPerNode,Xi,p,Weights,E,A,I,numElems,elConn,elRange,sctr,t) 2 | 3 | %Prepare Height Map. 4 | 5 | t_val = cell2mat(t(1)); 6 | t_knot = cell2mat(t(2)); 7 | t_p = cell2mat(t(3)); 8 | 9 | t_pts = zeros(length(t_val),2); 10 | 11 | t_step = 1/(length(t_val)-1); 12 | 13 | for j = 1:length(t_val) 14 | 15 | t_pts(j,:) = [(j-1)*t_step t_val(j)]; 16 | 17 | end 18 | 19 | numDofs = numDofsPerNode*length(Weights); 20 | 21 | fi_current = zeros(numDofs,1); 22 | 23 | for e = 1:numElems 24 | 25 | xiE = elRange(e,:); 26 | 27 | conn = elConn(e,:); 28 | 29 | Ex = refPts(conn,1); 30 | Ey = refPts(conn,2); 31 | 32 | defEx = pts(conn,1); 33 | defEy = pts(conn,2); 34 | 35 | [fm,fb] = computeInternalF(ngp,Ex,Ey,defEx,defEy,numDofsPerNode,xiE,Xi,p,Weights,E,A,I,t_pts,t_knot,t_p); 36 | 37 | fie = fm + fb; 38 | fi_current(sctr(e,:)) = fi_current(sctr(e,:)) + fie; 39 | end 40 | 41 | end 42 | 43 | 44 | -------------------------------------------------------------------------------- /Beam/Function Files/getFreeDofs.m: -------------------------------------------------------------------------------- 1 | function [freeDofs] = getFreeDofs(numDofs,zero_bc,nonzero_bc) 2 | 3 | freeDofs = zeros(numDofs-length(zero_bc)-length(nonzero_bc),1); 4 | i = 1; 5 | for dof = 1:numDofs 6 | dofConstrained = false; 7 | for zeroDofId = 1:length(zero_bc) 8 | zeroDof = zero_bc(zeroDofId); 9 | if dof == zeroDof 10 | dofConstrained = true; 11 | end 12 | end 13 | for nonzeroDofId = 1:length(nonzero_bc) 14 | nonzeroDof = nonzero_bc(nonzeroDofId); 15 | if dof == nonzeroDof 16 | dofConstrained = true; 17 | end 18 | end 19 | if dofConstrained 20 | else 21 | freeDofs(i) = dof; 22 | i = i+1; 23 | end 24 | end 25 | 26 | end -------------------------------------------------------------------------------- /Beam/Function Files/getGeometry.m: -------------------------------------------------------------------------------- 1 | function [pts, Xi, Weights] = getGeometry(p,y0,x0) 2 | 3 | %Curve data is taken from rhino 4 | if p == 1 5 | 6 | ptsX = [0; 7 | 0.178571; 8 | 0.535714; 9 | 1.071429; 10 | 1.785714; 11 | 2.5; 12 | 3.214286; 13 | 3.928571; 14 | 4.464286; 15 | 4.821429; 16 | 5]; 17 | 18 | ptsY= [2; 19 | 1.928571; 20 | 1.785714; 21 | 1.571429; 22 | 1.285714; 23 | 1; 24 | 0.714286; 25 | 0.428571; 26 | 0.214286; 27 | 0.071429; 28 | 0]; 29 | 30 | pts=[ptsX*x0 ptsY*y0]; 31 | 32 | Xi = [0 0 0 0 0 0.142857 0.285714 0.428571 0.571429 0.714286 0.857143 1 1 1 1 1]; 33 | 34 | end 35 | 36 | if p == 3 37 | 38 | ptsX = [0; 39 | 0.411282; 40 | 1.237762; 41 | 2.486612; 42 | 3.741717; 43 | 5.0; 44 | 6.258283; 45 | 7.513388; 46 | 8.762238; 47 | 9.588718; 48 | 10]; 49 | 50 | 51 | ptsY = [0; 52 | 0.082258; 53 | 0.227239; 54 | 0.384116; 55 | 0.478872; 56 | 0.510564; 57 | 0.478872; 58 | 0.384116; 59 | 0.227239; 60 | 0.082258; 61 | 0]; 62 | 63 | pts=[ptsX*x0 ptsY*y0]; 64 | Weights = [1 1 1 1 1 1 1 1 1 1 1]; 65 | 66 | Xi = [0 0 0 0 0.125 0.25 0.375 0.5 0.625 0.75 0.875 1 1 1 1]; 67 | 68 | end 69 | 70 | if p == 4 71 | 72 | ptsX = [0; 73 | 0.352528; 74 | 1.060134; 75 | 2.128276; 76 | 3.561764; 77 | 5.0; 78 | 6.438237; 79 | 7.871723; 80 | 8.939866; 81 | 9.647472; 82 | 10]; 83 | 84 | 85 | ptsY = [0; 86 | 0.070506; 87 | 0.198772; 88 | 0.352093; 89 | 0.475831; 90 | 0.517259; 91 | 0.475831; 92 | 0.352093; 93 | 0.198772; 94 | 0.070506; 95 | 0]; 96 | Weights = [1 1 1 1 1 1 1 1 1 1 1]; 97 | 98 | 99 | pts=[ptsX*x0 ptsY*y0]; 100 | 101 | Xi = [0 0 0 0 0 0.142857 0.285714 0.428571 0.571429 0.714286 0.857143 1 1 1 1 1]; 102 | end 103 | 104 | 105 | if p == 11 106 | 107 | ptsX = [0 108 | 0.044867 109 | 0.134636 110 | 0.269389 111 | 0.449262 112 | 0.674418 113 | 0.945079 114 | 1.261446 115 | 1.623785 116 | 2.032285 117 | 2.487155 118 | 2.98851 119 | 3.490672 120 | 3.99344 121 | 4.49662 122 | 4.999999 123 | 5.503383 124 | 6.006557 125 | 6.509333 126 | 7.011484 127 | 7.512853 128 | 7.967705 129 | 8.376226 130 | 8.738542 131 | 9.054932 132 | 9.325574 133 | 9.550742 134 | 9.730609 135 | 9.865365 136 | 9.955133 137 | 10 138 | ]; 139 | 140 | 141 | ptsY = [0 142 | 0.008974 143 | 0.02675 144 | 0.052903 145 | 0.086746 146 | 0.127331 147 | 0.17343 148 | 0.223567 149 | 0.275916 150 | 0.328426 151 | 0.378749 152 | 0.424098 153 | 0.459494 154 | 0.484804 155 | 0.499978 156 | 0.505092 157 | 0.499978 158 | 0.484805 159 | 0.459493 160 | 0.424098 161 | 0.378748 162 | 0.328428 163 | 0.275914 164 | 0.223569 165 | 0.173428 166 | 0.127332 167 | 0.086745 168 | 0.052904 169 | 0.02675 170 | 0.008974 171 | 0 172 | ]; 173 | 174 | Weights = [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]; 175 | 176 | 177 | pts=[ptsX*x0 ptsY*y0]; 178 | 179 | Xi = [0 180 | 0 181 | 0 182 | 0 183 | 0 184 | 0 185 | 0 186 | 0 187 | 0 188 | 0 189 | 0 190 | 0 191 | 0.05 192 | 0.1 193 | 0.15 194 | 0.2 195 | 0.25 196 | 0.3 197 | 0.35 198 | 0.4 199 | 0.45 200 | 0.5 201 | 0.55 202 | 0.6 203 | 0.65 204 | 0.7 205 | 0.75 206 | 0.8 207 | 0.85 208 | 0.9 209 | 0.95 210 | 1 211 | 1 212 | 1 213 | 1 214 | 1 215 | 1 216 | 1 217 | 1 218 | 1 219 | 1 220 | 1 221 | 1 222 | ]'; 223 | end 224 | 225 | 226 | 227 | 228 | end 229 | -------------------------------------------------------------------------------- /Beam/Function Files/getSctr.m: -------------------------------------------------------------------------------- 1 | function [numCpts,numDofsPerNode,numDofs,nodesPerElem,sctr] = getSctr(elConn,pts,numElems) 2 | 3 | 4 | 5 | numCpts = length(pts); 6 | numDofsPerNode = length(pts(1,:)); 7 | 8 | numDofs = numCpts*numDofsPerNode; 9 | 10 | nodesPerElem = length(elConn(1,:)); 11 | 12 | sctr = zeros(numElems,nodesPerElem*numDofsPerNode); 13 | 14 | 15 | for i = 1 : numElems 16 | 17 | for j = 1 : nodesPerElem 18 | 19 | sctr(i,(2*j)-1) = (2*elConn(i,j))-1; 20 | sctr(i,(2*j)) = (2*elConn(i,j)); 21 | 22 | end 23 | 24 | end 25 | 26 | end -------------------------------------------------------------------------------- /Beam/Function Files/initK.m: -------------------------------------------------------------------------------- 1 | function [K,Kmm,Kbb,f,fi] = initK(numDofs) 2 | 3 | K = zeros(numDofs, numDofs); 4 | Kmm = zeros(numDofs, numDofs); 5 | Kbb = zeros(numDofs, numDofs); 6 | f = zeros(numDofs, 1); 7 | fi = zeros(numDofs, 1); 8 | 9 | end -------------------------------------------------------------------------------- /Beam/Function Files/partK.m: -------------------------------------------------------------------------------- 1 | function [Kff,Kfc,Kcc] = partK(freeDofs,constrDofs,K) 2 | 3 | Kff = K(freeDofs,freeDofs); 4 | Kfc = K(freeDofs,constrDofs); 5 | Kcc = K(constrDofs,constrDofs); 6 | 7 | end -------------------------------------------------------------------------------- /Beam/Function Files/updateGeometry.m: -------------------------------------------------------------------------------- 1 | function [defPts] = updateGeometry(pts,a, scaleFact) 2 | 3 | numCpts = length(pts); 4 | dim = size(pts,2); 5 | 6 | defPts = zeros(numCpts,dim); 7 | 8 | for i = 1:numCpts 9 | if dim == 2 10 | defPts(i,:) = pts(i,:) + scaleFact*[a((2*i)-1) a(2*i)]; 11 | elseif dim == 3 12 | defPts(i,:) = pts(i,:) + scaleFact*[a((3*i)-2) a((3*i)-1) a(3*i)]; 13 | end 14 | end 15 | 16 | end -------------------------------------------------------------------------------- /Beam/Gifs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Beam/Gifs/.DS_Store -------------------------------------------------------------------------------- /Beam/Gifs/DR_Faster.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Beam/Gifs/DR_Faster.gif -------------------------------------------------------------------------------- /Beam/Gifs/DR_Slow.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Beam/Gifs/DR_Slow.gif -------------------------------------------------------------------------------- /Beam/Gifs/Elastica1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Beam/Gifs/Elastica1.gif -------------------------------------------------------------------------------- /Beam/Gifs/Elastica2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Beam/Gifs/Elastica2.gif -------------------------------------------------------------------------------- /Beam/Gifs/Gif_Homogeneous.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Beam/Gifs/Gif_Homogeneous.gif -------------------------------------------------------------------------------- /Beam/Gifs/Gif_Homogeneous_Outwards.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Beam/Gifs/Gif_Homogeneous_Outwards.gif -------------------------------------------------------------------------------- /Beam/Gifs/Gif_StiffEnds.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Beam/Gifs/Gif_StiffEnds.gif -------------------------------------------------------------------------------- /Beam/Gifs/Gif_VaryingStiffness.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Beam/Gifs/Gif_VaryingStiffness.gif -------------------------------------------------------------------------------- /Beam/Gifs/LoadAndUnload1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Beam/Gifs/LoadAndUnload1.gif -------------------------------------------------------------------------------- /Beam/Gifs/LoadAndUnload2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Beam/Gifs/LoadAndUnload2.gif -------------------------------------------------------------------------------- /KL Shell/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/KL Shell/.DS_Store -------------------------------------------------------------------------------- /KL Shell/Function Files/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/KL Shell/Function Files/.DS_Store -------------------------------------------------------------------------------- /KL Shell/Function Files/BasisFunctionsEvaluate.m: -------------------------------------------------------------------------------- 1 | function [BasisFun,GpW,GpJ,u,v] = BasisFunctionsEvaluate(p,q,ngp,numOfEl,index,elRangeXi,elRangeEta,Xi,Eta,weights) 2 | 3 | BasisFun = zeros((p+1)*(q+1),6,ngp*ngp,numOfEl); 4 | GpW = zeros(ngp*ngp); 5 | GpJ = zeros(ngp*ngp,numOfEl); 6 | u = zeros(ngp*ngp,numOfEl); 7 | v = zeros(ngp*ngp,numOfEl); 8 | 9 | for e = 1 : numOfEl 10 | 11 | xiID = index(e,1); 12 | etaID = index(e,2); 13 | xiE = elRangeXi(xiID,:); 14 | etaE = elRangeEta(etaID,:); 15 | 16 | [Q,W] = GetIntegrationConstants(ngp); 17 | 18 | gp = 1; 19 | for i = 1:ngp 20 | Q1 = Q(i); 21 | w1 = W(i); 22 | 23 | for j = 1:ngp 24 | 25 | Q2 = Q(j); 26 | w2 = W(j); 27 | xiVal = parent2ParametricSpace(xiE, Q1); 28 | etaVal = parent2ParametricSpace(etaE,Q2); 29 | J1 = jacobianPaPaMapping(xiE,etaE); 30 | 31 | u(gp,e) = xiVal; 32 | v(gp,e) = etaVal; 33 | 34 | [R, dRdxi, dRdeta, dR2dxi, dR2det, dR2dxe] = ... 35 | NURBS2DBasis2ndDers([xiVal; etaVal],p,q,Xi,Eta,weights'); 36 | 37 | BasisFun(:,:,gp,e) = [R' dRdxi' dRdeta' dR2dxi' dR2det' dR2dxe']; 38 | GpW(gp) = w1*w2; 39 | GpJ(gp,e) = J1; 40 | gp = gp + 1; 41 | 42 | end 43 | end 44 | end 45 | 46 | end -------------------------------------------------------------------------------- /KL Shell/Function Files/applyKinematicConstraints.m: -------------------------------------------------------------------------------- 1 | function [K,f_e,f_i] = applyKinematicConstraints(B,K,f_e,f_i,u_c) 2 | 3 | 4 | [B,keepCols1] = removeZeroCols(B); 5 | 6 | if nargin == 4 7 | u_c = zeros(size(B,2),1); 8 | end 9 | 10 | u_c = u_c(keepCols1); 11 | 12 | additionalSize = size(K,1) - size(B,1); 13 | 14 | if additionalSize == 1 15 | 16 | K = [K B; 17 | B' zeros(size(B,2))]; 18 | else 19 | 20 | K = [K [B; zeros(additionalSize,size(B,2))]; 21 | [B; zeros(additionalSize,size(B,2))]' zeros(size(B,2))]; 22 | 23 | end 24 | 25 | 26 | 27 | f_e = [f_e; 28 | u_c]; 29 | 30 | 31 | f_i = [f_i; 32 | zeros(size(u_c,1),1)]; 33 | 34 | 35 | 36 | end -------------------------------------------------------------------------------- /KL Shell/Function Files/assembleSequentialK.m: -------------------------------------------------------------------------------- 1 | function [K] = assembleSequentialK(K1,K2) 2 | 3 | size1 = size(K1,1); 4 | size2 = size(K2,1); 5 | 6 | zeroK = zeros(size1,size2); 7 | 8 | K = [K1 zeroK; 9 | zeroK' K2]; 10 | 11 | end 12 | 13 | -------------------------------------------------------------------------------- /KL Shell/Function Files/checkEq.m: -------------------------------------------------------------------------------- 1 | function [maxDiff,fDiff] = checkEq(freeDofs,f_i,f_e,r_LG) 2 | 3 | fi_f = f_i(freeDofs); 4 | fe_f = f_e(freeDofs); 5 | 6 | fi_res = abs(fi_f-fe_f); 7 | 8 | fDiff = abs(fi_res) - abs(r_LG); 9 | 10 | maxDiff = max(abs(fi_res) - abs(r_LG)); 11 | 12 | end -------------------------------------------------------------------------------- /KL Shell/Function Files/computeContravariant.m: -------------------------------------------------------------------------------- 1 | function [a1_c,a2_c] = computeContravariant(a1,a2) 2 | 3 | a1a2 = [a1; a2]; 4 | 5 | a1_c = a1a2 \ [1;0]; 6 | a2_c = a1a2 \ [0;1]; 7 | 8 | end -------------------------------------------------------------------------------- /KL Shell/Function Files/computeCouplingConstraints.m: -------------------------------------------------------------------------------- 1 | function [B] = computeCouplingConstraints(u,v,dof,n,m,p,q,Xi1,Xi2,Eta1,Eta2,index1,index2,elementGlobal1,elementGlobal2,weights1,weights2,numDofs) 2 | 3 | 4 | 5 | B = zeros(numDofs,1); 6 | % Return column matrix for one couple. 7 | % Compute shape functions for each node. 8 | 9 | spanXi1 = FindSpanPS(n(1),p(1),u(1),Xi1)-(p(1)-1); 10 | spanEta1 = FindSpanPS(m(1),q(1),v(1),Eta1)-(q(1)-1); 11 | 12 | spanXi2 = FindSpanPS(n(2),p(2),u(2),Xi2)-(p(2)-1); 13 | spanEta2 = FindSpanPS(m(2),q(2),v(2),Eta2)-(q(2)-1); 14 | 15 | for j = 1:length(index1) 16 | if index1(j,1) == spanXi1 && index1(j,2) == spanEta1 17 | e1 = j; 18 | break 19 | end 20 | end 21 | 22 | for j = 1:length(index2) 23 | if index1(j,1) == spanXi2 && index2(j,2) == spanEta2 24 | e2 = j; 25 | break 26 | end 27 | end 28 | 29 | ptsInd1 = elementGlobal1(e1,:); 30 | ptsInd2 = elementGlobal2(e2,:); 31 | 32 | % Get dofs/locations for values in stiffness matrix 33 | 34 | currentDofs1 = zeros(length(ptsInd1),1); 35 | currentDofs2 = zeros(length(ptsInd2),1); 36 | 37 | for j = 1:size(elementGlobal1,2) 38 | 39 | if dof == 1 40 | currentDofs1(j) = 3*ptsInd1(j)-2; 41 | elseif dof == 2 42 | currentDofs1(j) = 3*ptsInd1(j)-1; 43 | elseif dof == 3 44 | currentDofs1(j) = 3*ptsInd1(j); 45 | end 46 | 47 | end 48 | 49 | for j = 1:size(elementGlobal2,2) 50 | 51 | if dof == 1 52 | currentDofs2(j) = 3*ptsInd2(j)-2; 53 | elseif dof == 2 54 | currentDofs2(j) = 3*ptsInd2(j)-1; 55 | elseif dof == 3 56 | currentDofs2(j) = 3*ptsInd2(j); 57 | end 58 | 59 | end 60 | 61 | 62 | [R1, ~, ~, ~, ~, ~] = NURBS2DBasis2ndDers([u(1),v(1)], p(1), q(1), Xi1,Eta1, weights1); 63 | 64 | 65 | [R2, ~, ~, ~, ~, ~] = NURBS2DBasis2ndDers([u(2),v(2)], p(2), q(2), Xi2,Eta2, weights2); 66 | B(currentDofs1) = B(currentDofs1) + R1'; 67 | B(currentDofs2) = B(currentDofs2)-R2'; 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | end 76 | -------------------------------------------------------------------------------- /KL Shell/Function Files/computeMetricC.m: -------------------------------------------------------------------------------- 1 | function [alpha,beta] = computeMetricC(a1,a2,a11,a12,a22,a3) 2 | 3 | alpha = zeros(2,2); 4 | 5 | alpha(1,1) = dot(a1,a1); 6 | alpha(1,2) = dot(a1,a2); 7 | alpha(2,1) = dot(a2,a1); 8 | alpha(2,2) = dot(a2,a2); 9 | 10 | beta = zeros(2,2); 11 | 12 | beta(1,1) = dot(a11,a3); 13 | beta(1,2) = dot(a12,a3); 14 | beta(2,1) = dot(a12,a3); 15 | beta(2,2) = dot(a22,a3); 16 | 17 | 18 | end -------------------------------------------------------------------------------- /KL Shell/Function Files/computeReactionForces.m: -------------------------------------------------------------------------------- 1 | function [r_LG] = computeReactionForces(Kff,delta_a_f,freeDofs) 2 | 3 | if size(Kff,1) == freeDofs 4 | 5 | r_LG = zeros(length(freeDofs),1); 6 | 7 | else 8 | Bk = Kff(length(freeDofs):end,1:length(freeDofs)); 9 | 10 | r_LG = Bk' * delta_a_f(length(freeDofs):end); 11 | 12 | end 13 | end -------------------------------------------------------------------------------- /KL Shell/Function Files/computeStress.m: -------------------------------------------------------------------------------- 1 | function [n,m,dE1,dE2] = computePatchStress((BasisFunc,refPts,pts,ep) 2 | 3 | weights = cell2mat(nPar(1)); 4 | uKnot = cell2mat(nPar(2)); 5 | vKnot = cell2mat(nPar(3)); 6 | 7 | E = ep(1); 8 | nu = ep(2); 9 | t = ep(3); 10 | 11 | memStiff = E*t/(1-nu^2); 12 | benStiff = E*t^3/12/(1-nu^2); 13 | 14 | 15 | 16 | 17 | jacob1 = [dRdxi; dRdeta] * pts; % 2x3(?) matrix 18 | jacob2 = [dR2dxi; dR2det; dR2dxe] * pts; % 3x3(?) matrix 19 | 20 | djacob1 = [dRdxi; dRdeta] * defPts; % 2x3(?) matrix 21 | djacob2 = [dR2dxi; dR2det; dR2dxe] * defPts; % 3x3(?) matrix 22 | 23 | 24 | 25 | % dxdxi = jacob1(1,1); dydxi = jacob1(1,2); 26 | % dxdet = jacob1(2,1); dydet = jacob1(2,2); 27 | 28 | % a1, a2 and a3 vectors (surface basis vectors) 29 | % a1 & a2 defines the tangent plane at a specific point 30 | 31 | a1 = jacob1(1,:); 32 | a2 = jacob1(2,:); 33 | a3 = cross(a1,a2); 34 | norma = norm(a3); 35 | a3 = a3/norma; 36 | 37 | a1_norm = a1/norm(a1); 38 | a1_perp = cross(a1_norm,a3); 39 | 40 | if nargin == 9 41 | 42 | E1 = a1_norm; 43 | E2 = a1_perp; 44 | 45 | end 46 | 47 | J1 = norma; 48 | 49 | 50 | da1 = djacob1(1,:); 51 | da2 = djacob1(2,:); 52 | da3 = cross(da1,da2); 53 | dnorma = norm(da3); 54 | da3 = da3/dnorma; 55 | 56 | 57 | da1_norm = da1/norm(da1); 58 | da1_perp = cross(da1_norm,da3); 59 | 60 | dE1 = da1_norm; 61 | dE2 = da1_perp; 62 | 63 | dJ1 = dnorma; 64 | 65 | J = dJ1/J1; 66 | 67 | % Restriction of the metric tensor to the tangent plane 68 | % also called the 1st fundamental form of the surface, 69 | % given by its components 70 | a11 = jacob2(1,:); 71 | a22 = jacob2(2,:); 72 | a12 = jacob2(3,:); 73 | 74 | da11 = djacob2(1,:); 75 | da22 = djacob2(2,:); 76 | da12 = djacob2(3,:); 77 | 78 | % dot products of ai and ei 79 | 80 | % R_I,2*a1 + R_I,1*a2 for all shape functions 81 | 82 | [alpha,beta] = computeMetricC(a1,a2,a11,a12,a22,a3); 83 | [dalpha,dbeta] = computeMetricC(da1,da2,da11,da12,da22,da3); 84 | 85 | %Calculate Strains 86 | 87 | %Metric Coefficient 88 | 89 | e11 = 1/2*(dalpha(1,1) - alpha(1,1)); 90 | e22 = 1/2*(dalpha(2,2) - alpha(2,2)); 91 | e12 = 1/2*(dalpha(1,2) - alpha(1,2)); 92 | e21 = 1/2*(dalpha(2,1) - alpha(2,1)); 93 | 94 | eHat = [e11 e12; e21 e22]; 95 | 96 | k11 = 1/2*(beta(1,1) - dbeta(1,1)); 97 | k22 = 1/2*(beta(2,2) - dbeta(2,2)); 98 | k12 = 1/2*(beta(1,2) - dbeta(1,2)); 99 | k21 = k12; 100 | 101 | kHat = [k11 k12; k21 k22]; 102 | 103 | % Map eHat and kHat to local unitized cartesian basis E1xE2 104 | 105 | e_ortho = shiftBase2D(eHat,a1,a2,E1,E2,1); 106 | 107 | k_ortho = shiftBase2D(kHat,a1,a2,E1,E2,1); 108 | 109 | C_ortho = [1 nu 0; 110 | nu 1 0; 111 | 0 0 (1-nu)/2]; 112 | 113 | e_ortho_v = [e_ortho(1,1); e_ortho(2,2); e_ortho(1,2)+e_ortho(2,1)]; 114 | 115 | k_ortho_v = [k_ortho(1,1); k_ortho(2,2); k_ortho(1,2)+k_ortho(2,1)]; 116 | 117 | S_n = memStiff*(C_ortho * e_ortho_v); 118 | S_m = benStiff*(C_ortho * k_ortho_v); 119 | 120 | S_n_tensor = [S_n(1) S_n(3)*0.5; S_n(3)*0.5 S_n(2)]; 121 | S_m_tensor = [S_m(1) S_m(3)*0.5; S_m(3)*0.5 S_m(2)]; 122 | 123 | % Scale to correct value 124 | 125 | scaled_S_n = S_n_tensor * 1/J; 126 | scaled_S_m = S_m_tensor * 1/J; 127 | % Transform to actual configuration 128 | 129 | sigma_n = shiftBase2D(scaled_S_n,E1,E2,dE1,dE2,1); 130 | sigma_m = shiftBase2D(scaled_S_m,E1,E2,dE1,dE2,1); 131 | 132 | n = [sigma_n(1,1) sigma_n(2,2) 2*sigma_n(1,2)]; 133 | m = [sigma_m(1,1) sigma_m(2,2) 2*sigma_m(1,2)]; 134 | 135 | 136 | 137 | end -------------------------------------------------------------------------------- /KL Shell/Function Files/getEvalPts.m: -------------------------------------------------------------------------------- 1 | function [Xi_pos,Eta_pos] = getEvalPts(xiRes,etaRes,Xi,Eta) 2 | 3 | stepXi = 1 / xiRes; 4 | stepEta = 1 / etaRes; 5 | 6 | % Evaluation points for plots 7 | Xi_pos = 0 : stepXi : 1; % Evaluate basis functions at each xi in Xi_store 8 | Eta_pos = 0 : stepEta : 1; % Evaluate basis functions at each eta in Eta_store 9 | 10 | if(nargin == 4) 11 | Xi_pos = unique(sort([Xi_pos Xi])); % <- Makes sure that the knots are included (In order to plot the knots, otherwise we could ignore this) 12 | Eta_pos = unique(sort([Eta_pos Eta])); % <- Makes sure that the knots are included (In order to plot the knots) 13 | end 14 | 15 | 16 | end -------------------------------------------------------------------------------- /KL Shell/Function Files/getPatchStress.m: -------------------------------------------------------------------------------- 1 | function [stressVal, Sx, Sy ,Sz] = getPatchStress(a, pts, Xi, Eta, Xi_store, Eta_store, n, m, p, q,ep,weights,element,index,stressToPlot,layer,t_arr) 2 | 3 | % New control points 4 | at = a(1:3:end); 5 | au = a(2:3:end); 6 | an = a(3:3:end); 7 | 8 | defpts(:,1) = pts(:,1)+at; 9 | defpts(:,2) = pts(:,2)+au; 10 | defpts(:,3) = pts(:,3)+an; 11 | 12 | all_pts = [defpts(:,1),defpts(:,2),defpts(:,3)]; 13 | all_refPts = [pts(:,1), pts(:,2), pts(:,3)]; 14 | 15 | stressVal = zeros(length(Xi_store),length(Eta_store)); 16 | 17 | Sx = zeros(length(Xi_store),length(Eta_store)); 18 | Sy = zeros(length(Xi_store),length(Eta_store)); 19 | Sz = zeros(length(Xi_store),length(Eta_store)); 20 | 21 | B1 = zeros(4,n,m); 22 | 23 | B1(1:3,:) = defpts'; 24 | B1(4,:) = weights; 25 | 26 | kk = 1; 27 | % Construct NURBS surface 28 | for i = 1:length(Xi_store) 29 | for j = 1:length(Eta_store) 30 | 31 | xi = Xi_store(i); % Get current xi 32 | eta = Eta_store(j); % Get current eta 33 | 34 | if nargin == 17 35 | 36 | ep(3) = t_arr(i,j); 37 | 38 | end 39 | 40 | % Find xi span and get b-spline basis 41 | xiSpan = FindSpanPS(n,p,xi,Xi); % Find knot span 42 | N = BasisFun(xiSpan,xi,p,Xi); % Get only the non-zero basis functions (there are p + 1 non-zero basis functions). 43 | 44 | % Find eta span and get b-spline basis 45 | etaSpan = FindSpanPS(m,q,eta,Eta); % Find knot span 46 | M = BasisFun(etaSpan,eta,q,Eta); % Get only the non-zero basis functions (there are q + 1 non-zero basis functions). 47 | 48 | % Construct the bi-variate b-spline basis using the outer product 49 | NM=N'*M; 50 | 51 | % Get relevant control points for current non-zero basis funcitons. 52 | X=reshape(B1(1,xiSpan-p+1:xiSpan+1,etaSpan-q+1:etaSpan+1),p+1,q+1); 53 | Y=reshape(B1(2,xiSpan-p+1:xiSpan+1,etaSpan-q+1:etaSpan+1),p+1,q+1); 54 | Z=reshape(B1(3,xiSpan-p+1:xiSpan+1,etaSpan-q+1:etaSpan+1),p+1,q+1); 55 | w=reshape(B1(4,xiSpan-p+1:xiSpan+1,etaSpan-q+1:etaSpan+1),p+1,q+1); 56 | 57 | R = NM .* w; % Multiply Bspline basis by weights 58 | R = R / sum(sum(R)); % Divide by total W -> NURBS basis 59 | 60 | % find element 61 | 62 | for k = 1:length(index) 63 | 64 | if index(k,1) == xiSpan-(p-1) && index(k,2) == etaSpan-(q-1) 65 | 66 | e = k; 67 | break; 68 | end 69 | 70 | end 71 | 72 | 73 | conn = element(e,:); 74 | defpts = all_pts(conn,:); 75 | 76 | refPts = all_refPts(conn,:); 77 | 78 | [R2, dRdxi, dRdeta, dR2dxi, dR2det, dR2dxe] = ... 79 | NURBS2DBasis2ndDers([xi; eta],p,q,Xi,Eta,weights); 80 | 81 | BasisFunc = [R2; dRdxi; dRdeta; dR2dxi; dR2det; dR2dxe]; 82 | [S_n,S_m,E1,E2] = computePatchStress(BasisFunc,refPts,defpts,ep); 83 | 84 | Stress = [S_n(1:2)/ep(3)+S_m(1:2)*layer/(ep(3)^2/6) S_n(3)/ep(3) S_m(3)]'/1e6; 85 | 86 | % Current point 87 | x = sum(sum(X.*R)); 88 | y = sum(sum(Y.*R)); 89 | z = sum(sum(Z.*R)); 90 | 91 | % Save current surface point 92 | Sx(i,j) = x; 93 | Sy(i,j) = y; 94 | Sz(i,j) = z; 95 | 96 | stressVal(i,j) = Stress(stressToPlot); 97 | 98 | kk = kk + 1; 99 | end 100 | end 101 | 102 | 103 | 104 | 105 | end -------------------------------------------------------------------------------- /KL Shell/Function Files/removeZeroCols.m: -------------------------------------------------------------------------------- 1 | function [Bmod,keepCols] = removeZeroCols(B) 2 | 3 | keepCols = [size(B,2)]; 4 | 5 | for i = 1:size(B,2) 6 | 7 | if max(abs(B(:,i))) > 1e-8 8 | 9 | keepCols(i) = i; 10 | 11 | end 12 | 13 | end 14 | 15 | keepCols = keepCols(keepCols ~= 0); 16 | 17 | Bmod = B(:,keepCols); 18 | 19 | end -------------------------------------------------------------------------------- /KL Shell/Function Files/shiftBase2D.m: -------------------------------------------------------------------------------- 1 | function [e_trans] = shiftBase2D(e,a1,a2,b1,b2,format) 2 | 3 | % This function shifts the 2d tensor e from basis a1xa2 to b1xb2 4 | % 5 | % 6 | % 7 | 8 | e_trans = zeros(2,2); 9 | 10 | if format == 0 11 | % Getr 12 | 13 | a1b1 = dot(a1,b1); 14 | a1b2 = dot(a1,b2); 15 | a2b1 = dot(a2,b1); 16 | a2b2 = dot(a2,b2); 17 | 18 | ab = [a1b1 a1b2;a2b1 a2b2]; 19 | 20 | 21 | for l = 1:2 22 | for k = 1:2 23 | for j = 1:2 24 | for i = 1:2 25 | e_trans(k,l) = e_trans(k,l) + e(i,j)*ab(i,k)*ab(j,l); 26 | end 27 | end 28 | end 29 | end 30 | 31 | end 32 | 33 | if format == 1 34 | % Getr 35 | 36 | [a1_c,a2_c] = computeContravariant(a1,a2); 37 | 38 | a1b1 = dot(a1_c,b1); 39 | a1b2 = dot(a1_c,b2); 40 | a2b1 = dot(a2_c,b1); 41 | a2b2 = dot(a2_c,b2); 42 | 43 | ab = [a1b1 a1b2;a2b1 a2b2]; 44 | 45 | 46 | for l = 1:2 47 | for k = 1:2 48 | for j = 1:2 49 | for i = 1:2 50 | e_trans(k,l) = e_trans(k,l) + e(i,j)*ab(i,k)*ab(j,l); 51 | end 52 | end 53 | end 54 | end 55 | 56 | 57 | 58 | 59 | end 60 | 61 | if format == 2 62 | % Getr 63 | 64 | [b1_c,b2_c] = computeContravariant(b1,b2); 65 | 66 | a1b1 = dot(a1,b1_c); 67 | a1b2 = dot(a1,b2_c); 68 | a2b1 = dot(a2,b1_c); 69 | a2b2 = dot(a2,b2_c); 70 | 71 | ab = [a1b1 a1b2;a2b1 a2b2]; 72 | 73 | 74 | for l = 1:2 75 | for k = 1:2 76 | for j = 1:2 77 | for i = 1:2 78 | e_trans(k,l) = e_trans(k,l) + e(i,j)*ab(i,k)*ab(j,l); 79 | end 80 | end 81 | end 82 | end 83 | 84 | end 85 | 86 | if format == 3 87 | % Getr 88 | 89 | [b1_c,b2_c] = computeContravariant(b1,b2); 90 | [a1_c,a2_c] = computeContravariant(a1,a2); 91 | 92 | a1b1 = dot(a1_c,b1_c); 93 | a1b2 = dot(a1_c,b2_c); 94 | a2b1 = dot(a2_c,b1_c); 95 | a2b2 = dot(a2_c,b2_c); 96 | 97 | ab = [a1b1 a1b2;a2b1 a2b2]; 98 | 99 | 100 | for l = 1:2 101 | for k = 1:2 102 | for j = 1:2 103 | for i = 1:2 104 | e_trans(k,l) = e_trans(k,l) + e(i,j)*ab(i,k)*ab(j,l); 105 | end 106 | end 107 | end 108 | end 109 | 110 | end 111 | 112 | end -------------------------------------------------------------------------------- /KL Shell/Function Files/shiftBase2DVoigth.m: -------------------------------------------------------------------------------- 1 | function [e_trans_v] = shiftBase2DVoigth(e,ab,format) 2 | 3 | % This function shifts the 2d tensor e from basis a1xa2 to b1xb2 4 | % 5 | % 6 | % 7 | 8 | e_trans_v = zeros(3,1); 9 | e_trans = zeros(2,2); 10 | e_tensor = zeros(2,2); 11 | 12 | 13 | if format == 1 14 | % Ge 15 | 16 | 17 | e_tensor(1,1) = e(1); 18 | e_tensor(2,2) = e(2); 19 | e_tensor(1,2) = 0.5*e(3); 20 | e_tensor(2,1) = e_tensor(1,2); 21 | 22 | for l = 1:2 23 | for k = 1:2 24 | for j = 1:2 25 | for i = 1:2 26 | e_trans(k,l) = e_trans(k,l) + e_tensor(i,j)*ab(i,k)*ab(j,l); 27 | end 28 | end 29 | end 30 | end 31 | 32 | 33 | e_trans_v = [e_trans(1,1),e_trans(2,2),e_trans(2,1) + e_trans(1,2)]; 34 | end 35 | 36 | if format == 2 37 | % Getr 38 | 39 | [b1_c,b2_c] = computeContravariant(b1,b2); 40 | 41 | a1b1 = dot(a1,b1_c); 42 | a1b2 = dot(a1,b2_c); 43 | a2b1 = dot(a2,b1_c); 44 | a2b2 = dot(a2,b2_c); 45 | 46 | ab = [a1b1 a1b2;a2b1 a2b2]; 47 | 48 | 49 | e_tensor = [e(1) 0.5*e(3);0.5*e(3) e(2)]; 50 | 51 | for l = 1:2 52 | for k = 1:2 53 | for j = 1:2 54 | for i = 1:2 55 | e_trans(k,l) = e_trans(k,l) + e_tensor(i,j)*ab(i,k)*ab(j,l); 56 | end 57 | end 58 | end 59 | end 60 | 61 | 62 | e_trans_v = [e_trans(1,1) e_trans(2,2) e_trans(2,1) + e_trans(1,2)]; 63 | end 64 | 65 | if format == 3 66 | % Getr 67 | 68 | [a1_c,a2_c] = computeContravariant(a1,a2); 69 | [b1_c,b2_c] = computeContravariant(b1,b2); 70 | 71 | a1b1 = dot(a1_c,b1_c); 72 | a1b2 = dot(a1_c,b2_c); 73 | a2b1 = dot(a2_c,b1_c); 74 | a2b2 = dot(a2_c,b2_c); 75 | 76 | ab = [a1b1 a1b2;a2b1 a2b2]; 77 | 78 | 79 | e_tensor = [e(1) 0.5*e(3);0.5*e(3) e(2)]; 80 | 81 | for l = 1:2 82 | for k = 1:2 83 | for j = 1:2 84 | for i = 1:2 85 | e_trans(k,l) = e_trans(k,l) + e_tensor(i,j)*ab(i,k)*ab(j,l); 86 | end 87 | end 88 | end 89 | end 90 | 91 | 92 | e_trans_v = [e_trans(1,1) e_trans(2,2) e_trans(2,1) + e_trans(1,2)]; 93 | end 94 | 95 | 96 | end -------------------------------------------------------------------------------- /KL Shell/Function Files/solveEquations.m: -------------------------------------------------------------------------------- 1 | function [a_tot,delta_a,delta_r,r_LG] = solveEquations(a_tot,numDofs,freeDofs,K,f_e,f_i,Bu,Bcouple,a_c,u_c) 2 | 3 | constrDofs = setdiff(1:numDofs,freeDofs); 4 | 5 | if length(freeDofs) == numDofs 6 | 7 | if Bu ~= -1 8 | [K,f_e,f_i] = applyKinematicConstraints(Bu,K,f_e,f_i,u_c); 9 | end 10 | 11 | if Bcouple ~= -1 12 | [K,f_e,f_i] = applyKinematicConstraints(Bcouple,K,f_e,f_i); 13 | end 14 | 15 | f = f_e - f_i; 16 | 17 | [temp_a] = solveq(K,f); 18 | 19 | delta_a = temp_a(1:numDofs); 20 | lambda = temp_a(numDofs+1:end); 21 | delta_r = -1; 22 | 23 | a_tot = a_tot + delta_a; 24 | 25 | r_LG = computeReactionForces(K,temp_a,freeDofs); 26 | 27 | else 28 | 29 | fe_f = f_e(freeDofs); 30 | fi_f = f_i(freeDofs); 31 | 32 | % In K, freeDofs, constrDofs 33 | [Kff,Kfc,Kcc] = partK(freeDofs,constrDofs,K); 34 | 35 | f_eq = Kfc*a_c(:,2); 36 | 37 | if Bu ~= -1 38 | [Kff,fe_f,fi_f] = applyKinematicConstraints(Bu(freeDofs,:),Kff,fe_f,fi_f,u_c); 39 | end 40 | 41 | if Bcouple ~= -1 42 | [Kff,fe_f,fi_f] = applyKinematicConstraints(Bcouple(freeDofs,:),Kff,fe_f,fi_f); 43 | end 44 | 45 | 46 | f = fe_f - fi_f; 47 | 48 | f_eq = [f_eq; 49 | zeros(length(f)-length(f_eq),1)]; 50 | 51 | 52 | [temp_a] = solveq(Kff,f-f_eq); 53 | 54 | 55 | 56 | delta_a = temp_a(1:length(freeDofs)); 57 | 58 | delta_r = Kfc'*temp_a(1:length(freeDofs)) + Kcc*a_c(:,2); 59 | 60 | a_tot(freeDofs) = a_tot(freeDofs) + delta_a; 61 | a_tot(constrDofs) = a_tot(constrDofs) + a_c(:,2); 62 | 63 | r_LG = computeReactionForces(Kff,temp_a,freeDofs); 64 | 65 | end 66 | 67 | 68 | end 69 | -------------------------------------------------------------------------------- /KL Shell/Resources/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/KL Shell/Resources/.DS_Store -------------------------------------------------------------------------------- /KL Shell/Resources/NotEndBend.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/KL Shell/Resources/NotEndBend.gif -------------------------------------------------------------------------------- /KL Shell/Resources/Surface_e11.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/KL Shell/Resources/Surface_e11.gif -------------------------------------------------------------------------------- /KL Shell/Resources/testSurface.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/KL Shell/Resources/testSurface.gif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Joel Hilmersson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iga-matlab 2 | 3 | ### What is this? 4 | 5 | This repository contains a set of MATLAB functions to do geoemtric nonlinear Isogeometric analysis. 6 | 7 | ### Why was it done? 8 | 9 | This was developed as part of my master thesis in structural engineering at Chalmers University of Technology in the fall of 2018. Had previously experimented with actively bent forms, and in this thesis I wanted to investigate the use of nonlinear IGA as a means to design them. The core aim was to find a geometrically consistent (NURBS) way of relating deformed and undeformed design geometries to each other, accounting for the stiffness distribution. 10 | 11 | More information can be found in the final [thesis report](https://hdl.handle.net/20.500.12380/301616). 12 | 13 | It builds upon the work done by S. Almstedt and P. Safari Hesari in the their [thesis](https://hdl.handle.net/20.500.12380/301616) 14 | 15 | ### What is IGA? 16 | 17 | *Nurbs geometry vs a polygonal mesh.* 18 | 19 | ![NURBS_vs_MESH](https://user-images.githubusercontent.com/62885093/111032366-b5839580-8403-11eb-9d0d-7fef16fa37f3.jpg) 20 | 21 | *** 22 | 23 | ### Functionality 24 | 25 | - **Kirchhoff-Love (KL) Shells** 26 | 27 | The main target was the geometrically nonlinear analysis of single IGA patches. 28 | 29 | This repository contains a single patch implementation. 30 | 31 | As a design feature, allows the input of an independent thickness parameterization, which can be used to manipulate 32 | 33 | ![](https://github.com/joelhi/iga-matlab/blob/master/KL%20Shell/Resources/testSurface.gif) 34 | 35 | - **Euler-Bernoulli (EB) Beams** 36 | 37 | As a first step, prior to the shell implementation, and simplified version was made, as a proving ground. This was derived in a similar fashion to the shell, but for a 1-dimensiona object in 2-dimensional space. Effectively making it an Euler-Bernoulli beam (E-B). 38 | 39 | This implementation was made as a test, to try different solution schemes etc. and is probably not the best IGA implementation of an E-B beam. 40 | 41 | Below are two examples; the first is a displacement controlled solution to a simple elastica curve, and the second is a dynamic relaxation solution. 42 | 43 | ![alt text](https://github.com/joelhi/IGA_MATLAB/blob/master/Beam/Gifs/Elastica1.gif) 44 | 45 | ![alt text](https://github.com/joelhi/IGA_MATLAB/blob/master/Beam/Gifs/DR_Faster.gif) 46 | 47 | *** 48 | 49 | ### General Disclaimer 50 | 51 | The implementation does have some issues, so should be used with caution. 52 | 53 | Some examples are: 54 | 55 | - **Membrane locking for KL shells** *need a very high degree (>10) for the locking not to be substantial* 56 | - **Beam implementation not verified** *Sometimes looks to behave in a too stiff fashion, however, buckling load corresponds well to analytical solution.* 57 | 58 | But if you are interested in IGA, this repo can serve as a good point of entry. 59 | -------------------------------------------------------------------------------- /Util/C_files/BSPLINE2DBasisDers.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS basis functions and first derivatives to matlab 12 | All non-zero basis functions and derivatives at point [xi,eta] are 13 | computed. 14 | 15 | We expect the function to be called as 16 | [R dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, ... 17 | knotV, weights) 18 | 19 | xi = point, [xi eta], where we want to interpolate 20 | knotU, knotV = knot vectors 21 | weights = vector of weights 22 | 23 | Vinh Phu Nguyen, nvinhphu@gmail.com 24 | */ 25 | 26 | if(nrhs != 5) mexErrMsgTxt("You fool! You haven't passed in 6 arguments to the function." 27 | "We expect it to be in the form [dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, knotV)\n"); 28 | 29 | /* First get the inputs */ 30 | 31 | double *xi = mxGetPr(prhs[0]); 32 | double *p_in = mxGetPr(prhs[1]); 33 | double *q_in = mxGetPr(prhs[2]); 34 | 35 | int p = (int) *p_in; 36 | int q = (int) *q_in; 37 | 38 | double *knotU = mxGetPr(prhs[3]); 39 | double *knotV = mxGetPr(prhs[4]); 40 | 41 | int numKnotU = mxGetN(prhs[3]); 42 | int numKnotV = mxGetN(prhs[4]); 43 | 44 | int nU = numKnotU - 1 - p - 1; 45 | int nV = numKnotV - 1 - q - 1; 46 | int noFuncs = (p+1)*(q+1); 47 | 48 | 49 | 50 | double tol = 100*DBL_EPSILON; 51 | 52 | if(fabs(xi[0]-knotU[numKnotU-1]) < tol) 53 | xi[0] = knotU[numKnotU-1] - tol; 54 | 55 | if(fabs(xi[1]-knotV[numKnotV-1]) < tol) 56 | xi[1] = knotV[numKnotV-1] - tol; 57 | 58 | /* and evaluate the non-zero univariate B-spline basis functions 59 | * and first derivatives 60 | */ 61 | 62 | double *N = (double *)malloc(sizeof(double)*(p+1)); 63 | double *M = (double *)malloc(sizeof(double)*(q+1)); 64 | double **dersN = init2DArray(nU+1, p+1); 65 | double **dersM = init2DArray(nV+1, q+1); 66 | 67 | int spanU = FindSpan(nU, p, xi[0], knotU); 68 | int spanV = FindSpan(nV, q, xi[1], knotV); 69 | 70 | BasisFuns (spanU, xi[0], p, knotU, N); 71 | BasisFuns (spanV, xi[1], q, knotV, M); 72 | 73 | dersBasisFuns (spanU, xi[0], p, nU, knotU, dersN); 74 | dersBasisFuns (spanV, xi[1], q, nV, knotV, dersM); 75 | 76 | 77 | /* and create NURBS approximation */ 78 | 79 | int i, j, k, c; 80 | 81 | /* 82 | for(i=0;i<=p;i++){ 83 | printf("dNdxi= %f\n", dersN[1][i]); 84 | printf("dNdet= %f\n", dersM[1][i]); 85 | }*/ 86 | 87 | /* 88 | int uind = spanU - p; 89 | int vind; 90 | 91 | double w = 0.0; 92 | double dwdxi = 0.0; 93 | double dwdet = 0.0; 94 | double wgt; 95 | 96 | for(j = 0; j <= q; j++) 97 | { 98 | vind = spanV - q + j; 99 | 100 | for(i = 0; i <= p; i++) 101 | { 102 | c = uind + i + vind * (nU+1); 103 | wgt = weight[c]; 104 | 105 | w += N[i] * M[j] * wgt; 106 | dwdxi += dersN[1][i] * M[j] * wgt; 107 | dwdet += dersM[1][j] * N[i] * wgt; 108 | } 109 | } 110 | */ 111 | 112 | /* create output */ 113 | 114 | plhs[0] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 115 | plhs[1] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 116 | plhs[2] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 117 | 118 | double *R = mxGetPr(plhs[0]); 119 | double *dRdxi = mxGetPr(plhs[1]); 120 | double *dRdet = mxGetPr(plhs[2]); 121 | 122 | k = 0; 123 | 124 | double fac; 125 | 126 | /*printf("uind= %d\n", uind); 127 | printf("vind= %d\n", vind); 128 | printf("nU+1= %d\n", nU+1); */ 129 | 130 | for(j = 0; j <= q; j++) 131 | { 132 | for(i = 0; i <= p; i++) 133 | { 134 | R[k] = N[i]*M[j]; 135 | dRdxi[k] = dersN[1][i]*M[j]; 136 | dRdet[k] = dersM[1][j]*N[i]; 137 | 138 | k += 1; 139 | } 140 | } 141 | 142 | /*mexPrintf("\nWe have a knot vector with %d components\n", numWeights); 143 | for(k = 0; k < numWeights; k++) mexPrintf("%2.2f\t", weight[k]); 144 | mexPrintf("\n");*/ 145 | 146 | free(N); 147 | free(M); 148 | free2Darray(dersN, (nU+1)); 149 | free2Darray(dersM, (nV+1)); 150 | } 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /Util/C_files/BSPLINE2DBasisDers.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/BSPLINE2DBasisDers.mexa64 -------------------------------------------------------------------------------- /Util/C_files/BSPLINE2DBasisDers.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/BSPLINE2DBasisDers.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files/BSPLINE2DBasisDers.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/BSPLINE2DBasisDers.mexw64 -------------------------------------------------------------------------------- /Util/C_files/FindSpan.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "NURBS.h" 5 | 6 | /* 7 | * Robert Simpson, Cardiff University, UK 8 | */ 9 | 10 | int main(int arg, char* argv[]) 11 | { 12 | int p = 2; // our basis order 13 | double U[] = {0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0,5.0, 5.0}; // knot vector 14 | int m = sizeof(U)/sizeof(double) - 1; // number of knot points 15 | int n = m - p - 1; // number of basis functions 16 | 17 | double u; 18 | int c, span; 19 | 20 | /*printf("Number of knot points: %d\n", m); 21 | 22 | // 23 | // Test our knot span index code 24 | // 25 | 26 | for(c = 0; c < m+1; ++c) 27 | { 28 | span = FindSpan(n, p, U[c], U); 29 | printf("For Xi=%2.1f, the knot span index is i=%d\n\n",U[c], span); 30 | }*/ 31 | 32 | // 33 | // Now let's test our routines which calculate the basis functions and derivatives 34 | // 35 | 36 | int numNonZeroBsFns = p + 1; 37 | 38 | /* 39 | double *N = (double*)malloc(sizeof(double) * numNonZeroBsFns); 40 | 41 | double **ders = init2DArray(n+1, p+1); 42 | 43 | for(c = 0; c < numNonZeroBsFns; ++c) N[c] = 0.0; 44 | 45 | double point[] = {0.0, 1.0, 2,0, 3.0, 4.0, 5.0}; // some sample points to evaluate at 46 | int k = sizeof(point) / sizeof(double); // number of points (for our loop) 47 | int j,d; 48 | 49 | for(j = 0; j < k; ++j) 50 | { 51 | span = FindSpan(n, p, point[j], U); // get the span 52 | BasisFuns( span, point[j], p, U, N); // get the non-zero basis functions 53 | dersBasisFuns(span, point[j], p, n, U, ders); // get the derivatives ders[k][j] 54 | 55 | // print out basis functions 56 | 57 | printf("The non-zero basis functions in the range %2.2f and %2.2f and u=%2.2f are:\n",U[span], U[span+1], point[j]); 58 | for(c = 0; c < numNonZeroBsFns; ++c) printf("\n %2.2f\n", N[c]); 59 | 60 | 61 | // print out derivatives 62 | 63 | for(d = 0; d < (n+1); d++) 64 | { 65 | printf("For k=%d, derivatives are: \n", d); 66 | for(c = 0; c < numNonZeroBsFns; c++) printf("%2.2f\t", ders[d][c]); 67 | printf("\n"); 68 | } 69 | printf("\n\n"); 70 | 71 | } 72 | 73 | free(N); 74 | free2Darray(ders, n+1); 75 | */ 76 | 77 | double *dN = (double*)malloc(sizeof(double) * (n+1)); 78 | double **ders = init2DArray(n+1, p+1); 79 | 80 | double xi, Nip; 81 | int i=2; 82 | 83 | printf("xi\tN\tdNdxi\n"); 84 | for(xi=0.0; xi <= 5.0; xi+=0.1) 85 | { 86 | span = FindSpan(n, p, xi, U); 87 | Nip = OneBasisFun(p, m, U, i, xi); 88 | dersOneBasisFuns(p, m, U, i, xi, n, dN); 89 | 90 | } 91 | 92 | xi = 2.1; 93 | span = FindSpan(n, p, xi, U); 94 | dersBasisFuns(span, xi, p, n, U, ders); // get the derivatives ders[k][j] 95 | printf("\n\n%2.2f\t%2.20f\t%2.20f\t%2.20f\n",xi, ders[1][0], ders[1][1], ders[1][2]); 96 | 97 | free(dN); 98 | free2Darray(ders, n+1); 99 | return 0; 100 | } 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /Util/C_files/NURBS.h: -------------------------------------------------------------------------------- 1 | 2 | int FindSpan(int n, int p, double u, double U[]); 3 | void BasisFuns( int i, double u, int p, double U[], double* N); 4 | void dersBasisFuns(int i, double u, int p, int order, double knot[], double **ders); 5 | double OneBasisFun(int p, int m, double U[], int i, double u); 6 | void dersOneBasisFuns(int p, int m, double U[], int i, double u, int n, double* ders); 7 | double** init2DArray(int x, int y); 8 | void free2Darray(double **array, int x); 9 | 10 | -------------------------------------------------------------------------------- /Util/C_files/NURBS1DBasis2ndDers.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the univariate NURBS basis functions and first/second derivatives to matlab 12 | * All non-zero basis functions and derivatives at point [xi] are 13 | * computed. 14 | * 15 | * We expect the function to be called as 16 | * [R dRdxi dR2dxi] = NURBS1DBasis2ndDers(xi,p,knotU,weights) 17 | * 18 | * xi = where we want to interpolate 19 | * knotU = knot vector 20 | * weights = vector of weights 21 | * 22 | * Vinh Phu Nguyen, nvinhphu@gmail.com 23 | */ 24 | 25 | if(nrhs != 4) mexErrMsgTxt("You fool! You haven't passed in 4 arguments to the function." 26 | "We expect it to be in the form [R dR2dxi] = NURBSinterpolation(xi, p, q, knotU, knotV, weights)\n"); 27 | 28 | /* First get the inputs */ 29 | 30 | double *xi = mxGetPr(prhs[0]); 31 | double *p_in = mxGetPr(prhs[1]); 32 | int p = (int) *p_in; 33 | double *knotU = mxGetPr(prhs[2]); 34 | int numKnotU = mxGetN(prhs[2]); 35 | int nU = numKnotU - 1 - p - 1; 36 | int noFuncs = (p+1); 37 | double *weight = mxGetPr(prhs[3]); 38 | int numWeights = mxGetN(prhs[3]); 39 | 40 | double tol = 100*DBL_EPSILON; 41 | 42 | if(fabs(xi[0]-knotU[numKnotU-1]) < tol) 43 | xi[0] = knotU[numKnotU-1] - tol; 44 | 45 | /* and evaluate the non-zero univariate B-spline basis functions 46 | * and first derivatives 47 | */ 48 | 49 | double *N = (double *)malloc(sizeof(double)*(p+1)); 50 | double **dersN = init2DArray(nU+1, p+1); 51 | 52 | int spanU = FindSpan(nU, p, *xi, knotU); 53 | 54 | BasisFuns (spanU, *xi, p, knotU, N); 55 | dersBasisFuns (spanU, *xi, p, nU, knotU, dersN); 56 | 57 | /*printf("vind = %d\n", numWeights);printf("vind = %f\n", xi[0]);*/ 58 | 59 | /* and create NURBS approximation */ 60 | 61 | int i; 62 | 63 | /* 64 | * for(i=0;i<=p;i++){ 65 | * printf("dNdxi= %f\n", dersN[1][i]); 66 | * printf("dNdet= %f\n", dersM[1][i]); 67 | * }*/ 68 | 69 | int uind = spanU - p; 70 | double w = 0.0; /* N_iw_i */ 71 | double dwdxi = 0.0; /* first derivative of w */ 72 | double d2wdxi = 0.0; /* second derivative of w */ 73 | double wi; /* wi */ 74 | 75 | for(i = 0; i <= p; i++) 76 | { 77 | wi = weight[uind+i]; 78 | w += N[i] * wi; 79 | dwdxi += dersN[1][i] * wi; 80 | d2wdxi += dersN[2][i] * wi; 81 | } 82 | 83 | /* create output */ 84 | 85 | plhs[0] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 86 | plhs[1] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 87 | plhs[2] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 88 | 89 | double *R = mxGetPr(plhs[0]); 90 | double *dRdxi = mxGetPr(plhs[1]); 91 | double *dR2dxi = mxGetPr(plhs[2]); 92 | 93 | double fac; 94 | 95 | /*printf("uind= %d\n", uind); 96 | * printf("vind= %d\n", vind); 97 | * printf("nU+1= %d\n", nU+1); */ 98 | 99 | for(i = 0; i <= p; i++) 100 | { 101 | wi = weight[uind+i]; 102 | fac = wi/(w*w); 103 | R[i] = N[i]*wi/w; 104 | dRdxi[i] = (dersN[1][i]*w - N[i]*dwdxi) * fac; 105 | dR2dxi[i] = wi*(dersN[2][i]/w - 2*dersN[1][i]*dwdxi/w/w - N[i]*d2wdxi/w/w + 2*N[i]*dwdxi*dwdxi/w/w/w) ; 106 | } 107 | 108 | free(N); 109 | free2Darray(dersN, (nU+1)); 110 | } 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /Util/C_files/NURBS1DBasis2ndDers.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS1DBasis2ndDers.mexa64 -------------------------------------------------------------------------------- /Util/C_files/NURBS1DBasis2ndDers.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS1DBasis2ndDers.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files/NURBS1DBasis2ndDers.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS1DBasis2ndDers.mexw64 -------------------------------------------------------------------------------- /Util/C_files/NURBS1DBasisDers.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the univariate NURBS basis functions and first derivatives to matlab 12 | * // All non-zero basis functions and derivatives at point [xi] are 13 | * // computed. 14 | * // 15 | * // We expect the function to be called as 16 | * // [R dRdxi] = NURBS1DBasisDers(xi,p,knotU,weights) 17 | * // 18 | * // xi = where we want to interpolate 19 | * // knotU = knot vector 20 | * // weights = vector of weights 21 | * // 22 | * // Vinh Phu Nguyen, nvinhphu@gmail.com 23 | */ 24 | 25 | if(nrhs != 4) mexErrMsgTxt("You fool! You haven't passed in 6 arguments to the function." 26 | "We expect it to be in the form [dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, knotV, weights)\n"); 27 | 28 | /* First get the inputs */ 29 | 30 | double *xi = mxGetPr(prhs[0]); 31 | double *p_in = mxGetPr(prhs[1]); 32 | int p = (int) *p_in; 33 | double *knotU = mxGetPr(prhs[2]); 34 | int numKnotU = mxGetN(prhs[2]); 35 | int nU = numKnotU - 1 - p - 1; 36 | int noFuncs = (p+1); 37 | double *weight = mxGetPr(prhs[3]); 38 | int numWeights = mxGetN(prhs[3]); 39 | 40 | double tol = 100*DBL_EPSILON; 41 | 42 | if(fabs(xi[0]-knotU[numKnotU-1]) < tol) 43 | xi[0] = knotU[numKnotU-1] - tol; 44 | 45 | /* and evaluate the non-zero univariate B-spline basis functions 46 | * and first derivatives 47 | */ 48 | 49 | double *N = (double *)malloc(sizeof(double)*(p+1)); 50 | double **dersN = init2DArray(nU+1, p+1); 51 | 52 | int spanU = FindSpan(nU, p, *xi, knotU); 53 | 54 | BasisFuns (spanU, *xi, p, knotU, N); 55 | dersBasisFuns (spanU, *xi, p, nU, knotU, dersN); 56 | 57 | 58 | /* and create NURBS approximation */ 59 | 60 | int i; 61 | 62 | /* 63 | * for(i=0;i<=p;i++){ 64 | * printf("dNdxi= %f\n", dersN[1][i]); 65 | * printf("dNdet= %f\n", dersM[1][i]); 66 | * }*/ 67 | 68 | int uind = spanU - p; 69 | double w = 0.0; 70 | double dwdxi = 0.0; 71 | double wgt; 72 | 73 | for(i = 0; i <= p; i++) 74 | { 75 | wgt = weight[uind+i]; 76 | w += N[i] * wgt; 77 | dwdxi += dersN[1][i] * wgt; 78 | } 79 | 80 | /* create output */ 81 | 82 | plhs[0] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 83 | plhs[1] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 84 | 85 | double *R = mxGetPr(plhs[0]); 86 | double *dRdxi = mxGetPr(plhs[1]); 87 | 88 | double fac; 89 | 90 | /*printf("uind= %d\n", uind); 91 | * printf("vind= %d\n", vind); 92 | * printf("nU+1= %d\n", nU+1); */ 93 | 94 | for(i = 0; i <= p; i++) 95 | { 96 | fac = weight[uind+i]/(w*w); 97 | 98 | R[i] = N[i]*fac*w; 99 | dRdxi[i] = (dersN[1][i]*w - N[i]*dwdxi) * fac; 100 | } 101 | 102 | free(N); 103 | free2Darray(dersN, (nU+1)); 104 | } 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Util/C_files/NURBS1DBasisDers.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS1DBasisDers.mexa64 -------------------------------------------------------------------------------- /Util/C_files/NURBS1DBasisDers.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS1DBasisDers.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files/NURBS1DBasisDers.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS1DBasisDers.mexw64 -------------------------------------------------------------------------------- /Util/C_files/NURBS2DBasis2ndDers.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS2DBasis2ndDers.mexa64 -------------------------------------------------------------------------------- /Util/C_files/NURBS2DBasis2ndDers.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS2DBasis2ndDers.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files/NURBS2DBasis2ndDers.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS2DBasis2ndDers.mexw64 -------------------------------------------------------------------------------- /Util/C_files/NURBS2DBasisDers.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS basis functions and first derivatives to matlab 12 | // All non-zero basis functions and derivatives at point [xi,eta] are 13 | // computed. 14 | // 15 | // We expect the function to be called as 16 | // [R dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, ... 17 | // knotV, weights) 18 | // 19 | // xi = point, [xi eta], where we want to interpolate 20 | // knotU, knotV = knot vectors 21 | // weights = vector of weights 22 | // 23 | // Vinh Phu Nguyen, nvinhphu@gmail.com 24 | */ 25 | 26 | if(nrhs != 6) mexErrMsgTxt("You fool! You haven't passed in 6 arguments to the function." 27 | "We expect it to be in the form [dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, knotV, weights)\n"); 28 | 29 | /* First get the inputs */ 30 | 31 | double *xi = mxGetPr(prhs[0]); 32 | double *p_in = mxGetPr(prhs[1]); 33 | double *q_in = mxGetPr(prhs[2]); 34 | 35 | int p = (int) *p_in; 36 | int q = (int) *q_in; 37 | 38 | double *knotU = mxGetPr(prhs[3]); 39 | double *knotV = mxGetPr(prhs[4]); 40 | 41 | int numKnotU = mxGetN(prhs[3]); 42 | int numKnotV = mxGetN(prhs[4]); 43 | 44 | int nU = numKnotU - 1 - p - 1; 45 | int nV = numKnotV - 1 - q - 1; 46 | int noFuncs = (p+1)*(q+1); 47 | 48 | double *weight = mxGetPr(prhs[5]); 49 | int numWeights = mxGetN(prhs[5]); 50 | 51 | double tol = 100*DBL_EPSILON; 52 | 53 | if(fabs(xi[0]-knotU[numKnotU-1]) < tol) 54 | xi[0] = knotU[numKnotU-1] - tol; 55 | 56 | if(fabs(xi[1]-knotV[numKnotV-1]) < tol) 57 | xi[1] = knotV[numKnotV-1] - tol; 58 | 59 | /* and evaluate the non-zero univariate B-spline basis functions 60 | * and first derivatives 61 | */ 62 | 63 | double *N = (double *)malloc(sizeof(double)*(p+1)); 64 | double *M = (double *)malloc(sizeof(double)*(q+1)); 65 | double **dersN = init2DArray(nU+1, p+1); 66 | double **dersM = init2DArray(nV+1, q+1); 67 | 68 | int spanU = FindSpan(nU, p, xi[0], knotU); 69 | int spanV = FindSpan(nV, q, xi[1], knotV); 70 | 71 | BasisFuns (spanU, xi[0], p, knotU, N); 72 | BasisFuns (spanV, xi[1], q, knotV, M); 73 | 74 | dersBasisFuns (spanU, xi[0], p, nU, knotU, dersN); 75 | dersBasisFuns (spanV, xi[1], q, nV, knotV, dersM); 76 | 77 | /*printf("vind = %d\n", numWeights);printf("vind = %f\n", xi[0]); */ 78 | 79 | /* and create NURBS approximation */ 80 | 81 | int i, j, k, c; 82 | 83 | /* 84 | for(i=0;i<=p;i++){ 85 | printf("dNdxi= %f\n", dersN[1][i]); 86 | printf("dNdet= %f\n", dersM[1][i]); 87 | }*/ 88 | 89 | int uind = spanU - p; 90 | int vind; 91 | 92 | double w = 0.0; 93 | double dwdxi = 0.0; 94 | double dwdet = 0.0; 95 | double wgt; 96 | 97 | for(j = 0; j <= q; j++) 98 | { 99 | vind = spanV - q + j; 100 | 101 | for(i = 0; i <= p; i++) 102 | { 103 | c = uind + i + vind * (nU+1); 104 | wgt = weight[c]; 105 | 106 | w += N[i] * M[j] * wgt; 107 | dwdxi += dersN[1][i] * M[j] * wgt; 108 | dwdet += dersM[1][j] * N[i] * wgt; 109 | } 110 | } 111 | 112 | /* create output */ 113 | 114 | plhs[0] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 115 | plhs[1] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 116 | plhs[2] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 117 | 118 | double *R = mxGetPr(plhs[0]); 119 | double *dRdxi = mxGetPr(plhs[1]); 120 | double *dRdet = mxGetPr(plhs[2]); 121 | 122 | uind = spanU - p; 123 | k = 0; 124 | 125 | double fac; 126 | 127 | /*printf("uind= %d\n", uind); 128 | printf("vind= %d\n", vind); 129 | printf("nU+1= %d\n", nU+1); */ 130 | 131 | for(j = 0; j <= q; j++) 132 | { 133 | vind = spanV - q + j; 134 | 135 | for(i = 0; i <= p; i++) 136 | { 137 | c = uind + i + vind*(nU+1); 138 | fac = weight[c]/(w*w); 139 | 140 | R[k] = N[i]*M[j]*fac*w; 141 | dRdxi[k] = (dersN[1][i]*M[j]*w - N[i]*M[j]*dwdxi) * fac; 142 | dRdet[k] = (dersM[1][j]*N[i]*w - N[i]*M[j]*dwdet) * fac; 143 | 144 | k += 1; 145 | } 146 | } 147 | 148 | /*mexPrintf("\nWe have a knot vector with %d components\n", numWeights); 149 | for(k = 0; k < numWeights; k++) mexPrintf("%2.2f\t", weight[k]); 150 | mexPrintf("\n");*/ 151 | 152 | free(N); 153 | free(M); 154 | free2Darray(dersN, (nU+1)); 155 | free2Darray(dersM, (nV+1)); 156 | } 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /Util/C_files/NURBS2DBasisDers.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS2DBasisDers.mexa64 -------------------------------------------------------------------------------- /Util/C_files/NURBS2DBasisDers.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS2DBasisDers.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files/NURBS2DBasisDers.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS2DBasisDers.mexw64 -------------------------------------------------------------------------------- /Util/C_files/NURBS2DBasisDersSpecial.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS basis functions and first derivatives to matlab 12 | // All non-zero basis functions and derivatives at point [xi,eta] are 13 | // computed. With knot spans provided 14 | // 15 | // We expect the function to be called as 16 | // [R dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, ... 17 | // knotV, weights, spans) 18 | // 19 | // xi = point, [xi eta], where we want to interpolate 20 | // knotU, knotV = knot vectors 21 | // weights = vector of weights 22 | // 23 | // Vinh Phu Nguyen, nvinhphu@gmail.com 24 | */ 25 | 26 | if(nrhs != 7) mexErrMsgTxt("You fool! You haven't passed in 6 arguments to the function." 27 | "We expect it to be in the form [dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, knotV, weights)\n"); 28 | 29 | /* First get the inputs */ 30 | 31 | double *xi = mxGetPr(prhs[0]); 32 | double *p_in = mxGetPr(prhs[1]); 33 | double *q_in = mxGetPr(prhs[2]); 34 | 35 | int p = (int) *p_in; 36 | int q = (int) *q_in; 37 | 38 | double *knotU = mxGetPr(prhs[3]); 39 | double *knotV = mxGetPr(prhs[4]); 40 | 41 | int numKnotU = mxGetN(prhs[3]); 42 | int numKnotV = mxGetN(prhs[4]); 43 | 44 | int nU = numKnotU - 1 - p - 1; 45 | int nV = numKnotV - 1 - q - 1; 46 | int noFuncs = (p+1)*(q+1); 47 | 48 | double *weight = mxGetPr(prhs[5]); 49 | int numWeights = mxGetN(prhs[5]); 50 | double *spans = mxGetPr(prhs[6]); 51 | 52 | double tol = 100*DBL_EPSILON; 53 | 54 | if(fabs(xi[0]-knotU[numKnotU-1]) < tol) 55 | xi[0] = knotU[numKnotU-1] - tol; 56 | 57 | if(fabs(xi[1]-knotV[numKnotV-1]) < tol) 58 | xi[1] = knotV[numKnotV-1] - tol; 59 | 60 | /* and evaluate the non-zero univariate B-spline basis functions 61 | * and first derivatives 62 | */ 63 | 64 | double *N = (double *)malloc(sizeof(double)*(p+1)); 65 | double *M = (double *)malloc(sizeof(double)*(q+1)); 66 | double **dersN = init2DArray(nU+1, p+1); 67 | double **dersM = init2DArray(nV+1, q+1); 68 | 69 | int spanU = spans[0]; 70 | int spanV = spans[1]; 71 | 72 | BasisFuns (spanU, xi[0], p, knotU, N); 73 | BasisFuns (spanV, xi[1], q, knotV, M); 74 | 75 | dersBasisFuns (spanU, xi[0], p, nU, knotU, dersN); 76 | dersBasisFuns (spanV, xi[1], q, nV, knotV, dersM); 77 | 78 | /* and create NURBS approximation */ 79 | 80 | int i, j, k, c; 81 | 82 | /* 83 | for(i=0;i<=p;i++){ 84 | printf("dNdxi= %f\n", dersN[1][i]); 85 | printf("dNdet= %f\n", dersM[1][i]); 86 | }*/ 87 | 88 | int uind = spanU - p; 89 | int vind; 90 | 91 | double w = 0.0; 92 | double dwdxi = 0.0; 93 | double dwdet = 0.0; 94 | double wgt; 95 | 96 | for(j = 0; j <= q; j++) 97 | { 98 | vind = spanV - q + j; 99 | 100 | for(i = 0; i <= p; i++) 101 | { 102 | c = uind + i + vind * (nU+1); 103 | wgt = weight[c]; 104 | 105 | w += N[i] * M[j] * wgt; 106 | dwdxi += dersN[1][i] * M[j] * wgt; 107 | dwdet += dersM[1][j] * N[i] * wgt; 108 | } 109 | } 110 | 111 | /* create output */ 112 | 113 | plhs[0] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 114 | plhs[1] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 115 | plhs[2] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 116 | 117 | double *R = mxGetPr(plhs[0]); 118 | double *dRdxi = mxGetPr(plhs[1]); 119 | double *dRdet = mxGetPr(plhs[2]); 120 | 121 | uind = spanU - p; 122 | k = 0; 123 | 124 | double fac; 125 | 126 | /*printf("uind= %d\n", uind); 127 | printf("vind= %d\n", vind); 128 | printf("nU+1= %d\n", nU+1); */ 129 | 130 | for(j = 0; j <= q; j++) 131 | { 132 | vind = spanV - q + j; 133 | 134 | for(i = 0; i <= p; i++) 135 | { 136 | c = uind + i + vind*(nU+1); 137 | fac = weight[c]/(w*w); 138 | 139 | R[k] = N[i]*M[j]*fac*w; 140 | dRdxi[k] = (dersN[1][i]*M[j]*w - N[i]*M[j]*dwdxi) * fac; 141 | dRdet[k] = (dersM[1][j]*N[i]*w - N[i]*M[j]*dwdet) * fac; 142 | 143 | k += 1; 144 | } 145 | } 146 | 147 | /*mexPrintf("\nWe have a knot vector with %d components\n", numWeights); 148 | for(k = 0; k < numWeights; k++) mexPrintf("%2.2f\t", weight[k]); 149 | mexPrintf("\n");*/ 150 | 151 | free(N); 152 | free(M); 153 | free2Darray(dersN, (nU+1)); 154 | free2Darray(dersM, (nV+1)); 155 | } 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /Util/C_files/NURBS2DBasisDersSpecial.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS2DBasisDersSpecial.mexa64 -------------------------------------------------------------------------------- /Util/C_files/NURBS2DBasisDersSpecial.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS2DBasisDersSpecial.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files/NURBS2DBasisDersSpecial.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS2DBasisDersSpecial.mexw64 -------------------------------------------------------------------------------- /Util/C_files/NURBS2Dders.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS first derivatives w.r.t xi and eta to matlab 12 | // All non-zero derivatives at point [xi,eta] are computed. 13 | // 14 | // We expect the function to be called as 15 | // [dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, ... 16 | // knotV, weights) 17 | // 18 | // xi = point, [xi eta], where we want to interpolate 19 | // knotU, knotV = knot vectors 20 | // weights = vector of weights 21 | // 22 | // Vinh Phu Nguyen, nvinhphu@gmail.com 23 | */ 24 | 25 | if(nrhs != 6) mexErrMsgTxt("You fool! You haven't passed in 6 arguments to the function." 26 | "We expect it to be in the form [dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, knotV, weights)\n"); 27 | 28 | /* First get the inputs */ 29 | 30 | double *xi = mxGetPr(prhs[0]); 31 | double *p_in = mxGetPr(prhs[1]); 32 | double *q_in = mxGetPr(prhs[2]); 33 | 34 | int p = (int) *p_in; 35 | int q = (int) *q_in; 36 | 37 | double *knotU = mxGetPr(prhs[3]); 38 | double *knotV = mxGetPr(prhs[4]); 39 | 40 | int numKnotU = mxGetN(prhs[3]); 41 | int numKnotV = mxGetN(prhs[4]); 42 | 43 | int nU = numKnotU - 1 - p - 1; 44 | int nV = numKnotV - 1 - q - 1; 45 | int noFuncs = (p+1)*(q+1); 46 | 47 | double *weight = mxGetPr(prhs[5]); 48 | int numWeights = mxGetN(prhs[5]); 49 | 50 | 51 | double tol = 100*DBL_EPSILON; 52 | 53 | if(fabs(xi[0]-knotU[numKnotU-1]) < tol) 54 | xi[0] = knotU[numKnotU-1] - tol; 55 | 56 | if(fabs(xi[1]-knotV[numKnotV-1]) < tol) 57 | xi[1] = knotV[numKnotV-1] - tol; 58 | 59 | /* and evaluate the non-zero univariate B-spline basis functions 60 | * and first derivatives 61 | */ 62 | 63 | double *N = (double *)malloc(sizeof(double)*(p+1)); 64 | double *M = (double *)malloc(sizeof(double)*(q+1)); 65 | double **dersN = init2DArray(nU+1, p+1); 66 | double **dersM = init2DArray(nV+1, q+1); 67 | 68 | int spanU = FindSpan(nU, p, xi[0], knotU); 69 | int spanV = FindSpan(nV, q, xi[1], knotV); 70 | 71 | BasisFuns (spanU, xi[0], p, knotU, N); 72 | BasisFuns (spanV, xi[1], q, knotV, M); 73 | 74 | dersBasisFuns (spanU, xi[0], p, nU, knotU, dersN); 75 | dersBasisFuns (spanV, xi[1], q, nV, knotV, dersM); 76 | 77 | 78 | /* and create NURBS approximation */ 79 | 80 | int i, j, k, c; 81 | 82 | /* 83 | for(i=0;i<=p;i++){ 84 | printf("dNdxi= %f\n", dersN[1][i]); 85 | printf("dNdet= %f\n", dersM[1][i]); 86 | }*/ 87 | 88 | int uind = spanU - p; 89 | int vind; 90 | 91 | double w = 0.0; 92 | double dwdxi = 0.0; 93 | double dwdet = 0.0; 94 | double wgt; 95 | 96 | for(j = 0; j <= q; j++) 97 | { 98 | vind = spanV - q + j; 99 | 100 | for(i = 0; i <= p; i++) 101 | { 102 | c = uind + i + vind * (nU+1); 103 | wgt = weight[c]; 104 | 105 | w += N[i] * M[j] * wgt; 106 | dwdxi += dersN[1][i] * M[j] * wgt; 107 | dwdet += dersM[1][j] * N[i] * wgt; 108 | } 109 | } 110 | 111 | /* create output */ 112 | 113 | plhs[0] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 114 | plhs[1] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 115 | 116 | double *dRdxi = mxGetPr(plhs[0]); 117 | double *dRdet = mxGetPr(plhs[1]); 118 | 119 | uind = spanU - p; 120 | k = 0; 121 | 122 | double fac; 123 | 124 | for(j = 0; j <= q; j++) 125 | { 126 | vind = spanV - q + j; 127 | 128 | for(i = 0; i <= p; i++) 129 | { 130 | c = uind + i + vind*(nU+1); 131 | fac = weight[c]/(w*w); 132 | 133 | dRdxi[k] = (dersN[1][i]*M[j]*w - N[i]*M[j]*dwdxi) * fac; 134 | dRdet[k] = (dersM[1][j]*N[i]*w - N[i]*M[j]*dwdet) * fac; 135 | 136 | k += 1; 137 | } 138 | } 139 | 140 | /*mexPrintf("\nWe have a knot vector with %d components\n", numWeights); 141 | for(k = 0; k < numWeights; k++) mexPrintf("%2.2f\t", weight[k]); 142 | mexPrintf("\n");*/ 143 | 144 | free(N); 145 | free(M); 146 | free2Darray(dersN, (nU+1)); 147 | free2Darray(dersM, (nV+1)); 148 | } 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /Util/C_files/NURBS2Dders.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS2Dders.mexa64 -------------------------------------------------------------------------------- /Util/C_files/NURBS2Dders.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS2Dders.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files/NURBS2Dders.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS2Dders.mexw64 -------------------------------------------------------------------------------- /Util/C_files/NURBS3DBasisDers.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS3DBasisDers.mexa64 -------------------------------------------------------------------------------- /Util/C_files/NURBS3DBasisDers.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS3DBasisDers.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files/NURBS3DBasisDers.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS3DBasisDers.mexw64 -------------------------------------------------------------------------------- /Util/C_files/NURBS3DBasisDersSpecial.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS3DBasisDersSpecial.mexa64 -------------------------------------------------------------------------------- /Util/C_files/NURBS3DBasisDersSpecial.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS3DBasisDersSpecial.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files/NURBS3DBasisDersSpecial.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBS3DBasisDersSpecial.mexw64 -------------------------------------------------------------------------------- /Util/C_files/NURBSBasis_Ccode.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "NURBS.h" 5 | #include 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS basis function to matlab 12 | 13 | // 14 | // We expect the function to be called as [Nip] = NURBSBasis(i, p, xi, knot, weights) 15 | // 16 | // p = order of basis (0,1,2 etc) 17 | // knot = knot vector 18 | // i = basis function we want (1,2,3 ie. Hughes' notation) 19 | // xi = the coordinate we wish to evaluate at 20 | // weights = the weightings for the NURNS function (length(weights) = m - p -1) */ 21 | 22 | if(nrhs != 5) mexErrMsgTxt("You fool! You haven't passed in 5 arguments to the function." 23 | "We expect it to be in the form [Nip] = NURBSBasis(i, p, xi, knot, weights)\n"); 24 | 25 | int c, k, p, m, i, numKnot, numWeights; 26 | 27 | double *p_in, *m_in, *i_in; 28 | double *knot, *xi, *weight; 29 | 30 | double tol=100*DBL_EPSILON; 31 | 32 | for(c = 0; c < nrhs; c++) 33 | { 34 | switch(c) 35 | { 36 | case 0: 37 | i_in = mxGetPr(prhs[c]); 38 | i = (int)*i_in -1;; 39 | /*mexPrintf("\n\ni=%d\n", i);*/ 40 | 41 | case 1: 42 | p_in = mxGetPr(prhs[c]); 43 | p = (int)*p_in; 44 | /*mexPrintf("\n\np=%d\n", p);*/ 45 | 46 | case 2: 47 | xi = mxGetPr(prhs[c]); 48 | /*mexPrintf("\nxi=%2.20f\n", *xi); */ 49 | 50 | case 3: 51 | knot = mxGetPr(prhs[c]); 52 | numKnot = mxGetN(prhs[c]); 53 | m = numKnot - 1; 54 | /*mexPrintf("\nWe have a knot vector with %d components\n", numKnot); 55 | for(k = 0; k < numKnot; k++) mexPrintf("%2.2f\t", *(knot+k)); 56 | mexPrintf("\n");*/ 57 | 58 | case 4: 59 | weight = mxGetPr(prhs[c]); 60 | numWeights = mxGetM(prhs[c]); 61 | 62 | } 63 | } 64 | 65 | if(fabs(*xi-knot[numKnot-1]) < tol) 66 | *xi = knot[numKnot-1] - tol; 67 | 68 | 69 | /* and call the basis function routine*/ 70 | 71 | double Rip, Nip, dRip_dxi; 72 | double w_interp, dw_interp_dxi ; 73 | 74 | int n = m - p -1; 75 | 76 | double *N = (double *)malloc(sizeof(double)*(p+10)); 77 | double *dN = (double *)malloc(sizeof(double)*(n+10)); 78 | double **ders = init2DArray(n+10, p+10); 79 | 80 | int span = FindSpan(n, p, *xi, knot); 81 | BasisFuns(span, *xi, p, knot, N); 82 | dersBasisFuns(span, *xi, p, n, knot, ders); 83 | 84 | w_interp = 0.0; dw_interp_dxi = 0.0; 85 | 86 | for(c = 0; c <= p; c++) 87 | { 88 | w_interp += N[c] * weight[span-p+c]; 89 | dw_interp_dxi += ders[1][c] * weight[span-p+c]; 90 | } 91 | 92 | dersOneBasisFuns(p, m, knot, i, *xi, n, dN); 93 | 94 | Nip = OneBasisFun(p, m, knot, i, *xi); 95 | 96 | Rip = Nip * weight[i] / w_interp; 97 | 98 | dRip_dxi = weight[i] * ( w_interp * dN[1] - dw_interp_dxi * Nip ) / (w_interp * w_interp); 99 | 100 | free2Darray(ders, (n+10)); 101 | free(N); free(dN); 102 | 103 | plhs[0] = mxCreateDoubleScalar(Rip); plhs[1] = mxCreateDoubleScalar(dRip_dxi); 104 | 105 | 106 | } 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /Util/C_files/NURBSbasis.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "NURBS.h" 5 | #include 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS basis function to matlab 12 | 13 | // 14 | // We expect the function to be called as [Nip] = NURBSBasis(i, p, xi, knot, weights) 15 | // 16 | // p = order of basis (0,1,2 etc) 17 | // knot = knot vector 18 | // i = basis function we want (1,2,3 ie. Hughes' notation) 19 | // xi = the coordinate we wish to evaluate at 20 | // weights = the weightings for the NURBS function (length(weights) = m - p -1) */ 21 | 22 | if(nrhs != 5) mexErrMsgTxt("You fool! You haven't passed in 5 arguments to the function." 23 | "We expect it to be in the form [Nip] = NURBSBasis(i, p, xi, knot, weights)\n"); 24 | 25 | int c, k, p, m, i, numKnot, numWeights; 26 | 27 | double *p_in, *m_in, *i_in; 28 | double *knot, *xi, *weight; 29 | 30 | double tol=100*DBL_EPSILON; 31 | 32 | for(c = 0; c < nrhs; c++) 33 | { 34 | switch(c) 35 | { 36 | case 0: 37 | i_in = mxGetPr(prhs[c]); 38 | i = (int)*i_in -1; 39 | /*mexPrintf("\n\ni=%d\n", i);*/ 40 | 41 | case 1: 42 | p_in = mxGetPr(prhs[c]); 43 | p = (int)*p_in; 44 | /*mexPrintf("\n\np=%d\n", p);*/ 45 | 46 | case 2: 47 | xi = mxGetPr(prhs[c]); 48 | /*mexPrintf("\nxi=%2.20f\n", *xi); */ 49 | 50 | case 3: 51 | knot = mxGetPr(prhs[c]); 52 | numKnot = mxGetN(prhs[c]); 53 | m = numKnot - 1; 54 | /*mexPrintf("\nWe have a knot vector with %d components\n", numKnot); 55 | for(k = 0; k < numKnot; k++) mexPrintf("%2.2f\t", *(knot+k)); 56 | mexPrintf("\n");*/ 57 | 58 | case 4: 59 | weight = mxGetPr(prhs[c]); 60 | numWeights = mxGetM(prhs[c]); 61 | 62 | } 63 | } 64 | 65 | if(fabs(*xi-knot[numKnot-1]) < tol) 66 | *xi = knot[numKnot-1] - tol; 67 | 68 | 69 | /* and call the basis function routine*/ 70 | 71 | double Rip, Nip, dRip_dxi; 72 | double w_interp, dw_interp_dxi ; 73 | 74 | int n = m - p -1; 75 | 76 | double *N = (double *)malloc(sizeof(double)*(p+1)); 77 | double *dN = (double *)malloc(sizeof(double)*(p+1)); 78 | double **ders = init2DArray(p+1, p+1); 79 | 80 | int span = FindSpan(n, p, *xi, knot); 81 | 82 | BasisFuns (span, *xi, p, knot, N); 83 | dersBasisFuns(span, *xi, p, p, knot, ders); 84 | 85 | w_interp = 0.0; 86 | dw_interp_dxi = 0.0; 87 | 88 | for(c = 0; c <= p; c++) 89 | { 90 | w_interp += N[c] * weight[span-p+c]; 91 | dw_interp_dxi += ders[1][c] * weight[span-p+c]; 92 | } 93 | 94 | dersOneBasisFuns(p, m, knot, i, *xi, p, dN); 95 | 96 | Nip = OneBasisFun(p, m, knot, i, *xi); 97 | 98 | Rip = Nip * weight[i] / w_interp; 99 | 100 | dRip_dxi = weight[i] * ( w_interp * dN[1] - dw_interp_dxi * Nip ) / (w_interp * w_interp); 101 | 102 | 103 | free2Darray(ders, (p+1)); 104 | free(N); free(dN); 105 | 106 | plhs[0] = mxCreateDoubleScalar(Rip); 107 | plhs[1] = mxCreateDoubleScalar(dRip_dxi); 108 | } 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /Util/C_files/NURBSbasis.log: -------------------------------------------------------------------------------- 1 | This is pdfTeX, Version 3.1415926-2.3-1.40.12 (TeX Live 2011) (format=mex 2011.7.3) 12 NOV 2011 06:08 2 | entering extended mode 3 | restricted \write18 enabled. 4 | %&-line parsing enabled. 5 | **NURBSbasis.c NURBS.c 6 | (./NURBSbasis.c 7 | This is MeX Version 1.05 18 XII 1993 (B. Jackowski & M. Ry\'cko) 8 | ! You can't use `macro parameter character #' in vertical mode. 9 | l.1 # 10 | include 11 | ? ZZ 12 | Type to proceed, S to scroll future error messages, 13 | R to run without stopping, Q to run quietly, 14 | I to insert something, E to edit your file, 15 | 1 or ... or 9 to ignore the next 1 to 9 tokens of input, 16 | H for help, X to quit. 17 | ? X 18 | No pages of output. 19 | -------------------------------------------------------------------------------- /Util/C_files/NURBSbasis.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBSbasis.mexa64 -------------------------------------------------------------------------------- /Util/C_files/NURBSbasis.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBSbasis.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files/NURBSbasis.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBSbasis.mexw64 -------------------------------------------------------------------------------- /Util/C_files/NURBSfdfd2fInterpolation.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS interpolations: c(u), c'(u) and c''(u) to matlab 12 | 13 | // 14 | // We expect the function to be called as 15 | // [cu cu_der cu2_der] = NURBSfdfd2fInterpolation(xi, p, knot, points, weights) 16 | // 17 | // xi = point where we want to interpolate 18 | // knot = knot vector 19 | // vector of points in format [pt1 pt2 pt3 pt4 .... ptn] */ 20 | 21 | if(nrhs != 5) mexErrMsgTxt("You fool! You haven't passed in 3 arguments to the function." 22 | "We expect it to be in the form [interp interp_deriv] = NURBSinterpolation(xi, knot, points)\n"); 23 | 24 | /* First get the inputs */ 25 | 26 | double *xi = mxGetPr(prhs[0]); 27 | 28 | double *p_in = (mxGetPr(prhs[1])); 29 | int p = (int) *p_in; 30 | 31 | double *knot = mxGetPr(prhs[2]); 32 | int numKnot = mxGetN(prhs[2]); 33 | int m = numKnot - 1; 34 | int n = m - p -1; 35 | 36 | double *points = mxGetPr(prhs[3]); 37 | int numPoints = mxGetN(prhs[3]); 38 | 39 | double *weight = mxGetPr(prhs[4]); 40 | int numWeights = mxGetN(prhs[4]); 41 | 42 | double tol = 100*DBL_EPSILON; 43 | 44 | if(fabs(*xi-knot[numKnot-1]) < tol) 45 | *xi = knot[numKnot-1] - tol; 46 | 47 | /* and evaluate the non-zero basis functions*/ 48 | 49 | double *N = (double *)malloc(sizeof(double)*(p+1)); 50 | double *NURBS = (double *)malloc(sizeof(double)*(p+1)); 51 | double *NURBS_deriv = (double *)malloc(sizeof(double)*(p+1)); 52 | double *NURBS_deriv2 = (double *)malloc(sizeof(double)*(p+1)); 53 | double **ders = init2DArray(n+1, p+1); 54 | 55 | int span = FindSpan(n, p, *xi, knot); 56 | BasisFuns (span, *xi, p, knot, N); 57 | dersBasisFuns (span, *xi, p, n, knot, ders); 58 | 59 | /* and create NURBS approximation */ 60 | int k, c; 61 | double wc,wk,pc; 62 | 63 | for(k = 0; k <=p; k++) 64 | { 65 | double w_interp = 0.0; 66 | double dw_interp_dxi = 0.0; 67 | double dw2_interp_dxi = 0.0; 68 | 69 | for(c = 0; c <= p; c++) 70 | { 71 | wc = weight[span-p+c]; 72 | w_interp += N[c] * wc; 73 | dw_interp_dxi += ders[1][c] * wc; 74 | dw2_interp_dxi += ders[2][c] * wc; 75 | } 76 | 77 | wk = weight[span-p+k]; 78 | NURBS[k] = N[k] * wk / w_interp; 79 | NURBS_deriv[k] = wk * ( w_interp * ders[1][k] - dw_interp_dxi * N[k] ) / (w_interp * w_interp); 80 | NURBS_deriv2[k] = ( wk*ders[2][k] - 2*dw_interp_dxi * NURBS_deriv[k] - dw2_interp_dxi*NURBS[k]) / w_interp; 81 | } 82 | 83 | double interp = 0.0; 84 | double interp_deriv = 0.0; 85 | double interp_deriv2 = 0.0; 86 | 87 | for(c = 0; c <= p; c++) 88 | { 89 | pc = points[span-p+c]; 90 | interp += NURBS[c] * pc; 91 | interp_deriv += NURBS_deriv[c] * pc; 92 | interp_deriv2 += NURBS_deriv2[c] * pc; 93 | } 94 | 95 | free(N); 96 | free(NURBS); 97 | free(NURBS_deriv); 98 | free(NURBS_deriv2); 99 | free2Darray(ders, (n+1)); 100 | 101 | plhs[0] = mxCreateDoubleScalar(interp); 102 | plhs[1] = mxCreateDoubleScalar(interp_deriv); 103 | plhs[2] = mxCreateDoubleScalar(interp_deriv2); 104 | } 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Util/C_files/NURBSfdfd2fInterpolation.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBSfdfd2fInterpolation.mexa64 -------------------------------------------------------------------------------- /Util/C_files/NURBSfdfd2fInterpolation.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBSfdfd2fInterpolation.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files/NURBSfdfd2fInterpolation.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBSfdfd2fInterpolation.mexw64 -------------------------------------------------------------------------------- /Util/C_files/NURBSinterpolation.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS basis function to matlab 12 | 13 | 14 | We expect the function to be called as 15 | [interp interp_deriv] = NURBSinterpolation(xi, p, knot, points, weights) 16 | 17 | xi = point where we want to interpolate 18 | knot = knot vector 19 | vector of points in format [pt1 pt2 pt3 pt4 .... ptn] 20 | Robert Simpson, Cardiff University, UK */ 21 | 22 | if(nrhs != 5) mexErrMsgTxt("You fool! You haven't passed in 3 arguments to the function." 23 | "We expect it to be in the form [interp interp_deriv] = NURBSinterpolation(xi, knot, points)\n"); 24 | 25 | /* First get the inputs */ 26 | 27 | double *xi = mxGetPr(prhs[0]); 28 | 29 | double *p_in = (mxGetPr(prhs[1])); 30 | int p = (int) *p_in; 31 | 32 | double *knot = mxGetPr(prhs[2]); 33 | int numKnot = mxGetN(prhs[2]); 34 | int m = numKnot - 1; 35 | int n = m - p -1; 36 | 37 | double *points = mxGetPr(prhs[3]); 38 | int numPoints = mxGetN(prhs[3]); 39 | 40 | double *weight = mxGetPr(prhs[4]); 41 | int numWeights = mxGetN(prhs[4]); 42 | 43 | double tol = 100*DBL_EPSILON; 44 | 45 | if(fabs(*xi-knot[numKnot-1]) < tol) 46 | *xi = knot[numKnot-1] - tol; 47 | 48 | /* and evaluate the non-zero basis functions*/ 49 | 50 | double *N = (double *)malloc(sizeof(double)*(p+1)); 51 | double *NURBS = (double *)malloc(sizeof(double)*(p+1)); 52 | double *NURBS_deriv = (double *)malloc(sizeof(double)*(p+1)); 53 | double **ders = init2DArray(n+1, p+1); 54 | 55 | int span = FindSpan(n, p, *xi, knot); 56 | BasisFuns (span, *xi, p, knot, N); 57 | dersBasisFuns (span, *xi, p, n, knot, ders); 58 | 59 | /* and create NURBS approximation */ 60 | int k, c; 61 | 62 | for(k = 0; k <=p; k++) 63 | { 64 | double w_interp = 0.0, dw_interp_dxi= 0.0; 65 | 66 | for(c = 0; c <= p; c++) 67 | { 68 | w_interp += N[c] * weight[span-p+c]; 69 | dw_interp_dxi += ders[1][c] * weight[span-p+c]; 70 | } 71 | 72 | NURBS[k] = N[k] * weight[span-p+k] / w_interp; 73 | NURBS_deriv[k] = weight[span-p+k] * ( w_interp * ders[1][k] - dw_interp_dxi * N[k] ) / (w_interp * w_interp); 74 | } 75 | 76 | double interp = 0.0; 77 | double interp_deriv = 0.0; 78 | 79 | for(c = 0; c <= p; c++) 80 | { 81 | interp += NURBS[c] * points[span-p+c]; 82 | interp_deriv += NURBS_deriv[c] * points[span-p+c]; 83 | } 84 | 85 | free(N); 86 | free(NURBS); 87 | free(NURBS_deriv); 88 | free2Darray(ders, (n+1)); 89 | 90 | plhs[0] = mxCreateDoubleScalar(interp); 91 | plhs[1] = mxCreateDoubleScalar(interp_deriv); 92 | } 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /Util/C_files/NURBSinterpolation.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBSinterpolation.mexa64 -------------------------------------------------------------------------------- /Util/C_files/NURBSinterpolation.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBSinterpolation.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files/NURBSinterpolation.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/NURBSinterpolation.mexw64 -------------------------------------------------------------------------------- /Util/C_files/NURBSinterpolation2d.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS basis function to matlab 12 | 13 | // 14 | // We expect the function to be called as 15 | // [interp] = NURBSinterpolation(xi, eta, p, q, uknot, vknot 16 | pointsX, pointsY, weights) 17 | // 18 | // xi = point where we want to interpolate [xi eta] 19 | // uknot = knot vector u direction 20 | // vknot = knot vector v direction 21 | // vector of points in format [pt1 pt2 pt3 pt4 .... ptn] */ 22 | 23 | if(nrhs != 9) mexErrMsgTxt("You fool! You haven't passed in 9 arguments to the function." 24 | "We expect it to be in the form [interp interp_deriv]=NURBSinterpolation(xi, p, q, uknot, vknot, points, weights)\n"); 25 | 26 | /* First get the inputs */ 27 | 28 | double *xi = mxGetPr(prhs[0]); 29 | double *eta = mxGetPr(prhs[1]); 30 | double *p_in = mxGetPr(prhs[2]); 31 | double *q_in = mxGetPr(prhs[3]); 32 | double *uknot = mxGetPr(prhs[4]); 33 | double *vknot = mxGetPr(prhs[5]); 34 | double *pointsX = mxGetPr(prhs[6]); 35 | double *pointsY = mxGetPr(prhs[7]); 36 | double *weight = mxGetPr(prhs[8]); 37 | 38 | /* create output */ 39 | 40 | plhs[0] = mxCreateDoubleMatrix(1,2,mxREAL); 41 | 42 | double *interp = mxGetPr(plhs[0]); 43 | 44 | /* Then use them as in standard C*/ 45 | 46 | int p = (int) *p_in; 47 | int q = (int) *q_in; 48 | 49 | int numKnotU = mxGetN(prhs[4]); 50 | int numKnotV = mxGetN(prhs[5]); 51 | 52 | int mu = numKnotU - 1; 53 | int mv = numKnotV - 1; 54 | 55 | int nu = mu - p - 1; 56 | int nv = mv - q - 1; 57 | 58 | 59 | int numPoints = mxGetN(prhs[6]); 60 | int numWeights = mxGetN(prhs[7]); 61 | 62 | 63 | double tol = 100*DBL_EPSILON; 64 | 65 | if(fabs(*xi -uknot[numKnotU-1]) < tol) *xi = uknot[numKnotU-1] - tol; 66 | if(fabs(*eta-vknot[numKnotV-1]) < tol) *eta = vknot[numKnotV-1] - tol; 67 | 68 | /* and evaluate the non-zero B-spline basis functions*/ 69 | 70 | double *N = (double *)malloc(sizeof(double)*(p+1)); 71 | double *M = (double *)malloc(sizeof(double)*(q+1)); 72 | 73 | int spanU = FindSpan(nu, p, *xi, uknot); 74 | int spanV = FindSpan(nv, q, *eta, vknot); 75 | 76 | BasisFuns (spanU, *xi, p, uknot, N); 77 | BasisFuns (spanV, *eta, q, vknot, M); 78 | 79 | /* and compute the approximation */ 80 | 81 | interp[0] = 0.0; 82 | interp[1] = 0.0; 83 | 84 | double wght = 0.0; 85 | 86 | double tempu, tempv, tempw; 87 | 88 | int vind, uind = spanU - p;; 89 | int k,l,id; 90 | 91 | for(l = 0; l <= q; l++) 92 | { 93 | tempu = 0; 94 | tempv = 0; 95 | tempw = 0; 96 | 97 | vind = spanV - q + l; 98 | 99 | //printf("vind = %d\n", vind); 100 | //printf("uind = %d\n", uind); 101 | 102 | for(k = 0; k <= p; k++) 103 | { 104 | //access control point P(vind,uind+k) 105 | 106 | id = (uind+k)*(nv+1) + vind+1; 107 | tempu += N[k] * (*pointsX+vind*nv+uind+k) * weight[id]; 108 | tempv += N[k] * (*pointsY+vind*nv+uind+k) * weight[id]; 109 | tempw += N[k] * weight[id]; 110 | } 111 | 112 | interp[0] += tempu * M[l]; 113 | interp[1] += tempv * M[l]; 114 | wght += tempw * M[l]; 115 | } 116 | 117 | // projection 118 | 119 | interp[0] /= wght; 120 | interp[1] /= wght; 121 | 122 | free(N); 123 | free(M); 124 | } 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /Util/C_files/NURBSplotter.m: -------------------------------------------------------------------------------- 1 | % This routine uses the C-function to construct the B-spline functions 2 | % Robert Simpson, Cardiff University, UK 3 | 4 | close all 5 | clear all 6 | clc 7 | 8 | 9 | knot=[0 0 0 0.25 0.5 0.75 1 1 1]; 10 | xi=0:0.01:max(knot); 11 | numPts=numel(xi); 12 | m = numel(knot)-1; 13 | p = 2; 14 | n = m - p; 15 | weights = ones(1,n); 16 | weights(2) = 1; 17 | 18 | points = [0 0; 1 3; 2 2; 3 3; 4 5; 6 6; 7 8; 8 4]; 19 | interpolatedPoints = zeros(numPts,2); 20 | weights(4) =1; 21 | weights(6) = 1; 22 | 23 | BsplineVals = zeros(numPts,n); 24 | NURBSderivs = zeros(numPts,n); 25 | 26 | tic 27 | for i=1:n 28 | for c=1:numPts 29 | [BsplineVals(c,i+1) NURBSderivs(c,i+1)] = NURBSbasis(i, p, xi(c), knot, weights); 30 | end 31 | end 32 | toc 33 | 34 | figure 35 | plot(xi, BsplineVals) 36 | 37 | figure 38 | plot(xi, NURBSderivs) 39 | 40 | for c=1:numPts 41 | [interpolatedPoints(c,1)] = NURBSinterpolation(xi(c), p, knot, points(:,1)', weights); 42 | [interpolatedPoints(c,2)] = NURBSinterpolation(xi(c), p, knot, points(:,2)', weights); 43 | end 44 | 45 | figure 46 | plot(interpolatedPoints(:,1), interpolatedPoints(:,2), 'k-', points(:,1), points(:,2), 'ko') 47 | -------------------------------------------------------------------------------- /Util/C_files/SimpleSplinePlotter.m: -------------------------------------------------------------------------------- 1 | % Robert Simpson 2 | % Cardiff University, UK 3 | 4 | close all 5 | clear all 6 | clc 7 | 8 | 9 | knot=[0 0 0 1 2 3 4 4 4]; 10 | xi=0:0.1:max(knot); 11 | numPts=numel(xi); 12 | m = numel(knot)-1; 13 | p = 2; 14 | n = m - p; 15 | weights = ones(1,n); 16 | weights(2) = 1; 17 | 18 | points = [0 0; 0.5 0.5; 1 1.5; 2 2; 3 0.5; 4 2]; 19 | interpolatedPoints = zeros(numPts,2); 20 | % weights(2) =2; 21 | weights(2) =1.5; 22 | weights(3) =2.7; 23 | 24 | BsplineVals = zeros(numPts,n); 25 | 26 | tic 27 | for i=1:n 28 | for c=1:numPts 29 | [BsplineVals(c,i+1) ~] = NURBSbasis(i, p, xi(c), knot, weights); 30 | end 31 | end 32 | toc 33 | 34 | figure(1) 35 | plot(xi, BsplineVals) 36 | 37 | %% and now plot the spline 38 | 39 | for c=1:numPts 40 | [interpolatedPoints(c,1)] = NURBSinterpolation(xi(c), p, knot, points(:,1)', weights); 41 | [interpolatedPoints(c,2)] = NURBSinterpolation(xi(c), p, knot, points(:,2)', weights); 42 | end 43 | 44 | figure(3); hold on 45 | plot(interpolatedPoints(:,1), interpolatedPoints(:,2), 'k-', points(:,1), points(:,2), 'ko') 46 | hold off 47 | 48 | %% and save data for plot program 49 | 50 | save 'dat_files/coords' points -ASCII 51 | save 'dat_files/interpolatedPoints.dat' interpolatedPoints -ASCII 52 | 53 | -------------------------------------------------------------------------------- /Util/C_files/_NURBSbasis.c.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files/_NURBSbasis.c.swp -------------------------------------------------------------------------------- /Util/C_files_win/BSPLINE2DBasisDers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS basis functions and first derivatives to matlab 12 | All non-zero basis functions and derivatives at point [xi,eta] are 13 | computed. 14 | 15 | We expect the function to be called as 16 | [R dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, ... 17 | knotV, weights) 18 | 19 | xi = point, [xi eta], where we want to interpolate 20 | knotU, knotV = knot vectors 21 | weights = vector of weights 22 | 23 | Vinh Phu Nguyen, nvinhphu@gmail.com 24 | */ 25 | 26 | if(nrhs != 5) mexErrMsgTxt("You fool! You haven't passed in 6 arguments to the function." 27 | "We expect it to be in the form [dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, knotV)\n"); 28 | 29 | /* First get the inputs */ 30 | 31 | double *xi = mxGetPr(prhs[0]); 32 | double *p_in = mxGetPr(prhs[1]); 33 | double *q_in = mxGetPr(prhs[2]); 34 | 35 | int p = (int) *p_in; 36 | int q = (int) *q_in; 37 | 38 | double *knotU = mxGetPr(prhs[3]); 39 | double *knotV = mxGetPr(prhs[4]); 40 | 41 | int numKnotU = mxGetN(prhs[3]); 42 | int numKnotV = mxGetN(prhs[4]); 43 | 44 | int nU = numKnotU - 1 - p - 1; 45 | int nV = numKnotV - 1 - q - 1; 46 | int noFuncs = (p+1)*(q+1); 47 | 48 | 49 | 50 | double tol = 100*DBL_EPSILON; 51 | 52 | if(fabs(xi[0]-knotU[numKnotU-1]) < tol) 53 | xi[0] = knotU[numKnotU-1] - tol; 54 | 55 | if(fabs(xi[1]-knotV[numKnotV-1]) < tol) 56 | xi[1] = knotV[numKnotV-1] - tol; 57 | 58 | /* and evaluate the non-zero univariate B-spline basis functions 59 | * and first derivatives 60 | */ 61 | 62 | double *N = (double *)malloc(sizeof(double)*(p+1)); 63 | double *M = (double *)malloc(sizeof(double)*(q+1)); 64 | double **dersN = init2DArray(nU+1, p+1); 65 | double **dersM = init2DArray(nV+1, q+1); 66 | 67 | int spanU = FindSpan(nU, p, xi[0], knotU); 68 | int spanV = FindSpan(nV, q, xi[1], knotV); 69 | 70 | BasisFuns (spanU, xi[0], p, knotU, N); 71 | BasisFuns (spanV, xi[1], q, knotV, M); 72 | 73 | dersBasisFuns (spanU, xi[0], p, nU, knotU, dersN); 74 | dersBasisFuns (spanV, xi[1], q, nV, knotV, dersM); 75 | 76 | 77 | /* and create NURBS approximation */ 78 | 79 | int i, j, k, c; 80 | 81 | /* 82 | for(i=0;i<=p;i++){ 83 | printf("dNdxi= %f\n", dersN[1][i]); 84 | printf("dNdet= %f\n", dersM[1][i]); 85 | }*/ 86 | 87 | /* 88 | int uind = spanU - p; 89 | int vind; 90 | 91 | double w = 0.0; 92 | double dwdxi = 0.0; 93 | double dwdet = 0.0; 94 | double wgt; 95 | 96 | for(j = 0; j <= q; j++) 97 | { 98 | vind = spanV - q + j; 99 | 100 | for(i = 0; i <= p; i++) 101 | { 102 | c = uind + i + vind * (nU+1); 103 | wgt = weight[c]; 104 | 105 | w += N[i] * M[j] * wgt; 106 | dwdxi += dersN[1][i] * M[j] * wgt; 107 | dwdet += dersM[1][j] * N[i] * wgt; 108 | } 109 | } 110 | */ 111 | 112 | /* create output */ 113 | 114 | plhs[0] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 115 | plhs[1] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 116 | plhs[2] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 117 | 118 | double *R = mxGetPr(plhs[0]); 119 | double *dRdxi = mxGetPr(plhs[1]); 120 | double *dRdet = mxGetPr(plhs[2]); 121 | 122 | k = 0; 123 | 124 | double fac; 125 | 126 | /*printf("uind= %d\n", uind); 127 | printf("vind= %d\n", vind); 128 | printf("nU+1= %d\n", nU+1); */ 129 | 130 | for(j = 0; j <= q; j++) 131 | { 132 | for(i = 0; i <= p; i++) 133 | { 134 | R[k] = N[i]*M[j]; 135 | dRdxi[k] = dersN[1][i]*M[j]; 136 | dRdet[k] = dersM[1][j]*N[i]; 137 | 138 | k += 1; 139 | } 140 | } 141 | 142 | /*mexPrintf("\nWe have a knot vector with %d components\n", numWeights); 143 | for(k = 0; k < numWeights; k++) mexPrintf("%2.2f\t", weight[k]); 144 | mexPrintf("\n");*/ 145 | 146 | free(N); 147 | free(M); 148 | free2Darray(dersN, (nU+1)); 149 | free2Darray(dersM, (nV+1)); 150 | } 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /Util/C_files_win/BSPLINE2DBasisDers.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/BSPLINE2DBasisDers.mexa64 -------------------------------------------------------------------------------- /Util/C_files_win/BSPLINE2DBasisDers.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/BSPLINE2DBasisDers.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files_win/FindSpan.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "NURBS.h" 5 | 6 | /* 7 | * Robert Simpson, Cardiff University, UK 8 | */ 9 | 10 | int main(int arg, char* argv[]) 11 | { 12 | int p = 2; // our basis order 13 | double U[] = {0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0,5.0, 5.0}; // knot vector 14 | int m = sizeof(U)/sizeof(double) - 1; // number of knot points 15 | int n = m - p - 1; // number of basis functions 16 | 17 | double u; 18 | int c, span; 19 | 20 | /*printf("Number of knot points: %d\n", m); 21 | 22 | // 23 | // Test our knot span index code 24 | // 25 | 26 | for(c = 0; c < m+1; ++c) 27 | { 28 | span = FindSpan(n, p, U[c], U); 29 | printf("For Xi=%2.1f, the knot span index is i=%d\n\n",U[c], span); 30 | }*/ 31 | 32 | // 33 | // Now let's test our routines which calculate the basis functions and derivatives 34 | // 35 | 36 | int numNonZeroBsFns = p + 1; 37 | 38 | /* 39 | double *N = (double*)malloc(sizeof(double) * numNonZeroBsFns); 40 | 41 | double **ders = init2DArray(n+1, p+1); 42 | 43 | for(c = 0; c < numNonZeroBsFns; ++c) N[c] = 0.0; 44 | 45 | double point[] = {0.0, 1.0, 2,0, 3.0, 4.0, 5.0}; // some sample points to evaluate at 46 | int k = sizeof(point) / sizeof(double); // number of points (for our loop) 47 | int j,d; 48 | 49 | for(j = 0; j < k; ++j) 50 | { 51 | span = FindSpan(n, p, point[j], U); // get the span 52 | BasisFuns( span, point[j], p, U, N); // get the non-zero basis functions 53 | dersBasisFuns(span, point[j], p, n, U, ders); // get the derivatives ders[k][j] 54 | 55 | // print out basis functions 56 | 57 | printf("The non-zero basis functions in the range %2.2f and %2.2f and u=%2.2f are:\n",U[span], U[span+1], point[j]); 58 | for(c = 0; c < numNonZeroBsFns; ++c) printf("\n %2.2f\n", N[c]); 59 | 60 | 61 | // print out derivatives 62 | 63 | for(d = 0; d < (n+1); d++) 64 | { 65 | printf("For k=%d, derivatives are: \n", d); 66 | for(c = 0; c < numNonZeroBsFns; c++) printf("%2.2f\t", ders[d][c]); 67 | printf("\n"); 68 | } 69 | printf("\n\n"); 70 | 71 | } 72 | 73 | free(N); 74 | free2Darray(ders, n+1); 75 | */ 76 | 77 | double *dN = (double*)malloc(sizeof(double) * (n+1)); 78 | double **ders = init2DArray(n+1, p+1); 79 | 80 | double xi, Nip; 81 | int i=2; 82 | 83 | printf("xi\tN\tdNdxi\n"); 84 | for(xi=0.0; xi <= 5.0; xi+=0.1) 85 | { 86 | span = FindSpan(n, p, xi, U); 87 | Nip = OneBasisFun(p, m, U, i, xi); 88 | dersOneBasisFuns(p, m, U, i, xi, n, dN); 89 | 90 | } 91 | 92 | xi = 2.1; 93 | span = FindSpan(n, p, xi, U); 94 | dersBasisFuns(span, xi, p, n, U, ders); // get the derivatives ders[k][j] 95 | printf("\n\n%2.2f\t%2.20f\t%2.20f\t%2.20f\n",xi, ders[1][0], ders[1][1], ders[1][2]); 96 | 97 | free(dN); 98 | free2Darray(ders, n+1); 99 | return 0; 100 | } 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /Util/C_files_win/NURBS.h: -------------------------------------------------------------------------------- 1 | 2 | int FindSpan(int n, int p, double u, double U[]); 3 | void BasisFuns( int i, double u, int p, double U[], double* N); 4 | void dersBasisFuns(int i, double u, int p, int order, double knot[], double **ders); 5 | double OneBasisFun(int p, int m, double U[], int i, double u); 6 | void dersOneBasisFuns(int p, int m, double U[], int i, double u, int n, double* ders); 7 | double** init2DArray(int x, int y); 8 | void free2Darray(double **array, int x); 9 | 10 | -------------------------------------------------------------------------------- /Util/C_files_win/NURBS1DBasis2ndDers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the univariate NURBS basis functions and first/second derivatives to matlab 12 | * All non-zero basis functions and derivatives at point [xi] are 13 | * computed. 14 | * 15 | * We expect the function to be called as 16 | * [R dRdxi dR2dxi] = NURBS1DBasis2ndDers(xi,p,knotU,weights) 17 | * 18 | * xi = where we want to interpolate 19 | * knotU = knot vector 20 | * weights = vector of weights 21 | * 22 | * Vinh Phu Nguyen, nvinhphu@gmail.com 23 | */ 24 | 25 | if(nrhs != 4) mexErrMsgTxt("You fool! You haven't passed in 4 arguments to the function." 26 | "We expect it to be in the form [R dR2dxi] = NURBSinterpolation(xi, p, q, knotU, knotV, weights)\n"); 27 | 28 | /* First get the inputs */ 29 | 30 | double *xi = mxGetPr(prhs[0]); 31 | double *p_in = mxGetPr(prhs[1]); 32 | int p = (int) *p_in; 33 | double *knotU = mxGetPr(prhs[2]); 34 | int numKnotU = mxGetN(prhs[2]); 35 | int nU = numKnotU - 1 - p - 1; 36 | int noFuncs = (p+1); 37 | double *weight = mxGetPr(prhs[3]); 38 | int numWeights = mxGetN(prhs[3]); 39 | 40 | double tol = 100*DBL_EPSILON; 41 | 42 | if(fabs(xi[0]-knotU[numKnotU-1]) < tol) 43 | xi[0] = knotU[numKnotU-1] - tol; 44 | 45 | /* and evaluate the non-zero univariate B-spline basis functions 46 | * and first derivatives 47 | */ 48 | 49 | double *N = (double *)malloc(sizeof(double)*(p+1)); 50 | double **dersN = init2DArray(nU+1, p+1); 51 | 52 | int spanU = FindSpan(nU, p, *xi, knotU); 53 | 54 | BasisFuns (spanU, *xi, p, knotU, N); 55 | dersBasisFuns (spanU, *xi, p, nU, knotU, dersN); 56 | 57 | /*printf("vind = %d\n", numWeights);printf("vind = %f\n", xi[0]);*/ 58 | 59 | /* and create NURBS approximation */ 60 | 61 | int i; 62 | 63 | /* 64 | * for(i=0;i<=p;i++){ 65 | * printf("dNdxi= %f\n", dersN[1][i]); 66 | * printf("dNdet= %f\n", dersM[1][i]); 67 | * }*/ 68 | 69 | int uind = spanU - p; 70 | double w = 0.0; /* N_iw_i */ 71 | double dwdxi = 0.0; /* first derivative of w */ 72 | double d2wdxi = 0.0; /* second derivative of w */ 73 | double wi; /* wi */ 74 | 75 | for(i = 0; i <= p; i++) 76 | { 77 | wi = weight[uind+i]; 78 | w += N[i] * wi; 79 | dwdxi += dersN[1][i] * wi; 80 | d2wdxi += dersN[2][i] * wi; 81 | } 82 | 83 | /* create output */ 84 | 85 | plhs[0] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 86 | plhs[1] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 87 | plhs[2] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 88 | 89 | double *R = mxGetPr(plhs[0]); 90 | double *dRdxi = mxGetPr(plhs[1]); 91 | double *dR2dxi = mxGetPr(plhs[2]); 92 | 93 | double fac; 94 | 95 | /*printf("uind= %d\n", uind); 96 | * printf("vind= %d\n", vind); 97 | * printf("nU+1= %d\n", nU+1); */ 98 | 99 | for(i = 0; i <= p; i++) 100 | { 101 | wi = weight[uind+i]; 102 | fac = wi/(w*w); 103 | R[i] = N[i]*wi/w; 104 | dRdxi[i] = (dersN[1][i]*w - N[i]*dwdxi) * fac; 105 | dR2dxi[i] = wi*(dersN[2][i]/w - 2*dersN[1][i]*dwdxi/w/w - N[i]*d2wdxi/w/w + 2*N[i]*dwdxi*dwdxi/w/w/w) ; 106 | } 107 | 108 | free(N); 109 | free2Darray(dersN, (nU+1)); 110 | } 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /Util/C_files_win/NURBS1DBasis2ndDers.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS1DBasis2ndDers.mexa64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBS1DBasis2ndDers.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS1DBasis2ndDers.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBS1DBasisDers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the univariate NURBS basis functions and first derivatives to matlab 12 | * // All non-zero basis functions and derivatives at point [xi] are 13 | * // computed. 14 | * // 15 | * // We expect the function to be called as 16 | * // [R dRdxi] = NURBS1DBasisDers(xi,p,knotU,weights) 17 | * // 18 | * // xi = where we want to interpolate 19 | * // knotU = knot vector 20 | * // weights = vector of weights 21 | * // 22 | * // Vinh Phu Nguyen, nvinhphu@gmail.com 23 | */ 24 | 25 | if(nrhs != 4) mexErrMsgTxt("You fool! You haven't passed in 6 arguments to the function." 26 | "We expect it to be in the form [dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, knotV, weights)\n"); 27 | 28 | /* First get the inputs */ 29 | 30 | double *xi = mxGetPr(prhs[0]); 31 | double *p_in = mxGetPr(prhs[1]); 32 | int p = (int) *p_in; 33 | double *knotU = mxGetPr(prhs[2]); 34 | int numKnotU = mxGetN(prhs[2]); 35 | int nU = numKnotU - 1 - p - 1; 36 | int noFuncs = (p+1); 37 | double *weight = mxGetPr(prhs[3]); 38 | int numWeights = mxGetN(prhs[3]); 39 | 40 | double tol = 100*DBL_EPSILON; 41 | 42 | if(fabs(xi[0]-knotU[numKnotU-1]) < tol) 43 | xi[0] = knotU[numKnotU-1] - tol; 44 | 45 | /* and evaluate the non-zero univariate B-spline basis functions 46 | * and first derivatives 47 | */ 48 | 49 | double *N = (double *)malloc(sizeof(double)*(p+1)); 50 | double **dersN = init2DArray(nU+1, p+1); 51 | 52 | int spanU = FindSpan(nU, p, *xi, knotU); 53 | 54 | BasisFuns (spanU, *xi, p, knotU, N); 55 | dersBasisFuns (spanU, *xi, p, nU, knotU, dersN); 56 | 57 | 58 | /* and create NURBS approximation */ 59 | 60 | int i; 61 | 62 | /* 63 | * for(i=0;i<=p;i++){ 64 | * printf("dNdxi= %f\n", dersN[1][i]); 65 | * printf("dNdet= %f\n", dersM[1][i]); 66 | * }*/ 67 | 68 | int uind = spanU - p; 69 | double w = 0.0; 70 | double dwdxi = 0.0; 71 | double wgt; 72 | 73 | for(i = 0; i <= p; i++) 74 | { 75 | wgt = weight[uind+i]; 76 | w += N[i] * wgt; 77 | dwdxi += dersN[1][i] * wgt; 78 | } 79 | 80 | /* create output */ 81 | 82 | plhs[0] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 83 | plhs[1] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 84 | 85 | double *R = mxGetPr(plhs[0]); 86 | double *dRdxi = mxGetPr(plhs[1]); 87 | 88 | double fac; 89 | 90 | /*printf("uind= %d\n", uind); 91 | * printf("vind= %d\n", vind); 92 | * printf("nU+1= %d\n", nU+1); */ 93 | 94 | for(i = 0; i <= p; i++) 95 | { 96 | fac = weight[uind+i]/(w*w); 97 | 98 | R[i] = N[i]*fac*w; 99 | dRdxi[i] = (dersN[1][i]*w - N[i]*dwdxi) * fac; 100 | } 101 | 102 | free(N); 103 | free2Darray(dersN, (nU+1)); 104 | } 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Util/C_files_win/NURBS1DBasisDers.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS1DBasisDers.mexa64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBS1DBasisDers.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS1DBasisDers.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBS2DBasis2ndDers.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS2DBasis2ndDers.mexa64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBS2DBasis2ndDers.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS2DBasis2ndDers.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBS2DBasisDers.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS2DBasisDers.mexa64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBS2DBasisDers.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS2DBasisDers.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBS2DBasisDersSpecial.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS basis functions and first derivatives to matlab 12 | // All non-zero basis functions and derivatives at point [xi,eta] are 13 | // computed. With knot spans provided 14 | // 15 | // We expect the function to be called as 16 | // [R dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, ... 17 | // knotV, weights, spans) 18 | // 19 | // xi = point, [xi eta], where we want to interpolate 20 | // knotU, knotV = knot vectors 21 | // weights = vector of weights 22 | // 23 | // Vinh Phu Nguyen, nvinhphu@gmail.com 24 | */ 25 | 26 | if(nrhs != 7) mexErrMsgTxt("You fool! You haven't passed in 6 arguments to the function." 27 | "We expect it to be in the form [dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, knotV, weights)\n"); 28 | 29 | /* First get the inputs */ 30 | 31 | double *xi = mxGetPr(prhs[0]); 32 | double *p_in = mxGetPr(prhs[1]); 33 | double *q_in = mxGetPr(prhs[2]); 34 | 35 | int p = (int) *p_in; 36 | int q = (int) *q_in; 37 | 38 | double *knotU = mxGetPr(prhs[3]); 39 | double *knotV = mxGetPr(prhs[4]); 40 | 41 | int numKnotU = mxGetN(prhs[3]); 42 | int numKnotV = mxGetN(prhs[4]); 43 | 44 | int nU = numKnotU - 1 - p - 1; 45 | int nV = numKnotV - 1 - q - 1; 46 | int noFuncs = (p+1)*(q+1); 47 | 48 | double *weight = mxGetPr(prhs[5]); 49 | int numWeights = mxGetN(prhs[5]); 50 | double *spans = mxGetPr(prhs[6]); 51 | 52 | double tol = 100*DBL_EPSILON; 53 | 54 | if(fabs(xi[0]-knotU[numKnotU-1]) < tol) 55 | xi[0] = knotU[numKnotU-1] - tol; 56 | 57 | if(fabs(xi[1]-knotV[numKnotV-1]) < tol) 58 | xi[1] = knotV[numKnotV-1] - tol; 59 | 60 | /* and evaluate the non-zero univariate B-spline basis functions 61 | * and first derivatives 62 | */ 63 | 64 | double *N = (double *)malloc(sizeof(double)*(p+1)); 65 | double *M = (double *)malloc(sizeof(double)*(q+1)); 66 | double **dersN = init2DArray(nU+1, p+1); 67 | double **dersM = init2DArray(nV+1, q+1); 68 | 69 | int spanU = spans[0]; 70 | int spanV = spans[1]; 71 | 72 | BasisFuns (spanU, xi[0], p, knotU, N); 73 | BasisFuns (spanV, xi[1], q, knotV, M); 74 | 75 | dersBasisFuns (spanU, xi[0], p, nU, knotU, dersN); 76 | dersBasisFuns (spanV, xi[1], q, nV, knotV, dersM); 77 | 78 | /* and create NURBS approximation */ 79 | 80 | int i, j, k, c; 81 | 82 | /* 83 | for(i=0;i<=p;i++){ 84 | printf("dNdxi= %f\n", dersN[1][i]); 85 | printf("dNdet= %f\n", dersM[1][i]); 86 | }*/ 87 | 88 | int uind = spanU - p; 89 | int vind; 90 | 91 | double w = 0.0; 92 | double dwdxi = 0.0; 93 | double dwdet = 0.0; 94 | double wgt; 95 | 96 | for(j = 0; j <= q; j++) 97 | { 98 | vind = spanV - q + j; 99 | 100 | for(i = 0; i <= p; i++) 101 | { 102 | c = uind + i + vind * (nU+1); 103 | wgt = weight[c]; 104 | 105 | w += N[i] * M[j] * wgt; 106 | dwdxi += dersN[1][i] * M[j] * wgt; 107 | dwdet += dersM[1][j] * N[i] * wgt; 108 | } 109 | } 110 | 111 | /* create output */ 112 | 113 | plhs[0] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 114 | plhs[1] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 115 | plhs[2] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 116 | 117 | double *R = mxGetPr(plhs[0]); 118 | double *dRdxi = mxGetPr(plhs[1]); 119 | double *dRdet = mxGetPr(plhs[2]); 120 | 121 | uind = spanU - p; 122 | k = 0; 123 | 124 | double fac; 125 | 126 | /*printf("uind= %d\n", uind); 127 | printf("vind= %d\n", vind); 128 | printf("nU+1= %d\n", nU+1); */ 129 | 130 | for(j = 0; j <= q; j++) 131 | { 132 | vind = spanV - q + j; 133 | 134 | for(i = 0; i <= p; i++) 135 | { 136 | c = uind + i + vind*(nU+1); 137 | fac = weight[c]/(w*w); 138 | 139 | R[k] = N[i]*M[j]*fac*w; 140 | dRdxi[k] = (dersN[1][i]*M[j]*w - N[i]*M[j]*dwdxi) * fac; 141 | dRdet[k] = (dersM[1][j]*N[i]*w - N[i]*M[j]*dwdet) * fac; 142 | 143 | k += 1; 144 | } 145 | } 146 | 147 | /*mexPrintf("\nWe have a knot vector with %d components\n", numWeights); 148 | for(k = 0; k < numWeights; k++) mexPrintf("%2.2f\t", weight[k]); 149 | mexPrintf("\n");*/ 150 | 151 | free(N); 152 | free(M); 153 | free2Darray(dersN, (nU+1)); 154 | free2Darray(dersM, (nV+1)); 155 | } 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /Util/C_files_win/NURBS2DBasisDersSpecial.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS2DBasisDersSpecial.mexa64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBS2DBasisDersSpecial.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS2DBasisDersSpecial.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBS2Dders.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS first derivatives w.r.t xi and eta to matlab 12 | // All non-zero derivatives at point [xi,eta] are computed. 13 | // 14 | // We expect the function to be called as 15 | // [dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, ... 16 | // knotV, weights) 17 | // 18 | // xi = point, [xi eta], where we want to interpolate 19 | // knotU, knotV = knot vectors 20 | // weights = vector of weights 21 | // 22 | // Vinh Phu Nguyen, nvinhphu@gmail.com 23 | */ 24 | 25 | if(nrhs != 6) mexErrMsgTxt("You fool! You haven't passed in 6 arguments to the function." 26 | "We expect it to be in the form [dRdxi dRdeta] = NURBSinterpolation(xi, p, q, knotU, knotV, weights)\n"); 27 | 28 | /* First get the inputs */ 29 | 30 | double *xi = mxGetPr(prhs[0]); 31 | double *p_in = mxGetPr(prhs[1]); 32 | double *q_in = mxGetPr(prhs[2]); 33 | 34 | int p = (int) *p_in; 35 | int q = (int) *q_in; 36 | 37 | double *knotU = mxGetPr(prhs[3]); 38 | double *knotV = mxGetPr(prhs[4]); 39 | 40 | int numKnotU = mxGetN(prhs[3]); 41 | int numKnotV = mxGetN(prhs[4]); 42 | 43 | int nU = numKnotU - 1 - p - 1; 44 | int nV = numKnotV - 1 - q - 1; 45 | int noFuncs = (p+1)*(q+1); 46 | 47 | double *weight = mxGetPr(prhs[5]); 48 | int numWeights = mxGetN(prhs[5]); 49 | 50 | 51 | double tol = 100*DBL_EPSILON; 52 | 53 | if(fabs(xi[0]-knotU[numKnotU-1]) < tol) 54 | xi[0] = knotU[numKnotU-1] - tol; 55 | 56 | if(fabs(xi[1]-knotV[numKnotV-1]) < tol) 57 | xi[1] = knotV[numKnotV-1] - tol; 58 | 59 | /* and evaluate the non-zero univariate B-spline basis functions 60 | * and first derivatives 61 | */ 62 | 63 | double *N = (double *)malloc(sizeof(double)*(p+1)); 64 | double *M = (double *)malloc(sizeof(double)*(q+1)); 65 | double **dersN = init2DArray(nU+1, p+1); 66 | double **dersM = init2DArray(nV+1, q+1); 67 | 68 | int spanU = FindSpan(nU, p, xi[0], knotU); 69 | int spanV = FindSpan(nV, q, xi[1], knotV); 70 | 71 | BasisFuns (spanU, xi[0], p, knotU, N); 72 | BasisFuns (spanV, xi[1], q, knotV, M); 73 | 74 | dersBasisFuns (spanU, xi[0], p, nU, knotU, dersN); 75 | dersBasisFuns (spanV, xi[1], q, nV, knotV, dersM); 76 | 77 | 78 | /* and create NURBS approximation */ 79 | 80 | int i, j, k, c; 81 | 82 | /* 83 | for(i=0;i<=p;i++){ 84 | printf("dNdxi= %f\n", dersN[1][i]); 85 | printf("dNdet= %f\n", dersM[1][i]); 86 | }*/ 87 | 88 | int uind = spanU - p; 89 | int vind; 90 | 91 | double w = 0.0; 92 | double dwdxi = 0.0; 93 | double dwdet = 0.0; 94 | double wgt; 95 | 96 | for(j = 0; j <= q; j++) 97 | { 98 | vind = spanV - q + j; 99 | 100 | for(i = 0; i <= p; i++) 101 | { 102 | c = uind + i + vind * (nU+1); 103 | wgt = weight[c]; 104 | 105 | w += N[i] * M[j] * wgt; 106 | dwdxi += dersN[1][i] * M[j] * wgt; 107 | dwdet += dersM[1][j] * N[i] * wgt; 108 | } 109 | } 110 | 111 | /* create output */ 112 | 113 | plhs[0] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 114 | plhs[1] = mxCreateDoubleMatrix(1,noFuncs,mxREAL); 115 | 116 | double *dRdxi = mxGetPr(plhs[0]); 117 | double *dRdet = mxGetPr(plhs[1]); 118 | 119 | uind = spanU - p; 120 | k = 0; 121 | 122 | double fac; 123 | 124 | for(j = 0; j <= q; j++) 125 | { 126 | vind = spanV - q + j; 127 | 128 | for(i = 0; i <= p; i++) 129 | { 130 | c = uind + i + vind*(nU+1); 131 | fac = weight[c]/(w*w); 132 | 133 | dRdxi[k] = (dersN[1][i]*M[j]*w - N[i]*M[j]*dwdxi) * fac; 134 | dRdet[k] = (dersM[1][j]*N[i]*w - N[i]*M[j]*dwdet) * fac; 135 | 136 | k += 1; 137 | } 138 | } 139 | 140 | /*mexPrintf("\nWe have a knot vector with %d components\n", numWeights); 141 | for(k = 0; k < numWeights; k++) mexPrintf("%2.2f\t", weight[k]); 142 | mexPrintf("\n");*/ 143 | 144 | free(N); 145 | free(M); 146 | free2Darray(dersN, (nU+1)); 147 | free2Darray(dersM, (nV+1)); 148 | } 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /Util/C_files_win/NURBS2Dders.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS2Dders.mexa64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBS2Dders.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS2Dders.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBS3DBasisDers.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS3DBasisDers.mexa64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBS3DBasisDers.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS3DBasisDers.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBS3DBasisDersSpecial.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS3DBasisDersSpecial.mexa64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBS3DBasisDersSpecial.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBS3DBasisDersSpecial.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBSBasis_Ccode.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "NURBS.h" 5 | #include 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS basis function to matlab 12 | 13 | // 14 | // We expect the function to be called as [Nip] = NURBSBasis(i, p, xi, knot, weights) 15 | // 16 | // p = order of basis (0,1,2 etc) 17 | // knot = knot vector 18 | // i = basis function we want (1,2,3 ie. Hughes' notation) 19 | // xi = the coordinate we wish to evaluate at 20 | // weights = the weightings for the NURNS function (length(weights) = m - p -1) */ 21 | 22 | if(nrhs != 5) mexErrMsgTxt("You fool! You haven't passed in 5 arguments to the function." 23 | "We expect it to be in the form [Nip] = NURBSBasis(i, p, xi, knot, weights)\n"); 24 | 25 | int c, k, p, m, i, numKnot, numWeights; 26 | 27 | double *p_in, *m_in, *i_in; 28 | double *knot, *xi, *weight; 29 | 30 | double tol=100*DBL_EPSILON; 31 | 32 | for(c = 0; c < nrhs; c++) 33 | { 34 | switch(c) 35 | { 36 | case 0: 37 | i_in = mxGetPr(prhs[c]); 38 | i = (int)*i_in -1;; 39 | /*mexPrintf("\n\ni=%d\n", i);*/ 40 | 41 | case 1: 42 | p_in = mxGetPr(prhs[c]); 43 | p = (int)*p_in; 44 | /*mexPrintf("\n\np=%d\n", p);*/ 45 | 46 | case 2: 47 | xi = mxGetPr(prhs[c]); 48 | /*mexPrintf("\nxi=%2.20f\n", *xi); */ 49 | 50 | case 3: 51 | knot = mxGetPr(prhs[c]); 52 | numKnot = mxGetN(prhs[c]); 53 | m = numKnot - 1; 54 | /*mexPrintf("\nWe have a knot vector with %d components\n", numKnot); 55 | for(k = 0; k < numKnot; k++) mexPrintf("%2.2f\t", *(knot+k)); 56 | mexPrintf("\n");*/ 57 | 58 | case 4: 59 | weight = mxGetPr(prhs[c]); 60 | numWeights = mxGetM(prhs[c]); 61 | 62 | } 63 | } 64 | 65 | if(fabs(*xi-knot[numKnot-1]) < tol) 66 | *xi = knot[numKnot-1] - tol; 67 | 68 | 69 | /* and call the basis function routine*/ 70 | 71 | double Rip, Nip, dRip_dxi; 72 | double w_interp, dw_interp_dxi ; 73 | 74 | int n = m - p -1; 75 | 76 | double *N = (double *)malloc(sizeof(double)*(p+10)); 77 | double *dN = (double *)malloc(sizeof(double)*(n+10)); 78 | double **ders = init2DArray(n+10, p+10); 79 | 80 | int span = FindSpan(n, p, *xi, knot); 81 | BasisFuns(span, *xi, p, knot, N); 82 | dersBasisFuns(span, *xi, p, n, knot, ders); 83 | 84 | w_interp = 0.0; dw_interp_dxi = 0.0; 85 | 86 | for(c = 0; c <= p; c++) 87 | { 88 | w_interp += N[c] * weight[span-p+c]; 89 | dw_interp_dxi += ders[1][c] * weight[span-p+c]; 90 | } 91 | 92 | dersOneBasisFuns(p, m, knot, i, *xi, n, dN); 93 | 94 | Nip = OneBasisFun(p, m, knot, i, *xi); 95 | 96 | Rip = Nip * weight[i] / w_interp; 97 | 98 | dRip_dxi = weight[i] * ( w_interp * dN[1] - dw_interp_dxi * Nip ) / (w_interp * w_interp); 99 | 100 | free2Darray(ders, (n+10)); 101 | free(N); free(dN); 102 | 103 | plhs[0] = mxCreateDoubleScalar(Rip); plhs[1] = mxCreateDoubleScalar(dRip_dxi); 104 | 105 | 106 | } 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /Util/C_files_win/NURBSbasis.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "NURBS.h" 5 | #include 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS basis function to matlab 12 | 13 | // 14 | // We expect the function to be called as [Nip] = NURBSBasis(i, p, xi, knot, weights) 15 | // 16 | // p = order of basis (0,1,2 etc) 17 | // knot = knot vector 18 | // i = basis function we want (1,2,3 ie. Hughes' notation) 19 | // xi = the coordinate we wish to evaluate at 20 | // weights = the weightings for the NURBS function (length(weights) = m - p -1) */ 21 | 22 | if(nrhs != 5) mexErrMsgTxt("You fool! You haven't passed in 5 arguments to the function." 23 | "We expect it to be in the form [Nip] = NURBSBasis(i, p, xi, knot, weights)\n"); 24 | 25 | int c, k, p, m, i, numKnot, numWeights; 26 | 27 | double *p_in, *m_in, *i_in; 28 | double *knot, *xi, *weight; 29 | 30 | double tol=100*DBL_EPSILON; 31 | 32 | for(c = 0; c < nrhs; c++) 33 | { 34 | switch(c) 35 | { 36 | case 0: 37 | i_in = mxGetPr(prhs[c]); 38 | i = (int)*i_in -1; 39 | /*mexPrintf("\n\ni=%d\n", i);*/ 40 | 41 | case 1: 42 | p_in = mxGetPr(prhs[c]); 43 | p = (int)*p_in; 44 | /*mexPrintf("\n\np=%d\n", p);*/ 45 | 46 | case 2: 47 | xi = mxGetPr(prhs[c]); 48 | /*mexPrintf("\nxi=%2.20f\n", *xi); */ 49 | 50 | case 3: 51 | knot = mxGetPr(prhs[c]); 52 | numKnot = mxGetN(prhs[c]); 53 | m = numKnot - 1; 54 | /*mexPrintf("\nWe have a knot vector with %d components\n", numKnot); 55 | for(k = 0; k < numKnot; k++) mexPrintf("%2.2f\t", *(knot+k)); 56 | mexPrintf("\n");*/ 57 | 58 | case 4: 59 | weight = mxGetPr(prhs[c]); 60 | numWeights = mxGetM(prhs[c]); 61 | 62 | } 63 | } 64 | 65 | if(fabs(*xi-knot[numKnot-1]) < tol) 66 | *xi = knot[numKnot-1] - tol; 67 | 68 | 69 | /* and call the basis function routine*/ 70 | 71 | double Rip, Nip, dRip_dxi; 72 | double w_interp, dw_interp_dxi ; 73 | 74 | int n = m - p -1; 75 | 76 | double *N = (double *)malloc(sizeof(double)*(p+1)); 77 | double *dN = (double *)malloc(sizeof(double)*(p+1)); 78 | double **ders = init2DArray(p+1, p+1); 79 | 80 | int span = FindSpan(n, p, *xi, knot); 81 | 82 | BasisFuns (span, *xi, p, knot, N); 83 | dersBasisFuns(span, *xi, p, p, knot, ders); 84 | 85 | w_interp = 0.0; 86 | dw_interp_dxi = 0.0; 87 | 88 | for(c = 0; c <= p; c++) 89 | { 90 | w_interp += N[c] * weight[span-p+c]; 91 | dw_interp_dxi += ders[1][c] * weight[span-p+c]; 92 | } 93 | 94 | dersOneBasisFuns(p, m, knot, i, *xi, p, dN); 95 | 96 | Nip = OneBasisFun(p, m, knot, i, *xi); 97 | 98 | Rip = Nip * weight[i] / w_interp; 99 | 100 | dRip_dxi = weight[i] * ( w_interp * dN[1] - dw_interp_dxi * Nip ) / (w_interp * w_interp); 101 | 102 | 103 | free2Darray(ders, (p+1)); 104 | free(N); free(dN); 105 | 106 | plhs[0] = mxCreateDoubleScalar(Rip); 107 | plhs[1] = mxCreateDoubleScalar(dRip_dxi); 108 | } 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /Util/C_files_win/NURBSbasis.log: -------------------------------------------------------------------------------- 1 | This is pdfTeX, Version 3.1415926-2.3-1.40.12 (TeX Live 2011) (format=mex 2011.7.3) 12 NOV 2011 06:08 2 | entering extended mode 3 | restricted \write18 enabled. 4 | %&-line parsing enabled. 5 | **NURBSbasis.c NURBS.c 6 | (./NURBSbasis.c 7 | This is MeX Version 1.05 18 XII 1993 (B. Jackowski & M. Ry\'cko) 8 | ! You can't use `macro parameter character #' in vertical mode. 9 | l.1 # 10 | include 11 | ? ZZ 12 | Type to proceed, S to scroll future error messages, 13 | R to run without stopping, Q to run quietly, 14 | I to insert something, E to edit your file, 15 | 1 or ... or 9 to ignore the next 1 to 9 tokens of input, 16 | H for help, X to quit. 17 | ? X 18 | No pages of output. 19 | -------------------------------------------------------------------------------- /Util/C_files_win/NURBSbasis.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBSbasis.mexa64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBSbasis.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBSbasis.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBSfdfd2fInterpolation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS interpolations: c(u), c'(u) and c''(u) to matlab 12 | 13 | // 14 | // We expect the function to be called as 15 | // [cu cu_der cu2_der] = NURBSfdfd2fInterpolation(xi, p, knot, points, weights) 16 | // 17 | // xi = point where we want to interpolate 18 | // knot = knot vector 19 | // vector of points in format [pt1 pt2 pt3 pt4 .... ptn] */ 20 | 21 | if(nrhs != 5) mexErrMsgTxt("You fool! You haven't passed in 3 arguments to the function." 22 | "We expect it to be in the form [interp interp_deriv] = NURBSinterpolation(xi, knot, points)\n"); 23 | 24 | /* First get the inputs */ 25 | 26 | double *xi = mxGetPr(prhs[0]); 27 | 28 | double *p_in = (mxGetPr(prhs[1])); 29 | int p = (int) *p_in; 30 | 31 | double *knot = mxGetPr(prhs[2]); 32 | int numKnot = mxGetN(prhs[2]); 33 | int m = numKnot - 1; 34 | int n = m - p -1; 35 | 36 | double *points = mxGetPr(prhs[3]); 37 | int numPoints = mxGetN(prhs[3]); 38 | 39 | double *weight = mxGetPr(prhs[4]); 40 | int numWeights = mxGetN(prhs[4]); 41 | 42 | double tol = 100*DBL_EPSILON; 43 | 44 | if(fabs(*xi-knot[numKnot-1]) < tol) 45 | *xi = knot[numKnot-1] - tol; 46 | 47 | /* and evaluate the non-zero basis functions*/ 48 | 49 | double *N = (double *)malloc(sizeof(double)*(p+1)); 50 | double *NURBS = (double *)malloc(sizeof(double)*(p+1)); 51 | double *NURBS_deriv = (double *)malloc(sizeof(double)*(p+1)); 52 | double *NURBS_deriv2 = (double *)malloc(sizeof(double)*(p+1)); 53 | double **ders = init2DArray(n+1, p+1); 54 | 55 | int span = FindSpan(n, p, *xi, knot); 56 | BasisFuns (span, *xi, p, knot, N); 57 | dersBasisFuns (span, *xi, p, n, knot, ders); 58 | 59 | /* and create NURBS approximation */ 60 | int k, c; 61 | double wc,wk,pc; 62 | 63 | for(k = 0; k <=p; k++) 64 | { 65 | double w_interp = 0.0; 66 | double dw_interp_dxi = 0.0; 67 | double dw2_interp_dxi = 0.0; 68 | 69 | for(c = 0; c <= p; c++) 70 | { 71 | wc = weight[span-p+c]; 72 | w_interp += N[c] * wc; 73 | dw_interp_dxi += ders[1][c] * wc; 74 | dw2_interp_dxi += ders[2][c] * wc; 75 | } 76 | 77 | wk = weight[span-p+k]; 78 | NURBS[k] = N[k] * wk / w_interp; 79 | NURBS_deriv[k] = wk * ( w_interp * ders[1][k] - dw_interp_dxi * N[k] ) / (w_interp * w_interp); 80 | NURBS_deriv2[k] = ( wk*ders[2][k] - 2*dw_interp_dxi * NURBS_deriv[k] - dw2_interp_dxi*NURBS[k]) / w_interp; 81 | } 82 | 83 | double interp = 0.0; 84 | double interp_deriv = 0.0; 85 | double interp_deriv2 = 0.0; 86 | 87 | for(c = 0; c <= p; c++) 88 | { 89 | pc = points[span-p+c]; 90 | interp += NURBS[c] * pc; 91 | interp_deriv += NURBS_deriv[c] * pc; 92 | interp_deriv2 += NURBS_deriv2[c] * pc; 93 | } 94 | 95 | free(N); 96 | free(NURBS); 97 | free(NURBS_deriv); 98 | free(NURBS_deriv2); 99 | free2Darray(ders, (n+1)); 100 | 101 | plhs[0] = mxCreateDoubleScalar(interp); 102 | plhs[1] = mxCreateDoubleScalar(interp_deriv); 103 | plhs[2] = mxCreateDoubleScalar(interp_deriv2); 104 | } 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Util/C_files_win/NURBSfdfd2fInterpolation.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBSfdfd2fInterpolation.mexa64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBSfdfd2fInterpolation.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBSfdfd2fInterpolation.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBSinterpolation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS basis function to matlab 12 | 13 | 14 | We expect the function to be called as 15 | [interp interp_deriv] = NURBSinterpolation(xi, p, knot, points, weights) 16 | 17 | xi = point where we want to interpolate 18 | knot = knot vector 19 | vector of points in format [pt1 pt2 pt3 pt4 .... ptn] 20 | Robert Simpson, Cardiff University, UK */ 21 | 22 | if(nrhs != 5) mexErrMsgTxt("You fool! You haven't passed in 3 arguments to the function." 23 | "We expect it to be in the form [interp interp_deriv] = NURBSinterpolation(xi, knot, points)\n"); 24 | 25 | /* First get the inputs */ 26 | 27 | double *xi = mxGetPr(prhs[0]); 28 | 29 | double *p_in = (mxGetPr(prhs[1])); 30 | int p = (int) *p_in; 31 | 32 | double *knot = mxGetPr(prhs[2]); 33 | int numKnot = mxGetN(prhs[2]); 34 | int m = numKnot - 1; 35 | int n = m - p -1; 36 | 37 | double *points = mxGetPr(prhs[3]); 38 | int numPoints = mxGetN(prhs[3]); 39 | 40 | double *weight = mxGetPr(prhs[4]); 41 | int numWeights = mxGetN(prhs[4]); 42 | 43 | double tol = 100*DBL_EPSILON; 44 | 45 | if(fabs(*xi-knot[numKnot-1]) < tol) 46 | *xi = knot[numKnot-1] - tol; 47 | 48 | /* and evaluate the non-zero basis functions*/ 49 | 50 | double *N = (double *)malloc(sizeof(double)*(p+1)); 51 | double *NURBS = (double *)malloc(sizeof(double)*(p+1)); 52 | double *NURBS_deriv = (double *)malloc(sizeof(double)*(p+1)); 53 | double **ders = init2DArray(n+1, p+1); 54 | 55 | int span = FindSpan(n, p, *xi, knot); 56 | BasisFuns (span, *xi, p, knot, N); 57 | dersBasisFuns (span, *xi, p, n, knot, ders); 58 | 59 | /* and create NURBS approximation */ 60 | int k, c; 61 | 62 | for(k = 0; k <=p; k++) 63 | { 64 | double w_interp = 0.0, dw_interp_dxi= 0.0; 65 | 66 | for(c = 0; c <= p; c++) 67 | { 68 | w_interp += N[c] * weight[span-p+c]; 69 | dw_interp_dxi += ders[1][c] * weight[span-p+c]; 70 | } 71 | 72 | NURBS[k] = N[k] * weight[span-p+k] / w_interp; 73 | NURBS_deriv[k] = weight[span-p+k] * ( w_interp * ders[1][k] - dw_interp_dxi * N[k] ) / (w_interp * w_interp); 74 | } 75 | 76 | double interp = 0.0; 77 | double interp_deriv = 0.0; 78 | 79 | for(c = 0; c <= p; c++) 80 | { 81 | interp += NURBS[c] * points[span-p+c]; 82 | interp_deriv += NURBS_deriv[c] * points[span-p+c]; 83 | } 84 | 85 | free(N); 86 | free(NURBS); 87 | free(NURBS_deriv); 88 | free2Darray(ders, (n+1)); 89 | 90 | plhs[0] = mxCreateDoubleScalar(interp); 91 | plhs[1] = mxCreateDoubleScalar(interp_deriv); 92 | } 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /Util/C_files_win/NURBSinterpolation.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBSinterpolation.mexa64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBSinterpolation.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/NURBSinterpolation.mexmaci64 -------------------------------------------------------------------------------- /Util/C_files_win/NURBSinterpolation2d.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NURBS.h" 6 | #include "mex.h" 7 | 8 | 9 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 10 | { 11 | /* Return the NURBS basis function to matlab 12 | 13 | // 14 | // We expect the function to be called as 15 | // [interp] = NURBSinterpolation(xi, eta, p, q, uknot, vknot 16 | pointsX, pointsY, weights) 17 | // 18 | // xi = point where we want to interpolate [xi eta] 19 | // uknot = knot vector u direction 20 | // vknot = knot vector v direction 21 | // vector of points in format [pt1 pt2 pt3 pt4 .... ptn] */ 22 | 23 | if(nrhs != 9) mexErrMsgTxt("You fool! You haven't passed in 9 arguments to the function." 24 | "We expect it to be in the form [interp interp_deriv]=NURBSinterpolation(xi, p, q, uknot, vknot, points, weights)\n"); 25 | 26 | /* First get the inputs */ 27 | 28 | double *xi = mxGetPr(prhs[0]); 29 | double *eta = mxGetPr(prhs[1]); 30 | double *p_in = mxGetPr(prhs[2]); 31 | double *q_in = mxGetPr(prhs[3]); 32 | double *uknot = mxGetPr(prhs[4]); 33 | double *vknot = mxGetPr(prhs[5]); 34 | double *pointsX = mxGetPr(prhs[6]); 35 | double *pointsY = mxGetPr(prhs[7]); 36 | double *weight = mxGetPr(prhs[8]); 37 | 38 | /* create output */ 39 | 40 | plhs[0] = mxCreateDoubleMatrix(1,2,mxREAL); 41 | 42 | double *interp = mxGetPr(plhs[0]); 43 | 44 | /* Then use them as in standard C*/ 45 | 46 | int p = (int) *p_in; 47 | int q = (int) *q_in; 48 | 49 | int numKnotU = mxGetN(prhs[4]); 50 | int numKnotV = mxGetN(prhs[5]); 51 | 52 | int mu = numKnotU - 1; 53 | int mv = numKnotV - 1; 54 | 55 | int nu = mu - p - 1; 56 | int nv = mv - q - 1; 57 | 58 | 59 | int numPoints = mxGetN(prhs[6]); 60 | int numWeights = mxGetN(prhs[7]); 61 | 62 | 63 | double tol = 100*DBL_EPSILON; 64 | 65 | if(fabs(*xi -uknot[numKnotU-1]) < tol) *xi = uknot[numKnotU-1] - tol; 66 | if(fabs(*eta-vknot[numKnotV-1]) < tol) *eta = vknot[numKnotV-1] - tol; 67 | 68 | /* and evaluate the non-zero B-spline basis functions*/ 69 | 70 | double *N = (double *)malloc(sizeof(double)*(p+1)); 71 | double *M = (double *)malloc(sizeof(double)*(q+1)); 72 | 73 | int spanU = FindSpan(nu, p, *xi, uknot); 74 | int spanV = FindSpan(nv, q, *eta, vknot); 75 | 76 | BasisFuns (spanU, *xi, p, uknot, N); 77 | BasisFuns (spanV, *eta, q, vknot, M); 78 | 79 | /* and compute the approximation */ 80 | 81 | interp[0] = 0.0; 82 | interp[1] = 0.0; 83 | 84 | double wght = 0.0; 85 | 86 | double tempu, tempv, tempw; 87 | 88 | int vind, uind = spanU - p;; 89 | int k,l,id; 90 | 91 | for(l = 0; l <= q; l++) 92 | { 93 | tempu = 0; 94 | tempv = 0; 95 | tempw = 0; 96 | 97 | vind = spanV - q + l; 98 | 99 | //printf("vind = %d\n", vind); 100 | //printf("uind = %d\n", uind); 101 | 102 | for(k = 0; k <= p; k++) 103 | { 104 | //access control point P(vind,uind+k) 105 | 106 | id = (uind+k)*(nv+1) + vind+1; 107 | tempu += N[k] * (*pointsX+vind*nv+uind+k) * weight[id]; 108 | tempv += N[k] * (*pointsY+vind*nv+uind+k) * weight[id]; 109 | tempw += N[k] * weight[id]; 110 | } 111 | 112 | interp[0] += tempu * M[l]; 113 | interp[1] += tempv * M[l]; 114 | wght += tempw * M[l]; 115 | } 116 | 117 | // projection 118 | 119 | interp[0] /= wght; 120 | interp[1] /= wght; 121 | 122 | free(N); 123 | free(M); 124 | } 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /Util/C_files_win/NURBSplotter.m: -------------------------------------------------------------------------------- 1 | % This routine uses the C-function to construct the B-spline functions 2 | % Robert Simpson, Cardiff University, UK 3 | 4 | close all 5 | clear all 6 | clc 7 | 8 | 9 | knot=[0 0 0 0.25 0.5 0.75 1 1 1]; 10 | xi=0:0.01:max(knot); 11 | numPts=numel(xi); 12 | m = numel(knot)-1; 13 | p = 2; 14 | n = m - p; 15 | weights = ones(1,n); 16 | weights(2) = 1; 17 | 18 | points = [0 0; 1 3; 2 2; 3 3; 4 5; 6 6; 7 8; 8 4]; 19 | interpolatedPoints = zeros(numPts,2); 20 | weights(4) =1; 21 | weights(6) = 1; 22 | 23 | BsplineVals = zeros(numPts,n); 24 | NURBSderivs = zeros(numPts,n); 25 | 26 | tic 27 | for i=1:n 28 | for c=1:numPts 29 | [BsplineVals(c,i+1) NURBSderivs(c,i+1)] = NURBSbasis(i, p, xi(c), knot, weights); 30 | end 31 | end 32 | toc 33 | 34 | figure 35 | plot(xi, BsplineVals) 36 | 37 | figure 38 | plot(xi, NURBSderivs) 39 | 40 | for c=1:numPts 41 | [interpolatedPoints(c,1)] = NURBSinterpolation(xi(c), p, knot, points(:,1)', weights); 42 | [interpolatedPoints(c,2)] = NURBSinterpolation(xi(c), p, knot, points(:,2)', weights); 43 | end 44 | 45 | figure 46 | plot(interpolatedPoints(:,1), interpolatedPoints(:,2), 'k-', points(:,1), points(:,2), 'ko') 47 | -------------------------------------------------------------------------------- /Util/C_files_win/SimpleSplinePlotter.m: -------------------------------------------------------------------------------- 1 | % Robert Simpson 2 | % Cardiff University, UK 3 | 4 | close all 5 | clear all 6 | clc 7 | 8 | 9 | knot=[0 0 0 1 2 3 4 4 4]; 10 | xi=0:0.1:max(knot); 11 | numPts=numel(xi); 12 | m = numel(knot)-1; 13 | p = 2; 14 | n = m - p; 15 | weights = ones(1,n); 16 | weights(2) = 1; 17 | 18 | points = [0 0; 0.5 0.5; 1 1.5; 2 2; 3 0.5; 4 2]; 19 | interpolatedPoints = zeros(numPts,2); 20 | % weights(2) =2; 21 | weights(2) =1.5; 22 | weights(3) =2.7; 23 | 24 | BsplineVals = zeros(numPts,n); 25 | 26 | tic 27 | for i=1:n 28 | for c=1:numPts 29 | [BsplineVals(c,i+1) ~] = NURBSbasis(i, p, xi(c), knot, weights); 30 | end 31 | end 32 | toc 33 | 34 | figure(1) 35 | plot(xi, BsplineVals) 36 | 37 | %% and now plot the spline 38 | 39 | for c=1:numPts 40 | [interpolatedPoints(c,1)] = NURBSinterpolation(xi(c), p, knot, points(:,1)', weights); 41 | [interpolatedPoints(c,2)] = NURBSinterpolation(xi(c), p, knot, points(:,2)', weights); 42 | end 43 | 44 | figure(3); hold on 45 | plot(interpolatedPoints(:,1), interpolatedPoints(:,2), 'k-', points(:,1), points(:,2), 'ko') 46 | hold off 47 | 48 | %% and save data for plot program 49 | 50 | save 'dat_files/coords' points -ASCII 51 | save 'dat_files/interpolatedPoints.dat' interpolatedPoints -ASCII 52 | 53 | -------------------------------------------------------------------------------- /Util/C_files_win/_NURBSbasis.c.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/C_files_win/_NURBSbasis.c.swp -------------------------------------------------------------------------------- /Util/README.md: -------------------------------------------------------------------------------- 1 | This folder contains some utility files for NURBS originally written by Vinh Phu Nguyen. 2 | -------------------------------------------------------------------------------- /Util/nurbs-util/BasisFun.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | function N = BasisFun(i,u,p,U) 3 | %-------------------------------------------------------------- 4 | %function N = BasisFun(i,p,u,U) 5 | % NURBS-Book (algorithm A2.2) 6 | % evalute nonzero basis functions 7 | %INPUT: 8 | % i : current knotspan 9 | % u : evaluation point 10 | % p : degree of the basis functions 11 | % U : knot vector (row vector) 12 | %OUTPUT: 13 | % N : row vector (dim p+1) 14 | % values of the basis function N_(i-p) ... N_(i) 15 | % at the evaluation point u 16 | %-------------------------------------------------------------- 17 | N=zeros(1,p+1); 18 | N(1)=1; 19 | left=zeros(1,p+1); 20 | right=zeros(1,p+1); 21 | for j=1:p 22 | left(j+1) = u-U(i+1-j+1); 23 | right(j+1) = U(i+j+1)-u; 24 | saved = 0; 25 | for r=0:j-1 26 | temp = N(r+1)/(right(r+2)+left(j-r+1)); 27 | N(r+1) = saved + right(r+2)*temp; 28 | saved = left(j-r+1)*temp; 29 | end 30 | N(j+1) = saved; 31 | end 32 | end -------------------------------------------------------------------------------- /Util/nurbs-util/Der1BasisFun.m: -------------------------------------------------------------------------------- 1 | function ders = Der1BasisFun(i,u,p,U) 2 | %-------------------------------------------------------------- 3 | %function ders = Der1BasisFun(i,u,p,U) 4 | % NURBS-Book modified (algorithm A2.3) 5 | % evalute nonzero basis functions and first derivative 6 | %INPUT: 7 | % i : current knotspan 8 | % u : evaluation point 9 | % p : degree of the basis functions 10 | % U : knot vector 11 | %OUTPUT: 12 | % ders : matrix (2 , p+1) 13 | % 1. row vector (dim p+1) 14 | % values of the basis function N_(i-p) ... N_(i) 15 | % at the evaluation point u 16 | % 2. first derivation 17 | %-------------------------------------------------------------- 18 | 19 | ders = zeros(2,p+1); 20 | N = zeros(p+1,p+1); 21 | N(1,1) = 1; 22 | left = zeros(1,p+1); 23 | right = zeros(1,p+1); 24 | 25 | for j=1:p 26 | left(j+1) = u-U(i+1-j+1); 27 | right(j+1) = U(i+j+1)-u; 28 | saved = 0; 29 | for r=0:j-1 30 | N(j+1,r+1) = right(r+2) + left(j-r+1); 31 | temp = N(r+1,j)/N(j+1,r+1); 32 | N(r+1,j+1) = saved + right(r+2)*temp; 33 | saved = left(j-r+1)*temp; 34 | end 35 | N(j+1,j+1) = saved; 36 | end 37 | 38 | for j=0:p 39 | ders(1,j+1) = N(j+1,p+1); 40 | end 41 | %derivative 42 | for r=0:p 43 | %kth derivative 44 | if(r>=1) 45 | ders(2,r+1)= N(r,p)/N(p+1,r); 46 | end 47 | if (r<= p-1) 48 | ders(2,r+1) = ders(2,r+1) -N(r+1,p)/N(p+1,r+1); 49 | end 50 | end 51 | % Multiply through by the correct factors 52 | ders(2,:) = ders(2,:)*p; 53 | end -------------------------------------------------------------------------------- /Util/nurbs-util/FindSpan.m: -------------------------------------------------------------------------------- 1 | function knotSpanIndex = FindSpan(n,p,u,U) 2 | %-------------------------------------------------------------- 3 | %function knotSpanIndex = FindSpan(n,p,u,U) 4 | % NURBS-Book (algorithm A2.1) 5 | % find the knot span index for one variable u 6 | %INPUT: 7 | % n : number of basis function -1 8 | % NURBS-Book: np+1 # basis, np max index (startindex 0) 9 | % here np # basis and max index (startindex 1) 10 | % p : degree of the basis functions 11 | % u : evaluation point 12 | % U : knot vector (row vector) 13 | %OUTPUT: 14 | % knotSpanIndex : index of knot span 15 | %-------------------------------------------------------------- 16 | 17 | 18 | if (u == U(n+2)) 19 | knotSpanIndex= n; 20 | return 21 | end 22 | low = p; 23 | high = n+1; 24 | mid = floor((low + high)/2); 25 | while (u = U(mid+2) ) 26 | if( u < U(mid+1)) 27 | high = mid; 28 | else 29 | low = mid; 30 | end 31 | mid = floor((low+high)/2); 32 | end 33 | knotSpanIndex = mid; 34 | end -------------------------------------------------------------------------------- /Util/nurbs-util/RefineKnotVectCurve.m: -------------------------------------------------------------------------------- 1 | function [Ubar,Qw] = RefineKnotVectCurve(n,p,U,Pw,X,r) 2 | %-------------------------------------------------------------- 3 | %function [Ubar,Qw] = RefineKnotVectCurve(n,p,U,Pw,X,r) 4 | % NURBS-Book (algorithm A5.4) (modified) 5 | % insert multiple knots into curve 6 | %INPUT: 7 | % n : number ob basis functions -1 ! 8 | % NURBS-Book: n+1 # basis, np max index (startindex 0) 9 | % here n # basis and max index (startindex 1) 10 | % p : degree of the basis functions 11 | % U : old knotvector 12 | % Pw : old control points 13 | % X : vector of new knots (multiple entries possible) 14 | % r : (size of X) -1 (count the multple entries as well 15 | % reason: same as above: max X index 16 | %OUTPUT: 17 | % Ubar : newknot vector 18 | % Qw : new control points 19 | %-------------------------------------------------------------- 20 | 21 | %initialise arrays; 22 | dim = size(Pw,2); 23 | Qw = zeros(n+r+2,dim); 24 | Ubar = zeros(1,n+p+1+r); 25 | % 26 | m = n+p+1; 27 | a = FindSpan(n,p,X(1),U); 28 | b = FindSpan(n,p,X(r+1),U); 29 | b = b+1; 30 | 31 | for j=0:a-p 32 | Qw(j+1,:) = Pw(j+1,:); 33 | end 34 | for j=b-1:n 35 | Qw(j+r+2,:) = Pw(j+1,:); 36 | end 37 | for j=0:a 38 | Ubar(j+1)= U(j+1); 39 | end 40 | for j=b+p :m 41 | Ubar(j+r+2) = U(j+1); 42 | end 43 | i=b+p-1; 44 | k=b+p+r; 45 | for j=r:-1:0 46 | while (X(j+1) <= U(i+1) && i>a) 47 | Qw(k-p,:) = Pw(i-p,:); 48 | Ubar(k+1) = U(i+1); 49 | k=k-1; 50 | i=i-1; 51 | end 52 | Qw(k-p,:) = Qw(k-p+1,:); 53 | for l=1:p 54 | ind = k-p+l; 55 | alfa = Ubar(k+l+1) - X(j+1); 56 | if (abs(alfa) == 0) 57 | Qw(ind,:) = Qw(ind+1,:); 58 | else 59 | alfa = alfa/(Ubar(k+l+1) - U(i-p+l+1)); 60 | Qw(ind,:) = alfa* Qw(ind,:) + (1-alfa)* Qw(ind+1,:); 61 | end 62 | end 63 | Ubar(k+1) = X(j+1); 64 | k=k-1; 65 | end 66 | end -------------------------------------------------------------------------------- /Util/nurbs-util/bezierExtraction.m: -------------------------------------------------------------------------------- 1 | function [C nb] = bezierExtraction(knot,p) 2 | % Bezier extraction 3 | % Taken from the master thesis of 4 | % 5 | % 6 | 7 | m = length(knot)-p-1; 8 | a = p+1; 9 | b = a+1; 10 | nb = 1; 11 | C(:,:,1) = eye(p+1); 12 | 13 | while b <= m 14 | C(:,:,nb+1) = eye(p+1); 15 | i=b; 16 | while b <= m && knot(b+1) == knot(b) 17 | b=b+1; 18 | end 19 | 20 | multiplicity = b-i+1; 21 | if multiplicity < p 22 | numerator=knot(b)-knot(a); 23 | for j=p:-1:multiplicity+1 24 | alphas(j-multiplicity)=numerator/(knot(a+j)-knot(a)); 25 | end 26 | r=p-multiplicity; 27 | for j=1:r 28 | save = r-j+1; 29 | s = multiplicity + j; 30 | for k=p+1:-1:s+1 31 | alpha=alphas(k-s); 32 | C(:,k,nb)=alpha*C(:,k,nb)+(1-alpha)*C(:,k-1,nb); 33 | end 34 | if b <= m 35 | C(save:save+j,save,nb+1)=C(p-j+1:p+1,p+1,nb); 36 | end 37 | end 38 | nb=nb+1; 39 | if b <= m 40 | a=b; 41 | b=b+1; 42 | end 43 | elseif multiplicity==p 44 | if b <= m 45 | nb=nb+1; a=b; b=b+1; 46 | end 47 | end 48 | end 49 | 50 | -------------------------------------------------------------------------------- /Util/nurbs-util/bezierExtraction2D.m: -------------------------------------------------------------------------------- 1 | function [C,Cxi,Cet] = bezierExtraction2D(uknot,vknot,p,q) 2 | % 3 | % Bezier extraction operators for a 2D NURBS/BSpline. 4 | % 5 | % VP Nguyen 6 | % Cardiff University, UK 7 | 8 | % Bezier extraction operators for xi and eta 9 | % nb1: number of elements along xi direction 10 | % nb2: number of elements along eta direction 11 | 12 | [Cxi,nb1] = bezierExtraction(uknot,p); 13 | [Cet,nb2] = bezierExtraction(vknot,q); 14 | 15 | % For Bsplines/NURBS, the element Bezier extraction 16 | % operator is square. 17 | 18 | size1 = size(Cxi(:,:,1),1); 19 | size2 = size(Cet(:,:,1),1); 20 | 21 | % Bezier extraction operators for the whole mesh 22 | % as the tensor product of Cxi and Cet 23 | 24 | C = zeros(size1*size2,size1*size2,nb1*nb2); 25 | 26 | for eta=1:nb2 27 | for xi=1:nb1 28 | e = (eta-1)*nb1 + xi; 29 | for row=1:size2 30 | ird = (row-1)*size1 + 1; 31 | jrd = row*size1; 32 | for col=1:size2 33 | icd = (col-1)*size1 + 1; 34 | jcd = col*size1; 35 | C(ird:jrd,icd:jcd,e) = Cet(row,col,eta) * Cxi(:,:,xi); 36 | end 37 | end 38 | end 39 | end -------------------------------------------------------------------------------- /Util/nurbs-util/bezierExtractionExample.m: -------------------------------------------------------------------------------- 1 | % Example showing how to the Bezier extraction 2 | % 3 | 4 | uknot = [0 0 0 1/3 2/3 1 1 1]; 5 | vknot = [0 0 0 1/3 2/3 1 1 1]; 6 | p = 2; 7 | q = 2; 8 | 9 | [C1,nb1] = bezierExtraction(uknot,p); 10 | [C2,nb2] = bezierExtraction(vknot,q); 11 | 12 | C = bezierExtraction2D(uknot,vknot,p,q); -------------------------------------------------------------------------------- /Util/nurbs-util/bsplineBasisDers.m: -------------------------------------------------------------------------------- 1 | Nxi = []; 2 | Neta = []; 3 | dNdxi = []; 4 | dNdeta = []; 5 | dRdxi = []; 6 | dRdeta = []; 7 | N = []; 8 | 9 | % compute derivative of basis functions w.r.t parameter coord 10 | 11 | for in=1:noFnsU 12 | [Ni,dNi] = NURBSbasis (connU(in),p,Xi,uKnot,weights); 13 | Nxi = [Nxi Ni]; 14 | dNdxi = [dNdxi dNi]; 15 | end 16 | 17 | for in=1:noFnsV 18 | [Ni,dNi] = NURBSbasis (connV(in),q,Eta,vKnot,weights); 19 | Neta = [Neta Ni]; 20 | dNdeta = [dNdeta dNi]; 21 | end 22 | 23 | % derivate of R=Nxi*Neta w.r.t xi and eta 24 | % this is derivative of shape functions in FEM 25 | 26 | for j=1:noFnsV 27 | for i=1:noFnsU 28 | dRdxi = [dRdxi dNdxi(i) * Neta(j)]; 29 | dRdeta = [dRdeta Nxi(i) * dNdeta(j)]; 30 | N = [N Nxi(i) * Neta(j)]; 31 | end 32 | end -------------------------------------------------------------------------------- /Util/nurbs-util/c.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 0 0 1 1 2 3 4 4 5 6 7 7 8 ; 4 | 1 0 1 1 2 3 4 4 5 6 7 7 8 ; 5 | 6 | 7 | 0 0 1 2 2 3 4 5 5 6 7 8 8 ; 8 | 1 0 0 1 2 3 3 4 5 6 6 7 8 ; 9 | 10 | 11 | 0 1.0 1.0 0.5 0.5 1.0 1.0 0.5 0.5 1.0 1.0 0.5 0.5 ; 12 | 1 0.5 0.5 1.0 1.0 0.5 0.5 1.0 1.0 0.5 0.5 1.0 1.0 ; 13 | 14 | 15 | -------------------------------------------------------------------------------- /Util/nurbs-util/convert2DNurbs.m: -------------------------------------------------------------------------------- 1 | % convert a 2D NURBS object (created using nrbmak(controlPts,{uKnot 2 | % vKnot});) to the usual data structure 3 | % Vinh Phu Nguyen, March 2012 4 | % nvinhphu@gmail.com 5 | 6 | p = solid.order(1)-1; 7 | q = solid.order(2)-1; 8 | uKnot = cell2mat(solid.knots(1)); 9 | vKnot = cell2mat(solid.knots(2)); 10 | noPtsX = length(uKnot)-p-1; 11 | noPtsY = length(vKnot)-q-1; 12 | weights = reshape(solid.coefs(4,:,:),noPtsX*noPtsY,1); 13 | 14 | controlPts = []; 15 | 16 | for iy=1:noPtsY 17 | controlPts = [controlPts; solid.coefs(1:2,:,iy)']; 18 | end 19 | 20 | % our controlPts only stores (x,y,z) not (w*x,w*y,w*z) 21 | 22 | controlPts(:,1) = controlPts(:,1)./weights; 23 | controlPts(:,2) = controlPts(:,2)./weights; 24 | 25 | -------------------------------------------------------------------------------- /Util/nurbs-util/convert2DNurbsToPatch.m: -------------------------------------------------------------------------------- 1 | function patch = convert2DNurbsToPatch(nurbs) 2 | 3 | % convert a 2D NURBS object (created using nrbmak(controlPts,{uKnot 4 | % vKnot});) to the usual data structure 5 | % Vinh Phu Nguyen, March 2012 6 | % nvinhphu@gmail.com 7 | 8 | p = nurbs.order(1)-1; 9 | q = nurbs.order(2)-1; 10 | uKnot = cell2mat(nurbs.knots(1)); 11 | vKnot = cell2mat(nurbs.knots(2)); 12 | noPtsX = length(uKnot)-p-1; 13 | noPtsY = length(vKnot)-q-1; 14 | weights = reshape(nurbs.coefs(4,:,:),noPtsX*noPtsY,1); 15 | 16 | controlPts = []; 17 | 18 | for iy=1:noPtsY 19 | controlPts = [controlPts; nurbs.coefs(1:2,:,iy)']; 20 | end 21 | 22 | controlPts(:,1)=controlPts(:,1)./weights; 23 | controlPts(:,2)=controlPts(:,2)./weights; 24 | 25 | patch = patch2D(uKnot,vKnot,p,q,controlPts,weights); -------------------------------------------------------------------------------- /Util/nurbs-util/convert3DNurbs.m: -------------------------------------------------------------------------------- 1 | % convert GeoPDEs 3D NURBS object to the data structures 2 | % used in IGA code. 3 | % VP Nguyen, 2012. 4 | 5 | p = solid.order(1)-1; 6 | q = solid.order(2)-1; 7 | r = solid.order(3)-1; 8 | uKnot = cell2mat(solid.knots(1)); 9 | vKnot = cell2mat(solid.knots(2)); 10 | wKnot = cell2mat(solid.knots(3)); 11 | noPtsX = length(uKnot)-p-1; 12 | noPtsY = length(vKnot)-q-1; 13 | noPtsZ = length(wKnot)-r-1; 14 | weights = reshape(solid.coefs(4,:,:),noPtsX*noPtsY*noPtsZ,1); 15 | 16 | controlPts = []; 17 | 18 | for iz=1:noPtsZ 19 | for iy=1:noPtsY 20 | controlPts = [controlPts; solid.coefs(1:3,:,iy,iz)']; 21 | end 22 | end 23 | 24 | % our controlPts only stores (x,y,z) not (w*x,w*y,w*z) 25 | 26 | controlPts(:,1) = controlPts(:,1)./weights; 27 | controlPts(:,2) = controlPts(:,2)./weights; 28 | controlPts(:,3) = controlPts(:,3)./weights; 29 | -------------------------------------------------------------------------------- /Util/nurbs-util/dersbasisfuns.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/nurbs-util/dersbasisfuns.m -------------------------------------------------------------------------------- /Util/nurbs-util/feaplyc2.m: -------------------------------------------------------------------------------- 1 | function [kk,ff]=feaplyc2(kk,ff,bcdof,bcvall) 2 | 3 | %---------------------------------------------------------- 4 | % Purpose: 5 | % Apply constraints to matrix equation [kk]{x}={ff} 6 | % 7 | % Synopsis: 8 | % [kk,ff]=feaplybc(kk,ff,bcdof,bcval) 9 | % 10 | % Variable Description: 11 | % kk - system matrix before applying constraints 12 | % ff - system vector before applying constraints 13 | % bcdof - a vector containging constrained d.o.f 14 | % bcval - a vector containing contained value 15 | % 16 | % For example, there are constraints at d.o.f=2 and 10 17 | % and their constrained values are 0.0 and 2.5, 18 | % respectively. Then, bcdof(1)=2 and bcdof(2)=10; and 19 | % bcval(1)=1.0 and bcval(2)=2.5. 20 | %----------------------------------------------------------- 21 | 22 | n=length(bcdof); 23 | sdof=length(kk); 24 | 25 | for i=1:n 26 | c=bcdof(i); 27 | for j=1:sdof 28 | kk(c,j)=0; 29 | end 30 | kk(c,c)=1; 31 | ff(c,1)=bcvall(i); 32 | end 33 | 34 | -------------------------------------------------------------------------------- /Util/nurbs-util/gbeam.m: -------------------------------------------------------------------------------- 1 | function [eldisp,estress]=gbeam(x,y,p,emodu,poisson,d,l) 2 | %----------------------------------------------------------------------- 3 | % analytical solution: 4 | % ux=Py/(6EI)*[(6L-3x)*x+(2+poisson)*(y^2-D^2/4)]; 5 | % uy=-P/(6EI)*[3*poisson*y^2*(L-x)+(4+5*poisson)*D^2*x/4+(3*L-x)*x^2]; 6 | %----------------------------------------------------------------------- 7 | y=y-d/2;% move (0,0) to below left corner 8 | inert=d*d*d/12; 9 | pei=p/(6*emodu*inert); 10 | ux=pei*y*((6*l-3*x)*x+(2+poisson)*(y*y-d*d/4)); 11 | uy=-pei*(3*poisson*y*y*(l-x)+(4+5*poisson)*d*d*x/4+(3*l-x)*x*x); 12 | dux=pei*6*(l-x)*y; 13 | dvy=-pei*6*poisson*y*(l-x); 14 | dxy=pei*6*(1+poisson)*(y*y-d*d/4); % shearing strain: duy+dvx 15 | 16 | sigx=p*(l-x)*y/inert; 17 | sigy=0; 18 | sigxy=p*(y*y-d*d/4)/2/inert; 19 | 20 | eldisp=[ux;uy]; 21 | %estrain=[dux;dvy;dxy]; 22 | estress=[sigx;sigy;sigxy]; 23 | 24 | -------------------------------------------------------------------------------- /Util/nurbs-util/genGP_GW.m: -------------------------------------------------------------------------------- 1 | function [gp,gw]=genGP_GW(ngauss) 2 | if (ngauss==1) 3 | gp(1) = 0.000000000000000; 4 | gw(1) = 2.000000000000000; 5 | elseif ngauss==2 6 | gp(1) = 0.577350269189626; 7 | gp(2) =-0.577350269189626; 8 | gw(1) = 1.000000000000000; 9 | gw(2) = 1.000000000000000; 10 | elseif ngauss==3 11 | gp(1) = 0.774596669241483; 12 | gp(2) =-0.774596669241483; 13 | gp(3) = 0.000000000000000; 14 | gw(1) = 0.555555555555556; 15 | gw(2) = 0.555555555555556; 16 | gw(3) = 0.888888888888889; 17 | elseif(ngauss==4) 18 | gp(1) = -0.86113631159405257524; 19 | gp(2) = -0.33998104358485626481; 20 | gp(3) = 0.33998104358485626481; 21 | gp(4) = 0.86113631159405257524; 22 | gw(1) = 0.34785484513745385736; 23 | gw(2) = 0.65214515486254614264; 24 | gw(3) = 0.65214515486254614264; 25 | gw(4) = 0.34785484513745385736; 26 | elseif(ngauss==5) 27 | gp(1) = -.90617984593866399282; 28 | gp(2) = -.53846931010568309105; 29 | gp(3) = 0.0; 30 | gp(4) = .53846931010568309105; 31 | gp(5) = .90617984593866399282; 32 | gw(1) = .23692688505618908749; 33 | gw(2) = .47862867049936646808; 34 | gw(3) = .56888888888888888888; 35 | gw(4) = .47862867049936646808; 36 | gw(5) = .23692688505618908749; 37 | elseif(ngauss==6) 38 | gp(1) = -.9324695142031520; 39 | gp(2) = -.6612093864662645; 40 | gp(3) = -.2386191860831969; 41 | gp(4) = .2386191860831969; 42 | gp(5) = .6612093864662645; 43 | gp(6) = .9324695142031520; 44 | gw(1) = .1713244923791703; 45 | gw(2) = .3607615730481386; 46 | gw(3) = .4679139345726911; 47 | gw(4) = .4679139345726911; 48 | gw(5) = .3607615730481386; 49 | gw(6) = .1713244923791703; 50 | elseif(ngauss==7) 51 | gp(1) = -.9491079123427585; 52 | gp(2) = -.7415311855993944; 53 | gp(3) = -.4058451513773972; 54 | gp(4) = 0.0; 55 | gp(5) = .4058451513773972; 56 | gp(6) = .7415311855993944; 57 | gp(7) = .9491079123427585; 58 | gw(1) = .1294849661688697; 59 | gw(2) = .2797053914892767; 60 | gw(3) = .3818300505051189; 61 | gw(4) = .4179591836734694; 62 | gw(5) = .3818300505051189; 63 | gw(6) = .2797053914892767; 64 | gw(7) = .1294849661688697; 65 | elseif(ngauss==8) 66 | gp(1) = -.9602898564975362; 67 | gp(2) = -.7966664774136267; 68 | gp(3) = -.5255324099163290; 69 | gp(4) = -.1834346424956498; 70 | gp(5) = .1834346424956498; 71 | gp(6) = .5255324099163290; 72 | gp(7) = .7966664774136267; 73 | gp(8) = .9602898564975362; 74 | gw(1) = .1012285362903763; 75 | gw(2) = .2223810344533745; 76 | gw(3) = .3137066458778873; 77 | gw(4) = .3626837833783620; 78 | gw(5) = .3626837833783620; 79 | gw(6) = .3137066458778873; 80 | gw(7) = .2223810344533745; 81 | gw(8) = .1012285362903763; 82 | elseif(ngauss==9) 83 | gp(1) = -.9681602395076261; 84 | gp(2) = -.8360311073266358; 85 | gp(3) = -.6133714327005904; 86 | gp(4) = -.3242534234038089; 87 | gp(5) = 0.0; 88 | gp(6) = .3242534234038089; 89 | gp(7) = .6133714327005904; 90 | gp(8) = .8360311073266358; 91 | gp(9) = .9681602395076261; 92 | gw(1) = .0812743883615744; 93 | gw(2) = .1806481606948574; 94 | gw(3) = .2606106964029354; 95 | gw(4) = .3123470770400029; 96 | gw(5) = .3302393550012598; 97 | gw(6) = .3123470770400028; 98 | gw(7) = .2606106964029355; 99 | gw(8) = .1806481606948574; 100 | gw(9) = .0812743883615744; 101 | 102 | elseif (ngauss==15) 103 | gp(1) = -.9879925180204854; 104 | gp(2) = -.9372733924007059; 105 | gp(3) = -.8482065834104272; 106 | gp(4) = -.7244177313601700; 107 | gp(5) = -.5709721726085388; 108 | gp(6) = -.3941513470775634; 109 | gp(7) = -.2011940939974345; 110 | gp(8) = 0.0; 111 | gp(9) = .2011940939974345; 112 | gp(10) = .3941513470775634; 113 | gp(11) = .5709721726085388; 114 | gp(12) = .7244177313601700; 115 | gp(13) = .8482065834104272; 116 | gp(14) = .9372733924007059; 117 | gp(15) = .9879925180204854; 118 | gw(1) = .03075324199611807; 119 | gw(2) = .07036604748811134; 120 | gw(3) = .1071592204671351; 121 | gw(4) = .1395706779261761; 122 | gw(5) = .1662692058169852; 123 | gw(6) = .1861610000155741; 124 | gw(7) = .1984314853271374; 125 | gw(8) = .2025782419255562; 126 | gw(9) = .1984314853271374; 127 | gw(10) = .1861610000155741; 128 | gw(11) = .1662692058169852; 129 | gw(12) = .1395706779261761; 130 | gw(13) = .1071592204671351; 131 | gw(14) = .07036604748811134; 132 | gw(15) = .03075324199611807; 133 | else 134 | disp('Error: Invalid number of Gauss points') 135 | end 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /Util/nurbs-util/getNewKnots.m: -------------------------------------------------------------------------------- 1 | function newKnots = getNewKnots(uKnot,p,weights,controlPts,dir,elConnU) 2 | 3 | % Insert new knots into uKnot in such a way that the resulting mesh 4 | % in the physical space is uniform. 5 | % Vinh Phu Nguyen 6 | % Delft University of Technology, March 2012 7 | 8 | uniqueKnot = unique(uKnot); 9 | noPts = length(uniqueKnot); 10 | node = zeros(noPts,2); 11 | 12 | eps = 1e-12; 13 | 14 | %% 15 | %% the following is problem-dependent!!! 16 | 17 | if (dir==1) 18 | index = find(abs(controlPts(:,2)+6)<=eps); 19 | else 20 | index = find(controlPts(:,1)==0); 21 | end 22 | 23 | points = controlPts(index,:); 24 | %% 25 | 26 | for i=1:noPts 27 | xi = uniqueKnot(i); 28 | node(i,1) = NURBSinterpolation(xi,p, uKnot, points(:,1), weights); 29 | node(i,2) = NURBSinterpolation(xi,p, uKnot, points(:,2), weights); 30 | end 31 | 32 | newKnots = []; 33 | 34 | for i=1:noPts-1 35 | if dir==1 36 | x1 = node(i, 1); 37 | x2 = node(i+1,1); 38 | else 39 | x1 = node(i, 2); 40 | x2 = node(i+1,2); 41 | end 42 | 43 | x = 0.5*(x1 + x2); 44 | 45 | xi = inverseMapping1DNURBS (x,uKnot,points,p,dir,elConnU,1); 46 | 47 | newKnots = [newKnots xi]; 48 | end 49 | -------------------------------------------------------------------------------- /Util/nurbs-util/hRefineNURBS.m: -------------------------------------------------------------------------------- 1 | function nurbs = hRefineNURBS(nurbs,refineCount) 2 | 3 | % h-refinement for NURBS surfaces 4 | % Vinh Phu Nguyen, March 2012 5 | % nvinhphu@gmail.com 6 | 7 | uKnot = cell2mat(nurbs.knots(1)); 8 | vKnot = cell2mat(nurbs.knots(2)); 9 | 10 | for i=1:refineCount 11 | uKnotVectorU = unique(uKnot); 12 | uKnotVectorV = unique(vKnot); 13 | 14 | % new knots along two directions (uniform) 15 | 16 | newKnotsX = uKnotVectorU(1:end-1) + 0.5*diff(uKnotVectorU); 17 | newKnotsY = uKnotVectorV(1:end-1) + 0.5*diff(uKnotVectorV); 18 | 19 | newKnots = {newKnotsX newKnotsY}; 20 | 21 | % h-refinement 22 | 23 | nurbs = nrbkntins(nurbs,newKnots); 24 | uKnot = cell2mat(nurbs.knots(1)); 25 | vKnot = cell2mat(nurbs.knots(2)); 26 | end -------------------------------------------------------------------------------- /Util/nurbs-util/hRefinement2d.m: -------------------------------------------------------------------------------- 1 | % Vinh Phu Nguyen 2 | % Delft University of Technology 3 | % Adapted from ISOGAT, A.V. Vuong. 4 | 5 | for c=1:refineCount 6 | uKnotVectorU = unique(uKnot); 7 | uKnotVectorV = unique(vKnot); 8 | 9 | % new knots along two directions 10 | 11 | newKnotsX = uKnotVectorU(1:end-1) + 0.5*diff(uKnotVectorU); 12 | newKnotsY = uKnotVectorV(1:end-1) + 0.5*diff(uKnotVectorV); 13 | 14 | %% h-refinement (NURBS) in x-direction 15 | dim = size(controlPts,2); 16 | 17 | nonewkX = size(newKnotsX,2); 18 | newprojcoord = zeros(noPtsX*noPtsY+nonewkX*noPtsY,dim+1); 19 | 20 | rstart = 1; 21 | wstart = 1; 22 | 23 | for j=1:noPtsY 24 | rstop = rstart + noPtsX-1; 25 | wstop = wstart + noPtsX-1 + nonewkX; 26 | 27 | locCP = controlPts(rstart:rstop,:); 28 | locweights = weights (rstart:rstop); 29 | locprojcoord = nurb2proj(noPtsX, locCP, locweights); 30 | 31 | % refinement of x 32 | [tempknotVectorX,tempControlPts] = ... 33 | RefineKnotVectCurve(noPtsX-1,p,uKnot,locprojcoord,newKnotsX,nonewkX-1); 34 | 35 | newprojcoord(wstart:wstop,:)=tempControlPts; 36 | wstart = wstop+1; 37 | rstart = rstop+1; 38 | end 39 | 40 | uKnot = tempknotVectorX; 41 | [controlPts, weights] = proj2nurbs(newprojcoord); 42 | noPtsX = noPtsX+nonewkX; 43 | 44 | %% h-refinement (NURBS) in y-direction) 45 | nonewkY = size(newKnotsY,2); 46 | newprojcoord = zeros(noPtsX*noPtsY+nonewkY*noPtsY,dim+1); 47 | 48 | for i=1:noPtsX 49 | %create index for reading controlPoints 50 | rcpindex = i:noPtsX:noPtsX*noPtsY; 51 | locCP = controlPts(rcpindex,:); 52 | locweights = weights(rcpindex); 53 | locprojcoord = nurb2proj(noPtsY, locCP, locweights); 54 | 55 | % refinement of y 56 | [tempknotVectorY,tempcontrolPoints] = ... 57 | RefineKnotVectCurve(noPtsY-1,q,vKnot,locprojcoord,newKnotsY,nonewkY-1); 58 | 59 | wcpindex = i:noPtsX:noPtsX*(noPtsY+nonewkY); 60 | newprojcoord(wcpindex,:) = tempcontrolPoints; 61 | end 62 | 63 | vKnot = tempknotVectorY; 64 | [controlPts, weights] = proj2nurbs(newprojcoord); 65 | noPtsY = noPtsY + nonewkY; 66 | end 67 | -------------------------------------------------------------------------------- /Util/nurbs-util/hRefinement2dUniform.m: -------------------------------------------------------------------------------- 1 | % h-refinement using knot insertion 2 | % knots are inserted in such a way that a uniform mesh 3 | % in physical space is obtained. Positions of new knots 4 | % are determined by calling function "getNewKnots". 5 | % Vinh Phu Nguyen, March 2012 6 | % Delft University of Technology 7 | % Adapted from ISOGAT, A.V. Vuong. 8 | 9 | for c=1:refineCount 10 | uKnotVectorU = unique(uKnot); 11 | uKnotVectorV = unique(vKnot); 12 | 13 | noElemsU = length(uKnotVectorU)-1; % # of elements xi dir. 14 | noElemsV = length(uKnotVectorV)-1; % # of elements eta dir. 15 | 16 | [elRangeU,elConnU] = buildConnectivity(p,uKnot,noElemsU); 17 | [elRangeV,elConnV] = buildConnectivity(q,vKnot,noElemsV); 18 | 19 | % new knots along two directions 20 | 21 | newKnotsX = getNewKnots(uKnot,p,weights,controlPts,1,elConnU); 22 | newKnotsY = getNewKnots(vKnot,q,weights,controlPts,2,elConnV); 23 | 24 | %% h-refinement (NURBS) in x-direction 25 | dim = size(controlPts,2); 26 | nonewkX = size(newKnotsX,2); 27 | newprojcoord = zeros(noPtsX*noPtsY+nonewkX*noPtsY,dim+1); 28 | 29 | rstart = 1; 30 | wstart = 1; 31 | 32 | for j=1:noPtsY 33 | rstop = rstart + noPtsX-1; 34 | wstop = wstart + noPtsX-1 + nonewkX; 35 | 36 | locCP = controlPts(rstart:rstop,:); 37 | locweights = weights (rstart:rstop); 38 | locprojcoord = nurb2proj(noPtsX, locCP, locweights); 39 | 40 | % refinement of x 41 | [tempknotVectorX,tempControlPts] = ... 42 | RefineKnotVectCurve(noPtsX-1,p,uKnot,locprojcoord,newKnotsX,nonewkX-1); 43 | 44 | newprojcoord(wstart:wstop,:)=tempControlPts; 45 | wstart = wstop+1; 46 | rstart = rstop+1; 47 | end 48 | 49 | uKnot = tempknotVectorX; 50 | [controlPts, weights] = proj2nurbs(newprojcoord); 51 | noPtsX = noPtsX+nonewkX; 52 | 53 | %% h-refinement (NURBS) in y-direction) 54 | nonewkY = size(newKnotsY,2); 55 | newprojcoord = zeros(noPtsX*noPtsY+nonewkY*noPtsY,dim+1); 56 | 57 | for i=1:noPtsX 58 | %create index for reading controlPoints 59 | rcpindex = i:noPtsX:noPtsX*noPtsY; 60 | locCP = controlPts(rcpindex,:); 61 | locweights = weights(rcpindex); 62 | locprojcoord = nurb2proj(noPtsY, locCP, locweights); 63 | 64 | % refinement of y 65 | [tempknotVectorY,tempcontrolPoints] = ... 66 | RefineKnotVectCurve(noPtsY-1,q,vKnot,locprojcoord,newKnotsY,nonewkY-1); 67 | 68 | wcpindex = i:noPtsX:noPtsX*(noPtsY+nonewkY); 69 | newprojcoord(wcpindex,:) = tempcontrolPoints; 70 | end 71 | 72 | vKnot = tempknotVectorY; 73 | [controlPts, weights] = proj2nurbs(newprojcoord); 74 | noPtsY = noPtsY + nonewkY; 75 | end 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /Util/nurbs-util/inverseMapping1DNURBS.m: -------------------------------------------------------------------------------- 1 | function xi = inverseMapping1DNURBS (x0,knots,controlPts,p,dir,elConnU,mode) 2 | % inverse mapping of univariate NURBS interpolation. 3 | % Input: 4 | % x0 : point on the NURBS curve 5 | % knots : knot vector 6 | % p : basis order 7 | % controlPts: control points define this curve 8 | % dir : dir=1 for x and dir=2 for y 9 | % connU : connectivity 10 | % Method: 11 | % (1) find span in which x0 belongs to 12 | % (2) Newton-Raphson method to find xi 13 | 14 | 15 | global weights 16 | 17 | % knots = [0 0 0 0.5 1 1 1]; 18 | % controlPts = [0 0; 1 2; 2 2; 3 0]; 19 | % p = 2; 20 | % 21 | % weights = [1 1 1 1]; 22 | 23 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 24 | % compute knots images 25 | 26 | uniqueKnot = unique(knots); 27 | noPts = length(uniqueKnot); 28 | node = zeros(noPts,2); 29 | 30 | for i=1:noPts 31 | xi = uniqueKnot(i); 32 | node(i,1) = NURBSinterpolation(xi,p, knots, controlPts(:,1), weights); 33 | node(i,2) = NURBSinterpolation(xi,p, knots, controlPts(:,2), weights); 34 | end 35 | 36 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 37 | % find in which element x0 belongs to 38 | % x0; 39 | % dir; 40 | % node(:,dir); 41 | 42 | tem = node(:,dir) - x0; 43 | if mode == 1 44 | elemId = length(find(tem<=0)); 45 | else 46 | elemId = length(find(tem>=0)); 47 | end 48 | 49 | if elemId > length(elConnU) 50 | elemId = length(elConnU); 51 | end 52 | 53 | sctr = elConnU(elemId,:); 54 | 55 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 56 | % Newton-Raphson iteration 57 | 58 | noIterMax = 10; 59 | epsilon = 1e-4; 60 | inc = 1; 61 | count = 1; 62 | 63 | % initial value of xi 64 | 65 | xi = uniqueKnot(elemId); 66 | 67 | while (inc < noIterMax) 68 | [N, dNdxi] = NURBS1DBasisDers(xi,p,knots,weights); 69 | x = N * controlPts(sctr,dir); 70 | df = dNdxi * controlPts(sctr,dir); 71 | f = x - x0; 72 | xi = xi - f/df; 73 | 74 | if (abs(f) < epsilon) 75 | inc = noIterMax + 1; 76 | %disp(['inverse mapping converged in ', num2str(count), ' iterations']) 77 | %disp(['with residual ', num2str(abs(f))]) 78 | else 79 | inc = inc + 1; 80 | end 81 | count = count + 1; 82 | end 83 | -------------------------------------------------------------------------------- /Util/nurbs-util/inverseQ4Mapping.m: -------------------------------------------------------------------------------- 1 | function ntip = inverseQ4Mapping (tip,nodes) 2 | % inverse mapping of Q4 elements 3 | % using Newton-Raphson method 4 | % Input: 5 | % tip: global coord 6 | % nodes: global coord of 4 nodes 7 | % Output: 8 | % ntip: (xi,eta) coord of tip 9 | 10 | 11 | epsilon = 0.00001; 12 | iter = 10; 13 | 14 | coord = zeros(1,2); 15 | ksi = 0; 16 | eta = 0; 17 | 18 | inc = 1; 19 | count = 0; 20 | 21 | while (inc < iter) 22 | [N,dNdxi]=lagrange_basis('Q4',coord); % compute shape functions 23 | 24 | x = N'*nodes(:,1); 25 | y = N'*nodes(:,2); 26 | 27 | df1dr = dNdxi(:,1)' * nodes(:,1); 28 | df1ds = dNdxi(:,2)' * nodes(:,1); 29 | df2dr = dNdxi(:,1)' * nodes(:,2); 30 | df2ds = dNdxi(:,2)' * nodes(:,2); 31 | 32 | f1 = x - tip(1); 33 | f2 = y - tip(2); 34 | 35 | detF = df1dr*df2ds - df1ds*df2dr ; 36 | 37 | invf(1,1) = 1.0/detF * df2ds; 38 | invf(1,2) = -1.0/detF * df1ds; 39 | invf(2,1) = -1.0/detF * df2dr; 40 | invf(2,2) = 1.0/detF * df1dr; 41 | 42 | ksi = ksi - invf(1,1)*f1 - invf(1,2)*f2; 43 | eta = eta - invf(2,1)*f1 - invf(2,2)*f2; 44 | 45 | coord(1) = ksi; 46 | coord(2) = eta; 47 | 48 | if( (abs(f1) < epsilon) && ... 49 | (abs(f2) < epsilon) ) 50 | inc = iter + 1; 51 | ntip = coord; 52 | disp(['inverse mapping converged in ', num2str(count), ' iterations']) 53 | else 54 | inc = inc + 1; 55 | end 56 | 57 | count = count + 1; 58 | end 59 | 60 | -------------------------------------------------------------------------------- /Util/nurbs-util/jacobianPaMapping.m: -------------------------------------------------------------------------------- 1 | function j = jacobianPaMapping(rangeU) 2 | J2xi = 0.5 * ( rangeU(2) - rangeU(1) ); 3 | j = J2xi; 4 | end -------------------------------------------------------------------------------- /Util/nurbs-util/jacobianPaPaMapping.m: -------------------------------------------------------------------------------- 1 | function j = jacobianPaPaMapping(rangeU,rangeV) 2 | J2xi = 0.5 * ( rangeU(2) - rangeU(1) ); 3 | J2eta = 0.5 * ( rangeV(2) - rangeV(1) ); 4 | j = J2xi * J2eta; 5 | end -------------------------------------------------------------------------------- /Util/nurbs-util/jacobianPaPaMapping3d.m: -------------------------------------------------------------------------------- 1 | function j = jacobianPaPaMapping3d(rangeU,rangeV,rangeW) 2 | J2xi = 0.5 * ( rangeU(2) - rangeU(1) ); 3 | J2eta = 0.5 * ( rangeV(2) - rangeV(1) ); 4 | J2zeta = 0.5 * ( rangeW(2) - rangeW(1) ); 5 | j = J2xi * J2eta * J2zeta; 6 | end -------------------------------------------------------------------------------- /Util/nurbs-util/l2err.m: -------------------------------------------------------------------------------- 1 | %compute l2-error and energy norm 2 | 3 | l2errvar = 0; %l2 norm of the error 4 | l2norm = 0; %l2 norm of the solution 5 | energynorm = 0; %energy norm of the computed solution 6 | energyerrnorm = 0; %energy norm of the error 7 | invC = inv(C); 8 | 9 | for i=1:elementcounter 10 | localindex = 0; 11 | 12 | ximin = element_int(i,1); 13 | etamin = element_int(i,2); 14 | ximax = element_int(i,3); 15 | etamax = element_int(i,4); 16 | 17 | scalefac = (ximax - ximin)*(etamax - etamin)/4; 18 | [gpx,gwx]=genGP_GW(ngaussx); 19 | [gpy,gwy]=genGP_GW(ngaussy); 20 | 21 | temp = 0; 22 | 23 | dispmatx = zeros(ngaussy,ngaussx); 24 | dispmaty = zeros(ngaussy,ngaussx); 25 | exdispmatx = zeros(ngaussy, ngaussx); 26 | exdispmaty = zeros(ngaussy, ngaussx); 27 | 28 | %for each shape function in shapelist compute the matrices B, E 29 | for ii=1:ngaussx 30 | for jj=1:ngaussy 31 | [R, dRdx, coord, J] = nurbshaped(i, gpx(ii), gpy(jj), knotu, knotv, b_net, p, q, lenu, lenv, element_nod, coord_ij); 32 | B = zeros(localindex, 3); 33 | physx = coord(1); 34 | physy = coord(2); 35 | [eldisp, estress0] = gbeam(physx, physy, P, E, nu, W, L); 36 | exdispmatx(jj, ii) = eldisp(1); 37 | exdispmaty(jj, ii) = eldisp(2); 38 | scrtx = zeros(dim*nument, 1); 39 | for j=1:nument 40 | 41 | globnum = element_nod(i,j); 42 | cR = R(j); 43 | cdRdx = dRdx(1,j); 44 | cdRdy = dRdx(2,j); 45 | 46 | B(2*j-1, :) = [cdRdx, 0, cdRdy]; 47 | B(2*j, :) = [0, cdRdy, cdRdx]; 48 | 49 | globindx = 2*globnum-1; 50 | globindy = 2*globnum; 51 | 52 | scrtx(2*j-1) = 2*globnum-1; 53 | scrtx(2*j) = 2*globnum; 54 | 55 | dispmatx(jj,ii) = dispmatx(jj,ii) + cR*u(globindx); 56 | dispmaty(jj,ii) = dispmaty(jj,ii) + cR*u(globindy); 57 | 58 | end 59 | 60 | 61 | 62 | estress = C*B'*u(scrtx); 63 | 64 | energyerrnorm = energyerrnorm + (estress0-estress)'*invC*(estress0-estress)*J.*scalefac.*gwx(ii).*gwy(jj); 65 | energynorm = energynorm + estress'*invC*estress.*J.*scalefac.*gwx(ii).*gwy(jj); 66 | 67 | l2errvar = l2errvar + ((exdispmatx(jj,ii)-dispmatx(jj,ii))^2+(exdispmaty(jj,ii)-dispmaty(jj,ii))^2).*J.*scalefac.*gwx(ii).*gwy(jj); 68 | l2norm = l2norm + ((exdispmatx(jj,ii))^2+(exdispmaty(jj,ii))^2).*J.*scalefac.*gwx(ii).*gwy(jj); 69 | end 70 | end 71 | 72 | end 73 | 74 | l2errvar = sqrt(l2errvar); 75 | l2errrel = l2errvar/sqrt(l2norm) 76 | energyerrnorm = sqrt(0.5*energyerrnorm); 77 | energynorm = sqrt(0.5*energynorm); 78 | energyerrrel = energyerrnorm/energynorm -------------------------------------------------------------------------------- /Util/nurbs-util/nurb2proj.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | function projcoord = nurb2proj(nob, controlPoints, weights) 3 | %-------------------------------------------------------------- 4 | %function projcoord = nurb2proj(nob, controlPoints, weights) 5 | % transform NURBS data into projective coordinates 6 | %INPUT: 7 | % nob : # of basis function = # control points / weights 8 | % controlPoints: vector of control points (1 per row) 9 | % weights : : column vector of weights 10 | %OUTPUT: 11 | % projcoord : matrix with projective coordinates 12 | %-------------------------------------------------------------- 13 | projcoord = controlPoints; 14 | for i=1:nob 15 | projcoord(i,:) = projcoord(i,:)*weights(i); 16 | end 17 | projcoord = [projcoord, weights]; 18 | end -------------------------------------------------------------------------------- /Util/nurbs-util/nurbedge.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joelhi/iga-matlab/ebd9f23183b94b73b7b493c652f36792d2f63703/Util/nurbs-util/nurbedge.m -------------------------------------------------------------------------------- /Util/nurbs-util/nurbshaped.m: -------------------------------------------------------------------------------- 1 | function [N, dN, coord, J, normal]=nurbshaped(e,u_hat,v_hat,u_knot,v_knot,b_net,p,q,mcp,ncp,element_nod,coord_ij, corient) 2 | 3 | %calculate the shape function and second derivatives 4 | 5 | 6 | nsd = 2; 7 | % ------------------------------------------------------------------ 8 | % get nurbs coordinates forml local node 1; 9 | ni = coord_ij(element_nod(e,end),1); 10 | nj = coord_ij(element_nod(e,end),2); 11 | % get u and v coordinates of integration point; 12 | u =((u_knot(ni+1)-u_knot(ni))*u_hat +u_knot(ni+1) + u_knot(ni))/2; 13 | v =((v_knot(nj+1)-v_knot(nj))*v_hat +v_knot(nj+1) + v_knot(nj))/2; 14 | 15 | % evaluate 1d size functions and derivatives each direction; 16 | M=dersbasisfuns(ni,p,mcp,u,u_knot); % calculate in u direction 17 | P=dersbasisfuns(nj,q,ncp,v,v_knot); % calculate in v direction 18 | 19 | coord = zeros(nsd,1); 20 | w= zeros((p+1)*(q+1), 1); 21 | cpts = zeros((p+1)*(q+1), 2); 22 | B = zeros(1, (p+1)*(q+1)); 23 | dBxi = zeros(1, (p+1)*(q+1)); 24 | dBeta = zeros(1, (p+1)*(q+1)); 25 | 26 | N = zeros(1, (p+1)*(q+1)); 27 | dN = zeros(2, (p+1)*(q+1)); 28 | 29 | % Form tensor products 30 | icount = 0; 31 | for j = 1:q+1 32 | for i = 1:p+1 33 | icount = icount+1; 34 | 35 | w(icount) = b_net(ni+i-p-1,nj+j-q-1,nsd+1); 36 | cpts(icount, 1) = b_net(ni+i-p-1,nj+j-q-1,1); 37 | cpts(icount, 2) = b_net(ni+i-p-1,nj+j-q-1,2); 38 | % basis functions; 39 | B(icount) = M(1,i)*P(1,j); 40 | dBxi(icount) = M(2,i)*P(1,j); 41 | dBeta(icount) = M(1,i)*P(2,j); 42 | end 43 | end 44 | 45 | % Multiply each B-spline function with corresponding weight 46 | N(1,:) = B .* w'; 47 | dN(1,:) = dBxi .* w'; 48 | dN(2,:) = dBeta .* w'; 49 | 50 | % Compute the sums of B-spline functions 51 | w_sum = sum(N(1,:)); 52 | dw_xi = sum(dN(1,:)); 53 | dw_eta = sum(dN(2,:)); 54 | 55 | % Compute NURBS basis functions and its first and second derivatives in 56 | % local coordinates 57 | dN(1,:) = dN(1,:)/w_sum - N*dw_xi/w_sum^2; 58 | dN(2,:) = dN(2,:)/w_sum - N*dw_eta/w_sum^2; 59 | N = N/w_sum; 60 | 61 | % calculate coordinates in physical space 62 | icount = 0; 63 | for j=1:q+1 64 | for i=1:p+1 65 | icount = icount+1; 66 | coord(1) = coord(1) + N(icount)*cpts(icount, 1); 67 | coord(2) = coord(2) + N(icount)*cpts(icount, 2); 68 | end 69 | end 70 | 71 | % Compute Jacobian matrix 72 | dxdxi = [dN(1,:)*cpts(:,1), dN(2,:)*cpts(:,1); dN(1,:)*cpts(:,2), dN(2,:)*cpts(:,2)]; 73 | J = det(dxdxi); 74 | 75 | % Solve for first derivatives in global coordinates 76 | dN = dxdxi'\dN; 77 | 78 | % computation of normal, if function argument corient is given 79 | normal = [0,0]; 80 | if nargin==13 81 | if(corient==1) 82 | nor(1) = dxdxi(2,1);% dy/dxi 83 | nor(2) = -dxdxi(1,1);%dx/dxi 84 | elseif(corient==2) 85 | nor(1) = dxdxi(2,2); 86 | nor(2) = -dxdxi(1,2); 87 | elseif(corient==3) 88 | nor(1) = -dxdxi(2,1); 89 | nor(2) = dxdxi(1,1); 90 | else 91 | nor(1) = -dxdxi(2,2); 92 | nor(2) = dxdxi(1,2); 93 | end 94 | 95 | tmp = sqrt(nor(1)^2 + nor(2)^2); 96 | normal = nor/tmp; % normal vector in two dimensions 97 | end -------------------------------------------------------------------------------- /Util/nurbs-util/parent2ParametricSpace.m: -------------------------------------------------------------------------------- 1 | function xi = parent2ParametricSpace(range,xibar) 2 | xi = 0.5 * ( ( range(2) - range(1) ) * xibar + range(2) + range(1)); 3 | end -------------------------------------------------------------------------------- /Util/nurbs-util/plotBoundary.m: -------------------------------------------------------------------------------- 1 | %script plotboundary.m 2 | %1d plots of the boundary of the solution vs. exact solution (if available) 3 | 4 | 5 | NumPoints = 31; %number of evaluation points on each element 6 | 7 | 8 | for i=1:size(dirichlet,1) 9 | localindex = 0; 10 | elementind = dirichlet(i,1); 11 | 12 | curnod = element_nod(elementind, nument); 13 | ni = coord_ij(curnod, 1); 14 | nj = coord_ij(curnod, 2); 15 | 16 | corient = dirichlet(i, 5); 17 | 18 | EvalPoints = linspace(-1,1,NumPoints); 19 | PlotPointsX = zeros(1, NumPoints); 20 | PlotPointsY = zeros(1, NumPoints); 21 | PhysPoints = zeros(1, NumPoints); 22 | AnalSolPointsX = zeros(1, NumPoints); 23 | AnalSolPointsY = zeros(1, NumPoints); 24 | ErrPointsX = zeros(1, NumPoints); 25 | ErrPointsY = zeros(1, NumPoints); 26 | 27 | for iEval = 1:NumPoints 28 | 29 | [R, coord, normal, J] = nurbedge(EvalPoints(iEval), ni, nj, knotu, knotv, b_net, p, q, lenu, lenv, corient); 30 | 31 | [displacement, stress] = gbeam(coord(1), coord(2), P, E, nu, W, L); 32 | 33 | AnalSolPointsX(iEval) = displacement(1); 34 | AnalSolPointsY(iEval) = displacement(2); 35 | 36 | if (corient == 1) || (corient == 3) 37 | PhysPoints(iEval) = coord(1); 38 | else 39 | PhysPoints(iEval) = coord(2); 40 | end 41 | 42 | 43 | for j=1:nument 44 | globnum = element_nod(elementind,j); 45 | 46 | locnum = nument+1-j; 47 | cR = R(locnum); 48 | 49 | xcontrolpt = coordinates(globnum,1); 50 | ycontrolpt = coordinates(globnum,2); 51 | 52 | globindx = 2*globnum-1; 53 | globindy = 2*globnum; 54 | 55 | PlotPointsX(iEval) = PlotPointsX(iEval) + cR.*u(globindx); 56 | PlotPointsY(iEval) = PlotPointsY(iEval) + cR.*u(globindy); 57 | end 58 | end 59 | plot(PhysPoints, PlotPointsX, '-b', PhysPoints, AnalSolPointsX, '-g'); 60 | 61 | hold on 62 | plot(PhysPoints, PlotPointsY, '-b', PhysPoints, AnalSolPointsY, '-g'); 63 | 64 | hold on 65 | end 66 | title('Computed and analytical displacements on the Dirichlet boundary') 67 | -------------------------------------------------------------------------------- /Util/nurbs-util/proj2nurbs.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | function [controlPoints, weights] = proj2nurbs(projcoord) 3 | %-------------------------------------------------------------- 4 | %function [nob, controlPoints, weightVector] = proj2nurbs(projcoord) 5 | % transform projective coordinates into NURBS data 6 | %INPUT: 7 | % projcoord : matrix with projective coordinates 8 | %OUTPUT: 9 | % nob : # of basis function = # control points / weights 10 | % controlPoints: vector of control points (1 per row) 11 | % weightVector : column vector of weights 12 | %-------------------------------------------------------------- 13 | 14 | dimension = size(projcoord,2); 15 | weights = projcoord(:,dimension); 16 | controlPoints = projcoord(:,1:dimension-1); 17 | 18 | for i=1:size(weights,1) 19 | controlPoints(i,:) = controlPoints(i,:)* 1/(weights(i)); 20 | end 21 | end --------------------------------------------------------------------------------