307 std::vector<MathVector<dim> > interPoints;
308 size_t nOfPoints=co.size();
309 interPoints.resize(elementnoc);
310 std::vector<number> distToBaseP(nOfPoints);
311 std::vector<int> sortedList(nOfPoints);
313 size_t interpointssize = 0;
315 for (
size_t i=0;i<elementnoc;i++){
317 interPoints[interpointssize]=co[i];
321 for (
size_t j=i+1;j<elementnoc;j++){
322 if (phi[i]*phi[j]<0){
323 interPoints[interpointssize]=co[i];
330 for (
size_t i=0;i<nOfPoints;i++){
335 distToBaseP.resize(nOfPoints);
336 sortedList.resize(nOfPoints);
338 size_t criticalnofinterp;
339 if (order==2) criticalnofinterp=5;
340 if (order==3) criticalnofinterp=7;
341 size_t nrOfInterPoints=0;
342 std::vector<number> mat;
343 size_t vlength=(size_t)round(0.5*(order+1)*(order+2));
344 mat.resize(vlength*vlength);
345 std::vector<number> interphi;
346 std::vector<number> coeffs;
347 interphi.resize(vlength);
348 coeffs.resize(vlength);
349 for (
size_t i=criticalnofinterp*(vlength-1);i<vlength*vlength;i++){
350 mat[i] = (
number)(0.8*i*i-0.4*i)/(i+1)+i*i-0.5+sin(0.3*i)+cos(0.75*i)+i*i*i-exp(0.1*i);
354 for (
size_t j=0;j<nOfPoints;j++){
355 size_t i=sortedList[j];
357 for (
size_t ii=0;ii<=order;ii++){
358 for (
size_t k=0;k<=ii;k++){
360 mat[matindex]=std::pow((
number)co[i][0],(
int)(ii-k))*std::pow((
number)co[i][1],(
int)k);
364 interphi[nrOfInterPoints]=phi[i];
370 if (j>=criticalnofinterp){
372 if (
solveLS(coeffs,mat,interphi)==
false){
379 if (nrOfInterPoints==vlength)
break;
381 if (nrOfInterPoints<vlength){
382 UG_LOG(
"warning: not enough interpolations points for desired order "<< order <<
" (found " << nrOfInterPoints <<
", needed " << vlength <<
") Reduce order.\n");
383 if (order==1)
return false;
384 if (computeElementCurvature2d(kappa,elementnoc,co,phi,order-1)==
true)
return true;
else return false;
386 number dxphi,dyphi,dxxphi,dxyphi,dyyphi;
392 dxphi=coeffs[1]+2*coeffs[3]*elemBasePoint[0]+coeffs[4]*elemBasePoint[1];
393 dyphi=coeffs[2]+coeffs[4]*elemBasePoint[0]+2*coeffs[5]*elemBasePoint[1];
396 dxphi=coeffs[1]+2*coeffs[3]*elemBasePoint[0]+coeffs[4]*elemBasePoint[1]+3*coeffs[6]*elemBasePoint[0]*elemBasePoint[0]+2*coeffs[7]*elemBasePoint[0]*elemBasePoint[1]+coeffs[8]*elemBasePoint[1]*elemBasePoint[1];
397 dyphi=coeffs[2]+coeffs[4]*elemBasePoint[0]+2*coeffs[5]*elemBasePoint[1]+coeffs[7]*elemBasePoint[0]*elemBasePoint[0]+2*coeffs[8]*elemBasePoint[0]*elemBasePoint[1]+3*coeffs[9]*elemBasePoint[1]*elemBasePoint[1];
401 number gradnorm=sqrt(dxphi*dxphi+dyphi*dyphi);
404 number coelemBasePoint[dim];
406 coelemBasePoint[0] = elemBasePoint[0] + 0.5*hh*dxphi/gradnorm;
407 coelemBasePoint[1] = elemBasePoint[1] + 0.5*hh*dyphi/gradnorm;
411 size_t nrofiterations=0;
412 for (;nrofiterations<50;nrofiterations++){
413 number b = coelemBasePoint[0]-elemBasePoint[0];
414 number d = coelemBasePoint[1]-elemBasePoint[1];
415 sol[0] = elemBasePoint[0]+itgamma*(coelemBasePoint[0]-elemBasePoint[0]);
416 sol[1] = elemBasePoint[1]+itgamma*(coelemBasePoint[1]-elemBasePoint[1]);
418 phival = coeffs[0]+coeffs[1]*sol[0]+coeffs[2]*sol[1]+coeffs[3]*sol[0]*sol[0]+coeffs[4]*sol[0]*sol[1]+coeffs[5]*sol[1]*sol[1];
420 phival = coeffs[0]+coeffs[1]*sol[0]+coeffs[2]*sol[1]+coeffs[3]*sol[0]*sol[0]+coeffs[4]*sol[0]*sol[1]+coeffs[5]*sol[1]*sol[1]
421 +coeffs[6]*sol[0]*sol[0]*sol[0]+coeffs[7]*sol[0]*sol[0]*sol[1]+coeffs[8]*sol[0]*sol[1]*sol[1]+coeffs[9]*sol[1]*sol[1]*sol[1];
422 if (std::abs(phival)<1e-12)
break;
423 phigamma = coeffs[1]*b+coeffs[2]*d+2*coeffs[3]*sol[0]*b+coeffs[4]*b*sol[1]+coeffs[4]*sol[0]*d+2*coeffs[5]*sol[1]*d+3*coeffs[6]*sol[0]*sol[0]*b
424 +2*coeffs[7]*sol[0]*sol[1]*b+coeffs[7]*sol[0]*sol[0]*d+coeffs[8]*b*sol[1]*sol[1]+2*coeffs[8]*sol[0]*sol[1]*d+3*coeffs[9]*sol[1]*sol[1]*d;
425 itgamma -= phival/phigamma;
427 if (nrofiterations==80){
428 UG_THROW(
"Diverging Newton method in curvature computation (error=" << phival <<
")\n");
432 dxphi=coeffs[1]+2*coeffs[3]*sol[0]+coeffs[4]*sol[1];
433 dyphi=coeffs[2]+coeffs[4]*sol[0]+2*coeffs[5]*sol[1];
439 dxphi=coeffs[1]+2*coeffs[3]*sol[0]+coeffs[4]*sol[1]+3*coeffs[6]*sol[0]*sol[0]+2*coeffs[7]*sol[0]*sol[1]+coeffs[8]*sol[1]*sol[1];
440 dyphi=coeffs[2]+coeffs[4]*sol[0]+2*coeffs[5]*sol[1]+coeffs[7]*sol[0]*sol[0]+2*coeffs[8]*sol[0]*sol[1]+3*coeffs[9]*sol[1]*sol[1];
441 dxxphi=2*coeffs[3]+6*coeffs[6]*sol[0]+2*coeffs[7]*sol[1];
442 dxyphi=coeffs[4]+2*coeffs[7]*sol[0]+2*coeffs[8]*sol[1];
443 dyyphi=2*coeffs[5]+2*coeffs[8]*sol[0]+6*coeffs[9]*sol[1];
445 number t = sqrt(dxphi*dxphi+dyphi*dyphi);
446 kappa = - (dyyphi * dxphi * dxphi - 2 * dxyphi * dxphi * dyphi + dxxphi * dyphi * dyphi) / (t * t * t);
458 if (order<2)
return false;
459 std::vector<MathVector<dim> > interPoints;
460 size_t nOfPoints=co.size();
461 interPoints.resize(elementnoc);
462 std::vector<number> distToBaseP(nOfPoints);
463 std::vector<int> sortedList(nOfPoints);
465 size_t interpointssize = 0;
467 for (
size_t i=0;i<elementnoc;i++){
469 interPoints[interpointssize]=co[i];
473 for (
size_t j=i+1;j<elementnoc;j++){
474 if (phi[i]*phi[j]<0){
475 interPoints[interpointssize]=co[i];
482 for (
size_t i=0;i<nOfPoints;i++){
487 distToBaseP.resize(nOfPoints);
488 sortedList.resize(nOfPoints);
491 size_t vlength=(size_t)round(0.5*(order+1)*(order+2));
492 size_t nrOfInterPoints = round(vlength*nodefactor);
493 size_t totalNrOfInterpoints = co.size();
494 if (totalNrOfInterpoints<nrOfInterPoints){
495 UG_LOG(
"Warning: not enough nodes for desired order " << order <<
" and least squares factor " << nodefactor <<
". Needed " << nrOfInterPoints <<
" nodes, given " << totalNrOfInterpoints <<
" nodes. Reduce order to " << order-1 <<
".\n");
496 return computeElementCurvature2d2(kappa,elementnoc,co,phi,order-1,nodefactor);
498 std::vector<number> interM(vlength*nrOfInterPoints);
499 std::vector<number> coeffs(vlength);
500 std::vector<number> interRhs(nrOfInterPoints);
502 for (
size_t j=0;j<nrOfInterPoints;j++){
503 size_t i=sortedList[j];
505 interRhs[j] = phi[i];
507 for (
size_t ii=0;ii<=order;ii++){
508 for (
size_t k=0;k<=ii;k++){
509 interM[matindex]=std::pow((
number)co[i][0],(
int)(ii-k))*std::pow((
number)co[i][1],(
int)k);
515 UG_LOG(
"Least squares problem had no regular solution. Reduce order to " << order-1 <<
".\n");
524 return computeElementCurvature2d2(kappa,elementnoc,co,phi,order-1,nodefactor);
526 number dxphi,dyphi,dxxphi,dxyphi,dyyphi;
528 dxphi=coeffs[1]+2*coeffs[3]*elemBasePoint[0]+coeffs[4]*elemBasePoint[1];
529 dyphi=coeffs[2]+coeffs[4]*elemBasePoint[0]+2*coeffs[5]*elemBasePoint[1];
532 dxphi=coeffs[1]+2*coeffs[3]*elemBasePoint[0]+coeffs[4]*elemBasePoint[1]+3*coeffs[6]*elemBasePoint[0]*elemBasePoint[0]+2*coeffs[7]*elemBasePoint[0]*elemBasePoint[1]+coeffs[8]*elemBasePoint[1]*elemBasePoint[1];
533 dyphi=coeffs[2]+coeffs[4]*elemBasePoint[0]+2*coeffs[5]*elemBasePoint[1]+coeffs[7]*elemBasePoint[0]*elemBasePoint[0]+2*coeffs[8]*elemBasePoint[0]*elemBasePoint[1]+3*coeffs[9]*elemBasePoint[1]*elemBasePoint[1];
535 number gradnorm=sqrt(dxphi*dxphi+dyphi*dyphi);
538 number coelemBasePoint[dim];
540 coelemBasePoint[0] = elemBasePoint[0] + 0.5*hh*dxphi/gradnorm;
541 coelemBasePoint[1] = elemBasePoint[1] + 0.5*hh*dyphi/gradnorm;
545 size_t nrofiterations=0;
546 for (;nrofiterations<50;nrofiterations++){
547 number b = coelemBasePoint[0]-elemBasePoint[0];
548 number d = coelemBasePoint[1]-elemBasePoint[1];
549 sol[0] = elemBasePoint[0]+itgamma*(coelemBasePoint[0]-elemBasePoint[0]);
550 sol[1] = elemBasePoint[1]+itgamma*(coelemBasePoint[1]-elemBasePoint[1]);
552 phival = coeffs[0]+coeffs[1]*sol[0]+coeffs[2]*sol[1]+coeffs[3]*sol[0]*sol[0]+coeffs[4]*sol[0]*sol[1]+coeffs[5]*sol[1]*sol[1];
554 phival = coeffs[0]+coeffs[1]*sol[0]+coeffs[2]*sol[1]+coeffs[3]*sol[0]*sol[0]+coeffs[4]*sol[0]*sol[1]+coeffs[5]*sol[1]*sol[1]
555 +coeffs[6]*sol[0]*sol[0]*sol[0]+coeffs[7]*sol[0]*sol[0]*sol[1]+coeffs[8]*sol[0]*sol[1]*sol[1]+coeffs[9]*sol[1]*sol[1]*sol[1];
556 if (std::abs(phival)<1e-12)
break;
557 phigamma = coeffs[1]*b+coeffs[2]*d+2*coeffs[3]*sol[0]*b+coeffs[4]*b*sol[1]+coeffs[4]*sol[0]*d+2*coeffs[5]*sol[1]*d+3*coeffs[6]*sol[0]*sol[0]*b
558 +2*coeffs[7]*sol[0]*sol[1]*b+coeffs[7]*sol[0]*sol[0]*d+coeffs[8]*b*sol[1]*sol[1]+2*coeffs[8]*sol[0]*sol[1]*d+3*coeffs[9]*sol[1]*sol[1]*d;
559 itgamma -= phival/phigamma;
561 if (nrofiterations==80){
562 UG_THROW(
"Diverging Newton method in curvature computation (error=" << phival <<
")\n");
566 dxphi=coeffs[1]+2*coeffs[3]*sol[0]+coeffs[4]*sol[1];
567 dyphi=coeffs[2]+coeffs[4]*sol[0]+2*coeffs[5]*sol[1];
573 dxphi=coeffs[1]+2*coeffs[3]*sol[0]+coeffs[4]*sol[1]+3*coeffs[6]*sol[0]*sol[0]+2*coeffs[7]*sol[0]*sol[1]+coeffs[8]*sol[1]*sol[1];
574 dyphi=coeffs[2]+coeffs[4]*sol[0]+2*coeffs[5]*sol[1]+coeffs[7]*sol[0]*sol[0]+2*coeffs[8]*sol[0]*sol[1]+3*coeffs[9]*sol[1]*sol[1];
575 dxxphi=2*coeffs[3]+6*coeffs[6]*sol[0]+2*coeffs[7]*sol[1];
576 dxyphi=coeffs[4]+2*coeffs[7]*sol[0]+2*coeffs[8]*sol[1];
577 dyyphi=2*coeffs[5]+2*coeffs[8]*sol[0]+6*coeffs[9]*sol[1];
579 number t = sqrt(dxphi*dxphi+dyphi*dyphi);
580 kappa = - (dyyphi * dxphi * dxphi - 2 * dxyphi * dxphi * dyphi + dxxphi * dyphi * dyphi) / (t * t * t);
587 typedef typename TGridFunction::domain_type
domain_type;
589 typename domain_type::grid_type&
grid = *u.domain()->grid();
590 typedef typename TGridFunction::template dim_traits<dim>::const_iterator ElemIterator;
591 typedef typename TGridFunction::template dim_traits<dim>::grid_base_object ElemType;
592 typedef typename domain_type::position_accessor_type position_accessor_type;
593 const position_accessor_type& aaPos = u.domain()->position_accessor();
594 std::vector<DoFIndex> ind;
597 for (
int si=0;si<u.num_subsets();++si){
598 ElemIterator iter = u.template begin<ElemType>(si);
599 ElemIterator iterEnd = u.template end<ElemType>(si);
600 if (u.num_fct(si)<2){
601 UG_THROW(
"No curvature component in approximation space.");
604 UG_THROW(
"First component in approximation space must be of Lagrange 1 type.");
607 UG_THROW(
"Second component in approximation space must be of piecewise constant type.");
609 std::vector<MathVector<dim> > coord;
610 std::vector<number> phi;
611 std::vector<Vertex*> nbrs;
612 std::vector<Vertex*> nbrCandidates;
614 std::vector<size_t> stageStart(depth+2);
615 for( ;iter !=iterEnd; ++iter)
618 ElemType* elem = *iter;
620 size_t noc=elem->num_vertices();
625 bool nonzerophifound=
false;
628 for (
size_t i=0;i<noc;i++){
629 nbrs[i]=elem->vertex(i);
630 u.inner_dof_indices(nbrs[i], 0, ind);
631 phi[i] =
DoFRef(u, ind[0]);
632 if (nonzerophifound==
false){
634 nonzerophifound=
true;
638 if (nonzerophi*phi[i]<0){
643 if (onls==
false)
continue;
646 for (
size_t i=1;i<depth+2;i++){
650 for (
size_t stage=0;stage<depth;stage++){
652 for (
size_t i=stageStart[stage];i<stageStart[stage+1];i++){
655 for (
size_t j=0;j<nbrCandidates.size();j++){
656 bool newNeighbor=
true;
657 for (
size_t k=0;k<nbrs.size();k++){
658 if (nbrCandidates[j]==nbrs[k]){
663 if (newNeighbor==
true){
664 nbrs.push_back(nbrCandidates[j]);
670 stageStart[stage+2]=nbrs.size();
673 phi.resize(nbrs.size());
674 coord.resize(nbrs.size());
677 for (
size_t i=0;i<nbrs.size();i++){
680 coord[i] = aaPos[nbrs[i]];
683 u.inner_dof_indices(nbrs[i], 0, ind);
684 phi[i] =
DoFRef(u, ind[0]);
689 computeElementCurvature2d(kappa,noc,coord,phi,order);
691 u.dof_indices(elem,1,ind);
693 if (m_exactcurvatureknown==
true)
694 if (std::abs(kappa+m_exactcurv)>maxnormerr){
695 maxnormerr =std::abs(kappa+m_exactcurv);
701 if (m_exactcurvatureknown==
true)
UG_LOG(
"curvature maximum error " << maxnormerr <<
"\n");
708 typedef typename TGridFunction::domain_type
domain_type;
709 typedef typename domain_type::grid_type grid_type;
711 typename domain_type::grid_type&
grid = *u.domain()->grid();
712 typedef typename TGridFunction::template dim_traits<dim>::grid_base_object elem_type;
713 typedef typename TGridFunction::template dim_traits<dim>::const_iterator elem_iterator;
714 typedef typename elem_type::side side_type;
715 typedef typename TGridFunction::template traits<side_type>::const_iterator side_iterator;
716 typedef typename domain_type::position_accessor_type position_accessor_type;
717 const position_accessor_type& aaPos = u.domain()->position_accessor();
718 std::vector<MultiIndex<2> > ind;
720 aSideNumber acEdgeCurvature;
722 grid.template attach_to<side_type>(aEdgeCurvature);
723 acEdgeCurvature.access(
grid,aEdgeCurvature);
724 static number undefined = 1953853528.340591483532;
728 for (
int si=0;si<u.num_subsets();++si){
729 side_iterator iter = u.template begin<side_type>(si);
730 side_iterator iterEnd = u.template end<side_type>(si);
731 if (u.num_fct(si)<2){
732 UG_THROW(
"No curvature component in approximation space.");
735 UG_THROW(
"First component in approximation space must be of Lagrange 1 type.");
738 UG_THROW(
"Second component in approximation space must be of piecewise constant type.");
740 std::vector<MathVector<dim> > coord;
741 std::vector<number> phi;
742 std::vector<Vertex*> nbrs;
743 std::vector<Vertex*> nbrCandidates;
745 std::vector<size_t> stageStart(depth+2);
746 for( ;iter !=iterEnd; ++iter)
749 side_type* elem = *iter;
751 size_t noc=elem->num_vertices();
756 bool nonzerophifound=
false;
758 for (
size_t i=0;i<noc;i++){
759 nbrs[i]=elem->vertex(i);
760 u.inner_dof_indices(nbrs[i], 0, ind);
761 phi[i] =
DoFRef(u, ind[0]);
762 if (nonzerophifound==
false){
764 nonzerophifound=
true;
768 if (nonzerophi*phi[i]<0){
773 if (onls==
false)
continue;
776 for (
size_t i=1;i<depth+2;i++){
779 for (
size_t stage=0;stage<depth;stage++){
780 for (
size_t i=stageStart[stage];i<stageStart[stage+1];i++){
782 for (
size_t j=0;j<nbrCandidates.size();j++){
783 bool newNeighbor=
true;
784 for (
size_t k=0;k<nbrs.size();k++){
785 if (nbrCandidates[j]==nbrs[k]){
790 if (newNeighbor==
true){
791 nbrs.push_back(nbrCandidates[j]);
795 stageStart[stage+2]=nbrs.size();
797 phi.resize(nbrs.size());
798 coord.resize(nbrs.size());
799 for (
size_t i=0;i<nbrs.size();i++){
800 coord[i] = aaPos[nbrs[i]];
802 u.inner_dof_indices(nbrs[i], 0, ind);
803 phi[i] =
DoFRef(u,ind[0]);
807 computeElementCurvature2d(kappa,noc,coord,phi,order);
808 acEdgeCurvature[elem] = kappa;
810 elem_iterator elemIter = u.template begin<elem_type>(si);
811 elem_iterator elemIterEnd = u.template end<elem_type>(si);
812 for( ;elemIter !=elemIterEnd; ++elemIter)
815 elem_type* elem = *elemIter;
816 typename grid_type::template traits<side_type>::secure_container sides;
817 grid.associated_elements(sides, elem );
820 size_t nInterSides = 0;
821 for (
size_t i=0;i<sides.size();i++){
822 if (acEdgeCurvature[sides[i]]!= undefined){
824 ecurvature+=acEdgeCurvature[sides[i]];
828 if (onls==
false)
continue;
830 u.dof_indices(elem,1,ind);
832 if (m_exactcurvatureknown==
true)
833 if (std::abs(kappa+m_exactcurv)>maxnormerr){
834 maxnormerr =std::abs(kappa+m_exactcurv);
838 if (m_exactcurvatureknown==
true)
UG_LOG(
"curvature maximum error " << maxnormerr <<
"\n");