G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsContainerBasis.h
Go to the documentation of this file.
1 
16 #pragma once
17 
18 #include<gsCore/gsBasis.h>
19 
20 namespace gismo
21 {
22 
23  template<short_t d,class T>
24  class gsContainerBasis : public gsBasis<T>
25  {
26 
27  public:
29  typedef memory::shared_ptr< gsContainerBasis > Ptr;
30 
32  typedef memory::unique_ptr< gsContainerBasis > uPtr;
33 
34  gsContainerBasis(index_t numSubspaces)
35  {
36  basisContainer.clear();
37  for (index_t i = 0; i != numSubspaces; i++)
38  basisContainer.push_back(gsTensorBSplineBasis<d,T>());
39 
40  }
41 
42  ~gsContainerBasis() {};
43 
44  // boundary(boxSide const & side)
45 
46 // implementations of gsBasis
47  public:
48 
49  static uPtr make( const gsContainerBasis& other)
50  { return uPtr( new gsContainerBasis( other ) ); }
51 
52 
53  public:
54 
55  GISMO_CLONE_FUNCTION(gsContainerBasis)
56 
57  short_t domainDim() const
58  {
59  return d;
60  }
61 
62  void connectivity(const gsMatrix<T> & nodes,
63  gsMesh<T> & mesh) const
64  {
65  GISMO_UNUSED(nodes); GISMO_UNUSED(mesh);
67  }
68 
69  memory::unique_ptr<gsGeometry<T> > makeGeometry( gsMatrix<T> coefs ) const
70  {
71  GISMO_UNUSED(coefs);
73  }
74 
75  std::ostream &print(std::ostream &os) const
76  {
77  GISMO_UNUSED(os);
79  }
80 
81  void uniformRefine(int numKnots = 1, int mul=1, int dir=-1)
82  {
83  for (size_t i=0; i< basisContainer.size(); ++i)
84  basisContainer[i].uniformRefine(numKnots,mul,dir);
85  }
86 
87  // Returm max degree of all the spaces, otherwise i =
88  short_t degree(short_t dir) const
89  {
90  short_t deg = 0;
91  for (size_t i=0; i< basisContainer.size(); ++i)
92  if (basisContainer[i].degree(dir) > deg)
93  deg = basisContainer[i].degree(dir);
94 
95  return deg;
96  }
97 
98  index_t size() const {
99  index_t sz = 0;
100  for (size_t i=0; i< basisContainer.size(); ++i)
101  sz += basisContainer[i].size();
102  return sz;
103  }
104 
105  void reverse()
106  {
107  for (size_t i=0; i< basisContainer.size(); ++i)
108  {
109  if (gsTensorBSplineBasis<d, T> * mb =
110  dynamic_cast<gsTensorBSplineBasis<d, T> *>(&basisContainer[i]) )
111  {
112  gsTensorBSplineBasis<d, T> basis_temp = dynamic_cast<gsTensorBSplineBasis<d,T>&>(basisContainer[i]);
113  gsTensorBSplineBasis<d, T> newTensorBasis(basis_temp.knots(1),basis_temp.knots(0));
114  basisContainer[i] = newTensorBasis;
115  }
116  /*
117  else if (gsTensorNurbsBasis<d, T> * mb =
118  dynamic_cast<gsTensorNurbsBasis<d, T> *>(&basisContainer[i]) )
119  {
120  gsTensorNurbsBasis<d, T> basis_temp = dynamic_cast<gsTensorNurbsBasis<d,T>&>(basisContainer[i]);
121  basis_temp.swapDirections(1,0);
122  basisContainer[i] = basis_temp;
123  }
124  */
125  else
126  gsInfo << "Works for now just with gsTensorBSplineBasis<d, T> \n";
127 
128  }
129  }
130 
131  index_t nPieces() const {return basisContainer.size();}
132 
133  typename gsBasis<T>::domainIter makeDomainIterator(const boxSide & side) const
134  {
135  // Using the inner basis for iterating
136  return basisContainer[0].makeDomainIterator(side);
137  }
138 
139  typename gsBasis<T>::domainIter makeDomainIterator() const
140  {
141  // Using the inner basis for iterating
142  return basisContainer[0].makeDomainIterator();
143  }
144 
145  const gsBasis<T> & component(short_t i) const
146  {
147  return basisContainer[0].component(i);
148  }
149 
150 /* void matchWith(const boundaryInterface & bi, const gsBasis<T> & other,
151  gsMatrix<index_t> & bndThis, gsMatrix<index_t> & bndOther) const;
152 */
153 
154  gsMatrix<T> support() const
155  {
156  return basisContainer[0].support();
157  }
158 
159  gsBasis<T>* boundaryBasis_impl(boxSide const & s) const
160  {
161  /*
162  if (basisContainer.size() != 1)
163  {
164  typename gsBSplineTraits<d-1, T>::Basis* bBasis = new typename gsBSplineTraits<d-1, T>::Basis(*basisContainer[s.index()].boundaryBasis(s));
165  return bBasis;
166  }
167  else {
168  typename gsBSplineTraits<d-1, T>::Basis* bBasis = new typename gsBSplineTraits<d-1, T>::Basis(*basisContainer[0].boundaryBasis(s));
169  return bBasis;
170  }
171  */
172 
173  gsDebugVar(s.index());
174  // Maybe not working for approx C1 Basis functions
175  typename gsBSplineTraits<d-1, T>::Basis* bBasis = new typename gsBSplineTraits<d-1, T>::Basis(*basisContainer[0].boundaryBasis(s));
176  gsDebugVar(*bBasis);
177  return bBasis;
178  }
179 
180  void active_into(const gsMatrix<T> & u, gsMatrix<index_t> & result) const
181  {
182  GISMO_ASSERT(u.rows() == d, "Dimension of the points in active_into is wrong");
183  //GISMO_ASSERT(u.cols() == 1, "Active_into is wrong");
184 
185  index_t nr = 0;
186  std::vector<gsMatrix<index_t>> result_temp;
187  result_temp.resize(basisContainer.size());
188  for (size_t i=0; i< basisContainer.size(); ++i)
189  {
190  basisContainer[i].active_into(u, result_temp[i]);
191  nr += result_temp[i].rows();
192  }
193 
194  result.resize(nr,u.cols());
195 
196  index_t shift = 0;
197  index_t shift_rows = 0;
198  for (size_t i=0; i< basisContainer.size(); ++i)
199  {
200  result_temp[i].array() += shift;
201  result.block(shift_rows, 0, result_temp[i].rows(), u.cols()) = result_temp[i];
202  shift += basisContainer[i].size();
203  shift_rows += result_temp[i].rows();
204 
205  }
206  }
207 
208  void eval_into(const gsMatrix<T> & u, gsMatrix<T> & result) const
209  {
210  result.resize(0, u.cols());
211  for (size_t i=0; i< basisContainer.size(); ++i)
212  {
213  gsMatrix<T> result_temp;
214  basisContainer[i].eval_into(u, result_temp);
215  result.conservativeResize(result.rows()+result_temp.rows(), result.cols());
216  result.bottomRows(result_temp.rows()) = result_temp;
217 
218  }
219  }
220 
221  void deriv_into(const gsMatrix<T> & u, gsMatrix<T> & result) const
222  {
223  result.resize(0, u.cols());
224  for (size_t i=0; i< basisContainer.size(); ++i)
225  {
226  gsMatrix<T> result_temp;
227  basisContainer[i].deriv_into(u, result_temp);
228  result.conservativeResize(result.rows()+result_temp.rows(), result.cols());
229  result.bottomRows(result_temp.rows()) = result_temp;
230 
231  }
232  }
233 
234  void deriv2_into(const gsMatrix<T> & u, gsMatrix<T> & result) const
235  {
236  result.resize(0, u.cols());
237  for (size_t i=0; i< basisContainer.size(); ++i)
238  {
239  gsMatrix<T> result_temp;
240  basisContainer[i].deriv2_into(u, result_temp);
241  result.conservativeResize(result.rows()+result_temp.rows(), result.cols());
242  result.bottomRows(result_temp.rows()) = result_temp;
243 
244  }
245  }
246 
247  void matchWith(const boundaryInterface &bi, const gsBasis<T> &other, gsMatrix<index_t> &bndThis,
248  gsMatrix<index_t> &bndOther) const {
249  // First side
250  // edge
251  gsDebug << "matchWith() function is not implemented yet \n";
252 
253  /*
254  gsMatrix<index_t> indizes1, indizes2;
255  short_t side_id = bi.first().side().index();
256  indizes1 = basisG1Container[side_id].boundaryOffset(boxSide(bi.first().side()), 0);
257  indizes2 = basisG1Container[side_id].boundaryOffset(boxSide(bi.first().side()), 1);
258 
259  bndThis = indizes1;
260  bndThis.resize(indizes1.rows() + indizes2.rows(), indizes1.cols());
261  bndThis.block(0, 0, indizes1.rows(), indizes1.cols()) = indizes1;
262  bndThis.block(indizes1.rows(), 0, indizes2.rows(), indizes1.cols()) = indizes2;
263 
264  index_t shift = 0;
265  for (index_t i = 0; i < side_id; ++i)
266  shift += basisG1Container[side_id].size();
267 
268  bndOther.array() += shift;
269 
270  bndOther = bndThis;
271  */
272  }
273 
274 
275  gsMatrix<index_t> boundaryOffset(const boxSide & bside, index_t offset) const
276  {
277  gsMatrix<index_t> result;
278 
279  // TODO TEST WITH:
280  /*
281  index_t shift = 0;
282  result.resize(0, 1);
283  for (size_t i=0; i< basisContainer.size(); ++i)
284  {
285  gsMatrix<index_t> result_temp;
286  result_temp = basisContainer[i].boundaryOffset(bside, offset);
287  result_temp.array() += shift;
288  result.conservativeResize(result.rows()+result_temp.rows(), 1);
289  result.bottomRows(result_temp.rows()) = result_temp;
290  shift += basisContainer[i].size();
291  }
292  */
293  // Edges
294  short_t side_id = bside.index();
295  if (basisContainer.size() != 1)
296  {
297  index_t shift = 0;
298  for (index_t i=0; i< side_id; ++i)
299  shift += basisContainer[i].size();
300  result = basisContainer[side_id].boundaryOffset(bside, offset);
301  result.array() += shift;
302  }
303  else if (basisContainer.size() == 1)
304  result = basisContainer[0].boundaryOffset(bside, offset);
305 
306 
307  // Vertices:
308  if (basisContainer.size() != 1)
309  {
310  std::vector<boxCorner> containedCorners;
311  bside.getContainedCorners(d, containedCorners);
312 
313  GISMO_ASSERT(containedCorners.size() != 0, "No contained corner");
314 
315 
316  for (size_t nc = 0; nc < containedCorners.size(); nc++)
317  {
318  index_t corner_id = containedCorners[nc].m_index + 4; // + 4 included because of 4 sides!
319 
320  index_t shift = 0;
321  for (index_t i = 0; i < corner_id; ++i)
322  shift += basisContainer[i].size();
323 
324  gsMatrix<index_t> result_temp;
325  result_temp = basisContainer[corner_id].boundaryOffset(bside, offset);
326  result_temp.array() += shift;
327 
328  index_t r_rows = result.rows() + result_temp.rows();
329  result.conservativeResize(r_rows, 1);
330  result.bottomRows(result_temp.rows()) = result_temp;
331  }
332  }
333  return result;
334  }
335 
336  index_t functionAtCorner(const boxCorner & corner) const
337  {
338  if (basisContainer.size() != 1)
339  {
340  index_t corner_id = corner.m_index + 4; // + 4 included because of 4 sides!
341  index_t shift = 0;
342  for (index_t i = 0; i < corner_id; ++i)
343  shift += basisContainer[i].size();
344 
345  return basisContainer[corner_id].functionAtCorner(corner) + shift;
346  }
347  else
348  return basisContainer[0].functionAtCorner(corner);
349 
350  }
351 
352 // implementations of gsContainerBasis
353  public:
354 
355  // basisContainer:
356  void setBasis(index_t row, gsTensorBSplineBasis<d,T> basis) { basisContainer[row] = basis; }
357 
358  const gsBasis<T> & piece(const index_t k) const { return basisContainer[k]; }
359  // basisContainer END
360 
361  //std::vector<gsTensorBSplineBasis<d,T>> & getBasisContainer() { return basisContainer; }
362 
363  // Data members
364  protected:
365 
366  // Collection of the subspaces
367  std::vector<gsTensorBSplineBasis<d, T>> basisContainer;
368  };
369 
370 }
gsBasis< T >::uPtr boundaryBasis(boxSide const &s)
Returns the boundary basis for side s.
#define GISMO_NO_IMPLEMENTATION
Definition: gsDebug.h:129
#define gsDebug
Definition: gsDebug.h:61
#define short_t
Definition: gsConfig.h:35
Provides declaration of Basis abstract interface.
#define index_t
Definition: gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
#define gsInfo
Definition: gsDebug.h:43
virtual void matchWith(const boundaryInterface &bi, const gsBasis< T > &other, gsMatrix< index_t > &bndThis, gsMatrix< index_t > &bndOther, index_t offset=0) const
Computes the indices of DoFs that match on the interface bi. The interface is assumed to be a common ...
Definition: gsBasis.hpp:658
#define GISMO_UNUSED(x)
Definition: gsDebug.h:112
virtual gsMatrix< T > support(const index_t &i) const
Returns (a bounding box for) the support of the i-th basis function.
Definition: gsBasis.hpp:435
virtual gsBasis< T > & component(short_t i)
For a tensor product basis, return the 1-d basis for the i-th parameter component.
Definition: gsBasis.hpp:518