LCOV - code coverage report
Current view: top level - star/private - pgstar_abundance.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 196 0
Test Date: 2025-05-08 18:23:42 Functions: 0.0 % 9 0

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2010-2019  The MESA Team
       4              : !
       5              : !   This program is free software: you can redistribute it and/or modify
       6              : !   it under the terms of the GNU Lesser General Public License
       7              : !   as published by the Free Software Foundation,
       8              : !   either version 3 of the License, or (at your option) any later version.
       9              : !
      10              : !   This program is distributed in the hope that it will be useful,
      11              : !   but WITHOUT ANY WARRANTY; without even the implied warranty of
      12              : !   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      13              : !   See the GNU Lesser General Public License for more details.
      14              : !
      15              : !   You should have received a copy of the GNU Lesser General Public License
      16              : !   along with this program. If not, see <https://www.gnu.org/licenses/>.
      17              : !
      18              : ! ***********************************************************************
      19              : 
      20              :       module pgstar_abundance
      21              : 
      22              :       use star_private_def
      23              :       use const_def, only: dp
      24              :       use pgstar_support
      25              :       use star_pgstar
      26              : 
      27              :       implicit none
      28              : 
      29              :       contains
      30              : 
      31            0 :       subroutine abundance_plot(id, device_id, ierr)
      32              :          integer, intent(in) :: id, device_id
      33              :          integer, intent(out) :: ierr
      34              : 
      35              :          type (star_info), pointer :: s
      36              : 
      37              :          ierr = 0
      38            0 :          call get_star_ptr(id, s, ierr)
      39            0 :          if (ierr /= 0) return
      40              : 
      41            0 :          call pgslct(device_id)
      42            0 :          call pgbbuf()
      43            0 :          call pgeras()
      44              : 
      45              :          call do_abundance_plot(s, id, device_id, &
      46              :             s% pg% Abundance_xleft, s% pg% Abundance_xright, &
      47              :             s% pg% Abundance_ybot, s% pg% Abundance_ytop, .false., &
      48            0 :             s% pg% Abundance_title, s% pg% Abundance_txt_scale, ierr)
      49              : 
      50            0 :          call pgebuf()
      51              : 
      52              :       end subroutine abundance_plot
      53              : 
      54              : 
      55            0 :       subroutine do_abundance_plot(s, id, device_id, &
      56              :             winxmin, winxmax, winymin, winymax, subplot, &
      57              :             title, txt_scale, ierr)
      58              :          type (star_info), pointer :: s
      59              :          integer, intent(in) :: id, device_id
      60              :          real, intent(in) :: winxmin, winxmax, winymin, winymax
      61              :          logical, intent(in) :: subplot
      62              :          character (len=*), intent(in) :: title
      63              :          real, intent(in) :: txt_scale
      64              :          integer, intent(out) :: ierr
      65              :          call do_abundance_panel(s, id, device_id, &
      66              :             winxmin, winxmax, winymin, winymax, subplot, &
      67              :             title, txt_scale, s% pg% Abundance_xaxis_name, &
      68              :             s% pg% Abundance_xmin, s% pg% Abundance_xmax, s% pg% Abundance_xaxis_reversed, &
      69              :             s% pg% abundance_log_mass_frac_min, s% pg% abundance_log_mass_frac_max, &
      70            0 :             .false., .true., ierr)
      71            0 :       end subroutine do_abundance_plot
      72              : 
      73              : 
      74            0 :       subroutine do_abundance_panel(s, id, device_id, &
      75              :             winxmin, winxmax, winymin, winymax, subplot, title, txt_scale, &
      76              :             xaxis_name, xaxis_min, xaxis_max, xaxis_reversed, ymin_in, ymax_in, &
      77              :             panel_flag, xaxis_numeric_labels_flag, ierr)
      78              :          use utils_lib
      79              :          use chem_def
      80              :          use net_def
      81              :          use const_def, only: Msun, Rsun
      82              :          use pgstar_colors
      83              : 
      84              :          type (star_info), pointer :: s
      85              :          integer, intent(in) :: id, device_id
      86              :          real, intent(in) :: &
      87              :             winxmin, winxmax, winymin, winymax, xaxis_min, xaxis_max, ymin_in, ymax_in
      88              :          character (len=*), intent(in) :: title, xaxis_name
      89              :          real, intent(in) :: txt_scale
      90              :          logical, intent(in) :: subplot, &
      91              :             xaxis_reversed, panel_flag, xaxis_numeric_labels_flag
      92              :          integer, intent(out) :: ierr
      93              : 
      94              :          real, allocatable, dimension(:) :: xvec, yvec
      95            0 :          real :: xmin, xmax, xleft, xright, dx, dylbl, chScale, windy, xmargin, &
      96              :             ymin, ymax, legend_xmin, legend_xmax, legend_ymin, legend_ymax
      97              :          integer :: lw, lw_sav, grid_min, grid_max, npts, nz
      98              :          integer, parameter :: num_colors = 14
      99              :          integer :: colors(num_colors)
     100              :          integer, parameter :: max_num_labels = 30
     101              :          integer :: num_labels, iloc_abundance_label(max_num_labels)
     102            0 :          real :: xloc_abundance_label(max_num_labels)
     103              : 
     104              :          include 'formats'
     105            0 :          ierr = 0
     106            0 :          nz = s% nz
     107              : 
     108              :          colors(:) = [ &
     109              :                clr_Gold, clr_LightSkyBlue, clr_Crimson, clr_Goldenrod, clr_MediumSlateBlue, &
     110              :                clr_Coral, clr_LightSkyGreen, clr_DarkGray, clr_Lilac, &
     111            0 :                clr_Tan, clr_IndianRed, clr_Teal, clr_Silver, clr_BrightBlue ]
     112              : 
     113            0 :          chScale = txt_scale
     114              : 
     115            0 :          ymin = ymin_in
     116            0 :          ymax = ymax_in
     117            0 :          if (abs(ymin+101.0) < 1e-6) ymin = s% pg% abundance_log_mass_frac_min
     118            0 :          if (abs(ymax+101.0) < 1e-6) ymax = s% pg% abundance_log_mass_frac_max
     119              : 
     120            0 :          windy = winymax - winymin
     121              : 
     122            0 :          legend_xmin = winxmax
     123            0 :          legend_xmax = min(1.0, winxmax + (winxmax - winxmin)/5)
     124              : 
     125            0 :          legend_ymin = winymin
     126            0 :          legend_ymax = winymax
     127              : 
     128            0 :          allocate(xvec(nz), yvec(nz))
     129              : 
     130            0 :          xmargin = 0
     131              :          call set_xaxis_bounds( &
     132              :             s, xaxis_name, xaxis_min, xaxis_max, xaxis_reversed, &
     133              :             xmargin, xvec, xmin, xmax, xleft, xright, dx, &
     134            0 :             grid_min, grid_max, npts, ierr)
     135            0 :          if (ierr == 0) call plot(ierr)
     136              : 
     137            0 :          deallocate(xvec, yvec)
     138              : 
     139              :          contains
     140              : 
     141              : 
     142            0 :          subroutine plot(ierr)
     143            0 :             use rates_def
     144              :             integer, intent(out) :: ierr
     145              : 
     146              :             integer :: i, k
     147              :             logical, parameter :: dbg = .false.
     148            0 :             real(dp) :: photosphere_logxm
     149            0 :             real :: lgz, x, ybot
     150              : 
     151              :             include 'formats'
     152            0 :             ierr = 0
     153              : 
     154            0 :             if (ymin > 0) then
     155            0 :                ymin = -5.1
     156            0 :                lgz = log10(s% initial_z + 1e-9) - 1
     157            0 :                if (lgz-1 < ymin) ymin = lgz
     158              :             end if
     159            0 :             if (ymax >= 100) then
     160            0 :                if (ymin < -8) then
     161            0 :                   ymax = 0.5
     162              :                else
     163            0 :                   ymax = 0.25
     164              :                end if
     165              :             end if
     166              : 
     167            0 :             num_labels = max(0,min(max_num_labels, s% pg% num_abundance_line_labels))
     168              : 
     169            0 :             iloc_abundance_label = -HUGE(grid_min)
     170            0 :             xloc_abundance_label = -HUGE(grid_min)
     171            0 :             do i=1,num_labels
     172            0 :                x = xmin + (i-0.5)*dx/num_labels
     173            0 :                do k=2,nz
     174            0 :                   if ((xvec(k-1)-x)*(x-xvec(k)) >= 0) then
     175            0 :                      iloc_abundance_label(i) = k
     176            0 :                      xloc_abundance_label(i) = x
     177            0 :                      exit
     178              :                   end if
     179              :                end do
     180              :             end do
     181              : 
     182            0 :             dylbl = (ymax - ymin)*0.015
     183              : 
     184            0 :             lw = s% pg% pgstar_lw
     185            0 :             call pgqlw(lw_sav)
     186              : 
     187            0 :             call pgsave
     188            0 :             call pgsch(txt_scale)
     189            0 :             call pgsvp(legend_xmin, legend_xmax, legend_ymin, legend_ymax)
     190            0 :             call pgswin(0.0, 1.0, ymin, ymax)
     191            0 :             call do_all(.true.)
     192            0 :             call pgunsa
     193              : 
     194            0 :             call pgsave
     195            0 :             call pgsch(txt_scale)
     196              : 
     197            0 :             call pgsvp(winxmin, winxmax, winymin, winymax)
     198            0 :             if (.not. panel_flag) then
     199            0 :                if (.not. subplot) then
     200            0 :                   call show_model_number_pgstar(s)
     201            0 :                   call show_age_pgstar(s)
     202              :                end if
     203            0 :                call show_title_pgstar(s, title)
     204            0 :                call pgsci(clr_Foreground)
     205            0 :                call show_xaxis_name(s,xaxis_name,ierr)
     206            0 :                if (ierr /= 0) return
     207              :             end if
     208              : 
     209            0 :             ybot = -0.05
     210            0 :             call pgswin(xleft, xright, ymin+ybot, ymax)
     211            0 :             call pgscf(1)
     212            0 :             call pgsci(clr_Foreground)
     213            0 :             if (xaxis_numeric_labels_flag) then
     214            0 :                call show_box_pgstar(s,'BCNST','BCNSTV')
     215              :             else
     216            0 :                call show_box_pgstar(s,'BCST','BCNSTV')
     217              :             end if
     218            0 :             call show_left_yaxis_label_pgstar(s, 'log mass fraction')
     219              : 
     220            0 :             call pgsave
     221            0 :             call pgsch(txt_scale*1.05)
     222            0 :             call do_all(.false.)
     223            0 :             call pgunsa
     224              : 
     225            0 :             if (.not. panel_flag) then  ! show mix regions at bottom of plot
     226            0 :                call pgslw(10)
     227              :                call show_mix_regions_on_xaxis( &
     228            0 :                   s,ymin+ybot,ymax,grid_min,grid_max,xvec)
     229              :             end if
     230              : 
     231            0 :             call pgunsa
     232              : 
     233            0 :             if (s% pg% Abundance_show_photosphere_location .and. &
     234              :                   (xaxis_name == 'mass' .or. &
     235              :                    xaxis_name == 'logxm' .or. &
     236              :                    xaxis_name == 'radius')) then
     237            0 :                call pgsave
     238            0 :                call pgsvp(winxmin, winxmax, winymin, winymax)
     239            0 :                call pgswin(0.0, 1.0, 0.0, 1.0)
     240            0 :                call pgsci(clr_Gray)
     241            0 :                call pgsls(Line_Type_Dash)
     242            0 :                call pgslw(5)
     243            0 :                if (xaxis_name == 'radius') then
     244            0 :                   dx = (s% photosphere_r - xmin)/(xmax - xmin)
     245            0 :                else if (xaxis_name == 'radius_cm') then
     246            0 :                   dx = (s% photosphere_r*Rsun - xmin)/(xmax - xmin)
     247            0 :                else if (xaxis_name == 'mass') then
     248            0 :                   dx = (s% photosphere_m - xmin)/(xmax - xmin)
     249              :                else
     250            0 :                   if (s% star_mass > s% photosphere_m) then
     251            0 :                      photosphere_logxm = log10(s% star_mass - s% photosphere_m)
     252              :                   else
     253            0 :                      photosphere_logxm = -99
     254              :                   end if
     255              :                   !dx = (xmax - photosphere_logxm)/(xmin - xmax)
     256            0 :                   dx = 1 - (photosphere_logxm - xmin)/(xmax - xmin)
     257            0 :                   write(*,2) 'photosphere_xm xmin photo_x xmax dx', s% model_number, &
     258            0 :                      s% star_mass - s% photosphere_m, &
     259            0 :                      xmin, photosphere_logxm, xmax, dx
     260              :                end if
     261            0 :                call pgmove(dx, 0.0)
     262            0 :                call pgdraw(dx, 1.0)
     263            0 :                call pgunsa
     264              :             end if
     265              : 
     266            0 :          call show_pgstar_decorator(s%id,s% pg% Abundance_use_decorator,s% pg% Abundance_pgstar_decorator,0, ierr)
     267              : 
     268            0 :          end subroutine plot
     269              : 
     270              : 
     271            0 :          subroutine do_all(legend_flag)
     272              :             logical, intent(in) :: legend_flag
     273              :             integer :: cnt, num_to_show, i, j, jmax
     274            0 :             real(dp) :: max_abund(s% species)
     275              :             include 'formats'
     276            0 :             cnt = 0
     277            0 :             num_to_show = s% pg% Abundance_num_isos_to_show
     278            0 :             do j=1, s% species
     279            0 :                max_abund(j) = maxval(s% xa(j,grid_min:grid_max))
     280              :             end do
     281            0 :             if (num_to_show < 0) then  ! show as many as fit
     282            0 :                if (legend_flag) then
     283            0 :                   jmax = min(s% species, max_num_labels)
     284              :                else
     285              :                   jmax = s% species
     286              :                end if
     287            0 :                do j = 1, jmax
     288            0 :                   i = maxloc(max_abund(:),dim=1)
     289            0 :                   cnt = do1(cnt, chem_isos% name(s% chem_id(i)), legend_flag)
     290            0 :                   max_abund(i) = -1
     291              :                end do
     292              :             else
     293            0 :                do i = 1, num_to_show
     294            0 :                   cnt = do1(cnt, s% pg% Abundance_which_isos_to_show(i), legend_flag)
     295              :                end do
     296              :             end if
     297            0 :          end subroutine do_all
     298              : 
     299              : 
     300            0 :          integer function do1(cnt, str, legend_flag)
     301              :             use chem_lib, only: chem_get_iso_id
     302              :             integer, intent(in) :: cnt
     303              :             character (len=*), intent(in) :: str
     304              :             logical, intent(in) :: legend_flag
     305              :             integer :: i, cid, k
     306              :             include 'formats'
     307            0 :             do1 = cnt
     308            0 :             if (len_trim(str) == 0) return
     309            0 :             cid = chem_get_iso_id(str)
     310            0 :             if (cid <= 0) return
     311            0 :             i = s% net_iso(cid)
     312            0 :             if (i == 0) return
     313            0 :             do k=1,nz
     314            0 :                yvec(k) = safe_log10(s% xa(i,k))
     315              :             end do
     316            0 :             if (s% pg% abundance_log_mass_frac_min < 0) then
     317            0 :                if (maxval(yvec(grid_min:grid_max)) < &
     318              :                      s% pg% abundance_log_mass_frac_min) return
     319              :             end if
     320            0 :             if (legend_flag) then
     321            0 :                do1 = abundance_line_legend(cnt, str)
     322              :             else
     323            0 :                do1 = abundance_line(cnt, i, str)
     324              :             end if
     325            0 :          end function do1
     326              : 
     327              : 
     328            0 :          subroutine set_line_style(cnt)
     329              :             integer, intent(in) :: cnt
     330              :             integer :: iclr, itype
     331            0 :             iclr = cnt - num_colors*(cnt/num_colors) + 1
     332            0 :             call pgsci(colors(iclr))
     333            0 :             if (cnt >= num_colors) then
     334            0 :                itype = Line_Type_Dot
     335              :             else
     336            0 :                itype = Line_Type_Solid
     337              :             end if
     338            0 :             call pgsls(itype)
     339            0 :          end subroutine set_line_style
     340              : 
     341              : 
     342            0 :          integer function abundance_line(cnt, j, str)
     343              :             integer, intent(in) :: cnt, j
     344              :             character (len=*), intent(in) :: str
     345              :             integer :: i, ii
     346            0 :             real :: x, frac, y, dx
     347              :             include 'formats'
     348            0 :             call set_line_style(cnt)
     349            0 :             call pgslw(lw)
     350            0 :             call pgline(npts, xvec(grid_min:grid_max), yvec(grid_min:grid_max))
     351            0 :             call pgslw(lw_sav)
     352            0 :             call pgsch(txt_scale*s% pg% Abundance_line_txt_scale_factor)
     353            0 :             abundance_line = cnt + 1
     354            0 :             do i=1,num_labels
     355            0 :                ii = iloc_abundance_label(i)
     356            0 :                if (ii > grid_max .or. ii < grid_min) cycle
     357            0 :                x = xloc_abundance_label(i)
     358            0 :                if (ii > grid_min) then
     359            0 :                   dx = xvec(ii)-xvec(ii-1)
     360            0 :                   if (abs(dx) > 1e-20) then
     361            0 :                      frac = (x-xvec(ii-1))/dx
     362              :                   else
     363              :                      frac = 1.0
     364              :                   end if
     365            0 :                   y = frac*yvec(ii) + (1.0-frac)*yvec(ii-1) + dylbl
     366              :                else
     367            0 :                   y = yvec(ii) + dylbl
     368              :                end if
     369            0 :                if (y < ymin .or. y > ymax) cycle
     370            0 :                call pgptxt(x, y, 0.0, 0.5, str)
     371              :             end do
     372            0 :          end function abundance_line
     373              : 
     374              : 
     375            0 :          integer function abundance_line_legend(cnt, str)
     376              :             integer, intent(in) :: cnt
     377              :             character (len=*), intent(in) :: str
     378            0 :             real :: dx, dyline, ypos, xpts(2), ypts(2)
     379              :             integer :: max_cnt
     380            0 :             max_cnt = min(max_num_labels, s% pg% Abundance_legend_max_cnt)
     381            0 :             if (cnt >= max_cnt) then
     382            0 :                abundance_line_legend = cnt
     383              :                return
     384              :             end if
     385            0 :             call set_line_style(cnt)
     386            0 :             dx = 0.1
     387            0 :             dyline = (ymax-ymin)/max_cnt
     388            0 :             ypos = ymax - (cnt+0.5)*dyline
     389            0 :             xpts(1) = 1.3*dx
     390            0 :             xpts(2) = xpts(1) + 2.3*dx
     391            0 :             ypts = ypos + dyline*0.1
     392            0 :             call pgslw(lw)
     393            0 :             call pgline(2, xpts, ypts)
     394            0 :             call pgslw(lw_sav)
     395            0 :             call pgsci(clr_Foreground)
     396            0 :             call pgsch(txt_scale*s% pg% Abundance_legend_txt_scale_factor)
     397            0 :             call pgptxt(xpts(2) + dx, ypos, 0.0, 0.0, trim(str))
     398            0 :             abundance_line_legend = cnt + 1
     399            0 :          end function abundance_line_legend
     400              : 
     401              :       end subroutine do_abundance_panel
     402              : 
     403              :       end module pgstar_abundance
        

Generated by: LCOV version 2.0-1