69 static const int dim = TDomain::dim;
70 typedef typename TDomain::grid_type TGrid;
76 typedef typename TDomain::position_accessor_type TPositionAccessor;
81 typename TDomain::grid_type&
grid = *spGrid;
88 iter = dd->begin<TElem>(SurfaceView::ALL);
89 iterEnd = dd->end<TElem>(SurfaceView::ALL);
96 typename TGrid::template traits<TSide>::secure_container vSide;
97 grid.associated_elements_sorted(vSide, elem);
100 grid.begin_marking();
108 for(
size_t s = 0;
s < vSide.size(); ++
s){
111 typename TGrid::template traits<TElem>::secure_container vElemOfSide;
112 grid.associated_elements(vElemOfSide, vSide[
s]);
115 if(vElemOfSide.size() == 0)
116 UG_THROW(
"Huh, why no element? Should be at least the considered elem itself");
122 if(vElemOfSide.size() == 1){
128 if(vSide[
s]->is_constrained()){
130 TContrainedSide* cSide =
dynamic_cast<TContrainedSide*
>(vSide[
s]);
131 TSide* constrainingSide =
dynamic_cast<TSide*
>(cSide->get_constraining_object());
133 typename TGrid::template traits<TElem>::secure_container vElemOfContrainingSide;
134 grid.associated_elements(vElemOfContrainingSide, constrainingSide);
135 if(vElemOfContrainingSide.size() != 2)
UG_THROW(
"Huh, should be "<<2<<
" at constraining side");
137 for(
size_t nbr = 0; nbr < vElemOfContrainingSide.size(); ++nbr){
139 TElem* neighborElem = vElemOfContrainingSide[nbr];
140 if(
grid.template num_children<TElem,TElem>(neighborElem) > 0)
continue;
142 grid.mark(neighborElem);
143 vNeighbors.push_back(neighborElem);
151 else if(vSide[
s]->is_constraining()){
153 TContrainingSide* cSide =
dynamic_cast<TContrainingSide*
>(vSide[
s]);
154 const size_t numConstrained = cSide->template num_constrained<TSide>();
156 for(
size_t cs = 0; cs < numConstrained; ++cs){
158 TSide* constrainedSide = cSide->template constrained<TSide>(cs);
161 typename TGrid::template traits<TElem>::secure_container vElemOfContrainedSide;
162 grid.associated_elements(vElemOfContrainedSide, constrainedSide);
163 if(vElemOfContrainedSide.size() != 1)
UG_THROW(
"Huh, should be 1 at constrained side");
164 TElem* neighborElem = vElemOfContrainedSide[0];
165 grid.mark(neighborElem);
166 vNeighbors.push_back(neighborElem);
177 if(vElemOfSide.size() != 2)
178 UG_THROW(
"Huh, why more than 2 elements of side?");
180 for(
size_t eos = 0; eos < vElemOfSide.size(); ++eos){
183 TElem* neighborElem = vElemOfSide[eos];
186 if(
grid.template num_children<TElem,TElem>(neighborElem) > 0)
187 UG_THROW(
"Huh, why not on top level?");
190 if(neighborElem == elem)
continue;
191 grid.mark(neighborElem);
192 vNeighbors.push_back(neighborElem);
201 for(
size_t s = 0;
s < vSide.size(); ++
s){
204 typename TGrid::template traits<TElem>::secure_container vElemOfSide;
205 grid.associated_elements(vElemOfSide, vSide[
s]);
208 if(vElemOfSide.size() == 0)
209 UG_THROW(
"Huh, why no element? Should be at least the considered elem itself");
218 Vertex*
const* vVertex = vSide[
s]->vertices();
219 const size_t numVertex = vSide[
s]->num_vertices();
222 for(
size_t vrt = 0; vrt < numVertex; ++vrt)
225 typename TGrid::template traits<TElem>::secure_container vVertexNeighbor;
226 grid.associated_elements(vVertexNeighbor, vVertex[vrt]);
227 for(
size_t eov = 0; eov < vVertexNeighbor.size(); ++eov)
229 TElem* neighborElem = vVertexNeighbor[eov];
230 if(
grid.is_marked(neighborElem))
continue;
231 if(
grid.template num_children<TElem,TElem>(neighborElem) > 0)
continue;
233 grid.mark(neighborElem);
234 vNeighbors.push_back(neighborElem);
238 if(
grid.template num_children<Vertex,Vertex>(vVertex[vrt]) > 0){
240 if(
grid.template num_children<Vertex,Vertex>(vVertex[vrt]) != 1)
241 UG_THROW(
"Huh, why more than one vertex child?")
243 Vertex* fineVrt =
grid.template get_child<Vertex,Vertex>(vVertex[vrt], 0);
245 typename TGrid::template traits<TElem>::secure_container vVertexNeighbor;
246 grid.associated_elements(vVertexNeighbor, fineVrt);
247 for(
size_t eov = 0; eov < vVertexNeighbor.size(); ++eov)
249 TElem* neighborElem = vVertexNeighbor[eov];
250 if(
grid.is_marked(neighborElem))
continue;
251 if(
grid.template num_children<TElem,TElem>(neighborElem) > 0)
continue;
253 grid.mark(neighborElem);
254 vNeighbors.push_back(neighborElem);
260 if(
grid.get_parent(vVertex[vrt]) != 0){
267 typename TGrid::template traits<TElem>::secure_container vVertexNeighbor;
268 grid.associated_elements(vVertexNeighbor, coarseVrt);
269 for(
size_t eov = 0; eov < vVertexNeighbor.size(); ++eov)
271 TElem* neighborElem = vVertexNeighbor[eov];
272 if(
grid.is_marked(neighborElem))
continue;
273 if(
grid.template num_children<TElem,TElem>(neighborElem) > 0)
continue;
275 grid.mark(neighborElem);
276 vNeighbors.push_back(neighborElem);
299 std::vector<size_t>& vIndex,
302 typename TDomain::grid_type&
grid,
303 typename TDomain::position_accessor_type& aaPos,
309 static const int dim = TDomain::dim;
310 typedef typename TDomain::grid_type TGrid;
315 typedef typename TDomain::position_accessor_type TPositionAccessor;
319 const size_t fct = 0;
326 Vertex*
const* vVertex = elem->vertices();
327 const size_t numVertex = elem->num_vertices();
330 std::vector<MathVector<dim> > vCornerCoords;
331 vCornerCoords.resize(numVertex);
332 for(
size_t vrt = 0; vrt < numVertex; ++vrt){
333 vCornerCoords[vrt] = aaPos[ vVertex[vrt] ];
338 AveragePositions<dim>(ElemMidPoint, vCornerCoords);
342 if(fillElemSizeIntoVector){
345 std::vector<DoFIndex> ind;
346 if(spF->inner_dof_indices(elem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
347 const size_t i = ind[0][0];
350 (*spF)[i] = ElementSize<dim>(elem->reference_object_id(), &vCornerCoords[0]);
355 typename TGrid::template traits<TSide>::secure_container vSide;
356 grid.associated_elements_sorted(vSide, elem);
359 grid.begin_marking();
367 for(
size_t s = 0;
s < vSide.size(); ++
s){
370 typename TGrid::template traits<TElem>::secure_container vElemOfSide;
371 grid.associated_elements(vElemOfSide, vSide[
s]);
374 if(vElemOfSide.size() == 0)
381 if(vElemOfSide.size() == 1){
386 if(vSide[
s]->is_constrained()){
388 TContrainedSide* cSide =
dynamic_cast<TContrainedSide*
>(vSide[
s]);
389 TSide* constrainingSide =
dynamic_cast<TSide*
>(cSide->get_constraining_object());
391 typename TGrid::template traits<TElem>::secure_container vElemOfContrainingSide;
392 grid.associated_elements(vElemOfContrainingSide, constrainingSide);
393 if(vElemOfContrainingSide.size() != 2)
UG_THROW(
"Huh, should be "<<2<<
" at constraining side");
395 for(
size_t nbr = 0; nbr < vElemOfContrainingSide.size(); ++nbr){
397 TElem* neighborElem = vElemOfContrainingSide[nbr];
398 if(
grid.template num_children<TElem,TElem>(neighborElem) > 0)
continue;
400 grid.mark(neighborElem);
401 vElem.push_back(neighborElem);
404 std::vector<DoFIndex> ind;
405 if(spF->inner_dof_indices(neighborElem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
406 vIndex.push_back(ind[0][0]);
409 vDistance.resize(vDistance.size()+1);
411 AveragePositions<dim>(vDistance.back(), vCornerCoords);
412 VecScaleAdd(vDistance.back(), 1.0, ElemMidPoint, -1.0, vDistance.back());
422 vElem.push_back(vElemOfSide[0]);
425 std::vector<DoFIndex> ind;
426 if(spF->inner_dof_indices(elem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
427 vIndex.push_back(ind[0][0]);
432 ElementNormal<dim>(vSide[
s]->reference_object_id(), n, &vCornerCoords[0]);
434 vDistance.resize(vDistance.size()+1);
436 VecScaleAdd(vDistance.back(), 2.0, ElemMidPoint, -2.0, vDistance.back());
444 else if(vSide[
s]->is_constraining()){
446 TContrainingSide* cSide =
dynamic_cast<TContrainingSide*
>(vSide[
s]);
447 const size_t numConstrained = cSide->template num_constrained<TSide>();
449 for(
size_t cs = 0; cs < numConstrained; ++cs){
451 TSide* constrainedSide = cSide->template constrained<TSide>(cs);
454 typename TGrid::template traits<TElem>::secure_container vElemOfContrainedSide;
455 grid.associated_elements(vElemOfContrainedSide, constrainedSide);
456 if(vElemOfContrainedSide.size() != 1)
UG_THROW(
"Huh, should be 1 at constrained side");
457 TElem* neighborElem = vElemOfContrainedSide[0];
458 grid.mark(neighborElem);
459 vElem.push_back(neighborElem);
462 std::vector<DoFIndex> ind;
463 if(spF->inner_dof_indices(neighborElem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
464 vIndex.push_back(ind[0][0]);
467 vDistance.resize(vDistance.size()+1);
469 AveragePositions<dim>(vDistance.back(), vCornerCoords);
470 VecScaleAdd(vDistance.back(), 1.0, ElemMidPoint, -1.0, vDistance.back());
481 if(vElemOfSide.size() != 2)
482 UG_THROW(
"Huh, why more than 2 elements of side?");
484 for(
size_t eos = 0; eos < vElemOfSide.size(); ++eos){
487 TElem* neighborElem = vElemOfSide[eos];
490 if(neighborElem == elem)
continue;
493 grid.mark(neighborElem);
494 vElem.push_back(neighborElem);
497 std::vector<DoFIndex> ind;
498 if(spF->inner_dof_indices(neighborElem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
499 vIndex.push_back(ind[0][0]);
502 vDistance.resize(vDistance.size()+1);
504 AveragePositions<dim>(vDistance.back(), vCornerCoords);
505 VecScaleAdd(vDistance.back(), 1.0, ElemMidPoint, -1.0, vDistance.back());
514 for(
size_t vrt = 0; vrt < numVertex; ++vrt)
516 typename TGrid::template traits<TElem>::secure_container vVertexNeighbor;
517 grid.associated_elements(vVertexNeighbor, vVertex[vrt]);
520 for(
size_t eov = 0; eov < vVertexNeighbor.size(); ++eov)
522 TElem* neighborElem = vVertexNeighbor[eov];
523 if(
grid.is_marked(neighborElem))
continue;
524 if(
grid.template num_children<TElem,TElem>(neighborElem) > 0)
continue;
526 grid.mark(neighborElem);
527 vElem.push_back(neighborElem);
530 std::vector<DoFIndex> ind;
531 if(spF->inner_dof_indices(neighborElem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
532 vIndex.push_back(ind[0][0]);
535 vDistance.resize(vDistance.size()+1);
537 AveragePositions<dim>(vDistance.back(), vCornerCoords);
538 VecScaleAdd(vDistance.back(), 1.0, ElemMidPoint, -1.0, vDistance.back());
543 if(
grid.template num_children<Vertex,Vertex>(vVertex[vrt]) > 0){
545 if(
grid.template num_children<Vertex,Vertex>(vVertex[vrt]) != 1)
546 UG_THROW(
"Huh, why more than one vertex child?")
548 Vertex* fineVrt =
grid.template get_child<Vertex,Vertex>(vVertex[vrt], 0);
550 typename TGrid::template traits<TElem>::secure_container vVertexNeighbor;
551 grid.associated_elements(vVertexNeighbor, fineVrt);
552 for(
size_t eov = 0; eov < vVertexNeighbor.size(); ++eov)
554 TElem* neighborElem = vVertexNeighbor[eov];
555 if(
grid.is_marked(neighborElem))
continue;
556 if(
grid.template num_children<TElem,TElem>(neighborElem) > 0)
continue;
558 grid.mark(neighborElem);
559 vElem.push_back(neighborElem);
562 std::vector<DoFIndex> ind;
563 if(spF->inner_dof_indices(neighborElem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
564 vIndex.push_back(ind[0][0]);
567 vDistance.resize(vDistance.size()+1);
569 AveragePositions<dim>(vDistance.back(), vCornerCoords);
570 VecScaleAdd(vDistance.back(), 1.0, ElemMidPoint, -1.0, vDistance.back());
576 if(
grid.get_parent(vVertex[vrt]) != 0){
582 typename TGrid::template traits<TElem>::secure_container vVertexNeighbor;
583 grid.associated_elements(vVertexNeighbor, coarseVrt);
584 for(
size_t eov = 0; eov < vVertexNeighbor.size(); ++eov)
586 TElem* neighborElem = vVertexNeighbor[eov];
587 if(
grid.is_marked(neighborElem))
continue;
588 if(
grid.template num_children<TElem,TElem>(neighborElem) > 0)
continue;
590 grid.mark(neighborElem);
591 vElem.push_back(neighborElem);
594 std::vector<DoFIndex> ind;
595 if(spF->inner_dof_indices(neighborElem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
596 vIndex.push_back(ind[0][0]);
599 vDistance.resize(vDistance.size()+1);
601 AveragePositions<dim>(vDistance.back(), vCornerCoords);
602 VecScaleAdd(vDistance.back(), 1.0, ElemMidPoint, -1.0, vDistance.back());
623 std::vector< std::vector< number > >& vStencil,
624 std::vector< std::vector<size_t> >& vIndex,
625 int quadRuleType,
bool fillElemSizeIntoVector)
629 static const int dim = TDomain::dim;
630 typedef typename TDomain::grid_type TGrid;
636 typedef typename TDomain::position_accessor_type TPositionAccessor;
639 UG_THROW(
"This implementation is 2d only, currently. Handle vertex neighbors properly in 3d...");
641 const size_t fct = 0;
646 if(quadRuleType == 1)
651 else if (quadRuleType == 2)
653 sideWeight = 4.0/6.0;
654 vertexWeight = 1.0/6.0;
657 UG_THROW(
"InitLaplacian_PartialIntegration: wrong quad rule")
663 typename TDomain::grid_type&
grid = *spGrid;
664 typename TDomain::position_accessor_type& aaPos = domain->position_accessor();
671 iter = dd->begin<TElem>(SurfaceView::ALL);
672 iterEnd = dd->end<TElem>(SurfaceView::ALL);
675 const size_t numIndex = spF->num_dofs();
676 vIndex.resize(numIndex);
677 vStencil.resize(numIndex);
680 std::vector<MathVector<dim> > vCornerCoords, vNbrCornerCoords;
684 for(;iter != iterEnd; ++iter)
690 std::vector<DoFIndex> ind;
691 if(spF->inner_dof_indices(elem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
692 const size_t i = ind[0][0];
696 vIndex[i].push_back(i);
700 vStencil[i].resize(1, 0.0);
703 Vertex*
const* vVertex = elem->vertices();
704 const size_t numVertex = elem->num_vertices();
707 vCornerCoords.resize(numVertex);
708 for(
size_t vrt = 0; vrt < numVertex; ++vrt){
709 vCornerCoords[vrt] = aaPos[ vVertex[vrt] ];
713 const number vol = ElementSize<dim>(elem->reference_object_id(), &vCornerCoords[0]);
715 if(fillElemSizeIntoVector)
719 AveragePositions<dim>(ElemMidPoint, vCornerCoords);
722 typename TGrid::template traits<TSide>::secure_container vSide;
723 grid.associated_elements_sorted(vSide, elem);
726 grid.begin_marking();
734 for(
size_t s = 0;
s < vSide.size(); ++
s){
737 SideNormal<dim>(elem->reference_object_id(), Normal,
s, &vCornerCoords[0]);
740 typename TGrid::template traits<TElem>::secure_container vElemOfSide;
741 grid.associated_elements(vElemOfSide, vSide[
s]);
744 if(vElemOfSide.size() == 0)
745 UG_THROW(
"Huh, why no element? Should be at least the considered elem itself");
751 if(vElemOfSide.size() == 1){
757 if(vSide[
s]->is_constrained()){
759 TContrainedSide* cSide =
dynamic_cast<TContrainedSide*
>(vSide[
s]);
760 TSide* constrainingSide =
dynamic_cast<TSide*
>(cSide->get_constraining_object());
762 typename TGrid::template traits<TElem>::secure_container vElemOfContrainingSide;
763 grid.associated_elements(vElemOfContrainingSide, constrainingSide);
764 if(vElemOfContrainingSide.size() != 2)
UG_THROW(
"Huh, should be 2 at constraining side");
766 for(
size_t nbr = 0; nbr < vElemOfContrainingSide.size(); ++nbr){
768 TElem* neighborElem = vElemOfContrainingSide[nbr];
769 if(
grid.template num_children<TElem,TElem>(neighborElem) > 0)
continue;
771 grid.mark(neighborElem);
775 AveragePositions<dim>(Distance, vNbrCornerCoords);
776 VecScaleAdd(Distance, 1.0, ElemMidPoint, -1.0, Distance);
779 vStencil[i].push_back( -cpl );
780 vStencil[i][0] += cpl;
782 std::vector<DoFIndex> ind;
783 if(spF->inner_dof_indices(neighborElem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
784 vIndex[i].push_back(ind[0][0]);
795 VecScaleAdd(Distance, 2.0, ElemMidPoint, -2.0, Distance);
798 vStencil[i].push_back( -cpl );
799 vStencil[i][0] += cpl;
801 std::vector<DoFIndex> ind;
802 if(spF->inner_dof_indices(elem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
803 vIndex[i].push_back(ind[0][0]);
810 else if(vSide[
s]->is_constraining()){
812 TContrainingSide* cSide =
dynamic_cast<TContrainingSide*
>(vSide[
s]);
813 const size_t numConstrained = cSide->template num_constrained<TSide>();
815 for(
size_t cs = 0; cs < numConstrained; ++cs){
817 TSide* constrainedSide = cSide->template constrained<TSide>(cs);
820 typename TGrid::template traits<TElem>::secure_container vElemOfContrainedSide;
821 grid.associated_elements(vElemOfContrainedSide, constrainedSide);
822 if(vElemOfContrainedSide.size() != 1)
UG_THROW(
"Huh, should be 1 at constrained side");
823 TElem* neighborElem = vElemOfContrainedSide[0];
824 grid.mark(neighborElem);
828 AveragePositions<dim>(Distance, vNbrCornerCoords);
829 VecScaleAdd(Distance, 1.0, ElemMidPoint, -1.0, Distance);
832 vStencil[i].push_back( -cpl );
833 vStencil[i][0] += cpl;
835 std::vector<DoFIndex> ind;
836 if(spF->inner_dof_indices(neighborElem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
837 vIndex[i].push_back(ind[0][0]);
847 if(vElemOfSide.size() != 2)
848 UG_THROW(
"Huh, why more than 2 elements of side?");
850 for(
size_t eos = 0; eos < vElemOfSide.size(); ++eos){
853 TElem* neighborElem = vElemOfSide[eos];
856 if(
grid.template num_children<TElem,TElem>(neighborElem) > 0)
857 UG_THROW(
"Huh, why not on top level?");
860 if(neighborElem == elem)
continue;
861 grid.mark(neighborElem);
865 AveragePositions<dim>(Distance, vNbrCornerCoords);
866 VecScaleAdd(Distance, 1.0, ElemMidPoint, -1.0, Distance);
869 vStencil[i].push_back( -cpl );
870 vStencil[i][0] += cpl;
872 std::vector<DoFIndex> ind;
873 if(spF->inner_dof_indices(neighborElem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
874 vIndex[i].push_back(ind[0][0]);
883 if(vertexWeight != 0.0){
885 for(
size_t s = 0;
s < vSide.size(); ++
s){
888 SideNormal<dim>(elem->reference_object_id(), Normal,
s, &vCornerCoords[0]);
891 typename TGrid::template traits<TElem>::secure_container vElemOfSide;
892 grid.associated_elements(vElemOfSide, vSide[
s]);
895 if(vElemOfSide.size() == 0)
896 UG_THROW(
"Huh, why no element? Should be at least the considered elem itself");
905 Vertex*
const* vVertex = vSide[
s]->vertices();
906 const size_t numVertex = vSide[
s]->num_vertices();
909 for(
size_t vrt = 0; vrt < numVertex; ++vrt)
911 std::vector<TElem*> vDiagNeighbors;
914 typename TGrid::template traits<TElem>::secure_container vVertexNeighbor;
915 grid.associated_elements(vVertexNeighbor, vVertex[vrt]);
916 for(
size_t eov = 0; eov < vVertexNeighbor.size(); ++eov)
918 TElem* neighborElem = vVertexNeighbor[eov];
919 if(
grid.is_marked(neighborElem))
continue;
920 if(
grid.template num_children<TElem,TElem>(neighborElem) > 0)
continue;
926 vDiagNeighbors.push_back(neighborElem);
930 if(
grid.template num_children<Vertex,Vertex>(vVertex[vrt]) > 0){
932 if(
grid.template num_children<Vertex,Vertex>(vVertex[vrt]) != 1)
933 UG_THROW(
"Huh, why more than one vertex child?")
935 Vertex* fineVrt =
grid.template get_child<Vertex,Vertex>(vVertex[vrt], 0);
937 typename TGrid::template traits<TElem>::secure_container vVertexNeighbor;
938 grid.associated_elements(vVertexNeighbor, fineVrt);
939 for(
size_t eov = 0; eov < vVertexNeighbor.size(); ++eov)
941 TElem* neighborElem = vVertexNeighbor[eov];
942 if(
grid.is_marked(neighborElem))
continue;
943 if(
grid.template num_children<TElem,TElem>(neighborElem) > 0)
continue;
949 vDiagNeighbors.push_back(neighborElem);
955 if(
grid.get_parent(vVertex[vrt]) != 0){
962 typename TGrid::template traits<TElem>::secure_container vVertexNeighbor;
963 grid.associated_elements(vVertexNeighbor, coarseVrt);
964 for(
size_t eov = 0; eov < vVertexNeighbor.size(); ++eov)
966 TElem* neighborElem = vVertexNeighbor[eov];
967 if(
grid.is_marked(neighborElem))
continue;
968 if(
grid.template num_children<TElem,TElem>(neighborElem) > 0)
continue;
974 vDiagNeighbors.push_back(neighborElem);
980 const size_t numDiagElem = vDiagNeighbors.size();
981 for(
size_t diag = 0; diag < numDiagElem; ++diag){
983 TElem* neighborElem = vDiagNeighbors[diag];
987 AveragePositions<dim>(Distance, vNbrCornerCoords);
988 VecScaleAdd(Distance, 1.0, ElemMidPoint, -1.0, Distance);
993 std::vector<DoFIndex> ind;
994 if(spF->inner_dof_indices(neighborElem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
995 const size_t j = ind[0][0];
998 for(; k < vIndex[i].size(); ++k){
999 if(vIndex[i][k] == j)
1002 if(k == vIndex[i].size())
1004 vIndex[i].push_back(j);
1005 vStencil[i].push_back(0.0);
1010 vStencil[i][k] -= cpl;
1011 vStencil[i][0] += cpl;
1023 static int call = 0; call++;
1037 std::vector< std::vector< number > >& vStencil,
1038 std::vector< std::vector<size_t> >& vIndex,
bool fillElemSizeIntoVector)
1042 static const int dim = TDomain::dim;
1043 typedef typename TDomain::grid_type TGrid;
1049 typedef typename TDomain::position_accessor_type TPositionAccessor;
1051 const size_t fct = 0;
1056 typename TDomain::position_accessor_type& aaPos = domain->position_accessor();
1063 iter = dd->begin<TElem>(SurfaceView::ALL);
1064 iterEnd = dd->end<TElem>(SurfaceView::ALL);
1067 const size_t numIndex = spF->num_dofs();
1068 vStencil.resize(numIndex);
1069 vIndex.resize(numIndex);
1073 std::vector<TElem*> vElem;
1074 std::vector<size_t> vNbrIndex;
1075 std::vector< MathVector<dim> > vDistance;
1091 for(;iter != iterEnd; ++iter)
1094 TElem* elem = *iter;
1102 const int numNeighborsRequired = 2*dim + (dim * (dim-1)) / 2;
1103 const int numSideNeighbors = std::pow(2,dim);
1104 if(vNbrIndex.size() < numNeighborsRequired || vDistance.size() < numNeighborsRequired)
1105 UG_THROW(
"Wrong number of neighbors detected: " << vNbrIndex.size());
1108 if(dim == 3)
UG_THROW(
"DamageFunctionUpdater: This is 2d only --- extend to 3d by looking for 3 additional neighbors");
1109 if(numNeighborsRequired != numSideNeighbors+1)
UG_THROW(
"DamageFunctionUpdater: Only 2d implemented")
1113 int closest = -1;
number closestDist = std::numeric_limits<number>::max();
1114 for(
int k = numSideNeighbors; k < (int)vDistance.size(); ++k)
1117 if(dist < closestDist){closest = k; closestDist = dist;}
1119 if(closest < 0)
UG_THROW(
"DamageFunctionUpdater: closest not detected.")
1121 vElem[numSideNeighbors] = vElem[closest];
1122 vNbrIndex[numSideNeighbors] = vNbrIndex[closest];
1123 vDistance[numSideNeighbors] = vDistance[closest];
1129 BlockInv.resize(numNeighborsRequired, numNeighborsRequired);
1131 for (
size_t j = 0; j < numNeighborsRequired; ++j)
1133 for (
int d = 0; d < dim; ++d)
1134 BlockInv(j,d) = vDistance[j][d];
1137 for (
int d1 = 0; d1 < dim-1; ++d1)
1138 for (
int d2 = d1+1; d2 < dim; ++d2)
1140 BlockInv(j,cnt++) = vDistance[j][d1] * vDistance[j][d2];
1143 for (
int d = 0; d < dim; ++d)
1144 BlockInv(j,cnt++) = 0.5 * vDistance[j][d] * vDistance[j][d];
1146 if(cnt != numNeighborsRequired)
1147 UG_THROW(
"Wrong number of equations")
1199 std::vector<DoFIndex> ind;
1200 if(spF->inner_dof_indices(elem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
1201 const size_t i = ind[0][0];
1203 vStencil[i].clear();
1204 vStencil[i].resize(numNeighborsRequired+1);
1205 vStencil[i][0] = 0.0;
1207 for (
size_t k = 0; k < numNeighborsRequired; ++k){
1208 vStencil[i][k+1] = 0.0;
1209 for (
int d = 0; d < dim; ++d){
1210 vStencil[i][k+1] += BlockInv( (numNeighborsRequired-dim)+d, k);
1211 vStencil[i][0] -= BlockInv( (numNeighborsRequired-dim)+d, k);
1216 vIndex[i].resize(numNeighborsRequired+1);
1218 for (
size_t k = 0; k < numNeighborsRequired; ++k){
1219 vIndex[i][k+1] = vNbrIndex[k];
1244 std::vector< std::vector< number > >& vStencil,
1245 std::vector< std::vector<size_t> >& vIndex,
bool fillElemSizeIntoVector)
1249 static const int dim = TDomain::dim;
1250 typedef typename TDomain::grid_type TGrid;
1256 typedef typename TDomain::position_accessor_type TPositionAccessor;
1258 const size_t fct = 0;
1263 typename TDomain::position_accessor_type& aaPos = domain->position_accessor();
1270 iter = dd->begin<TElem>(SurfaceView::ALL);
1271 iterEnd = dd->end<TElem>(SurfaceView::ALL);
1274 const size_t numIndex = spF->num_dofs();
1275 vStencil.resize(numIndex);
1276 vIndex.resize(numIndex);
1280 std::vector<TElem*> vElem;
1281 std::vector<size_t> vNbrIndex;
1282 std::vector< MathVector<dim> > vDistance;
1285 std::vector<number> W;
1288 for(;iter != iterEnd; ++iter)
1291 TElem* elem = *iter;
1299 const int numDerivs = 2*dim + (dim * (dim-1)) / 2;
1300 const int numNeighbors = vElem.size();
1301 if(vElem.size() < numDerivs || vNbrIndex.size() < numDerivs || vDistance.size() < numDerivs)
1302 UG_THROW(
"Wrong number of neighbors detected: #elems: " << vElem.size() <<
1303 ", #Index: " << vNbrIndex.size() <<
", #Distance: " << vDistance.size());
1310 W.resize(numNeighbors);
1311 for (
int i = 0; i < numNeighbors; ++i){
1318 X.resize(numNeighbors, numDerivs);
1320 for (
int j = 0; j < numNeighbors; ++j)
1322 for (
int d = 0; d < dim; ++d)
1323 X(j,d) = vDistance[j][d];
1326 for (
int d1 = 0; d1 < dim-1; ++d1)
1327 for (
int d2 = d1+1; d2 < dim; ++d2)
1329 X(j,cnt++) = vDistance[j][d1] * vDistance[j][d2];
1332 for (
int d = 0; d < dim; ++d)
1333 X(j,cnt++) = 0.5 * vDistance[j][d] * vDistance[j][d];
1335 if(cnt != numDerivs)
1336 UG_THROW(
"Wrong number of equations")
1340 for (
int i = 0; i < numNeighbors; ++i){
1341 for(
int j = 0; j < numDerivs; ++j){
1347 XTX.resize(numDerivs, numDerivs);
1348 for(
int i = 0; i < numDerivs; ++i){
1349 for(
int j = 0; j < i; ++j){
1351 for(
int k = 0; k < numNeighbors; ++k){
1352 XTX(i,j) += X(k,i) * X(k,j);
1354 XTX(j,i) = XTX(i,j);
1357 for(
int k = 0; k < numNeighbors; ++k){
1358 XTX(i,i) += X(k,i) * X(k,i);
1367 B.resize(numDerivs, numNeighbors);
1368 for(
int i = 0; i < numDerivs; ++i){
1369 for(
int j = 0; j < numNeighbors; ++j){
1371 for(
int k = 0; k < numDerivs; ++k){
1372 B(i,j) += XTX(i,k) * X(j,k);
1384 std::vector<DoFIndex> ind;
1385 if(spF->inner_dof_indices(elem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
1386 const size_t i = ind[0][0];
1388 vStencil[i].clear();
1389 vStencil[i].resize(numNeighbors+1);
1390 vStencil[i][0] = 0.0;
1392 for (
int k = 0; k < numNeighbors; ++k){
1393 vStencil[i][k+1] = 0.0;
1394 for (
int d = 0; d < dim; ++d){
1395 vStencil[i][k+1] += B( (numDerivs-dim)+d, k);
1396 vStencil[i][0] -= B( (numDerivs-dim)+d, k);
1401 vIndex[i].resize(numNeighbors+1);
1403 for (
int k = 0; k < numNeighbors; ++k){
1404 vIndex[i][k+1] = vNbrIndex[k];
1419 std::vector< std::vector< number > >& vStencil,
1420 std::vector< std::vector<size_t> >& vIndex,
bool fillElemSizeIntoVector =
false)
1424 static const int dim = TDomain::dim;
1425 typedef typename TDomain::grid_type TGrid;
1431 typedef typename TDomain::position_accessor_type TPositionAccessor;
1433 const size_t fct = 0;
1438 typename TDomain::position_accessor_type& aaPos = domain->position_accessor();
1445 iter = dd->begin<TElem>(SurfaceView::ALL);
1446 iterEnd = dd->end<TElem>(SurfaceView::ALL);
1449 const size_t numIndex = spF->num_dofs();
1450 vStencil.resize(numIndex);
1451 vIndex.resize(numIndex);
1455 std::vector<TElem*> vElem;
1456 std::vector<size_t> vNbrIndex;
1457 std::vector< MathVector<dim> > vDistance;
1460 std::vector<number> XTXr;
1463 for(;iter != iterEnd; ++iter)
1466 TElem* elem = *iter;
1474 const int numDerivs = 2*dim + (dim * (dim-1)) / 2;
1475 const int numNeighbors = vElem.size();
1476 if(vElem.size() < numDerivs || vNbrIndex.size() < numDerivs || vDistance.size() < numDerivs)
1477 UG_THROW(
"Wrong number of neighbors detected: #elems: " << vElem.size() <<
1478 ", #Index: " << vNbrIndex.size() <<
", #Distance: " << vDistance.size());
1485 X.resize(numNeighbors, numDerivs);
1487 for (
int j = 0; j < numNeighbors; ++j)
1489 for (
int d = 0; d < dim; ++d)
1490 X(j,d) = vDistance[j][d];
1493 for (
int d1 = 0; d1 < dim-1; ++d1)
1494 for (
int d2 = d1+1; d2 < dim; ++d2)
1496 X(j,cnt++) = vDistance[j][d1] * vDistance[j][d2];
1499 for (
int d = 0; d < dim; ++d)
1500 X(j,cnt++) = 0.5 * vDistance[j][d] * vDistance[j][d];
1502 if(cnt != numDerivs)
1503 UG_THROW(
"Wrong number of equations")
1507 XTX.resize(numDerivs, numDerivs);
1508 for(
int i = 0; i < numDerivs; ++i){
1509 for(
int j = 0; j < i; ++j){
1511 for(
int k = 0; k < numNeighbors; ++k){
1512 XTX(i,j) += X(k,i) * X(k,j);
1514 XTX(j,i) = XTX(i,j);
1517 for(
int k = 0; k < numNeighbors; ++k){
1518 XTX(i,i) += X(k,i) * X(k,i);
1531 std::vector<DoFIndex> ind;
1532 if(spF->inner_dof_indices(elem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
1533 const size_t i = ind[0][0];
1535 vStencil[i].clear();
1536 vStencil[i].resize(numNeighbors+1);
1537 vStencil[i][0] = 0.0;
1540 XTXr.resize(numNeighbors);
1541 for (
int j = 0; j < numNeighbors; ++j){
1544 for (
int d = 0; d < dim; ++d)
1545 XTXr[j] += XTX(j,(numDerivs-dim)+d);
1549 for (
int k = 0; k < numNeighbors; ++k){
1550 vStencil[i][k+1] = 0.0;
1551 for (
int j = 0; j < numNeighbors; ++j){
1552 vStencil[i][k+1] += X(k,j) * XTXr[j];
1554 vStencil[i][0] -= vStencil[i][k+1];
1558 vIndex[i].resize(numNeighbors+1);
1560 for (
int k = 0; k < numNeighbors; ++k){
1561 vIndex[i][k+1] = vNbrIndex[k];
1865 static int call = 0; call++;
1875 if(approxSpace != spDrivingForce->approx_space())
1876 UG_THROW(
"RelativeDensityUpdater<TDomain>::solve: expected same ApproximationSpace for f and psi0");
1879 if(m_ApproxSpaceRevision != approxSpace->revision())
1881 m_spElemSize = spChi->clone();
1882 m_spLaplaceChi = spChi->clone();
1883 m_spChiTrial = spChi->clone();
1886 UG_LOG (
"RelativeDensityUpdater: reinit laplacian using type '"<< m_discType <<
"'\n");
1890 case _PARTIAL_INTEGRATION_:
1893 case _TAYLOR_EXPANSION_:
1896 case _LEAST_SQUARES_:
1899 case _TAYLOR_DIRECT_:
1903 UG_THROW(
"RelativeDensityUpdater: internal error, "
1904 "unrecognized type number '"<<m_discType<<
"'.");
1908 m_ApproxSpaceRevision = approxSpace->revision();
1911 write_stencil_matrix_debug(spChi,
"STENCIL", call);
1920 number h2 = std::numeric_limits<number>::max();
1921 for(
size_t i = 0; i < m_vIndex.size(); ++i){
1922 const number vol = (*m_spElemSize)[i];
1923 h2 = std::min(h2, sqrt(dim) * std::pow(vol, 2.0/dim));
1926 const int n = std::floor(6*betaStar / (etaChiStar * h2)) + 1;
1928 const number dt_chi = dt / n;
1933 for(
int j = 0; j < n; ++j)
1939 number min_p_chi = std::numeric_limits<number>::max();
1940 number max_p_chi = std::numeric_limits<number>::min();
1942 number int_g_p = 0.0, int_g = 0.0;
1943 for(
size_t i = 0; i < m_vIndex.size(); ++i)
1945 const number chi = (*spChi)[i];
1946 const number vol = (*m_spElemSize)[i];
1947 const number p_chi = (*spDrivingForce)[i];
1948 (*m_spLaplaceChi)[i] = Lambda(i, spChi);
1950 const number g = (chi - chiMin) * (1.0 - chi);
1953 int_g_p += vol * g * p_chi;
1955 min_p_chi = std::min(min_p_chi, p_chi);
1956 max_p_chi = std::max(max_p_chi, p_chi);
1959 const number p_w = int_g_p / int_g;
1961 number beta = betaStar * p_w;
1962 const number eta_chi = etaChiStar * p_w;
1991 number Llow = (min_p_chi - eta_chi);
1992 number Lhigh = (max_p_chi + eta_chi);
2004 for(
size_t i = 0; i < m_vIndex.size(); ++i)
2006 const number chi = (*spChi)[i];
2007 const number p_chi = (*spDrivingForce)[i];
2008 const number laplaceChi = (*m_spLaplaceChi)[i];
2009 const number vol = (*m_spElemSize)[i];
2011 if(m_bEnforceLocalRequiredBeta){
2012 beta = std::max(2 * sqrt(dim) * std::pow(vol, 2.0/dim) * p_w, betaStar * p_w);
2015 number& chi_tr = (*m_spChiTrial)[i];
2018 chi_tr = chi + (dt_chi / eta_chi) * (p_chi - L_tr + beta * laplaceChi);
2021 if(std::isfinite(chi_tr) ==
false){
2023 UG_LOG(
" ############### \n");
2024 UG_LOG(
"chi_tr : " << chi_tr <<
"\n");
2025 UG_LOG(
"dt_chi : " << dt_chi <<
"\n");
2026 UG_LOG(
"eta_chi : " << eta_chi <<
"\n");
2027 UG_LOG(
"p_chi : " << p_chi <<
"\n");
2028 UG_LOG(
"lambda : " << L_tr <<
"\n");
2029 UG_LOG(
"beta : " << beta <<
"\n");
2030 UG_LOG(
"laplaceChi : " << laplaceChi <<
"\n");
2031 UG_LOG(
"p_w : " << p_w <<
"\n");
2032 UG_LOG(
" ############### \n");
2033 UG_THROW(
"Value for chi not finite, but: " << chi_tr);
2037 if(chi_tr > 1.0) chi_tr = 1.0;
2038 if(chi_tr < chiMin) chi_tr = chiMin;
2040 rho_tr += chi_tr * vol;
2044 rho_tr /= Vol_Omega;
2048 if(fabs(rho_tr - rho_target) < MassTol)
break;
2051 if(rho_tr > rho_target) Llow = L_tr;
2052 if(rho_tr < rho_target) Lhigh = L_tr;
2054 L_tr = (Lhigh + Llow)/2.0;
2059 for(
size_t i = 0; i < m_vIndex.size(); ++i)
2061 number& chi = (*spChi)[i];
2062 number& p_chi = (*spDrivingForce)[i];
2063 const number chi_tr = (*m_spChiTrial)[i];
2066 p_chi *= std::pow( (chi_tr / chi),
p-1);
2073 std::vector<number> vRes;
2075 vRes.push_back((
number)n);
2076 vRes.push_back((
number)numBisect);
2163 number lowerValueToCoarsen,
2165 number upperValueToCoarsen,
2166 number maxJumpDifferenceToNeighborsForCoarsen,
2167 number minJumpDifferenceToNeighborsForRefine,
2172 static const int dim = TDomain::dim;
2175 typedef typename TDomain::position_accessor_type position_accessor_type;
2184 if( minValueToRefine > maxValueToRefine )
UG_THROW(
"minValueToRefine > maxValueToRefine")
2185 if( lowerValueToCoarsen > minValueToRefine )
UG_THROW(
"lowerValueToCoarsen > minValueToRefine")
2186 if( upperValueToCoarsen < maxValueToRefine )
UG_THROW(
"upperValueToCoarsen < maxValueToRefine")
2195 int numMarkedRefine = 0, numMarkedCoarse = 0;
2198 std::vector<MathVector<dim> > vCornerCoords;
2201 std::vector<TElem*> vNeighbors;
2204 const_iterator iter = spChi->template begin<TElem>();
2205 const_iterator iterEnd = spChi->template end<TElem>();
2206 for(; iter != iterEnd; ++iter)
2209 TElem* elem = *iter;
2211 std::vector<DoFIndex> ind;
2212 if(spChi->inner_dof_indices(elem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
2219 bool neighborsHaveLargeJump =
false;
2220 bool neighborsHaveSmallJump =
true;
2221 for(
size_t i = 0; i < vNeighbors.size(); ++i){
2223 TElem* neighbor = vNeighbors[i];
2225 std::vector<DoFIndex> ind;
2226 if(spChi->inner_dof_indices(neighbor, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
2229 if(fabs(val - valNeighbor) > minJumpDifferenceToNeighborsForRefine)
2231 neighborsHaveLargeJump =
true;
2234 if(fabs(val - valNeighbor) > maxJumpDifferenceToNeighborsForCoarsen)
2236 neighborsHaveSmallJump =
false;
2242 if( (val >= minValueToRefine && val <= maxValueToRefine)
2243 || (neighborsHaveLargeJump) )
2246 if(spChi->dd()->multi_grid()->get_level(elem) < maxLevel)
2256 if( (val < lowerValueToCoarsen || val > upperValueToCoarsen)
2257 && neighborsHaveSmallJump )
2261 TElem* parent =
dynamic_cast<TElem*
>(spChi->dd()->multi_grid()->get_parent(elem));
2276 UG_LOG(
"MarkForAdaption_ValueRangeIndicator:\n")
2280 UG_LOG(
" >>> Marked on Proc "<<
pcl::ProcRank()<<
": refine: " << numMarkedRefine <<
", coarsen : " << numMarkedCoarse <<
"\n");
2282 int numMarkedRefineLocal = numMarkedRefine, numMarkedCoarseLocal = numMarkedCoarse;
2288 UG_LOG(
" >>> Marked refine: " << numMarkedRefine <<
", coarsen: " << numMarkedCoarse <<
"\n" );
2524 static const int dim = TDomain::dim;
2533 number max_fPsi0 = std::numeric_limits<number>::min();
2534 number min_fPsi0 = std::numeric_limits<number>::max();
2537 number max_l2_fPsi0 = std::numeric_limits<number>::min();
2538 number min_l2_fPsi0 = std::numeric_limits<number>::max();
2539 number sum_l2_fPsi0 = 0.0;
2541 number max_l_fPsi0 = std::numeric_limits<number>::min();
2542 number min_l_fPsi0 = std::numeric_limits<number>::max();
2543 number sum_l_fPsi0 = 0.0;
2546 const_iterator iter = spF->template begin<TElem>();
2547 const_iterator iterEnd = spF->template end<TElem>();
2551 for(; iter != iterEnd; ++iter)
2554 TElem* elem = *iter; ++numElem;
2556 std::vector<DoFIndex> ind;
2557 if(spF->inner_dof_indices(elem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
2562 max_fPsi0 = std::max(max_fPsi0, f*psi0);
2563 min_fPsi0 = std::min(min_fPsi0, f*psi0);
2564 sum_fPsi0 += f*psi0;
2568 max_l2_fPsi0 = std::max(max_l2_fPsi0, l2*f*psi0);
2569 min_l2_fPsi0 = std::min(min_l2_fPsi0, l2*f*psi0);
2570 sum_l2_fPsi0 += l2*f*psi0;
2572 const number l = std::sqrt(l2);
2574 max_l_fPsi0 = std::max(max_l_fPsi0, l*f*psi0);
2575 min_l_fPsi0 = std::min(min_l_fPsi0, l*f*psi0);
2576 sum_l_fPsi0 += l*f*psi0;
2578 number avg_fPsi0 = sum_fPsi0 / numElem;
2579 number avg_l2_fPsi0 = sum_l2_fPsi0 / numElem;
2580 number avg_l_fPsi0 = sum_l_fPsi0 / numElem;
2583 std::vector<number> vRes;
2584 vRes.push_back(max_fPsi0);
2585 vRes.push_back(min_fPsi0);
2586 vRes.push_back(avg_fPsi0);
2588 vRes.push_back(max_l2_fPsi0);
2589 vRes.push_back(min_l2_fPsi0);
2590 vRes.push_back(avg_l2_fPsi0);
2592 vRes.push_back(max_l_fPsi0);
2593 vRes.push_back(min_l_fPsi0);
2594 vRes.push_back(avg_l_fPsi0);