Tuesday, September 8, 2026

Steady state solution

Intro

The need for, and use of a steady state solution is a peculiar thing. A steady state solution can be a different thing for different purposes. In the area of simulation it is usually one of:

  1. It's the solution one seeks.
  2. It's the state for which one wants to do perturbations around. Typically for control/governor analysis.
  3. It's the starting point for a transient simulation. For waterhammer analysis it's the state just before closing the valve or shutting down the turbine for instance.
No matter the use cause, it's important to get the steady state correct, or everything else will also be wrong.

The normal handling of steady state

Looking at the 3 cases above, this is often handled as follows.

Case 1. The use of a steady state solver is the normal procedure to find the steady state. The transients are not of interrest in this case. Steady state solvers are made to converge fast and efficient. In some cases though, a set of boundary conditions could satisfy several steady state solutions. The particular solution is dependent on the previous trajectory. A transient solver will reach all of these solutions in a meaningful way. This is not possible with a dedicated steady state solver.  

Case 2. The use of a steady state solver is a good thing, but it's not crucially necessary for this case. It's not the accuracy in the number of decimal places that is of interest, but the correct dynamic behavior.

Case 3. You set a start time and an end time and push "run". Then look at the results. This leads to a way of thinking that needs a steady state solution, and thus a steady state solver to set the state before the transient analysis. Even Wylie and Streeter in the examples in the book, solves the steady state separately before doing the transient analysis.

Another way of thinking is with an interactive transient software, every need for a separate steady state solutions disappears.

LVTrans and steady state

LVTrans has only one way of calculating. It's a continuous simulation in time of the system. There's no start or ending. No start or ending of any interest at least. There's no separate steady state solver. Yet, all the use cases for a steady state solution are handled just fine with the highest precision.

A key in making this possible and perfectly intuitive, is interactive simulation. Just start the simulation, then while it is running, interactively do the things needed to create the analysis you want.

Case 1

A transient solver is always also a steady state solver. Just set the wanted power and the correct boundary conditions, and the solution is there within seconds. Let it run, adjust to new boundary values and the next solution is ready in seconds.

Case 2

Steady state is obtained as in Case 1. Then frequency response analysis is automatically done with the push of a button. Frequency domain values are obtained through FFT of the saved values. This makes it not only correct, but also enables one to see the amplitude dependence.

The effect of nonlinearities, and how the amplitude will affect damping and the nonlinearities can be studied. Hydro powerplants are very susceptible to transient damping and amplitudes regarding stability. Such things can be analyzed, in every detail.

Case 3 

Obviously the transient simulation is started once the steady state is achieved. The results are logged for further display and analysis, or the interactive graphs are used directly. No switching or transfer of data is needed.


Shortcomings

There are very few shortcoming to this method of analysis, but a couple of shortcomings come to mind. 

For instance, one can be interested in the steady state level of a surge shaft for all possible variations of power and reservoir levels. To get this result, a dedicated steady state solver would be faster. However, this is essentially a batch process in any case. A matrix of states has to be entered and the simulation has to automatically run these states one by one and output the result.

It's no problem creating such a batch process. It's essentially what is already done in some of the analyses in the digital twin version of LVTrans. For "pure" LVTrans no such batch process exists, but it certainly is on the roadmap.

Another shortcoming is there's no ability to do different transient simulations starting from the exact same steady state without first calculating that steady state for each run. This requires the state to be saved. For a state to be saved, all internal variables must be saved. This is not possible in LVTrans today. Taking this a step furter one also would like to save the state at any arbitrary time, also in the middle of a transient. This would be very helpfull in several ways, especially for digital twins and doing predictive control more efficiently.


Summary

Having done transient simulations for over 30 years, I have never really missed having a dedicated steady state solver as a part of the simulation. However, the transient simulation would improve considerably by including the ability to do batch processing and the ability to completely save the state at arbitrary times, and the corresponding ability to load these states and continue simulating from there.

Tuesday, March 17, 2026

The basic MOC algorithm for a system

The Method of Characteristics - MOC

To get the full understanding, MOC should be explained in more detail. That's for a later post. For the time being I just refer to Wylie and Streeter and Wikipedia:

In mathematics, the method of characteristics is a technique for solving particular partial differential equations. Typically, it applies to first-order equations, though in general characteristic curves can also be found for hyperbolic and parabolic partial differential equation. The method is to reduce a partial differential equation (PDE) to a family of ordinary differential equations (ODEs) along which the solution can be integrated from some initial data given on a suitable hypersurface.


Explained below is the basic system algorithm for MOC in a system, not MOC itself. It's how it is programmed in LVTrans, and how it will be programmed in any eventual future versions.


System of hydraulic pipes

Each hydraulic pipe is modelled with MOC. A Pipe has a length and two ends. Each of these ends must be connected to a "non pipe" element, called NP. This NP element is typically a valve, a T-joint, a turbine, a reservoir but can also simply be an open or closed end of the Pipe. Thus for each Pipe, the NP represent the spatial boundary elements at each end.

Each NP can have one or more boundaries. These boundaries are typically Pipes, but can also be other NP elements. An example is a PID for a turbine. Many of these NP elements also have natural boundaries. For instance, a reservoir can be connected to one or several pipes but also have a surface level that is relatively constant seen in relation to waterhammer transients. This surface level is a natural boundary condition. The surface level can also vary, and can be measured and given as input for a digital twin.


The figure above shows a simple system of Pipes and NPs. Each Pipe has an arrow towards the NP elements. Why becomes apparent soon.

Basic element algorithm

Each pipe is divided into smaller sections. For each time step, the H and Q (head and flow) for each section is calculated based on the values for the previous time step. The boundaries are yet unknown, but the C+ and C- characteristics can be calculated. This is how far each Pipe can be calculated alone. All the internal values and the C+ and C+ characteristics at the boundaries. What is missing is the H and Q at each end.

Each NP element do almost the same. They start with the values from previous time step and the C+ and C- characteristics from the connecting pipes that just were calculated. All the inner variables and the H and Q at the boundaries can be fully resolved. These H and Q are then sent back to each pipe and make their calculations complete. Now the time step is fully resolved everywhere. The procedure is repeated for the next time step and so on.

Note that NP elements normally use Runge-Kutta or Newton-Raphson methods.

NP elements also can have manual inputs. For instance the opening of a valve. This is also updated for each time step.

MOC System algorithm



From the figure the full arrows are the C+ and C- characteristics at each end of the pipe. The back propagation of H and Q at the boundaries are the dotted lines. The PID does not send H, Q or C, but rather sends A and receives B, where A and B typically but not necessarily, are guide vane opening and turbine speed.

The MOC system algorithm therefore becomes:
  1. For all Pipes and (PID).
    1. Calculate the internal variables; H Q and predict the A in (PID) for T1 based on T0
    2. Send C+, C- and A to each connected NP element
  2. For all NP elements
    1.  Calculate all internal variables and the boundary values for T1 based on T0 and values received from Pipe and (PID)
    2. Iterate each NP-PID pair once more to correct the predicted A if needed*.
    3. Send H, Q and B to each Pipe and (PID)
  3. Update the boundary H and Q for each pipe and B for the (PID)
  4. Start at 1 again for the next time step.

Programmatically there are many ways to to this depending on choice and the programming language. In "native" LVTrans these connections happens almost by itself. It's the way LabVIEW works by default. In a text based programming language this can be done by lists or arrays of Pipes and NPs. A major point is that the inner workings and transfer of values of each element is the same no matter how this is done. An independent library of MOC can thus be made. Here independent means independent from the actual implementation of the MOC system algorithm. 

*Note that the (PID) is not a Pipe with MOC inside. It does not have analytically correct C+ and C- characteristics for T1. The initial A it sends is a forward in time predicted value at T1 based on the time step T0 for all variables in (PID) including B. The B which is sent back from NP, is based on this predicted value of A. This B is used to update all variables inside (PID) and can be used to correct the predicted value of A at T1. This corrected value can be sent once more for a new iteration in the connected NP. Default is a predictor method. One extra iteration becomes a predictor-corrector method. An error analysis of this is found in the LVTrans manual, and is a part of choosing the correct time step.

It must be noted that the initial "error" comes from the fact that the B used when calculating the PID at T1 comes from the previous time step T0. This is also very much what happens in real life. The update frequency of a real PID is seldom better than 0.01 Hz for practical purposes. There's no reason it should be faster than this, because the physical frequencies for which it shall control is already several decades lower. What all this means is that with a time step in the simulation of roughly 0.05 s or lower, none of this matters - at all. This is also explained in detail in the LVTrans manual (I may also write a blog post at some time).  

In Wylie and Streeter the procedure is to gather all connected NP elements together and iterate them as one single block with regard to connected Pipe elements. In practice this is equivalent to an NP-NP pair iteration. It's a matter of choice, but the method of Wylie and Streeter may be more practical for blocks of NPs with more than two NPs. Such blocks never happens in LVTrans. With the exception of PID elements, it's probably more practical to create separate elements where larger collections of NP blocks are are pre-made.  

Conclusion

The MOC system algorithm is very simple. MOC is also superfast. Orders of magnitude faster than anything else while being analytically correct and with no numerical artifacts. With an object oriented approach for each elements, the same core library can be used in several different applications. This is very useful when different use cases are needed.

Monday, March 16, 2026

Ponderings about the future of open source transient simulation software

Intro

It's more than 25 years ago since LVTrans started. Lots have happened during that time. Neither AI or Python existed in some generally usable form 25 years ago, but today AI and Python are everywhere along with many other new and modern programming languages.

My first programming was done with interpreted BASIC on a Commodore 64. At computer courses at the university I learned Pascal and then FORTRAN. I liked them both. Then came C and C++ and ruled the world. I wrote a FEM software in C++ for my PhD, linking in FORTRAN matrix library. Compilers were expensive stuff. I used Watcom, which was the only one that really could combine C/C++ and FORTRAN. Today compilers are free and open source and can link in whatever other language you want.


C/C++ and FORTRAN

Even though FORTRAN has received more attention lately due to vector programming and AI/machine learning, it's still very specialized. Perfect for "hard numerical computing" but not particularly suited for anything else. C/C++ is still popular and can be used for everything. Compared with newer languages, C/C++ is complicated and not particularly suited for the casual programmer or engineers cheating in the field. I really like the cheer power, the brute force, of C/C++ but for the programming stuff I actually do, I always go in another direction, a simpler direction that gets the job done faster.


High level specialization

Another kind of programming has developed during the years, partly from academia, partly from the industry and goes way back. This is Matlab/Simulink, LabVIEW, Modelica, Scilab/Xcos and so on. Of these it's Labview first and foremost I have used but I have also used Scilab/Xcos a lot. Then there's Excel with Visual Basic/C or whatever "Visual" it has these days. It's a very powerful tool for a wide variety of tasks. All of them are perfect tools for the casual programmer and engineer who don't want to make an app, but rather want to get solutions to engineering problems.


Python

In comes Python. It has existed since long, but remained in the shadows for a long time. The largest effect in engineering and academia is that it has made Matlab etc. much less relevant. Matlab has still some considerable momentum due to its sheer size (and perhaps it's similarities with Python), but LabVIEW has gone backwards. It's no longer in the top 50 at the TIOBE index. Ladder Logic (PLC) and COBOL are much more popular. I never envisioned LabVIEW to become anything like C/C++ in popularity, but didn't really envision the ill fate it has received either. An open source program on a programming language that hardly exists anymore is a real tough hill to climb.


What to do?

The question is what to do. Does anything need to be done? LabVIEW is not likely to simply disappear from the face of the earth, but it will perhaps shrink in generality and focus more on the stuff it's actually designed to do. The choice of LabVIEW for LVTrans was more of a coincidence anyway. I was doing some LabVIEW work in the lab, and was asked to do a transient analysis of acoustics in gas risers. I said yes, and got myself a license of the commercial transient simulation software Flowmaster. It turned out that Flowmaster couldn't handle the particular problem, so I made a quick MOC solver for one pipe in LabVIEW that could. The Method of Characteristics (MOC) is very easy to program, for one pipe at least. The rest is history.

There have been several good points about this:

  • LabVIEW is compiled to machine code, and is relatively fast. About 1/3-1/2 the speed of C in my experience. Sometimes even directly comparable to C.
  • All graphics, graphs and charts are already there, professional looking and ready to use.
  • The LabVIEW programming environment is used directly in setting up systems. It's very functional and easy to use, and additionally sets and organize the topology of the system.
This has enabled me to work as an engineer, doing lots of other stuff, while still maintaining and developing LVTrans, and using it in my work. There is no way this would have been possible in C/C++ for instance. Using Matlab (or Python for that matter) would be too slow execution vise. Last, but not least, LVTrans is also used as the numerical core in digital twins at Aker Solutions This is due to its speed and the native embeddedness of LabVIEW. It was just a matter of compiling it down to one of National Instrument's boxes, very simplistically speaking. 

It's safe to say that LabVIEW has served me well. It has enabled me to get the job done just perfectly. I have never been super happy with the solution though. The open source part has never taken off to put it mildly. Closed proprietary binary source code is no boost for open source (have to put in a "duh" here :-) ) 12-13 years ago I started making a C++ library. I never finished that, but I still have it for the core MOC solver. In the beginning, LVTrans actually had the core MOC solver programmed in (pure) C for 3-4 years. The long term plan was always to finish the C++ library and move on from there. Due to being busy with work, it never happened. Linking in the C++ library as DLL, LVTrans will be the same. LabVIEW would be used as the HMI only, while the numerical core could move on to other projects. It would be free and truly open source.

C++ or? 

Is C++ the right way forward today? In some ways yes, in other ways no. It's perfect for the job, but C++ is bloated and overly complicated for this simple job. There are other languages today that could be much better suited. Even professional programmers find C++ to be overkill for most of the work they do, or simply not suited and not efficient enough. I don't need efficiency as such, but there is a strong correlation between efficiency and having the right tool for the job.

This is where I'm right now. Is C++ the right tool for the job today, and if not, which other options are there. One of my sons is a lead programmer in IT now. He has opened my eyes to other stuff. Lots have happened in the last 25 years, lots more than just Python and AI. That's for another post.

Friday, September 12, 2025

Frequency Containment Reserve (FCR)

 Frequency Containment Reserve (FCR) is a new method and a service for containing the frequency on the grid during large and fast initial deviations.

FCR requires that the power-plant is qualified up front doing tests on site. This qualification is rather elaborate. It is also very costly because the plant will be off grid for roughly a week. A substantial amount of planning and preparations must be done to assure efficient tests, yet there is no guaranty up front that the plant is suitable. Statnett is responsible for this qualifications together with entso-e. A bit surprisingly, the qualification scheme describes no theoretical analysis, only on-site tests to be approved by Statnett.

Information about everything FCR can be found on Statnett web site here.

LVTrans is a transient simulation software. Since the plant is modelled in minute details, this enables transient simulations of all the FCR tests. Such a simulation will therefore be very useful. It will:

  • Assess how likely the plant is able to run FCR, and if so:
  • Determine the best possible PID parameter sets for FCR-N, FCR-D up and FCR-D down
  • Determine the ranges of droop for FCR
  • Determine the theoretical stability and performance of the plant when in FCR mode using the special FCP IT-Tool by entso-e/Svenska Kraftnät. The same tool as used in the tests on site.
Including FCR simulations using LVTrans will therefore reduce the economic risk associated with these tests dramatically. It will also enable the best possible starting point for the PID parameter sets. Less tuning on site. The low frequency sine-sweep of the tests can be dangerous for some plants since they may in a worst case scenario coincide with the resonant frequency of the waterway (surge shafts). Using LVTrans this will be analyzed and prevented.

All in all, using LVTrans up front as part of the planning and screening, will greatly enhance the possibilities for a successful, efficient and accurate FCR deployment, as well as prevent FCR deployment/tests on plants not suitable for it.

The FCR capability of LVTrans is not open source. It's much too special to have a broad interest, while at the same time requires a substantial amount of programming and testing to adhere to specifications. Interesting parties can get in contact for further information. As of today, four companies have purchased a license, enabling the development.


Links:

FCR in general

FCR and FCP IT-Tool

Thursday, October 17, 2024

PID tuning - hybrid Skogestad

What could be called a hybrid, or combined, Skogestad method will consist of the following.


1. Find Ti according to Skogestad.

The plant should run at approximately 85% of nominal power on isolated grid. Set it in manual mode and adjust the guide vane until the speed is at or very close to 50 Hz (or 60 Hz as may be the case). The speed in pu should be close to 1.0.


Find the time it takes for the speed to reach 63% of the steady state value for a step in guide vane (injectors in this particular example, since it is a Pelton) of 0.1 pu from the value above. The steady state value after the step is noted as 1,059 pu. 63% of this change becomes a speed of 1.037 pu.


This gives a Ti of 7.1 s.


2. The PID is placed in auto mode on isolated grid and with this Ti = 7.1 s. Now adjust the SP n [pu] down and up again as in the previous trial and error method. Then increase Kp until the overshoot is somewhere between 5 and 20 % depending on how aggressive the PID should be.

In this example a Kp of 3.2 will do fine, but it certainly could be more aggressive.


That's it. The Ti is as good as it gets based on the physics of the plant, and the Kp is as good as one can hope for.

For tuning at idle no load, just set the P Grid [pu] to zero. This is usually done with only one injector.

A PID could be tuned by adjusting Kp until the overspeed is about 30% in step 2. Then increase Td until the overshoot is 5 to 20%. This is similar to the trial and error method. This last step, Td, has not been tested, but is in theory a straight forward extension.

Saturday, November 11, 2023

PID tuning - modified Skogestad

As mentioned in the previous post, in some cases, particularly for servo positioning systems, it's a good idea to dive a bit deeper into the theories of tuning. One method I have found useful is the Skogestad method.

All the details can be found the linked paper. This is a modified form that I have found useful for hydro-turbines in combination with the trial and error method. The method consists of:

  • A step in input, plotting the output and the input.
  • Finding characteristic values from that plot.
  • Using a single parameter called tau_c as tuning parameter.
The reason that this method is sometimes useful for hydro turbines, is that these systems can be very dynamic and oscillating. It can therefore be very difficult to identify the 15% and 30% overshoot from the trial and error method with any accuracy at all (although not entirely impossible). The Skogestad method (modified) will give usable values in these cases, at least for Ti.

The modifications to the method are:

  • Disregard everything about time delay. Although one can often find something looking like a time delay, and it can be 2-3 seconds long, this is NOT a time delay in the normal sense, and should not be treated as one. Treating it as a time delay will in most cases produce unworkable PID parameters (instability or way too much overshoot).
  • Use a tau_c of approximately 5 as a starting point (subject to tuning, see further down)
The disadvantage of the method, is it only works for PI. It does not work for PID unless approximating the system as a second order system (which a hydro power plant definitely is not, and a rather impossible thing to do in the field anyway). A good point of the method, is that Ti always comes out with a good value. It's really only tau_c (Kp in practice) that would eventually be adjusted to fit performance specs. A tau_c of 5 is found by me as a good starting point on idealized systems. It could however be way off on real systems.


Well behaved system

Looking first at a "well behaved" system. In hydro-power plant circumstances, this will mean a very simple system, an idealized plant.

The system is set in open loop, and a step in "kappa" (guide vanes) of 10% (0.1 pu) is done. This is seen as the green line, where we also can see the speed of the servo. The red line is the turbine speed in "per units", starting at 1.0. Here we can clearly see the speed going in the opposite direction during the first 2 seconds. This is fairly typical, but it's not really a time delay. The pink line shows the 63% rise in speed and the corresponding time for that rise (approximately 5.8 seconds).


This plot is all the information we need to tune according to Skogestad, which is rather neat. We find:
  • Time constant tau_1 = 5.8 seconds
  • Steady state gain k = delta(n)/delta(kappa) = 0.063/0.1 = 0.63
According to the rules of Skogestad, pretending this is some kind of first/second order system, disregarding time delay and setting tau_c = 5, we get:
  • Kp = (1/k)(tau_1/tau_c) = (1/0.63)(5.8/5) = 1.84
  • Ti = tau_1 = 5.8 s
That's it, super simple and super fast. Tuning this plant using the trial and error approach we get Kp = 1.9 and Ti = 6.3. From a practical point of view, this is more or less identical. Both will give fairly equal performance, and both well withing specs. It's not coincidental that a well behaved system has a generator inertia constant of approximately Ta = 6, and this corresponds well to the "optimal" Ti in this case.  

A realistic system

This is a real system. It's certainly on the "fuzzy" and oscillating side, but far from unusual. Doing the same as for the idealized system, we get the plot:


We find:
  • Time constant tau_1 = 9.5 seconds
  • Steady state gain k = delta(n)/delta(kappa) = 0.022/0.1 = 0.22
Then with tau_c = 5 as before:
  • Kp = (1/k)(tau_1/tau_c) = (1/0.22)(9.5/5) = 8.63
  • Ti = tau_1 = 9.5 s
This time Ti seems reasonable, and is in line with what the trial and error method gives. Kp on the other hand seems way off, and it is. It will produce a system behaving like this:


The system will oscillate forever, the PID is unusable. Note also the slow servo speed, needed for safety reasons on this plant to prevent water hammer. Since Ti is OK, we can simply use step 5 from the trial and error approach to get a working Kp. Doing this, I find that Kp = 1.4 is as "good as it gets", and still be within performance specifications. A step response in set-point of the closed system, certainly does not look good, but the physics of the system does not allow for anything better.


In the last plot below, I have introduced anti-windup. It doesn't improve the closed loop response, but makes a smoother servo run (less wear and tear) and will have a much better performance in terms of handling disturbances because Ti is reduced considerably. This is done by trial and error.


For real systems, some trial and error usually has to be done no matter what, but Skogestad method is very helpful in obtaining Ti for systems with difficult behavior. An open loop step plot will also reveal useful information of the system. In the next post, a combined approach is shown.

Sunday, November 5, 2023

PID tuning the simple way

Tuning that works "every" time

Throughout the years I have tried every method I could find, from text book classical analytical s-plane methods to trial and error types. It's mostly turbine governors I have been working with, both in theory and in practice. The only method I have found that works almost every time, in theory and on site, is a trial and error method. Sadly I cannot find the copy of the original text, nor can I remember where I found it. I have written down the method though, ages ago.

The method requires that you are able to set the set-point arbitrarily and can read off the process value. A graphical representation is of much help rather than just numbers, although numbers works as well. The method is also described in the manual of LVTrans. The method requires no knowledge of the system, although such knowledge certainly helps.

The first thing to do is to stabilize the system. This can usually be done by setting Kp to 1 or less, and Ti to 10 or more and Td to 0. Then set the set-point (SP) to a desired value of which you are going to tune around, the operational point OP, and let the whole system settle. It's useful to have some integral value here to get the SP and the process value (PV) equal, but not strictly necessary. When this is done, and looks OK and steady state, the tuning can start.

  1. Set Ti to a really large number, or deactivate further integration if possible. In parallel form, Ki can be set to zero. Keep Td = 0. Let the system stabilize if it isn't already.
  2. Do steps in SP of approximately 10% up and down from the OP and observe the PV.
  3. Increase Kp bit by bit until an overshoot of the PV of about 15% is observed. That is 15% of the size of the step in SP, not 15% of the total PV.
  4. With the Kp from 3, decrease Ti bit by bit until the overshoot increases to around 30%.
  5. For a PI governor: Decrease Kp bit by bit until the overshoot is 5-20% or looks OK - finished.
  6. For a PID: Increase Td bit by bit until the overshoot is 5-20% or looks OK - finished.
That's it. An "optimal" PID will have some overshoot, but for some applications an overshoot may not be wanted. Then simply adjust Kp or Td in step 5/6 until little or no overshoot is seen. By coincidence these steps looks very much like the graphical animation in the Wikipedia article.

Note. This method makes it possible to tune most PID controllers in most systems, but doesn't necessarily create the "best possible parameters" whatever that may be. For turbines the specs for the governor are in frequency domain (a separate analysis) and the ability to follow changes in SP and changes in frequency. Any tuning that makes the system behave according to spec is good enough. If no formal specs exists, then this method results in no better or worse parameters than any other method. It does however create good and stable results almost every time, and with little knowledge of the system.

On a second note, the tuning of systems where servos saturate can be tricky. By saturation I mean the output is restricted in amplitude and speed. Some anti-windup algorithm should then be included for best behavior of the PID controller. This should be in effect for step 4 and 5/6 if it isn't already. Most commercial PID's have anti-windup implemented.

On a third note, a pure 1st order system may not give any noticeable overshoot in step 3. If that happens, then you know it's a first order system. A typical example is PID servo positioning. For such systems you can set Kp to almost "whatever you want", and adjust Ti to achieve a response with no, or desired overshoot. If performance is specified, you simply adjust to achieve the wanted performance. In this case, it is however a good idea to dive a bit further into the theories of PID tuning, starting for instance here.

Background

Tuning a PID governor is the process of determining the proportional gain, the integral gain and the derivative gain so the process behave the way you want it to. A key element is "behave the way you want it to".

If the stability is important, then there could be industry standards specifying the stability gains. Typically there are gain margins and phase margins that are standardized. These are obtained in frequency domain analysis, either directly or through FFT analysis. An industrial standard could also specify certain time parameters, how fast the PID should be, how accurate, the overshoot and so on. If no specifications are given, then the usual way is to get the PID so "optimal" as possible while keeping it stable.

There are therefore no universal descriptions of what a proper tuned PID actually is. It will be dependent on the application, the industry and the very process it is governing. The only common denominator is stability of the system as a whole. Theory and practice are usually different when working with PIDs, especially when it comes to derivative. This is sometimes referred to as realizable forms of the PID vs mathematical/theoretical forms. 

Two popular versions of the PID exists. The standard form and the parallel form. From Wikipedia the standard form is:


and the parallel form is:

where

As long as the relations between the constants (above) are remembered and taken into account, these two are equivalent mathematically. The tuning procedure shown above uses the standard form. The parallel form could also be used as long as the relations above are taken into account. Both these forms above happen to be mathematical forms rather than realizable forms, but that is of little relevance here.