G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsWeightMapper.hpp
Go to the documentation of this file.
1 
15 
16 namespace gismo
17 {
18 
19 namespace
20 {
21 void increment(const index_t ** ptr){++(*ptr);}
22 
23 template <class T, typename matrixT>
24 void getNonZeroInnerOfMatrix ( matrixT const &mat, typename gsWeightMapper<T>::IndexContainer const & outer, typename gsWeightMapper<T>::IndexContainer & inner)
25 {
26  const index_t numSource=outer.size();
27  std::vector<const index_t*> nzIndices(numSource);
28  std::vector<const index_t*> end(numSource);
29  std::vector<const index_t**> nzMin;
30  nzMin.reserve(numSource);
31  inner.clear();
32  inner.reserve(10*numSource); // reserve more memory then expected to be used
33 
34  // init the vectors
35  for (index_t i=0; i<numSource;++i)
36  {
37  nzIndices[i]=mat.innerIndexPtr()+mat.outerIndexPtr()[outer[i]];
38  end[i]=mat.innerIndexPtr()+mat.outerIndexPtr()[outer[i]+1];
39  }
40 
41  const index_t idMax=mat.cols();
42  index_t curMin;
43 
44  while (true) {
45  curMin=idMax;
46  nzMin.clear();
47  for(index_t i=0; i<numSource;++i)
48  {
49  if(nzIndices[i]<end[i])
50  {
51  if (*nzIndices[i]<curMin)
52  {
53  curMin=*nzIndices[i];
54  nzMin.clear();
55  nzMin.push_back(&nzIndices[i]);
56  }
57  else if (*nzIndices[i]==curMin)
58  {
59  nzMin.push_back(&nzIndices[i]);
60  }
61  }
62  }
63  if (curMin>=idMax)
64  break;
65  inner.push_back(curMin);
66  std::for_each(nzMin.begin(),nzMin.end(),increment);
67  }
68 }
69 
70 }
71 
72 template<class T>
73 void gsWeightMapper<T>::mapToTargetCoefs(gsMatrix<weightType> const & sourceCoefs,gsMatrix<weightType> & targetCoefs) const
74 {
75  // THIS DOES NOT WORK AS EIGEN SOLVERS ARE NOT ABLE TO SOLVE A ROW MAJOR MATRIX (last checked EIGEN::3.4)
76  // GISMO_ASSERT(m_matrix.isCompressed(),"Mapping has to be compressed for this.");
77  // gsSparseSolver<gsWeightMapper<T>::LToGMatrix>::QR solver;
78  // solver.compute(m_matrix);
79  // if(solver.info()!=gsEigen::Success)
80  // GISMO_ERROR("Could not compute the solver SparseQR");
81  // targetCoefs=solver.solve(sourceCoefs);
82  // if(solver.info()!=gsEigen::Success)
83  // GISMO_ERROR("Could not solve the QR system for the specific b");
84 
85  GISMO_ASSERT(sourceCoefs.rows()==m_matrix.rows(),"Wrong coefficient size!");
86  // WORKAROUND
87  if(!m_optimizationMatrix)
88  optimize(gsWeightMapper<T>::optTargetToSource);
89  // solve system with least squares method
90  typename gsSparseSolver<T>::QR solver;
91  solver.compute(*m_optimizationMatrix);
92  if(solver.info()!=gsEigen::Success)
93  GISMO_ERROR("Could not compute the solver SparseQR");
94  targetCoefs=solver.solve(sourceCoefs);
95  if(solver.info()!=gsEigen::Success)
96  GISMO_ERROR("Could not solve the QR system for the specific b");
97 }
98 
99 template<class T>
100 void gsWeightMapper<T>::sourceToTarget(indexType source, IndexContainer & target, WeightContainer & weights) const
101 {
102  target.clear();
103  weights.clear();
104  // todo: add reserve
105  for(InIterMat it = InIterMat(m_matrix,source);it;++it)
106  {
107  target.push_back(it.col());
108  weights.push_back(it.value());
109  }
110 }
111 
112 template<class T>
113 void gsWeightMapper<T>::targetToSource(indexType target,IndexContainer & indizes,WeightContainer & weights) const
114 {
115  indizes.clear();
116  weights.clear();
117  // todo: add reserve
118  for(indexType i=0;i<m_matrix.rows();i++)
119  {
120  const weightType w = m_matrix.coeff(i,target);
121  if(w!=0)
122  {
123  indizes.push_back(i);
124  weights.push_back(w);
125  }
126  }
127 }
128 
129 template<class T>
130 void gsWeightMapper<T>::fastSourceToTarget(IndexContainer const & source,IndexContainer & target) const
131 {
132  GISMO_ASSERT(m_matrix.isCompressed(),"optimize() must be called on the mapper with fastSourceToTarget flag before using this function.");
133  getNonZeroInnerOfMatrix<T>(m_matrix,source,target);
134 }
135 
136 template<class T>
137 void gsWeightMapper<T>::fastTargetToSource(const IndexContainer &target, IndexContainer &source) const
138 {
139  GISMO_ASSERT(m_optimizationMatrix,"optimize() must be called on the mapper with fastTargetToSource flag before using this function.");
140  getNonZeroInnerOfMatrix<T>(*m_optimizationMatrix,target,source);
141 }
142 
143 
144 template<class T>
145 void gsWeightMapper<T>::getLocalMap (IndexContainer const & source, IndexContainer const & target, gsMatrix<T> &map) const
146 {
147  GISMO_ASSERT(m_matrix.isCompressed(),"optimize() must be called on the mapper with fastSourceToTarget flag before using this function.");
148 
149  const index_t numRow=source.size();
150  const index_t numCol=target.size();
151 
152  map.resize(numRow,numCol);
153 
154  for (index_t r=0;r<numRow;++r)
155  {
156  index_t c=0;
157  Iterator coef = fastSourceToTarget(source[r]);
158 
159  while (c<numCol && coef)
160  {
161  if (target[c]< coef.index())
162  {
163  map(r,c)=0;
164  ++c;
165  continue;
166  }
167  if (target[c]== coef.index())
168  {
169  map(r,c)=coef.weight();
170  ++c;
171  }
172  ++coef;
173  }
174  while(c<numCol)
175  {
176  map(r,c)=0;
177  ++c;
178  }
179  }
180 }
181 
182 template<class T>
183 void gsWeightMapper<T>::getLocalMap (IndexContainer const & source, gsMatrix<T> &map) const
184 {
185  GISMO_ASSERT(m_matrix.isCompressed(),"optimize() must be called on the mapper with fastSourceToTarget flag before using this function.");
186 
187  const index_t numRow=source.size();
188  const index_t numCol=getNrOfTargets();
189 
190  map.resize(numRow,numCol);
191 
192  for (index_t r=0;r<numRow;++r)
193  {
194  index_t c=0;
195  Iterator coef = fastSourceToTarget(source[r]);
196 
197  while (c<numCol && coef)
198  {
199  if (c< coef.index())
200  {
201  map(r,c)=0;
202  ++c;
203  continue;
204  }
205  if (c== coef.index())
206  {
207  map(r,c)=coef.weight();
208  ++c;
209  }
210  ++coef;
211  }
212  while(c<numCol)
213  {
214  map(r,c)=0;
215  ++c;
216  }
217  }
218 }
219 
220 
221 }
#define index_t
Definition: gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
Provides declaration of gsWeightMapper class.
#define GISMO_ERROR(message)
Definition: gsDebug.h:118