G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsC1SurfBasisEdge.h
1
14#pragma once
15
16#include <gsUnstructuredSplines/src/gsC1SurfGluingData.h>
17#include <gsUnstructuredSplines/src/gsC1SurfVisitorBasisEdge.h>
18
19namespace gismo
20{
21 template<class T, class bhVisitor = gsC1SurfVisitorBasisEdge<T>>
22 class gsC1SurfBasisEdge : public gsAssembler<T>
23 {
24 public:
25 typedef gsAssembler<T> Base;
26
27 public:
28 gsC1SurfBasisEdge(const gsMultiPatch<T> & mp, // single patch
29 const gsMultiBasis<T> & basis, // single basis
30 index_t uv, // !!! 0 == u; 1 == v !!!
31 bool isBoundary,
32 gsC1SurfGluingData<T> gluingD)
33 : m_mp(mp), m_basis(basis), m_uv(uv), m_isBoundary(isBoundary), m_gD(gluingD)
34 {
35
36 // Computing the G1 - basis function at the edge
37 gsBSplineBasis<T> basis_edge = dynamic_cast<gsBSplineBasis<T> &>(m_basis.basis(0).component(m_uv)); // 0 -> v, 1 -> u
38
39 gsBSplineBasis<T> basis_plus(basis_edge);
40 basis_plus.elevateContinuity(1);
41 m_basis_plus = basis_plus;
42 //gsDebugVar(basis_plus.knots().asMatrix());
43
44
45 gsBSplineBasis<T> basis_minus(basis_edge);
46 basis_minus.degreeReduce(1);
47 m_basis_minus = basis_minus;
48 //gsDebugVar(basis_minus.knots().asMatrix());
49
50 // Basis for the G1 basis
51 m_basis_g1 = m_basis.basis(0);
52
53// gsTensorBSplineBasis<2, T> basis_edge_ab = dynamic_cast<gsTensorBSplineBasis<2, T> &>(m_basis_g1.basis(0));
54// gsInfo << "Basis edge 0: " << basis_edge_ab.component(0).knots().asMatrix() << "\n";
55// gsInfo << "Basis edge 1: " << basis_edge_ab.component(1).knots().asMatrix() << "\n";
56 }
57
58 // Computed the gluing data globally
59 void setG1BasisEdge(gsMultiPatch<T> & result);
60
61 void refresh();
62 void assemble(index_t i, std::string typeBf); // i == number of bf
63 inline void apply(bhVisitor & visitor, index_t i, std::string typeBf); // i == number of bf
64 void solve();
65
67 void constructSolution(const gsMatrix<T> & solVector,
68 gsMultiPatch<T> & result, short_t unk = 0) const;
69
70 private:
71 // Avoid hidden overloads w.r.t. gsAssembler
72 void assemble()
74
75 using gsAssembler<T>::assemble;
76 void assemble(const gsMultiPatch<T> & /* curSolution */)
78
79 protected:
80
81 // Input
82 gsMultiPatch<T> m_mp;
83 gsMultiBasis<T> m_basis;
84 index_t m_uv;
85 bool m_isBoundary;
86
87 // Gluing data
88 gsC1SurfGluingData<T> m_gD;
89
90 // Basis for getting the G1 Basis
91 gsBSplineBasis<T> m_basis_plus;
92 gsBSplineBasis<T> m_basis_minus;
93
94 // Basis for the G1 Basis
95 gsMultiBasis<T> m_basis_g1;
96
97 // Basis for Integration
98 gsMultiBasis<T> m_geo;
99
100 // For Dirichlet boundary
101 using Base::m_ddof;
102 using Base::m_system;
103
104
105 }; // class gsG1BasisEdge
106
107 template <class T, class bhVisitor>
108 void gsC1SurfBasisEdge<T,bhVisitor>::setG1BasisEdge(gsMultiPatch<T> & result)
109 {
110 result.clear();
111
112 index_t n_plus = m_basis_plus.size();
113 index_t n_minus = m_basis_minus.size();
114
115 gsMultiPatch<T> g1EdgeBasis;
116 index_t bfID_init = 3;
117
118 for (index_t bfID = bfID_init; bfID < n_plus - bfID_init; bfID++) // first 3 and last 3 bf are eliminated
119 {
120 m_geo = m_basis_g1; // Basis for Integration
121
122 refresh();
123
124 assemble(bfID,"plus"); // i == number of bf
125
126 typename gsSparseSolver<T>::SimplicialLDLT solver;
127// typename gsSparseSolver<T>::LU solver;
128 gsMatrix<T> sol;
129 solver.compute(m_system.matrix());
130 sol = solver.solve(m_system.rhs());
131
132 constructSolution(sol,g1EdgeBasis);
133 }
134 bfID_init = 2;
135 for (index_t bfID = bfID_init; bfID < n_minus-bfID_init; bfID++) // first 2 and last 2 bf are eliminated
136 {
137
138
139 m_geo = m_basis_g1; // Basis for Integration
140
141 refresh();
142
143 assemble(bfID,"minus"); // i == number of bf
144
145 typename gsSparseSolver<T>::SimplicialLDLT solver;
146// typename gsSparseSolver<T>::LU solver;
147 gsMatrix<T> sol;
148 solver.compute(m_system.matrix());
149 sol = solver.solve(m_system.rhs());
150
151 constructSolution(sol,g1EdgeBasis);
152 }
153
154 result = g1EdgeBasis;
155 } // setG1BasisEdge
156
157 template <class T, class bhVisitor>
158 void gsC1SurfBasisEdge<T,bhVisitor>::constructSolution(const gsMatrix<T> & solVector, gsMultiPatch<T> & result, short_t unk) const
159 {
160 GISMO_UNUSED(unk);
161
162 // Dim is the same for all basis functions
163 const index_t dim = ( 0!=solVector.cols() ? solVector.cols() : m_ddof[0].cols() );
164
165 gsMatrix<T> coeffs;
166 const gsDofMapper & mapper = m_system.colMapper(0); // unknown = 0
167
168 // Reconstruct solution coefficients on patch p
169 index_t sz;
170 sz = m_basis.basis(0).size();
171
172 coeffs.resize(sz, dim);
173
174 for (index_t i = 0; i < sz; ++i)
175 {
176 if (mapper.is_free(i, 0)) // DoF value is in the solVector // 0 = unitPatch
177 {
178 coeffs.row(i) = solVector.row(mapper.index(i, 0));
179 }
180 else // eliminated DoF: fill with Dirichlet data
181 {
182 //gsInfo << "mapper index dirichlet: " << m_ddof[unk].row( mapper.bindex(i, p) ).head(dim) << "\n";
183 coeffs.row(i) = m_ddof[0].row( mapper.bindex(i, 0) ).head(dim); // = 0
184 }
185 }
186 result.addPatch(m_basis_g1.basis(0).makeGeometry(give(coeffs)));
187
188 }
189
190 template <class T, class bhVisitor>
191 void gsC1SurfBasisEdge<T,bhVisitor>::refresh()
192 {
193 // 1. Obtain a map from basis functions to matrix columns and rows
194 gsDofMapper map(m_basis.basis(0));
195
197
198 for (index_t i = 2; i < m_basis.basis(0).component(1-m_uv).size(); i++) // only the first two u/v-columns are Dofs (0/1)
199 {
200 act = m_basis.basis(0).boundaryOffset(m_uv == 0 ? 3 : 1, i); // WEST
201 map.markBoundary(0, act); // Patch 0
202 }
203
204 map.finalize();
205
206 // 2. Create the sparse system
207 m_system = gsSparseSystem<T>(map);
208
209 } // refresh()
210
211 template <class T, class bhVisitor>
212 void gsC1SurfBasisEdge<T,bhVisitor>::assemble(index_t bfID, std::string typeBf)
213 {
214 // Reserve sparse system
215 const index_t nz = gsAssemblerOptions::numColNz(m_basis[0],2,1,0.333333);
216 m_system.reserve(nz, 1);
217
218 if(m_ddof.size()==0)
219 m_ddof.resize(1); // 0,1
220
221 const gsDofMapper & map = m_system.colMapper(0); // Map same for every functions
222
223 m_ddof[0].setZero(map.boundarySize(), 1 );
224
225 // Assemble volume integrals
226 bhVisitor visitor;
227 apply(visitor, bfID, typeBf); // basis function i
228
229 m_system.matrix().makeCompressed();
230
231 } // assemble()
232
233 template <class T, class bhVisitor>
234 void gsC1SurfBasisEdge<T,bhVisitor>::apply(bhVisitor & visitor, index_t bf_index, std::string typeBf)
235 {
236#pragma omp parallel
237 {
238
239 gsQuadRule<T> quRule ; // Quadrature rule
240 gsMatrix<T> quNodes ; // Temp variable for mapped nodes
241 gsVector<T> quWeights; // Temp variable for mapped weights
242
243 bhVisitor
244#ifdef _OPENMP
245 // Create thread-private visitor
246 visitor_(visitor);
247 const int tid = omp_get_thread_num();
248 const int nt = omp_get_num_threads();
249#else
250 &visitor_ = visitor;
251#endif
252
253 gsBasis<T> & basis_g1 = m_basis_g1.basis(0); // basis for construction
254
255 // Same for all patches
256 gsBasis<T> & basis_geo = m_basis.basis(0).component(1-m_uv);
257 gsBasis<T> & basis_plus = m_basis_plus;
258 gsBasis<T> & basis_minus = m_basis_minus;
259
260 // Initialize reference quadrature rule and visitor data
261 visitor_.initialize(basis_g1, quRule);
262
263 const gsGeometry<T> & patch = m_mp.patch(0);
264
265 // Initialize domain element iterator
266 typename gsBasis<T>::domainIter domIt = m_geo.basis(0).makeDomainIterator(boundary::none);
267
268#ifdef _OPENMP
269 for ( domIt->next(tid); domIt->good(); domIt->next(nt) )
270#else
271 for (; domIt->good(); domIt->next() )
272#endif
273 {
274 // Map the Quadrature rule to the element
275 quRule.mapTo( domIt->lowerCorner(), domIt->upperCorner(), quNodes, quWeights );
276
277 // Perform required evaluations on the quadrature nodes
278 visitor_.evaluate(bf_index, typeBf, basis_g1, basis_geo, basis_plus, basis_minus, patch, quNodes, m_uv, m_gD, m_isBoundary);
279
280 // Assemble on element
281 visitor_.assemble(*domIt, quWeights);
282
283 // Push to global matrix and right-hand side vector
284#pragma omp critical(localToGlobal)
285 visitor_.localToGlobal(0, m_ddof, m_system); // omp_locks inside // patchIndex == 0
286 }
287 }//omp parallel
288 } // apply
289
290} // namespace gismo
The assembler class provides generic routines for volume and boundary integrals that are used for for...
Definition gsAssembler.h:266
gsSparseSystem< T > m_system
Global sparse linear system.
Definition gsAssembler.h:290
virtual void constructSolution(const gsMatrix< T > &solVector, gsMultiPatch< T > &result, short_t unk=0) const
Construct solution from computed solution vector for a single unknows.
Definition gsAssembler.hpp:537
void apply(ElementVisitor &visitor, size_t patchIndex=0, boxSide side=boundary::none)
Generic assembly routine for volume or boundary integrals.
Definition gsAssembler.h:668
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
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
#define GISMO_UNUSED(x)
Definition gsDebug.h:112
The G+Smo namespace, containing all definitions for the library.
S give(S &x)
Definition gsMemory.h:266