G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsC1SurfBasisVertex.h
1
14#pragma once
15
16
17#include <gsUnstructuredSplines/src/gsC1SurfGluingData.h>
18#include <gsUnstructuredSplines/src/gsC1SurfVisitorBasisVertex.h>
19
20
21
22namespace gismo
23{
24 template<class T, class bhVisitor = gsG1ASVisitorBasisVertex<T>>
25 class gsC1SurfBasisVertex : public gsAssembler<T>
26 {
27 public:
28 typedef gsAssembler<T> Base;
29
30 public:
31 gsC1SurfBasisVertex(gsMultiPatch<T> mp, // Single Patch
32 gsMultiBasis<T> basis, // Single Basis
33 std::vector<bool> isBoundary,
34 gsMatrix<T> &Phi,
35 gsMatrix<T> gluingD)
36 : m_mp(mp), m_basis(basis), m_isBoundary(isBoundary), m_Phi(Phi), m_gD(gluingD)
37 {
38
39 for (index_t dir = 0; dir < m_mp.parDim(); dir++) // For the TWO directions
40 {
41 // Computing the G1 - basis function at the edge
42 // Spaces for computing the g1 basis
43 gsBSplineBasis<T> basis_edge = dynamic_cast<gsBSplineBasis<T> &>(m_basis.basis(0).component(dir)); // 0 -> u, 1 -> v
44
45 gsBSplineBasis<T> basis_plus(basis_edge);
46 basis_plus.elevateContinuity(1);
47 m_basis_plus.push_back(basis_plus);
48
49 gsBSplineBasis<T> basis_minus(basis_edge);
50 basis_minus.degreeReduce(1);
51 m_basis_minus.push_back(basis_minus);
52 }
53
54 // Basis for the G1 basis
55 m_basis_g1 = m_basis.basis(0);
56
57
58 }
59
60
61 void refresh();
62 using Base::assemble;
63 void assemble();
64 inline void apply(bhVisitor & visitor, index_t patchIndex);
65 void solve();
66
67 void constructSolution(gsMultiPatch<T> & result);
68
69 void setG1BasisVertex(gsMultiPatch<T> & result)
70 {
71 m_geo = m_basis_g1;
72 refresh();
73 assemble();
74 solve();
75
76 constructSolution(result);
77 }
78
79
80 private:
81 // Avoid hidden overloads w.r.t. gsAssembler
82 void constructSolution(const gsMatrix<T>& /* solVector */,
83 gsMultiPatch<T>& /* result */, short_t /* unk */) const
85
86 void constructSolution(const gsMatrix<T>& /* solVector */,
87 gsMultiPatch<T>& /* result */,
88 const gsVector<index_t> & /* unknowns */) const
90
91 protected:
92
93 // Input
94 gsMultiPatch<T> m_mp;
95 gsMultiBasis<T> m_basis;
96 std::vector<bool> m_isBoundary;
97 gsMatrix<T> m_Phi;
98
99 // Gluing data
100 gsMatrix<T> m_gD;
101
102 // Basis for getting the G1 Basis
103 std::vector<gsBSplineBasis<T>> m_basis_plus;
104 std::vector<gsBSplineBasis<T>> m_basis_minus;
105
106 // Basis for the G1 Basis
107 gsMultiBasis<T> m_basis_g1;
108
109 // Basis for Integration
110 gsMultiBasis<T> m_geo;
111
112 // System
113 std::vector<gsSparseSystem<T> > m_f;
114
115 // For Dirichlet boundary
116 using Base::m_ddof;
117
118 std::vector<gsMatrix<T>> solVec;
119
120 }; // class gsG1BasisEdge
121
122
123 template <class T, class bhVisitor>
124 void gsC1SurfBasisVertex<T,bhVisitor>::constructSolution(gsMultiPatch<T> & result)
125 {
126
127 result.clear();
128
129 // Dim is the same for all basis functions
130 const index_t dim = ( 0!=solVec.at(0).cols() ? solVec.at(0).cols() : m_ddof[0].cols() );
131
132 gsMatrix<T> coeffs;
133 for (index_t p = 0; p < 6; ++p)
134 {
135 const gsDofMapper & mapper = m_f.at(p).colMapper(0); // unknown = 0
136
137 // Reconstruct solution coefficients on patch p
138 index_t sz;
139 sz = m_basis.basis(0).size();
140
141 coeffs.resize(sz, dim);
142
143 for (index_t i = 0; i < sz; ++i)
144 {
145 if (mapper.is_free(i, 0)) // DoF value is in the solVector // 0 = unitPatch
146 {
147 coeffs.row(i) = solVec.at(p).row(mapper.index(i, 0));
148 }
149 else // eliminated DoF: fill with Dirichlet data
150 {
151 //gsInfo << "mapper index dirichlet: " << m_ddof[unk].row( mapper.bindex(i, p) ).head(dim) << "\n";
152 coeffs.row(i) = m_ddof[0].row( mapper.bindex(i, 0) ).head(dim); // = 0
153 }
154 }
155 result.addPatch(m_basis_g1.basis(0).makeGeometry(give(coeffs)));
156 }
157 }
158
159 template <class T, class bhVisitor>
160 void gsC1SurfBasisVertex<T,bhVisitor>::refresh()
161 {
162 // 1. Obtain a map from basis functions to matrix columns and rows
163 gsDofMapper map(m_basis.basis(0));
164
165 // SET THE DOFS
166
167 map.finalize();
168
169
170 // 2. Create the sparse system
171 gsSparseSystem<T> m_system = gsSparseSystem<T>(map);
172 for (index_t i = 0; i < 6; i++)
173 m_f.push_back(m_system);
174
175 } // refresh()
176
177 template <class T, class bhVisitor>
178 void gsC1SurfBasisVertex<T,bhVisitor>::assemble()
179 {
180 // Reserve sparse system
181 const index_t nz = gsAssemblerOptions::numColNz(m_basis[0],2,1,0.333333);
182 for (size_t i = 0; i < m_f.size(); i++)
183 m_f.at(i).reserve(nz, 1);
184
185
186 if(m_ddof.size()==0)
187 m_ddof.resize(1); // 0,1
188
189 const gsDofMapper & map = m_f.at(0).colMapper(0); // Map same for every
190
191 m_ddof[0].setZero(map.boundarySize(), 1 ); // plus
192
193 // Assemble volume integrals
194 bhVisitor visitor;
195 apply(visitor,0); // patch 0
196
197 for (size_t i = 0; i < m_f.size(); i++)
198 m_f.at(i).matrix().makeCompressed();
199
200 } // assemble()
201
202 template <class T, class bhVisitor>
203 void gsC1SurfBasisVertex<T,bhVisitor>::apply(bhVisitor & visitor, index_t patchIndex)
204 {
205#pragma omp parallel
206 {
207
208 gsQuadRule<T> quRule ; // Quadrature rule
209 gsMatrix<T> quNodes ; // Temp variable for mapped nodes
210 gsVector<T> quWeights; // Temp variable for mapped weights
211
212 bhVisitor
213#ifdef _OPENMP
214 // Create thread-private visitor
215 visitor_(visitor);
216 const int tid = omp_get_thread_num();
217 const int nt = omp_get_num_threads();
218#else
219 &visitor_ = visitor;
220#endif
221
222 gsBasis<T> & basis_g1 = m_basis_g1.basis(0); // basis for construction
223
224 // Same for all patches
225 gsBasis<T> & basis_geo = m_basis.basis(0); // 2D
226
227 // Initialize reference quadrature rule and visitor data
228 visitor_.initialize(basis_g1, quRule);
229
230 const gsGeometry<T> & patch = m_mp.patch(0);
231
232 // Initialize domain element iterator
233 typename gsBasis<T>::domainIter domIt = m_geo.basis(0).makeDomainIterator(boundary::none);
234
235#ifdef _OPENMP
236 for ( domIt->next(tid); domIt->good(); domIt->next(nt) )
237#else
238 for (; domIt->good(); domIt->next() )
239#endif
240 {
241 // Map the Quadrature rule to the element
242 quRule.mapTo( domIt->lowerCorner(), domIt->upperCorner(), quNodes, quWeights );
243#pragma omp critical(evaluate)
244 // Perform required evaluations on the quadrature nodes
245 visitor_.evaluate(basis_g1, basis_geo, m_basis_plus, m_basis_minus, patch, quNodes, m_gD, m_isBoundary, m_Phi);
246
247 // Assemble on element
248 visitor_.assemble(*domIt, quWeights);
249
250 // Push to global matrix and right-hand side vector
251#pragma omp critical(localToGlobal)
252 visitor_.localToGlobal(patchIndex, m_ddof, m_f); // omp_locks inside // patchIndex == 0
253 }
254 }//omp parallel
255 } // apply
256
257 template <class T, class bhVisitor>
258 void gsC1SurfBasisVertex<T,bhVisitor>::solve()
259 {
260 typename gsSparseSolver<T>::SimplicialLDLT solver;
261// typename gsSparseSolver<T>::LU solver;
262
263
264// gsInfo << "rhs: " << m_f.at(4).rhs() << "\n";
265
266 for (index_t i = 0; i < 6; i++) // Tilde
267 {
268 solver.compute(m_f.at(i).matrix());
269 solVec.push_back(solver.solve(m_f.at(i).rhs()));
270 }
271 } // solve
272
273} // namespace gismo
The assembler class provides generic routines for volume and boundary integrals that are used for for...
Definition gsAssembler.h:266
void apply(ElementVisitor &visitor, size_t patchIndex=0, boxSide side=boundary::none)
Generic assembly routine for volume or boundary integrals.
Definition gsAssembler.h:668
virtual void assemble()
Main assemble routine, to be implemented in derived classes.
Definition gsAssembler.hpp:51
std::vector< gsMatrix< T > > m_ddof
Definition gsAssembler.h:295
A univariate B-spline basis.
Definition gsBSplineBasis.h:700
A basis represents a family of scalar basis functions defined over a common parameter domain.
Definition gsBasis.h:79
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition gsDofMapper.h:69
index_t bindex(index_t i, index_t k=0, index_t c=0) const
Returns the boundary index of local dof i of patch k.
Definition gsDofMapper.h:334
index_t boundarySize() const
Returns the number of eliminated dofs.
Definition gsDofMapper.h:457
index_t index(index_t i, index_t k=0, index_t c=0) const
Returns the global dof index associated to local dof i of patch k.
Definition gsDofMapper.h:325
bool is_free(index_t i, index_t k=0, index_t c=0) const
Returns true if local dof i of patch k is not eliminated.
Definition gsDofMapper.h:382
const gsBasis< T > & basis(const index_t k) const
Helper which casts and returns the k-th piece of this function set as a gsBasis.
Definition gsFunctionSet.hpp:33
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
T at(index_t i) const
Returns the i-th element of the vectorization of the matrix.
Definition gsMatrix.h:211
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
index_t addPatch(typename gsGeometry< T >::uPtr g)
Add a patch from a gsGeometry<T>::uPtr.
Definition gsMultiPatch.hpp:211
void clear()
Clear (delete) all patches.
Definition gsMultiPatch.h:388
Class representing a reference quadrature rule.
Definition gsQuadRule.h:29
virtual void mapTo(const gsVector< T > &lower, const gsVector< T > &upper, gsMatrix< T > &nodes, gsVector< T > &weights) const
Maps quadrature rule (i.e., points and weights) from the reference domain to an element.
Definition gsQuadRule.h:177
A sparse linear system indexed by sets of degrees of freedom.
Definition gsSparseSystem.h:30
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
#define index_t
Definition gsConfig.h:32
#define GISMO_NO_IMPLEMENTATION
Definition gsDebug.h:129
The G+Smo namespace, containing all definitions for the library.
S give(S &x)
Definition gsMemory.h:266