20#include <gsUnstructuredSplines/src/gsApproxC1GluingData.h> 
   24template<
short_t d, 
class T>
 
   29    typedef gsContainerBasis<d, T> Basis;
 
   30    typedef typename std::vector<Basis> BasisContainer;
 
   31    typedef typename std::vector<gsPatchReparameterized<d,T>> C1AuxPatchContainer;
 
   34    typedef memory::shared_ptr<gsApproxC1Vertex> Ptr;
 
   37    typedef memory::unique_ptr<gsApproxC1Vertex> uPtr;
 
   42    ~gsApproxC1Vertex() { }
 
   46                BasisContainer & bases,
 
   47                const std::vector<size_t> & patchesAroundVertex,
 
   48                const std::vector<size_t> & vertexIndices,
 
   49                const index_t & numVer,
 
   51                : m_mp(mp), m_bases(bases), m_patchesAroundVertex(patchesAroundVertex),
 
   52                m_vertexIndices(vertexIndices), m_optionList(optionList)
 
   57        basisVertexResult.clear();
 
   59        for(
size_t i = 0; i < m_patchesAroundVertex.size(); i++)
 
   61            index_t patch_1 = m_patchesAroundVertex[i];
 
   63            m_auxPatches.push_back(gsPatchReparameterized<d,T>(m_mp.patch(patch_1), m_bases[patch_1]));
 
   66        reparametrizeVertexPatches();
 
   69        T sigma = computeSigma(m_vertexIndices);
 
   75        Phi.col(3) *= sigma * sigma;
 
   76        Phi.col(4) *= sigma * sigma;
 
   77        Phi.col(5) *= sigma * sigma;
 
   80        if (m_auxPatches[0].getPatchRotated().parDim() + 1 == m_auxPatches[0].getPatchRotated().targetDim()) 
 
   84            gsMatrix<T> Jk = m_auxPatches[0].getPatchRotated().jacobian(zero);
 
   88            gsMatrix<T> geoMapDeriv1 = m_auxPatches[0].getPatchRotated()
 
   90            gsMatrix<T> geoMapDeriv2 = m_auxPatches[0].getPatchRotated()
 
   96            n(0) = Jk(1,0)*Jk(2,1)-Jk(2,0)*Jk(1,1);
 
   97            n(1) = Jk(2,0)*Jk(0,1)-Jk(0,0)*Jk(2,1);
 
   98            n(2) = Jk(0,0)*Jk(1,1)-Jk(1,0)*Jk(0,1);
 
  106            rotVec(0) = n(1,0)*z(2,0)-n(2,0)*z(1,0);
 
  107            rotVec(1) = n(2,0)*z(0,0)-n(0,0)*z(2,0);
 
  108            rotVec(2) = n(0,0)*z(1,0)-n(1,0)*z(0,0);
 
  110            T cos_t = (n.dot(z))/ (n.norm() * z.norm());
 
  111            T sin_t = rotVec.norm() / (n.norm() * z.norm());
 
  117            R(0, 0) = cos_t + rotVec.x() * rotVec.x() * (1 - cos_t);
 
  118            R(0, 1) = rotVec.x() * rotVec.y() * (1 - cos_t) - rotVec.z() * sin_t;
 
  119            R(0, 2) = rotVec.x() * rotVec.z() * (1 - cos_t) + rotVec.y() * sin_t;
 
  121            R(1, 0) = rotVec.x() * rotVec.y() * (1 - cos_t) + rotVec.z() * sin_t;
 
  122            R(1, 1) = cos_t + rotVec.y() * rotVec.y() * (1 - cos_t);
 
  123            R(1, 2) = rotVec.y() * rotVec.z() * (1 - cos_t) - rotVec.x() * sin_t;
 
  125            R(2, 0) = rotVec.x() * rotVec.z() * (1 - cos_t) - rotVec.y() * sin_t;
 
  126            R(2, 1) = rotVec.y() * rotVec.z() * (1 - cos_t) + rotVec.x() * sin_t;
 
  127            R(2, 2) = cos_t + rotVec.z() * rotVec.z() * (1 - cos_t);
 
  129            for (
size_t np = 0; np < m_auxPatches.size(); np++)
 
  131                gsMatrix<T> coeffPatch = m_auxPatches[np].getPatchRotated().coefs();
 
  133                for (index_t i = 0; i < coeffPatch.rows(); i++)
 
  136                            (coeffPatch.row(i) - coeffPatch.row(0)) * R.transpose() + coeffPatch.row(0);
 
  139                rotPatch.
addPatch(m_auxPatches[np].getPatchRotated());
 
  140                rotPatch.
patch(np).setCoefs(coeffPatch);
 
  148            Phi(4, 3) = sigma * sigma;
 
  149            Phi(5, 4) = sigma * sigma;
 
  150            Phi(7, 4) = sigma * sigma;
 
  151            Phi(8, 5) = sigma * sigma;
 
  155            for (
size_t np = 0; np < m_auxPatches.size(); np++)
 
  156                rotPatch.
addPatch(m_auxPatches[np].getPatchRotated());
 
  160        for(
size_t i = 0; i < m_patchesAroundVertex.size(); i++)
 
  162            C1AuxPatchContainer auxPatchSingle;
 
  163            auxPatchSingle.push_back(m_auxPatches[i]);
 
  165            std::vector<patchSide> containingSides;  
 
  166            patchCorner pC(m_patchesAroundVertex[i], m_vertexIndices[i]);
 
  167            pC.getContainingSides(d, containingSides);
 
  173            if (containingSides.at(0).side() < 3) 
 
  175                patchSide side_temp = containingSides[0];
 
  176                containingSides[0] = containingSides[1];
 
  177                containingSides[1] = side_temp;
 
  184            std::vector<bool> isInterface(2);
 
  185            isInterface[0] = m_mp.isInterface(
patchSide(m_patchesAroundVertex[i], containingSides.at(0).side()));  
 
  186            isInterface[1] = m_mp.isInterface(
patchSide(m_patchesAroundVertex[i], containingSides.at(1).side()));  
 
  189            std::vector<gsBSpline<T>> alpha, beta;
 
  190            std::vector<gsBSplineBasis<T>> basis_plus, basis_minus;
 
  192            std::vector<bool> kindOfEdge;
 
  194            alpha.resize(2); beta.resize(2); basis_plus.resize(2); basis_minus.resize(2);
 
  195            kindOfEdge.resize(2);
 
  199            for (
size_t dir = 0; dir < containingSides.size(); ++dir)
 
  202                if (isInterface[dir])
 
  205                    m_mp.getNeighbour(containingSides[dir], result);
 
  208                    for (
size_t i_tmp = 0; i_tmp < m_patchesAroundVertex.size(); i_tmp++)
 
  209                        if (m_patchesAroundVertex[i_tmp] == 
size_t(result.
patch))
 
  216                    index_t dir_1 = auxPatchSingle[0].getMapIndex(containingSides[dir].side()) < 3 ? 1 : 0;
 
  217                    index_t dir_2 = m_auxPatches[patch2].getMapIndex(result.side().
index()) < 3 ? 1 : 0;
 
  218                    if (basis.component(dir_1).numElements() > basis2.
component(dir_2).numElements())
 
  226            gsApproxC1GluingData<d, T> approxGluingData(auxPatchSingle, m_optionList, containingSides, isInterface, basis_pm);
 
  230            gsMultiBasis<T> initSpace(auxPatchSingle[0].getBasisRotated().piece(0));
 
  231            for (
size_t dir = 0; dir < containingSides.size(); ++dir)
 
  233                index_t localdir = auxPatchSingle[0].getMapIndex(containingSides[dir].index()) < 3 ? 1 : 0;
 
  235                if (isInterface[dir])
 
  237                    alpha[localdir] = approxGluingData.alphaS(localdir);
 
  238                    beta[localdir] = approxGluingData.betaS(localdir);
 
  241                kindOfEdge[localdir] = isInterface[dir];
 
  244                if (isInterface[dir])
 
  247                    createPlusSpace(geo, basis_pm, localdir, b_plus);
 
  248                    createMinusSpace(geo, basis_pm, localdir, b_minus);
 
  254                    createPlusSpace(geo, initSpace.basis(0), localdir, b_plus);
 
  255                    createMinusSpace(geo, initSpace.basis(0), localdir, b_minus);
 
  262                basis_plus[localdir] = b_plus;
 
  263                basis_minus[localdir] = b_minus;
 
  266            typename gsSparseSolver<T>::SimplicialLDLT solver;
 
  270            gsMultiBasis<T> vertexSpace(auxPatchSingle[0].getBasisRotated().piece(m_vertexIndices[i] + 4));
 
  271            A.setIntegrationElements(vertexSpace);
 
  275            auto u = A.getSpace(vertexSpace);
 
  279            if (!m_optionList.getSwitch(
"interpolation"))
 
  282                for (index_t dir = 0; dir < vertexSpace.basis(0).domainDim(); dir++)
 
  283                    for (index_t i = 3 * vertexSpace.basis(0).degree(dir) + 1; i < vertexSpace.basis(0).component(
 
  284                            1 - dir).size(); i++) 
 
  286                        act = vertexSpace.basis(0).boundaryOffset(dir == 0 ? 3 : 1, i); 
 
  294                fixedDofs.setZero(u.mapper().boundarySize(), 1);
 
  297                A.assemble(u * u.tr());
 
  298                solver.compute(A.matrix());
 
  303            for (index_t bfID = 0; bfID < 6; bfID++)
 
  305                gsVertexBasis<T> vertexBasis(geo, basis_pm, alpha, beta, basis_plus, basis_minus, Phi,
 
  307                if (m_optionList.getSwitch(
"interpolation"))
 
  311                    gsMatrix<T> anchors = vertexSpace.basis(0).anchors();
 
  313                    result_1.
addPatch(vertexSpace.basis(0).interpolateAtAnchors(
give(values)));
 
  319                    auto aa = A.getCoeff(vertexBasis);
 
  324                    auto u_sol = A.getSolution(u, solVector);
 
  328                    result_1.
addPatch(vertexSpace.basis(0).makeGeometry(
give(sol)));
 
  334            basisVertexResult.push_back(result_1);
 
  338        for (
size_t j = 0; j < m_patchesAroundVertex.size(); j++)
 
  339            temp_mp.
addPatch(m_mp.patch(m_patchesAroundVertex[j]));
 
  342        if (m_patchesAroundVertex.size() != temp_mp.
interfaces().size()) 
 
  346            for(
size_t i = 0; i < m_patchesAroundVertex.size(); i++)
 
  347                m_auxPatches[i].parametrizeBasisBack(basisVertexResult[i]); 
 
  351            for(
size_t i = 0; i < m_patchesAroundVertex.size(); i++)
 
  352                m_auxPatches[i].parametrizeBasisBack(basisVertexResult[i]); 
 
  380    void reparametrizeVertexPatches();
 
  382    void checkOrientation(
size_t i);
 
  384    T computeSigma(
const std::vector<size_t> & vertexIndices);
 
  386    void computeKernel();
 
  388    std::vector<gsMultiPatch<T>> getVertexBasis() { 
return basisVertexResult; }
 
  395    BasisContainer & m_bases;
 
  397    const std::vector<size_t> & m_patchesAroundVertex;
 
  398    const std::vector<size_t> & m_vertexIndices;
 
  403    C1AuxPatchContainer m_auxPatches;
 
  406    std::vector<gsMultiPatch<T>> basisVertexResult;
 
  412#ifndef GISMO_BUILD_LIB 
  413#include GISMO_HPP_HEADER(gsApproxC1Vertex.hpp) 
short_t index() const
Returns the index (as specified in boundary::side) of the box side.
Definition gsBoundary.h:140
 
Definition gsExpressions.h:973
 
A univariate B-spline basis.
Definition gsBSplineBasis.h:700
 
const ifContainer & interfaces() const
Return the vector of interfaces.
Definition gsBoxTopology.h:252
 
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition gsDofMapper.h:69
 
Definition gsExprAssembler.h:33
 
Generic evaluator of isogeometric expressions.
Definition gsExprEvaluator.h:39
 
Abstract base class representing a geometry map.
Definition gsGeometry.h:93
 
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
 
Holds a set of patch-wise bases and their topology information.
Definition gsMultiBasis.h:37
 
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition gsMultiPatch.h:100
 
bool computeTopology(T tol=1e-4, bool cornersOnly=false, bool tjunctions=false)
Attempt to compute interfaces and boundaries automatically.
Definition gsMultiPatch.hpp:377
 
gsGeometry< T > & patch(size_t i) const
Return the i-th patch.
Definition gsMultiPatch.h:292
 
index_t addPatch(typename gsGeometry< T >::uPtr g)
Add a patch from a gsGeometry<T>::uPtr.
Definition gsMultiPatch.hpp:211
 
Class which holds a list of parameters/options, and provides easy access to them.
Definition gsOptionList.h:33
 
A tensor product B-spline basis.
Definition gsTensorBSplineBasis.h:37
 
const Basis_t & component(short_t dir) const
For a tensor product basis, return the (const) 1-d basis for the i-th parameter component.
Definition gsTensorBSplineBasis.h:202
 
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
 
Provides declaration of Basis abstract interface.
 
#define index_t
Definition gsConfig.h:32
 
Provides declaration of Basis abstract interface. Similar to gsMultiBasis, but without topology.
 
#define GISMO_UNUSED(x)
Definition gsDebug.h:112
 
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
 
The G+Smo namespace, containing all definitions for the library.
 
S give(S &x)
Definition gsMemory.h:266
 
Struct which represents a certain corner of a patch.
Definition gsBoundary.h:393
 
Struct which represents a certain side of a patch.
Definition gsBoundary.h:232
 
index_t patch
The index of the patch.
Definition gsBoundary.h:234