G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsMappedSpline.hpp
Go to the documentation of this file.
1
15#include <gsCore/gsDofMapper.h>
16
17namespace gismo
18{
19
20template<short_t d,class T>
21gsMappedSpline<d,T>::gsMappedSpline( const gsMultiPatch<T> & mp, const gsSparseMatrix<T> & m )
22{
23 GISMO_ASSERT(mp.nPatches()>0,"MultiPatch is empty?");
24 m_mbases = new gsMappedBasis<d,T>(gsMultiBasis<T>(mp),m);
25
26 // collect and transform the coefficients
27 gsMatrix<T> local = mp.coefs();
28 m_mbases->local_coef_to_global_coef(local,m_global);
29
30 init(*m_mbases);
31}
32
33template<short_t d,class T>
34gsMappedSpline<d,T>::gsMappedSpline( const gsMappedBasis<d,T> & mbases, const gsMatrix<T> & coefs )
35:
36m_global(coefs)
37{
38 m_mbases=mbases.clone().release();
39 init(mbases);
40}
41
42template<short_t d,class T>
43gsMappedSpline<d,T>::gsMappedSpline( const gsMappedSpline& other )
44: gsFunctionSet<T>(), m_global(other.m_global)
45{
46 m_mbases=other.m_mbases->clone().release();
47}
48
49template<short_t d,class T>
50gsMappedSpline<d,T> & gsMappedSpline<d,T>::operator=( const gsMappedSpline& other )
51{
52 delete m_mbases;
53 m_mbases=other.m_mbases->clone().release();
54 m_global = other.m_global;
55 m_ss = other.m_ss;
56 for (auto & s : m_ss) s.setSource(*this);
57 return *this;
58}
59
60template<short_t d,class T>
61void gsMappedSpline<d,T>::eval_into(const unsigned patch, const gsMatrix<T> & u, gsMatrix<T>& result ) const
62{
63 gsMatrix<index_t> actives;
64 gsMatrix<T> evals;
65
66 index_t N = targetDim();
67 // gsC1Basis<d,t> * basis = dynamic_cast<gsC1Basis<d,t> *>(this->getBase(patch));
68 // if (basis==NULL)
69 // {
70 // m_mbases->active_into(patch,u,actives);
71 // m_mbases->eval_into(patch,u,evals);
72 // m_mbases->getBase(patch).linearCombination_into(m_coefs,actives,evals,result);
73 // }
74 // else
75 // {
76 gsMatrix<T> tmp;
77 result.resize( N,u.cols());
78 // This loop enables that the number of actives can be different for each column in u
79 for (index_t k = 0; k!=u.cols(); k++)
80 {
81 m_mbases->active_into(patch,u.col(k),actives);
82 m_mbases->eval_into(patch,u.col(k),evals);
83 m_mbases->getBase(patch).linearCombination_into(m_global,actives,evals,tmp);
84 result.col(k) = tmp;
85 }
86 // }
87}
88
89template<short_t d,class T>
90void gsMappedSpline<d,T>::deriv_into(const unsigned patch, const gsMatrix<T> & u, gsMatrix<T>& result ) const
91{
92 gsMatrix<index_t> actives;
93 gsMatrix<T> evals;
94
95 index_t N = targetDim();
96 index_t M = domainDim();
97 result.resize( N * M,u.cols());
98
99 gsMatrix<T> tmp;
100 // This loop enables that the number of actives can be different for each column in u
101 for (index_t k = 0; k!=u.cols(); k++)
102 {
103 m_mbases->active_into(patch,u.col(k),actives);
104 m_mbases->deriv_into(patch,u.col(k),evals);
105 m_mbases->getBase(patch).linearCombination_into(m_global,actives,evals,tmp);
106 result.col(k) = tmp;
107 }
108}
109
110template<short_t d,class T>
111void gsMappedSpline<d,T>::deriv2_into(const unsigned patch, const gsMatrix<T> & u, gsMatrix<T>& result ) const
112{
113 gsMatrix<index_t> actives;
114 gsMatrix<T> evals;
115
116 index_t N = targetDim();
117 index_t M = domainDim();
118 index_t S = M*(M+1)/2;
119 result.resize( S*N,u.cols());
120 gsMatrix<T> tmp;
121 // This loop enables that the number of actives can be different for each column in u
122 for (index_t k = 0; k!=u.cols(); k++)
123 {
124 m_mbases->active_into(patch,u.col(k),actives);
125 m_mbases->deriv2_into(patch,u.col(k),evals);
126 m_mbases->getBase(patch).linearCombination_into(m_global,actives,evals,tmp);
127 result.col(k) = tmp;
128 }
129}
130
131template<short_t d,class T>
132void gsMappedSpline<d,T>::evalAllDers_into(const unsigned patch, const gsMatrix<T> & u,
133 const int n, std::vector<gsMatrix<T> >& result,
134 bool sameElement) const
135{
136 result.resize(n+1);
137
138 gsMatrix<index_t> actives;
139 std::vector< gsMatrix<T> > evals;
140
141 index_t N = targetDim();
142 index_t m = domainDim();
143 index_t S = m*(m+1)/2;
144
145 std::vector<index_t> blocksizes(3);
146 blocksizes[0] = N;
147 blocksizes[1] = N*m;
148 blocksizes[2] = N*S;
149
150 gsMatrix<T> tmp;
151 // todo: change the loop over i and the loop over k
152 for( int i = 0; i <= n; i++)
153 {
154 result[i].resize(blocksizes[i],u.cols());
155 // This loop enables that the number of actives can be different for each column in u
156 for (index_t k = 0; k!=u.cols(); k++)
157 {
158 m_mbases->active_into(patch,u.col(k),actives);//..
159 m_mbases->evalAllDers_into(patch,u.col(k),n,evals,sameElement);
160 m_mbases->getBase(patch).linearCombination_into(m_global,actives,evals[i],tmp);
161 result[i].col(k) = tmp;
162
163 }
164 }
165
166 // for( int i = 0; i <= n; i++)
167 // result[i].resize(blocksizes[i],u.cols());
168
169 // // todo: change the loop over i and the loop over k
170 // for (index_t k = 0; k!=u.cols(); k++)
171 // {
172 // // This loop enables that the number of actives can be different for each column in u
173 // m_mbases->active_into(patch,u.col(k),actives);
174 // m_mbases->evalAllDers_into(patch,u.col(k),n,evals);
175 // for( int i = 0; i <= n; i++)
176 // {
177 // m_mbases->getBase(patch).linearCombination_into(m_global,actives,evals[i],tmp);
178 // result[i].col(k) = tmp;
179 // }
180 // }
181}
182
183template<short_t d,class T>
184gsMultiPatch<T> gsMappedSpline<d,T>::exportToPatches() const
185{
186 gsMatrix<T> local;
187 m_mbases->global_coef_to_local_coef(m_global,local);
188 return m_mbases->exportToPatches(local);
189}
190
191template<short_t d,class T>
192gsGeometry<T> * gsMappedSpline<d,T>::exportPatch(int i,gsMatrix<T> const & localCoef) const
193{
194 return m_mbases->exportPatch(i,localCoef);
195}
196
197template<short_t d,class T>
198std::map<std::array<size_t, 4>, internal::ElementBlock> gsMappedSpline<d,T>::BezierOperator() const
199{
200 GISMO_ENSURE( 2==domainDim(), "Anything other than bivariate splines is not yet supported!");
201
202 // Loop over all the elements of the given Mapped Spline and collect all relevant
203 // information in ElementBlocks. These will be grouped in a std::map
204 // with respect to the number of active basis functions ( = NNj/NCV )
205 // of each Bezier element
206 std::map<std::array<size_t, 4>, internal::ElementBlock> ElementBlocks;
207
208 // index_t NNj; // Number of control points of the Bezier elements of block j
209 gsMatrix<index_t> mappedActives, globalActives, localActives; // Active basis functions
210
211 gsMatrix<T> coefVectors, center_point(2,1);
212 // Center point of the Bezier element, all basis functions are active here
213 center_point.setConstant( (T)(0.5) );
214
215 // The control points of the MappedSpline
216 gsMatrix<T> globalCoefs = this->getMappedCoefs();
217
218 // The transpose of the global Bezier Operator
219 gsWeightMapper<T> mapper = this->getMapper();
220
221 // The Bezier operator, transpose is used because we are constructing
222 // the basis functions, the mapper.asMatrix() is used for the control points
223 gsMatrix<> bezOperator = mapper.asMatrix().transpose();
224
225// TODO: Delete if implementation is OK as is
226/* gsMultiPatch<> mp = this->exportToPatches();
227 mp.computeTopology();
228 // gsMultiBasis<> mb(mp);
229 gsDofMapper dofMapper = mp.getMapper(1e-4);
230 // dofMapper.finalize(); */
231
232 // The mapped spline's basis functions
233 gsMappedBasis<d,T> mappedBasis = this->getMappedBasis();
234
235 std::array<size_t, 4> key;
236 for (size_t p=0; p<this->nPatches(); ++p)
237 {
238 // Mapped active basis functions
239 mappedBasis.active_into(p, center_point,mappedActives);
240
241 // Patch-local active basis functions
242 this->getBase(p).active_into(center_point,localActives);
243 // gsInfo << "Local ("<< localActives.rows()<<"):" << localActives.transpose() << "\n";
244
245 globalActives.resizeLike(localActives);
246 globalActives.setZero();
247
248 // OPTION 1: Global, all considered uncoupled
249 // Get the global indices of the active basis functions
250 globalActives = mappedBasis.getGlobalIndex(p,localActives);
251
252 // OPTION 2: Global, considering coupling (i.e. as in the multi patch)
253 // globalActives.resizeLike(localActives);
254 // for (index_t i=0; i<localActives.rows(); ++i)
255 // {
256 // globalActives(i) = dofMapper.index( localActives(i), p);
257 // }
258
259 //OPTION 3: Global, considering coupling and mapping
260 std::vector<index_t> sourceID, mappedID;
261 // mappedActives.resizeLike(globalActives);
262 // for (index_t i=0; i<localActives.rows(); ++i)
263 // {
264 // sourceID.clear();
265 // mappedID.clear();
266 // sourceID.push_back( globalActives(i) );
267 // mapper.sourceToTarget(sourceID, mappedID);
268 // mappedActives(i) = mappedID.front();
269 // }
270
271
272 // gsInfo << "Global("<< globalActives.rows()<<"):" << globalActives.transpose() << "\n";
273 // gsInfo << "Mapped("<< mappedActives.rows()<<"):" << mappedActives.transpose() <<"\n";
274
275
276 // coefVectors is the patch-local Bezier operator, size (NNj x NCVCj), NCVCj = (PR+1)*(PS+1)*(PT+1)
277 coefVectors.resize(mappedActives.rows(), globalActives.rows());
278 coefVectors.setZero();
279
280 // std::vector<std::pair<index_t,index_t> > preImage;
281 // Extract the local bezier operator from the global one
282 for (index_t i=0; i<mappedActives.rows(); ++i)
283 {
284 for (index_t j=0; j<globalActives.rows(); ++j)
285 {
286 // if (dofMapper.is_coupled_index(globalActives(j)))
287 // {
288 // dofMapper.preImage(globalActives(j), preImage);
289 // // gsInfo << globalActives(j) << " is coupled with ";
290 // for (size_t k = 0; k != preImage.size(); ++k)
291 // // gsInfo << preImage.at(k).first << "," << preImage.at(k).second << " ";
292 // coefVectors(i,j) += bezOperator(mappedActives(i), mappedBasis.getGlobalIndex(preImage.at(k).first, preImage.at(k).second) );
293 // // gsInfo << "\n";
294 // }
295 // else
296 // {
297 // // gsInfo << globalActives(j) << " is free.\n";
298 // coefVectors(i,j) = bezOperator(mappedActives(i), mappedBasis.getGlobalIndex(p, localActives(j))) ;
299 // }
300
301 // sourceID.clear();
302 // mappedID.clear();
303 // sourceID.push_back( globalActives(j) );
304 // mapper.sourceToTarget(sourceID, mappedID);
305 coefVectors(i,j) = bezOperator(mappedActives(i), globalActives(j)) ;
306 }
307
308 }
309 // gsInfo << "Coefs size:" << coefVectors.rows() << "x" << coefVectors.cols() << "\n\n";
310
311 // Put everything in the ElementBlock
312 key[0] = mappedActives.rows();
313 key[1] = this->getBase(p).degree(0);
314 key[2] = this->getBase(p).degree(1);
315 key[3] = 0; // TODO: if implemented for trivariates fix this
316 // NNj = mappedActives.size(); // Number of control points (nodes) of the Bezier element
317 ElementBlocks[key].numElements += 1; // Increment the Number of Elements contained in the ElementBlock
318 ElementBlocks[key].actives.push_back(mappedActives); // Append the active basis functions ( = the Node IDs ) for this element.
319 ElementBlocks[key].PR = this->getBase(p).degree(0); // Degree of the Bezier element in the r-direction
320 ElementBlocks[key].PS = this->getBase(p).degree(1); // Degree of the Bezier element in the s-direction
321 ElementBlocks[key].PT = 0; // TODO: if implemented for trivariates fix this
322 ElementBlocks[key].coefVectors.push_back( coefVectors ); //(!) If it is not bezier
323 }
324
325 return ElementBlocks;
326}
327
328
329} //namespace gismo
#define index_t
Definition gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition gsDebug.h:102
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Provides the gsDofMapper class for re-indexing DoFs.
Provides declaration of Basis abstract interface.
The G+Smo namespace, containing all definitions for the library.