The bane of Perple_X users (errors ver041 and ver058 and solvi) and what Perple_X (6.8.8) is doing in 2057 words

During adaptive minimization (VERTEX/MEEMUM, Connolly 2009) Perple_X uses static (aka pseudocompound) and dynamic arrays of compositional coordinates. The best quality result is obtained when the memory allocated for both these arrays is fully utilized. The cost of quality is computation time; the art of using Perple_X effectively is to balance quality against cost. Users (or at least I) have a tendency to squander computer memory and time for aesthetic improvements that have little or no scientific value. Errors ver041 and ver058 occur when, respectively, the memory allocated for the static and dynamic arrays is exhausted, most often in the pursuit of quality.


Perple_X makes iterative refinements in up to three different ways, to understand this discussion it is important not to confuse these. They are:


auto-refinement - if the auto_refine option is on or default, VERTEX and CONVEX do one iteration on an initial result, the computations of the initial and iterated result are referred to as the exploratory and auto-refine stages of the calculation. Based on the exploratory stage results, in the auto-refine stage unstable phases are eliminated, the compositional ranges of the stable phase restricted, and the resolution of all iterative refinement schemes (i.e., gridding and adaptive minimization) is increased. MEEMUM does not do auto-refinement, but it can be instructed to use auto-refine data generated by a calculation with VERTEX or CONVEX.


gridded-minimization - VERTEX samples phase relations on a grid and iteratively refines the grid around phase boundaries. This iterative refinement is controlled by the grid_parameters keyword group (Fig 2 of Connolly 2005) and has no direct relation to memory consumption. The name gridded-minimization is unfortunate because the process is simply iterative mapping on a multi-level grid and has nothing to do with the minimization method.


adaptive-minimization VERTEX and MEEMUM determine stable phase relations at any physicochemical condition by first doing a minimization that considers only a predetermined (i.e., static) set of phase compositions. The stable and nearly-stable compositions identified in this initial optimization are then iteratively refined (Fig 4 of Connolly 2009 and adaptive_mininmization_keyword_group).


It is the nature of iterative schemes that accuracy is dependent on the quality of the lowest resolution result. For example: a) during auto-refinement, if a phase is not found to be stable in the exploratory stage it will not be considered in the auto-refine stage; b) during gridded minimization, if a small phase field occurs between two nodes of the grid where a second phase assemblage is stable, the small phase field will not be identified (this sounds worse than it is, because although the phase field will not be located between the two nodes, in general, it will be located at other nodes of the grid); c) during adaptive-minimization, if the concentration of an endmember of a solution is far below the range of concentrations represented by the static composition array then the endmember may not be detected during subsequent refinement. This dependence can have indirect impact on memory consumption, but only in a trivial way. A presumption here is that the relevant parameters have been specified in such a way that the initial phase relations and compositions are resolved adequately.


**error ver041** static compositions static compositions are generated at the beginning of the exploratory and auto-refine stages of a calculation. The number of static compositions is controlled by the initial_resolution option (6.8.6+, and initial_resolution and auto_refine_factor_I 6.8.5-) and the subdivision ranges specified for the individual solution models (see the commentary in the header of solution_model.dat for an explanation of how these can be modified).


The correction of ver041 is dependent on whether it occurs during the exploratory or auto-refine stage of a calculation:


exploratory stage: either increase the first value of the initial_resolution keyword or restrict the subdivision range for minor endmembers or compositions of the solutions chosen for the calculation. For example, Mn-, Ti-, and Fe(3+)-endmembers are rarely present in concentrations above 10 mol %, reducing the subdivision range for an endmember from [0, 1] to [0, 0.1] will result in roughly an order of magnitude reduction in the amount of memory required by the solution. Thus restricting subdivision ranges can be a highly effective method for reducing memory consumption by complex solutions. However, if such restrictions it is critical that the user verify, either from the console output or from the auto_refine_file data (6.8.6+), that these restrictions do not limit the composition of a stable phase at the end of the exploratory stage of the calculation (see warning_ver991_relax_solution_model_limits for examples and further discussion).


auto-refine stage: increase the second value of the initial_resolution keyword (or, in 6.8.5-, decrease auto_refine_factor_I). To do this efficiently, set auto_refine to manual, then increase the second value of the initial_resolution keyword and run VERTEX answering no to the prompt about reinitializing the auto-refine data. Repeat this process, incrementally increasing initial_resolution until the error does not occur. As the exploratory stage results are independent of the auto-refine stage parameters, there is no need to repeat the exploratory stage.


**error ver058** dynamic compositions dynamic compositions are generated during every individual minimization and the number of compositions is controlled by three options, as in the case of error ver041, if error ver058 occurs during the auto-refine stage, then set auto_refine to manual when the options mentioned below are changed to save needless repetition of the exploratory stage. In cases where it is possible to reproduce the error in MEEMUM, it is most efficient to eliminate the error in MEEMUM first, because it is probable that once the error has been eliminated in MEEMUM it will also have been eliminated in VERTEX:


refine_switch (6.8.8+): controls whether metastable refinement points corresponding to a stable phase are retained during the iterative stages of an adaptive optimization. For problems involving complex solutions (e.g., amphiboles), setting this switch to F may substantially reduce the usage of memory allocated for dynamic compositions, accelerate calculations, and, counter-intuitively, improve the resolution of phase boundaries. In simpler problems, setting this switch to T marginally improves the resolution of phase boundaries. refine_switch defaults to F, and in this case its modification will not eliminate error ver058.


resolution_factor (aka iteration in 6.8.4-): controls how fast the iterative adaptive minimization scheme converges to the target resolution (final_resolution). Dynamic memory consumption increases exponentially with resolution_factor but, because its default value is the minimum permitted, unless this option has been modified resolution_factor cannot be reduced to eliminate error ver058. Increasing resolution_factor does improve quality, but the associated cost rarely justifies this course of action.


reach_increment: is an option the widens the range of compositions around each refinement point (see below) considered during adaptive minimization. It is an effective means for increasing numerical accuracy and stability, but, particularly for complex solutions, it is extremely costly in terms of memory. Reach-increments (reach_increment or global_reach_increment) are usually specified in individual solution models in the solution model file. The prolog written to the console when VERTEX begins the auto-refine stage of a calculation indicates when reach-increments are in use. Reducing or eliminating reach-increments may substantially reduce the memory consumed by dynamic compositions. Reach-increments may be disabled globally by setting reach_increment_switch to off.


refinement_points: specifies the number of metastable solution compositions (metastable refinement-points) that are to be refined during adaptive minimization. The refinement of nearly-stable metastable compositions is important because the relative stability of phases, particularly in the vicinity of a phase boundary, may change as the compositional resolution of the minimization improves. Consequently, the number of refinement_points has an important role in controlling the roughness of phase boundaries. For a problem involving c thermodynamic components, adaptive minimization always involves c stable refinement-points and, by default, Max [5, c+2] metastable refinement-points. Thus, by default, more than half the memory allocated for dynamic compositions is consumed by metastable refinement-points. The optimal number of metastable refinement-points is dependent on the specifics of the problem at hand. If memory is not limiting, then the optimal value can be found by increasing or decreasing the number of refinement-points until the quality of the result becomes insensitive to the specified value. When memory is limiting, refinement_points can usually be reduced to 5 with minimal consequences, use of lower values is a matter of judgement.


low_reach (6.8.8+): is a solution model option keyword that is added to the text of individual models prior to the end_of_model keyword. Presence of the low_reach keyword signals that the composition of a solution is to be discretized by only two points about a refinement point during the iterative stage of an adaptive optimization. For a solution with an n-dimensional composition space this option reduces the usage of memory allocated for dynamic compositions by a factor of (2/3)^n compared to that required using the default value of the resolution_factor keyword. For a 10-dimensional solution, this effect reduces memory usage and computation time by nearly two orders of magnitude. Although these benefits are dramatic, they are offset by a notable reduction in quality; thus low_reach is an option of last resort.


If neither resolution_factor nor refinement_points can be reduced without unsatisfactory impact on quality, then simplifying the computational problem (e.g., eliminating minor components) or using a program that splits the computational domain into small pieces, such as Paralyzer, are the most practical means of circumventing error ver058. Increasing memory allocation is usually not a viable option both because the default allocation is close to what some/most(?) FORTRAN 77 compilers will bear and because it requires that the user compiler her own version of the code.


Solvi (and rough phase boundaries) irregular and stepped phase boundaries and/or spurious solvi (see adaptive_mininmization_keyword_group for examples) are undesirable features that arise in adaptive minimization problems that involve solutions with exceptionally flat thermodynamic surfaces (a characteristic of any immiscible solution). The difficulty caused by flat thermodynamic surfaces is that the stable compositions, i.e., stable refinement points, of a solution may change so much during iteration that the composition becomes artificially limited by the range of dynamic compositions generated during the iteration. Once this occurs, multiple refinement points that represent a single homogeneous phase can not converge in subsequent iterations because the absolute range of compositions considered in each iteration decreases more rapidly than the refinement points are able to approach each other (Fig 4 of Connolly 2009). Small values of initial_resolution mitigate this because it reduces the changes in composition that occur during iteration. Reach-increments (and, conceivably, increasing resolution_factor) are also effective because they widen the possible range of compositions around each refinement point and thereby increase the probability that the refinement points will converge toward the stable composition during iteration.


Spurious solvi occur when initial_resolution is so coarse that two or more refinement points of the same phase do not converge to within the solvus_tolerance before iteration has achieved the target final_resolution value. Increasing the solvus_tolerance keyword value hides this condition, but does not truly eliminate the underlying problem. Stepped solvi reflect a similar problem, in which an initial stable refinement point of an immiscible phase is so far from the true stable composition that the true composition is not achieved before iteration ceases. Both these effects may be aggravated if the number of refinement_points is small. In my experience, the best strategy for eliminating these features is, sequentially:


1) Minimize the value of initial_resolution, i.e., find the smallest value that does not result in error ver041.

2) Minimize the value of final_resolution that can be borne without causing an excessive number of failed minimizations (warning ver042; red patches in plotted section).

3) Maximize the reach_increment for the solution model of the immiscible phase, i.e., find the largest value that does not result in error ver058.

4) Maximize the number of refinement_points.


Ideally an early step in this sequence will solve the problem and obviate the later steps. In principle maximizing resolution_factor could be added to this sequence between steps 2 and 3, but as remarked earlier, my experience has been that resolution_factor does not have a strong influence on quality.


solvus_tolerance_II, an option of last, or maybe first, resort - For problems with solutions that generate a large number of dynamic compositions, it may be impossible to achieve any significant improvement by changing initial_resolution, reach_increment, or refinement_points because of memory limitations (i.e., errors ver041 and ver058). In such cases, and in cases where computation time is a concern, reducing solvus_tolerance_II is an inexpensive alternative to using reach-increments. The original purpose of the solvus_tolerance_II option was to specify the minimum distance between a stable refinement point and any metastable refinement points for the same solution model. The idea being to prevent the list of metastable refinement points from being populated entirely by solutions that are known to be stable at the current level of iteration and thus increasing the probability of detecting the stability of new phases during iteration. There is no question that reducing solvus_tolerance_II effectively increases the range of compositions around stable refinement points and improves the resolution of solvi (Figure 7 at adaptive_mininmization_keyword_group) but it does so at the cost of lowering the resolution of other types of phase boundaries (or at least it used to). solvus_tolerance_II is an ad hoc parameter and I am afraid that its influence is problem specific. For that reason, I am wary of making recommendations about its optimal value based on individual results. The cumulative experience of Perple_X users over the years, suggests that a value roughly twice the auto-refine stage initial_resolution is reasonable, but that experience was gleaned with different versions of Perple_X. I would be delighted to discover that in the current version, setting solvus_tolerance to zero (effectively any value below initial_resolution) yields the best results and obviates the option.