diff --git a/C++/nonLin/libNonLin.cc b/C++/nonLin/libNonLin.cc
index 3c57814c598c54e253b8ba837c07d72b724b3dbe..5c5d63075c0d5df6926a12d2802cf49b23fc325f 100644
--- a/C++/nonLin/libNonLin.cc
+++ b/C++/nonLin/libNonLin.cc
@@ -22,9 +22,7 @@
 
 
 template<typename T, unsigned int DIM>
-void declare_nonLinCF(py::module &main_m){
-    py::module_ m = main_m.def_submodule("nonLin", "nonLinear CoefficientFunction");
-
+void declare_nonLinCF(py::module &m){
 
     std::string pyclass_name = std::string("nonLinCF") + std::to_string(DIM);
 
@@ -69,16 +67,52 @@ void declare_nonLinCF(py::module &main_m){
 }
 
 
-void ExportReclibNonLin(py::module &m)
+template<typename T, unsigned int DIM>
+void declare_nonLinCF_harmonicBalance(py::module &m){
+
+
+    std::string pyclass_name = std::string("nonLinCF_harmonicBalance") + std::to_string(DIM);
+
+    py::class_<nonLinCF_harmonicBalance<T, DIM>, shared_ptr<nonLinCF_harmonicBalance<T, DIM>>, nonLinCF<T, DIM>>
+    (m, pyclass_name.c_str(), "nonLinear CoefficientFunction\n\
+    mesh, intrule, ptrInput ... scalar input CF, points of x axis, points of y axis, cFieldIn='H'/'B', cFieldOut = 'H/B/mu/mudiff', mask=1, order=1/3")
+	.def(py::init(
+			[](shared_ptr<MeshAccess>& mesh, IntegrationRule& intrule, 
+                        const vector<shared_ptr<CoefficientFunction>> ptrInput_i, 
+                        vector<double> H_KL, 
+                        vector<double> B_KL,
+                        vector<double> ti,  
+                        const std::string cFieldIn, const std::string cFieldOut, const shared_ptr<CoefficientFunction>& ptrMask, unsigned int order, 
+                        bool usePreisBiro)
+	{
+		return new nonLinCF_harmonicBalance<T, DIM>(mesh, intrule, ptrInput_i, H_KL, B_KL, ti, cFieldIn, cFieldOut, ptrMask, order, usePreisBiro);
+	}), py::arg("mesh"), py::arg("IntegrationRule"), py::arg("InputFunctions"), py::arg("H_KL"), py::arg("B_KL"), py::arg("ti"), py::arg("field_in") = "H", py::arg("field_out") = "B",py::arg("mask")=nullptr, py::arg("order")=3, py::arg("usePreisBiro")=false)
+    .def("Update",  overload_cast_<>()(&nonLinCF_harmonicBalance<T, DIM>::Update), "Updates the output CF according to the current input CF")
+    .def("Update",  overload_cast_<const vector<shared_ptr<CoefficientFunction>> >()(&nonLinCF_harmonicBalance<T, DIM>::Update), "Updates the output CF according to the given input CF")
+    .def("getParts", &nonLinCF_harmonicBalance<T, DIM>::getParts)
+    .def("getTi", &nonLinCF_harmonicBalance<T, DIM>::getTi)
+    .def_property("omega0",  &nonLinCF_harmonicBalance<T, DIM>::getOmega, &nonLinCF_harmonicBalance<T, DIM>::setOmega)
+
+    ;
+}
+
+
+void ExportReclibNonLin(py::module &main_m)
 {
 
     // --------------------------------------------------------------------------- *
     // -----------   NonLin CF KL                                                 
     // --------------------------------------------------------------------------- *
+    py::module_ m = main_m.def_submodule("nonLin", "nonLinear CoefficientFunction");
 
     declare_nonLinCF<double, 1>(m);
     declare_nonLinCF<double, 2>(m);
     declare_nonLinCF<double, 3>(m);
+
+    declare_nonLinCF_harmonicBalance<double, 1>(m);
+    declare_nonLinCF_harmonicBalance<double, 2>(m);
+    declare_nonLinCF_harmonicBalance<double, 3>(m);
+
 }
 
 
diff --git a/C++/nonLin/nonLinCF.cc b/C++/nonLin/nonLinCF.cc
index b4969cc324a85a723ffa876f063c8ea44f6dad54..bf1cdee84f59821f31994a5b446a048534576bf2 100644
--- a/C++/nonLin/nonLinCF.cc
+++ b/C++/nonLin/nonLinCF.cc
@@ -43,7 +43,6 @@ nonLinCF<T, DIM>::nonLinCF(shared_ptr<MeshAccess>& mesh, IntegrationRule& intrul
     // Update();
 }; 
 
-
 /* --------------------------------------------------------------------------- *
 *  -----------   Member Funcitons                                              *
 *  --------------------------------------------------------------------------- */
@@ -56,7 +55,6 @@ void nonLinCF<T, DIM>::findConcavePoints(){
 			while(oKL->GetData()[i].first == 0){
 				++i;
 			}
-			cout << oKL->GetData().size() << endl;
 			double max = oKL->GetData()[i].second/oKL->GetData()[i].first;
 			for(i = i+1; i!= oKL->GetData().size(); ++i){
 				if(oKL->GetData()[i].second/oKL->GetData()[i].first > max){
@@ -68,7 +66,7 @@ void nonLinCF<T, DIM>::findConcavePoints(){
 			concaveB = std::fabs(oKL->GetData()[ind_max].second);
 			concaveH = std::fabs(oKL->GetData()[ind_max].first);
 
-			cout << "concaveB" << concaveB << " " << concaveH << endl;
+			
 		}
 
 
@@ -408,6 +406,183 @@ unsigned int nonLinCF<T, DIM>::getOrder() const{
 }
 
 
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+template <typename T, unsigned int DIM>
+nonLinCF_harmonicBalance<T, DIM>::nonLinCF_harmonicBalance(shared_ptr<MeshAccess>& mesh, IntegrationRule& intrule, 
+            const vector<shared_ptr<CoefficientFunction>> ptrInput_i, 
+            vector<double> H_KL, 
+            vector<double> B_KL, 
+            vector<double> ti, 
+            const std::string cFieldIn, const std::string cFieldOut, 
+            const shared_ptr<CoefficientFunction>& ptrMask, unsigned int order, bool usePreisBiro):
+            nonLinCF<T, DIM>{mesh, intrule, nullptr, H_KL, B_KL, cFieldIn, cFieldOut, ptrMask, order, usePreisBiro}, 
+            ptrInput_i{ptrInput_i}, ti{ti}, omega_0{2.0*M_PI/(ti.back() - ti.front())}{
+                unsigned int i;
+
+                for(i = 0; i!= ti.size(); ++i){
+                    nonLin_parts.push_back(std::make_shared<nonLinCF<T, DIM>>(mesh, intrule, this->mips, nullptr, H_KL, B_KL, cFieldIn, cFieldOut, ptrMask, order, usePreisBiro ));
+                }
+                Update();
+            }
+
+template <typename T, unsigned int DIM>
+void nonLinCF_harmonicBalance<T, DIM>::Update(){
+    Update(ptrInput_i);
+}
+
+
+
+
+
+template <typename T, unsigned int DIM>
+void nonLinCF_harmonicBalance<T, DIM>::Update(const vector<shared_ptr<CoefficientFunction>> ptrInput_i){
+
+
+    if(ptrInput_i.size() == 0)
+        cout << __PRETTY_FUNCTION__ << ": invalid input pointer" << endl;
+
+
+ 
+    parFor(this->mips.size(), [&](int el) {
+        unsigned int ip;
+        std::complex<double> val_in_c;
+        Vector<Complex> fV_tmp(1);
+        
+        double val_in;
+        double out_old;
+        unsigned int i;
+        unsigned int j;
+
+        for(ip = 0; ip != this->mips[el].size(); ++ip){
+
+
+            // --------------------- update parts -----------------
+            for(i = 0; i!= ti.size(); ++i){
+
+                val_in_c = 0;
+                for(j = 0; j!= ptrInput_i.size(); ++j){
+                    ptrInput_i[j]->Evaluate(this->mips[el][ip], fV_tmp);
+
+                    val_in_c += fV_tmp(0) * std::exp( j * 1i * omega_0 * ti[i]);
+                }
+
+                val_in = std::abs(val_in_c.real());
+
+                if(!std::strcmp(this->sFieldIn.c_str(), "H")){       
+                    
+                    if(!std::strcmp(this->sFieldOut.c_str(), "B"))
+                        nonLin_parts[i]->Set(el, ip, this->oKL->EvaluateH(val_in));
+                    else if(!std::strcmp(this->sFieldOut.c_str(), "mu")){
+                        if (this->usePreisBiro && std::abs(val_in) <= this->concaveH){
+                            // double	b = h*pastMu[el][p];
+                            // double hnew = bh->GetHfromB(b);
+                            // return b / hnew;
+                            val_in = this->oKL->EvaluateB(val_in * nonLin_parts[i]->Get(el, ip).getxx());
+                        }   
+                        if(abs(val_in) < 1e-6)
+                            nonLin_parts[i]->Set(el, ip, this->oKL->getZeroMu());
+                        else{
+
+                            nonLin_parts[i]->Set(el, ip, this->oKL->EvaluateH(val_in)/val_in);
+                        }
+                    }
+                    else if(!std::strcmp(this->sFieldOut.c_str(), "mu_diff")){
+                        if (this->usePreisBiro && std::abs(val_in) <= this->concaveH){
+                            val_in = this->oKL->EvaluateB(val_in * nonLin_parts[i]->Get(el, ip).getxx());
+                        }   
+                        nonLin_parts[i]->Set(el, ip, this->oKL->DifferentiateH(val_in));
+                    }
+                    else{
+                        throw std::invalid_argument("invalid input parameter: valid parameters are (H, B, mu, mu_diff)");
+                    }
+                }
+
+                else {
+                    if(!std::strcmp(this->sFieldOut.c_str(), "H"))
+                        nonLin_parts[i]->Set(el, ip, this->oKL->EvaluateB(val_in));
+                    else if(!std::strcmp(this->sFieldOut.c_str(), "nu")){
+                        if (this->usePreisBiro && std::abs(val_in) > this->concaveB){
+                            val_in = this->oKL->EvaluateH(val_in * nonLin_parts[i]->Get(el, ip).getxx());
+                        }   
+                        if(abs(this->oKL->EvaluateB(val_in)) < 1e-6)
+                            nonLin_parts[i]->Set(el, ip, 1/(this->oKL->getZeroMu()));
+                        else
+                            nonLin_parts[i]->Set(el, ip, this->oKL->EvaluateB(val_in)/val_in);
+                    }
+
+                    else if(!std::strcmp(this->sFieldOut.c_str(), "nu_diff")){
+                        if (this->usePreisBiro && std::abs(val_in) > this->concaveB){
+                            val_in = this->oKL->EvaluateH(val_in * nonLin_parts[i]->Get(el, ip).getxx());
+                        }   
+                        nonLin_parts[i]->Set(el, ip, this->oKL->DifferentiateB(val_in));
+                    }
+                    else{
+                        throw std::invalid_argument("invalid input parameter: valid parameters are (H, B, nu, nu_diff)");
+                    }
+
+                }
+            
+            }
+
+            
+
+            // --------------------- update global -----------------
+            out_old = this->Get(el, ip).xx();
+            val_in = 0;
+            for(i = 0; i!= ti.size()-1; ++i){
+                val_in += nonLin_parts[i]->Get(el, ip).xx() * (ti[i+1] - ti[i]);
+            }    
+            this->Set(el, ip, val_in * 1.0/(ti.back() - ti.front()));
+
+
+            // --------------------- error calc -----------------
+            if (this->ptrError != nullptr){
+                // cout << "error calculation" << endl;
+                this->ptrError->Set(el, ip,  this->Get(el, ip).xx() - out_old);
+            }
+        }
+
+    });
+
+
+
+
+
+
+
+    this->maxError = 0;
+    double sumOut = 0;
+    this->meanError = 0;
+
+    
+    if (this->ptrError != nullptr){
+        int el, ip;
+        for(el = 0; el != this->mips.size(); ++el){
+            for(ip = 0; ip != this->mips[el].size(); ++ip){                
+                this->maxError = std::max(this->ptrError->Get(el, ip).norm()/this->Get(el, ip).norm(), this->maxError);
+                this->meanError += this->ptrError->Get(el, ip).norm();
+                sumOut += this->Get(el, ip).norm();
+            }
+        }
+        
+        if (sumOut > 1e-14) {
+            this->meanError = this->meanError / sumOut;
+        }
+        else {
+            this->meanError = 0;
+        }
+    }
+
+    this->meanError *= 100;
+    this->maxError *= 100;
+}
+
 template class nonLinCF<double, 1>;
 template class nonLinCF<double, 2>;
 template class nonLinCF<double, 3>;
+
+template class nonLinCF_harmonicBalance<double, 1>;
+template class nonLinCF_harmonicBalance<double, 2>;
+template class nonLinCF_harmonicBalance<double, 3>;
+
diff --git a/C++/nonLin/nonLinCF.h b/C++/nonLin/nonLinCF.h
index a9c1e7d80e57c984d14eeede88f3ce0d8a755c19..46ffcd0af2b3614c0ca6f6453dec0400dcba2fb1 100644
--- a/C++/nonLin/nonLinCF.h
+++ b/C++/nonLin/nonLinCF.h
@@ -13,6 +13,8 @@
 #include <cstring>
 
 
+
+
 #include "../basicClasses/ngData_class.h"
 #include "../basicClasses/magCurve.h"
 
@@ -22,6 +24,8 @@ using namespace ngfem;
 using namespace ngsolve;
 using namespace ngcomp;
 
+using namespace std::complex_literals;
+
 // #define _Pi 3.141592653589793
 
 template <unsigned int DIM>
@@ -46,6 +50,8 @@ class nonLinCF:public ngScalar_class<T, DIM>
                         const shared_ptr<CoefficientFunction>& ptrMask=nullptr, unsigned int order=1, bool usePreisBiro=false);
 
 
+
+
         ~nonLinCF() = default;
 
         using ngScalar_class<T, DIM>::mips;
@@ -55,8 +61,8 @@ class nonLinCF:public ngScalar_class<T, DIM>
 
         bool HasConverged(double aMeanError, double aMaxError, bool print_it=true);
 
-        void Update();
-        void Update(const shared_ptr<CoefficientFunction>& ptrInput);
+        virtual void Update();
+        virtual void Update(const shared_ptr<CoefficientFunction>& ptrInput);
         
         void UpdateEnergyDensity();
         const shared_ptr<ngScalar_class<T, DIM>> GetEnergyDensity();
@@ -102,7 +108,7 @@ class nonLinCF:public ngScalar_class<T, DIM>
 
       
 
-    private:
+    protected:
 
 
         shared_ptr<CoefficientFunction> ptrInput;
@@ -127,8 +133,52 @@ class nonLinCF:public ngScalar_class<T, DIM>
         double maxError;
 
 
+
+    private:
         void findConcavePoints();
 };
 
+template<typename T, unsigned int DIM>
+class nonLinCF_harmonicBalance : public nonLinCF<T, DIM>{
+
+    public:
+        nonLinCF_harmonicBalance(shared_ptr<MeshAccess>& mesh, IntegrationRule& intrule, 
+                    const vector<shared_ptr<CoefficientFunction>> ptrInput_i, 
+                    vector<double> H_KL, 
+                    vector<double> B_KL, 
+                    vector<double> ti, 
+                    const std::string cFieldIn="H", const std::string cFieldOut="B", 
+                    const shared_ptr<CoefficientFunction>& ptrMask=nullptr, unsigned int order=1, bool usePreisBiro=false);
+    
+
+        virtual void Update();
+        virtual void Update(const vector<shared_ptr<CoefficientFunction>> ptrInput);
+
+        
+        double getOmega()const{
+            return omega_0;
+        }
+        
+        void setOmega(const double val){
+            omega_0 = val;
+        }
+
+        vector<double> getTi() const{
+            return  ti;
+        }
+
+        vector<std::shared_ptr<nonLinCF<T, DIM>>> getParts() const{
+            return nonLin_parts;
+        }
+
+
+    private:
+        vector<shared_ptr<CoefficientFunction>> ptrInput_i;
+        vector<double> ti;
+        double omega_0 = 0;
+        vector<std::shared_ptr<nonLinCF<T, DIM>>> nonLin_parts;
+        
+};
+
 #endif /* NONLINCF_H */