diff --git a/contrib/HighOrderMeshOptimizer/OptHomObjContribMetricMin.h b/contrib/HighOrderMeshOptimizer/OptHomObjContribMetricMin.h index 3d44138e33fe4b2b16e95cbeb07a94ae2999ea5b..b86b383e1cc436205bade8c2bee9e4592634a4d2 100644 --- a/contrib/HighOrderMeshOptimizer/OptHomObjContribMetricMin.h +++ b/contrib/HighOrderMeshOptimizer/OptHomObjContribMetricMin.h @@ -13,6 +13,7 @@ class ObjContribMetricMin : public ObjContrib, public FuncType public: ObjContribMetricMin(double weight); virtual ~ObjContribMetricMin() {} + virtual ObjContrib *copy() const; virtual void initialize(Patch *mesh); virtual bool fail() { return false; } virtual bool addContrib(double &Obj, alglib::real_1d_array &gradObj); @@ -36,6 +37,13 @@ ObjContribMetricMin<FuncType>::ObjContribMetricMin(double weight) : } +template<class FuncType> +ObjContrib *ObjContribMetricMin<FuncType>::copy() const +{ + return new ObjContribMetricMin<FuncType>(*this); +} + + template<class FuncType> void ObjContribMetricMin<FuncType>::initialize(Patch *mesh) { diff --git a/contrib/HighOrderMeshOptimizer/OptHomObjContribScaledJac.h b/contrib/HighOrderMeshOptimizer/OptHomObjContribScaledJac.h index dd260fc8c18796628a3244059f0e8a6000ecf5db..93b3768eebb38d927caa8dd5fae890540d82287c 100644 --- a/contrib/HighOrderMeshOptimizer/OptHomObjContribScaledJac.h +++ b/contrib/HighOrderMeshOptimizer/OptHomObjContribScaledJac.h @@ -13,6 +13,7 @@ class ObjContribScaledJac : public ObjContrib, public FuncType public: ObjContribScaledJac(double weight); virtual ~ObjContribScaledJac() {} + virtual ObjContrib *copy() const; virtual void initialize(Patch *mesh); virtual bool fail() { return _min <= 0.; } virtual bool addContrib(double &Obj, alglib::real_1d_array &gradObj); @@ -36,6 +37,13 @@ ObjContribScaledJac<FuncType>::ObjContribScaledJac(double weight) : } +template<class FuncType> +ObjContrib *ObjContribScaledJac<FuncType>::copy() const +{ + return new ObjContribScaledJac<FuncType>(*this); +} + + template<class FuncType> void ObjContribScaledJac<FuncType>::initialize(Patch *mesh) { diff --git a/contrib/HighOrderMeshOptimizer/OptHomRun.cpp b/contrib/HighOrderMeshOptimizer/OptHomRun.cpp index c462487e0a8dc16d10f0a805eef71a55055b92e8..52095e5862e9246be42a566310f8f12dc4839b6a 100644 --- a/contrib/HighOrderMeshOptimizer/OptHomRun.cpp +++ b/contrib/HighOrderMeshOptimizer/OptHomRun.cpp @@ -745,7 +745,6 @@ void HighOrderMeshOptimizer(GModel *gm, OptHomParameters &p) //#include "OptHomRun.h" #include "MeshOptCommon.h" #include "MeshOptObjContribFunc.h" -#include "MeshOptObjectiveFunction.h" #include "MeshOptObjContrib.h" #include "MeshOptObjContribScaledNodeDispSq.h" #include "OptHomObjContribScaledJac.h" @@ -808,27 +807,35 @@ void HighOrderMeshOptimizerNew(GModel *gm, OptHomParameters &p) par.patchDef = &patchDef; par.optDisplay = 30; par.verbose = 4; + ObjContribScaledNodeDispSq<ObjContribFuncSimple> nodeDistFunc(p.weightFixed, p.weightFree); ObjContribScaledJac<ObjContribFuncBarrierMin> minJacBarFunc(1.); + minJacBarFunc.setTarget(p.BARRIER_MIN, 1.); ObjContribScaledJac<ObjContribFuncBarrierMinMax> minMaxJacBarFunc(1.); + minMaxJacBarFunc.setTarget(p.BARRIER_MAX, 1.); + par.allContrib.resize(3); + par.allContrib[0] = &nodeDistFunc; + par.allContrib[1] = &minJacBarFunc; + par.allContrib[2] = &minMaxJacBarFunc; + MeshOptParameters::PassParameters minJacPass; minJacPass.barrierIterMax = p.optPassMax; minJacPass.optIterMax = p.itMax; - minJacPass.objFunc = ObjectiveFunction(); - minJacPass.objFunc.push_back(&nodeDistFunc); - minJacBarFunc.setTarget(p.BARRIER_MIN, 1.); - minJacPass.objFunc.push_back(&minJacBarFunc); + minJacPass.contribInd.resize(2); + minJacPass.contribInd[0] = 0; + minJacPass.contribInd[1] = 1; par.pass.push_back(minJacPass); + if (p.BARRIER_MAX > 0.) { MeshOptParameters::PassParameters minMaxJacPass; minMaxJacPass.barrierIterMax = p.optPassMax; minMaxJacPass.optIterMax = p.itMax; - minMaxJacPass.objFunc = ObjectiveFunction(); - minMaxJacPass.objFunc.push_back(&nodeDistFunc); - minMaxJacBarFunc.setTarget(p.BARRIER_MAX, 1.); - minMaxJacPass.objFunc.push_back(&minMaxJacBarFunc); + minMaxJacPass.contribInd.resize(2); + minMaxJacPass.contribInd[0] = 0; + minMaxJacPass.contribInd[1] = 2; par.pass.push_back(minMaxJacPass); } + MeshOptResults res; meshOptimizer(gm, par, res); diff --git a/contrib/MeshOptimizer/MeshOpt.cpp b/contrib/MeshOptimizer/MeshOpt.cpp index f3812c0a81918a4d6956baf2f98da2c34a76c447..1ffb8678b17f4a2c86b0a3fd3fb9cce52dead85a 100644 --- a/contrib/MeshOptimizer/MeshOpt.cpp +++ b/contrib/MeshOptimizer/MeshOpt.cpp @@ -65,11 +65,19 @@ void printProgressFunc(const alglib::real_1d_array &x, double Obj, void *MOInst) MeshOpt::MeshOpt(const std::map<MElement*,GEntity*> &element2entity, - const std::set<MElement*> &els, std::set<MVertex*> & toFix, - bool fixBndNodes) : + const std::set<MElement*> &els, std::set<MVertex*> &toFix, + bool fixBndNodes, const std::vector<ObjContrib*> &allContrib) : patch(element2entity, els, toFix, fixBndNodes), _verbose(0), - _iPass(0), _objFunc(0), _iter(0), _intervDisplay(0), _initObj(0) + _iPass(0), _objFunc(), _iter(0), _intervDisplay(0), _initObj(0) { + _allContrib.resize(allContrib.size()); + for (int i = 0; i < allContrib.size(); i++) _allContrib[i] = allContrib[i]->copy(); +} + + +MeshOpt::~MeshOpt() +{ + for (int i = 0; i < _allContrib.size(); i++) delete _allContrib[i]; } @@ -77,8 +85,8 @@ void MeshOpt::evalObjGrad(const alglib::real_1d_array &x, double &obj, alglib::real_1d_array &gradObj) { patch.updateMesh(x.getcontent()); - _objFunc->compute(obj, gradObj); - if (_objFunc->targetReached()) { + _objFunc.compute(obj, gradObj); + if (_objFunc.targetReached()) { if (_verbose > 2) Msg::Info("Reached target values, setting null gradient"); obj = 0.; for (int i = 0; i < gradObj.length(); i++) gradObj[i] = 0.; @@ -92,7 +100,7 @@ void MeshOpt::printProgress(const alglib::real_1d_array &x, double Obj) if ((_verbose > 2) && (_iter % _intervDisplay == 0)) Msg::Info(("--> Iteration %3d --- OBJ %12.5E (relative decrease = %12.5E)" + - _objFunc->minMaxStr()).c_str(), _iter, Obj, Obj/_initObj); + _objFunc.minMaxStr()).c_str(), _iter, Obj, Obj/_initObj); } @@ -112,7 +120,7 @@ void MeshOpt::calcScale(alglib::real_1d_array &scale) void MeshOpt::updateResults(MeshOptResults &res) { - _objFunc->updateResults(res); + _objFunc.updateResults(res); } @@ -180,15 +188,15 @@ int MeshOpt::optimize(MeshOptParameters &par) for (_iPass=0; _iPass<par.pass.size(); _iPass++) { // Set objective function Output if required - _objFunc = &par.pass[_iPass].objFunc; + _objFunc = ObjectiveFunction(_allContrib, par.pass[_iPass].contribInd); if (_verbose > 2) { - std::string msgStr = "* Pass %d with contributions: " + _objFunc->contribNames(); + std::string msgStr = "* Pass %d with contributions: " + _objFunc.contribNames(); Msg::Info(msgStr.c_str(), _iPass); } // Initialize contributions - _objFunc->initialize(&patch); - _objFunc->updateParameters(); + _objFunc.initialize(&patch); + _objFunc.updateParameters(); // Calculate initial objective function value and gradient _initObj = 0.; @@ -198,14 +206,14 @@ int MeshOpt::optimize(MeshOptParameters &par) evalObjGrad(x, _initObj, gradObj); // Loop for update of objective function parameters (barrier movement) - bool targetReached = _objFunc->targetReached(); + bool targetReached = _objFunc.targetReached(); for (int iBar=0; (iBar<par.pass[_iPass].barrierIterMax) && (!targetReached); iBar++) { if (_verbose > 2) Msg::Info("--- Optimization run %d", iBar); - _objFunc->updateParameters(); + _objFunc.updateParameters(); runOptim(x, gradObj, par.pass[_iPass].optIterMax); - _objFunc->updateMinMax(); - targetReached = _objFunc->targetReached(); - if (_objFunc->stagnated()) { + _objFunc.updateMinMax(); + targetReached = _objFunc.targetReached(); + if (_objFunc.stagnated()) { if (_verbose > 2) Msg::Info("Stagnation detected, stopping optimization"); break; } @@ -213,7 +221,7 @@ int MeshOpt::optimize(MeshOptParameters &par) // Check results of pass and output if required if (!targetReached) result = 0; - std::string failMeasures = _objFunc->failMeasures(); + std::string failMeasures = _objFunc.failMeasures(); if (!failMeasures.empty()) { result = -1; if (_verbose > 2) @@ -224,7 +232,7 @@ int MeshOpt::optimize(MeshOptParameters &par) if (targetReached) Msg::Info("Target reached for pass %d", _iPass); else { - std::string failedTargets = _objFunc->targetsNotReached(); + std::string failedTargets = _objFunc.targetsNotReached(); Msg::Warning("Failed to reach target in pass %d for " "contributions %s", _iPass, failedTargets.c_str()); } diff --git a/contrib/MeshOptimizer/MeshOpt.h b/contrib/MeshOptimizer/MeshOpt.h index 6d72d1b30205184cd1255ea7e640ed0b6b6f01de..b3fd41e72cdc99a7e3a4990a1ef1e534aad95ab3 100644 --- a/contrib/MeshOptimizer/MeshOpt.h +++ b/contrib/MeshOptimizer/MeshOpt.h @@ -48,7 +48,9 @@ class MeshOpt public: Patch patch; MeshOpt(const std::map<MElement*,GEntity*> &element2entity, - const std::set<MElement*> &els, std::set<MVertex*> &toFix, bool fixBndNodes); + const std::set<MElement*> &els, std::set<MVertex*> &toFix, + bool fixBndNodes, const std::vector<ObjContrib*> &allContrib); + ~MeshOpt(); int optimize(MeshOptParameters &par); void updateMesh(const alglib::real_1d_array &x); void updateResults(MeshOptResults &res); @@ -59,7 +61,8 @@ public: private: int _verbose; int _iPass; - ObjectiveFunction *_objFunc; // Current contributions to objective function + std::vector<ObjContrib*> _allContrib; // All contributions to objective function for all passes + ObjectiveFunction _objFunc; // Contributions to objective function for current pass int _iter, _intervDisplay; // Current iteration, interval of iterations for reporting double _initObj; // Values for reporting void calcScale(alglib::real_1d_array &scale); diff --git a/contrib/MeshOptimizer/MeshOptCommon.h b/contrib/MeshOptimizer/MeshOptCommon.h index 87736d4f8b748576f022aead842d7c4cf3e7c3bf..7314c0ea5bcde3b55c08bc5c3fe9d77ee01ec419 100644 --- a/contrib/MeshOptimizer/MeshOptCommon.h +++ b/contrib/MeshOptimizer/MeshOptCommon.h @@ -31,10 +31,10 @@ #define _MESHOPTCOMMON_H_ #include <vector> -#include "MeshOptObjectiveFunction.h" class MElement; +class ObjContrib; struct MeshOptResults { // Output of mesh optimization @@ -52,9 +52,9 @@ private: struct MeshOptParameters { // Parameters controlling the strategy enum { STRAT_CONNECTED, STRAT_ONEBYONE }; struct PassParameters { // Parameters controlling the optimization procedure in each pass - ObjectiveFunction objFunc; // Contributions to objective function - int optIterMax ; // Max. number of opt. iterations each time the barrier is moved - int barrierIterMax ; // Max. number of times the barrier is moved + std::vector<int> contribInd; // Indices of contributions to objective function + int optIterMax; // Max. number of opt. iterations each time the barrier is moved + int barrierIterMax; // Max. number of times the barrier is moved }; struct PatchDefParameters { int strategy; // Strategy: connected patches or adaptive one-by-one @@ -74,6 +74,7 @@ struct MeshOptParameters { // Parameters controlling bool onlyVisible ; // Apply optimization to visible entities ONLY bool fixBndNodes; // If points can move on boundaries PatchDefParameters *patchDef; + std::vector<ObjContrib*> allContrib; // All contributions to objective functions for all passes std::vector<PassParameters> pass; int optDisplay; // Sampling rate in opt. iterations for display int verbose; // Level of information displayed and written to disk diff --git a/contrib/MeshOptimizer/MeshOptObjContrib.h b/contrib/MeshOptimizer/MeshOptObjContrib.h index edb60b58e176e1c5aa46d7659eb1882440f4b2aa..91b31b09416eccbe0170e96d3c8fb2998bfdddf6 100644 --- a/contrib/MeshOptimizer/MeshOptObjContrib.h +++ b/contrib/MeshOptimizer/MeshOptObjContrib.h @@ -16,6 +16,7 @@ class ObjContrib public: ObjContrib(std::string mesName, std::string name); virtual ~ObjContrib() {} + virtual ObjContrib *copy() const = 0; const double getMin() { return _min; } const double getMax() { return _max; } const std::string &getName() const { return _name; } diff --git a/contrib/MeshOptimizer/MeshOptObjContribScaledNodeDispSq.h b/contrib/MeshOptimizer/MeshOptObjContribScaledNodeDispSq.h index 2a452eaf4f43d2eb54d54eb119dc27e107cf397c..b8cb7b831394d02fcdedac14380193ea7162af14 100644 --- a/contrib/MeshOptimizer/MeshOptObjContribScaledNodeDispSq.h +++ b/contrib/MeshOptimizer/MeshOptObjContribScaledNodeDispSq.h @@ -13,6 +13,7 @@ class ObjContribScaledNodeDispSq : public ObjContrib, public FuncType public: ObjContribScaledNodeDispSq(double weightFixed, double weightFree); virtual ~ObjContribScaledNodeDispSq() {} + virtual ObjContrib *copy() const; virtual void initialize(Patch *mesh); virtual bool fail() { return false; } virtual bool addContrib(double &Obj, alglib::real_1d_array &gradObj); @@ -38,6 +39,13 @@ ObjContribScaledNodeDispSq<FuncType>::ObjContribScaledNodeDispSq(double weightFi } +template<class FuncType> +ObjContrib *ObjContribScaledNodeDispSq<FuncType>::copy() const +{ + return new ObjContribScaledNodeDispSq<FuncType>(*this); +} + + template<class FuncType> void ObjContribScaledNodeDispSq<FuncType>::initialize(Patch *mesh) { diff --git a/contrib/MeshOptimizer/MeshOptObjectiveFunction.cpp b/contrib/MeshOptimizer/MeshOptObjectiveFunction.cpp index 3fac82abecf625c5614ae8b3467c70941efdeb4e..3b03d3010c3900d6d904b31b1073def2d1a95a98 100644 --- a/contrib/MeshOptimizer/MeshOptObjectiveFunction.cpp +++ b/contrib/MeshOptimizer/MeshOptObjectiveFunction.cpp @@ -5,6 +5,14 @@ #include "MeshOptObjectiveFunction.h" +ObjectiveFunction::ObjectiveFunction(const std::vector<ObjContrib*> &allContrib, + const std::vector<int> &contribInd) +{ + resize(contribInd.size()); + for (int i=0; i<contribInd.size(); i++) operator[](i) = allContrib[contribInd[i]]; +} + + void ObjectiveFunction::initialize(Patch *mesh) { for (std::vector<ObjContrib*>::iterator it=begin(); it!=end(); it++) diff --git a/contrib/MeshOptimizer/MeshOptObjectiveFunction.h b/contrib/MeshOptimizer/MeshOptObjectiveFunction.h index f74f1368842ac6112e9d2b9437170da95f209bee..116c7dc32f413d75685881a6b0024c83009c625f 100644 --- a/contrib/MeshOptimizer/MeshOptObjectiveFunction.h +++ b/contrib/MeshOptimizer/MeshOptObjectiveFunction.h @@ -12,9 +12,12 @@ class MeshOptResults; class Patch; -class ObjectiveFunction : public std::vector<ObjContrib*> // Contributions to objective function in each pass +class ObjectiveFunction : protected std::vector<ObjContrib*> // Contributions to objective function in each pass { public: + ObjectiveFunction() {} + ObjectiveFunction(const std::vector<ObjContrib*> &model, + const std::vector<int> &contribInd); void initialize(Patch *mesh); std::string contribNames(); std::string minMaxStr(); diff --git a/contrib/MeshOptimizer/MeshOptimizer.cpp b/contrib/MeshOptimizer/MeshOptimizer.cpp index f672741ad0eb1e2120570384ffac684788ac2987..4aa3958d6cfc3c16f184c745f737e2f9da4716ae 100644 --- a/contrib/MeshOptimizer/MeshOptimizer.cpp +++ b/contrib/MeshOptimizer/MeshOptimizer.cpp @@ -267,7 +267,7 @@ static void optimizeConnectedPatches Msg::Info("Optimizing patch %i/%i composed of %i elements", iPatch, toOptimize.size()-1, toOptimize[iPatch].first.size()); MeshOpt opt(element2entity, toOptimize[iPatch].first, toOptimize[iPatch].second, - par.fixBndNodes); + par.fixBndNodes, par.allContrib); if (par.verbose > 3) { std::ostringstream ossI1; ossI1 << "initial_patch-" << iPatch << ".msh"; @@ -356,7 +356,7 @@ static void optimizeOneByOne if (par.verbose > 1) Msg::Info("Optimizing patch %i (max. %i remaining) composed of %4d elements", iBadEl, badElts.size(), toOptimize.size()); - MeshOpt opt(element2entity, toOptimize, toFix, par.fixBndNodes); + MeshOpt opt(element2entity, toOptimize, toFix, par.fixBndNodes, par.allContrib); if (par.verbose > 3) { std::ostringstream ossI1; ossI1 << "initial_patch-" << iBadEl << ".msh";