G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsWeightMapper.hpp
Go to the documentation of this file.
1
15
16namespace gismo
17{
18
19namespace
20{
21void increment(const index_t ** ptr){++(*ptr);}
22
23template <class T, typename matrixT>
24void 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
72template<class T>
73void 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
99template<class T>
100void 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
112template<class T>
113void 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
129template<class T>
130void 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
136template<class T>
137void 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
144template<class T>
145void 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
182template<class T>
183void 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_ERROR(message)
Definition gsDebug.h:118
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Provides declaration of gsWeightMapper class.
The G+Smo namespace, containing all definitions for the library.