1 /*//////////////////////////////////////////////////////////////////////////////
2 //
10 //
11 // See the README.txt file in this directory for copyright and license
12 // information.
13 //
14 //
15 //
16 // Example to demonstrate how to use libnucnet routines to create
17 // a new Libnucnet structure from an input xml file, evolve a multi-zone
18 // nuclear network system, and clear the structure and free the
19 // allocated memory.
20 //
21 //
22 //
23 //////////////////////////////////////////////////////////////////////////////*/
24
25 /*##############################################################################
26 // Includes.
27 //############################################################################*/
28
29 #include
30 #include "remove_duplicate.h"
31 #include "screen.h"
32 #include "coul_corr.h"
33
34 /*##############################################################################
35 // Define some parameters.
36 //############################################################################*/
37
38 #define D_MIN 1.e-4 /* Newton-Raphson convergence criterion */
39 #define D_Y_MIN 1.e-30 /* Smallest y for convergence */
40 #define D_Y_MIN_PRINT 1.e-30 /* Smallest y to print out */
41 #define I_ITMAX 4 /* Maximum number of Newton-Raphson iterations */
42
43 #define D_REGT 0.15 /* Max fractional change in dt */
44 #define D_REGY 0.15 /* Max fractional change in y */
45 #define D_YMIN 1.e-10 /* Smallest y for change in dt */
46
47 /*##############################################################################
48 // Screening. "no" = no screening, "yes" = screening.
49 //############################################################################*/
50
51 #define USE_SCREENING "yes"
52
53 /*##############################################################################
54 // User structures.
55 //############################################################################*/
56
57 typedef struct {
58 Libnucnet *pLibnucnet;
59 gsl_vector *pYOld;
60 gsl_vector *pRhs;
61 gsl_vector *pSolution;
62 WnMatrix *pMatrix;
63 double *aT9;
64 double *aRho;
65 double dMixTime;
66 double dDt;
67 double dCheck;
68 } user_data;
69
70 user_screening_data my_screening_data;
71 user_coul_corr_data my_corr_data;
72
73 /*##############################################################################
74 // Prototypes.
75 //############################################################################*/
76
77 int evolve_system( Libnucnet *, double *, double *, double, double );
78 int print_zone( Libnucnet__Zone *, void * );
79 void print_abunds( Libnucnet__Zone * );
80 int print_abund( Libnucnet__Species *, Libnucnet__Zone * );
81 int get_next_timestep( Libnucnet__Zone *, double * );
82 int set_zone_abundances( Libnucnet__Zone *, gsl_vector * );
83 int set_zone( Libnucnet__Zone *, user_data * );
84 int set_mixing_terms( Libnucnet__Zone *, user_data * );
85 int update_abundances( Libnucnet__Zone *, user_data * );
86 int update_abundance_changes( Libnucnet__Zone *, gsl_vector * );
87 int initialize_zone( Libnucnet__Zone *, void * );
88
89 /*##############################################################################
90 // main()
91 //############################################################################*/
92
93 int main( int argc, char * argv[] ) {
94
95 double *a_t9, *a_rho, d_tend, d_t, d_dt;
96 double d_t9, d_rho, d_mix_time;
97 size_t i_index;
98 int i_step;
99 Libnucnet *p_my_nucnet;
100 FILE *p_in;
101
102 /*============================================================================
103 // Check input.
104 //==========================================================================*/
105
106 if ( argc < 5 || argc > 7 ) {
107 fprintf(
108 stderr,
109 "\nUsage: %s network_file param_file mix_time t_end xpath_nuc xpath_reac\n\n",
110 argv[0]
111 );
112 fprintf(
113 stderr, " network_file = input nuclear data xml filename\n\n"
114 );
115 fprintf(
116 stderr, " param_file = input t9 and rho data filename\n\n"
117 );
118 fprintf(
119 stderr, " mix_time = mixing time between zones (0 = no mixing)\n\n"
120 );
121 fprintf(
122 stderr, " t_end = time to evolve system\n\n"
123 );
124 fprintf(
125 stderr, " xpath_nuc = nuclear xpath expression (optional--required if xpath_reac specified\n\n"
126 );
127 fprintf(
128 stderr, " xpath_reac = reaction xpath expression (optional)\n\n"
129 );
130 return EXIT_FAILURE;
131 }
132
133 /*============================================================================
134 // Validate input xml.
135 //==========================================================================*/
136
137 if( !Libnucnet__is_valid_input_xml( argv[1] ) ) {
138 fprintf( stderr, "Not valid libnucnet input xml!\n" );
139 return EXIT_FAILURE;
140 }
141
142 /*============================================================================
143 // Read and store network data.
144 //==========================================================================*/
145
146 if( argc == 5 ) {
147 p_my_nucnet = Libnucnet__new_from_xml( argv[1], NULL, NULL );
148 } else if( argc == 6 ) {
149 p_my_nucnet = Libnucnet__new_from_xml( argv[1], argv[5], NULL );
150 } else {
151 p_my_nucnet = Libnucnet__new_from_xml( argv[1], argv[5], argv[6] );
152 }
153
154 /*============================================================================
155 // Open input file containing zone data.
156 //==========================================================================*/
157
158 if ( ( p_in = fopen( argv[2], "r" ) ) == NULL ) {
159
160 fprintf( stderr, "\nCannot open input param file!\n" );
161 return EXIT_FAILURE;
162
163 }
164
165 /*============================================================================
166 // Allocate memory for t9 and rho arrays.
167 //==========================================================================*/
168
169 a_t9 = ( double * ) malloc(
170 sizeof( double ) * Libnucnet__getNumberOfZones( p_my_nucnet )
171 );
172
173 if( !a_t9 ) {
174 fprintf( stderr, "Couldn't allocate memory for t9 array!\n" );
175 return EXIT_FAILURE;
176 }
177
178 a_rho = ( double * ) malloc(
179 sizeof( double ) * Libnucnet__getNumberOfZones( p_my_nucnet )
180 );
181
182 if( !a_rho ) {
183 fprintf( stderr, "Couldn't allocate memory for rho array!\n" );
184 return EXIT_FAILURE;
185 }
186
187 /*============================================================================
188 // Read in zone data.
189 //==========================================================================*/
190
191 i_index = 0;
192
193 while ( !feof( p_in ) ) {
194
195 if( i_index == Libnucnet__getNumberOfZones( p_my_nucnet ) ) {
196 fprintf( stderr, "Too many zones in input file!\n" );
197 return EXIT_FAILURE;
198 }
199
200 fscanf( p_in, "%lf %lf\n", &d_t9, &d_rho );
201 a_t9[i_index] = d_t9;
202 a_rho[i_index] = d_rho;
203 ++i_index;
204
205 }
206
207 /*============================================================================
208 // Close input file.
209 //==========================================================================*/
210
211 fclose( p_in );
212
213 /*============================================================================
214 // Check number of zones.
215 //==========================================================================*/
216
217 if ( Libnucnet__getNumberOfZones( p_my_nucnet ) != i_index ) {
218 printf( "Number of zones wrong in param.dat!\n" );
219 return EXIT_FAILURE;
220 }
221
222 /*============================================================================
223 // Iterate over zones to remove duplicates and set screening.
224 //==========================================================================*/
225
226 Libnucnet__iterateZones(
227 p_my_nucnet,
228 (Libnucnet__Zone__iterateFunction) initialize_zone,
229 NULL
230 );
231
232 /*============================================================================
233 // Store mixing time and final time.
234 //==========================================================================*/
235
236 d_mix_time = atof( argv[3] );
237 d_tend = atof( argv[4] );
238
239 /*============================================================================
240 // Initialize time.
241 //==========================================================================*/
242
243 d_dt = 1.e-10;
244 d_t = 0.0;
245
246 /*============================================================================
247 // Evolve network while t < final t.
248 //==========================================================================*/
249
250 i_step = 0;
251
252 while ( d_t < d_tend ) {
253
254 d_t += d_dt;
255
256 if ( evolve_system( p_my_nucnet, a_t9, a_rho, d_mix_time, d_dt ) != 0 ) {
257
258 fprintf( stderr, "Error evolving system!\n" );
259 return EXIT_FAILURE;
260
261 }
262
263 /*============================================================================
264 // Print out abundances every 25th time step.
265 //==========================================================================*/
266
267 if( i_step % 25 == 0 ) {
268
269 printf( "t = %10.4e, dt = %10.4e\n\n", d_t, d_dt );
270
271 Libnucnet__iterateZones(
272 p_my_nucnet,
273 (Libnucnet__Zone__iterateFunction) print_zone,
274 NULL
275 );
276
277 }
278
279 /*============================================================================
280 // Update timestep.
281 //==========================================================================*/
282
283 Libnucnet__iterateZones(
284 p_my_nucnet,
285 (Libnucnet__Zone__iterateFunction) get_next_timestep,
286 &d_dt
287 );
288
289 if ( d_t + d_dt > d_tend ) {
290
291 d_dt = d_tend - d_t;
292
293 }
294
295 i_step++;
296
297 }
298
299 /*============================================================================
300 // Print out final abundances.
301 //==========================================================================*/
302
303 printf( "t = %10.4e, dt = %10.4e\n\n", d_t, d_dt );
304
305 Libnucnet__iterateZones(
306 p_my_nucnet,
307 (Libnucnet__Zone__iterateFunction) print_zone,
308 NULL
309 );
310
311 /*============================================================================
312 // Clean up and exit.
313 //==========================================================================*/
314
315 free( a_t9 );
316 free( a_rho );
317 Libnucnet__free( p_my_nucnet );
318 return EXIT_SUCCESS;
319
320 }
321
322 /*##############################################################################
323 // evolve_system()
324 //############################################################################*/
325
326 int
327 evolve_system(
328 Libnucnet *self, double *a_t9, double *a_rho, double d_mix_time, double d_dt
329 ) {
330
331 size_t i_species, i_zones, i_dim, i_iter;
332 gsl_vector *p_abundance_changes;
333 user_data *p_user_data;
334
335 /*============================================================================
336 // Allocate Memory.
337 //==========================================================================*/
338
339 i_species =
340 Libnucnet__Nuc__getNumberOfSpecies(
341 Libnucnet__Net__getNuc(
342 Libnucnet__getNet( self )
343 )
344 );
345
346 i_zones = Libnucnet__getNumberOfZones( self );
347
348 i_dim = i_species * i_zones;
349
350 p_abundance_changes = gsl_vector_calloc( i_dim );
351
352 p_user_data = ( user_data * ) malloc( sizeof( user_data ) );
353
354 p_user_data->pRhs = gsl_vector_calloc( i_dim );
355
356 p_user_data->aT9 = a_t9;
357 p_user_data->aRho = a_rho;
358 p_user_data->dMixTime = d_mix_time;
359 p_user_data->dDt = d_dt;
360 p_user_data->pYOld = gsl_vector_calloc( i_dim );
361
362 /*============================================================================
363 // Store initial abundances.
364 //==========================================================================*/
365
366 p_user_data->pLibnucnet = self;
367
368 Libnucnet__iterateZones(
369 self,
370 (Libnucnet__Zone__iterateFunction) set_zone_abundances,
371 p_user_data->pYOld
372 );
373
374 /*============================================================================
375 // Newton-Raphson iterations.
376 //==========================================================================*/
377
378 for( i_iter = 0; i_iter < I_ITMAX; i_iter++ ) {
379
380 p_user_data->pMatrix = WnMatrix__new( i_dim, i_dim );
381
382 /*==========================================================================
383 // Loop Over Zones.
384 //========================================================================*/
385
386 Libnucnet__iterateZones(
387 self,
388 (Libnucnet__Zone__iterateFunction) set_zone,
389 p_user_data
390 );
391
392
393 /*==========================================================================
394 // Assign mixing terms.
395 //========================================================================*/
396
397 if( d_mix_time < 0. ) {
398 fprintf( stderr, "Invalid mixing time" );
399 exit( EXIT_FAILURE );
400 }
401
402 if( d_mix_time != 0. )
403 Libnucnet__iterateZones(
404 self,
405 (Libnucnet__Zone__iterateFunction) set_mixing_terms,
406 p_user_data
407 );
408
409 /*========================================================================
410 // Add 1/dt to diagonals.
411 //========================================================================*/
412
413 WnMatrix__addValueToDiagonals( p_user_data->pMatrix, 1.0 / d_dt );
414
415 /*========================================================================
416 // Solve matrix.
417 //========================================================================*/
418
419 p_user_data->pSolution =
420 WnMatrix__solve( p_user_data->pMatrix, p_user_data->pRhs );
421
422 /*==========================================================================
423 // Update abundances.
424 //========================================================================*/
425
426 p_user_data->dCheck = 0.;
427
428 Libnucnet__iterateZones(
429 self,
430 (Libnucnet__Zone__iterateFunction) update_abundances,
431 p_user_data
432 );
433
434 /*==========================================================================
435 // Update abundance changes.
436 //========================================================================*/
437
438 gsl_vector_add( p_abundance_changes, p_user_data->pSolution );
439
440 /*==========================================================================
441 // Free matrix and solution vector.
442 //========================================================================*/
443
444 gsl_vector_free( p_user_data->pSolution );
445 WnMatrix__free( p_user_data->pMatrix );
446
447 /*==========================================================================
448 // Break if solution converged.
449 //========================================================================*/
450
451 if( p_user_data->dCheck < D_MIN ) break;
452
453 }
454
455 /*============================================================================
456 // Update abundance changes.
457 //==========================================================================*/
458
459 Libnucnet__iterateZones(
460 self,
461 (Libnucnet__Zone__iterateFunction) update_abundance_changes,
462 p_abundance_changes
463 );
464
465
466 /*==========================================================================
467 // Free allocated memory.
468 //========================================================================*/
469
470 gsl_vector_free( p_abundance_changes );
471
472 gsl_vector_free( p_user_data->pRhs );
473 gsl_vector_free( p_user_data->pYOld );
474
475 free( p_user_data );
476
477 return 0;
478
479 }
480
481 /*##############################################################################
482 // print_zone()
483 //############################################################################*/
484
485 int
486 print_zone( Libnucnet__Zone *p_zone, void *p_data )
487 {
488
489 if( p_data ) {
490 fprintf( stderr, "Routine should have no extra data!\n" );
491 return 0;
492 }
493
494 fprintf(
495 stdout,
496 "Zone: %s %s %s\n\n",
497 Libnucnet__Zone__getLabel( p_zone, 1 ),
498 Libnucnet__Zone__getLabel( p_zone, 2 ),
499 Libnucnet__Zone__getLabel( p_zone, 3 )
500 );
501
502 print_abunds( p_zone );
503
504 return 1;
505
506 }
507
508 /*##############################################################################
509 // print_abunds()
510 //############################################################################*/
511
512 void
513 print_abunds( Libnucnet__Zone *p_zone ) {
514
515 Libnucnet__Nuc__iterateSpecies(
516 Libnucnet__Net__getNuc(
517 Libnucnet__Zone__getNet( p_zone )
518 ),
519 (Libnucnet__Species__iterateFunction) print_abund,
520 p_zone
521 );
522
523 fprintf(
524 stdout,
525 "\n1 - xsum = %g\n",
526 1. - Libnucnet__Zone__computeAMoment( p_zone, 1 )
527 );
528
529 }
530
531 /*##############################################################################
532 // print_abund()
533 //############################################################################*/
534
535 int
536 print_abund( Libnucnet__Species *p_species, Libnucnet__Zone *p_zone )
537 {
538
539 double d_abund;
540
541 d_abund = Libnucnet__Zone__getSpeciesAbundance( p_zone, p_species );
542
543 if ( d_abund > D_Y_MIN_PRINT ) {
544
545 printf(
546 "%5d%5d%14.4e%14.4e\n",
547 Libnucnet__Species__getZ( p_species ),
548 Libnucnet__Species__getA( p_species ),
549 d_abund,
550 Libnucnet__Zone__getSpeciesAbundanceChange( p_zone, p_species )
551 );
552
553 }
554
555 return 1;
556
557 }
558
559 /*##############################################################################
560 // get_next_timestep().
561 //############################################################################*/
562
563 int
564 get_next_timestep( Libnucnet__Zone *p_zone, double *p_dt )
565 {
566
567 Libnucnet__Zone__updateTimeStep(
568 p_zone,
569 p_dt,
570 D_REGT,
571 D_REGY,
572 D_YMIN
573 );
574
575 return 1;
576
577 }
578
579 /*##############################################################################
580 // set_zone_abundances().
581 //############################################################################*/
582
583 int
584 set_zone_abundances( Libnucnet__Zone *p_zone, gsl_vector *p_old )
585 {
586
587 gsl_vector *p_abundances;
588 gsl_vector_view v_old;
589 size_t i_zone;
590
591 i_zone = atoi( Libnucnet__Zone__getLabel( p_zone, 1 ) );
592
593 p_abundances =
594 Libnucnet__Zone__getAbundances( p_zone );
595
596 v_old =
597 gsl_vector_subvector(
598 p_old,
599 i_zone * WnMatrix__get_gsl_vector_size( p_abundances ),
600 WnMatrix__get_gsl_vector_size( p_abundances )
601 );
602
603 gsl_vector_memcpy( &v_old.vector, p_abundances );
604
605 gsl_vector_free( p_abundances );
606
607 return 1;
608
609 }
610
611 /*##############################################################################
612 // set_zone()
613 //############################################################################*/
614
615 int
616 set_zone( Libnucnet__Zone *p_zone, user_data *p_user_data )
617 {
618
619 size_t i_zone;
620 gsl_vector *p_abund, *p_rhs;
621 gsl_vector_view v_old, v_rhs;
622 WnMatrix *p_matrix;
623
624 /*========================================================================
625 // Get zone.
626 //======================================================================*/
627
628 i_zone = atoi( Libnucnet__Zone__getLabel( p_zone, 1 ) );
629
630 /*========================================================================
631 // If T9 = 0, return.
632 //======================================================================*/
633
634 if( p_user_data->aT9[i_zone] == 0 ) return 1;
635
636 /*========================================================================
637 // Compute rates.
638 //======================================================================*/
639
640 Libnucnet__Zone__computeRates(
641 p_zone,
642 p_user_data->aT9[i_zone],
643 p_user_data->aRho[i_zone]
644 );
645
646 /*======================================================================
647 // Get right hand side vector.
648 //======================================================================*/
649
650 p_rhs = Libnucnet__Zone__computeFlowVector( p_zone );
651
652 p_abund =
653 Libnucnet__Zone__getAbundances( p_zone );
654
655 v_old =
656 gsl_vector_subvector(
657 p_user_data->pYOld,
658 i_zone * WnMatrix__get_gsl_vector_size( p_abund ),
659 WnMatrix__get_gsl_vector_size( p_abund )
660 );
661
662 gsl_vector_sub(
663 p_abund, &v_old.vector
664 );
665
666 gsl_vector_scale( p_abund, 1. / p_user_data->dDt );
667
668 gsl_vector_sub( p_rhs, p_abund );
669
670 /*======================================================================
671 // Insert into large vector.
672 //======================================================================*/
673
674 v_rhs =
675 gsl_vector_subvector(
676 p_user_data->pRhs,
677 i_zone * WnMatrix__get_gsl_vector_size( p_rhs ),
678 WnMatrix__get_gsl_vector_size( p_rhs )
679 );
680
681 gsl_vector_memcpy( &v_rhs.vector, p_rhs );
682
683 gsl_vector_free( p_rhs );
684
685 /*========================================================================
686 // Get the Jacobian Matrix.
687 //======================================================================*/
688
689 p_matrix = Libnucnet__Zone__computeJacobianMatrix( p_zone );
690
691 /*========================================================================
692 // Insert single-zone matrix into full matrix.
693 //======================================================================*/
694
695 WnMatrix__insertMatrix(
696 p_user_data->pMatrix,
697 p_matrix,
698 i_zone * WnMatrix__get_gsl_vector_size( p_abund ) + 1,
699 i_zone * WnMatrix__get_gsl_vector_size( p_abund ) + 1
700 );
701
702 /*========================================================================
703 // Free memory allocated for single-zone matrix and abundances.
704 //======================================================================*/
705
706 gsl_vector_free( p_abund );
707 WnMatrix__free( p_matrix );
708
709 return 1;
710
711 }
712
713 /*##############################################################################
714 // set_mixing_terms().
715 //############################################################################*/
716
717 int
718 set_mixing_terms( Libnucnet__Zone *p_zone, user_data *p_user_data )
719 {
720
721 Libnucnet__Zone *p_previous, *p_next;
722 gsl_vector *p_abundances;
723 gsl_vector_view v_view;
724 size_t i, i_species, i_zone;
725 char s_label[256];
726
727 i_species =
728 Libnucnet__Nuc__getNumberOfSpecies(
729 Libnucnet__Net__getNuc(
730 Libnucnet__Zone__getNet( p_zone )
731 )
732 );
733
734 i_zone = atoi( Libnucnet__Zone__getLabel( p_zone, 1 ) );
735
736 /*============================================================================
737 // Add mixing to/from previous zone.
738 //==========================================================================*/
739
740 if( i_zone != 0 ) {
741
742 sprintf( s_label, "%d", i_zone - 1 );
743
744 v_view =
745 gsl_vector_subvector(
746 p_user_data->pRhs,
747 i_zone * i_species,
748 i_species
749 );
750
751 p_previous =
752 Libnucnet__getZoneByLabels(
753 p_user_data->pLibnucnet,
754 s_label,
755 "0",
756 "0"
757 );
758
759 for( i = 0; i < i_species; i++ )
760 WnMatrix__assignElement(
761 p_user_data->pMatrix,
762 i_zone * i_species + i + 1,
763 ( i_zone - 1 ) * i_species + i + 1,
764 -1. / p_user_data->dMixTime
765 );
766
767 p_abundances = Libnucnet__Zone__getAbundances( p_previous );
768
769 gsl_vector_scale( p_abundances, 1. / p_user_data->dMixTime );
770
771 gsl_vector_add( &v_view.vector, p_abundances );
772
773 gsl_vector_free( p_abundances );
774
775 for( i = 0; i < i_species; i++ )
776 WnMatrix__assignElement(
777 p_user_data->pMatrix,
778 i_zone * i_species + i + 1,
779 i_zone * i_species + i + 1,
780 1. / p_user_data->dMixTime
781 );
782
783 p_abundances = Libnucnet__Zone__getAbundances( p_zone );
784
785 gsl_vector_scale( p_abundances, -1. / p_user_data->dMixTime );
786
787 gsl_vector_add( &v_view.vector, p_abundances );
788
789 gsl_vector_free( p_abundances );
790
791 }
792
793 /*============================================================================
794 // Add mixing to/from next zone.
795 //==========================================================================*/
796
797 if( i_zone < Libnucnet__getNumberOfZones( p_user_data->pLibnucnet ) - 1 ) {
798
799 sprintf( s_label, "%d", i_zone + 1 );
800
801 v_view =
802 gsl_vector_subvector(
803 p_user_data->pRhs,
804 i_zone * i_species,
805 i_species
806 );
807
808 p_next =
809 Libnucnet__getZoneByLabels(
810 p_user_data->pLibnucnet,
811 s_label,
812 "0",
813 "0"
814 );
815
816 for( i = 0; i < i_species; i++ )
817 WnMatrix__assignElement(
818 p_user_data->pMatrix,
819 i_zone * i_species + i + 1,
820 ( i_zone + 1 ) * i_species + i + 1,
821 -1. / p_user_data->dMixTime
822 );
823
824 p_abundances = Libnucnet__Zone__getAbundances( p_next );
825
826 gsl_vector_scale( p_abundances, 1. / p_user_data->dMixTime );
827
828 gsl_vector_add( &v_view.vector, p_abundances );
829
830 gsl_vector_free( p_abundances );
831
832 for( i = 0; i < i_species; i++ )
833 WnMatrix__assignElement(
834 p_user_data->pMatrix,
835 i_zone * i_species + i + 1,
836 i_zone * i_species + i + 1,
837 1. / p_user_data->dMixTime
838 );
839
840 p_abundances = Libnucnet__Zone__getAbundances( p_zone );
841
842 gsl_vector_scale( p_abundances, -1. / p_user_data->dMixTime );
843
844 gsl_vector_add( &v_view.vector, p_abundances );
845
846 gsl_vector_free( p_abundances );
847
848 }
849
850 return 1;
851
852 }
853
854 /*##############################################################################
855 // update_abundances().
856 //############################################################################*/
857
858 int
859 update_abundances( Libnucnet__Zone *p_zone, user_data *p_user_data )
860 {
861
862 size_t i, i_zone, i_species;
863 double d_y, d_checkT;
864 gsl_vector *p_new_abundances;
865 gsl_vector_view v_view;
866
867 i_zone = atoi( Libnucnet__Zone__getLabel( p_zone, 1 ) );
868
869 i_species =
870 Libnucnet__Nuc__getNumberOfSpecies(
871 Libnucnet__Net__getNuc(
872 Libnucnet__Zone__getNet( p_zone )
873 )
874 );
875
876 p_new_abundances = Libnucnet__Zone__getAbundances( p_zone );
877
878 v_view =
879 gsl_vector_subvector(
880 p_user_data->pSolution,
881 i_species * i_zone,
882 i_species
883 );
884
885 gsl_vector_add( p_new_abundances, &v_view.vector );
886
887 Libnucnet__Zone__updateAbundances( p_zone, p_new_abundances );
888
889 for( i = 0; i < WnMatrix__get_gsl_vector_size( p_new_abundances ); i++ ) {
890 d_y = gsl_vector_get( p_new_abundances, i );
891 if( d_y > D_Y_MIN ) {
892 d_checkT = fabs( gsl_vector_get( &v_view.vector, i ) / d_y );
893 if( d_checkT > p_user_data->dCheck )
894 p_user_data->dCheck = d_checkT;
895 }
896
897 }
898
899 gsl_vector_free( p_new_abundances );
900
901 return 1;
902
903 }
904
905 /*##############################################################################
906 // update_abundance_changes().
907 //############################################################################*/
908
909 int
910 update_abundance_changes( Libnucnet__Zone *p_zone, gsl_vector *p_changes )
911 {
912
913 size_t i_zone, i_species;
914 gsl_vector_view v_view;
915
916 i_zone = atoi( Libnucnet__Zone__getLabel( p_zone, 1 ) );
917
918 i_species =
919 Libnucnet__Nuc__getNumberOfSpecies(
920 Libnucnet__Net__getNuc(
921 Libnucnet__Zone__getNet( p_zone )
922 )
923 );
924
925 v_view =
926 gsl_vector_subvector(
927 p_changes,
928 i_zone * i_species,
929 i_species
930 );
931
932 Libnucnet__Zone__updateAbundanceChanges( p_zone, &v_view.vector );
933
934 return 1;
935
936 }
937
938 /*##############################################################################
939 // initialize_zone().
940 //############################################################################*/
941
942 int
943 initialize_zone( Libnucnet__Zone *p_zone, void *p_data )
944 {
945
946 Libnucnet__Reac *p_my_duplicates;
947
948 /*============================================================================
949 // Check input.
950 //==========================================================================*/
951
952 if( p_data ) {
953 fprintf( stderr, "Routine takes no extra data!\n" );
954 exit( EXIT_FAILURE );
955 }
956
957 /*============================================================================
958 // Remove duplicate reactions.
959 //==========================================================================*/
960
961 p_my_duplicates =
962 Libnucnet__Reac__getDuplicateReactions(
963 Libnucnet__Net__getReac(
964 Libnucnet__Zone__getNet( p_zone )
965 )
966 );
967
968 Libnucnet__Reac__iterateReactions(
969 p_my_duplicates,
970 (Libnucnet__Reaction__iterateFunction) remove_duplicate,
971 Libnucnet__Zone__getNet( p_zone )
972 );
973
974 Libnucnet__Reac__free( p_my_duplicates );
975
976 /*============================================================================
977 // Set screening, if desired.
978 //==========================================================================*/
979
980 if( strcmp( USE_SCREENING, "yes" ) == 0 ) {
981
982 /*==========================================================================
983 // Set screening data and function.
984 //========================================================================*/
985
986 my_screening_data.dYe2 =
987 Libnucnet__Zone__computeZMoment( p_zone, 2 );
988
989 Libnucnet__Zone__setScreeningFunction(
990 p_zone,
991 (Libnucnet__Net__screeningFunction) my_screening_function,
992 &my_screening_data
993 );
994
995 /*==========================================================================
996 // Set correction function.
997 //========================================================================*/
998
999 my_corr_data.dA1 = -0.9052;
1000 my_corr_data.dA2 = 0.6322;
1001
1002 Libnucnet__Zone__setNseCorrectionFactorFunction(
1003 p_zone,
1004 (Libnucnet__Species__nseCorrectionFactorFunction) my_coulomb_correction,
1005 &my_corr_data
1006 );
1007
1008 }
1009
1010 return 1;
1011
1012 }
1013