CirclePattern.cpp

Go to the documentation of this file.
00001 
00006 #include "CirclePattern.h"
00007 #include "util.h"
00008 #include "Mesh.h"
00009 
00010 using namespace std;
00011 
00012 static double M2_PI = 2*M_PI;
00013 
00023 double CirclePattern::ImLi2Sum (const double& theta, const double& x, 
00024                                     const double& tanHalfThetaStar, const double& clThetaStar)
00025 {
00026    double tStar = M_PI - theta;
00027    double p = 2*atan(tanh(0.5*x)*tanHalfThetaStar);
00028 
00029    return  p*x + Cl2(p + tStar) + Cl2(-p + tStar) - clThetaStar;
00030 }
00031 
00040 double CirclePattern::evaluateEnergy (Mesh * mesh, double *xx) {
00041    int i, j;
00042    double energy = 0;
00043    for (i = 0; i < mesh->numFaces(); i++) {
00044       energy += xx[i];
00045    }
00046 
00047    energy = M2_PI*energy;   // Total contribution from faces
00048 
00049    Mesh::HalfEdgeIterator hIter = mesh->halfEdgeIterator();
00050    for (hIter.reset(); !hIter.end(); hIter++) {
00051       Edge * e = hIter.half_edge();
00052 
00053       if (!e->isBoundary()) {
00054           i = e->face->ID;
00055           j = e->pair->face->ID;
00056           if (i > j) {
00057              double theta = e->theta();
00058              energy += ImLi2Sum(theta, xx[i] - xx[j], e->tanHalfTStar(), e->Cl2TStar());
00059              energy -= (M_PI - theta)*(xx[i] + xx[j]);
00060           }
00061       }
00062       else {
00063           if (e->face) {
00064              i = e->face->ID;
00065              energy -= 2*(M_PI - e->theta())*(xx[i]);
00066           }
00067       }
00068    }
00069    return energy;
00070 }
00071 
00080 void CirclePattern::computeGradient (Mesh * mesh, double * xx, double * grad) {
00081 
00082    Mesh::FaceIterator fIter = mesh->faceIterator();
00083 
00084    /* Compute and store the gradient of the f. */
00085    int i, j;
00086    for (i = 0; i < mesh->numFaces(); i++)
00087       grad[i] = M2_PI;
00088 
00089    // sum over edges
00090    Mesh::HalfEdgeIterator hIter = mesh->halfEdgeIterator();
00091    for (hIter.reset(); !hIter.end(); hIter++) {
00092       Edge * e = hIter.half_edge();
00093       if (!e->isBoundary()) {
00094           i = e->face->ID;
00095           j = e->pair->face->ID;
00096           if (i > j) {
00097              grad[i] -= fTheta2(e->cosTheta(), e->sinTheta(), xx[j] - xx[i]);
00098              grad[j] -= fTheta2(e->cosTheta(), e->sinTheta(), xx[i] - xx[j]);
00099           }
00100       }
00101       else if (e->face) {
00102           i = e->face->ID;
00103           grad[i] -= 2*(M_PI - e->theta());
00104       }
00105    }
00106 
00107 }
00108 
00110 void CirclePattern::buildSparsityForHessian (Mesh * mesh, int * hessI, int * hessJ) {
00111    int i, k, j;
00112 
00114    for (k = 0; k < mesh->numFaces(); k++) {
00115       hessI[k] = k; 
00116       hessJ[k] = k;
00117    }
00118 
00119    k = mesh->numFaces();
00121    Mesh::HalfEdgeIterator hIter = mesh->halfEdgeIterator();
00122    for (hIter.reset(); !hIter.end(); hIter++) {
00123       if (!hIter.half_edge()->isBoundary()) {
00124           i = hIter.half_edge()->face->ID;
00125           j  = hIter.half_edge()->pair->face->ID;
00126           if (i > j) {
00127              hessI[k] = i; 
00128              hessJ[k] = j;
00129              k++;
00130           }       
00131       }
00132    }
00133 }
00134 
00142 void CirclePattern::computeHessian (Mesh * mesh, double * xx, double * hessval) {
00143    for (int k = 0; k < mesh->numFaces(); k++) 
00144       hessval[k] = 0;
00145 
00146    int count = mesh->numFaces();
00147    int i,j;
00148    Mesh::HalfEdgeIterator hIter = mesh->halfEdgeIterator();
00149    for (hIter.reset(); !hIter.end(); hIter++) {
00150       Edge * e = hIter.half_edge();
00151       if (!e->isBoundary()) {
00152           i = e->face->ID;
00153           j = e->pair->face->ID;
00154           if (i > j) {
00155              double ximj = xx[i] - xx[j];
00156              double fThPrime2 = fThetaPrime2(e->cosTheta(), e->sinTheta(), ximj);
00157              hessval[count] = -fThPrime2;
00158              hessval[i] += fThPrime2;
00159              hessval[j] += fThPrime2;
00160              count++;
00161           }
00162       }
00163    }
00164 }
00165 

Generated on Sat Jun 3 13:33:41 2006 for CirclePatterns by  doxygen 1.4.5