33 #ifndef __SMALL_STRAIN_MECHANICS__DAMAGE_IMPL_H_
34 #define __SMALL_STRAIN_MECHANICS__DAMAGE_IMPL_H_
40 namespace SmallStrainMechanics{
47 vCenter = vCornerCoords[0];
48 for(
size_t j = 1; j < vCornerCoords.size(); ++j)
50 vCenter += vCornerCoords[j];
52 vCenter *= 1./(
number)( vCornerCoords.size());
61 template <
typename TDomain>
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){
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());
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);
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){
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)
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);
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){
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);
295 template <
typename TDomain>
299 std::vector<size_t>& vIndex,
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){
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());
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);
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)
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);
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){
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());
620 template <
typename TDomain>
623 std::vector< std::vector< number > >& vStencil,
624 std::vector< std::vector<size_t> >& vIndex,
625 int quadRuleType,
bool fillElemSizeIntoVector)
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")
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]);
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());
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);
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]);
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;
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);
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){
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++;
1034 template <
typename TDomain>
1037 std::vector< std::vector< number > >& vStencil,
1038 std::vector< std::vector<size_t> >& vIndex,
bool fillElemSizeIntoVector)
1051 const size_t fct = 0;
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];
1241 template <
typename TDomain>
1244 std::vector< std::vector< number > >& vStencil,
1245 std::vector< std::vector<size_t> >& vIndex,
bool fillElemSizeIntoVector)
1258 const size_t fct = 0;
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];
1416 template <
typename TDomain>
1419 std::vector< std::vector< number > >& vStencil,
1420 std::vector< std::vector<size_t> >& vIndex,
bool fillElemSizeIntoVector =
false)
1433 const size_t fct = 0;
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];
1578 template <
typename TDomain>
1583 std::transform(
type.begin(),
type.end(),
type.begin(), ::tolower);
1585 UG_LOG (
"DamageFunctionUpdater: setting laplacian type to '"<< theType <<
"' \n");
1586 if(
type ==
"least-squares") {m_discType = _LEAST_SQUARES_;
return;}
1587 if(
type ==
"taylor-expansion") {m_discType = _TAYLOR_EXPANSION_;
return;}
1588 if(
type ==
"partial-integration") {m_discType = _PARTIAL_INTEGRATION_;
return;}
1589 if(
type ==
"taylor-direct") {m_discType = _TAYLOR_DIRECT_;
return;}
1591 UG_THROW(
"DamageFunctionUpdater: unrecognized type '"<<
type<<
"'.");
1595 template <
typename TDomain>
1600 const number eps,
const int maxIter,
const number dampNewton)
1608 static int call = 0; call++;
1612 if(approxSpace != spPsi0->approx_space())
1613 UG_THROW(
"DamageFunctionUpdater<TDomain>::solve: expected same ApproximationSpace for f and psi0");
1616 if(m_ApproxSpaceRevision != approxSpace->revision())
1618 UG_LOG (
"DamageFunctionUpdater: reinit laplacian using type '"<< m_discType <<
"'\n");
1622 case _PARTIAL_INTEGRATION_:
1625 case _TAYLOR_EXPANSION_:
1628 case _LEAST_SQUARES_:
1631 case _TAYLOR_DIRECT_:
1635 UG_THROW(
"DamageFunctionUpdater: internal error, "
1636 "unrecognized type number '"<<m_discType<<
"'.");
1640 m_ApproxSpaceRevision = approxSpace->revision();
1642 write_stencil_matrix_debug(spF,
"STENCIL", call);
1670 number maxPhi = std::numeric_limits<number>::max();
1673 while(maxPhi > eps && (iterCnt++ <= maxIter) )
1678 for(
size_t i = 0; i < m_vIndex.size(); ++i)
1679 (*spLambdaOld)[i] = Lambda(i, spF);
1685 for(
size_t i = 0; i < m_vIndex.size(); ++i)
1687 const number lambda = (*spLambdaOld)[i];
1688 const number& psi0 = (*spPsi0)[i];
1691 number phi = f * ( psi0 - beta * lambda) - r;
1708 f = f - dampNewton * (phi / (psi0 - beta * (lambda + f * DLambda(i)) ));
1718 if(std::isfinite(f) ==
false){
1720 UG_LOG(
" ############### \n");
1721 UG_LOG(
"f : " << f <<
"\n");
1722 UG_LOG(
"psi0 : " << psi0 <<
"\n");
1723 UG_LOG(
"lambda: " << lambda <<
"\n");
1724 UG_LOG(
"DLambda: " << DLambda(i) <<
"\n");
1725 UG_LOG(
"beta : " << beta <<
"\n");
1726 UG_LOG(
"r : " << r <<
"\n");
1727 UG_LOG(
"phi : " << phi <<
"\n");
1728 UG_LOG(
" ############### \n");
1729 UG_THROW(
"Value for f not finite, but: " << f);
1734 maxPhi = std::max(maxPhi, phi);
1748 m_lastNumIters = iterCnt;
1750 if(iterCnt >= maxIter){
1752 UG_LOG(
"DamageFunctionUpdater: no convergence after " << iterCnt <<
" iterations");
1757 UG_LOG (
"DamageFunctionUpdater: maxPhi: " << maxPhi <<
" after " <<iterCnt <<
" iterations\n");
1765 template <
typename TDomain>
1769 m_spDebugWriter = spDebugWriter;
1772 template <
typename TDomain>
1777 if(m_spDebugWriter.invalid())
return;
1781 std::stringstream ss;
1782 ss <<
"InDamageUpdate_" << name ;
1783 ss <<
"_call" << std::setfill(
'0') << std::setw(3) << call;
1784 if (iter >= 0) ss <<
"_iter" << std::setfill(
'0') << std::setw(3) << iter;
1788 m_spDebugWriter->set_grid_level(gl);
1789 m_spDebugWriter->write_vector(*spGF, ss.str().c_str());
1792 template <
typename TDomain>
1796 std::string name,
int call)
1798 if(m_spDebugWriter.invalid())
return;
1802 int numDoFs = spGF->num_dofs();
1803 std::stringstream ss;
1804 ss <<
"InDamageUpdate_" << name ;
1805 ss <<
"_call" << std::setfill(
'0') << std::setw(3) << call;
1812 A.resize_and_clear(numDoFs,numDoFs);
1814 for(
size_t i = 0; i < m_vStencil.size(); ++i){
1815 for(
size_t k = 0; k < m_vStencil[i].size(); ++k){
1816 const int j = m_vIndex[i][k];
1818 A(i,j) = m_vStencil[i][k];
1823 m_spDebugWriter->set_grid_level(gl);
1824 m_spDebugWriter->write_matrix(A, ss.str().c_str());
1838 template <
typename TDomain>
1843 std::transform(
type.begin(),
type.end(),
type.begin(), ::tolower);
1845 UG_LOG (
"DamageFunctionUpdater: setting laplacian type to '"<< theType <<
"' \n");
1846 if(
type ==
"least-squares") {m_discType = _LEAST_SQUARES_;
return;}
1847 if(
type ==
"taylor-expansion") {m_discType = _TAYLOR_EXPANSION_;
return;}
1848 if(
type ==
"partial-integration") {m_discType = _PARTIAL_INTEGRATION_;
return;}
1849 if(
type ==
"taylor-direct") {m_discType = _TAYLOR_DIRECT_;
return;}
1851 UG_THROW(
"DamageFunctionUpdater: unrecognized type '"<<
type<<
"'.");
1856 template <
typename TDomain>
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);
2085 template <
typename TDomain>
2089 m_spDebugWriter = spDebugWriter;
2092 template <
typename TDomain>
2097 if(m_spDebugWriter.invalid())
return;
2101 std::stringstream ss;
2102 ss <<
"InDensityUpdate_" << name ;
2103 ss <<
"_call" << std::setfill(
'0') << std::setw(3) << call;
2104 if (iter >= 0) ss <<
"_iter" << std::setfill(
'0') << std::setw(3) << iter;
2108 m_spDebugWriter->set_grid_level(gl);
2109 m_spDebugWriter->write_vector(*spGF, ss.str().c_str());
2112 template <
typename TDomain>
2116 std::string name,
int call)
2118 if(m_spDebugWriter.invalid())
return;
2122 int numDoFs = spGF->num_dofs();
2123 std::stringstream ss;
2124 ss <<
"InDensityUpdate_" << name ;
2125 ss <<
"_call" << std::setfill(
'0') << std::setw(3) << call;
2132 A.resize_and_clear(numDoFs,numDoFs);
2134 for(
size_t i = 0; i < m_vStencil.size(); ++i){
2135 for(
size_t k = 0; k < m_vStencil[i].size(); ++k){
2136 const int j = m_vIndex[i][k];
2138 A(i,j) = m_vStencil[i][k];
2143 m_spDebugWriter->set_grid_level(gl);
2144 m_spDebugWriter->write_matrix(A, ss.str().c_str());
2159 template<
typename TDomain>
2163 number lowerValueToCoarsen,
2165 number upperValueToCoarsen,
2166 number maxJumpDifferenceToNeighborsForCoarsen,
2167 number minJumpDifferenceToNeighborsForRefine,
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" );
2292 template<
typename TDomain>
2299 const std::vector<number>& vRadius)
2315 if( (minValueToRefine < maxValueToCoarsen) )
2316 UG_THROW(
"Coarsen threshold must be smaller than refine threshold")
2318 if( !(vRadius.size() == vCenter.size()) )
2319 UG_THROW(
"Num radius and center must match")
2327 std::vector<number> vRadiusSq;
2328 for(
size_t i = 0; i < vRadius.size(); ++i)
2329 vRadiusSq.push_back( vRadius[i] * vRadius[i]);
2331 std::vector<MathVector<dim> > vCircleCenter;
2332 for(
size_t i = 0; i < vCenter.size(); ++i)
2333 vCircleCenter.push_back( *(vCenter[i]));
2337 int numMarkedRefine = 0, numMarkedCoarse = 0;
2340 std::vector<MathVector<dim> > vCornerCoords;
2344 const_iterator iter = spF->template begin<TElem>();
2345 const_iterator iterEnd = spF->template end<TElem>();
2346 for(; iter != iterEnd; ++iter)
2349 TElem* elem = *iter;
2351 std::vector<DoFIndex> ind;
2352 if(spF->inner_dof_indices(elem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
2356 bool bInCircle =
false;
2357 if(!vRadiusSq.empty()){
2359 AveragePositions<dim>(ElemCenter, vCornerCoords);
2361 for(
size_t i = 0; i < vRadiusSq.size(); ++i){
2362 if(
VecDistanceSq(vCircleCenter[i], ElemCenter) <= vRadiusSq[i]){
2369 if( val > minValueToRefine || bInCircle)
2371 if(spF->dd()->multi_grid()->get_level(elem) < maxLevel)
2381 if( val < maxValueToCoarsen)
2396 UG_LOG(
" >>> Marked on Proc "<<
pcl::ProcRank()<<
": refine: " << numMarkedRefine <<
", coarsen : " << numMarkedCoarse <<
"\n");
2398 int numMarkedRefineLocal = numMarkedRefine, numMarkedCoarseLocal = numMarkedCoarse;
2404 UG_LOG(
" >>> Marked refine: " << numMarkedRefine <<
", coarsen: " << numMarkedCoarse <<
"\n" );
2409 template<
typename TDomain>
2428 number maxValue = std::numeric_limits<number>::min();
2429 number minValue = std::numeric_limits<number>::max();
2433 const size_t numElem = spF->size();
2434 for(
size_t i = 0; i < numElem; ++i){
2435 const number val = (*spF)[i] * (*spPsi0)[i];
2437 maxValue = std::max(maxValue, val);
2438 minValue = std::min(minValue, val);
2441 number avgValue = sumValue / numElem;
2444 UG_LOG(
" +++ numElem: " << numElem <<
"\n");
2445 UG_LOG(
" +++ maxValue: " << maxValue <<
"\n");
2446 UG_LOG(
" +++ minValue: " << minValue <<
"\n");
2447 UG_LOG(
" +++ avgValue: " << avgValue <<
"\n");
2454 number minValueToRefine = std::min( refineFrac * maxValue, avgRefineFactor * avgValue);
2455 number maxValueToCoarsen = std::max( (1 + coarseFrac) * minValue, avgCoarsenFactor * avgValue);
2457 UG_LOG(
" +++ minValueToRefine: " << minValueToRefine <<
"\n");
2458 UG_LOG(
" +++ maxValueToCoarsen: " << maxValueToCoarsen <<
"\n");
2465 int numMarkedRefine = 0, numMarkedCoarse = 0;
2467 const_iterator iter = spF->template begin<TElem>();
2468 const_iterator iterEnd = spF->template end<TElem>();
2471 for(; iter != iterEnd; ++iter)
2474 TElem* elem = *iter;
2476 std::vector<DoFIndex> ind;
2477 if(spF->inner_dof_indices(elem, fct, ind) != 1)
UG_THROW(
"Wrong number dofs");
2481 if( val >= minValueToRefine)
2482 if(spF->dd()->multi_grid()->get_level(elem) < maxLevel)
2489 if( val <= maxValueToCoarsen)
2504 UG_LOG(
" +++ Marked for refinement on Proc "<<
pcl::ProcRank()<<
": " << numMarkedRefine <<
" Elements.\n");
2505 UG_LOG(
" +++ Marked for coarsening on Proc "<<
pcl::ProcRank()<<
": " << numMarkedCoarse <<
" Elements.\n");
2507 int numMarkedRefineLocal = numMarkedRefine, numMarkedCoarseLocal = numMarkedCoarse;
2513 UG_LOG(
" +++ Marked for refinement: " << numMarkedRefine <<
" Elements.\n");
2514 UG_LOG(
" +++ Marked for coarsening: " << numMarkedCoarse <<
" Elements.\n");
2518 template<
typename TDomain>
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);
2601 template<
typename TDomain>
2606 if(spF->size() != spPsi0->size() || spF->size() != spFPsi0->size())
2607 UG_THROW(
"HadamardProd: Size mismatch");
2609 for(
size_t i = 0; i < spF->size(); ++i){
2610 (*spFPsi0)[i] = (*spF)[i] * (*spPsi0)[i];
2617 template<
typename TDomain>
2630 const_iterator iter = spF->template begin<TElem>();
2631 const_iterator iterEnd = spF->template end<TElem>();
2635 number min = std::numeric_limits<number>::max();
2636 for(; iter != iterEnd; ++iter){
2638 max = std::max(max, size);
2639 min = std::min(min, size);
2649 std::vector<number> vRes;
2651 vRes.push_back( std::sqrt(min) );
2652 vRes.push_back( std::sqrt(max) );
parameterString p
Definition: Biogas.lua:1
size_t allreduce(const size_t &t, pcl::ReduceOperation op) const
void mark(const TIterator &iterBegin, const TIterator &iterEnd, RefinementMark refMark=RM_REFINE)
void write_debug(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spGF, std::string name, int call, int iter)
Definition: damage_impl.h:1774
void set_debug(SmartPtr< GridFunctionDebugWriter< TDomain, CPUAlgebra > > spDebugWriter)
Definition: damage_impl.h:1767
bool solve(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spF, SmartPtr< GridFunction< TDomain, CPUAlgebra > > spPsi0, const number beta, const number r, const number eps, const int maxIter, const number dampNewton)
Definition: damage_impl.h:1597
void set_disc_type(const std::string &type)
Definition: damage_impl.h:1580
void write_stencil_matrix_debug(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spGF, std::string name, int call)
Definition: damage_impl.h:1794
void write_debug(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spGF, std::string name, int call, int iter)
Definition: damage_impl.h:2094
void write_stencil_matrix_debug(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spGF, std::string name, int call)
Definition: damage_impl.h:2114
std::vector< number > solve(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spChi, SmartPtr< GridFunction< TDomain, CPUAlgebra > > spDrivingForce, const number betaStar, const number etaChiStar, const number chiMin, const number dt, const int p, const number rho_target, const number MassTol)
Definition: damage_impl.h:1858
void set_debug(SmartPtr< GridFunctionDebugWriter< TDomain, CPUAlgebra > > spDebugWriter)
Definition: damage_impl.h:2087
void set_disc_type(const std::string &type)
Definition: damage_impl.h:1840
Grid::VertexAttachmentAccessor< position_attachment_type > position_accessor_type
number ElementDiameterSq(const TElem &elem, TDomain &domain)
void CollectCornerCoordinates(int base_object_id, std::vector< typename TDomain::position_type > &vCornerCoordsOut, GridObject &elem, const TDomain &domain, bool clearContainer)
bool Invert(DenseMatrix< FixedArray2< double, 1, 1 > > &mat)
UG_API std::string TrimString(const std::string &str)
void ProjectPointToPlane(vector_t &vOut, const vector_t &v, const vector_t &p, const vector_t &n)
vector_t::value_type VecTwoNormSq(const vector_t &v)
vector_t::value_type VecTwoNorm(const vector_t &v)
vector_t::value_type VecDot(const vector_t &v1, const vector_t &v2)
void InitLaplacian_PartialIntegration(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spF, std::vector< std::vector< number > > &vStencil, std::vector< std::vector< size_t > > &vIndex, int quadRuleType, bool fillElemSizeIntoVector=false)
Definition: damage_impl.h:621
void MarkDamage(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spF, SmartPtr< GridFunction< TDomain, CPUAlgebra > > spPsi0, IRefiner &refiner, number minValueToRefine, number maxValueToCoarsen, int maxLevel, const std::vector< MathVector< TDomain::dim, number > * > &vCenter, const std::vector< number > &vRadius)
Definition: damage_impl.h:2293
void MarkForAdaption_ValueRangeIndicator(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spChi, IRefiner &refiner, number lowerValueToCoarsen, number minValueToRefine, number maxValueToRefine, number upperValueToCoarsen, number maxJumpDifferenceToNeighborsForCoarsen, number minJumpDifferenceToNeighborsForRefine, int maxLevel)
Definition: damage_impl.h:2160
void AveragePositions(MathVector< dim > &vCenter, const std::vector< MathVector< dim > > &vCornerCoords)
Definition: damage_impl.h:44
void InitLaplacian_LeastSquares(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spF, std::vector< std::vector< number > > &vStencil, std::vector< std::vector< size_t > > &vIndex, bool fillElemSizeIntoVector=false)
Definition: damage_impl.h:1242
void HadamardProd(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spFPsi0, ConstSmartPtr< GridFunction< TDomain, CPUAlgebra > > spF, ConstSmartPtr< GridFunction< TDomain, CPUAlgebra > > spPsi0)
Definition: damage_impl.h:2602
void CollectStencilNeighbors_NeumannZeroBND_IndexAndDistance(std::vector< typename grid_dim_traits< TDomain::dim >::element_type * > &vElem, std::vector< size_t > &vIndex, std::vector< MathVector< TDomain::dim > > &vDistance, typename grid_dim_traits< TDomain::dim >::element_type *elem, typename TDomain::grid_type &grid, typename TDomain::position_accessor_type &aaPos, SmartPtr< GridFunction< TDomain, CPUAlgebra > > spF, bool fillElemSizeIntoVector=false)
Definition: damage_impl.h:297
std::vector< number > MinMaxElementDiameter(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spF)
Definition: damage_impl.h:2618
void CollectSurfaceNeighbors(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spF, typename grid_dim_traits< TDomain::dim >::element_type *elem, std::vector< typename grid_dim_traits< TDomain::dim >::element_type * > &vNeighbors)
Definition: damage_impl.h:62
void InitLaplacian_TaylorExpansion(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spF, std::vector< std::vector< number > > &vStencil, std::vector< std::vector< size_t > > &vIndex, bool fillElemSizeIntoVector=false)
Definition: damage_impl.h:1035
void MarkDamage_OLD_AND_DEPRECATED(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spF, SmartPtr< GridFunction< TDomain, CPUAlgebra > > spPsi0, IRefiner &refiner, number refineFrac, number coarseFrac, number avgRefineFactor, number avgCoarsenFactor, int maxLevel)
Definition: damage_impl.h:2410
void InitLaplacian_TaylorDirect(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spF, std::vector< std::vector< number > > &vStencil, std::vector< std::vector< size_t > > &vIndex, bool fillElemSizeIntoVector=false)
Definition: damage_impl.h:1417
std::vector< number > DamageStatistic(SmartPtr< GridFunction< TDomain, CPUAlgebra > > spF, SmartPtr< GridFunction< TDomain, CPUAlgebra > > spPsi0)
Definition: damage_impl.h:2519
const number & DoFRef(const TMatrix &mat, const DoFIndex &iInd, const DoFIndex &jInd)
TVector::value_type VecDistanceSq(const TVector &v1, const TVector &v2, const TMatrix &M)
void VecScaleAdd(double &dest, double alpha1, const double &v1, double alpha2, const double &v2)
#define PROFILE_FUNC_GROUP(groups)
#define PROFILE_BEGIN_GROUP(name, groups)
SurfaceView::traits< TElem >::const_iterator const_iterator
PointerConstArray< TElem * > secure_container