| 441 | | int eparamc=0; |
| 442 | | |
| 443 | | #ifdef DEBUG |
| 444 | | printf ("Facet %d: %g,%g %g,%g %g,%g\n", i, |
| 445 | | corners[0], corners[1], corners[3], |
| 446 | | corners[4], corners[6], corners[7]); |
| 447 | | printf (" Curves: %d %d %d, points %d %d %d, Area: %g\n", |
| 448 | | eparam[0], eparam[1], eparam[2], |
| 449 | | thepoint[0], thepoint[1], thepoint[2], |
| 450 | | fabs((corners[3]-corners[0])*(corners[7]-corners[1]) - |
| 451 | | (corners[6]-corners[0])*(corners[4]-corners[1]))); |
| 452 | | #endif |
| 453 | | |
| | 441 | #ifdef DEBUG |
| | 442 | printf ("Facet %d: %g,%g %g,%g %g,%g\n", i, |
| | 443 | corners[0], corners[1], corners[3], |
| | 444 | corners[4], corners[6], corners[7]); |
| | 445 | printf (" Curves: %d %d %d, points %d %d %d, Area: %g\n", |
| | 446 | eparam[0], eparam[1], eparam[2], |
| | 447 | thepoint[0], thepoint[1], thepoint[2], |
| | 448 | fabs((corners[3]-corners[0])*(corners[7]-corners[1]) - |
| | 449 | (corners[6]-corners[0])*(corners[4]-corners[1]))); |
| | 450 | #endif |
| | 451 | |
| | 452 | /*+ |
| | 453 | +latex+\item |
| | 454 | +html+ <li> |
| | 455 | If this is a one-phase facet, optionally add the centroid as a new |
| | 456 | vertex. |
| | 457 | +html+ </li> |
| | 458 | +*/ |
| | 459 | centroid[0] = (corners[0] + corners[3] + corners[6]) / 3.; |
| | 460 | centroid[1] = (corners[1] + corners[4] + corners[7]) / 3.; |
| | 461 | centroid[2] = (corners[2] + corners[5] + corners[8]) / 3.; |
| | 462 | |
| | 463 | if ((*facets) [i].type == ONE_PHASE && one_phase_refine) |
| | 464 | { |
| | 465 | #ifdef DEBUG |
| | 466 | printf (" Refining one-phase triangle at centroid\n"); |
| | 467 | #endif |
| | 468 | if (numnewpoints >= newpointsize) |
| | 469 | newpoints = realloc |
| | 470 | (newpoints, (newpointsize+=100)*sizeof(ternary_point)); |
| | 471 | newpoints [numnewpoints].C2 = centroid[0]; |
| | 472 | newpoints [numnewpoints].C3 = centroid[1]; |
| | 473 | newpoints [numnewpoints].G = free_energy |
| | 474 | (centroid[0], centroid[1], T, P, eparams+eparam [0]); |
| | 475 | newpoints [numnewpoints].efunc = eparam [0]; |
| | 476 | numnewpoints++; |
| | 477 | } |
| | 478 | |
| | 479 | /*+ |
| | 480 | +latex+\item |
| | 481 | +html+ <li> |
| | 482 | Otherwise, use Newton-Raphson iteration to refine each vertex, |
| | 483 | which consists of the remaining steps. |
| | 484 | +html+ </li> |
| | 485 | +*/ |
| | 486 | else if ((*facets) [i].type != ONE_PHASE) |
| | 487 | { |
| | 488 | coordT newcorners [9] = { corners[0], corners[1], corners[2], |
| | 489 | corners[3], corners[4], corners[5], |
| | 490 | corners[6], corners[7], corners[8]}; |
| | 491 | |
| | 492 | #ifdef DEBUG |
| | 493 | printf (" Refining multi-phase triangle\n"); |
| | 494 | #endif |
| 484 | | Otherwise, use Newton-Raphson iteration to refine each vertex, |
| 485 | | which consists of the remaining steps. |
| | 526 | Refine the vertices of the facet using |
| | 527 | +latex+{\tt NewtonRefine()} (section |
| | 528 | +latex+\ref{func_NewtonRefine_qhull.c} page |
| | 529 | +latex+\pageref{func_NewtonRefine_qhull.c}). |
| | 530 | +html+ <a href="#func-NewtonRefine"><tt>NewtonRefine()</tt></a>.</li> |
| | 531 | +*/ |
| | 532 | for (j=0; j<3; j++) |
| | 533 | { |
| | 534 | #ifdef DEBUG |
| | 535 | printf (" Refining point at %g, %g function %d\n", |
| | 536 | newcorners[3*j], newcorners[3*j+1], eparam[j]); |
| | 537 | #endif |
| | 538 | NewtonRefine (newcorners+3*j, corners, eparams+eparam[j], |
| | 539 | T,P, 3,3, newton_tolerance); |
| | 540 | #ifdef DEBUG |
| | 541 | printf (" -> %g, %g\n", newcorners[3*j], |
| | 542 | newcorners[3*j+1]); |
| | 543 | #endif |
| | 544 | |
| | 545 | newcorners[3*j+2] = free_energy |
| | 546 | (newcorners[3*j],newcorners[3*j+1], T,P, eparams+eparam[j]); |
| | 547 | } |
| | 548 | |
| | 549 | /*+ |
| | 550 | +latex+\item |
| | 551 | +html+ <li> |
| | 552 | Add new points, leaving out duplicates in same place (closer |
| | 553 | than vertex_tolerance). |
| 490 | | coordT newcorners [9] = { corners[0], corners[1], corners[2], |
| 491 | | corners[3], corners[4], corners[5], |
| 492 | | corners[6], corners[7], corners[8]}; |
| 493 | | |
| 494 | | #ifdef DEBUG |
| 495 | | printf (" Refining multi-phase triangle\n"); |
| 496 | | #endif |
| 497 | | for (j=0; j<3; j++) |
| 498 | | { |
| 499 | | /*+ |
| 500 | | +latex+\item |
| 501 | | +html+ <li> |
| 502 | | If the vertex is on a side of the phase diagram (one or |
| 503 | | more composition variables is zero or they sum to one), |
| 504 | | refine generally starting a bit closer to the others. |
| 505 | | +html+ </li> |
| 506 | | +*/ |
| 507 | | if (corners[3*j] == 0. || corners[3*j+1] == 0 || |
| 508 | | corners[3*j] + corners[3*j+1] == 1.) |
| 509 | | { |
| 510 | | newcorners[3*j] = |
| 511 | | 0.9999999998 * corners[3*j] + |
| 512 | | 0.0000000001 * corners[3*((j+1)%3)] + |
| 513 | | 0.0000000001 * corners[3*((j+2)%3)]; |
| 514 | | newcorners[3*j+1] = |
| 515 | | 0.9999999998 * corners[3*j+1] + |
| 516 | | 0.0000000001 * corners[3*((j+1)%3)+1] + |
| 517 | | 0.0000000001 * corners[3*((j+2)%3)+1]; |
| 518 | | newcorners[3*j+2] = |
| 519 | | 0.9999999998 * corners[3*j+2] + |
| 520 | | 0.0000000001 * corners[3*((j+1)%3)+2] + |
| 521 | | 0.0000000001 * corners[3*((j+2)%3)+2]; |
| 522 | | } |
| 523 | | } |
| 524 | | |
| 525 | | /*+ |
| 526 | | +latex+\item |
| 527 | | +html+ <li> |
| 528 | | Refine the vertices of the facet using |
| 529 | | +latex+{\tt NewtonRefine()} (section |
| 530 | | +latex+\ref{func_NewtonRefine_qhull.c} page |
| 531 | | +latex+\pageref{func_NewtonRefine_qhull.c}). |
| 532 | | +html+ <a href="#func-NewtonRefine"><tt>NewtonRefine()</tt></a>.</li> |
| 533 | | +*/ |
| 534 | | for (j=0; j<3; j++) |
| 535 | | { |
| 536 | | #ifdef DEBUG |
| 537 | | printf (" Refining point at %g, %g function %d\n", |
| 538 | | newcorners[3*j], newcorners[3*j+1], eparam[j]); |
| 539 | | #endif |
| 540 | | NewtonRefine (newcorners+3*j, corners, eparams+eparam[j], |
| 541 | | T,P, 3,3, newton_tolerance); |
| 542 | | #ifdef DEBUG |
| 543 | | printf (" -> %g, %g\n", newcorners[3*j], |
| 544 | | newcorners[3*j+1]); |
| 545 | | #endif |
| 546 | | |
| 547 | | newcorners[3*j+2] = free_energy |
| 548 | | (newcorners[3*j],newcorners[3*j+1], T,P, eparams+eparam[j]); |
| 549 | | } |
| 550 | | |
| 551 | | /*+ |
| 552 | | +latex+\item |
| 553 | | +html+ <li> |
| 554 | | Add new points, leaving out duplicates in same place (closer |
| 555 | | than vertex_tolerance). |
| 556 | | +html+ </li> |
| 557 | | +*/ |
| 558 | | |
| 559 | | // Don't add the point, reallocate the points array instead! |
| 560 | | if (newcorners[0]>=0. && newcorners[1]>=0. && |
| 561 | | newcorners[0]+newcorners[1]<=1.) |
| 562 | | { |
| 563 | | #ifdef DEBUG |
| 564 | | printf (" Adding new point %g,%g,%g\n", |
| 565 | | newcorners[0], newcorners[1], newcorners[2]); |
| 566 | | #endif |
| 567 | | if (numnewpoints >= newpointsize) |
| 568 | | newpoints = realloc |
| 569 | | (newpoints, (newpointsize+=100)*sizeof(ternary_point)); |
| 570 | | newpoints [numnewpoints].C2 = newcorners[0]; |
| 571 | | newpoints [numnewpoints].C3 = newcorners[1]; |
| 572 | | newpoints [numnewpoints].G = newcorners[2]; |
| 573 | | newpoints [numnewpoints].efunc = eparam[0]; |
| 574 | | numnewpoints++; |
| 575 | | } |
| 576 | | |
| 577 | | if ((newcorners[3]-newcorners[0])*(newcorners[3]-newcorners[0]) + |
| 578 | | (newcorners[4]-newcorners[1])*(newcorners[4]-newcorners[1]) + |
| 579 | | (newcorners[5]-newcorners[2])*(newcorners[5]-newcorners[2]) > |
| 580 | | vertex_tolerance * vertex_tolerance && |
| 581 | | newcorners[3]>=0. && newcorners[4]>=0. && |
| 582 | | newcorners[3]+newcorners[4]<=1.) |
| 583 | | { |
| 584 | | #ifdef DEBUG |
| 585 | | printf (" Adding new point %g,%g,%g\n", |
| 586 | | newcorners[3], newcorners[4], newcorners[5]); |
| 587 | | #endif |
| 588 | | if (numnewpoints >= newpointsize) |
| 589 | | newpoints = realloc |
| 590 | | (newpoints, (newpointsize+=100)*sizeof(ternary_point)); |
| 591 | | newpoints [numnewpoints].C2 = newcorners[3]; |
| 592 | | newpoints [numnewpoints].C3 = newcorners[4]; |
| 593 | | newpoints [numnewpoints].G = newcorners[5]; |
| 594 | | newpoints [numnewpoints].efunc = eparam[1]; |
| 595 | | numnewpoints++; |
| 596 | | } |
| 597 | | |
| 598 | | if ((newcorners[6]-newcorners[0])*(newcorners[6]-newcorners[0]) + |
| 599 | | (newcorners[7]-newcorners[1])*(newcorners[7]-newcorners[1]) + |
| 600 | | (newcorners[8]-newcorners[2])*(newcorners[8]-newcorners[2]) > |
| 601 | | vertex_tolerance * vertex_tolerance && |
| 602 | | (newcorners[6]-newcorners[3])*(newcorners[6]-newcorners[3]) + |
| 603 | | (newcorners[7]-newcorners[4])*(newcorners[7]-newcorners[4]) + |
| 604 | | (newcorners[8]-newcorners[5])*(newcorners[8]-newcorners[5]) > |
| 605 | | vertex_tolerance * vertex_tolerance && |
| 606 | | newcorners[6]>=0. && newcorners[7]>=0. && |
| 607 | | newcorners[6]+newcorners[7]<=1.) |
| 608 | | { |
| 609 | | #ifdef DEBUG |
| 610 | | printf (" Adding new point %g,%g,%g\n", |
| 611 | | newcorners[6], newcorners[7], newcorners[8]); |
| 612 | | #endif |
| 613 | | if (numnewpoints >= newpointsize) |
| 614 | | newpoints = realloc |
| 615 | | (newpoints, (newpointsize+=100)*sizeof(ternary_point)); |
| 616 | | newpoints [numnewpoints].C2 = newcorners[6]; |
| 617 | | newpoints [numnewpoints].C3 = newcorners[7]; |
| 618 | | newpoints [numnewpoints].G = newcorners[8]; |
| 619 | | newpoints [numnewpoints].efunc = eparam[1]; |
| 620 | | numnewpoints++; |
| 621 | | } |
| | 561 | #ifdef DEBUG |
| | 562 | printf (" Adding new point %g,%g,%g\n", |
| | 563 | newcorners[0], newcorners[1], newcorners[2]); |
| | 564 | #endif |
| | 565 | if (numnewpoints >= newpointsize) |
| | 566 | newpoints = realloc |
| | 567 | (newpoints, (newpointsize+=100)*sizeof(ternary_point)); |
| | 568 | newpoints [numnewpoints].C2 = newcorners[0]; |
| | 569 | newpoints [numnewpoints].C3 = newcorners[1]; |
| | 570 | newpoints [numnewpoints].G = newcorners[2]; |
| | 571 | newpoints [numnewpoints].efunc = eparam[0]; |
| | 572 | numnewpoints++; |
| | 574 | |
| | 575 | if ((newcorners[3]-newcorners[0])*(newcorners[3]-newcorners[0]) + |
| | 576 | (newcorners[4]-newcorners[1])*(newcorners[4]-newcorners[1]) + |
| | 577 | (newcorners[5]-newcorners[2])*(newcorners[5]-newcorners[2]) > |
| | 578 | vertex_tolerance * vertex_tolerance && |
| | 579 | newcorners[3]>=0. && newcorners[4]>=0. && |
| | 580 | newcorners[3]+newcorners[4]<=1.) |
| | 581 | { |
| | 582 | #ifdef DEBUG |
| | 583 | printf (" Adding new point %g,%g,%g\n", |
| | 584 | newcorners[3], newcorners[4], newcorners[5]); |
| | 585 | #endif |
| | 586 | if (numnewpoints >= newpointsize) |
| | 587 | newpoints = realloc |
| | 588 | (newpoints, (newpointsize+=100)*sizeof(ternary_point)); |
| | 589 | newpoints [numnewpoints].C2 = newcorners[3]; |
| | 590 | newpoints [numnewpoints].C3 = newcorners[4]; |
| | 591 | newpoints [numnewpoints].G = newcorners[5]; |
| | 592 | newpoints [numnewpoints].efunc = eparam[1]; |
| | 593 | numnewpoints++; |
| | 594 | } |
| | 595 | |
| | 596 | if ((newcorners[6]-newcorners[0])*(newcorners[6]-newcorners[0]) + |
| | 597 | (newcorners[7]-newcorners[1])*(newcorners[7]-newcorners[1]) + |
| | 598 | (newcorners[8]-newcorners[2])*(newcorners[8]-newcorners[2]) > |
| | 599 | vertex_tolerance * vertex_tolerance && |
| | 600 | (newcorners[6]-newcorners[3])*(newcorners[6]-newcorners[3]) + |
| | 601 | (newcorners[7]-newcorners[4])*(newcorners[7]-newcorners[4]) + |
| | 602 | (newcorners[8]-newcorners[5])*(newcorners[8]-newcorners[5]) > |
| | 603 | vertex_tolerance * vertex_tolerance && |
| | 604 | newcorners[6]>=0. && newcorners[7]>=0. && |
| | 605 | newcorners[6]+newcorners[7]<=1.) |
| | 606 | { |
| | 607 | #ifdef DEBUG |
| | 608 | printf (" Adding new point %g,%g,%g\n", |
| | 609 | newcorners[6], newcorners[7], newcorners[8]); |
| | 610 | #endif |
| | 611 | if (numnewpoints >= newpointsize) |
| | 612 | newpoints = realloc |
| | 613 | (newpoints, (newpointsize+=100)*sizeof(ternary_point)); |
| | 614 | newpoints [numnewpoints].C2 = newcorners[6]; |
| | 615 | newpoints [numnewpoints].C3 = newcorners[7]; |
| | 616 | newpoints [numnewpoints].G = newcorners[8]; |
| | 617 | newpoints [numnewpoints].efunc = eparam[1]; |
| | 618 | numnewpoints++; |
| | 619 | } |
| | 620 | } |