ISLEC  Version 4.2
gem_ipopt.c
Go to the documentation of this file.
1 /* src/gem_ipopt.c
2  *
3  * Copyright (C) 2011-2018 Dongdong Li
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundataion; either version 3 of the License, or (at
8  * your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABLITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
31 #include "ipopt/IpStdCInterface.h"
32 #include <stdlib.h>
33 #include <assert.h>
34 #include <stdio.h>
35 
43 extern int gem_ipopt ();
44 
63 static Bool eval_f (Index n, Number* x, Bool new_x,
64  Number* obj_value, UserDataPtr user_data);
65 
85 static Bool eval_grad_f (Index n, Number* x, Bool new_x,
86  Number* grad_f, UserDataPtr user_data);
87 
107 static Bool eval_g (Index n, Number* x, Bool new_x,
108  Index m, Number* g, UserDataPtr user_data);
109 
132 static Bool eval_jac_g (Index n, Number *x, Bool new_x,
133  Index m, Index nele_jac,
134  Index *iRow, Index *jCol, Number *values,
135  UserDataPtr user_data);
136 
164 static Bool eval_h (Index n, Number *x, Bool new_x, Number obj_factor,
165  Index m, Number *lambda, Bool new_lambda,
166  Index nele_hess, Index *iRow, Index *jCol,
167  Number *values, UserDataPtr user_data);
168 
175 static Bool intermediate_cb (Index alg_mod, Index iter_count, Number obj_value,
176  Number inf_pr, Number inf_du, Number mu, Number d_norm,
177  Number regularization_size, Number alpha_du,
178  Number alpha_pr, Index ls_trials, UserDataPtr user_data);
179 
180 extern int gem_ipopt()
181 {
182  Index n=-1; /* number of variables */
183  Index m=-1; /* number of constraints */
184  Number* x_L = NULL; /* lower bounds on x */
185  Number* x_U = NULL; /* upper bounds on x */
186  Number* g_L = NULL; /* lower bounds on g */
187  Number* g_U = NULL; /* upper bounds on g */
188  IpoptProblem nlp = NULL; /* IpoptProblem */
189  enum ApplicationReturnStatus status; /* Solve return code */
190  Number* x = NULL; /* starting point and solution vector */
191  Number* mult_g = NULL; /* constraint multipliers
192  at the solution */
193  Number* mult_x_L = NULL; /* lower bound multipliers
194  at the solution */
195  Number* mult_x_U = NULL; /* upper bound multipliers
196  at the solution */
197  Number obj; /* objective value */
198  Index i; /* generic counter */
199 
200  /* Number of nonzeros in the Jacobian of the constraints */
201  Index nele_jac = (total_comp_num + 1) * total_species_num;
202  /* Number of nonzeros in the Hessian of the Lagrangian (lower or
203  upper triangual part only) */
204  Index nele_hess = total_species_num * total_species_num;
205  /* indexing style for matrices */
206  Index index_style = 0; /* C-style; start counting of rows and column
207  indices at 0 */
208 
209  /* set the number of variables and allocate space for the bounds */
210  n = total_species_num;
211  x_L = (Number*)malloc(sizeof(Number) * n);
212  x_U = (Number*)malloc(sizeof(Number) * n);
213 
214  /* set the values for the variable bounds */
215  for (i = 0; i < n; i++)
216  {
217  x_L[i] = 0.0;
218  x_U[i] = 2.0e+19;
219  }
220 
221  /* set the number of constraints and allocate space for the bounds */
222  m = total_comp_num + 1; // mass balance + charge blance
223  g_L = (Number*)malloc(sizeof(Number) * m);
224  g_U = (Number*)malloc(sizeof(Number) * m);
225  /* set the values of the constraint bounds */
226 
227  for (i = 0; i < m; i++)
228  {
229  g_L[i] = 0;
230  g_U[i] = 0;
231  }
232 
233  /* create the IpoptProblem */
234  nlp = CreateIpoptProblem(n, x_L, x_U, m, g_L, g_U, nele_jac, nele_hess,
235  index_style, &eval_f, &eval_g, &eval_grad_f,
236  &eval_jac_g, &eval_h);
237 
238  /* We can free the memory now - the values for the bounds have been
239  copied internally in CreateIpoptProblem */
240  free(x_L);
241  free(x_U);
242  free(g_L);
243  free(g_U);
244 
245  /* Set some options. Note the following ones are only examples,
246  they might not be suitable for your problem. */
247  AddIpoptNumOption(nlp, "tol", 1e-10);
248  AddIpoptStrOption(nlp, "mu_strategy", "adaptive");
249  AddIpoptStrOption(nlp, "hessian_approximation", "limited-memory");
250  AddIpoptIntOption(nlp, "print_level", 0);
251 
252 
253  /* allocate space for the initial point and set the values */
254  x = (Number*)malloc(sizeof(Number) * n);
255 
256  for (i = 0; i < n; i ++)
257  {
258  x[i] = 1.0;
259  }
260 
261  /* allocate space to store the bound multipliers at the solution */
262  mult_g = (Number*)malloc(sizeof(Number) * m);
263  mult_x_L = (Number*)malloc(sizeof(Number) * n);
264  mult_x_U = (Number*)malloc(sizeof(Number) * n);
265 
266  /* Set the callback method for intermediate user-control. This is
267  * not required, just gives you some intermediate control in case
268  * you need it. */
269  /* SetIntermediateCallback(nlp, intermediate_cb); */
270 
271  /* solve the problem */
272  status = IpoptSolve(nlp, x, NULL, &obj, mult_g, mult_x_L, mult_x_U, NULL);
273 
274  if (status == Solve_Succeeded)
275  {
276  printf("\nSUCCESSED IPOPT OPTIMIZATION.\n");
277  successed = TRUE;
278  }
279  else
280  {
281  printf("\nERROR OCCURRED DURING IPOPT OPTIMIZATION.\n");
282  successed = FALSE;
283  }
284 
285  if (status == Solve_Succeeded)
286  {
287  n_eq = (double *)malloc (sizeof(double) * n);
288 
289  for (i=0; i < n; i++)
290  {
291  n_eq[i] = x[i];
292  }
293 
294  gibbs_eq = obj;
295 
296  successed = TRUE;
297  }
298 
299  /* free allocated memory */
300  FreeIpoptProblem(nlp);
301  free(x);
302  free(mult_g);
303  free(mult_x_L);
304  free(mult_x_U);
305 
306  return (int)status;
307 }
308 
309 /* Function Implementations */
310 static Bool eval_f(Index n, Number* x, Bool new_x,
311  Number* obj_value, UserDataPtr user_data)
312 {
313  assert(n == total_species_num);
314 
315  *obj_value = 0;
316 
317  double t = system_T/1000.0;
318  double T = system_T;
319  double P = system_P;
320 
321  int i, j;
322  int species_num_index = 0;
323 
324  //Total Gibbs energy of gas phases
325  for (i = 0; i < gas_phase_num; i++)
326  {
327  double sumn = 0;
328  double ngi[phases.gas[i].species_num];
329 
330  for (j = 0; j < phases.gas[i].species_num; j++)
331  {
332  ngi[j] = x[j + species_num_index];
333  }
334 
335  for (j = 0; j < phases.gas[i].species_num; j++)
336  {
337  sumn += ngi[j];
338  }
339 
340  for (j = 0; j < phases.gas[i].species_num; j++)
341  {
342  double A = phases.gas[i].gas_species[j].thermo_coeff[0];
343  double B = phases.gas[i].gas_species[j].thermo_coeff[1];
344  double C = phases.gas[i].gas_species[j].thermo_coeff[2];
345  double D = phases.gas[i].gas_species[j].thermo_coeff[3];
346  double E = phases.gas[i].gas_species[j].thermo_coeff[4];
347  double F = phases.gas[i].gas_species[j].thermo_coeff[5];
348  double G = phases.gas[i].gas_species[j].thermo_coeff[6];
349 
350  double G0 = A * (t - t*log(t)) - B/2.0 *t*t - C/6.0 *t*t*t -
351  D/12.0 * t*t*t*t - E/2.0/t + F - G * t;
352 
353  // kJ
354  *obj_value += ngi[j] * (G0 + R * T * log (ngi[j]/sumn) / 1000);
355 
356  species_num_index ++;
357  }
358  }
359 
360  //Total Gibbs energy of aqueous phases
361  for (i = 0; i < aqueous_phase_num; i++)
362  {
363  double sumn = 0;
364  double naqi[phases.aqueous[i].species_num];
365 
366  for (j = 0; j < phases.aqueous[i].species_num; j++)
367  {
368  naqi[j] = x[j + species_num_index];
369  }
370 
371  for (j = 0; j < phases.aqueous[i].species_num; j++)
372  {
373  sumn += naqi[j];
374  }
375 
376  for (j = 0; j < phases.aqueous[i].species_num; j++)
377  {
378  double A = phases.aqueous[i].aqueous_species[j].thermo_coeff[0];
379  double B = phases.aqueous[i].aqueous_species[j].thermo_coeff[1];
380  double C = phases.aqueous[i].aqueous_species[j].thermo_coeff[2];
381  double D = phases.aqueous[i].aqueous_species[j].thermo_coeff[3];
382  double E = phases.aqueous[i].aqueous_species[j].thermo_coeff[4];
383  double F = phases.aqueous[i].aqueous_species[j].thermo_coeff[5];
384  double G = phases.aqueous[i].aqueous_species[j].thermo_coeff[6];
385 
386  double G0 = A * (t - t*log(t)) - B/2.0 *t*t - C/6.0 *t*t*t -
387  D/12.0 * t*t*t*t - E/2.0/t + F - G * t;
388 
389  double aj = psc_a (phases.aqueous[i], j, naqi, T, P);
390 
391  *obj_value += naqi[j] * (G0 + R * T * log (aj) / 1000);
392 
393  species_num_index ++;
394  }
395  }
396 
397  //Total Gibbs energy of solid phases
398  for (i = 0; i < solid_phase_num; i++)
399  {
400  double sumn = 0;
401  double nsi[phases.solids[i].species_num];
402 
403  for (j = 0; j < phases.solids[i].species_num; j++)
404  {
405  nsi[j] = x[j + species_num_index];
406  }
407 
408  for (j = 0; j < phases.solids[i].species_num; j++)
409  {
410  double A = phases.solids[i].solid_species[j].thermo_coeff[0];
411  double B = phases.solids[i].solid_species[j].thermo_coeff[1];
412  double C = phases.solids[i].solid_species[j].thermo_coeff[2];
413  double D = phases.solids[i].solid_species[j].thermo_coeff[3];
414  double E = phases.solids[i].solid_species[j].thermo_coeff[4];
415  double F = phases.solids[i].solid_species[j].thermo_coeff[5];
416  double G = phases.solids[i].solid_species[j].thermo_coeff[6];
417 
418  double G0 = A * (t - t*log(t)) - B/2.0 *t*t - C/6.0 *t*t*t -
419  D/12.0 * t*t*t*t - E/2.0/t + F - G * t;
420 
421  *obj_value += nsi[j] * G0;
422 
423  species_num_index ++;
424  }
425  }
426 
427  //Total Gibbs energy of solid solution phases
428  for (i = 0; i < solidsolution_phase_num; i++)
429  {
430  double sumn = 0;
431  double nssi[phases.solidsolution[i].species_num];
432 
433  for (j = 0; j < phases.solidsolution[i].species_num; j++)
434  {
435  nssi[j] = x[j + species_num_index];
436  }
437 
438  for (j = 0; j < phases.solidsolution[i].species_num; j++)
439  {
440  sumn += nssi[j];
441  }
442 
443  for (j = 0; j < phases.solidsolution[i].species_num; j++)
444  {
452 
453  double G0 = A * (t - t*log(t)) - B/2.0 *t*t - C/6.0 *t*t*t -
454  D/12.0 * t*t*t*t - E/2.0/t + F - G * t;
455 
456  double aj = rkg_a (phases.solidsolution[i], j, nssi, T, P);
457 
458  *obj_value += nssi[j] * (G0 + R * T * log (aj) / 1000);
459 
460  species_num_index ++;
461  }
462  }
463 
464  return TRUE;
465 }
466 
467 static Bool eval_grad_f(Index n, Number* x, Bool new_x,
468  Number* grad_f, UserDataPtr user_data)
469 {
470  assert(n == total_species_num);
471 
472  double t = system_T/1000.0;
473  double T = system_T;
474  double P = system_P;
475 
476  int species_num_index = 0;
477 
478  int i, j;
479 
480  // Gas phases
481  for (i = 0; i < gas_phase_num; i ++)
482  {
483  double sumn = 0;
484  double ngi[phases.gas[i].species_num];
485 
486  for (j = 0; j < phases.gas[i].species_num; j++)
487  {
488  ngi[j] = x[j + species_num_index];
489  }
490 
491  for (j = 0; j < phases.gas[i].species_num; j++)
492  {
493  sumn += ngi[j];
494  }
495 
496  for (j = 0; j < phases.gas[i].species_num; j ++)
497  {
498  double A = phases.gas[i].gas_species[j].thermo_coeff[0];
499  double B = phases.gas[i].gas_species[j].thermo_coeff[1];
500  double C = phases.gas[i].gas_species[j].thermo_coeff[2];
501  double D = phases.gas[i].gas_species[j].thermo_coeff[3];
502  double E = phases.gas[i].gas_species[j].thermo_coeff[4];
503  double F = phases.gas[i].gas_species[j].thermo_coeff[5];
504  double G = phases.gas[i].gas_species[j].thermo_coeff[6];
505 
506  double G0 = A * (t - t*log(t)) - B/2.0 *t*t - C/6.0 *t*t*t -
507  D/12.0 * t*t*t*t - E/2.0/t + F - G * t;
508 
509  grad_f[species_num_index] = (G0 + R * T * log (ngi[j]/sumn) / 1000);
510 
511  species_num_index ++;
512  }
513  }
514 
515  // Aqueous phases
516  for (i = 0; i < aqueous_phase_num; i ++)
517  {
518  double sumn = 0;
519  double naqi[phases.aqueous[i].species_num];
520 
521  for (j = 0; j < phases.aqueous[i].species_num; j++)
522  {
523  naqi[j] = x[j + species_num_index];
524  }
525 
526  for (j = 0; j < phases.aqueous[i].species_num; j++)
527  {
528  sumn += naqi[j];
529  }
530 
531  for (j = 0; j < phases.aqueous[i].species_num; j ++)
532  {
533  double A = phases.aqueous[i].aqueous_species[j].thermo_coeff[0];
534  double B = phases.aqueous[i].aqueous_species[j].thermo_coeff[1];
535  double C = phases.aqueous[i].aqueous_species[j].thermo_coeff[2];
536  double D = phases.aqueous[i].aqueous_species[j].thermo_coeff[3];
537  double E = phases.aqueous[i].aqueous_species[j].thermo_coeff[4];
538  double F = phases.aqueous[i].aqueous_species[j].thermo_coeff[5];
539  double G = phases.aqueous[i].aqueous_species[j].thermo_coeff[6];
540 
541  double G0 = A * (t - t*log(t)) - B/2.0 *t*t - C/6.0 *t*t*t -
542  D/12.0 * t*t*t*t - E/2.0/t + F - G * t;
543 
544  double aj = psc_a (phases.aqueous[i], j, naqi, T, P);
545 
546  grad_f[species_num_index] = (G0 + R * T * log (aj) / 1000);
547 
548  species_num_index ++;
549  }
550  }
551 
552  // Solid phases;
553  for (i = 0; i < solid_phase_num; i ++)
554  {
555  double sumn = 0;
556  double nsi[phases.solids[i].species_num];
557 
558  for (j = 0; j < phases.solids[i].species_num; j++)
559  {
560  nsi[j] = x[j + species_num_index];
561  }
562 
563  for (j = 0; j < phases.solids[i].species_num; j++)
564  {
565  sumn += nsi[j];
566  }
567 
568  for (j = 0; j < phases.solids[i].species_num; j ++)
569  {
570  double A = phases.solids[i].solid_species[j].thermo_coeff[0];
571  double B = phases.solids[i].solid_species[j].thermo_coeff[1];
572  double C = phases.solids[i].solid_species[j].thermo_coeff[2];
573  double D = phases.solids[i].solid_species[j].thermo_coeff[3];
574  double E = phases.solids[i].solid_species[j].thermo_coeff[4];
575  double F = phases.solids[i].solid_species[j].thermo_coeff[5];
576  double G = phases.solids[i].solid_species[j].thermo_coeff[6];
577 
578  double G0 = A * (t - t*log(t)) - B/2.0 *t*t - C/6.0 *t*t*t -
579  D/12.0 * t*t*t*t - E/2.0/t + F - G * t;
580 
581  grad_f[species_num_index] = (G0);
582 
583  species_num_index ++;
584  }
585  }
586 
587  // Solid solid phases;
588  for (i = 0; i < solidsolution_phase_num; i ++)
589  {
590  double sumn = 0;
591  double nssi[phases.solidsolution[i].species_num];
592 
593  for (j = 0; j < phases.solidsolution[i].species_num; j++)
594  {
595  nssi[j] = x[j + species_num_index];
596  }
597 
598  for (j = 0; j < phases.solidsolution[i].species_num; j++)
599  {
600  sumn += nssi[j];
601  }
602 
603  for (j = 0; j < phases.solidsolution[i].species_num; j ++)
604  {
612 
613  double G0 = A * (t - t*log(t)) - B/2.0 *t*t - C/6.0 *t*t*t -
614  D/12.0 * t*t*t*t - E/2.0/t + F - G * t;
615 
616  double aj = rkg_ai (phases.solidsolution[i], j, nssi, T, P);
617 
618  grad_f[species_num_index] = (G0 + R * T * log(aj) / 1000);
619 
620  species_num_index ++;
621  }
622  }
623 
624  return TRUE;
625 }
626 
627 static Bool eval_g(Index n, Number* x, Bool new_x,
628  Index m, Number* g, UserDataPtr user_data)
629 {
630  assert(n == total_species_num);
631  assert(m == total_comp_num + 1);
632 
633  int i, j, k;
634 
635  // mass balance
636  for (i = 0; i < m - 1; i ++)
637  {
638  g[i] = 0;
639 
640  int species_num_index = 0;
641 
642  // Gas phases
643  for(j = 0; j < gas_phase_num; j ++)
644  {
645  for (k = 0; k < phases.gas[j].species_num; k ++)
646  {
647  g[i] += phases.gas[j].gas_species[k].elements[i] * x[species_num_index];
648 
649  species_num_index ++;
650  }
651  }
652 
653  // Aqueous phases
654  for(j = 0; j < aqueous_phase_num; j ++)
655  {
656  for (k = 0; k < phases.aqueous[j].species_num; k ++)
657  {
658  g[i] += phases.aqueous[j].aqueous_species[k].elements[i] * x[species_num_index];
659 
660  species_num_index ++;
661  }
662  }
663 
664  // Solid phases
665  for(j = 0; j < solid_phase_num; j ++)
666  {
667  for (k = 0; k < phases.solids[j].species_num; k ++)
668  {
669  g[i] += phases.solids[j].solid_species[k].elements[i] * x[species_num_index];
670 
671  species_num_index ++;
672  }
673  }
674 
675  // Solid solution phases
676  for(j = 0; j < solidsolution_phase_num; j ++)
677  {
678  for (k = 0; k < phases.solidsolution[j].species_num; k ++)
679  {
680  g[i] += phases.solidsolution[j].solidsolution_species[k].elements[i] * x[species_num_index];
681 
682  species_num_index ++;
683  }
684  }
685 
686  g[i] -= total_components[i];
687  }
688 
689  // charge balance
690  {
691  g[i] = 0;
692 
693  int species_num_index = 0;
694 
695  // Gas phases
696  for(j = 0; j < gas_phase_num; j ++)
697  {
698  for (k = 0; k < phases.gas[j].species_num; k ++)
699  {
700  g[i] += phases.gas[j].gas_species[k].charge * x[species_num_index];
701 
702  species_num_index ++;
703  }
704  }
705 
706  // Aqueous phases
707  for(j = 0; j < aqueous_phase_num; j ++)
708  {
709  for (k = 0; k < phases.aqueous[j].species_num; k ++)
710  {
711  g[i] += phases.aqueous[j].aqueous_species[k].charge * x[species_num_index];
712 
713  species_num_index ++;
714  }
715  }
716 
717  // Solid phases
718  for(j = 0; j < solid_phase_num; j ++)
719  {
720  for (k = 0; k < phases.solids[j].species_num; k ++)
721  {
722  g[i] += phases.solids[j].solid_species[k].charge * x[species_num_index];
723 
724  species_num_index ++;
725  }
726  }
727 
728  // Solid solution phases
729  for(j = 0; j < solidsolution_phase_num; j ++)
730  {
731  for (k = 0; k < phases.solidsolution[j].species_num; k ++)
732  {
733  g[i] += phases.solidsolution[j].solidsolution_species[k].charge * x[species_num_index];
734 
735  species_num_index ++;
736  }
737  }
738 
739  g[i] -= system_charge;
740  }
741 
742  return TRUE;
743 }
744 
745 static Bool eval_jac_g(Index n, Number *x, Bool new_x,
746  Index m, Index nele_jac,
747  Index *iRow, Index *jCol, Number *values,
748  UserDataPtr user_data)
749 {
750  int i, j, k;
751 
752  if (values == NULL)
753  {
754  /* return the structure of the jacobian */
755 
756  /* this particular jacobian is dense */
757  for (i = 0; i < m; i ++)
758  {
759  for (j = 0; j < n; j ++)
760  {
761  iRow[i*n + j] = i;
762  jCol[i*n + j] = j;
763  }
764  }
765  }
766  else
767  {
768  /* return the values of the jacobian of the constraints */
769 
770  int species_num_index = 0;
771  // Gas species
772  for (i = 0; i < gas_phase_num; i ++)
773  {
774  for (j = 0; j < phases.gas[i].species_num; j ++)
775  {
776  for (k = 0; k < m - 1; k ++)
777  {
778  //[component i, species j]
779  values[k * total_species_num + species_num_index] = phases.gas[i].gas_species[j].elements[k];
780  }
781 
782  values[(m - 1) * total_species_num + species_num_index] = phases.gas[i].gas_species[j].charge;
783 
784  species_num_index ++;
785  }
786  }
787 
788  // aqueous species
789  for (i = 0; i < aqueous_phase_num; i ++)
790  {
791  for (j = 0; j < phases.aqueous[i].species_num; j ++)
792  {
793  for (k = 0; k < m - 1; k ++)
794  {
795  values[k * total_species_num + species_num_index] = phases.aqueous[i].aqueous_species[j].elements[k];
796  }
797 
798  values[(m - 1) * total_species_num + species_num_index] = phases.aqueous[i].aqueous_species[j].charge;
799 
800  species_num_index ++;
801  }
802  }
803 
804  // Solid species
805  for (i = 0; i < solid_phase_num; i ++)
806  {
807  for (j = 0; j < phases.solids[i].species_num; j ++)
808  {
809  for (k = 0; k < total_comp_num; k ++)
810  {
811  values[k * total_species_num + species_num_index] = phases.solids[i].solid_species[j].elements[k];
812  }
813 
814  values[k * total_species_num + species_num_index] = phases.solids[i].solid_species[j].charge;
815 
816  species_num_index ++;
817  }
818  }
819 
820  // Solid solution species
821  for (i = 0; i < solidsolution_phase_num; i ++)
822  {
823  for (j = 0; j < phases.solidsolution[i].species_num; j ++)
824  {
825  for (k = 0; k < total_comp_num; k ++)
826  {
827  values[k * total_species_num + species_num_index] = phases.solidsolution[i].solidsolution_species[j].elements[k];
828  }
829 
830  values[k * total_species_num + species_num_index] = phases.solidsolution[i].solidsolution_species[j].charge;
831 
832  species_num_index ++;
833  }
834  }
835  }
836 
837  return TRUE;
838 }
839 
840 static Bool eval_h(Index n, Number *x, Bool new_x, Number obj_factor,
841  Index m, Number *lambda, Bool new_lambda,
842  Index nele_hess, Index *iRow, Index *jCol,
843  Number *values, UserDataPtr user_data)
844 {
845  return FALSE;
846 }
847 
848 static Bool intermediate_cb(Index alg_mod, Index iter_count, Number obj_value,
849  Number inf_pr, Number inf_du, Number mu, Number d_norm,
850  Number regularization_size, Number alpha_du,
851  Number alpha_pr, Index ls_trials, UserDataPtr user_data)
852 {
853  printf("Testing intermediate callback in iteration %d\n", iter_count);
854  if (inf_pr < 1e-4) return FALSE;
855 
856  return TRUE;
857 }
double rkg_a(SOLIDSOLUTION_PHASE ss, int index, double *n, double T, double P)
Definition: rkg_model.c:99
AQUEOUS_PHASE * aqueous
Definition: islec.h:189
int solidsolution_phase_num
Definition: islec.h:198
int species_num
Definition: islec.h:150
int species_num
Definition: islec.h:156
double * total_components
Definition: islec.h:213
SPECIES * gas_species
Definition: islec.h:151
double psc_a(AQUEOUS_PHASE aq, int index, double *n, double T, double P)
Definition: psc_model.c:3496
bool successed
Definition: islec.h:217
SPECIES * aqueous_species
Definition: islec.h:157
int species_num
Definition: islec.h:174
double system_T
Definition: islec.h:210
int charge
Definition: islec.h:80
int gem_ipopt()
Perform Gibbs energy minimization (GEM) using the IPOPT algrithium.
Definition: gem_ipopt.c:180
SOLIDSOLUTION_PHASE * solidsolution
Definition: islec.h:191
double * n_eq
Definition: islec.h:215
GAS_PHASE * gas
Definition: islec.h:188
double thermo_coeff[7]
Definition: islec.h:82
double system_P
Definition: islec.h:211
int aqueous_phase_num
Definition: islec.h:196
SOLID_PHASE * solids
Definition: islec.h:190
SPECIES * solid_species
Definition: islec.h:175
double * elements
Definition: islec.h:81
#define R
Definition: islec.h:37
int total_species_num
Definition: islec.h:200
double gibbs_eq
Definition: islec.h:216
PHASES phases
Definition: islec.h:206
int total_comp_num
Definition: islec.h:194
double system_charge
Definition: islec.h:212
int solid_phase_num
Definition: islec.h:197
int gas_phase_num
Definition: islec.h:195
SPECIES * solidsolution_species
Definition: islec.h:181