From a0020497eca0b5798c6bcfbcd944c878b1587eb9 Mon Sep 17 00:00:00 2001 From: Jonathan Lambrechts <jonathan.lambrechts@uclouvain.be> Date: Tue, 14 Aug 2012 14:34:59 +0000 Subject: [PATCH] HighOrderMeshOptimizer : optimize barrier max (2 passes for now) --- contrib/HighOrderMeshOptimizer/OptHOM.cpp | 61 +++++++++++++++++++---- contrib/HighOrderMeshOptimizer/OptHOM.h | 34 ++----------- 2 files changed, 54 insertions(+), 41 deletions(-) diff --git a/contrib/HighOrderMeshOptimizer/OptHOM.cpp b/contrib/HighOrderMeshOptimizer/OptHOM.cpp index a9a0954cca..445576fa6e 100644 --- a/contrib/HighOrderMeshOptimizer/OptHOM.cpp +++ b/contrib/HighOrderMeshOptimizer/OptHOM.cpp @@ -14,6 +14,31 @@ #include "linalg.h" #include "optimization.h" +static inline double compute_f(double v, double barrier) +{ + if ((v > barrier && barrier < 1) || (v < barrier && barrier > 1)) { + const double l = log((v - barrier) / (1 - barrier)); + const double m = (v - 1); + return l * l + m * m; + } + else return 1.e300; +// if (v < 1.) return pow(1.-v,powM); +// if (v < 1.) return exp((long double)pow(1.-v,3)); +// else return pow(v-1.,powP); +} + +static inline double compute_f1(double v, double barrier) +{ + if ((v > barrier && barrier < 1) || (v < barrier && barrier > 1)) { + return 2 * (v - 1) + 2 * log((v - barrier) / (1 - barrier)) / (v - barrier); + } + else return barrier < 1 ? -1.e300 : 1e300; +// if (v < 1.) return -powM*pow(1.-v,powM-1.); +// if (v < 1.) return -3.*pow(1.-v,2)*exp((long double)pow(1.-v,3)); +// else return powP*pow(v-1.,powP-1.); +} + + // Constructor @@ -38,12 +63,16 @@ bool OptHOM::addJacObjGrad(double &Obj, alglib::real_1d_array &gradObj) mesh.scaledJacAndGradients (iEl,sJ,gSJ); for (int l = 0; l < mesh.nBezEl(iEl); l++) { - Obj += compute_f(sJ[l]); - const double f1 = compute_f1(sJ[l]); + double f1 = compute_f1(sJ[l], jacBar); + Obj += compute_f(sJ[l], jacBar); + if (_optimizeBarrierMax) { + Obj += compute_f(sJ[l], barrier_min); + f1 += compute_f1(sJ[l], barrier_min); + } for (int iPC = 0; iPC < mesh.nPCEl(iEl); iPC++) gradObj[mesh.indPCEl(iEl,iPC)] += f1*gSJ[mesh.indGSJ(iEl,l,iPC)]; - minJac = std::min(minJac,sJ[l]); - maxJac = std::max(maxJac,sJ[l]); + minJac = std::min(minJac, sJ[l]); + maxJac = std::max(maxJac, sJ[l]); } } @@ -63,8 +92,8 @@ bool OptHOM::addMetricMinObjGrad(double &Obj, alglib::real_1d_array &gradObj) mesh.metricMinAndGradients (iEl,sJ,gSJ); for (int l = 0; l < mesh.nBezEl(iEl); l++) { - Obj += compute_f(sJ[l]); - const double f1 = compute_f1(sJ[l]); + Obj += compute_f(sJ[l], jacBar); + const double f1 = compute_f1(sJ[l], jacBar); for (int iPC = 0; iPC < mesh.nPCEl(iEl); iPC++) gradObj[mesh.indPCEl(iEl,iPC)] += f1*gSJ[mesh.indGSJ(iEl,l,iPC)]; minJac = std::min(minJac, sJ[l]); @@ -115,9 +144,7 @@ void OptHOM::evalObjGrad(const alglib::real_1d_array &x, double &Obj, alglib::re addDistObjGrad(lambda, lambda2, Obj, gradObj); if(_optimizeMetricMin) addMetricMinObjGrad(Obj, gradObj); - - - if ((minJac > barrier_min) && (maxJac < barrier_max)) { + if ((minJac > barrier_min) && (maxJac < barrier_max || !_optimizeBarrierMax)) { printf("INFO: reached %s (%g %g) requirements, setting null gradient\n", _optimizeMetricMin ? "svd" : "jacobian", minJac, maxJac); Obj = 0.; for (int i = 0; i < gradObj.length(); i++) gradObj[i] = 0.; @@ -296,6 +323,7 @@ int OptHOM::optimize(double weightFixed, double weightFree, double b_min, double jacBar = jacBarStart; setBarrierTerm(jacBarStart); + _optimizeBarrierMax = false; // Calculate initial objective function value and gradient initObj = 0.; alglib::real_1d_array gradObj; @@ -309,7 +337,7 @@ int OptHOM::optimize(double weightFixed, double weightFree, double b_min, double << " and max. barrier = " << barrier_max << std::endl; int ITER = 0; - while (minJac < barrier_min || maxJac > barrier_max ) { + while (minJac < barrier_min) { OptimPass(x, gradObj, itMax); recalcJacDist(); jacBar = (minJac > 0.) ? 0.9*minJac : 1.1*minJac; @@ -317,6 +345,19 @@ int OptHOM::optimize(double weightFixed, double weightFree, double b_min, double if (ITER ++ > 50) break; } + if (!_optimizeMetricMin) { + _optimizeBarrierMax = true; + jacBar = 1.1 * maxJac; + setBarrierTerm(jacBar); + while (maxJac > barrier_max ) { + OptimPass(x, gradObj, itMax); + recalcJacDist(); + jacBar = 1.1 * maxJac; + setBarrierTerm(jacBar); + if (ITER ++ > 50) break; + } + } + // for (int i = 0; i<3; i++) { // lambda *= 100; // OptimPass(x, gradObj, itMax); diff --git a/contrib/HighOrderMeshOptimizer/OptHOM.h b/contrib/HighOrderMeshOptimizer/OptHOM.h index 431c7413eb..85f7fd868d 100644 --- a/contrib/HighOrderMeshOptimizer/OptHOM.h +++ b/contrib/HighOrderMeshOptimizer/OptHOM.h @@ -14,9 +14,9 @@ class Mesh; + class OptHOM { - public: Mesh mesh; @@ -43,46 +43,18 @@ private: double initObj, initMaxDist, initAvgDist; // Values for reporting double minJac, maxJac, maxDist, avgDist; // Values for reporting + bool _optimizeBarrierMax; // false : only moving barrier min; true : fixed barrier min + moving barrier max + inline void setBarrierTerm(double jacBarrier) {jacBar = jacBarrier;} - inline double compute_f(double v); - inline double compute_f1(double v); bool addJacObjGrad(double &Obj, alglib::real_1d_array &gradObj); bool addMetricMinObjGrad(double &Obj, alglib::real_1d_array &gradObj); bool addDistObjGrad(double Fact, double Fact2, double &Obj, alglib::real_1d_array &gradObj); void calcScale(alglib::real_1d_array &scale); void OptimPass(alglib::real_1d_array &x, const alglib::real_1d_array &initGradObj, int itMax); - }; -inline double OptHOM::compute_f(double v) -{ - if (v > jacBar) { - const double l = log((v - jacBar) / (1 -jacBar)); - const double m = (v - 1); - return l * l + m * m; - } - else return 1.e300; -// if (v < 1.) return pow(1.-v,powM); -// if (v < 1.) return exp((long double)pow(1.-v,3)); -// else return pow(v-1.,powP); -} - - - -inline double OptHOM::compute_f1(double v) -{ - if (v > jacBar) { - return 2 * (v - 1) + 2 * log((v - jacBar) / (1 - jacBar)) / (v - jacBar); - } - else return -1.e300; -// if (v < 1.) return -powM*pow(1.-v,powM-1.); -// if (v < 1.) return -3.*pow(1.-v,2)*exp((long double)pow(1.-v,3)); -// else return powP*pow(v-1.,powP-1.); -} - - void OptHOM::getJacDist(double &minJ, double &maxJ, double &maxD, double &avgD) { -- GitLab