Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
p1_continuity_constraints_impl.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2015: G-CSC, Goethe University Frankfurt
3 * Author: Andreas Vogel
4 *
5 * This file is part of UG4.
6 *
7 * UG4 is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License version 3 (as published by the
9 * Free Software Foundation) with the following additional attribution
10 * requirements (according to LGPL/GPL v3 §7):
11 *
12 * (1) The following notice must be displayed in the Appropriate Legal Notices
13 * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 *
15 * (2) The following notice must be displayed at a prominent place in the
16 * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 *
18 * (3) The following bibliography is recommended for citation and must be
19 * preserved in all covered files:
20 * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 * parallel geometric multigrid solver on hierarchically distributed grids.
22 * Computing and visualization in science 16, 4 (2013), 151-164"
23 * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 * flexible software system for simulating pde based models on high performance
25 * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU Lesser General Public License for more details.
31 */
32
33#ifndef __H__UG__LIB_DISC__SPATIAL_DISC__CONSTRAINTS__CONTINUITY_CONSTRAINTS__P1_CONTINUITY_CONSTRAINTS_IMPL__
34#define __H__UG__LIB_DISC__SPATIAL_DISC__CONSTRAINTS__CONTINUITY_CONSTRAINTS__P1_CONTINUITY_CONSTRAINTS_IMPL__
35
37#include "lib_disc/domain.h"
38
39namespace ug {
40
42template <typename TMatrix>
43void SetInterpolation(TMatrix& A,
44 std::vector<size_t> & constrainedIndex,
45 std::vector<std::vector<size_t> >& vConstrainingIndex,
46 bool assembleLinearProblem = true)
47{
48 //typedef typename TMatrix::row_iterator row_iterator;
49 //typedef typename TMatrix::value_type block_type;
50
51 // check number of indices passed
52 for(size_t i = 0; i < vConstrainingIndex.size(); ++i)
53 UG_ASSERT(vConstrainingIndex[i].size() == constrainedIndex.size(),
54 "Wrong number of indices.");
55
56// loop all constrained dofs
57 for(size_t i = 0; i < constrainedIndex.size(); ++i)
58 {
59 const size_t ai = constrainedIndex[i];
60
61 // remove all couplings
62 SetRow(A, ai, 0.0);
63
64 // set diag of row to identity
65 A(ai, ai) = 1.0;
66
67 // set coupling to all constraining dofs the inverse of the
68 // number of constraining dofs
69 // This is only required if assembling for a linear problem.
70 if (assembleLinearProblem)
71 {
72 const number frac = -1.0/(vConstrainingIndex.size());
73 for(size_t j=0; j < vConstrainingIndex.size(); ++j)
74 A(ai, vConstrainingIndex[j][i]) = frac;
75 }
76 }
77}
78
79template <typename TVector>
80void InterpolateValues(TVector& u,
81 std::vector<size_t>& constrainedIndex,
82 std::vector<std::vector<size_t> >& vConstrainingIndex)
83{
84 typedef typename TVector::value_type block_type;
85
86 // check number of indices passed
87 for(size_t i = 0; i < vConstrainingIndex.size(); ++i)
88 UG_ASSERT(vConstrainingIndex[i].size() == constrainedIndex.size(),
89 "Wrong number of indices.");
90
91// scaling factor
92 const number frac = 1./(vConstrainingIndex.size());
93
94// loop constrained indices
95 for(size_t i = 0; i < constrainedIndex.size(); ++i)
96 {
97 // get value to be interpolated
98 block_type& val = u[constrainedIndex[i]];
99
100 // reset value
101 val = 0.0;
102
103 // add equally from all constraining indices
104 for(size_t j=0; j < vConstrainingIndex.size(); ++j)
105 VecScaleAdd(val, 1.0, val, frac, u[vConstrainingIndex[j][i]]);
106 //val += frac * u[vConstrainingIndex[j][i]];
107 }
108}
109
110
111
112template <typename TMatrix>
113void SplitAddRow_Symmetric(TMatrix& A,
114 std::vector<size_t>& constrainedIndex,
115 std::vector<std::vector<size_t> >& vConstrainingIndex)
116{
117 typedef typename TMatrix::value_type block_type;
118 typedef typename TMatrix::row_iterator row_iterator;
119
120 size_t nConstrg = vConstrainingIndex.size();
121 UG_ASSERT(nConstrg, "There have to be constraining indices!");
122
123 // check number of indices passed
124 for(size_t i = 0; i < nConstrg; ++i)
125 UG_ASSERT(vConstrainingIndex[i].size() == constrainedIndex.size(),
126 "Wrong number of indices.");
127
128// scaling factor
129 const number frac = 1.0 / nConstrg;
130
131// handle each constrained index
132 for(size_t i = 0; i < constrainedIndex.size(); ++i)
133 {
134 const size_t algInd = constrainedIndex[i];
135
136 // add coupling constrained index -> constrained index
137 // we don't have to adjust the block itself, since the row of
138 // constraints will be set to interpolation afterwards
139 block_type diagEntry = A(algInd, algInd);
140
141 // scale by weight
142 diagEntry *= frac*frac;
143
144 // add coupling constrained dof -> constrained dof
145 for(size_t k = 0; k < vConstrainingIndex.size(); ++k)
146 for(size_t m = 0; m < vConstrainingIndex.size(); ++m)
147 A(vConstrainingIndex[k][i], vConstrainingIndex[m][i]) += diagEntry;
148
149#if 0
150
151 // (handled separately as it would otherwise trigger an assert -
152 // manipulation of matrix row while iterating over it)
153 const block_type block = A(algInd, algInd);
154 size_t nBlockCols = GetCols(block);
155 UG_ASSERT(nBlockCols == constrainedIndex.size(),
156 "Number of block cols and number of constrained DoFs in hanging vertex not equal.");
157 for (size_t blockIndConn = 0; blockIndConn < nBlockCols; ++blockIndConn)
158 {
159 const number val = BlockRef(block, blockInd, blockIndConn) * frac*frac;
160 for (size_t k = 0; k < nConstrg; ++k)
161 for (size_t m = 0; m < nConstrg; ++m)
162 DoFRef(A, vConstrainingIndex[k][i], vConstrainingIndex[m][blockIndConn]) += val;
163 }
164#endif
165
166 // loop coupling between constrained dof -> any other dof
167 for(row_iterator conn = A.begin_row(algInd); conn != A.end_row(algInd); ++conn)
168 {
169 const size_t algIndConn = conn.index();
170
171 // diagonal entry already handled
172 if (algIndConn == algInd)
173 continue;
174
175 // warning: do NOT use references here!
176 // they might become invalid when A is accessed at an entry that does not exist yet
177 // FIXME: This will only work properly if there is an entry A(i,j) for any entry
178 // A(j,i) in the matrix! Is this always the case!?
179 block_type block = conn.value();
180 block_type blockT = A(algIndConn, algInd);
181
182 // multiply the cpl value by the inverse number of constraining
183 block *= frac;
184 blockT *= frac;
185
186 // add the coupling to the constraining indices rows
187 for (size_t k = 0; k < nConstrg; ++k)
188 {
189 UG_ASSERT(vConstrainingIndex[k][i] != constrainedIndex[i],
190 "Modifying 'this' (=conn referenced) matrix row is invalid!" << constrainedIndex[i]);
191 A(vConstrainingIndex[k][i], algIndConn) += block;
192 A(algIndConn, vConstrainingIndex[k][i]) += blockT;
193 }
194
195 // set the split coupling to zero
196 // this needs to be done only in columns, since the row associated to
197 // the constrained index will be set to unity (or interpolation).
198 A(algIndConn, algInd) = 0.0;
199 }
200 }
201}
202
203template <typename TMatrix>
204void SplitAddRow_OneSide(TMatrix& A,
205 std::vector<size_t>& constrainedIndex,
206 std::vector<std::vector<size_t> >& vConstrainingIndex)
207{
208 typedef typename TMatrix::value_type block_type;
209 typedef typename TMatrix::row_iterator row_iterator;
210
211 UG_ASSERT(!vConstrainingIndex.empty(), "There have to be constraining indices!");
212
213 // check number of indices passed
214 for(size_t i = 0; i < vConstrainingIndex.size(); ++i)
215 UG_ASSERT(vConstrainingIndex[i].size() == constrainedIndex.size(),
216 "Wrong number of indices.");
217
218// scaling factor
219 const number frac = 1./(vConstrainingIndex.size());
220
221 for(size_t i = 0; i < constrainedIndex.size(); ++i)
222 {
223 const size_t algInd = constrainedIndex[i];
224
225 // choose randomly the first dof to add whole row
226 const size_t addTo = vConstrainingIndex[0][i];
227
228 block_type diagEntry = A(algInd, algInd);
229
230 // scale by weight
231 diagEntry *= frac;
232
233 // add coupling
234 for(size_t k = 0; k < vConstrainingIndex.size(); ++k)
235 A(addTo, vConstrainingIndex[k][i]) += diagEntry;
236
237 // loop coupling between constrained dof -> any other dof
238 for(row_iterator conn = A.begin_row(algInd); conn != A.end_row(algInd); ++conn)
239 {
240 const size_t algIndConn = conn.index();
241
242 // skip self-coupling (already handled)
243 if (algIndConn == algInd) continue;
244
245 // warning: do NOT use references here!
246 // they might become invalid when A is accessed at an entry that does not exist yet
247 // FIXME: This will only work properly if there is an entry A(i,j) for any entry
248 // A(j,i) in the matrix! Is this always the case!?
249 const block_type block = conn.value();
250 block_type blockT = A(algIndConn, algInd);
251
252 blockT *= frac;
253
254 // add the coupling to the constraining indices rows
255 for(size_t k = 0; k < vConstrainingIndex.size(); ++k)
256 A(algIndConn, vConstrainingIndex[k][i]) += blockT;
257
258 // coupling due to one side adding
259 A(addTo, algIndConn) += block;
260
261 // set the split coupling to zero
262 // this must only be done in columns, since the row associated to
263 // the constrained index will be set to an interpolation.
264 A(algIndConn, algInd) = 0.0;
265 }
266 }
267}
268
269template <typename TVector>
270void SplitAddRhs_Symmetric(TVector& rhs,
271 std::vector<size_t> & constrainedIndex,
272 std::vector<std::vector<size_t> >& vConstrainingIndex)
273{
274 typedef typename TVector::value_type block_type;
275
276 // check number of indices passed
277 for(size_t i = 0; i < vConstrainingIndex.size(); ++i)
278 UG_ASSERT(vConstrainingIndex[i].size() == constrainedIndex.size(),
279 "Wrong number of indices.");
280
281// scaling factor
282 const number frac = 1./(vConstrainingIndex.size());
283
284// loop constrained indices
285 for(size_t i = 0; i < constrainedIndex.size(); ++i)
286 {
287 // get constrained rhs
288 // modify block directly since set to zero afterwards
289 block_type& val = rhs[constrainedIndex[i]];
290 val *= frac;
291
292 // split equally on all constraining indices
293 for(size_t j=0; j < vConstrainingIndex.size(); ++j)
294 rhs[vConstrainingIndex[j][i]] += val;
295
296 // set rhs to zero for constrained index
297 val = 0.0;
298 }
299}
300
301template <typename TVector>
302void SplitAddRhs_OneSide(TVector& rhs,
303 std::vector<size_t> & constrainedIndex,
304 std::vector<std::vector<size_t> >& vConstrainingIndex)
305{
306 typedef typename TVector::value_type block_type;
307
308 // check number of indices passed
309 for(size_t i = 0; i < vConstrainingIndex.size(); ++i)
310 UG_ASSERT(vConstrainingIndex[i].size() == constrainedIndex.size(),
311 "Wrong number of indices.");
312
313 for(size_t i = 0; i < constrainedIndex.size(); ++i)
314 {
315 // choose randomly the first dof to add whole
316 // (must be the same as for row)
317 const size_t addTo = vConstrainingIndex[0][i];
318
319 block_type& val = rhs[constrainedIndex[i]];
320 rhs[addTo] += val;
321 val = 0.0;
322 }
323}
324
325
336 ConstrainedVertex* hgVrt,
337 std::vector<Vertex*>& vConstrainingVrt,
338 std::vector<size_t>& constrainedInd,
339 std::vector<std::vector<size_t> >& vConstrainingInd)
340{
341// get subset index
342 const int si = dd->subset_handler()->get_subset_index(hgVrt);
343
344// get constraining vertices
345 CollectConstraining(vConstrainingVrt, *dd->multi_grid(), hgVrt);
346
347// clear constrainedInd
348 constrainedInd.clear();
349
350// resize constraining indices
351 vConstrainingInd.clear();
352 vConstrainingInd.resize(vConstrainingVrt.size());
353
354 if (dd->grouped()) // block algebra (assuming constrainers have exactly the same functions as constrained)
355 {
356 // get indices for constrained vertex
357 dd->inner_algebra_indices(hgVrt, constrainedInd, false);
358
359 // get indices for constraining vertices
360 for (size_t i = 0; i < vConstrainingVrt.size(); ++i)
361 dd->inner_algebra_indices(vConstrainingVrt[i], vConstrainingInd[i], false);
362 }
363 else // scalar algebra
364 {
365 // get algebra indices for constrained and constraining vertices
366 for (size_t fct = 0; fct < dd->num_fct(); ++fct)
367 {
368 // check that function is defined on subset
369 if (!dd->is_def_in_subset(fct, si)) continue;
370
371 // get indices for constrained vertex
372 dd->inner_algebra_indices_for_fct(hgVrt, constrainedInd, false, fct);
373
374 // get indices for constraining vertices
375 for (size_t i = 0; i < vConstrainingVrt.size(); ++i)
376 {
377 const int siC = dd->subset_handler()->get_subset_index(vConstrainingVrt[i]);
378
379 // check that function is defined on subset
380 UG_COND_THROW(!dd->is_def_in_subset(fct, siC),
381 "Function " << fct << " is defined for a constrained vertex, "
382 "but not for one of its constraining vertices!");
383
384 dd->inner_algebra_indices_for_fct(vConstrainingVrt[i], vConstrainingInd[i], false, fct);
385 }
386 }
387 }
388}
389
392// Sym P1 Constraints
395
396template <typename TDomain, typename TAlgebra>
397void
400 ConstSmartPtr<DoFDistribution> dd, int type, number time,
402 const std::vector<number>* vScaleMass,
403 const std::vector<number>* vScaleStiff)
404{
405 if(this->m_spAssTuner->single_index_assembling_enabled())
406 UG_THROW("index-wise assemble routine is not "
407 "implemented for SymP1Constraints \n");
408
409// storage for indices and vertices
410 std::vector<std::vector<size_t> > vConstrainingInd;
411 std::vector<size_t> constrainedInd;
412 std::vector<Vertex*> vConstrainingVrt;
413
414// get begin end of hanging vertices
416 iter = dd->begin<ConstrainedVertex>();
417 iterEnd = dd->end<ConstrainedVertex>();
418
419// loop constrained vertices
420 for(; iter != iterEnd; ++iter)
421 {
422 // get hanging vert
423 ConstrainedVertex* hgVrt = *iter;
424
425 // get algebra indices for constrained and constraining vertices
426 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
427
428 // adapt rhs
429 SplitAddRhs_Symmetric(d, constrainedInd, vConstrainingInd);
430 }
431}
432
433
434template <typename TDomain, typename TAlgebra>
435void
437adjust_rhs(vector_type& rhs, const vector_type& u,
438 ConstSmartPtr<DoFDistribution> dd, int type, number time)
439{
440 if(this->m_spAssTuner->single_index_assembling_enabled())
441 UG_THROW("index-wise assemble routine is not "
442 "implemented for SymP1Constraints \n");
443
444// storage for indices and vertices
445 std::vector<std::vector<size_t> > vConstrainingInd;
446 std::vector<size_t> constrainedInd;
447 std::vector<Vertex*> vConstrainingVrt;
448
449// get begin end of hanging vertices
451 iter = dd->begin<ConstrainedVertex>();
452 iterEnd = dd->end<ConstrainedVertex>();
453
454// loop constrained vertices
455 for(; iter != iterEnd; ++iter)
456 {
457 // get hanging vert
458 ConstrainedVertex* hgVrt = *iter;
459
460 // get algebra indices for constrained and constraining vertices
461 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
462
463 // adapt rhs
464 SplitAddRhs_Symmetric(rhs, constrainedInd, vConstrainingInd);
465 }
466}
467
468template <typename TDomain, typename TAlgebra>
469void
472 ConstSmartPtr<DoFDistribution> dd, int type, number time,
474 const number s_a0)
475{
476 if(this->m_spAssTuner->single_index_assembling_enabled())
477 UG_THROW("index-wise assemble routine is not "
478 "implemented for SymP1Constraints \n");
479
480// storage for indices and vertices
481 std::vector<std::vector<size_t> > vConstrainingInd;
482 std::vector<size_t> constrainedInd;
483 std::vector<Vertex*> vConstrainingVrt;
484
485// get begin end of hanging vertices
487 iter = dd->begin<ConstrainedVertex>();
488 iterEnd = dd->end<ConstrainedVertex>();
489
490// loop constrained vertices
491 for(; iter != iterEnd; ++iter)
492 {
493 // get hanging vert
494 ConstrainedVertex* hgVrt = *iter;
495
496 // get algebra indices for constrained and constraining vertices
497 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
498
499 // Split using indices
500 SplitAddRow_Symmetric(J, constrainedInd, vConstrainingInd);
501
502 // set interpolation
503 SetInterpolation(J, constrainedInd, vConstrainingInd, m_bAssembleLinearProblem);
504 }
505}
506
507template <typename TDomain, typename TAlgebra>
508void
511 ConstSmartPtr<DoFDistribution> dd, int type, number time)
512{
513 m_bAssembleLinearProblem = true;
514
515 if(this->m_spAssTuner->single_index_assembling_enabled())
516 UG_THROW("index-wise assemble routine is not "
517 "implemented for SymP1Constraints \n");
518
519// storage for indices and vertices
520 std::vector<std::vector<size_t> > vConstrainingInd;
521 std::vector<size_t> constrainedInd;
522 std::vector<Vertex*> vConstrainingVrt;
523
524// get begin end of hanging vertices
526 iter = dd->begin<ConstrainedVertex>();
527 iterEnd = dd->end<ConstrainedVertex>();
528
529// loop constrained vertices
530 for(; iter != iterEnd; ++iter)
531 {
532 // get hanging vert
533 ConstrainedVertex* hgVrt = *iter;
534
535 // get algebra indices for constrained and constraining vertices
536 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
537
538 // Split using indices
539 SplitAddRow_Symmetric(mat, constrainedInd, vConstrainingInd);
540
541 // set interpolation
542 SetInterpolation(mat, constrainedInd, vConstrainingInd, true);
543
544 // adapt rhs
545 SplitAddRhs_Symmetric(rhs, constrainedInd, vConstrainingInd);
546 }
547}
548
549template <typename TDomain, typename TAlgebra>
550void
553 int type, number time)
554{
555 if(this->m_spAssTuner->single_index_assembling_enabled())
556 UG_THROW("index-wise assemble routine is not "
557 "implemented for SymP1Constraints \n");
558
559// storage for indices and vertices
560 std::vector<std::vector<size_t> > vConstrainingInd;
561 std::vector<size_t> constrainedInd;
562 std::vector<Vertex*> vConstrainingVrt;
563
564// get begin end of hanging vertices
566 iter = dd->begin<ConstrainedVertex>();
567 iterEnd = dd->end<ConstrainedVertex>();
568
569// loop constraining edges
570 for(; iter != iterEnd; ++iter)
571 {
572 // get hanging vert
573 ConstrainedVertex* hgVrt = *iter;
574
575 // get algebra indices for constrained and constraining vertices
576 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
577
578 // Interpolate values
579 InterpolateValues(u, constrainedInd, vConstrainingInd);
580 }
581}
582
583
584template <typename TDomain, typename TAlgebra>
585void
588(
589 matrix_type& P,
592 int type,
593 number time
594)
595{
596 if (m_bAssembleLinearProblem) return;
597
598 if (this->m_spAssTuner->single_index_assembling_enabled())
599 UG_THROW("index-wise assemble routine is not "
600 "implemented for SymP1Constraints \n");
601
602// storage for indices and vertices
603 std::vector<std::vector<size_t> > vConstrainingInd;
604 std::vector<size_t> constrainedInd;
605 std::vector<Vertex*> vConstrainingVrt;
606
607// get begin end of hanging vertices
609 iter = ddFine->begin<ConstrainedVertex>();
610 iterEnd = ddFine->end<ConstrainedVertex>();
611
612// loop constrained vertices
613 for(; iter != iterEnd; ++iter)
614 {
615 // get hanging vert
616 ConstrainedVertex* hgVrt = *iter;
617
618 // get algebra indices for constrained and constraining vertices
619 get_algebra_indices(ddFine, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
620
621 // set zero row
622 size_t sz = constrainedInd.size();
623 for (size_t i = 0; i < sz; ++i)
624 SetRow(P, constrainedInd[i], 0.0);
625 }
626}
627
628
629template <typename TDomain, typename TAlgebra>
630void
633(
634 matrix_type& R,
637 int type,
638 number time
639)
640{
641
642}
643
644
645
646template <typename TDomain, typename TAlgebra>
647void
650( vector_type& u,
652 int type,
653 number time
654)
655{
656 //typedef typename vector_type::value_type block_type;
657
658 if (this->m_spAssTuner->single_index_assembling_enabled())
659 UG_THROW("index-wise assemble routine is not "
660 "implemented for OneSideP1Constraints \n");
661
662 // storage for indices and vertices
663 std::vector<std::vector<size_t> > vConstrainingInd;
664 std::vector<size_t> constrainedInd;
665 std::vector<Vertex*> vConstrainingVrt;
666
667 // get begin end of hanging vertices
669 iter = dd->begin<ConstrainedVertex>();
670 iterEnd = dd->end<ConstrainedVertex>();
671
672 // loop constrained vertices
673 for (; iter != iterEnd; ++iter)
674 {
675 // get hanging vert
676 ConstrainedVertex* hgVrt = *iter;
677
678 // get algebra indices for constrained and constraining vertices
679 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
680
681 // set all entries corresponding to constrained dofs to zero
682 for (size_t i = 0; i < constrainedInd.size(); ++i)
683 u[constrainedInd[i]] = 0.0;
684 }
685}
686
687
690// OneSide P1 Constraints
693
694template<int dim>
696
698 : m_aaPos(spDomain->position_accessor())
699 {}
700
701 inline bool operator() (Vertex* vrt1, Vertex* vrt2)
702 {UG_THROW(dim <<" not implemented.");}
703
704 protected:
706};
707
708template<>
710{
711 if(m_aaPos[vrt1][0] < m_aaPos[vrt2][0]) {
712 return true;
713 }
714 return false;
715}
716
717template<>
719{
720 if(m_aaPos[vrt1][0] < m_aaPos[vrt2][0]) {
721 return true;
722 }
723 else if(m_aaPos[vrt1][0] == m_aaPos[vrt2][0]) {
724 if(m_aaPos[vrt1][1] < m_aaPos[vrt2][1])
725 return true;
726 }
727 return false;
728}
729
730template<>
732{
733 if(m_aaPos[vrt1][0] < m_aaPos[vrt2][0]) {
734 return true;
735 }
736 else if(m_aaPos[vrt1][0] == m_aaPos[vrt2][0]) {
737 if(m_aaPos[vrt1][1] < m_aaPos[vrt2][1]){
738 return true;
739 }
740 else if(m_aaPos[vrt1][1] == m_aaPos[vrt2][1]){
741 if(m_aaPos[vrt1][2] < m_aaPos[vrt2][2])
742 return true;
743 }
744 return false;
745 }
746 return false;
747}
748
749
764template <typename TDomain>
766 ConstrainedVertex* hgVrt,
767 std::vector<Vertex*>& vConstrainingVrt,
768 std::vector<size_t>& constrainedInd,
769 std::vector<std::vector<size_t> >& vConstrainingInd,
770 const SortVertexPos<TDomain::dim>& sortVertexPos)
771{
772// get subset index
773 const int si = dd->subset_handler()->get_subset_index(hgVrt);
774
775// get constraining vertices
776 CollectConstraining(vConstrainingVrt, *dd->multi_grid(), hgVrt);
777
778#ifdef UG_PARALLEL
779 std::sort(vConstrainingVrt.begin(), vConstrainingVrt.end(), sortVertexPos);
780#endif
781
782// clear constrainedInd
783 constrainedInd.clear();
784
785// resize constraining indices
786 vConstrainingInd.clear();
787 vConstrainingInd.resize(vConstrainingVrt.size());
788
789// get algebra indices for constrained and constraining vertices
790 if (dd->grouped()) // block algebra (assuming constrainers have exactly the same functions as constrained)
791 {
792 // get indices for constrained vertex
793 dd->inner_algebra_indices(hgVrt, constrainedInd, false);
794
795 // get indices for constraining vertices
796 for (size_t i = 0; i < vConstrainingVrt.size(); ++i)
797 dd->inner_algebra_indices(vConstrainingVrt[i], vConstrainingInd[i], false);
798 }
799 else // scalar algebra
800 {
801 for (size_t fct = 0; fct < dd->num_fct(); fct++)
802 {
803 // check that function is defined on subset
804 if (!dd->is_def_in_subset(fct, si)) continue;
805
806 // get indices for constrained vertex
807 dd->inner_algebra_indices_for_fct(hgVrt, constrainedInd, false, fct);
808
809 // get indices for constraining vertices
810 for (size_t i = 0; i < vConstrainingVrt.size(); ++i)
811 {
812 const int siC = dd->subset_handler()->get_subset_index(vConstrainingVrt[i]);
813
814 // check that function is defined on subset
815 UG_COND_THROW(!dd->is_def_in_subset(fct, siC),
816 "Function " << fct << " is defined for a constrained vertex, "
817 "but not for one of its constraining vertices!");
818
819 dd->inner_algebra_indices_for_fct(vConstrainingVrt[i], vConstrainingInd[i], false, fct);
820 }
821 }
822 }
823}
824
825
826template <typename TDomain, typename TAlgebra>
827void
830 ConstSmartPtr<DoFDistribution> dd, int type, number time,
832 const std::vector<number>* vScaleMass,
833 const std::vector<number>* vScaleStiff)
834{
835 if(this->m_spAssTuner->single_index_assembling_enabled())
836 UG_THROW("index-wise assemble routine is not "
837 "implemented for OneSideP1Constraints \n");
838
839// storage for indices and vertices
840 std::vector<std::vector<size_t> > vConstrainingInd;
841 std::vector<size_t> constrainedInd;
842 std::vector<Vertex*> vConstrainingVrt;
843
844#ifdef UG_PARALLEL
845 SortVertexPos<TDomain::dim> sortVertexPos(this->approximation_space()->domain());
846#endif
847
848// get begin end of hanging vertices
850 iter = dd->begin<ConstrainedVertex>();
851 iterEnd = dd->end<ConstrainedVertex>();
852
853// loop constrained vertices
854 for(; iter != iterEnd; ++iter)
855 {
856 // get hanging vert
857 ConstrainedVertex* hgVrt = *iter;
858
859 // get algebra indices for constrained and constraining vertices
860#ifdef UG_PARALLEL
861 get_algebra_indices<TDomain>(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd, sortVertexPos);
862#else
863 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
864#endif
865
866 // adapt rhs
867 SplitAddRhs_OneSide(d, constrainedInd, vConstrainingInd);
868 }
869}
870
871
872template <typename TDomain, typename TAlgebra>
873void
875adjust_rhs(vector_type& rhs, const vector_type& u,
876 ConstSmartPtr<DoFDistribution> dd, int type, number time)
877{
878 if(this->m_spAssTuner->single_index_assembling_enabled())
879 UG_THROW("index-wise assemble routine is not "
880 "implemented for OneSideP1Constraints \n");
881
882// storage for indices and vertices
883 std::vector<std::vector<size_t> > vConstrainingInd;
884 std::vector<size_t> constrainedInd;
885 std::vector<Vertex*> vConstrainingVrt;
886
887#ifdef UG_PARALLEL
888 SortVertexPos<TDomain::dim> sortVertexPos(this->approximation_space()->domain());
889#endif
890
891// get begin end of hanging vertices
893 iter = dd->begin<ConstrainedVertex>();
894 iterEnd = dd->end<ConstrainedVertex>();
895
896// loop constrained vertices
897 for(; iter != iterEnd; ++iter)
898 {
899 // get hanging vert
900 ConstrainedVertex* hgVrt = *iter;
901
902 // get algebra indices for constrained and constraining vertices
903#ifdef UG_PARALLEL
904 get_algebra_indices<TDomain>(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd, sortVertexPos);
905#else
906 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
907#endif
908
909 // adapt rhs
910 SplitAddRhs_OneSide(rhs, constrainedInd, vConstrainingInd);
911 }
912}
913
914template <typename TDomain, typename TAlgebra>
915void
918 ConstSmartPtr<DoFDistribution> dd, int type, number time,
920 const number s_a0)
921{
922 if(this->m_spAssTuner->single_index_assembling_enabled())
923 UG_THROW("index-wise assemble routine is not "
924 "implemented for OneSideP1Constraints \n");
925
926// storage for indices and vertices
927 std::vector<std::vector<size_t> > vConstrainingInd;
928 std::vector<size_t> constrainedInd;
929 std::vector<Vertex*> vConstrainingVrt;
930
931#ifdef UG_PARALLEL
932 SortVertexPos<TDomain::dim> sortVertexPos(this->approximation_space()->domain());
933#endif
934
935// get begin end of hanging vertices
937 iter = dd->begin<ConstrainedVertex>();
938 iterEnd = dd->end<ConstrainedVertex>();
939
940// loop constrained vertices
941 for(; iter != iterEnd; ++iter)
942 {
943 // get hanging vert
944 ConstrainedVertex* hgVrt = *iter;
945
946 // get algebra indices for constrained and constraining vertices
947#ifdef UG_PARALLEL
948 get_algebra_indices<TDomain>(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd, sortVertexPos);
949#else
950 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
951#endif
952
953 // Split using indices
954 SplitAddRow_OneSide(J, constrainedInd, vConstrainingInd);
955
956 // set interpolation
957 SetInterpolation(J, constrainedInd, vConstrainingInd, m_bAssembleLinearProblem);
958 }
959}
960
961template <typename TDomain, typename TAlgebra>
962void
965 ConstSmartPtr<DoFDistribution> dd, int type, number time)
966{
967 m_bAssembleLinearProblem = true;
968
969 if(this->m_spAssTuner->single_index_assembling_enabled())
970 UG_THROW("index-wise assemble routine is not "
971 "implemented for OneSideP1Constraints \n");
972
973// storage for indices and vertices
974 std::vector<std::vector<size_t> > vConstrainingInd;
975 std::vector<size_t> constrainedInd;
976 std::vector<Vertex*> vConstrainingVrt;
977
978#ifdef UG_PARALLEL
979 SortVertexPos<TDomain::dim> sortVertexPos(this->approximation_space()->domain());
980#endif
981
982// get begin end of hanging vertices
984 iter = dd->begin<ConstrainedVertex>();
985 iterEnd = dd->end<ConstrainedVertex>();
986
987// loop constraining edges
988 for(; iter != iterEnd; ++iter)
989 {
990 // get hanging vert
991 ConstrainedVertex* hgVrt = *iter;
992
993 // get algebra indices for constrained and constraining vertices
994#ifdef UG_PARALLEL
995 get_algebra_indices<TDomain>(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd, sortVertexPos);
996#else
997 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
998#endif
999
1000 // Split using indices
1001 SplitAddRow_OneSide(mat, constrainedInd, vConstrainingInd);
1002
1003 // Set interpolation
1004 SetInterpolation(mat, constrainedInd, vConstrainingInd, true);
1005
1006 // adapt rhs
1007 SplitAddRhs_OneSide(rhs, constrainedInd, vConstrainingInd);
1008 }
1009}
1010
1011template <typename TDomain, typename TAlgebra>
1012void
1015 int type, number time)
1016{
1017 if(this->m_spAssTuner->single_index_assembling_enabled())
1018 UG_THROW("index-wise assemble routine is not "
1019 "implemented for OneSideP1Constraints \n");
1020
1021// storage for indices and vertices
1022 std::vector<std::vector<size_t> > vConstrainingInd;
1023 std::vector<size_t> constrainedInd;
1024 std::vector<Vertex*> vConstrainingVrt;
1025
1026// get begin end of hanging vertices
1028 iter = dd->begin<ConstrainedVertex>();
1029 iterEnd = dd->end<ConstrainedVertex>();
1030
1031// loop constraining edges
1032 for(; iter != iterEnd; ++iter)
1033 {
1034 // get hanging vert
1035 ConstrainedVertex* hgVrt = *iter;
1036
1037 // get algebra indices for constrained and constraining vertices
1038 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
1039
1040 // Interpolate values
1041 InterpolateValues(u, constrainedInd, vConstrainingInd);
1042 }
1043}
1044
1045
1046
1047template <typename TDomain, typename TAlgebra>
1048void
1051(
1052 matrix_type& P,
1055 int type,
1056 number time
1057)
1058{
1059 if (m_bAssembleLinearProblem) return;
1060
1061 if (this->m_spAssTuner->single_index_assembling_enabled())
1062 UG_THROW("index-wise assemble routine is not "
1063 "implemented for SymP1Constraints \n");
1064
1065// storage for indices and vertices
1066 std::vector<std::vector<size_t> > vConstrainingInd;
1067 std::vector<size_t> constrainedInd;
1068 std::vector<Vertex*> vConstrainingVrt;
1069
1070// get begin end of hanging vertices
1072 iter = ddFine->begin<ConstrainedVertex>();
1073 iterEnd = ddFine->end<ConstrainedVertex>();
1074
1075// loop constrained vertices
1076 for(; iter != iterEnd; ++iter)
1077 {
1078 // get hanging vert
1079 ConstrainedVertex* hgVrt = *iter;
1080
1081 // get algebra indices for constrained and constraining vertices
1082 get_algebra_indices(ddFine, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
1083
1084 // set zero row
1085 size_t sz = constrainedInd.size();
1086 for (size_t i = 0; i < sz; ++i)
1087 SetRow(P, constrainedInd[i], 0.0);
1088 }
1089}
1090
1091
1092template <typename TDomain, typename TAlgebra>
1093void
1104
1105
1106
1107
1108template <typename TDomain, typename TAlgebra>
1109void
1112( vector_type& u,
1114 int type,
1115 number time
1116)
1117{
1118 //typedef typename vector_type::value_type block_type;
1119
1120 if (this->m_spAssTuner->single_index_assembling_enabled())
1121 UG_THROW("index-wise assemble routine is not "
1122 "implemented for OneSideP1Constraints \n");
1123
1124 // storage for indices and vertices
1125 std::vector<std::vector<size_t> > vConstrainingInd;
1126 std::vector<size_t> constrainedInd;
1127 std::vector<Vertex*> vConstrainingVrt;
1128
1129 // get begin end of hanging vertices
1131 iter = dd->begin<ConstrainedVertex>();
1132 iterEnd = dd->end<ConstrainedVertex>();
1133
1134 // loop constrained vertices
1135 for (; iter != iterEnd; ++iter)
1136 {
1137 // get hanging vert
1138 ConstrainedVertex* hgVrt = *iter;
1139
1140 // get algebra indices for constrained and constraining vertices
1141 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
1142
1143 // set all entries corresponding to constrained dofs to zero
1144 for (size_t i = 0; i < constrainedInd.size(); ++i)
1145 u[constrainedInd[i]] = 0.0;
1146 }
1147}
1148
1149
1150}; // namespace ug
1151
1152
1153
1154#endif /* __H__UG__LIB_DISC__SPATIAL_DISC__CONSTRAINTS__CONTINUITY_CONSTRAINTS__P1_CONTINUITY_CONSTRAINTS_IMPL__ */
Definition smart_pointer.h:296
Definition smart_pointer.h:108
A vertex appearing on edges or faces.
Definition grid_objects_0d.h:110
Definition domain.h:287
algebra_type::vector_type vector_type
Definition p1_continuity_constraints.h:126
void adjust_jacobian(matrix_type &J, const vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0, ConstSmartPtr< VectorTimeSeries< vector_type > > vSol=NULL, const number s_a0=1.0)
adapts jacobian to enforce constraints
Definition p1_continuity_constraints_impl.h:917
virtual void adjust_correction(vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0)
Definition p1_continuity_constraints_impl.h:1112
void adjust_prolongation(matrix_type &P, ConstSmartPtr< DoFDistribution > ddFine, ConstSmartPtr< DoFDistribution > ddCoarse, int type, number time=0.0)
sets constraints in prolongation
Definition p1_continuity_constraints_impl.h:1051
void adjust_rhs(vector_type &rhs, const vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0)
adapts a rhs to enforce constraints
Definition p1_continuity_constraints_impl.h:875
algebra_type::matrix_type matrix_type
Definition p1_continuity_constraints.h:123
void adjust_solution(vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0)
sets the constraints in a solution vector
Definition p1_continuity_constraints_impl.h:1014
void adjust_defect(vector_type &d, const vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0, ConstSmartPtr< VectorTimeSeries< vector_type > > vSol=NULL, const std::vector< number > *vScaleMass=NULL, const std::vector< number > *vScaleStiff=NULL)
adapts defect to enforce constraints
Definition p1_continuity_constraints_impl.h:829
void adjust_restriction(matrix_type &R, ConstSmartPtr< DoFDistribution > ddCoarse, ConstSmartPtr< DoFDistribution > ddFine, int type, number time=0.0)
sets constraints in restriction
Definition p1_continuity_constraints_impl.h:1096
void adjust_linear(matrix_type &mat, vector_type &rhs, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0)
adapts matrix and rhs (linear case) to enforce constraints
Definition p1_continuity_constraints_impl.h:964
void adjust_defect(vector_type &d, const vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0, ConstSmartPtr< VectorTimeSeries< vector_type > > vSol=NULL, const std::vector< number > *vScaleMass=NULL, const std::vector< number > *vScaleStiff=NULL)
adapts defect to enforce constraints
Definition p1_continuity_constraints_impl.h:399
void adjust_prolongation(matrix_type &P, ConstSmartPtr< DoFDistribution > ddFine, ConstSmartPtr< DoFDistribution > ddCoarse, int type, number time=0.0)
sets constraints in prolongation
Definition p1_continuity_constraints_impl.h:588
void adjust_restriction(matrix_type &R, ConstSmartPtr< DoFDistribution > ddCoarse, ConstSmartPtr< DoFDistribution > ddFine, int type, number time=0.0)
sets constraints in restriction
Definition p1_continuity_constraints_impl.h:633
void adjust_rhs(vector_type &rhs, const vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0)
adapts a rhs to enforce constraints
Definition p1_continuity_constraints_impl.h:437
void adjust_jacobian(matrix_type &J, const vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0, ConstSmartPtr< VectorTimeSeries< vector_type > > vSol=NULL, const number s_a0=1.0)
adapts jacobian to enforce constraints
Definition p1_continuity_constraints_impl.h:471
algebra_type::matrix_type matrix_type
Definition p1_continuity_constraints.h:58
virtual void adjust_correction(vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0)
Definition p1_continuity_constraints_impl.h:650
void adjust_linear(matrix_type &mat, vector_type &rhs, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0)
adapts matrix and rhs (linear case) to enforce constraints
Definition p1_continuity_constraints_impl.h:510
algebra_type::vector_type vector_type
Definition p1_continuity_constraints.h:61
void adjust_solution(vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0)
sets the constraints in a solution vector
Definition p1_continuity_constraints_impl.h:552
time series of solutions and corresponding time point
Definition solution_time_series.h:59
Base-class for all vertex-types.
Definition grid_base_objects.h:231
void SetRow(TSparseMatrix &A, size_t i, size_t alpha, number val=0.0)
Definition sparsematrix_util.h:710
#define UG_ASSERT(expr, msg)
Definition assert.h:70
#define UG_THROW(msg)
Definition error.h:57
#define UG_COND_THROW(cond, msg)
UG_COND_THROW(cond, msg) : performs a UG_THROW(msg) if cond == true.
Definition error.h:61
double number
Definition types.h:124
void VecScaleAdd(vector_t &vOut, typename vector_t::value_type s1, const vector_t &v1, typename vector_t::value_type s2, const vector_t &v2)
Scales two Vectors, adds them and returns the sum in a third vector.
Definition math_vector_functions_common_impl.hpp:265
parameterNumber frac
the ug namespace
size_t GetCols(const T &t)
void SetInterpolation(TMatrix &A, std::vector< size_t > &constrainedIndex, std::vector< std::vector< size_t > > &vConstrainingIndex, bool assembleLinearProblem=true)
sets a matrix row corresponding to averaging the constrained index
Definition p1_continuity_constraints_impl.h:43
void InterpolateValues(TVector &u, std::vector< size_t > &constrainedIndex, std::vector< std::vector< size_t > > &vConstrainingIndex)
Definition p1_continuity_constraints_impl.h:80
void SplitAddRhs_OneSide(TVector &rhs, std::vector< size_t > &constrainedIndex, std::vector< std::vector< size_t > > &vConstrainingIndex)
Definition p1_continuity_constraints_impl.h:302
double & BlockRef(T &vec, size_t i)
Definition blocks.h:66
void SplitAddRow_Symmetric(TMatrix &A, std::vector< size_t > &constrainedIndex, std::vector< std::vector< size_t > > &vConstrainingIndex)
Definition p1_continuity_constraints_impl.h:113
void get_algebra_indices(ConstSmartPtr< DoFDistribution > dd, ConstrainedVertex *hgVrt, std::vector< Vertex * > &vConstrainingVrt, std::vector< size_t > &constrainedInd, std::vector< std::vector< size_t > > &vConstrainingInd)
Extract algebra indices for constrained and constraining indices from DoF distribution.
Definition p1_continuity_constraints_impl.h:335
void SplitAddRhs_Symmetric(TVector &rhs, std::vector< size_t > &constrainedIndex, std::vector< std::vector< size_t > > &vConstrainingIndex)
Definition p1_continuity_constraints_impl.h:270
void CollectConstraining(std::vector< Vertex * > &vConstrainingVrt, const Grid &grid, ConstrainedVertex *hgVrt, bool bClearContainer)
returns the vertices of the object constraining a hanging vertex
Definition p1_continuity_constraints.cpp:41
void SplitAddRow_OneSide(TMatrix &A, std::vector< size_t > &constrainedIndex, std::vector< std::vector< size_t > > &vConstrainingIndex)
Definition p1_continuity_constraints_impl.h:204
number & DoFRef(TMatrix &mat, const DoFIndex &iInd, const DoFIndex &jInd)
Definition multi_index.h:276
SurfaceView::traits< TElem >::const_iterator const_iterator
Definition dof_distribution.h:82
Definition p1_continuity_constraints_impl.h:695
SortVertexPos(SmartPtr< Domain< dim, MultiGrid, MGSubsetHandler > > spDomain)
Definition p1_continuity_constraints_impl.h:697
Domain< dim, MultiGrid, MGSubsetHandler >::position_accessor_type & m_aaPos
Definition p1_continuity_constraints_impl.h:705
bool operator()(Vertex *vrt1, Vertex *vrt2)
Definition p1_continuity_constraints_impl.h:701