2 use,
intrinsic :: ieee_arithmetic, only: ieee_value,ieee_quiet_nan, &
65 integer,
parameter :: mt_vti_kind_float64 = 1
66 integer,
parameter :: mt_vti_kind_int32 = 2
67 integer,
parameter :: mt_vti_name_len = 64
68 integer,
parameter :: mt_task_name_len = 128
69 double precision,
parameter :: mt_unset_real = huge(1.d0)
71 character(len=mt_task_name_len) :: mt_mode =
''
72 character(len=mt_task_name_len) :: mt_output_file =
''
73 character(len=mt_task_name_len) :: mt_output_prefix =
''
74 character(len=mt_task_name_len) :: mt_seed_file =
''
75 character(len=mt_task_name_len) :: mt_seed_surface =
''
76 character(len=mt_task_name_len) :: mt_seed_layout =
'endpoint'
77 character(len=mt_task_name_len) :: mt_vtk_detail =
'minimal'
78 character(len=mt_task_name_len) :: mt_step_control =
'global_cell_fraction'
79 character(len=mt_task_name_len) :: mt_trace_integrator =
'rk2'
80 double precision :: mt_dL = -1.d0
81 double precision :: mt_step_fraction = 0.25d0
82 double precision :: mt_dL_min = 0.d0
83 double precision :: mt_rk45_atol = 1.
d-8
84 double precision :: mt_rk45_rtol = 1.
d-6
85 double precision :: mt_rk45_safety = 0.9d0
86 double precision :: mt_rk45_min_shrink = 0.2d0
87 double precision :: mt_rk45_max_grow = 5.d0
88 double precision :: mt_rk45_tangent_floor = 1.d0
89 double precision :: mt_rk45_tangent_rtol = 2.
d-5
90 integer :: mt_max_steps = -1
91 double precision :: mt_max_steps_factor = 2.d0
92 double precision :: mt_b_min = -1.d0
93 double precision :: mt_seed_coord = mt_unset_real
94 double precision :: mt_seed_theta0 = mt_unset_real
95 double precision :: mt_seed_phi0 = mt_unset_real
96 double precision :: mt_seed_alpha = mt_unset_real
97 logical :: mt_compute_length = .true.
98 logical :: mt_compute_twist = .false.
99 logical :: mt_compute_q = .false.
100 logical :: mt_compute_qperp = .false.
101 logical :: mt_rk2_step_diagnostic = .false.
102 logical :: mt_rk45_step_diagnostic = .false.
103 logical :: mt_rk45_tangent_diagnostic = .false.
104 logical :: mt_rk2_fusion_diagnostic = .false.
105 logical :: mt_write_csv = .false.
106 character(len=mt_task_name_len) :: mt_plane =
''
107 double precision :: mt_origin(3) = mt_unset_real
108 double precision :: mt_e1(3) = mt_unset_real
109 double precision :: mt_e2(3) = mt_unset_real
110 double precision :: mt_xmin = mt_unset_real
111 double precision :: mt_xmax = mt_unset_real
112 double precision :: mt_ymin = mt_unset_real
113 double precision :: mt_ymax = mt_unset_real
114 double precision :: mt_zmin = mt_unset_real
115 double precision :: mt_zmax = mt_unset_real
116 double precision :: mt_x0 = mt_unset_real
117 double precision :: mt_y0 = mt_unset_real
118 double precision :: mt_z0 = mt_unset_real
119 integer :: mt_nx = -1
120 integer :: mt_ny = -1
121 integer :: mt_nz = -1
122 double precision :: mt_s1min = mt_unset_real
123 double precision :: mt_s1max = mt_unset_real
124 double precision :: mt_s2min = mt_unset_real
125 double precision :: mt_s2max = mt_unset_real
126 double precision :: mt_s3min = mt_unset_real
127 double precision :: mt_s3max = mt_unset_real
128 integer :: mt_n1 = -1
129 integer :: mt_n2 = -1
130 integer :: mt_n3 = -1
131 integer :: mt_chunk_nz = -1
132 logical :: mt_profile_spherical = .false.
133 logical :: mt_params_loaded = .false.
135 type,
private :: mt_vti_array_desc
136 character(len=mt_vti_name_len) :: name
138 integer(kind=8) :: nbytes
139 integer(kind=8) :: offset
140 end type mt_vti_array_desc
142 type,
private :: mt_volume_products
143 double precision,
allocatable :: length_total(:)
144 double precision,
allocatable :: length_backward(:)
145 double precision,
allocatable :: length_forward(:)
146 integer,
allocatable :: nstep_backward_length(:)
147 integer,
allocatable :: nstep_forward_length(:)
148 integer,
allocatable :: status_backward_length(:)
149 integer,
allocatable :: status_forward_length(:)
150 double precision,
allocatable :: twist_total(:)
151 double precision,
allocatable :: twist_backward(:)
152 double precision,
allocatable :: twist_forward(:)
153 integer,
allocatable :: nstep_backward_twist(:)
154 integer,
allocatable :: nstep_forward_twist(:)
155 integer,
allocatable :: status_backward_twist(:)
156 integer,
allocatable :: status_forward_twist(:)
157 double precision,
allocatable :: q(:)
158 double precision,
allocatable :: logq(:)
159 double precision,
allocatable :: N2_q(:)
160 double precision,
allocatable :: bfactor_q(:)
161 double precision,
allocatable :: length_forward_q(:)
162 double precision,
allocatable :: length_backward_q(:)
163 double precision,
allocatable :: Bseed_norm_q(:)
164 double precision,
allocatable :: Bf_norm_q(:)
165 double precision,
allocatable :: Bb_norm_q(:)
166 integer,
allocatable :: valid_q(:)
167 integer,
allocatable :: status_q(:)
168 integer,
allocatable :: face_forward_q(:)
169 integer,
allocatable :: face_backward_q(:)
170 integer,
allocatable :: status_forward_q(:)
171 integer,
allocatable :: status_backward_q(:)
172 double precision,
allocatable :: qperp(:)
173 double precision,
allocatable :: logqperp(:)
174 double precision,
allocatable :: N2(:)
175 double precision,
allocatable :: bfactor(:)
176 double precision,
allocatable :: length_forward_qperp(:)
177 double precision,
allocatable :: length_backward_qperp(:)
178 double precision,
allocatable :: Bseed_norm(:)
179 double precision,
allocatable :: Bf_norm(:)
180 double precision,
allocatable :: Bb_norm(:)
181 integer,
allocatable :: valid_qperp(:)
182 integer,
allocatable :: status_qperp(:)
183 integer,
allocatable :: face_forward_qperp(:)
184 integer,
allocatable :: face_backward_qperp(:)
185 integer,
allocatable :: status_forward_qperp(:)
186 integer,
allocatable :: status_backward_qperp(:)
187 end type mt_volume_products
194 character(len=*),
intent(in) :: files(:)
198 namelist /magnetic_topology_list/ mt_mode,mt_output_file, &
199 mt_output_prefix,mt_seed_file,mt_vtk_detail, &
200 mt_seed_surface,mt_seed_layout,mt_seed_coord, &
201 mt_seed_theta0,mt_seed_phi0,mt_seed_alpha, &
202 mt_step_control,mt_dl,mt_step_fraction,mt_dl_min, &
203 mt_trace_integrator,mt_rk45_atol,mt_rk45_rtol, &
204 mt_rk45_safety,mt_rk45_min_shrink,mt_rk45_max_grow, &
205 mt_rk45_tangent_floor,mt_rk45_tangent_rtol, &
206 mt_max_steps,mt_max_steps_factor,mt_b_min, &
207 mt_compute_length,mt_compute_twist,mt_compute_q,mt_compute_qperp, &
208 mt_rk2_step_diagnostic,mt_rk45_step_diagnostic, &
209 mt_rk45_tangent_diagnostic,mt_rk2_fusion_diagnostic, &
210 mt_write_csv,mt_plane, &
211 mt_origin,mt_e1,mt_e2,mt_xmin,mt_xmax,mt_ymin,mt_ymax, &
212 mt_zmin,mt_zmax,mt_nx,mt_ny,mt_nz,mt_x0,mt_y0,mt_z0, &
213 mt_s1min,mt_s1max,mt_n1,mt_s2min,mt_s2max,mt_n2, &
214 mt_s3min,mt_s3max,mt_n3, &
215 mt_chunk_nz,mt_profile_spherical
217 call mt_set_default_params()
219 open(
unitpar,file=trim(files(n)),status=
'old')
220 read(
unitpar,magnetic_topology_list,
end=111)
223 mt_params_loaded=.true.
231 character(len=mt_task_name_len) :: mode
232 logical :: report_rk2,report_rk45
235 'magnetic-topology conversion requires npe=1; use OpenMP threads')
237 call getbc(global_time,0.d0,ps,iwstart,nwgc)
239 mode=mt_lowercase(trim(mt_mode))
240 call mt_validate_common_params(mode)
241 call mt_validate_trace_integrator(mode)
242 call mt_apply_trace_step_control()
243 call mt_apply_auto_max_steps()
244 call trace_set_integrator(mt_trace_integrator,mt_rk45_atol, &
245 mt_rk45_rtol,mt_rk45_safety,mt_rk45_min_shrink, &
246 mt_rk45_max_grow,mt_rk45_tangent_floor,mt_rk45_tangent_rtol)
247 report_rk2=mt_lowercase(trim(mt_trace_integrator))==
'rk2' .and. &
248 mt_rk2_step_diagnostic
249 report_rk45=(mt_lowercase(trim(mt_trace_integrator))==
'rk45_cartesian' &
250 .or. mt_lowercase(trim(mt_trace_integrator))==
'rk45_spherical') &
251 .and. mt_rk45_step_diagnostic
252 call trace_rk2_stats_set_enabled(report_rk2)
253 call trace_rk45_stats_set_enabled(report_rk45)
254 if (report_rk2)
call trace_rk2_stats_reset()
255 if (report_rk45)
call trace_rk45_stats_reset()
256 if (mt_profile_spherical .and. &
257 trim(mode)/=
'spherical_surface_products' .and. &
258 trim(mode)/=
'spherical_cloud_products')
then
259 write(*,
'(a)')
'mt_run_topology_task: mt_profile_spherical applies '// &
260 'only to spherical topology modes'
263 select case (trim(mode))
264 case (
'axis_plane_full_vtu')
265 call mt_run_axis_plane_full_vtu_task()
267 call mt_run_volume_vti_task()
268 case (
'arbitrary_plane_products')
269 call mt_run_arbitrary_plane_products_task()
270 case (
'seed_products')
271 call mt_run_seed_products_task()
272 case (
'axis_plane_csv')
273 call mt_run_axis_plane_csv_task()
274 case (
'spherical_surface_products')
275 call mt_run_spherical_surface_products_task()
276 case (
'spherical_cloud_products')
277 call mt_run_spherical_cloud_products_task()
279 call mpistop(
'mt_run_topology_task: unknown mt_mode='//trim(mt_mode))
281 if (report_rk2)
call trace_rk2_stats_report(trim(mode))
282 call trace_rk2_stats_set_enabled(.false.)
283 if (report_rk45)
call trace_rk45_stats_report(trim(mode))
284 call trace_rk45_stats_set_enabled(.false.)
287 subroutine mt_set_default_params()
288 mt_params_loaded=.false.
294 mt_seed_layout=
'endpoint'
295 mt_vtk_detail=
'minimal'
296 mt_step_control=
'global_cell_fraction'
297 mt_trace_integrator=
'rk2'
299 mt_step_fraction=0.25d0
304 mt_rk45_min_shrink=0.2d0
305 mt_rk45_max_grow=5.d0
306 mt_rk45_tangent_floor=1.d0
307 mt_rk45_tangent_rtol=2.d-5
309 mt_max_steps_factor=2.d0
311 mt_seed_coord=mt_unset_real
312 mt_seed_theta0=mt_unset_real
313 mt_seed_phi0=mt_unset_real
314 mt_seed_alpha=mt_unset_real
315 mt_compute_length=.true.
316 mt_compute_twist=.false.
318 mt_compute_qperp=.false.
319 mt_rk2_step_diagnostic=.false.
320 mt_rk45_step_diagnostic=.false.
321 mt_rk45_tangent_diagnostic=.false.
322 mt_rk2_fusion_diagnostic=.false.
325 mt_origin=mt_unset_real
328 mt_xmin=mt_unset_real
329 mt_xmax=mt_unset_real
330 mt_ymin=mt_unset_real
331 mt_ymax=mt_unset_real
332 mt_zmin=mt_unset_real
333 mt_zmax=mt_unset_real
340 mt_s1min=mt_unset_real
341 mt_s1max=mt_unset_real
342 mt_s2min=mt_unset_real
343 mt_s2max=mt_unset_real
344 mt_s3min=mt_unset_real
345 mt_s3max=mt_unset_real
350 mt_profile_spherical=.false.
351 end subroutine mt_set_default_params
353 subroutine mt_validate_common_params(mode)
354 character(len=*),
intent(in) :: mode
356 if (len_trim(mode)==0)
then
357 call mpistop(
'mt_run_topology_task requires mt_mode')
359 select case (trim(mode))
360 case (
'spherical_surface_products',
'spherical_cloud_products')
362 call mpistop(trim(mode)//
' requires 3D spherical geometry')
365 if (geo_coordinate/=geo_spherical)
then
366 call mpistop(trim(mode)//
' requires 3D spherical geometry')
369 call mpistop(trim(mode)//
' does not yet support periodic phi')
372 case (
'seed_products')
374 call mpistop(
'seed_products requires 3D Cartesian or spherical geometry')
377 select case (geo_coordinate)
378 case (geo_cartesian,geo_cartesian_stretched,geo_spherical)
380 call mpistop(
'seed_products requires Cartesian or spherical geometry')
382 if (geo_coordinate==geo_spherical .and. periodb(3))
then
383 call mpistop(
'spherical seed_products does not yet support periodic phi')
388 call mpistop(
'volume_vti requires 3D Cartesian geometry')
391 select case (geo_coordinate)
395 case (geo_cartesian_stretched)
399 call mpistop(
'volume_vti requires Cartesian geometry')
402 case (
'axis_plane_full_vtu',
'axis_plane_csv')
404 call mpistop(trim(mode)//
' requires 3D Cartesian geometry')
407 select case (geo_coordinate)
411 case (geo_cartesian_stretched)
413 call mpistop(trim(mode)//
' requires Cartesian geometry')
416 case (
'arbitrary_plane_products')
418 call mpistop(
'arbitrary_plane_products requires 3D Cartesian geometry')
421 select case (geo_coordinate)
422 case (geo_cartesian,geo_cartesian_stretched)
424 call mpistop(
'arbitrary_plane_products requires Cartesian geometry')
428 if (ndim/=3 .or. geo_coordinate/=geo_cartesian .or. &
429 .not.slab_uniform)
then
430 call mpistop(
'mt_run_topology_task mode requires 3D uniform Cartesian geometry')
433 if (len_trim(mt_output_file)==0 .and. &
434 len_trim(mt_output_prefix)==0)
then
435 call mpistop(
'mt_run_topology_task requires mt_output_file or mt_output_prefix')
437 select case (mt_lowercase(trim(mt_step_control)))
439 if (mt_dl<=0.d0)
then
440 call mpistop(
'mt_step_control=fixed requires mt_dL > 0')
442 case (
'cell_fraction')
443 select case (geo_coordinate)
444 case (geo_cartesian,geo_cartesian_stretched)
446 select case (trim(mode))
447 case (
'seed_products',
'spherical_surface_products', &
448 'spherical_cloud_products')
450 call mpistop(
'mt_step_control=cell_fraction is only supported '// &
451 'for spherical topology modes')
454 call mpistop(
'mt_step_control=cell_fraction requires Cartesian or '// &
455 'supported spherical geometry')
457 if (mt_step_fraction<=0.d0)
then
458 call mpistop(
'mt_step_control=cell_fraction requires '// &
459 'mt_step_fraction > 0')
461 if (mt_dl_min<0.d0)
then
462 call mpistop(
'mt_step_control=cell_fraction requires mt_dL_min >= 0')
464 case (
'global_cell_fraction')
465 if (mt_step_fraction<=0.d0)
then
466 call mpistop(
'mt_step_control=global_cell_fraction requires '// &
467 'mt_step_fraction > 0')
469 if (mt_dl_min<0.d0)
then
470 call mpistop(
'mt_step_control=global_cell_fraction requires mt_dL_min >= 0')
473 call mpistop(
'mt_run_topology_task requires mt_step_control=fixed '// &
474 'or cell_fraction/global_cell_fraction')
476 if (mt_max_steps<=0 .and. mt_max_steps_factor<=0.d0)
then
477 call mpistop(
'mt_max_steps auto requires mt_max_steps_factor > 0')
479 select case (mt_lowercase(trim(mt_vtk_detail)))
480 case (
'minimal',
'full')
482 call mpistop(
'mt_run_topology_task requires mt_vtk_detail=minimal or full')
484 end subroutine mt_validate_common_params
486 subroutine mt_validate_trace_integrator(mode)
487 character(len=*),
intent(in) :: mode
489 character(len=mt_task_name_len) :: integrator
491 integrator=mt_lowercase(trim(mt_trace_integrator))
492 select case (trim(integrator))
495 case (
'rk45_cartesian')
496 if (trim(mode)/=
'seed_products' .and. trim(mode)/=
'volume_vti' .and. &
497 trim(mode)/=
'arbitrary_plane_products' .and. &
498 trim(mode)/=
'axis_plane_full_vtu' .and. &
499 trim(mode)/=
'axis_plane_csv')
then
500 write(*,
'(a)')
'mt_trace_integrator=rk45_cartesian supports '// &
501 'only Cartesian seed_products, volume_vti, arbitrary_plane_products, '// &
502 'or axis-plane products'
504 call mpistop(
'mt_trace_integrator=rk45_cartesian supports '// &
505 'only seed_products, volume_vti, arbitrary_plane_products, '// &
506 'or axis-plane products')
509 call mpistop(
'mt_trace_integrator=rk45_cartesian requires 3D Cartesian geometry')
512 select case (geo_coordinate)
513 case (geo_cartesian,geo_cartesian_stretched)
515 write(*,
'(a)')
'mt_trace_integrator=rk45_cartesian is Cartesian-only'
517 call mpistop(
'mt_trace_integrator=rk45_cartesian is Cartesian-only')
520 if (mt_rk45_atol<0.d0 .or. mt_rk45_rtol<0.d0 .or. &
521 mt_rk45_atol+mt_rk45_rtol<=0.d0)
then
522 call mpistop(
'mt_trace_integrator=rk45_cartesian requires '// &
523 'non-negative tolerances with atol+rtol > 0')
525 if (mt_rk45_safety<=0.d0 .or. mt_rk45_safety>1.d0)
then
526 call mpistop(
'mt_rk45_safety must be in (0,1]')
528 if (mt_rk45_min_shrink<=0.d0 .or. mt_rk45_min_shrink>1.d0)
then
529 call mpistop(
'mt_rk45_min_shrink must be in (0,1]')
531 if (mt_rk45_max_grow<1.d0)
then
532 call mpistop(
'mt_rk45_max_grow must be >= 1')
534 if (mt_rk45_tangent_floor<=0.d0)
then
535 call mpistop(
'mt_rk45_tangent_floor must be > 0')
537 if (mt_rk45_tangent_rtol<=0.d0)
then
538 call mpistop(
'mt_rk45_tangent_rtol must be > 0')
540 case (
'rk45_spherical')
541 if (trim(mode)/=
'seed_products' .and. &
542 trim(mode)/=
'spherical_cloud_products' .and. &
543 trim(mode)/=
'spherical_surface_products')
then
544 write(*,
'(a)')
'mt_trace_integrator=rk45_spherical supports '// &
545 'only spherical seed_products, spherical_cloud_products, '// &
546 'or spherical_surface_products'
548 call mpistop(
'mt_trace_integrator=rk45_spherical supports '// &
549 'only seed_products, spherical_cloud_products, '// &
550 'or spherical_surface_products')
553 call mpistop(
'mt_trace_integrator=rk45_spherical requires 3D spherical geometry')
556 if (geo_coordinate/=geo_spherical)
then
557 write(*,
'(a)')
'mt_trace_integrator=rk45_spherical is spherical-only'
559 call mpistop(
'mt_trace_integrator=rk45_spherical is spherical-only')
562 call mpistop(
'mt_trace_integrator=rk45_spherical does not yet support periodic phi')
565 if (mt_compute_q)
then
567 if (geo_coordinate/=geo_spherical)
then
568 call mpistop(
'mt_trace_integrator=rk45_spherical standard '// &
569 'logQ currently requires spherical geometry')
573 if (mt_rk45_atol<0.d0 .or. mt_rk45_rtol<0.d0 .or. &
574 mt_rk45_atol+mt_rk45_rtol<=0.d0)
then
575 call mpistop(
'mt_trace_integrator=rk45_spherical requires '// &
576 'non-negative tolerances with atol+rtol > 0')
578 if (mt_rk45_safety<=0.d0 .or. mt_rk45_safety>1.d0)
then
579 call mpistop(
'mt_rk45_safety must be in (0,1]')
581 if (mt_rk45_min_shrink<=0.d0 .or. mt_rk45_min_shrink>1.d0)
then
582 call mpistop(
'mt_rk45_min_shrink must be in (0,1]')
584 if (mt_rk45_max_grow<1.d0)
then
585 call mpistop(
'mt_rk45_max_grow must be >= 1')
587 if (mt_rk45_tangent_floor<=0.d0)
then
588 call mpistop(
'mt_rk45_tangent_floor must be > 0')
590 if (mt_rk45_tangent_rtol<=0.d0)
then
591 call mpistop(
'mt_rk45_tangent_rtol must be > 0')
594 call mpistop(
'mt_trace_integrator must be rk2, rk45_cartesian, or rk45_spherical')
596 if (mt_rk45_tangent_diagnostic)
then
597 if (trim(mode)/=
'seed_products')
then
598 call mpistop(
'mt_rk45_tangent_diagnostic requires seed_products')
600 if (trim(integrator)/=
'rk45_cartesian')
then
601 call mpistop(
'mt_rk45_tangent_diagnostic requires '// &
602 'mt_trace_integrator=rk45_cartesian')
604 if (mt_compute_q .or. mt_compute_qperp)
then
605 call mpistop(
'mt_rk45_tangent_diagnostic is q0 diagnostic-only; '// &
606 'disable public Q and Qperp')
608 if (ndim/=3 .or. .not.slab_uniform)
then
609 call mpistop(
'mt_rk45_tangent_diagnostic requires 3D uniform Cartesian geometry')
612 if (geo_coordinate/=geo_cartesian)
then
613 call mpistop(
'mt_rk45_tangent_diagnostic requires Cartesian geometry')
617 if (mt_rk2_fusion_diagnostic)
then
618 if (trim(mode)/=
'seed_products')
then
619 call mpistop(
'mt_rk2_fusion_diagnostic requires seed_products')
621 if (trim(integrator)/=
'rk2')
then
622 call mpistop(
'mt_rk2_fusion_diagnostic requires '// &
623 'mt_trace_integrator=rk2')
625 if (.not.mt_compute_twist)
then
626 call mpistop(
'mt_rk2_fusion_diagnostic requires twist diagnostics')
628 if (mt_compute_q .or. mt_compute_qperp)
then
629 call mpistop(
'mt_rk2_fusion_diagnostic is q0 diagnostic-only; '// &
630 'disable public Q and Qperp')
633 end subroutine mt_validate_trace_integrator
635 subroutine mt_apply_trace_step_control()
636 character(len=mt_task_name_len) :: step_mode
637 double precision :: hmin,dl_eff,dl_cap
640 step_mode=mt_lowercase(trim(mt_step_control))
641 select case (trim(step_mode))
642 case (
'cell_fraction')
643 if ((geo_coordinate==geo_cartesian .or. &
644 geo_coordinate==geo_cartesian_stretched .or. &
645 geo_coordinate==geo_spherical) .and. mt_dl<=0.d0)
then
646 dl_cap=mt_domain_diagonal()
647 if (dl_cap<=0.d0)
then
648 call mpistop(
'mt_step_control=cell_fraction could not determine '// &
652 write(*,
'(a,es16.8,a,es16.8,a,es16.8)') &
653 'mt_step_control=cell_fraction: mt_step_fraction=', &
654 mt_step_fraction,
', automatic dL_cap=',mt_dl, &
655 ', mt_dL_min=',mt_dl_min
657 write(*,
'(a,es16.8,a,es16.8,a,es16.8)') &
658 'mt_step_control=cell_fraction: mt_step_fraction=', &
659 mt_step_fraction,
', mt_dL_cap=',mt_dl, &
660 ', mt_dL_min=',mt_dl_min
662 call trace_set_step_control(
'cell_fraction',mt_step_fraction,mt_dl_min)
663 case (
'global_cell_fraction')
664 select case (geo_coordinate)
665 case (geo_cartesian,geo_cartesian_stretched)
666 call trace_cartesian_global_min_cell_size(hmin,status)
668 call trace_spherical_global_min_cell_size(hmin,status)
670 status=trace_status_unsupported_geometry
673 if (status/=trace_status_active .or. hmin<=0.d0)
then
674 call mpistop(
'mt_step_control=global_cell_fraction could not determine h_global_min')
676 dl_eff=mt_step_fraction*hmin
677 if (mt_dl>0.d0) dl_eff=min(dl_eff,mt_dl)
678 if (mt_dl_min>0.d0)
then
680 dl_eff=max(dl_eff,min(mt_dl_min,mt_dl))
682 dl_eff=max(dl_eff,mt_dl_min)
685 if (dl_eff<=0.d0)
then
686 call mpistop(
'mt_step_control=global_cell_fraction produced non-positive mt_dL')
689 write(*,
'(a,es16.8,a,es16.8,a,es16.8,a,es16.8)') &
690 'mt_step_control=global_cell_fraction: h_global_min=',hmin, &
691 ', mt_step_fraction=',mt_step_fraction,
', mt_dL_cap=',mt_dl, &
692 ', effective_mt_dL=',dl_eff
694 write(*,
'(a,es16.8,a,es16.8,a,es16.8)') &
695 'mt_step_control=global_cell_fraction: h_global_min=',hmin, &
696 ', mt_step_fraction=',mt_step_fraction,
', effective_mt_dL=',dl_eff
699 call trace_set_step_control(
'fixed',mt_step_fraction,mt_dl_min)
701 call trace_set_step_control(
'fixed',mt_step_fraction,mt_dl_min)
703 end subroutine mt_apply_trace_step_control
705 subroutine mt_apply_auto_max_steps()
706 character(len=mt_task_name_len) :: step_mode
707 double precision :: hmin,step_est,ldiag,nsteps_real
710 if (mt_max_steps>0)
return
712 ldiag=mt_domain_diagonal()
713 if (ldiag<=0.d0)
then
714 call mpistop(
'mt_max_steps auto could not determine domain diagonal')
717 step_mode=mt_lowercase(trim(mt_step_control))
718 select case (trim(step_mode))
721 case (
'cell_fraction',
'global_cell_fraction')
722 select case (geo_coordinate)
723 case (geo_cartesian,geo_cartesian_stretched)
724 call trace_cartesian_global_min_cell_size(hmin,status)
726 call trace_spherical_global_min_cell_size(hmin,status)
728 status=trace_status_unsupported_geometry
731 if (status/=trace_status_active .or. hmin<=0.d0)
then
732 call mpistop(
'mt_max_steps auto could not determine h_global_min')
734 step_est=mt_step_fraction*hmin
735 if (mt_dl>0.d0) step_est=min(step_est,mt_dl)
740 if (step_est<=0.d0)
then
741 call mpistop(
'mt_max_steps auto produced non-positive step estimate')
743 nsteps_real=mt_max_steps_factor*ldiag/step_est
744 if (nsteps_real>dble(huge(mt_max_steps)-1))
then
745 call mpistop(
'mt_max_steps auto estimate exceeds integer range')
747 mt_max_steps=max(1,ceiling(nsteps_real))
748 write(*,
'(a,es16.8,a,es16.8,a,es16.8,a,es16.8,a,i0)') &
749 'mt_max_steps auto: Ldiag=',ldiag,
', step_est=',step_est, &
750 ', factor=',mt_max_steps_factor,
', nsteps_real=',nsteps_real, &
751 ', mt_max_steps=',mt_max_steps
752 end subroutine mt_apply_auto_max_steps
754 double precision function mt_domain_diagonal()
result(Ldiag)
756 double precision :: r,theta,phi,dist
757 double precision :: corners(8,3),dx(3)
759 ldiag=abs(xprobmax1-xprobmin1)
761 if (geo_coordinate==geo_spherical)
then
782 corners(n,1)=r*dsin(theta)*dcos(phi)
783 corners(n,2)=r*dsin(theta)*dsin(phi)
784 corners(n,3)=r*dcos(theta)
792 dx(m)=corners(i,m)-corners(j,m)
794 dist=dsqrt(sum(dx*dx))
795 ldiag=max(ldiag,dist)
799 ldiag=dsqrt((xprobmax1-xprobmin1)**2+ &
800 (xprobmax2-xprobmin2)**2+(xprobmax3-xprobmin3)**2)
803 end function mt_domain_diagonal
805 subroutine mt_run_axis_plane_full_vtu_task()
806 character(len=mt_task_name_len) :: plane
807 character(len=mt_task_name_len) :: output_file
808 logical :: minimal_output
810 plane=mt_lowercase(trim(mt_plane))
811 minimal_output=.not.mt_vtk_detail_is_full()
812 if (minimal_output)
then
813 call mt_resolve_output_file(
'axis_plane_full_vtu',
'.vti', &
814 '_'//trim(plane)//
'_minimal.vti',output_file)
816 call mt_resolve_output_file(
'axis_plane_full_vtu',
'.vtu', &
817 '_'//trim(plane)//
'_full.vtu',output_file)
819 if (.not.minimal_output .and. &
820 (mt_compute_twist .or. mt_compute_q .or. mt_compute_qperp))
then
821 write(*,
'(a)')
'mt_run_topology_task: axis_plane_full_vtu ignores compute flags'
822 write(*,
'(a)')
'mt_run_topology_task: it always writes full plane products'
825 select case (trim(plane))
827 call mt_require_real(
'mt_xmin',mt_xmin)
828 call mt_require_real(
'mt_xmax',mt_xmax)
829 call mt_require_real(
'mt_ymin',mt_ymin)
830 call mt_require_real(
'mt_ymax',mt_ymax)
831 call mt_require_real(
'mt_z0',mt_z0)
832 call mt_require_positive_int(
'mt_nx',mt_nx)
833 call mt_require_positive_int(
'mt_ny',mt_ny)
834 call mt_require_ordered(
'mt_xmin',
'mt_xmax',mt_xmin,mt_xmax)
835 call mt_require_ordered(
'mt_ymin',
'mt_ymax',mt_ymin,mt_ymax)
836 if (minimal_output)
then
837 write(*,
'(a)')
'mt_run_topology_task: writing axis-plane minimal VTI '//trim(output_file)
838 if (mt_b_min>0.d0)
then
839 call mt_qsl_plane_vti_xy(mt_xmin,mt_xmax,mt_nx,mt_ymin,mt_ymax, &
840 mt_ny,mt_z0,mt_dl,mt_max_steps,trim(output_file), &
841 mt_compute_length,mt_compute_twist,mt_compute_q, &
842 mt_compute_qperp,b_min=mt_b_min)
844 call mt_qsl_plane_vti_xy(mt_xmin,mt_xmax,mt_nx,mt_ymin,mt_ymax, &
845 mt_ny,mt_z0,mt_dl,mt_max_steps,trim(output_file), &
846 mt_compute_length,mt_compute_twist,mt_compute_q, &
850 write(*,
'(a)')
'mt_run_topology_task: writing axis-plane full VTU '//trim(output_file)
851 if (mt_b_min>0.d0)
then
853 mt_ny,mt_z0,mt_dl,mt_max_steps,trim(output_file), &
857 mt_ny,mt_z0,mt_dl,mt_max_steps,trim(output_file))
861 call mt_require_real(
'mt_xmin',mt_xmin)
862 call mt_require_real(
'mt_xmax',mt_xmax)
863 call mt_require_real(
'mt_zmin',mt_zmin)
864 call mt_require_real(
'mt_zmax',mt_zmax)
865 call mt_require_real(
'mt_y0',mt_y0)
866 call mt_require_positive_int(
'mt_nx',mt_nx)
867 call mt_require_positive_int(
'mt_nz',mt_nz)
868 call mt_require_ordered(
'mt_xmin',
'mt_xmax',mt_xmin,mt_xmax)
869 call mt_require_ordered(
'mt_zmin',
'mt_zmax',mt_zmin,mt_zmax)
870 if (minimal_output)
then
871 write(*,
'(a)')
'mt_run_topology_task: writing axis-plane minimal VTI '//trim(output_file)
872 if (mt_b_min>0.d0)
then
873 call mt_qsl_plane_vti_xz(mt_xmin,mt_xmax,mt_nx,mt_zmin,mt_zmax, &
874 mt_nz,mt_y0,mt_dl,mt_max_steps,trim(output_file), &
875 mt_compute_length,mt_compute_twist,mt_compute_q, &
876 mt_compute_qperp,b_min=mt_b_min)
878 call mt_qsl_plane_vti_xz(mt_xmin,mt_xmax,mt_nx,mt_zmin,mt_zmax, &
879 mt_nz,mt_y0,mt_dl,mt_max_steps,trim(output_file), &
880 mt_compute_length,mt_compute_twist,mt_compute_q, &
884 write(*,
'(a)')
'mt_run_topology_task: writing axis-plane full VTU '//trim(output_file)
885 if (mt_b_min>0.d0)
then
887 mt_nz,mt_y0,mt_dl,mt_max_steps,trim(output_file), &
891 mt_nz,mt_y0,mt_dl,mt_max_steps,trim(output_file))
895 call mt_require_real(
'mt_ymin',mt_ymin)
896 call mt_require_real(
'mt_ymax',mt_ymax)
897 call mt_require_real(
'mt_zmin',mt_zmin)
898 call mt_require_real(
'mt_zmax',mt_zmax)
899 call mt_require_real(
'mt_x0',mt_x0)
900 call mt_require_positive_int(
'mt_ny',mt_ny)
901 call mt_require_positive_int(
'mt_nz',mt_nz)
902 call mt_require_ordered(
'mt_ymin',
'mt_ymax',mt_ymin,mt_ymax)
903 call mt_require_ordered(
'mt_zmin',
'mt_zmax',mt_zmin,mt_zmax)
904 if (minimal_output)
then
905 write(*,
'(a)')
'mt_run_topology_task: writing axis-plane minimal VTI '//trim(output_file)
906 if (mt_b_min>0.d0)
then
907 call mt_qsl_plane_vti_yz(mt_ymin,mt_ymax,mt_ny,mt_zmin,mt_zmax, &
908 mt_nz,mt_x0,mt_dl,mt_max_steps,trim(output_file), &
909 mt_compute_length,mt_compute_twist,mt_compute_q, &
910 mt_compute_qperp,b_min=mt_b_min)
912 call mt_qsl_plane_vti_yz(mt_ymin,mt_ymax,mt_ny,mt_zmin,mt_zmax, &
913 mt_nz,mt_x0,mt_dl,mt_max_steps,trim(output_file), &
914 mt_compute_length,mt_compute_twist,mt_compute_q, &
918 write(*,
'(a)')
'mt_run_topology_task: writing axis-plane full VTU '//trim(output_file)
919 if (mt_b_min>0.d0)
then
921 mt_nz,mt_x0,mt_dl,mt_max_steps,trim(output_file), &
925 mt_nz,mt_x0,mt_dl,mt_max_steps,trim(output_file))
929 call mpistop(
'mt_run_topology_task: axis_plane_full_vtu requires mt_plane=xy, xz, or yz')
931 end subroutine mt_run_axis_plane_full_vtu_task
933 subroutine mt_run_axis_plane_csv_task()
934 character(len=mt_task_name_len) :: plane
935 character(len=mt_task_name_len) :: length_csv,twist_csv
936 character(len=mt_task_name_len) :: q_csv
937 character(len=mt_task_name_len) :: qperp_csv
939 if (len_trim(mt_output_prefix)==0)
then
940 call mpistop(
'axis_plane_csv requires mt_output_prefix')
942 if (len_trim(mt_output_file)>0)
then
943 write(*,
'(a)')
'mt_run_topology_task: axis_plane_csv ignores mt_output_file'
944 write(*,
'(a)')
'mt_run_topology_task: axis_plane_csv uses mt_output_prefix for CSV outputs'
947 plane=mt_lowercase(trim(mt_plane))
948 call mt_resolve_prefix_file(
'_'//trim(plane)//
'_length.csv', &
949 length_csv,
'axis_plane_csv length requires mt_output_prefix')
953 if (mt_compute_twist)
then
954 call mt_resolve_prefix_file(
'_'//trim(plane)//
'_twist.csv', &
955 twist_csv,
'axis_plane_csv twist requires mt_output_prefix')
957 if (mt_compute_q)
then
958 call mt_resolve_prefix_file(
'_'//trim(plane)//
'_q.csv', &
959 q_csv,
'axis_plane_csv Q requires mt_output_prefix')
961 if (mt_compute_qperp)
then
962 call mt_resolve_prefix_file(
'_'//trim(plane)//
'_qperp_method2.csv', &
963 qperp_csv,
'axis_plane_csv Qperp requires mt_output_prefix')
966 select case (trim(plane))
968 call mt_require_real(
'mt_xmin',mt_xmin)
969 call mt_require_real(
'mt_xmax',mt_xmax)
970 call mt_require_real(
'mt_ymin',mt_ymin)
971 call mt_require_real(
'mt_ymax',mt_ymax)
972 call mt_require_real(
'mt_z0',mt_z0)
973 call mt_require_positive_int(
'mt_nx',mt_nx)
974 call mt_require_positive_int(
'mt_ny',mt_ny)
975 call mt_require_ordered(
'mt_xmin',
'mt_xmax',mt_xmin,mt_xmax)
976 call mt_require_ordered(
'mt_ymin',
'mt_ymax',mt_ymin,mt_ymax)
977 if (mt_b_min>0.d0)
then
978 call mt_axis_plane_products_csv_axis(mt_xmin,mt_xmax,mt_nx, &
979 mt_ymin,mt_ymax,mt_ny,mt_z0,1,2,3,mt_dl,mt_max_steps, &
980 trim(length_csv),trim(twist_csv),trim(q_csv), &
981 trim(qperp_csv),
'mt_axis_plane_products_csv_xy',
'ix,iy', &
982 'ix,iy',b_min=mt_b_min)
984 call mt_axis_plane_products_csv_axis(mt_xmin,mt_xmax,mt_nx, &
985 mt_ymin,mt_ymax,mt_ny,mt_z0,1,2,3,mt_dl,mt_max_steps, &
986 trim(length_csv),trim(twist_csv),trim(q_csv), &
987 trim(qperp_csv),
'mt_axis_plane_products_csv_xy',
'ix,iy', &
991 call mt_require_real(
'mt_xmin',mt_xmin)
992 call mt_require_real(
'mt_xmax',mt_xmax)
993 call mt_require_real(
'mt_zmin',mt_zmin)
994 call mt_require_real(
'mt_zmax',mt_zmax)
995 call mt_require_real(
'mt_y0',mt_y0)
996 call mt_require_positive_int(
'mt_nx',mt_nx)
997 call mt_require_positive_int(
'mt_nz',mt_nz)
998 call mt_require_ordered(
'mt_xmin',
'mt_xmax',mt_xmin,mt_xmax)
999 call mt_require_ordered(
'mt_zmin',
'mt_zmax',mt_zmin,mt_zmax)
1000 if (mt_b_min>0.d0)
then
1001 call mt_axis_plane_products_csv_axis(mt_xmin,mt_xmax,mt_nx, &
1002 mt_zmin,mt_zmax,mt_nz,mt_y0,1,3,2,mt_dl,mt_max_steps, &
1003 trim(length_csv),trim(twist_csv),trim(q_csv), &
1004 trim(qperp_csv),
'mt_axis_plane_products_csv_xz',
'ix,iz', &
1005 'i,j',b_min=mt_b_min)
1007 call mt_axis_plane_products_csv_axis(mt_xmin,mt_xmax,mt_nx, &
1008 mt_zmin,mt_zmax,mt_nz,mt_y0,1,3,2,mt_dl,mt_max_steps, &
1009 trim(length_csv),trim(twist_csv),trim(q_csv), &
1010 trim(qperp_csv),
'mt_axis_plane_products_csv_xz',
'ix,iz', &
1014 call mt_require_real(
'mt_ymin',mt_ymin)
1015 call mt_require_real(
'mt_ymax',mt_ymax)
1016 call mt_require_real(
'mt_zmin',mt_zmin)
1017 call mt_require_real(
'mt_zmax',mt_zmax)
1018 call mt_require_real(
'mt_x0',mt_x0)
1019 call mt_require_positive_int(
'mt_ny',mt_ny)
1020 call mt_require_positive_int(
'mt_nz',mt_nz)
1021 call mt_require_ordered(
'mt_ymin',
'mt_ymax',mt_ymin,mt_ymax)
1022 call mt_require_ordered(
'mt_zmin',
'mt_zmax',mt_zmin,mt_zmax)
1023 if (mt_b_min>0.d0)
then
1024 call mt_axis_plane_products_csv_axis(mt_ymin,mt_ymax,mt_ny, &
1025 mt_zmin,mt_zmax,mt_nz,mt_x0,2,3,1,mt_dl,mt_max_steps, &
1026 trim(length_csv),trim(twist_csv),trim(q_csv), &
1027 trim(qperp_csv),
'mt_axis_plane_products_csv_yz',
'iy,iz', &
1028 'i,j',b_min=mt_b_min)
1030 call mt_axis_plane_products_csv_axis(mt_ymin,mt_ymax,mt_ny, &
1031 mt_zmin,mt_zmax,mt_nz,mt_x0,2,3,1,mt_dl,mt_max_steps, &
1032 trim(length_csv),trim(twist_csv),trim(q_csv), &
1033 trim(qperp_csv),
'mt_axis_plane_products_csv_yz',
'iy,iz', &
1037 call mpistop(
'mt_run_topology_task: axis_plane_csv requires mt_plane=xy, xz, or yz')
1040 write(*,
'(a)')
'mt_run_topology_task: wrote axis-plane CSV length '// &
1042 if (mt_compute_twist)
write(*,
'(a)') &
1043 'mt_run_topology_task: wrote axis-plane CSV twist '//trim(twist_csv)
1044 if (mt_compute_q)
write(*,
'(a)') &
1045 'mt_run_topology_task: wrote axis-plane CSV Q '//trim(q_csv)
1046 if (mt_compute_qperp)
write(*,
'(a)') &
1047 'mt_run_topology_task: wrote axis-plane CSV Qperp '//trim(qperp_csv)
1048 end subroutine mt_run_axis_plane_csv_task
1050 subroutine mt_run_volume_vti_task()
1051 character(len=mt_task_name_len) :: output_file
1053 call mt_resolve_output_file(
'volume_vti',
'.vti',
'_volume.vti', &
1055 call mt_require_real(
'mt_xmin',mt_xmin)
1056 call mt_require_real(
'mt_xmax',mt_xmax)
1057 call mt_require_real(
'mt_ymin',mt_ymin)
1058 call mt_require_real(
'mt_ymax',mt_ymax)
1059 call mt_require_real(
'mt_zmin',mt_zmin)
1060 call mt_require_real(
'mt_zmax',mt_zmax)
1061 call mt_require_positive_int(
'mt_nx',mt_nx)
1062 call mt_require_positive_int(
'mt_ny',mt_ny)
1063 call mt_require_positive_int(
'mt_nz',mt_nz)
1064 call mt_require_ordered(
'mt_xmin',
'mt_xmax',mt_xmin,mt_xmax)
1065 call mt_require_ordered(
'mt_ymin',
'mt_ymax',mt_ymin,mt_ymax)
1066 call mt_require_ordered(
'mt_zmin',
'mt_zmax',mt_zmin,mt_zmax)
1067 write(*,
'(a)')
'mt_run_topology_task: writing volume VTI '//trim(output_file)
1068 if (mt_b_min>0.d0)
then
1069 if (mt_chunk_nz>0)
then
1071 mt_ymin,mt_ymax,mt_ny,mt_zmin,mt_zmax,mt_nz, &
1072 mt_dl,mt_max_steps,trim(output_file),b_min=mt_b_min, &
1073 compute_twist=mt_compute_twist, &
1074 compute_length=mt_compute_length, &
1075 compute_q=mt_compute_q,compute_qperp=mt_compute_qperp, &
1076 chunk_nz=mt_chunk_nz)
1079 mt_ymin,mt_ymax,mt_ny,mt_zmin,mt_zmax,mt_nz, &
1080 mt_dl,mt_max_steps,trim(output_file),b_min=mt_b_min, &
1081 compute_twist=mt_compute_twist, &
1082 compute_length=mt_compute_length, &
1083 compute_q=mt_compute_q,compute_qperp=mt_compute_qperp)
1086 if (mt_chunk_nz>0)
then
1088 mt_ymin,mt_ymax,mt_ny,mt_zmin,mt_zmax,mt_nz, &
1089 mt_dl,mt_max_steps,trim(output_file), &
1090 compute_twist=mt_compute_twist, &
1091 compute_length=mt_compute_length, &
1092 compute_q=mt_compute_q,compute_qperp=mt_compute_qperp, &
1093 chunk_nz=mt_chunk_nz)
1096 mt_ymin,mt_ymax,mt_ny,mt_zmin,mt_zmax,mt_nz, &
1097 mt_dl,mt_max_steps,trim(output_file), &
1098 compute_twist=mt_compute_twist, &
1099 compute_length=mt_compute_length, &
1100 compute_q=mt_compute_q,compute_qperp=mt_compute_qperp)
1103 end subroutine mt_run_volume_vti_task
1105 subroutine mt_run_arbitrary_plane_products_task()
1106 character(len=mt_task_name_len) :: vtu_file,csv_file
1108 call mt_resolve_output_file(
'arbitrary_plane_products',
'.vtu', &
1109 '_arbitrary_plane_products.vtu',vtu_file)
1111 if (mt_write_csv)
then
1112 call mt_resolve_prefix_file(
'_arbitrary_plane_products.csv',csv_file, &
1113 'arbitrary_plane_products CSV requires mt_output_prefix')
1115 call mt_require_real(
'mt_origin(1)',mt_origin(1))
1116 call mt_require_real(
'mt_origin(2)',mt_origin(2))
1117 call mt_require_real(
'mt_origin(3)',mt_origin(3))
1118 call mt_require_real(
'mt_e1(1)',mt_e1(1))
1119 call mt_require_real(
'mt_e1(2)',mt_e1(2))
1120 call mt_require_real(
'mt_e1(3)',mt_e1(3))
1121 call mt_require_real(
'mt_e2(1)',mt_e2(1))
1122 call mt_require_real(
'mt_e2(2)',mt_e2(2))
1123 call mt_require_real(
'mt_e2(3)',mt_e2(3))
1124 call mt_require_real(
'mt_s1min',mt_s1min)
1125 call mt_require_real(
'mt_s1max',mt_s1max)
1126 call mt_require_real(
'mt_s2min',mt_s2min)
1127 call mt_require_real(
'mt_s2max',mt_s2max)
1128 call mt_require_positive_int(
'mt_n1',mt_n1)
1129 call mt_require_positive_int(
'mt_n2',mt_n2)
1130 call mt_require_ordered(
'mt_s1min',
'mt_s1max',mt_s1min,mt_s1max)
1131 call mt_require_ordered(
'mt_s2min',
'mt_s2max',mt_s2min,mt_s2max)
1133 write(*,
'(a)')
'mt_run_topology_task: writing arbitrary-plane VTU '// &
1135 if (mt_write_csv)
then
1136 write(*,
'(a)')
'mt_run_topology_task: writing arbitrary-plane CSV '// &
1140 if (mt_b_min>0.d0)
then
1142 mt_e1(1:ndim),mt_e2(1:ndim),mt_s1min,mt_s1max,mt_n1, &
1143 mt_s2min,mt_s2max,mt_n2,mt_dl,mt_max_steps,trim(csv_file), &
1144 b_min=mt_b_min,compute_length=mt_compute_length, &
1145 compute_twist=mt_compute_twist, &
1146 compute_q=mt_compute_q,compute_qperp=mt_compute_qperp, &
1147 vtu_file=trim(vtu_file),write_csv=mt_write_csv)
1150 mt_e1(1:ndim),mt_e2(1:ndim),mt_s1min,mt_s1max,mt_n1, &
1151 mt_s2min,mt_s2max,mt_n2,mt_dl,mt_max_steps,trim(csv_file), &
1152 compute_length=mt_compute_length, &
1153 compute_twist=mt_compute_twist, &
1154 compute_q=mt_compute_q,compute_qperp=mt_compute_qperp, &
1155 vtu_file=trim(vtu_file),write_csv=mt_write_csv)
1157 end subroutine mt_run_arbitrary_plane_products_task
1159 subroutine mt_run_seed_products_task()
1160 character(len=mt_task_name_len) :: csv_file,vtu_file,diag_file
1161 character(len=mt_task_name_len) :: rk2_diag_file
1162 double precision,
allocatable :: seeds(:,:)
1165 if (len_trim(mt_output_prefix)==0)
then
1166 call mpistop(
'seed_products requires mt_output_prefix')
1168 if (len_trim(mt_output_file)>0)
then
1169 write(*,
'(a)')
'mt_run_topology_task: seed_products ignores mt_output_file'
1170 write(*,
'(a)')
'mt_run_topology_task: seed_products uses mt_output_prefix for CSV and VTU'
1172 if (len_trim(mt_seed_file)==0)
then
1173 call mpistop(
'seed_products requires mt_seed_file')
1177 if (mt_write_csv)
then
1178 call mt_resolve_prefix_file(
'_seed_products.csv',csv_file, &
1179 'seed_products CSV requires mt_output_prefix')
1181 call mt_resolve_prefix_file(
'_seed_products.vtu',vtu_file, &
1182 'seed_products VTU requires mt_output_prefix')
1183 if (mt_rk45_tangent_diagnostic)
then
1184 call mt_resolve_prefix_file(
'_rk45_tangent_diag.csv',diag_file, &
1185 'seed_products RK45 tangent diagnostic requires mt_output_prefix')
1187 if (mt_rk2_fusion_diagnostic)
then
1188 call mt_resolve_prefix_file(
'_rk2_fusion_diag.csv',rk2_diag_file, &
1189 'seed_products RK2 fusion diagnostic requires mt_output_prefix')
1191 call mt_read_seed_file(trim(mt_seed_file),seeds,nseed)
1193 if (mt_write_csv)
write(*,
'(a)') &
1194 'mt_run_topology_task: writing seed-products CSV '//trim(csv_file)
1195 write(*,
'(a)')
'mt_run_topology_task: writing seed-products VTU '// &
1198 if (mt_b_min>0.d0)
then
1200 trim(csv_file),b_min=mt_b_min,compute_length=mt_compute_length, &
1201 compute_twist=mt_compute_twist, &
1202 compute_q=mt_compute_q,compute_qperp=mt_compute_qperp, &
1203 vtu_file=trim(vtu_file))
1204 if (mt_rk45_tangent_diagnostic)
then
1205 write(*,
'(a)')
'mt_run_topology_task: writing RK45 tangent '// &
1206 'diagnostic CSV '//trim(diag_file)
1207 call mt_rk45_tangent_diagnostic_seeds(seeds,nseed,mt_dl, &
1208 mt_max_steps,trim(diag_file),b_min=mt_b_min)
1210 if (mt_rk2_fusion_diagnostic)
then
1211 write(*,
'(a)')
'mt_run_topology_task: writing RK2 fusion '// &
1212 'diagnostic CSV '//trim(rk2_diag_file)
1213 call mt_rk2_fusion_diagnostic_seeds(seeds,nseed,mt_dl, &
1214 mt_max_steps,trim(rk2_diag_file),b_min=mt_b_min)
1218 trim(csv_file),compute_length=mt_compute_length, &
1219 compute_twist=mt_compute_twist, &
1220 compute_q=mt_compute_q,compute_qperp=mt_compute_qperp, &
1221 vtu_file=trim(vtu_file))
1222 if (mt_rk45_tangent_diagnostic)
then
1223 write(*,
'(a)')
'mt_run_topology_task: writing RK45 tangent '// &
1224 'diagnostic CSV '//trim(diag_file)
1225 call mt_rk45_tangent_diagnostic_seeds(seeds,nseed,mt_dl, &
1226 mt_max_steps,trim(diag_file))
1228 if (mt_rk2_fusion_diagnostic)
then
1229 write(*,
'(a)')
'mt_run_topology_task: writing RK2 fusion '// &
1230 'diagnostic CSV '//trim(rk2_diag_file)
1231 call mt_rk2_fusion_diagnostic_seeds(seeds,nseed,mt_dl, &
1232 mt_max_steps,trim(rk2_diag_file))
1237 end subroutine mt_run_seed_products_task
1239 subroutine mt_run_spherical_surface_products_task()
1240 character(len=mt_task_name_len) :: surface,csv_file,vtu_file,suffix
1241 double precision :: seed_coord,s1_min,s1_max,s2_min,s2_max
1242 double precision :: seed_theta0,seed_phi0,seed_alpha
1244 surface=mt_lowercase(trim(mt_seed_surface))
1245 if (len_trim(surface)==0) surface=
'rmin'
1246 select case (trim(surface))
1248 seed_coord=xprobmin1
1249 case (
'rconst',
'r_const')
1251 call mt_require_real(
'mt_seed_coord',mt_seed_coord)
1252 seed_coord=mt_seed_coord
1253 if (seed_coord<xprobmin1 .or. seed_coord>xprobmax1)
then
1254 call mpistop(
'spherical_surface_products requires rconst '// &
1255 'mt_seed_coord inside domain')
1258 case (
'theta_const',
'thetaconst')
1259 surface=
'theta_const'
1260 call mt_require_real(
'mt_seed_coord',mt_seed_coord)
1261 seed_coord=mt_seed_coord
1262 if (seed_coord<xprobmin2 .or. seed_coord>xprobmax2)
then
1263 call mpistop(
'spherical_surface_products requires theta_const '// &
1264 'mt_seed_coord inside domain')
1266 case (
'phi_const',
'phiconst')
1268 call mt_require_real(
'mt_seed_coord',mt_seed_coord)
1269 seed_coord=mt_seed_coord
1270 if (seed_coord<xprobmin3 .or. seed_coord>xprobmax3)
then
1271 call mpistop(
'spherical_surface_products requires phi_const '// &
1272 'mt_seed_coord inside domain')
1274 case (
'radial_plane',
'radialplane')
1275 surface=
'radial_plane'
1277 call mt_require_real(
'mt_seed_theta0',mt_seed_theta0)
1278 call mt_require_real(
'mt_seed_phi0',mt_seed_phi0)
1279 call mt_require_real(
'mt_seed_alpha',mt_seed_alpha)
1280 if (mt_seed_theta0<xprobmin2 .or. mt_seed_theta0>xprobmax2)
then
1281 call mpistop(
'spherical_surface_products requires radial_plane '// &
1282 'mt_seed_theta0 inside domain')
1284 if (mt_seed_phi0<xprobmin3 .or. mt_seed_phi0>xprobmax3)
then
1285 call mpistop(
'spherical_surface_products requires radial_plane '// &
1286 'mt_seed_phi0 inside domain')
1288 if (abs(dsin(mt_seed_theta0))<=1.d-12)
then
1289 call mpistop(
'spherical_surface_products radial_plane requires '// &
1290 'mt_seed_theta0 away from the polar singularity')
1294 call mpistop(
'spherical_surface_products supports '// &
1295 'mt_seed_surface=rmin, rconst, theta_const, phi_const, or radial_plane')
1297 call mt_require_positive_int(
'mt_n1',mt_n1)
1298 call mt_require_positive_int(
'mt_n2',mt_n2)
1304 select case (trim(surface))
1305 case (
'rmin',
'rconst')
1310 case (
'theta_const')
1320 case (
'radial_plane')
1323 s2_min=-0.5d0*min(xprobmax2-xprobmin2,xprobmax3-xprobmin3)
1324 s2_max= 0.5d0*min(xprobmax2-xprobmin2,xprobmax3-xprobmin3)
1327 if (mt_is_set_real(mt_s1min)) s1_min=mt_s1min
1328 if (mt_is_set_real(mt_s1max)) s1_max=mt_s1max
1329 if (mt_is_set_real(mt_s2min)) s2_min=mt_s2min
1330 if (mt_is_set_real(mt_s2max)) s2_max=mt_s2max
1331 call mt_require_ordered(
'mt_s1min',
'mt_s1max',s1_min,s1_max)
1332 call mt_require_ordered(
'mt_s2min',
'mt_s2max',s2_min,s2_max)
1335 if (mt_write_csv)
then
1336 if (trim(surface)==
'rmin')
then
1337 suffix=
'_spherical_rmin_products.csv'
1338 else if (trim(surface)==
'radial_plane')
then
1339 suffix=
'_spherical_radial_plane_products.csv'
1341 suffix=
'_spherical_'//trim(surface)//
'_products.csv'
1343 call mt_resolve_prefix_file(trim(suffix),csv_file, &
1344 'spherical_surface_products CSV requires mt_output_prefix')
1346 if (trim(surface)==
'rmin')
then
1347 suffix=
'_spherical_rmin_products.vtu'
1348 else if (trim(surface)==
'radial_plane')
then
1349 suffix=
'_spherical_radial_plane_products.vtu'
1351 suffix=
'_spherical_'//trim(surface)//
'_products.vtu'
1353 call mt_resolve_output_file(
'spherical_surface_products',
'.vtu', &
1354 trim(suffix),vtu_file)
1356 if (mt_write_csv)
then
1357 write(*,
'(a)')
'mt_run_topology_task: writing spherical '// &
1358 trim(surface)//
' CSV '//trim(csv_file)
1360 write(*,
'(a)')
'mt_run_topology_task: writing spherical '// &
1361 trim(surface)//
' VTU '//trim(vtu_file)
1363 if (mt_profile_spherical)
then
1364 call trace_spherical_profile_reset()
1365 call trace_spherical_profile_set(.true.)
1368 seed_theta0=mt_seed_theta0
1369 seed_phi0=mt_seed_phi0
1370 seed_alpha=mt_seed_alpha
1371 if (mt_b_min>0.d0)
then
1372 call mt_fieldline_products_spherical_surface(trim(surface),seed_coord, &
1373 s1_min,s1_max,mt_n1,s2_min,s2_max,mt_n2,mt_dl,mt_max_steps, &
1374 trim(csv_file),trim(vtu_file),trim(mt_seed_layout), &
1375 seed_theta0,seed_phi0,seed_alpha, &
1376 compute_twist=mt_compute_twist,compute_q=mt_compute_q, &
1377 compute_qperp=mt_compute_qperp,b_min=mt_b_min)
1379 call mt_fieldline_products_spherical_surface(trim(surface),seed_coord, &
1380 s1_min,s1_max,mt_n1,s2_min,s2_max,mt_n2,mt_dl,mt_max_steps, &
1381 trim(csv_file),trim(vtu_file),trim(mt_seed_layout), &
1382 seed_theta0,seed_phi0,seed_alpha, &
1383 compute_twist=mt_compute_twist,compute_q=mt_compute_q, &
1384 compute_qperp=mt_compute_qperp)
1386 if (mt_profile_spherical)
then
1387 call trace_spherical_profile_report(
'spherical_surface_products '// &
1389 call trace_spherical_profile_set(.false.)
1391 end subroutine mt_run_spherical_surface_products_task
1393 subroutine mt_run_spherical_cloud_products_task()
1394 character(len=mt_task_name_len) :: vtu_file
1395 double precision :: s1_min,s1_max,s2_min,s2_max,s3_min,s3_max
1397 if (mt_write_csv)
then
1398 write(*,
'(a)')
'mt_run_topology_task: spherical_cloud_products '// &
1399 'does not write CSV; use seed_products for selected-point diagnostics'
1401 call mt_require_positive_int(
'mt_n1',mt_n1)
1402 call mt_require_positive_int(
'mt_n2',mt_n2)
1403 call mt_require_positive_int(
'mt_n3',mt_n3)
1416 if (mt_is_set_real(mt_s1min)) s1_min=mt_s1min
1417 if (mt_is_set_real(mt_s1max)) s1_max=mt_s1max
1418 if (mt_is_set_real(mt_s2min)) s2_min=mt_s2min
1419 if (mt_is_set_real(mt_s2max)) s2_max=mt_s2max
1420 if (mt_is_set_real(mt_s3min)) s3_min=mt_s3min
1421 if (mt_is_set_real(mt_s3max)) s3_max=mt_s3max
1422 call mt_require_ordered(
'mt_s1min',
'mt_s1max',s1_min,s1_max)
1423 call mt_require_ordered(
'mt_s2min',
'mt_s2max',s2_min,s2_max)
1424 call mt_require_ordered(
'mt_s3min',
'mt_s3max',s3_min,s3_max)
1426 call mt_resolve_output_file(
'spherical_cloud_products',
'.vtu', &
1427 '_spherical_cloud_products.vtu',vtu_file)
1429 write(*,
'(a)')
'mt_run_topology_task: writing spherical cloud VTU '// &
1432 if (mt_profile_spherical)
then
1433 call trace_spherical_profile_reset()
1434 call trace_spherical_profile_set(.true.)
1437 if (mt_b_min>0.d0)
then
1438 call mt_fieldline_products_spherical_cloud(s1_min,s1_max,mt_n1, &
1439 s2_min,s2_max,mt_n2,s3_min,s3_max,mt_n3,mt_dl,mt_max_steps, &
1440 trim(vtu_file),trim(mt_seed_layout), &
1441 compute_twist=mt_compute_twist,compute_q=mt_compute_q, &
1442 compute_qperp=mt_compute_qperp,b_min=mt_b_min)
1444 call mt_fieldline_products_spherical_cloud(s1_min,s1_max,mt_n1, &
1445 s2_min,s2_max,mt_n2,s3_min,s3_max,mt_n3,mt_dl,mt_max_steps, &
1446 trim(vtu_file),trim(mt_seed_layout), &
1447 compute_twist=mt_compute_twist,compute_q=mt_compute_q, &
1448 compute_qperp=mt_compute_qperp)
1450 if (mt_profile_spherical)
then
1451 call trace_spherical_profile_report(
'spherical_cloud_products')
1452 call trace_spherical_profile_set(.false.)
1454 end subroutine mt_run_spherical_cloud_products_task
1456 subroutine mt_resolve_output_file(mode,extension,suffix,output_file)
1457 character(len=*),
intent(in) :: mode,extension,suffix
1458 character(len=*),
intent(out) :: output_file
1459 integer :: required_len
1462 if (len_trim(mt_output_file)>0)
then
1463 output_file=trim(mt_output_file)
1464 if (len_trim(mt_output_prefix)>0)
then
1465 write(*,
'(a)')
'mt_run_topology_task: mt_output_file takes precedence over mt_output_prefix'
1467 call mt_warn_extension(output_file,extension,mode)
1469 required_len=len_trim(mt_output_prefix)+len_trim(suffix)
1470 if (required_len>len(output_file))
then
1471 call mpistop(
'mt_run_topology_task output filename exceeds internal length')
1473 output_file=trim(mt_output_prefix)//trim(suffix)
1475 end subroutine mt_resolve_output_file
1477 subroutine mt_resolve_prefix_file(suffix,output_file,missing_message)
1478 character(len=*),
intent(in) :: suffix,missing_message
1479 character(len=*),
intent(out) :: output_file
1480 integer :: required_len
1482 if (len_trim(mt_output_prefix)==0)
then
1483 call mpistop(trim(missing_message))
1485 required_len=len_trim(mt_output_prefix)+len_trim(suffix)
1486 if (required_len>len(output_file))
then
1487 call mpistop(
'mt_run_topology_task output filename exceeds internal length')
1489 output_file=trim(mt_output_prefix)//trim(suffix)
1490 end subroutine mt_resolve_prefix_file
1492 logical function mt_is_set_real(value)
result(is_set)
1493 double precision,
intent(in) :: value
1495 is_set=(
value/=mt_unset_real)
1496 end function mt_is_set_real
1498 subroutine mt_require_real(name,value)
1499 character(len=*),
intent(in) :: name
1500 double precision,
intent(in) :: value
1502 if (.not.mt_is_set_real(
value))
then
1503 call mpistop(
'mt_run_topology_task requires '//trim(name))
1505 end subroutine mt_require_real
1507 subroutine mt_require_positive_int(name,value)
1508 character(len=*),
intent(in) :: name
1509 integer,
intent(in) :: value
1512 call mpistop(
'mt_run_topology_task requires '//trim(name)//
' > 0')
1514 end subroutine mt_require_positive_int
1516 subroutine mt_require_ordered(name_min,name_max,value_min,value_max)
1517 character(len=*),
intent(in) :: name_min,name_max
1518 double precision,
intent(in) :: value_min,value_max
1520 if (value_max<value_min)
then
1521 call mpistop(
'mt_run_topology_task requires ordered '// &
1522 trim(name_min)//
'/'//trim(name_max))
1524 end subroutine mt_require_ordered
1526 subroutine mt_require_requested_science(do_length,do_twist,do_q,do_qperp, &
1528 logical,
intent(in) :: do_length,do_twist,do_q,do_qperp
1529 character(len=*),
intent(in) :: caller
1531 if (.not.(do_length .or. do_twist .or. do_q .or. do_qperp))
then
1532 call mpistop(trim(caller)//
' requires at least one requested science array')
1534 end subroutine mt_require_requested_science
1536 subroutine mt_read_seed_file(filename,seeds,nseed)
1537 character(len=*),
intent(in) :: filename
1538 double precision,
allocatable,
intent(out) :: seeds(:,:)
1539 integer,
intent(out) :: nseed
1541 character(len=1024) :: line
1542 double precision :: xyz(3)
1543 integer :: io,ios,line_no,iseed
1546 open(newunit=io,file=trim(filename),status=
'old',action=
'read', &
1547 form=
'formatted',iostat=ios)
1549 call mpistop(
'mt_read_seed_file could not open '//trim(filename))
1553 read(io,
'(a)',iostat=ios) line
1556 if (.not.mt_seed_line_is_data(line)) cycle
1557 call mt_validate_seed_line(filename,line,line_no)
1562 call mpistop(
'mt_read_seed_file found no seeds in '//trim(filename))
1565 allocate(seeds(nseed,ndim))
1567 open(newunit=io,file=trim(filename),status=
'old',action=
'read', &
1568 form=
'formatted',iostat=ios)
1570 call mpistop(
'mt_read_seed_file could not reopen '//trim(filename))
1575 read(io,
'(a)',iostat=ios) line
1578 if (.not.mt_seed_line_is_data(line)) cycle
1580 read(line,*,iostat=ios) xyz
1582 call mt_fail_seed_line(filename,line_no)
1584 seeds(iseed,1:ndim)=xyz(1:ndim)
1587 end subroutine mt_read_seed_file
1589 logical function mt_seed_line_is_data(line)
result(is_data)
1590 character(len=*),
intent(in) :: line
1591 character(len=len(line)) :: trimmed
1593 trimmed=adjustl(line)
1594 is_data=len_trim(trimmed)>0
1595 if (is_data) is_data=trimmed(1:1)/=
'#'
1596 end function mt_seed_line_is_data
1598 subroutine mt_validate_seed_line(filename,line,line_no)
1599 character(len=*),
intent(in) :: filename,line
1600 integer,
intent(in) :: line_no
1602 double precision :: x,y,z
1605 if (index(line,
',')>0)
then
1606 call mt_fail_seed_line(filename,line_no)
1608 if (mt_count_tokens(line)/=3)
then
1609 call mt_fail_seed_line(filename,line_no)
1611 read(line,*,iostat=ios) x,y,z
1613 call mt_fail_seed_line(filename,line_no)
1615 end subroutine mt_validate_seed_line
1617 integer function mt_count_tokens(line)
result(ntoken)
1618 character(len=*),
intent(in) :: line
1624 do i=1,len_trim(line)
1625 if (line(i:i)==
' ' .or. line(i:i)==achar(9))
then
1628 if (.not.in_token)
then
1634 end function mt_count_tokens
1636 subroutine mt_fail_seed_line(filename,line_no)
1637 character(len=*),
intent(in) :: filename
1638 integer,
intent(in) :: line_no
1640 call mpistop(
'mt_read_seed_file malformed line '// &
1641 trim(mt_int_to_string(line_no))//
' in '//trim(filename))
1642 end subroutine mt_fail_seed_line
1644 function mt_int_to_string(value)
result(text)
1645 integer,
intent(in) :: value
1646 character(len=32) :: text
1648 write(text,
'(i0)')
value
1649 end function mt_int_to_string
1651 subroutine mt_warn_extension(filename,extension,mode)
1652 character(len=*),
intent(in) :: filename,extension,mode
1654 if (.not.mt_has_extension(filename,extension))
then
1655 write(*,
'(a)')
'mt_run_topology_task warning: '//trim(mode)// &
1656 ' output file does not end in '//trim(extension)
1658 end subroutine mt_warn_extension
1660 logical function mt_has_extension(filename,extension)
result(has_ext)
1661 character(len=*),
intent(in) :: filename,extension
1662 character(len=mt_task_name_len) :: fname,ext
1665 fname=mt_lowercase(trim(filename))
1666 ext=mt_lowercase(trim(extension))
1670 if (lf>=le) has_ext=(fname(lf-le+1:lf)==ext(1:le))
1671 end function mt_has_extension
1673 function mt_lowercase(input)
result(output)
1674 character(len=*),
intent(in) :: input
1675 character(len=len(input)) :: output
1680 code=iachar(output(i:i))
1681 if (code>=iachar(
'A') .and. code<=iachar(
'Z'))
then
1682 output(i:i)=achar(code+iachar(
'a')-iachar(
'A'))
1685 end function mt_lowercase
1687 logical function mt_vtk_detail_is_full()
result(is_full)
1688 is_full=(mt_lowercase(trim(mt_vtk_detail))==
'full')
1689 end function mt_vtk_detail_is_full
1691 double precision function mt_visual_float(value)
result(out_value)
1692 double precision,
intent(in) :: value
1694 if (ieee_is_finite(
value))
then
1699 end function mt_visual_float
1701 double precision function mt_visual_valid_float(value,is_valid) &
1703 double precision,
intent(in) :: value
1704 logical,
intent(in) :: is_valid
1706 if (is_valid .and. ieee_is_finite(
value))
then
1711 end function mt_visual_valid_float
1713 double precision function mt_vc(vec,icomp)
result(value)
1716 double precision,
intent(in) :: vec(ndim)
1717 integer,
intent(in) :: icomp
1719 if (icomp>=1 .and. icomp<=ndim)
then
1728 double precision,
intent(in) :: seed(ndim),dl
1729 integer,
intent(in) :: max_steps
1730 character(len=*),
intent(in) :: csv_file
1731 double precision,
intent(in),
optional :: b_min
1733 type(trace_length_result) :: result
1734 double precision :: seed_xyz(3)
1735 integer :: csv_unit,io_status
1738 call mpistop(
'mt_length_single currently requires npe=1')
1741 if (
present(b_min))
then
1742 call trace_field_length_single(seed,dl,max_steps,result,b_min)
1744 call trace_field_length_single(seed,dl,max_steps,result)
1748 seed_xyz(1:ndim)=result%seed
1750 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
1751 action=
'write',form=
'formatted',iostat=io_status)
1752 if (io_status/=0)
then
1753 call mpistop(
'mt_length_single could not open CSV file')
1756 write(csv_unit,
'(a)',iostat=io_status) &
1757 'seed_x,seed_y,seed_z,'// &
1758 'length_total,length_backward,length_forward,'// &
1759 'nstep_backward,nstep_forward,'// &
1760 'status_backward,status_forward'
1761 if (io_status/=0)
then
1763 call mpistop(
'mt_length_single could not write CSV header')
1766 write(csv_unit,
'(es24.16,5(",",es24.16),4(",",i0))',iostat=io_status) &
1767 seed_xyz,result%total_length, &
1768 result%backward_length,result%forward_length, &
1769 result%backward_nstep,result%forward_nstep, &
1770 result%backward_status,result%forward_status
1771 if (io_status/=0)
then
1773 call mpistop(
'mt_length_single could not write CSV data')
1781 integer,
intent(in) :: nseed,max_steps
1782 double precision,
intent(in) :: seeds(nseed,ndim),dl
1783 character(len=*),
intent(in) :: csv_file
1784 double precision,
intent(in),
optional :: b_min
1786 type(trace_length_result),
allocatable :: results(:)
1787 double precision :: seed_xyz(3)
1788 integer :: csv_unit,io_status,iseed
1791 call mpistop(
'mt_length_seeds currently requires npe=1')
1794 call mpistop(
'mt_length_seeds requires nseed>=0')
1797 allocate(results(nseed))
1798 if (
present(b_min))
then
1799 call trace_field_length_multi(seeds,nseed,dl,max_steps,results,b_min)
1801 call trace_field_length_multi(seeds,nseed,dl,max_steps,results)
1804 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
1805 action=
'write',form=
'formatted',iostat=io_status)
1806 if (io_status/=0)
then
1808 call mpistop(
'mt_length_seeds could not open CSV file')
1811 write(csv_unit,
'(a)',iostat=io_status) &
1812 'seed_id,seed_x,seed_y,seed_z,'// &
1813 'length_total,length_backward,length_forward,'// &
1814 'nstep_backward,nstep_forward,'// &
1815 'status_backward,status_forward'
1816 if (io_status/=0)
then
1819 call mpistop(
'mt_length_seeds could not write CSV header')
1824 seed_xyz(1:ndim)=results(iseed)%seed
1825 write(csv_unit,
'(i0,6(",",es24.16),4(",",i0))',iostat=io_status) &
1826 iseed,seed_xyz,results(iseed)%total_length, &
1827 results(iseed)%backward_length,results(iseed)%forward_length, &
1828 results(iseed)%backward_nstep,results(iseed)%forward_nstep, &
1829 results(iseed)%backward_status,results(iseed)%forward_status
1830 if (io_status/=0)
then
1833 call mpistop(
'mt_length_seeds could not write CSV data')
1842 b_min,compute_length,compute_twist,compute_q,compute_qperp,vtu_file)
1844 integer,
intent(in) :: nseed,max_steps
1845 double precision,
intent(in) :: seeds(nseed,ndim),dl
1846 character(len=*),
intent(in) :: csv_file
1847 double precision,
intent(in),
optional :: b_min
1848 logical,
intent(in),
optional :: compute_length,compute_twist
1849 logical,
intent(in),
optional :: compute_q,compute_qperp
1850 character(len=*),
intent(in),
optional :: vtu_file
1852 type(trace_length_result),
allocatable :: length_results(:)
1853 type(trace_twist_result),
allocatable :: twist_results(:)
1854 type(trace_qperp_result),
allocatable :: q_results(:)
1855 type(trace_qperp_result),
allocatable :: qperp_results(:)
1856 logical :: do_length,do_twist,do_q,do_qperp
1857 character(len=mt_task_name_len) :: integrator
1863 if (
present(compute_length)) do_length=compute_length
1864 if (
present(compute_twist)) do_twist=compute_twist
1865 if (
present(compute_q)) do_q=compute_q
1866 if (
present(compute_qperp)) do_qperp=compute_qperp
1867 integrator=mt_lowercase(trim(mt_trace_integrator))
1870 call mpistop(
'mt_fieldline_products_seeds currently requires npe=1')
1873 call mpistop(
'mt_fieldline_products_seeds requires 3D Cartesian or spherical geometry')
1876 select case (geo_coordinate)
1877 case (geo_cartesian,geo_cartesian_stretched)
1878 case (geo_spherical)
1879 if (periodb(3))
then
1880 call mpistop(
'spherical seed_products does not yet support periodic phi')
1883 call mpistop(
'mt_fieldline_products_seeds requires Cartesian or spherical geometry')
1887 select case (trim(integrator))
1890 case (
'rk45_cartesian')
1892 if (geo_coordinate==geo_spherical)
then
1893 call mpistop(
'seed_products logQperp with spherical geometry '// &
1894 'requires mt_trace_integrator=rk45_spherical')
1897 case (
'rk45_spherical')
1899 if (geo_coordinate/=geo_spherical)
then
1900 call mpistop(
'seed_products logQperp with Cartesian geometry '// &
1901 'requires mt_trace_integrator=rk45_cartesian')
1905 call mpistop(
'seed_products logQperp requires mt_trace_integrator='// &
1906 'rk2, rk45_cartesian, or rk45_spherical')
1910 select case (trim(integrator))
1913 case (
'rk45_cartesian')
1915 if (geo_coordinate==geo_spherical)
then
1916 call mpistop(
'seed_products logQ with spherical geometry '// &
1917 'requires mt_trace_integrator=rk45_spherical')
1920 case (
'rk45_spherical')
1922 if (geo_coordinate/=geo_spherical)
then
1923 call mpistop(
'seed_products logQ with Cartesian geometry '// &
1924 'requires mt_trace_integrator=rk45_cartesian')
1928 call mpistop(
'seed_products logQ requires mt_trace_integrator='// &
1929 'rk2, rk45_cartesian, or rk45_spherical')
1933 call mpistop(
'mt_fieldline_products_seeds requires nseed>=0')
1935 call mt_require_requested_science(do_length,do_twist,do_q,do_qperp, &
1936 'mt_fieldline_products_seeds')
1938 allocate(length_results(nseed))
1940 allocate(twist_results(nseed))
1942 allocate(twist_results(0))
1945 allocate(q_results(nseed))
1947 allocate(q_results(0))
1950 allocate(qperp_results(nseed))
1952 allocate(qperp_results(0))
1955 if (
present(b_min))
then
1956 call mt_trace_fieldline_products_seedset(seeds,nseed,dl,max_steps, &
1957 length_results,twist_results,q_results,qperp_results,do_twist, &
1958 do_q,do_qperp,b_min)
1960 call mt_trace_fieldline_products_seedset(seeds,nseed,dl,max_steps, &
1961 length_results,twist_results,q_results,qperp_results,do_twist, &
1965 if (len_trim(csv_file)>0)
then
1966 call mt_write_fieldline_products_seeds_csv(length_results, &
1967 twist_results,q_results,qperp_results,nseed,csv_file,do_twist, &
1970 if (
present(vtu_file))
then
1971 if (len_trim(vtu_file)>0)
then
1972 call mt_write_fieldline_products_vtu_vertices(vtu_file, &
1973 length_results,twist_results,q_results,qperp_results,nseed, &
1974 do_length,do_twist,do_q,do_qperp,
'mt_fieldline_products_seeds')
1978 if (
allocated(qperp_results))
deallocate(qperp_results)
1979 if (
allocated(q_results))
deallocate(q_results)
1980 if (
allocated(twist_results))
deallocate(twist_results)
1981 deallocate(length_results)
1984 subroutine mt_rk45_tangent_diagnostic_seeds(seeds,nseed,dL,max_steps, &
1986 integer,
intent(in) :: nseed,max_steps
1987 double precision,
intent(in) :: seeds(nseed,ndim),dl
1988 character(len=*),
intent(in) :: csv_file
1989 double precision,
intent(in),
optional :: b_min
1991 type(trace_qperp_result),
allocatable :: rk2_results(:)
1992 type(trace_qperp_result),
allocatable :: rk45_results(:)
1995 call mpistop(
'mt_rk45_tangent_diagnostic_seeds currently requires npe=1')
1998 call mpistop(
'mt_rk45_tangent_diagnostic_seeds requires nseed>=0')
2001 allocate(rk2_results(nseed),rk45_results(nseed))
2002 if (
present(b_min))
then
2003 call trace_field_qperp_multi(seeds,nseed,dl,max_steps,rk2_results, &
2005 call trace_debug_cartesian_rk45_tangent_q0_multi(seeds,nseed,dl, &
2006 max_steps,rk45_results,b_min)
2008 call trace_field_qperp_multi(seeds,nseed,dl,max_steps,rk2_results)
2009 call trace_debug_cartesian_rk45_tangent_q0_multi(seeds,nseed,dl, &
2010 max_steps,rk45_results)
2013 call mt_write_rk45_tangent_diagnostic_csv(rk2_results,rk45_results, &
2015 deallocate(rk45_results,rk2_results)
2016 end subroutine mt_rk45_tangent_diagnostic_seeds
2018 subroutine mt_write_rk45_tangent_diagnostic_csv(rk2_results,rk45_results, &
2020 integer,
intent(in) :: nseed
2021 type(trace_qperp_result),
intent(in) :: rk2_results(nseed)
2022 type(trace_qperp_result),
intent(in) :: rk45_results(nseed)
2023 character(len=*),
intent(in) :: csv_file
2025 double precision :: seed_xyz(3),logq_diff,q_diff,length_diff
2026 double precision :: f_endpoint_diff,b_endpoint_diff
2027 double precision :: uf_diff,vf_diff,ub_diff,vb_diff
2028 integer :: csv_unit,io_status,iseed
2030 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
2031 action=
'write',form=
'formatted',iostat=io_status)
2032 if (io_status/=0)
then
2033 call mpistop(
'mt_rk45_tangent_diagnostic could not open CSV file')
2036 write(csv_unit,
'(a)',iostat=io_status) &
2037 'seed_id,seed_x,seed_y,seed_z,'// &
2038 'rk2_status_q0,rk45_status_q0,'// &
2039 'rk2_forward_status,rk45_forward_status,'// &
2040 'rk2_backward_status,rk45_backward_status,'// &
2041 'rk2_logq0,rk45_logq0,abs_diff_logq0,'// &
2042 'rk2_q0,rk45_q0,abs_diff_q0,'// &
2043 'rk2_length_total,rk45_length_total,abs_diff_length_total,'// &
2044 'endpoint_diff_forward,endpoint_diff_backward,'// &
2045 'u_forward_perp_diff,v_forward_perp_diff,'// &
2046 'u_backward_perp_diff,v_backward_perp_diff'
2047 if (io_status/=0)
then
2049 call mpistop(
'mt_rk45_tangent_diagnostic could not write CSV header')
2054 seed_xyz(1:ndim)=rk2_results(iseed)%seed
2055 logq_diff=mt_absdiff_or_nan(rk2_results(iseed)%logq0, &
2056 rk45_results(iseed)%logq0)
2057 q_diff=mt_absdiff_or_nan(rk2_results(iseed)%q0, &
2058 rk45_results(iseed)%q0)
2059 length_diff=abs((rk2_results(iseed)%forward_length+ &
2060 rk2_results(iseed)%backward_length)- &
2061 (rk45_results(iseed)%forward_length+ &
2062 rk45_results(iseed)%backward_length))
2063 f_endpoint_diff=dsqrt(sum((rk2_results(iseed)%forward_endpoint- &
2064 rk45_results(iseed)%forward_endpoint)**2))
2065 b_endpoint_diff=dsqrt(sum((rk2_results(iseed)%backward_endpoint- &
2066 rk45_results(iseed)%backward_endpoint)**2))
2067 uf_diff=dsqrt(sum((rk2_results(iseed)%u_forward_perp- &
2068 rk45_results(iseed)%u_forward_perp)**2))
2069 vf_diff=dsqrt(sum((rk2_results(iseed)%v_forward_perp- &
2070 rk45_results(iseed)%v_forward_perp)**2))
2071 ub_diff=dsqrt(sum((rk2_results(iseed)%u_backward_perp- &
2072 rk45_results(iseed)%u_backward_perp)**2))
2073 vb_diff=dsqrt(sum((rk2_results(iseed)%v_backward_perp- &
2074 rk45_results(iseed)%v_backward_perp)**2))
2076 write(csv_unit,
'(i0,3(",",es24.16),6(",",i0),15(",",es24.16))', &
2079 rk2_results(iseed)%status_q0, &
2080 rk45_results(iseed)%status_q0, &
2081 rk2_results(iseed)%forward_status, &
2082 rk45_results(iseed)%forward_status, &
2083 rk2_results(iseed)%backward_status, &
2084 rk45_results(iseed)%backward_status, &
2085 rk2_results(iseed)%logq0,rk45_results(iseed)%logq0,logq_diff, &
2086 rk2_results(iseed)%q0,rk45_results(iseed)%q0,q_diff, &
2087 rk2_results(iseed)%forward_length+ &
2088 rk2_results(iseed)%backward_length, &
2089 rk45_results(iseed)%forward_length+ &
2090 rk45_results(iseed)%backward_length, &
2091 length_diff,f_endpoint_diff,b_endpoint_diff, &
2092 uf_diff,vf_diff,ub_diff,vb_diff
2093 if (io_status/=0)
then
2095 call mpistop(
'mt_rk45_tangent_diagnostic could not write CSV data')
2100 end subroutine mt_write_rk45_tangent_diagnostic_csv
2102 subroutine mt_rk2_fusion_diagnostic_seeds(seeds,nseed,dL,max_steps, &
2104 integer,
intent(in) :: nseed,max_steps
2105 double precision,
intent(in) :: seeds(nseed,ndim),dl
2106 character(len=*),
intent(in) :: csv_file
2107 double precision,
intent(in),
optional :: b_min
2109 type(trace_topology_result),
allocatable :: summary(:)
2110 type(trace_qperp_result),
allocatable :: q_trace(:)
2111 type(trace_qperp_result),
allocatable :: q_short(:)
2112 type(trace_twist_result),
allocatable :: q_twist(:)
2113 type(trace_twist_result),
allocatable :: q_short_twist(:)
2114 integer :: cache_status
2115 logical :: use_spherical_cache
2118 call mpistop(
'mt_rk2_fusion_diagnostic currently requires npe=1')
2121 call mpistop(
'mt_rk2_fusion_diagnostic requires nseed>=0')
2123 if (mt_lowercase(trim(mt_trace_integrator))/=
'rk2')
then
2124 call mpistop(
'mt_rk2_fusion_diagnostic requires rk2 tracing')
2127 allocate(summary(nseed),q_trace(nseed),q_short(nseed), &
2128 q_twist(nseed),q_short_twist(nseed))
2129 use_spherical_cache=.false.
2131 if (geo_coordinate==geo_spherical)
then
2132 call trace_spherical_curl_cache_build(cache_status)
2133 if (cache_status/=trace_status_active)
then
2134 call mpistop(
'mt_rk2_fusion_diagnostic failed to build '// &
2135 'spherical curl cache')
2137 use_spherical_cache=.true.
2141 if (
present(b_min))
then
2142 call trace_field_topology_multi(seeds,nseed,dl,max_steps,summary, &
2143 need_twist=.true.,need_mapping=.false.,b_min=b_min)
2144 if (geo_coordinate==geo_spherical)
then
2145 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl,max_steps, &
2146 q_trace,b_min,twist_results=q_twist)
2147 call trace_field_rk2_short_boundary_q_multi(seeds,nseed,dl, &
2148 max_steps,q_short,b_min,twist_results=q_short_twist)
2150 call trace_field_qperp_multi(seeds,nseed,dl,max_steps,q_trace, &
2151 b_min,twist_results=q_twist)
2152 call trace_field_rk2_short_boundary_q_multi(seeds,nseed,dl, &
2153 max_steps,q_short,b_min,twist_results=q_short_twist)
2156 call trace_field_topology_multi(seeds,nseed,dl,max_steps,summary, &
2157 need_twist=.true.,need_mapping=.false.)
2158 if (geo_coordinate==geo_spherical)
then
2159 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl,max_steps, &
2160 q_trace,twist_results=q_twist)
2161 call trace_field_rk2_short_boundary_q_multi(seeds,nseed,dl, &
2162 max_steps,q_short,twist_results=q_short_twist)
2164 call trace_field_qperp_multi(seeds,nseed,dl,max_steps,q_trace, &
2165 twist_results=q_twist)
2166 call trace_field_rk2_short_boundary_q_multi(seeds,nseed,dl, &
2167 max_steps,q_short,twist_results=q_short_twist)
2171 if (use_spherical_cache)
call trace_spherical_curl_cache_clear()
2172 call mt_write_rk2_fusion_diagnostic_csv(summary,q_trace,q_twist, &
2173 q_short,q_short_twist,nseed,csv_file)
2174 deallocate(q_short_twist,q_twist,q_short,q_trace,summary)
2175 end subroutine mt_rk2_fusion_diagnostic_seeds
2177 subroutine mt_write_rk2_fusion_diagnostic_csv(summary,q_trace,q_twist, &
2178 q_short,q_short_twist,nseed,csv_file)
2179 integer,
intent(in) :: nseed
2180 type(trace_topology_result),
intent(in) :: summary(nseed)
2181 type(trace_qperp_result),
intent(in) :: q_trace(nseed)
2182 type(trace_twist_result),
intent(in) :: q_twist(nseed)
2183 type(trace_qperp_result),
intent(in) :: q_short(nseed)
2184 type(trace_twist_result),
intent(in) :: q_short_twist(nseed)
2185 character(len=*),
intent(in) :: csv_file
2187 double precision :: seed_xyz(3),length_summary,length_q,length_diff
2188 double precision :: length_short,length_diff_short,length_q_short_diff
2189 double precision :: twist_summary,twist_q,twist_diff
2190 double precision :: twist_short,twist_diff_short,twist_q_short_diff
2191 double precision :: max_length_diff,max_twist_diff
2192 double precision :: max_length_short_diff,max_twist_short_diff
2193 integer :: csv_unit,io_status,iseed
2194 integer :: status_mismatch,face_mismatch,twist_status_mismatch
2195 integer :: short_status_mismatch,short_face_mismatch
2196 integer :: short_twist_status_mismatch,short_valid_q_mismatch
2198 max_length_diff=0.d0
2200 max_length_short_diff=0.d0
2201 max_twist_short_diff=0.d0
2204 twist_status_mismatch=0
2205 short_status_mismatch=0
2206 short_face_mismatch=0
2207 short_twist_status_mismatch=0
2208 short_valid_q_mismatch=0
2210 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
2211 action=
'write',form=
'formatted',iostat=io_status)
2212 if (io_status/=0)
then
2213 call mpistop(
'mt_rk2_fusion_diagnostic could not open CSV file')
2216 write(csv_unit,
'(a)',iostat=io_status) &
2217 'seed_id,seed_x,seed_y,seed_z,'// &
2218 'length_summary,length_qtrace,dlength_summary_minus_qtrace,'// &
2219 'length_forward_summary,length_forward_qtrace,'// &
2220 'length_backward_summary,length_backward_qtrace,'// &
2221 'twist_summary,twist_qtrace,dtwist_summary_minus_qtrace,'// &
2222 'twist_forward_summary,twist_forward_qtrace,'// &
2223 'twist_backward_summary,twist_backward_qtrace,'// &
2224 'length_short,dlength_summary_minus_short,'// &
2225 'dlength_qtrace_minus_short,'// &
2226 'length_forward_short,length_backward_short,'// &
2227 'twist_short,dtwist_summary_minus_short,'// &
2228 'dtwist_qtrace_minus_short,'// &
2229 'twist_forward_short,twist_backward_short,'// &
2230 'status_forward_summary,status_forward_qtrace,status_forward_short,'// &
2231 'status_backward_summary,status_backward_qtrace,status_backward_short,'// &
2232 'face_forward_summary,face_forward_qtrace,face_forward_short,'// &
2233 'face_backward_summary,face_backward_qtrace,face_backward_short,'// &
2234 'status_twist_summary,status_twist_qtrace,status_twist_short,'// &
2235 'logQ,valid_Q,status_Q,logQ_short,valid_Q_short,status_Q_short'
2236 if (io_status/=0)
then
2238 call mpistop(
'mt_rk2_fusion_diagnostic could not write CSV header')
2243 seed_xyz(1:ndim)=summary(iseed)%seed
2244 length_summary=summary(iseed)%length_total
2245 length_q=q_trace(iseed)%forward_length+q_trace(iseed)%backward_length
2246 length_short=q_short(iseed)%forward_length+ &
2247 q_short(iseed)%backward_length
2248 length_diff=length_summary-length_q
2249 length_diff_short=length_summary-length_short
2250 length_q_short_diff=length_q-length_short
2251 twist_summary=summary(iseed)%twist_total
2252 twist_q=q_twist(iseed)%total_twist
2253 twist_short=q_short_twist(iseed)%total_twist
2254 twist_diff=twist_summary-twist_q
2255 twist_diff_short=twist_summary-twist_short
2256 twist_q_short_diff=twist_q-twist_short
2257 max_length_diff=max(max_length_diff,abs(length_diff))
2258 max_twist_diff=max(max_twist_diff,abs(twist_diff))
2259 max_length_short_diff=max(max_length_short_diff, &
2260 abs(length_diff_short))
2261 max_twist_short_diff=max(max_twist_short_diff, &
2262 abs(twist_diff_short))
2263 if (summary(iseed)%forward_status/=q_trace(iseed)%forward_status .or. &
2264 summary(iseed)%backward_status/=q_trace(iseed)%backward_status) &
2265 status_mismatch=status_mismatch+1
2266 if (summary(iseed)%forward_face/=q_trace(iseed)%forward_face .or. &
2267 summary(iseed)%backward_face/=q_trace(iseed)%backward_face) &
2268 face_mismatch=face_mismatch+1
2269 if (summary(iseed)%status_twist/=q_twist(iseed)%status_twist) &
2270 twist_status_mismatch=twist_status_mismatch+1
2271 if (summary(iseed)%forward_status/=q_short(iseed)%forward_status .or. &
2272 summary(iseed)%backward_status/=q_short(iseed)%backward_status) &
2273 short_status_mismatch=short_status_mismatch+1
2274 if (summary(iseed)%forward_face/=q_short(iseed)%forward_face .or. &
2275 summary(iseed)%backward_face/=q_short(iseed)%backward_face) &
2276 short_face_mismatch=short_face_mismatch+1
2277 if (summary(iseed)%status_twist/=q_short_twist(iseed)%status_twist) &
2278 short_twist_status_mismatch=short_twist_status_mismatch+1
2279 if (q_trace(iseed)%valid_q0 .neqv. q_short(iseed)%valid_q0) &
2280 short_valid_q_mismatch=short_valid_q_mismatch+1
2283 '(i0,3(",",es24.16),24(",",es24.16),15(",",i0),'// &
2284 '",",es24.16,",",l1,",",i0,",",es24.16,",",l1,",",i0)', &
2287 length_summary,length_q,length_diff, &
2288 summary(iseed)%length_forward,q_trace(iseed)%forward_length, &
2289 summary(iseed)%length_backward,q_trace(iseed)%backward_length, &
2290 twist_summary,twist_q,twist_diff, &
2291 summary(iseed)%twist_forward,q_twist(iseed)%forward_twist, &
2292 summary(iseed)%twist_backward,q_twist(iseed)%backward_twist, &
2293 length_short,length_diff_short,length_q_short_diff, &
2294 q_short(iseed)%forward_length,q_short(iseed)%backward_length, &
2295 twist_short,twist_diff_short,twist_q_short_diff, &
2296 q_short_twist(iseed)%forward_twist, &
2297 q_short_twist(iseed)%backward_twist, &
2298 summary(iseed)%forward_status,q_trace(iseed)%forward_status, &
2299 q_short(iseed)%forward_status, &
2300 summary(iseed)%backward_status,q_trace(iseed)%backward_status, &
2301 q_short(iseed)%backward_status, &
2302 summary(iseed)%forward_face,q_trace(iseed)%forward_face, &
2303 q_short(iseed)%forward_face, &
2304 summary(iseed)%backward_face,q_trace(iseed)%backward_face, &
2305 q_short(iseed)%backward_face, &
2306 summary(iseed)%status_twist,q_twist(iseed)%status_twist, &
2307 q_short_twist(iseed)%status_twist, &
2308 q_trace(iseed)%logq0,q_trace(iseed)%valid_q0, &
2309 q_trace(iseed)%status_q0, &
2310 q_short(iseed)%logq0,q_short(iseed)%valid_q0, &
2311 q_short(iseed)%status_q0
2312 if (io_status/=0)
then
2314 call mpistop(
'mt_rk2_fusion_diagnostic could not write CSV data')
2319 write(*,
'(a,es12.4)')
'mt_rk2_fusion_diagnostic max_abs_length_diff: ', &
2321 write(*,
'(a,es12.4)')
'mt_rk2_fusion_diagnostic max_abs_twist_diff: ', &
2323 write(*,
'(a,es12.4)') &
2324 'mt_rk2_fusion_diagnostic max_abs_length_diff_short: ', &
2325 max_length_short_diff
2326 write(*,
'(a,es12.4)') &
2327 'mt_rk2_fusion_diagnostic max_abs_twist_diff_short: ', &
2328 max_twist_short_diff
2329 write(*,
'(a,i0)')
'mt_rk2_fusion_diagnostic status_mismatch_count: ', &
2331 write(*,
'(a,i0)')
'mt_rk2_fusion_diagnostic face_mismatch_count: ', &
2334 'mt_rk2_fusion_diagnostic twist_status_mismatch_count: ', &
2335 twist_status_mismatch
2337 'mt_rk2_fusion_diagnostic short_status_mismatch_count: ', &
2338 short_status_mismatch
2340 'mt_rk2_fusion_diagnostic short_face_mismatch_count: ', &
2343 'mt_rk2_fusion_diagnostic short_twist_status_mismatch_count: ', &
2344 short_twist_status_mismatch
2346 'mt_rk2_fusion_diagnostic short_valid_q_mismatch_count: ', &
2347 short_valid_q_mismatch
2348 end subroutine mt_write_rk2_fusion_diagnostic_csv
2350 double precision function mt_absdiff_or_nan(a,b)
result(diff)
2351 double precision,
intent(in) :: a,b
2353 if (ieee_is_finite(a) .and. ieee_is_finite(b))
then
2356 diff=ieee_value(0.d0,ieee_quiet_nan)
2358 end function mt_absdiff_or_nan
2360 subroutine mt_fieldline_products_spherical_surface(surface,seed_coord, &
2361 s1_min,s1_max,n1,s2_min,s2_max,n2,dL,max_steps,csv_file, &
2362 vtu_file,seed_layout,seed_theta0,seed_phi0,seed_alpha, &
2363 compute_twist,compute_q,compute_qperp,b_min)
2364 character(len=*),
intent(in) :: surface,csv_file,vtu_file,seed_layout
2365 integer,
intent(in) :: n1,n2,max_steps
2366 double precision,
intent(in) :: seed_coord,s1_min,s1_max,s2_min,s2_max,dl
2367 double precision,
intent(in) :: seed_theta0,seed_phi0,seed_alpha
2368 logical,
intent(in),
optional :: compute_twist,compute_q,compute_qperp
2369 double precision,
intent(in),
optional :: b_min
2371 type(trace_topology_result),
allocatable :: topology(:)
2372 type(trace_qperp_result),
allocatable :: q_results(:)
2373 type(trace_qperp_result),
allocatable :: qperp_results(:)
2374 double precision,
allocatable :: seeds(:,:)
2376 logical :: do_twist,do_q,do_qperp
2379 call mpistop(
'mt_fieldline_products_spherical_surface currently '// &
2382 if (ndim/=3 .or. geo_coordinate/=geo_spherical)
then
2383 call mpistop(
'mt_fieldline_products_spherical_surface requires '// &
2384 '3D spherical geometry')
2387 if (periodb(3))
then
2388 call mpistop(
'mt_fieldline_products_spherical_surface does not '// &
2389 'yet support periodic phi')
2392 if (n1<1 .or. n2<1)
then
2393 call mpistop(
'mt_fieldline_products_spherical_surface requires '// &
2394 'sample counts >=1')
2396 if (s1_max<s1_min .or. s2_max<s2_min)
then
2397 call mpistop(
'mt_fieldline_products_spherical_surface requires ordered bounds')
2402 if (
present(compute_twist)) do_twist=compute_twist
2403 if (
present(compute_q)) do_q=compute_q
2404 if (
present(compute_qperp)) do_qperp=compute_qperp
2405 call mt_build_spherical_surface_seeds(surface,seed_coord,s1_min,s1_max, &
2406 n1,s2_min,s2_max,n2,seed_layout,seed_theta0,seed_phi0, &
2409 if (mt_profile_spherical)
call trace_spherical_profile_count_seeds(nseed)
2410 allocate(topology(nseed))
2412 allocate(q_results(nseed))
2414 allocate(q_results(0))
2417 allocate(qperp_results(nseed))
2419 allocate(qperp_results(0))
2422 if (
present(b_min))
then
2423 call mt_trace_spherical_surface_products(seeds,nseed,dl,max_steps, &
2424 topology,q_results,qperp_results,do_twist,do_q,do_qperp,b_min)
2426 call mt_trace_spherical_surface_products(seeds,nseed,dl,max_steps, &
2427 topology,q_results,qperp_results,do_twist,do_q,do_qperp)
2430 if (len_trim(csv_file)>0)
then
2431 call mt_write_spherical_rmin_csv(topology,n1,n2,csv_file, &
2432 'mt_fieldline_products_spherical_surface',do_twist,do_q, &
2433 q_results,do_qperp,qperp_results)
2435 call mt_write_spherical_topology_vtu(vtu_file,topology,n1,n2, &
2436 'mt_fieldline_products_spherical_surface',do_twist,do_q,q_results, &
2437 do_qperp,qperp_results)
2439 deallocate(qperp_results,q_results,topology,seeds)
2440 end subroutine mt_fieldline_products_spherical_surface
2442 subroutine mt_fieldline_products_spherical_cloud(s1_min,s1_max,n1, &
2443 s2_min,s2_max,n2,s3_min,s3_max,n3,dL,max_steps,vtu_file, &
2444 seed_layout,compute_twist,compute_q,compute_qperp,b_min)
2445 character(len=*),
intent(in) :: vtu_file,seed_layout
2446 integer,
intent(in) :: n1,n2,n3,max_steps
2447 double precision,
intent(in) :: s1_min,s1_max,s2_min,s2_max
2448 double precision,
intent(in) :: s3_min,s3_max,dl
2449 logical,
intent(in),
optional :: compute_twist,compute_q,compute_qperp
2450 double precision,
intent(in),
optional :: b_min
2452 type(trace_topology_result),
allocatable :: topology(:)
2453 type(trace_qperp_result),
allocatable :: q_results(:)
2454 type(trace_qperp_result),
allocatable :: qperp_results(:)
2455 double precision,
allocatable :: seeds(:,:)
2457 logical :: do_twist,do_q,do_qperp
2458 character(len=mt_task_name_len) :: integrator
2461 call mpistop(
'mt_fieldline_products_spherical_cloud currently '// &
2464 if (ndim/=3 .or. geo_coordinate/=geo_spherical)
then
2465 call mpistop(
'mt_fieldline_products_spherical_cloud requires '// &
2466 '3D spherical geometry')
2469 if (periodb(3))
then
2470 call mpistop(
'mt_fieldline_products_spherical_cloud does not '// &
2471 'yet support periodic phi')
2474 if (n1<1 .or. n2<1 .or. n3<1)
then
2475 call mpistop(
'mt_fieldline_products_spherical_cloud requires '// &
2476 'sample counts >=1')
2478 if (s1_max<s1_min .or. s2_max<s2_min .or. s3_max<s3_min)
then
2479 call mpistop(
'mt_fieldline_products_spherical_cloud requires ordered bounds')
2485 if (
present(compute_twist)) do_twist=compute_twist
2486 if (
present(compute_q)) do_q=compute_q
2487 if (
present(compute_qperp)) do_qperp=compute_qperp
2488 integrator=mt_lowercase(trim(mt_trace_integrator))
2490 call mt_build_spherical_cloud_seeds(s1_min,s1_max,n1,s2_min,s2_max, &
2491 n2,s3_min,s3_max,n3,seed_layout,seeds)
2493 if (mt_profile_spherical)
call trace_spherical_profile_count_seeds(nseed)
2494 allocate(topology(nseed))
2496 allocate(q_results(nseed))
2498 allocate(q_results(0))
2501 allocate(qperp_results(nseed))
2503 allocate(qperp_results(0))
2506 if (
present(b_min))
then
2507 call mt_trace_spherical_cloud_products(seeds,nseed,dl,max_steps, &
2508 topology,q_results,qperp_results,do_twist,do_q,do_qperp,b_min)
2510 call mt_trace_spherical_cloud_products(seeds,nseed,dl,max_steps, &
2511 topology,q_results,qperp_results,do_twist,do_q,do_qperp)
2514 call mt_write_spherical_cloud_vtu(vtu_file,topology,nseed, &
2515 'mt_fieldline_products_spherical_cloud',do_twist,do_q,q_results, &
2516 do_qperp,qperp_results)
2518 deallocate(qperp_results,q_results,topology,seeds)
2519 end subroutine mt_fieldline_products_spherical_cloud
2521 subroutine mt_trace_spherical_surface_products(seeds,nseed,dL,max_steps, &
2522 topology,q_results,qperp_results,do_twist,do_q,do_qperp,b_min)
2523 integer,
intent(in) :: nseed,max_steps
2524 double precision,
intent(in) :: seeds(nseed,ndim),dl
2525 type(trace_topology_result),
intent(out) :: topology(nseed)
2526 type(trace_qperp_result),
intent(out) :: q_results(:)
2527 type(trace_qperp_result),
intent(out) :: qperp_results(:)
2528 logical,
intent(in) :: do_twist,do_q,do_qperp
2529 double precision,
intent(in),
optional :: b_min
2531 type(trace_qperp_result) :: q_local,qperp_local
2532 double precision :: seed_local(ndim)
2533 integer :: iseed,cache_status
2535 if (nseed<=0)
return
2538 call trace_spherical_curl_cache_build(cache_status)
2539 if (cache_status/=trace_status_active)
then
2540 call mpistop(
'mt_trace_spherical_surface_products failed to '// &
2541 'build spherical curl cache')
2545 if (
present(b_min))
then
2548 seed_local=seeds(iseed,:)
2549 call mt_trace_spherical_surface_seed(seed_local,dl,max_steps, &
2550 topology(iseed),q_local,qperp_local,do_twist,do_q, &
2552 if (do_q) q_results(iseed)=q_local
2553 if (do_qperp) qperp_results(iseed)=qperp_local
2559 seed_local=seeds(iseed,:)
2560 call mt_trace_spherical_surface_seed(seed_local,dl,max_steps, &
2561 topology(iseed),q_local,qperp_local,do_twist,do_q, &
2563 if (do_q) q_results(iseed)=q_local
2564 if (do_qperp) qperp_results(iseed)=qperp_local
2569 if (do_twist)
call trace_spherical_curl_cache_clear()
2570 end subroutine mt_trace_spherical_surface_products
2572 subroutine mt_trace_spherical_surface_seed(seed,dL,max_steps,topology, &
2573 q_result,qperp_result,do_twist,do_q,do_qperp,b_min)
2574 integer,
intent(in) :: max_steps
2575 double precision,
intent(in) :: seed(ndim),dl
2576 type(trace_topology_result),
intent(out) :: topology
2577 type(trace_qperp_result),
intent(out) :: q_result,qperp_result
2578 logical,
intent(in) :: do_twist,do_q,do_qperp
2579 double precision,
intent(in),
optional :: b_min
2581 type(trace_topology_result) :: topology_one(1)
2582 type(trace_qperp_result) :: q_one(1),qperp_one(1)
2583 type(trace_twist_result) :: twist_one(1)
2584 double precision :: seed_one(1,ndim),source_normal(3)
2588 source_normal(1)=-1.d0
2590 if (do_q .and. do_qperp)
then
2591 if (
present(b_min))
then
2593 call trace_field_spherical_rmin_q_qperp_multi(seed_one,1,dl, &
2594 max_steps,q_one,qperp_one,b_min,twist_results=twist_one)
2596 call trace_field_spherical_rmin_q_qperp_multi(seed_one,1,dl, &
2597 max_steps,q_one,qperp_one,b_min)
2601 call trace_field_spherical_rmin_q_qperp_multi(seed_one,1,dl, &
2602 max_steps,q_one,qperp_one,twist_results=twist_one)
2604 call trace_field_spherical_rmin_q_qperp_multi(seed_one,1,dl, &
2605 max_steps,q_one,qperp_one)
2608 call mt_q0_trace_to_topology(q_one,twist_one,1,topology_one,do_twist)
2609 topology=topology_one(1)
2611 qperp_result=qperp_one(1)
2616 if (
present(b_min))
then
2618 call trace_field_spherical_rmin_q_multi(seed_one,1,dl,max_steps, &
2619 q_one,b_min,twist_results=twist_one)
2621 call trace_field_spherical_rmin_q_multi(seed_one,1,dl,max_steps, &
2626 call trace_field_spherical_rmin_q_multi(seed_one,1,dl,max_steps, &
2627 q_one,twist_results=twist_one)
2629 call trace_field_spherical_rmin_q_multi(seed_one,1,dl,max_steps, &
2633 call mt_q0_trace_to_topology(q_one,twist_one,1,topology_one,do_twist)
2634 topology=topology_one(1)
2639 if (
present(b_min))
then
2640 call trace_field_topology_multi(seed_one,1,dl,max_steps,topology_one, &
2641 need_twist=do_twist,need_mapping=.false.,b_min=b_min, &
2642 source_normal=source_normal)
2644 call trace_field_topology_multi(seed_one,1,dl,max_steps,topology_one, &
2645 need_twist=do_twist,need_mapping=.false., &
2646 source_normal=source_normal)
2648 topology=topology_one(1)
2651 if (
present(b_min))
then
2652 call trace_field_spherical_qperp_multi(seed_one,1,dl,max_steps, &
2655 call trace_field_spherical_qperp_multi(seed_one,1,dl,max_steps, &
2658 qperp_result=qperp_one(1)
2660 end subroutine mt_trace_spherical_surface_seed
2662 subroutine mt_trace_spherical_cloud_products(seeds,nseed,dL,max_steps, &
2663 topology,q_results,qperp_results,do_twist,do_q,do_qperp,b_min)
2664 integer,
intent(in) :: nseed,max_steps
2665 double precision,
intent(in) :: seeds(nseed,ndim),dl
2666 type(trace_topology_result),
intent(out) :: topology(nseed)
2667 type(trace_qperp_result),
intent(out) :: q_results(:)
2668 type(trace_qperp_result),
intent(out) :: qperp_results(:)
2669 logical,
intent(in) :: do_twist,do_q,do_qperp
2670 double precision,
intent(in),
optional :: b_min
2672 type(trace_topology_result) :: topology_one(1)
2673 type(trace_twist_result),
allocatable :: twist_results(:)
2674 double precision :: seed_local(ndim),seed_one(1,ndim)
2675 integer :: iseed,cache_status
2676 character(len=mt_task_name_len) :: integrator
2678 if (nseed<=0)
return
2680 integrator=mt_lowercase(trim(mt_trace_integrator))
2681 if (do_q .and. do_qperp .and. &
2682 (integrator==
'rk2' .or. integrator==
'rk45_spherical'))
then
2686 if (
present(b_min))
then
2687 call mt_trace_spherical_surface_products(seeds,nseed,dl,max_steps, &
2688 topology,q_results,qperp_results,do_twist,do_q,do_qperp,b_min)
2690 call mt_trace_spherical_surface_products(seeds,nseed,dl,max_steps, &
2691 topology,q_results,qperp_results,do_twist,do_q,do_qperp)
2696 if (do_q .and. .not.do_qperp)
then
2698 allocate(twist_results(nseed))
2699 if (
present(b_min))
then
2700 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl,max_steps, &
2701 q_results,b_min,twist_results=twist_results)
2703 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl,max_steps, &
2704 q_results,twist_results=twist_results)
2706 call mt_q0_trace_to_topology(q_results,twist_results,nseed,topology, &
2708 deallocate(twist_results)
2710 allocate(twist_results(0))
2711 if (
present(b_min))
then
2712 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl,max_steps, &
2715 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl,max_steps, &
2718 call mt_q0_trace_to_topology(q_results,twist_results,nseed,topology, &
2720 deallocate(twist_results)
2727 allocate(twist_results(nseed))
2728 if (
present(b_min))
then
2729 call trace_field_spherical_qperp_multi(seeds,nseed,dl,max_steps, &
2730 qperp_results,b_min,twist_results=twist_results)
2732 call trace_field_spherical_qperp_multi(seeds,nseed,dl,max_steps, &
2733 qperp_results,twist_results=twist_results)
2735 call mt_qperp_trace_to_topology(qperp_results,twist_results,nseed, &
2737 deallocate(twist_results)
2739 allocate(twist_results(0))
2740 if (
present(b_min))
then
2741 call trace_field_spherical_qperp_multi(seeds,nseed,dl,max_steps, &
2742 qperp_results,b_min)
2744 call trace_field_spherical_qperp_multi(seeds,nseed,dl,max_steps, &
2747 call mt_qperp_trace_to_topology(qperp_results,twist_results,nseed, &
2749 deallocate(twist_results)
2755 call trace_spherical_curl_cache_build(cache_status)
2756 if (cache_status/=trace_status_active)
then
2757 call mpistop(
'mt_trace_spherical_cloud_products failed to '// &
2758 'build spherical curl cache')
2762 if (
present(b_min))
then
2765 seed_local=seeds(iseed,:)
2766 seed_one(1,:)=seed_local
2767 call trace_field_topology_multi(seed_one,1,dl,max_steps, &
2768 topology_one,need_twist=do_twist,need_mapping=.false., &
2770 topology(iseed)=topology_one(1)
2776 seed_local=seeds(iseed,:)
2777 seed_one(1,:)=seed_local
2778 call trace_field_topology_multi(seed_one,1,dl,max_steps, &
2779 topology_one,need_twist=do_twist,need_mapping=.false.)
2780 topology(iseed)=topology_one(1)
2785 if (do_twist)
call trace_spherical_curl_cache_clear()
2786 end subroutine mt_trace_spherical_cloud_products
2789 max_steps,csv_file,b_min)
2791 integer,
intent(in) :: nx,ny,max_steps
2792 double precision,
intent(in) :: xmin,xmax,ymin,ymax,z0,dl
2793 character(len=*),
intent(in) :: csv_file
2794 double precision,
intent(in),
optional :: b_min
2796 if (
present(b_min))
then
2797 call mt_length_plane_axis(xmin,xmax,nx,ymin,ymax,ny,z0,1,2,3, &
2798 dl,max_steps,csv_file,
'mt_length_plane_xy',
'ix,iy',b_min)
2800 call mt_length_plane_axis(xmin,xmax,nx,ymin,ymax,ny,z0,1,2,3, &
2801 dl,max_steps,csv_file,
'mt_length_plane_xy',
'ix,iy')
2806 max_steps,csv_file,b_min)
2808 integer,
intent(in) :: nx,ny,max_steps
2809 double precision,
intent(in) :: xmin,xmax,ymin,ymax,z0,dl
2810 character(len=*),
intent(in) :: csv_file
2811 double precision,
intent(in),
optional :: b_min
2813 type(trace_mapping_result),
allocatable :: results(:)
2814 double precision,
allocatable :: seeds(:,:)
2815 double precision :: source_normal(3)
2818 call mt_validate_axis_plane(xmin,xmax,nx,ymin,ymax,ny, &
2819 'mt_mapping_plane_xy')
2820 call mt_build_axis_plane_seeds(xmin,xmax,nx,ymin,ymax,ny,z0, &
2824 source_normal(3)=1.d0
2826 allocate(results(nseed))
2827 if (
present(b_min))
then
2828 call trace_field_mapping_multi(seeds,nseed,dl,max_steps,results, &
2829 b_min=b_min,source_normal=source_normal)
2831 call trace_field_mapping_multi(seeds,nseed,dl,max_steps,results, &
2832 source_normal=source_normal)
2834 call mt_write_mapping_plane_xy_csv(results,nx,ny,csv_file)
2836 deallocate(seeds,results)
2839 subroutine mt_q_plane_xy(xmin,xmax,nx,ymin,ymax,ny,z0,dL, &
2840 max_steps,csv_file,b_min)
2842 integer,
intent(in) :: nx,ny,max_steps
2843 double precision,
intent(in) :: xmin,xmax,ymin,ymax,z0,dl
2844 character(len=*),
intent(in) :: csv_file
2845 double precision,
intent(in),
optional :: b_min
2847 if (
present(b_min))
then
2848 call mt_q_plane_axis(xmin,xmax,nx,ymin,ymax,ny,z0,1,2,3, &
2849 dl,max_steps,csv_file,
'mt_q_plane_xy',
'ix,iy',b_min)
2851 call mt_q_plane_axis(xmin,xmax,nx,ymin,ymax,ny,z0,1,2,3, &
2852 dl,max_steps,csv_file,
'mt_q_plane_xy',
'ix,iy')
2854 end subroutine mt_q_plane_xy
2856 subroutine mt_q_plane_xz(xmin,xmax,nx,zmin,zmax,nz,y0,dL, &
2857 max_steps,csv_file,b_min)
2859 integer,
intent(in) :: nx,nz,max_steps
2860 double precision,
intent(in) :: xmin,xmax,zmin,zmax,y0,dl
2861 character(len=*),
intent(in) :: csv_file
2862 double precision,
intent(in),
optional :: b_min
2864 if (
present(b_min))
then
2865 call mt_q_plane_axis(xmin,xmax,nx,zmin,zmax,nz,y0,1,3,2, &
2866 dl,max_steps,csv_file,
'mt_q_plane_xz',
'ix,iz',b_min)
2868 call mt_q_plane_axis(xmin,xmax,nx,zmin,zmax,nz,y0,1,3,2, &
2869 dl,max_steps,csv_file,
'mt_q_plane_xz',
'ix,iz')
2871 end subroutine mt_q_plane_xz
2873 subroutine mt_q_plane_yz(ymin,ymax,ny,zmin,zmax,nz,x0,dL, &
2874 max_steps,csv_file,b_min)
2876 integer,
intent(in) :: ny,nz,max_steps
2877 double precision,
intent(in) :: ymin,ymax,zmin,zmax,x0,dl
2878 character(len=*),
intent(in) :: csv_file
2879 double precision,
intent(in),
optional :: b_min
2881 if (
present(b_min))
then
2882 call mt_q_plane_axis(ymin,ymax,ny,zmin,zmax,nz,x0,2,3,1, &
2883 dl,max_steps,csv_file,
'mt_q_plane_yz',
'iy,iz',b_min)
2885 call mt_q_plane_axis(ymin,ymax,ny,zmin,zmax,nz,x0,2,3,1, &
2886 dl,max_steps,csv_file,
'mt_q_plane_yz',
'iy,iz')
2888 end subroutine mt_q_plane_yz
2891 max_steps,csv_file,b_min)
2893 integer,
intent(in) :: nx,ny,max_steps
2894 double precision,
intent(in) :: xmin,xmax,ymin,ymax,z0,dl
2895 character(len=*),
intent(in) :: csv_file
2896 double precision,
intent(in),
optional :: b_min
2898 if (
present(b_min))
then
2899 call mt_qperp_plane_axis(xmin,xmax,nx,ymin,ymax,ny,z0,1,2,3, &
2900 dl,max_steps,csv_file,
'mt_qperp_plane_xy',
'ix,iy',b_min)
2902 call mt_qperp_plane_axis(xmin,xmax,nx,ymin,ymax,ny,z0,1,2,3, &
2903 dl,max_steps,csv_file,
'mt_qperp_plane_xy',
'ix,iy')
2908 max_steps,csv_file,b_min)
2910 integer,
intent(in) :: nx,nz,max_steps
2911 double precision,
intent(in) :: xmin,xmax,zmin,zmax,y0,dl
2912 character(len=*),
intent(in) :: csv_file
2913 double precision,
intent(in),
optional :: b_min
2915 if (
present(b_min))
then
2916 call mt_qperp_plane_axis(xmin,xmax,nx,zmin,zmax,nz,y0,1,3,2, &
2917 dl,max_steps,csv_file,
'mt_qperp_plane_xz',
'ix,iz',b_min)
2919 call mt_qperp_plane_axis(xmin,xmax,nx,zmin,zmax,nz,y0,1,3,2, &
2920 dl,max_steps,csv_file,
'mt_qperp_plane_xz',
'ix,iz')
2925 max_steps,csv_file,b_min)
2927 integer,
intent(in) :: ny,nz,max_steps
2928 double precision,
intent(in) :: ymin,ymax,zmin,zmax,x0,dl
2929 character(len=*),
intent(in) :: csv_file
2930 double precision,
intent(in),
optional :: b_min
2932 if (
present(b_min))
then
2933 call mt_qperp_plane_axis(ymin,ymax,ny,zmin,zmax,nz,x0,2,3,1, &
2934 dl,max_steps,csv_file,
'mt_qperp_plane_yz',
'iy,iz',b_min)
2936 call mt_qperp_plane_axis(ymin,ymax,ny,zmin,zmax,nz,x0,2,3,1, &
2937 dl,max_steps,csv_file,
'mt_qperp_plane_yz',
'iy,iz')
2942 s2min,s2max,n2,dL,max_steps,csv_file,b_min)
2944 integer,
intent(in) :: n1,n2,max_steps
2945 double precision,
intent(in) :: origin(ndim),e1(ndim),e2(ndim)
2946 double precision,
intent(in) :: s1min,s1max,s2min,s2max,dl
2947 character(len=*),
intent(in) :: csv_file
2948 double precision,
intent(in),
optional :: b_min
2950 type(trace_qperp_result),
allocatable :: results(:)
2951 double precision,
allocatable :: seeds(:,:),s1(:),s2(:)
2954 if (.not.mt_validate_arbitrary_plane_basis(e1,e2,s1min,s1max,n1, &
2955 s2min,s2max,n2,
'mt_qperp_plane_arbitrary'))
then
2956 call mt_write_qperp_arbitrary_header(csv_file, &
2957 'mt_qperp_plane_arbitrary')
2961 call mt_build_arbitrary_plane_seeds(origin,e1,e2,s1min,s1max,n1, &
2962 s2min,s2max,n2,seeds,s1,s2)
2965 allocate(results(nseed))
2966 if (
present(b_min))
then
2967 call trace_field_qperp_multi(seeds,nseed,dl,max_steps,results,b_min)
2969 call trace_field_qperp_multi(seeds,nseed,dl,max_steps,results)
2971 call mt_write_qperp_arbitrary_csv(results,s1,s2,n1,n2,csv_file, &
2972 'mt_qperp_plane_arbitrary')
2974 deallocate(seeds,s1,s2,results)
2978 s1max,n1,s2min,s2max,n2,dL,max_steps,csv_file,b_min, &
2979 compute_length,compute_twist,compute_q,compute_qperp,vtu_file, &
2982 integer,
intent(in) :: n1,n2,max_steps
2983 double precision,
intent(in) :: origin(ndim),e1(ndim),e2(ndim)
2984 double precision,
intent(in) :: s1min,s1max,s2min,s2max,dl
2985 character(len=*),
intent(in) :: csv_file
2986 double precision,
intent(in),
optional :: b_min
2987 logical,
intent(in),
optional :: compute_length,compute_twist
2988 logical,
intent(in),
optional :: compute_q,compute_qperp
2989 character(len=*),
intent(in),
optional :: vtu_file
2990 logical,
intent(in),
optional :: write_csv
2992 type(trace_length_result),
allocatable :: length_results(:)
2993 type(trace_twist_result),
allocatable :: twist_results(:)
2994 type(trace_qperp_result),
allocatable :: q_results(:)
2995 type(trace_qperp_result),
allocatable :: qperp_results(:)
2996 double precision,
allocatable :: seeds(:,:),s1(:),s2(:)
2998 logical :: do_length,do_twist,do_q,do_qperp,do_csv
3005 if (
present(compute_length)) do_length=compute_length
3006 if (
present(compute_twist)) do_twist=compute_twist
3007 if (
present(compute_q)) do_q=compute_q
3008 if (
present(compute_qperp)) do_qperp=compute_qperp
3009 if (
present(write_csv)) do_csv=write_csv
3011 if (.not.mt_validate_arbitrary_plane_basis(e1,e2,s1min,s1max,n1, &
3012 s2min,s2max,n2,
'mt_fieldline_products_plane_arbitrary'))
then
3014 call mt_write_fieldline_products_plane_arbitrary_header(csv_file, &
3015 'mt_fieldline_products_plane_arbitrary',do_twist,do_q,do_qperp)
3017 if (
present(vtu_file))
then
3018 if (len_trim(vtu_file)>0)
then
3019 call mt_write_fieldline_products_vtu_empty(vtu_file,do_twist, &
3020 do_q,do_qperp,
'mt_fieldline_products_plane_arbitrary', &
3021 do_length=do_length)
3026 call mt_require_requested_science(do_length,do_twist,do_q,do_qperp, &
3027 'mt_fieldline_products_plane_arbitrary')
3029 call mt_build_arbitrary_plane_seeds(origin,e1,e2,s1min,s1max,n1, &
3030 s2min,s2max,n2,seeds,s1,s2)
3033 allocate(length_results(nseed))
3035 allocate(twist_results(nseed))
3037 allocate(twist_results(0))
3040 allocate(q_results(nseed))
3042 allocate(q_results(0))
3045 allocate(qperp_results(nseed))
3047 allocate(qperp_results(0))
3050 if (
present(b_min))
then
3051 call mt_trace_fieldline_products_seedset(seeds,nseed,dl,max_steps, &
3052 length_results,twist_results,q_results,qperp_results,do_twist, &
3053 do_q,do_qperp,b_min)
3055 call mt_trace_fieldline_products_seedset(seeds,nseed,dl,max_steps, &
3056 length_results,twist_results,q_results,qperp_results,do_twist, &
3061 call mt_write_fieldline_products_plane_arbitrary_csv(length_results, &
3062 twist_results,q_results,qperp_results,s1,s2,n1,n2,csv_file, &
3063 do_twist,do_q,do_qperp,
'mt_fieldline_products_plane_arbitrary')
3065 if (
present(vtu_file))
then
3066 if (len_trim(vtu_file)>0)
then
3067 call mt_write_fieldline_products_vtu_plane(vtu_file, &
3068 length_results,twist_results,q_results,qperp_results,n1,n2, &
3069 do_twist,do_q,do_qperp,
'mt_fieldline_products_plane_arbitrary', &
3070 do_length=do_length)
3074 deallocate(qperp_results,q_results,twist_results,length_results,seeds,s1,s2)
3078 max_steps,length_csv,twist_csv,mapping_csv,b_min)
3080 integer,
intent(in) :: nx,ny,max_steps
3081 double precision,
intent(in) :: xmin,xmax,ymin,ymax,z0,dl
3082 character(len=*),
intent(in) :: length_csv,twist_csv,mapping_csv
3083 double precision,
intent(in),
optional :: b_min
3085 if (
present(b_min))
then
3086 call mt_topology_plane_axis(xmin,xmax,nx,ymin,ymax,ny,z0,1,2,3, &
3087 dl,max_steps,length_csv,twist_csv,mapping_csv, &
3088 'mt_topology_plane_xy',
'ix,iy',
'ix,iy',b_min)
3090 call mt_topology_plane_axis(xmin,xmax,nx,ymin,ymax,ny,z0,1,2,3, &
3091 dl,max_steps,length_csv,twist_csv,mapping_csv, &
3092 'mt_topology_plane_xy',
'ix,iy',
'ix,iy')
3097 max_steps,length_csv,twist_csv,mapping_csv,b_min)
3099 integer,
intent(in) :: nx,nz,max_steps
3100 double precision,
intent(in) :: xmin,xmax,zmin,zmax,y0,dl
3101 character(len=*),
intent(in) :: length_csv,twist_csv,mapping_csv
3102 double precision,
intent(in),
optional :: b_min
3104 if (
present(b_min))
then
3105 call mt_topology_plane_axis(xmin,xmax,nx,zmin,zmax,nz,y0,1,3,2, &
3106 dl,max_steps,length_csv,twist_csv,mapping_csv, &
3107 'mt_topology_plane_xz',
'ix,iz',
'i,j',b_min)
3109 call mt_topology_plane_axis(xmin,xmax,nx,zmin,zmax,nz,y0,1,3,2, &
3110 dl,max_steps,length_csv,twist_csv,mapping_csv, &
3111 'mt_topology_plane_xz',
'ix,iz',
'i,j')
3116 max_steps,length_csv,twist_csv,mapping_csv,b_min)
3118 integer,
intent(in) :: ny,nz,max_steps
3119 double precision,
intent(in) :: ymin,ymax,zmin,zmax,x0,dl
3120 character(len=*),
intent(in) :: length_csv,twist_csv,mapping_csv
3121 double precision,
intent(in),
optional :: b_min
3123 if (
present(b_min))
then
3124 call mt_topology_plane_axis(ymin,ymax,ny,zmin,zmax,nz,x0,2,3,1, &
3125 dl,max_steps,length_csv,twist_csv,mapping_csv, &
3126 'mt_topology_plane_yz',
'iy,iz',
'i,j',b_min)
3128 call mt_topology_plane_axis(ymin,ymax,ny,zmin,zmax,nz,x0,2,3,1, &
3129 dl,max_steps,length_csv,twist_csv,mapping_csv, &
3130 'mt_topology_plane_yz',
'iy,iz',
'i,j')
3135 max_steps,vtu_file,b_min)
3137 integer,
intent(in) :: nx,ny,max_steps
3138 double precision,
intent(in) :: xmin,xmax,ymin,ymax,z0,dl
3139 character(len=*),
intent(in) :: vtu_file
3140 double precision,
intent(in),
optional :: b_min
3142 if (
present(b_min))
then
3143 call mt_qsl_plane_vtu_axis(xmin,xmax,nx,ymin,ymax,ny,z0,1,2,3, &
3144 dl,max_steps,vtu_file,
'mt_qsl_plane_vtu_xy',b_min)
3146 call mt_qsl_plane_vtu_axis(xmin,xmax,nx,ymin,ymax,ny,z0,1,2,3, &
3147 dl,max_steps,vtu_file,
'mt_qsl_plane_vtu_xy')
3152 max_steps,vtu_file,b_min)
3154 integer,
intent(in) :: nx,nz,max_steps
3155 double precision,
intent(in) :: xmin,xmax,zmin,zmax,y0,dl
3156 character(len=*),
intent(in) :: vtu_file
3157 double precision,
intent(in),
optional :: b_min
3159 if (
present(b_min))
then
3160 call mt_qsl_plane_vtu_axis(xmin,xmax,nx,zmin,zmax,nz,y0,1,3,2, &
3161 dl,max_steps,vtu_file,
'mt_qsl_plane_vtu_xz',b_min)
3163 call mt_qsl_plane_vtu_axis(xmin,xmax,nx,zmin,zmax,nz,y0,1,3,2, &
3164 dl,max_steps,vtu_file,
'mt_qsl_plane_vtu_xz')
3169 max_steps,vtu_file,b_min)
3171 integer,
intent(in) :: ny,nz,max_steps
3172 double precision,
intent(in) :: ymin,ymax,zmin,zmax,x0,dl
3173 character(len=*),
intent(in) :: vtu_file
3174 double precision,
intent(in),
optional :: b_min
3176 if (
present(b_min))
then
3177 call mt_qsl_plane_vtu_axis(ymin,ymax,ny,zmin,zmax,nz,x0,2,3,1, &
3178 dl,max_steps,vtu_file,
'mt_qsl_plane_vtu_yz',b_min)
3180 call mt_qsl_plane_vtu_axis(ymin,ymax,ny,zmin,zmax,nz,x0,2,3,1, &
3181 dl,max_steps,vtu_file,
'mt_qsl_plane_vtu_yz')
3185 subroutine mt_qsl_plane_vti_xy(xmin,xmax,nx,ymin,ymax,ny,z0,dL, &
3186 max_steps,vti_file,do_length,do_twist,do_q,do_qperp,b_min)
3188 integer,
intent(in) :: nx,ny,max_steps
3189 double precision,
intent(in) :: xmin,xmax,ymin,ymax,z0,dl
3190 character(len=*),
intent(in) :: vti_file
3191 logical,
intent(in) :: do_length,do_twist,do_q,do_qperp
3192 double precision,
intent(in),
optional :: b_min
3194 if (
present(b_min))
then
3195 call mt_qsl_plane_vti_axis(xmin,xmax,nx,ymin,ymax,ny,z0, &
3196 1,2,3,dl,max_steps,vti_file,do_twist,do_q,do_qperp, &
3197 'mt_qsl_plane_vti_xy',b_min,do_length=do_length)
3199 call mt_qsl_plane_vti_axis(xmin,xmax,nx,ymin,ymax,ny,z0, &
3200 1,2,3,dl,max_steps,vti_file,do_twist,do_q,do_qperp, &
3201 'mt_qsl_plane_vti_xy',do_length=do_length)
3203 end subroutine mt_qsl_plane_vti_xy
3205 subroutine mt_qsl_plane_vti_xz(xmin,xmax,nx,zmin,zmax,nz,y0,dL, &
3206 max_steps,vti_file,do_length,do_twist,do_q,do_qperp,b_min)
3208 integer,
intent(in) :: nx,nz,max_steps
3209 double precision,
intent(in) :: xmin,xmax,zmin,zmax,y0,dl
3210 character(len=*),
intent(in) :: vti_file
3211 logical,
intent(in) :: do_length,do_twist,do_q,do_qperp
3212 double precision,
intent(in),
optional :: b_min
3214 if (
present(b_min))
then
3215 call mt_qsl_plane_vti_axis(xmin,xmax,nx,zmin,zmax,nz,y0, &
3216 1,3,2,dl,max_steps,vti_file,do_twist,do_q,do_qperp, &
3217 'mt_qsl_plane_vti_xz',b_min,do_length=do_length)
3219 call mt_qsl_plane_vti_axis(xmin,xmax,nx,zmin,zmax,nz,y0, &
3220 1,3,2,dl,max_steps,vti_file,do_twist,do_q,do_qperp, &
3221 'mt_qsl_plane_vti_xz',do_length=do_length)
3223 end subroutine mt_qsl_plane_vti_xz
3225 subroutine mt_qsl_plane_vti_yz(ymin,ymax,ny,zmin,zmax,nz,x0,dL, &
3226 max_steps,vti_file,do_length,do_twist,do_q,do_qperp,b_min)
3228 integer,
intent(in) :: ny,nz,max_steps
3229 double precision,
intent(in) :: ymin,ymax,zmin,zmax,x0,dl
3230 character(len=*),
intent(in) :: vti_file
3231 logical,
intent(in) :: do_length,do_twist,do_q,do_qperp
3232 double precision,
intent(in),
optional :: b_min
3234 if (
present(b_min))
then
3235 call mt_qsl_plane_vti_axis(ymin,ymax,ny,zmin,zmax,nz,x0, &
3236 2,3,1,dl,max_steps,vti_file,do_twist,do_q,do_qperp, &
3237 'mt_qsl_plane_vti_yz',b_min,do_length=do_length)
3239 call mt_qsl_plane_vti_axis(ymin,ymax,ny,zmin,zmax,nz,x0, &
3240 2,3,1,dl,max_steps,vti_file,do_twist,do_q,do_qperp, &
3241 'mt_qsl_plane_vti_yz',do_length=do_length)
3243 end subroutine mt_qsl_plane_vti_yz
3246 ymin,ymax,ny,zmin,zmax,nz,length_total,qperp,status)
3250 character(len=*),
intent(in) :: vti_file
3251 integer,
intent(in) :: nx,ny,nz
3252 double precision,
intent(in) :: xmin,xmax,ymin,ymax,zmin,zmax
3253 double precision,
intent(in) :: length_total(:),qperp(:)
3254 integer,
intent(in) :: status(:)
3257 double precision :: origin(3),spacing(3)
3259 if (len_trim(vti_file)==0)
then
3260 call mpistop(
'mt_write_cartesian_vti_pointdata requires a VTI file')
3262 if (nx<=0 .or. ny<=0 .or. nz<=0)
then
3263 call mpistop(
'mt_write_cartesian_vti_pointdata requires positive dimensions')
3267 if (
size(length_total)/=npoint .or.
size(qperp)/=npoint .or. &
3268 size(status)/=npoint)
then
3269 call mpistop(
'mt_write_cartesian_vti_pointdata array size mismatch')
3272 origin=(/ xmin,ymin,zmin /)
3273 spacing(1)=mt_vti_axis_spacing(xmin,xmax,nx)
3274 spacing(2)=mt_vti_axis_spacing(ymin,ymax,ny)
3275 spacing(3)=mt_vti_axis_spacing(zmin,zmax,nz)
3276 call mt_write_vti_pointdata_fixed(vti_file,origin,spacing,nx,ny,nz, &
3277 length_total,qperp,status,
'mt_write_cartesian_vti_pointdata')
3281 ymin,ymax,ny,zmin,zmax,nz,dL,max_steps,vti_file,b_min, &
3282 compute_length,compute_twist,compute_q,compute_qperp,chunk_nz)
3285 integer,
intent(in) :: nx,ny,nz,max_steps
3286 double precision,
intent(in) :: xmin,xmax,ymin,ymax,zmin,zmax,dl
3287 character(len=*),
intent(in) :: vti_file
3288 double precision,
intent(in),
optional :: b_min
3289 logical,
intent(in),
optional :: compute_length,compute_twist
3290 logical,
intent(in),
optional :: compute_q,compute_qperp
3291 integer,
intent(in),
optional :: chunk_nz
3293 type(trace_length_result),
allocatable :: length_slab(:)
3294 type(trace_twist_result),
allocatable :: twist_slab(:)
3295 type(trace_qperp_result),
allocatable :: q_slab(:)
3296 type(trace_qperp_result),
allocatable :: qperp_slab(:)
3297 type(mt_volume_products) :: products
3298 double precision,
allocatable :: seeds_slab(:,:)
3299 double precision :: origin(3),spacing(3)
3300 integer :: k_start,k_end,slab_nz,slab_nseed,nseed
3301 integer :: chunk_nz_eff
3302 integer(kind=8) :: nseed64
3303 logical :: do_length,do_twist,do_q,do_qperp
3305 if (len_trim(vti_file)==0)
then
3306 call mpistop(
'mt_fieldline_products_volume_vti requires a VTI file')
3309 call mpistop(
'mt_fieldline_products_volume_vti currently requires npe=1')
3312 call mpistop(
'mt_fieldline_products_volume_vti requires 3D Cartesian geometry')
3315 select case (geo_coordinate)
3316 case (geo_cartesian)
3319 case (geo_cartesian_stretched)
3321 call mpistop(
'volume_vti requires Cartesian geometry')
3324 if (nx<=0 .or. ny<=0 .or. nz<=0)
then
3325 call mpistop(
'mt_fieldline_products_volume_vti requires positive dimensions')
3327 if (xmax<xmin .or. ymax<ymin .or. zmax<zmin)
then
3328 call mpistop(
'mt_fieldline_products_volume_vti requires ordered bounds')
3331 nseed64=int(nx,kind=8)*int(ny,kind=8)*int(nz,kind=8)
3332 if (nseed64>int(huge(nseed),kind=8))
then
3333 call mpistop(
'mt_fieldline_products_volume_vti seed count overflows integer')
3335 if (nseed64>1000000_8)
then
3336 write(*,
'(a,i0,a)') &
3337 'mt_fieldline_products_volume_vti warning: volume has ', &
3338 nseed64,
' seeds; final VTI arrays still scale with nseed'
3346 if (
present(compute_length)) do_length=compute_length
3347 if (
present(compute_twist)) do_twist=compute_twist
3348 if (
present(compute_q)) do_q=compute_q
3349 if (
present(compute_qperp)) do_qperp=compute_qperp
3350 call mt_require_requested_science(do_length,do_twist,do_q,do_qperp, &
3351 'mt_fieldline_products_volume_vti')
3354 if (
present(chunk_nz)) chunk_nz_eff=max(1,min(nz,chunk_nz))
3356 origin=(/ xmin,ymin,zmin /)
3357 spacing(1)=mt_vti_axis_spacing(xmin,xmax,nx)
3358 spacing(2)=mt_vti_axis_spacing(ymin,ymax,ny)
3359 spacing(3)=mt_vti_axis_spacing(zmin,zmax,nz)
3361 call mt_allocate_volume_products(products,nseed,do_twist,do_q,do_qperp)
3363 do k_start=1,nz,chunk_nz_eff
3364 k_end=min(nz,k_start+chunk_nz_eff-1)
3365 slab_nz=k_end-k_start+1
3366 slab_nseed=nx*ny*slab_nz
3368 allocate(seeds_slab(slab_nseed,ndim))
3369 call mt_build_volume_slab_seeds(seeds_slab,xmin,ymin,zmin, &
3370 spacing,nx,ny,k_start,slab_nz)
3372 allocate(length_slab(slab_nseed))
3374 allocate(twist_slab(slab_nseed))
3376 allocate(twist_slab(0))
3379 allocate(q_slab(slab_nseed))
3385 allocate(qperp_slab(slab_nseed))
3387 allocate(qperp_slab(0))
3390 if (
present(b_min))
then
3391 call mt_trace_fieldline_products_seedset(seeds_slab,slab_nseed, &
3392 dl,max_steps,length_slab,twist_slab,q_slab,qperp_slab, &
3393 do_twist,do_q,do_qperp,b_min)
3395 call mt_trace_fieldline_products_seedset(seeds_slab,slab_nseed, &
3396 dl,max_steps,length_slab,twist_slab,q_slab,qperp_slab, &
3397 do_twist,do_q,do_qperp)
3400 call mt_copy_volume_length_slab(products,length_slab,nx,ny, &
3402 deallocate(length_slab)
3405 call mt_copy_volume_twist_slab(products,twist_slab,nx,ny, &
3408 deallocate(twist_slab)
3411 call mt_copy_volume_q_slab(products,q_slab,nx,ny,k_start,slab_nz)
3416 call mt_copy_volume_qperp_slab(products,qperp_slab,nx,ny, &
3419 deallocate(qperp_slab)
3421 deallocate(seeds_slab)
3424 call mt_write_fieldline_products_volume_vti(vti_file,origin,spacing, &
3425 nx,ny,nz,products, &
3426 do_length,do_twist,do_q,do_qperp,
'mt_fieldline_products_volume_vti')
3427 call mt_deallocate_volume_products(products)
3430 subroutine mt_trace_fieldline_products_seedset(seeds,nseed,dL,max_steps, &
3431 length_results,twist_results,q_results,qperp_results,do_twist, &
3432 do_q,do_qperp,b_min)
3433 integer,
intent(in) :: nseed,max_steps
3434 double precision,
intent(in) :: seeds(nseed,ndim),dl
3435 type(trace_length_result),
intent(out) :: length_results(nseed)
3436 type(trace_twist_result),
intent(out) :: twist_results(:)
3437 type(trace_qperp_result),
intent(out) :: q_results(:)
3438 type(trace_qperp_result),
intent(out) :: qperp_results(:)
3439 logical,
intent(in) :: do_twist,do_q,do_qperp
3440 double precision,
intent(in),
optional :: b_min
3442 type(trace_topology_result) :: topology_one(1)
3443 double precision :: seed_local(ndim),seed_one(1,ndim)
3445 character(len=mt_task_name_len) :: integrator
3447 integrator=mt_lowercase(trim(mt_trace_integrator))
3448 if (do_q .and. do_qperp .and. geo_coordinate==geo_spherical .and. &
3449 (integrator==
'rk2' .or. integrator==
'rk45_spherical'))
then
3451 if (
present(b_min))
then
3452 call trace_field_spherical_rmin_q_qperp_multi(seeds,nseed,dl, &
3453 max_steps,q_results,qperp_results,b_min, &
3454 twist_results=twist_results)
3456 call trace_field_spherical_rmin_q_qperp_multi(seeds,nseed,dl, &
3457 max_steps,q_results,qperp_results, &
3458 twist_results=twist_results)
3461 if (
present(b_min))
then
3462 call trace_field_spherical_rmin_q_qperp_multi(seeds,nseed,dl, &
3463 max_steps,q_results,qperp_results,b_min)
3465 call trace_field_spherical_rmin_q_qperp_multi(seeds,nseed,dl, &
3466 max_steps,q_results,qperp_results)
3469 call mt_q0_trace_to_length(q_results,nseed,length_results)
3473 if (do_q .and. do_qperp .and. geo_coordinate/=geo_spherical .and. &
3474 (integrator==
'rk2' .or. integrator==
'rk45_cartesian'))
then
3476 if (
present(b_min))
then
3477 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
3478 qperp_results,b_min,twist_results=twist_results)
3480 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
3481 qperp_results,twist_results=twist_results)
3484 if (
present(b_min))
then
3485 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
3486 qperp_results,b_min)
3488 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
3492 q_results=qperp_results
3493 call mt_qperp_trace_to_length(qperp_results,nseed,length_results)
3497 if (do_qperp .and. .not.do_q .and. &
3498 (integrator==
'rk2' .or. &
3499 (integrator==
'rk45_cartesian' .and. geo_coordinate/=geo_spherical) &
3500 .or. (integrator==
'rk45_spherical' .and. &
3501 geo_coordinate==geo_spherical)))
then
3502 select case (geo_coordinate)
3503 case (geo_spherical)
3505 if (
present(b_min))
then
3506 call trace_field_spherical_qperp_multi(seeds,nseed,dl,max_steps, &
3507 qperp_results,b_min,twist_results=twist_results)
3509 call trace_field_spherical_qperp_multi(seeds,nseed,dl,max_steps, &
3510 qperp_results,twist_results=twist_results)
3513 if (
present(b_min))
then
3514 call trace_field_spherical_qperp_multi(seeds,nseed,dl,max_steps, &
3515 qperp_results,b_min)
3517 call trace_field_spherical_qperp_multi(seeds,nseed,dl,max_steps, &
3523 if (
present(b_min))
then
3524 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
3525 qperp_results,b_min,twist_results=twist_results)
3527 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
3528 qperp_results,twist_results=twist_results)
3531 if (
present(b_min))
then
3532 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
3533 qperp_results,b_min)
3535 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
3540 call mt_qperp_trace_to_length(qperp_results,nseed,length_results)
3544 if (do_q .and. .not.do_qperp .and. geo_coordinate==geo_spherical .and. &
3545 (integrator==
'rk2' .or. integrator==
'rk45_spherical'))
then
3547 if (
present(b_min))
then
3548 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl,max_steps, &
3549 q_results,b_min,twist_results=twist_results)
3551 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl,max_steps, &
3552 q_results,twist_results=twist_results)
3555 if (
present(b_min))
then
3556 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl,max_steps, &
3559 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl,max_steps, &
3563 call mt_q0_trace_to_length(q_results,nseed,length_results)
3567 if (do_q .and. .not.do_qperp .and. &
3568 (integrator==
'rk2' .or. &
3569 (integrator==
'rk45_cartesian' .and. geo_coordinate/=geo_spherical) &
3570 .or. (integrator==
'rk45_spherical' .and. &
3571 geo_coordinate==geo_spherical)))
then
3572 if (integrator==
'rk2')
then
3573 if (geo_coordinate==geo_cartesian_stretched .or. &
3574 (geo_coordinate==geo_cartesian .and. .not.slab_uniform))
then
3576 if (
present(b_min))
then
3577 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
3578 q_results,b_min,twist_results=twist_results)
3580 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
3581 q_results,twist_results=twist_results)
3584 if (
present(b_min))
then
3585 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
3588 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
3594 if (
present(b_min))
then
3595 call trace_field_rk2_short_boundary_q_multi(seeds,nseed,dl, &
3596 max_steps,q_results,b_min,twist_results=twist_results)
3598 call trace_field_rk2_short_boundary_q_multi(seeds,nseed,dl, &
3599 max_steps,q_results,twist_results=twist_results)
3602 if (
present(b_min))
then
3603 call trace_field_rk2_short_boundary_q_multi(seeds,nseed,dl, &
3604 max_steps,q_results,b_min)
3606 call trace_field_rk2_short_boundary_q_multi(seeds,nseed,dl, &
3607 max_steps,q_results)
3611 else if (integrator==
'rk45_cartesian')
then
3613 if (
present(b_min))
then
3614 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
3615 q_results,b_min,twist_results=twist_results)
3617 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
3618 q_results,twist_results=twist_results)
3621 if (
present(b_min))
then
3622 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
3625 call trace_field_qperp_multi(seeds,nseed,dl,max_steps,q_results)
3630 if (
present(b_min))
then
3631 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl, &
3632 max_steps,q_results,b_min,twist_results=twist_results)
3634 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl, &
3635 max_steps,q_results,twist_results=twist_results)
3638 if (
present(b_min))
then
3639 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl, &
3640 max_steps,q_results,b_min)
3642 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl, &
3643 max_steps,q_results)
3647 call mt_q0_trace_to_length(q_results,nseed,length_results)
3651 if (
present(b_min))
then
3654 seed_local=seeds(iseed,:)
3656 seed_one(1,:)=seed_local
3657 call trace_field_topology_multi(seed_one,1,dl,max_steps, &
3658 topology_one,need_twist=.true.,need_mapping=.false., &
3660 call mt_topology_to_length(topology_one,1, &
3661 length_results(iseed:iseed))
3662 call mt_topology_to_twist(topology_one,1, &
3663 twist_results(iseed:iseed))
3665 call trace_field_length_single(seed_local,dl,max_steps, &
3666 length_results(iseed),b_min)
3669 call trace_field_qperp_single(seed_local,dl,max_steps, &
3670 qperp_results(iseed),b_min)
3677 seed_local=seeds(iseed,:)
3679 seed_one(1,:)=seed_local
3680 call trace_field_topology_multi(seed_one,1,dl,max_steps, &
3681 topology_one,need_twist=.true.,need_mapping=.false.)
3682 call mt_topology_to_length(topology_one,1, &
3683 length_results(iseed:iseed))
3684 call mt_topology_to_twist(topology_one,1, &
3685 twist_results(iseed:iseed))
3687 call trace_field_length_single(seed_local,dl,max_steps, &
3688 length_results(iseed))
3691 call trace_field_qperp_single(seed_local,dl,max_steps, &
3692 qperp_results(iseed))
3699 if (mt_lowercase(trim(mt_trace_integrator))==
'rk45_cartesian')
then
3700 if (
present(b_min))
then
3701 call trace_field_qperp_multi(seeds,nseed,dl,max_steps,q_results, &
3704 call trace_field_qperp_multi(seeds,nseed,dl,max_steps,q_results)
3706 else if (geo_coordinate==geo_spherical)
then
3707 if (
present(b_min))
then
3708 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl, &
3709 max_steps,q_results,b_min)
3711 call trace_field_spherical_rmin_q_multi(seeds,nseed,dl, &
3712 max_steps,q_results)
3714 else if (do_qperp)
then
3715 q_results=qperp_results
3717 if (
present(b_min))
then
3718 call trace_field_qperp_multi(seeds,nseed,dl,max_steps,q_results, &
3721 call trace_field_qperp_multi(seeds,nseed,dl,max_steps,q_results)
3725 end subroutine mt_trace_fieldline_products_seedset
3729 double precision,
intent(in) :: seed(ndim),dl
3730 integer,
intent(in) :: max_steps
3731 character(len=*),
intent(in) :: csv_file
3732 double precision,
intent(in),
optional :: b_min
3734 type(trace_twist_result) :: result
3735 double precision :: seed_xyz(3)
3736 integer :: csv_unit,io_status
3739 call mpistop(
'mt_twist_single currently requires npe=1')
3741 if (ndim/=3 .or. .not.slab_uniform)
then
3742 call mpistop(
'mt_twist_single requires 3D uniform Cartesian geometry')
3745 if (
present(b_min))
then
3746 call trace_field_twist_single(seed,dl,max_steps,result,b_min)
3748 call trace_field_twist_single(seed,dl,max_steps,result)
3752 seed_xyz(1:ndim)=result%line%seed
3754 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
3755 action=
'write',form=
'formatted',iostat=io_status)
3756 if (io_status/=0)
then
3757 call mpistop(
'mt_twist_single could not open CSV file')
3760 write(csv_unit,
'(a)',iostat=io_status) &
3761 'seed_id,seed_x,seed_y,seed_z,'// &
3762 'length_total,length_backward,length_forward,'// &
3763 'twist_total,twist_backward,twist_forward,'// &
3764 'nstep_backward,nstep_forward,'// &
3765 'status_backward,status_forward'
3766 if (io_status/=0)
then
3768 call mpistop(
'mt_twist_single could not write CSV header')
3771 write(csv_unit,
'(i0,9(",",es24.16),4(",",i0))',iostat=io_status) &
3772 1,seed_xyz,result%line%total_length, &
3773 result%line%backward_length,result%line%forward_length, &
3774 result%total_twist,result%backward_twist,result%forward_twist, &
3775 result%line%backward_nstep,result%line%forward_nstep, &
3776 result%line%backward_status,result%line%forward_status
3777 if (io_status/=0)
then
3779 call mpistop(
'mt_twist_single could not write CSV data')
3787 integer,
intent(in) :: nseed,max_steps
3788 double precision,
intent(in) :: seeds(nseed,ndim),dl
3789 character(len=*),
intent(in) :: csv_file
3790 double precision,
intent(in),
optional :: b_min
3792 type(trace_twist_result),
allocatable :: results(:)
3793 double precision :: seed_xyz(3)
3794 integer :: csv_unit,io_status,iseed
3797 call mpistop(
'mt_twist_seeds currently requires npe=1')
3799 if (ndim/=3 .or. .not.slab_uniform)
then
3800 call mpistop(
'mt_twist_seeds requires 3D uniform Cartesian geometry')
3803 call mpistop(
'mt_twist_seeds requires nseed>=0')
3806 allocate(results(nseed))
3807 if (
present(b_min))
then
3808 call trace_field_twist_multi(seeds,nseed,dl,max_steps,results,b_min)
3810 call trace_field_twist_multi(seeds,nseed,dl,max_steps,results)
3813 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
3814 action=
'write',form=
'formatted',iostat=io_status)
3815 if (io_status/=0)
then
3817 call mpistop(
'mt_twist_seeds could not open CSV file')
3820 write(csv_unit,
'(a)',iostat=io_status) &
3821 'seed_id,seed_x,seed_y,seed_z,'// &
3822 'length_total,length_backward,length_forward,'// &
3823 'twist_total,twist_backward,twist_forward,'// &
3824 'nstep_backward,nstep_forward,'// &
3825 'status_backward,status_forward'
3826 if (io_status/=0)
then
3829 call mpistop(
'mt_twist_seeds could not write CSV header')
3834 seed_xyz(1:ndim)=results(iseed)%line%seed
3835 write(csv_unit,
'(i0,9(",",es24.16),4(",",i0))',iostat=io_status) &
3836 iseed,seed_xyz,results(iseed)%line%total_length, &
3837 results(iseed)%line%backward_length, &
3838 results(iseed)%line%forward_length, &
3839 results(iseed)%total_twist,results(iseed)%backward_twist, &
3840 results(iseed)%forward_twist, &
3841 results(iseed)%line%backward_nstep, &
3842 results(iseed)%line%forward_nstep, &
3843 results(iseed)%line%backward_status, &
3844 results(iseed)%line%forward_status
3845 if (io_status/=0)
then
3848 call mpistop(
'mt_twist_seeds could not write CSV data')
3857 max_steps,csv_file,b_min)
3859 integer,
intent(in) :: nx,ny,max_steps
3860 double precision,
intent(in) :: xmin,xmax,ymin,ymax,z0,dl
3861 character(len=*),
intent(in) :: csv_file
3862 double precision,
intent(in),
optional :: b_min
3864 if (
present(b_min))
then
3865 call mt_twist_plane_axis(xmin,xmax,nx,ymin,ymax,ny,z0,1,2,3, &
3866 dl,max_steps,csv_file,
'mt_twist_plane_xy',
'ix,iy',b_min)
3868 call mt_twist_plane_axis(xmin,xmax,nx,ymin,ymax,ny,z0,1,2,3, &
3869 dl,max_steps,csv_file,
'mt_twist_plane_xy',
'ix,iy')
3874 max_steps,csv_file,b_min)
3875 integer,
intent(in) :: nx,nz,max_steps
3876 double precision,
intent(in) :: xmin,xmax,zmin,zmax,y0,dl
3877 character(len=*),
intent(in) :: csv_file
3878 double precision,
intent(in),
optional :: b_min
3880 if (
present(b_min))
then
3881 call mt_length_plane_axis(xmin,xmax,nx,zmin,zmax,nz,y0,1,3,2, &
3882 dl,max_steps,csv_file,
'mt_length_plane_xz',
'i,j',b_min)
3884 call mt_length_plane_axis(xmin,xmax,nx,zmin,zmax,nz,y0,1,3,2, &
3885 dl,max_steps,csv_file,
'mt_length_plane_xz',
'i,j')
3890 max_steps,csv_file,b_min)
3891 integer,
intent(in) :: ny,nz,max_steps
3892 double precision,
intent(in) :: ymin,ymax,zmin,zmax,x0,dl
3893 character(len=*),
intent(in) :: csv_file
3894 double precision,
intent(in),
optional :: b_min
3896 if (
present(b_min))
then
3897 call mt_length_plane_axis(ymin,ymax,ny,zmin,zmax,nz,x0,2,3,1, &
3898 dl,max_steps,csv_file,
'mt_length_plane_yz',
'i,j',b_min)
3900 call mt_length_plane_axis(ymin,ymax,ny,zmin,zmax,nz,x0,2,3,1, &
3901 dl,max_steps,csv_file,
'mt_length_plane_yz',
'i,j')
3906 max_steps,csv_file,b_min)
3907 integer,
intent(in) :: nx,nz,max_steps
3908 double precision,
intent(in) :: xmin,xmax,zmin,zmax,y0,dl
3909 character(len=*),
intent(in) :: csv_file
3910 double precision,
intent(in),
optional :: b_min
3912 if (
present(b_min))
then
3913 call mt_twist_plane_axis(xmin,xmax,nx,zmin,zmax,nz,y0,1,3,2, &
3914 dl,max_steps,csv_file,
'mt_twist_plane_xz',
'i,j',b_min)
3916 call mt_twist_plane_axis(xmin,xmax,nx,zmin,zmax,nz,y0,1,3,2, &
3917 dl,max_steps,csv_file,
'mt_twist_plane_xz',
'i,j')
3922 max_steps,csv_file,b_min)
3923 integer,
intent(in) :: ny,nz,max_steps
3924 double precision,
intent(in) :: ymin,ymax,zmin,zmax,x0,dl
3925 character(len=*),
intent(in) :: csv_file
3926 double precision,
intent(in),
optional :: b_min
3928 if (
present(b_min))
then
3929 call mt_twist_plane_axis(ymin,ymax,ny,zmin,zmax,nz,x0,2,3,1, &
3930 dl,max_steps,csv_file,
'mt_twist_plane_yz',
'i,j',b_min)
3932 call mt_twist_plane_axis(ymin,ymax,ny,zmin,zmax,nz,x0,2,3,1, &
3933 dl,max_steps,csv_file,
'mt_twist_plane_yz',
'i,j')
3937 subroutine mt_length_plane_axis(c1min,c1max,n1,c2min,c2max,n2, &
3938 fixed_value,axis1,axis2,fixed_axis,dL,max_steps,csv_file, &
3939 caller,index_header,b_min)
3940 integer,
intent(in) :: n1,n2,axis1,axis2,fixed_axis,max_steps
3941 double precision,
intent(in) :: c1min,c1max,c2min,c2max
3942 double precision,
intent(in) :: fixed_value,dl
3943 character(len=*),
intent(in) :: csv_file,caller,index_header
3944 double precision,
intent(in),
optional :: b_min
3946 type(trace_length_result),
allocatable :: results(:)
3947 double precision,
allocatable :: seeds(:,:)
3950 call mt_validate_axis_plane(c1min,c1max,n1,c2min,c2max,n2,caller)
3951 call mt_build_axis_plane_seeds(c1min,c1max,n1,c2min,c2max,n2, &
3952 fixed_value,axis1,axis2,fixed_axis,seeds)
3955 allocate(results(nseed))
3956 if (
present(b_min))
then
3957 call trace_field_length_multi(seeds,nseed,dl,max_steps,results,b_min)
3959 call trace_field_length_multi(seeds,nseed,dl,max_steps,results)
3961 call mt_write_length_plane_csv(results,n1,n2,csv_file,caller, &
3964 deallocate(seeds,results)
3965 end subroutine mt_length_plane_axis
3967 subroutine mt_twist_plane_axis(c1min,c1max,n1,c2min,c2max,n2, &
3968 fixed_value,axis1,axis2,fixed_axis,dL,max_steps,csv_file, &
3969 caller,index_header,b_min)
3970 integer,
intent(in) :: n1,n2,axis1,axis2,fixed_axis,max_steps
3971 double precision,
intent(in) :: c1min,c1max,c2min,c2max
3972 double precision,
intent(in) :: fixed_value,dl
3973 character(len=*),
intent(in) :: csv_file,caller,index_header
3974 double precision,
intent(in),
optional :: b_min
3976 type(trace_twist_result),
allocatable :: results(:)
3977 double precision,
allocatable :: seeds(:,:)
3980 call mt_validate_axis_plane(c1min,c1max,n1,c2min,c2max,n2,caller)
3981 call mt_build_axis_plane_seeds(c1min,c1max,n1,c2min,c2max,n2, &
3982 fixed_value,axis1,axis2,fixed_axis,seeds)
3985 allocate(results(nseed))
3986 if (
present(b_min))
then
3987 call trace_field_twist_multi(seeds,nseed,dl,max_steps,results,b_min)
3989 call trace_field_twist_multi(seeds,nseed,dl,max_steps,results)
3991 call mt_write_twist_plane_csv(results,n1,n2,csv_file,caller, &
3994 deallocate(seeds,results)
3995 end subroutine mt_twist_plane_axis
3997 subroutine mt_q_plane_axis(c1min,c1max,n1,c2min,c2max,n2, &
3998 fixed_value,axis1,axis2,fixed_axis,dL,max_steps,csv_file,caller, &
4000 integer,
intent(in) :: n1,n2,axis1,axis2,fixed_axis,max_steps
4001 double precision,
intent(in) :: c1min,c1max,c2min,c2max
4002 double precision,
intent(in) :: fixed_value,dl
4003 character(len=*),
intent(in) :: csv_file,caller,index_header
4004 double precision,
intent(in),
optional :: b_min
4006 type(trace_qperp_result),
allocatable :: results(:)
4007 double precision,
allocatable :: seeds(:,:)
4010 call mt_validate_axis_plane(c1min,c1max,n1,c2min,c2max,n2,caller)
4011 call mt_build_axis_plane_seeds(c1min,c1max,n1,c2min,c2max,n2, &
4012 fixed_value,axis1,axis2,fixed_axis,seeds)
4015 allocate(results(nseed))
4016 if (
present(b_min))
then
4017 call trace_field_qperp_multi(seeds,nseed,dl,max_steps,results,b_min)
4019 call trace_field_qperp_multi(seeds,nseed,dl,max_steps,results)
4021 call mt_write_q_plane_csv(results,n1,n2,csv_file,caller,index_header)
4023 deallocate(seeds,results)
4024 end subroutine mt_q_plane_axis
4026 subroutine mt_qperp_plane_axis(c1min,c1max,n1,c2min,c2max,n2, &
4027 fixed_value,axis1,axis2,fixed_axis,dL,max_steps,csv_file, &
4028 caller,index_header,b_min)
4029 integer,
intent(in) :: n1,n2,axis1,axis2,fixed_axis,max_steps
4030 double precision,
intent(in) :: c1min,c1max,c2min,c2max
4031 double precision,
intent(in) :: fixed_value,dl
4032 character(len=*),
intent(in) :: csv_file,caller,index_header
4033 double precision,
intent(in),
optional :: b_min
4035 type(trace_qperp_result),
allocatable :: results(:)
4036 double precision,
allocatable :: seeds(:,:)
4039 call mt_validate_axis_plane(c1min,c1max,n1,c2min,c2max,n2,caller)
4040 call mt_build_axis_plane_seeds(c1min,c1max,n1,c2min,c2max,n2, &
4041 fixed_value,axis1,axis2,fixed_axis,seeds)
4044 allocate(results(nseed))
4045 if (
present(b_min))
then
4046 call trace_field_qperp_multi(seeds,nseed,dl,max_steps,results,b_min)
4048 call trace_field_qperp_multi(seeds,nseed,dl,max_steps,results)
4050 call mt_write_qperp_plane_csv(results,n1,n2,csv_file,caller, &
4053 deallocate(seeds,results)
4054 end subroutine mt_qperp_plane_axis
4056 subroutine mt_axis_plane_products_csv_axis(c1min,c1max,n1,c2min,c2max, &
4057 n2,fixed_value,axis1,axis2,fixed_axis,dL,max_steps,length_csv, &
4058 twist_csv,q_csv,qperp_csv,caller,index_header,length_index_header, &
4060 integer,
intent(in) :: n1,n2,axis1,axis2,fixed_axis,max_steps
4061 double precision,
intent(in) :: c1min,c1max,c2min,c2max
4062 double precision,
intent(in) :: fixed_value,dl
4063 character(len=*),
intent(in) :: length_csv,twist_csv,q_csv,qperp_csv
4064 character(len=*),
intent(in) :: caller,index_header,length_index_header
4065 double precision,
intent(in),
optional :: b_min
4067 type(trace_length_result),
allocatable :: length_results(:)
4068 type(trace_twist_result),
allocatable :: twist_results(:)
4069 type(trace_qperp_result),
allocatable :: q_results(:)
4070 type(trace_qperp_result),
allocatable :: qperp_results(:)
4071 double precision,
allocatable :: seeds(:,:)
4073 logical :: do_twist,do_q,do_qperp
4075 call mt_validate_axis_plane(c1min,c1max,n1,c2min,c2max,n2,caller)
4076 if (len_trim(length_csv)==0)
then
4077 call mpistop(trim(caller)//
' requires a length CSV file')
4080 do_twist=len_trim(twist_csv)>0
4081 do_q=len_trim(q_csv)>0
4082 do_qperp=len_trim(qperp_csv)>0
4084 call mt_build_axis_plane_seeds(c1min,c1max,n1,c2min,c2max,n2, &
4085 fixed_value,axis1,axis2,fixed_axis,seeds)
4087 allocate(length_results(nseed))
4089 allocate(twist_results(nseed))
4091 allocate(twist_results(0))
4094 allocate(q_results(nseed))
4096 allocate(q_results(0))
4099 allocate(qperp_results(nseed))
4101 allocate(qperp_results(0))
4104 if (
present(b_min))
then
4105 call mt_trace_fieldline_products_seedset(seeds,nseed,dl,max_steps, &
4106 length_results,twist_results,q_results,qperp_results, &
4107 do_twist,do_q,do_qperp,b_min)
4109 call mt_trace_fieldline_products_seedset(seeds,nseed,dl,max_steps, &
4110 length_results,twist_results,q_results,qperp_results, &
4111 do_twist,do_q,do_qperp)
4114 call mt_write_length_plane_csv(length_results,n1,n2,length_csv, &
4115 caller,length_index_header)
4117 call mt_write_twist_plane_csv(twist_results,n1,n2,twist_csv, &
4118 caller,length_index_header)
4121 call mt_write_q_plane_csv(q_results,n1,n2,q_csv,caller, &
4125 call mt_write_qperp_plane_csv(qperp_results,n1,n2,qperp_csv, &
4126 caller,index_header)
4129 deallocate(qperp_results,q_results,twist_results,length_results,seeds)
4130 end subroutine mt_axis_plane_products_csv_axis
4132 subroutine mt_topology_plane_axis(c1min,c1max,n1,c2min,c2max,n2, &
4133 fixed_value,axis1,axis2,fixed_axis,dL,max_steps,length_csv, &
4134 twist_csv,mapping_csv,caller,index_header,length_index_header, &
4136 integer,
intent(in) :: n1,n2,axis1,axis2,fixed_axis,max_steps
4137 double precision,
intent(in) :: c1min,c1max,c2min,c2max
4138 double precision,
intent(in) :: fixed_value,dl
4139 character(len=*),
intent(in) :: length_csv,twist_csv,mapping_csv
4140 character(len=*),
intent(in) :: caller,index_header,length_index_header
4141 double precision,
intent(in),
optional :: b_min
4143 type(trace_topology_result),
allocatable :: topology(:)
4144 type(trace_length_result),
allocatable :: length_results(:)
4145 type(trace_twist_result),
allocatable :: twist_results(:)
4146 type(trace_mapping_result),
allocatable :: mapping_results(:)
4147 double precision,
allocatable :: seeds(:,:)
4148 double precision :: source_normal(3)
4150 logical :: write_twist,write_mapping,need_mapping
4152 call mt_validate_axis_plane(c1min,c1max,n1,c2min,c2max,n2,caller)
4153 if (len_trim(length_csv)==0)
then
4154 call mpistop(trim(caller)//
' requires a length CSV file')
4157 write_twist=len_trim(twist_csv)>0
4158 write_mapping=len_trim(mapping_csv)>0
4159 need_mapping=write_mapping
4161 call mt_build_axis_plane_seeds(c1min,c1max,n1,c2min,c2max,n2, &
4162 fixed_value,axis1,axis2,fixed_axis,seeds)
4164 allocate(topology(nseed),length_results(nseed))
4166 source_normal(fixed_axis)=1.d0
4167 if (
present(b_min))
then
4168 call trace_field_topology_multi(seeds,nseed,dl,max_steps,topology, &
4169 need_twist=write_twist,need_mapping=need_mapping,b_min=b_min, &
4170 source_normal=source_normal)
4172 call trace_field_topology_multi(seeds,nseed,dl,max_steps,topology, &
4173 need_twist=write_twist,need_mapping=need_mapping, &
4174 source_normal=source_normal)
4177 call mt_topology_to_length(topology,nseed,length_results)
4178 call mt_write_length_plane_csv(length_results,n1,n2,length_csv, &
4179 caller,length_index_header)
4181 if (write_twist)
then
4182 allocate(twist_results(nseed))
4183 call mt_topology_to_twist(topology,nseed,twist_results)
4184 call mt_write_twist_plane_csv(twist_results,n1,n2,twist_csv, &
4185 caller,length_index_header)
4186 deallocate(twist_results)
4189 if (need_mapping)
then
4190 allocate(mapping_results(nseed))
4191 call mt_topology_to_mapping(topology,nseed,mapping_results)
4192 if (write_mapping)
then
4193 call mt_write_mapping_plane_csv(mapping_results,n1,n2,mapping_csv, &
4194 caller,index_header)
4196 deallocate(mapping_results)
4199 deallocate(length_results,topology,seeds)
4200 end subroutine mt_topology_plane_axis
4202 subroutine mt_qsl_plane_vtu_axis(c1min,c1max,n1,c2min,c2max,n2, &
4203 fixed_value,axis1,axis2,fixed_axis,dL,max_steps,vtu_file,caller, &
4205 integer,
intent(in) :: n1,n2,axis1,axis2,fixed_axis,max_steps
4206 double precision,
intent(in) :: c1min,c1max,c2min,c2max
4207 double precision,
intent(in) :: fixed_value,dl
4208 character(len=*),
intent(in) :: vtu_file,caller
4209 double precision,
intent(in),
optional :: b_min
4211 type(trace_length_result),
allocatable :: length_results(:)
4212 type(trace_twist_result),
allocatable :: twist_results(:)
4213 type(trace_mapping_result),
allocatable :: mapping_results(:)
4214 type(trace_qperp_result),
allocatable :: qperp_results(:)
4215 double precision,
allocatable :: seeds(:,:)
4216 double precision :: source_normal(3)
4218 logical :: need_mapping
4220 call mt_validate_axis_plane(c1min,c1max,n1,c2min,c2max,n2,caller)
4221 if (len_trim(vtu_file)==0)
then
4222 call mpistop(trim(caller)//
' requires a VTU file')
4225 call mt_build_axis_plane_seeds(c1min,c1max,n1,c2min,c2max,n2, &
4226 fixed_value,axis1,axis2,fixed_axis,seeds)
4228 allocate(length_results(nseed),twist_results(nseed), &
4229 mapping_results(nseed),qperp_results(nseed))
4232 source_normal(fixed_axis)=1.d0
4233 need_mapping=mt_vtk_detail_is_full()
4234 if (need_mapping)
then
4235 if (
present(b_min))
then
4236 call mt_trace_qsl_plane_full(seeds,nseed,dl,max_steps,source_normal, &
4237 qperp_results,twist_results,mapping_results,b_min)
4239 call mt_trace_qsl_plane_full(seeds,nseed,dl,max_steps,source_normal, &
4240 qperp_results,twist_results,mapping_results)
4242 call mt_qperp_trace_to_length(qperp_results,nseed,length_results)
4244 if (
present(b_min))
then
4245 call mt_trace_qsl_plane_minimal(seeds,nseed,dl,max_steps, &
4246 qperp_results,twist_results,b_min)
4248 call mt_trace_qsl_plane_minimal(seeds,nseed,dl,max_steps, &
4249 qperp_results,twist_results)
4251 call mt_qperp_trace_to_length(qperp_results,nseed,length_results)
4254 call mt_write_qsl_plane_vtu(vtu_file,length_results,twist_results, &
4255 mapping_results,qperp_results,n1,n2,caller)
4257 deallocate(qperp_results,mapping_results,twist_results, &
4258 length_results,seeds)
4259 end subroutine mt_qsl_plane_vtu_axis
4261 subroutine mt_qsl_plane_vti_axis(c1min,c1max,n1,c2min,c2max,n2, &
4262 fixed_value,axis1,axis2,fixed_axis,dL,max_steps,vti_file, &
4263 do_twist,do_q,do_qperp,caller,b_min,do_length)
4264 integer,
intent(in) :: n1,n2,axis1,axis2,fixed_axis,max_steps
4265 double precision,
intent(in) :: c1min,c1max,c2min,c2max
4266 double precision,
intent(in) :: fixed_value,dl
4267 character(len=*),
intent(in) :: vti_file,caller
4268 logical,
intent(in) :: do_twist,do_q,do_qperp
4269 double precision,
intent(in),
optional :: b_min
4270 logical,
intent(in),
optional :: do_length
4272 type(trace_length_result),
allocatable :: length_results(:)
4273 type(trace_twist_result),
allocatable :: twist_results(:)
4274 type(trace_qperp_result),
allocatable :: q_results(:)
4275 type(trace_qperp_result),
allocatable :: qperp_results(:)
4276 type(mt_volume_products) :: products
4277 double precision,
allocatable :: seeds(:,:)
4278 double precision :: origin(3),spacing(3)
4279 integer :: nseed,nx_vti,ny_vti,nz_vti
4280 logical :: do_length_eff
4282 call mt_validate_axis_plane(c1min,c1max,n1,c2min,c2max,n2,caller)
4283 if (len_trim(vti_file)==0)
then
4284 call mpistop(trim(caller)//
' requires a VTI file')
4286 do_length_eff=.true.
4287 if (
present(do_length)) do_length_eff=do_length
4288 call mt_require_requested_science(do_length_eff,do_twist,do_q,do_qperp, &
4291 call mt_build_axis_plane_seeds(c1min,c1max,n1,c2min,c2max,n2, &
4292 fixed_value,axis1,axis2,fixed_axis,seeds)
4295 allocate(length_results(nseed))
4297 allocate(twist_results(nseed))
4299 allocate(twist_results(0))
4302 allocate(q_results(nseed))
4304 allocate(q_results(0))
4307 allocate(qperp_results(nseed))
4309 allocate(qperp_results(0))
4312 if (
present(b_min))
then
4313 call mt_trace_fieldline_products_seedset(seeds,nseed,dl,max_steps, &
4314 length_results,twist_results,q_results,qperp_results,do_twist, &
4315 do_q,do_qperp,b_min)
4317 call mt_trace_fieldline_products_seedset(seeds,nseed,dl,max_steps, &
4318 length_results,twist_results,q_results,qperp_results,do_twist, &
4322 call mt_allocate_volume_products(products,nseed,do_twist,do_q,do_qperp)
4323 call mt_copy_volume_length_slab(products,length_results,nseed,1,1,1)
4324 if (do_twist)
call mt_copy_volume_twist_slab(products,twist_results, &
4326 if (do_q)
call mt_copy_volume_q_slab(products,q_results,nseed,1,1,1)
4327 if (do_qperp)
call mt_copy_volume_qperp_slab(products,qperp_results, &
4337 origin(fixed_axis)=fixed_value
4338 spacing(axis1)=mt_vti_axis_spacing(c1min,c1max,n1)
4339 spacing(axis2)=mt_vti_axis_spacing(c2min,c2max,n2)
4357 call mt_write_fieldline_products_volume_vti(vti_file,origin,spacing, &
4358 nx_vti,ny_vti,nz_vti,products,do_length_eff,do_twist,do_q, &
4361 call mt_deallocate_volume_products(products)
4362 deallocate(qperp_results,q_results,twist_results,length_results,seeds)
4363 end subroutine mt_qsl_plane_vti_axis
4365 subroutine mt_trace_qsl_plane_full(seeds,nseed,dL,max_steps,source_normal, &
4366 qperp_results,twist_results,mapping_results,b_min)
4367 integer,
intent(in) :: nseed,max_steps
4368 double precision,
intent(in) :: seeds(nseed,ndim),dl,source_normal(3)
4369 type(trace_qperp_result),
intent(out) :: qperp_results(nseed)
4370 type(trace_twist_result),
intent(out) :: twist_results(nseed)
4371 type(trace_mapping_result),
intent(out) :: mapping_results(nseed)
4372 double precision,
intent(in),
optional :: b_min
4374 double precision :: seed_local(ndim)
4377 if (
present(b_min))
then
4380 seed_local=seeds(iseed,:)
4381 call trace_field_mapping_single(seed_local,dl,max_steps, &
4382 mapping_results(iseed),b_min,source_normal)
4385 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
4386 qperp_results,b_min,twist_results=twist_results)
4390 seed_local=seeds(iseed,:)
4391 call trace_field_mapping_single(seed_local,dl,max_steps, &
4392 mapping_results(iseed),source_normal=source_normal)
4395 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
4396 qperp_results,twist_results=twist_results)
4398 end subroutine mt_trace_qsl_plane_full
4400 subroutine mt_trace_qsl_plane_minimal(seeds,nseed,dL,max_steps, &
4401 qperp_results,twist_results,b_min)
4402 integer,
intent(in) :: nseed,max_steps
4403 double precision,
intent(in) :: seeds(nseed,ndim),dl
4404 type(trace_qperp_result),
intent(out) :: qperp_results(nseed)
4405 type(trace_twist_result),
intent(out) :: twist_results(nseed)
4406 double precision,
intent(in),
optional :: b_min
4408 if (
present(b_min))
then
4409 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
4410 qperp_results,b_min,twist_results=twist_results)
4412 call trace_field_qperp_multi(seeds,nseed,dl,max_steps, &
4413 qperp_results,twist_results=twist_results)
4415 end subroutine mt_trace_qsl_plane_minimal
4417 subroutine mt_qperp_to_length(qperp_results,nseed,results)
4418 integer,
intent(in) :: nseed
4419 type(trace_qperp_result),
intent(in) :: qperp_results(nseed)
4420 type(trace_length_result),
intent(out) :: results(nseed)
4425 results(iseed)%seed=qperp_results(iseed)%seed
4426 results(iseed)%forward_footpoint=qperp_results(iseed)%forward_endpoint
4427 results(iseed)%backward_footpoint=qperp_results(iseed)%backward_endpoint
4428 results(iseed)%forward_status=qperp_results(iseed)%forward_status
4429 results(iseed)%backward_status=qperp_results(iseed)%backward_status
4430 results(iseed)%forward_nstep=0
4431 results(iseed)%backward_nstep=0
4432 if (qperp_results(iseed)%valid_q0)
then
4433 results(iseed)%forward_length=qperp_results(iseed)%forward_length
4434 results(iseed)%backward_length=qperp_results(iseed)%backward_length
4435 results(iseed)%total_length=results(iseed)%forward_length &
4436 +results(iseed)%backward_length
4438 results(iseed)%forward_length=0.d0
4439 results(iseed)%backward_length=0.d0
4440 results(iseed)%total_length=0.d0
4443 end subroutine mt_qperp_to_length
4445 subroutine mt_qperp_trace_to_length(qperp_results,nseed,results)
4446 integer,
intent(in) :: nseed
4447 type(trace_qperp_result),
intent(in) :: qperp_results(nseed)
4448 type(trace_length_result),
intent(out) :: results(nseed)
4453 results(iseed)%seed=qperp_results(iseed)%seed
4454 results(iseed)%forward_footpoint=qperp_results(iseed)%forward_endpoint
4455 results(iseed)%backward_footpoint=qperp_results(iseed)%backward_endpoint
4456 results(iseed)%forward_length=qperp_results(iseed)%forward_length
4457 results(iseed)%backward_length=qperp_results(iseed)%backward_length
4458 results(iseed)%total_length=results(iseed)%forward_length+ &
4459 results(iseed)%backward_length
4460 results(iseed)%forward_nstep=qperp_results(iseed)%forward_nstep
4461 results(iseed)%backward_nstep=qperp_results(iseed)%backward_nstep
4462 results(iseed)%forward_status=qperp_results(iseed)%forward_status
4463 results(iseed)%backward_status=qperp_results(iseed)%backward_status
4465 end subroutine mt_qperp_trace_to_length
4467 subroutine mt_qperp_trace_to_topology(qperp_results,twist_results,nseed, &
4469 integer,
intent(in) :: nseed
4470 type(trace_qperp_result),
intent(in) :: qperp_results(nseed)
4471 type(trace_twist_result),
intent(in) :: twist_results(:)
4472 type(trace_topology_result),
intent(out) :: topology(nseed)
4473 logical,
intent(in) :: do_twist
4478 topology(iseed)%seed=qperp_results(iseed)%seed
4479 topology(iseed)%length_forward=qperp_results(iseed)%forward_length
4480 topology(iseed)%length_backward=qperp_results(iseed)%backward_length
4481 topology(iseed)%length_total=topology(iseed)%length_forward &
4482 +topology(iseed)%length_backward
4483 topology(iseed)%twist_forward=0.d0
4484 topology(iseed)%twist_backward=0.d0
4485 topology(iseed)%twist_total=0.d0
4487 topology(iseed)%twist_forward=twist_results(iseed)%forward_twist
4488 topology(iseed)%twist_backward=twist_results(iseed)%backward_twist
4489 topology(iseed)%twist_total=twist_results(iseed)%total_twist
4491 topology(iseed)%forward_endpoint=qperp_results(iseed)%forward_endpoint
4492 topology(iseed)%backward_endpoint=qperp_results(iseed)%backward_endpoint
4493 topology(iseed)%forward_nstep=qperp_results(iseed)%forward_nstep
4494 topology(iseed)%backward_nstep=qperp_results(iseed)%backward_nstep
4495 topology(iseed)%forward_face=qperp_results(iseed)%forward_face
4496 topology(iseed)%backward_face=qperp_results(iseed)%backward_face
4497 topology(iseed)%forward_status=qperp_results(iseed)%forward_status
4498 topology(iseed)%backward_status=qperp_results(iseed)%backward_status
4499 topology(iseed)%map_forward_endpoint=qperp_results(iseed)%forward_endpoint
4500 topology(iseed)%map_backward_endpoint=qperp_results(iseed)%backward_endpoint
4501 topology(iseed)%map_forward_length=qperp_results(iseed)%forward_length
4502 topology(iseed)%map_backward_length=qperp_results(iseed)%backward_length
4503 topology(iseed)%map_forward_face=qperp_results(iseed)%forward_face
4504 topology(iseed)%map_backward_face=qperp_results(iseed)%backward_face
4505 topology(iseed)%map_forward_status=qperp_results(iseed)%forward_status
4506 topology(iseed)%map_backward_status=qperp_results(iseed)%backward_status
4507 topology(iseed)%source_B=0.d0
4508 topology(iseed)%forward_B=0.d0
4509 topology(iseed)%backward_B=0.d0
4510 topology(iseed)%source_B(1:ndim)=qperp_results(iseed)%B_seed
4511 topology(iseed)%forward_B(1:ndim)=qperp_results(iseed)%forward_B
4512 topology(iseed)%backward_B(1:ndim)=qperp_results(iseed)%backward_B
4513 topology(iseed)%source_Bn=0.d0
4514 topology(iseed)%forward_Bn=0.d0
4515 topology(iseed)%backward_Bn=0.d0
4516 topology(iseed)%has_twist=do_twist
4517 topology(iseed)%has_mapping=.false.
4518 topology(iseed)%valid_twist=.false.
4519 topology(iseed)%status_twist=qperp_results(iseed)%status
4521 topology(iseed)%valid_twist=twist_results(iseed)%valid_twist
4522 topology(iseed)%status_twist=twist_results(iseed)%status_twist
4524 topology(iseed)%valid=qperp_results(iseed)%status==trace_status_boundary
4525 topology(iseed)%status=qperp_results(iseed)%status
4527 end subroutine mt_qperp_trace_to_topology
4529 subroutine mt_q0_trace_to_length(q_results,nseed,results)
4530 integer,
intent(in) :: nseed
4531 type(trace_qperp_result),
intent(in) :: q_results(nseed)
4532 type(trace_length_result),
intent(out) :: results(nseed)
4537 results(iseed)%seed=q_results(iseed)%seed
4538 results(iseed)%forward_footpoint=q_results(iseed)%forward_endpoint
4539 results(iseed)%backward_footpoint=q_results(iseed)%backward_endpoint
4540 results(iseed)%forward_length=q_results(iseed)%forward_length
4541 results(iseed)%backward_length=q_results(iseed)%backward_length
4542 results(iseed)%total_length=results(iseed)%forward_length &
4543 +results(iseed)%backward_length
4544 results(iseed)%forward_nstep=q_results(iseed)%forward_nstep
4545 results(iseed)%backward_nstep=q_results(iseed)%backward_nstep
4546 results(iseed)%forward_status=q_results(iseed)%forward_status
4547 results(iseed)%backward_status=q_results(iseed)%backward_status
4549 end subroutine mt_q0_trace_to_length
4551 subroutine mt_q0_trace_to_topology(q_results,twist_results,nseed, &
4553 integer,
intent(in) :: nseed
4554 type(trace_qperp_result),
intent(in) :: q_results(nseed)
4555 type(trace_twist_result),
intent(in) :: twist_results(:)
4556 type(trace_topology_result),
intent(out) :: topology(nseed)
4557 logical,
intent(in) :: do_twist
4562 topology(iseed)%seed=q_results(iseed)%seed
4563 topology(iseed)%length_forward=q_results(iseed)%forward_length
4564 topology(iseed)%length_backward=q_results(iseed)%backward_length
4565 topology(iseed)%length_total=topology(iseed)%length_forward &
4566 +topology(iseed)%length_backward
4567 topology(iseed)%twist_forward=0.d0
4568 topology(iseed)%twist_backward=0.d0
4569 topology(iseed)%twist_total=0.d0
4571 topology(iseed)%twist_forward=twist_results(iseed)%forward_twist
4572 topology(iseed)%twist_backward=twist_results(iseed)%backward_twist
4573 topology(iseed)%twist_total=twist_results(iseed)%total_twist
4575 topology(iseed)%forward_endpoint=q_results(iseed)%forward_endpoint
4576 topology(iseed)%backward_endpoint=q_results(iseed)%backward_endpoint
4577 topology(iseed)%forward_nstep=q_results(iseed)%forward_nstep
4578 topology(iseed)%backward_nstep=q_results(iseed)%backward_nstep
4579 topology(iseed)%forward_face=q_results(iseed)%forward_face
4580 topology(iseed)%backward_face=q_results(iseed)%backward_face
4581 topology(iseed)%forward_status=q_results(iseed)%forward_status
4582 topology(iseed)%backward_status=q_results(iseed)%backward_status
4583 topology(iseed)%map_forward_endpoint=q_results(iseed)%forward_endpoint
4584 topology(iseed)%map_backward_endpoint=q_results(iseed)%backward_endpoint
4585 topology(iseed)%map_forward_length=q_results(iseed)%forward_length
4586 topology(iseed)%map_backward_length=q_results(iseed)%backward_length
4587 topology(iseed)%map_forward_face=q_results(iseed)%forward_face
4588 topology(iseed)%map_backward_face=q_results(iseed)%backward_face
4589 topology(iseed)%map_forward_status=q_results(iseed)%forward_status
4590 topology(iseed)%map_backward_status=q_results(iseed)%backward_status
4591 topology(iseed)%source_B=0.d0
4592 topology(iseed)%forward_B=0.d0
4593 topology(iseed)%backward_B=0.d0
4594 topology(iseed)%source_B(1:ndim)=q_results(iseed)%B_seed
4595 topology(iseed)%forward_B(1:ndim)=q_results(iseed)%forward_B
4596 topology(iseed)%backward_B(1:ndim)=q_results(iseed)%backward_B
4597 topology(iseed)%source_Bn=0.d0
4598 topology(iseed)%forward_Bn=q_results(iseed)%forward_Bn_q0
4599 topology(iseed)%backward_Bn=q_results(iseed)%backward_Bn_q0
4600 topology(iseed)%has_twist=do_twist
4601 topology(iseed)%has_mapping=.false.
4602 topology(iseed)%valid_twist=.false.
4603 topology(iseed)%status_twist=q_results(iseed)%status
4605 topology(iseed)%valid_twist=twist_results(iseed)%valid_twist
4606 topology(iseed)%status_twist=twist_results(iseed)%status_twist
4608 topology(iseed)%valid=q_results(iseed)%status==trace_status_boundary
4609 topology(iseed)%status=q_results(iseed)%status
4611 end subroutine mt_q0_trace_to_topology
4613 subroutine mt_topology_to_length(topology,nseed,results)
4614 integer,
intent(in) :: nseed
4615 type(trace_topology_result),
intent(in) :: topology(nseed)
4616 type(trace_length_result),
intent(out) :: results(nseed)
4621 results(iseed)%seed=topology(iseed)%seed
4622 results(iseed)%forward_footpoint=topology(iseed)%forward_endpoint
4623 results(iseed)%backward_footpoint=topology(iseed)%backward_endpoint
4624 results(iseed)%forward_length=topology(iseed)%length_forward
4625 results(iseed)%backward_length=topology(iseed)%length_backward
4626 results(iseed)%total_length=topology(iseed)%length_total
4627 results(iseed)%forward_nstep=topology(iseed)%forward_nstep
4628 results(iseed)%backward_nstep=topology(iseed)%backward_nstep
4629 results(iseed)%forward_status=topology(iseed)%forward_status
4630 results(iseed)%backward_status=topology(iseed)%backward_status
4632 end subroutine mt_topology_to_length
4634 subroutine mt_topology_to_twist(topology,nseed,results)
4635 integer,
intent(in) :: nseed
4636 type(trace_topology_result),
intent(in) :: topology(nseed)
4637 type(trace_twist_result),
intent(out) :: results(nseed)
4642 results(iseed)%line%seed=topology(iseed)%seed
4643 results(iseed)%line%forward_footpoint=topology(iseed)%forward_endpoint
4644 results(iseed)%line%backward_footpoint=topology(iseed)%backward_endpoint
4645 results(iseed)%line%forward_length=topology(iseed)%length_forward
4646 results(iseed)%line%backward_length=topology(iseed)%length_backward
4647 results(iseed)%line%total_length=topology(iseed)%length_total
4648 results(iseed)%line%forward_nstep=topology(iseed)%forward_nstep
4649 results(iseed)%line%backward_nstep=topology(iseed)%backward_nstep
4650 results(iseed)%line%forward_status=topology(iseed)%forward_status
4651 results(iseed)%line%backward_status=topology(iseed)%backward_status
4652 results(iseed)%forward_twist=topology(iseed)%twist_forward
4653 results(iseed)%backward_twist=topology(iseed)%twist_backward
4654 results(iseed)%total_twist=topology(iseed)%twist_total
4655 results(iseed)%valid_twist=topology(iseed)%valid_twist
4656 results(iseed)%status_twist=topology(iseed)%status_twist
4658 end subroutine mt_topology_to_twist
4660 subroutine mt_topology_to_mapping(topology,nseed,results)
4661 integer,
intent(in) :: nseed
4662 type(trace_topology_result),
intent(in) :: topology(nseed)
4663 type(trace_mapping_result),
intent(out) :: results(nseed)
4668 results(iseed)%seed=topology(iseed)%seed
4669 results(iseed)%source_B=topology(iseed)%source_B
4670 results(iseed)%forward_footpoint=topology(iseed)%map_forward_endpoint
4671 results(iseed)%backward_footpoint=topology(iseed)%map_backward_endpoint
4672 results(iseed)%forward_B=topology(iseed)%forward_B
4673 results(iseed)%backward_B=topology(iseed)%backward_B
4674 results(iseed)%forward_length=topology(iseed)%map_forward_length
4675 results(iseed)%backward_length=topology(iseed)%map_backward_length
4676 results(iseed)%source_Bn=topology(iseed)%source_Bn
4677 results(iseed)%forward_Bn=topology(iseed)%forward_Bn
4678 results(iseed)%backward_Bn=topology(iseed)%backward_Bn
4679 results(iseed)%forward_face=topology(iseed)%map_forward_face
4680 results(iseed)%backward_face=topology(iseed)%map_backward_face
4681 results(iseed)%forward_status=topology(iseed)%map_forward_status
4682 results(iseed)%backward_status=topology(iseed)%map_backward_status
4683 results(iseed)%valid=topology(iseed)%has_mapping .and. &
4684 topology(iseed)%valid
4686 end subroutine mt_topology_to_mapping
4688 subroutine mt_validate_axis_plane(c1min,c1max,n1,c2min,c2max,n2,caller)
4689 integer,
intent(in) :: n1,n2
4690 double precision,
intent(in) :: c1min,c1max,c2min,c2max
4691 character(len=*),
intent(in) :: caller
4694 call mpistop(trim(caller)//
' currently requires npe=1')
4697 call mpistop(trim(caller)//
' requires ndim=3')
4701 select case (geo_coordinate)
4702 case (geo_cartesian)
4705 case (geo_cartesian_stretched)
4707 call mpistop(trim(caller)//
' requires Cartesian geometry')
4710 if (n1<1 .or. n2<1)
then
4711 call mpistop(trim(caller)//
' requires both sample counts >=1')
4713 if (c1max<c1min .or. c2max<c2min)
then
4714 call mpistop(trim(caller)//
' requires ordered plane bounds')
4716 end subroutine mt_validate_axis_plane
4718 subroutine mt_build_axis_plane_seeds(c1min,c1max,n1,c2min,c2max,n2, &
4719 fixed_value,axis1,axis2,fixed_axis,seeds)
4720 integer,
intent(in) :: n1,n2,axis1,axis2,fixed_axis
4721 double precision,
intent(in) :: c1min,c1max,c2min,c2max,fixed_value
4722 double precision,
allocatable,
intent(out) :: seeds(:,:)
4724 double precision :: dc1,dc2
4725 integer :: i,j,iseed
4729 if (n1>1) dc1=(c1max-c1min)/dble(n1-1)
4730 if (n2>1) dc2=(c2max-c2min)/dble(n2-1)
4732 allocate(seeds(n1*n2,ndim))
4737 seeds(iseed,axis1)=c1min+dble(i-1)*dc1
4738 seeds(iseed,axis2)=c2min+dble(j-1)*dc2
4739 seeds(iseed,fixed_axis)=fixed_value
4742 end subroutine mt_build_axis_plane_seeds
4744 subroutine mt_build_spherical_surface_seeds(surface,seed_coord,s1_min, &
4745 s1_max,n1,s2_min,s2_max,n2,seed_layout,seed_theta0,seed_phi0, &
4747 character(len=*),
intent(in) :: surface,seed_layout
4748 integer,
intent(in) :: n1,n2
4749 double precision,
intent(in) :: seed_coord,s1_min,s1_max,s2_min,s2_max
4750 double precision,
intent(in) :: seed_theta0,seed_phi0,seed_alpha
4751 double precision,
allocatable,
intent(out) :: seeds(:,:)
4753 character(len=mt_task_name_len) :: layout
4754 double precision :: s1,s2
4755 integer :: i,j,iseed,status
4757 layout=mt_lowercase(trim(seed_layout))
4758 if (len_trim(layout)==0) layout=
'endpoint'
4759 select case (trim(layout))
4760 case (
'endpoint',
'endpoints',
'boundary')
4761 case (
'cell_centered',
'cell-centered',
'centered',
'center')
4763 call mpistop(
'spherical_surface_products requires '// &
4764 'mt_seed_layout=endpoint or cell_centered')
4767 allocate(seeds(n1*n2,ndim))
4770 s2=mt_seed_axis_coord(s2_min,s2_max,n2,j,layout)
4772 s1=mt_seed_axis_coord(s1_min,s1_max,n1,i,layout)
4774 select case (trim(surface))
4775 case (
'rmin',
'rconst')
4776 seeds(iseed,1)=seed_coord
4779 case (
'theta_const')
4781 seeds(iseed,2)=seed_coord
4786 seeds(iseed,3)=seed_coord
4787 case (
'radial_plane')
4788 call mt_spherical_radial_plane_seed(s1,s2,seed_theta0,seed_phi0, &
4789 seed_alpha,seeds(iseed,:),status)
4791 call mpistop(
'mt_build_spherical_surface_seeds radial_plane '// &
4792 'seed lies outside the spherical domain; adjust '// &
4793 'mt_seed_theta0/mt_seed_phi0/mt_seed_alpha or mt_s2 bounds')
4796 call mpistop(
'mt_build_spherical_surface_seeds got '// &
4797 'unsupported surface')
4801 end subroutine mt_build_spherical_surface_seeds
4803 subroutine mt_spherical_radial_plane_seed(radius,u,theta0,phi0,alpha,seed, &
4805 double precision,
intent(in) :: radius,u,theta0,phi0,alpha
4806 double precision,
intent(out) :: seed(ndim)
4807 integer,
intent(out) :: status
4809 double precision :: sin_theta0,cos_theta0,sin_phi0,cos_phi0
4810 double precision :: n0(3),etheta(3),ephi(3),tangent(3),nhat(3)
4811 double precision :: norm_n,theta,phi,cos_u,sin_u
4816 if (radius<xprobmin1 .or. radius>xprobmax1)
return
4817 if (theta0<xprobmin2 .or. theta0>xprobmax2)
return
4818 if (phi0<xprobmin3 .or. phi0>xprobmax3)
return
4820 sin_theta0=dsin(theta0)
4821 cos_theta0=dcos(theta0)
4822 if (abs(sin_theta0)<=1.d-12)
return
4826 n0=(/sin_theta0*cos_phi0,sin_theta0*sin_phi0,cos_theta0/)
4827 etheta=(/cos_theta0*cos_phi0,cos_theta0*sin_phi0,-sin_theta0/)
4828 ephi=(/-sin_phi0,cos_phi0,0.d0/)
4829 tangent=dcos(alpha)*etheta+dsin(alpha)*ephi
4833 nhat=cos_u*n0+sin_u*tangent
4834 norm_n=dsqrt(sum(nhat**2))
4835 if (norm_n<=0.d0)
return
4838 theta=dacos(max(-1.d0,min(1.d0,nhat(3))))
4839 phi=datan2(nhat(2),nhat(1))
4840 if (theta<xprobmin2 .or. theta>xprobmax2)
return
4841 if (phi<xprobmin3 .or. phi>xprobmax3)
return
4848 end subroutine mt_spherical_radial_plane_seed
4850 subroutine mt_build_spherical_cloud_seeds(s1_min,s1_max,n1,s2_min, &
4851 s2_max,n2,s3_min,s3_max,n3,seed_layout,seeds)
4852 character(len=*),
intent(in) :: seed_layout
4853 integer,
intent(in) :: n1,n2,n3
4854 double precision,
intent(in) :: s1_min,s1_max,s2_min,s2_max
4855 double precision,
intent(in) :: s3_min,s3_max
4856 double precision,
allocatable,
intent(out) :: seeds(:,:)
4858 character(len=mt_task_name_len) :: layout
4859 double precision :: s1,s2,s3
4860 integer :: i,j,k,iseed
4862 layout=mt_lowercase(trim(seed_layout))
4863 if (len_trim(layout)==0) layout=
'endpoint'
4864 select case (trim(layout))
4865 case (
'endpoint',
'endpoints',
'boundary')
4866 case (
'cell_centered',
'cell-centered',
'centered',
'center')
4868 call mpistop(
'spherical_cloud_products requires '// &
4869 'mt_seed_layout=endpoint or cell_centered')
4872 allocate(seeds(n1*n2*n3,ndim))
4875 s3=mt_seed_axis_coord(s3_min,s3_max,n3,k,layout)
4877 s2=mt_seed_axis_coord(s2_min,s2_max,n2,j,layout)
4879 s1=mt_seed_axis_coord(s1_min,s1_max,n1,i,layout)
4880 iseed=(k-1)*n1*n2+(j-1)*n1+i
4887 end subroutine mt_build_spherical_cloud_seeds
4889 double precision function mt_seed_axis_coord(cmin,cmax,n,i,layout) &
4891 double precision,
intent(in) :: cmin,cmax
4892 integer,
intent(in) :: n,i
4893 character(len=*),
intent(in) :: layout
4895 select case (trim(layout))
4896 case (
'cell_centered',
'cell-centered',
'centered',
'center')
4897 coord=cmin+(dble(i)-0.5d0)*(cmax-cmin)/dble(n)
4900 coord=cmin+dble(i-1)*(cmax-cmin)/dble(n-1)
4905 end function mt_seed_axis_coord
4907 integer function mt_spherical_connection_type(face_b,face_f,is_valid) &
4908 result(connection_type)
4909 integer,
intent(in) :: face_b,face_f
4910 logical,
intent(in) :: is_valid
4912 logical :: b_rmin,f_rmin,b_rmax,f_rmax,b_side,f_side
4915 if (.not.is_valid)
return
4916 if (.not.mt_q_face_valid(face_b))
return
4917 if (.not.mt_q_face_valid(face_f))
return
4919 b_rmin=face_b==trace_face_xmin
4920 f_rmin=face_f==trace_face_xmin
4921 b_rmax=face_b==trace_face_xmax
4922 f_rmax=face_f==trace_face_xmax
4923 b_side=.not.(b_rmin .or. b_rmax)
4924 f_side=.not.(f_rmin .or. f_rmax)
4926 if (b_rmin .and. f_rmin)
then
4928 else if ((b_rmin .and. f_rmax) .or. (b_rmax .and. f_rmin))
then
4930 else if ((b_rmin .and. f_side) .or. (f_rmin .and. b_side))
then
4932 else if (b_rmax .and. f_rmax)
then
4934 else if (b_side .and. f_side .and. face_b==face_f)
then
4939 end function mt_spherical_connection_type
4941 logical function mt_validate_arbitrary_plane_basis(e1,e2,s1min,s1max, &
4942 n1,s2min,s2max,n2,caller)
result(valid)
4943 integer,
intent(in) :: n1,n2
4944 double precision,
intent(in) :: e1(ndim),e2(ndim)
4945 double precision,
intent(in) :: s1min,s1max,s2min,s2max
4946 character(len=*),
intent(in) :: caller
4948 double precision,
parameter :: basis_tol=1.d-10
4949 double precision :: e1_norm,e2_norm,e12_dot
4953 write(*,
'(a)') trim(caller)//
' currently requires npe=1'
4957 write(*,
'(a)') trim(caller)//
' requires ndim=3'
4961 select case (geo_coordinate)
4962 case (geo_cartesian,geo_cartesian_stretched)
4964 write(*,
'(a)') trim(caller)//
' requires Cartesian geometry'
4968 if (n1<1 .or. n2<1)
then
4969 write(*,
'(a)') trim(caller)//
' requires both sample counts >=1'
4972 if (s1max<s1min .or. s2max<s2min)
then
4973 write(*,
'(a)') trim(caller)//
' requires ordered plane bounds'
4976 e1_norm=dsqrt(sum(e1**2))
4977 e2_norm=dsqrt(sum(e2**2))
4979 if (abs(e1_norm-1.d0)>basis_tol .or. &
4980 abs(e2_norm-1.d0)>basis_tol .or. &
4981 abs(e12_dot)>basis_tol)
then
4982 write(*,
'(a)') trim(caller)//
' requires orthonormal e1/e2'
4987 end function mt_validate_arbitrary_plane_basis
4989 subroutine mt_build_arbitrary_plane_seeds(origin,e1,e2,s1min,s1max,n1, &
4990 s2min,s2max,n2,seeds,s1,s2)
4991 integer,
intent(in) :: n1,n2
4992 double precision,
intent(in) :: origin(ndim),e1(ndim),e2(ndim)
4993 double precision,
intent(in) :: s1min,s1max,s2min,s2max
4994 double precision,
allocatable,
intent(out) :: seeds(:,:),s1(:),s2(:)
4996 double precision :: ds1,ds2
4997 integer :: i,j,iseed
5001 if (n1>1) ds1=(s1max-s1min)/dble(n1-1)
5002 if (n2>1) ds2=(s2max-s2min)/dble(n2-1)
5004 allocate(seeds(n1*n2,ndim),s1(n1*n2),s2(n1*n2))
5008 s1(iseed)=s1min+dble(i-1)*ds1
5009 s2(iseed)=s2min+dble(j-1)*ds2
5010 seeds(iseed,:)=origin+s1(iseed)*e1+s2(iseed)*e2
5013 end subroutine mt_build_arbitrary_plane_seeds
5015 subroutine mt_write_length_plane_csv(results,n1,n2,csv_file,caller, &
5017 integer,
intent(in) :: n1,n2
5018 type(trace_length_result),
intent(in) :: results(n1*n2)
5019 character(len=*),
intent(in) :: csv_file,caller,index_header
5021 double precision :: seed_xyz(3)
5022 integer :: csv_unit,io_status,i,j,iseed
5024 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
5025 action=
'write',form=
'formatted',iostat=io_status)
5026 if (io_status/=0)
then
5027 call mpistop(trim(caller)//
' could not open CSV file')
5030 write(csv_unit,
'(a)',iostat=io_status) &
5031 trim(index_header)//
',seed_x,seed_y,seed_z,'// &
5032 'length_total,length_backward,length_forward,'// &
5033 'nstep_backward,nstep_forward,'// &
5034 'status_backward,status_forward'
5035 if (io_status/=0)
then
5037 call mpistop(trim(caller)//
' could not write CSV header')
5044 seed_xyz(1:ndim)=results(iseed)%seed
5045 write(csv_unit,
'(i0,",",i0,6(",",es24.16),4(",",i0))', &
5046 iostat=io_status) i,j,seed_xyz,results(iseed)%total_length, &
5047 results(iseed)%backward_length, &
5048 results(iseed)%forward_length, &
5049 results(iseed)%backward_nstep, &
5050 results(iseed)%forward_nstep, &
5051 results(iseed)%backward_status, &
5052 results(iseed)%forward_status
5053 if (io_status/=0)
then
5055 call mpistop(trim(caller)//
' could not write CSV data')
5061 end subroutine mt_write_length_plane_csv
5063 subroutine mt_write_spherical_rmin_csv(topology,n1,n2,csv_file,caller, &
5064 do_twist,do_q,q_results,do_qperp,qperp_results)
5065 integer,
intent(in) :: n1,n2
5066 type(trace_topology_result),
intent(in) :: topology(n1*n2)
5067 character(len=*),
intent(in) :: csv_file,caller
5068 logical,
intent(in) :: do_twist,do_q,do_qperp
5069 type(trace_qperp_result),
intent(in) :: q_results(:)
5070 type(trace_qperp_result),
intent(in) :: qperp_results(:)
5072 integer :: csv_unit,io_status,i,j,iseed,connection_type
5074 character(len=2048) :: header
5076 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
5077 action=
'write',form=
'formatted',iostat=io_status)
5078 if (io_status/=0)
then
5079 call mpistop(trim(caller)//
' could not open CSV file')
5082 header=
'i,j,seed_r,seed_theta,seed_phi,'// &
5083 'length_total,length_backward,length_forward'
5085 header=trim(header)//
','// &
5086 'twist_total,twist_backward,twist_forward'
5089 header=trim(header)//
','// &
5090 'logQ,valid_Q,status_Q'
5093 header=trim(header)//
','// &
5094 'logQperp,valid_Qperp,status_Qperp'
5096 header=trim(header)//
','// &
5097 'r_b,theta_b,phi_b,r_f,theta_f,phi_f,'// &
5098 'face_backward,face_forward,connection_type_spherical,'// &
5099 'nstep_backward,nstep_forward,status_backward,status_forward'
5101 header=trim(header)//
','// &
5102 'status_twist,valid_twist'
5104 header=trim(header)//
',valid'
5105 write(csv_unit,
'(a)',iostat=io_status) trim(header)
5106 if (io_status/=0)
then
5108 call mpistop(trim(caller)//
' could not write CSV header')
5114 valid=topology(iseed)%valid
5115 connection_type=mt_spherical_connection_type( &
5116 topology(iseed)%backward_face,topology(iseed)%forward_face, &
5118 write(csv_unit,
'(i0,",",i0,6(",",es24.16))',advance=
'no', &
5119 iostat=io_status) i,j,topology(iseed)%seed, &
5120 topology(iseed)%length_total, &
5121 topology(iseed)%length_backward, &
5122 topology(iseed)%length_forward
5123 if (io_status/=0)
exit
5125 write(csv_unit,
'(3(",",es24.16))',advance=
'no', &
5126 iostat=io_status) topology(iseed)%twist_total, &
5127 topology(iseed)%twist_backward, &
5128 topology(iseed)%twist_forward
5129 if (io_status/=0)
exit
5132 write(csv_unit,
'(",",es24.16,",",l1,",",i0)',advance=
'no', &
5133 iostat=io_status) q_results(iseed)%logq0, &
5134 q_results(iseed)%valid_q0,q_results(iseed)%status_q0
5135 if (io_status/=0)
exit
5138 write(csv_unit,
'(",",es24.16,",",l1,",",i0)',advance=
'no', &
5139 iostat=io_status) qperp_results(iseed)%logqperp, &
5140 qperp_results(iseed)%valid,qperp_results(iseed)%status
5141 if (io_status/=0)
exit
5143 write(csv_unit,
'(6(",",es24.16),7(",",i0))',advance=
'no', &
5144 iostat=io_status) topology(iseed)%backward_endpoint, &
5145 topology(iseed)%forward_endpoint, &
5146 topology(iseed)%backward_face,topology(iseed)%forward_face, &
5147 connection_type,topology(iseed)%backward_nstep, &
5148 topology(iseed)%forward_nstep, &
5149 topology(iseed)%backward_status, &
5150 topology(iseed)%forward_status
5151 if (io_status/=0)
exit
5153 write(csv_unit,
'(",",i0,",",l1)',advance=
'no',iostat=io_status) &
5154 topology(iseed)%status_twist,topology(iseed)%valid_twist
5155 if (io_status/=0)
exit
5157 write(csv_unit,
'(",",l1)',iostat=io_status) valid
5158 if (io_status/=0)
then
5160 call mpistop(trim(caller)//
' could not write CSV data')
5166 end subroutine mt_write_spherical_rmin_csv
5168 subroutine mt_write_spherical_topology_vtu(vtu_file,topology,n1,n2, &
5169 caller,do_twist,do_q,q_results,do_qperp,qperp_results)
5170 character(len=*),
intent(in) :: vtu_file,caller
5171 integer,
intent(in) :: n1,n2
5172 type(trace_topology_result),
intent(in) :: topology(n1*n2)
5173 logical,
intent(in) :: do_twist,do_q,do_qperp
5174 type(trace_qperp_result),
intent(in) :: q_results(:)
5175 type(trace_qperp_result),
intent(in) :: qperp_results(:)
5177 integer :: vtu_unit,io_status,npoint,ncell
5181 if (n1>1 .and. n2>1) ncell=(n1-1)*(n2-1)
5182 if (ncell==0) ncell=npoint
5184 open(newunit=vtu_unit,file=trim(vtu_file),status=
'replace', &
5185 action=
'write',form=
'formatted',iostat=io_status)
5186 if (io_status/=0)
then
5187 call mpistop(trim(caller)//
' could not open VTU file')
5190 call mt_write_vtu_file_header(vtu_unit,npoint,ncell)
5191 call mt_write_vtu_spherical_topology_pointdata(vtu_unit,topology, &
5192 npoint,do_twist,do_q,q_results,do_qperp,qperp_results,io_status)
5193 if (io_status==0)
call mt_write_vtu_topology_points(vtu_unit, &
5194 topology,npoint,io_status)
5195 if (io_status==0)
then
5196 if (n1>1 .and. n2>1)
then
5197 call mt_write_vtu_quad_cells(vtu_unit,n1,n2,io_status)
5199 call mt_write_vtu_vertex_cells(vtu_unit,npoint,io_status)
5202 if (io_status==0)
call mt_write_vtu_file_footer(vtu_unit,io_status)
5204 if (io_status/=0)
then
5205 call mpistop(trim(caller)//
' could not write VTU file')
5207 end subroutine mt_write_spherical_topology_vtu
5209 subroutine mt_write_spherical_cloud_csv(topology,n1,n2,n3,csv_file, &
5210 caller,do_twist,do_qperp,qperp_results)
5211 integer,
intent(in) :: n1,n2,n3
5212 type(trace_topology_result),
intent(in) :: topology(n1*n2*n3)
5213 character(len=*),
intent(in) :: csv_file,caller
5214 logical,
intent(in) :: do_twist,do_qperp
5215 type(trace_qperp_result),
intent(in) :: qperp_results(:)
5217 integer :: csv_unit,io_status,i,j,k,iseed,connection_type
5219 character(len=2048) :: header
5221 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
5222 action=
'write',form=
'formatted',iostat=io_status)
5223 if (io_status/=0)
then
5224 call mpistop(trim(caller)//
' could not open CSV file')
5227 header=
'i,j,k,seed_r,seed_theta,seed_phi,'// &
5228 'length_total,length_backward,length_forward'
5230 header=trim(header)//
','// &
5231 'twist_total,twist_backward,twist_forward'
5234 header=trim(header)//
','// &
5235 'logQperp,valid_Qperp,status_Qperp'
5237 header=trim(header)//
','// &
5238 'r_b,theta_b,phi_b,r_f,theta_f,phi_f,'// &
5239 'face_backward,face_forward,connection_type_spherical,'// &
5240 'nstep_backward,nstep_forward,status_backward,status_forward'
5242 header=trim(header)//
','// &
5243 'status_twist,valid_twist'
5245 header=trim(header)//
',valid'
5246 write(csv_unit,
'(a)',iostat=io_status) trim(header)
5247 if (io_status/=0)
then
5249 call mpistop(trim(caller)//
' could not write CSV header')
5255 iseed=(k-1)*n1*n2+(j-1)*n1+i
5256 valid=topology(iseed)%valid
5257 connection_type=mt_spherical_connection_type( &
5258 topology(iseed)%backward_face,topology(iseed)%forward_face, &
5260 write(csv_unit,
'(i0,",",i0,",",i0,6(",",es24.16))', &
5261 advance=
'no',iostat=io_status) i,j,k,topology(iseed)%seed, &
5262 topology(iseed)%length_total, &
5263 topology(iseed)%length_backward, &
5264 topology(iseed)%length_forward
5265 if (io_status/=0)
exit
5267 write(csv_unit,
'(3(",",es24.16))',advance=
'no', &
5268 iostat=io_status) topology(iseed)%twist_total, &
5269 topology(iseed)%twist_backward, &
5270 topology(iseed)%twist_forward
5271 if (io_status/=0)
exit
5274 write(csv_unit,
'(",",es24.16,",",l1,",",i0)',advance=
'no', &
5275 iostat=io_status) qperp_results(iseed)%logqperp, &
5276 qperp_results(iseed)%valid,qperp_results(iseed)%status
5277 if (io_status/=0)
exit
5279 write(csv_unit,
'(6(",",es24.16),7(",",i0))',advance=
'no', &
5280 iostat=io_status) topology(iseed)%backward_endpoint, &
5281 topology(iseed)%forward_endpoint, &
5282 topology(iseed)%backward_face,topology(iseed)%forward_face, &
5283 connection_type,topology(iseed)%backward_nstep, &
5284 topology(iseed)%forward_nstep, &
5285 topology(iseed)%backward_status, &
5286 topology(iseed)%forward_status
5287 if (io_status/=0)
exit
5289 write(csv_unit,
'(",",i0,",",l1)',advance=
'no', &
5290 iostat=io_status) topology(iseed)%status_twist, &
5291 topology(iseed)%valid_twist
5292 if (io_status/=0)
exit
5294 write(csv_unit,
'(",",l1)',iostat=io_status) valid
5295 if (io_status/=0)
exit
5297 if (io_status/=0)
exit
5299 if (io_status/=0)
exit
5302 if (io_status/=0)
then
5304 call mpistop(trim(caller)//
' could not write CSV data')
5307 end subroutine mt_write_spherical_cloud_csv
5309 subroutine mt_write_spherical_cloud_vtu(vtu_file,topology,npoint,caller, &
5310 do_twist,do_q,q_results,do_qperp,qperp_results)
5311 character(len=*),
intent(in) :: vtu_file,caller
5312 integer,
intent(in) :: npoint
5313 type(trace_topology_result),
intent(in) :: topology(npoint)
5314 logical,
intent(in) :: do_twist,do_q,do_qperp
5315 type(trace_qperp_result),
intent(in) :: q_results(:)
5316 type(trace_qperp_result),
intent(in) :: qperp_results(:)
5318 integer :: vtu_unit,io_status
5320 open(newunit=vtu_unit,file=trim(vtu_file),status=
'replace', &
5321 action=
'write',form=
'formatted',iostat=io_status)
5322 if (io_status/=0)
then
5323 call mpistop(trim(caller)//
' could not open VTU file')
5326 call mt_write_vtu_file_header(vtu_unit,npoint,npoint)
5327 call mt_write_vtu_spherical_topology_pointdata(vtu_unit,topology, &
5328 npoint,do_twist,do_q,q_results,do_qperp,qperp_results,io_status)
5329 if (io_status==0)
call mt_write_vtu_topology_points(vtu_unit, &
5330 topology,npoint,io_status)
5331 if (io_status==0)
call mt_write_vtu_vertex_cells(vtu_unit,npoint, &
5333 if (io_status==0)
call mt_write_vtu_file_footer(vtu_unit,io_status)
5335 if (io_status/=0)
then
5336 call mpistop(trim(caller)//
' could not write VTU file')
5338 end subroutine mt_write_spherical_cloud_vtu
5340 subroutine mt_write_fieldline_products_seeds_csv(length_results, &
5341 twist_results,q_results,qperp_results,nseed,csv_file,do_twist, &
5343 integer,
intent(in) :: nseed
5344 type(trace_length_result),
intent(in) :: length_results(nseed)
5345 type(trace_twist_result),
intent(in) :: twist_results(:)
5346 type(trace_qperp_result),
intent(in) :: q_results(:)
5347 type(trace_qperp_result),
intent(in) :: qperp_results(:)
5348 character(len=*),
intent(in) :: csv_file
5349 logical,
intent(in) :: do_twist,do_q,do_qperp
5351 double precision :: seed_xyz(3)
5352 double precision :: bseed_norm,bf_norm,bb_norm
5353 character(len=2048) :: header
5354 integer :: csv_unit,io_status,iseed
5356 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
5357 action=
'write',form=
'formatted',iostat=io_status)
5358 if (io_status/=0)
then
5359 call mpistop(
'mt_fieldline_products_seeds could not open CSV file')
5362 header=
'seed_id,seed_x,seed_y,seed_z,'// &
5363 'length_total,length_backward,length_forward,'// &
5364 'nstep_backward_length,nstep_forward_length,'// &
5365 'status_backward_length,status_forward_length'
5367 header=trim(header)//
','// &
5368 'twist_total,twist_backward,twist_forward,'// &
5369 'nstep_backward_twist,nstep_forward_twist,'// &
5370 'status_backward_twist,status_forward_twist'
5373 header=trim(header)//
','// &
5374 'logQ,valid_Q,status_Q,'// &
5375 'face_forward_Q,face_backward_Q,'// &
5376 'status_forward_Q,status_backward_Q,'// &
5377 'length_forward_Q,length_backward_Q,'// &
5378 'x_f_Q,y_f_Q,z_f_Q,x_b_Q,y_b_Q,z_b_Q'
5381 header=trim(header)//
','// &
5382 'qperp,logqperp,valid_qperp,status_qperp,'// &
5384 'face_forward_qperp,face_backward_qperp,'// &
5385 'status_forward_qperp,status_backward_qperp,'// &
5386 'length_forward_qperp,length_backward_qperp,'// &
5387 'Bseed_norm,Bf_norm,Bb_norm,'// &
5388 'x_f_qperp,y_f_qperp,z_f_qperp,'// &
5389 'x_b_qperp,y_b_qperp,z_b_qperp'
5391 write(csv_unit,
'(a)',iostat=io_status) trim(header)
5392 if (io_status/=0)
then
5394 call mpistop(
'mt_fieldline_products_seeds could not write CSV header')
5399 seed_xyz(1:ndim)=length_results(iseed)%seed
5400 write(csv_unit,
'(i0,6(",",es24.16),4(",",i0))', &
5401 advance=
'no',iostat=io_status) &
5402 iseed,seed_xyz,length_results(iseed)%total_length, &
5403 length_results(iseed)%backward_length, &
5404 length_results(iseed)%forward_length, &
5405 length_results(iseed)%backward_nstep, &
5406 length_results(iseed)%forward_nstep, &
5407 length_results(iseed)%backward_status, &
5408 length_results(iseed)%forward_status
5409 if (io_status/=0)
exit
5412 write(csv_unit,
'(3(",",es24.16),4(",",i0))', &
5413 advance=
'no',iostat=io_status) &
5414 twist_results(iseed)%total_twist, &
5415 twist_results(iseed)%backward_twist, &
5416 twist_results(iseed)%forward_twist, &
5417 twist_results(iseed)%line%backward_nstep, &
5418 twist_results(iseed)%line%forward_nstep, &
5419 twist_results(iseed)%line%backward_status, &
5420 twist_results(iseed)%line%forward_status
5421 if (io_status/=0)
exit
5426 '(",",es24.16,",",l1,",",i0,4(",",i0),8(",",es24.16))', &
5427 advance=
'no',iostat=io_status) &
5428 q_results(iseed)%logq0, &
5429 q_results(iseed)%valid_q0,q_results(iseed)%status_q0, &
5430 q_results(iseed)%forward_face, &
5431 q_results(iseed)%backward_face, &
5432 q_results(iseed)%forward_status, &
5433 q_results(iseed)%backward_status, &
5434 q_results(iseed)%forward_length, &
5435 q_results(iseed)%backward_length, &
5436 q_results(iseed)%forward_endpoint, &
5437 q_results(iseed)%backward_endpoint
5438 if (io_status/=0)
exit
5442 bseed_norm=dsqrt(sum(qperp_results(iseed)%B_seed**2))
5443 bf_norm=dsqrt(sum(qperp_results(iseed)%forward_B**2))
5444 bb_norm=dsqrt(sum(qperp_results(iseed)%backward_B**2))
5446 '(2(",",es24.16),",",l1,",",i0,2(",",es24.16),'// &
5447 '4(",",i0),11(",",es24.16))', &
5448 advance=
'no',iostat=io_status) &
5449 qperp_results(iseed)%qperp, &
5450 qperp_results(iseed)%logqperp, &
5451 qperp_results(iseed)%valid,qperp_results(iseed)%status, &
5452 qperp_results(iseed)%N2,qperp_results(iseed)%bfactor, &
5453 qperp_results(iseed)%forward_face, &
5454 qperp_results(iseed)%backward_face, &
5455 qperp_results(iseed)%forward_status, &
5456 qperp_results(iseed)%backward_status, &
5457 qperp_results(iseed)%forward_length, &
5458 qperp_results(iseed)%backward_length, &
5459 bseed_norm,bf_norm,bb_norm, &
5460 qperp_results(iseed)%forward_endpoint, &
5461 qperp_results(iseed)%backward_endpoint
5462 if (io_status/=0)
exit
5465 write(csv_unit,
'()',iostat=io_status)
5466 if (io_status/=0)
exit
5469 if (io_status/=0)
then
5471 call mpistop(
'mt_fieldline_products_seeds could not write CSV data')
5474 end subroutine mt_write_fieldline_products_seeds_csv
5476 subroutine mt_fieldline_products_append_header(header,do_twist,do_q,do_qperp)
5477 character(len=*),
intent(inout) :: header
5478 logical,
intent(in) :: do_twist,do_q,do_qperp
5480 header=trim(header)//
','// &
5481 'length_total,length_backward,length_forward,'// &
5482 'nstep_backward_length,nstep_forward_length,'// &
5483 'status_backward_length,status_forward_length'
5485 header=trim(header)//
','// &
5486 'twist_total,twist_backward,twist_forward,'// &
5487 'nstep_backward_twist,nstep_forward_twist,'// &
5488 'status_backward_twist,status_forward_twist'
5491 header=trim(header)//
','// &
5492 'logQ,valid_Q,status_Q,'// &
5493 'face_forward_Q,face_backward_Q,'// &
5494 'status_forward_Q,status_backward_Q,'// &
5495 'length_forward_Q,length_backward_Q,'// &
5496 'x_f_Q,y_f_Q,z_f_Q,x_b_Q,y_b_Q,z_b_Q'
5499 header=trim(header)//
','// &
5500 'qperp,logqperp,valid_qperp,status_qperp,'// &
5502 'face_forward_qperp,face_backward_qperp,'// &
5503 'status_forward_qperp,status_backward_qperp,'// &
5504 'length_forward_qperp,length_backward_qperp,'// &
5505 'Bseed_norm,Bf_norm,Bb_norm,'// &
5506 'x_f_qperp,y_f_qperp,z_f_qperp,'// &
5507 'x_b_qperp,y_b_qperp,z_b_qperp'
5509 end subroutine mt_fieldline_products_append_header
5511 subroutine mt_write_fieldline_products_plane_arbitrary_header(csv_file, &
5512 caller,do_twist,do_q,do_qperp)
5513 character(len=*),
intent(in) :: csv_file,caller
5514 logical,
intent(in) :: do_twist,do_q,do_qperp
5516 character(len=2048) :: header
5517 integer :: csv_unit,io_status
5519 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
5520 action=
'write',form=
'formatted',iostat=io_status)
5521 if (io_status/=0)
then
5522 call mpistop(trim(caller)//
' could not open CSV file')
5525 header=
'i,j,s1,s2,seed_x,seed_y,seed_z'
5526 call mt_fieldline_products_append_header(header,do_twist,do_q,do_qperp)
5527 write(csv_unit,
'(a)',iostat=io_status) trim(header)
5528 if (io_status/=0)
then
5530 call mpistop(trim(caller)//
' could not write CSV header')
5534 end subroutine mt_write_fieldline_products_plane_arbitrary_header
5536 subroutine mt_write_fieldline_products_plane_arbitrary_csv( &
5537 length_results,twist_results,q_results,qperp_results,s1,s2,n1,n2, &
5538 csv_file,do_twist,do_q,do_qperp,caller)
5539 integer,
intent(in) :: n1,n2
5540 type(trace_length_result),
intent(in) :: length_results(n1*n2)
5541 type(trace_twist_result),
intent(in) :: twist_results(:)
5542 type(trace_qperp_result),
intent(in) :: q_results(:)
5543 type(trace_qperp_result),
intent(in) :: qperp_results(:)
5544 double precision,
intent(in) :: s1(n1*n2),s2(n1*n2)
5545 character(len=*),
intent(in) :: csv_file,caller
5546 logical,
intent(in) :: do_twist,do_q,do_qperp
5548 double precision :: seed_xyz(3)
5549 double precision :: bseed_norm,bf_norm,bb_norm
5550 character(len=2048) :: header
5551 integer :: csv_unit,io_status,i,j,iseed
5553 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
5554 action=
'write',form=
'formatted',iostat=io_status)
5555 if (io_status/=0)
then
5556 call mpistop(trim(caller)//
' could not open CSV file')
5559 header=
'i,j,s1,s2,seed_x,seed_y,seed_z'
5560 call mt_fieldline_products_append_header(header,do_twist,do_q,do_qperp)
5561 write(csv_unit,
'(a)',iostat=io_status) trim(header)
5562 if (io_status/=0)
then
5564 call mpistop(trim(caller)//
' could not write CSV header')
5571 seed_xyz(1:ndim)=length_results(iseed)%seed
5572 write(csv_unit,
'(i0,",",i0,8(",",es24.16),4(",",i0))', &
5573 advance=
'no',iostat=io_status) &
5574 i,j,s1(iseed),s2(iseed),seed_xyz, &
5575 length_results(iseed)%total_length, &
5576 length_results(iseed)%backward_length, &
5577 length_results(iseed)%forward_length, &
5578 length_results(iseed)%backward_nstep, &
5579 length_results(iseed)%forward_nstep, &
5580 length_results(iseed)%backward_status, &
5581 length_results(iseed)%forward_status
5582 if (io_status/=0)
exit
5585 write(csv_unit,
'(3(",",es24.16),4(",",i0))', &
5586 advance=
'no',iostat=io_status) &
5587 twist_results(iseed)%total_twist, &
5588 twist_results(iseed)%backward_twist, &
5589 twist_results(iseed)%forward_twist, &
5590 twist_results(iseed)%line%backward_nstep, &
5591 twist_results(iseed)%line%forward_nstep, &
5592 twist_results(iseed)%line%backward_status, &
5593 twist_results(iseed)%line%forward_status
5594 if (io_status/=0)
exit
5599 '(",",es24.16,",",l1,",",i0,4(",",i0),8(",",es24.16))', &
5600 advance=
'no',iostat=io_status) &
5601 q_results(iseed)%logq0, &
5602 q_results(iseed)%valid_q0,q_results(iseed)%status_q0, &
5603 q_results(iseed)%forward_face, &
5604 q_results(iseed)%backward_face, &
5605 q_results(iseed)%forward_status, &
5606 q_results(iseed)%backward_status, &
5607 q_results(iseed)%forward_length, &
5608 q_results(iseed)%backward_length, &
5609 q_results(iseed)%forward_endpoint, &
5610 q_results(iseed)%backward_endpoint
5611 if (io_status/=0)
exit
5615 bseed_norm=dsqrt(sum(qperp_results(iseed)%B_seed**2))
5616 bf_norm=dsqrt(sum(qperp_results(iseed)%forward_B**2))
5617 bb_norm=dsqrt(sum(qperp_results(iseed)%backward_B**2))
5619 '(2(",",es24.16),",",l1,",",i0,2(",",es24.16),'// &
5620 '4(",",i0),11(",",es24.16))', &
5621 advance=
'no',iostat=io_status) &
5622 qperp_results(iseed)%qperp, &
5623 qperp_results(iseed)%logqperp, &
5624 qperp_results(iseed)%valid,qperp_results(iseed)%status, &
5625 qperp_results(iseed)%N2,qperp_results(iseed)%bfactor, &
5626 qperp_results(iseed)%forward_face, &
5627 qperp_results(iseed)%backward_face, &
5628 qperp_results(iseed)%forward_status, &
5629 qperp_results(iseed)%backward_status, &
5630 qperp_results(iseed)%forward_length, &
5631 qperp_results(iseed)%backward_length, &
5632 bseed_norm,bf_norm,bb_norm, &
5633 qperp_results(iseed)%forward_endpoint, &
5634 qperp_results(iseed)%backward_endpoint
5635 if (io_status/=0)
exit
5638 write(csv_unit,
'()',iostat=io_status)
5639 if (io_status/=0)
exit
5641 if (io_status/=0)
exit
5644 if (io_status/=0)
then
5646 call mpistop(trim(caller)//
' could not write CSV data')
5649 end subroutine mt_write_fieldline_products_plane_arbitrary_csv
5651 subroutine mt_write_fieldline_products_vtu_empty(vtu_file,do_twist, &
5652 do_q,do_qperp,caller,do_length)
5653 character(len=*),
intent(in) :: vtu_file,caller
5654 logical,
intent(in) :: do_twist,do_q,do_qperp
5655 logical,
intent(in),
optional :: do_length
5657 integer :: vtu_unit,io_status
5658 logical :: do_length_eff
5660 open(newunit=vtu_unit,file=trim(vtu_file),status=
'replace', &
5661 action=
'write',form=
'formatted',iostat=io_status)
5662 if (io_status/=0)
then
5663 call mpistop(trim(caller)//
' could not open VTU file')
5666 call mt_write_vtu_file_header(vtu_unit,0,0)
5667 do_length_eff=.true.
5668 if (
present(do_length)) do_length_eff=do_length
5669 call mt_write_vtu_empty_pointdata(vtu_unit,do_length_eff,do_twist, &
5671 write(vtu_unit,
'(a)',iostat=io_status)
'<CellData>'
5672 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'</CellData>'
5673 if (io_status==0)
then
5674 write(vtu_unit,
'(a)',iostat=io_status)
'<Points>'
5676 if (io_status==0)
then
5677 write(vtu_unit,
'(a)',iostat=io_status) &
5678 '<DataArray type="Float64" NumberOfComponents="3" format="ascii">'
5680 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'</DataArray>'
5681 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'</Points>'
5682 if (io_status==0)
call mt_write_vtu_cells_empty(vtu_unit,io_status)
5683 if (io_status==0)
call mt_write_vtu_file_footer(vtu_unit,io_status)
5684 if (io_status/=0)
then
5686 call mpistop(trim(caller)//
' could not write VTU file')
5690 end subroutine mt_write_fieldline_products_vtu_empty
5692 subroutine mt_write_fieldline_products_vtu_vertices(vtu_file, &
5693 length_results,twist_results,q_results,qperp_results,npoint, &
5694 do_length,do_twist,do_q,do_qperp,caller)
5695 integer,
intent(in) :: npoint
5696 type(trace_length_result),
intent(in) :: length_results(npoint)
5697 type(trace_twist_result),
intent(in) :: twist_results(:)
5698 type(trace_qperp_result),
intent(in) :: q_results(:)
5699 type(trace_qperp_result),
intent(in) :: qperp_results(:)
5700 character(len=*),
intent(in) :: vtu_file,caller
5701 logical,
intent(in) :: do_length,do_twist,do_q,do_qperp
5703 integer :: vtu_unit,io_status
5705 open(newunit=vtu_unit,file=trim(vtu_file),status=
'replace', &
5706 action=
'write',form=
'formatted',iostat=io_status)
5707 if (io_status/=0)
then
5708 call mpistop(trim(caller)//
' could not open VTU file')
5711 call mt_write_vtu_file_header(vtu_unit,npoint,npoint)
5712 call mt_write_vtu_product_pointdata(vtu_unit,length_results, &
5713 twist_results,q_results,qperp_results,npoint,do_twist,do_q, &
5714 do_qperp,io_status,do_length=do_length)
5715 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'<CellData>'
5716 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'</CellData>'
5717 if (io_status==0)
call mt_write_vtu_points(vtu_unit,length_results, &
5719 if (io_status==0)
call mt_write_vtu_vertex_cells(vtu_unit,npoint, &
5721 if (io_status==0)
call mt_write_vtu_file_footer(vtu_unit,io_status)
5722 if (io_status/=0)
then
5724 call mpistop(trim(caller)//
' could not write VTU file')
5728 end subroutine mt_write_fieldline_products_vtu_vertices
5730 subroutine mt_write_fieldline_products_vtu_plane(vtu_file, &
5731 length_results,twist_results,q_results,qperp_results,n1,n2,do_twist, &
5732 do_q,do_qperp,caller,do_length)
5733 integer,
intent(in) :: n1,n2
5734 type(trace_length_result),
intent(in) :: length_results(n1*n2)
5735 type(trace_twist_result),
intent(in) :: twist_results(:)
5736 type(trace_qperp_result),
intent(in) :: q_results(:)
5737 type(trace_qperp_result),
intent(in) :: qperp_results(:)
5738 character(len=*),
intent(in) :: vtu_file,caller
5739 logical,
intent(in) :: do_twist,do_q,do_qperp
5740 logical,
intent(in),
optional :: do_length
5742 integer :: npoint,ncell,vtu_unit,io_status
5743 logical :: do_length_eff
5746 if (n1>1 .and. n2>1)
then
5752 open(newunit=vtu_unit,file=trim(vtu_file),status=
'replace', &
5753 action=
'write',form=
'formatted',iostat=io_status)
5754 if (io_status/=0)
then
5755 call mpistop(trim(caller)//
' could not open VTU file')
5758 call mt_write_vtu_file_header(vtu_unit,npoint,ncell)
5759 do_length_eff=.true.
5760 if (
present(do_length)) do_length_eff=do_length
5761 call mt_write_vtu_product_pointdata(vtu_unit,length_results, &
5762 twist_results,q_results,qperp_results,npoint,do_twist,do_q, &
5763 do_qperp,io_status,do_length=do_length_eff)
5764 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'<CellData>'
5765 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'</CellData>'
5766 if (io_status==0)
call mt_write_vtu_points(vtu_unit,length_results, &
5768 if (io_status==0)
then
5769 if (n1>1 .and. n2>1)
then
5770 call mt_write_vtu_quad_cells(vtu_unit,n1,n2,io_status)
5772 call mt_write_vtu_vertex_cells(vtu_unit,npoint,io_status)
5775 if (io_status==0)
call mt_write_vtu_file_footer(vtu_unit,io_status)
5776 if (io_status/=0)
then
5778 call mpistop(trim(caller)//
' could not write VTU file')
5782 end subroutine mt_write_fieldline_products_vtu_plane
5784 subroutine mt_write_qsl_plane_vtu(vtu_file,length_results,twist_results, &
5785 mapping_results,qperp_results,n1,n2,caller)
5786 integer,
intent(in) :: n1,n2
5787 type(trace_length_result),
intent(in) :: length_results(n1*n2)
5788 type(trace_twist_result),
intent(in) :: twist_results(n1*n2)
5789 type(trace_mapping_result),
intent(in) :: mapping_results(n1*n2)
5790 type(trace_qperp_result),
intent(in) :: qperp_results(n1*n2)
5791 character(len=*),
intent(in) :: vtu_file,caller
5793 integer :: npoint,ncell,vtu_unit,io_status
5796 if (n1>1 .and. n2>1)
then
5802 open(newunit=vtu_unit,file=trim(vtu_file),status=
'replace', &
5803 action=
'write',form=
'formatted',iostat=io_status)
5804 if (io_status/=0)
then
5805 call mpistop(trim(caller)//
' could not open VTU file')
5808 call mt_write_vtu_file_header(vtu_unit,npoint,ncell)
5809 call mt_write_qsl_plane_vtu_pointdata(vtu_unit,length_results, &
5810 twist_results,mapping_results,qperp_results,npoint,io_status)
5811 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'<CellData>'
5812 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'</CellData>'
5813 if (io_status==0)
call mt_write_vtu_points(vtu_unit,length_results, &
5815 if (io_status==0)
then
5816 if (n1>1 .and. n2>1)
then
5817 call mt_write_vtu_quad_cells(vtu_unit,n1,n2,io_status)
5819 call mt_write_vtu_vertex_cells(vtu_unit,npoint,io_status)
5822 if (io_status==0)
call mt_write_vtu_file_footer(vtu_unit,io_status)
5823 if (io_status/=0)
then
5825 call mpistop(trim(caller)//
' could not write VTU file')
5829 end subroutine mt_write_qsl_plane_vtu
5831 subroutine mt_write_qsl_plane_vtu_pointdata(vtu_unit,length_results, &
5832 twist_results,mapping_results,qperp_results,npoint,io_status)
5833 integer,
intent(in) :: vtu_unit,npoint
5834 type(trace_length_result),
intent(in) :: length_results(npoint)
5835 type(trace_twist_result),
intent(in) :: twist_results(npoint)
5836 type(trace_mapping_result),
intent(in) :: mapping_results(npoint)
5837 type(trace_qperp_result),
intent(in) :: qperp_results(npoint)
5838 integer,
intent(inout) :: io_status
5840 write(vtu_unit,
'(a)',iostat=io_status)
'<PointData>'
5841 if (io_status/=0)
return
5843 if (mt_vtk_detail_is_full())
then
5844 call mt_write_vtu_length_pointdata(vtu_unit,length_results,npoint, &
5846 call mt_write_vtu_twist_pointdata(vtu_unit,twist_results,npoint, &
5848 call mt_write_vtu_mapping_pointdata(vtu_unit,mapping_results,npoint, &
5850 call mt_write_vtu_q_product_pointdata(vtu_unit,qperp_results, &
5851 npoint,.true.,io_status)
5852 call mt_write_vtu_qperp_public_pointdata(vtu_unit,qperp_results, &
5854 call mt_write_vtu_qperp_method2_pointdata(vtu_unit,qperp_results, &
5857 call mt_write_vtu_qsl_minimal_pointdata(vtu_unit,length_results, &
5858 twist_results,qperp_results,npoint,io_status)
5861 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'</PointData>'
5862 end subroutine mt_write_qsl_plane_vtu_pointdata
5864 subroutine mt_write_vtu_qsl_minimal_pointdata(vtu_unit,length_results, &
5865 twist_results,qperp_results,npoint,io_status)
5866 integer,
intent(in) :: vtu_unit,npoint
5867 type(trace_length_result),
intent(in) :: length_results(npoint)
5868 type(trace_twist_result),
intent(in) :: twist_results(npoint)
5869 type(trace_qperp_result),
intent(in) :: qperp_results(npoint)
5870 integer,
intent(inout) :: io_status
5874 call mt_write_vtu_float_array_start(vtu_unit,
'length_total',io_status)
5875 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
5876 (mt_visual_float(length_results(ipoint)%total_length), &
5878 call mt_write_vtu_data_array_end(vtu_unit,io_status)
5880 call mt_write_vtu_float_array_start(vtu_unit,
'twist_total',io_status)
5881 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
5882 (mt_visual_float(twist_results(ipoint)%total_twist), &
5884 call mt_write_vtu_data_array_end(vtu_unit,io_status)
5886 call mt_write_vtu_float_array_start(vtu_unit,
'logQ',io_status)
5887 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
5888 (mt_visual_valid_float(qperp_results(ipoint)%logq0, &
5889 qperp_results(ipoint)%valid_q0),ipoint=1,npoint)
5890 call mt_write_vtu_data_array_end(vtu_unit,io_status)
5892 call mt_write_vtu_float_array_start(vtu_unit,
'logQperp',io_status)
5893 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
5894 (mt_visual_valid_float(qperp_results(ipoint)%logqperp, &
5895 qperp_results(ipoint)%valid),ipoint=1,npoint)
5896 call mt_write_vtu_data_array_end(vtu_unit,io_status)
5898 end subroutine mt_write_vtu_qsl_minimal_pointdata
5900 double precision function mt_vti_axis_spacing(xmin,xmax,n)
5901 integer,
intent(in) :: n
5902 double precision,
intent(in) :: xmin,xmax
5905 mt_vti_axis_spacing=(xmax-xmin)/dble(n-1)
5907 mt_vti_axis_spacing=0.d0
5909 end function mt_vti_axis_spacing
5911 subroutine mt_allocate_volume_products(products,nseed,do_twist,do_q, &
5913 type(mt_volume_products),
intent(inout) :: products
5914 integer,
intent(in) :: nseed
5915 logical,
intent(in) :: do_twist,do_q,do_qperp
5917 allocate(products%length_total(nseed))
5918 allocate(products%length_backward(nseed))
5919 allocate(products%length_forward(nseed))
5920 allocate(products%nstep_backward_length(nseed))
5921 allocate(products%nstep_forward_length(nseed))
5922 allocate(products%status_backward_length(nseed))
5923 allocate(products%status_forward_length(nseed))
5926 allocate(products%twist_total(nseed))
5927 allocate(products%twist_backward(nseed))
5928 allocate(products%twist_forward(nseed))
5929 allocate(products%nstep_backward_twist(nseed))
5930 allocate(products%nstep_forward_twist(nseed))
5931 allocate(products%status_backward_twist(nseed))
5932 allocate(products%status_forward_twist(nseed))
5936 allocate(products%q(nseed))
5937 allocate(products%logq(nseed))
5938 allocate(products%N2_q(nseed))
5939 allocate(products%bfactor_q(nseed))
5940 allocate(products%length_forward_q(nseed))
5941 allocate(products%length_backward_q(nseed))
5942 allocate(products%Bseed_norm_q(nseed))
5943 allocate(products%Bf_norm_q(nseed))
5944 allocate(products%Bb_norm_q(nseed))
5945 allocate(products%valid_q(nseed))
5946 allocate(products%status_q(nseed))
5947 allocate(products%face_forward_q(nseed))
5948 allocate(products%face_backward_q(nseed))
5949 allocate(products%status_forward_q(nseed))
5950 allocate(products%status_backward_q(nseed))
5954 allocate(products%qperp(nseed))
5955 allocate(products%logqperp(nseed))
5956 allocate(products%N2(nseed))
5957 allocate(products%bfactor(nseed))
5958 allocate(products%length_forward_qperp(nseed))
5959 allocate(products%length_backward_qperp(nseed))
5960 allocate(products%Bseed_norm(nseed))
5961 allocate(products%Bf_norm(nseed))
5962 allocate(products%Bb_norm(nseed))
5963 allocate(products%valid_qperp(nseed))
5964 allocate(products%status_qperp(nseed))
5965 allocate(products%face_forward_qperp(nseed))
5966 allocate(products%face_backward_qperp(nseed))
5967 allocate(products%status_forward_qperp(nseed))
5968 allocate(products%status_backward_qperp(nseed))
5970 end subroutine mt_allocate_volume_products
5972 subroutine mt_deallocate_volume_products(products)
5973 type(mt_volume_products),
intent(inout) :: products
5975 if (
allocated(products%length_total))
deallocate(products%length_total)
5976 if (
allocated(products%length_backward))
deallocate(products%length_backward)
5977 if (
allocated(products%length_forward))
deallocate(products%length_forward)
5978 if (
allocated(products%nstep_backward_length)) &
5979 deallocate(products%nstep_backward_length)
5980 if (
allocated(products%nstep_forward_length)) &
5981 deallocate(products%nstep_forward_length)
5982 if (
allocated(products%status_backward_length)) &
5983 deallocate(products%status_backward_length)
5984 if (
allocated(products%status_forward_length)) &
5985 deallocate(products%status_forward_length)
5987 if (
allocated(products%twist_total))
deallocate(products%twist_total)
5988 if (
allocated(products%twist_backward))
deallocate(products%twist_backward)
5989 if (
allocated(products%twist_forward))
deallocate(products%twist_forward)
5990 if (
allocated(products%nstep_backward_twist)) &
5991 deallocate(products%nstep_backward_twist)
5992 if (
allocated(products%nstep_forward_twist)) &
5993 deallocate(products%nstep_forward_twist)
5994 if (
allocated(products%status_backward_twist)) &
5995 deallocate(products%status_backward_twist)
5996 if (
allocated(products%status_forward_twist)) &
5997 deallocate(products%status_forward_twist)
5999 if (
allocated(products%q))
deallocate(products%q)
6000 if (
allocated(products%logq))
deallocate(products%logq)
6001 if (
allocated(products%N2_q))
deallocate(products%N2_q)
6002 if (
allocated(products%bfactor_q))
deallocate(products%bfactor_q)
6003 if (
allocated(products%length_forward_q)) &
6004 deallocate(products%length_forward_q)
6005 if (
allocated(products%length_backward_q)) &
6006 deallocate(products%length_backward_q)
6007 if (
allocated(products%Bseed_norm_q))
deallocate(products%Bseed_norm_q)
6008 if (
allocated(products%Bf_norm_q))
deallocate(products%Bf_norm_q)
6009 if (
allocated(products%Bb_norm_q))
deallocate(products%Bb_norm_q)
6010 if (
allocated(products%valid_q))
deallocate(products%valid_q)
6011 if (
allocated(products%status_q))
deallocate(products%status_q)
6012 if (
allocated(products%face_forward_q)) &
6013 deallocate(products%face_forward_q)
6014 if (
allocated(products%face_backward_q)) &
6015 deallocate(products%face_backward_q)
6016 if (
allocated(products%status_forward_q)) &
6017 deallocate(products%status_forward_q)
6018 if (
allocated(products%status_backward_q)) &
6019 deallocate(products%status_backward_q)
6021 if (
allocated(products%qperp))
deallocate(products%qperp)
6022 if (
allocated(products%logqperp))
deallocate(products%logqperp)
6023 if (
allocated(products%N2))
deallocate(products%N2)
6024 if (
allocated(products%bfactor))
deallocate(products%bfactor)
6025 if (
allocated(products%length_forward_qperp)) &
6026 deallocate(products%length_forward_qperp)
6027 if (
allocated(products%length_backward_qperp)) &
6028 deallocate(products%length_backward_qperp)
6029 if (
allocated(products%Bseed_norm))
deallocate(products%Bseed_norm)
6030 if (
allocated(products%Bf_norm))
deallocate(products%Bf_norm)
6031 if (
allocated(products%Bb_norm))
deallocate(products%Bb_norm)
6032 if (
allocated(products%valid_qperp))
deallocate(products%valid_qperp)
6033 if (
allocated(products%status_qperp))
deallocate(products%status_qperp)
6034 if (
allocated(products%face_forward_qperp)) &
6035 deallocate(products%face_forward_qperp)
6036 if (
allocated(products%face_backward_qperp)) &
6037 deallocate(products%face_backward_qperp)
6038 if (
allocated(products%status_forward_qperp)) &
6039 deallocate(products%status_forward_qperp)
6040 if (
allocated(products%status_backward_qperp)) &
6041 deallocate(products%status_backward_qperp)
6042 end subroutine mt_deallocate_volume_products
6044 subroutine mt_build_volume_slab_seeds(seeds,xmin,ymin,zmin,spacing, &
6045 nx,ny,k_start,slab_nz)
6046 double precision,
intent(out) :: seeds(:,:)
6047 double precision,
intent(in) :: xmin,ymin,zmin,spacing(3)
6048 integer,
intent(in) :: nx,ny,k_start,slab_nz
6050 integer :: i,j,k,kk,iseed
6056 iseed=(kk-1)*nx*ny+(j-1)*nx+i
6057 seeds(iseed,1)=xmin+dble(i-1)*spacing(1)
6058 seeds(iseed,2)=ymin+dble(j-1)*spacing(2)
6059 seeds(iseed,3)=zmin+dble(k-1)*spacing(3)
6063 end subroutine mt_build_volume_slab_seeds
6065 subroutine mt_copy_volume_length_slab(products,results,nx,ny,k_start, &
6067 type(mt_volume_products),
intent(inout) :: products
6068 type(trace_length_result),
intent(in) :: results(:)
6069 integer,
intent(in) :: nx,ny,k_start,slab_nz
6071 integer :: i,j,kk,k,ilocal,iglobal
6077 ilocal=(kk-1)*nx*ny+(j-1)*nx+i
6078 iglobal=(k-1)*nx*ny+(j-1)*nx+i
6079 products%length_total(iglobal)=results(ilocal)%total_length
6080 products%length_backward(iglobal)=results(ilocal)%backward_length
6081 products%length_forward(iglobal)=results(ilocal)%forward_length
6082 products%nstep_backward_length(iglobal)= &
6083 results(ilocal)%backward_nstep
6084 products%nstep_forward_length(iglobal)= &
6085 results(ilocal)%forward_nstep
6086 products%status_backward_length(iglobal)= &
6087 results(ilocal)%backward_status
6088 products%status_forward_length(iglobal)= &
6089 results(ilocal)%forward_status
6093 end subroutine mt_copy_volume_length_slab
6095 subroutine mt_copy_volume_twist_slab(products,results,nx,ny,k_start, &
6097 type(mt_volume_products),
intent(inout) :: products
6098 type(trace_twist_result),
intent(in) :: results(:)
6099 integer,
intent(in) :: nx,ny,k_start,slab_nz
6101 integer :: i,j,kk,k,ilocal,iglobal
6107 ilocal=(kk-1)*nx*ny+(j-1)*nx+i
6108 iglobal=(k-1)*nx*ny+(j-1)*nx+i
6109 products%twist_total(iglobal)=results(ilocal)%total_twist
6110 products%twist_backward(iglobal)=results(ilocal)%backward_twist
6111 products%twist_forward(iglobal)=results(ilocal)%forward_twist
6112 products%nstep_backward_twist(iglobal)= &
6113 results(ilocal)%line%backward_nstep
6114 products%nstep_forward_twist(iglobal)= &
6115 results(ilocal)%line%forward_nstep
6116 products%status_backward_twist(iglobal)= &
6117 results(ilocal)%line%backward_status
6118 products%status_forward_twist(iglobal)= &
6119 results(ilocal)%line%forward_status
6123 end subroutine mt_copy_volume_twist_slab
6125 subroutine mt_copy_volume_q_slab(products,results,nx,ny,k_start,slab_nz)
6126 type(mt_volume_products),
intent(inout) :: products
6127 type(trace_qperp_result),
intent(in) :: results(:)
6128 integer,
intent(in) :: nx,ny,k_start,slab_nz
6130 integer :: i,j,kk,k,ilocal,iglobal
6136 ilocal=(kk-1)*nx*ny+(j-1)*nx+i
6137 iglobal=(k-1)*nx*ny+(j-1)*nx+i
6138 products%q(iglobal)=results(ilocal)%q0
6139 products%logq(iglobal)=results(ilocal)%logq0
6140 products%N2_q(iglobal)=results(ilocal)%N2_qperp0
6141 products%bfactor_q(iglobal)=results(ilocal)%bfactor_qperp0
6142 products%length_forward_q(iglobal)=results(ilocal)%forward_length
6143 products%length_backward_q(iglobal)=results(ilocal)%backward_length
6144 products%Bseed_norm_q(iglobal)=dsqrt(sum(results(ilocal)%B_seed**2))
6145 products%Bf_norm_q(iglobal)=dsqrt(sum(results(ilocal)%forward_B**2))
6146 products%Bb_norm_q(iglobal)=dsqrt(sum(results(ilocal)%backward_B**2))
6147 products%valid_q(iglobal)=merge(1,0,results(ilocal)%valid_q0)
6148 products%status_q(iglobal)=results(ilocal)%status_q0
6149 products%face_forward_q(iglobal)=results(ilocal)%forward_face
6150 products%face_backward_q(iglobal)=results(ilocal)%backward_face
6151 products%status_forward_q(iglobal)=results(ilocal)%forward_status
6152 products%status_backward_q(iglobal)=results(ilocal)%backward_status
6156 end subroutine mt_copy_volume_q_slab
6158 subroutine mt_copy_volume_qperp_slab(products,results,nx,ny,k_start, &
6160 type(mt_volume_products),
intent(inout) :: products
6161 type(trace_qperp_result),
intent(in) :: results(:)
6162 integer,
intent(in) :: nx,ny,k_start,slab_nz
6164 integer :: i,j,kk,k,ilocal,iglobal
6170 ilocal=(kk-1)*nx*ny+(j-1)*nx+i
6171 iglobal=(k-1)*nx*ny+(j-1)*nx+i
6172 products%qperp(iglobal)=results(ilocal)%qperp
6173 products%logqperp(iglobal)=results(ilocal)%logqperp
6174 products%N2(iglobal)=results(ilocal)%N2
6175 products%bfactor(iglobal)=results(ilocal)%bfactor
6176 products%length_forward_qperp(iglobal)= &
6177 results(ilocal)%forward_length
6178 products%length_backward_qperp(iglobal)= &
6179 results(ilocal)%backward_length
6180 products%Bseed_norm(iglobal)=dsqrt(sum(results(ilocal)%B_seed**2))
6181 products%Bf_norm(iglobal)=dsqrt(sum(results(ilocal)%forward_B**2))
6182 products%Bb_norm(iglobal)=dsqrt(sum(results(ilocal)%backward_B**2))
6183 products%valid_qperp(iglobal)=merge(1,0,results(ilocal)%valid)
6184 products%status_qperp(iglobal)=results(ilocal)%status
6185 products%face_forward_qperp(iglobal)=results(ilocal)%forward_face
6186 products%face_backward_qperp(iglobal)=results(ilocal)%backward_face
6187 products%status_forward_qperp(iglobal)= &
6188 results(ilocal)%forward_status
6189 products%status_backward_qperp(iglobal)= &
6190 results(ilocal)%backward_status
6194 end subroutine mt_copy_volume_qperp_slab
6196 subroutine mt_build_vti_desc(desc,name,array_kind,npoint)
6197 type(mt_vti_array_desc),
intent(out) :: desc
6198 character(len=*),
intent(in) :: name
6199 integer,
intent(in) :: array_kind,npoint
6202 desc%name=trim(name)
6203 desc%kind=array_kind
6204 select case (array_kind)
6205 case (mt_vti_kind_float64)
6206 desc%nbytes=int(npoint,kind=8)*8_8
6207 case (mt_vti_kind_int32)
6208 desc%nbytes=int(npoint,kind=8)*4_8
6213 end subroutine mt_build_vti_desc
6215 subroutine mt_finalize_vti_desc_offsets(descs,ndesc)
6216 integer,
intent(in) :: ndesc
6217 type(mt_vti_array_desc),
intent(inout) :: descs(ndesc)
6220 integer(kind=8) :: offset
6224 descs(idesc)%offset=offset
6225 offset=offset+descs(idesc)%nbytes+4_8
6227 end subroutine mt_finalize_vti_desc_offsets
6229 subroutine mt_append_vti_desc(descs,idesc,name,array_kind,npoint)
6230 type(mt_vti_array_desc),
intent(inout) :: descs(:)
6231 integer,
intent(inout) :: idesc
6232 character(len=*),
intent(in) :: name
6233 integer,
intent(in) :: array_kind,npoint
6236 call mt_build_vti_desc(descs(idesc),name,array_kind,npoint)
6237 end subroutine mt_append_vti_desc
6239 subroutine mt_build_cartesian_vti_pointdata_descs(npoint,descs,ndesc)
6240 integer,
intent(in) :: npoint
6241 type(mt_vti_array_desc),
allocatable,
intent(out) :: descs(:)
6242 integer,
intent(out) :: ndesc
6245 allocate(descs(ndesc))
6246 call mt_build_vti_desc(descs(1),
'length_total',mt_vti_kind_float64, &
6248 call mt_build_vti_desc(descs(2),
'qperp',mt_vti_kind_float64,npoint)
6249 call mt_build_vti_desc(descs(3),
'status',mt_vti_kind_int32,npoint)
6250 call mt_finalize_vti_desc_offsets(descs,ndesc)
6251 end subroutine mt_build_cartesian_vti_pointdata_descs
6253 subroutine mt_build_volume_vti_descs(npoint,do_length,do_twist,do_q, &
6254 do_qperp,descs,ndesc)
6255 integer,
intent(in) :: npoint
6256 logical,
intent(in) :: do_length,do_twist,do_q,do_qperp
6257 type(mt_vti_array_desc),
allocatable,
intent(out) :: descs(:)
6258 integer,
intent(out) :: ndesc
6260 integer :: idesc,max_desc
6262 if (.not.mt_vtk_detail_is_full())
then
6264 if (do_length) max_desc=max_desc+1
6265 if (do_twist) max_desc=max_desc+1
6266 if (do_q) max_desc=max_desc+1
6267 if (do_qperp) max_desc=max_desc+1
6270 if (do_length) max_desc=max_desc+7
6271 if (do_twist) max_desc=max_desc+7
6272 if (do_q) max_desc=max_desc+15
6273 if (do_qperp) max_desc=max_desc+15
6275 allocate(descs(max_desc))
6279 call mt_append_vti_desc(descs,idesc,
'length_total', &
6280 mt_vti_kind_float64,npoint)
6282 if (.not.mt_vtk_detail_is_full())
then
6284 call mt_append_vti_desc(descs,idesc,
'twist_total', &
6285 mt_vti_kind_float64,npoint)
6288 call mt_append_vti_desc(descs,idesc,
'logQ', &
6289 mt_vti_kind_float64,npoint)
6292 call mt_append_vti_desc(descs,idesc,
'logQperp', &
6293 mt_vti_kind_float64,npoint)
6296 call mt_finalize_vti_desc_offsets(descs,ndesc)
6301 call mt_append_vti_desc(descs,idesc,
'length_backward', &
6302 mt_vti_kind_float64,npoint)
6303 call mt_append_vti_desc(descs,idesc,
'length_forward', &
6304 mt_vti_kind_float64,npoint)
6305 call mt_append_vti_desc(descs,idesc,
'nstep_backward_length', &
6306 mt_vti_kind_int32,npoint)
6307 call mt_append_vti_desc(descs,idesc,
'nstep_forward_length', &
6308 mt_vti_kind_int32,npoint)
6309 call mt_append_vti_desc(descs,idesc,
'status_backward_length', &
6310 mt_vti_kind_int32,npoint)
6311 call mt_append_vti_desc(descs,idesc,
'status_forward_length', &
6312 mt_vti_kind_int32,npoint)
6316 call mt_append_vti_desc(descs,idesc,
'twist_total', &
6317 mt_vti_kind_float64,npoint)
6318 call mt_append_vti_desc(descs,idesc,
'twist_backward', &
6319 mt_vti_kind_float64,npoint)
6320 call mt_append_vti_desc(descs,idesc,
'twist_forward', &
6321 mt_vti_kind_float64,npoint)
6322 call mt_append_vti_desc(descs,idesc,
'nstep_backward_twist', &
6323 mt_vti_kind_int32,npoint)
6324 call mt_append_vti_desc(descs,idesc,
'nstep_forward_twist', &
6325 mt_vti_kind_int32,npoint)
6326 call mt_append_vti_desc(descs,idesc,
'status_backward_twist', &
6327 mt_vti_kind_int32,npoint)
6328 call mt_append_vti_desc(descs,idesc,
'status_forward_twist', &
6329 mt_vti_kind_int32,npoint)
6333 call mt_append_vti_desc(descs,idesc,
'q',mt_vti_kind_float64,npoint)
6334 call mt_append_vti_desc(descs,idesc,
'logq', &
6335 mt_vti_kind_float64,npoint)
6336 call mt_append_vti_desc(descs,idesc,
'N2_q',mt_vti_kind_float64,npoint)
6337 call mt_append_vti_desc(descs,idesc,
'bfactor_q', &
6338 mt_vti_kind_float64,npoint)
6339 call mt_append_vti_desc(descs,idesc,
'length_forward_q', &
6340 mt_vti_kind_float64,npoint)
6341 call mt_append_vti_desc(descs,idesc,
'length_backward_q', &
6342 mt_vti_kind_float64,npoint)
6343 call mt_append_vti_desc(descs,idesc,
'Bseed_norm_q', &
6344 mt_vti_kind_float64,npoint)
6345 call mt_append_vti_desc(descs,idesc,
'Bf_norm_q', &
6346 mt_vti_kind_float64,npoint)
6347 call mt_append_vti_desc(descs,idesc,
'Bb_norm_q', &
6348 mt_vti_kind_float64,npoint)
6349 call mt_append_vti_desc(descs,idesc,
'valid_Q', &
6350 mt_vti_kind_int32,npoint)
6351 call mt_append_vti_desc(descs,idesc,
'status_Q', &
6352 mt_vti_kind_int32,npoint)
6353 call mt_append_vti_desc(descs,idesc,
'face_forward_Q', &
6354 mt_vti_kind_int32,npoint)
6355 call mt_append_vti_desc(descs,idesc,
'face_backward_Q', &
6356 mt_vti_kind_int32,npoint)
6357 call mt_append_vti_desc(descs,idesc,
'status_forward_Q', &
6358 mt_vti_kind_int32,npoint)
6359 call mt_append_vti_desc(descs,idesc,
'status_backward_Q', &
6360 mt_vti_kind_int32,npoint)
6364 call mt_append_vti_desc(descs,idesc,
'qperp', &
6365 mt_vti_kind_float64,npoint)
6366 call mt_append_vti_desc(descs,idesc,
'logqperp', &
6367 mt_vti_kind_float64,npoint)
6368 call mt_append_vti_desc(descs,idesc,
'N2',mt_vti_kind_float64, &
6370 call mt_append_vti_desc(descs,idesc,
'bfactor', &
6371 mt_vti_kind_float64,npoint)
6372 call mt_append_vti_desc(descs,idesc,
'length_forward_qperp', &
6373 mt_vti_kind_float64,npoint)
6374 call mt_append_vti_desc(descs,idesc,
'length_backward_qperp', &
6375 mt_vti_kind_float64,npoint)
6376 call mt_append_vti_desc(descs,idesc,
'Bseed_norm', &
6377 mt_vti_kind_float64,npoint)
6378 call mt_append_vti_desc(descs,idesc,
'Bf_norm', &
6379 mt_vti_kind_float64,npoint)
6380 call mt_append_vti_desc(descs,idesc,
'Bb_norm', &
6381 mt_vti_kind_float64,npoint)
6382 call mt_append_vti_desc(descs,idesc,
'valid_qperp', &
6383 mt_vti_kind_int32,npoint)
6384 call mt_append_vti_desc(descs,idesc,
'status_qperp', &
6385 mt_vti_kind_int32,npoint)
6386 call mt_append_vti_desc(descs,idesc,
'face_forward_qperp', &
6387 mt_vti_kind_int32,npoint)
6388 call mt_append_vti_desc(descs,idesc,
'face_backward_qperp', &
6389 mt_vti_kind_int32,npoint)
6390 call mt_append_vti_desc(descs,idesc,
'status_forward_qperp', &
6391 mt_vti_kind_int32,npoint)
6392 call mt_append_vti_desc(descs,idesc,
'status_backward_qperp', &
6393 mt_vti_kind_int32,npoint)
6397 call mt_finalize_vti_desc_offsets(descs,ndesc)
6398 end subroutine mt_build_volume_vti_descs
6400 character(len=8) function mt_vti_type_name(array_kind)
6401 integer,
intent(in) :: array_kind
6403 select case (array_kind)
6404 case (mt_vti_kind_float64)
6405 mt_vti_type_name=
'Float64'
6406 case (mt_vti_kind_int32)
6407 mt_vti_type_name=
'Int32'
6409 mt_vti_type_name=
'Unknown'
6411 end function mt_vti_type_name
6413 subroutine mt_write_vti_image_header(vti_unit,origin,spacing,nx,ny,nz, &
6414 descs,ndesc,io_status)
6415 integer,
intent(in) :: vti_unit,nx,ny,nz,ndesc
6416 double precision,
intent(in) :: origin(3),spacing(3)
6417 type(mt_vti_array_desc),
intent(in) :: descs(ndesc)
6418 integer,
intent(out) :: io_status
6420 integer :: extent(6),idesc
6422 extent=(/ 0,nx-1,0,ny-1,0,nz-1 /)
6423 write(vti_unit,
'(a)',iostat=io_status)
'<?xml version="1.0"?>'
6424 if (io_status/=0)
return
6425 write(vti_unit,
'(a)',iostat=io_status) &
6426 '<VTKFile type="ImageData" version="0.1" byte_order="LittleEndian">'
6427 if (io_status/=0)
return
6428 write(vti_unit,
'(a,3(1pe24.16),a,6(i0,1x),a,3(1pe24.16),a)', &
6429 iostat=io_status)
' <ImageData Origin="',origin, &
6430 '" WholeExtent="',extent,
'" Spacing="',spacing,
'">'
6431 if (io_status/=0)
return
6432 write(vti_unit,
'(a,6(i0,1x),a)',iostat=io_status) &
6433 ' <Piece Extent="',extent,
'">'
6434 if (io_status/=0)
return
6435 write(vti_unit,
'(a)',iostat=io_status)
' <PointData>'
6436 if (io_status/=0)
return
6439 call mt_write_vti_appended_array(vti_unit, &
6440 mt_vti_type_name(descs(idesc)%kind),trim(descs(idesc)%name), &
6441 descs(idesc)%offset,io_status)
6442 if (io_status/=0)
return
6445 write(vti_unit,
'(a)',iostat=io_status)
' </PointData>'
6446 if (io_status/=0)
return
6447 write(vti_unit,
'(a)',iostat=io_status)
' </Piece>'
6448 if (io_status/=0)
return
6449 write(vti_unit,
'(a)',iostat=io_status)
' </ImageData>'
6450 if (io_status/=0)
return
6451 write(vti_unit,
'(a)',iostat=io_status)
'<AppendedData encoding="raw">'
6452 end subroutine mt_write_vti_image_header
6454 subroutine mt_write_fieldline_products_volume_vti(vti_file,origin, &
6455 spacing,nx,ny,nz,products,do_length,do_twist,do_q,do_qperp,caller)
6456 integer,
intent(in) :: nx,ny,nz
6457 double precision,
intent(in) :: origin(3),spacing(3)
6458 type(mt_volume_products),
intent(in) :: products
6459 logical,
intent(in) :: do_length,do_twist,do_q,do_qperp
6460 character(len=*),
intent(in) :: vti_file,caller
6462 integer :: vti_unit,io_status,npoint
6463 character(len=1) :: marker
6464 type(mt_vti_array_desc),
allocatable :: descs(:)
6468 call mt_check_vti_byte_count(npoint,caller)
6469 call mt_build_volume_vti_descs(npoint,do_length,do_twist,do_q, &
6470 do_qperp,descs,ndesc)
6472 open(newunit=vti_unit,file=trim(vti_file),status=
'replace', &
6473 action=
'write',form=
'formatted',iostat=io_status)
6474 if (io_status/=0)
then
6475 call mpistop(trim(caller)//
' could not open VTI file')
6478 call mt_write_vti_image_header(vti_unit,origin,spacing,nx,ny,nz, &
6479 descs,ndesc,io_status)
6480 if (io_status/=0)
then
6482 call mpistop(trim(caller)//
' could not write VTI header')
6486 open(newunit=vti_unit,file=trim(vti_file),access=
'stream', &
6487 form=
'unformatted',status=
'old',position=
'append', &
6488 action=
'write',iostat=io_status)
6489 if (io_status/=0)
then
6490 call mpistop(trim(caller)//
' could not append VTI payload')
6494 write(vti_unit,iostat=io_status) marker
6495 if (io_status==0)
then
6496 call mt_write_volume_vti_payload(vti_unit,products,npoint,descs, &
6500 if (io_status/=0)
then
6501 call mpistop(trim(caller)//
' could not write VTI payload')
6504 open(newunit=vti_unit,file=trim(vti_file),status=
'old', &
6505 action=
'write',form=
'formatted',position=
'append',iostat=io_status)
6506 if (io_status/=0)
then
6507 call mpistop(trim(caller)//
' could not append VTI footer')
6509 write(vti_unit,
'(a)',iostat=io_status)
'</AppendedData>'
6510 if (io_status==0)
write(vti_unit,
'(a)',iostat=io_status)
'</VTKFile>'
6512 if (io_status/=0)
then
6513 call mpistop(trim(caller)//
' could not write VTI footer')
6516 end subroutine mt_write_fieldline_products_volume_vti
6518 subroutine mt_write_volume_vti_payload(vti_unit,products,npoint,descs, &
6520 integer,
intent(in) :: vti_unit,npoint,ndesc
6521 type(mt_volume_products),
intent(in) :: products
6522 type(mt_vti_array_desc),
intent(in) :: descs(ndesc)
6523 integer,
intent(inout) :: io_status
6528 select case (trim(descs(idesc)%name))
6529 case (
'length_total')
6530 if (mt_vtk_detail_is_full())
then
6531 call mt_write_vti_payload_float64(vti_unit,products%length_total, &
6534 call mt_write_vti_payload_float64_visual(vti_unit, &
6535 products%length_total,npoint,io_status)
6537 case (
'length_backward')
6538 call mt_write_vti_payload_float64(vti_unit,products%length_backward, &
6540 case (
'length_forward')
6541 call mt_write_vti_payload_float64(vti_unit,products%length_forward, &
6543 case (
'nstep_backward_length')
6544 call mt_write_vti_payload_int32(vti_unit, &
6545 products%nstep_backward_length,npoint,io_status)
6546 case (
'nstep_forward_length')
6547 call mt_write_vti_payload_int32(vti_unit, &
6548 products%nstep_forward_length,npoint,io_status)
6549 case (
'status_backward_length')
6550 call mt_write_vti_payload_int32(vti_unit, &
6551 products%status_backward_length,npoint,io_status)
6552 case (
'status_forward_length')
6553 call mt_write_vti_payload_int32(vti_unit, &
6554 products%status_forward_length,npoint,io_status)
6555 case (
'twist_total')
6556 if (mt_vtk_detail_is_full())
then
6557 call mt_write_vti_payload_float64(vti_unit,products%twist_total, &
6560 call mt_write_vti_payload_float64_visual(vti_unit, &
6561 products%twist_total,npoint,io_status)
6563 case (
'twist_backward')
6564 call mt_write_vti_payload_float64(vti_unit,products%twist_backward, &
6566 case (
'twist_forward')
6567 call mt_write_vti_payload_float64(vti_unit,products%twist_forward, &
6569 case (
'nstep_backward_twist')
6570 call mt_write_vti_payload_int32(vti_unit, &
6571 products%nstep_backward_twist,npoint,io_status)
6572 case (
'nstep_forward_twist')
6573 call mt_write_vti_payload_int32(vti_unit, &
6574 products%nstep_forward_twist,npoint,io_status)
6575 case (
'status_backward_twist')
6576 call mt_write_vti_payload_int32(vti_unit, &
6577 products%status_backward_twist,npoint,io_status)
6578 case (
'status_forward_twist')
6579 call mt_write_vti_payload_int32(vti_unit, &
6580 products%status_forward_twist,npoint,io_status)
6582 call mt_write_vti_payload_float64(vti_unit,products%q,npoint, &
6585 call mt_write_vti_payload_float64(vti_unit,products%logq,npoint, &
6588 call mt_write_vti_payload_logq_visual(vti_unit,products,npoint, &
6591 call mt_write_vti_payload_float64(vti_unit,products%N2_q,npoint, &
6594 call mt_write_vti_payload_float64(vti_unit,products%bfactor_q, &
6596 case (
'length_forward_q')
6597 call mt_write_vti_payload_float64(vti_unit, &
6598 products%length_forward_q,npoint,io_status)
6599 case (
'length_backward_q')
6600 call mt_write_vti_payload_float64(vti_unit, &
6601 products%length_backward_q,npoint,io_status)
6602 case (
'Bseed_norm_q')
6603 call mt_write_vti_payload_float64(vti_unit,products%Bseed_norm_q, &
6606 call mt_write_vti_payload_float64(vti_unit,products%Bf_norm_q,npoint, &
6609 call mt_write_vti_payload_float64(vti_unit,products%Bb_norm_q,npoint, &
6612 call mt_write_vti_payload_int32(vti_unit,products%valid_q,npoint, &
6615 call mt_write_vti_payload_int32(vti_unit,products%status_q,npoint, &
6617 case (
'face_forward_Q')
6618 call mt_write_vti_payload_int32(vti_unit,products%face_forward_q, &
6620 case (
'face_backward_Q')
6621 call mt_write_vti_payload_int32(vti_unit,products%face_backward_q, &
6623 case (
'status_forward_Q')
6624 call mt_write_vti_payload_int32(vti_unit,products%status_forward_q, &
6626 case (
'status_backward_Q')
6627 call mt_write_vti_payload_int32(vti_unit,products%status_backward_q, &
6630 call mt_write_vti_payload_float64(vti_unit,products%qperp,npoint, &
6633 call mt_write_vti_payload_float64(vti_unit,products%logqperp, &
6636 call mt_write_vti_payload_logqperp_visual(vti_unit,products,npoint, &
6639 call mt_write_vti_payload_float64(vti_unit,products%N2,npoint, &
6642 call mt_write_vti_payload_float64(vti_unit,products%bfactor,npoint, &
6644 case (
'length_forward_qperp')
6645 call mt_write_vti_payload_float64(vti_unit, &
6646 products%length_forward_qperp,npoint,io_status)
6647 case (
'length_backward_qperp')
6648 call mt_write_vti_payload_float64(vti_unit, &
6649 products%length_backward_qperp,npoint,io_status)
6651 call mt_write_vti_payload_float64(vti_unit,products%Bseed_norm, &
6654 call mt_write_vti_payload_float64(vti_unit,products%Bf_norm,npoint, &
6657 call mt_write_vti_payload_float64(vti_unit,products%Bb_norm,npoint, &
6659 case (
'valid_qperp')
6660 call mt_write_vti_payload_int32(vti_unit,products%valid_qperp, &
6662 case (
'valid_Qperp')
6663 call mt_write_vti_payload_int32(vti_unit,products%valid_qperp, &
6665 case (
'status_qperp')
6666 call mt_write_vti_payload_int32(vti_unit,products%status_qperp, &
6668 case (
'status_Qperp')
6669 call mt_write_vti_payload_int32(vti_unit,products%status_qperp, &
6671 case (
'face_forward_qperp')
6672 call mt_write_vti_payload_int32(vti_unit, &
6673 products%face_forward_qperp,npoint,io_status)
6674 case (
'face_backward_qperp')
6675 call mt_write_vti_payload_int32(vti_unit, &
6676 products%face_backward_qperp,npoint,io_status)
6677 case (
'status_forward_qperp')
6678 call mt_write_vti_payload_int32(vti_unit, &
6679 products%status_forward_qperp,npoint,io_status)
6680 case (
'status_backward_qperp')
6681 call mt_write_vti_payload_int32(vti_unit, &
6682 products%status_backward_qperp,npoint,io_status)
6686 if (io_status/=0)
exit
6688 end subroutine mt_write_volume_vti_payload
6690 subroutine mt_write_vti_payload_logq_visual(vti_unit,products,npoint, &
6692 integer,
intent(in) :: vti_unit,npoint
6693 type(mt_volume_products),
intent(in) :: products
6694 integer,
intent(inout) :: io_status
6696 double precision,
allocatable :: visual_values(:)
6699 allocate(visual_values(npoint))
6701 visual_values(ipoint)=mt_visual_valid_float(products%logq(ipoint), &
6702 products%valid_q(ipoint)==1)
6704 call mt_write_vti_payload_float64(vti_unit,visual_values,npoint, &
6706 deallocate(visual_values)
6707 end subroutine mt_write_vti_payload_logq_visual
6709 subroutine mt_write_vti_payload_float64_visual(vti_unit,values,npoint, &
6711 integer,
intent(in) :: vti_unit,npoint
6712 double precision,
intent(in) :: values(npoint)
6713 integer,
intent(inout) :: io_status
6715 double precision,
allocatable :: visual_values(:)
6718 if (io_status/=0)
return
6719 allocate(visual_values(npoint))
6721 visual_values(ipoint)=mt_visual_float(values(ipoint))
6723 call mt_write_vti_payload_float64(vti_unit,visual_values,npoint, &
6725 deallocate(visual_values)
6726 end subroutine mt_write_vti_payload_float64_visual
6728 subroutine mt_write_vti_payload_logqperp_visual(vti_unit,products,npoint, &
6730 integer,
intent(in) :: vti_unit,npoint
6731 type(mt_volume_products),
intent(in) :: products
6732 integer,
intent(inout) :: io_status
6734 double precision,
allocatable :: visual_values(:)
6737 if (io_status/=0)
return
6738 allocate(visual_values(npoint))
6740 visual_values(ipoint)=mt_visual_valid_float(products%logqperp(ipoint), &
6741 products%valid_qperp(ipoint)==1)
6743 call mt_write_vti_payload_float64(vti_unit,visual_values,npoint, &
6745 deallocate(visual_values)
6746 end subroutine mt_write_vti_payload_logqperp_visual
6748 subroutine mt_check_vti_byte_count(npoint,caller)
6749 integer,
intent(in) :: npoint
6750 character(len=*),
intent(in) :: caller
6752 if (int(npoint,kind=8)*8_8>int(huge(0),kind=8))
then
6753 call mpistop(trim(caller)//
' exceeds 32-bit VTI byte count')
6755 end subroutine mt_check_vti_byte_count
6757 subroutine mt_write_vti_payload_float64(vti_unit,values,npoint,io_status)
6758 integer,
intent(in) :: vti_unit,npoint
6759 double precision,
intent(in) :: values(npoint)
6760 integer,
intent(inout) :: io_status
6762 integer :: byte_count
6764 if (io_status/=0)
return
6766 write(vti_unit,iostat=io_status) byte_count
6767 if (io_status==0)
write(vti_unit,iostat=io_status) values
6768 end subroutine mt_write_vti_payload_float64
6770 subroutine mt_write_vti_payload_int32(vti_unit,values,npoint,io_status)
6771 integer,
intent(in) :: vti_unit,npoint
6772 integer,
intent(in) :: values(npoint)
6773 integer,
intent(inout) :: io_status
6775 integer :: byte_count
6777 if (io_status/=0)
return
6779 write(vti_unit,iostat=io_status) byte_count
6780 if (io_status==0)
write(vti_unit,iostat=io_status) values
6781 end subroutine mt_write_vti_payload_int32
6783 subroutine mt_write_vti_pointdata_fixed(vti_file,origin,spacing,nx,ny,nz, &
6784 length_total,qperp,status,caller)
6785 character(len=*),
intent(in) :: vti_file,caller
6786 integer,
intent(in) :: nx,ny,nz
6787 double precision,
intent(in) :: origin(3),spacing(3)
6788 double precision,
intent(in) :: length_total(nx*ny*nz),qperp(nx*ny*nz)
6789 integer,
intent(in) :: status(nx*ny*nz)
6791 integer :: vti_unit,io_status,npoint
6792 integer :: idesc,ndesc
6793 character(len=1) :: marker
6794 type(mt_vti_array_desc),
allocatable :: descs(:)
6797 call mt_check_vti_byte_count(npoint,caller)
6798 call mt_build_cartesian_vti_pointdata_descs(npoint,descs,ndesc)
6800 open(newunit=vti_unit,file=trim(vti_file),status=
'replace', &
6801 action=
'write',form=
'formatted',iostat=io_status)
6802 if (io_status/=0)
then
6803 call mpistop(trim(caller)//
' could not open VTI file')
6806 call mt_write_vti_image_header(vti_unit,origin,spacing,nx,ny,nz, &
6807 descs,ndesc,io_status)
6808 if (io_status/=0)
then
6810 call mpistop(trim(caller)//
' could not write VTI header')
6814 open(newunit=vti_unit,file=trim(vti_file),access=
'stream', &
6815 form=
'unformatted',status=
'old',position=
'append', &
6816 action=
'write',iostat=io_status)
6817 if (io_status/=0)
then
6818 call mpistop(trim(caller)//
' could not append VTI payload')
6822 write(vti_unit,iostat=io_status) marker
6824 if (io_status/=0)
exit
6825 select case (trim(descs(idesc)%name))
6826 case (
'length_total')
6827 call mt_write_vti_payload_float64(vti_unit,length_total,npoint, &
6830 call mt_write_vti_payload_float64(vti_unit,qperp,npoint,io_status)
6832 call mt_write_vti_payload_int32(vti_unit,status,npoint,io_status)
6838 if (io_status/=0)
then
6839 call mpistop(trim(caller)//
' could not write VTI payload')
6842 open(newunit=vti_unit,file=trim(vti_file),status=
'old', &
6843 action=
'write',form=
'formatted',position=
'append',iostat=io_status)
6844 if (io_status/=0)
then
6845 call mpistop(trim(caller)//
' could not append VTI footer')
6847 write(vti_unit,
'(a)',iostat=io_status)
'</AppendedData>'
6848 if (io_status==0)
write(vti_unit,
'(a)',iostat=io_status)
'</VTKFile>'
6850 if (io_status/=0)
then
6851 call mpistop(trim(caller)//
' could not write VTI footer')
6854 end subroutine mt_write_vti_pointdata_fixed
6856 subroutine mt_write_vti_appended_array(vti_unit,vtk_type,name,offset, &
6858 integer,
intent(in) :: vti_unit
6859 character(len=*),
intent(in) :: vtk_type,name
6860 integer(kind=8),
intent(in) :: offset
6861 integer,
intent(out) :: io_status
6863 write(vti_unit,
'(a)',advance=
'no',iostat=io_status) &
6864 ' <DataArray type="'
6865 if (io_status==0)
write(vti_unit,
'(a)',advance=
'no', &
6866 iostat=io_status) trim(vtk_type)
6867 if (io_status==0)
write(vti_unit,
'(a)',advance=
'no', &
6868 iostat=io_status)
'" Name="'
6869 if (io_status==0)
write(vti_unit,
'(a)',advance=
'no', &
6870 iostat=io_status) trim(name)
6871 if (io_status==0)
write(vti_unit,
'(a)',advance=
'no', &
6872 iostat=io_status)
'" format="appended" offset="'
6873 if (io_status==0)
write(vti_unit,
'(i0)',advance=
'no', &
6874 iostat=io_status) offset
6875 if (io_status==0)
write(vti_unit,
'(a)',iostat=io_status)
'"/>'
6876 end subroutine mt_write_vti_appended_array
6878 subroutine mt_write_vtu_length_pointdata(vtu_unit,length_results,npoint, &
6880 integer,
intent(in) :: vtu_unit,npoint
6881 type(trace_length_result),
intent(in) :: length_results(npoint)
6882 integer,
intent(inout) :: io_status
6886 call mt_write_vtu_float_array_start(vtu_unit,
'length_total',io_status)
6887 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
6888 (length_results(ipoint)%total_length,ipoint=1,npoint)
6889 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6890 call mt_write_vtu_float_array_start(vtu_unit,
'length_backward', &
6892 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
6893 (length_results(ipoint)%backward_length,ipoint=1,npoint)
6894 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6895 call mt_write_vtu_float_array_start(vtu_unit,
'length_forward', &
6897 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
6898 (length_results(ipoint)%forward_length,ipoint=1,npoint)
6899 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6901 call mt_write_vtu_int_array_start(vtu_unit,
'nstep_backward_length', &
6903 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
6904 (length_results(ipoint)%backward_nstep,ipoint=1,npoint)
6905 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6906 call mt_write_vtu_int_array_start(vtu_unit,
'nstep_forward_length', &
6908 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
6909 (length_results(ipoint)%forward_nstep,ipoint=1,npoint)
6910 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6911 call mt_write_vtu_int_array_start(vtu_unit,
'status_backward_length', &
6913 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
6914 (length_results(ipoint)%backward_status,ipoint=1,npoint)
6915 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6916 call mt_write_vtu_int_array_start(vtu_unit,
'status_forward_length', &
6918 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
6919 (length_results(ipoint)%forward_status,ipoint=1,npoint)
6920 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6921 end subroutine mt_write_vtu_length_pointdata
6923 subroutine mt_write_vtu_mapping_pointdata(vtu_unit,mapping_results, &
6925 integer,
intent(in) :: vtu_unit,npoint
6926 type(trace_mapping_result),
intent(in) :: mapping_results(npoint)
6927 integer,
intent(inout) :: io_status
6931 call mt_write_vtu_float_array_start(vtu_unit,
'x_f_mapping',io_status)
6932 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
6933 (mt_vc(mapping_results(ipoint)%forward_footpoint,1),ipoint=1,npoint)
6934 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6935 call mt_write_vtu_float_array_start(vtu_unit,
'y_f_mapping',io_status)
6936 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
6937 (mt_vc(mapping_results(ipoint)%forward_footpoint,2),ipoint=1,npoint)
6938 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6939 call mt_write_vtu_float_array_start(vtu_unit,
'z_f_mapping',io_status)
6940 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
6941 (mt_vc(mapping_results(ipoint)%forward_footpoint,3),ipoint=1,npoint)
6942 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6943 call mt_write_vtu_float_array_start(vtu_unit,
'x_b_mapping',io_status)
6944 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
6945 (mt_vc(mapping_results(ipoint)%backward_footpoint,1),ipoint=1,npoint)
6946 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6947 call mt_write_vtu_float_array_start(vtu_unit,
'y_b_mapping',io_status)
6948 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
6949 (mt_vc(mapping_results(ipoint)%backward_footpoint,2),ipoint=1,npoint)
6950 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6951 call mt_write_vtu_float_array_start(vtu_unit,
'z_b_mapping',io_status)
6952 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
6953 (mt_vc(mapping_results(ipoint)%backward_footpoint,3),ipoint=1,npoint)
6954 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6956 call mt_write_vtu_float_array_start(vtu_unit,
'source_Bn_mapping', &
6958 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
6959 (mapping_results(ipoint)%source_Bn,ipoint=1,npoint)
6960 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6961 call mt_write_vtu_float_array_start(vtu_unit,
'forward_Bn_mapping', &
6963 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
6964 (mapping_results(ipoint)%forward_Bn,ipoint=1,npoint)
6965 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6966 call mt_write_vtu_float_array_start(vtu_unit,
'backward_Bn_mapping', &
6968 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
6969 (mapping_results(ipoint)%backward_Bn,ipoint=1,npoint)
6970 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6972 call mt_write_vtu_int_array_start(vtu_unit,
'face_forward_mapping', &
6974 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
6975 (mapping_results(ipoint)%forward_face,ipoint=1,npoint)
6976 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6977 call mt_write_vtu_int_array_start(vtu_unit,
'face_backward_mapping', &
6979 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
6980 (mapping_results(ipoint)%backward_face,ipoint=1,npoint)
6981 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6982 call mt_write_vtu_int_array_start(vtu_unit,
'status_forward_mapping', &
6984 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
6985 (mapping_results(ipoint)%forward_status,ipoint=1,npoint)
6986 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6987 call mt_write_vtu_int_array_start(vtu_unit,
'status_backward_mapping', &
6989 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
6990 (mapping_results(ipoint)%backward_status,ipoint=1,npoint)
6991 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6992 call mt_write_vtu_int_array_start(vtu_unit,
'valid_mapping',io_status)
6993 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
6994 (merge(1,0,mapping_results(ipoint)%valid),ipoint=1,npoint)
6995 call mt_write_vtu_data_array_end(vtu_unit,io_status)
6996 end subroutine mt_write_vtu_mapping_pointdata
6998 subroutine mt_write_vtu_qperp_public_pointdata(vtu_unit,qperp_results, &
7000 integer,
intent(in) :: vtu_unit,npoint
7001 type(trace_qperp_result),
intent(in) :: qperp_results(npoint)
7002 integer,
intent(inout) :: io_status
7006 call mt_write_vtu_float_array_start(vtu_unit,
'logQperp',io_status)
7007 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7008 (mt_visual_valid_float(qperp_results(ipoint)%logqperp, &
7009 qperp_results(ipoint)%valid),ipoint=1,npoint)
7010 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7011 call mt_write_vtu_int_array_start(vtu_unit,
'valid_Qperp',io_status)
7012 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7013 (merge(1,0,qperp_results(ipoint)%valid),ipoint=1,npoint)
7014 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7015 call mt_write_vtu_int_array_start(vtu_unit,
'status_Qperp',io_status)
7016 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7017 (qperp_results(ipoint)%status,ipoint=1,npoint)
7018 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7019 end subroutine mt_write_vtu_qperp_public_pointdata
7021 subroutine mt_write_vtu_qperp_method2_pointdata(vtu_unit,qperp_results, &
7023 integer,
intent(in) :: vtu_unit,npoint
7024 type(trace_qperp_result),
intent(in) :: qperp_results(npoint)
7025 integer,
intent(inout) :: io_status
7029 call mt_write_vtu_float_array_start(vtu_unit,
'qperp_method2',io_status)
7030 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7031 (qperp_results(ipoint)%qperp,ipoint=1,npoint)
7032 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7033 call mt_write_vtu_float_array_start(vtu_unit,
'logqperp_method2', &
7035 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7036 (qperp_results(ipoint)%logqperp,ipoint=1,npoint)
7037 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7038 call mt_write_vtu_float_array_start(vtu_unit,
'N2_qperp',io_status)
7039 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7040 (qperp_results(ipoint)%N2,ipoint=1,npoint)
7041 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7042 call mt_write_vtu_float_array_start(vtu_unit,
'bfactor_qperp',io_status)
7043 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7044 (qperp_results(ipoint)%bfactor,ipoint=1,npoint)
7045 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7046 call mt_write_vtu_float_array_start(vtu_unit,
'length_forward_qperp', &
7048 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7049 (qperp_results(ipoint)%forward_length,ipoint=1,npoint)
7050 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7051 call mt_write_vtu_float_array_start(vtu_unit,
'length_backward_qperp', &
7053 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7054 (qperp_results(ipoint)%backward_length,ipoint=1,npoint)
7055 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7057 call mt_write_vtu_float_array_start(vtu_unit,
'Bseed_norm_qperp', &
7059 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7060 (dsqrt(sum(qperp_results(ipoint)%B_seed**2)),ipoint=1,npoint)
7061 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7062 call mt_write_vtu_float_array_start(vtu_unit,
'Bf_norm_qperp',io_status)
7063 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7064 (dsqrt(sum(qperp_results(ipoint)%forward_B**2)),ipoint=1,npoint)
7065 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7066 call mt_write_vtu_float_array_start(vtu_unit,
'Bb_norm_qperp',io_status)
7067 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7068 (dsqrt(sum(qperp_results(ipoint)%backward_B**2)),ipoint=1,npoint)
7069 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7071 call mt_write_vtu_float_array_start(vtu_unit,
'x_f_qperp',io_status)
7072 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7073 (mt_vc(qperp_results(ipoint)%forward_endpoint,1),ipoint=1,npoint)
7074 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7075 call mt_write_vtu_float_array_start(vtu_unit,
'y_f_qperp',io_status)
7076 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7077 (mt_vc(qperp_results(ipoint)%forward_endpoint,2),ipoint=1,npoint)
7078 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7079 call mt_write_vtu_float_array_start(vtu_unit,
'z_f_qperp',io_status)
7080 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7081 (mt_vc(qperp_results(ipoint)%forward_endpoint,3),ipoint=1,npoint)
7082 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7083 call mt_write_vtu_float_array_start(vtu_unit,
'x_b_qperp',io_status)
7084 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7085 (mt_vc(qperp_results(ipoint)%backward_endpoint,1),ipoint=1,npoint)
7086 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7087 call mt_write_vtu_float_array_start(vtu_unit,
'y_b_qperp',io_status)
7088 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7089 (mt_vc(qperp_results(ipoint)%backward_endpoint,2),ipoint=1,npoint)
7090 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7091 call mt_write_vtu_float_array_start(vtu_unit,
'z_b_qperp',io_status)
7092 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7093 (mt_vc(qperp_results(ipoint)%backward_endpoint,3),ipoint=1,npoint)
7094 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7096 call mt_write_vtu_int_array_start(vtu_unit,
'valid_qperp_method2', &
7098 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7099 (merge(1,0,qperp_results(ipoint)%valid),ipoint=1,npoint)
7100 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7101 call mt_write_vtu_int_array_start(vtu_unit,
'status_qperp_method2', &
7103 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7104 (qperp_results(ipoint)%status,ipoint=1,npoint)
7105 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7106 call mt_write_vtu_int_array_start(vtu_unit,
'face_forward_qperp', &
7108 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7109 (qperp_results(ipoint)%forward_face,ipoint=1,npoint)
7110 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7111 call mt_write_vtu_int_array_start(vtu_unit,
'face_backward_qperp', &
7113 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7114 (qperp_results(ipoint)%backward_face,ipoint=1,npoint)
7115 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7116 call mt_write_vtu_int_array_start(vtu_unit,
'status_forward_qperp', &
7118 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7119 (qperp_results(ipoint)%forward_status,ipoint=1,npoint)
7120 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7121 call mt_write_vtu_int_array_start(vtu_unit,
'status_backward_qperp', &
7123 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7124 (qperp_results(ipoint)%backward_status,ipoint=1,npoint)
7125 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7126 end subroutine mt_write_vtu_qperp_method2_pointdata
7128 subroutine mt_write_vtu_q_product_pointdata(vtu_unit,qperp_results, &
7129 npoint,write_raw_q,io_status)
7130 integer,
intent(in) :: vtu_unit,npoint
7131 type(trace_qperp_result),
intent(in) :: qperp_results(npoint)
7132 logical,
intent(in) :: write_raw_q
7133 integer,
intent(inout) :: io_status
7137 if (write_raw_q)
then
7138 call mt_write_vtu_float_array_start(vtu_unit,
'q',io_status)
7139 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7140 (qperp_results(ipoint)%q0,ipoint=1,npoint)
7141 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7144 call mt_write_vtu_float_array_start(vtu_unit,
'logQ',io_status)
7145 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7146 (mt_visual_valid_float(qperp_results(ipoint)%logq0, &
7147 qperp_results(ipoint)%valid_q0),ipoint=1,npoint)
7148 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7149 call mt_write_vtu_int_array_start(vtu_unit,
'valid_Q',io_status)
7150 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7151 (merge(1,0,qperp_results(ipoint)%valid_q0),ipoint=1,npoint)
7152 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7153 call mt_write_vtu_int_array_start(vtu_unit,
'status_Q',io_status)
7154 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7155 (qperp_results(ipoint)%status_q0,ipoint=1,npoint)
7156 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7157 call mt_write_vtu_int_array_start(vtu_unit,
'face_pair_Q',io_status)
7158 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7159 (mt_q_result_face_pair(qperp_results(ipoint)),ipoint=1,npoint)
7160 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7161 call mt_write_vtu_int_array_start(vtu_unit,
'connection_type_Q', &
7163 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7164 (mt_q_result_connection_type(qperp_results(ipoint)),ipoint=1,npoint)
7165 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7166 end subroutine mt_write_vtu_q_product_pointdata
7168 subroutine mt_write_vtu_spherical_topology_pointdata(vtu_unit,topology, &
7169 npoint,do_twist,do_q,q_results,do_qperp,qperp_results,io_status)
7170 integer,
intent(in) :: vtu_unit,npoint
7171 type(trace_topology_result),
intent(in) :: topology(npoint)
7172 logical,
intent(in) :: do_twist,do_q,do_qperp
7173 type(trace_qperp_result),
intent(in) :: q_results(:)
7174 type(trace_qperp_result),
intent(in) :: qperp_results(:)
7175 integer,
intent(inout) :: io_status
7179 write(vtu_unit,
'(a)',iostat=io_status)
'<PointData>'
7180 if (io_status/=0)
return
7182 if (.not.mt_vtk_detail_is_full())
then
7183 call mt_write_vtu_spherical_minimal_pointdata(vtu_unit,topology, &
7184 npoint,do_twist,do_q,q_results,do_qperp,qperp_results, &
7186 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7191 call mt_write_vtu_float_array_start(vtu_unit,
'length_total',io_status)
7192 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7193 (mt_visual_float(topology(ipoint)%length_total),ipoint=1,npoint)
7194 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7195 call mt_write_vtu_float_array_start(vtu_unit,
'length_backward', &
7197 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7198 (topology(ipoint)%length_backward,ipoint=1,npoint)
7199 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7200 call mt_write_vtu_float_array_start(vtu_unit,
'length_forward', &
7202 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7203 (topology(ipoint)%length_forward,ipoint=1,npoint)
7204 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7207 call mt_write_vtu_float_array_start(vtu_unit,
'twist_total',io_status)
7208 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7209 (mt_visual_valid_float(topology(ipoint)%twist_total, &
7210 topology(ipoint)%valid_twist),ipoint=1,npoint)
7211 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7212 call mt_write_vtu_float_array_start(vtu_unit,
'twist_backward', &
7214 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7215 (mt_visual_valid_float(topology(ipoint)%twist_backward, &
7216 topology(ipoint)%valid_twist),ipoint=1,npoint)
7217 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7218 call mt_write_vtu_float_array_start(vtu_unit,
'twist_forward', &
7220 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7221 (mt_visual_valid_float(topology(ipoint)%twist_forward, &
7222 topology(ipoint)%valid_twist),ipoint=1,npoint)
7223 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7224 call mt_write_vtu_int_array_start(vtu_unit,
'valid_twist',io_status)
7225 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7226 (merge(1,0,topology(ipoint)%valid_twist),ipoint=1,npoint)
7227 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7228 call mt_write_vtu_int_array_start(vtu_unit,
'status_twist',io_status)
7229 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7230 (topology(ipoint)%status_twist,ipoint=1,npoint)
7231 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7235 call mt_write_vtu_float_array_start(vtu_unit,
'logQ',io_status)
7236 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7237 (mt_visual_valid_float(q_results(ipoint)%logq0, &
7238 q_results(ipoint)%valid_q0),ipoint=1,npoint)
7239 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7240 call mt_write_vtu_int_array_start(vtu_unit,
'valid_Q',io_status)
7241 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7242 (merge(1,0,q_results(ipoint)%valid_q0),ipoint=1,npoint)
7243 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7244 call mt_write_vtu_int_array_start(vtu_unit,
'status_Q',io_status)
7245 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7246 (q_results(ipoint)%status_q0,ipoint=1,npoint)
7247 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7251 call mt_write_vtu_float_array_start(vtu_unit,
'logQperp',io_status)
7252 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7253 (mt_visual_valid_float(qperp_results(ipoint)%logqperp, &
7254 qperp_results(ipoint)%valid),ipoint=1,npoint)
7255 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7256 call mt_write_vtu_int_array_start(vtu_unit,
'valid_Qperp',io_status)
7257 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7258 (merge(1,0,qperp_results(ipoint)%valid),ipoint=1,npoint)
7259 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7260 call mt_write_vtu_int_array_start(vtu_unit,
'status_Qperp',io_status)
7261 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7262 (qperp_results(ipoint)%status,ipoint=1,npoint)
7263 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7266 call mt_write_vtu_float_array_start(vtu_unit,
'r_b',io_status)
7267 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7268 (topology(ipoint)%backward_endpoint(1),ipoint=1,npoint)
7269 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7270 call mt_write_vtu_float_array_start(vtu_unit,
'theta_b',io_status)
7271 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7272 (mt_vc(topology(ipoint)%backward_endpoint,2), &
7274 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7275 call mt_write_vtu_float_array_start(vtu_unit,
'phi_b',io_status)
7276 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7277 (mt_vc(topology(ipoint)%backward_endpoint,3), &
7279 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7280 call mt_write_vtu_float_array_start(vtu_unit,
'r_f',io_status)
7281 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7282 (topology(ipoint)%forward_endpoint(1),ipoint=1,npoint)
7283 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7284 call mt_write_vtu_float_array_start(vtu_unit,
'theta_f',io_status)
7285 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7286 (mt_vc(topology(ipoint)%forward_endpoint,2), &
7288 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7289 call mt_write_vtu_float_array_start(vtu_unit,
'phi_f',io_status)
7290 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7291 (mt_vc(topology(ipoint)%forward_endpoint,3), &
7293 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7295 call mt_write_vtu_int_array_start(vtu_unit,
'face_backward',io_status)
7296 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7297 (topology(ipoint)%backward_face,ipoint=1,npoint)
7298 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7299 call mt_write_vtu_int_array_start(vtu_unit,
'face_forward',io_status)
7300 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7301 (topology(ipoint)%forward_face,ipoint=1,npoint)
7302 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7303 call mt_write_vtu_int_array_start(vtu_unit,
'connection_type_spherical', &
7305 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7306 (mt_spherical_connection_type(topology(ipoint)%backward_face, &
7307 topology(ipoint)%forward_face,topology(ipoint)%valid), &
7309 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7310 call mt_write_vtu_int_array_start(vtu_unit,
'nstep_backward',io_status)
7311 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7312 (topology(ipoint)%backward_nstep,ipoint=1,npoint)
7313 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7314 call mt_write_vtu_int_array_start(vtu_unit,
'nstep_forward',io_status)
7315 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7316 (topology(ipoint)%forward_nstep,ipoint=1,npoint)
7317 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7318 call mt_write_vtu_int_array_start(vtu_unit,
'status_backward',io_status)
7319 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7320 (topology(ipoint)%backward_status,ipoint=1,npoint)
7321 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7322 call mt_write_vtu_int_array_start(vtu_unit,
'status_forward',io_status)
7323 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7324 (topology(ipoint)%forward_status,ipoint=1,npoint)
7325 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7326 call mt_write_vtu_int_array_start(vtu_unit,
'valid',io_status)
7327 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7328 (merge(1,0,topology(ipoint)%valid),ipoint=1,npoint)
7329 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7331 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'</PointData>'
7332 end subroutine mt_write_vtu_spherical_topology_pointdata
7334 subroutine mt_write_vtu_spherical_minimal_pointdata(vtu_unit,topology, &
7335 npoint,do_twist,do_q,q_results,do_qperp,qperp_results,io_status)
7336 integer,
intent(in) :: vtu_unit,npoint
7337 type(trace_topology_result),
intent(in) :: topology(npoint)
7338 logical,
intent(in) :: do_twist,do_q,do_qperp
7339 type(trace_qperp_result),
intent(in) :: q_results(:)
7340 type(trace_qperp_result),
intent(in) :: qperp_results(:)
7341 integer,
intent(inout) :: io_status
7345 call mt_write_vtu_float_array_start(vtu_unit,
'length_total',io_status)
7346 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7347 (mt_visual_float(topology(ipoint)%length_total),ipoint=1,npoint)
7348 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7351 call mt_write_vtu_float_array_start(vtu_unit,
'twist_total',io_status)
7352 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7353 (mt_visual_valid_float(topology(ipoint)%twist_total, &
7354 topology(ipoint)%valid_twist),ipoint=1,npoint)
7355 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7359 call mt_write_vtu_float_array_start(vtu_unit,
'logQ',io_status)
7360 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7361 (mt_visual_valid_float(q_results(ipoint)%logq0, &
7362 q_results(ipoint)%valid_q0),ipoint=1,npoint)
7363 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7367 call mt_write_vtu_float_array_start(vtu_unit,
'logQperp',io_status)
7368 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7369 (mt_visual_valid_float(qperp_results(ipoint)%logqperp, &
7370 qperp_results(ipoint)%valid),ipoint=1,npoint)
7371 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7373 end subroutine mt_write_vtu_spherical_minimal_pointdata
7375 subroutine mt_write_vtu_file_header(vtu_unit,npoint,ncell)
7376 integer,
intent(in) :: vtu_unit,npoint,ncell
7378 write(vtu_unit,
'(a)')
'<?xml version="1.0"?>'
7379 write(vtu_unit,
'(a)') &
7380 '<VTKFile type="UnstructuredGrid" version="0.1" byte_order="LittleEndian">'
7381 write(vtu_unit,
'(a)')
'<UnstructuredGrid>'
7382 write(vtu_unit,
'(a,i0,a,i0,a)')
'<Piece NumberOfPoints="',npoint, &
7383 '" NumberOfCells="',ncell,
'">'
7384 end subroutine mt_write_vtu_file_header
7386 subroutine mt_write_vtu_file_footer(vtu_unit,io_status)
7387 integer,
intent(in) :: vtu_unit
7388 integer,
intent(inout) :: io_status
7390 write(vtu_unit,
'(a)',iostat=io_status)
'</Piece>'
7391 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7392 '</UnstructuredGrid>'
7393 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'</VTKFile>'
7394 end subroutine mt_write_vtu_file_footer
7396 subroutine mt_write_vtu_product_pointdata(vtu_unit,length_results, &
7397 twist_results,q_results,qperp_results,npoint,do_twist,do_q, &
7398 do_qperp,io_status,do_length)
7399 integer,
intent(in) :: vtu_unit,npoint
7400 type(trace_length_result),
intent(in) :: length_results(npoint)
7401 type(trace_twist_result),
intent(in) :: twist_results(:)
7402 type(trace_qperp_result),
intent(in) :: q_results(:)
7403 type(trace_qperp_result),
intent(in) :: qperp_results(:)
7404 logical,
intent(in) :: do_twist,do_q,do_qperp
7405 integer,
intent(inout) :: io_status
7406 logical,
intent(in),
optional :: do_length
7409 logical :: do_length_eff
7411 write(vtu_unit,
'(a)',iostat=io_status)
'<PointData>'
7412 if (io_status/=0)
return
7413 do_length_eff=.true.
7414 if (
present(do_length)) do_length_eff=do_length
7416 if (.not.mt_vtk_detail_is_full())
then
7417 call mt_write_vtu_product_minimal_pointdata(vtu_unit,length_results, &
7418 twist_results,q_results,qperp_results,npoint,do_twist,do_q, &
7419 do_qperp,io_status,do_length=do_length_eff)
7420 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7425 if (do_length_eff)
then
7426 call mt_write_vtu_float_array_start(vtu_unit,
'length_total',io_status)
7427 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7428 (length_results(ipoint)%total_length,ipoint=1,npoint)
7429 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7430 call mt_write_vtu_float_array_start(vtu_unit,
'length_backward', &
7432 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7433 (length_results(ipoint)%backward_length,ipoint=1,npoint)
7434 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7435 call mt_write_vtu_float_array_start(vtu_unit,
'length_forward', &
7437 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7438 (length_results(ipoint)%forward_length,ipoint=1,npoint)
7439 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7441 call mt_write_vtu_int_array_start(vtu_unit,
'nstep_backward_length', &
7443 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7444 (length_results(ipoint)%backward_nstep,ipoint=1,npoint)
7445 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7446 call mt_write_vtu_int_array_start(vtu_unit,
'nstep_forward_length', &
7448 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7449 (length_results(ipoint)%forward_nstep,ipoint=1,npoint)
7450 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7451 call mt_write_vtu_int_array_start(vtu_unit,
'status_backward_length', &
7453 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7454 (length_results(ipoint)%backward_status,ipoint=1,npoint)
7455 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7456 call mt_write_vtu_int_array_start(vtu_unit,
'status_forward_length', &
7458 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7459 (length_results(ipoint)%forward_status,ipoint=1,npoint)
7460 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7464 call mt_write_vtu_twist_pointdata(vtu_unit,twist_results,npoint, &
7468 call mt_write_vtu_q_product_pointdata(vtu_unit,q_results,npoint, &
7472 call mt_write_vtu_qperp_pointdata(vtu_unit,qperp_results,npoint, &
7476 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'</PointData>'
7477 end subroutine mt_write_vtu_product_pointdata
7479 subroutine mt_write_vtu_product_minimal_pointdata(vtu_unit, &
7480 length_results,twist_results,q_results,qperp_results,npoint, &
7481 do_twist,do_q,do_qperp,io_status,do_length)
7482 integer,
intent(in) :: vtu_unit,npoint
7483 type(trace_length_result),
intent(in) :: length_results(npoint)
7484 type(trace_twist_result),
intent(in) :: twist_results(:)
7485 type(trace_qperp_result),
intent(in) :: q_results(:)
7486 type(trace_qperp_result),
intent(in) :: qperp_results(:)
7487 logical,
intent(in) :: do_twist,do_q,do_qperp
7488 integer,
intent(inout) :: io_status
7489 logical,
intent(in),
optional :: do_length
7492 logical :: do_length_eff
7494 do_length_eff=.true.
7495 if (
present(do_length)) do_length_eff=do_length
7497 if (do_length_eff)
then
7498 call mt_write_vtu_float_array_start(vtu_unit,
'length_total',io_status)
7499 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7500 (mt_visual_float(length_results(ipoint)%total_length), &
7502 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7506 call mt_write_vtu_float_array_start(vtu_unit,
'twist_total',io_status)
7507 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))', &
7509 (mt_visual_float(twist_results(ipoint)%total_twist), &
7511 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7515 call mt_write_vtu_float_array_start(vtu_unit,
'logQ',io_status)
7516 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))', &
7518 (mt_visual_valid_float(q_results(ipoint)%logq0, &
7519 q_results(ipoint)%valid_q0),ipoint=1,npoint)
7520 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7524 call mt_write_vtu_float_array_start(vtu_unit,
'logQperp',io_status)
7525 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))', &
7527 (mt_visual_valid_float(qperp_results(ipoint)%logqperp, &
7528 qperp_results(ipoint)%valid),ipoint=1,npoint)
7529 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7531 end subroutine mt_write_vtu_product_minimal_pointdata
7533 subroutine mt_write_vtu_twist_pointdata(vtu_unit,twist_results,npoint, &
7535 integer,
intent(in) :: vtu_unit,npoint
7536 type(trace_twist_result),
intent(in) :: twist_results(npoint)
7537 integer,
intent(inout) :: io_status
7541 call mt_write_vtu_float_array_start(vtu_unit,
'twist_total',io_status)
7542 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7543 (twist_results(ipoint)%total_twist,ipoint=1,npoint)
7544 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7545 call mt_write_vtu_float_array_start(vtu_unit,
'twist_backward', &
7547 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7548 (twist_results(ipoint)%backward_twist,ipoint=1,npoint)
7549 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7550 call mt_write_vtu_float_array_start(vtu_unit,
'twist_forward', &
7552 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7553 (twist_results(ipoint)%forward_twist,ipoint=1,npoint)
7554 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7556 call mt_write_vtu_int_array_start(vtu_unit,
'nstep_backward_twist', &
7558 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7559 (twist_results(ipoint)%line%backward_nstep,ipoint=1,npoint)
7560 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7561 call mt_write_vtu_int_array_start(vtu_unit,
'nstep_forward_twist', &
7563 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7564 (twist_results(ipoint)%line%forward_nstep,ipoint=1,npoint)
7565 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7566 call mt_write_vtu_int_array_start(vtu_unit,
'status_backward_twist', &
7568 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7569 (twist_results(ipoint)%line%backward_status,ipoint=1,npoint)
7570 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7571 call mt_write_vtu_int_array_start(vtu_unit,
'status_forward_twist', &
7573 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7574 (twist_results(ipoint)%line%forward_status,ipoint=1,npoint)
7575 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7576 end subroutine mt_write_vtu_twist_pointdata
7578 subroutine mt_write_vtu_qperp_pointdata(vtu_unit,qperp_results,npoint, &
7580 integer,
intent(in) :: vtu_unit,npoint
7581 type(trace_qperp_result),
intent(in) :: qperp_results(npoint)
7582 integer,
intent(inout) :: io_status
7586 call mt_write_vtu_float_array_start(vtu_unit,
'qperp',io_status)
7587 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7588 (qperp_results(ipoint)%qperp,ipoint=1,npoint)
7589 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7590 call mt_write_vtu_float_array_start(vtu_unit,
'logqperp',io_status)
7591 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7592 (qperp_results(ipoint)%logqperp,ipoint=1,npoint)
7593 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7594 call mt_write_vtu_float_array_start(vtu_unit,
'N2',io_status)
7595 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7596 (qperp_results(ipoint)%N2,ipoint=1,npoint)
7597 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7598 call mt_write_vtu_float_array_start(vtu_unit,
'bfactor',io_status)
7599 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7600 (qperp_results(ipoint)%bfactor,ipoint=1,npoint)
7601 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7602 call mt_write_vtu_float_array_start(vtu_unit,
'length_forward_qperp', &
7604 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7605 (qperp_results(ipoint)%forward_length,ipoint=1,npoint)
7606 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7607 call mt_write_vtu_float_array_start(vtu_unit,
'length_backward_qperp', &
7609 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7610 (qperp_results(ipoint)%backward_length,ipoint=1,npoint)
7611 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7613 call mt_write_vtu_float_array_start(vtu_unit,
'Bseed_norm',io_status)
7614 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7615 (dsqrt(sum(qperp_results(ipoint)%B_seed**2)),ipoint=1,npoint)
7616 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7617 call mt_write_vtu_float_array_start(vtu_unit,
'Bf_norm',io_status)
7618 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7619 (dsqrt(sum(qperp_results(ipoint)%forward_B**2)),ipoint=1,npoint)
7620 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7621 call mt_write_vtu_float_array_start(vtu_unit,
'Bb_norm',io_status)
7622 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7623 (dsqrt(sum(qperp_results(ipoint)%backward_B**2)),ipoint=1,npoint)
7624 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7626 call mt_write_vtu_qperp_endpoint_pointdata(vtu_unit,qperp_results, &
7628 call mt_write_vtu_qperp_int_pointdata(vtu_unit,qperp_results,npoint, &
7630 end subroutine mt_write_vtu_qperp_pointdata
7632 subroutine mt_write_vtu_qperp_endpoint_pointdata(vtu_unit,qperp_results, &
7634 integer,
intent(in) :: vtu_unit,npoint
7635 type(trace_qperp_result),
intent(in) :: qperp_results(npoint)
7636 integer,
intent(inout) :: io_status
7640 call mt_write_vtu_float_array_start(vtu_unit,
'x_f_qperp',io_status)
7641 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7642 (mt_vc(qperp_results(ipoint)%forward_endpoint,1),ipoint=1,npoint)
7643 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7644 call mt_write_vtu_float_array_start(vtu_unit,
'y_f_qperp',io_status)
7645 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7646 (mt_vc(qperp_results(ipoint)%forward_endpoint,2),ipoint=1,npoint)
7647 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7648 call mt_write_vtu_float_array_start(vtu_unit,
'z_f_qperp',io_status)
7649 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7650 (mt_vc(qperp_results(ipoint)%forward_endpoint,3),ipoint=1,npoint)
7651 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7652 call mt_write_vtu_float_array_start(vtu_unit,
'x_b_qperp',io_status)
7653 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7654 (mt_vc(qperp_results(ipoint)%backward_endpoint,1),ipoint=1,npoint)
7655 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7656 call mt_write_vtu_float_array_start(vtu_unit,
'y_b_qperp',io_status)
7657 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7658 (mt_vc(qperp_results(ipoint)%backward_endpoint,2),ipoint=1,npoint)
7659 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7660 call mt_write_vtu_float_array_start(vtu_unit,
'z_b_qperp',io_status)
7661 if (io_status==0)
write(vtu_unit,
'(4(1pe24.16))',iostat=io_status) &
7662 (mt_vc(qperp_results(ipoint)%backward_endpoint,3),ipoint=1,npoint)
7663 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7664 end subroutine mt_write_vtu_qperp_endpoint_pointdata
7666 subroutine mt_write_vtu_qperp_int_pointdata(vtu_unit,qperp_results, &
7668 integer,
intent(in) :: vtu_unit,npoint
7669 type(trace_qperp_result),
intent(in) :: qperp_results(npoint)
7670 integer,
intent(inout) :: io_status
7674 call mt_write_vtu_int_array_start(vtu_unit,
'valid_qperp',io_status)
7675 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7676 (merge(1,0,qperp_results(ipoint)%valid),ipoint=1,npoint)
7677 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7678 call mt_write_vtu_int_array_start(vtu_unit,
'status_qperp',io_status)
7679 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7680 (qperp_results(ipoint)%status,ipoint=1,npoint)
7681 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7682 call mt_write_vtu_int_array_start(vtu_unit,
'face_forward_qperp', &
7684 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7685 (qperp_results(ipoint)%forward_face,ipoint=1,npoint)
7686 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7687 call mt_write_vtu_int_array_start(vtu_unit,
'face_backward_qperp', &
7689 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7690 (qperp_results(ipoint)%backward_face,ipoint=1,npoint)
7691 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7692 call mt_write_vtu_int_array_start(vtu_unit,
'status_forward_qperp', &
7694 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7695 (qperp_results(ipoint)%forward_status,ipoint=1,npoint)
7696 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7697 call mt_write_vtu_int_array_start(vtu_unit,
'status_backward_qperp', &
7699 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7700 (qperp_results(ipoint)%backward_status,ipoint=1,npoint)
7701 call mt_write_vtu_data_array_end(vtu_unit,io_status)
7702 end subroutine mt_write_vtu_qperp_int_pointdata
7704 subroutine mt_write_vtu_empty_pointdata(vtu_unit,do_length,do_twist, &
7706 integer,
intent(in) :: vtu_unit
7707 logical,
intent(in) :: do_length,do_twist,do_q,do_qperp
7709 write(vtu_unit,
'(a)')
'<PointData>'
7710 if (.not.mt_vtk_detail_is_full())
then
7712 call mt_write_vtu_empty_float_array(vtu_unit,
'length_total')
7715 call mt_write_vtu_empty_float_array(vtu_unit,
'twist_total')
7718 call mt_write_vtu_empty_float_array(vtu_unit,
'logQ')
7721 call mt_write_vtu_empty_float_array(vtu_unit,
'logQperp')
7723 write(vtu_unit,
'(a)')
'</PointData>'
7727 call mt_write_vtu_empty_float_array(vtu_unit,
'length_total')
7728 call mt_write_vtu_empty_float_array(vtu_unit,
'length_backward')
7729 call mt_write_vtu_empty_float_array(vtu_unit,
'length_forward')
7730 call mt_write_vtu_empty_int_array(vtu_unit,
'nstep_backward_length')
7731 call mt_write_vtu_empty_int_array(vtu_unit,
'nstep_forward_length')
7732 call mt_write_vtu_empty_int_array(vtu_unit,
'status_backward_length')
7733 call mt_write_vtu_empty_int_array(vtu_unit,
'status_forward_length')
7736 call mt_write_vtu_empty_float_array(vtu_unit,
'twist_total')
7737 call mt_write_vtu_empty_float_array(vtu_unit,
'twist_backward')
7738 call mt_write_vtu_empty_float_array(vtu_unit,
'twist_forward')
7739 call mt_write_vtu_empty_int_array(vtu_unit,
'nstep_backward_twist')
7740 call mt_write_vtu_empty_int_array(vtu_unit,
'nstep_forward_twist')
7741 call mt_write_vtu_empty_int_array(vtu_unit,
'status_backward_twist')
7742 call mt_write_vtu_empty_int_array(vtu_unit,
'status_forward_twist')
7745 call mt_write_vtu_empty_float_array(vtu_unit,
'q')
7746 call mt_write_vtu_empty_float_array(vtu_unit,
'logQ')
7747 call mt_write_vtu_empty_float_array(vtu_unit,
'N2_q')
7748 call mt_write_vtu_empty_float_array(vtu_unit,
'bfactor_q')
7749 call mt_write_vtu_empty_float_array(vtu_unit,
'length_forward_q')
7750 call mt_write_vtu_empty_float_array(vtu_unit,
'length_backward_q')
7751 call mt_write_vtu_empty_float_array(vtu_unit,
'Bseed_norm_q')
7752 call mt_write_vtu_empty_float_array(vtu_unit,
'Bf_norm_q')
7753 call mt_write_vtu_empty_float_array(vtu_unit,
'Bb_norm_q')
7754 call mt_write_vtu_empty_int_array(vtu_unit,
'valid_Q')
7755 call mt_write_vtu_empty_int_array(vtu_unit,
'status_Q')
7756 call mt_write_vtu_empty_int_array(vtu_unit,
'face_forward_Q')
7757 call mt_write_vtu_empty_int_array(vtu_unit,
'face_backward_Q')
7758 call mt_write_vtu_empty_int_array(vtu_unit,
'status_forward_Q')
7759 call mt_write_vtu_empty_int_array(vtu_unit,
'status_backward_Q')
7762 call mt_write_vtu_empty_float_array(vtu_unit,
'qperp')
7763 call mt_write_vtu_empty_float_array(vtu_unit,
'logqperp')
7764 call mt_write_vtu_empty_float_array(vtu_unit,
'N2')
7765 call mt_write_vtu_empty_float_array(vtu_unit,
'bfactor')
7766 call mt_write_vtu_empty_float_array(vtu_unit,
'length_forward_qperp')
7767 call mt_write_vtu_empty_float_array(vtu_unit,
'length_backward_qperp')
7768 call mt_write_vtu_empty_float_array(vtu_unit,
'Bseed_norm')
7769 call mt_write_vtu_empty_float_array(vtu_unit,
'Bf_norm')
7770 call mt_write_vtu_empty_float_array(vtu_unit,
'Bb_norm')
7771 call mt_write_vtu_empty_float_array(vtu_unit,
'x_f_qperp')
7772 call mt_write_vtu_empty_float_array(vtu_unit,
'y_f_qperp')
7773 call mt_write_vtu_empty_float_array(vtu_unit,
'z_f_qperp')
7774 call mt_write_vtu_empty_float_array(vtu_unit,
'x_b_qperp')
7775 call mt_write_vtu_empty_float_array(vtu_unit,
'y_b_qperp')
7776 call mt_write_vtu_empty_float_array(vtu_unit,
'z_b_qperp')
7777 call mt_write_vtu_empty_int_array(vtu_unit,
'valid_qperp')
7778 call mt_write_vtu_empty_int_array(vtu_unit,
'status_qperp')
7779 call mt_write_vtu_empty_int_array(vtu_unit,
'face_forward_qperp')
7780 call mt_write_vtu_empty_int_array(vtu_unit,
'face_backward_qperp')
7781 call mt_write_vtu_empty_int_array(vtu_unit,
'status_forward_qperp')
7782 call mt_write_vtu_empty_int_array(vtu_unit,
'status_backward_qperp')
7784 write(vtu_unit,
'(a)')
'</PointData>'
7785 end subroutine mt_write_vtu_empty_pointdata
7787 subroutine mt_write_vtu_empty_float_array(vtu_unit,name)
7788 integer,
intent(in) :: vtu_unit
7789 character(len=*),
intent(in) :: name
7791 write(vtu_unit,
'(a,a,a)')
'<DataArray type="Float64" Name="', &
7792 trim(name),
'" format="ascii">'
7793 write(vtu_unit,
'(a)')
'</DataArray>'
7794 end subroutine mt_write_vtu_empty_float_array
7796 subroutine mt_write_vtu_empty_int_array(vtu_unit,name)
7797 integer,
intent(in) :: vtu_unit
7798 character(len=*),
intent(in) :: name
7800 write(vtu_unit,
'(a,a,a)')
'<DataArray type="Int32" Name="', &
7801 trim(name),
'" format="ascii">'
7802 write(vtu_unit,
'(a)')
'</DataArray>'
7803 end subroutine mt_write_vtu_empty_int_array
7805 subroutine mt_write_vtu_float_array_start(vtu_unit,name,io_status)
7806 integer,
intent(in) :: vtu_unit
7807 character(len=*),
intent(in) :: name
7808 integer,
intent(inout) :: io_status
7810 if (io_status/=0)
return
7811 write(vtu_unit,
'(a,a,a)',iostat=io_status) &
7812 '<DataArray type="Float64" Name="',trim(name),
'" format="ascii">'
7813 end subroutine mt_write_vtu_float_array_start
7815 subroutine mt_write_vtu_int_array_start(vtu_unit,name,io_status)
7816 integer,
intent(in) :: vtu_unit
7817 character(len=*),
intent(in) :: name
7818 integer,
intent(inout) :: io_status
7820 if (io_status/=0)
return
7821 write(vtu_unit,
'(a,a,a)',iostat=io_status) &
7822 '<DataArray type="Int32" Name="',trim(name),
'" format="ascii">'
7823 end subroutine mt_write_vtu_int_array_start
7825 subroutine mt_write_vtu_data_array_end(vtu_unit,io_status)
7826 integer,
intent(in) :: vtu_unit
7827 integer,
intent(inout) :: io_status
7829 if (io_status/=0)
return
7830 write(vtu_unit,
'(a)',iostat=io_status)
'</DataArray>'
7831 end subroutine mt_write_vtu_data_array_end
7833 subroutine mt_write_vtu_points(vtu_unit,length_results,npoint,io_status)
7834 integer,
intent(in) :: vtu_unit,npoint
7835 type(trace_length_result),
intent(in) :: length_results(npoint)
7836 integer,
intent(inout) :: io_status
7838 double precision :: seed_xyz(3)
7841 write(vtu_unit,
'(a)',iostat=io_status)
'<Points>'
7842 if (io_status==0)
then
7843 write(vtu_unit,
'(a)',iostat=io_status) &
7844 '<DataArray type="Float64" NumberOfComponents="3" format="ascii">'
7847 call mt_vtu_point_from_coord(length_results(ipoint)%seed,seed_xyz)
7848 if (io_status==0)
write(vtu_unit,
'(3(1pe24.16))', &
7849 iostat=io_status) seed_xyz
7851 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7853 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'</Points>'
7854 end subroutine mt_write_vtu_points
7856 subroutine mt_write_vtu_topology_points(vtu_unit,topology,npoint, &
7858 integer,
intent(in) :: vtu_unit,npoint
7859 type(trace_topology_result),
intent(in) :: topology(npoint)
7860 integer,
intent(inout) :: io_status
7862 double precision :: seed_xyz(3)
7865 write(vtu_unit,
'(a)',iostat=io_status)
'<Points>'
7866 if (io_status==0)
then
7867 write(vtu_unit,
'(a)',iostat=io_status) &
7868 '<DataArray type="Float64" NumberOfComponents="3" format="ascii">'
7871 call mt_vtu_point_from_coord(topology(ipoint)%seed,seed_xyz)
7872 if (io_status==0)
write(vtu_unit,
'(3(1pe24.16))', &
7873 iostat=io_status) seed_xyz
7875 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7877 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'</Points>'
7878 end subroutine mt_write_vtu_topology_points
7880 subroutine mt_vtu_point_from_coord(coord,point_xyz)
7881 double precision,
intent(in) :: coord(ndim)
7882 double precision,
intent(out) :: point_xyz(3)
7884 double precision :: r,theta,phi,sin_theta
7887 if (geo_coordinate==geo_spherical .and. ndim==3)
then
7892 sin_theta=dsin(theta)
7893 point_xyz(1)=r*sin_theta*dcos(phi)
7894 point_xyz(2)=r*sin_theta*dsin(phi)
7895 point_xyz(3)=r*dcos(theta)
7898 point_xyz(1)=mt_vc(coord,1)
7899 point_xyz(2)=mt_vc(coord,2)
7900 point_xyz(3)=mt_vc(coord,3)
7902 end subroutine mt_vtu_point_from_coord
7904 subroutine mt_write_vtu_vertex_cells(vtu_unit,npoint,io_status)
7905 integer,
intent(in) :: vtu_unit,npoint
7906 integer,
intent(inout) :: io_status
7910 write(vtu_unit,
'(a)',iostat=io_status)
'<Cells>'
7911 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7912 '<DataArray type="Int32" Name="connectivity" format="ascii">'
7913 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7914 (ipoint-1,ipoint=1,npoint)
7915 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7917 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7918 '<DataArray type="Int32" Name="offsets" format="ascii">'
7919 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7920 (ipoint,ipoint=1,npoint)
7921 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7923 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7924 '<DataArray type="UInt8" Name="types" format="ascii">'
7925 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7927 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7929 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'</Cells>'
7930 end subroutine mt_write_vtu_vertex_cells
7932 subroutine mt_write_vtu_quad_cells(vtu_unit,n1,n2,io_status)
7933 integer,
intent(in) :: vtu_unit,n1,n2
7934 integer,
intent(inout) :: io_status
7936 integer :: i,j,icell,p,ncell
7939 write(vtu_unit,
'(a)',iostat=io_status)
'<Cells>'
7940 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7941 '<DataArray type="Int32" Name="connectivity" format="ascii">'
7945 if (io_status==0)
write(vtu_unit,
'(4(i0,1x))',iostat=io_status) &
7949 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7951 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7952 '<DataArray type="Int32" Name="offsets" format="ascii">'
7953 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7954 (4*icell,icell=1,ncell)
7955 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7957 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7958 '<DataArray type="UInt8" Name="types" format="ascii">'
7959 if (io_status==0)
write(vtu_unit,
'(12(i0,1x))',iostat=io_status) &
7961 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7963 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'</Cells>'
7964 end subroutine mt_write_vtu_quad_cells
7966 subroutine mt_write_vtu_cells_empty(vtu_unit,io_status)
7967 integer,
intent(in) :: vtu_unit
7968 integer,
intent(inout) :: io_status
7970 write(vtu_unit,
'(a)',iostat=io_status)
'<Cells>'
7971 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7972 '<DataArray type="Int32" Name="connectivity" format="ascii">'
7973 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7975 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7976 '<DataArray type="Int32" Name="offsets" format="ascii">'
7977 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7979 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7980 '<DataArray type="UInt8" Name="types" format="ascii">'
7981 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status) &
7983 if (io_status==0)
write(vtu_unit,
'(a)',iostat=io_status)
'</Cells>'
7984 end subroutine mt_write_vtu_cells_empty
7986 subroutine mt_write_twist_plane_csv(results,n1,n2,csv_file,caller, &
7988 integer,
intent(in) :: n1,n2
7989 type(trace_twist_result),
intent(in) :: results(n1*n2)
7990 character(len=*),
intent(in) :: csv_file,caller,index_header
7992 double precision :: seed_xyz(3)
7993 integer :: csv_unit,io_status,i,j,iseed
7995 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
7996 action=
'write',form=
'formatted',iostat=io_status)
7997 if (io_status/=0)
then
7998 call mpistop(trim(caller)//
' could not open CSV file')
8001 write(csv_unit,
'(a)',iostat=io_status) &
8002 trim(index_header)//
',seed_x,seed_y,seed_z,'// &
8003 'length_total,length_backward,length_forward,'// &
8004 'twist_total,twist_backward,twist_forward,'// &
8005 'nstep_backward,nstep_forward,'// &
8006 'status_backward,status_forward'
8007 if (io_status/=0)
then
8009 call mpistop(trim(caller)//
' could not write CSV header')
8016 seed_xyz(1:ndim)=results(iseed)%line%seed
8017 write(csv_unit,
'(i0,",",i0,9(",",es24.16),4(",",i0))', &
8018 iostat=io_status) i,j,seed_xyz, &
8019 results(iseed)%line%total_length, &
8020 results(iseed)%line%backward_length, &
8021 results(iseed)%line%forward_length, &
8022 results(iseed)%total_twist, &
8023 results(iseed)%backward_twist, &
8024 results(iseed)%forward_twist, &
8025 results(iseed)%line%backward_nstep, &
8026 results(iseed)%line%forward_nstep, &
8027 results(iseed)%line%backward_status, &
8028 results(iseed)%line%forward_status
8029 if (io_status/=0)
then
8031 call mpistop(trim(caller)//
' could not write CSV data')
8037 end subroutine mt_write_twist_plane_csv
8039 subroutine mt_write_q_plane_csv(results,n1,n2,csv_file,caller, &
8041 integer,
intent(in) :: n1,n2
8042 type(trace_qperp_result),
intent(in) :: results(n1*n2)
8043 character(len=*),
intent(in) :: csv_file,caller,index_header
8045 integer :: csv_unit,io_status,i,j,iseed
8047 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
8048 action=
'write',form=
'formatted',iostat=io_status)
8049 if (io_status/=0)
then
8050 call mpistop(trim(caller)//
' could not open CSV file')
8053 write(csv_unit,
'(a)',iostat=io_status) &
8054 trim(index_header)//
',seed_x,seed_y,seed_z,'// &
8055 'logQ,valid_Q,status_Q,'// &
8056 'face_forward_Q,face_backward_Q,'// &
8057 'status_forward_Q,status_backward_Q,'// &
8058 'length_forward_Q,length_backward_Q,'// &
8059 'x_f_Q,y_f_Q,z_f_Q,x_b_Q,y_b_Q,z_b_Q'
8060 if (io_status/=0)
then
8062 call mpistop(trim(caller)//
' could not write CSV header')
8069 '(i0,",",i0,4(",",es24.16),",",l1,5(",",i0),'// &
8070 '8(",",es24.16))',iostat=io_status) &
8071 i,j,results(iseed)%seed, &
8072 results(iseed)%logq0, &
8073 results(iseed)%valid_q0,results(iseed)%status_q0, &
8074 results(iseed)%forward_face,results(iseed)%backward_face, &
8075 results(iseed)%forward_status,results(iseed)%backward_status, &
8076 results(iseed)%forward_length,results(iseed)%backward_length, &
8077 results(iseed)%forward_endpoint, &
8078 results(iseed)%backward_endpoint
8079 if (io_status/=0)
then
8081 call mpistop(trim(caller)//
' could not write CSV data')
8087 end subroutine mt_write_q_plane_csv
8089 subroutine mt_write_qperp_plane_csv(results,n1,n2,csv_file,caller, &
8091 integer,
intent(in) :: n1,n2
8092 type(trace_qperp_result),
intent(in) :: results(n1*n2)
8093 character(len=*),
intent(in) :: csv_file,caller,index_header
8095 double precision :: bseed_norm,bf_norm,bb_norm
8096 integer :: csv_unit,io_status,i,j,iseed
8098 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
8099 action=
'write',form=
'formatted',iostat=io_status)
8100 if (io_status/=0)
then
8101 call mpistop(trim(caller)//
' could not open CSV file')
8104 write(csv_unit,
'(a)',iostat=io_status) &
8105 trim(index_header)//
',seed_x,seed_y,seed_z,'// &
8106 'qperp,logqperp,valid,status,'// &
8108 'face_forward,face_backward,'// &
8109 'status_forward,status_backward,'// &
8110 'length_forward,length_backward,'// &
8111 'Bseed_norm,Bf_norm,Bb_norm,'// &
8112 'x_f,y_f,z_f,x_b,y_b,z_b'
8113 if (io_status/=0)
then
8115 call mpistop(trim(caller)//
' could not write CSV header')
8121 bseed_norm=dsqrt(sum(results(iseed)%B_seed**2))
8122 bf_norm=dsqrt(sum(results(iseed)%forward_B**2))
8123 bb_norm=dsqrt(sum(results(iseed)%backward_B**2))
8125 '(i0,",",i0,5(",",es24.16),",",l1,",",i0,'// &
8126 '2(",",es24.16),4(",",i0),11(",",es24.16))', &
8128 i,j,results(iseed)%seed, &
8129 results(iseed)%qperp,results(iseed)%logqperp, &
8130 results(iseed)%valid,results(iseed)%status, &
8131 results(iseed)%N2,results(iseed)%bfactor, &
8132 results(iseed)%forward_face,results(iseed)%backward_face, &
8133 results(iseed)%forward_status,results(iseed)%backward_status, &
8134 results(iseed)%forward_length,results(iseed)%backward_length, &
8135 bseed_norm,bf_norm,bb_norm, &
8136 results(iseed)%forward_endpoint, &
8137 results(iseed)%backward_endpoint
8138 if (io_status/=0)
then
8140 call mpistop(trim(caller)//
' could not write CSV data')
8146 end subroutine mt_write_qperp_plane_csv
8148 subroutine mt_write_qperp_arbitrary_header(csv_file,caller)
8149 character(len=*),
intent(in) :: csv_file,caller
8151 integer :: csv_unit,io_status
8153 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
8154 action=
'write',form=
'formatted',iostat=io_status)
8155 if (io_status/=0)
then
8156 call mpistop(trim(caller)//
' could not open CSV file')
8159 write(csv_unit,
'(a)',iostat=io_status) &
8160 'i,j,s1,s2,seed_x,seed_y,seed_z,'// &
8161 'qperp,logqperp,valid,status,'// &
8163 'face_forward,face_backward,'// &
8164 'status_forward,status_backward,'// &
8165 'length_forward,length_backward,'// &
8166 'Bseed_norm,Bf_norm,Bb_norm,'// &
8167 'x_f,y_f,z_f,x_b,y_b,z_b'
8168 if (io_status/=0)
then
8170 call mpistop(trim(caller)//
' could not write CSV header')
8174 end subroutine mt_write_qperp_arbitrary_header
8176 subroutine mt_write_qperp_arbitrary_csv(results,s1,s2,n1,n2,csv_file, &
8178 integer,
intent(in) :: n1,n2
8179 type(trace_qperp_result),
intent(in) :: results(n1*n2)
8180 double precision,
intent(in) :: s1(n1*n2),s2(n1*n2)
8181 character(len=*),
intent(in) :: csv_file,caller
8183 double precision :: bseed_norm,bf_norm,bb_norm
8184 integer :: csv_unit,io_status,i,j,iseed
8186 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
8187 action=
'write',form=
'formatted',iostat=io_status)
8188 if (io_status/=0)
then
8189 call mpistop(trim(caller)//
' could not open CSV file')
8192 write(csv_unit,
'(a)',iostat=io_status) &
8193 'i,j,s1,s2,seed_x,seed_y,seed_z,'// &
8194 'qperp,logqperp,valid,status,'// &
8196 'face_forward,face_backward,'// &
8197 'status_forward,status_backward,'// &
8198 'length_forward,length_backward,'// &
8199 'Bseed_norm,Bf_norm,Bb_norm,'// &
8200 'x_f,y_f,z_f,x_b,y_b,z_b'
8201 if (io_status/=0)
then
8203 call mpistop(trim(caller)//
' could not write CSV header')
8209 bseed_norm=dsqrt(sum(results(iseed)%B_seed**2))
8210 bf_norm=dsqrt(sum(results(iseed)%forward_B**2))
8211 bb_norm=dsqrt(sum(results(iseed)%backward_B**2))
8213 '(i0,",",i0,7(",",es24.16),",",l1,",",i0,'// &
8214 '2(",",es24.16),4(",",i0),11(",",es24.16))', &
8216 i,j,s1(iseed),s2(iseed),results(iseed)%seed, &
8217 results(iseed)%qperp,results(iseed)%logqperp, &
8218 results(iseed)%valid,results(iseed)%status, &
8219 results(iseed)%N2,results(iseed)%bfactor, &
8220 results(iseed)%forward_face,results(iseed)%backward_face, &
8221 results(iseed)%forward_status,results(iseed)%backward_status, &
8222 results(iseed)%forward_length,results(iseed)%backward_length, &
8223 bseed_norm,bf_norm,bb_norm, &
8224 results(iseed)%forward_endpoint, &
8225 results(iseed)%backward_endpoint
8226 if (io_status/=0)
then
8228 call mpistop(trim(caller)//
' could not write CSV data')
8234 end subroutine mt_write_qperp_arbitrary_csv
8236 subroutine mt_write_mapping_plane_xy_csv(results,nx,ny,csv_file)
8237 integer,
intent(in) :: nx,ny
8238 type(trace_mapping_result),
intent(in) :: results(nx*ny)
8239 character(len=*),
intent(in) :: csv_file
8241 call mt_write_mapping_plane_csv(results,nx,ny,csv_file, &
8242 'mt_mapping_plane_xy',
'ix,iy')
8243 end subroutine mt_write_mapping_plane_xy_csv
8245 subroutine mt_write_mapping_plane_csv(results,n1,n2,csv_file,caller, &
8247 integer,
intent(in) :: n1,n2
8248 type(trace_mapping_result),
intent(in) :: results(n1*n2)
8249 character(len=*),
intent(in) :: csv_file,caller,index_header
8251 integer :: csv_unit,io_status,i,j,iseed
8253 open(newunit=csv_unit,file=trim(csv_file),status=
'replace', &
8254 action=
'write',form=
'formatted',iostat=io_status)
8255 if (io_status/=0)
then
8256 call mpistop(trim(caller)//
' could not open CSV file')
8259 write(csv_unit,
'(a)',iostat=io_status) &
8260 trim(index_header)//
','// &
8261 'seed_x,seed_y,seed_z,'// &
8262 'source_Bx,source_By,source_Bz,source_Bn,'// &
8263 'backward_x,backward_y,backward_z,'// &
8264 'backward_Bx,backward_By,backward_Bz,backward_Bn,'// &
8265 'backward_face,backward_length,backward_status,'// &
8266 'forward_x,forward_y,forward_z,'// &
8267 'forward_Bx,forward_By,forward_Bz,forward_Bn,'// &
8268 'forward_face,forward_length,forward_status,valid'
8269 if (io_status/=0)
then
8271 call mpistop(trim(caller)//
' could not write CSV header')
8278 '(i0,",",i0,14(",",es24.16),",",i0,",",es24.16,'// &
8279 '",",i0,7(",",es24.16),",",i0,",",es24.16,'// &
8280 '",",i0,",",l1)',iostat=io_status) &
8282 results(iseed)%seed, &
8283 results(iseed)%source_B,results(iseed)%source_Bn, &
8284 results(iseed)%backward_footpoint, &
8285 results(iseed)%backward_B,results(iseed)%backward_Bn, &
8286 results(iseed)%backward_face, &
8287 results(iseed)%backward_length, &
8288 results(iseed)%backward_status, &
8289 results(iseed)%forward_footpoint, &
8290 results(iseed)%forward_B,results(iseed)%forward_Bn, &
8291 results(iseed)%forward_face, &
8292 results(iseed)%forward_length, &
8293 results(iseed)%forward_status, &
8294 results(iseed)%valid
8295 if (io_status/=0)
then
8297 call mpistop(trim(caller)//
' could not write CSV data')
8303 end subroutine mt_write_mapping_plane_csv
8305 integer function mt_q_result_face_pair(qperp_result)
result(face_pair)
8306 type(trace_qperp_result),
intent(in) :: qperp_result
8309 if (.not.qperp_result%valid_q0)
return
8310 face_pair=mt_q_face_pair_from_faces(qperp_result%backward_face, &
8311 qperp_result%forward_face)
8312 end function mt_q_result_face_pair
8314 integer function mt_q_result_connection_type(qperp_result) &
8315 result(connection_type)
8316 type(trace_qperp_result),
intent(in) :: qperp_result
8319 if (.not.qperp_result%valid_q0)
return
8320 connection_type=mt_q_connection_type_from_faces( &
8321 qperp_result%backward_face,qperp_result%forward_face)
8322 end function mt_q_result_connection_type
8324 integer function mt_q_face_pair_from_faces(face_b,face_f)
result(face_pair)
8325 integer,
intent(in) :: face_b,face_f
8328 if (.not.mt_q_face_valid(face_b))
return
8329 if (.not.mt_q_face_valid(face_f))
return
8330 face_pair=10*face_b+face_f
8331 end function mt_q_face_pair_from_faces
8333 integer function mt_q_connection_type_from_faces(face_b,face_f) &
8334 result(connection_type)
8335 integer,
intent(in) :: face_b,face_f
8338 if (.not.mt_q_face_valid(face_b))
return
8339 if (.not.mt_q_face_valid(face_f))
return
8340 if (face_b==trace_face_zmin .and. face_f==trace_face_zmin)
then
8342 else if (face_b==trace_face_zmax .and. face_f==trace_face_zmax)
then
8344 else if ((face_b==trace_face_zmin .and. face_f==trace_face_zmax) .or. &
8345 (face_b==trace_face_zmax .and. face_f==trace_face_zmin))
then
8347 else if (face_b==face_f)
then
8352 end function mt_q_connection_type_from_faces
8354 logical function mt_q_face_valid(face)
8355 integer,
intent(in) :: face
8357 mt_q_face_valid=face>=trace_face_xmin .and. face<=trace_face_zmax
8358 end function mt_q_face_valid
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Module with geometry-related routines (e.g., divergence, curl)
integer, parameter spherical
integer, parameter cartesian
integer, parameter cartesian_stretched
update ghost cells of all blocks including physical boundaries
subroutine getbc(time, qdt, psb, nwstart, nwbc)
do update ghost cells of all blocks including physical boundaries
This module contains definitions of global parameters and variables and some generic functions/subrou...
integer, parameter unitpar
file handle for IO
double precision global_time
The global simulation time.
integer, parameter ndim
Number of spatial dimensions for grid variables.
character(len=std_len), dimension(:), allocatable par_files
Which par files are used as input.
double precision, dimension(:), allocatable, parameter d
integer npe
The number of MPI tasks.
logical, dimension(ndim) periodb
True for dimensions with periodic boundaries.
logical slab_uniform
uniform Cartesian geometry or not (stretched Cartesian)
subroutine, public mt_write_cartesian_vti_pointdata(vti_file, xmin, xmax, nx, ymin, ymax, ny, zmin, zmax, nz, length_total, qperp, status)
subroutine, public mt_fieldline_products_plane_arbitrary(origin, e1, e2, s1min, s1max, n1, s2min, s2max, n2, dl, max_steps, csv_file, b_min, compute_length, compute_twist, compute_q, compute_qperp, vtu_file, write_csv)
subroutine, public mt_twist_plane_yz(ymin, ymax, ny, zmin, zmax, nz, x0, dl, max_steps, csv_file, b_min)
subroutine, public mt_topology_plane_xy(xmin, xmax, nx, ymin, ymax, ny, z0, dl, max_steps, length_csv, twist_csv, mapping_csv, b_min)
subroutine, public mt_qsl_plane_vtu_yz(ymin, ymax, ny, zmin, zmax, nz, x0, dl, max_steps, vtu_file, b_min)
subroutine, public mt_qperp_plane_xz(xmin, xmax, nx, zmin, zmax, nz, y0, dl, max_steps, csv_file, b_min)
subroutine, public mt_qsl_plane_vtu_xy(xmin, xmax, nx, ymin, ymax, ny, z0, dl, max_steps, vtu_file, b_min)
subroutine, public mt_twist_plane_xz(xmin, xmax, nx, zmin, zmax, nz, y0, dl, max_steps, csv_file, b_min)
subroutine, public mt_length_plane_xy(xmin, xmax, nx, ymin, ymax, ny, z0, dl, max_steps, csv_file, b_min)
subroutine, public mt_fieldline_products_seeds(seeds, nseed, dl, max_steps, csv_file, b_min, compute_length, compute_twist, compute_q, compute_qperp, vtu_file)
subroutine, public mt_length_seeds(seeds, nseed, dl, max_steps, csv_file, b_min)
subroutine, public mt_topology_plane_yz(ymin, ymax, ny, zmin, zmax, nz, x0, dl, max_steps, length_csv, twist_csv, mapping_csv, b_min)
subroutine, public mt_qperp_plane_yz(ymin, ymax, ny, zmin, zmax, nz, x0, dl, max_steps, csv_file, b_min)
subroutine, public mt_qperp_plane_arbitrary(origin, e1, e2, s1min, s1max, n1, s2min, s2max, n2, dl, max_steps, csv_file, b_min)
subroutine, public mt_qperp_plane_xy(xmin, xmax, nx, ymin, ymax, ny, z0, dl, max_steps, csv_file, b_min)
subroutine, public mt_length_plane_xz(xmin, xmax, nx, zmin, zmax, nz, y0, dl, max_steps, csv_file, b_min)
subroutine, public mt_length_single(seed, dl, max_steps, csv_file, b_min)
subroutine, public mt_fieldline_products_volume_vti(xmin, xmax, nx, ymin, ymax, ny, zmin, zmax, nz, dl, max_steps, vti_file, b_min, compute_length, compute_twist, compute_q, compute_qperp, chunk_nz)
subroutine, public mt_qsl_plane_vtu_xz(xmin, xmax, nx, zmin, zmax, nz, y0, dl, max_steps, vtu_file, b_min)
subroutine, public mt_twist_plane_xy(xmin, xmax, nx, ymin, ymax, ny, z0, dl, max_steps, csv_file, b_min)
subroutine, public mt_params_read(files)
subroutine, public mt_topology_plane_xz(xmin, xmax, nx, zmin, zmax, nz, y0, dl, max_steps, length_csv, twist_csv, mapping_csv, b_min)
subroutine, public mt_mapping_plane_xy(xmin, xmax, nx, ymin, ymax, ny, z0, dl, max_steps, csv_file, b_min)
subroutine, public mt_twist_seeds(seeds, nseed, dl, max_steps, csv_file, b_min)
subroutine, public mt_length_plane_yz(ymin, ymax, ny, zmin, zmax, nz, x0, dl, max_steps, csv_file, b_min)
subroutine, public mt_run_topology_task()
subroutine, public mt_twist_single(seed, dl, max_steps, csv_file, b_min)
integer, parameter, public trace_face_ymin
integer, parameter, public trace_face_zmax
subroutine, public trace_spherical_profile_set(enabled)
subroutine, public trace_rk45_stats_reset()
subroutine, public trace_field_twist_multi(seeds, nseed, dl, max_steps, results, b_min)
subroutine, public trace_field_rk2_short_boundary_q_multi(seeds, nseed, dl, max_steps, results, b_min, twist_results)
subroutine, public trace_cartesian_global_min_cell_size(hmin, status)
subroutine, public trace_spherical_curl_cache_clear()
subroutine, public trace_field_qperp_multi(seeds, nseed, dl, max_steps, results, b_min, twist_results)
subroutine, public trace_field_spherical_rmin_q_multi(seeds, nseed, dl, max_steps, results, b_min, twist_results)
subroutine, public trace_rk45_stats_report(label)
subroutine, public trace_field_topology_multi(seeds, nseed, dl, max_steps, results, need_twist, need_mapping, b_min, source_normal)
integer, parameter, public trace_face_xmax
subroutine, public trace_field_twist_single(seed, dl, max_steps, result, b_min)
subroutine, public trace_field_mapping_single(seed, dl, max_steps, result, b_min, source_normal)
integer, parameter, public trace_face_none
integer, parameter, public trace_status_boundary
subroutine, public trace_spherical_profile_report(label)
integer, parameter, public trace_face_ambiguous
subroutine, public trace_field_qperp_single(seed, dl, max_steps, result, b_min)
integer, parameter, public trace_face_zmin
integer, parameter, public trace_status_unsupported_geometry
subroutine, public trace_set_step_control(mode, step_fraction, step_min)
subroutine, public trace_debug_cartesian_rk45_tangent_q0_multi(seeds, nseed, dl, max_steps, results, b_min)
integer, parameter, public trace_face_ymax
subroutine, public trace_spherical_global_min_cell_size(hmin, status)
subroutine, public trace_rk2_stats_reset()
subroutine, public trace_spherical_curl_cache_build(status)
subroutine, public trace_spherical_profile_count_seeds(nseed)
subroutine, public trace_spherical_profile_reset()
subroutine, public trace_field_spherical_rmin_q_qperp_multi(seeds, nseed, dl, max_steps, q_results, qperp_results, b_min, twist_results)
subroutine, public trace_field_length_multi(seeds, nseed, dl, max_steps, results, b_min)
subroutine, public trace_rk45_stats_set_enabled(enabled)
subroutine, public trace_set_integrator(mode, atol, rtol, safety, min_shrink, max_grow, tangent_floor, tangent_rtol)
subroutine, public trace_rk2_stats_set_enabled(enabled)
subroutine, public trace_field_spherical_qperp_multi(seeds, nseed, dl, max_steps, results, b_min, twist_results)
subroutine, public trace_rk2_stats_report(label)
subroutine, public trace_field_length_single(seed, dl, max_steps, result, b_min)
integer, parameter, public trace_face_xmin
subroutine, public trace_field_mapping_multi(seeds, nseed, dl, max_steps, results, b_min, source_normal)
integer, parameter, public trace_status_active