| | 74 | |
| | 75 | return 0; |
| | 76 | } |
| | 77 | |
| | 78 | |
| | 79 | /*++++++++++++++++++++++++++++++++++++++ |
| | 80 | This uses Newton iteration to refine a single |
| | 81 | |
| | 82 | double *point Composition coordinates of the starting point for refining; the |
| | 83 | result will be returned here. |
| | 84 | |
| | 85 | double *corners Coordinates (including energies) of the corners of this |
| | 86 | facet, used for the facet normal. |
| | 87 | |
| | 88 | energy_params *eparams Collection of energy parameter structures. |
| | 89 | |
| | 90 | int nparams Number of energy parameter structures in eparams. |
| | 91 | |
| | 92 | int globaldims Dimensionality of the global space. |
| | 93 | |
| | 94 | int localdims Dimensionality over which to do the refinement. |
| | 95 | |
| | 96 | int side Side of the phase diagram on which to refine, if |
| | 97 | localdims<globaldims. |
| | 98 | |
| | 99 | double newton_tolerance Stop Newton iterations when the vertex motion falls |
| | 100 | below this value. |
| | 101 | ++++++++++++++++++++++++++++++++++++++*/ |
| | 102 | |
| | 103 | static inline void NewtonRefine |
| | 104 | (coordT *point, coordT *corners, energy_params *eparams, int nparams, |
| | 105 | int globaldims, int localdims, int side, double newton_tolerance) |
| | 106 | { |
| | 107 | double distance = 0.; |
| | 108 | |
| | 109 | /*+ Determine which is the lowest energy function at this point +*/ |
| | 110 | |
| | 111 | while (distance >= newton_tolerance) |
| | 112 | { |
| | 113 | /*+ Calculate the energy derivatives +*/ |
| | 114 | |
| | 115 | /*+ Subtract the facet slopes from the energy derivatives +*/ |
| | 116 | |
| | 117 | /*+ Solve the linear system to estimate the distance to the minimum +*/ |
| | 118 | |
| | 119 | /*+ Add that distance to the point +*/ |
| | 120 | } |
| | 121 | } |
| | 122 | |
| | 123 | |
| | 124 | /*++++++++++++++++++++++++++++++++++++++ |
| | 125 | This refines each of the facets in the hull, adding a new vertex at its |
| | 126 | centroid if in a one-phase region, and using Newton-Raphson iteration to |
| | 127 | refine down the vertices of multi-phase facets. |
| | 128 | |
| | 129 | int hullRefine It returns zero or an error code. |
| | 130 | |
| | 131 | energy_params *eparams Collection of energy parameter structures. |
| | 132 | |
| | 133 | int nparams Number of energy parameter structures in eparams. |
| | 134 | |
| | 135 | double newton_tolerance Stop Newton iterations when the vertex motion falls |
| | 136 | below this value. |
| | 137 | |
| | 138 | double vertex_tolerance Minimum distance between two vertices. When refining |
| | 139 | a two-phase facet, two of the vertices should go to the same local minimum; |
| | 140 | choose this parameter to indicate how close to consider them the "same" |
| | 141 | point. |
| | 142 | ++++++++++++++++++++++++++++++++++++++*/ |
| | 143 | |
| | 144 | int hullRefine (energy_params *eparams, int nparams, double newton_tolerance, |
| | 145 | double vertex_tolerance) |
| | 146 | { |
| | 147 | facetT *facet; |
| | 148 | |
| | 149 | /*+ Steps in the algorithm: |
| | 150 | +latex+\begin{enumerate} |
| | 151 | +latex+\item |
| | 152 | +html+ <ol><li> |
| | 153 | Loop over the facets |
| | 154 | +html+ </li> |
| | 155 | +*/ |
| | 156 | |
| | 157 | FORALLfacets |
| | 158 | { |
| | 159 | coordT corners [6], centroid [2]; |
| | 160 | vertexT *vertex, **vertexp; |
| | 161 | |
| | 162 | /*+ |
| | 163 | +latex+\item |
| | 164 | +html+ <li> |
| | 165 | If the lowest free energy function at the centroid has lower energy |
| | 166 | than the average energy of the vertices, add it as a new vertex. |
| | 167 | +html+ </li> |
| | 168 | +*/ |
| | 169 | if (centroid[0] < corners[0]) |
| | 170 | ; |
| | 171 | |
| | 172 | /*+ |
| | 173 | +latex+\item |
| | 174 | +html+ <li> |
| | 175 | Otherwise, use Newton-Raphson iteration to refine each vertex. |
| | 176 | +html+ </li> |
| | 177 | +*/ |
| | 178 | else |
| | 179 | { |
| | 180 | |
| | 181 | /*+ |
| | 182 | +latex+\item |
| | 183 | +html+ <li> |
| | 184 | Find the lowest free energy function at this vertex. |
| | 185 | +html+ </li> |
| | 186 | +*/ |
| | 187 | |
| | 188 | /*+ |
| | 189 | +latex+\item |
| | 190 | +html+ <li> |
| | 191 | If the vertex is on a side of the phase diagram (one or more |
| | 192 | composition variables is zero or they sum to one), refine along |
| | 193 | each side that it's on, to avoid the "infinite slope at the edge" |
| | 194 | problem. If it's on more than one side, add a new candidate vertex |
| | 195 | for each side it's on. |
| | 196 | +html+ </li> |
| | 197 | +*/ |
| | 198 | |
| | 199 | /*+ |
| | 200 | +latex+\item |
| | 201 | +html+ <li> |
| | 202 | Otherwise refine starting at this vertex. |
| | 203 | +html+ </li> |
| | 204 | +*/ |
| | 205 | } |
| | 206 | |
| | 207 | /*+ |
| | 208 | +latex+\item |
| | 209 | +html+ <li> |
| | 210 | If any two new candidate vertices are in the same place (closer than |
| | 211 | vertex_tolerance), eliminate one. |
| | 212 | +html+ </li> |
| | 213 | +*/ |
| | 214 | } |
| | 215 | /*+ |
| | 216 | +latex+\end{enumerate} |
| | 217 | +html+ </ol> |
| | 218 | +*/ |