From 412ddd0fa4a6e32651619897c8606d4cbaaa1ffa Mon Sep 17 00:00:00 2001 From: Thales Lima Oliveira Date: Thu, 4 May 2017 17:03:19 -0300 Subject: Control solver class created Just the basics methods implemented --- Project/ControlElementSolver.cpp | 74 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 Project/ControlElementSolver.cpp (limited to 'Project/ControlElementSolver.cpp') diff --git a/Project/ControlElementSolver.cpp b/Project/ControlElementSolver.cpp new file mode 100644 index 0000000..799ca57 --- /dev/null +++ b/Project/ControlElementSolver.cpp @@ -0,0 +1,74 @@ +#include "ControlElementSolver.h" + +#include "ControlElementContainer.h" +#include "ControlEditor.h" +#include "ConnectionLine.h" +#include "Constant.h" +#include "Exponential.h" +#include "Gain.h" +#include "IOControl.h" +#include "Limiter.h" +#include "Multiplier.h" +#include "RateLimiter.h" +#include "Sum.h" +#include "TransferFunction.h" + +ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, double timeStep, bool startAllZero, double input) +{ + m_ctrlContainer = new ControlElementContainer(); + m_ctrlContainer->FillContainer(controlEditor); + + //Check if the sistem have one input and one output + bool fail = false; + wxString failMessage = ""; + auto ioList = m_ctrlContainer->GetIOControlList(); + if(ioList.size() != 2) { + fail = true; + failMessage = _("The control system must have one input and one output."); + } + bool haveInput, haveOutput; + haveInput = haveOutput = false; + for(auto it = ioList.begin(), itEnd = ioList.end(); it != itEnd; ++it) { + IOControl* io = *it; + if(io->GetType() == Node::NODE_OUT) { + m_inputControl = io; + haveInput = true; + } + else if(io->GetType() == Node::NODE_IN) { + m_outputControl = io; + haveOutput = true; + } + } + if(!fail && !haveInput) { + fail = true; + failMessage = _("There is no input in the control system."); + } + if(!fail && !haveOutput) { + fail = true; + failMessage = _("There is no output in the control system."); + } + + if(fail) { + wxMessageDialog msgDialog(controlEditor, failMessage, _("Error"), wxOK | wxCENTRE | wxICON_ERROR); + msgDialog.ShowModal(); + } + + m_timeStep = timeStep; + if(!startAllZero) InitializeValues(input); +} + +void ControlElementSolver::InitializeValues(double input) +{ + +} + +void ControlElementSolver::SolveNextStep(double input) +{ + auto connectionLineList = m_ctrlContainer->GetConnectionLineList(); + for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) { + ConnectionLine* cLine = *it; + cLine->SetSolved(false); + } + // Get first node (connected with input) + ConnectionLine +} \ No newline at end of file -- cgit From 74d795cb074b6ae9aa93bcfacee8995d7e6d5945 Mon Sep 17 00:00:00 2001 From: Thales Lima Oliveira Date: Sat, 6 May 2017 18:28:23 -0300 Subject: Streight control solver implemented Buggy, running 2x... Why?? --- Project/ControlElementSolver.cpp | 114 +++++++++++++++++++++++++++++++++------ 1 file changed, 99 insertions(+), 15 deletions(-) (limited to 'Project/ControlElementSolver.cpp') diff --git a/Project/ControlElementSolver.cpp b/Project/ControlElementSolver.cpp index 799ca57..d1c9b26 100644 --- a/Project/ControlElementSolver.cpp +++ b/Project/ControlElementSolver.cpp @@ -13,12 +13,15 @@ #include "Sum.h" #include "TransferFunction.h" -ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, double timeStep, bool startAllZero, double input) +ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, + double timeStep, + bool startAllZero, + double input) { m_ctrlContainer = new ControlElementContainer(); m_ctrlContainer->FillContainer(controlEditor); - - //Check if the sistem have one input and one output + + // Check if the sistem have one input and one output bool fail = false; wxString failMessage = ""; auto ioList = m_ctrlContainer->GetIOControlList(); @@ -33,8 +36,7 @@ ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, double if(io->GetType() == Node::NODE_OUT) { m_inputControl = io; haveInput = true; - } - else if(io->GetType() == Node::NODE_IN) { + } else if(io->GetType() == Node::NODE_IN) { m_outputControl = io; haveOutput = true; } @@ -47,28 +49,110 @@ ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, double fail = true; failMessage = _("There is no output in the control system."); } - + if(fail) { wxMessageDialog msgDialog(controlEditor, failMessage, _("Error"), wxOK | wxCENTRE | wxICON_ERROR); msgDialog.ShowModal(); } - + m_timeStep = timeStep; if(!startAllZero) InitializeValues(input); } -void ControlElementSolver::InitializeValues(double input) -{ - -} - +void ControlElementSolver::InitializeValues(double input) {} void ControlElementSolver::SolveNextStep(double input) { + // Set all elements as not solved + auto elementList = m_ctrlContainer->GetControlElementsList(); + for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) { + ControlElement* element = *it; + element->SetSolved(false); + } auto connectionLineList = m_ctrlContainer->GetConnectionLineList(); for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) { ConnectionLine* cLine = *it; cLine->SetSolved(false); } - // Get first node (connected with input) - ConnectionLine -} \ No newline at end of file + + // Get first node and set input value on connected lines + ConnectionLine* firstConn = static_cast(m_inputControl->GetChildList()[0]); + m_inputControl->SetSolved(); + firstConn->SetValue(input); + firstConn->SetSolved(); + FillAllConnectedChildren(firstConn); + + // Set value to the connected lines in constants + auto constantList = m_ctrlContainer->GetConstantList(); + for(auto it = constantList.begin(), itEnd = constantList.end(); it != itEnd; ++it) { + Constant* constant = *it; + constant->SetSolved(); + ConnectionLine* child = static_cast(constant->GetChildList()[0]); + child->SetValue(constant->GetValue()); + child->SetSolved(); + FillAllConnectedChildren(child); + } + + ConnectionLine* currentLine = firstConn; + while(currentLine) { + wxMessageBox(wxString::Format("%d", currentLine->GetID())); + currentLine = SolveNextElement(currentLine); + } +} + +void ControlElementSolver::FillAllConnectedChildren(ConnectionLine* parent) +{ + auto childList = parent->GetLineChildList(); + for(auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) { + ConnectionLine* child = *it; + child->SetValue(parent->GetValue()); + child->SetSolved(); + FillAllConnectedChildren(child); + } +} + +ConnectionLine* ControlElementSolver::SolveNextElement(ConnectionLine* currentLine) +{ + auto parentList = currentLine->GetParentList(); + for(auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) { + ControlElement* element = static_cast(*it); + // Solve the unsolved parent. + if(!element->IsSolved()) { + if(!element->Solve(currentLine->GetValue())) return NULL; + element->SetSolved(); + + // Get the output node (must have one or will result NULL). + Node* outNode = NULL; + auto nodeList = element->GetNodeList(); + for(auto itN = nodeList.begin(), itNEnd = nodeList.end(); itN != itNEnd; ++itN) { + Node* node = *itN; + if(node->GetNodeType() == Node::NODE_OUT) + outNode = node; + } + if(!outNode) return NULL; + + // Set connection line value associated with the output node. + auto childList = element->GetChildList(); + for(auto itC = childList.begin(), itCEnd = childList.end(); itC != itCEnd; ++itC) { + ConnectionLine* cLine = static_cast(*itC); + if(!cLine->IsSolved()) { // Only check unsolved lines + // Check if the connection line have the output node on the list + auto lineNodeList = cLine->GetNodeList(); + for(auto itCN = nodeList.begin(), itCNEnd = nodeList.end(); itCN != itCNEnd; ++itCN) { + Node* childNode = *itCN; + if(childNode == outNode) { + // Check if the line connect two elements, otherwise return NULL + if(cLine->GetType() != ConnectionLine::ELEMENT_ELEMENT) return NULL; + + // Set the connection line value and return it. + cLine->SetValue(element->GetOutput()); + cLine->SetSolved(); + FillAllConnectedChildren(cLine); + return cLine; + } + } + } + } + } + } + return NULL; +} -- cgit From 9fb33a91aa22fbce6d0b74529e07af9f7781b916 Mon Sep 17 00:00:00 2001 From: Thales Lima Oliveira Date: Mon, 8 May 2017 21:43:17 -0300 Subject: Secondary branch, TF and limiter solution much work, such results --- Project/ControlElementSolver.cpp | 86 ++++++++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 16 deletions(-) (limited to 'Project/ControlElementSolver.cpp') diff --git a/Project/ControlElementSolver.cpp b/Project/ControlElementSolver.cpp index d1c9b26..42445f4 100644 --- a/Project/ControlElementSolver.cpp +++ b/Project/ControlElementSolver.cpp @@ -15,6 +15,7 @@ ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, double timeStep, + double integrationError, bool startAllZero, double input) { @@ -56,10 +57,36 @@ ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, } m_timeStep = timeStep; - if(!startAllZero) InitializeValues(input); + m_integrationError = integrationError; + InitializeValues(input, startAllZero); +} + +void ControlElementSolver::InitializeValues(double input, bool startAllZero) +{ + // Reset Elements values + auto elementList = m_ctrlContainer->GetControlElementsList(); + for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) { + ControlElement* element = *it; + element->SetSolved(false); + element->SetOutput(0.0); + } + auto tfList = m_ctrlContainer->GetTFList(); + for(auto it = tfList.begin(), itEnd = tfList.end(); it != itEnd; ++it) { + TransferFunction* tf = *it; + tf->CalculateSpaceState(m_timeStep, m_integrationError); + } + auto connectionLineList = m_ctrlContainer->GetConnectionLineList(); + for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) { + ConnectionLine* cLine = *it; + cLine->SetSolved(false); + cLine->SetValue(0.0); + } + + if(!startAllZero) { + // Calculate the steady-state results according to the input. + } } -void ControlElementSolver::InitializeValues(double input) {} void ControlElementSolver::SolveNextStep(double input) { // Set all elements as not solved @@ -73,7 +100,7 @@ void ControlElementSolver::SolveNextStep(double input) ConnectionLine* cLine = *it; cLine->SetSolved(false); } - + // Get first node and set input value on connected lines ConnectionLine* firstConn = static_cast(m_inputControl->GetChildList()[0]); m_inputControl->SetSolved(); @@ -85,17 +112,45 @@ void ControlElementSolver::SolveNextStep(double input) auto constantList = m_ctrlContainer->GetConstantList(); for(auto it = constantList.begin(), itEnd = constantList.end(); it != itEnd; ++it) { Constant* constant = *it; - constant->SetSolved(); - ConnectionLine* child = static_cast(constant->GetChildList()[0]); - child->SetValue(constant->GetValue()); - child->SetSolved(); - FillAllConnectedChildren(child); + if(constant->GetChildList().size() == 1) { + constant->SetSolved(); + ConnectionLine* child = static_cast(constant->GetChildList()[0]); + child->SetValue(constant->GetValue()); + child->SetSolved(); + FillAllConnectedChildren(child); + } } - + ConnectionLine* currentLine = firstConn; while(currentLine) { - wxMessageBox(wxString::Format("%d", currentLine->GetID())); + ConnectionLine* lastLine = currentLine; currentLine = SolveNextElement(currentLine); + if(!currentLine) m_solutions.push_back(lastLine->GetValue()); + } + + bool haveUnsolvedElement = true; + while(haveUnsolvedElement) { + haveUnsolvedElement = false; + // Get the solved line connected with unsolved element (elements not connected in the main branch). + for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) { + ConnectionLine* cLine = *it; + if(cLine->IsSolved()) { + auto parentList = cLine->GetParentList(); + for(auto itP = parentList.begin(), itPEnd = parentList.end(); itP != itPEnd; ++itP) { + ControlElement* parent = static_cast(*itP); + if(!parent->IsSolved()) { + haveUnsolvedElement = true; + // Solve secondary branch. + currentLine = cLine; + while(currentLine) { + currentLine = SolveNextElement(currentLine); + } + break; + } + } + } + if(haveUnsolvedElement) break; + } } } @@ -119,22 +174,21 @@ ConnectionLine* ControlElementSolver::SolveNextElement(ConnectionLine* currentLi if(!element->IsSolved()) { if(!element->Solve(currentLine->GetValue())) return NULL; element->SetSolved(); - + // Get the output node (must have one or will result NULL). Node* outNode = NULL; auto nodeList = element->GetNodeList(); for(auto itN = nodeList.begin(), itNEnd = nodeList.end(); itN != itNEnd; ++itN) { Node* node = *itN; - if(node->GetNodeType() == Node::NODE_OUT) - outNode = node; + if(node->GetNodeType() == Node::NODE_OUT) outNode = node; } if(!outNode) return NULL; - + // Set connection line value associated with the output node. auto childList = element->GetChildList(); for(auto itC = childList.begin(), itCEnd = childList.end(); itC != itCEnd; ++itC) { ConnectionLine* cLine = static_cast(*itC); - if(!cLine->IsSolved()) { // Only check unsolved lines + if(!cLine->IsSolved()) { // Only check unsolved lines // Check if the connection line have the output node on the list auto lineNodeList = cLine->GetNodeList(); for(auto itCN = nodeList.begin(), itCNEnd = nodeList.end(); itCN != itCNEnd; ++itCN) { @@ -142,7 +196,7 @@ ConnectionLine* ControlElementSolver::SolveNextElement(ConnectionLine* currentLi if(childNode == outNode) { // Check if the line connect two elements, otherwise return NULL if(cLine->GetType() != ConnectionLine::ELEMENT_ELEMENT) return NULL; - + // Set the connection line value and return it. cLine->SetValue(element->GetOutput()); cLine->SetSolved(); -- cgit From 4269e9370873ac31fe671c710536958ca4374aad Mon Sep 17 00:00:00 2001 From: Thales Lima Oliveira Date: Wed, 10 May 2017 18:27:30 -0300 Subject: All element's solutions implemented Initialization is missing --- Project/ControlElementSolver.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'Project/ControlElementSolver.cpp') diff --git a/Project/ControlElementSolver.cpp b/Project/ControlElementSolver.cpp index 42445f4..a1aee27 100644 --- a/Project/ControlElementSolver.cpp +++ b/Project/ControlElementSolver.cpp @@ -75,6 +75,11 @@ void ControlElementSolver::InitializeValues(double input, bool startAllZero) TransferFunction* tf = *it; tf->CalculateSpaceState(m_timeStep, m_integrationError); } + auto rateLimiterList = m_ctrlContainer->GetRateLimiterList(); + for(auto it = rateLimiterList.begin(), itEnd = rateLimiterList.end(); it != itEnd; ++it) { + RateLimiter* rl = *it; + rl->SetTimeStep(m_timeStep); + } auto connectionLineList = m_ctrlContainer->GetConnectionLineList(); for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) { ConnectionLine* cLine = *it; @@ -84,6 +89,8 @@ void ControlElementSolver::InitializeValues(double input, bool startAllZero) if(!startAllZero) { // Calculate the steady-state results according to the input. + double minError = 1e-6; + } } @@ -123,9 +130,9 @@ void ControlElementSolver::SolveNextStep(double input) ConnectionLine* currentLine = firstConn; while(currentLine) { - ConnectionLine* lastLine = currentLine; + //ConnectionLine* lastLine = currentLine; currentLine = SolveNextElement(currentLine); - if(!currentLine) m_solutions.push_back(lastLine->GetValue()); + //if(!currentLine) m_solutions.push_back(lastLine->GetValue()); } bool haveUnsolvedElement = true; @@ -152,6 +159,13 @@ void ControlElementSolver::SolveNextStep(double input) if(haveUnsolvedElement) break; } } + + // Set the control system step output. + if(m_outputControl->GetChildList().size() == 1) { + ConnectionLine* cLine = static_cast(m_outputControl->GetChildList()[0]); + m_solutions.push_back(cLine->GetValue()); + } + else m_solutions.push_back(0.0); } void ControlElementSolver::FillAllConnectedChildren(ConnectionLine* parent) -- cgit From 6cf253651521f0cdaf3a80f8ae58e9917fe2ec57 Mon Sep 17 00:00:00 2001 From: Thales Lima Oliveira Date: Thu, 11 May 2017 17:07:11 -0300 Subject: Initialization implemented --- Project/ControlElementSolver.cpp | 62 ++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 12 deletions(-) (limited to 'Project/ControlElementSolver.cpp') diff --git a/Project/ControlElementSolver.cpp b/Project/ControlElementSolver.cpp index a1aee27..d48e39f 100644 --- a/Project/ControlElementSolver.cpp +++ b/Project/ControlElementSolver.cpp @@ -51,17 +51,22 @@ ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, failMessage = _("There is no output in the control system."); } + m_timeStep = timeStep; + m_integrationError = integrationError; + if(!InitializeValues(input, startAllZero)) { + fail = true; + failMessage = _("It was not possible to initialize the control system."); + } + if(fail) { wxMessageDialog msgDialog(controlEditor, failMessage, _("Error"), wxOK | wxCENTRE | wxICON_ERROR); msgDialog.ShowModal(); + } else { + m_isOK = true; } - - m_timeStep = timeStep; - m_integrationError = integrationError; - InitializeValues(input, startAllZero); } -void ControlElementSolver::InitializeValues(double input, bool startAllZero) +bool ControlElementSolver::InitializeValues(double input, bool startAllZero) { // Reset Elements values auto elementList = m_ctrlContainer->GetControlElementsList(); @@ -88,10 +93,43 @@ void ControlElementSolver::InitializeValues(double input, bool startAllZero) } if(!startAllZero) { + // double origTimeStep = m_timeStep; // Calculate the steady-state results according to the input. - double minError = 1e-6; - + double minError = 1e-7 * m_timeStep; + int minIteration = 20; + int maxIteration = 100 / m_timeStep; + //double timeStep = 0.1; // Initial value is the maximum step value. + /* + // Get the minimum time step + for(auto it = tfList.begin(), itEnd = tfList.end(); it != itEnd; ++it) { + TransferFunction* tf = *it; + std::vector num = tf->GetNumerator(); + std::vector den = tf->GetDenominator(); + for(unsigned int i = 0; i < num.size(); ++i) { + if(num[i] < timeStep) timeStep = num[i]; + } + for(unsigned int i = 0; i < den.size(); ++i) { + if(den[i] < timeStep) timeStep = den[i]; + } + } + m_timeStep = timeStep;*/ + + double prevSol = 0.0; + double currentSol = 1.0; + int numIt = 0; + while(std::abs(prevSol - currentSol) > minError || numIt <= minIteration) { + prevSol = currentSol; + SolveNextStep(input); + currentSol = GetLastSolution(); + numIt++; + if(numIt >= maxIteration) return false; + } + wxMessageBox(wxString::Format("%d\n%e\n%f", numIt, minError,currentSol)); + // m_timeStep = origTimeStep; + m_solutions.clear(); } + + return true; } void ControlElementSolver::SolveNextStep(double input) @@ -130,9 +168,9 @@ void ControlElementSolver::SolveNextStep(double input) ConnectionLine* currentLine = firstConn; while(currentLine) { - //ConnectionLine* lastLine = currentLine; + // ConnectionLine* lastLine = currentLine; currentLine = SolveNextElement(currentLine); - //if(!currentLine) m_solutions.push_back(lastLine->GetValue()); + // if(!currentLine) m_solutions.push_back(lastLine->GetValue()); } bool haveUnsolvedElement = true; @@ -159,13 +197,13 @@ void ControlElementSolver::SolveNextStep(double input) if(haveUnsolvedElement) break; } } - + // Set the control system step output. if(m_outputControl->GetChildList().size() == 1) { ConnectionLine* cLine = static_cast(m_outputControl->GetChildList()[0]); m_solutions.push_back(cLine->GetValue()); - } - else m_solutions.push_back(0.0); + } else + m_solutions.push_back(0.0); } void ControlElementSolver::FillAllConnectedChildren(ConnectionLine* parent) -- cgit From d44c3a76943c90cfcbf336961d9ba3516a1c80dc Mon Sep 17 00:00:00 2001 From: Thales Lima Oliveira Date: Sat, 13 May 2017 16:13:12 -0300 Subject: Several bugs fixed, ready to pull --- Project/ControlElementSolver.cpp | 63 ++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 32 deletions(-) (limited to 'Project/ControlElementSolver.cpp') diff --git a/Project/ControlElementSolver.cpp b/Project/ControlElementSolver.cpp index d48e39f..e67cb9a 100644 --- a/Project/ControlElementSolver.cpp +++ b/Project/ControlElementSolver.cpp @@ -50,12 +50,20 @@ ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, fail = true; failMessage = _("There is no output in the control system."); } + if(!fail) { + if(m_inputControl->GetChildList().size() == 0) { + fail = true; + failMessage = _("Input not connected."); + } + } m_timeStep = timeStep; m_integrationError = integrationError; - if(!InitializeValues(input, startAllZero)) { - fail = true; - failMessage = _("It was not possible to initialize the control system."); + if(!fail) { + if(!InitializeValues(input, startAllZero)) { + fail = true; + failMessage = _("It was not possible to initialize the control system."); + } } if(fail) { @@ -78,12 +86,7 @@ bool ControlElementSolver::InitializeValues(double input, bool startAllZero) auto tfList = m_ctrlContainer->GetTFList(); for(auto it = tfList.begin(), itEnd = tfList.end(); it != itEnd; ++it) { TransferFunction* tf = *it; - tf->CalculateSpaceState(m_timeStep, m_integrationError); - } - auto rateLimiterList = m_ctrlContainer->GetRateLimiterList(); - for(auto it = rateLimiterList.begin(), itEnd = rateLimiterList.end(); it != itEnd; ++it) { - RateLimiter* rl = *it; - rl->SetTimeStep(m_timeStep); + tf->CalculateSpaceState(100, m_integrationError); } auto connectionLineList = m_ctrlContainer->GetConnectionLineList(); for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) { @@ -93,39 +96,37 @@ bool ControlElementSolver::InitializeValues(double input, bool startAllZero) } if(!startAllZero) { - // double origTimeStep = m_timeStep; + double origTimeStep = m_timeStep; + double minStep = m_timeStep / 10; + double maxStep = m_timeStep * 10; // Calculate the steady-state results according to the input. double minError = 1e-7 * m_timeStep; - int minIteration = 20; int maxIteration = 100 / m_timeStep; - //double timeStep = 0.1; // Initial value is the maximum step value. - /* - // Get the minimum time step - for(auto it = tfList.begin(), itEnd = tfList.end(); it != itEnd; ++it) { - TransferFunction* tf = *it; - std::vector num = tf->GetNumerator(); - std::vector den = tf->GetDenominator(); - for(unsigned int i = 0; i < num.size(); ++i) { - if(num[i] < timeStep) timeStep = num[i]; - } - for(unsigned int i = 0; i < den.size(); ++i) { - if(den[i] < timeStep) timeStep = den[i]; - } - } - m_timeStep = timeStep;*/ double prevSol = 0.0; double currentSol = 1.0; + double error = 1.0; + double prevError = 1.0; int numIt = 0; - while(std::abs(prevSol - currentSol) > minError || numIt <= minIteration) { + while(error > minError) { prevSol = currentSol; + prevError = error; SolveNextStep(input); currentSol = GetLastSolution(); numIt++; + error = std::abs(prevSol - currentSol); + if(std::abs(error - prevError) < 1e-1) { + if(m_timeStep < maxStep) { + m_timeStep *= 1.5; + } + } else if(std::abs(error - prevError) > 10) { + if(m_timeStep > minStep) { + m_timeStep /= 1.5; + } + } if(numIt >= maxIteration) return false; } - wxMessageBox(wxString::Format("%d\n%e\n%f", numIt, minError,currentSol)); - // m_timeStep = origTimeStep; + m_timeStep = origTimeStep; m_solutions.clear(); } @@ -168,9 +169,7 @@ void ControlElementSolver::SolveNextStep(double input) ConnectionLine* currentLine = firstConn; while(currentLine) { - // ConnectionLine* lastLine = currentLine; currentLine = SolveNextElement(currentLine); - // if(!currentLine) m_solutions.push_back(lastLine->GetValue()); } bool haveUnsolvedElement = true; @@ -224,7 +223,7 @@ ConnectionLine* ControlElementSolver::SolveNextElement(ConnectionLine* currentLi ControlElement* element = static_cast(*it); // Solve the unsolved parent. if(!element->IsSolved()) { - if(!element->Solve(currentLine->GetValue())) return NULL; + if(!element->Solve(currentLine->GetValue(), m_timeStep)) return NULL; element->SetSolved(); // Get the output node (must have one or will result NULL). -- cgit