G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsG1AuxiliaryPatch.h
Go to the documentation of this file.
1 
13 #pragma once
14 
15 #include <gismo.h>
16 #include <gsCore/gsMultiPatch.h>
17 
18 
19 namespace gismo
20 {
21 
22  template<short_t d, class T>
23  class gsG1AuxiliaryPatch
24  {
25  public:
26 
27  gsG1AuxiliaryPatch()
28  {}
29 
30  gsG1AuxiliaryPatch(const gsGeometry<T> & singlePatch, const index_t globalPatchIndex):
31  auxPatch(singlePatch), patchIndex(globalPatchIndex){
32  rotationNum = 0;
33  axisOrientation = 0;
34 // gsInfo << "Single patch created: " << patchIndex << "\n";
35  };
36 
37  void setPlusMinus(index_t plus, index_t minus)
38  {
39  m_plus = plus;
40  m_minus = minus;
41  }
42 
43  index_t get_n_plus() { return m_plus; }
44  index_t get_n_minus() { return m_minus; }
45 
46  void rotateParamAntiClock(){
47  gsMultiBasis<T> auxBase(auxPatch);
48  gsTensorBSplineBasis<d, T> & temp_L = dynamic_cast<gsTensorBSplineBasis<d, T> &>(auxBase.basis(0));
49  gsBSplineBasis<T> temp_basisLU = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(0));
50  gsBSplineBasis<T> temp_basisLV = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(1));
51  index_t dimU = temp_L.size(0);
52  index_t dimV = temp_L.size(1);
53 
54  // The number of cols has to match the dimension of the space
55  gsMatrix<T> mpar(dimU * dimV, auxPatch.targetDim());
56 
57  // Loop over the cols
58  for (index_t j = 0; j < dimU; j++)
59  { // Loop over the rows
60  for (index_t i = 0; i < dimV; i++)
61  {
62  mpar.row(i + j * dimV) = auxPatch.patch(0).coefs().row((dimU - 1 - j) + dimU * i);
63  }
64  }
65 
66  // Create a new geometry starting from kntot vectors and the matrix of the coefficients reparametrized
67  gsTensorBSpline<d, T> newgeom1(temp_basisLV.knots(), temp_basisLU.knots(), mpar);
68 
69  // Create a new single-patch object
70  gsMultiPatch<T> newpatch;
71 
72  newpatch.addPatch(newgeom1);
73 
74  auxPatch.swap(newpatch);
75  auxPatch.computeTopology();
76 
77  // Update the number of rotation of the axis
78  rotationNum++;
79  }
80 
81  void rotateBasisAntiClock(){
82  gsMultiPatch<T> newpatch;
83  for(size_t np = 0; np < G1repBasis.nPatches(); np++)
84  {
85  gsMultiBasis<T> auxBase(G1repBasis.patch(np));
87  & temp_L = dynamic_cast<gsTensorBSplineBasis<d, T> &>(auxBase.basis(0));
88  gsBSplineBasis<T> temp_basisLU = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(0));
89  gsBSplineBasis<T> temp_basisLV = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(1));
90  index_t dimU = temp_L.size(0);
91  index_t dimV = temp_L.size(1);
92 
93  // The number of cols has to match the dimension of the space
94  gsMatrix<T> mpar(dimU * dimV, G1repBasis.patch(np).targetDim());
95 
96  // Loop over the cols
97  for (index_t j = 0; j < dimU; j++)
98  { // Loop over the rows
99  for (index_t i = 0; i < dimV; i++)
100  {
101  mpar.row(i + j * dimV) = G1repBasis.patch(np).coefs().row((dimU - 1 - j) + dimU * i);
102  }
103  }
104 
105  // Create a new geometry starting from kntot vectors and the matrix of the coefficients reparametrized
106  gsTensorBSpline<d, T> newgeom1(temp_basisLV.knots(), temp_basisLU.knots(), mpar);
107 
108  newpatch.addPatch(newgeom1);
109  }
110  G1repBasis.swap(newpatch);
111  }
112 
113 
114  void rotateParamClock(){
115  gsMultiBasis<T> auxBase(auxPatch);
116  gsTensorBSplineBasis<d, T> & temp_L = dynamic_cast<gsTensorBSplineBasis<d, T> &>(auxBase.basis(0));
117  gsBSplineBasis<T> temp_basisLU = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(0));
118  gsBSplineBasis<T> temp_basisLV = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(1));
119  index_t dimU = temp_L.size(0);
120  index_t dimV = temp_L.size(1);
121 
122  // The number of cols has to match the dimension of the space
123  gsMatrix<T> mpar(dimU * dimV, auxPatch.targetDim());
124 
125  for (index_t j = (dimU - 1 ) ; j >= 0; j--)
126  { // Loop over the rows
127  for (index_t i = 0; i < dimV; i++)
128  {
129  mpar.row(i + (dimU - j - 1) * dimV) = auxPatch.patch(0).coefs().row((dimV * dimU -1 - j) - dimU * i);
130  }
131  }
132 
133  // Create a new geometry starting from kntot vectors and the matrix of the coefficients reparametrized
134  gsTensorBSpline<d, T> newgeom1(temp_basisLV.knots(), temp_basisLU.knots(), mpar);
135 
136  // Create a new single-patch object
137  gsMultiPatch<T> newpatch;
138 
139  newpatch.addPatch(newgeom1);
140 
141  auxPatch.swap(newpatch);
142  auxPatch.computeTopology();
143 
144  // Update the number of rotation of the axis
145  rotationNum--;
146  this->checkRotation();
147  }
148 
149 
150  void rotateBasisClock(){
151  gsMultiPatch<T> newpatch;
152  for(size_t np = 0; np < G1repBasis.nPatches(); np++)
153  {
154  gsMultiBasis<T> auxBase(G1repBasis.patch(np));
156  & temp_L = dynamic_cast<gsTensorBSplineBasis<d, T> &>(auxBase.basis(0));
157  gsBSplineBasis<T> temp_basisLU = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(0));
158  gsBSplineBasis<T> temp_basisLV = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(1));
159  index_t dimU = temp_L.size(0);
160  index_t dimV = temp_L.size(1);
161 
162  //gsInfo << " dimU: " << dimU << "\t dimV: " << dimV << "\n";
163 
164  // The number of cols has to match the dimension of the space
165  gsMatrix<T> mpar(dimU * dimV, G1repBasis.patch(np).targetDim());
166 
167  for (index_t j = (dimU - 1); j >= 0; j--)
168  { // Loop over the rows
169  for (index_t i = 0; i < dimV; i++)
170  {
171  mpar.row(i + (dimU - j - 1) * dimV) =
172  G1repBasis.patch(np).coefs().row((dimV * dimU - 1 - j) - dimU * i);
173  }
174  }
175 
176  // Create a new geometry starting from kntot vectors and the matrix of the coefficients reparametrized
177  gsTensorBSpline<d, T> newgeom1(temp_basisLV.knots(), temp_basisLU.knots(), mpar);
178 
179  newpatch.addPatch(newgeom1);
180  }
181  G1repBasis = newpatch;
182  }
183 
184 
185  void rotateParamAntiClockTwice(){
186  gsMultiBasis<T> auxBase(auxPatch);
187  gsTensorBSplineBasis<d, T> & temp_L = dynamic_cast<gsTensorBSplineBasis<d, T> &>(auxBase.basis(0));
188  gsBSplineBasis<T> temp_basisLU = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(0));
189  gsBSplineBasis<T> temp_basisLV = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(1));
190  index_t dimU = temp_L.size(0);
191  index_t dimV = temp_L.size(1);
192 
193  // The number of cols has to match the dimension of the space
194  gsMatrix<T> mpar(dimU * dimV, auxPatch.targetDim());
195 
196  for (index_t i = 0; i < ( dimU * dimV ); i++)
197  {
198  mpar.row(i) = auxPatch.patch(0).coefs().row((dimU * dimV - 1) - i);
199  }
200  // Create a new geometry starting from kntot vectors and the matrix of the coefficients reparametrized
201  gsTensorBSpline<d, T> newgeom1(temp_basisLU.knots(), temp_basisLV.knots(), mpar);
202 
203  // Create a new single-patch object
204  gsMultiPatch<T> newpatch;
205 
206  newpatch.addPatch(newgeom1);
207 
208  auxPatch.swap(newpatch);
209  auxPatch.computeTopology();
210 
211  // Update the number of rotation of the axis (anti-clockwise)
212  rotationNum+=2;
213  this->checkRotation();
214  }
215 
216 
217  void rotateBasisAntiClockTwice(){
218  gsMultiPatch<T> newpatch;
219  for(size_t np = 0; np < G1repBasis.nPatches(); np++)
220  {
221  gsMultiBasis<T> auxBase(G1repBasis.patch(np));
223  & temp_L = dynamic_cast<gsTensorBSplineBasis<d, T> &>(auxBase.basis(0));
224  gsBSplineBasis<T> temp_basisLU = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(0));
225  gsBSplineBasis<T> temp_basisLV = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(1));
226  index_t dimU = temp_L.size(0);
227  index_t dimV = temp_L.size(1);
228 
229  // The number of cols has to match the dimension of the space
230  gsMatrix<T> mpar(dimU * dimV, G1repBasis.patch(np).targetDim());
231 
232  for (index_t i = 0; i < (dimU * dimV); i++)
233  {
234  mpar.row(i) = G1repBasis.patch(np).coefs().row((dimU * dimV - 1) - i);
235  }
236  // Create a new geometry starting from kntot vectors and the matrix of the coefficients reparametrized
237  gsTensorBSpline<d, T> newgeom1(temp_basisLU.knots(), temp_basisLV.knots(), mpar);
238 
239  newpatch.addPatch(newgeom1);
240  }
241  G1repBasis = newpatch;
242  }
243 
244 
245  void swapAxis(){
246  gsMultiBasis<T> auxBase(auxPatch);
247  gsTensorBSplineBasis<d, T> & temp_L = dynamic_cast<gsTensorBSplineBasis<d, T> &>(auxBase.basis(0));
248  gsBSplineBasis<T> temp_basisLU = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(0));
249  gsBSplineBasis<T> temp_basisLV = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(1));
250  index_t dimU = temp_L.size(0);
251  index_t dimV = temp_L.size(1);
252 
253  // The number of cols has to match the dimension of the space
254  gsMatrix<T> mpar(dimU * dimV, auxPatch.targetDim());
255 
256  for (index_t j = 0; j < dimU; j++)
257  { // Loop over the rows
258  for (index_t i = 0; i < dimV; i++)
259  {
260  mpar.row(i + j * dimV) = auxPatch.patch(0).coefs().row(j + dimU * i);
261  }
262  }
263 
264  // Create a new geometry starting from kntot vectors and the matrix of the coefficients reparametrized
265  gsTensorBSpline<d, T> newgeom1(temp_basisLV.knots(), temp_basisLU.knots(), mpar);
266 
267  // Create a new single-patch object
268  gsMultiPatch<T> newpatch;
269 
270  newpatch.addPatch(newgeom1);
271 
272  auxPatch.swap(newpatch);
273  //auxPatch.computeTopology();
274 
275  axisOrientation = 1;
276  }
277 
278 
279  void swapBasisAxis(){
280  gsMultiPatch<T> newpatch;
281  for(size_t np = 0; np < G1repBasis.nPatches(); np++)
282  {
283  gsMultiBasis<T> auxBase(G1repBasis.patch(np));
284  gsTensorBSplineBasis<d, T> & temp_L = dynamic_cast<gsTensorBSplineBasis<d, T> &>(auxBase.basis(0));
285  gsBSplineBasis<T> temp_basisLU = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(0));
286  gsBSplineBasis<T> temp_basisLV = dynamic_cast<gsBSplineBasis<T> &>(temp_L.component(1));
287  index_t dimU = temp_L.size(0);
288  index_t dimV = temp_L.size(1);
289 
290  // The number of cols has to match the dimension of the space
291  gsMatrix<T> mpar(dimU * dimV, G1repBasis.patch(np).targetDim());
292 
293  for (index_t j = 0; j < dimU; j++)
294  { // Loop over the rows
295  for (index_t i = 0; i < dimV; i++)
296  {
297  mpar.row(i + j * dimV) = G1repBasis.patch(np).coefs().row(j + dimU * i);
298  }
299  }
300 
301  // Create a new geometry starting from kntot vectors and the matrix of the coefficients reparametrized
302  gsTensorBSpline<d, T> newgeom1(temp_basisLV.knots(), temp_basisLU.knots(), mpar);
303 
304  newpatch.addPatch(newgeom1);
305  }
306  G1repBasis.swap(newpatch);
307 
308  }
309 
310 
311  void parametrizeBasisBack( gsMultiPatch<T> g1Basis){
312  G1repBasis = g1Basis;
313 
314  //gsInfo << "Patch " << patchIndex << " old: " << G1repBasis.patch(0).coefs()<< "\n";
315 
316  switch (rotationNum)
317  {
318  case 2:
319  this->rotateBasisAntiClockTwice();
320  break;
321  case -1:
322  this->rotateBasisAntiClock();
323  break;
324  case 1:
325  this->rotateBasisClock();
326  break;
327  case 0:
328  break;
329  default:
330  break;
331  }
332 
333  if(axisOrientation)
334  this->swapBasisAxis();
335 
336  //gsInfo << "Patch " << patchIndex << " new: " << G1repBasis.patch(0).coefs() << "\n";
337  }
338 
339  void setG1Basis(gsMultiPatch<T> g1Ba)
340  {
341  G1repBasis = g1Ba;
342  }
343 
344  void computeTopology(){
345  this->auxPatch.computeTopology();
346  }
347 
348  gsGeometry<T>& getPatch(){
349  return auxPatch.patch(0);
350  }
351 
352  const index_t getGlobalPatchIndex(){
353  return patchIndex;
354  }
355 
356  const index_t getNumberOfRotatioin(){
357  return rotationNum;
358  }
359 
360  const index_t getOrient(){
361  return axisOrientation;
362  }
363 
364  const gsMatrix<T> getG1BasisCoefs(index_t i) const
365  {
366  return G1repBasis.patch(i).coefs();
367  }
368 
369  const gsMultiPatch<T> & getG1Basis() const
370  {
371  return G1repBasis;
372  }
373 
374  void checkRotation(){
375  if(rotationNum == 4)
376  rotationNum = 0;
377  }
378 
379  void checkOrientation(){
380  axisOrientation = ( axisOrientation == 0 ? 1 : 0 );
381  }
382 
383 
384 
385  protected:
386 
387  gsMultiPatch<T> auxPatch;
388  gsMultiPatch<T> G1repBasis;
389 
390  // Global patch index in the initial geometry
391  index_t patchIndex;
392  // Stores the changing of the axis
393  // 0 -> axis not changed
394  // 1 -> axis swapped (x, y --> y, x)
395  bool axisOrientation;
396  // How many rotation of the axis has been executed
397  // Positive -> anticlockwise Negative -> clockwise
398  index_t rotationNum;
399 
400  index_t m_plus, m_minus;
401 
402  };
403 
404 }
index_t addPatch(typename gsGeometry< T >::uPtr g)
Add a patch from a gsGeometry&lt;T&gt;::uPtr.
Definition: gsMultiPatch.hpp:210
Abstract base class representing a geometry map.
Definition: gsGeometry.h:92
index_t size() const
Returns the number of elements in the basis.
Definition: gsTensorBasis.h:108
Main header to be included by clients using the G+Smo library.
A tensor product of d B-spline functions, with arbitrary target dimension.
Definition: gsTensorBSpline.h:44
int size(size_t i) const
The number of basis functions in basis i.
Definition: gsMultiBasis.h:232
#define index_t
Definition: gsConfig.h:32
A tensor product B-spline basis.
Definition: gsTensorBSplineBasis.h:36
virtual short_t targetDim() const
Dimension of the target space.
Definition: gsFunctionSet.h:560
A univariate B-spline basis.
Definition: gsBSplineBasis.h:694
Holds a set of patch-wise bases and their topology information.
Definition: gsMultiBasis.h:36
const KnotVectorType & knots(int i=0) const
Returns the knot vector of the basis.
Definition: gsBSplineBasis.h:369
Provides declaration of the MultiPatch class.
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition: gsMultiPatch.h:33
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
bool computeTopology(T tol=1e-4, bool cornersOnly=false, bool tjunctions=false)
Attempt to compute interfaces and boundaries automatically.
Definition: gsMultiPatch.hpp:366