diff --git a/.clang-tidy b/.clang-tidy index 892b1b8a..84742de4 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,46 +1,46 @@ -Checks: > - '-*, - bugprone-*, - -bugprone-branch-clone, - -bugprone-easily-swappable-parameters, - -bugprone-exception-escape, - -bugprone-implicit-widening-of-multiplication-result, - clang-analyzer-*, - -clang-analyzer-optin.mpi.MPI-Checker, - clang-diagnostic-*, - cppcoreguidelines-*, - -cppcoreguidelines-avoid-c-arrays, - -cppcoreguidelines-avoid-goto, - -cppcoreguidelines-avoid-magic-numbers, - -cppcoreguidelines-avoid-non-const-global-variables, - -cppcoreguidelines-init-variables, - -cppcoreguidelines-interfaces-global-init, - -cppcoreguidelines-macro-usage, - -cppcoreguidelines-no-malloc, - -cppcoreguidelines-non-private-member-variables-in-classes, - -cppcoreguidelines-owning-memory, - -cppcoreguidelines-pro-*, - modernize-*, - -modernize-avoid-c-arrays, - -modernize-macro-to-enum, - -modernize-return-braced-init-list, - -modernize-use-trailing-return-type, - -modernize-use-using, - performance-*, - readability-*, - -readability-braces-around-statements, - -readability-container-data-pointer, - -readability-else-after-return, - -readability-function-cognitive-complexity, - -readability-function-size, - -readability-identifier-length, - -readability-implicit-bool-conversion, - -readability-isolate-declaration, - -readability-magic-numbers, - -readability-named-parameter, - -readability-simplify-boolean-expr, - mpi-* - ' - -# Files not ending with nolint.H will be filtered in. -HeaderFilterRegex: '([^n].....|[^o]....|[^l]...|[^i]..|[^n].|[^t])\.H$' +Checks: > + '-*, + bugprone-*, + -bugprone-branch-clone, + -bugprone-easily-swappable-parameters, + -bugprone-exception-escape, + -bugprone-implicit-widening-of-multiplication-result, + clang-analyzer-*, + -clang-analyzer-optin.mpi.MPI-Checker, + clang-diagnostic-*, + cppcoreguidelines-*, + -cppcoreguidelines-avoid-c-arrays, + -cppcoreguidelines-avoid-goto, + -cppcoreguidelines-avoid-magic-numbers, + -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-init-variables, + -cppcoreguidelines-interfaces-global-init, + -cppcoreguidelines-macro-usage, + -cppcoreguidelines-no-malloc, + -cppcoreguidelines-non-private-member-variables-in-classes, + -cppcoreguidelines-owning-memory, + -cppcoreguidelines-pro-*, + modernize-*, + -modernize-avoid-c-arrays, + -modernize-macro-to-enum, + -modernize-return-braced-init-list, + -modernize-use-trailing-return-type, + -modernize-use-using, + performance-*, + readability-*, + -readability-braces-around-statements, + -readability-container-data-pointer, + -readability-else-after-return, + -readability-function-cognitive-complexity, + -readability-function-size, + -readability-identifier-length, + -readability-implicit-bool-conversion, + -readability-isolate-declaration, + -readability-magic-numbers, + -readability-named-parameter, + -readability-simplify-boolean-expr, + mpi-* + ' + +# Files not ending with nolint.H will be filtered in. +HeaderFilterRegex: '([^n].....|[^o]....|[^l]...|[^i]..|[^n].|[^t])\.H$' diff --git a/.editorconfig b/.editorconfig index 446ca9f2..c9b6a028 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,49 +1,49 @@ -# http://EditorConfig.org -# -# precedence of rules is bottom to top - -# this is the top-most EditorConfig file -root = true - - -[*.{c,h,cpp,hpp,H,py}] -# 4 space indentation -indent_style = space -indent_size = 4 - -# setting it to true would result in too many white changes to amrex -trim_trailing_whitespace = true - -# unix-style newlines -end_of_line = lf - -# newline ending in files -insert_final_newline = true - - -[*.md] -# two end of line whitespaces are newlines without a paragraph -trim_trailing_whitespace = false - - -[*.rst] -# Enforce UTF-8 encoding -charset = utf-8 - -# Unix-style newlines -end_of_line = lf - -# Newline ending in files -insert_final_newline = true - -# 3 space indentation -indent_style = space -indent_size = 3 - -# Clean up trailing whitespace -trim_trailing_whitespace = true - -[Makefile] -# TABs are part of its syntax -indent_style = tab -indent_size = unset +# http://EditorConfig.org +# +# precedence of rules is bottom to top + +# this is the top-most EditorConfig file +root = true + + +[*.{c,h,cpp,hpp,H,py}] +# 4 space indentation +indent_style = space +indent_size = 4 + +# setting it to true would result in too many white changes to amrex +trim_trailing_whitespace = true + +# unix-style newlines +end_of_line = lf + +# newline ending in files +insert_final_newline = true + + +[*.md] +# two end of line whitespaces are newlines without a paragraph +trim_trailing_whitespace = false + + +[*.rst] +# Enforce UTF-8 encoding +charset = utf-8 + +# Unix-style newlines +end_of_line = lf + +# Newline ending in files +insert_final_newline = true + +# 3 space indentation +indent_style = space +indent_size = 3 + +# Clean up trailing whitespace +trim_trailing_whitespace = true + +[Makefile] +# TABs are part of its syntax +indent_style = tab +indent_size = unset diff --git a/.gitattributes b/.gitattributes index 87122e07..6771b5c1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,6 @@ -*.ipynb linguist-vendored -*.tex linguist-documentation - -*.H linguist-language=C++ +*.ipynb linguist-vendored +*.tex linguist-documentation + +*.H linguist-language=C++ +# Force use of LF +* text=auto eol=lf \ No newline at end of file diff --git a/.gitignore b/.gitignore index 866c2cfe..3ae97540 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,18 @@ -nohup.out -*.[oa] -*.ex -*~ -chk????? -plt????? -d/ -f/ -o/ -chk?????.old* -plt?????.old* -Tutorials_profling/*/* -log* -bl_prof* -case_results*/ -tmp_build_dir/ +nohup.out +*.[oa] +*.ex +*~ +chk????? +plt????? +d/ +f/ +o/ +chk?????.old* +plt?????.old* +Tutorials_profling/*/* +log* +bl_prof* +case_results*/ +tmp_build_dir/ .codegpt \ No newline at end of file diff --git a/JOSS_paper/paper.bib b/JOSS_paper/paper.bib index 612cff62..b22c1b41 100644 --- a/JOSS_paper/paper.bib +++ b/JOSS_paper/paper.bib @@ -1,87 +1,87 @@ -@ARTICLE{almgren1998conservative, - title={{A conservative adaptive projection method for the variable density incompressible Navier--Stokes equations}}, - author={Almgren, Ann S and Bell, John B and Colella, Phillip and Howell, Louis H and Welcome, Michael L}, - journal={Journal of Computational Physics}, - volume={142}, - number={1}, - pages={1--46}, - year={1998}, - publisher={Elsevier}, - DOI = {10.1006/jcph.1998.5890} -} - -@ARTICLE{zeng2022parallel, - title={{A parallel cell-centered adaptive level set framework for efficient simulation of two-phase flows with subcycling and non-subcycling}}, - author={Zeng, Yadong and Xuan, Anqing and Blaschke, Johannes and Shen, Lian}, - journal={Journal of Computational Physics}, - volume={448}, - pages={110740}, - year={2022}, - publisher={Elsevier}, - DOI = {10.1016/j.jcp.2021.110740} -} - -@ARTICLE{zeng2023consistent, - title={{A consistent adaptive level set framework for incompressible two-phase flows with high density ratios and high Reynolds numbers}}, - author={Zeng, Yadong and Liu, Han and Gao, Qiang and Almgren, Ann and Bhalla, Amneet Pal Singh and Shen, Lian}, - journal={Journal of Computational Physics}, - volume={478}, - pages={111971}, - year={2023}, - publisher={Elsevier}, - DOI = {10.1016/j.jcp.2023.111971} -} - -@ARTICLE{li2024open, - title={{An open-source, adaptive solver for particle-resolved simulations with both subcycling and non-subcycling methods}}, - author={Li, Xuzhu and Li, Chun and Li, Xiaokai and Li, Wenzhuo and Tang, Mingze and Zeng, Yadong and Zhu, Zhengping}, - journal={Physics of Fluids}, - volume={36}, - number={11}, - year={2024}, - publisher={AIP Publishing}, - DOI = {10.1063/5.0236509} -} - -@ARTICLE{zhang2019amrex, - title={{AMReX: a framework for block-structured adaptive mesh refinement}}, - author={Zhang, Weiqun and Almgren, Ann and Beckner, Vince and Bell, John and Blaschke, Johannes and Chan, Cy and Day, Marcus and Friesen, Brian and Gott, Kevin and Graves, Daniel and others}, - journal={Journal of Open Source Software}, - volume={4}, - number={37}, - year={2019}, - publisher = {The Open Journal}, - DOI = {10.21105/joss.01370} -} - -@article{gong2023cp3d, - title={CP3d: A comprehensive Euler-Lagrange solver for direct numerical simulation of particle-laden flows}, - author={Gong, Zheng and Wu, Zi and An, Chenge and Zhang, Bangwen and Fu, Xudong}, - journal={Computer Physics Communications}, - volume={286}, - pages={108666}, - year={2023}, - publisher={Elsevier} -} - -@article{costa2018fft, - title={A FFT-based finite-difference solver for massively-parallel direct numerical simulations of turbulent flows}, - author={Costa, Pedro}, - journal={Computers \& Mathematics with Applications}, - volume={76}, - number={8}, - pages={1853--1862}, - year={2018}, - publisher={Elsevier} -} - -@article{laizet2011incompact3d, - title={Incompact3d: A powerful tool to tackle turbulence problems with up to O (105) computational cores}, - author={Laizet, Sylvain and Li, Ning}, - journal={International Journal for Numerical Methods in Fluids}, - volume={67}, - number={11}, - pages={1735--1757}, - year={2011}, - publisher={Wiley Online Library} -} +@ARTICLE{almgren1998conservative, + title={{A conservative adaptive projection method for the variable density incompressible Navier--Stokes equations}}, + author={Almgren, Ann S and Bell, John B and Colella, Phillip and Howell, Louis H and Welcome, Michael L}, + journal={Journal of Computational Physics}, + volume={142}, + number={1}, + pages={1--46}, + year={1998}, + publisher={Elsevier}, + DOI = {10.1006/jcph.1998.5890} +} + +@ARTICLE{zeng2022parallel, + title={{A parallel cell-centered adaptive level set framework for efficient simulation of two-phase flows with subcycling and non-subcycling}}, + author={Zeng, Yadong and Xuan, Anqing and Blaschke, Johannes and Shen, Lian}, + journal={Journal of Computational Physics}, + volume={448}, + pages={110740}, + year={2022}, + publisher={Elsevier}, + DOI = {10.1016/j.jcp.2021.110740} +} + +@ARTICLE{zeng2023consistent, + title={{A consistent adaptive level set framework for incompressible two-phase flows with high density ratios and high Reynolds numbers}}, + author={Zeng, Yadong and Liu, Han and Gao, Qiang and Almgren, Ann and Bhalla, Amneet Pal Singh and Shen, Lian}, + journal={Journal of Computational Physics}, + volume={478}, + pages={111971}, + year={2023}, + publisher={Elsevier}, + DOI = {10.1016/j.jcp.2023.111971} +} + +@ARTICLE{li2024open, + title={{An open-source, adaptive solver for particle-resolved simulations with both subcycling and non-subcycling methods}}, + author={Li, Xuzhu and Li, Chun and Li, Xiaokai and Li, Wenzhuo and Tang, Mingze and Zeng, Yadong and Zhu, Zhengping}, + journal={Physics of Fluids}, + volume={36}, + number={11}, + year={2024}, + publisher={AIP Publishing}, + DOI = {10.1063/5.0236509} +} + +@ARTICLE{zhang2019amrex, + title={{AMReX: a framework for block-structured adaptive mesh refinement}}, + author={Zhang, Weiqun and Almgren, Ann and Beckner, Vince and Bell, John and Blaschke, Johannes and Chan, Cy and Day, Marcus and Friesen, Brian and Gott, Kevin and Graves, Daniel and others}, + journal={Journal of Open Source Software}, + volume={4}, + number={37}, + year={2019}, + publisher = {The Open Journal}, + DOI = {10.21105/joss.01370} +} + +@article{gong2023cp3d, + title={CP3d: A comprehensive Euler-Lagrange solver for direct numerical simulation of particle-laden flows}, + author={Gong, Zheng and Wu, Zi and An, Chenge and Zhang, Bangwen and Fu, Xudong}, + journal={Computer Physics Communications}, + volume={286}, + pages={108666}, + year={2023}, + publisher={Elsevier} +} + +@article{costa2018fft, + title={A FFT-based finite-difference solver for massively-parallel direct numerical simulations of turbulent flows}, + author={Costa, Pedro}, + journal={Computers \& Mathematics with Applications}, + volume={76}, + number={8}, + pages={1853--1862}, + year={2018}, + publisher={Elsevier} +} + +@article{laizet2011incompact3d, + title={Incompact3d: A powerful tool to tackle turbulence problems with up to O (105) computational cores}, + author={Laizet, Sylvain and Li, Ning}, + journal={International Journal for Numerical Methods in Fluids}, + volume={67}, + number={11}, + pages={1735--1757}, + year={2011}, + publisher={Wiley Online Library} +} diff --git a/JOSS_paper/paper.md b/JOSS_paper/paper.md index 2ef86e25..293ff286 100644 --- a/JOSS_paper/paper.md +++ b/JOSS_paper/paper.md @@ -1,96 +1,96 @@ ---- -title: 'IAMReX: an adaptive framework for the multiphase flow and fluid-particle interaction problems' -tags: - - C++ - - Computational Fluid Dynamics - - Adaptive Mesh Refinement - - Immersed Boundary Method - - Multiphase Flow -authors: - - name: Chun Li - orcid: 0009-0001-6081-5450 - affiliation: "1, 2" - - name: Xuzhu Li - orcid: 0009-0007-5348-4159 - affiliation: "1, 3" - - name: Yiliang Wang - orcid: 0000-0002-0156-2203 - affiliation: 4 - - name: Dewen Liu - orcid: 0009-0006-2728-421X - affiliation: 5 - - name: Shuai He - orcid: 0009-0004-7754-8346 - affiliation: 6 - - name: Haoran Cheng - orcid: 0009-0002-7636-038X - affiliation: 7 - - name: Xiaokai Li - orcid: 0009-0001-6639-0473 - affiliation: 8 - - name: Wenzhuo Li - orcid: 0009-0001-7608-2992 - affiliation: 9 - - name: Mingze Tang - orcid: 0009-0007-4194-9908 - affiliation: 10 - - name: Zhengping Zhu - orcid: 0000-0002-1315-3554 - affiliation: 1 - - name: Yadong Zeng - corresponding: true - orcid: 0009-0001-7944-3597 - affiliation: 11 -affiliations: - - name: Research Center for Astronomical Computing, Zhejiang Laboratory, Hangzhou, 311100, China - index: 1 - - name: School of Energy and Power Engineering, Lanzhou University of Technology, Lanzhou, 730050, China - index: 2 - - name: School of Mechanical Engineering, Hefei University of Technology, Hefei, 230009, China - index: 3 - - name: Independent Researcher, Loveland, 45140, USA - index: 4 - - name: School of Civil Engineering, Southwest Jiaotong University, Chengdu, 611756, China - index: 5 - - name: School of Power and Energy, Northwestern Polytechnical University, Xi'an, 710129, China - index: 6 - - name: Department of Electrical Engineering and Computer Science, University of Michigan, Ann Arbor, 48104, USA - index: 7 - - name: School of Physical Science and Technology, ShanghaiTech University, Shanghai, 201210, China - index: 8 - - name: Advanced Propulsion Laboratory, Department of Modern Mechanics, University of Science and Technology of China, Hefei, 230026, China - index: 9 - - name: School of Aeronautics, Northwestern Polytechnical University, Xi'an, 710072, China - index: 10 - - name: Department of Computer Science, University of Texas at Austin, Austin, 78712, USA - index: 11 - -date: 17 January 2025 -bibliography: paper.bib - -# # Optional fields if submitting to a ASS, AS journal too, see this blog post: -# # https://blog.joss.theoj.org/2018/12/a-new-collaboration-with-aas-publishing -# aas-doi: 10.3847/xxxxx <- update this with the DOI from ASS, AS once you know it. -# aas-journal: Astrophysical Journal <- The name of the ASS, AS journal. ---- - -# Summary - -IAMReX is an adaptive C++ solver designed for multiphase flow and fluid-particle interaction problems. It is built in a objected-oriented style and capable of high-performance massively parallel computing complex systems (e.g., gas-fluid interaction, cluster of particles). - -The original goal of IAMReX is to extend the capability of IAMR codes [@almgren1998conservative], which only uses a density-based solver to capture the diffused interface of the two-phase flow. IAMReX offers the Level Set (LS) method and the reinitialization techniques for accurately capturing the two-phase interface [@zeng2022parallel], which increases the robustness of simulations with high Reynolds number [@zeng2023consistent]. For fluid-particle interaction problems, IAMReX employs the multidirect forcing immersed boundary method [@li2024open]. The associated Lagrangian markers used to resolve fluid-particle interface only exist on the finest-level grid, which greatly reduces memory cost. Both the subcycling and non-subcycling time advancement methods are implemented, and these methods help to decouple the time advancement at different levels. In addition, IAMReX is a publicly accessible platform designed specifically for developing massively parallel block-structured adaptive mesh refinement (BSAMR) applications. The code now supports hybrid parallelization using either pure MPI or MPI & OpenMP for multicore machines with the help of the AMReX framework [@zhang2019amrex]. - -The IAMReX code has undergone considerable development since 2023 and gained a few new contributors in the past two years. Although the projection-based flow solver is inherited from IAMR, IAMReX has added over 3,000 lines of new code, introduced 10 more new test cases, and contributed approximately 60 new commits on GitHub. The versatility, accuracy, and efficiency of the present IAMReX framework are demonstrated by simulating two-phase flow and fluid-particle interaction problems with various types of kinematic constraints. We carefully designed the document such that users can easily compile and run cases. Input files, profiling scripts, and raw postprocessing data are also available for reproducing all results. - -# Statement of need - -IAMReX is suitable for modeling multiphase flow problems and fluid-structure interaction problems. Its Level Set-based interface capturing technique can be beneficial for researchers studying phenomena such as wind over waves, breaking waves, and simulating the formation and disappearance of bubbles and droplets. Additionally, the immersed boundary method along with the collision models can parallelly resolve large-scale particles and capture their motions. Researchers working on studies of biological particle aggregation, sandstorms, wind erosion of ground surfaces, and seawater erosion of riverbeds are also among the target audience for this software. - -# State of the field -We made great efforts to simulate more complex multiphase flows at higher resolution using IAMReX. One effort is to combine the AMR technique with the multidirect forcing immersed boundary method to resolve particles only on the finest-level grid. It significantly reduces the grid requirements for particle-resolved simulation compared with commonly used uniform grid solvers [Incompact3d](https://github.com/xcompact3d/Incompact3d), [CaNS](https://github.com/CaNS-World/CaNS), and [CP3d](https://github.com/GongZheng-Justin/CP3d). Additionally, we utilized a subcycling technique to alleviate the time step constraint on coarser levels. It minimizes the total time step needed by time advancement compared with the non-subcycling technique used in other AMR-related packages, such as [IBAMR](https://github.com/IBAMR/IBAMR.git), [basilisk](http://basilisk.fr/), and [incflo](https://github.com/AMReX-Fluids/incflo.git). - -# Acknowledgements - -C.L., X.L., Y.Z., and Z.Z. are grateful to Ann Almgren, John Bell, Andy Nonaka, Candace Gilet, Andrew Myers, Axel Huebl, Marc Day, and Weiqun Zhang in the Lawrence Berkeley National Laboratory (LBNL) for their discussions related to AMReX and IAMR. We sincerely thank all the developers who have contributed to the original IAMR repository, although this paper focus on the newly added features and does not include the names of all contributors. Y.Z. and Z.Z. also thank Prof. Lian Shen, Prof. Ruifeng Hu, and Prof. Xiaojing Zheng during their Ph.D. studies. - -# References +--- +title: 'IAMReX: an adaptive framework for the multiphase flow and fluid-particle interaction problems' +tags: + - C++ + - Computational Fluid Dynamics + - Adaptive Mesh Refinement + - Immersed Boundary Method + - Multiphase Flow +authors: + - name: Chun Li + orcid: 0009-0001-6081-5450 + affiliation: "1, 2" + - name: Xuzhu Li + orcid: 0009-0007-5348-4159 + affiliation: "1, 3" + - name: Yiliang Wang + orcid: 0000-0002-0156-2203 + affiliation: 4 + - name: Dewen Liu + orcid: 0009-0006-2728-421X + affiliation: 5 + - name: Shuai He + orcid: 0009-0004-7754-8346 + affiliation: 6 + - name: Haoran Cheng + orcid: 0009-0002-7636-038X + affiliation: 7 + - name: Xiaokai Li + orcid: 0009-0001-6639-0473 + affiliation: 8 + - name: Wenzhuo Li + orcid: 0009-0001-7608-2992 + affiliation: 9 + - name: Mingze Tang + orcid: 0009-0007-4194-9908 + affiliation: 10 + - name: Zhengping Zhu + orcid: 0000-0002-1315-3554 + affiliation: 1 + - name: Yadong Zeng + corresponding: true + orcid: 0009-0001-7944-3597 + affiliation: 11 +affiliations: + - name: Research Center for Astronomical Computing, Zhejiang Laboratory, Hangzhou, 311100, China + index: 1 + - name: School of Energy and Power Engineering, Lanzhou University of Technology, Lanzhou, 730050, China + index: 2 + - name: School of Mechanical Engineering, Hefei University of Technology, Hefei, 230009, China + index: 3 + - name: Independent Researcher, Loveland, 45140, USA + index: 4 + - name: School of Civil Engineering, Southwest Jiaotong University, Chengdu, 611756, China + index: 5 + - name: School of Power and Energy, Northwestern Polytechnical University, Xi'an, 710129, China + index: 6 + - name: Department of Electrical Engineering and Computer Science, University of Michigan, Ann Arbor, 48104, USA + index: 7 + - name: School of Physical Science and Technology, ShanghaiTech University, Shanghai, 201210, China + index: 8 + - name: Advanced Propulsion Laboratory, Department of Modern Mechanics, University of Science and Technology of China, Hefei, 230026, China + index: 9 + - name: School of Aeronautics, Northwestern Polytechnical University, Xi'an, 710072, China + index: 10 + - name: Department of Computer Science, University of Texas at Austin, Austin, 78712, USA + index: 11 + +date: 17 January 2025 +bibliography: paper.bib + +# # Optional fields if submitting to a ASS, AS journal too, see this blog post: +# # https://blog.joss.theoj.org/2018/12/a-new-collaboration-with-aas-publishing +# aas-doi: 10.3847/xxxxx <- update this with the DOI from ASS, AS once you know it. +# aas-journal: Astrophysical Journal <- The name of the ASS, AS journal. +--- + +# Summary + +IAMReX is an adaptive C++ solver designed for multiphase flow and fluid-particle interaction problems. It is built in a objected-oriented style and capable of high-performance massively parallel computing complex systems (e.g., gas-fluid interaction, cluster of particles). + +The original goal of IAMReX is to extend the capability of IAMR codes [@almgren1998conservative], which only uses a density-based solver to capture the diffused interface of the two-phase flow. IAMReX offers the Level Set (LS) method and the reinitialization techniques for accurately capturing the two-phase interface [@zeng2022parallel], which increases the robustness of simulations with high Reynolds number [@zeng2023consistent]. For fluid-particle interaction problems, IAMReX employs the multidirect forcing immersed boundary method [@li2024open]. The associated Lagrangian markers used to resolve fluid-particle interface only exist on the finest-level grid, which greatly reduces memory cost. Both the subcycling and non-subcycling time advancement methods are implemented, and these methods help to decouple the time advancement at different levels. In addition, IAMReX is a publicly accessible platform designed specifically for developing massively parallel block-structured adaptive mesh refinement (BSAMR) applications. The code now supports hybrid parallelization using either pure MPI or MPI & OpenMP for multicore machines with the help of the AMReX framework [@zhang2019amrex]. + +The IAMReX code has undergone considerable development since 2023 and gained a few new contributors in the past two years. Although the projection-based flow solver is inherited from IAMR, IAMReX has added over 3,000 lines of new code, introduced 10 more new test cases, and contributed approximately 60 new commits on GitHub. The versatility, accuracy, and efficiency of the present IAMReX framework are demonstrated by simulating two-phase flow and fluid-particle interaction problems with various types of kinematic constraints. We carefully designed the document such that users can easily compile and run cases. Input files, profiling scripts, and raw postprocessing data are also available for reproducing all results. + +# Statement of need + +IAMReX is suitable for modeling multiphase flow problems and fluid-structure interaction problems. Its Level Set-based interface capturing technique can be beneficial for researchers studying phenomena such as wind over waves, breaking waves, and simulating the formation and disappearance of bubbles and droplets. Additionally, the immersed boundary method along with the collision models can parallelly resolve large-scale particles and capture their motions. Researchers working on studies of biological particle aggregation, sandstorms, wind erosion of ground surfaces, and seawater erosion of riverbeds are also among the target audience for this software. + +# State of the field +We made great efforts to simulate more complex multiphase flows at higher resolution using IAMReX. One effort is to combine the AMR technique with the multidirect forcing immersed boundary method to resolve particles only on the finest-level grid. It significantly reduces the grid requirements for particle-resolved simulation compared with commonly used uniform grid solvers [Incompact3d](https://github.com/xcompact3d/Incompact3d), [CaNS](https://github.com/CaNS-World/CaNS), and [CP3d](https://github.com/GongZheng-Justin/CP3d). Additionally, we utilized a subcycling technique to alleviate the time step constraint on coarser levels. It minimizes the total time step needed by time advancement compared with the non-subcycling technique used in other AMR-related packages, such as [IBAMR](https://github.com/IBAMR/IBAMR.git), [basilisk](http://basilisk.fr/), and [incflo](https://github.com/AMReX-Fluids/incflo.git). + +# Acknowledgements + +C.L., X.L., Y.Z., and Z.Z. are grateful to Ann Almgren, John Bell, Andy Nonaka, Candace Gilet, Andrew Myers, Axel Huebl, Marc Day, and Weiqun Zhang in the Lawrence Berkeley National Laboratory (LBNL) for their discussions related to AMReX and IAMR. We sincerely thank all the developers who have contributed to the original IAMR repository, although this paper focus on the newly added features and does not include the names of all contributors. Y.Z. and Z.Z. also thank Prof. Lian Shen, Prof. Ruifeng Hu, and Prof. Xiaojing Zheng during their Ph.D. studies. + +# References diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 1736e9dd..00000000 --- a/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2018, -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/LICENSES/BSD-3-Clause.txt b/LICENSES/BSD-3-Clause.txt new file mode 100644 index 00000000..b51e7d67 --- /dev/null +++ b/LICENSES/BSD-3-Clause.txt @@ -0,0 +1,12 @@ +Copyright (c) 2022-2025 +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/OpenSource.txt b/LICENSES/LicenseRef-OpenSource.txt similarity index 98% rename from OpenSource.txt rename to LICENSES/LicenseRef-OpenSource.txt index 725199eb..1f22ddf2 100644 --- a/OpenSource.txt +++ b/LICENSES/LicenseRef-OpenSource.txt @@ -1,176 +1,176 @@ -SOURCE CODE LICENSE AGREEMENT -Software: IAMR -Version: Oct. 12, 2000 Release - -IMPORTANT - READ CAREFULLY: This License Agreement ("Agreement") is a -legal agreement between you (in your capacity as an individual and as -an agent for your company, institution or other entity) and The -Regents of the University of California, Department of Energy -contract-operators of the Ernest Orlando Lawrence Berkeley National -Laboratory ("Berkeley Lab"). Downloading, installing, using, or -copying of the Software (as defined below) by you or by a third party -on your behalf indicates your agreement to be bound by the terms and -conditions of this Agreement. If you do not agree to these terms and -conditions, do not download, install or use the Software. - -1. LICENSE GRANT. Berkeley Lab grants you, and you hereby accept, a - non-exclusive, royalty-free perpetual license to install, use, - modify, prepare derivative works, incorporate into other computer - software, and distribute the version noted above of the computer - software program noted above, in binary and source code format, or - any derivative work thereof, together with any associated media, - printed materials, and on-line or electronic documentation (if - any) provided by Berkeley Lab (collectively, the "Software"), - subject to the following terms and conditions: (i) any - distribution of the Software shall bind the receiver to the terms - and conditions of this Agreement; (ii) any distribution of the - Software in modified form shall clearly state that the Software - has been modified from the version originally obtained from - Berkeley Lab. This version of the Software constitutes a research - prototype and may be changed substantially. The license grant set - forth above is subject to receipt by Berkeley Lab of any required - U.S. Department of Energy approvals. - -2. COPYRIGHT; RETENTION OF RIGHTS. The above license grant is - conditioned on the following: (i) you must reproduce all copyright - notices and other proprietary notices on any copies of the - Software and you must not remove such notices; (ii) in the event - you compile the Software, you will include the copyright notice - with the binary in such a manner as to allow it to be easily - viewable; (iii) if you incorporate the Software into other code, - you must provide notice that the code contains the Software and - include a copy of the copyright notices and other proprietary - notices. All copies of the Software shall be subject to the terms - of this Agreement. Subject to approval by the U.S. Department of - Energy: (a) you hereby acknowledge that the Software is protected - by United States copyright law and international treaty - provisions; (b) Berkeley Lab, and its licensors (if any), hereby - reserve all rights in the Software which are not explicitly - granted to you herein; (c) without limiting the generality of the - foregoing, Berkeley Lab and its licensors retain all title, - copyright, and other proprietary interests in the Software and any - copies thereof, and you do not acquire any rights, express or - implied, in the Software, other than those specifically set forth - in this Agreement. - -3. NO MAINTENANCE OR SUPPORT; TREATMENT OF ENHANCEMENTS YOU CHOOSE TO - PROVIDE TO BERKELEY LAB. Berkeley Lab is under no obligation - whatsoever to: (i) provide maintenance or support for the - Software; or (ii) to notify you of bug fixes, patches, or upgrades - to the features, functionality or performance of the Software - ("Enhancements") (if any), whether developed by Berkeley Lab or - third parties. If, in its sole discretion, Berkeley Lab makes an - Enhancement available to you and Berkeley Lab does not separately - enter into a written license agreement with you relating to such - bug fix, patch or upgrade, then it shall be deemed incorporated - into the Software and subject to this Agreement. You are under no - obligation whatsoever to provide any Enhancements to Berkeley Lab - that you may develop over time; however, if you choose to provide - Berkeley Lab with Enhancements in source code form that you have - developed without contemporaneously requiring Berkeley Lab to - enter into a separate written license agreement, then you hereby - grant Berkeley Lab a non-exclusive, royalty-free perpetual license - to install, use, modify, prepare derivative works, incorporate - into the Software or other computer software, distribute, and - sublicense your Enhancements or derivative works thereof, in - binary and source code form. - -4. U.S. GOVERNMENT RIGHTS. The Software was developed under funding - from the U.S. Department of Energy and the U.S. Government - consequently retains certain rights as follows: the - U.S. Government has been granted for itself and others acting on - its behalf a paid-up, nonexclusive, irrevocable, worldwide license - in the Software to reproduce, prepare derivative works, and - perform publicly and display publicly. Beginning five (5) years - after the date permission to assert copyright was granted by the - U.S. Dept. of Energy, and subject to any subsequent five (5) year - renewals, the U.S. Government is granted for itself and others - acting on its behalf a paid-up, nonexclusive, irrevocable, - worldwide license in the Software to reproduce, prepare derivative - works, distribute copies to the public, perform publicly and - display publicly, and to permit others to do so. - -5. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT - WARRANTY OF ANY KIND. BERKELEY LAB, ITS LICENSORS, THE UNITED - STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND THEIR - EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR - NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY OR - RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF - THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD - NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE - SOFTWARE WILL FUNCTION UNINTERRUPTED, THAT IT IS ERROR-FREE OR - THAT ANY ERRORS WILL BE CORRECTED. - -6. LIMITATION OF LIABILITY. IN NO EVENT WILL BERKELEY LAB OR ITS - LICENSORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL, CONSEQUENTIAL, - SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING BUT - NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON - WHATSOEVER, WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF - CONTRACT, TORT (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR - OTHERWISE, EVEN IF BERKELEY LAB HAS BEEN WARNED OF THE POSSIBILITY - OF SUCH LOSS OR DAMAGES. IN NO EVENT SHALL BERKELEY LAB'S - LIABILITY FOR DAMAGES ARISING FROM OR IN CONNECTION WITH THIS - AGREEMENT EXCEED THE AMOUNT PAID BY YOU FOR THE SOFTWARE. - -7. INDEMNITY. You shall indemnify, defend, and hold harmless - Berkeley Lab, the U.S. Government, the Software developers, the - Software sponsors, and their agents, officers, and employees, - against any and all claims, suits, losses, damage, costs, fees, - and expenses arising out of or in connection with this Agreement. - You shall pay all costs incurred by Berkeley Lab in enforcing this - provision, including reasonable attorney fees. - -8. TERM AND TERMINATION. The license granted to you under this - Agreement will continue perpetually unless terminated by Berkeley - Lab in accordance with this Agreement. If you breach any term of - this Agreement, and fail to cure such breach within thirty (30) - days of the date of written notice, this Agreement shall - immediately terminate. Upon such termination, you shall - immediately cease using the Software, return to Berkeley Lab, or - destroy, all copies of the Software, and provide Berkeley Lab with - written certification of your compliance with the foregoing. - Termination shall not relieve you from your obligations arising - prior to such termination. Notwithstanding any provision of this - Agreement to the contrary, Sections 5 through 10 shall survive - termination of this Agreement. - -9. EXPORT CONTROLS. You shall observe all applicable United States - and foreign laws and regulations (if any) with respect to the - export, re-export, diversion or transfer of the Software, related - technical data and direct products thereof, including, without - limitation, the International Traffic in Arms Regulations (ITAR) - and the Export Administration Regulations. - -10. NO ENDORSEMENT. In accordance with California Education Code - Section 92000, you shall not use in advertising, publicity or - other promotional activities any name, trade name, trademark, or - other designation of the University of California, nor shall you - so use "Ernest Orlando Lawrence Berkeley National Laboratory" or - "United States Department of Energy" (including any contraction, - abbreviation, or simulation of any of the foregoing) without - Berkeley Lab's prior written consent. - -11. GENERAL. This Agreement shall be governed by the laws of the - State of California, excluding its rules governing conflicts of - laws. No provision in either party's purchase orders, or in any - other business forms employed by either party will supersede the - terms of this Agreement, and no modification or amendment of this - Agreement is binding, unless in writing signed by a duly - authorized representative of each party. This Agreement is - binding upon and shall inure to the benefit of Berkeley Lab, its - successors and assigns. This Agreement represents the entire - understanding of the parties, and supersedes all previous - communications, written or oral, relating to the subject of this - Agreement. If you have any questions concerning this license, - contact Lawrence Berkeley National Laboratory, Technology Transfer - Department, One Cyclotron Road, MS 90-1070, Berkeley, CA 94720, - Attn: Software Licensing or via e-mail at ipo@lbl.gov. - -If you have any questions or feedback concerning this Software, -contact the Center for Computational Sciences and Engineering, -Lawrence Berkeley National Laboratory, One Cyclotron Road, MS -50A-3111, Berkeley, CA 94720 or via email at ASAlmgren@lbl.gov - -Form rev000928 +SOURCE CODE LICENSE AGREEMENT +Software: IAMR +Version: Oct. 12, 2000 Release + +IMPORTANT - READ CAREFULLY: This License Agreement ("Agreement") is a +legal agreement between you (in your capacity as an individual and as +an agent for your company, institution or other entity) and The +Regents of the University of California, Department of Energy +contract-operators of the Ernest Orlando Lawrence Berkeley National +Laboratory ("Berkeley Lab"). Downloading, installing, using, or +copying of the Software (as defined below) by you or by a third party +on your behalf indicates your agreement to be bound by the terms and +conditions of this Agreement. If you do not agree to these terms and +conditions, do not download, install or use the Software. + +1. LICENSE GRANT. Berkeley Lab grants you, and you hereby accept, a + non-exclusive, royalty-free perpetual license to install, use, + modify, prepare derivative works, incorporate into other computer + software, and distribute the version noted above of the computer + software program noted above, in binary and source code format, or + any derivative work thereof, together with any associated media, + printed materials, and on-line or electronic documentation (if + any) provided by Berkeley Lab (collectively, the "Software"), + subject to the following terms and conditions: (i) any + distribution of the Software shall bind the receiver to the terms + and conditions of this Agreement; (ii) any distribution of the + Software in modified form shall clearly state that the Software + has been modified from the version originally obtained from + Berkeley Lab. This version of the Software constitutes a research + prototype and may be changed substantially. The license grant set + forth above is subject to receipt by Berkeley Lab of any required + U.S. Department of Energy approvals. + +2. COPYRIGHT; RETENTION OF RIGHTS. The above license grant is + conditioned on the following: (i) you must reproduce all copyright + notices and other proprietary notices on any copies of the + Software and you must not remove such notices; (ii) in the event + you compile the Software, you will include the copyright notice + with the binary in such a manner as to allow it to be easily + viewable; (iii) if you incorporate the Software into other code, + you must provide notice that the code contains the Software and + include a copy of the copyright notices and other proprietary + notices. All copies of the Software shall be subject to the terms + of this Agreement. Subject to approval by the U.S. Department of + Energy: (a) you hereby acknowledge that the Software is protected + by United States copyright law and international treaty + provisions; (b) Berkeley Lab, and its licensors (if any), hereby + reserve all rights in the Software which are not explicitly + granted to you herein; (c) without limiting the generality of the + foregoing, Berkeley Lab and its licensors retain all title, + copyright, and other proprietary interests in the Software and any + copies thereof, and you do not acquire any rights, express or + implied, in the Software, other than those specifically set forth + in this Agreement. + +3. NO MAINTENANCE OR SUPPORT; TREATMENT OF ENHANCEMENTS YOU CHOOSE TO + PROVIDE TO BERKELEY LAB. Berkeley Lab is under no obligation + whatsoever to: (i) provide maintenance or support for the + Software; or (ii) to notify you of bug fixes, patches, or upgrades + to the features, functionality or performance of the Software + ("Enhancements") (if any), whether developed by Berkeley Lab or + third parties. If, in its sole discretion, Berkeley Lab makes an + Enhancement available to you and Berkeley Lab does not separately + enter into a written license agreement with you relating to such + bug fix, patch or upgrade, then it shall be deemed incorporated + into the Software and subject to this Agreement. You are under no + obligation whatsoever to provide any Enhancements to Berkeley Lab + that you may develop over time; however, if you choose to provide + Berkeley Lab with Enhancements in source code form that you have + developed without contemporaneously requiring Berkeley Lab to + enter into a separate written license agreement, then you hereby + grant Berkeley Lab a non-exclusive, royalty-free perpetual license + to install, use, modify, prepare derivative works, incorporate + into the Software or other computer software, distribute, and + sublicense your Enhancements or derivative works thereof, in + binary and source code form. + +4. U.S. GOVERNMENT RIGHTS. The Software was developed under funding + from the U.S. Department of Energy and the U.S. Government + consequently retains certain rights as follows: the + U.S. Government has been granted for itself and others acting on + its behalf a paid-up, nonexclusive, irrevocable, worldwide license + in the Software to reproduce, prepare derivative works, and + perform publicly and display publicly. Beginning five (5) years + after the date permission to assert copyright was granted by the + U.S. Dept. of Energy, and subject to any subsequent five (5) year + renewals, the U.S. Government is granted for itself and others + acting on its behalf a paid-up, nonexclusive, irrevocable, + worldwide license in the Software to reproduce, prepare derivative + works, distribute copies to the public, perform publicly and + display publicly, and to permit others to do so. + +5. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT + WARRANTY OF ANY KIND. BERKELEY LAB, ITS LICENSORS, THE UNITED + STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND THEIR + EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR + NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY OR + RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF + THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD + NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE + SOFTWARE WILL FUNCTION UNINTERRUPTED, THAT IT IS ERROR-FREE OR + THAT ANY ERRORS WILL BE CORRECTED. + +6. LIMITATION OF LIABILITY. IN NO EVENT WILL BERKELEY LAB OR ITS + LICENSORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL, CONSEQUENTIAL, + SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING BUT + NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON + WHATSOEVER, WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF + CONTRACT, TORT (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR + OTHERWISE, EVEN IF BERKELEY LAB HAS BEEN WARNED OF THE POSSIBILITY + OF SUCH LOSS OR DAMAGES. IN NO EVENT SHALL BERKELEY LAB'S + LIABILITY FOR DAMAGES ARISING FROM OR IN CONNECTION WITH THIS + AGREEMENT EXCEED THE AMOUNT PAID BY YOU FOR THE SOFTWARE. + +7. INDEMNITY. You shall indemnify, defend, and hold harmless + Berkeley Lab, the U.S. Government, the Software developers, the + Software sponsors, and their agents, officers, and employees, + against any and all claims, suits, losses, damage, costs, fees, + and expenses arising out of or in connection with this Agreement. + You shall pay all costs incurred by Berkeley Lab in enforcing this + provision, including reasonable attorney fees. + +8. TERM AND TERMINATION. The license granted to you under this + Agreement will continue perpetually unless terminated by Berkeley + Lab in accordance with this Agreement. If you breach any term of + this Agreement, and fail to cure such breach within thirty (30) + days of the date of written notice, this Agreement shall + immediately terminate. Upon such termination, you shall + immediately cease using the Software, return to Berkeley Lab, or + destroy, all copies of the Software, and provide Berkeley Lab with + written certification of your compliance with the foregoing. + Termination shall not relieve you from your obligations arising + prior to such termination. Notwithstanding any provision of this + Agreement to the contrary, Sections 5 through 10 shall survive + termination of this Agreement. + +9. EXPORT CONTROLS. You shall observe all applicable United States + and foreign laws and regulations (if any) with respect to the + export, re-export, diversion or transfer of the Software, related + technical data and direct products thereof, including, without + limitation, the International Traffic in Arms Regulations (ITAR) + and the Export Administration Regulations. + +10. NO ENDORSEMENT. In accordance with California Education Code + Section 92000, you shall not use in advertising, publicity or + other promotional activities any name, trade name, trademark, or + other designation of the University of California, nor shall you + so use "Ernest Orlando Lawrence Berkeley National Laboratory" or + "United States Department of Energy" (including any contraction, + abbreviation, or simulation of any of the foregoing) without + Berkeley Lab's prior written consent. + +11. GENERAL. This Agreement shall be governed by the laws of the + State of California, excluding its rules governing conflicts of + laws. No provision in either party's purchase orders, or in any + other business forms employed by either party will supersede the + terms of this Agreement, and no modification or amendment of this + Agreement is binding, unless in writing signed by a duly + authorized representative of each party. This Agreement is + binding upon and shall inure to the benefit of Berkeley Lab, its + successors and assigns. This Agreement represents the entire + understanding of the parties, and supersedes all previous + communications, written or oral, relating to the subject of this + Agreement. If you have any questions concerning this license, + contact Lawrence Berkeley National Laboratory, Technology Transfer + Department, One Cyclotron Road, MS 90-1070, Berkeley, CA 94720, + Attn: Software Licensing or via e-mail at ipo@lbl.gov. + +If you have any questions or feedback concerning this Software, +contact the Center for Computational Sciences and Engineering, +Lawrence Berkeley National Laboratory, One Cyclotron Road, MS +50A-3111, Berkeley, CA 94720 or via email at ASAlmgren@lbl.gov + +Form rev000928 diff --git a/README.md b/README.md index b73037ff..97505a64 100644 --- a/README.md +++ b/README.md @@ -1,223 +1,223 @@ -
-title -

- - arxiv - -

- - -[Overview](#Overview) - -[Features](#Features) - -[Examples](#Examples) - -[Install](#Install) - -[Tools](#Tools) - -[Acknowledgements](#Acknowledgements) - -[Contact](#Contact) - -
- - -## Overview - -This IAMReX repo extends the capability of original [IAMR](https://github.com/AMReX-Fluids/IAMR) codes, aiming at simulating the multiphase incompressible flows and fluid structure interaction problems on both CPUs and GPUs with/without subcycling. The Navier-Stokes equations are solved on an adaptive semi-staggered grid using the projection method. The gas-liquid interface is captured using the level set (LS) method. The fluid-solid interface is resolved using the multidirect forcing immersed boundary method (IBM). The particle-wall as well as the particle-particle collisions are also captured by the adaptive collision time model (ACTM). - - - -## Features - -- LS method and reinitialization schemes -- Multidirect forcing Immersed Boundary Method -- Particle Collision Algorithms with Discrete Element Method - - - -## Examples - -- [Reversed Single Vortex (RSV)](./Tutorials/RSV/) - -
- Profiles of drop interface in the RSV problem -
-
Profiles of drop interface in the RSV problem at t/T=1 after one rotation. Black line: Analytical Solution; Red line: 64*64; Blue line: 128*128; Green line: 256*256
-
-
-
- -- [Rayleigh-Taylor (RT) instability](./Tutorials/RayleighTaylor_LS/) - -
- -
- Short Description 1 -
-
(a) Density profile at t/T=2.42 using LS method. (b) Density profile at t/T=2.42 using IAMR convective scheme.
-
-
- -
-
- Short Description 2 -
-
Comparison of the tip locations of the falling fluid and the rising fluid.
-
-
-
-
- - -- [Cluster of monodisperse particles](./Tutorials/Monodisperse/) - -
- Cluster of monodisperse particles -
-
Contours of velocity magnitude in y − z plane
-
-
-
- - - -## Install - -### Download - -Our codes rely on the following packages: - -1. AMReX:`git clone https://github.com/ruohai0925/amrex` -2. AMReX-Hydro:`git clone https://github.com/ruohai0925/AMReX-Hydro` -3. This repo:`git clone https://github.com/ruohai0925/IAMReX/tree/development` - -After cloning, one will have three folder in your current directory:`AMReX`,`AMReX-Hydro`,`IAMReX`. - -### Compile - -We recommend using the GNU compiler to compile the program on the Linux platform. The compilation process requires preparing a `make` file, which you can find in the example folder under Tutorials. It is strongly recommended to use the `GNUmakefile` prepared in advance by the example. If you want to know more about the configuration information of the compilation parameters, you can check it in the [AMReX building](https://amrex-codes.github.io/amrex/docs_html/BuildingAMReX.html). - -For example, if we want to compile in the `FlowPastSphere` , refer to the following steps: - -1. `cd` to the FlowPastSphere directory - - ```shell - cd IAMReX/Tutorials/FlowPastSphere - ``` - -2. Modify compilation parameters in `GNUmakefile`. - - The compilation parameters depend on your computing platform. If you use `MPI` to run your program, then set `USE_MPI = TRUE`. If you are running the program with `Nvidia GPU(CUDA)`, then set `USE_CUDA = TRUE`. When using GPU runtime, please make sure your CUDA environment is ok. - -3. Compile - - With the above settings, you can compile the program: - - ```shell - make - ``` - - You can add parameters after `make`, such as `-f your_make_file` to customize your parameter file, and `-j 8` to specify `8` threads to participate in the compilation. - - If the compilation is successful, an executable file will be generated. Usually the executable file is named in the following format:`amr[DIM].[Compiler manufacturers].[computing platform].[is Debug].ex`. The executable file name of the Release version of the three-dimensional compiled using the GNU compiler in the MPI environment is: `amr3d.GNU.MPI.ex`. - - -### Usage - -You should takes an input file as its first command-line argument. The file may contain a set of parameter definitions that will overrides defaults set in the code. In the `FlowPastSphere`, you can find a file named `inputs.3d.flow_past_sphere`, run: - -```shell -./amr3d.GNU.MPI.ex inputs.3d.flow_past_sphere -``` - -If you use `MPI` to run your program, you can type: - -```shell -mpirun -np how_many_threads amr3d.GNU.MPI.ex inputs.3d.flow_past_sphere -``` - -This code typically generates subfolders in the current folder that are named `plt00000`, `plt00010`, etc, and `chk00000`, `chk00010`, etc. These are called plotfiles and checkpoint files. The plotfiles are used for visualization of derived fields; the checkpoint files are used for restarting the code. - - - -## Tools - -In the `Tools` folder, there are some post-processing script for DIBM. The `postProcess` submodule is used to process the generated particle data file. The specific usage can be seen in the `README`. - -In addition, a Fortran code for generating a particle bed is provided, You can customize the domain size and particle size you want. - -```fortran -! Line 10 - 15 -! domain scheme -LX_DOMAIN=3.0D0*Pi -LY_DOMAIN=6.0D0*Pi -LZ_DOMAIN=3.0D0*Pi -! D -SPD=1.D0 -``` - -Compile the code and run it, and a file named `SPC.DAT` will be generated, in which each line represents the position of a particle. - -```shell -gfortran -o fixBed DomainFill.F90 -./fixBed -``` - -## State of the field -We made great efforts to simulate more complex multiphase flows at higher resolution using IAMReX. One effort is to combine the AMR technique with the multidirect forcing immersed boundary method to resolve particles only on the finest-level grid. It significantly reduces the grid requirements for particle-resolved simulation compared with commonly used uniform grid solvers [Incompact3d](https://github.com/xcompact3d/Incompact3d), [CaNS](https://github.com/CaNS-World/CaNS), and [CP3d](https://github.com/GongZheng-Justin/CP3d). Additionally, we utilized a subcycling technique to alleviate the time step constraint on coarser levels. It minimizes the total time step needed by time advancement compared with the non-subcycling technique used in other AMR-related packages, such as [IBAMR](https://github.com/IBAMR/IBAMR.git), [basilisk](http://basilisk.fr/), and [incflo](https://github.com/AMReX-Fluids/incflo.git). - -## Get Help - -You can also view questions -and ask your own on our [GitHub Discussions](https://github.com/ruohai0925/IAMReX/discussions) page. -To obtain additional help, simply post an issue. - -## Contribute - -We are always happy to have users contribute to the IAMReX source code. To -contribute, issue a pull request against the development branch. -Any level of changes are welcomed: documentation, bug fixes, new test problems, -new solvers, etc. For more details on how to contribute to IAMReX, please see -[CONTRIBUTING.md](CONTRIBUTING.md). - -💡 If you're using IAMReX in your own GitHub projects, consider adding `IAMReX` -as a [repository topic](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/classifying-your-repository-with-topics)! -This helps others discover related work and strengthens the IAMReX ecosystem. - -## Citation - -To cite IAMReX, please use - -``` -@article{10.1063/5.0236509, - author = {Li, Xuzhu (李虚竹) and Li, Chun (李春) and Li, Xiaokai (李晓凯) and Li, Wenzhuo (李文卓) and Tang, Mingze (唐铭泽) and Zeng, Yadong (曾亚东) and Zhu, Zhengping (朱正平)}, - title = {An open-source, adaptive solver for particle-resolved simulations with both subcycling and non-subcycling methods}, - journal = {Physics of Fluids}, - volume = {36}, - number = {11}, - pages = {113335}, - year = {2024}, - month = {11}, - issn = {1070-6631}, - doi = {10.1063/5.0236509}, - url = {https://doi.org/10.1063/5.0236509}, - eprint = {https://pubs.aip.org/aip/pof/article-pdf/doi/10.1063/5.0236509/20247663/113335\_1\_5.0236509.pdf}, -} - -@inbook{doi:10.2514/6.2025-1865, - author = {Dewen Liu and Shuai He and Haoran Cheng and Yadong Zeng}, - title = {Investigate the Efficiency of Incompressible Flow Simulations on CPUs and GPUs With BSAMR}, - booktitle = {AIAA SCITECH 2025 Forum}, - doi = {10.2514/6.2025-1865}, - URL = {https://arc.aiaa.org/doi/abs/10.2514/6.2025-1865}, - eprint = {https://arc.aiaa.org/doi/pdf/10.2514/6.2025-1865}, -} - -``` - -## Acknowledgements - -We are grateful to Ann Almgren, Andy Nonaka, Andrew Myers, Axel Huebl, Marc Day, and Weiqun Zhang in the Lawrence Berkeley National Laboratory (LBNL) for their discussions related to [AMReX](https://github.com/AMReX-Codes/amrex) and [IAMR](https://github.com/AMReX-Fluids/IAMR). Y.Z. and Z.Z. also thank Prof. Lian Shen, Prof. Ruifeng Hu, and Prof. Xiaojing Zheng during their Ph.D. studies. - - - -## Contact - -If you have any question or wanna contribute to the code, please don't hesitate to contact us via the [GitHub Issues](https://github.com/ruohai0925/IAMReX/issues) or zdsjtu@gmail.com. +
+title +

+ + arxiv + +

+ + +[Overview](#Overview) - +[Features](#Features) - +[Examples](#Examples) - +[Install](#Install) - +[Tools](#Tools) - +[Acknowledgements](#Acknowledgements) - +[Contact](#Contact) + +
+ + +## Overview + +This IAMReX repo extends the capability of original [IAMR](https://github.com/AMReX-Fluids/IAMR) codes, aiming at simulating the multiphase incompressible flows and fluid structure interaction problems on both CPUs and GPUs with/without subcycling. The Navier-Stokes equations are solved on an adaptive semi-staggered grid using the projection method. The gas-liquid interface is captured using the level set (LS) method. The fluid-solid interface is resolved using the multidirect forcing immersed boundary method (IBM). The particle-wall as well as the particle-particle collisions are also captured by the adaptive collision time model (ACTM). + + + +## Features + +- LS method and reinitialization schemes +- Multidirect forcing Immersed Boundary Method +- Particle Collision Algorithms with Discrete Element Method + + + +## Examples + +- [Reversed Single Vortex (RSV)](./Tutorials/RSV/) + +
+ Profiles of drop interface in the RSV problem +
+
Profiles of drop interface in the RSV problem at t/T=1 after one rotation. Black line: Analytical Solution; Red line: 64*64; Blue line: 128*128; Green line: 256*256
+
+
+
+ +- [Rayleigh-Taylor (RT) instability](./Tutorials/RayleighTaylor_LS/) + +
+ +
+ Short Description 1 +
+
(a) Density profile at t/T=2.42 using LS method. (b) Density profile at t/T=2.42 using IAMR convective scheme.
+
+
+ +
+
+ Short Description 2 +
+
Comparison of the tip locations of the falling fluid and the rising fluid.
+
+
+
+
+ + +- [Cluster of monodisperse particles](./Tutorials/Monodisperse/) + +
+ Cluster of monodisperse particles +
+
Contours of velocity magnitude in y − z plane
+
+
+
+ + + +## Install + +### Download + +Our codes rely on the following packages: + +1. AMReX:`git clone https://github.com/ruohai0925/amrex` +2. AMReX-Hydro:`git clone https://github.com/ruohai0925/AMReX-Hydro` +3. This repo:`git clone https://github.com/ruohai0925/IAMReX/tree/development` + +After cloning, one will have three folder in your current directory:`AMReX`,`AMReX-Hydro`,`IAMReX`. + +### Compile + +We recommend using the GNU compiler to compile the program on the Linux platform. The compilation process requires preparing a `make` file, which you can find in the example folder under Tutorials. It is strongly recommended to use the `GNUmakefile` prepared in advance by the example. If you want to know more about the configuration information of the compilation parameters, you can check it in the [AMReX building](https://amrex-codes.github.io/amrex/docs_html/BuildingAMReX.html). + +For example, if we want to compile in the `FlowPastSphere` , refer to the following steps: + +1. `cd` to the FlowPastSphere directory + + ```shell + cd IAMReX/Tutorials/FlowPastSphere + ``` + +2. Modify compilation parameters in `GNUmakefile`. + + The compilation parameters depend on your computing platform. If you use `MPI` to run your program, then set `USE_MPI = TRUE`. If you are running the program with `Nvidia GPU(CUDA)`, then set `USE_CUDA = TRUE`. When using GPU runtime, please make sure your CUDA environment is ok. + +3. Compile + + With the above settings, you can compile the program: + + ```shell + make + ``` + + You can add parameters after `make`, such as `-f your_make_file` to customize your parameter file, and `-j 8` to specify `8` threads to participate in the compilation. + + If the compilation is successful, an executable file will be generated. Usually the executable file is named in the following format:`amr[DIM].[Compiler manufacturers].[computing platform].[is Debug].ex`. The executable file name of the Release version of the three-dimensional compiled using the GNU compiler in the MPI environment is: `amr3d.GNU.MPI.ex`. + + +### Usage + +You should takes an input file as its first command-line argument. The file may contain a set of parameter definitions that will overrides defaults set in the code. In the `FlowPastSphere`, you can find a file named `inputs.3d.flow_past_sphere`, run: + +```shell +./amr3d.GNU.MPI.ex inputs.3d.flow_past_sphere +``` + +If you use `MPI` to run your program, you can type: + +```shell +mpirun -np how_many_threads amr3d.GNU.MPI.ex inputs.3d.flow_past_sphere +``` + +This code typically generates subfolders in the current folder that are named `plt00000`, `plt00010`, etc, and `chk00000`, `chk00010`, etc. These are called plotfiles and checkpoint files. The plotfiles are used for visualization of derived fields; the checkpoint files are used for restarting the code. + + + +## Tools + +In the `Tools` folder, there are some post-processing script for DIBM. The `postProcess` submodule is used to process the generated particle data file. The specific usage can be seen in the `README`. + +In addition, a Fortran code for generating a particle bed is provided, You can customize the domain size and particle size you want. + +```fortran +! Line 10 - 15 +! domain scheme +LX_DOMAIN=3.0D0*Pi +LY_DOMAIN=6.0D0*Pi +LZ_DOMAIN=3.0D0*Pi +! D +SPD=1.D0 +``` + +Compile the code and run it, and a file named `SPC.DAT` will be generated, in which each line represents the position of a particle. + +```shell +gfortran -o fixBed DomainFill.F90 +./fixBed +``` + +## State of the field +We made great efforts to simulate more complex multiphase flows at higher resolution using IAMReX. One effort is to combine the AMR technique with the multidirect forcing immersed boundary method to resolve particles only on the finest-level grid. It significantly reduces the grid requirements for particle-resolved simulation compared with commonly used uniform grid solvers [Incompact3d](https://github.com/xcompact3d/Incompact3d), [CaNS](https://github.com/CaNS-World/CaNS), and [CP3d](https://github.com/GongZheng-Justin/CP3d). Additionally, we utilized a subcycling technique to alleviate the time step constraint on coarser levels. It minimizes the total time step needed by time advancement compared with the non-subcycling technique used in other AMR-related packages, such as [IBAMR](https://github.com/IBAMR/IBAMR.git), [basilisk](http://basilisk.fr/), and [incflo](https://github.com/AMReX-Fluids/incflo.git). + +## Get Help + +You can also view questions +and ask your own on our [GitHub Discussions](https://github.com/ruohai0925/IAMReX/discussions) page. +To obtain additional help, simply post an issue. + +## Contribute + +We are always happy to have users contribute to the IAMReX source code. To +contribute, issue a pull request against the development branch. +Any level of changes are welcomed: documentation, bug fixes, new test problems, +new solvers, etc. For more details on how to contribute to IAMReX, please see +[CONTRIBUTING.md](CONTRIBUTING.md). + +💡 If you're using IAMReX in your own GitHub projects, consider adding `IAMReX` +as a [repository topic](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/classifying-your-repository-with-topics)! +This helps others discover related work and strengthens the IAMReX ecosystem. + +## Citation + +To cite IAMReX, please use + +``` +@article{10.1063/5.0236509, + author = {Li, Xuzhu (李虚竹) and Li, Chun (李春) and Li, Xiaokai (李晓凯) and Li, Wenzhuo (李文卓) and Tang, Mingze (唐铭泽) and Zeng, Yadong (曾亚东) and Zhu, Zhengping (朱正平)}, + title = {An open-source, adaptive solver for particle-resolved simulations with both subcycling and non-subcycling methods}, + journal = {Physics of Fluids}, + volume = {36}, + number = {11}, + pages = {113335}, + year = {2024}, + month = {11}, + issn = {1070-6631}, + doi = {10.1063/5.0236509}, + url = {https://doi.org/10.1063/5.0236509}, + eprint = {https://pubs.aip.org/aip/pof/article-pdf/doi/10.1063/5.0236509/20247663/113335\_1\_5.0236509.pdf}, +} + +@inbook{doi:10.2514/6.2025-1865, + author = {Dewen Liu and Shuai He and Haoran Cheng and Yadong Zeng}, + title = {Investigate the Efficiency of Incompressible Flow Simulations on CPUs and GPUs With BSAMR}, + booktitle = {AIAA SCITECH 2025 Forum}, + doi = {10.2514/6.2025-1865}, + URL = {https://arc.aiaa.org/doi/abs/10.2514/6.2025-1865}, + eprint = {https://arc.aiaa.org/doi/pdf/10.2514/6.2025-1865}, +} + +``` + +## Acknowledgements + +We are grateful to Ann Almgren, Andy Nonaka, Andrew Myers, Axel Huebl, Marc Day, and Weiqun Zhang in the Lawrence Berkeley National Laboratory (LBNL) for their discussions related to [AMReX](https://github.com/AMReX-Codes/amrex) and [IAMR](https://github.com/AMReX-Fluids/IAMR). Y.Z. and Z.Z. also thank Prof. Lian Shen, Prof. Ruifeng Hu, and Prof. Xiaojing Zheng during their Ph.D. studies. + + + +## Contact + +If you have any question or wanna contribute to the code, please don't hesitate to contact us via the [GitHub Issues](https://github.com/ruohai0925/IAMReX/issues) or zdsjtu@gmail.com. diff --git a/Source/Collision.H b/Source/Collision.H index 802606af..8bc9ce29 100644 --- a/Source/Collision.H +++ b/Source/Collision.H @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & ZhuXu Li<1246206018@qq.com> + * + * SPDX-License-Identifier: BSD-3-Clause + */ + #ifndef COLLISION_H #define COLLISION_H diff --git a/Source/Collision.cpp b/Source/Collision.cpp index 576be555..c2305287 100644 --- a/Source/Collision.cpp +++ b/Source/Collision.cpp @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & ZhuXu Li<1246206018@qq.com> +// +// SPDX-License-Identifier: BSD-3-Clause + #include "Collision.H" #include diff --git a/Source/DiffusedIB.H b/Source/DiffusedIB.H index 3cc7da8a..445e1568 100644 --- a/Source/DiffusedIB.H +++ b/Source/DiffusedIB.H @@ -1,201 +1,207 @@ -#ifndef DIFFUSEDIB_H -#define DIFFUSEDIB_H - -#include -#include - -#include -#include - -#include "Collision.H" -using namespace amrex; -// using deltaFuncType = std::function; - -AMREX_INLINE AMREX_GPU_DEVICE -Real nodal_phi_to_heavi(Real phi) -{ - if (phi <= 0.0) { - return 0.0; - } - else { - return 1.0; - } -} - -void nodal_phi_to_pvf(MultiFab& pvf, const MultiFab& phi_nodal); - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* particle and markers */ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -enum P_ATTR{ - U_Marker = 0, - V_Marker, - W_Marker, - Fx_Marker, - Fy_Marker, - Fz_Marker, - Mx_Marker, - My_Marker, - Mz_Marker, - numAttri -}; - -enum DELTA_FUNCTION_TYPE{ - FOUR_POINT_IB = 0, - THREE_POINT_IB -}; - -struct kernel{ - int id; - RealVect velocity{0.0,0.0,0.0}; - RealVect location{0.0,0.0,0.0}; - RealVect omega{0.0,0.0,0.0}; - - RealVect velocity_old{0.0,0.0,0.0}; - RealVect location_old{0.0,0.0,0.0}; - RealVect omega_old{0.0,0.0,0.0}; - - RealVect varphi{0.0,0.0,0.0}; - Real radius{0.0}; - Real rho{0.0}; - int ml{0}; - Real dv{0.0}; - Real Vp{0.0}; - RealVect ib_force{0.0,0.0,0.0}; - RealVect ib_moment{0.0, 0.0, 0.0}; - - RealVect sum_u_new{0.0,0.0,0.0}; - RealVect sum_u_old{0.0,0.0,0.0}; - RealVect sum_t_new{0.0,0.0,0.0}; - RealVect sum_t_old{0.0,0.0,0.0}; - - RealVect Fcp{0.0,0.0,0.0}; - RealVect Tcp{0.0,0.0,0.0}; - - amrex::Gpu::DeviceVector phiK; - amrex::Gpu::DeviceVector thetaK; - - IntVect TL{0, 0, 0}, RL{0, 0, 0}; -}; - -class mParIter : public ParIter<0, 0, numAttri>{ -public: - using amrex::ParIter<0, 0, numAttri>::ParIter; - using RealVector = amrex::ParIter<0, 0, numAttri>::ContainerType::RealVector; - - [[nodiscard]] const std::array& GetAttribs () const { - return GetStructOfArrays().GetRealData(); - } - - [[nodiscard]] const RealVector& GetAttribs (int comp) const { - return GetStructOfArrays().GetRealData(comp); - } - - std::array& GetAttribs () { - return GetStructOfArrays().GetRealData(); - } - - RealVector& GetAttribs (int comp) { - return GetStructOfArrays().GetRealData(comp); - } -}; - -void deltaFunction(Real xf, Real xp, Real h, Real& value); - -using mParticleContainer = ParticleContainer<0, 0, numAttri>; - -class mParticle -{ -public: - explicit mParticle() = default; - - void InitParticles(const Vector& x, - const Vector& y, - const Vector& z, - const Vector& rho_s, - const Vector& Vx, - const Vector& Vy, - const Vector& Vz, - const Vector& Ox, - const Vector& Oy, - const Vector& Oz, - const Vector& TLX, - const Vector& TLY, - const Vector& TLZ, - const Vector& RLX, - const Vector& RLY, - const Vector& RLZ, - const Vector& radius, - Real h, - Real gravity, - int verbose = 0); - - void InteractWithEuler(MultiFab &EulerVel, MultiFab &EulerForce, Real dt = 0.1, DELTA_FUNCTION_TYPE type = FOUR_POINT_IB); - - void WriteParticleFile(int index); - - void InitialWithLargrangianPoints(const kernel& current_kernel); - - void ResetLargrangianPoints(); - - void VelocityInterpolation(amrex::MultiFab &Euler, DELTA_FUNCTION_TYPE type); - - void ComputeLagrangianForce(Real dt, const kernel& kernel); - - void ForceSpreading(amrex::MultiFab &Euler, kernel& kernel, DELTA_FUNCTION_TYPE type); - - void VelocityCorrection(amrex::MultiFab &Euler, amrex::MultiFab &EulerForce, Real dt) const; - - void UpdateParticles(int iStep, Real time, const MultiFab& Euler_old, const MultiFab& Euler, MultiFab& phi_nodal, MultiFab& pvf, Real dt); - - void DoParticleCollision(int model); - - static void WriteIBForceAndMoment(int step, amrex::Real time, amrex::Real dt, kernel& current_kernel); - - void RecordOldValue(kernel& kernel); - - Vector particle_kernels; - - mParticleContainer *mContainer{nullptr}; - - ParticleCollision m_Collision; - - int max_largrangian_num = 0; - - uint32_t ib_force_file_index = 0; - - RealVect m_gravity{0.0,0.0,0.0}; - - int verbose = 0; - - Real spend_time; -}; - -class Particles{ -public: - static void create_particles(const Geometry &gm, - const DistributionMapping & dm, - const BoxArray & ba); - - static mParticle* get_particles(); - static void init_particle(Real gravity, Real h); - static void Restart(Real gravity, Real h, int iStep); - static void Initialize(); - static int ParticleFinestLevel(); - static void define_para(const Vector& x, - const Vector& y, - const Vector& z, - Real rho_s, - Real radius, - Real rho_f, - int force_index, - int velocity_index, - int finest_level); - - inline static bool isInitial{false}; -private: - inline static mParticle* particle = nullptr; -}; - -#endif +/* + * SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & ZhuXu Li<1246206018@qq.com> + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef DIFFUSEDIB_H +#define DIFFUSEDIB_H + +#include +#include + +#include +#include + +#include "Collision.H" +using namespace amrex; +// using deltaFuncType = std::function; + +AMREX_INLINE AMREX_GPU_DEVICE +Real nodal_phi_to_heavi(Real phi) +{ + if (phi <= 0.0) { + return 0.0; + } + else { + return 1.0; + } +} + +void nodal_phi_to_pvf(MultiFab& pvf, const MultiFab& phi_nodal); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* particle and markers */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +enum P_ATTR{ + U_Marker = 0, + V_Marker, + W_Marker, + Fx_Marker, + Fy_Marker, + Fz_Marker, + Mx_Marker, + My_Marker, + Mz_Marker, + numAttri +}; + +enum DELTA_FUNCTION_TYPE{ + FOUR_POINT_IB = 0, + THREE_POINT_IB +}; + +struct kernel{ + int id; + RealVect velocity{0.0,0.0,0.0}; + RealVect location{0.0,0.0,0.0}; + RealVect omega{0.0,0.0,0.0}; + + RealVect velocity_old{0.0,0.0,0.0}; + RealVect location_old{0.0,0.0,0.0}; + RealVect omega_old{0.0,0.0,0.0}; + + RealVect varphi{0.0,0.0,0.0}; + Real radius{0.0}; + Real rho{0.0}; + int ml{0}; + Real dv{0.0}; + Real Vp{0.0}; + RealVect ib_force{0.0,0.0,0.0}; + RealVect ib_moment{0.0, 0.0, 0.0}; + + RealVect sum_u_new{0.0,0.0,0.0}; + RealVect sum_u_old{0.0,0.0,0.0}; + RealVect sum_t_new{0.0,0.0,0.0}; + RealVect sum_t_old{0.0,0.0,0.0}; + + RealVect Fcp{0.0,0.0,0.0}; + RealVect Tcp{0.0,0.0,0.0}; + + amrex::Gpu::DeviceVector phiK; + amrex::Gpu::DeviceVector thetaK; + + IntVect TL{0, 0, 0}, RL{0, 0, 0}; +}; + +class mParIter : public ParIter<0, 0, numAttri>{ +public: + using amrex::ParIter<0, 0, numAttri>::ParIter; + using RealVector = amrex::ParIter<0, 0, numAttri>::ContainerType::RealVector; + + [[nodiscard]] const std::array& GetAttribs () const { + return GetStructOfArrays().GetRealData(); + } + + [[nodiscard]] const RealVector& GetAttribs (int comp) const { + return GetStructOfArrays().GetRealData(comp); + } + + std::array& GetAttribs () { + return GetStructOfArrays().GetRealData(); + } + + RealVector& GetAttribs (int comp) { + return GetStructOfArrays().GetRealData(comp); + } +}; + +void deltaFunction(Real xf, Real xp, Real h, Real& value); + +using mParticleContainer = ParticleContainer<0, 0, numAttri>; + +class mParticle +{ +public: + explicit mParticle() = default; + + void InitParticles(const Vector& x, + const Vector& y, + const Vector& z, + const Vector& rho_s, + const Vector& Vx, + const Vector& Vy, + const Vector& Vz, + const Vector& Ox, + const Vector& Oy, + const Vector& Oz, + const Vector& TLX, + const Vector& TLY, + const Vector& TLZ, + const Vector& RLX, + const Vector& RLY, + const Vector& RLZ, + const Vector& radius, + Real h, + Real gravity, + int verbose = 0); + + void InteractWithEuler(MultiFab &EulerVel, MultiFab &EulerForce, Real dt = 0.1, DELTA_FUNCTION_TYPE type = FOUR_POINT_IB); + + void WriteParticleFile(int index); + + void InitialWithLargrangianPoints(const kernel& current_kernel); + + void ResetLargrangianPoints(); + + void VelocityInterpolation(amrex::MultiFab &Euler, DELTA_FUNCTION_TYPE type); + + void ComputeLagrangianForce(Real dt, const kernel& kernel); + + void ForceSpreading(amrex::MultiFab &Euler, kernel& kernel, DELTA_FUNCTION_TYPE type); + + void VelocityCorrection(amrex::MultiFab &Euler, amrex::MultiFab &EulerForce, Real dt) const; + + void UpdateParticles(int iStep, Real time, const MultiFab& Euler_old, const MultiFab& Euler, MultiFab& phi_nodal, MultiFab& pvf, Real dt); + + void DoParticleCollision(int model); + + static void WriteIBForceAndMoment(int step, amrex::Real time, amrex::Real dt, kernel& current_kernel); + + void RecordOldValue(kernel& kernel); + + Vector particle_kernels; + + mParticleContainer *mContainer{nullptr}; + + ParticleCollision m_Collision; + + int max_largrangian_num = 0; + + uint32_t ib_force_file_index = 0; + + RealVect m_gravity{0.0,0.0,0.0}; + + int verbose = 0; + + Real spend_time; +}; + +class Particles{ +public: + static void create_particles(const Geometry &gm, + const DistributionMapping & dm, + const BoxArray & ba); + + static mParticle* get_particles(); + static void init_particle(Real gravity, Real h); + static void Restart(Real gravity, Real h, int iStep); + static void Initialize(); + static int ParticleFinestLevel(); + static void define_para(const Vector& x, + const Vector& y, + const Vector& z, + Real rho_s, + Real radius, + Real rho_f, + int force_index, + int velocity_index, + int finest_level); + + inline static bool isInitial{false}; +private: + inline static mParticle* particle = nullptr; +}; + +#endif diff --git a/Source/DiffusedIB.cpp b/Source/DiffusedIB.cpp index 704a1bea..2dc473f9 100644 --- a/Source/DiffusedIB.cpp +++ b/Source/DiffusedIB.cpp @@ -1,1222 +1,1225 @@ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -namespace fs = std::filesystem; - -#define GHOST_CELLS 2 - -using namespace amrex; - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* global variable */ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#define LOCAL_LEVEL 0 - -const Vector direction_str{"X","Y","Z"}; - -namespace ParticleProperties{ - Vector _x{}, _y{}, _z{}, _rho{}; - Vector Vx{}, Vy{}, Vz{}; - Vector Ox{}, Oy{}, Oz{}; - Vector _radius; - Real rd{0.0}; - Vector TLX{}, TLY{},TLZ{},RLX{},RLY{},RLZ{}; - int euler_finest_level{0}; - int euler_velocity_index{0}; - int euler_force_index{0}; - Real euler_fluid_rho{0.0}; - int verbose{0}; - int loop_ns{2}; - int loop_solid{1}; - int Uhlmann{0}; - - Vector GLO, GHI; - int start_step{-1}; - int collision_model{0}; - - int write_freq{1}; - bool init_particle_from_file{false}; - - GpuArray plo{0.0,0.0,0.0}, phi{0.0,0.0,0.0}, dx{0.0, 0.0, 0.0}; -} - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* other function */ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -void nodal_phi_to_pvf(MultiFab& pvf, const MultiFab& phi_nodal) -{ - - // amrex::Print() << "In the nodal_phi_to_pvf\n"; - - pvf.setVal(0.0); - - // Only set the valid cells of pvf -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(pvf,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - auto const& pvffab = pvf.array(mfi); - auto const& pnfab = phi_nodal.array(mfi); - amrex::ParallelFor(bx, [pvffab, pnfab] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - Real num = 0.0; - for(int kk=k; kk<=k+1; kk++) { - for(int jj=j; jj<=j+1; jj++) { - for(int ii=i; ii<=i+1; ii++) { - num += (-pnfab(ii,jj,kk)) * nodal_phi_to_heavi(-pnfab(ii,jj,kk)); - } - } - } - Real deo = 0.0; - for(int kk=k; kk<=k+1; kk++) { - for(int jj=j; jj<=j+1; jj++) { - for(int ii=i; ii<=i+1; ii++) { - deo += std::abs(pnfab(ii,jj,kk)); - } - } - } - pvffab(i,j,k) = num / (deo + 1.e-12); - }); - } - -} - -void calculate_phi_nodal(MultiFab& phi_nodal, kernel& current_kernel) -{ - phi_nodal.setVal(0.0); - - amrex::Real Xp = current_kernel.location[0]; - amrex::Real Yp = current_kernel.location[1]; - amrex::Real Zp = current_kernel.location[2]; - amrex::Real Rp = current_kernel.radius; - - // Only set the valid cells of phi_nodal - for (MFIter mfi(phi_nodal,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - auto const& pnfab = phi_nodal.array(mfi); - auto dx = ParticleProperties::dx; - auto plo = ParticleProperties::plo; - amrex::ParallelFor(bx, [=] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - Real Xn = i * dx[0] + plo[0]; - Real Yn = j * dx[1] + plo[1]; - Real Zn = k * dx[2] + plo[2]; - - pnfab(i,j,k) = std::sqrt( (Xn - Xp)*(Xn - Xp) - + (Yn - Yp)*(Yn - Yp) + (Zn - Zp)*(Zn - Zp)) - Rp; - pnfab(i,j,k) = pnfab(i,j,k) / Rp; - - } - ); - } -} - -// May use ParReduce later, https://amrex-codes.github.io/amrex/docs_html/GPU.html#multifab-reductions -void CalculateSumU_cir (RealVect& sum, - const MultiFab& E, - const MultiFab& pvf, - int EulerVelIndex) -{ - auto const& E_data = E.const_arrays(); - auto const& pvf_data = pvf.const_arrays(); - const Real d = Math::powi<3>(ParticleProperties::dx[0]); - amrex::GpuTuple tmpSum = ParReduce(TypeList{}, TypeList{},E, IntVect{0}, - [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> amrex::GpuTuple{ - auto E_ = E_data[box_no]; - auto pvf_ = pvf_data[box_no]; - return { - E_(i, j, k, EulerVelIndex ) * d * pvf_(i,j,k), - E_(i, j, k, EulerVelIndex + 1) * d * pvf_(i,j,k), - E_(i, j, k, EulerVelIndex + 2) * d * pvf_(i,j,k) - }; - }); - sum[0] = amrex::get<0>(tmpSum); - sum[1] = amrex::get<1>(tmpSum); - sum[2] = amrex::get<2>(tmpSum); -} - -void CalculateSumT_cir (RealVect& sum, - const MultiFab& E, - const MultiFab& pvf, - const RealVect pLoc, - int EulerVelIndex) -{ - auto plo = ParticleProperties::plo; - auto dx = ParticleProperties::dx; - - auto const& E_data = E.const_arrays(); - auto const& pvf_data = pvf.const_arrays(); - const Real d = Math::powi<3>(ParticleProperties::dx[0]); - amrex::GpuTuple tmpSum = ParReduce(TypeList{}, TypeList{},E, IntVect{0}, - [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> amrex::GpuTuple{ - auto E_ = E_data[box_no]; - auto pvf_ = pvf_data[box_no]; - - Real x = plo[0] + i*dx[0] + 0.5*dx[0]; - Real y = plo[1] + j*dx[1] + 0.5*dx[1]; - Real z = plo[2] + k*dx[2] + 0.5*dx[2]; - - Real vx = E_(i, j, k, EulerVelIndex ); - Real vy = E_(i, j, k, EulerVelIndex + 1); - Real vz = E_(i, j, k, EulerVelIndex + 2); - - RealVect tmp = RealVect(x - pLoc[0], y - pLoc[1], z - pLoc[2]).crossProduct(RealVect(vx, vy, vz)); - - return { - tmp[0] * d * pvf_(i, j, k), - tmp[1] * d * pvf_(i, j, k), - tmp[2] * d * pvf_(i, j, k) - }; - }); - sum[0] = amrex::get<0>(tmpSum); - sum[1] = amrex::get<1>(tmpSum); - sum[2] = amrex::get<2>(tmpSum); -} - -[[nodiscard]] AMREX_FORCE_INLINE -Real cal_momentum(Real rho, Real radius) -{ - return 8.0 * Math::pi() * rho * Math::powi<5>(radius) / 15.0; -} - -AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE -void deltaFunction(Real xf, Real xp, Real h, Real& value, DELTA_FUNCTION_TYPE type) -{ - Real rr = amrex::Math::abs(( xf - xp ) / h); - - switch (type) { - case DELTA_FUNCTION_TYPE::FOUR_POINT_IB: - if(rr >= 0 && rr < 1 ){ - value = 1.0 / 8.0 * ( 3.0 - 2.0 * rr + std::sqrt( 1.0 + 4.0 * rr - 4 * Math::powi<2>(rr))) / h; - }else if (rr >= 1 && rr < 2) { - value = 1.0 / 8.0 * ( 5.0 - 2.0 * rr - std::sqrt( -7.0 + 12.0 * rr - 4 * Math::powi<2>(rr))) / h; - }else { - value = 0; - } - break; - case DELTA_FUNCTION_TYPE::THREE_POINT_IB: - if(rr >= 0.5 && rr < 1.5){ - value = 1.0 / 6.0 * ( 5.0 - 3.0 * rr - std::sqrt( - 3.0 * Math::powi<2>( 1 - rr) + 1.0 )) / h; - }else if (rr >= 0 && rr < 0.5) { - value = 1.0 / 3.0 * ( 1.0 + std::sqrt( 1.0 - 3 * Math::powi<2>(rr))) / h; - }else { - value = 0; - } - break; - default: - break; - } -} - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* mParticle member function */ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -//loop all particels -void mParticle::InteractWithEuler(MultiFab &EulerVel, - MultiFab &EulerForce, - Real dt, - DELTA_FUNCTION_TYPE type) -{ - if (verbose) amrex::Print() << "[Particle] mParticle::InteractWithEuler\n"; - // clear time , start record - spend_time = 0; - auto InteractWithEulerStart = ParallelDescriptor::second(); - - MultiFab EulerForceTmp(EulerForce.boxArray(), EulerForce.DistributionMap(), 3, EulerForce.nGrow()); - //clean preStep's IB_porperties - for(auto& kernel : particle_kernels) { - kernel.ib_force.scale(0.0); - kernel.ib_moment.scale(0.0); - } - - //for 1 -> Ns - int loop = ParticleProperties::loop_ns; - BL_ASSERT(loop > 0); - while(loop > 0){ - if(verbose) amrex::Print() << "[Particle] Ns loop index : " << loop << "\n"; - - EulerForce.setVal(0.0); - - for(kernel& kernel : particle_kernels){ - InitialWithLargrangianPoints(kernel); // Initialize markers for a specific particle - ResetLargrangianPoints(); - EulerForceTmp.setVal(0.0); - auto ib_force = kernel.ib_force; - auto ib_moment = kernel.ib_moment; - kernel.ib_force.scale(0.0); // clear kernel ib_force - kernel.ib_moment.scale(0.0); // clear kernel ib_moment - - VelocityInterpolation(EulerVel, type); - ComputeLagrangianForce(dt, kernel); - ForceSpreading(EulerForceTmp, kernel, type); - MultiFab::Add(EulerForce, EulerForceTmp, 0, 0, 3, EulerForce.nGrow()); - - kernel.ib_force += ib_force; - kernel.ib_moment += ib_moment; - } - VelocityCorrection(EulerVel, EulerForce, dt); - loop--; - } - spend_time += ParallelDescriptor::second() - InteractWithEulerStart; -} - -void mParticle::InitParticles(const Vector& x, - const Vector& y, - const Vector& z, - const Vector& rho_s, - const Vector& Vx, - const Vector& Vy, - const Vector& Vz, - const Vector& Ox, - const Vector& Oy, - const Vector& Oz, - const Vector& TLXt, - const Vector& TLYt, - const Vector& TLZt, - const Vector& RLXt, - const Vector& RLYt, - const Vector& RLZt, - const Vector& radius, - Real h, - Real gravity, - int _verbose) -{ - verbose = _verbose; - if (verbose) amrex::Print() << "[Particle] mParticle::InitParticles\n"; - - m_gravity[2] = gravity; - - //pre judge - if(!((x.size() == y.size()) && (x.size() == z.size()))){ - Print() << "particle's position container are all different size"; - return; - } - - //all the particles have different radius - for(int index = 0; index < x.size(); index++){ - int real_index; - // if initial with input file, initialized by [0] data - if(ParticleProperties::init_particle_from_file){ - real_index = 0; - }else{ - real_index = index; - } - - kernel mKernel; - mKernel.id = index + 1; - mKernel.location[0] = x[index]; - mKernel.location[1] = y[index]; - mKernel.location[2] = z[index]; - mKernel.velocity[0] = Vx[real_index]; - mKernel.velocity[1] = Vy[real_index]; - mKernel.velocity[2] = Vz[real_index]; - mKernel.omega[0] = Ox[real_index]; - mKernel.omega[1] = Oy[real_index]; - mKernel.omega[2] = Oz[real_index]; - - // use current state to initialize old state - mKernel.location_old = mKernel.location; - mKernel.velocity_old = mKernel.velocity; - mKernel.omega_old = mKernel.omega; - - mKernel.TL[0] = TLXt[real_index]; - mKernel.TL[1] = TLYt[real_index]; - mKernel.TL[2] = TLZt[real_index]; - mKernel.RL[0] = RLXt[real_index]; - mKernel.RL[1] = RLYt[real_index]; - mKernel.RL[2] = RLZt[real_index]; - mKernel.rho = rho_s[real_index]; - mKernel.radius = radius[real_index]; - mKernel.Vp = Math::pi() * 4 / 3 * Math::powi<3>(radius[real_index]); - - //int Ml = static_cast( Math::pi() / 3 * (12 * Math::powi<2>(mKernel.radius / h))); - //Real dv = Math::pi() * h / 3 / Ml * (12 * mKernel.radius * mKernel.radius + h * h); - int Ml = static_cast((amrex::Math::powi<3>(mKernel.radius - (ParticleProperties::rd - 0.5) * h) - - amrex::Math::powi<3>(mKernel.radius - (ParticleProperties::rd + 0.5) * h))/(3.*h*h*h/4./Math::pi())); - Real dv = (amrex::Math::powi<3>(mKernel.radius - (ParticleProperties::rd - 0.5) * h) - - amrex::Math::powi<3>(mKernel.radius - (ParticleProperties::rd + 0.5) * h))/(3.*Ml/4./Math::pi()); - mKernel.ml = Ml; - mKernel.dv = dv; - if( Ml > max_largrangian_num ) max_largrangian_num = Ml; - - Real phiK = 0; - for(int marker_index = 0; marker_index < Ml; marker_index++){ - Real Hk = -1.0 + 2.0 * (marker_index) / ( Ml - 1.0); - Real thetaK = std::acos(Hk); - if(marker_index == 0 || marker_index == (Ml - 1)){ - phiK = 0; - }else { - phiK = std::fmod( phiK + 3.809 / std::sqrt(Ml) / std::sqrt( 1 - Math::powi<2>(Hk)) , 2 * Math::pi()); - } - mKernel.phiK.push_back(phiK); - mKernel.thetaK.push_back(thetaK); - } - - particle_kernels.emplace_back(mKernel); - - if (verbose) amrex::Print() << "h: " << h << ", Ml: " << Ml << ", D: " << Math::powi<3>(h) << " gravity : " << gravity << "\n" - << "Kernel : " << index << ": Location (" << x[index] << ", " << y[index] << ", " << z[index] - << "), Velocity : (" << mKernel.velocity[0] << ", " << mKernel.velocity[1] << ", "<< mKernel.velocity[2] - << "), Radius: " << mKernel.radius << ", Ml: " << Ml << ", dv: " << dv << ", Rho: " << mKernel.rho << "\n"; - } - //collision box generate - m_Collision.SetGeometry(RealVect(ParticleProperties::GLO), RealVect(ParticleProperties::GHI),particle_kernels[0].radius, h); -} - -void mParticle::InitialWithLargrangianPoints(const kernel& current_kernel){ - - if (verbose) amrex::Print() << "mParticle::InitialWithLargrangianPoints\n"; - for(mParIter pti(*mContainer, LOCAL_LEVEL); pti.isValid(); ++pti){ - const Long np = pti.numParticles(); - if(np == 0) continue; - auto *particles = pti.GetArrayOfStructs().data(); - - const auto location = current_kernel.location; - const auto radius = current_kernel.radius; - const auto* phiK = current_kernel.phiK.dataPtr(); - const auto* thetaK = current_kernel.thetaK.dataPtr(); - - amrex::ParallelFor( np, [=] - AMREX_GPU_DEVICE (int i) noexcept { - auto id = particles[i].id(); - particles[i].pos(0) = location[0] + radius * std::sin(thetaK[id - 1]) * std::cos(phiK[id - 1]); - particles[i].pos(1) = location[1] + radius * std::sin(thetaK[id - 1]) * std::sin(phiK[id - 1]); - particles[i].pos(2) = location[2] + radius * std::cos(thetaK[id - 1]); - } - ); - } - // Redistribute the markers after updating their locations - mContainer->Redistribute(); - if (verbose) { - amrex::Print() << "[particle] : particle num :" << mContainer->TotalNumberOfParticles() << "\n"; - mContainer->WriteAsciiFile(amrex::Concatenate("particle", 1)); - } -} - -template > -AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE -void VelocityInterpolation_cir(int p_iter, P const& p, Real& Up, Real& Vp, Real& Wp, - Array4 const& E, int EulerVIndex, - const int *lo, const int *hi, - GpuArray const& plo, - GpuArray const& dx, - DELTA_FUNCTION_TYPE type) -{ - - //std::cout << "lo " << lo[0] << " " << lo[1] << " "<< lo[2] << "\n"; - //std::cout << "hi " << hi[0] << " " << hi[1] << " "<< hi[2] << "\n"; - - const Real d = AMREX_D_TERM(dx[0], *dx[1], *dx[2]); - - const Real lx = (p.pos(0) - plo[0]) / dx[0]; // x - const Real ly = (p.pos(1) - plo[1]) / dx[1]; // y - const Real lz = (p.pos(2) - plo[2]) / dx[2]; // z - - int i = static_cast(Math::floor(lx)); // i - int j = static_cast(Math::floor(ly)); // j - int k = static_cast(Math::floor(lz)); // k - - //std::cout << "p_iter " << p_iter << " p.pos(0): " << p.pos(0) << " p.pos(1): " << p.pos(1) << " p.pos(2): " << p.pos(2) << "\n"; - - // std::cout << "d: " << d << "\n" - // << "lx: " << lx << ", ly: " << ly << ", lz: " << lz << "\n" - // << "i: " << i << ", j: " << j << ", k: " << k << std::endl; - - Up = 0; - Vp = 0; - Wp = 0; - //Euler to largrangian - for(int ii = -2; ii < 3; ii++){ - for(int jj = -2; jj < 3; jj++){ - for(int kk = -2; kk < 3; kk ++){ - Real tU, tV, tW; - const Real xi = plo[0] + (i + ii) * dx[0] + dx[0]/2; - const Real yj = plo[1] + (j + jj) * dx[1] + dx[1]/2; - const Real kz = plo[2] + (k + kk) * dx[2] + dx[2]/2; - deltaFunction( p.pos(0), xi, dx[0], tU, type); - deltaFunction( p.pos(1), yj, dx[1], tV, type); - deltaFunction( p.pos(2), kz, dx[2], tW, type); - const Real delta_value = tU * tV * tW; - Up += delta_value * E(i + ii, j + jj, k + kk, EulerVIndex ) * d; - Vp += delta_value * E(i + ii, j + jj, k + kk, EulerVIndex + 1) * d; - Wp += delta_value * E(i + ii, j + jj, k + kk, EulerVIndex + 2) * d; - } - } - } -} - -void mParticle::VelocityInterpolation(MultiFab &EulerVel, - DELTA_FUNCTION_TYPE type)// -{ - if (verbose) amrex::Print() << "\tmParticle::VelocityInterpolation\n"; - - //amrex::Print() << "euler_finest_level " << euler_finest_level << std::endl; - const auto& gm = mContainer->GetParGDB()->Geom(LOCAL_LEVEL); - auto plo = gm.ProbLoArray(); - auto dx = gm.CellSizeArray(); - // attention - // velocity ghost cells will be up-to-date - EulerVel.FillBoundary(ParticleProperties::euler_velocity_index, 3, gm.periodicity()); - - const int EulerVelocityIndex = ParticleProperties::euler_velocity_index; - - for(mParIter pti(*mContainer, LOCAL_LEVEL); pti.isValid(); ++pti){ - - const Box& box = pti.validbox(); - - auto& particles = pti.GetArrayOfStructs(); - auto *p_ptr = particles.data(); - const Long np = pti.numParticles(); - - auto& attri = pti.GetAttribs(); - auto* Up = attri[P_ATTR::U_Marker].data(); - auto* Vp = attri[P_ATTR::V_Marker].data(); - auto* Wp = attri[P_ATTR::W_Marker].data(); - const auto& E = EulerVel.array(pti); - - amrex::ParallelFor(np, [=] - AMREX_GPU_DEVICE (int i) noexcept{ - VelocityInterpolation_cir(i, p_ptr[i], Up[i], Vp[i], Wp[i], E, EulerVelocityIndex, box.loVect(), box.hiVect(), plo, dx, type); - }); - } - if (verbose) mContainer->WriteAsciiFile(amrex::Concatenate("particle", 2)); - //amrex::Abort("stop here!"); -} - -template -AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE -void ForceSpreading_cic (P const& p, - Real Px, - Real Py, - Real Pz, - ParticleReal& fxP, - ParticleReal& fyP, - ParticleReal& fzP, - ParticleReal& mxP, - ParticleReal& myP, - ParticleReal& mzP, - Array4 const& E, - int EulerForceIndex, - Real dv, - GpuArray const& plo, - GpuArray const& dx, - DELTA_FUNCTION_TYPE type) -{ - //const Real d = AMREX_D_TERM(dx[0], *dx[1], *dx[2]); - //plo to ii jj kk - Real lx = (p.pos(0) - plo[0]) / dx[0]; - Real ly = (p.pos(1) - plo[1]) / dx[1]; - Real lz = (p.pos(2) - plo[2]) / dx[2]; - - int i = static_cast(Math::floor(lx)); - int j = static_cast(Math::floor(ly)); - int k = static_cast(Math::floor(lz)); - fxP *= dv; - fyP *= dv; - fzP *= dv; - RealVect moment = RealVect((p.pos(0) - Px), (p.pos(1) - Py), (p.pos(2) - Pz)).crossProduct(RealVect(fxP, fyP, fzP)); - mxP = moment[0]; - myP = moment[1]; - mzP = moment[2]; - //lagrangian to Euler - for(int ii = -2; ii < +3; ii++){ - for(int jj = -2; jj < +3; jj++){ - for(int kk = -2; kk < +3; kk ++){ - Real tU, tV, tW; - const Real xi =plo[0] + (i + ii) * dx[0] + dx[0]/2; - const Real yj =plo[1] + (j + jj) * dx[1] + dx[1]/2; - const Real kz =plo[2] + (k + kk) * dx[2] + dx[2]/2; - deltaFunction( p.pos(0), xi, dx[0], tU, type); - deltaFunction( p.pos(1), yj, dx[1], tV, type); - deltaFunction( p.pos(2), kz, dx[2], tW, type); - Real delta_value = tU * tV * tW; - Gpu::Atomic::AddNoRet(&E(i + ii, j + jj, k + kk, EulerForceIndex ), delta_value * fxP); - Gpu::Atomic::AddNoRet(&E(i + ii, j + jj, k + kk, EulerForceIndex+1), delta_value * fyP); - Gpu::Atomic::AddNoRet(&E(i + ii, j + jj, k + kk, EulerForceIndex+2), delta_value * fzP); - } - } - } -} - -void mParticle::ForceSpreading(MultiFab & EulerForce, - kernel& kernel, - DELTA_FUNCTION_TYPE type) -{ - if (verbose) amrex::Print() << "\tmParticle::ForceSpreading\n"; - const auto& gm = mContainer->GetParGDB()->Geom(LOCAL_LEVEL); - auto plo = gm.ProbLoArray(); - auto dxi = gm.CellSizeArray(); - for(mParIter pti(*mContainer, LOCAL_LEVEL); pti.isValid(); ++pti){ - const Long np = pti.numParticles(); - const auto& particles = pti.GetArrayOfStructs(); - auto Uarray = EulerForce[pti].array(); - auto& attri = pti.GetAttribs(); - - auto *const fxP_ptr = attri[P_ATTR::Fx_Marker].data(); - auto *const fyP_ptr = attri[P_ATTR::Fy_Marker].data(); - auto *const fzP_ptr = attri[P_ATTR::Fz_Marker].data(); - auto *const mxP_ptr = attri[P_ATTR::Mx_Marker].data(); - auto *const myP_ptr = attri[P_ATTR::My_Marker].data(); - auto *const mzP_ptr = attri[P_ATTR::Mz_Marker].data(); - const auto *const p_ptr = particles().data(); - - auto loc_ptr = kernel.location; - auto dv = kernel.dv; - auto force_index = ParticleProperties::euler_force_index; - amrex::ParallelFor(np, [=] - AMREX_GPU_DEVICE (int i) noexcept{ - ForceSpreading_cic(p_ptr[i], loc_ptr[0], loc_ptr[1], loc_ptr[2], - fxP_ptr[i], fyP_ptr[i], fzP_ptr[i], - mxP_ptr[i], myP_ptr[i], mzP_ptr[i], - Uarray, force_index, dv, plo, dxi, type); - }); - } - //barrier for sync; - amrex::ParallelDescriptor::Barrier(); - - using pc = mParticleContainer::SuperParticleType; - // Each Processor - auto fx = amrex::ReduceSum( *mContainer, [=]AMREX_GPU_HOST_DEVICE(const pc& p)->ParticleReal{return p.rdata(P_ATTR::Fx_Marker);}); - auto fy = amrex::ReduceSum( *mContainer, [=]AMREX_GPU_HOST_DEVICE(const pc& p)->ParticleReal{return p.rdata(P_ATTR::Fy_Marker);}); - auto fz = amrex::ReduceSum( *mContainer, [=]AMREX_GPU_HOST_DEVICE(const pc& p)->ParticleReal{return p.rdata(P_ATTR::Fz_Marker);}); - auto mx = amrex::ReduceSum( *mContainer, [=]AMREX_GPU_HOST_DEVICE(const pc& p)->ParticleReal{return p.rdata(P_ATTR::Mx_Marker);}); - auto my = amrex::ReduceSum( *mContainer, [=]AMREX_GPU_HOST_DEVICE(const pc& p)->ParticleReal{return p.rdata(P_ATTR::My_Marker);}); - auto mz = amrex::ReduceSum( *mContainer, [=]AMREX_GPU_HOST_DEVICE(const pc& p)->ParticleReal{return p.rdata(P_ATTR::Mz_Marker);}); - // MPI sum reduce -> current particle all IB force and moment - amrex::ParallelAllReduce::Sum(fx, ParallelDescriptor::Communicator()); - amrex::ParallelAllReduce::Sum(fy, ParallelDescriptor::Communicator()); - amrex::ParallelAllReduce::Sum(fz, ParallelDescriptor::Communicator()); - amrex::ParallelAllReduce::Sum(mx, ParallelDescriptor::Communicator()); - amrex::ParallelAllReduce::Sum(my, ParallelDescriptor::Communicator()); - amrex::ParallelAllReduce::Sum(mz, ParallelDescriptor::Communicator()); - - kernel.ib_force = {fx, fy, fz}; - kernel.ib_moment = {mx, my, mz}; - - EulerForce.SumBoundary(ParticleProperties::euler_force_index, 3, gm.periodicity()); - - // if (false) { - // // Check the Multifab - // // Open a file stream for output - // std::ofstream outFile("EulerForce.txt"); - - // // Check the Multifab - // // for (MFIter mfi(EulerForce, TilingIfNotGPU()); mfi.isValid(); ++mfi) - // for (MFIter mfi(EulerForce, TilingIfNotGPU()); mfi.isValid(); ++mfi) - // { - // const Box& bx = mfi.validbox(); - // outFile << "Box: " << bx << "\n" - // << "From: (" << bx.smallEnd(0) << ", " << bx.smallEnd(1) << ", " << bx.smallEnd(2) << ") " - // << "To: (" << bx.bigEnd(0) << ", " << bx.bigEnd(1) << ", " << bx.bigEnd(2) << ")\n"; - - // Array4 const& a = EulerForce[mfi].array(); - - // // CPU context or illustrative purposes only - // for (int k = bx.smallEnd(2); k <= bx.bigEnd(2); ++k) { - // for (int j = bx.smallEnd(1); j <= bx.bigEnd(1); ++j) { - // for (int i = bx.smallEnd(0); i <= bx.bigEnd(0); ++i) { - // // This print statement is for demonstration and should not be used in actual GPU code. - // outFile << "Processing i: " << i << ", j: " << j << ", k: " << k << " " << a(i,j,k,0) << " " << a(i,j,k,1) << " " << a(i,j,k,2) << "\n"; - // } - // } - // } - // } - - // // Close the file when done - // outFile.close(); - // } - -} - -void mParticle::ResetLargrangianPoints() -{ - if (verbose) amrex::Print() << "\tmParticle::ResetLargrangianPoints\n"; - - for(mParIter pti(*mContainer, LOCAL_LEVEL); pti.isValid(); ++pti){ - const Long np = pti.numParticles(); - auto& attri = pti.GetAttribs(); - - auto *const vUP_ptr = attri[P_ATTR::U_Marker].data(); - auto *const vVP_ptr = attri[P_ATTR::V_Marker].data(); - auto *const vWP_ptr = attri[P_ATTR::W_Marker].data(); - auto *const fxP_ptr = attri[P_ATTR::Fx_Marker].data(); - auto *const fyP_ptr = attri[P_ATTR::Fy_Marker].data(); - auto *const fzP_ptr = attri[P_ATTR::Fz_Marker].data(); - auto *const mxP_ptr = attri[P_ATTR::Mx_Marker].data(); - auto *const myP_ptr = attri[P_ATTR::My_Marker].data(); - auto *const mzP_ptr = attri[P_ATTR::Mz_Marker].data(); - amrex::ParallelFor(np, [=] - AMREX_GPU_DEVICE (int i) noexcept{ - vUP_ptr[i] = 0.0; - vVP_ptr[i] = 0.0; - vWP_ptr[i] = 0.0; - fxP_ptr[i] = 0.0; - fyP_ptr[i] = 0.0; - fzP_ptr[i] = 0.0; - mxP_ptr[i] = 0.0; - myP_ptr[i] = 0.0; - mzP_ptr[i] = 0.0; - }); - } -} - -void mParticle::UpdateParticles(int iStep, - Real time, - const MultiFab& Euler_old, - const MultiFab& Euler, - MultiFab& phi_nodal, - MultiFab& pvf, - Real dt) -{ - if (verbose) amrex::Print() << "mParticle::UpdateParticles\n"; - // start record - auto UpdateParticlesStart = ParallelDescriptor::second(); - - //Particle Collision calculation - DoParticleCollision(ParticleProperties::collision_model); - - MultiFab AllParticlePVF(pvf.boxArray(), pvf.DistributionMap(), pvf.nComp(), pvf.nGrow()); - AllParticlePVF.setVal(0.0); - - //continue condition 6DOF - for(auto& kernel : particle_kernels){ - - calculate_phi_nodal(phi_nodal, kernel); - nodal_phi_to_pvf(pvf, phi_nodal); - - // // fixed particle - // if( ( kernel.TL.sum() == 0 ) && - // ( kernel.RL.sum() == 0 ) ) { - // amrex::Print() << "Particle (" << kernel.id << ") is fixed\n"; - // MultiFab::Add(AllParticlePVF, pvf, 0, 0, 1, 0); // do not copy ghost cell values - // continue; - // } - - int ncomp = pvf.nComp(); - int ngrow = pvf.nGrow(); - MultiFab pvf_old(pvf.boxArray(), pvf.DistributionMap(), ncomp, ngrow); - MultiFab::Copy(pvf_old, pvf, 0, 0, ncomp, ngrow); - - // bool at_least_one_free_trans_motion = ( kernel.TL[0] == 2 ) || - // ( kernel.TL[1] == 2 ) || - // ( kernel.TL[2] == 2 ); - // bool at_least_one_free_rot_motion = ( kernel.RL[0] == 2 ) || - // ( kernel.RL[1] == 2 ) || - // ( kernel.RL[2] == 2 ); - - int loop = ParticleProperties::loop_solid; - - while (loop > 0 && iStep > ParticleProperties::start_step) { - - // if(at_least_one_free_trans_motion) { - kernel.sum_u_new.scale(0.0); - kernel.sum_u_old.scale(0.0); - // sum U - CalculateSumU_cir(kernel.sum_u_new, Euler, pvf, ParticleProperties::euler_velocity_index); - CalculateSumU_cir(kernel.sum_u_old, Euler_old, pvf_old, ParticleProperties::euler_velocity_index); - amrex::ParallelAllReduce::Sum(kernel.sum_u_new.dataPtr(), 3, amrex::ParallelDescriptor::Communicator()); - amrex::ParallelAllReduce::Sum(kernel.sum_u_old.dataPtr(), 3, amrex::ParallelDescriptor::Communicator()); - // } - - // if(at_least_one_free_rot_motion) { - kernel.sum_t_new.scale(0.0); - kernel.sum_t_old.scale(0.0); - // sum T - CalculateSumT_cir(kernel.sum_t_new, Euler, pvf, kernel.location, ParticleProperties::euler_velocity_index); - CalculateSumT_cir(kernel.sum_t_old, Euler_old, pvf_old, kernel.location, ParticleProperties::euler_velocity_index); - amrex::ParallelAllReduce::Sum(kernel.sum_t_new.dataPtr(), 3, amrex::ParallelDescriptor::Communicator()); - amrex::ParallelAllReduce::Sum(kernel.sum_t_old.dataPtr(), 3, amrex::ParallelDescriptor::Communicator()); - // } - - // 6DOF - if(ParallelDescriptor::MyProc() == ParallelDescriptor::IOProcessorNumber()){ - - for(auto idir : {0,1,2}) - { - //TL - if (kernel.TL[idir] == 0) { - kernel.velocity[idir] = 0.0; - } - else if (kernel.TL[idir] == 1) { - kernel.location[idir] = kernel.location_old[idir] + (kernel.velocity[idir] + kernel.velocity_old[idir]) * dt * 0.5; - } - else if (kernel.TL[idir] == 2) { - if(!ParticleProperties::Uhlmann){ - kernel.velocity[idir] = kernel.velocity_old[idir] - + ((kernel.sum_u_new[idir] - kernel.sum_u_old[idir]) * ParticleProperties::euler_fluid_rho / dt - - kernel.ib_force[idir] * ParticleProperties::euler_fluid_rho - + m_gravity[idir] * (kernel.rho - ParticleProperties::euler_fluid_rho) * kernel.Vp - + kernel.Fcp[idir]) * dt / kernel.rho / kernel.Vp ; - }else{ - //Uhlmann - kernel.velocity[idir] = kernel.velocity_old[idir] - + (ParticleProperties::euler_fluid_rho / kernel.Vp /(ParticleProperties::euler_fluid_rho - kernel.rho)*kernel.ib_force[idir] - + m_gravity[idir]) * dt; - } - kernel.location[idir] = kernel.location_old[idir] + (kernel.velocity[idir] + kernel.velocity_old[idir]) * dt * 0.5; - } - else { - amrex::Print() << "Particle (" << kernel.id << ") has wrong TL"<< direction_str[idir] <<" value\n"; - amrex::Abort("Stop here!"); - } - //RL - if (kernel.RL[idir] == 0) { - kernel.omega[idir] = 0.0; - } - else if (kernel.RL[idir] == 1) { - } - else if (kernel.RL[idir] == 2) { - if(!ParticleProperties::Uhlmann){ - kernel.omega[idir] = kernel.omega_old[idir] - + ((kernel.sum_t_new[idir] - kernel.sum_t_old[idir]) * ParticleProperties::euler_fluid_rho / dt - - kernel.ib_moment[idir] * ParticleProperties::euler_fluid_rho - + kernel.Tcp[idir]) * dt / cal_momentum(kernel.rho, kernel.radius); - }else{ - //Uhlmann - kernel.omega[idir] = kernel.omega_old[idir] - + ParticleProperties::euler_fluid_rho /(ParticleProperties::euler_fluid_rho - kernel.rho) * kernel.ib_moment[idir] * kernel.dv - / cal_momentum(kernel.rho, kernel.radius) * kernel.rho * dt; - } - } - else { - amrex::Print() << "Particle (" << kernel.id << ") has wrong RL"<< direction_str[idir] <<" value\n"; - amrex::Abort("Stop here!"); - } - - } - } - ParallelDescriptor::Bcast(&kernel.location[0],3,ParallelDescriptor::IOProcessorNumber()); - ParallelDescriptor::Bcast(&kernel.location_old[0],3,ParallelDescriptor::IOProcessorNumber()); - ParallelDescriptor::Bcast(&kernel.velocity[0],3,ParallelDescriptor::IOProcessorNumber()); - ParallelDescriptor::Bcast(&kernel.velocity_old[0],3,ParallelDescriptor::IOProcessorNumber()); - ParallelDescriptor::Bcast(&kernel.omega[0],3,ParallelDescriptor::IOProcessorNumber()); - ParallelDescriptor::Bcast(&kernel.omega_old[0],3,ParallelDescriptor::IOProcessorNumber()); - - loop--; - - if (loop > 0) { - calculate_phi_nodal(phi_nodal, kernel); - nodal_phi_to_pvf(pvf, phi_nodal); - } - - } - - RecordOldValue(kernel); - MultiFab::Add(AllParticlePVF, pvf, 0, 0, 1, 0); // do not copy ghost cell values - } - // calculate the pvf based on the information of all particles - MultiFab::Copy(pvf, AllParticlePVF, 0, 0, 1, pvf.nGrow()); - - spend_time += ParallelDescriptor::second() - UpdateParticlesStart; - ParallelDescriptor::ReduceRealMax(spend_time); - amrex::Print() << "[DIBM] IB and update particle, step : "<< iStep <<", time : " << spend_time << "\n"; - - int particle_write_freq = ParticleProperties::write_freq; - if (iStep % particle_write_freq == 0) { - for(auto kernel: particle_kernels) - WriteIBForceAndMoment(iStep, time, dt, kernel); - } - - if (verbose) mContainer->WriteAsciiFile(amrex::Concatenate("particle", 4)); -} - -void mParticle::DoParticleCollision(int model) -{ - if(particle_kernels.size() < 2 ) return ; - - if (verbose) amrex::Print() << "\tmParticle::DoParticleCollision\n"; - - if(ParallelDescriptor::MyProc() == ParallelDescriptor::IOProcessorNumber()){ - for(const auto& kernel : particle_kernels){ - m_Collision.InsertParticle(kernel.location, kernel.velocity, kernel.radius, kernel.rho); - } - - m_Collision.takeModel(model); - - for(auto & particle_kernel : particle_kernels){ - particle_kernel.Fcp = m_Collision.Particles.front().preForece - * particle_kernel.Vp * particle_kernel.rho * m_gravity.vectorLength(); - m_Collision.Particles.pop_front(); - } - } - for(auto& kernel : particle_kernels){ - ParallelDescriptor::Bcast(kernel.Fcp.dataPtr(), 3, ParallelDescriptor::IOProcessorNumber()); - } -} - -void mParticle::ComputeLagrangianForce(Real dt, - const kernel& kernel) -{ - - if (verbose) amrex::Print() << "\tmParticle::ComputeLagrangianForce\n"; - - Real Ub = kernel.velocity[0]; - Real Vb = kernel.velocity[1]; - Real Wb = kernel.velocity[2]; - Real Px = kernel.location[0]; - Real Py = kernel.location[1]; - Real Pz = kernel.location[2]; - - for(mParIter pti(*mContainer, LOCAL_LEVEL); pti.isValid(); ++pti){ - const Long np = pti.numParticles(); - auto& attri = pti.GetAttribs(); - auto const* p_ptr = pti.GetArrayOfStructs().data(); - - auto* Up = attri[P_ATTR::U_Marker].data(); - auto* Vp = attri[P_ATTR::V_Marker].data(); - auto* Wp = attri[P_ATTR::W_Marker].data(); - auto *FxP = attri[P_ATTR::Fx_Marker].data(); - auto *FyP = attri[P_ATTR::Fy_Marker].data(); - auto *FzP = attri[P_ATTR::Fz_Marker].data(); - - amrex::ParallelFor(np, - [=] AMREX_GPU_DEVICE (int i) noexcept{ - auto Ur = (kernel.omega).crossProduct(RealVect(p_ptr[i].pos(0) - Px, p_ptr[i].pos(1) - Py, p_ptr[i].pos(2) - Pz)); - FxP[i] = (Ub + Ur[0] - Up[i])/dt; // - FyP[i] = (Vb + Ur[1] - Vp[i])/dt; // - FzP[i] = (Wb + Ur[2] - Wp[i])/dt; // - }); - } - if (verbose) mContainer->WriteAsciiFile(amrex::Concatenate("particle", 3)); -} - -void mParticle::VelocityCorrection(amrex::MultiFab &Euler, amrex::MultiFab &EulerForce, Real dt) const -{ - if(verbose) amrex::Print() << "\tmParticle::VelocityCorrection\n"; - MultiFab::Saxpy(Euler, dt, EulerForce, ParticleProperties::euler_force_index, ParticleProperties::euler_velocity_index, 3, 0); //VelocityCorrection -} - -void mParticle::RecordOldValue(kernel& kernel) -{ - kernel.location_old = kernel.location; - kernel.velocity_old = kernel.velocity; - kernel.omega_old = kernel.omega; -} - -void mParticle::WriteParticleFile(int index) -{ - mContainer->WriteAsciiFile(amrex::Concatenate("particle", index)); -} - -void mParticle::WriteIBForceAndMoment(int step, amrex::Real time, amrex::Real dt, kernel& current_kernel) -{ - - if(amrex::ParallelDescriptor::MyProc() != ParallelDescriptor::IOProcessorNumber()) return; - - std::string file("IB_Particle_" + std::to_string(current_kernel.id) + ".csv"); - std::ofstream out_ib_force; - - std::string head; - if(!fs::exists(file)){ - head = "iStep,time,X,Y,Z,Vx,Vy,Vz,Rx,Ry,Rz,Fx,Fy,Fz,Mx,My,Mz,Fcpx,Fcpy,Fcpz,Tcpx,Tcpy,Tcpz,SumUx,SumUy,SumUz,SumTx,SumTy,SumTz\n"; - }else{ - head = ""; - } - - out_ib_force.open(file, std::ios::app); - if(!out_ib_force.is_open()){ - amrex::Print() << "[Particle] write particle file error , step: " << step; - }else{ - out_ib_force << head << step << "," << time << "," - << current_kernel.location[0] << "," << current_kernel.location[1] << "," << current_kernel.location[2] << "," - << current_kernel.velocity[0] << "," << current_kernel.velocity[1] << "," << current_kernel.velocity[2] << "," - << current_kernel.omega[0] << "," << current_kernel.omega[1] << "," << current_kernel.omega[2] << "," - << current_kernel.ib_force[0] << "," << current_kernel.ib_force[1] << "," << current_kernel.ib_force[2] << "," - << current_kernel.ib_moment[0] << "," << current_kernel.ib_moment[1] << "," << current_kernel.ib_moment[2] << "," - << current_kernel.Fcp[0] << "," << current_kernel.Fcp[1] << "," << current_kernel.Fcp[2] << "," - << current_kernel.Tcp[0] << "," << current_kernel.Tcp[1] << "," << current_kernel.Tcp[2] << "," - << (current_kernel.sum_u_new[0] - current_kernel.sum_u_old[0])/dt << "," - << (current_kernel.sum_u_new[1] - current_kernel.sum_u_old[1])/dt << "," - << (current_kernel.sum_u_new[2] - current_kernel.sum_u_old[2])/dt << "," - << (current_kernel.sum_t_new[0] - current_kernel.sum_t_old[0])/dt << "," - << (current_kernel.sum_t_new[1] - current_kernel.sum_t_old[1])/dt << "," - << (current_kernel.sum_t_new[2] - current_kernel.sum_t_old[2])/dt << "\n"; - } - out_ib_force.close(); -} - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* Particles member function */ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -void Particles::create_particles(const Geometry &gm, - const DistributionMapping & dm, - const BoxArray & ba) -{ - amrex::Print() << "[Particle] : create Particle Container\n"; - if(particle->mContainer != nullptr){ - delete particle->mContainer; - particle->mContainer = nullptr; - } - particle->mContainer = new mParticleContainer(gm, dm, ba); - - //get particle tile - std::pair key{0,0}; - auto& particleTileTmp = particle->mContainer->GetParticles(0)[key]; - //insert markers - if ( ParallelDescriptor::MyProc() == ParallelDescriptor::IOProcessorNumber() ) { - //insert particle's markers - //Real phiK = 0; - for(int marker_index = 0; marker_index < particle->particle_kernels[0].ml; marker_index++){ - //insert code - mParticleContainer::ParticleType markerP; - markerP.id() = marker_index + 1; - markerP.cpu() = ParallelDescriptor::MyProc(); - markerP.pos(0) = particle->particle_kernels[0].location[0]; - markerP.pos(1) = particle->particle_kernels[0].location[1]; - markerP.pos(2) = particle->particle_kernels[0].location[2]; - - std::array Marker_attr; - Marker_attr[U_Marker] = 0.0; - Marker_attr[V_Marker] = 0.0; - Marker_attr[W_Marker] = 0.0; - Marker_attr[Fx_Marker] = 0.0; - Marker_attr[Fy_Marker] = 0.0; - Marker_attr[Fz_Marker] = 0.0; - - particleTileTmp.push_back(markerP); - particleTileTmp.push_back_real(Marker_attr); - } - } - particle->mContainer->Redistribute(); // Still needs to redistribute here! - - ParticleProperties::plo = gm.ProbLoArray(); - ParticleProperties::phi = gm.ProbHiArray(); - ParticleProperties::dx = gm.CellSizeArray(); -} - -mParticle* Particles::get_particles() -{ - return particle; -} - - -void Particles::init_particle(Real gravity, Real h) -{ - amrex::Print() << "[Particle] : create Particle's kernel\n"; - particle = new mParticle; - if(particle != nullptr){ - isInitial = true; - particle->InitParticles( - ParticleProperties::_x, - ParticleProperties::_y, - ParticleProperties::_z, - ParticleProperties::_rho, - ParticleProperties::Vx, - ParticleProperties::Vy, - ParticleProperties::Vz, - ParticleProperties::Ox, - ParticleProperties::Oy, - ParticleProperties::Oz, - ParticleProperties::TLX, - ParticleProperties::TLY, - ParticleProperties::TLZ, - ParticleProperties::RLX, - ParticleProperties::RLY, - ParticleProperties::RLZ, - ParticleProperties::_radius, - h, - gravity, - ParticleProperties::verbose); - } - -} - -void Particles::Restart(Real gravity, Real h, int iStep) -{ - amrex::Print() << "[Particle] : restart Particle's kernel, step :" << iStep << "\n" - << "\tstart read particle csv file , default name is IB_Particle_x.csv\n" - << "\tdo not delete those file before \"restart\"\n\n"; - delete particle; - particle = new mParticle; - particle->InitParticles( - ParticleProperties::_x, - ParticleProperties::_y, - ParticleProperties::_z, - ParticleProperties::_rho, - ParticleProperties::Vx, - ParticleProperties::Vy, - ParticleProperties::Vz, - ParticleProperties::Ox, - ParticleProperties::Oy, - ParticleProperties::Oz, - ParticleProperties::TLX, - ParticleProperties::TLY, - ParticleProperties::TLZ, - ParticleProperties::RLX, - ParticleProperties::RLY, - ParticleProperties::RLZ, - ParticleProperties::_radius, - h, - gravity, - ParticleProperties::verbose); - //deal in IO processor - //start read csv file - for(auto& kernel : particle->particle_kernels){ - //filename - if(amrex::ParallelDescriptor::MyProc() == amrex::ParallelDescriptor::IOProcessorNumber()){ - std::string fileName = "IB_Particle_" + std::to_string(kernel.id) + ".csv"; - std::string tmpfile = "tmp" + fileName; - //file stream - std::ifstream particle_data(fileName); - std::ofstream particle_file(tmpfile); - // open state - if(!particle_data.is_open() || !particle_file.is_open()){ - amrex::Abort("\tCan not open particle file : " + fileName); - } - std::string lineData; - int line{0}; - while(std::getline(particle_data, lineData)){ - line++; - particle_file << lineData << "\n"; - if(line <= iStep) { - continue; - } - //old location - //iStep,time,X,Y,Z,Vx,Vy,Vz,Rx,Ry,Rz,Fx,Fy,Fz,Mx,My,Mz,Fcpx,Fcpy,Fcpz,Tcpx,Tcpy,Tcpz - if(line == iStep + 1){ - std::stringstream ss(lineData); - std::string data; - std::vector dataStruct; - while(std::getline(ss, data, ',')){ - dataStruct.emplace_back(std::stod(data)); - } - kernel.location[0] = dataStruct[2]; - kernel.location[1] = dataStruct[3]; - kernel.location[2] = dataStruct[4]; - kernel.velocity[0] = dataStruct[5]; - kernel.velocity[1] = dataStruct[6]; - kernel.velocity[2] = dataStruct[7]; - kernel.omega[0] = dataStruct[8]; - kernel.omega[1] = dataStruct[9]; - kernel.omega[2] = dataStruct[10]; - - kernel.location_old = kernel.location; - kernel.velocity_old = kernel.velocity; - kernel.omega_old = kernel.omega; - break; - } - else - break; - } - particle_data.close(); - particle_file.close(); - std::remove(fileName.c_str()); - std::rename(tmpfile.c_str(), fileName.c_str()); - } - ParallelDescriptor::Bcast(&kernel.location[0], 3, ParallelDescriptor::IOProcessorNumber()); - ParallelDescriptor::Bcast(&kernel.velocity[0], 3,ParallelDescriptor::IOProcessorNumber()); - ParallelDescriptor::Bcast(&kernel.omega[0], 3,ParallelDescriptor::IOProcessorNumber()); - - ParallelDescriptor::Bcast(&kernel.location_old[0], 3, ParallelDescriptor::IOProcessorNumber()); - ParallelDescriptor::Bcast(&kernel.velocity_old[0], 3,ParallelDescriptor::IOProcessorNumber()); - ParallelDescriptor::Bcast(&kernel.omega_old[0], 3,ParallelDescriptor::IOProcessorNumber()); - } - - isInitial = true; -} - -void Particles::Initialize() -{ - ParmParse pp("particle"); - - std::string particle_inputfile; - std::string particle_init_file; - pp.get("input",particle_inputfile); - - if(!particle_inputfile.empty()){ - ParmParse p_file(particle_inputfile); - p_file.query("init", particle_init_file); - p_file.getarr("x", ParticleProperties::_x); - p_file.getarr("y", ParticleProperties::_y); - p_file.getarr("z", ParticleProperties::_z); - p_file.getarr("rho", ParticleProperties::_rho); - p_file.getarr("velocity_x", ParticleProperties::Vx); - p_file.getarr("velocity_y", ParticleProperties::Vy); - p_file.getarr("velocity_z", ParticleProperties::Vz); - p_file.getarr("omega_x", ParticleProperties::Ox); - p_file.getarr("omega_y", ParticleProperties::Oy); - p_file.getarr("omega_z", ParticleProperties::Oz); - p_file.getarr("TLX", ParticleProperties::TLX); - p_file.getarr("TLY", ParticleProperties::TLY); - p_file.getarr("TLZ", ParticleProperties::TLZ); - p_file.getarr("RLX", ParticleProperties::RLX); - p_file.getarr("RLY", ParticleProperties::RLY); - p_file.getarr("RLZ", ParticleProperties::RLZ); - p_file.getarr("radius", ParticleProperties::_radius); - p_file.query("RD", ParticleProperties::rd); - p_file.query("LOOP_NS", ParticleProperties::loop_ns); - p_file.query("LOOP_SOLID", ParticleProperties::loop_solid); - p_file.query("verbose", ParticleProperties::verbose); - p_file.query("start_step", ParticleProperties::start_step); - p_file.query("Uhlmann", ParticleProperties::Uhlmann); - p_file.query("collision_model", ParticleProperties::collision_model); - p_file.query("write_freq", ParticleProperties::write_freq); - - ParmParse ns("ns"); - ns.get("fluid_rho", ParticleProperties::euler_fluid_rho); - - ParmParse level_parse("amr"); - level_parse.get("max_level", ParticleProperties::euler_finest_level); - - ParmParse geometry_parse("geometry"); - geometry_parse.getarr("prob_lo", ParticleProperties::GLO); - geometry_parse.getarr("prob_hi", ParticleProperties::GHI); - amrex::Print() << "[Particle] : Reading partilces cfg file : " << particle_inputfile << "\n" - << " Particle's level : " << ParticleProperties::euler_finest_level << "\n"; - - if(!particle_init_file.empty()){ - ParticleProperties::init_particle_from_file = true; - //clear particle position container - ParticleProperties::_x.clear(); - ParticleProperties::_y.clear(); - ParticleProperties::_z.clear(); - // parse particle's location data - std::ifstream init_particle(particle_init_file); - std::string line_data; - while(std::getline(init_particle, line_data)){ - // id x_location y_location z_location - std::istringstream line(line_data); - std::vector str_tokne; - std::string token; - while(line >> token){ - str_tokne.push_back(token); - } - - ParticleProperties::_x.push_back(std::stod(str_tokne[0])); - ParticleProperties::_y.push_back(std::stod(str_tokne[1])); - ParticleProperties::_z.push_back(std::stod(str_tokne[2])); - } - ParticleProperties::_x.shrink_to_fit(); - ParticleProperties::_y.shrink_to_fit(); - ParticleProperties::_z.shrink_to_fit(); - amrex::Print() << " initial Particle by file : " << particle_init_file - << " particle's size : " << ParticleProperties::_x.size() << "\n"; - } - - }else { - amrex::Abort("[Particle] : can't read particles settings, pls check your config file \"particle.input\""); - } -} - -int Particles::ParticleFinestLevel() -{ - return ParticleProperties::euler_finest_level; -} +// SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & ZhuXu Li<1246206018@qq.com> +// +// SPDX-License-Identifier: BSD-3-Clause + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +namespace fs = std::filesystem; + +#define GHOST_CELLS 2 + +using namespace amrex; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* global variable */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +#define LOCAL_LEVEL 0 + +const Vector direction_str{"X","Y","Z"}; + +namespace ParticleProperties{ + Vector _x{}, _y{}, _z{}, _rho{}; + Vector Vx{}, Vy{}, Vz{}; + Vector Ox{}, Oy{}, Oz{}; + Vector _radius; + Real rd{0.0}; + Vector TLX{}, TLY{},TLZ{},RLX{},RLY{},RLZ{}; + int euler_finest_level{0}; + int euler_velocity_index{0}; + int euler_force_index{0}; + Real euler_fluid_rho{0.0}; + int verbose{0}; + int loop_ns{2}; + int loop_solid{1}; + int Uhlmann{0}; + + Vector GLO, GHI; + int start_step{-1}; + int collision_model{0}; + + int write_freq{1}; + bool init_particle_from_file{false}; + + GpuArray plo{0.0,0.0,0.0}, phi{0.0,0.0,0.0}, dx{0.0, 0.0, 0.0}; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* other function */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void nodal_phi_to_pvf(MultiFab& pvf, const MultiFab& phi_nodal) +{ + + // amrex::Print() << "In the nodal_phi_to_pvf\n"; + + pvf.setVal(0.0); + + // Only set the valid cells of pvf +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(pvf,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + auto const& pvffab = pvf.array(mfi); + auto const& pnfab = phi_nodal.array(mfi); + amrex::ParallelFor(bx, [pvffab, pnfab] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + Real num = 0.0; + for(int kk=k; kk<=k+1; kk++) { + for(int jj=j; jj<=j+1; jj++) { + for(int ii=i; ii<=i+1; ii++) { + num += (-pnfab(ii,jj,kk)) * nodal_phi_to_heavi(-pnfab(ii,jj,kk)); + } + } + } + Real deo = 0.0; + for(int kk=k; kk<=k+1; kk++) { + for(int jj=j; jj<=j+1; jj++) { + for(int ii=i; ii<=i+1; ii++) { + deo += std::abs(pnfab(ii,jj,kk)); + } + } + } + pvffab(i,j,k) = num / (deo + 1.e-12); + }); + } + +} + +void calculate_phi_nodal(MultiFab& phi_nodal, kernel& current_kernel) +{ + phi_nodal.setVal(0.0); + + amrex::Real Xp = current_kernel.location[0]; + amrex::Real Yp = current_kernel.location[1]; + amrex::Real Zp = current_kernel.location[2]; + amrex::Real Rp = current_kernel.radius; + + // Only set the valid cells of phi_nodal + for (MFIter mfi(phi_nodal,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + auto const& pnfab = phi_nodal.array(mfi); + auto dx = ParticleProperties::dx; + auto plo = ParticleProperties::plo; + amrex::ParallelFor(bx, [=] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + Real Xn = i * dx[0] + plo[0]; + Real Yn = j * dx[1] + plo[1]; + Real Zn = k * dx[2] + plo[2]; + + pnfab(i,j,k) = std::sqrt( (Xn - Xp)*(Xn - Xp) + + (Yn - Yp)*(Yn - Yp) + (Zn - Zp)*(Zn - Zp)) - Rp; + pnfab(i,j,k) = pnfab(i,j,k) / Rp; + + } + ); + } +} + +// May use ParReduce later, https://amrex-codes.github.io/amrex/docs_html/GPU.html#multifab-reductions +void CalculateSumU_cir (RealVect& sum, + const MultiFab& E, + const MultiFab& pvf, + int EulerVelIndex) +{ + auto const& E_data = E.const_arrays(); + auto const& pvf_data = pvf.const_arrays(); + const Real d = Math::powi<3>(ParticleProperties::dx[0]); + amrex::GpuTuple tmpSum = ParReduce(TypeList{}, TypeList{},E, IntVect{0}, + [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> amrex::GpuTuple{ + auto E_ = E_data[box_no]; + auto pvf_ = pvf_data[box_no]; + return { + E_(i, j, k, EulerVelIndex ) * d * pvf_(i,j,k), + E_(i, j, k, EulerVelIndex + 1) * d * pvf_(i,j,k), + E_(i, j, k, EulerVelIndex + 2) * d * pvf_(i,j,k) + }; + }); + sum[0] = amrex::get<0>(tmpSum); + sum[1] = amrex::get<1>(tmpSum); + sum[2] = amrex::get<2>(tmpSum); +} + +void CalculateSumT_cir (RealVect& sum, + const MultiFab& E, + const MultiFab& pvf, + const RealVect pLoc, + int EulerVelIndex) +{ + auto plo = ParticleProperties::plo; + auto dx = ParticleProperties::dx; + + auto const& E_data = E.const_arrays(); + auto const& pvf_data = pvf.const_arrays(); + const Real d = Math::powi<3>(ParticleProperties::dx[0]); + amrex::GpuTuple tmpSum = ParReduce(TypeList{}, TypeList{},E, IntVect{0}, + [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> amrex::GpuTuple{ + auto E_ = E_data[box_no]; + auto pvf_ = pvf_data[box_no]; + + Real x = plo[0] + i*dx[0] + 0.5*dx[0]; + Real y = plo[1] + j*dx[1] + 0.5*dx[1]; + Real z = plo[2] + k*dx[2] + 0.5*dx[2]; + + Real vx = E_(i, j, k, EulerVelIndex ); + Real vy = E_(i, j, k, EulerVelIndex + 1); + Real vz = E_(i, j, k, EulerVelIndex + 2); + + RealVect tmp = RealVect(x - pLoc[0], y - pLoc[1], z - pLoc[2]).crossProduct(RealVect(vx, vy, vz)); + + return { + tmp[0] * d * pvf_(i, j, k), + tmp[1] * d * pvf_(i, j, k), + tmp[2] * d * pvf_(i, j, k) + }; + }); + sum[0] = amrex::get<0>(tmpSum); + sum[1] = amrex::get<1>(tmpSum); + sum[2] = amrex::get<2>(tmpSum); +} + +[[nodiscard]] AMREX_FORCE_INLINE +Real cal_momentum(Real rho, Real radius) +{ + return 8.0 * Math::pi() * rho * Math::powi<5>(radius) / 15.0; +} + +AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE +void deltaFunction(Real xf, Real xp, Real h, Real& value, DELTA_FUNCTION_TYPE type) +{ + Real rr = amrex::Math::abs(( xf - xp ) / h); + + switch (type) { + case DELTA_FUNCTION_TYPE::FOUR_POINT_IB: + if(rr >= 0 && rr < 1 ){ + value = 1.0 / 8.0 * ( 3.0 - 2.0 * rr + std::sqrt( 1.0 + 4.0 * rr - 4 * Math::powi<2>(rr))) / h; + }else if (rr >= 1 && rr < 2) { + value = 1.0 / 8.0 * ( 5.0 - 2.0 * rr - std::sqrt( -7.0 + 12.0 * rr - 4 * Math::powi<2>(rr))) / h; + }else { + value = 0; + } + break; + case DELTA_FUNCTION_TYPE::THREE_POINT_IB: + if(rr >= 0.5 && rr < 1.5){ + value = 1.0 / 6.0 * ( 5.0 - 3.0 * rr - std::sqrt( - 3.0 * Math::powi<2>( 1 - rr) + 1.0 )) / h; + }else if (rr >= 0 && rr < 0.5) { + value = 1.0 / 3.0 * ( 1.0 + std::sqrt( 1.0 - 3 * Math::powi<2>(rr))) / h; + }else { + value = 0; + } + break; + default: + break; + } +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* mParticle member function */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +//loop all particels +void mParticle::InteractWithEuler(MultiFab &EulerVel, + MultiFab &EulerForce, + Real dt, + DELTA_FUNCTION_TYPE type) +{ + if (verbose) amrex::Print() << "[Particle] mParticle::InteractWithEuler\n"; + // clear time , start record + spend_time = 0; + auto InteractWithEulerStart = ParallelDescriptor::second(); + + MultiFab EulerForceTmp(EulerForce.boxArray(), EulerForce.DistributionMap(), 3, EulerForce.nGrow()); + //clean preStep's IB_porperties + for(auto& kernel : particle_kernels) { + kernel.ib_force.scale(0.0); + kernel.ib_moment.scale(0.0); + } + + //for 1 -> Ns + int loop = ParticleProperties::loop_ns; + BL_ASSERT(loop > 0); + while(loop > 0){ + if(verbose) amrex::Print() << "[Particle] Ns loop index : " << loop << "\n"; + + EulerForce.setVal(0.0); + + for(kernel& kernel : particle_kernels){ + InitialWithLargrangianPoints(kernel); // Initialize markers for a specific particle + ResetLargrangianPoints(); + EulerForceTmp.setVal(0.0); + auto ib_force = kernel.ib_force; + auto ib_moment = kernel.ib_moment; + kernel.ib_force.scale(0.0); // clear kernel ib_force + kernel.ib_moment.scale(0.0); // clear kernel ib_moment + + VelocityInterpolation(EulerVel, type); + ComputeLagrangianForce(dt, kernel); + ForceSpreading(EulerForceTmp, kernel, type); + MultiFab::Add(EulerForce, EulerForceTmp, 0, 0, 3, EulerForce.nGrow()); + + kernel.ib_force += ib_force; + kernel.ib_moment += ib_moment; + } + VelocityCorrection(EulerVel, EulerForce, dt); + loop--; + } + spend_time += ParallelDescriptor::second() - InteractWithEulerStart; +} + +void mParticle::InitParticles(const Vector& x, + const Vector& y, + const Vector& z, + const Vector& rho_s, + const Vector& Vx, + const Vector& Vy, + const Vector& Vz, + const Vector& Ox, + const Vector& Oy, + const Vector& Oz, + const Vector& TLXt, + const Vector& TLYt, + const Vector& TLZt, + const Vector& RLXt, + const Vector& RLYt, + const Vector& RLZt, + const Vector& radius, + Real h, + Real gravity, + int _verbose) +{ + verbose = _verbose; + if (verbose) amrex::Print() << "[Particle] mParticle::InitParticles\n"; + + m_gravity[2] = gravity; + + //pre judge + if(!((x.size() == y.size()) && (x.size() == z.size()))){ + Print() << "particle's position container are all different size"; + return; + } + + //all the particles have different radius + for(int index = 0; index < x.size(); index++){ + int real_index; + // if initial with input file, initialized by [0] data + if(ParticleProperties::init_particle_from_file){ + real_index = 0; + }else{ + real_index = index; + } + + kernel mKernel; + mKernel.id = index + 1; + mKernel.location[0] = x[index]; + mKernel.location[1] = y[index]; + mKernel.location[2] = z[index]; + mKernel.velocity[0] = Vx[real_index]; + mKernel.velocity[1] = Vy[real_index]; + mKernel.velocity[2] = Vz[real_index]; + mKernel.omega[0] = Ox[real_index]; + mKernel.omega[1] = Oy[real_index]; + mKernel.omega[2] = Oz[real_index]; + + // use current state to initialize old state + mKernel.location_old = mKernel.location; + mKernel.velocity_old = mKernel.velocity; + mKernel.omega_old = mKernel.omega; + + mKernel.TL[0] = TLXt[real_index]; + mKernel.TL[1] = TLYt[real_index]; + mKernel.TL[2] = TLZt[real_index]; + mKernel.RL[0] = RLXt[real_index]; + mKernel.RL[1] = RLYt[real_index]; + mKernel.RL[2] = RLZt[real_index]; + mKernel.rho = rho_s[real_index]; + mKernel.radius = radius[real_index]; + mKernel.Vp = Math::pi() * 4 / 3 * Math::powi<3>(radius[real_index]); + + //int Ml = static_cast( Math::pi() / 3 * (12 * Math::powi<2>(mKernel.radius / h))); + //Real dv = Math::pi() * h / 3 / Ml * (12 * mKernel.radius * mKernel.radius + h * h); + int Ml = static_cast((amrex::Math::powi<3>(mKernel.radius - (ParticleProperties::rd - 0.5) * h) + - amrex::Math::powi<3>(mKernel.radius - (ParticleProperties::rd + 0.5) * h))/(3.*h*h*h/4./Math::pi())); + Real dv = (amrex::Math::powi<3>(mKernel.radius - (ParticleProperties::rd - 0.5) * h) + - amrex::Math::powi<3>(mKernel.radius - (ParticleProperties::rd + 0.5) * h))/(3.*Ml/4./Math::pi()); + mKernel.ml = Ml; + mKernel.dv = dv; + if( Ml > max_largrangian_num ) max_largrangian_num = Ml; + + Real phiK = 0; + for(int marker_index = 0; marker_index < Ml; marker_index++){ + Real Hk = -1.0 + 2.0 * (marker_index) / ( Ml - 1.0); + Real thetaK = std::acos(Hk); + if(marker_index == 0 || marker_index == (Ml - 1)){ + phiK = 0; + }else { + phiK = std::fmod( phiK + 3.809 / std::sqrt(Ml) / std::sqrt( 1 - Math::powi<2>(Hk)) , 2 * Math::pi()); + } + mKernel.phiK.push_back(phiK); + mKernel.thetaK.push_back(thetaK); + } + + particle_kernels.emplace_back(mKernel); + + if (verbose) amrex::Print() << "h: " << h << ", Ml: " << Ml << ", D: " << Math::powi<3>(h) << " gravity : " << gravity << "\n" + << "Kernel : " << index << ": Location (" << x[index] << ", " << y[index] << ", " << z[index] + << "), Velocity : (" << mKernel.velocity[0] << ", " << mKernel.velocity[1] << ", "<< mKernel.velocity[2] + << "), Radius: " << mKernel.radius << ", Ml: " << Ml << ", dv: " << dv << ", Rho: " << mKernel.rho << "\n"; + } + //collision box generate + m_Collision.SetGeometry(RealVect(ParticleProperties::GLO), RealVect(ParticleProperties::GHI),particle_kernels[0].radius, h); +} + +void mParticle::InitialWithLargrangianPoints(const kernel& current_kernel){ + + if (verbose) amrex::Print() << "mParticle::InitialWithLargrangianPoints\n"; + for(mParIter pti(*mContainer, LOCAL_LEVEL); pti.isValid(); ++pti){ + const Long np = pti.numParticles(); + if(np == 0) continue; + auto *particles = pti.GetArrayOfStructs().data(); + + const auto location = current_kernel.location; + const auto radius = current_kernel.radius; + const auto* phiK = current_kernel.phiK.dataPtr(); + const auto* thetaK = current_kernel.thetaK.dataPtr(); + + amrex::ParallelFor( np, [=] + AMREX_GPU_DEVICE (int i) noexcept { + auto id = particles[i].id(); + particles[i].pos(0) = location[0] + radius * std::sin(thetaK[id - 1]) * std::cos(phiK[id - 1]); + particles[i].pos(1) = location[1] + radius * std::sin(thetaK[id - 1]) * std::sin(phiK[id - 1]); + particles[i].pos(2) = location[2] + radius * std::cos(thetaK[id - 1]); + } + ); + } + // Redistribute the markers after updating their locations + mContainer->Redistribute(); + if (verbose) { + amrex::Print() << "[particle] : particle num :" << mContainer->TotalNumberOfParticles() << "\n"; + mContainer->WriteAsciiFile(amrex::Concatenate("particle", 1)); + } +} + +template > +AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE +void VelocityInterpolation_cir(int p_iter, P const& p, Real& Up, Real& Vp, Real& Wp, + Array4 const& E, int EulerVIndex, + const int *lo, const int *hi, + GpuArray const& plo, + GpuArray const& dx, + DELTA_FUNCTION_TYPE type) +{ + + //std::cout << "lo " << lo[0] << " " << lo[1] << " "<< lo[2] << "\n"; + //std::cout << "hi " << hi[0] << " " << hi[1] << " "<< hi[2] << "\n"; + + const Real d = AMREX_D_TERM(dx[0], *dx[1], *dx[2]); + + const Real lx = (p.pos(0) - plo[0]) / dx[0]; // x + const Real ly = (p.pos(1) - plo[1]) / dx[1]; // y + const Real lz = (p.pos(2) - plo[2]) / dx[2]; // z + + int i = static_cast(Math::floor(lx)); // i + int j = static_cast(Math::floor(ly)); // j + int k = static_cast(Math::floor(lz)); // k + + //std::cout << "p_iter " << p_iter << " p.pos(0): " << p.pos(0) << " p.pos(1): " << p.pos(1) << " p.pos(2): " << p.pos(2) << "\n"; + + // std::cout << "d: " << d << "\n" + // << "lx: " << lx << ", ly: " << ly << ", lz: " << lz << "\n" + // << "i: " << i << ", j: " << j << ", k: " << k << std::endl; + + Up = 0; + Vp = 0; + Wp = 0; + //Euler to largrangian + for(int ii = -2; ii < 3; ii++){ + for(int jj = -2; jj < 3; jj++){ + for(int kk = -2; kk < 3; kk ++){ + Real tU, tV, tW; + const Real xi = plo[0] + (i + ii) * dx[0] + dx[0]/2; + const Real yj = plo[1] + (j + jj) * dx[1] + dx[1]/2; + const Real kz = plo[2] + (k + kk) * dx[2] + dx[2]/2; + deltaFunction( p.pos(0), xi, dx[0], tU, type); + deltaFunction( p.pos(1), yj, dx[1], tV, type); + deltaFunction( p.pos(2), kz, dx[2], tW, type); + const Real delta_value = tU * tV * tW; + Up += delta_value * E(i + ii, j + jj, k + kk, EulerVIndex ) * d; + Vp += delta_value * E(i + ii, j + jj, k + kk, EulerVIndex + 1) * d; + Wp += delta_value * E(i + ii, j + jj, k + kk, EulerVIndex + 2) * d; + } + } + } +} + +void mParticle::VelocityInterpolation(MultiFab &EulerVel, + DELTA_FUNCTION_TYPE type)// +{ + if (verbose) amrex::Print() << "\tmParticle::VelocityInterpolation\n"; + + //amrex::Print() << "euler_finest_level " << euler_finest_level << std::endl; + const auto& gm = mContainer->GetParGDB()->Geom(LOCAL_LEVEL); + auto plo = gm.ProbLoArray(); + auto dx = gm.CellSizeArray(); + // attention + // velocity ghost cells will be up-to-date + EulerVel.FillBoundary(ParticleProperties::euler_velocity_index, 3, gm.periodicity()); + + const int EulerVelocityIndex = ParticleProperties::euler_velocity_index; + + for(mParIter pti(*mContainer, LOCAL_LEVEL); pti.isValid(); ++pti){ + + const Box& box = pti.validbox(); + + auto& particles = pti.GetArrayOfStructs(); + auto *p_ptr = particles.data(); + const Long np = pti.numParticles(); + + auto& attri = pti.GetAttribs(); + auto* Up = attri[P_ATTR::U_Marker].data(); + auto* Vp = attri[P_ATTR::V_Marker].data(); + auto* Wp = attri[P_ATTR::W_Marker].data(); + const auto& E = EulerVel.array(pti); + + amrex::ParallelFor(np, [=] + AMREX_GPU_DEVICE (int i) noexcept{ + VelocityInterpolation_cir(i, p_ptr[i], Up[i], Vp[i], Wp[i], E, EulerVelocityIndex, box.loVect(), box.hiVect(), plo, dx, type); + }); + } + if (verbose) mContainer->WriteAsciiFile(amrex::Concatenate("particle", 2)); + //amrex::Abort("stop here!"); +} + +template +AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE +void ForceSpreading_cic (P const& p, + Real Px, + Real Py, + Real Pz, + ParticleReal& fxP, + ParticleReal& fyP, + ParticleReal& fzP, + ParticleReal& mxP, + ParticleReal& myP, + ParticleReal& mzP, + Array4 const& E, + int EulerForceIndex, + Real dv, + GpuArray const& plo, + GpuArray const& dx, + DELTA_FUNCTION_TYPE type) +{ + //const Real d = AMREX_D_TERM(dx[0], *dx[1], *dx[2]); + //plo to ii jj kk + Real lx = (p.pos(0) - plo[0]) / dx[0]; + Real ly = (p.pos(1) - plo[1]) / dx[1]; + Real lz = (p.pos(2) - plo[2]) / dx[2]; + + int i = static_cast(Math::floor(lx)); + int j = static_cast(Math::floor(ly)); + int k = static_cast(Math::floor(lz)); + fxP *= dv; + fyP *= dv; + fzP *= dv; + RealVect moment = RealVect((p.pos(0) - Px), (p.pos(1) - Py), (p.pos(2) - Pz)).crossProduct(RealVect(fxP, fyP, fzP)); + mxP = moment[0]; + myP = moment[1]; + mzP = moment[2]; + //lagrangian to Euler + for(int ii = -2; ii < +3; ii++){ + for(int jj = -2; jj < +3; jj++){ + for(int kk = -2; kk < +3; kk ++){ + Real tU, tV, tW; + const Real xi =plo[0] + (i + ii) * dx[0] + dx[0]/2; + const Real yj =plo[1] + (j + jj) * dx[1] + dx[1]/2; + const Real kz =plo[2] + (k + kk) * dx[2] + dx[2]/2; + deltaFunction( p.pos(0), xi, dx[0], tU, type); + deltaFunction( p.pos(1), yj, dx[1], tV, type); + deltaFunction( p.pos(2), kz, dx[2], tW, type); + Real delta_value = tU * tV * tW; + Gpu::Atomic::AddNoRet(&E(i + ii, j + jj, k + kk, EulerForceIndex ), delta_value * fxP); + Gpu::Atomic::AddNoRet(&E(i + ii, j + jj, k + kk, EulerForceIndex+1), delta_value * fyP); + Gpu::Atomic::AddNoRet(&E(i + ii, j + jj, k + kk, EulerForceIndex+2), delta_value * fzP); + } + } + } +} + +void mParticle::ForceSpreading(MultiFab & EulerForce, + kernel& kernel, + DELTA_FUNCTION_TYPE type) +{ + if (verbose) amrex::Print() << "\tmParticle::ForceSpreading\n"; + const auto& gm = mContainer->GetParGDB()->Geom(LOCAL_LEVEL); + auto plo = gm.ProbLoArray(); + auto dxi = gm.CellSizeArray(); + for(mParIter pti(*mContainer, LOCAL_LEVEL); pti.isValid(); ++pti){ + const Long np = pti.numParticles(); + const auto& particles = pti.GetArrayOfStructs(); + auto Uarray = EulerForce[pti].array(); + auto& attri = pti.GetAttribs(); + + auto *const fxP_ptr = attri[P_ATTR::Fx_Marker].data(); + auto *const fyP_ptr = attri[P_ATTR::Fy_Marker].data(); + auto *const fzP_ptr = attri[P_ATTR::Fz_Marker].data(); + auto *const mxP_ptr = attri[P_ATTR::Mx_Marker].data(); + auto *const myP_ptr = attri[P_ATTR::My_Marker].data(); + auto *const mzP_ptr = attri[P_ATTR::Mz_Marker].data(); + const auto *const p_ptr = particles().data(); + + auto loc_ptr = kernel.location; + auto dv = kernel.dv; + auto force_index = ParticleProperties::euler_force_index; + amrex::ParallelFor(np, [=] + AMREX_GPU_DEVICE (int i) noexcept{ + ForceSpreading_cic(p_ptr[i], loc_ptr[0], loc_ptr[1], loc_ptr[2], + fxP_ptr[i], fyP_ptr[i], fzP_ptr[i], + mxP_ptr[i], myP_ptr[i], mzP_ptr[i], + Uarray, force_index, dv, plo, dxi, type); + }); + } + //barrier for sync; + amrex::ParallelDescriptor::Barrier(); + + using pc = mParticleContainer::SuperParticleType; + // Each Processor + auto fx = amrex::ReduceSum( *mContainer, [=]AMREX_GPU_HOST_DEVICE(const pc& p)->ParticleReal{return p.rdata(P_ATTR::Fx_Marker);}); + auto fy = amrex::ReduceSum( *mContainer, [=]AMREX_GPU_HOST_DEVICE(const pc& p)->ParticleReal{return p.rdata(P_ATTR::Fy_Marker);}); + auto fz = amrex::ReduceSum( *mContainer, [=]AMREX_GPU_HOST_DEVICE(const pc& p)->ParticleReal{return p.rdata(P_ATTR::Fz_Marker);}); + auto mx = amrex::ReduceSum( *mContainer, [=]AMREX_GPU_HOST_DEVICE(const pc& p)->ParticleReal{return p.rdata(P_ATTR::Mx_Marker);}); + auto my = amrex::ReduceSum( *mContainer, [=]AMREX_GPU_HOST_DEVICE(const pc& p)->ParticleReal{return p.rdata(P_ATTR::My_Marker);}); + auto mz = amrex::ReduceSum( *mContainer, [=]AMREX_GPU_HOST_DEVICE(const pc& p)->ParticleReal{return p.rdata(P_ATTR::Mz_Marker);}); + // MPI sum reduce -> current particle all IB force and moment + amrex::ParallelAllReduce::Sum(fx, ParallelDescriptor::Communicator()); + amrex::ParallelAllReduce::Sum(fy, ParallelDescriptor::Communicator()); + amrex::ParallelAllReduce::Sum(fz, ParallelDescriptor::Communicator()); + amrex::ParallelAllReduce::Sum(mx, ParallelDescriptor::Communicator()); + amrex::ParallelAllReduce::Sum(my, ParallelDescriptor::Communicator()); + amrex::ParallelAllReduce::Sum(mz, ParallelDescriptor::Communicator()); + + kernel.ib_force = {fx, fy, fz}; + kernel.ib_moment = {mx, my, mz}; + + EulerForce.SumBoundary(ParticleProperties::euler_force_index, 3, gm.periodicity()); + + // if (false) { + // // Check the Multifab + // // Open a file stream for output + // std::ofstream outFile("EulerForce.txt"); + + // // Check the Multifab + // // for (MFIter mfi(EulerForce, TilingIfNotGPU()); mfi.isValid(); ++mfi) + // for (MFIter mfi(EulerForce, TilingIfNotGPU()); mfi.isValid(); ++mfi) + // { + // const Box& bx = mfi.validbox(); + // outFile << "Box: " << bx << "\n" + // << "From: (" << bx.smallEnd(0) << ", " << bx.smallEnd(1) << ", " << bx.smallEnd(2) << ") " + // << "To: (" << bx.bigEnd(0) << ", " << bx.bigEnd(1) << ", " << bx.bigEnd(2) << ")\n"; + + // Array4 const& a = EulerForce[mfi].array(); + + // // CPU context or illustrative purposes only + // for (int k = bx.smallEnd(2); k <= bx.bigEnd(2); ++k) { + // for (int j = bx.smallEnd(1); j <= bx.bigEnd(1); ++j) { + // for (int i = bx.smallEnd(0); i <= bx.bigEnd(0); ++i) { + // // This print statement is for demonstration and should not be used in actual GPU code. + // outFile << "Processing i: " << i << ", j: " << j << ", k: " << k << " " << a(i,j,k,0) << " " << a(i,j,k,1) << " " << a(i,j,k,2) << "\n"; + // } + // } + // } + // } + + // // Close the file when done + // outFile.close(); + // } + +} + +void mParticle::ResetLargrangianPoints() +{ + if (verbose) amrex::Print() << "\tmParticle::ResetLargrangianPoints\n"; + + for(mParIter pti(*mContainer, LOCAL_LEVEL); pti.isValid(); ++pti){ + const Long np = pti.numParticles(); + auto& attri = pti.GetAttribs(); + + auto *const vUP_ptr = attri[P_ATTR::U_Marker].data(); + auto *const vVP_ptr = attri[P_ATTR::V_Marker].data(); + auto *const vWP_ptr = attri[P_ATTR::W_Marker].data(); + auto *const fxP_ptr = attri[P_ATTR::Fx_Marker].data(); + auto *const fyP_ptr = attri[P_ATTR::Fy_Marker].data(); + auto *const fzP_ptr = attri[P_ATTR::Fz_Marker].data(); + auto *const mxP_ptr = attri[P_ATTR::Mx_Marker].data(); + auto *const myP_ptr = attri[P_ATTR::My_Marker].data(); + auto *const mzP_ptr = attri[P_ATTR::Mz_Marker].data(); + amrex::ParallelFor(np, [=] + AMREX_GPU_DEVICE (int i) noexcept{ + vUP_ptr[i] = 0.0; + vVP_ptr[i] = 0.0; + vWP_ptr[i] = 0.0; + fxP_ptr[i] = 0.0; + fyP_ptr[i] = 0.0; + fzP_ptr[i] = 0.0; + mxP_ptr[i] = 0.0; + myP_ptr[i] = 0.0; + mzP_ptr[i] = 0.0; + }); + } +} + +void mParticle::UpdateParticles(int iStep, + Real time, + const MultiFab& Euler_old, + const MultiFab& Euler, + MultiFab& phi_nodal, + MultiFab& pvf, + Real dt) +{ + if (verbose) amrex::Print() << "mParticle::UpdateParticles\n"; + // start record + auto UpdateParticlesStart = ParallelDescriptor::second(); + + //Particle Collision calculation + DoParticleCollision(ParticleProperties::collision_model); + + MultiFab AllParticlePVF(pvf.boxArray(), pvf.DistributionMap(), pvf.nComp(), pvf.nGrow()); + AllParticlePVF.setVal(0.0); + + //continue condition 6DOF + for(auto& kernel : particle_kernels){ + + calculate_phi_nodal(phi_nodal, kernel); + nodal_phi_to_pvf(pvf, phi_nodal); + + // // fixed particle + // if( ( kernel.TL.sum() == 0 ) && + // ( kernel.RL.sum() == 0 ) ) { + // amrex::Print() << "Particle (" << kernel.id << ") is fixed\n"; + // MultiFab::Add(AllParticlePVF, pvf, 0, 0, 1, 0); // do not copy ghost cell values + // continue; + // } + + int ncomp = pvf.nComp(); + int ngrow = pvf.nGrow(); + MultiFab pvf_old(pvf.boxArray(), pvf.DistributionMap(), ncomp, ngrow); + MultiFab::Copy(pvf_old, pvf, 0, 0, ncomp, ngrow); + + // bool at_least_one_free_trans_motion = ( kernel.TL[0] == 2 ) || + // ( kernel.TL[1] == 2 ) || + // ( kernel.TL[2] == 2 ); + // bool at_least_one_free_rot_motion = ( kernel.RL[0] == 2 ) || + // ( kernel.RL[1] == 2 ) || + // ( kernel.RL[2] == 2 ); + + int loop = ParticleProperties::loop_solid; + + while (loop > 0 && iStep > ParticleProperties::start_step) { + + // if(at_least_one_free_trans_motion) { + kernel.sum_u_new.scale(0.0); + kernel.sum_u_old.scale(0.0); + // sum U + CalculateSumU_cir(kernel.sum_u_new, Euler, pvf, ParticleProperties::euler_velocity_index); + CalculateSumU_cir(kernel.sum_u_old, Euler_old, pvf_old, ParticleProperties::euler_velocity_index); + amrex::ParallelAllReduce::Sum(kernel.sum_u_new.dataPtr(), 3, amrex::ParallelDescriptor::Communicator()); + amrex::ParallelAllReduce::Sum(kernel.sum_u_old.dataPtr(), 3, amrex::ParallelDescriptor::Communicator()); + // } + + // if(at_least_one_free_rot_motion) { + kernel.sum_t_new.scale(0.0); + kernel.sum_t_old.scale(0.0); + // sum T + CalculateSumT_cir(kernel.sum_t_new, Euler, pvf, kernel.location, ParticleProperties::euler_velocity_index); + CalculateSumT_cir(kernel.sum_t_old, Euler_old, pvf_old, kernel.location, ParticleProperties::euler_velocity_index); + amrex::ParallelAllReduce::Sum(kernel.sum_t_new.dataPtr(), 3, amrex::ParallelDescriptor::Communicator()); + amrex::ParallelAllReduce::Sum(kernel.sum_t_old.dataPtr(), 3, amrex::ParallelDescriptor::Communicator()); + // } + + // 6DOF + if(ParallelDescriptor::MyProc() == ParallelDescriptor::IOProcessorNumber()){ + + for(auto idir : {0,1,2}) + { + //TL + if (kernel.TL[idir] == 0) { + kernel.velocity[idir] = 0.0; + } + else if (kernel.TL[idir] == 1) { + kernel.location[idir] = kernel.location_old[idir] + (kernel.velocity[idir] + kernel.velocity_old[idir]) * dt * 0.5; + } + else if (kernel.TL[idir] == 2) { + if(!ParticleProperties::Uhlmann){ + kernel.velocity[idir] = kernel.velocity_old[idir] + + ((kernel.sum_u_new[idir] - kernel.sum_u_old[idir]) * ParticleProperties::euler_fluid_rho / dt + - kernel.ib_force[idir] * ParticleProperties::euler_fluid_rho + + m_gravity[idir] * (kernel.rho - ParticleProperties::euler_fluid_rho) * kernel.Vp + + kernel.Fcp[idir]) * dt / kernel.rho / kernel.Vp ; + }else{ + //Uhlmann + kernel.velocity[idir] = kernel.velocity_old[idir] + + (ParticleProperties::euler_fluid_rho / kernel.Vp /(ParticleProperties::euler_fluid_rho - kernel.rho)*kernel.ib_force[idir] + + m_gravity[idir]) * dt; + } + kernel.location[idir] = kernel.location_old[idir] + (kernel.velocity[idir] + kernel.velocity_old[idir]) * dt * 0.5; + } + else { + amrex::Print() << "Particle (" << kernel.id << ") has wrong TL"<< direction_str[idir] <<" value\n"; + amrex::Abort("Stop here!"); + } + //RL + if (kernel.RL[idir] == 0) { + kernel.omega[idir] = 0.0; + } + else if (kernel.RL[idir] == 1) { + } + else if (kernel.RL[idir] == 2) { + if(!ParticleProperties::Uhlmann){ + kernel.omega[idir] = kernel.omega_old[idir] + + ((kernel.sum_t_new[idir] - kernel.sum_t_old[idir]) * ParticleProperties::euler_fluid_rho / dt + - kernel.ib_moment[idir] * ParticleProperties::euler_fluid_rho + + kernel.Tcp[idir]) * dt / cal_momentum(kernel.rho, kernel.radius); + }else{ + //Uhlmann + kernel.omega[idir] = kernel.omega_old[idir] + + ParticleProperties::euler_fluid_rho /(ParticleProperties::euler_fluid_rho - kernel.rho) * kernel.ib_moment[idir] * kernel.dv + / cal_momentum(kernel.rho, kernel.radius) * kernel.rho * dt; + } + } + else { + amrex::Print() << "Particle (" << kernel.id << ") has wrong RL"<< direction_str[idir] <<" value\n"; + amrex::Abort("Stop here!"); + } + + } + } + ParallelDescriptor::Bcast(&kernel.location[0],3,ParallelDescriptor::IOProcessorNumber()); + ParallelDescriptor::Bcast(&kernel.location_old[0],3,ParallelDescriptor::IOProcessorNumber()); + ParallelDescriptor::Bcast(&kernel.velocity[0],3,ParallelDescriptor::IOProcessorNumber()); + ParallelDescriptor::Bcast(&kernel.velocity_old[0],3,ParallelDescriptor::IOProcessorNumber()); + ParallelDescriptor::Bcast(&kernel.omega[0],3,ParallelDescriptor::IOProcessorNumber()); + ParallelDescriptor::Bcast(&kernel.omega_old[0],3,ParallelDescriptor::IOProcessorNumber()); + + loop--; + + if (loop > 0) { + calculate_phi_nodal(phi_nodal, kernel); + nodal_phi_to_pvf(pvf, phi_nodal); + } + + } + + RecordOldValue(kernel); + MultiFab::Add(AllParticlePVF, pvf, 0, 0, 1, 0); // do not copy ghost cell values + } + // calculate the pvf based on the information of all particles + MultiFab::Copy(pvf, AllParticlePVF, 0, 0, 1, pvf.nGrow()); + + spend_time += ParallelDescriptor::second() - UpdateParticlesStart; + ParallelDescriptor::ReduceRealMax(spend_time); + amrex::Print() << "[DIBM] IB and update particle, step : "<< iStep <<", time : " << spend_time << "\n"; + + int particle_write_freq = ParticleProperties::write_freq; + if (iStep % particle_write_freq == 0) { + for(auto kernel: particle_kernels) + WriteIBForceAndMoment(iStep, time, dt, kernel); + } + + if (verbose) mContainer->WriteAsciiFile(amrex::Concatenate("particle", 4)); +} + +void mParticle::DoParticleCollision(int model) +{ + if(particle_kernels.size() < 2 ) return ; + + if (verbose) amrex::Print() << "\tmParticle::DoParticleCollision\n"; + + if(ParallelDescriptor::MyProc() == ParallelDescriptor::IOProcessorNumber()){ + for(const auto& kernel : particle_kernels){ + m_Collision.InsertParticle(kernel.location, kernel.velocity, kernel.radius, kernel.rho); + } + + m_Collision.takeModel(model); + + for(auto & particle_kernel : particle_kernels){ + particle_kernel.Fcp = m_Collision.Particles.front().preForece + * particle_kernel.Vp * particle_kernel.rho * m_gravity.vectorLength(); + m_Collision.Particles.pop_front(); + } + } + for(auto& kernel : particle_kernels){ + ParallelDescriptor::Bcast(kernel.Fcp.dataPtr(), 3, ParallelDescriptor::IOProcessorNumber()); + } +} + +void mParticle::ComputeLagrangianForce(Real dt, + const kernel& kernel) +{ + + if (verbose) amrex::Print() << "\tmParticle::ComputeLagrangianForce\n"; + + Real Ub = kernel.velocity[0]; + Real Vb = kernel.velocity[1]; + Real Wb = kernel.velocity[2]; + Real Px = kernel.location[0]; + Real Py = kernel.location[1]; + Real Pz = kernel.location[2]; + + for(mParIter pti(*mContainer, LOCAL_LEVEL); pti.isValid(); ++pti){ + const Long np = pti.numParticles(); + auto& attri = pti.GetAttribs(); + auto const* p_ptr = pti.GetArrayOfStructs().data(); + + auto* Up = attri[P_ATTR::U_Marker].data(); + auto* Vp = attri[P_ATTR::V_Marker].data(); + auto* Wp = attri[P_ATTR::W_Marker].data(); + auto *FxP = attri[P_ATTR::Fx_Marker].data(); + auto *FyP = attri[P_ATTR::Fy_Marker].data(); + auto *FzP = attri[P_ATTR::Fz_Marker].data(); + + amrex::ParallelFor(np, + [=] AMREX_GPU_DEVICE (int i) noexcept{ + auto Ur = (kernel.omega).crossProduct(RealVect(p_ptr[i].pos(0) - Px, p_ptr[i].pos(1) - Py, p_ptr[i].pos(2) - Pz)); + FxP[i] = (Ub + Ur[0] - Up[i])/dt; // + FyP[i] = (Vb + Ur[1] - Vp[i])/dt; // + FzP[i] = (Wb + Ur[2] - Wp[i])/dt; // + }); + } + if (verbose) mContainer->WriteAsciiFile(amrex::Concatenate("particle", 3)); +} + +void mParticle::VelocityCorrection(amrex::MultiFab &Euler, amrex::MultiFab &EulerForce, Real dt) const +{ + if(verbose) amrex::Print() << "\tmParticle::VelocityCorrection\n"; + MultiFab::Saxpy(Euler, dt, EulerForce, ParticleProperties::euler_force_index, ParticleProperties::euler_velocity_index, 3, 0); //VelocityCorrection +} + +void mParticle::RecordOldValue(kernel& kernel) +{ + kernel.location_old = kernel.location; + kernel.velocity_old = kernel.velocity; + kernel.omega_old = kernel.omega; +} + +void mParticle::WriteParticleFile(int index) +{ + mContainer->WriteAsciiFile(amrex::Concatenate("particle", index)); +} + +void mParticle::WriteIBForceAndMoment(int step, amrex::Real time, amrex::Real dt, kernel& current_kernel) +{ + + if(amrex::ParallelDescriptor::MyProc() != ParallelDescriptor::IOProcessorNumber()) return; + + std::string file("IB_Particle_" + std::to_string(current_kernel.id) + ".csv"); + std::ofstream out_ib_force; + + std::string head; + if(!fs::exists(file)){ + head = "iStep,time,X,Y,Z,Vx,Vy,Vz,Rx,Ry,Rz,Fx,Fy,Fz,Mx,My,Mz,Fcpx,Fcpy,Fcpz,Tcpx,Tcpy,Tcpz,SumUx,SumUy,SumUz,SumTx,SumTy,SumTz\n"; + }else{ + head = ""; + } + + out_ib_force.open(file, std::ios::app); + if(!out_ib_force.is_open()){ + amrex::Print() << "[Particle] write particle file error , step: " << step; + }else{ + out_ib_force << head << step << "," << time << "," + << current_kernel.location[0] << "," << current_kernel.location[1] << "," << current_kernel.location[2] << "," + << current_kernel.velocity[0] << "," << current_kernel.velocity[1] << "," << current_kernel.velocity[2] << "," + << current_kernel.omega[0] << "," << current_kernel.omega[1] << "," << current_kernel.omega[2] << "," + << current_kernel.ib_force[0] << "," << current_kernel.ib_force[1] << "," << current_kernel.ib_force[2] << "," + << current_kernel.ib_moment[0] << "," << current_kernel.ib_moment[1] << "," << current_kernel.ib_moment[2] << "," + << current_kernel.Fcp[0] << "," << current_kernel.Fcp[1] << "," << current_kernel.Fcp[2] << "," + << current_kernel.Tcp[0] << "," << current_kernel.Tcp[1] << "," << current_kernel.Tcp[2] << "," + << (current_kernel.sum_u_new[0] - current_kernel.sum_u_old[0])/dt << "," + << (current_kernel.sum_u_new[1] - current_kernel.sum_u_old[1])/dt << "," + << (current_kernel.sum_u_new[2] - current_kernel.sum_u_old[2])/dt << "," + << (current_kernel.sum_t_new[0] - current_kernel.sum_t_old[0])/dt << "," + << (current_kernel.sum_t_new[1] - current_kernel.sum_t_old[1])/dt << "," + << (current_kernel.sum_t_new[2] - current_kernel.sum_t_old[2])/dt << "\n"; + } + out_ib_force.close(); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Particles member function */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +void Particles::create_particles(const Geometry &gm, + const DistributionMapping & dm, + const BoxArray & ba) +{ + amrex::Print() << "[Particle] : create Particle Container\n"; + if(particle->mContainer != nullptr){ + delete particle->mContainer; + particle->mContainer = nullptr; + } + particle->mContainer = new mParticleContainer(gm, dm, ba); + + //get particle tile + std::pair key{0,0}; + auto& particleTileTmp = particle->mContainer->GetParticles(0)[key]; + //insert markers + if ( ParallelDescriptor::MyProc() == ParallelDescriptor::IOProcessorNumber() ) { + //insert particle's markers + //Real phiK = 0; + for(int marker_index = 0; marker_index < particle->particle_kernels[0].ml; marker_index++){ + //insert code + mParticleContainer::ParticleType markerP; + markerP.id() = marker_index + 1; + markerP.cpu() = ParallelDescriptor::MyProc(); + markerP.pos(0) = particle->particle_kernels[0].location[0]; + markerP.pos(1) = particle->particle_kernels[0].location[1]; + markerP.pos(2) = particle->particle_kernels[0].location[2]; + + std::array Marker_attr; + Marker_attr[U_Marker] = 0.0; + Marker_attr[V_Marker] = 0.0; + Marker_attr[W_Marker] = 0.0; + Marker_attr[Fx_Marker] = 0.0; + Marker_attr[Fy_Marker] = 0.0; + Marker_attr[Fz_Marker] = 0.0; + + particleTileTmp.push_back(markerP); + particleTileTmp.push_back_real(Marker_attr); + } + } + particle->mContainer->Redistribute(); // Still needs to redistribute here! + + ParticleProperties::plo = gm.ProbLoArray(); + ParticleProperties::phi = gm.ProbHiArray(); + ParticleProperties::dx = gm.CellSizeArray(); +} + +mParticle* Particles::get_particles() +{ + return particle; +} + + +void Particles::init_particle(Real gravity, Real h) +{ + amrex::Print() << "[Particle] : create Particle's kernel\n"; + particle = new mParticle; + if(particle != nullptr){ + isInitial = true; + particle->InitParticles( + ParticleProperties::_x, + ParticleProperties::_y, + ParticleProperties::_z, + ParticleProperties::_rho, + ParticleProperties::Vx, + ParticleProperties::Vy, + ParticleProperties::Vz, + ParticleProperties::Ox, + ParticleProperties::Oy, + ParticleProperties::Oz, + ParticleProperties::TLX, + ParticleProperties::TLY, + ParticleProperties::TLZ, + ParticleProperties::RLX, + ParticleProperties::RLY, + ParticleProperties::RLZ, + ParticleProperties::_radius, + h, + gravity, + ParticleProperties::verbose); + } + +} + +void Particles::Restart(Real gravity, Real h, int iStep) +{ + amrex::Print() << "[Particle] : restart Particle's kernel, step :" << iStep << "\n" + << "\tstart read particle csv file , default name is IB_Particle_x.csv\n" + << "\tdo not delete those file before \"restart\"\n\n"; + delete particle; + particle = new mParticle; + particle->InitParticles( + ParticleProperties::_x, + ParticleProperties::_y, + ParticleProperties::_z, + ParticleProperties::_rho, + ParticleProperties::Vx, + ParticleProperties::Vy, + ParticleProperties::Vz, + ParticleProperties::Ox, + ParticleProperties::Oy, + ParticleProperties::Oz, + ParticleProperties::TLX, + ParticleProperties::TLY, + ParticleProperties::TLZ, + ParticleProperties::RLX, + ParticleProperties::RLY, + ParticleProperties::RLZ, + ParticleProperties::_radius, + h, + gravity, + ParticleProperties::verbose); + //deal in IO processor + //start read csv file + for(auto& kernel : particle->particle_kernels){ + //filename + if(amrex::ParallelDescriptor::MyProc() == amrex::ParallelDescriptor::IOProcessorNumber()){ + std::string fileName = "IB_Particle_" + std::to_string(kernel.id) + ".csv"; + std::string tmpfile = "tmp" + fileName; + //file stream + std::ifstream particle_data(fileName); + std::ofstream particle_file(tmpfile); + // open state + if(!particle_data.is_open() || !particle_file.is_open()){ + amrex::Abort("\tCan not open particle file : " + fileName); + } + std::string lineData; + int line{0}; + while(std::getline(particle_data, lineData)){ + line++; + particle_file << lineData << "\n"; + if(line <= iStep) { + continue; + } + //old location + //iStep,time,X,Y,Z,Vx,Vy,Vz,Rx,Ry,Rz,Fx,Fy,Fz,Mx,My,Mz,Fcpx,Fcpy,Fcpz,Tcpx,Tcpy,Tcpz + if(line == iStep + 1){ + std::stringstream ss(lineData); + std::string data; + std::vector dataStruct; + while(std::getline(ss, data, ',')){ + dataStruct.emplace_back(std::stod(data)); + } + kernel.location[0] = dataStruct[2]; + kernel.location[1] = dataStruct[3]; + kernel.location[2] = dataStruct[4]; + kernel.velocity[0] = dataStruct[5]; + kernel.velocity[1] = dataStruct[6]; + kernel.velocity[2] = dataStruct[7]; + kernel.omega[0] = dataStruct[8]; + kernel.omega[1] = dataStruct[9]; + kernel.omega[2] = dataStruct[10]; + + kernel.location_old = kernel.location; + kernel.velocity_old = kernel.velocity; + kernel.omega_old = kernel.omega; + break; + } + else + break; + } + particle_data.close(); + particle_file.close(); + std::remove(fileName.c_str()); + std::rename(tmpfile.c_str(), fileName.c_str()); + } + ParallelDescriptor::Bcast(&kernel.location[0], 3, ParallelDescriptor::IOProcessorNumber()); + ParallelDescriptor::Bcast(&kernel.velocity[0], 3,ParallelDescriptor::IOProcessorNumber()); + ParallelDescriptor::Bcast(&kernel.omega[0], 3,ParallelDescriptor::IOProcessorNumber()); + + ParallelDescriptor::Bcast(&kernel.location_old[0], 3, ParallelDescriptor::IOProcessorNumber()); + ParallelDescriptor::Bcast(&kernel.velocity_old[0], 3,ParallelDescriptor::IOProcessorNumber()); + ParallelDescriptor::Bcast(&kernel.omega_old[0], 3,ParallelDescriptor::IOProcessorNumber()); + } + + isInitial = true; +} + +void Particles::Initialize() +{ + ParmParse pp("particle"); + + std::string particle_inputfile; + std::string particle_init_file; + pp.get("input",particle_inputfile); + + if(!particle_inputfile.empty()){ + ParmParse p_file(particle_inputfile); + p_file.query("init", particle_init_file); + p_file.getarr("x", ParticleProperties::_x); + p_file.getarr("y", ParticleProperties::_y); + p_file.getarr("z", ParticleProperties::_z); + p_file.getarr("rho", ParticleProperties::_rho); + p_file.getarr("velocity_x", ParticleProperties::Vx); + p_file.getarr("velocity_y", ParticleProperties::Vy); + p_file.getarr("velocity_z", ParticleProperties::Vz); + p_file.getarr("omega_x", ParticleProperties::Ox); + p_file.getarr("omega_y", ParticleProperties::Oy); + p_file.getarr("omega_z", ParticleProperties::Oz); + p_file.getarr("TLX", ParticleProperties::TLX); + p_file.getarr("TLY", ParticleProperties::TLY); + p_file.getarr("TLZ", ParticleProperties::TLZ); + p_file.getarr("RLX", ParticleProperties::RLX); + p_file.getarr("RLY", ParticleProperties::RLY); + p_file.getarr("RLZ", ParticleProperties::RLZ); + p_file.getarr("radius", ParticleProperties::_radius); + p_file.query("RD", ParticleProperties::rd); + p_file.query("LOOP_NS", ParticleProperties::loop_ns); + p_file.query("LOOP_SOLID", ParticleProperties::loop_solid); + p_file.query("verbose", ParticleProperties::verbose); + p_file.query("start_step", ParticleProperties::start_step); + p_file.query("Uhlmann", ParticleProperties::Uhlmann); + p_file.query("collision_model", ParticleProperties::collision_model); + p_file.query("write_freq", ParticleProperties::write_freq); + + ParmParse ns("ns"); + ns.get("fluid_rho", ParticleProperties::euler_fluid_rho); + + ParmParse level_parse("amr"); + level_parse.get("max_level", ParticleProperties::euler_finest_level); + + ParmParse geometry_parse("geometry"); + geometry_parse.getarr("prob_lo", ParticleProperties::GLO); + geometry_parse.getarr("prob_hi", ParticleProperties::GHI); + amrex::Print() << "[Particle] : Reading partilces cfg file : " << particle_inputfile << "\n" + << " Particle's level : " << ParticleProperties::euler_finest_level << "\n"; + + if(!particle_init_file.empty()){ + ParticleProperties::init_particle_from_file = true; + //clear particle position container + ParticleProperties::_x.clear(); + ParticleProperties::_y.clear(); + ParticleProperties::_z.clear(); + // parse particle's location data + std::ifstream init_particle(particle_init_file); + std::string line_data; + while(std::getline(init_particle, line_data)){ + // id x_location y_location z_location + std::istringstream line(line_data); + std::vector str_tokne; + std::string token; + while(line >> token){ + str_tokne.push_back(token); + } + + ParticleProperties::_x.push_back(std::stod(str_tokne[0])); + ParticleProperties::_y.push_back(std::stod(str_tokne[1])); + ParticleProperties::_z.push_back(std::stod(str_tokne[2])); + } + ParticleProperties::_x.shrink_to_fit(); + ParticleProperties::_y.shrink_to_fit(); + ParticleProperties::_z.shrink_to_fit(); + amrex::Print() << " initial Particle by file : " << particle_init_file + << " particle's size : " << ParticleProperties::_x.size() << "\n"; + } + + }else { + amrex::Abort("[Particle] : can't read particles settings, pls check your config file \"particle.input\""); + } +} + +int Particles::ParticleFinestLevel() +{ + return ParticleProperties::euler_finest_level; +} diff --git a/Source/Diffusion.H b/Source/Diffusion.H index 58726ef6..8c65b91d 100644 --- a/Source/Diffusion.H +++ b/Source/Diffusion.H @@ -1,268 +1,273 @@ - -#ifndef IAMR_Diffusion_H_ -#define IAMR_Diffusion_H_ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#ifdef AMREX_USE_EB -#include -#include -#else -#include -#include -#endif - - -// -// Useful enumeration of the different forms of the diffusion terms -// -enum DiffusionForm { RhoInverse_Laplacian_S, Laplacian_SoverRho, Laplacian_S }; - -class NavierStokesBase; - -class Diffusion -{ -public: - - Diffusion (); - - Diffusion (amrex::Amr* Parent, - NavierStokesBase* Caller, - Diffusion* coarser, - int num_state, - amrex::FluxRegister* Viscflux_reg, - const amrex::Vector& _is_diffusive); - - void echo_settings () const; - - amrex::FluxRegister* viscFluxReg (); - - static amrex::Real get_scaled_abs_tol (const amrex::MultiFab& rhs, - amrex::Real reduction); - - void diffuse_scalar (const amrex::Vector& S_old, - const amrex::Vector& Rho_old, - amrex::Vector& S_new, - const amrex::Vector& Rho_new, - int S_comp, - int nComp, - int Rho_comp, - amrex::Real prev_time, - amrex::Real curr_time, - amrex::Real be_cn_theta, - const amrex::MultiFab& rho_half, - int rho_flag, - amrex::MultiFab* const* fluxn, - amrex::MultiFab* const* fluxnp1, - int fluxComp, - amrex::MultiFab* delta_rhs, - int rhsComp, - const amrex::MultiFab* alpha, - int alpha_in_comp, - const amrex::MultiFab* const* betan, - const amrex::MultiFab* const* betanp1, - int betaComp, - const amrex::IntVect& cratio, - const amrex::BCRec& bc, - const amrex::Geometry& geom, - bool add_old_time_divFlux = true, - const amrex::Vector& is_diffusive = amrex::Vector()); - - void diffuse_velocity (amrex::Real dt, - amrex::Real be_cn_theta, - const amrex::MultiFab& rho_half, - int rho_flag, - amrex::MultiFab* delta_rhs, - const amrex::MultiFab* const* betan, - const amrex::MultiFab* betanCC, - const amrex::MultiFab* const* betanp1, - const amrex::MultiFab* betanp1CC); - - void diffuse_velocity (amrex::Real dt, - amrex::Real be_cn_theta, - const amrex::MultiFab& rho_half, - int rho_flag, - amrex::MultiFab* delta_rhs, - int rhsComp, - const amrex::MultiFab* const* betan, - const amrex::MultiFab* betanCC, - const amrex::MultiFab* const* betanp1, - const amrex::MultiFab* betanp1CC, - int betaComp); - - void diffuse_tensor_velocity (amrex::Real dt, - amrex::Real be_cn_theta, - const amrex::MultiFab& rho_half, - int rho_flag, - amrex::MultiFab* delta_rhs, - int rhsComp, - const amrex::MultiFab* const* betan, - const amrex::MultiFab* betanCC, - const amrex::MultiFab* const* betanp1, - const amrex::MultiFab* betanp1CC, - int betaComp); - - void diffuse_Vsync (amrex::MultiFab& Vsync, - amrex::Real dt, - amrex::Real be_cn_theta, - const amrex::MultiFab& rho_half, - int rho_flag, - const amrex::MultiFab* const* beta, - int betaComp = 0, - bool update_fluxreg = true); - - void diffuse_tensor_Vsync (amrex::MultiFab& Vsync, - amrex::Real dt, - amrex::Real be_cn_theta, - const amrex::MultiFab& rho_half, - int rho_flag, - const amrex::MultiFab* const* beta, - int betaComp, - bool update_fluxreg); - - - void diffuse_Ssync (amrex::MultiFab& Ssync, - int sigma, - int nComp, - amrex::Real dt, - amrex::Real be_cn_theta, - const amrex::MultiFab& rho_half, - int rho_flag, - amrex::MultiFab* const* flux, - int fluxComp, - const amrex::MultiFab* const* beta, - int betaComp, - const amrex::MultiFab* alpha, - int alphaComp); - - - void getViscTerms (amrex::MultiFab& visc_terms, - int src_comp, - int comp, - amrex::Real time, - int rho_flag, - const amrex::MultiFab* const* beta, - int betaComp); - - - void getTensorViscTerms (amrex::MultiFab& visc_terms, - amrex::Real time, - const amrex::MultiFab* const* beta, - const amrex::MultiFab* betaCC, - int betaComp); - - void FillBoundary (amrex::BndryRegister& bdry, - int state_ind, - int dest_comp, - int num_comp, - amrex::Real time, - int rho_flag); - - static void checkBeta (const amrex::MultiFab* const* beta, - int& allthere, - int& allnull); - - static void checkBeta (const amrex::MultiFab* const* beta, - int& allthere); - - [[nodiscard]] static int maxOrder (); - [[nodiscard]] static int tensorMaxOrder (); - - static int set_rho_flag (DiffusionForm compDiffusionType); - - static void setDomainBC (std::array& mlmg_lobc, - std::array& mlmg_hibc, - const amrex::BCRec& bc); - - static void computeAlpha (amrex::MultiFab& alpha, - std::pair& scalars, - amrex::Real a, - amrex::Real b, - amrex::Real* rhsscale, - const amrex::MultiFab* alpha_in, - int alpha_in_comp, - int rho_flag, - const amrex::MultiFab* rho, - int rho_comp); - -#ifdef AMREX_USE_EB - static void setBeta(amrex::MLEBABecLap& op, - const amrex::MultiFab* const* beta, - int betaComp, - int nComp = 1); - - static void setViscosity(amrex::MLEBTensorOp& tensorop, - const amrex::MultiFab* const* beta, - int betaComp, - const amrex::MultiFab& beta_cc); -#else - static void setBeta(amrex::MLABecLaplacian& op, - const amrex::MultiFab* const* beta, - int betaComp, - int nComp = 1); - - static void setViscosity(amrex::MLTensorOp& tensorop, - const amrex::MultiFab* const* beta, - int betaComp); -#endif - - static void computeExtensiveFluxes(amrex::MLMG& a_mg, - amrex::MultiFab& Soln, - amrex::MultiFab* const* flux, - int fluxComp, - int ncomp, - amrex::MultiFab* area, - amrex::Real fac ); - -protected: - - void setDomainBC (std::array& mlmg_lobc, - std::array& mlmg_hibc, - int src_comp); - - - static void Finalize (); - // - // Data Required by Derived Classes - // - amrex::Amr* parent; - NavierStokesBase* navier_stokes; - const amrex::BoxArray& grids; - const amrex::DistributionMapping& dmap; - const int level; - // - // Static data. - // - static int scale_abec; - static amrex::Vector is_diffusive; // Does variable diffuse? - static int verbose; - static amrex::Real visc_tol; - -private: - // - // The data. - // - Diffusion* coarser; - Diffusion* finer; - int NUM_STATE; - amrex::IntVect crse_ratio; - amrex::FluxRegister* viscflux_reg; - // - // Static data. - // - static int do_reflux; - static int max_order; - static int tensor_max_order; -}; - -#endif +/* + * SPDX-FileCopyrightText: 1997 - 2023 Berkeley Lab + * + * SPDX-License-Identifier: LicenseRef-OpenSource + */ + +#ifndef IAMR_Diffusion_H_ +#define IAMR_Diffusion_H_ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#ifdef AMREX_USE_EB +#include +#include +#else +#include +#include +#endif + + +// +// Useful enumeration of the different forms of the diffusion terms +// +enum DiffusionForm { RhoInverse_Laplacian_S, Laplacian_SoverRho, Laplacian_S }; + +class NavierStokesBase; + +class Diffusion +{ +public: + + Diffusion (); + + Diffusion (amrex::Amr* Parent, + NavierStokesBase* Caller, + Diffusion* coarser, + int num_state, + amrex::FluxRegister* Viscflux_reg, + const amrex::Vector& _is_diffusive); + + void echo_settings () const; + + amrex::FluxRegister* viscFluxReg (); + + static amrex::Real get_scaled_abs_tol (const amrex::MultiFab& rhs, + amrex::Real reduction); + + void diffuse_scalar (const amrex::Vector& S_old, + const amrex::Vector& Rho_old, + amrex::Vector& S_new, + const amrex::Vector& Rho_new, + int S_comp, + int nComp, + int Rho_comp, + amrex::Real prev_time, + amrex::Real curr_time, + amrex::Real be_cn_theta, + const amrex::MultiFab& rho_half, + int rho_flag, + amrex::MultiFab* const* fluxn, + amrex::MultiFab* const* fluxnp1, + int fluxComp, + amrex::MultiFab* delta_rhs, + int rhsComp, + const amrex::MultiFab* alpha, + int alpha_in_comp, + const amrex::MultiFab* const* betan, + const amrex::MultiFab* const* betanp1, + int betaComp, + const amrex::IntVect& cratio, + const amrex::BCRec& bc, + const amrex::Geometry& geom, + bool add_old_time_divFlux = true, + const amrex::Vector& is_diffusive = amrex::Vector()); + + void diffuse_velocity (amrex::Real dt, + amrex::Real be_cn_theta, + const amrex::MultiFab& rho_half, + int rho_flag, + amrex::MultiFab* delta_rhs, + const amrex::MultiFab* const* betan, + const amrex::MultiFab* betanCC, + const amrex::MultiFab* const* betanp1, + const amrex::MultiFab* betanp1CC); + + void diffuse_velocity (amrex::Real dt, + amrex::Real be_cn_theta, + const amrex::MultiFab& rho_half, + int rho_flag, + amrex::MultiFab* delta_rhs, + int rhsComp, + const amrex::MultiFab* const* betan, + const amrex::MultiFab* betanCC, + const amrex::MultiFab* const* betanp1, + const amrex::MultiFab* betanp1CC, + int betaComp); + + void diffuse_tensor_velocity (amrex::Real dt, + amrex::Real be_cn_theta, + const amrex::MultiFab& rho_half, + int rho_flag, + amrex::MultiFab* delta_rhs, + int rhsComp, + const amrex::MultiFab* const* betan, + const amrex::MultiFab* betanCC, + const amrex::MultiFab* const* betanp1, + const amrex::MultiFab* betanp1CC, + int betaComp); + + void diffuse_Vsync (amrex::MultiFab& Vsync, + amrex::Real dt, + amrex::Real be_cn_theta, + const amrex::MultiFab& rho_half, + int rho_flag, + const amrex::MultiFab* const* beta, + int betaComp = 0, + bool update_fluxreg = true); + + void diffuse_tensor_Vsync (amrex::MultiFab& Vsync, + amrex::Real dt, + amrex::Real be_cn_theta, + const amrex::MultiFab& rho_half, + int rho_flag, + const amrex::MultiFab* const* beta, + int betaComp, + bool update_fluxreg); + + + void diffuse_Ssync (amrex::MultiFab& Ssync, + int sigma, + int nComp, + amrex::Real dt, + amrex::Real be_cn_theta, + const amrex::MultiFab& rho_half, + int rho_flag, + amrex::MultiFab* const* flux, + int fluxComp, + const amrex::MultiFab* const* beta, + int betaComp, + const amrex::MultiFab* alpha, + int alphaComp); + + + void getViscTerms (amrex::MultiFab& visc_terms, + int src_comp, + int comp, + amrex::Real time, + int rho_flag, + const amrex::MultiFab* const* beta, + int betaComp); + + + void getTensorViscTerms (amrex::MultiFab& visc_terms, + amrex::Real time, + const amrex::MultiFab* const* beta, + const amrex::MultiFab* betaCC, + int betaComp); + + void FillBoundary (amrex::BndryRegister& bdry, + int state_ind, + int dest_comp, + int num_comp, + amrex::Real time, + int rho_flag); + + static void checkBeta (const amrex::MultiFab* const* beta, + int& allthere, + int& allnull); + + static void checkBeta (const amrex::MultiFab* const* beta, + int& allthere); + + [[nodiscard]] static int maxOrder (); + [[nodiscard]] static int tensorMaxOrder (); + + static int set_rho_flag (DiffusionForm compDiffusionType); + + static void setDomainBC (std::array& mlmg_lobc, + std::array& mlmg_hibc, + const amrex::BCRec& bc); + + static void computeAlpha (amrex::MultiFab& alpha, + std::pair& scalars, + amrex::Real a, + amrex::Real b, + amrex::Real* rhsscale, + const amrex::MultiFab* alpha_in, + int alpha_in_comp, + int rho_flag, + const amrex::MultiFab* rho, + int rho_comp); + +#ifdef AMREX_USE_EB + static void setBeta(amrex::MLEBABecLap& op, + const amrex::MultiFab* const* beta, + int betaComp, + int nComp = 1); + + static void setViscosity(amrex::MLEBTensorOp& tensorop, + const amrex::MultiFab* const* beta, + int betaComp, + const amrex::MultiFab& beta_cc); +#else + static void setBeta(amrex::MLABecLaplacian& op, + const amrex::MultiFab* const* beta, + int betaComp, + int nComp = 1); + + static void setViscosity(amrex::MLTensorOp& tensorop, + const amrex::MultiFab* const* beta, + int betaComp); +#endif + + static void computeExtensiveFluxes(amrex::MLMG& a_mg, + amrex::MultiFab& Soln, + amrex::MultiFab* const* flux, + int fluxComp, + int ncomp, + amrex::MultiFab* area, + amrex::Real fac ); + +protected: + + void setDomainBC (std::array& mlmg_lobc, + std::array& mlmg_hibc, + int src_comp); + + + static void Finalize (); + // + // Data Required by Derived Classes + // + amrex::Amr* parent; + NavierStokesBase* navier_stokes; + const amrex::BoxArray& grids; + const amrex::DistributionMapping& dmap; + const int level; + // + // Static data. + // + static int scale_abec; + static amrex::Vector is_diffusive; // Does variable diffuse? + static int verbose; + static amrex::Real visc_tol; + +private: + // + // The data. + // + Diffusion* coarser; + Diffusion* finer; + int NUM_STATE; + amrex::IntVect crse_ratio; + amrex::FluxRegister* viscflux_reg; + // + // Static data. + // + static int do_reflux; + static int max_order; + static int tensor_max_order; +}; + +#endif diff --git a/Source/Diffusion.cpp b/Source/Diffusion.cpp index c651b02b..533bcfb9 100644 --- a/Source/Diffusion.cpp +++ b/Source/Diffusion.cpp @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 1997 - 2023 Berkeley Lab +// +// SPDX-License-Identifier: LicenseRef-OpenSource + #include #include #include diff --git a/Source/EBUserDefined.H b/Source/EBUserDefined.H index 45a10ce1..2384e2b6 100644 --- a/Source/EBUserDefined.H +++ b/Source/EBUserDefined.H @@ -1,27 +1,33 @@ -#ifndef IAMR_EBUSERDEFINED_H_ -#define IAMR_EBUSERDEFINED_H_ - -using namespace amrex; - -#ifdef AMREX_USE_EB -#include -#include -void -EBUserDefined(const Geometry& /*geom*/, - const int /*required_coarsening_level*/, - const int /*max_coarsening_level*/) -{ - // ParmParse your geometry parameters - - // Build geometry pieces using EB2::* methods - - // Build your geometry shop using EB2::makeShop - - // Build geom using EB2::Build - - // We shoulnd't be here, copy this file in your run folder - // and implement your geometry - Abort("In default EBUserDefined function! Shouldn't be here. Copy and edit this file for your needs"); -} -#endif -#endif +/* + * SPDX-FileCopyrightText: 2021 - 2023 Berkeley Lab + * + * SPDX-License-Identifier: LicenseRef-OpenSource + */ + +#ifndef IAMR_EBUSERDEFINED_H_ +#define IAMR_EBUSERDEFINED_H_ + +using namespace amrex; + +#ifdef AMREX_USE_EB +#include +#include +void +EBUserDefined(const Geometry& /*geom*/, + const int /*required_coarsening_level*/, + const int /*max_coarsening_level*/) +{ + // ParmParse your geometry parameters + + // Build geometry pieces using EB2::* methods + + // Build your geometry shop using EB2::makeShop + + // Build geom using EB2::Build + + // We shoulnd't be here, copy this file in your run folder + // and implement your geometry + Abort("In default EBUserDefined function! Shouldn't be here. Copy and edit this file for your needs"); +} +#endif +#endif diff --git a/Source/FluxBoxes.H b/Source/FluxBoxes.H index 966c381e..c00e0afa 100644 --- a/Source/FluxBoxes.H +++ b/Source/FluxBoxes.H @@ -1,34 +1,40 @@ -#ifndef IAMR_FLUXBOXES_H_ -#define IAMR_FLUXBOXES_H_ - -#include - -class FluxBoxes -{ -public: - - FluxBoxes () = default; - - explicit FluxBoxes (const amrex::AmrLevel* amr_level, int nvar=1, int nghost=0) - { define(amr_level, nvar, nghost); } - - ~FluxBoxes () { clear(); } - - FluxBoxes (FluxBoxes const&) = delete; - FluxBoxes (FluxBoxes &&) = delete; - FluxBoxes& operator= (FluxBoxes const&) = delete; - FluxBoxes& operator= (FluxBoxes &&) = delete; - - amrex::MultiFab** define (const amrex::AmrLevel* amr_level, int nvar=1, int nghost=0); - - void clear (); - - amrex::MultiFab** get () {return data;} - -private: - - amrex::MultiFab** data = nullptr; - -}; - -#endif +/* + * SPDX-FileCopyrightText: 2016 - 2023 Berkeley Lab + * + * SPDX-License-Identifier: LicenseRef-OpenSource + */ + +#ifndef IAMR_FLUXBOXES_H_ +#define IAMR_FLUXBOXES_H_ + +#include + +class FluxBoxes +{ +public: + + FluxBoxes () = default; + + explicit FluxBoxes (const amrex::AmrLevel* amr_level, int nvar=1, int nghost=0) + { define(amr_level, nvar, nghost); } + + ~FluxBoxes () { clear(); } + + FluxBoxes (FluxBoxes const&) = delete; + FluxBoxes (FluxBoxes &&) = delete; + FluxBoxes& operator= (FluxBoxes const&) = delete; + FluxBoxes& operator= (FluxBoxes &&) = delete; + + amrex::MultiFab** define (const amrex::AmrLevel* amr_level, int nvar=1, int nghost=0); + + void clear (); + + amrex::MultiFab** get () {return data;} + +private: + + amrex::MultiFab** data = nullptr; + +}; + +#endif diff --git a/Source/FluxBoxes.cpp b/Source/FluxBoxes.cpp index 31cf2bf1..956dacdb 100644 --- a/Source/FluxBoxes.cpp +++ b/Source/FluxBoxes.cpp @@ -1,30 +1,34 @@ -#include - -using namespace amrex; - -MultiFab** -FluxBoxes::define (const AmrLevel* amr_level, int nvar, int nghost) -{ - AMREX_ASSERT(data == nullptr); - data = new MultiFab*[AMREX_SPACEDIM]; - for (int dir = 0; dir < AMREX_SPACEDIM; dir++) - { - const BoxArray& ba = amr_level->getEdgeBoxArray(dir); - const DistributionMapping& dm = amr_level->DistributionMap(); - data[dir] = new MultiFab(ba,dm,nvar,nghost,MFInfo(),amr_level->Factory()); - } - return data; -} - -void -FluxBoxes::clear () -{ - if (data != nullptr) - { - for (int i = 0; i + +using namespace amrex; + +MultiFab** +FluxBoxes::define (const AmrLevel* amr_level, int nvar, int nghost) +{ + AMREX_ASSERT(data == nullptr); + data = new MultiFab*[AMREX_SPACEDIM]; + for (int dir = 0; dir < AMREX_SPACEDIM; dir++) + { + const BoxArray& ba = amr_level->getEdgeBoxArray(dir); + const DistributionMapping& dm = amr_level->DistributionMap(); + data[dir] = new MultiFab(ba,dm,nvar,nghost,MFInfo(),amr_level->Factory()); + } + return data; +} + +void +FluxBoxes::clear () +{ + if (data != nullptr) + { + for (int i = 0; i -#include -#include -#include -#include -#ifdef AMREX_USE_EB -#include -#endif - -// -// A useful enumeration of the forms for the advective terms -// -enum AdvectionForm {Conservative = 0, NonConservative}; - -class MacProj -{ -public: - - MacProj (amrex::Amr* parent, - int _finest_level, - amrex::BCRec* _phys_bc, - int /*not used*/ ); - - void install_level (int level, - amrex::AmrLevel* level_data); - - void setup (int level); - void cleanup (int level); - // - // The level advance mac projection. - // - void mac_project (int level, - amrex::MultiFab* u_mac, - amrex::MultiFab& S, - amrex::Real dt, - amrex::Real prev_time, - const amrex::MultiFab& divu, - int have_divu, - const amrex::BCRec& density_math_bc, - bool increment_vel_register = true ); - - // - // The sync solve. - // - void mac_sync_solve (int level, - amrex::Real dt, - amrex::MultiFab& rho_half, - const amrex::BCRec& rho_math_bc, - amrex::IntVect& fine_ratio, - amrex::Array& Ucorr, - amrex::MultiFab* Rhs_increment = nullptr); - - // - // Computing the sync tendency. - // - void mac_sync_compute (int level, - amrex::Array& Ucorr, - amrex::MultiFab& Vsync, - amrex::MultiFab& Ssync, - amrex::Vector& advectionType, - amrex::Real prev_time, - amrex::Real dt, - int num_state_comps, - amrex::Real be_cn_theta, - int do_mom_diff, - bool update_fluxreg = true); - - void mac_sync_compute (int level, - amrex::Array& Ucorr, - amrex::MultiFab& Sync, - int comp, - int Sync_indx, - amrex::MultiFab* const* edgestate, - int edge_comp, - amrex::Real dt, - bool update_fluxreg = true); - - static void mlmg_mac_solve (amrex::Amr* parent, const amrex::MultiFab* cphi, - const amrex::BCRec& phys_bc, - const amrex::BCRec& density_math_bc, - int level, amrex::Real mac_tol, amrex::Real mac_abs_tol, - amrex::Real rhs_scale, - const amrex::MultiFab &rho, const amrex::MultiFab &Rhs, - amrex::Array& u_mac, - amrex::MultiFab *mac_phi, - amrex::Array& fluxes); - - static void set_mac_solve_bc (amrex::Array& mlmg_lobc, - amrex::Array& mlmg_hibc, - const amrex::BCRec& phys_bc, const amrex::Geometry& geom); - - static void Initialize (); - static void Finalize (); - - void test_umac_periodic (int level, amrex::MultiFab* u_mac) const; - - // - // Test the divergence constraint. - // - void check_div_cond (int level, - amrex::MultiFab U_edge[]) const; - // - // Boundary conditions. - // - void set_outflow_bcs (int level, - amrex::MultiFab* mac_phi, - const amrex::MultiFab* u_mac, - const amrex::MultiFab& S, - const amrex::MultiFab& divu); - // - // Pointers to amr,amrlevel. - // - amrex::Amr* parent; - amrex::Vector LevelData; - // - // Boundary condition objects. - // - amrex::BCRec* phys_bc; - // - // MAC sync correction and solution. - // - amrex::Vector > mac_phi_crse; - amrex::Vector > mac_reg; - // - // Parameters. - // - int finest_level; - int finest_level_allocated; - - static int verbose; - static int do_outflow_bcs; - static amrex::Real mac_tol; - static amrex::Real mac_abs_tol; - static amrex::Real mac_sync_tol; - static int check_umac_periodicity; - static int fix_mac_sync_rhs; - - // - // Options for MacProjector - // NOTE: IAMR uses a different max_order default than amrex::MacProjector, - // which uses a default of 3 - // - static int max_order; - static int agglomeration; - static int consolidation; - static int max_fmg_iter; - -}; - -#endif +/* + * SPDX-FileCopyrightText: 1997 - 2023 Berkeley Lab; 2023 - 2025 Yadong Zeng + * + * SPDX-License-Identifier: LicenseRef-OpenSource + * Modified from IAMR, originally developed at Lawrence Berkeley National Lab. + * Original source: https://github.com/AMReX-Fluids/IAMR + */ + +#ifndef IAMR_MacProj_H_ +#define IAMR_MacProj_H_ + +#include +#include +#include +#include +#include +#ifdef AMREX_USE_EB +#include +#endif + +// +// A useful enumeration of the forms for the advective terms +// +enum AdvectionForm {Conservative = 0, NonConservative}; + +class MacProj +{ +public: + + MacProj (amrex::Amr* parent, + int _finest_level, + amrex::BCRec* _phys_bc, + int /*not used*/ ); + + void install_level (int level, + amrex::AmrLevel* level_data); + + void setup (int level); + void cleanup (int level); + // + // The level advance mac projection. + // + void mac_project (int level, + amrex::MultiFab* u_mac, + amrex::MultiFab& S, + amrex::Real dt, + amrex::Real prev_time, + const amrex::MultiFab& divu, + int have_divu, + const amrex::BCRec& density_math_bc, + bool increment_vel_register = true ); + + // + // The sync solve. + // + void mac_sync_solve (int level, + amrex::Real dt, + amrex::MultiFab& rho_half, + const amrex::BCRec& rho_math_bc, + amrex::IntVect& fine_ratio, + amrex::Array& Ucorr, + amrex::MultiFab* Rhs_increment = nullptr); + + // + // Computing the sync tendency. + // + void mac_sync_compute (int level, + amrex::Array& Ucorr, + amrex::MultiFab& Vsync, + amrex::MultiFab& Ssync, + amrex::Vector& advectionType, + amrex::Real prev_time, + amrex::Real dt, + int num_state_comps, + amrex::Real be_cn_theta, + int do_mom_diff, + bool update_fluxreg = true); + + void mac_sync_compute (int level, + amrex::Array& Ucorr, + amrex::MultiFab& Sync, + int comp, + int Sync_indx, + amrex::MultiFab* const* edgestate, + int edge_comp, + amrex::Real dt, + bool update_fluxreg = true); + + static void mlmg_mac_solve (amrex::Amr* parent, const amrex::MultiFab* cphi, + const amrex::BCRec& phys_bc, + const amrex::BCRec& density_math_bc, + int level, amrex::Real mac_tol, amrex::Real mac_abs_tol, + amrex::Real rhs_scale, + const amrex::MultiFab &rho, const amrex::MultiFab &Rhs, + amrex::Array& u_mac, + amrex::MultiFab *mac_phi, + amrex::Array& fluxes); + + static void set_mac_solve_bc (amrex::Array& mlmg_lobc, + amrex::Array& mlmg_hibc, + const amrex::BCRec& phys_bc, const amrex::Geometry& geom); + + static void Initialize (); + static void Finalize (); + + void test_umac_periodic (int level, amrex::MultiFab* u_mac) const; + + // + // Test the divergence constraint. + // + void check_div_cond (int level, + amrex::MultiFab U_edge[]) const; + // + // Boundary conditions. + // + void set_outflow_bcs (int level, + amrex::MultiFab* mac_phi, + const amrex::MultiFab* u_mac, + const amrex::MultiFab& S, + const amrex::MultiFab& divu); + // + // Pointers to amr,amrlevel. + // + amrex::Amr* parent; + amrex::Vector LevelData; + // + // Boundary condition objects. + // + amrex::BCRec* phys_bc; + // + // MAC sync correction and solution. + // + amrex::Vector > mac_phi_crse; + amrex::Vector > mac_reg; + // + // Parameters. + // + int finest_level; + int finest_level_allocated; + + static int verbose; + static int do_outflow_bcs; + static amrex::Real mac_tol; + static amrex::Real mac_abs_tol; + static amrex::Real mac_sync_tol; + static int check_umac_periodicity; + static int fix_mac_sync_rhs; + + // + // Options for MacProjector + // NOTE: IAMR uses a different max_order default than amrex::MacProjector, + // which uses a default of 3 + // + static int max_order; + static int agglomeration; + static int consolidation; + static int max_fmg_iter; + +}; + +#endif diff --git a/Source/MacProj.cpp b/Source/MacProj.cpp index 2c7e5447..32768af9 100644 --- a/Source/MacProj.cpp +++ b/Source/MacProj.cpp @@ -1,3 +1,8 @@ +// SPDX-FileCopyrightText: 1997 - 2023 Berkeley Lab; 2023 - 2025 Yadong Zeng +// +// SPDX-License-Identifier: LicenseRef-OpenSource +// Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +// Original source: https://github.com/AMReX-Fluids/IAMR #include #include diff --git a/Source/Make.package b/Source/Make.package index d1334cb2..ef505c82 100644 --- a/Source/Make.package +++ b/Source/Make.package @@ -1,52 +1,52 @@ - -CEXE_sources += main.cpp SyncRegister.cpp NS_init_eb2.cpp - -ifneq ($(SKIP_NS_SPECIFIC_CODE), TRUE) - # - # These files contain routines that may be overridden by code that - # inherits from NavierStokes. They should only be included if they - # aren't implemented by inherited code. In particular, LMC has its own - # implementation of these routines. - # - CEXE_sources += NS_error.cpp NS_setup.cpp NSBld.cpp NavierStokes.cpp - CEXE_headers += NavierStokes.H NS_bcfill.H - -endif - -CEXE_sources += NS_getForce.cpp - -CEXE_sources += OutFlowBC.cpp - -CEXE_sources += FluxBoxes.cpp - -CEXE_headers += OutFlowBC.H - -CEXE_headers += SyncRegister.H RegType.H - -CEXE_headers += iamr_constants.H - -CEXE_sources += NavierStokesBase.cpp Projection.cpp MacProj.cpp Diffusion.cpp - -CEXE_sources += NS_LES.cpp - -CEXE_sources += NS_derive.cpp NS_average.cpp -CEXE_headers += NS_derive.H - -CEXE_headers += Projection.H MacProj.H Diffusion.H NavierStokesBase.H FluxBoxes.H EBUserDefined.H - -CEXE_sources += NS_util.cpp -CEXE_headers += NS_util.H - -CEXE_sources += NS_kernels.cpp -CEXE_headers += NS_kernels.H - -CEXE_sources += NS_LS.cpp -CEXE_headers += NS_LS.H - -ifeq ($(USE_PARTICLES), TRUE) - CEXE_sources += DiffusedIB.cpp - CEXE_headers += DiffusedIB.H - - CEXE_sources += Collision.cpp - CEXE_headers += Collision.H + +CEXE_sources += main.cpp SyncRegister.cpp NS_init_eb2.cpp + +ifneq ($(SKIP_NS_SPECIFIC_CODE), TRUE) + # + # These files contain routines that may be overridden by code that + # inherits from NavierStokes. They should only be included if they + # aren't implemented by inherited code. In particular, LMC has its own + # implementation of these routines. + # + CEXE_sources += NS_error.cpp NS_setup.cpp NSBld.cpp NavierStokes.cpp + CEXE_headers += NavierStokes.H NS_bcfill.H + +endif + +CEXE_sources += NS_getForce.cpp + +CEXE_sources += OutFlowBC.cpp + +CEXE_sources += FluxBoxes.cpp + +CEXE_headers += OutFlowBC.H + +CEXE_headers += SyncRegister.H RegType.H + +CEXE_headers += iamr_constants.H + +CEXE_sources += NavierStokesBase.cpp Projection.cpp MacProj.cpp Diffusion.cpp + +CEXE_sources += NS_LES.cpp + +CEXE_sources += NS_derive.cpp NS_average.cpp +CEXE_headers += NS_derive.H + +CEXE_headers += Projection.H MacProj.H Diffusion.H NavierStokesBase.H FluxBoxes.H EBUserDefined.H + +CEXE_sources += NS_util.cpp +CEXE_headers += NS_util.H + +CEXE_sources += NS_kernels.cpp +CEXE_headers += NS_kernels.H + +CEXE_sources += NS_LS.cpp +CEXE_headers += NS_LS.H + +ifeq ($(USE_PARTICLES), TRUE) + CEXE_sources += DiffusedIB.cpp + CEXE_headers += DiffusedIB.H + + CEXE_sources += Collision.cpp + CEXE_headers += Collision.H endif \ No newline at end of file diff --git a/Source/NSB_K.H b/Source/NSB_K.H index 1b2efd3b..65fc7923 100644 --- a/Source/NSB_K.H +++ b/Source/NSB_K.H @@ -1,29 +1,35 @@ -#ifndef NSB_K_H_ -#define NSB_K_H_ - -#include -#include -#include - - -AMREX_GPU_HOST_DEVICE -inline -void -set_body_state_k(int i, int j, int k, - int ncomp, - amrex::Real const b [], - int bval, - amrex::Array4 const& mask, - amrex::Array4 const& state) noexcept -{ - using namespace amrex::literals; - - if ( mask(i,j,k) == bval ) { - for (int n = 0; n < ncomp; n++) { - state(i,j,k,n) = b[n]; - } - } - -} - -#endif +/* + * SPDX-FileCopyrightText: 2020 - 2023 Berkeley Lab + * + * SPDX-License-Identifier: LicenseRef-OpenSource + */ + +#ifndef NSB_K_H_ +#define NSB_K_H_ + +#include +#include +#include + + +AMREX_GPU_HOST_DEVICE +inline +void +set_body_state_k(int i, int j, int k, + int ncomp, + amrex::Real const b [], + int bval, + amrex::Array4 const& mask, + amrex::Array4 const& state) noexcept +{ + using namespace amrex::literals; + + if ( mask(i,j,k) == bval ) { + for (int n = 0; n < ncomp; n++) { + state(i,j,k,n) = b[n]; + } + } + +} + +#endif diff --git a/Source/NSBld.cpp b/Source/NSBld.cpp index 31306af0..fd87b27a 100644 --- a/Source/NSBld.cpp +++ b/Source/NSBld.cpp @@ -1,45 +1,47 @@ - - -#include - -using namespace amrex; - -// -------------------------------------------------------------------- -// ----- NSBld class instantiation -// -------------------------------------------------------------------- - -NSBld nsbld; - -LevelBld* getLevelBld() -{ - return &nsbld; -} - -// -------------------------------------------------------------------- -// ----- NSBld class implementation -// -------------------------------------------------------------------- - -void -NSBld::variableSetUp() -{ - NavierStokes::variableSetUp(); -} - -void -NSBld::variableCleanUp() -{ - NavierStokes::variableCleanUp(); -} - -AmrLevel* -NSBld::operator()() -{ - return new NavierStokes; -} - -AmrLevel* -NSBld::operator()(Amr &papa, int lev, const Geometry &level_geom, - const BoxArray &ba, const DistributionMapping& dm, Real time) -{ - return new NavierStokes(papa, lev, level_geom, ba, dm, time); -} +// SPDX-FileCopyrightText: 1997 - 2023 Berkeley Lab +// +// SPDX-License-Identifier: LicenseRef-OpenSource + +#include + +using namespace amrex; + +// -------------------------------------------------------------------- +// ----- NSBld class instantiation +// -------------------------------------------------------------------- + +NSBld nsbld; + +LevelBld* getLevelBld() +{ + return &nsbld; +} + +// -------------------------------------------------------------------- +// ----- NSBld class implementation +// -------------------------------------------------------------------- + +void +NSBld::variableSetUp() +{ + NavierStokes::variableSetUp(); +} + +void +NSBld::variableCleanUp() +{ + NavierStokes::variableCleanUp(); +} + +AmrLevel* +NSBld::operator()() +{ + return new NavierStokes; +} + +AmrLevel* +NSBld::operator()(Amr &papa, int lev, const Geometry &level_geom, + const BoxArray &ba, const DistributionMapping& dm, Real time) +{ + return new NavierStokes(papa, lev, level_geom, ba, dm, time); +} diff --git a/Source/NS_BC.H b/Source/NS_BC.H index b3681e42..370d435b 100644 --- a/Source/NS_BC.H +++ b/Source/NS_BC.H @@ -1,3 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2010 - 2023 Berkeley Lab; 2023 - 2025 Yadong Zeng + * + * SPDX-License-Identifier: LicenseRef-OpenSource + * Modified from IAMR, originally developed at Lawrence Berkeley National Lab. + * Original source: https://github.com/AMReX-Fluids/IAMR + */ + #include #include diff --git a/Source/NS_LES.cpp b/Source/NS_LES.cpp index 3c48a0f4..9094d53f 100644 --- a/Source/NS_LES.cpp +++ b/Source/NS_LES.cpp @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng +// +// SPDX-License-Identifier: BSD-3-Clause + #include #include diff --git a/Source/NS_LS.H b/Source/NS_LS.H index b0892afa..9f0068dd 100644 --- a/Source/NS_LS.H +++ b/Source/NS_LS.H @@ -1,22 +1,27 @@ - -#ifndef NS_LS_H -#define NS_LS_H - -#include - -using namespace amrex; - -void phi_to_heavi(const Geometry& geom, int epsilon, MultiFab& phi, MultiFab& heaviside); -void heavi_to_rhoormu(MultiFab& heaviside, Real var1, Real var2, MultiFab& outmf); - -Real calculate_eps (const Geometry& geom, int epsilon); -Real calculate_eps_one (const Geometry& geom, int reinit_levelset); -Real calculate_eps_two (const Geometry& geom, int reinit_levelset); -void levelset_diffcomp (Array,AMREX_SPACEDIM>& phi_cc_grad, - MultiFab& phi_ctime, - MultiFab& phi1, - MultiFab& phi2, - int epsG1, - int epsG2); - -#endif +/* + * SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef NS_LS_H +#define NS_LS_H + +#include + +using namespace amrex; + +void phi_to_heavi(const Geometry& geom, int epsilon, MultiFab& phi, MultiFab& heaviside); +void heavi_to_rhoormu(MultiFab& heaviside, Real var1, Real var2, MultiFab& outmf); + +Real calculate_eps (const Geometry& geom, int epsilon); +Real calculate_eps_one (const Geometry& geom, int reinit_levelset); +Real calculate_eps_two (const Geometry& geom, int reinit_levelset); +void levelset_diffcomp (Array,AMREX_SPACEDIM>& phi_cc_grad, + MultiFab& phi_ctime, + MultiFab& phi1, + MultiFab& phi2, + int epsG1, + int epsG2); + +#endif diff --git a/Source/NS_LS.cpp b/Source/NS_LS.cpp index c910a15b..68947c34 100644 --- a/Source/NS_LS.cpp +++ b/Source/NS_LS.cpp @@ -1,159 +1,162 @@ - -#include - -#include -#include -#include -#include -#include -#include -#include - -using namespace amrex; - -// ls related - -Real calculate_eps (const Geometry& geom, int epsilon) -{ - const Real* dx = geom.CellSize(); - Real dxmin = dx[0]; - for (int d=1; d eps) { - heavifab(i,j,k) = 1.0; - } else if (phifab(i,j,k) > -eps) { - heavifab(i,j,k) = 0.5 * (1.0 + phifab(i,j,k) / eps + 1.0 / pi * std::sin(phifab(i,j,k) * pi / eps)); - } else { - heavifab(i,j,k) = 0.0; - } - - }); - } -} - -void -heavi_to_rhoormu(MultiFab& heaviside, Real var1, Real var2, MultiFab& outmf) -{ - - amrex::Print() << "In the heavi_to_rhomu " << std::endl; - - BL_ASSERT(heaviside.nComp() == outmf.nComp()); - - int ncomp = outmf.nComp(); - int ngrow = outmf.nGrow(); - - // build heaviside_temp because we might need to smooth the heaviside function - MultiFab heaviside_temp(heaviside.boxArray(), heaviside.DistributionMap(), ncomp, ngrow); - MultiFab::Copy(heaviside_temp, heaviside, 0, 0, ncomp, ngrow); - - // if( smoothforrhomu==1 && (parent->levelSteps(0)%lev0step_of_smoothforrhomu == 0) ){ - // smooth_sf(heaviside_temp); - // } - - heaviside_temp.mult(var1-var2, 0, ncomp, ngrow); - - MultiFab rtmp(heaviside.boxArray(), heaviside.DistributionMap(), ncomp, ngrow); - rtmp.setVal(var2, 0, ncomp, ngrow); - - MultiFab::Add(heaviside_temp, rtmp, 0, 0, ncomp, ngrow); - MultiFab::Copy(outmf, heaviside_temp, 0, 0, ncomp, ngrow); - -} - -Real calculate_eps_one (const Geometry& geom, int reinit_levelset) -{ - - Print() << "In the calculate_eps_one " << std::endl; - - Real eps_one = 0.0; - - const Real* dx = geom.CellSize(); - Real dxmax = dx[0]; - for (int d=1; d,AMREX_SPACEDIM>& phi_cc_grad, - MultiFab& phi_ctime, - MultiFab& phi1, - MultiFab& phi2, - int epsG, - int epsG2) -{ - - Print() << "In the levelset_diffcomp " << std::endl; - - // Step 1: calculate the comp term phi1 - - // Step 2: calculate the diff terms phi2 - - -} +// SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng +// +// SPDX-License-Identifier: BSD-3-Clause + +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace amrex; + +// ls related + +Real calculate_eps (const Geometry& geom, int epsilon) +{ + const Real* dx = geom.CellSize(); + Real dxmin = dx[0]; + for (int d=1; d eps) { + heavifab(i,j,k) = 1.0; + } else if (phifab(i,j,k) > -eps) { + heavifab(i,j,k) = 0.5 * (1.0 + phifab(i,j,k) / eps + 1.0 / pi * std::sin(phifab(i,j,k) * pi / eps)); + } else { + heavifab(i,j,k) = 0.0; + } + + }); + } +} + +void +heavi_to_rhoormu(MultiFab& heaviside, Real var1, Real var2, MultiFab& outmf) +{ + + amrex::Print() << "In the heavi_to_rhomu " << std::endl; + + BL_ASSERT(heaviside.nComp() == outmf.nComp()); + + int ncomp = outmf.nComp(); + int ngrow = outmf.nGrow(); + + // build heaviside_temp because we might need to smooth the heaviside function + MultiFab heaviside_temp(heaviside.boxArray(), heaviside.DistributionMap(), ncomp, ngrow); + MultiFab::Copy(heaviside_temp, heaviside, 0, 0, ncomp, ngrow); + + // if( smoothforrhomu==1 && (parent->levelSteps(0)%lev0step_of_smoothforrhomu == 0) ){ + // smooth_sf(heaviside_temp); + // } + + heaviside_temp.mult(var1-var2, 0, ncomp, ngrow); + + MultiFab rtmp(heaviside.boxArray(), heaviside.DistributionMap(), ncomp, ngrow); + rtmp.setVal(var2, 0, ncomp, ngrow); + + MultiFab::Add(heaviside_temp, rtmp, 0, 0, ncomp, ngrow); + MultiFab::Copy(outmf, heaviside_temp, 0, 0, ncomp, ngrow); + +} + +Real calculate_eps_one (const Geometry& geom, int reinit_levelset) +{ + + Print() << "In the calculate_eps_one " << std::endl; + + Real eps_one = 0.0; + + const Real* dx = geom.CellSize(); + Real dxmax = dx[0]; + for (int d=1; d,AMREX_SPACEDIM>& phi_cc_grad, + MultiFab& phi_ctime, + MultiFab& phi1, + MultiFab& phi2, + int epsG, + int epsG2) +{ + + Print() << "In the levelset_diffcomp " << std::endl; + + // Step 1: calculate the comp term phi1 + + // Step 2: calculate the diff terms phi2 + + +} diff --git a/Source/NS_average.cpp b/Source/NS_average.cpp index 80c3282a..627055ba 100644 --- a/Source/NS_average.cpp +++ b/Source/NS_average.cpp @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2020 - 2023 Berkeley Lab +// +// SPDX-License-Identifier: LicenseRef-OpenSource + #include using namespace amrex; diff --git a/Source/NS_bcfill.H b/Source/NS_bcfill.H index 4f230429..c586122d 100644 --- a/Source/NS_bcfill.H +++ b/Source/NS_bcfill.H @@ -1,368 +1,376 @@ -#ifndef NS_bcfill_H_ -#define NS_bcfill_H_ - -#include -#include -#include -#include - -using namespace amrex; - -// -// Fill external Dirichlet boundary for State variables. -// This simple version only makes use constant BC values set in the inputs file. -// Create a struct, then use it to build a function that then gets passed to -// the StateDescriptor in NavierStokes::variableSetUp() in NS_setup.cpp -// -struct stateFill -{ - amrex::GpuArray, AMREX_SPACEDIM*2> bcv; - - AMREX_GPU_HOST - constexpr stateFill ( amrex::GpuArray, - AMREX_SPACEDIM*2> const& a_bcv) - : bcv(a_bcv) {} - - // iv : Cell index - // dest, dcomp, numcomp: Fill numcomp components of dest starting from dcomp. - // bcr, bcomp : bcr[bcomp] specifies BC for component dcomp and so on. - // orig_comp : component index for dcomp as in the descriptor set up in NS_setup.cpp - AMREX_GPU_DEVICE - void operator() (const amrex::IntVect& iv, amrex::Array4 const& dest, - const int dcomp, const int numcomp, - amrex::GeometryData const& geom, const amrex::Real /*time*/, - const amrex::BCRec* bcr, const int bcomp, - const int orig_comp) const - { - using namespace amrex; - - // do something for external Dirichlet (BCType::ext_dir) - - const int i = iv[0]; - const int j = iv[1]; -#if (AMREX_SPACEDIM == 3) - const int k = iv[2]; -#else - const int k = 0; -#endif - - const Box& domain_box = geom.Domain(); - - for (int nc = 0; nc < numcomp; ++nc) - { - const BCRec& bc = bcr[bcomp+nc]; - - if (bc.lo(0) == BCType::ext_dir and i < domain_box.smallEnd(0)) - { - dest(i,j,k,dcomp+nc) = bcv[Orientation(Direction::x,Orientation::low)][orig_comp+nc]; - } - else if (bc.hi(0) == BCType::ext_dir and i > domain_box.bigEnd(0)) - { - dest(i,j,k,dcomp+nc) = bcv[Orientation(Direction::x,Orientation::high)][orig_comp+nc]; - } - - if (bc.lo(1) == BCType::ext_dir and j < domain_box.smallEnd(1)) - { - dest(i,j,k,dcomp+nc) = bcv[Orientation(Direction::y,Orientation::low)][orig_comp+nc]; - } - else if (bc.hi(1) == BCType::ext_dir and j > domain_box.bigEnd(1)) - { - dest(i,j,k,dcomp+nc) = bcv[Orientation(Direction::y,Orientation::high)][orig_comp+nc]; - } - -#if (AMREX_SPACEDIM == 3) - if (bc.lo(2) == BCType::ext_dir and k < domain_box.smallEnd(2)) - { - dest(i,j,k,dcomp+nc) = bcv[Orientation(Direction::z,Orientation::low)][orig_comp+nc]; - } - else if (bc.hi(2) == BCType::ext_dir and k > domain_box.bigEnd(2)) - { - dest(i,j,k,dcomp+nc) = bcv[Orientation(Direction::z,Orientation::high)][orig_comp+nc]; - } -#endif - } - } -}; - -void state_fill (Box const& bx, FArrayBox& data, - const int dcomp, const int numcomp, - Geometry const& geom, const Real time, - const Vector& bcr, const int bcomp, - const int scomp) -{ - GpuBndryFuncFab gpu_bndry_func(stateFill{NavierStokes::get_bc_values()}); - gpu_bndry_func(bx,data,dcomp,numcomp,geom,time,bcr,bcomp,scomp); -} - -// -// Fill external Dirichlet boundary for velocity -// Use this to create time and/or spatially dependent BCs -// -struct velFill -{ - int probtype; - amrex::Real ub; - amrex::Real shearrate; - amrex::GpuArray, AMREX_SPACEDIM*2> bcv; - - AMREX_GPU_HOST - constexpr velFill (int a_probtype, amrex::Real a_ub, amrex::Real a_shearrate, - amrex::GpuArray, - AMREX_SPACEDIM*2> const& a_bcv) - : probtype(a_probtype), ub(a_ub), shearrate(a_shearrate), bcv(a_bcv) {} - - // iv : Cell index - // dest, dcomp, numcomp: Fill numcomp components of dest starting from dcomp. - // bcr, bcomp : bcr[bcomp] specifies BC for component dcomp and so on. - // orig_comp : component index for dcomp as in the descriptor set up in NS_setup.cpp - - // For X vel, dcomp = 0; numcomp = 1; bcomp = 0; orig_comp = 0; - // For Y vel, dcomp = 1; numcomp = 1; bcomp = 0; orig_comp = 1; - // For Z vel, dcomp = 2; numcomp = 1; bcomp = 0; orig_comp = 2; - - AMREX_GPU_DEVICE - void operator() (const amrex::IntVect& iv, amrex::Array4 const& dest, - const int dcomp, const int numcomp, - amrex::GeometryData const& geom, const amrex::Real /*time*/, - const amrex::BCRec* bcr, const int bcomp, - const int orig_comp) const - { - using namespace amrex; - - // amrex::Print() << "probtype " << probtype << std::endl; - // amrex::Print() << "ub " << ub << std::endl; - // amrex::Print() << "shearrate " << shearrate << std::endl; - - // do something for external Dirichlet (BCType::ext_dir) - - const int i = iv[0]; - const int j = iv[1]; -#if (AMREX_SPACEDIM == 3) - const int k = iv[2]; -#else - const int k = 0; -#endif - - const Box& domain_box = geom.Domain(); - - const Real* prob_lo = geom.ProbLo(); - const Real* dx = geom.CellSize(); - amrex::Real y = dx[1]*(0.5+j) + prob_lo[1]; - - for (int nc = 0; nc < numcomp; ++nc) - { - const BCRec& bc = bcr[bcomp+nc]; - - for ( int idir = 0; idir < AMREX_SPACEDIM; idir++) - { - if (bc.lo(idir) == BCType::ext_dir && iv[idir] < domain_box.smallEnd(idir)) - { - dest(i,j,k,dcomp+nc) = bcv[idir][orig_comp+nc]; - if ( (probtype == 102 || probtype == 103) && orig_comp == 0) { // shear flow inlet in x dir - dest(i,j,k,dcomp+nc) = ub + shearrate * y; - // amrex::Print() << i << " " << j << " " << k << " " << ub << " " << shearrate << " " << y << " " << idir << std::endl; - } - } - else if (bc.hi(idir) == BCType::ext_dir && iv[idir] > domain_box.bigEnd(idir)) - { - dest(i,j,k,dcomp+nc) = bcv[idir+AMREX_SPACEDIM][orig_comp+nc]; - } - } - } - } -}; - -void vel_fill (Box const& bx, FArrayBox& data, - const int dcomp, const int numcomp, - Geometry const& geom, const Real time, - const Vector& bcr, const int bcomp, - const int scomp) -{ - - GpuBndryFuncFab gpu_bndry_func(velFill{NavierStokes::probtype, NavierStokes::ub, NavierStokes::shearrate, - NavierStokes::get_bc_values()}); - gpu_bndry_func(bx,data,dcomp,numcomp,geom,time,bcr,bcomp,scomp); - -} - -// -// Could add boundary Fill functions for density, tracer and temperature here. -// Make sure NavierStokes::variableSetUp() passes new Fill to StateDescriptor -// - -struct homogeneousFill -{ - AMREX_GPU_DEVICE - void operator() (const amrex::IntVect& iv, amrex::Array4 const& dest, - const int dcomp, const int numcomp, - amrex::GeometryData const& geom, const amrex::Real /*time*/, - const amrex::BCRec* bcr, const int bcomp, - const int /*orig_comp*/) const - { - using namespace amrex; - - // Homogeneous Dirichlet BC - - const int i = iv[0]; - const int j = iv[1]; -#if (AMREX_SPACEDIM == 3) - const int k = iv[2]; -#else - const int k = 0; -#endif - - const Box& domain_box = geom.Domain(); - - for (int nc = 0; nc < numcomp; ++nc) - { - const BCRec& bc = bcr[bcomp+nc]; - - for ( int idir = 0; idir < AMREX_SPACEDIM; idir++) - { - if (bc.lo(idir) == BCType::ext_dir && iv[idir] < domain_box.smallEnd(idir)) - { - dest(i,j,k,dcomp+nc) = 0.; - - // - // Do something interesting - // - // if (probtype == ) - // { - // dest(i,j,k,n) = some f(x,y,z,t) - // } - } - else if (bc.hi(idir) == BCType::ext_dir && iv[idir] > domain_box.bigEnd(idir)) - { - dest(i,j,k,dcomp+nc) = 0.; - } - } - } - } -}; - -void homogeneous_fill (Box const& bx, FArrayBox& data, - const int dcomp, const int numcomp, - Geometry const& geom, const Real time, - const Vector& bcr, const int bcomp, - const int scomp) -{ - GpuBndryFuncFab gpu_bndry_func(homogeneousFill{}); - gpu_bndry_func(bx,data,dcomp,numcomp,geom,time,bcr,bcomp,scomp); - -} - -struct dummyFill -{ - AMREX_GPU_DEVICE - void operator()( - const amrex::IntVect& iv, - amrex::Array4 const& dest, - const int dcomp, - const int numcomp, - amrex::GeometryData const& geom, - const amrex::Real /*time*/, - const amrex::BCRec* bcr, - const int bcomp, - const int /*orig_comp*/) const - { - // Shouldn't actually ever use this, just need something computable. - // Set to some ridiculous value so we know if it does get used. - amrex::Real bogus_bc = 1.2345e40; - - const int i = iv[0]; - const int j = iv[1]; -#if (AMREX_SPACEDIM == 3) - const int k = iv[2]; -#else - const int k = 0; -#endif - - const Box& domain_box = geom.Domain(); - - for (int nc = 0; nc < numcomp; ++nc) - { - const BCRec& bc = bcr[bcomp+nc]; - - if (bc.lo(0) == BCType::ext_dir and i < domain_box.smallEnd(0)) - { - dest(i,j,k,dcomp+nc) = bogus_bc; - // - // Do something interesting with velocity BC - // - // if (probtype == ) - // { - // // some f(x,y,z,t) to fill dest - // } - } - else if (bc.hi(0) == BCType::ext_dir and i > domain_box.bigEnd(0)) - { - dest(i,j,k,dcomp+nc) = bogus_bc; - } - - if (bc.lo(1) == BCType::ext_dir and j < domain_box.smallEnd(1)) - { - dest(i,j,k,dcomp+nc) = bogus_bc; - } - else if (bc.hi(1) == BCType::ext_dir and j > domain_box.bigEnd(1)) - { - dest(i,j,k,dcomp+nc) = bogus_bc; - } -#if (AMREX_SPACEDIM == 3) - if (bc.lo(2) == BCType::ext_dir and k < domain_box.smallEnd(2)) - { - dest(i,j,k,dcomp+nc) = bogus_bc; - } - else if (bc.hi(2) == BCType::ext_dir and k > domain_box.bigEnd(2)) - { - dest(i,j,k,dcomp+nc) = bogus_bc; - } -#endif - } - } -}; - -void dummy_fill (Box const& bx, FArrayBox& data, - const int dcomp, const int numcomp, - Geometry const& geom, const Real time, - const Vector& bcr, const int bcomp, - const int scomp) -{ - - GpuBndryFuncFab gpu_bndry_func(dummyFill{}); - gpu_bndry_func(bx,data,dcomp,numcomp,geom,time,bcr,bcomp,scomp); - -} - - -// struct NodalFillExtDir -// { -// AMREX_GPU_DEVICE -// void operator()( -// const amrex::IntVect& iv, -// amrex::Array4 const& dest, -// const int dcomp, -// const int numcomp, -// amrex::GeometryData const& geom, -// const amrex::Real time, -// const amrex::BCRec* bcr, -// const int bcomp, -// const int orig_comp) const -// { -// // do something for external Dirichlet (BCType::ext_dir) -// } -// }; - -void press_fill (Box const& /*bx*/, FArrayBox& /*data*/, - const int /*dcomp*/, const int /*numcomp*/, - Geometry const& /*geom*/, const Real /*time*/, - const Vector& /*bcr*/, const int /*bcomp*/, - const int /*scomp*/) -{ - amrex::Abort("press_fill: Need to write fill for external Dirichlet (BCType::ext_dir)"); - - // GpuBndryFuncFab gpu_bndry_func(NodalFillExtDir{}); - // gpu_bndry_func(bx,data,dcomp,numcomp,geom,time,bcr,bcomp,scomp); - -} - -#endif +/* + * SPDX-FileCopyrightText: 2021 - 2023 Berkeley Lab; 2023 - 2025 Yadong Zeng + * + * SPDX-License-Identifier: LicenseRef-OpenSource + * Modified from IAMR, originally developed at Lawrence Berkeley National Lab. + * Original source: https://github.com/AMReX-Fluids/IAMR + */ + +#ifndef NS_bcfill_H_ +#define NS_bcfill_H_ + +#include +#include +#include +#include + +using namespace amrex; + +// +// Fill external Dirichlet boundary for State variables. +// This simple version only makes use constant BC values set in the inputs file. +// Create a struct, then use it to build a function that then gets passed to +// the StateDescriptor in NavierStokes::variableSetUp() in NS_setup.cpp +// +struct stateFill +{ + amrex::GpuArray, AMREX_SPACEDIM*2> bcv; + + AMREX_GPU_HOST + constexpr stateFill ( amrex::GpuArray, + AMREX_SPACEDIM*2> const& a_bcv) + : bcv(a_bcv) {} + + // iv : Cell index + // dest, dcomp, numcomp: Fill numcomp components of dest starting from dcomp. + // bcr, bcomp : bcr[bcomp] specifies BC for component dcomp and so on. + // orig_comp : component index for dcomp as in the descriptor set up in NS_setup.cpp + AMREX_GPU_DEVICE + void operator() (const amrex::IntVect& iv, amrex::Array4 const& dest, + const int dcomp, const int numcomp, + amrex::GeometryData const& geom, const amrex::Real /*time*/, + const amrex::BCRec* bcr, const int bcomp, + const int orig_comp) const + { + using namespace amrex; + + // do something for external Dirichlet (BCType::ext_dir) + + const int i = iv[0]; + const int j = iv[1]; +#if (AMREX_SPACEDIM == 3) + const int k = iv[2]; +#else + const int k = 0; +#endif + + const Box& domain_box = geom.Domain(); + + for (int nc = 0; nc < numcomp; ++nc) + { + const BCRec& bc = bcr[bcomp+nc]; + + if (bc.lo(0) == BCType::ext_dir and i < domain_box.smallEnd(0)) + { + dest(i,j,k,dcomp+nc) = bcv[Orientation(Direction::x,Orientation::low)][orig_comp+nc]; + } + else if (bc.hi(0) == BCType::ext_dir and i > domain_box.bigEnd(0)) + { + dest(i,j,k,dcomp+nc) = bcv[Orientation(Direction::x,Orientation::high)][orig_comp+nc]; + } + + if (bc.lo(1) == BCType::ext_dir and j < domain_box.smallEnd(1)) + { + dest(i,j,k,dcomp+nc) = bcv[Orientation(Direction::y,Orientation::low)][orig_comp+nc]; + } + else if (bc.hi(1) == BCType::ext_dir and j > domain_box.bigEnd(1)) + { + dest(i,j,k,dcomp+nc) = bcv[Orientation(Direction::y,Orientation::high)][orig_comp+nc]; + } + +#if (AMREX_SPACEDIM == 3) + if (bc.lo(2) == BCType::ext_dir and k < domain_box.smallEnd(2)) + { + dest(i,j,k,dcomp+nc) = bcv[Orientation(Direction::z,Orientation::low)][orig_comp+nc]; + } + else if (bc.hi(2) == BCType::ext_dir and k > domain_box.bigEnd(2)) + { + dest(i,j,k,dcomp+nc) = bcv[Orientation(Direction::z,Orientation::high)][orig_comp+nc]; + } +#endif + } + } +}; + +void state_fill (Box const& bx, FArrayBox& data, + const int dcomp, const int numcomp, + Geometry const& geom, const Real time, + const Vector& bcr, const int bcomp, + const int scomp) +{ + GpuBndryFuncFab gpu_bndry_func(stateFill{NavierStokes::get_bc_values()}); + gpu_bndry_func(bx,data,dcomp,numcomp,geom,time,bcr,bcomp,scomp); +} + +// +// Fill external Dirichlet boundary for velocity +// Use this to create time and/or spatially dependent BCs +// +struct velFill +{ + int probtype; + amrex::Real ub; + amrex::Real shearrate; + amrex::GpuArray, AMREX_SPACEDIM*2> bcv; + + AMREX_GPU_HOST + constexpr velFill (int a_probtype, amrex::Real a_ub, amrex::Real a_shearrate, + amrex::GpuArray, + AMREX_SPACEDIM*2> const& a_bcv) + : probtype(a_probtype), ub(a_ub), shearrate(a_shearrate), bcv(a_bcv) {} + + // iv : Cell index + // dest, dcomp, numcomp: Fill numcomp components of dest starting from dcomp. + // bcr, bcomp : bcr[bcomp] specifies BC for component dcomp and so on. + // orig_comp : component index for dcomp as in the descriptor set up in NS_setup.cpp + + // For X vel, dcomp = 0; numcomp = 1; bcomp = 0; orig_comp = 0; + // For Y vel, dcomp = 1; numcomp = 1; bcomp = 0; orig_comp = 1; + // For Z vel, dcomp = 2; numcomp = 1; bcomp = 0; orig_comp = 2; + + AMREX_GPU_DEVICE + void operator() (const amrex::IntVect& iv, amrex::Array4 const& dest, + const int dcomp, const int numcomp, + amrex::GeometryData const& geom, const amrex::Real /*time*/, + const amrex::BCRec* bcr, const int bcomp, + const int orig_comp) const + { + using namespace amrex; + + // amrex::Print() << "probtype " << probtype << std::endl; + // amrex::Print() << "ub " << ub << std::endl; + // amrex::Print() << "shearrate " << shearrate << std::endl; + + // do something for external Dirichlet (BCType::ext_dir) + + const int i = iv[0]; + const int j = iv[1]; +#if (AMREX_SPACEDIM == 3) + const int k = iv[2]; +#else + const int k = 0; +#endif + + const Box& domain_box = geom.Domain(); + + const Real* prob_lo = geom.ProbLo(); + const Real* dx = geom.CellSize(); + amrex::Real y = dx[1]*(0.5+j) + prob_lo[1]; + + for (int nc = 0; nc < numcomp; ++nc) + { + const BCRec& bc = bcr[bcomp+nc]; + + for ( int idir = 0; idir < AMREX_SPACEDIM; idir++) + { + if (bc.lo(idir) == BCType::ext_dir && iv[idir] < domain_box.smallEnd(idir)) + { + dest(i,j,k,dcomp+nc) = bcv[idir][orig_comp+nc]; + if ( (probtype == 102 || probtype == 103) && orig_comp == 0) { // shear flow inlet in x dir + dest(i,j,k,dcomp+nc) = ub + shearrate * y; + // amrex::Print() << i << " " << j << " " << k << " " << ub << " " << shearrate << " " << y << " " << idir << std::endl; + } + } + else if (bc.hi(idir) == BCType::ext_dir && iv[idir] > domain_box.bigEnd(idir)) + { + dest(i,j,k,dcomp+nc) = bcv[idir+AMREX_SPACEDIM][orig_comp+nc]; + } + } + } + } +}; + +void vel_fill (Box const& bx, FArrayBox& data, + const int dcomp, const int numcomp, + Geometry const& geom, const Real time, + const Vector& bcr, const int bcomp, + const int scomp) +{ + + GpuBndryFuncFab gpu_bndry_func(velFill{NavierStokes::probtype, NavierStokes::ub, NavierStokes::shearrate, + NavierStokes::get_bc_values()}); + gpu_bndry_func(bx,data,dcomp,numcomp,geom,time,bcr,bcomp,scomp); + +} + +// +// Could add boundary Fill functions for density, tracer and temperature here. +// Make sure NavierStokes::variableSetUp() passes new Fill to StateDescriptor +// + +struct homogeneousFill +{ + AMREX_GPU_DEVICE + void operator() (const amrex::IntVect& iv, amrex::Array4 const& dest, + const int dcomp, const int numcomp, + amrex::GeometryData const& geom, const amrex::Real /*time*/, + const amrex::BCRec* bcr, const int bcomp, + const int /*orig_comp*/) const + { + using namespace amrex; + + // Homogeneous Dirichlet BC + + const int i = iv[0]; + const int j = iv[1]; +#if (AMREX_SPACEDIM == 3) + const int k = iv[2]; +#else + const int k = 0; +#endif + + const Box& domain_box = geom.Domain(); + + for (int nc = 0; nc < numcomp; ++nc) + { + const BCRec& bc = bcr[bcomp+nc]; + + for ( int idir = 0; idir < AMREX_SPACEDIM; idir++) + { + if (bc.lo(idir) == BCType::ext_dir && iv[idir] < domain_box.smallEnd(idir)) + { + dest(i,j,k,dcomp+nc) = 0.; + + // + // Do something interesting + // + // if (probtype == ) + // { + // dest(i,j,k,n) = some f(x,y,z,t) + // } + } + else if (bc.hi(idir) == BCType::ext_dir && iv[idir] > domain_box.bigEnd(idir)) + { + dest(i,j,k,dcomp+nc) = 0.; + } + } + } + } +}; + +void homogeneous_fill (Box const& bx, FArrayBox& data, + const int dcomp, const int numcomp, + Geometry const& geom, const Real time, + const Vector& bcr, const int bcomp, + const int scomp) +{ + GpuBndryFuncFab gpu_bndry_func(homogeneousFill{}); + gpu_bndry_func(bx,data,dcomp,numcomp,geom,time,bcr,bcomp,scomp); + +} + +struct dummyFill +{ + AMREX_GPU_DEVICE + void operator()( + const amrex::IntVect& iv, + amrex::Array4 const& dest, + const int dcomp, + const int numcomp, + amrex::GeometryData const& geom, + const amrex::Real /*time*/, + const amrex::BCRec* bcr, + const int bcomp, + const int /*orig_comp*/) const + { + // Shouldn't actually ever use this, just need something computable. + // Set to some ridiculous value so we know if it does get used. + amrex::Real bogus_bc = 1.2345e40; + + const int i = iv[0]; + const int j = iv[1]; +#if (AMREX_SPACEDIM == 3) + const int k = iv[2]; +#else + const int k = 0; +#endif + + const Box& domain_box = geom.Domain(); + + for (int nc = 0; nc < numcomp; ++nc) + { + const BCRec& bc = bcr[bcomp+nc]; + + if (bc.lo(0) == BCType::ext_dir and i < domain_box.smallEnd(0)) + { + dest(i,j,k,dcomp+nc) = bogus_bc; + // + // Do something interesting with velocity BC + // + // if (probtype == ) + // { + // // some f(x,y,z,t) to fill dest + // } + } + else if (bc.hi(0) == BCType::ext_dir and i > domain_box.bigEnd(0)) + { + dest(i,j,k,dcomp+nc) = bogus_bc; + } + + if (bc.lo(1) == BCType::ext_dir and j < domain_box.smallEnd(1)) + { + dest(i,j,k,dcomp+nc) = bogus_bc; + } + else if (bc.hi(1) == BCType::ext_dir and j > domain_box.bigEnd(1)) + { + dest(i,j,k,dcomp+nc) = bogus_bc; + } +#if (AMREX_SPACEDIM == 3) + if (bc.lo(2) == BCType::ext_dir and k < domain_box.smallEnd(2)) + { + dest(i,j,k,dcomp+nc) = bogus_bc; + } + else if (bc.hi(2) == BCType::ext_dir and k > domain_box.bigEnd(2)) + { + dest(i,j,k,dcomp+nc) = bogus_bc; + } +#endif + } + } +}; + +void dummy_fill (Box const& bx, FArrayBox& data, + const int dcomp, const int numcomp, + Geometry const& geom, const Real time, + const Vector& bcr, const int bcomp, + const int scomp) +{ + + GpuBndryFuncFab gpu_bndry_func(dummyFill{}); + gpu_bndry_func(bx,data,dcomp,numcomp,geom,time,bcr,bcomp,scomp); + +} + + +// struct NodalFillExtDir +// { +// AMREX_GPU_DEVICE +// void operator()( +// const amrex::IntVect& iv, +// amrex::Array4 const& dest, +// const int dcomp, +// const int numcomp, +// amrex::GeometryData const& geom, +// const amrex::Real time, +// const amrex::BCRec* bcr, +// const int bcomp, +// const int orig_comp) const +// { +// // do something for external Dirichlet (BCType::ext_dir) +// } +// }; + +void press_fill (Box const& /*bx*/, FArrayBox& /*data*/, + const int /*dcomp*/, const int /*numcomp*/, + Geometry const& /*geom*/, const Real /*time*/, + const Vector& /*bcr*/, const int /*bcomp*/, + const int /*scomp*/) +{ + amrex::Abort("press_fill: Need to write fill for external Dirichlet (BCType::ext_dir)"); + + // GpuBndryFuncFab gpu_bndry_func(NodalFillExtDir{}); + // gpu_bndry_func(bx,data,dcomp,numcomp,geom,time,bcr,bcomp,scomp); + +} + +#endif diff --git a/Source/NS_derive.H b/Source/NS_derive.H index aa7e7573..9ae59ea7 100644 --- a/Source/NS_derive.H +++ b/Source/NS_derive.H @@ -1,47 +1,52 @@ - -#ifndef NS_DERIVE_CPP_H -#define NS_DERIVE_CPP_H - -#include -#include - - -namespace derive_functions { - - void der_vel_avg (const amrex::Box& bx, - amrex::FArrayBox& derfab, int dcomp, int ncomp, - const amrex::FArrayBox& datfab, - const amrex::Geometry& geomdata, - amrex::Real time, const int* bcrec, int level); - - // - // Compute cell-centered pressure as average of the - // surrounding nodal values - // - void deravgpres (const amrex::Box& bx, - amrex::FArrayBox& derfab, int dcomp, int ncomp, - const amrex::FArrayBox& datfab, - const amrex::Geometry& geomdata, - amrex::Real time, const int* bcrec, int level); - - // - // Compute the magnitude of the vorticity - // - void dermgvort (const amrex::Box& bx, amrex::FArrayBox& derfab, int dcomp, int ncomp, - const amrex::FArrayBox& datfab, const amrex::Geometry& geomdata, - amrex::Real time, const int* bcrec, int level); - // - // Compute kinetic energy - // - void derkeng (const amrex::Box& bx, amrex::FArrayBox& derfab, int dcomp, int ncomp, - const amrex::FArrayBox& datfab, const amrex::Geometry& geomdata, - amrex::Real time, const int* bcrec, int level); - // - // Do nothing - // - void dernull (const amrex::Box& bx, amrex::FArrayBox& derfab, int dcomp, int ncomp, - const amrex::FArrayBox& datfab, const amrex::Geometry& geomdata, - amrex::Real time, const int* bcrec, int level); - -} -#endif +/* + * SPDX-FileCopyrightText: 2020 - 2023 Berkeley Lab + * + * SPDX-License-Identifier: LicenseRef-OpenSource + */ + +#ifndef NS_DERIVE_CPP_H +#define NS_DERIVE_CPP_H + +#include +#include + + +namespace derive_functions { + + void der_vel_avg (const amrex::Box& bx, + amrex::FArrayBox& derfab, int dcomp, int ncomp, + const amrex::FArrayBox& datfab, + const amrex::Geometry& geomdata, + amrex::Real time, const int* bcrec, int level); + + // + // Compute cell-centered pressure as average of the + // surrounding nodal values + // + void deravgpres (const amrex::Box& bx, + amrex::FArrayBox& derfab, int dcomp, int ncomp, + const amrex::FArrayBox& datfab, + const amrex::Geometry& geomdata, + amrex::Real time, const int* bcrec, int level); + + // + // Compute the magnitude of the vorticity + // + void dermgvort (const amrex::Box& bx, amrex::FArrayBox& derfab, int dcomp, int ncomp, + const amrex::FArrayBox& datfab, const amrex::Geometry& geomdata, + amrex::Real time, const int* bcrec, int level); + // + // Compute kinetic energy + // + void derkeng (const amrex::Box& bx, amrex::FArrayBox& derfab, int dcomp, int ncomp, + const amrex::FArrayBox& datfab, const amrex::Geometry& geomdata, + amrex::Real time, const int* bcrec, int level); + // + // Do nothing + // + void dernull (const amrex::Box& bx, amrex::FArrayBox& derfab, int dcomp, int ncomp, + const amrex::FArrayBox& datfab, const amrex::Geometry& geomdata, + amrex::Real time, const int* bcrec, int level); + +} +#endif diff --git a/Source/NS_derive.cpp b/Source/NS_derive.cpp index 3d06ae9d..33c2132c 100644 --- a/Source/NS_derive.cpp +++ b/Source/NS_derive.cpp @@ -1,311 +1,315 @@ -#include -#include "NS_derive.H" -#ifdef AMREX_USE_EB -#include -#endif - -using namespace amrex; - -namespace derive_functions -{ - void der_vel_avg (const Box& bx, FArrayBox& derfab, int dcomp, int ncomp, - const FArrayBox& datfab, const Geometry& /*geomdata*/, - Real /*time*/, const int* /*bcrec*/, int level) - - { - amrex::ignore_unused(ncomp); - AMREX_ASSERT(derfab.box().contains(bx)); - AMREX_ASSERT(datfab.box().contains(bx)); - AMREX_ASSERT(derfab.nComp() >= dcomp + ncomp); - AMREX_ASSERT(datfab.nComp() >= AMREX_SPACEDIM*2); - AMREX_ASSERT(ncomp == AMREX_SPACEDIM*2); - auto const in_dat = datfab.array(); - auto der = derfab.array(dcomp); - amrex::Real inv_time; - amrex::Real inv_time_fluct; - - if (NavierStokesBase::time_avg[level] == 0){ - inv_time = 1.0; - }else{ - inv_time = 1.0 / NavierStokesBase::time_avg[level]; - } - - if (NavierStokesBase::time_avg_fluct[level] == 0){ - inv_time_fluct = 1.0; - }else{ - inv_time_fluct = 1.0 / NavierStokesBase::time_avg_fluct[level]; - } - - amrex::ParallelFor(bx, AMREX_SPACEDIM, [inv_time,inv_time_fluct,der,in_dat] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { - der(i,j,k,n) = in_dat(i,j,k,n) * inv_time; - der(i,j,k,n+AMREX_SPACEDIM) = sqrt(in_dat(i,j,k,n+AMREX_SPACEDIM) * inv_time_fluct); - }); - } - - // - // Compute cell-centered pressure as average of the - // surrounding nodal values - // - void deravgpres (const Box& bx, FArrayBox& derfab, int dcomp, int ncomp, - const FArrayBox& datfab, const Geometry& /*geomdata*/, - Real /*time*/, const int* /*bcrec*/, int /*level*/) - - { - amrex::ignore_unused(ncomp); - AMREX_ASSERT(derfab.box().contains(bx)); - AMREX_ASSERT(Box(datfab.box()).enclosedCells().contains(bx)); - AMREX_ASSERT(derfab.nComp() >= dcomp + ncomp); - AMREX_ASSERT(datfab.nComp() >= 1); - AMREX_ASSERT(ncomp == 1); - - auto const in_dat = datfab.array(); - auto der = derfab.array(dcomp); -#if (AMREX_SPACEDIM == 2 ) - Real factor = 0.25; -#elif (AMREX_SPACEDIM == 3 ) - Real factor = 0.125; -#endif - - amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - der(i,j,k) = factor * ( in_dat(i+1,j,k) + in_dat(i,j,k) - + in_dat(i+1,j+1,k) + in_dat(i,j+1,k) -#if (AMREX_SPACEDIM == 3 ) - + in_dat(i+1,j,k+1) + in_dat(i,j,k+1) - + in_dat(i+1,j+1,k+1) + in_dat(i,j+1,k+1) -#endif - ); - }); - } - - // - // Compute magnitude of vorticity - // - void dermgvort (const Box& bx, FArrayBox& derfab, int dcomp, int ncomp, - const FArrayBox& datfab, const Geometry& geomdata, - Real /*time*/, const int* /*bcrec*/, int /*level*/) - - { - amrex::ignore_unused(ncomp); - AMREX_ASSERT(derfab.box().contains(bx)); - AMREX_ASSERT(datfab.box().contains(bx)); - AMREX_ASSERT(derfab.nComp() >= dcomp + ncomp); - AMREX_ASSERT(datfab.nComp() >= AMREX_SPACEDIM); - AMREX_ASSERT(ncomp == 1); - - AMREX_D_TERM(const amrex::Real idx = geomdata.InvCellSize(0);, - const amrex::Real idy = geomdata.InvCellSize(1);, - const amrex::Real idz = geomdata.InvCellSize(2);); - - amrex::Array4 const& dat_arr = datfab.const_array(); - amrex::Array4 const&vort_arr = derfab.array(dcomp); - -#ifdef AMREX_USE_EB - const auto& ebfab = static_cast(datfab); - const EBCellFlagFab& flags = ebfab.getEBCellFlagFab(); - auto typ = flags.getType(bx); - if (typ == FabType::covered) - { - amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - vort_arr(i,j,k) = 0.0; - }); - } else if (typ == FabType::singlevalued) - { - const auto& flag_fab = flags.const_array(); - amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - constexpr amrex::Real c0 = -1.5; - constexpr amrex::Real c1 = 2.0; - constexpr amrex::Real c2 = -0.5; - if (flag_fab(i,j,k).isCovered()) { - vort_arr(i,j,k) = 0.0; - } else { - amrex::Real vx = 0.0; - amrex::Real uy = 0.0; - -#if ( AMREX_SPACEDIM == 2 ) - - // Need to check if there are covered cells in neighbours -- - // -- if so, use one-sided difference computation (but still quadratic) - if (!flag_fab(i,j,k).isConnected( 1,0,0)) { - vx = - (c0 * dat_arr(i ,j,k,1) - + c1 * dat_arr(i-1,j,k,1) - + c2 * dat_arr(i-2,j,k,1)) * idx; - } else if (!flag_fab(i,j,k).isConnected(-1,0,0)) { - vx = (c0 * dat_arr(i ,j,k,1) - + c1 * dat_arr(i+1,j,k,1) - + c2 * dat_arr(i+2,j,k,1)) * idx; - } else { - vx = 0.5 * (dat_arr(i+1,j,k,1) - dat_arr(i-1,j,k,1)) * idx; - } - // Do the same in y-direction - if (!flag_fab(i,j,k).isConnected( 0,1,0)) { - uy = - (c0 * dat_arr(i,j ,k,0) - + c1 * dat_arr(i,j-1,k,0) - + c2 * dat_arr(i,j-2,k,0)) * idy; - } else if (!flag_fab(i,j,k).isConnected(0,-1,0)) { - uy = (c0 * dat_arr(i,j ,k,0) - + c1 * dat_arr(i,j+1,k,0) - + c2 * dat_arr(i,j+2,k,0)) * idy; - } else { - uy = 0.5 * (dat_arr(i,j+1,k,0) - dat_arr(i,j-1,k,0)) * idy; - } - - vort_arr(i,j,k) = amrex::Math::abs(vx-uy); - - -#elif ( AMREX_SPACEDIM == 3 ) - - amrex::Real wx = 0.0; - amrex::Real wy = 0.0; - amrex::Real uz = 0.0; - amrex::Real vz = 0.0; - // Need to check if there are covered cells in neighbours -- - // -- if so, use one-sided difference computation (but still quadratic) - if (!flag_fab(i,j,k).isConnected( 1,0,0)) { - // Covered cell to the right, go fish left - vx = - (c0 * dat_arr(i ,j,k,1) - + c1 * dat_arr(i-1,j,k,1) - + c2 * dat_arr(i-2,j,k,1)) * idx; - wx = - (c0 * dat_arr(i ,j,k,2) - + c1 * dat_arr(i-1,j,k,2) - + c2 * dat_arr(i-2,j,k,2)) * idx; - } else if (!flag_fab(i,j,k).isConnected(-1,0,0)) { - // Covered cell to the left, go fish right - vx = (c0 * dat_arr(i ,j,k,1) - + c1 * dat_arr(i+1,j,k,1) - + c2 * dat_arr(i+2,j,k,1)) * idx; - wx = (c0 * dat_arr(i ,j,k,2) - + c1 * dat_arr(i+1,j,k,2) - + c2 * dat_arr(i+2,j,k,2)) * idx; - } else { - // No covered cells right or left, use standard stencil - vx = 0.5 * (dat_arr(i+1,j,k,1) - dat_arr(i-1,j,k,1)) * idx; - wx = 0.5 * (dat_arr(i+1,j,k,2) - dat_arr(i-1,j,k,2)) * idx; - } - // Do the same in y-direction - if (!flag_fab(i,j,k).isConnected(0, 1,0)) { - uy = - (c0 * dat_arr(i,j ,k,0) - + c1 * dat_arr(i,j-1,k,0) - + c2 * dat_arr(i,j-2,k,0)) * idy; - wy = - (c0 * dat_arr(i,j ,k,2) - + c1 * dat_arr(i,j-1,k,2) - + c2 * dat_arr(i,j-2,k,2)) * idy; - } else if (!flag_fab(i,j,k).isConnected(0,-1,0)) { - uy = (c0 * dat_arr(i,j ,k,0) - + c1 * dat_arr(i,j+1,k,0) - + c2 * dat_arr(i,j+2,k,0)) * idy; - wy = (c0 * dat_arr(i,j ,k,2) - + c1 * dat_arr(i,j+1,k,2) - + c2 * dat_arr(i,j+2,k,2)) * idy; - } else { - uy = 0.5 * (dat_arr(i,j+1,k,0) - dat_arr(i,j-1,k,0)) * idy; - wy = 0.5 * (dat_arr(i,j+1,k,2) - dat_arr(i,j-1,k,2)) * idy; - } - // Do the same in z-direction - if (!flag_fab(i,j,k).isConnected(0,0, 1)) { - uz = - (c0 * dat_arr(i,j,k ,0) - + c1 * dat_arr(i,j,k-1,0) - + c2 * dat_arr(i,j,k-2,0)) * idz; - vz = - (c0 * dat_arr(i,j,k ,1) - + c1 * dat_arr(i,j,k-1,1) - + c2 * dat_arr(i,j,k-2,1)) * idz; - } else if (!flag_fab(i,j,k).isConnected(0,0,-1)) { - uz = (c0 * dat_arr(i,j,k ,0) - + c1 * dat_arr(i,j,k+1,0) - + c2 * dat_arr(i,j,k+2,0)) * idz; - vz = (c0 * dat_arr(i,j,k ,1) - + c1 * dat_arr(i,j,k+1,1) - + c2 * dat_arr(i,j,k+2,1)) * idz; - } else { - uz = 0.5 * (dat_arr(i,j,k+1,0) - dat_arr(i,j,k-1,0)) * idz; - vz = 0.5 * (dat_arr(i,j,k+1,1) - dat_arr(i,j,k-1,1)) * idz; - } - - vort_arr(i,j,k) = std::sqrt((wy-vz)*(wy-vz) + (uz-wx)*(uz-wx) + (vx-uy)*(vx-uy)); - -#endif - } - }); - } else // non-EB -#endif - { - amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { -#if ( AMREX_SPACEDIM == 2 ) - - amrex::Real vx = 0.5 * (dat_arr(i+1,j,k,1) - dat_arr(i-1,j,k,1)) * idx; - amrex::Real uy = 0.5 * (dat_arr(i,j+1,k,0) - dat_arr(i,j-1,k,0)) * idy; - - vort_arr(i,j,k) = amrex::Math::abs(vx-uy); - - -#elif ( AMREX_SPACEDIM == 3 ) - - amrex::Real vx = 0.5 * (dat_arr(i+1,j,k,1) - dat_arr(i-1,j,k,1)) * idx; - amrex::Real wx = 0.5 * (dat_arr(i+1,j,k,2) - dat_arr(i-1,j,k,2)) * idx; - - amrex::Real uy = 0.5 * (dat_arr(i,j+1,k,0) - dat_arr(i,j-1,k,0)) * idy; - amrex::Real wy = 0.5 * (dat_arr(i,j+1,k,2) - dat_arr(i,j-1,k,2)) * idy; - - amrex::Real uz = 0.5 * (dat_arr(i,j,k+1,0) - dat_arr(i,j,k-1,0)) * idz; - amrex::Real vz = 0.5 * (dat_arr(i,j,k+1,1) - dat_arr(i,j,k-1,1)) * idz; - - vort_arr(i,j,k) = std::sqrt((wy-vz)*(wy-vz) + (uz-wx)*(uz-wx) + (vx-uy)*(vx-uy)); -#endif - }); - } - } - - // - // Compute kinetic energy - // - void derkeng (const Box& bx, FArrayBox& derfab, int dcomp, int ncomp, - const FArrayBox& datfab, const Geometry& /*geomdata*/, - Real /*time*/, const int* /*bcrec*/, int /*level*/) - - { - amrex::ignore_unused(ncomp); - AMREX_ASSERT(derfab.box().contains(bx)); - AMREX_ASSERT(Box(datfab.box()).contains(bx)); - AMREX_ASSERT(derfab.nComp() >= dcomp + ncomp); - AMREX_ASSERT(datfab.nComp() >= 1); - AMREX_ASSERT(ncomp == 1); - auto const in_dat = datfab.array(); - auto der = derfab.array(dcomp); - - amrex::ParallelFor(bx,[=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - const Real rho = in_dat(i,j,k,0); - const Real vx = in_dat(i,j,k,1); - const Real vy = in_dat(i,j,k,2); -#if (AMREX_SPACEDIM ==3) - const Real vz = in_dat(i,j,k,3); -#endif - - der(i,j,k) = 0.5 * rho * ( vx*vx + vy*vy -#if (AMREX_SPACEDIM == 3 ) - + vz*vz -#endif - ); - }); - } - - // - // Null function - // - void dernull (const Box& /*bx*/, - FArrayBox& /*derfab*/, int /*dcomp*/, int /*ncomp*/, - const FArrayBox& /*datfab*/, const Geometry& /*geomdata*/, - Real /*time*/, const int* /*bcrec*/, int /*level*/) - - { - // - // Do nothing. - // - } - -} +// SPDX-FileCopyrightText: 2020 - 2023 Berkeley Lab +// +// SPDX-License-Identifier: LicenseRef-OpenSource + +#include +#include "NS_derive.H" +#ifdef AMREX_USE_EB +#include +#endif + +using namespace amrex; + +namespace derive_functions +{ + void der_vel_avg (const Box& bx, FArrayBox& derfab, int dcomp, int ncomp, + const FArrayBox& datfab, const Geometry& /*geomdata*/, + Real /*time*/, const int* /*bcrec*/, int level) + + { + amrex::ignore_unused(ncomp); + AMREX_ASSERT(derfab.box().contains(bx)); + AMREX_ASSERT(datfab.box().contains(bx)); + AMREX_ASSERT(derfab.nComp() >= dcomp + ncomp); + AMREX_ASSERT(datfab.nComp() >= AMREX_SPACEDIM*2); + AMREX_ASSERT(ncomp == AMREX_SPACEDIM*2); + auto const in_dat = datfab.array(); + auto der = derfab.array(dcomp); + amrex::Real inv_time; + amrex::Real inv_time_fluct; + + if (NavierStokesBase::time_avg[level] == 0){ + inv_time = 1.0; + }else{ + inv_time = 1.0 / NavierStokesBase::time_avg[level]; + } + + if (NavierStokesBase::time_avg_fluct[level] == 0){ + inv_time_fluct = 1.0; + }else{ + inv_time_fluct = 1.0 / NavierStokesBase::time_avg_fluct[level]; + } + + amrex::ParallelFor(bx, AMREX_SPACEDIM, [inv_time,inv_time_fluct,der,in_dat] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { + der(i,j,k,n) = in_dat(i,j,k,n) * inv_time; + der(i,j,k,n+AMREX_SPACEDIM) = sqrt(in_dat(i,j,k,n+AMREX_SPACEDIM) * inv_time_fluct); + }); + } + + // + // Compute cell-centered pressure as average of the + // surrounding nodal values + // + void deravgpres (const Box& bx, FArrayBox& derfab, int dcomp, int ncomp, + const FArrayBox& datfab, const Geometry& /*geomdata*/, + Real /*time*/, const int* /*bcrec*/, int /*level*/) + + { + amrex::ignore_unused(ncomp); + AMREX_ASSERT(derfab.box().contains(bx)); + AMREX_ASSERT(Box(datfab.box()).enclosedCells().contains(bx)); + AMREX_ASSERT(derfab.nComp() >= dcomp + ncomp); + AMREX_ASSERT(datfab.nComp() >= 1); + AMREX_ASSERT(ncomp == 1); + + auto const in_dat = datfab.array(); + auto der = derfab.array(dcomp); +#if (AMREX_SPACEDIM == 2 ) + Real factor = 0.25; +#elif (AMREX_SPACEDIM == 3 ) + Real factor = 0.125; +#endif + + amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + der(i,j,k) = factor * ( in_dat(i+1,j,k) + in_dat(i,j,k) + + in_dat(i+1,j+1,k) + in_dat(i,j+1,k) +#if (AMREX_SPACEDIM == 3 ) + + in_dat(i+1,j,k+1) + in_dat(i,j,k+1) + + in_dat(i+1,j+1,k+1) + in_dat(i,j+1,k+1) +#endif + ); + }); + } + + // + // Compute magnitude of vorticity + // + void dermgvort (const Box& bx, FArrayBox& derfab, int dcomp, int ncomp, + const FArrayBox& datfab, const Geometry& geomdata, + Real /*time*/, const int* /*bcrec*/, int /*level*/) + + { + amrex::ignore_unused(ncomp); + AMREX_ASSERT(derfab.box().contains(bx)); + AMREX_ASSERT(datfab.box().contains(bx)); + AMREX_ASSERT(derfab.nComp() >= dcomp + ncomp); + AMREX_ASSERT(datfab.nComp() >= AMREX_SPACEDIM); + AMREX_ASSERT(ncomp == 1); + + AMREX_D_TERM(const amrex::Real idx = geomdata.InvCellSize(0);, + const amrex::Real idy = geomdata.InvCellSize(1);, + const amrex::Real idz = geomdata.InvCellSize(2);); + + amrex::Array4 const& dat_arr = datfab.const_array(); + amrex::Array4 const&vort_arr = derfab.array(dcomp); + +#ifdef AMREX_USE_EB + const auto& ebfab = static_cast(datfab); + const EBCellFlagFab& flags = ebfab.getEBCellFlagFab(); + auto typ = flags.getType(bx); + if (typ == FabType::covered) + { + amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + vort_arr(i,j,k) = 0.0; + }); + } else if (typ == FabType::singlevalued) + { + const auto& flag_fab = flags.const_array(); + amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + constexpr amrex::Real c0 = -1.5; + constexpr amrex::Real c1 = 2.0; + constexpr amrex::Real c2 = -0.5; + if (flag_fab(i,j,k).isCovered()) { + vort_arr(i,j,k) = 0.0; + } else { + amrex::Real vx = 0.0; + amrex::Real uy = 0.0; + +#if ( AMREX_SPACEDIM == 2 ) + + // Need to check if there are covered cells in neighbours -- + // -- if so, use one-sided difference computation (but still quadratic) + if (!flag_fab(i,j,k).isConnected( 1,0,0)) { + vx = - (c0 * dat_arr(i ,j,k,1) + + c1 * dat_arr(i-1,j,k,1) + + c2 * dat_arr(i-2,j,k,1)) * idx; + } else if (!flag_fab(i,j,k).isConnected(-1,0,0)) { + vx = (c0 * dat_arr(i ,j,k,1) + + c1 * dat_arr(i+1,j,k,1) + + c2 * dat_arr(i+2,j,k,1)) * idx; + } else { + vx = 0.5 * (dat_arr(i+1,j,k,1) - dat_arr(i-1,j,k,1)) * idx; + } + // Do the same in y-direction + if (!flag_fab(i,j,k).isConnected( 0,1,0)) { + uy = - (c0 * dat_arr(i,j ,k,0) + + c1 * dat_arr(i,j-1,k,0) + + c2 * dat_arr(i,j-2,k,0)) * idy; + } else if (!flag_fab(i,j,k).isConnected(0,-1,0)) { + uy = (c0 * dat_arr(i,j ,k,0) + + c1 * dat_arr(i,j+1,k,0) + + c2 * dat_arr(i,j+2,k,0)) * idy; + } else { + uy = 0.5 * (dat_arr(i,j+1,k,0) - dat_arr(i,j-1,k,0)) * idy; + } + + vort_arr(i,j,k) = amrex::Math::abs(vx-uy); + + +#elif ( AMREX_SPACEDIM == 3 ) + + amrex::Real wx = 0.0; + amrex::Real wy = 0.0; + amrex::Real uz = 0.0; + amrex::Real vz = 0.0; + // Need to check if there are covered cells in neighbours -- + // -- if so, use one-sided difference computation (but still quadratic) + if (!flag_fab(i,j,k).isConnected( 1,0,0)) { + // Covered cell to the right, go fish left + vx = - (c0 * dat_arr(i ,j,k,1) + + c1 * dat_arr(i-1,j,k,1) + + c2 * dat_arr(i-2,j,k,1)) * idx; + wx = - (c0 * dat_arr(i ,j,k,2) + + c1 * dat_arr(i-1,j,k,2) + + c2 * dat_arr(i-2,j,k,2)) * idx; + } else if (!flag_fab(i,j,k).isConnected(-1,0,0)) { + // Covered cell to the left, go fish right + vx = (c0 * dat_arr(i ,j,k,1) + + c1 * dat_arr(i+1,j,k,1) + + c2 * dat_arr(i+2,j,k,1)) * idx; + wx = (c0 * dat_arr(i ,j,k,2) + + c1 * dat_arr(i+1,j,k,2) + + c2 * dat_arr(i+2,j,k,2)) * idx; + } else { + // No covered cells right or left, use standard stencil + vx = 0.5 * (dat_arr(i+1,j,k,1) - dat_arr(i-1,j,k,1)) * idx; + wx = 0.5 * (dat_arr(i+1,j,k,2) - dat_arr(i-1,j,k,2)) * idx; + } + // Do the same in y-direction + if (!flag_fab(i,j,k).isConnected(0, 1,0)) { + uy = - (c0 * dat_arr(i,j ,k,0) + + c1 * dat_arr(i,j-1,k,0) + + c2 * dat_arr(i,j-2,k,0)) * idy; + wy = - (c0 * dat_arr(i,j ,k,2) + + c1 * dat_arr(i,j-1,k,2) + + c2 * dat_arr(i,j-2,k,2)) * idy; + } else if (!flag_fab(i,j,k).isConnected(0,-1,0)) { + uy = (c0 * dat_arr(i,j ,k,0) + + c1 * dat_arr(i,j+1,k,0) + + c2 * dat_arr(i,j+2,k,0)) * idy; + wy = (c0 * dat_arr(i,j ,k,2) + + c1 * dat_arr(i,j+1,k,2) + + c2 * dat_arr(i,j+2,k,2)) * idy; + } else { + uy = 0.5 * (dat_arr(i,j+1,k,0) - dat_arr(i,j-1,k,0)) * idy; + wy = 0.5 * (dat_arr(i,j+1,k,2) - dat_arr(i,j-1,k,2)) * idy; + } + // Do the same in z-direction + if (!flag_fab(i,j,k).isConnected(0,0, 1)) { + uz = - (c0 * dat_arr(i,j,k ,0) + + c1 * dat_arr(i,j,k-1,0) + + c2 * dat_arr(i,j,k-2,0)) * idz; + vz = - (c0 * dat_arr(i,j,k ,1) + + c1 * dat_arr(i,j,k-1,1) + + c2 * dat_arr(i,j,k-2,1)) * idz; + } else if (!flag_fab(i,j,k).isConnected(0,0,-1)) { + uz = (c0 * dat_arr(i,j,k ,0) + + c1 * dat_arr(i,j,k+1,0) + + c2 * dat_arr(i,j,k+2,0)) * idz; + vz = (c0 * dat_arr(i,j,k ,1) + + c1 * dat_arr(i,j,k+1,1) + + c2 * dat_arr(i,j,k+2,1)) * idz; + } else { + uz = 0.5 * (dat_arr(i,j,k+1,0) - dat_arr(i,j,k-1,0)) * idz; + vz = 0.5 * (dat_arr(i,j,k+1,1) - dat_arr(i,j,k-1,1)) * idz; + } + + vort_arr(i,j,k) = std::sqrt((wy-vz)*(wy-vz) + (uz-wx)*(uz-wx) + (vx-uy)*(vx-uy)); + +#endif + } + }); + } else // non-EB +#endif + { + amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { +#if ( AMREX_SPACEDIM == 2 ) + + amrex::Real vx = 0.5 * (dat_arr(i+1,j,k,1) - dat_arr(i-1,j,k,1)) * idx; + amrex::Real uy = 0.5 * (dat_arr(i,j+1,k,0) - dat_arr(i,j-1,k,0)) * idy; + + vort_arr(i,j,k) = amrex::Math::abs(vx-uy); + + +#elif ( AMREX_SPACEDIM == 3 ) + + amrex::Real vx = 0.5 * (dat_arr(i+1,j,k,1) - dat_arr(i-1,j,k,1)) * idx; + amrex::Real wx = 0.5 * (dat_arr(i+1,j,k,2) - dat_arr(i-1,j,k,2)) * idx; + + amrex::Real uy = 0.5 * (dat_arr(i,j+1,k,0) - dat_arr(i,j-1,k,0)) * idy; + amrex::Real wy = 0.5 * (dat_arr(i,j+1,k,2) - dat_arr(i,j-1,k,2)) * idy; + + amrex::Real uz = 0.5 * (dat_arr(i,j,k+1,0) - dat_arr(i,j,k-1,0)) * idz; + amrex::Real vz = 0.5 * (dat_arr(i,j,k+1,1) - dat_arr(i,j,k-1,1)) * idz; + + vort_arr(i,j,k) = std::sqrt((wy-vz)*(wy-vz) + (uz-wx)*(uz-wx) + (vx-uy)*(vx-uy)); +#endif + }); + } + } + + // + // Compute kinetic energy + // + void derkeng (const Box& bx, FArrayBox& derfab, int dcomp, int ncomp, + const FArrayBox& datfab, const Geometry& /*geomdata*/, + Real /*time*/, const int* /*bcrec*/, int /*level*/) + + { + amrex::ignore_unused(ncomp); + AMREX_ASSERT(derfab.box().contains(bx)); + AMREX_ASSERT(Box(datfab.box()).contains(bx)); + AMREX_ASSERT(derfab.nComp() >= dcomp + ncomp); + AMREX_ASSERT(datfab.nComp() >= 1); + AMREX_ASSERT(ncomp == 1); + auto const in_dat = datfab.array(); + auto der = derfab.array(dcomp); + + amrex::ParallelFor(bx,[=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + const Real rho = in_dat(i,j,k,0); + const Real vx = in_dat(i,j,k,1); + const Real vy = in_dat(i,j,k,2); +#if (AMREX_SPACEDIM ==3) + const Real vz = in_dat(i,j,k,3); +#endif + + der(i,j,k) = 0.5 * rho * ( vx*vx + vy*vy +#if (AMREX_SPACEDIM == 3 ) + + vz*vz +#endif + ); + }); + } + + // + // Null function + // + void dernull (const Box& /*bx*/, + FArrayBox& /*derfab*/, int /*dcomp*/, int /*ncomp*/, + const FArrayBox& /*datfab*/, const Geometry& /*geomdata*/, + Real /*time*/, const int* /*bcrec*/, int /*level*/) + + { + // + // Do nothing. + // + } + +} diff --git a/Source/NS_error.cpp b/Source/NS_error.cpp index ce6a2577..dc5d1dc7 100644 --- a/Source/NS_error.cpp +++ b/Source/NS_error.cpp @@ -1,145 +1,148 @@ - -#include -#include -#include - -using std::string; - -using namespace amrex; - -void -NavierStokes::error_setup() -{ - // - // Dynamically generated error tagging functions - // - std::string amr_prefix = "amr"; - ParmParse ppamr(amr_prefix); - Vector refinement_indicators; - ppamr.queryarr("refinement_indicators",refinement_indicators,0,ppamr.countval("refinement_indicators")); - for (int i=0; i box_lo(AMREX_SPACEDIM), box_hi(AMREX_SPACEDIM); - ppr.getarr("in_box_lo",box_lo,0,AMREX_SPACEDIM); - ppr.getarr("in_box_hi",box_hi,0,AMREX_SPACEDIM); - realbox = RealBox(&(box_lo[0]),&(box_hi[0])); - } - - AMRErrorTagInfo info; - - if (realbox.ok()) { - info.SetRealBox(realbox); - } - if (ppr.countval("start_time") > 0) { - Real min_time; ppr.get("start_time",min_time); - info.SetMinTime(min_time); - } - if (ppr.countval("end_time") > 0) { - Real max_time; ppr.get("end_time",max_time); - info.SetMaxTime(max_time); - } - if (ppr.countval("max_level") > 0) { - int max_level; ppr.get("max_level",max_level); - info.SetMaxLevel(max_level); - } - - if (ppr.countval("value_greater")) { - int num_val = ppr.countval("value_greater"); - Vector value(num_val); - ppr.getarr("value_greater",value,0,num_val); - std::string field; ppr.get("field_name",field); - errtags.push_back(AMRErrorTag(value,AMRErrorTag::GREATER,field,info)); - } - else if (ppr.countval("value_less")) { - int num_val = ppr.countval("value_less"); - Vector value(num_val); - ppr.getarr("value_less",value,0,num_val); - std::string field; ppr.get("field_name",field); - errtags.push_back(AMRErrorTag(value,AMRErrorTag::LESS,field,info)); - } - else if (ppr.countval("vorticity_greater")) { - int num_val = ppr.countval("vorticity_greater"); - Vector value(num_val); - ppr.getarr("vorticity_greater",value,0,num_val); - const std::string field="mag_vort"; - errtags.push_back(AMRErrorTag(value,AMRErrorTag::VORT,field,info)); - } - else if (ppr.countval("adjacent_difference_greater")) { - int num_val = ppr.countval("adjacent_difference_greater"); - Vector value(num_val); - ppr.getarr("adjacent_difference_greater",value,0,num_val); - std::string field; ppr.get("field_name",field); - errtags.push_back(AMRErrorTag(value,AMRErrorTag::GRAD,field,info)); - } - else if (realbox.ok()) - { - errtags.push_back(AMRErrorTag(info)); - } - // // - // // User defined error function: - // // Could create an AMRErrorTag::UserFunc as outlined below. - // // However, this only allows you to use one "field", i.e. one - // // component of State or a derived value (as defined in NS_setup.cpp). - // // For all cases I can think of, a better option is to create a - // // derived value in NS_setup.cpp and use one of the comparisons - // // defined above (eg. value_greater will tag based on - // // derived_value > value). - // // - // else if (ppr.countval("value")) { - // Real value; ppr.get("value",value); - // std::string field; ppr.get("field_name",field); - - // // set ngrow for "field" based on what errFunc needs - // int ngrow = ; - // AMRErrorTag::UserFunc* errFunc; - // // - // // define error estimation function - // // - - // errtags.push_back(AMRErrorTag(errFunc,field,ngrow,info)); - // } - else { - Abort(std::string("Unrecognized refinement indicator for " + refinement_indicators[i]).c_str()); - } - } - - // - // For hard-coded error estimation function, that would go in - // NavierStokes::errorEst() - // -} - - -void -NavierStokes::errorEst (TagBoxArray& tags, - int clearval, - int tagval, - Real time, - int n_error_buf, - int ngrow) -{ - - NavierStokesBase::errorEst(tags,clearval,tagval,time,n_error_buf,ngrow); - - for (int j=0; j mf; - if (! errtags[j].Field().empty()) { - mf = derive(errtags[j].Field(), time, errtags[j].NGrow()); - } - // - // Create a derive to use ABecLap to compute grad - // take level max here - // add into errtags info for relative threshold ... - // - errtags[j](tags,mf.get(),char(clearval),char(tagval),time,level,geom); - } - - // - // If needed, hard-code error function here - // -} +// SPDX-FileCopyrightText: 2012 - 2023 Berkeley Lab +// +// SPDX-License-Identifier: LicenseRef-OpenSource + +#include +#include +#include + +using std::string; + +using namespace amrex; + +void +NavierStokes::error_setup() +{ + // + // Dynamically generated error tagging functions + // + std::string amr_prefix = "amr"; + ParmParse ppamr(amr_prefix); + Vector refinement_indicators; + ppamr.queryarr("refinement_indicators",refinement_indicators,0,ppamr.countval("refinement_indicators")); + for (int i=0; i box_lo(AMREX_SPACEDIM), box_hi(AMREX_SPACEDIM); + ppr.getarr("in_box_lo",box_lo,0,AMREX_SPACEDIM); + ppr.getarr("in_box_hi",box_hi,0,AMREX_SPACEDIM); + realbox = RealBox(&(box_lo[0]),&(box_hi[0])); + } + + AMRErrorTagInfo info; + + if (realbox.ok()) { + info.SetRealBox(realbox); + } + if (ppr.countval("start_time") > 0) { + Real min_time; ppr.get("start_time",min_time); + info.SetMinTime(min_time); + } + if (ppr.countval("end_time") > 0) { + Real max_time; ppr.get("end_time",max_time); + info.SetMaxTime(max_time); + } + if (ppr.countval("max_level") > 0) { + int max_level; ppr.get("max_level",max_level); + info.SetMaxLevel(max_level); + } + + if (ppr.countval("value_greater")) { + int num_val = ppr.countval("value_greater"); + Vector value(num_val); + ppr.getarr("value_greater",value,0,num_val); + std::string field; ppr.get("field_name",field); + errtags.push_back(AMRErrorTag(value,AMRErrorTag::GREATER,field,info)); + } + else if (ppr.countval("value_less")) { + int num_val = ppr.countval("value_less"); + Vector value(num_val); + ppr.getarr("value_less",value,0,num_val); + std::string field; ppr.get("field_name",field); + errtags.push_back(AMRErrorTag(value,AMRErrorTag::LESS,field,info)); + } + else if (ppr.countval("vorticity_greater")) { + int num_val = ppr.countval("vorticity_greater"); + Vector value(num_val); + ppr.getarr("vorticity_greater",value,0,num_val); + const std::string field="mag_vort"; + errtags.push_back(AMRErrorTag(value,AMRErrorTag::VORT,field,info)); + } + else if (ppr.countval("adjacent_difference_greater")) { + int num_val = ppr.countval("adjacent_difference_greater"); + Vector value(num_val); + ppr.getarr("adjacent_difference_greater",value,0,num_val); + std::string field; ppr.get("field_name",field); + errtags.push_back(AMRErrorTag(value,AMRErrorTag::GRAD,field,info)); + } + else if (realbox.ok()) + { + errtags.push_back(AMRErrorTag(info)); + } + // // + // // User defined error function: + // // Could create an AMRErrorTag::UserFunc as outlined below. + // // However, this only allows you to use one "field", i.e. one + // // component of State or a derived value (as defined in NS_setup.cpp). + // // For all cases I can think of, a better option is to create a + // // derived value in NS_setup.cpp and use one of the comparisons + // // defined above (eg. value_greater will tag based on + // // derived_value > value). + // // + // else if (ppr.countval("value")) { + // Real value; ppr.get("value",value); + // std::string field; ppr.get("field_name",field); + + // // set ngrow for "field" based on what errFunc needs + // int ngrow = ; + // AMRErrorTag::UserFunc* errFunc; + // // + // // define error estimation function + // // + + // errtags.push_back(AMRErrorTag(errFunc,field,ngrow,info)); + // } + else { + Abort(std::string("Unrecognized refinement indicator for " + refinement_indicators[i]).c_str()); + } + } + + // + // For hard-coded error estimation function, that would go in + // NavierStokes::errorEst() + // +} + + +void +NavierStokes::errorEst (TagBoxArray& tags, + int clearval, + int tagval, + Real time, + int n_error_buf, + int ngrow) +{ + + NavierStokesBase::errorEst(tags,clearval,tagval,time,n_error_buf,ngrow); + + for (int j=0; j mf; + if (! errtags[j].Field().empty()) { + mf = derive(errtags[j].Field(), time, errtags[j].NGrow()); + } + // + // Create a derive to use ABecLap to compute grad + // take level max here + // add into errtags info for relative threshold ... + // + errtags[j](tags,mf.get(),char(clearval),char(tagval),time,level,geom); + } + + // + // If needed, hard-code error function here + // +} diff --git a/Source/NS_getForce.cpp b/Source/NS_getForce.cpp index 10afcbab..152ce5aa 100644 --- a/Source/NS_getForce.cpp +++ b/Source/NS_getForce.cpp @@ -1,190 +1,193 @@ - -#include -#include - - -using namespace amrex; - -// -// Virtual access function for getting the forcing terms for the -// velocities and scalars. The base version computes a buoyancy. -// -// NOTE: This function returns a rho weighted source term. -// -// For conservative (i.e. do_mom_diff=1, do_cons_trac=1), velocities -// are integrated according to the equation -// -// ui_t + uj ui_j = S_ui ===> tforces = rho S_ui -// -// and scalars psi where (psi = rho q = Scal) as -// -// psi_t + (uj psi)_j = S_psi ===> tforces = S_psi = rho S_q -// -// For non-conservative, this rho-weighted source term will get divided -// by rho in the predict_velocity, velocity_advection, scalar_advection, -// and advection_update routines. -// -// For temperature (which is always non-conservative), we evolve -// -// dT/dt - U dot grad T = [del dot lambda grad T + S_T] / (rho*c_p) -// ===> tforces = S_T/c_p -// -// -// For user-defined forcing, this means -// - For conservative variables, the force term computed here gets used -// as-is -// - For non-conservative variables, the force term computed here is -// divided by rho before use -// - -void -NavierStokesBase::getForce (FArrayBox& force, - const Box& bx, - int scomp, // first component in force - int ncomp, // number of components - const Real time, - const FArrayBox& State, // state data, may not contain all components; e.g. may be velocities only - const FArrayBox& Aux, // auxiliary data - int auxScomp,// first component in Aux - const MFIter& /*mfi*/) -{ - if (ParallelDescriptor::IOProcessor() && getForceVerbose) - { - const int* f_lo = force.loVect(); - const int* f_hi = force.hiVect(); - const int* v_lo = State.loVect(); - const int* v_hi = State.hiVect(); - const int* s_lo = Aux.loVect(); - const int* s_hi = Aux.hiVect(); - - amrex::Print() << "NavierStokesBase::getForce(): Entered..." << std::endl - << "time = " << time << std::endl - << "scomp = " << scomp << std::endl - << "ncomp = " << ncomp << std::endl - << "auxScomp = " << auxScomp << std::endl; - - if (ncomp==1) amrex::Print() << "Doing only component " << scomp << std::endl; - else if (scomp==0 && ncomp==AMREX_SPACEDIM) amrex::Print() << "Doing velocities only" << std::endl; - else if (scomp>=AMREX_SPACEDIM) amrex::Print() << "Doing " << ncomp << " component(s) starting with component " << scomp << std::endl; - - amrex::Print() << "NavierStokesBase::getForce(): Filling Force on box:" - << bx << std::endl; -#if (AMREX_SPACEDIM == 3) - amrex::Print() << "NavierStokesBase::getForce(): Force Domain:" << std::endl; - amrex::Print() << "(" << f_lo[0] << "," << f_lo[1] << "," << f_lo[2] << ") - " - << "(" << f_hi[0] << "," << f_hi[1] << "," << f_hi[2] << ")" << std::endl; - amrex::Print() << "NavierStokesBase::getForce(): Vel Domain:" << std::endl; - amrex::Print() << "(" << v_lo[0] << "," << v_lo[1] << "," << v_lo[2] << ") - " - << "(" << v_hi[0] << "," << v_hi[1] << "," << v_hi[2] << ")" << std::endl; - amrex::Print() << "NavierStokesBase::getForce(): Scal Domain:" << std::endl; - amrex::Print() << "(" << s_lo[0] << "," << s_lo[1] << "," << s_lo[2] << ") - " - << "(" << s_hi[0] << "," << s_hi[1] << "," << s_hi[2] << ")" << std::endl; -#else - amrex::Print() << "NavierStokesBase::getForce(): Force Domain:" << std::endl; - amrex::Print() << "(" << f_lo[0] << "," << f_lo[1] << ") - " - << "(" << f_hi[0] << "," << f_hi[1] << ")" << std::endl; - amrex::Print() << "NavierStokesBase::getForce(): State Domain:" << std::endl; - amrex::Print() << "(" << v_lo[0] << "," << v_lo[1] << ") - " - << "(" << v_hi[0] << "," << v_hi[1] << ")" << std::endl; - amrex::Print() << "NavierStokesBase::getForce(): Aux Domain:" << std::endl; - amrex::Print() << "(" << s_lo[0] << "," << s_lo[1] << ") - " - << "(" << s_hi[0] << "," << s_hi[1] << ")" << std::endl; -#endif - - // Compute min/max - for (int n=0; n(scomp+n) << " / " - << State.max(scomp+n) << std::endl; - } - for (int n=auxScomp; n(n) << " / " - << Aux.max(n) << std::endl; - } - } //end if(getForceVerbose) - - // - // Here's the meat - // - // Velocity forcing - // - if ( scomp=AMREX_SPACEDIM); - } - - if ( scomp==Xvel ){ - // - // TODO: add some switch for user-supplied/problem-dependent forcing - // - auto const& frc = force.array(scomp); - auto const& aux = Aux.array(auxScomp); - const Real grav = gravity; - - if ( std::abs(grav) > 0.0001) { - amrex::ParallelFor(bx, [frc, aux, grav] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - frc(i,j,k,0) = Real(0.0); -#if ( AMREX_SPACEDIM == 2 ) - frc(i,j,k,1) = grav*aux(i,j,k,0); -#elif ( AMREX_SPACEDIM == 3 ) - frc(i,j,k,1) = Real(0.0); - frc(i,j,k,2) = grav*aux(i,j,k,0); -#endif - }); - } - else { - force.setVal(0.0, bx, Xvel, AMREX_SPACEDIM); - } - } - - // - // Scalar forcing - // - // During a regular timestep, getForce is called on scalars only. - // During the multilevel sync, scalars are done with velocity. - // - int scomp_scal = -1; - int ncomp_scal = -1; - if ( scomp >= AMREX_SPACEDIM ) { - // Doing only scalars - scomp_scal = 0; - ncomp_scal = ncomp; - } - // Recall that we will only get here if previous block is false, - // i.e. if scomp < AMREX_SPACEDIM - else if ( scomp+ncomp > AMREX_SPACEDIM) { - // Doing scalars with vel - scomp_scal = Density; - ncomp_scal = ncomp-Density; - } - - if (ncomp_scal > 0) { - force.setVal(0.0, bx, scomp_scal, ncomp_scal); - // - // Or create user-defined forcing. - // Recall we compute a density-weighted forcing term. - // - // auto const& frc = force.array(scomp_scal); - // amrex::ParallelFor(bx, ncomp_scal, [frc] - // AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept - // { - // frc(i,j,k,n) = ; - // frc(i,j,k,n) *= rho; - // }); - } - - if (ParallelDescriptor::IOProcessor() && getForceVerbose) { - // Compute min/max - for (int n=0; n(scomp+n) << " / " - << force.max(scomp+n) << std::endl; - } - - amrex::Print() << "NavierStokesBase::getForce(): Leaving..." - << std::endl << "---" << std::endl; - } -} +// SPDX-FileCopyrightText: 2012 - 2023 Berkeley Lab +// +// SPDX-License-Identifier: LicenseRef-OpenSource + +#include +#include + + +using namespace amrex; + +// +// Virtual access function for getting the forcing terms for the +// velocities and scalars. The base version computes a buoyancy. +// +// NOTE: This function returns a rho weighted source term. +// +// For conservative (i.e. do_mom_diff=1, do_cons_trac=1), velocities +// are integrated according to the equation +// +// ui_t + uj ui_j = S_ui ===> tforces = rho S_ui +// +// and scalars psi where (psi = rho q = Scal) as +// +// psi_t + (uj psi)_j = S_psi ===> tforces = S_psi = rho S_q +// +// For non-conservative, this rho-weighted source term will get divided +// by rho in the predict_velocity, velocity_advection, scalar_advection, +// and advection_update routines. +// +// For temperature (which is always non-conservative), we evolve +// +// dT/dt - U dot grad T = [del dot lambda grad T + S_T] / (rho*c_p) +// ===> tforces = S_T/c_p +// +// +// For user-defined forcing, this means +// - For conservative variables, the force term computed here gets used +// as-is +// - For non-conservative variables, the force term computed here is +// divided by rho before use +// + +void +NavierStokesBase::getForce (FArrayBox& force, + const Box& bx, + int scomp, // first component in force + int ncomp, // number of components + const Real time, + const FArrayBox& State, // state data, may not contain all components; e.g. may be velocities only + const FArrayBox& Aux, // auxiliary data + int auxScomp,// first component in Aux + const MFIter& /*mfi*/) +{ + if (ParallelDescriptor::IOProcessor() && getForceVerbose) + { + const int* f_lo = force.loVect(); + const int* f_hi = force.hiVect(); + const int* v_lo = State.loVect(); + const int* v_hi = State.hiVect(); + const int* s_lo = Aux.loVect(); + const int* s_hi = Aux.hiVect(); + + amrex::Print() << "NavierStokesBase::getForce(): Entered..." << std::endl + << "time = " << time << std::endl + << "scomp = " << scomp << std::endl + << "ncomp = " << ncomp << std::endl + << "auxScomp = " << auxScomp << std::endl; + + if (ncomp==1) amrex::Print() << "Doing only component " << scomp << std::endl; + else if (scomp==0 && ncomp==AMREX_SPACEDIM) amrex::Print() << "Doing velocities only" << std::endl; + else if (scomp>=AMREX_SPACEDIM) amrex::Print() << "Doing " << ncomp << " component(s) starting with component " << scomp << std::endl; + + amrex::Print() << "NavierStokesBase::getForce(): Filling Force on box:" + << bx << std::endl; +#if (AMREX_SPACEDIM == 3) + amrex::Print() << "NavierStokesBase::getForce(): Force Domain:" << std::endl; + amrex::Print() << "(" << f_lo[0] << "," << f_lo[1] << "," << f_lo[2] << ") - " + << "(" << f_hi[0] << "," << f_hi[1] << "," << f_hi[2] << ")" << std::endl; + amrex::Print() << "NavierStokesBase::getForce(): Vel Domain:" << std::endl; + amrex::Print() << "(" << v_lo[0] << "," << v_lo[1] << "," << v_lo[2] << ") - " + << "(" << v_hi[0] << "," << v_hi[1] << "," << v_hi[2] << ")" << std::endl; + amrex::Print() << "NavierStokesBase::getForce(): Scal Domain:" << std::endl; + amrex::Print() << "(" << s_lo[0] << "," << s_lo[1] << "," << s_lo[2] << ") - " + << "(" << s_hi[0] << "," << s_hi[1] << "," << s_hi[2] << ")" << std::endl; +#else + amrex::Print() << "NavierStokesBase::getForce(): Force Domain:" << std::endl; + amrex::Print() << "(" << f_lo[0] << "," << f_lo[1] << ") - " + << "(" << f_hi[0] << "," << f_hi[1] << ")" << std::endl; + amrex::Print() << "NavierStokesBase::getForce(): State Domain:" << std::endl; + amrex::Print() << "(" << v_lo[0] << "," << v_lo[1] << ") - " + << "(" << v_hi[0] << "," << v_hi[1] << ")" << std::endl; + amrex::Print() << "NavierStokesBase::getForce(): Aux Domain:" << std::endl; + amrex::Print() << "(" << s_lo[0] << "," << s_lo[1] << ") - " + << "(" << s_hi[0] << "," << s_hi[1] << ")" << std::endl; +#endif + + // Compute min/max + for (int n=0; n(scomp+n) << " / " + << State.max(scomp+n) << std::endl; + } + for (int n=auxScomp; n(n) << " / " + << Aux.max(n) << std::endl; + } + } //end if(getForceVerbose) + + // + // Here's the meat + // + // Velocity forcing + // + if ( scomp=AMREX_SPACEDIM); + } + + if ( scomp==Xvel ){ + // + // TODO: add some switch for user-supplied/problem-dependent forcing + // + auto const& frc = force.array(scomp); + auto const& aux = Aux.array(auxScomp); + const Real grav = gravity; + + if ( std::abs(grav) > 0.0001) { + amrex::ParallelFor(bx, [frc, aux, grav] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + frc(i,j,k,0) = Real(0.0); +#if ( AMREX_SPACEDIM == 2 ) + frc(i,j,k,1) = grav*aux(i,j,k,0); +#elif ( AMREX_SPACEDIM == 3 ) + frc(i,j,k,1) = Real(0.0); + frc(i,j,k,2) = grav*aux(i,j,k,0); +#endif + }); + } + else { + force.setVal(0.0, bx, Xvel, AMREX_SPACEDIM); + } + } + + // + // Scalar forcing + // + // During a regular timestep, getForce is called on scalars only. + // During the multilevel sync, scalars are done with velocity. + // + int scomp_scal = -1; + int ncomp_scal = -1; + if ( scomp >= AMREX_SPACEDIM ) { + // Doing only scalars + scomp_scal = 0; + ncomp_scal = ncomp; + } + // Recall that we will only get here if previous block is false, + // i.e. if scomp < AMREX_SPACEDIM + else if ( scomp+ncomp > AMREX_SPACEDIM) { + // Doing scalars with vel + scomp_scal = Density; + ncomp_scal = ncomp-Density; + } + + if (ncomp_scal > 0) { + force.setVal(0.0, bx, scomp_scal, ncomp_scal); + // + // Or create user-defined forcing. + // Recall we compute a density-weighted forcing term. + // + // auto const& frc = force.array(scomp_scal); + // amrex::ParallelFor(bx, ncomp_scal, [frc] + // AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept + // { + // frc(i,j,k,n) = ; + // frc(i,j,k,n) *= rho; + // }); + } + + if (ParallelDescriptor::IOProcessor() && getForceVerbose) { + // Compute min/max + for (int n=0; n(scomp+n) << " / " + << force.max(scomp+n) << std::endl; + } + + amrex::Print() << "NavierStokesBase::getForce(): Leaving..." + << std::endl << "---" << std::endl; + } +} diff --git a/Source/NS_init_eb2.cpp b/Source/NS_init_eb2.cpp index b896f087..17da71f7 100644 --- a/Source/NS_init_eb2.cpp +++ b/Source/NS_init_eb2.cpp @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng +// +// SPDX-License-Identifier: BSD-3-Clause + #include using namespace amrex; diff --git a/Source/NS_kernels.H b/Source/NS_kernels.H index 4345fe6c..bf7e12c6 100644 --- a/Source/NS_kernels.H +++ b/Source/NS_kernels.H @@ -1,27 +1,32 @@ - -#ifndef NS_KERNELS_H -#define NS_KERNELS_H - -#include - -using namespace amrex; - -AMREX_INLINE AMREX_GPU_DEVICE -Real minmod(Real alpha_1, Real beta_1) -{ - if (alpha_1 * beta_1 <= 0.0) { - return 0.0; - } - else if (fabs(alpha_1) <= fabs(beta_1)) { - return alpha_1; - } - else { - return beta_1; - } -} - -void cc_to_cc_grad(Array,AMREX_SPACEDIM>& phi_cc_grad, const MultiFab& phi, const Geometry& geom, int normalize); -void cc_grad_to_cc_div(MultiFab& phi_cc_div, Array,AMREX_SPACEDIM>& phi_cc_grad, const Geometry& geom); -void cc_to_cc_lap(MultiFab& phi_cc_lap, MultiFab& phi, const Geometry& geom); -void cc_to_fc(Array,AMREX_SPACEDIM>& phi_fc, const MultiFab& phi, const Geometry& geom); -#endif +/* + * SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef NS_KERNELS_H +#define NS_KERNELS_H + +#include + +using namespace amrex; + +AMREX_INLINE AMREX_GPU_DEVICE +Real minmod(Real alpha_1, Real beta_1) +{ + if (alpha_1 * beta_1 <= 0.0) { + return 0.0; + } + else if (fabs(alpha_1) <= fabs(beta_1)) { + return alpha_1; + } + else { + return beta_1; + } +} + +void cc_to_cc_grad(Array,AMREX_SPACEDIM>& phi_cc_grad, const MultiFab& phi, const Geometry& geom, int normalize); +void cc_grad_to_cc_div(MultiFab& phi_cc_div, Array,AMREX_SPACEDIM>& phi_cc_grad, const Geometry& geom); +void cc_to_cc_lap(MultiFab& phi_cc_lap, MultiFab& phi, const Geometry& geom); +void cc_to_fc(Array,AMREX_SPACEDIM>& phi_fc, const MultiFab& phi, const Geometry& geom); +#endif diff --git a/Source/NS_kernels.cpp b/Source/NS_kernels.cpp index 9b83d129..56ea5943 100644 --- a/Source/NS_kernels.cpp +++ b/Source/NS_kernels.cpp @@ -1,236 +1,239 @@ - -#include - -#include -#include -#include -#include -#include -#include -#include - -using namespace amrex; - -// ls related -// Assume all gts are filled -// phi: cc variables, at least 2 gts -// phi_cc_grad: cc variables, 1 gt -void cc_to_cc_grad(Array,AMREX_SPACEDIM>& phi_cc_grad, const MultiFab& phi, const Geometry& geom, - int normalize) -{ - - Print() << "In the cc_to_cc_grad " << std::endl; - - const BoxArray& ba = phi.boxArray(); - const DistributionMapping& dm = phi.DistributionMap(); - const int ncomp = phi.nComp(); - const int ngrow = phi.nGrow(); - BL_ASSERT(ngrow>=2); - - for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) - { - phi_cc_grad[idim] = std::make_unique(ba, dm, ncomp, 1); - } - - // 1. Calculate the gradient - AMREX_D_TERM(const Real dxi = static_cast(geom.InvCellSize(0));, - const Real dyi = static_cast(geom.InvCellSize(1));, - const Real dzi = static_cast(geom.InvCellSize(2));); -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi, TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.growntilebox(1); // 1 gt - const auto& s = phi.array(mfi); - AMREX_D_TERM(const auto& gx = phi_cc_grad[0]->array(mfi);, - const auto& gy = phi_cc_grad[1]->array(mfi);, - const auto& gz = phi_cc_grad[2]->array(mfi);); - - AMREX_HOST_DEVICE_PARALLEL_FOR_4D ( bx, ncomp, i, j, k, n, - { - gx(i,j,k,n) = 0.5 * dxi*(s(i+1,j,k,n) - s(i-1,j,k,n)); - }); - AMREX_HOST_DEVICE_PARALLEL_FOR_4D ( bx, ncomp, i, j, k, n, - { - gy(i,j,k,n) = 0.5 * dyi*(s(i,j+1,k,n) - s(i,j-1,k,n)); - }); -#if (AMREX_SPACEDIM == 3) - AMREX_HOST_DEVICE_PARALLEL_FOR_4D ( bx, ncomp, i, j, k, n, - { - gz(i,j,k,n) = 0.5 * dzi*(s(i,j,k+1,n) - s(i,j,k-1,n)); - }); -#endif - } - - // 2. Normalize the gradient if needed - if (normalize == 1) { - Real eps = 1.e-10; - FArrayBox magfb; -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi, TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.growntilebox(1); // 1 gt - magfb.resize(bx,ncomp); - Elixir eli = magfb.elixir(); - const auto& mag = magfb.array(); - AMREX_D_TERM(const auto& gx = phi_cc_grad[0]->array(mfi);, - const auto& gy = phi_cc_grad[1]->array(mfi);, - const auto& gz = phi_cc_grad[2]->array(mfi);); -#if (AMREX_SPACEDIM == 2) - ParallelFor(bx, ncomp, [gx, gy, mag] - AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept - { - mag(i,j,k,n) = std::sqrt(gx(i,j,k,n) * gx(i,j,k,n) + gy(i,j,k,n) * gy(i,j,k,n)); - }); - ParallelFor(bx, ncomp, [gx, gy, mag, eps] - AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept - { - gx(i,j,k,n) = gx(i,j,k,n) / (mag(i,j,k,n) + eps); - gy(i,j,k,n) = gy(i,j,k,n) / (mag(i,j,k,n) + eps); - }); -#endif -#if (AMREX_SPACEDIM == 3) - ParallelFor(bx, ncomp, [gx, gy, gz, mag] - AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept - { - mag(i,j,k,n) = std::sqrt(gx(i,j,k,n) * gx(i,j,k,n) + gy(i,j,k,n) * gy(i,j,k,n) + gz(i,j,k,n) * gz(i,j,k,n)); - }); - ParallelFor(bx, ncomp, [gx, gy, gz, mag, eps] - AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept - { - gx(i,j,k,n) = gx(i,j,k,n) / (mag(i,j,k,n) + eps); - gy(i,j,k,n) = gy(i,j,k,n) / (mag(i,j,k,n) + eps); - gz(i,j,k,n) = gz(i,j,k,n) / (mag(i,j,k,n) + eps); - }); -#endif - } - } - - // 2. Normalize the gradient based on phi_max - if (normalize == 2) { - - } - -// const Real* dx = geom.CellSize(); - -} - -// Assume all gts are filled -// phi_cc_grad: cc variables, at least 1 gt -// phi_cc_div: cc variables, 0 gt, it has been defined outside this function -void cc_grad_to_cc_div(MultiFab& phi_cc_div, - Array,AMREX_SPACEDIM>& phi_cc_grad, - const Geometry& geom) -{ - - Print() << "In the cc_grad_to_cc_div " << std::endl; - - const int ncomp = phi_cc_grad[0]->nComp(); - BL_ASSERT(ncomp==phi_cc_div.nComp()); - const int ngrow = phi_cc_grad[0]->nGrow(); - BL_ASSERT(ngrow>=1); - - // 1. Calculate the divergence - AMREX_D_TERM(const Real dxi = static_cast(geom.InvCellSize(0));, - const Real dyi = static_cast(geom.InvCellSize(1));, - const Real dzi = static_cast(geom.InvCellSize(2));); -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi_cc_div, TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); // 0 gt - const auto& s = phi_cc_div.array(mfi); - AMREX_D_TERM(const auto& gx = phi_cc_grad[0]->array(mfi);, - const auto& gy = phi_cc_grad[1]->array(mfi);, - const auto& gz = phi_cc_grad[2]->array(mfi);); - -#if (AMREX_SPACEDIM == 2) - ParallelFor(bx, ncomp, [s, gx, gy, dxi, dyi] - AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept - { - s(i,j,k,n) = 0.5 * dxi*(gx(i+1,j,k,n) - gx(i-1,j,k,n)) + - 0.5 * dyi*(gy(i,j+1,k,n) - gy(i,j-1,k,n)); - }); -#endif -#if (AMREX_SPACEDIM == 3) - ParallelFor(bx, ncomp, [s, gx, gy, gz, dxi, dyi, dzi] - AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept - { - s(i,j,k,n) = 0.5 * dxi*(gx(i+1,j,k,n) - gx(i-1,j,k,n)) + - 0.5 * dyi*(gy(i,j+1,k,n) - gy(i,j-1,k,n)) + - 0.5 * dzi*(gz(i,j,k+1,n) - gz(i,j,k-1,n)); - }); -#endif - } - -} - -// Assume all gts are filled -// phi: cc variables, at least 2 gts -// phi_cc_lap: cc variables, 1 gt, it has been defined outside this function -void cc_to_cc_lap(MultiFab& phi_cc_lap, MultiFab& phi, const Geometry& geom) -{ - - Print() << "In the cc_to_cc_lap " << std::endl; - - const int ncomp = phi.nComp(); - BL_ASSERT(ncomp==phi_cc_lap.nComp()); - const int ngrow = phi.nGrow(); - BL_ASSERT(ngrow>=2); - - // 1. Calculate the divergence - AMREX_D_TERM(const Real dxi = static_cast(geom.InvCellSize(0));, - const Real dyi = static_cast(geom.InvCellSize(1));, - const Real dzi = static_cast(geom.InvCellSize(2));); -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi_cc_lap, TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.growntilebox(1); // 1 gt - const auto& s = phi_cc_lap.array(mfi); - const auto& s_in = phi.array(mfi); - -#if (AMREX_SPACEDIM == 2) - ParallelFor(bx, ncomp, [s, s_in, dxi, dyi] - AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept - { - s(i,j,k,n) = dxi*dxi*(s_in(i+1,j,k,n) - 2.0 * s_in(i,j,k,n) + s_in(i-1,j,k,n)) + - dyi*dyi*(s_in(i,j+1,k,n) - 2.0 * s_in(i,j,k,n) + s_in(i,j-1,k,n)); - }); -#endif -#if (AMREX_SPACEDIM == 3) - ParallelFor(bx, ncomp, [s, s_in, dxi, dyi, dzi] - AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept - { - s(i,j,k,n) = dxi*dxi*(s_in(i+1,j,k,n) - 2.0 * s_in(i,j,k,n) + s_in(i-1,j,k,n)) + - dyi*dyi*(s_in(i,j+1,k,n) - 2.0 * s_in(i,j,k,n) + s_in(i,j-1,k,n)) + - dzi*dzi*(s_in(i,j,k+1,n) - 2.0 * s_in(i,j,k,n) + s_in(i,j,k-1,n)); - }); -#endif - } - -} - -void cc_to_fc(Array,AMREX_SPACEDIM>& phi_fc, const MultiFab& phi, const Geometry& geom) -{ - - Print() << "In the cc_to_fc " << std::endl; - - const BoxArray& ba = phi.boxArray(); - const DistributionMapping& dm = phi.DistributionMap(); - const int ncomp = phi.nComp(); - const int ngrow = phi.nGrow(); - - for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) - { - BoxArray nba = convert(ba,IntVect::TheDimensionVector(idim)); - phi_fc[idim] = std::make_unique(nba, dm, ncomp, 0); - } - average_cellcenter_to_face(GetArrOfPtrs(phi_fc), phi, geom, ncomp); - +// SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng +// +// SPDX-License-Identifier: BSD-3-Clause + +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace amrex; + +// ls related +// Assume all gts are filled +// phi: cc variables, at least 2 gts +// phi_cc_grad: cc variables, 1 gt +void cc_to_cc_grad(Array,AMREX_SPACEDIM>& phi_cc_grad, const MultiFab& phi, const Geometry& geom, + int normalize) +{ + + Print() << "In the cc_to_cc_grad " << std::endl; + + const BoxArray& ba = phi.boxArray(); + const DistributionMapping& dm = phi.DistributionMap(); + const int ncomp = phi.nComp(); + const int ngrow = phi.nGrow(); + BL_ASSERT(ngrow>=2); + + for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) + { + phi_cc_grad[idim] = std::make_unique(ba, dm, ncomp, 1); + } + + // 1. Calculate the gradient + AMREX_D_TERM(const Real dxi = static_cast(geom.InvCellSize(0));, + const Real dyi = static_cast(geom.InvCellSize(1));, + const Real dzi = static_cast(geom.InvCellSize(2));); +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi, TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.growntilebox(1); // 1 gt + const auto& s = phi.array(mfi); + AMREX_D_TERM(const auto& gx = phi_cc_grad[0]->array(mfi);, + const auto& gy = phi_cc_grad[1]->array(mfi);, + const auto& gz = phi_cc_grad[2]->array(mfi);); + + AMREX_HOST_DEVICE_PARALLEL_FOR_4D ( bx, ncomp, i, j, k, n, + { + gx(i,j,k,n) = 0.5 * dxi*(s(i+1,j,k,n) - s(i-1,j,k,n)); + }); + AMREX_HOST_DEVICE_PARALLEL_FOR_4D ( bx, ncomp, i, j, k, n, + { + gy(i,j,k,n) = 0.5 * dyi*(s(i,j+1,k,n) - s(i,j-1,k,n)); + }); +#if (AMREX_SPACEDIM == 3) + AMREX_HOST_DEVICE_PARALLEL_FOR_4D ( bx, ncomp, i, j, k, n, + { + gz(i,j,k,n) = 0.5 * dzi*(s(i,j,k+1,n) - s(i,j,k-1,n)); + }); +#endif + } + + // 2. Normalize the gradient if needed + if (normalize == 1) { + Real eps = 1.e-10; + FArrayBox magfb; +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi, TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.growntilebox(1); // 1 gt + magfb.resize(bx,ncomp); + Elixir eli = magfb.elixir(); + const auto& mag = magfb.array(); + AMREX_D_TERM(const auto& gx = phi_cc_grad[0]->array(mfi);, + const auto& gy = phi_cc_grad[1]->array(mfi);, + const auto& gz = phi_cc_grad[2]->array(mfi);); +#if (AMREX_SPACEDIM == 2) + ParallelFor(bx, ncomp, [gx, gy, mag] + AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept + { + mag(i,j,k,n) = std::sqrt(gx(i,j,k,n) * gx(i,j,k,n) + gy(i,j,k,n) * gy(i,j,k,n)); + }); + ParallelFor(bx, ncomp, [gx, gy, mag, eps] + AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept + { + gx(i,j,k,n) = gx(i,j,k,n) / (mag(i,j,k,n) + eps); + gy(i,j,k,n) = gy(i,j,k,n) / (mag(i,j,k,n) + eps); + }); +#endif +#if (AMREX_SPACEDIM == 3) + ParallelFor(bx, ncomp, [gx, gy, gz, mag] + AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept + { + mag(i,j,k,n) = std::sqrt(gx(i,j,k,n) * gx(i,j,k,n) + gy(i,j,k,n) * gy(i,j,k,n) + gz(i,j,k,n) * gz(i,j,k,n)); + }); + ParallelFor(bx, ncomp, [gx, gy, gz, mag, eps] + AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept + { + gx(i,j,k,n) = gx(i,j,k,n) / (mag(i,j,k,n) + eps); + gy(i,j,k,n) = gy(i,j,k,n) / (mag(i,j,k,n) + eps); + gz(i,j,k,n) = gz(i,j,k,n) / (mag(i,j,k,n) + eps); + }); +#endif + } + } + + // 2. Normalize the gradient based on phi_max + if (normalize == 2) { + + } + +// const Real* dx = geom.CellSize(); + +} + +// Assume all gts are filled +// phi_cc_grad: cc variables, at least 1 gt +// phi_cc_div: cc variables, 0 gt, it has been defined outside this function +void cc_grad_to_cc_div(MultiFab& phi_cc_div, + Array,AMREX_SPACEDIM>& phi_cc_grad, + const Geometry& geom) +{ + + Print() << "In the cc_grad_to_cc_div " << std::endl; + + const int ncomp = phi_cc_grad[0]->nComp(); + BL_ASSERT(ncomp==phi_cc_div.nComp()); + const int ngrow = phi_cc_grad[0]->nGrow(); + BL_ASSERT(ngrow>=1); + + // 1. Calculate the divergence + AMREX_D_TERM(const Real dxi = static_cast(geom.InvCellSize(0));, + const Real dyi = static_cast(geom.InvCellSize(1));, + const Real dzi = static_cast(geom.InvCellSize(2));); +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi_cc_div, TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); // 0 gt + const auto& s = phi_cc_div.array(mfi); + AMREX_D_TERM(const auto& gx = phi_cc_grad[0]->array(mfi);, + const auto& gy = phi_cc_grad[1]->array(mfi);, + const auto& gz = phi_cc_grad[2]->array(mfi);); + +#if (AMREX_SPACEDIM == 2) + ParallelFor(bx, ncomp, [s, gx, gy, dxi, dyi] + AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept + { + s(i,j,k,n) = 0.5 * dxi*(gx(i+1,j,k,n) - gx(i-1,j,k,n)) + + 0.5 * dyi*(gy(i,j+1,k,n) - gy(i,j-1,k,n)); + }); +#endif +#if (AMREX_SPACEDIM == 3) + ParallelFor(bx, ncomp, [s, gx, gy, gz, dxi, dyi, dzi] + AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept + { + s(i,j,k,n) = 0.5 * dxi*(gx(i+1,j,k,n) - gx(i-1,j,k,n)) + + 0.5 * dyi*(gy(i,j+1,k,n) - gy(i,j-1,k,n)) + + 0.5 * dzi*(gz(i,j,k+1,n) - gz(i,j,k-1,n)); + }); +#endif + } + +} + +// Assume all gts are filled +// phi: cc variables, at least 2 gts +// phi_cc_lap: cc variables, 1 gt, it has been defined outside this function +void cc_to_cc_lap(MultiFab& phi_cc_lap, MultiFab& phi, const Geometry& geom) +{ + + Print() << "In the cc_to_cc_lap " << std::endl; + + const int ncomp = phi.nComp(); + BL_ASSERT(ncomp==phi_cc_lap.nComp()); + const int ngrow = phi.nGrow(); + BL_ASSERT(ngrow>=2); + + // 1. Calculate the divergence + AMREX_D_TERM(const Real dxi = static_cast(geom.InvCellSize(0));, + const Real dyi = static_cast(geom.InvCellSize(1));, + const Real dzi = static_cast(geom.InvCellSize(2));); +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi_cc_lap, TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.growntilebox(1); // 1 gt + const auto& s = phi_cc_lap.array(mfi); + const auto& s_in = phi.array(mfi); + +#if (AMREX_SPACEDIM == 2) + ParallelFor(bx, ncomp, [s, s_in, dxi, dyi] + AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept + { + s(i,j,k,n) = dxi*dxi*(s_in(i+1,j,k,n) - 2.0 * s_in(i,j,k,n) + s_in(i-1,j,k,n)) + + dyi*dyi*(s_in(i,j+1,k,n) - 2.0 * s_in(i,j,k,n) + s_in(i,j-1,k,n)); + }); +#endif +#if (AMREX_SPACEDIM == 3) + ParallelFor(bx, ncomp, [s, s_in, dxi, dyi, dzi] + AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept + { + s(i,j,k,n) = dxi*dxi*(s_in(i+1,j,k,n) - 2.0 * s_in(i,j,k,n) + s_in(i-1,j,k,n)) + + dyi*dyi*(s_in(i,j+1,k,n) - 2.0 * s_in(i,j,k,n) + s_in(i,j-1,k,n)) + + dzi*dzi*(s_in(i,j,k+1,n) - 2.0 * s_in(i,j,k,n) + s_in(i,j,k-1,n)); + }); +#endif + } + +} + +void cc_to_fc(Array,AMREX_SPACEDIM>& phi_fc, const MultiFab& phi, const Geometry& geom) +{ + + Print() << "In the cc_to_fc " << std::endl; + + const BoxArray& ba = phi.boxArray(); + const DistributionMapping& dm = phi.DistributionMap(); + const int ncomp = phi.nComp(); + const int ngrow = phi.nGrow(); + + for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) + { + BoxArray nba = convert(ba,IntVect::TheDimensionVector(idim)); + phi_fc[idim] = std::make_unique(nba, dm, ncomp, 0); + } + average_cellcenter_to_face(GetArrOfPtrs(phi_fc), phi, geom, ncomp); + } \ No newline at end of file diff --git a/Source/NS_setup.cpp b/Source/NS_setup.cpp index 7b3421fd..408a11d0 100644 --- a/Source/NS_setup.cpp +++ b/Source/NS_setup.cpp @@ -1,515 +1,519 @@ - - -#include -#include -#include -#include -#include -#include - -using namespace amrex; - -static Box the_same_box (const Box& b) { return b; } -static Box grow_box_by_two (const Box& b) { return amrex::grow(b,2); } - -// NOTE: the int arrays that define the mapping from physical BCs to mathematical -// (norm_vel_bc, tang_vel_bc, scalar_bc, temp_bc, press_bc, divu_bc, dsdt_bc) -// are now all defined in IAMR/Source/NS_BC.H - -static -void -set_x_vel_bc (BCRec& bc, - const BCRec& phys_bc) -{ - const int* lo_bc = phys_bc.lo(); - const int* hi_bc = phys_bc.hi(); - bc.setLo(0,norm_vel_bc[lo_bc[0]]); - bc.setHi(0,norm_vel_bc[hi_bc[0]]); - bc.setLo(1,tang_vel_bc[lo_bc[1]]); - bc.setHi(1,tang_vel_bc[hi_bc[1]]); -#if (AMREX_SPACEDIM == 3) - bc.setLo(2,tang_vel_bc[lo_bc[2]]); - bc.setHi(2,tang_vel_bc[hi_bc[2]]); -#endif -} - -static -void -set_y_vel_bc (BCRec& bc, - const BCRec& phys_bc) -{ - const int* lo_bc = phys_bc.lo(); - const int* hi_bc = phys_bc.hi(); - bc.setLo(0,tang_vel_bc[lo_bc[0]]); - bc.setHi(0,tang_vel_bc[hi_bc[0]]); - bc.setLo(1,norm_vel_bc[lo_bc[1]]); - bc.setHi(1,norm_vel_bc[hi_bc[1]]); -#if (AMREX_SPACEDIM == 3) - bc.setLo(2,tang_vel_bc[lo_bc[2]]); - bc.setHi(2,tang_vel_bc[hi_bc[2]]); -#endif -} - -#if (AMREX_SPACEDIM == 3) -static -void -set_z_vel_bc (BCRec& bc, - const BCRec& phys_bc) -{ - const int* lo_bc = phys_bc.lo(); - const int* hi_bc = phys_bc.hi(); - bc.setLo(0,tang_vel_bc[lo_bc[0]]); - bc.setHi(0,tang_vel_bc[hi_bc[0]]); - bc.setLo(1,tang_vel_bc[lo_bc[1]]); - bc.setHi(1,tang_vel_bc[hi_bc[1]]); - bc.setLo(2,norm_vel_bc[lo_bc[2]]); - bc.setHi(2,norm_vel_bc[hi_bc[2]]); -} -#endif - -static -void -set_scalar_bc (BCRec& bc, - const BCRec& phys_bc, - const std::string& advection) -{ - const int* lo_bc = phys_bc.lo(); - const int* hi_bc = phys_bc.hi(); - for (int i = 0; i < AMREX_SPACEDIM; i++) - { - if (advection == "BDS"){ - bc.setLo(i,bds_scalar_bc[lo_bc[i]]); - bc.setHi(i,bds_scalar_bc[hi_bc[i]]); - } - else { - bc.setLo(i,scalar_bc[lo_bc[i]]); - bc.setHi(i,scalar_bc[hi_bc[i]]); - } - } -} - -static -void -set_temp_bc (BCRec& bc, - const BCRec& phys_bc) -{ - const int* lo_bc = phys_bc.lo(); - const int* hi_bc = phys_bc.hi(); - for (int i = 0; i < AMREX_SPACEDIM; i++) - { - bc.setLo(i,temp_bc[lo_bc[i]]); - bc.setHi(i,temp_bc[hi_bc[i]]); - } -} - -static -void -set_pressure_bc (BCRec& bc, - const BCRec& phys_bc) -{ - const int* lo_bc = phys_bc.lo(); - const int* hi_bc = phys_bc.hi(); - for (int i = 0; i < AMREX_SPACEDIM; i++) - { - bc.setLo(i,press_bc[lo_bc[i]]); - bc.setHi(i,press_bc[hi_bc[i]]); - } -} - -static -void -set_gradpx_bc (BCRec& bc, - const BCRec& phys_bc) -{ - const int* lo_bc = phys_bc.lo(); - const int* hi_bc = phys_bc.hi(); - bc.setLo(0,norm_gradp_bc[lo_bc[0]]); - bc.setHi(0,norm_gradp_bc[hi_bc[0]]); - bc.setLo(1,tang_gradp_bc[lo_bc[1]]); - bc.setHi(1,tang_gradp_bc[hi_bc[1]]); -#if (AMREX_SPACEDIM == 3) - bc.setLo(2,tang_gradp_bc[lo_bc[2]]); - bc.setHi(2,tang_gradp_bc[hi_bc[2]]); -#endif -} - -static -void -set_gradpy_bc (BCRec& bc, - const BCRec& phys_bc) -{ - const int* lo_bc = phys_bc.lo(); - const int* hi_bc = phys_bc.hi(); - bc.setLo(0,tang_gradp_bc[lo_bc[0]]); - bc.setHi(0,tang_gradp_bc[hi_bc[0]]); - bc.setLo(1,norm_gradp_bc[lo_bc[1]]); - bc.setHi(1,norm_gradp_bc[hi_bc[1]]); -#if (AMREX_SPACEDIM == 3) - bc.setLo(2,tang_gradp_bc[lo_bc[2]]); - bc.setHi(2,tang_gradp_bc[hi_bc[2]]); -#endif -} - -#if (AMREX_SPACEDIM == 3) -static -void -set_gradpz_bc (BCRec& bc, - const BCRec& phys_bc) -{ - const int* lo_bc = phys_bc.lo(); - const int* hi_bc = phys_bc.hi(); - bc.setLo(0,tang_gradp_bc[lo_bc[0]]); - bc.setHi(0,tang_gradp_bc[hi_bc[0]]); - bc.setLo(1,tang_gradp_bc[lo_bc[1]]); - bc.setHi(1,tang_gradp_bc[hi_bc[1]]); - bc.setLo(2,norm_gradp_bc[lo_bc[2]]); - bc.setHi(2,norm_gradp_bc[hi_bc[2]]); -} -#endif - -static -void -set_divu_bc(BCRec& bc, const BCRec& phys_bc) -{ - const int* lo_bc = phys_bc.lo(); - const int* hi_bc = phys_bc.hi(); - for (int i = 0; i < AMREX_SPACEDIM; i++) - { - bc.setLo(i,divu_bc[lo_bc[i]]); - bc.setHi(i,divu_bc[hi_bc[i]]); - } -} - -static -void -set_dsdt_bc(BCRec& bc, const BCRec& phys_bc) -{ - const int* lo_bc = phys_bc.lo(); - const int* hi_bc = phys_bc.hi(); - for (int i = 0; i < AMREX_SPACEDIM; i++) - { - bc.setLo(i,dsdt_bc[lo_bc[i]]); - bc.setHi(i,dsdt_bc[hi_bc[i]]); - } -} - -static -void -set_average_bc(BCRec& bc, const BCRec& phys_bc) -{ - const int* lo_bc = phys_bc.lo(); - const int* hi_bc = phys_bc.hi(); - for (int i = 0; i < AMREX_SPACEDIM; i++) - { - bc.setLo(i,average_bc[lo_bc[i]]); - bc.setHi(i,average_bc[hi_bc[i]]); - } -} - - -typedef StateDescriptor::BndryFunc BndryFunc; - -// -// Get EB-aware interpolater when needed -// -#ifdef AMREX_USE_EB - static auto& cc_interp = eb_cell_cons_interp; -#else - static auto& cc_interp = cell_cons_interp; -#endif - -void -NavierStokes::variableSetUp () -{ - AMREX_ASSERT(desc_lst.size() == 0); - - Initialize(); - - BCRec bc; - - // - // ************** DEFINE VELOCITY VARIABLES ******************** - // - bool state_data_extrap = false; - bool store_in_checkpoint = true; - desc_lst.addDescriptor(State_Type,IndexType::TheCellType(), - StateDescriptor::Point,NUM_GROW,NUM_STATE, - &cc_interp,state_data_extrap,store_in_checkpoint); - // TODO: state does not really need to carry ghost cells, since it is the - // philosophy of IAMR to FillPatch before using. - // However, changing NUM_GROW here creates a problem for restarting from - // older checkpoint files with more ghost cells, so a workaround is - // needed. - - BndryFunc vel_bf(vel_fill); - vel_bf.setRunOnGPU(true); - - BndryFunc state_bf(state_fill); - state_bf.setRunOnGPU(true); - - BndryFunc press_bf(press_fill); - press_bf.setRunOnGPU(true); - - BndryFunc null_bf(dummy_fill); - null_bf.setRunOnGPU(true); - - BndryFunc homogeneous_bf(homogeneous_fill); - homogeneous_bf.setRunOnGPU(true); - - set_x_vel_bc(bc,phys_bc); - desc_lst.setComponent(State_Type,Xvel,"x_velocity",bc,vel_bf); - - set_y_vel_bc(bc,phys_bc); - desc_lst.setComponent(State_Type,Yvel,"y_velocity",bc,vel_bf); - -#if (AMREX_SPACEDIM == 3) - set_z_vel_bc(bc,phys_bc); - desc_lst.setComponent(State_Type,Zvel,"z_velocity",bc,vel_bf); -#endif - // Note: the vel_bf will nor directly call vel_fill within the setComponent function. - // It calls when needed. See the amr_level.setPhysBoundaryValues(S_new[mfi],State_Type,curr_time,Xvel,Xvel,AMREX_SPACEDIM) function - // in the Projection::initialVelocityProject function. - // - // ************** DEFINE SCALAR VARIABLES ******************** - // - set_scalar_bc(bc,phys_bc,advection_scheme); - desc_lst.setComponent(State_Type,Density,"density",bc,state_bf); - - set_scalar_bc(bc,phys_bc,advection_scheme); - desc_lst.setComponent(State_Type,Tracer,"tracer",bc,state_bf); - - if (do_trac2) - { - set_scalar_bc(bc,phys_bc,advection_scheme); - desc_lst.setComponent(State_Type,Tracer2,"tracer2",bc,state_bf); - } - // - // ************** DEFINE TEMPERATURE ******************** - // - if (do_temp) - { - set_temp_bc(bc,phys_bc); - desc_lst.setComponent(State_Type,Temp,"temp",bc,state_bf); - } - // - // ls related - // I still use the set_scalar_bc here. May need improvement. - // - if (do_phi) { - set_scalar_bc(bc,phys_bc,advection_scheme); - desc_lst.setComponent(State_Type,phicomp,"phi",bc,state_bf); - } - - is_diffusive.resize(NUM_STATE); - advectionType.resize(NUM_STATE); - diffusionType.resize(NUM_STATE); - for (int i = 0; i < NUM_STATE; i++) - { - advectionType[i] = NonConservative; - diffusionType[i] = RhoInverse_Laplacian_S; - is_diffusive[i] = false; - if (visc_coef[i] > 0.0) - is_diffusive[i] = true; - } - - if (do_mom_diff == 1) { - amrex::Print() << "Using conservative scheme with do_mom_diff = " << do_mom_diff << "\n"; - } - else { - amrex::Print() << "Using non-conservative scheme with do_mom_diff = " << do_mom_diff << "\n"; - } - - - if (do_mom_diff == 1) - for (int d = 0; d < AMREX_SPACEDIM; d++) - advectionType[Xvel+d] = Conservative; - - advectionType[Density] = Conservative; - if (do_temp) advectionType[Temp] = NonConservative; - - advectionType[Tracer] = NonConservative; - diffusionType[Tracer] = Laplacian_S; - if (do_cons_trac) { - advectionType[Tracer] = Conservative; - diffusionType[Tracer] = Laplacian_SoverRho; - amrex::Print() << "Using conservative advection update for tracer.\n"; - } - - if (do_trac2) { - advectionType[Tracer2] = NonConservative; - diffusionType[Tracer2] = Laplacian_S; - if (do_cons_trac2) { - advectionType[Tracer2] = Conservative; - diffusionType[Tracer2] = Laplacian_SoverRho; - amrex::Print() << "Using conservative advection update for tracer2.\n"; - } - } - - if (is_diffusive[Density]) - { - amrex::Error("Density cannot diffuse, bad visc_coef"); - } - // - // ls related - // - if (do_phi) { - advectionType[phicomp] = NonConservative; - diffusionType[phicomp] = Laplacian_S; - if (do_cons_phi) { - advectionType[phicomp] = Conservative; - diffusionType[phicomp] = Laplacian_SoverRho; - amrex::Print() << "Using conservative advection update for phi.\n"; - } - if (is_diffusive[phicomp]) - { - amrex::Error("phi cannot diffuse"); - } - } - - // - // ---- pressure - // - desc_lst.addDescriptor(Press_Type,IndexType::TheNodeType(), - StateDescriptor::Interval,1,1, - &node_bilinear_interp); - - set_pressure_bc(bc,phys_bc); - desc_lst.setComponent(Press_Type,Pressure,"pressure",bc,press_bf); - - // - // ---- grad P - // - desc_lst.addDescriptor(Gradp_Type,IndexType::TheCellType(), - StateDescriptor::Interval,gradp_grow,AMREX_SPACEDIM, - &cc_interp,state_data_extrap,store_in_checkpoint); - - Vector bcs(AMREX_SPACEDIM); - Vector name(AMREX_SPACEDIM); - - set_gradpx_bc(bc,phys_bc); - bcs[0] = bc; - name[0] = "gradpx"; - - set_gradpy_bc(bc,phys_bc); - bcs[1] = bc; - name[1] = "gradpy"; - -#if(AMREX_SPACEDIM==3) - set_gradpz_bc(bc,phys_bc); - bcs[2] = bc; - name[2] = "gradpz"; -#endif - - desc_lst.setComponent(Gradp_Type, Gradpx, name, bcs, null_bf); - - // - // ---- Additions for using Temperature - // - if (do_temp) - { - // stick Divu_Type on the end of the descriptor list - Divu_Type = desc_lst.size(); - int nGrowDivu = 1; - desc_lst.addDescriptor(Divu_Type,IndexType::TheCellType(), - StateDescriptor::Point,nGrowDivu,1, - &cc_interp); - set_divu_bc(bc,phys_bc); - desc_lst.setComponent(Divu_Type,Divu,"divu",bc,null_bf); - - // stick Dsdt_Type on the end of the descriptor list - Dsdt_Type = desc_lst.size(); - int nGrowDsdt = 0; - desc_lst.addDescriptor(Dsdt_Type,IndexType::TheCellType(), - StateDescriptor::Point,nGrowDsdt,1, - &cc_interp); - set_dsdt_bc(bc,phys_bc); - desc_lst.setComponent(Dsdt_Type,Dsdt,"dsdt",bc,homogeneous_bf); - } - - // - // For using on-the-fly averaging - // - if (NavierStokesBase::avg_interval > 0) - { - Average_Type = desc_lst.size(); - desc_lst.addDescriptor(Average_Type,IndexType::TheCellType(), - StateDescriptor::Point,0,AMREX_SPACEDIM*2, - &cc_interp,state_data_extrap,store_in_checkpoint); - - set_average_bc(bc,phys_bc); - desc_lst.setComponent(Average_Type,Xvel,"xvel_avg_dummy",bc,null_bf); - desc_lst.setComponent(Average_Type,Xvel+AMREX_SPACEDIM,"xvel_rms_dummy",bc,null_bf); - desc_lst.setComponent(Average_Type,Yvel,"yvel_avg_dummy",bc,null_bf); - desc_lst.setComponent(Average_Type,Yvel+AMREX_SPACEDIM,"yvel_rms_dummy",bc,null_bf); -#if (AMREX_SPACEDIM==3) - desc_lst.setComponent(Average_Type,Zvel,"zvel_avg_dummy",bc,null_bf); - desc_lst.setComponent(Average_Type,Zvel+AMREX_SPACEDIM,"zvel_rms_dummy",bc,null_bf); -#endif - } - - // - // ************** DEFINE DERIVED QUANTITIES ******************** - // - using namespace derive_functions; - - if (NavierStokesBase::avg_interval > 0) - { - // - // Average and RMS velocity - // - Vector var_names_ave(AMREX_SPACEDIM*2); - var_names_ave[Xvel] = "x_vel_average"; - var_names_ave[Yvel] = "y_vel_average"; -#if (AMREX_SPACEDIM==3) - var_names_ave[Zvel] = "z_vel_average"; -#endif - var_names_ave[Xvel+AMREX_SPACEDIM] = "x_vel_rms"; - var_names_ave[Yvel+AMREX_SPACEDIM] = "y_vel_rms"; -#if (AMREX_SPACEDIM==3) - var_names_ave[Zvel+AMREX_SPACEDIM] = "z_vel_rms"; -#endif - derive_lst.add("velocity_average",IndexType::TheCellType(),AMREX_SPACEDIM*2, - var_names_ave,der_vel_avg,the_same_box); - derive_lst.addComponent("velocity_average",desc_lst,Average_Type,Xvel,AMREX_SPACEDIM*2); - } - - // - // kinetic energy - // - derive_lst.add("energy",IndexType::TheCellType(),1,derkeng,the_same_box); - derive_lst.addComponent("energy",desc_lst,State_Type,Density,1); - derive_lst.addComponent("energy",desc_lst,State_Type,Xvel,AMREX_SPACEDIM); - // - // magnitude of vorticity - // - derive_lst.add("mag_vort",IndexType::TheCellType(),1,dermgvort,grow_box_by_two); - derive_lst.addComponent("mag_vort",desc_lst,State_Type,Xvel,AMREX_SPACEDIM); - // - // average pressure - // - derive_lst.add("avg_pressure",IndexType::TheCellType(),1,deravgpres, - the_same_box); - derive_lst.addComponent("avg_pressure",desc_lst,Press_Type,Pressure,1); - -#ifdef AMREX_PARTICLES - if (do_nspc) { - // - // The particle count at this level. - // - derive_lst.add("particle_count",IndexType::TheCellType(),1, - dernull,the_same_box); - derive_lst.addComponent("particle_count",desc_lst,State_Type,Density,1); - // - // The total # of particles at our level or above. - // - derive_lst.add("total_particle_count",IndexType::TheCellType(),1, - dernull,the_same_box); - derive_lst.addComponent("total_particle_count",desc_lst,State_Type,Density,1); - } -#endif - - // - // ************** DEFINE ERROR ESTIMATION QUANTITIES ************* - // - error_setup(); -} +// SPDX-FileCopyrightText: 1997 - 2023 Berkeley Lab; 2023 - 2025 Yadong Zeng +// +// SPDX-License-Identifier: LicenseRef-OpenSource +// Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +// Original source: https://github.com/AMReX-Fluids/IAMR + +#include +#include +#include +#include +#include +#include + +using namespace amrex; + +static Box the_same_box (const Box& b) { return b; } +static Box grow_box_by_two (const Box& b) { return amrex::grow(b,2); } + +// NOTE: the int arrays that define the mapping from physical BCs to mathematical +// (norm_vel_bc, tang_vel_bc, scalar_bc, temp_bc, press_bc, divu_bc, dsdt_bc) +// are now all defined in IAMR/Source/NS_BC.H + +static +void +set_x_vel_bc (BCRec& bc, + const BCRec& phys_bc) +{ + const int* lo_bc = phys_bc.lo(); + const int* hi_bc = phys_bc.hi(); + bc.setLo(0,norm_vel_bc[lo_bc[0]]); + bc.setHi(0,norm_vel_bc[hi_bc[0]]); + bc.setLo(1,tang_vel_bc[lo_bc[1]]); + bc.setHi(1,tang_vel_bc[hi_bc[1]]); +#if (AMREX_SPACEDIM == 3) + bc.setLo(2,tang_vel_bc[lo_bc[2]]); + bc.setHi(2,tang_vel_bc[hi_bc[2]]); +#endif +} + +static +void +set_y_vel_bc (BCRec& bc, + const BCRec& phys_bc) +{ + const int* lo_bc = phys_bc.lo(); + const int* hi_bc = phys_bc.hi(); + bc.setLo(0,tang_vel_bc[lo_bc[0]]); + bc.setHi(0,tang_vel_bc[hi_bc[0]]); + bc.setLo(1,norm_vel_bc[lo_bc[1]]); + bc.setHi(1,norm_vel_bc[hi_bc[1]]); +#if (AMREX_SPACEDIM == 3) + bc.setLo(2,tang_vel_bc[lo_bc[2]]); + bc.setHi(2,tang_vel_bc[hi_bc[2]]); +#endif +} + +#if (AMREX_SPACEDIM == 3) +static +void +set_z_vel_bc (BCRec& bc, + const BCRec& phys_bc) +{ + const int* lo_bc = phys_bc.lo(); + const int* hi_bc = phys_bc.hi(); + bc.setLo(0,tang_vel_bc[lo_bc[0]]); + bc.setHi(0,tang_vel_bc[hi_bc[0]]); + bc.setLo(1,tang_vel_bc[lo_bc[1]]); + bc.setHi(1,tang_vel_bc[hi_bc[1]]); + bc.setLo(2,norm_vel_bc[lo_bc[2]]); + bc.setHi(2,norm_vel_bc[hi_bc[2]]); +} +#endif + +static +void +set_scalar_bc (BCRec& bc, + const BCRec& phys_bc, + const std::string& advection) +{ + const int* lo_bc = phys_bc.lo(); + const int* hi_bc = phys_bc.hi(); + for (int i = 0; i < AMREX_SPACEDIM; i++) + { + if (advection == "BDS"){ + bc.setLo(i,bds_scalar_bc[lo_bc[i]]); + bc.setHi(i,bds_scalar_bc[hi_bc[i]]); + } + else { + bc.setLo(i,scalar_bc[lo_bc[i]]); + bc.setHi(i,scalar_bc[hi_bc[i]]); + } + } +} + +static +void +set_temp_bc (BCRec& bc, + const BCRec& phys_bc) +{ + const int* lo_bc = phys_bc.lo(); + const int* hi_bc = phys_bc.hi(); + for (int i = 0; i < AMREX_SPACEDIM; i++) + { + bc.setLo(i,temp_bc[lo_bc[i]]); + bc.setHi(i,temp_bc[hi_bc[i]]); + } +} + +static +void +set_pressure_bc (BCRec& bc, + const BCRec& phys_bc) +{ + const int* lo_bc = phys_bc.lo(); + const int* hi_bc = phys_bc.hi(); + for (int i = 0; i < AMREX_SPACEDIM; i++) + { + bc.setLo(i,press_bc[lo_bc[i]]); + bc.setHi(i,press_bc[hi_bc[i]]); + } +} + +static +void +set_gradpx_bc (BCRec& bc, + const BCRec& phys_bc) +{ + const int* lo_bc = phys_bc.lo(); + const int* hi_bc = phys_bc.hi(); + bc.setLo(0,norm_gradp_bc[lo_bc[0]]); + bc.setHi(0,norm_gradp_bc[hi_bc[0]]); + bc.setLo(1,tang_gradp_bc[lo_bc[1]]); + bc.setHi(1,tang_gradp_bc[hi_bc[1]]); +#if (AMREX_SPACEDIM == 3) + bc.setLo(2,tang_gradp_bc[lo_bc[2]]); + bc.setHi(2,tang_gradp_bc[hi_bc[2]]); +#endif +} + +static +void +set_gradpy_bc (BCRec& bc, + const BCRec& phys_bc) +{ + const int* lo_bc = phys_bc.lo(); + const int* hi_bc = phys_bc.hi(); + bc.setLo(0,tang_gradp_bc[lo_bc[0]]); + bc.setHi(0,tang_gradp_bc[hi_bc[0]]); + bc.setLo(1,norm_gradp_bc[lo_bc[1]]); + bc.setHi(1,norm_gradp_bc[hi_bc[1]]); +#if (AMREX_SPACEDIM == 3) + bc.setLo(2,tang_gradp_bc[lo_bc[2]]); + bc.setHi(2,tang_gradp_bc[hi_bc[2]]); +#endif +} + +#if (AMREX_SPACEDIM == 3) +static +void +set_gradpz_bc (BCRec& bc, + const BCRec& phys_bc) +{ + const int* lo_bc = phys_bc.lo(); + const int* hi_bc = phys_bc.hi(); + bc.setLo(0,tang_gradp_bc[lo_bc[0]]); + bc.setHi(0,tang_gradp_bc[hi_bc[0]]); + bc.setLo(1,tang_gradp_bc[lo_bc[1]]); + bc.setHi(1,tang_gradp_bc[hi_bc[1]]); + bc.setLo(2,norm_gradp_bc[lo_bc[2]]); + bc.setHi(2,norm_gradp_bc[hi_bc[2]]); +} +#endif + +static +void +set_divu_bc(BCRec& bc, const BCRec& phys_bc) +{ + const int* lo_bc = phys_bc.lo(); + const int* hi_bc = phys_bc.hi(); + for (int i = 0; i < AMREX_SPACEDIM; i++) + { + bc.setLo(i,divu_bc[lo_bc[i]]); + bc.setHi(i,divu_bc[hi_bc[i]]); + } +} + +static +void +set_dsdt_bc(BCRec& bc, const BCRec& phys_bc) +{ + const int* lo_bc = phys_bc.lo(); + const int* hi_bc = phys_bc.hi(); + for (int i = 0; i < AMREX_SPACEDIM; i++) + { + bc.setLo(i,dsdt_bc[lo_bc[i]]); + bc.setHi(i,dsdt_bc[hi_bc[i]]); + } +} + +static +void +set_average_bc(BCRec& bc, const BCRec& phys_bc) +{ + const int* lo_bc = phys_bc.lo(); + const int* hi_bc = phys_bc.hi(); + for (int i = 0; i < AMREX_SPACEDIM; i++) + { + bc.setLo(i,average_bc[lo_bc[i]]); + bc.setHi(i,average_bc[hi_bc[i]]); + } +} + + +typedef StateDescriptor::BndryFunc BndryFunc; + +// +// Get EB-aware interpolater when needed +// +#ifdef AMREX_USE_EB + static auto& cc_interp = eb_cell_cons_interp; +#else + static auto& cc_interp = cell_cons_interp; +#endif + +void +NavierStokes::variableSetUp () +{ + AMREX_ASSERT(desc_lst.size() == 0); + + Initialize(); + + BCRec bc; + + // + // ************** DEFINE VELOCITY VARIABLES ******************** + // + bool state_data_extrap = false; + bool store_in_checkpoint = true; + desc_lst.addDescriptor(State_Type,IndexType::TheCellType(), + StateDescriptor::Point,NUM_GROW,NUM_STATE, + &cc_interp,state_data_extrap,store_in_checkpoint); + // TODO: state does not really need to carry ghost cells, since it is the + // philosophy of IAMR to FillPatch before using. + // However, changing NUM_GROW here creates a problem for restarting from + // older checkpoint files with more ghost cells, so a workaround is + // needed. + + BndryFunc vel_bf(vel_fill); + vel_bf.setRunOnGPU(true); + + BndryFunc state_bf(state_fill); + state_bf.setRunOnGPU(true); + + BndryFunc press_bf(press_fill); + press_bf.setRunOnGPU(true); + + BndryFunc null_bf(dummy_fill); + null_bf.setRunOnGPU(true); + + BndryFunc homogeneous_bf(homogeneous_fill); + homogeneous_bf.setRunOnGPU(true); + + set_x_vel_bc(bc,phys_bc); + desc_lst.setComponent(State_Type,Xvel,"x_velocity",bc,vel_bf); + + set_y_vel_bc(bc,phys_bc); + desc_lst.setComponent(State_Type,Yvel,"y_velocity",bc,vel_bf); + +#if (AMREX_SPACEDIM == 3) + set_z_vel_bc(bc,phys_bc); + desc_lst.setComponent(State_Type,Zvel,"z_velocity",bc,vel_bf); +#endif + // Note: the vel_bf will nor directly call vel_fill within the setComponent function. + // It calls when needed. See the amr_level.setPhysBoundaryValues(S_new[mfi],State_Type,curr_time,Xvel,Xvel,AMREX_SPACEDIM) function + // in the Projection::initialVelocityProject function. + // + // ************** DEFINE SCALAR VARIABLES ******************** + // + set_scalar_bc(bc,phys_bc,advection_scheme); + desc_lst.setComponent(State_Type,Density,"density",bc,state_bf); + + set_scalar_bc(bc,phys_bc,advection_scheme); + desc_lst.setComponent(State_Type,Tracer,"tracer",bc,state_bf); + + if (do_trac2) + { + set_scalar_bc(bc,phys_bc,advection_scheme); + desc_lst.setComponent(State_Type,Tracer2,"tracer2",bc,state_bf); + } + // + // ************** DEFINE TEMPERATURE ******************** + // + if (do_temp) + { + set_temp_bc(bc,phys_bc); + desc_lst.setComponent(State_Type,Temp,"temp",bc,state_bf); + } + // + // ls related + // I still use the set_scalar_bc here. May need improvement. + // + if (do_phi) { + set_scalar_bc(bc,phys_bc,advection_scheme); + desc_lst.setComponent(State_Type,phicomp,"phi",bc,state_bf); + } + + is_diffusive.resize(NUM_STATE); + advectionType.resize(NUM_STATE); + diffusionType.resize(NUM_STATE); + for (int i = 0; i < NUM_STATE; i++) + { + advectionType[i] = NonConservative; + diffusionType[i] = RhoInverse_Laplacian_S; + is_diffusive[i] = false; + if (visc_coef[i] > 0.0) + is_diffusive[i] = true; + } + + if (do_mom_diff == 1) { + amrex::Print() << "Using conservative scheme with do_mom_diff = " << do_mom_diff << "\n"; + } + else { + amrex::Print() << "Using non-conservative scheme with do_mom_diff = " << do_mom_diff << "\n"; + } + + + if (do_mom_diff == 1) + for (int d = 0; d < AMREX_SPACEDIM; d++) + advectionType[Xvel+d] = Conservative; + + advectionType[Density] = Conservative; + if (do_temp) advectionType[Temp] = NonConservative; + + advectionType[Tracer] = NonConservative; + diffusionType[Tracer] = Laplacian_S; + if (do_cons_trac) { + advectionType[Tracer] = Conservative; + diffusionType[Tracer] = Laplacian_SoverRho; + amrex::Print() << "Using conservative advection update for tracer.\n"; + } + + if (do_trac2) { + advectionType[Tracer2] = NonConservative; + diffusionType[Tracer2] = Laplacian_S; + if (do_cons_trac2) { + advectionType[Tracer2] = Conservative; + diffusionType[Tracer2] = Laplacian_SoverRho; + amrex::Print() << "Using conservative advection update for tracer2.\n"; + } + } + + if (is_diffusive[Density]) + { + amrex::Error("Density cannot diffuse, bad visc_coef"); + } + // + // ls related + // + if (do_phi) { + advectionType[phicomp] = NonConservative; + diffusionType[phicomp] = Laplacian_S; + if (do_cons_phi) { + advectionType[phicomp] = Conservative; + diffusionType[phicomp] = Laplacian_SoverRho; + amrex::Print() << "Using conservative advection update for phi.\n"; + } + if (is_diffusive[phicomp]) + { + amrex::Error("phi cannot diffuse"); + } + } + + // + // ---- pressure + // + desc_lst.addDescriptor(Press_Type,IndexType::TheNodeType(), + StateDescriptor::Interval,1,1, + &node_bilinear_interp); + + set_pressure_bc(bc,phys_bc); + desc_lst.setComponent(Press_Type,Pressure,"pressure",bc,press_bf); + + // + // ---- grad P + // + desc_lst.addDescriptor(Gradp_Type,IndexType::TheCellType(), + StateDescriptor::Interval,gradp_grow,AMREX_SPACEDIM, + &cc_interp,state_data_extrap,store_in_checkpoint); + + Vector bcs(AMREX_SPACEDIM); + Vector name(AMREX_SPACEDIM); + + set_gradpx_bc(bc,phys_bc); + bcs[0] = bc; + name[0] = "gradpx"; + + set_gradpy_bc(bc,phys_bc); + bcs[1] = bc; + name[1] = "gradpy"; + +#if(AMREX_SPACEDIM==3) + set_gradpz_bc(bc,phys_bc); + bcs[2] = bc; + name[2] = "gradpz"; +#endif + + desc_lst.setComponent(Gradp_Type, Gradpx, name, bcs, null_bf); + + // + // ---- Additions for using Temperature + // + if (do_temp) + { + // stick Divu_Type on the end of the descriptor list + Divu_Type = desc_lst.size(); + int nGrowDivu = 1; + desc_lst.addDescriptor(Divu_Type,IndexType::TheCellType(), + StateDescriptor::Point,nGrowDivu,1, + &cc_interp); + set_divu_bc(bc,phys_bc); + desc_lst.setComponent(Divu_Type,Divu,"divu",bc,null_bf); + + // stick Dsdt_Type on the end of the descriptor list + Dsdt_Type = desc_lst.size(); + int nGrowDsdt = 0; + desc_lst.addDescriptor(Dsdt_Type,IndexType::TheCellType(), + StateDescriptor::Point,nGrowDsdt,1, + &cc_interp); + set_dsdt_bc(bc,phys_bc); + desc_lst.setComponent(Dsdt_Type,Dsdt,"dsdt",bc,homogeneous_bf); + } + + // + // For using on-the-fly averaging + // + if (NavierStokesBase::avg_interval > 0) + { + Average_Type = desc_lst.size(); + desc_lst.addDescriptor(Average_Type,IndexType::TheCellType(), + StateDescriptor::Point,0,AMREX_SPACEDIM*2, + &cc_interp,state_data_extrap,store_in_checkpoint); + + set_average_bc(bc,phys_bc); + desc_lst.setComponent(Average_Type,Xvel,"xvel_avg_dummy",bc,null_bf); + desc_lst.setComponent(Average_Type,Xvel+AMREX_SPACEDIM,"xvel_rms_dummy",bc,null_bf); + desc_lst.setComponent(Average_Type,Yvel,"yvel_avg_dummy",bc,null_bf); + desc_lst.setComponent(Average_Type,Yvel+AMREX_SPACEDIM,"yvel_rms_dummy",bc,null_bf); +#if (AMREX_SPACEDIM==3) + desc_lst.setComponent(Average_Type,Zvel,"zvel_avg_dummy",bc,null_bf); + desc_lst.setComponent(Average_Type,Zvel+AMREX_SPACEDIM,"zvel_rms_dummy",bc,null_bf); +#endif + } + + // + // ************** DEFINE DERIVED QUANTITIES ******************** + // + using namespace derive_functions; + + if (NavierStokesBase::avg_interval > 0) + { + // + // Average and RMS velocity + // + Vector var_names_ave(AMREX_SPACEDIM*2); + var_names_ave[Xvel] = "x_vel_average"; + var_names_ave[Yvel] = "y_vel_average"; +#if (AMREX_SPACEDIM==3) + var_names_ave[Zvel] = "z_vel_average"; +#endif + var_names_ave[Xvel+AMREX_SPACEDIM] = "x_vel_rms"; + var_names_ave[Yvel+AMREX_SPACEDIM] = "y_vel_rms"; +#if (AMREX_SPACEDIM==3) + var_names_ave[Zvel+AMREX_SPACEDIM] = "z_vel_rms"; +#endif + derive_lst.add("velocity_average",IndexType::TheCellType(),AMREX_SPACEDIM*2, + var_names_ave,der_vel_avg,the_same_box); + derive_lst.addComponent("velocity_average",desc_lst,Average_Type,Xvel,AMREX_SPACEDIM*2); + } + + // + // kinetic energy + // + derive_lst.add("energy",IndexType::TheCellType(),1,derkeng,the_same_box); + derive_lst.addComponent("energy",desc_lst,State_Type,Density,1); + derive_lst.addComponent("energy",desc_lst,State_Type,Xvel,AMREX_SPACEDIM); + // + // magnitude of vorticity + // + derive_lst.add("mag_vort",IndexType::TheCellType(),1,dermgvort,grow_box_by_two); + derive_lst.addComponent("mag_vort",desc_lst,State_Type,Xvel,AMREX_SPACEDIM); + // + // average pressure + // + derive_lst.add("avg_pressure",IndexType::TheCellType(),1,deravgpres, + the_same_box); + derive_lst.addComponent("avg_pressure",desc_lst,Press_Type,Pressure,1); + +#ifdef AMREX_PARTICLES + if (do_nspc) { + // + // The particle count at this level. + // + derive_lst.add("particle_count",IndexType::TheCellType(),1, + dernull,the_same_box); + derive_lst.addComponent("particle_count",desc_lst,State_Type,Density,1); + // + // The total # of particles at our level or above. + // + derive_lst.add("total_particle_count",IndexType::TheCellType(),1, + dernull,the_same_box); + derive_lst.addComponent("total_particle_count",desc_lst,State_Type,Density,1); + } +#endif + + // + // ************** DEFINE ERROR ESTIMATION QUANTITIES ************* + // + error_setup(); +} diff --git a/Source/NS_util.H b/Source/NS_util.H index 0d75e8f8..3a00b939 100644 --- a/Source/NS_util.H +++ b/Source/NS_util.H @@ -1,50 +1,56 @@ -#ifndef NS_util_H -#define NS_util_H - -#include -#include - -namespace amrex -{ - amrex::Vector - VectorMax(const amrex::Vector& mf, - const amrex::IntVect& tilesize, - int sComp, - int nComp, - int nGrow); - - amrex::Vector - VectorMin(const amrex::Vector& mf, - const amrex::IntVect& tilesize, - int sComp, - int nComp, - int nGrow); - - amrex::Vector - VectorMaxAbs(const amrex::Vector& mf, - const amrex::IntVect& tilesize, - int sComp, - int nComp, - int nGrow); - - - template - Gpu::DeviceVector - convertToDeviceVector ( Vector v) - { - int ncomp = v.size(); - Gpu::DeviceVector v_d(ncomp); -#ifdef AMREX_USE_GPU - Gpu::htod_memcpy -#else - std::memcpy -#endif - (v_d.data(), v.data(), sizeof(T)*ncomp); - - return v_d; - } - - -} - -#endif +/* + * SPDX-FileCopyrightText: 2019 - 2023 Berkeley Lab + * + * SPDX-License-Identifier: LicenseRef-OpenSource + */ + +#ifndef NS_util_H +#define NS_util_H + +#include +#include + +namespace amrex +{ + amrex::Vector + VectorMax(const amrex::Vector& mf, + const amrex::IntVect& tilesize, + int sComp, + int nComp, + int nGrow); + + amrex::Vector + VectorMin(const amrex::Vector& mf, + const amrex::IntVect& tilesize, + int sComp, + int nComp, + int nGrow); + + amrex::Vector + VectorMaxAbs(const amrex::Vector& mf, + const amrex::IntVect& tilesize, + int sComp, + int nComp, + int nGrow); + + + template + Gpu::DeviceVector + convertToDeviceVector ( Vector v) + { + int ncomp = v.size(); + Gpu::DeviceVector v_d(ncomp); +#ifdef AMREX_USE_GPU + Gpu::htod_memcpy +#else + std::memcpy +#endif + (v_d.data(), v.data(), sizeof(T)*ncomp); + + return v_d; + } + + +} + +#endif diff --git a/Source/NS_util.cpp b/Source/NS_util.cpp index a1d377a3..548db378 100644 --- a/Source/NS_util.cpp +++ b/Source/NS_util.cpp @@ -1,79 +1,83 @@ -#include - -#include -#ifdef _OPENMP -#include -#endif - -namespace amrex { - - Vector - VectorMax(const Vector& mfs, - const IntVect& /*tilesize*/, - int sComp, - int nComp, - int nGrow) - { - Vector gMax(nComp); - - for (int n=0; nmax(sComp+n,nGrow); - } - - for (int i=1; imax(sComp+n,nGrow)); - } - } - - return gMax; - } - - Vector - VectorMaxAbs(const Vector& mfs, - const IntVect& /*tilesize*/, - int sComp, - int nComp, - int nGrow) - { - Vector gMaxAbs(nComp); - - for (int n=0; nnorm0(sComp+n,nGrow,false, true); - } - - for (int i=1; inorm0(sComp+n,nGrow,false,true)); - } - } - - return gMaxAbs; - } - - Vector - VectorMin(const Vector& mfs, - const IntVect& /*tilesize*/, - int sComp, - int nComp, - int nGrow) - { - Vector gMin(nComp); - - for (int n=0; nmin(sComp+n,nGrow); - } - - for (int i=1; imin(sComp+n,nGrow)); - } - } - - return gMin; - } - -} +// SPDX-FileCopyrightText: 2019 - 2023 Berkeley Lab +// +// SPDX-License-Identifier: LicenseRef-OpenSource + +#include + +#include +#ifdef _OPENMP +#include +#endif + +namespace amrex { + + Vector + VectorMax(const Vector& mfs, + const IntVect& /*tilesize*/, + int sComp, + int nComp, + int nGrow) + { + Vector gMax(nComp); + + for (int n=0; nmax(sComp+n,nGrow); + } + + for (int i=1; imax(sComp+n,nGrow)); + } + } + + return gMax; + } + + Vector + VectorMaxAbs(const Vector& mfs, + const IntVect& /*tilesize*/, + int sComp, + int nComp, + int nGrow) + { + Vector gMaxAbs(nComp); + + for (int n=0; nnorm0(sComp+n,nGrow,false, true); + } + + for (int i=1; inorm0(sComp+n,nGrow,false,true)); + } + } + + return gMaxAbs; + } + + Vector + VectorMin(const Vector& mfs, + const IntVect& /*tilesize*/, + int sComp, + int nComp, + int nGrow) + { + Vector gMin(nComp); + + for (int n=0; nmin(sComp+n,nGrow); + } + + for (int i=1; imin(sComp+n,nGrow)); + } + } + + return gMin; + } + +} diff --git a/Source/NavierStokes.H b/Source/NavierStokes.H index f6a820ae..fcc85493 100644 --- a/Source/NavierStokes.H +++ b/Source/NavierStokes.H @@ -1,278 +1,285 @@ - -#ifndef IAMR_NavierStokes_H_ -#define IAMR_NavierStokes_H_ - -#include -#include -#include "Utilities.H" - -class NSBld - : - public amrex::LevelBld -{ - void variableSetUp () override; - void variableCleanUp () override; - amrex::AmrLevel *operator() () override; - amrex::AmrLevel *operator() (amrex::Amr& papa, - int lev, - const amrex::Geometry& level_geom, - const amrex::BoxArray& ba, - const amrex::DistributionMapping& dm, - amrex::Real time) override; -}; - -class NavierStokes - : - public NavierStokesBase -{ -public: - - friend class Projection; - friend class MacProj; - friend class Diffusion; - - NavierStokes (); - - NavierStokes (amrex::Amr& papa, - int lev, - const amrex::Geometry& level_geom, - const amrex::BoxArray& bl, - const amrex::DistributionMapping& dm, - amrex::Real time); - - ~NavierStokes () override = default; - - NavierStokes (NavierStokes const&) = delete; - NavierStokes (NavierStokes &&) = delete; - NavierStokes& operator= (NavierStokes const&) = delete; - NavierStokes& operator= (NavierStokes &&) = delete; - - //////////////////////////////////////////////////////////////////////////// - // AmrLevel virtual functions // - //////////////////////////////////////////////////////////////////////////// - // - // Init grid data at problem start-up. - // - void initData () override; - // - // Problem initialization functions - // -#include "prob_init.H" - // - // Build/fill any additional data structures after restart. - // - void post_restart () override; - // - // Do pre-plotfile work - // - void writePlotFilePre (const std::string& dir, - std::ostream& os) override; - // - // Do post-plotfile work - // - void writePlotFilePost (const std::string& dir, - std::ostream& os) override; - // - // Modify list of variables to be plotted - // - void setPlotVariables() override; - // - // Returns a amrex::MultiFab containing the derived data for this level. - // The user is responsible for deleting this pointer when done - // with it. If ngrow>0 the amrex::MultiFab is built on the appropriately - // grown BoxArray. - // - std::unique_ptr - derive (const std::string& name, amrex::Real time, int ngrow) override; - // - // This version of derive() fills the dcomp'th component of mf with the derived quantity. - // - void derive (const std::string& name, - amrex::Real time, - amrex::MultiFab& mf, - int dcomp) override; - // - // Insure state, and pressure are consistent. - // - void post_init (amrex::Real stop_time) override; - // - // Advance grids at this level in time. - // - amrex::Real advance (amrex::Real time, - amrex::Real dt, - int iteration, - int ncycle) override; - - // ls related - amrex::Real advance_semistaggered_twophase_ls (amrex::Real time, - amrex::Real dt, - int iteration, - int ncycle); -#ifdef AMREX_PARTICLES - amrex::Real advance_semistaggered_fsi_diffusedib (amrex::Real time, - amrex::Real dt, - int iteration, - int ncycle); -#endif - - amrex::Real advance_semistaggered_twophase_phasefield (amrex::Real time, - amrex::Real dt, - int iteration, - int ncycle); - - //////////////////////////////////////////////////////////////////////////// - // NavierStokesBase public virtual functions // - //////////////////////////////////////////////////////////////////////////// - - // - // Compute the mac sync correction. - // - void mac_sync () override; - // - // Reflux function. - // - void reflux () override; - // - // Calculate divU, which sets them to zero by default. - // - void calc_divu (amrex::Real time, - amrex::Real dt, - amrex::MultiFab& divu) override; - - //////////////////////////////////////////////////////////////////////////// - // NavierStokes public static functions // - //////////////////////////////////////////////////////////////////////////// - - // - // Define data descriptors. - // - static void variableSetUp (); - - // - // ls related - // - // Max possible number of scalars is 5: Density, 2 Tracers, Temperature, ls - static constexpr int NUM_STATE_MAX = AMREX_SPACEDIM+5; - static amrex::GpuArray, AMREX_SPACEDIM*2> - //static auto - get_bc_values () { return m_bc_values; } - - //////////////////////////////////////////////////////////////////////////// - // NavierStokes public functions // - //////////////////////////////////////////////////////////////////////////// - - // - // Advect scalars. - // - void scalar_advection (amrex::Real dt, - int fscalar, - int lscalar); - // - void scalar_diffusion_update (amrex::Real dt, - int first_scalar, - int last_scalar); - -protected: - - //////////////////////////////////////////////////////////////////////////// - // Overriding Virtual Functions in NavierStokesBase // - //////////////////////////////////////////////////////////////////////////// - - void avgDown () override; // Average down for all the state types. - // - // Calculate nonuniform viscosity and diffusivity - // - void calcViscosity (amrex::Real time, - amrex::Real dt, - int iteration, - int ncycle) override; - // - void calcDiffusivity (amrex::Real time) override; - // - void getViscosity (amrex::MultiFab* viscosity[AMREX_SPACEDIM], - amrex::Real time) override; - // - // Compute viscous terms. - // - void getViscTerms (amrex::MultiFab& visc_terms, - int src_comp, - int ncomp, - amrex::Real time) override; - // - void sum_integrated_quantities () override; - // - void velocity_diffusion_update (amrex::Real dt) override; - - //////////////////////////////////////////////////////////////////////////// - // NavierStokes protected static functions // - //////////////////////////////////////////////////////////////////////////// - - void errorEst (amrex::TagBoxArray& tags, - int clearval, - int tagval, - amrex::Real time, - int n_error_buf, - int ngrow) override; - - static void Initialize (); // Read input file - static void Initialize_bcs (); - static void Initialize_diffusivities (); - static void Finalize (); - -private: - - static void getDiffusivity (amrex::MultiFab* diffusivity[AMREX_SPACEDIM], - amrex::Real time, - int state_comp, - int dst_comp, - int ncomp); - - NavierStokes& getLevel (int lev) { - return dynamic_cast ( parent->getLevel(lev) ); - } - - // - // Initialize the pressure by iterating the initial timestep. - // - void post_init_press (amrex::Real& dt_init, - amrex::Vector& nc_save, - amrex::Vector& dt_save); - // - // Update scalars, (viscous solve in scalar_update). - // - void scalar_update (amrex::Real dt, - int first_scalar, - int last_scalar); - // - // Define error estimators - // - static void error_setup (); - - /////////////////// - // Private data // - /////////////////// - - // - // Runtime parameters - // - // For EB, set all covered cells to zero (1, default), or show whatever is - // in covered cells in plotfile (0). - static int set_plot_coveredCell_val; - - // - // Holds info for dynamically generated error estimators - // - static amrex::Vector errtags; - - // - // Hold external Dirichlet BC values - // - // - // ls related - // - // Max possible number of scalars is 5: Density, 2 Tracers, Temperature, ls - static amrex::GpuArray, - AMREX_SPACEDIM*2> m_bc_values; -}; - -#endif /*_NavierStokes_H_*/ +/* + * SPDX-FileCopyrightText: 1997 - 2023 Berkeley Lab; 2023 - 2025 Yadong Zeng & ZhuXu Li<1246206018@qq.com> + * + * SPDX-License-Identifier: LicenseRef-OpenSource + * Modified from IAMR, originally developed at Lawrence Berkeley National Lab. + * Original source: https://github.com/AMReX-Fluids/IAMR + */ + +#ifndef IAMR_NavierStokes_H_ +#define IAMR_NavierStokes_H_ + +#include +#include +#include "Utilities.H" + +class NSBld + : + public amrex::LevelBld +{ + void variableSetUp () override; + void variableCleanUp () override; + amrex::AmrLevel *operator() () override; + amrex::AmrLevel *operator() (amrex::Amr& papa, + int lev, + const amrex::Geometry& level_geom, + const amrex::BoxArray& ba, + const amrex::DistributionMapping& dm, + amrex::Real time) override; +}; + +class NavierStokes + : + public NavierStokesBase +{ +public: + + friend class Projection; + friend class MacProj; + friend class Diffusion; + + NavierStokes (); + + NavierStokes (amrex::Amr& papa, + int lev, + const amrex::Geometry& level_geom, + const amrex::BoxArray& bl, + const amrex::DistributionMapping& dm, + amrex::Real time); + + ~NavierStokes () override = default; + + NavierStokes (NavierStokes const&) = delete; + NavierStokes (NavierStokes &&) = delete; + NavierStokes& operator= (NavierStokes const&) = delete; + NavierStokes& operator= (NavierStokes &&) = delete; + + //////////////////////////////////////////////////////////////////////////// + // AmrLevel virtual functions // + //////////////////////////////////////////////////////////////////////////// + // + // Init grid data at problem start-up. + // + void initData () override; + // + // Problem initialization functions + // +#include "prob_init.H" + // + // Build/fill any additional data structures after restart. + // + void post_restart () override; + // + // Do pre-plotfile work + // + void writePlotFilePre (const std::string& dir, + std::ostream& os) override; + // + // Do post-plotfile work + // + void writePlotFilePost (const std::string& dir, + std::ostream& os) override; + // + // Modify list of variables to be plotted + // + void setPlotVariables() override; + // + // Returns a amrex::MultiFab containing the derived data for this level. + // The user is responsible for deleting this pointer when done + // with it. If ngrow>0 the amrex::MultiFab is built on the appropriately + // grown BoxArray. + // + std::unique_ptr + derive (const std::string& name, amrex::Real time, int ngrow) override; + // + // This version of derive() fills the dcomp'th component of mf with the derived quantity. + // + void derive (const std::string& name, + amrex::Real time, + amrex::MultiFab& mf, + int dcomp) override; + // + // Insure state, and pressure are consistent. + // + void post_init (amrex::Real stop_time) override; + // + // Advance grids at this level in time. + // + amrex::Real advance (amrex::Real time, + amrex::Real dt, + int iteration, + int ncycle) override; + + // ls related + amrex::Real advance_semistaggered_twophase_ls (amrex::Real time, + amrex::Real dt, + int iteration, + int ncycle); +#ifdef AMREX_PARTICLES + amrex::Real advance_semistaggered_fsi_diffusedib (amrex::Real time, + amrex::Real dt, + int iteration, + int ncycle); +#endif + + amrex::Real advance_semistaggered_twophase_phasefield (amrex::Real time, + amrex::Real dt, + int iteration, + int ncycle); + + //////////////////////////////////////////////////////////////////////////// + // NavierStokesBase public virtual functions // + //////////////////////////////////////////////////////////////////////////// + + // + // Compute the mac sync correction. + // + void mac_sync () override; + // + // Reflux function. + // + void reflux () override; + // + // Calculate divU, which sets them to zero by default. + // + void calc_divu (amrex::Real time, + amrex::Real dt, + amrex::MultiFab& divu) override; + + //////////////////////////////////////////////////////////////////////////// + // NavierStokes public static functions // + //////////////////////////////////////////////////////////////////////////// + + // + // Define data descriptors. + // + static void variableSetUp (); + + // + // ls related + // + // Max possible number of scalars is 5: Density, 2 Tracers, Temperature, ls + static constexpr int NUM_STATE_MAX = AMREX_SPACEDIM+5; + static amrex::GpuArray, AMREX_SPACEDIM*2> + //static auto + get_bc_values () { return m_bc_values; } + + //////////////////////////////////////////////////////////////////////////// + // NavierStokes public functions // + //////////////////////////////////////////////////////////////////////////// + + // + // Advect scalars. + // + void scalar_advection (amrex::Real dt, + int fscalar, + int lscalar); + // + void scalar_diffusion_update (amrex::Real dt, + int first_scalar, + int last_scalar); + +protected: + + //////////////////////////////////////////////////////////////////////////// + // Overriding Virtual Functions in NavierStokesBase // + //////////////////////////////////////////////////////////////////////////// + + void avgDown () override; // Average down for all the state types. + // + // Calculate nonuniform viscosity and diffusivity + // + void calcViscosity (amrex::Real time, + amrex::Real dt, + int iteration, + int ncycle) override; + // + void calcDiffusivity (amrex::Real time) override; + // + void getViscosity (amrex::MultiFab* viscosity[AMREX_SPACEDIM], + amrex::Real time) override; + // + // Compute viscous terms. + // + void getViscTerms (amrex::MultiFab& visc_terms, + int src_comp, + int ncomp, + amrex::Real time) override; + // + void sum_integrated_quantities () override; + // + void velocity_diffusion_update (amrex::Real dt) override; + + //////////////////////////////////////////////////////////////////////////// + // NavierStokes protected static functions // + //////////////////////////////////////////////////////////////////////////// + + void errorEst (amrex::TagBoxArray& tags, + int clearval, + int tagval, + amrex::Real time, + int n_error_buf, + int ngrow) override; + + static void Initialize (); // Read input file + static void Initialize_bcs (); + static void Initialize_diffusivities (); + static void Finalize (); + +private: + + static void getDiffusivity (amrex::MultiFab* diffusivity[AMREX_SPACEDIM], + amrex::Real time, + int state_comp, + int dst_comp, + int ncomp); + + NavierStokes& getLevel (int lev) { + return dynamic_cast ( parent->getLevel(lev) ); + } + + // + // Initialize the pressure by iterating the initial timestep. + // + void post_init_press (amrex::Real& dt_init, + amrex::Vector& nc_save, + amrex::Vector& dt_save); + // + // Update scalars, (viscous solve in scalar_update). + // + void scalar_update (amrex::Real dt, + int first_scalar, + int last_scalar); + // + // Define error estimators + // + static void error_setup (); + + /////////////////// + // Private data // + /////////////////// + + // + // Runtime parameters + // + // For EB, set all covered cells to zero (1, default), or show whatever is + // in covered cells in plotfile (0). + static int set_plot_coveredCell_val; + + // + // Holds info for dynamically generated error estimators + // + static amrex::Vector errtags; + + // + // Hold external Dirichlet BC values + // + // + // ls related + // + // Max possible number of scalars is 5: Density, 2 Tracers, Temperature, ls + static amrex::GpuArray, + AMREX_SPACEDIM*2> m_bc_values; +}; + +#endif /*_NavierStokes_H_*/ diff --git a/Source/NavierStokes.cpp b/Source/NavierStokes.cpp index 7a835a8b..9531ab65 100644 --- a/Source/NavierStokes.cpp +++ b/Source/NavierStokes.cpp @@ -1,2964 +1,2970 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef AMREX_PARTICLES -#include -#endif - -#ifdef BL_USE_VELOCITY -#include -#include -#endif - -#ifdef AMREX_USE_EB -#include -#endif - - -using namespace amrex; - -int NavierStokes::set_plot_coveredCell_val = 1; - -namespace -{ - bool initialized = false; -} - -Vector NavierStokes::errtags; -GpuArray, AMREX_SPACEDIM*2> NavierStokes::m_bc_values; - -void -NavierStokes::Initialize () -{ - if (initialized) return; - - NavierStokesBase::Initialize(); - - // - // Set number of state variables. - // - NUM_STATE = Density + 1; - Tracer = NUM_STATE++; - if (do_trac2) - Tracer2 = NUM_STATE++; - if (do_temp) - Temp = NUM_STATE++; - - // - // ls related - // - if (do_phi) - phicomp = NUM_STATE++; - if (verbose) - amrex::Print() << "do_phi, phicomp, NUM_STATE " << do_phi << " " << phicomp << " " << NUM_STATE << std::endl; - - // - // ls related - // - // NUM_STATE_MAX is defined in NavierStokes.H - // to be AMREX_SPACEDIM + 5 (for Density, 2 scalars, Temp, ls) - AMREX_ALWAYS_ASSERT(NUM_STATE <= NUM_STATE_MAX); - - NUM_SCALARS = NUM_STATE - Density; - - NavierStokes::Initialize_bcs(); - - NavierStokes::Initialize_diffusivities(); - - amrex::ExecOnFinalize(NavierStokes::Finalize); - - initialized = true; -} - -void -NavierStokes::Initialize_bcs () -{ - // - // Default BC values - // - int ntrac = do_trac2 ? 2 : 1; - for (OrientationIter face; face; ++face) - { - int ori = int(face()); - AMREX_D_TERM(m_bc_values[ori][0] = 0.0;, - m_bc_values[ori][1] = 0.0;, - m_bc_values[ori][2] = 0.0;); - m_bc_values[ori][Density] = 1.0; - for ( int nc = 0; nc < ntrac; nc++ ) - m_bc_values[ori][Tracer+nc] = 0.0; - if (do_temp) - m_bc_values[ori][Temp] = 1.0; - // - // ls related - // - if (do_phi) - m_bc_values[ori][phicomp] = 0.0; - } - - ParmParse pp("ns"); - - // - // Check for integer BC type specification in inputs file (older style) - // - if ( pp.contains("lo_bc") ) - { - Vector lo_bc(AMREX_SPACEDIM), hi_bc(AMREX_SPACEDIM); - pp.getarr("lo_bc",lo_bc,0,AMREX_SPACEDIM); - pp.getarr("hi_bc",hi_bc,0,AMREX_SPACEDIM); - for (int i = 0; i < AMREX_SPACEDIM; i++) - { - phys_bc.setLo(i,lo_bc[i]); - phys_bc.setHi(i,hi_bc[i]); - } - } - - // - // Read string BC specifications and BC values - // - { - int bc_tmp[2*AMREX_SPACEDIM]; - - auto f = [&bc_tmp] (std::string const& bcid, Orientation ori) - { - ParmParse pbc(bcid); - std::string bc_type_in = "null"; - pbc.query("type", bc_type_in); - std::string bc_type = amrex::toLower(bc_type_in); - - if (bc_type == "no_slip_wall" or bc_type == "nsw" - or phys_bc.data()[ori] == PhysBCType::noslipwall) - { - amrex::Print() << bcid <<" set to no-slip wall.\n"; - - bc_tmp[ori] = PhysBCType::noslipwall; - - // Note that m_bc_velocity defaults to 0 above so we are ok if - // queryarr finds nothing - std::vector v; - if (pbc.queryarr("velocity", v, 0, AMREX_SPACEDIM)) { - // Here we make sure that we only use the tangential components - // of a specified velocity field -- the wall is not allowed - // to move in the normal direction - v[ori.coordDir()] = 0.0; - for (int i=0; i v; - if (pbc.queryarr("velocity", v, 0, AMREX_SPACEDIM)) { - for (int i=0; i 1 ) - amrex::Abort("NavierStokes::Initialize_specific: Please set tracer 2 inflow bc value with it's own entry in inputs file, e.g. xlo.tracer2 = bc_value"); - pbc.query("tracer2", m_bc_values[ori][Tracer2]); - } - if (do_temp) - pbc.query("temp", m_bc_values[ori][Temp]); - } - else if (bc_type == "pressure_inflow" or bc_type == "pi") - { - amrex::Abort("NavierStokes::Initialize_specific: Pressure inflow boundary condition not yet implemented. If needed for your simulation, please contact us."); - - // amrex::Print() << bcid << " set to pressure inflow.\n"; - - // bc_tmp[ori] = PhysBCType::pressure_inflow; - - // pbc.get("pressure", m_bc_pressure[ori]); - } - else if (bc_type == "pressure_outflow" or bc_type == "po" - or phys_bc.data()[ori] == PhysBCType::outflow) - { - amrex::Print() << bcid << " set to pressure outflow.\n"; - - bc_tmp[ori] = PhysBCType::outflow; - - //pbc.query("pressure", m_bc_pressure[ori]); - Real tmp = 0.; - pbc.query("pressure", tmp); - - if ( tmp != 0. ) - amrex::Abort("NavierStokes::Initialize_specific: Pressure outflow boundary condition != 0 not yet implemented. If needed for your simulation, please contact us."); - } - else if (bc_type == "symmetry" or bc_type == "sym") - { - amrex::Print() << bcid <<" set to symmetry.\n"; - - bc_tmp[ori] = PhysBCType::symmetry; - } - else - { - bc_tmp[ori] = BCType::bogus; - } - - if ( DefaultGeometry().isPeriodic(ori.coordDir()) ) { - if (bc_tmp[ori] == BCType::bogus || phys_bc.data()[ori] == PhysBCType::interior) { - bc_tmp[ori] = PhysBCType::interior; - } else { - std::cerr << " Wrong BC type for periodic boundary at " - << bcid << ". Please correct inputs file."< scal_diff_coefs(n_scal_diff_coefs); - pp.getarr("scal_diff_coefs",scal_diff_coefs,0,n_scal_diff_coefs); - - int scalId = Density; - - for (int i = 0; i < n_scal_diff_coefs; i++) - { - visc_coef[++scalId] = scal_diff_coefs[i]; - } - // - // Set the coefficient for temperature. - // - if (do_temp) - { - pp.get("temp_cond_coef",visc_coef[++scalId]); - } - // - // ls related - // - if (do_phi) - { - visc_coef[phicomp] = -1; - } -} - -void -NavierStokes::Finalize () -{ - initialized = false; -} - -NavierStokes::NavierStokes () = default; - -NavierStokes::NavierStokes (Amr& papa, - int lev, - const Geometry& level_geom, - const BoxArray& bl, - const DistributionMapping& dm, - Real time) - : - NavierStokesBase(papa,lev,level_geom,bl,dm,time) -{ } - -// -// This function initializes the State and Pressure with data. -// -void -NavierStokes::initData () -{ - // - // Initialize the state and the pressure. - // - prob_initData(); - - // - // Initialize GradP - // - computeGradP(state[Press_Type].curTime()); - - // - // Initialize averaging, if using - // - if (avg_interval > 0){ - MultiFab& Save_new = get_new_data(Average_Type); - Save_new.setVal(0.); - } - - -#ifdef BL_USE_VELOCITY - { - // - // We want to add the velocity from the supplied plotfile - // to what we already put into the velocity field via FORT_INITDATA. - // - // This code has a few drawbacks. It assumes that the physical - // domain size of the current problem is the same as that of the - // one that generated the pltfile. It also assumes that the pltfile - // has at least as many levels (with the same refinement ratios) as does - // the current problem. If either of these are false this code is - // likely to core dump. - // - - ParmParse pp("ns"); - - std::string velocity_plotfile; - pp.query("velocity_plotfile", velocity_plotfile); - - std::string velocity_plotfile_xvel_name = "x_velocity"; - pp.query("velocity_plotfile_xvel_name", velocity_plotfile_xvel_name); - - Real velocity_plotfile_scale(1.0); - pp.query("velocity_plotfile_scale",velocity_plotfile_scale); - - if (!velocity_plotfile.empty()) - { - Print() << "initData: reading data from: " << velocity_plotfile << " (" - << velocity_plotfile_xvel_name << ")" << '\n'; - - DataServices::SetBatchMode(); - Amrvis::FileType fileType(Amrvis::NEWPLT); - DataServices dataServices(velocity_plotfile, fileType); - - if (!dataServices.AmrDataOk()) - // - // This calls ParallelDescriptor::EndParallel() and exit() - // - DataServices::Dispatch(DataServices::ExitRequest, NULL); - - AmrData& amrData = dataServices.AmrDataRef(); - Vector plotnames = amrData.PlotVarNames(); - - int idX = -1; - for (int i = 0; i < plotnames.size(); ++i) - if (plotnames[i] == velocity_plotfile_xvel_name) idX = i; - - if (idX == -1) - Abort("Could not find velocity fields in supplied velocity_plotfile"); - else - Print() << "Found " << velocity_plotfile_xvel_name << ", idX = " << idX << '\n'; - - MultiFab& S_new = get_new_data(State_Type); - MultiFab tmp(S_new.boxArray(), S_new.DistributionMap(), 1, 0); - for (int i = 0; i < AMREX_SPACEDIM; i++) - { - amrData.FillVar(tmp, level, plotnames[idX+i], 0); - - MultiFab::Saxpy(S_new, velocity_plotfile_scale, tmp, 0, Xvel+i, 1, 0); - - amrData.FlushGrids(idX+i); - } - - Print() << "initData: finished init from velocity_plotfile" << '\n'; - } - } -#endif /*BL_USE_VELOCITY*/ - -#ifdef AMREX_USE_EB - // - // Perform redistribution on initial fields - // This changes the input velocity fields - // - if (redistribution_type == "StateRedist") { - InitialRedistribution(); - } - - // - // Make sure EB covered cell are set, and that it's not zero, as we - // sometimes divide by rho. - // - { - MultiFab& S_new = get_new_data(State_Type); - EB_set_covered(S_new, COVERED_VAL); - - // - // In some cases, it may be necessary for the covered cells to - // contain a value typical (or around the same order of magnitude) - // to the uncovered cells (e.g. if code to compute variable - // viscosity fails for COVERED_VAL). - // - // set_body_state(S_new); - } -#endif - - // - // Make rho MFs with filled ghost cells - // Not really sure why these are needed as opposed to just filling the - // the ghost cells in state and using that. - // - make_rho_prev_time(); - make_rho_curr_time(); - - // - // Initialize divU and dSdt. - // - if (have_divu) - { - const Real dt = 1.0; - const Real dtin = -1.0; // Dummy value denotes initialization. - const Real curTime = state[Divu_Type].curTime(); - MultiFab& Divu_new = get_new_data(Divu_Type); - - state[State_Type].setTimeLevel(curTime,dt,dt); - - //Make sure something reasonable is in diffn_ec - calcDiffusivity(curTime); - - calc_divu(curTime,dtin,Divu_new); - - if (have_dsdt) - get_new_data(Dsdt_Type).setVal(0); - } - -#ifdef AMREX_PARTICLES - if (do_nspc) { - initParticleData (); - } -#endif -} - -// -// Build/fill any additional data structures after restart. -// -void -NavierStokes::post_restart () -{ - NavierStokesBase::post_restart(); - - //Get probtype, ub, and shearrate; NS_bcfill.H may expect them. - ParmParse pp("prob"); - pp.query("probtype",probtype); - pp.query("ub",ub); - pp.query("shearrate",shearrate); -} - -// -// ADVANCE FUNCTIONS -// - -// -// This function ensures that the multifab registers and boundary -// flux registers needed for syncing the composite grid -// -// u_mac, Vsync, Ssync, rhoavg, fr_adv, fr_visc -// -// are initialized to zero. In general these quantities -// along with the pressure sync registers (sync_reg) and -// advective velocity registers (mac_reg) are compiled by first -// setting them to the coarse value acquired during a coarse timestep -// and then incrementing in the fine values acquired during the -// subcycled fine timesteps. This compilation procedure occurs in -// different parts for different quantities -// -// * u_mac is set in predict_velocity and mac_project. -// * fr_adv, fr_visc are set in velocity_advect and scalar_advect -// * Vsync, Ssync are set in subcycled calls to post_timestep -// * mac_reg is set in mac_project -// * sync_reg is set in level_project -// * rhoavg, pavg are set in advance_setup and advance -// -// After these quantities have been compiled during a coarse -// timestep and subcycled fine timesteps. The post_timestep function -// uses them to sync the fine and coarse levels. If the coarse level -// is not the base level, post_timestep modifies the next coarsest levels -// registers appropriately. -// -// Note :: There is a little ambiguity as to which level owns the -// boundary flux registers. The Multifab registers are quantities -// sized by the coarse level BoxArray and belong to the coarse level. -// The fine levels own the boundary registers, since they are sized by -// the boundaries of the fine level BoxArray. -// - -// -// Compute a timestep at a level. Return largest safe timestep. -// - -Real -NavierStokes::advance (Real time, - Real dt, - int iteration, - int ncycle) -{ - BL_PROFILE("NavierStokes::advance()"); - - //if (verbose) - //{ - Print() << "Advancing grids at level " << level - << " : starting time = " << time - << " with dt = " << dt - << std::endl; - //} - - advance_setup(time,dt,iteration,ncycle); - - amrex::Real dt_test = 0.0; - if (isolver==0) { - dt_test = advance_semistaggered_twophase_ls(time,dt,iteration,ncycle); - } - else if(isolver==1 && do_diffused_ib==1) { -#ifdef AMREX_PARTICLES - dt_test = advance_semistaggered_fsi_diffusedib(time,dt,iteration,ncycle); -#endif - } - else if (isolver==2) { // To be implemented - dt_test = advance_semistaggered_twophase_phasefield(time,dt,iteration,ncycle); - } - else{ - amrex::Abort("Wrong isolver"); - } - - // - // Clean up after the predicted value at t^n+1. - // Estimate new timestep from umac cfl. - // - advance_cleanup(iteration,ncycle); - - //if (verbose) - //{ - Print() << "NavierStokes::advance(): exiting." << std::endl; - printMaxValues(); - //} - - return dt_test; // Return estimate of best new timestep. -} - -// -// This routine advects the scalars -// - -void -NavierStokes::scalar_advection (Real dt, - int fscalar, - int lscalar) -{ - BL_PROFILE("NavierStokes::scalar_advection()"); - - if (advect_and_update_scalar) { - - if (verbose) Print() << "... advect scalars\n"; - // - // Get simulation parameters. - // - const int num_scalars = lscalar - fscalar + 1; - const Real prev_time = state[State_Type].prevTime(); - - // divu - std::unique_ptr divu_fp(getDivCond(nghost_force(),prev_time)); - - // - // Start FillPatchIterator block - // - MultiFab forcing_term( grids, dmap, num_scalars, nghost_force(),MFInfo(),Factory()); - - FillPatchIterator S_fpi(*this,forcing_term,nghost_state(),prev_time,State_Type,fscalar,num_scalars); - MultiFab& Smf=S_fpi.get_mf(); - - // Floor small values of states to be extrapolated - floor(Smf); - - if ( advection_scheme == "Godunov_PLM" || advection_scheme == "Godunov_PPM" || advection_scheme == "BDS") - { - MultiFab visc_terms(grids,dmap,num_scalars,nghost_force(),MFInfo(),Factory()); - FillPatchIterator U_fpi(*this,visc_terms,nghost_state(),prev_time,State_Type,Xvel,AMREX_SPACEDIM); - const MultiFab& Umf=U_fpi.get_mf(); - - { - std::unique_ptr dsdt(getDsdt(nghost_force(),prev_time)); - MultiFab::Saxpy(*divu_fp, 0.5*dt, *dsdt, 0, 0, 1, nghost_force()); - } - - // Compute viscous term - if (be_cn_theta != 1.0) - getViscTerms(visc_terms,fscalar,num_scalars,prev_time); - else - visc_terms.setVal(0.0,1); - - #ifdef _OPENMP - #pragma omp parallel if (Gpu::notInLaunchRegion()) - #endif - for (MFIter S_mfi(Smf,TilingIfNotGPU()); S_mfi.isValid(); ++S_mfi) - { - - // Box for forcing terms - auto const force_bx = S_mfi.growntilebox(nghost_force()); - - if (getForceVerbose) - { - Print() << "---" << '\n' << "C - scalar advection:" << '\n' - << " Calling getForce..." << '\n'; - } - - getForce(forcing_term[S_mfi],force_bx,fscalar,num_scalars, - prev_time,Umf[S_mfi],Smf[S_mfi],0,S_mfi); - - for (int n=0; n nghost_force. - - if ( do_temp && n+fscalar==Temp ) - { - // - // Solving - // dT/dt + U dot del T = ( del dot lambda grad T + H_T ) / (rho c_p) - // with tforces = H_T/c_p (since it's always density-weighted), and - // visc = del dot mu grad T, where mu = lambda/c_p - // - amrex::ParallelFor(force_bx, [tf, visc, rho] - AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { tf(i,j,k) = ( tf(i,j,k) + visc(i,j,k) ) / rho(i,j,k); }); - } - else - { - if (advectionType[fscalar+n] == Conservative) - { - // - // For tracers, Solving - // dS/dt + del dot (U S) = del dot beta grad (S/rho) + rho H_q - // where S = rho q, q is a concentration - // tforces = rho H_q (since it's always density-weighted) - // visc = del dot beta grad (S/rho) - // - amrex::ParallelFor(force_bx, [tf, visc] - AMREX_GPU_DEVICE (int i, int j, int k ) noexcept - { tf(i,j,k) += visc(i,j,k); }); - } - else - { - // - // Solving - // dS/dt + U dot del S = del dot beta grad S + H_q - // where S = q, q is a concentration - // tforces = rho H_q (since it's always density-weighted) - // visc = del dot beta grad S - // - amrex::ParallelFor(force_bx, [tf, visc, rho] - AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { tf(i,j,k) = tf(i,j,k) / rho(i,j,k) + visc(i,j,k); }); - } - } - } - } - } - - ComputeAofs(fscalar, num_scalars, Smf, 0, forcing_term, *divu_fp, false, dt); - - } -} - -// -// This subroutine updates the scalars, before the velocity update -// and the level projection -// -// AT this point in time, all we know is psi^n, rho^n+1/2, and the -// general forcing terms at t^n, and after solving in this routine -// viscous forcing at t^n+1/2. Note, unless more complicated logic -// is invoked earlier, we do not have any estimate of general forcing -// terms at t^n+1/2. -// - -void -NavierStokes::scalar_update (Real dt, - int first_scalar, - int last_scalar) -{ - BL_PROFILE("NavierStokes::scalar_update()"); - - if (advect_and_update_scalar) { - - if (verbose) Print() << "... update scalars\n"; - - scalar_advection_update(dt, first_scalar, last_scalar); - - bool do_any_diffuse = false; - for (int sigma = first_scalar; sigma <= last_scalar; sigma++) - if (is_diffusive[sigma]) do_any_diffuse = true; - - if (do_any_diffuse) - scalar_diffusion_update(dt, first_scalar, last_scalar); - - MultiFab& S_new = get_new_data(State_Type); - //#ifdef AMREX_USE_EB - // set_body_state(S_new); - //#endif - for (int sigma = first_scalar; sigma <= last_scalar; sigma++) - { - if (S_new.contains_nan(sigma,1,0)) - { - Print() << "New scalar " << sigma << " contains Nans" << '\n'; - exit(0); - } - } - } -} - -void -NavierStokes::scalar_diffusion_update (Real dt, - int first_scalar, - int last_scalar) -{ - BL_PROFILE("NavierStokes::scalar_diffusion_update()"); - - const MultiFab& Rh = get_rho_half_time(); - - int ng=1; - const Real prev_time = state[State_Type].prevTime(); - const Real curr_time = state[State_Type].curTime(); - - FillPatch(*this,get_old_data(State_Type),ng,prev_time,State_Type,Density,NUM_SCALARS,Density); - FillPatch(*this,get_new_data(State_Type),ng,curr_time,State_Type,Density,NUM_SCALARS,Density); - - auto Snc = std::make_unique(); - auto Snp1c = std::make_unique(); - - if (level > 0) { - auto& crselev = getLevel(level-1); - Snc->define(crselev.boxArray(), crselev.DistributionMap(), NUM_STATE, ng, MFInfo(), crselev.Factory()); - FillPatch(crselev,*Snc ,ng,prev_time,State_Type,0,NUM_STATE); - - Snp1c->define(crselev.boxArray(), crselev.DistributionMap(), NUM_STATE, ng, MFInfo(), crselev.Factory()); - FillPatch(crselev,*Snp1c,ng,curr_time,State_Type,0,NUM_STATE); - } - - const int nlev = (level ==0 ? 1 : 2); - Vector Sn(nlev,nullptr), Snp1(nlev,nullptr); - Sn[0] = &(get_old_data(State_Type)); - Snp1[0] = &(get_new_data(State_Type)); - - if (nlev>1) { - Sn[1] = Snc.get() ; - Snp1[1] = Snp1c.get() ; - } - - const Vector& theBCs = AmrLevel::desc_lst[State_Type].getBCs(); - - FluxBoxes fb_diffn, fb_diffnp1; - MultiFab **cmp_diffn = nullptr, **cmp_diffnp1 = nullptr; - - MultiFab *delta_rhs = nullptr; - MultiFab *alpha = nullptr; - const int rhsComp = 0, alphaComp = 0, fluxComp = 0; - - FluxBoxes fb_fluxn (this); - FluxBoxes fb_fluxnp1(this); - MultiFab** fluxn = fb_fluxn.get(); - MultiFab** fluxnp1 = fb_fluxnp1.get(); - - Vector diffuse_comp(1); - - for (int sigma = first_scalar; sigma <= last_scalar; sigma++) - { - if (verbose) { - Print()<<"scalar_diffusion_update "<diffuse_scalar (Sn, Sn, Snp1, Snp1, sigma, 1, Rho_comp, - prev_time,curr_time,be_cn_theta,Rh,rho_flag, - fluxn,fluxnp1,fluxComp,delta_rhs,rhsComp, - alpha,alphaComp, - cmp_diffn,cmp_diffnp1,betaComp, - crse_ratio,theBCs[bc_comp],geom, - add_old_time_divFlux, - diffuse_comp); - - delete alpha; - - // - // Increment the viscous flux registers - // - if (do_reflux) - { - FArrayBox fluxtot; - for (int d = 0; d < AMREX_SPACEDIM; d++) - { - MultiFab fluxes; - - if (level < parent->finestLevel()) - { - fluxes.define(fluxn[d]->boxArray(), fluxn[d]->DistributionMap(), 1, 0, MFInfo(), Factory()); - } - - for (MFIter fmfi(*fluxn[d]); fmfi.isValid(); ++fmfi) - { - const Box& ebox = (*fluxn[d])[fmfi].box(); - - fluxtot.resize(ebox,1); - Elixir fdata_i = fluxtot.elixir(); - - auto const& ftot = fluxtot.array(); - auto const& fn = fluxn[d]->array(fmfi); - auto const& fnp1 = fluxnp1[d]->array(fmfi); - - amrex::ParallelFor(ebox, [ftot, fn, fnp1 ] - AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - ftot(i,j,k) = fn(i,j,k) + fnp1(i,j,k); - }); - - if (level < parent->finestLevel()) { - fluxes[fmfi].copy(fluxtot); - } - - if (level > 0) { - getViscFluxReg().FineAdd(fluxtot,d,fmfi.index(),0,sigma,1,dt,RunOn::Gpu); - } - } // mfi - - if (level < parent->finestLevel()) { - getLevel(level+1).getViscFluxReg().CrseInit(fluxes,d,0,sigma,1,-dt); - } - - } // d - } // do_reflux - - if (be_cn_theta != 1) { - fb_diffn.clear(); - } - fb_diffnp1.clear(); - - }//end if(is_diffusive) - } -} -void -NavierStokes::velocity_diffusion_update (Real dt) -{ - BL_PROFILE("NavierStokes::velocity_diffusion_update()"); - - const Real strt_time = ParallelDescriptor::second(); - // - // Compute the viscous forcing. - // Do following except at initial iteration. - // - if (is_diffusive[Xvel]) - { - int rho_flag = (do_mom_diff == 0) ? 1 : 3; - - FluxBoxes fb_viscn, fb_viscnp1; - MultiFab** loc_viscn = nullptr; - MultiFab** loc_viscnp1 = nullptr; - - Real viscTime = state[State_Type].prevTime(); - loc_viscn = fb_viscn.define(this); - getViscosity(loc_viscn, viscTime); - - viscTime = state[State_Type].curTime(); - loc_viscnp1 = fb_viscnp1.define(this); - getViscosity(loc_viscnp1, viscTime); - - diffusion->diffuse_velocity(dt,be_cn_theta,get_rho_half_time(),rho_flag, - nullptr,loc_viscn,viscn_cc,loc_viscnp1,viscnp1_cc); - } - - if (verbose) - { - Real run_time = ParallelDescriptor::second() - strt_time; - const int IOProc = ParallelDescriptor::IOProcessorNumber(); - - ParallelDescriptor::ReduceRealMax(run_time,IOProc); - - Print() << "NavierStokes:velocity_diffusion_update(): lev: " << level - << ", time: " << run_time << '\n'; - } -} - -void -NavierStokes::sum_integrated_quantities () -{ - const int finest_level = parent->finestLevel(); - const Real time = state[State_Type].curTime(); - - Vector mf(finest_level+1); - - // Container to hold derived data - Vector> derived_mf(finest_level+1); - // Proper container for call to volumeWeightedSum - Vector derived_mf_ptrs(finest_level+1); - - for (int lev = 0; lev <= finest_level; lev++) - { - NavierStokes& ns_level = getLevel(lev); - - mf[lev] = &ns_level.get_new_data(State_Type); - derived_mf[lev] = ns_level.derive("energy",time,0); - derived_mf_ptrs[lev] = derived_mf[lev].get(); - } - - Real mass = volumeWeightedSum(mf, Density, - parent->Geom(), parent->refRatio()); - Real trac = volumeWeightedSum(mf, Tracer, - parent->Geom(), parent->refRatio()); - Real energy = volumeWeightedSum(derived_mf_ptrs, 0, - parent->Geom(), parent->refRatio()); - - Print() << '\n'; - Print().SetPrecision(12) << "TIME= " << time << " MASS= " << mass << '\n'; - Print().SetPrecision(12) << "TIME= " << time << " TRAC= " << trac << '\n'; - Print().SetPrecision(12) << "TIME= " << time << " KINETIC ENERGY= " << energy << '\n'; - - // - // ls related - // - if (ParallelDescriptor::IOProcessor()) { - std::ofstream ofs("mass.txt", std::ios::app); // append mode - // std::ofstream ofs("mass.txt", std::ios::out); // override mode - if (ofs.is_open()) - { - amrex::Print(ofs).SetPrecision(12) << time << " " << mass << " " << trac << " " << energy << '\n'; - ofs.close(); - } - else - { - amrex::Abort("Failed to open mass.txt for writing"); - } - } -} - -void -NavierStokes::setPlotVariables() -{ - AmrLevel::setPlotVariables(); -} - -void -NavierStokes::writePlotFilePre (const std::string& /*dir*/, - std::ostream& /*os*/) -{ -#ifdef AMREX_USE_EB - if ( set_plot_coveredCell_val ) - { - for (amrex::Long i =0; i < state.size(); i++) - { - auto& sdata = state[i].newData(); - // only cell-centered state data goes into plotfile - if ( sdata.ixType().cellCentered() ){ - // set covered values for ease of viewing - EB_set_covered(sdata, 0.0); - } - } - } -#endif -} - -void -NavierStokes::writePlotFilePost (const std::string& dir, - std::ostream& /*os*/) -{ - if (level == 0 && ParallelDescriptor::IOProcessor()) - { - // job_info file with details about the run - std::ofstream jobInfoFile; - std::string FullPathJobInfoFile = dir; - FullPathJobInfoFile += "/job_info"; - jobInfoFile.open(FullPathJobInfoFile.c_str(), std::ios::out); - - std::string PrettyLine = "===============================================================================\n"; - std::string OtherLine = "--------------------------------------------------------------------------------\n"; - std::string SkipSpace = " "; - - - // job information - jobInfoFile << PrettyLine; - jobInfoFile << " Job Information\n"; - jobInfoFile << PrettyLine; - - jobInfoFile << "number of MPI processes: " << ParallelDescriptor::NProcs() << '\n'; -#ifdef _OPENMP - jobInfoFile << "number of threads: " << omp_get_max_threads() << '\n'; -#endif - jobInfoFile << "\n\n"; - - // plotfile information - jobInfoFile << PrettyLine; - jobInfoFile << " Plotfile Information\n"; - jobInfoFile << PrettyLine; - - time_t now = time(nullptr); - - // Convert now to tm struct for local timezone - tm* localtm = localtime(&now); - jobInfoFile << "output data / time: " << asctime(localtm); - - char currentDir[FILENAME_MAX]; - if (getcwd(currentDir, FILENAME_MAX)) { - jobInfoFile << "output dir: " << currentDir << '\n'; - } - - jobInfoFile << "\n\n"; - - - // build information - jobInfoFile << PrettyLine; - jobInfoFile << " Build Information\n"; - jobInfoFile << PrettyLine; - - jobInfoFile << "build date: " << buildInfoGetBuildDate() << '\n'; - jobInfoFile << "build machine: " << buildInfoGetBuildMachine() << '\n'; - jobInfoFile << "build dir: " << buildInfoGetBuildDir() << '\n'; - jobInfoFile << "AMReX dir: " << buildInfoGetAMReXDir() << '\n'; - - jobInfoFile << '\n'; - - jobInfoFile << "COMP: " << buildInfoGetComp() << '\n'; - jobInfoFile << "COMP version: " << buildInfoGetCompVersion() << "\n"; - jobInfoFile << "FCOMP: " << buildInfoGetFcomp() << '\n'; - jobInfoFile << "FCOMP version: " << buildInfoGetFcompVersion() << "\n"; - - jobInfoFile << "\n"; - - const char* githash1 = buildInfoGetGitHash(1); - const char* githash2 = buildInfoGetGitHash(2); - if (strlen(githash1) > 0) { - jobInfoFile << "IAMR git hash: " << githash1 << "\n"; - } - if (strlen(githash2) > 0) { - jobInfoFile << "AMReX git hash: " << githash2 << "\n"; - } - - jobInfoFile << "\n\n"; - - - // runtime parameters - jobInfoFile << PrettyLine; - jobInfoFile << " Inputs File Parameters\n"; - jobInfoFile << PrettyLine; - - ParmParse::dumpTable(jobInfoFile, true); - - jobInfoFile.close(); - - } - - // - // Put particles in plotfile? - // Used in regression testing, but also useful if you want to use - // AMReX's tool particle_compare without writing a full checkpoint - // -#ifdef AMREX_PARTICLES - if (level == 0 && theNSPC() != 0 && particles_in_plotfile) - { - theNSPC()->Checkpoint(dir,"Particles"); - } -#endif - -#ifdef AMREX_PARTICLES - if(level == parent->finestLevel()){ - Particles::get_particles()->mContainer->Checkpoint(dir, "particles"); - } -#endif - -#ifdef AMREX_USE_EB - if ( set_plot_coveredCell_val ) - { - for (amrex::Long i =0; i < state.size(); i++) - { - auto& sdata = state[i].newData(); - // only cell-centered state data goes into plotfile - if ( sdata.ixType().cellCentered() ){ - // put COVERED_VAL back or set_body_state - EB_set_covered(sdata, COVERED_VAL); - } - } - } -#endif - -} - -std::unique_ptr -NavierStokes::derive (const std::string& name, - Real time, - int ngrow) -{ -#ifdef AMREX_PARTICLES - return ParticleDerive(name, time, ngrow); -#else - return AmrLevel::derive(name, time, ngrow); -#endif -} - -void -NavierStokes::derive (const std::string& name, - Real time, - MultiFab& mf, - int dcomp) -{ -#ifdef AMREX_PARTICLES - ParticleDerive(name,time,mf,dcomp); -#else - AmrLevel::derive(name,time,mf,dcomp); -#endif -} - -// -// Ensure state, and pressure are consistent. -// -void -NavierStokes::post_init (Real stop_time) -{ - - if (level > 0) - // - // Nothing to sync up at level > 0. - // - return; - - const int finest_level = parent->finestLevel(); - Real dt_init = 0.0; - Vector dt_save(finest_level+1); - Vector nc_save(finest_level+1); - // - // Ensure state is consistent, i.e. velocity field is non-divergent, - // pressure & Gradp have been initialized, Coarse levels are fine - // level averages. - // - post_init_state(); - // - // Estimate the initial timestepping. - // - post_init_estDT(dt_init, nc_save, dt_save, stop_time); - // - // Initialize the pressure by iterating the initial timestep. - // - post_init_press(dt_init, nc_save, dt_save); - // - // Compute the initial estimate of conservation. - // - if (sum_interval > 0) - sum_integrated_quantities(); - - if (NavierStokesBase::avg_interval > 0) - { - NavierStokesBase::time_avg.resize(finest_level+1); - NavierStokesBase::time_avg_fluct.resize(finest_level+1); - NavierStokesBase::dt_avg.resize(finest_level+1); - NavierStokesBase::time_avg[level] = 0.; - NavierStokesBase::time_avg_fluct[level] = 0.; - NavierStokesBase::dt_avg[level] = 0.; - const amrex::Real dt_level = parent->dtLevel(level); - time_average(NavierStokesBase::time_avg[level], NavierStokesBase::time_avg_fluct[level], NavierStokesBase::dt_avg[level], dt_level); - } - -} - -// -// Initialize the pressure by iterating the initial timestep -// - -void -NavierStokes::post_init_press (Real& dt_init, - Vector& nc_save, - Vector& dt_save) -{ - if ( init_iter <= 0 ) - { - parent->setDtLevel(dt_save); - parent->setNCycle(nc_save); - - NavierStokes::initial_step = false; - - Print()<< "WARNING! post_init_press(): exiting without doing initial iterations because init_iter <= 0."<finestLevel(); - NavierStokes::initial_iter = true; - - if (verbose) - { - Print() << std::endl - << "post_init_press(): " - << "doing initial pressure iterations with dt = " - << dt_init - << std::endl; - } - - // - // Iterate over the advance function. - // - for (int iter = 0; iter < init_iter; iter++) - { - - if (verbose) - { - Print() << std::endl - << "post_init_press(): iter = " << iter - << std::endl; - } - - for (int k = 0; k <= finest_level; k++ ) - { - getLevel(k).advance(strt_time,dt_init,1,1); - } - - // - // Constructs a guess at P. - // - Vector sig(finest_level+1, nullptr); - - for (int k = 0; k <= finest_level; k++) - { - sig[k] = &(getLevel(k).get_rho_half_time()); - } - - if (projector) - { - projector->initialSyncProject(0,sig,dt_init, - strt_time,have_divu); - } - - for (int k = finest_level-1; k >= 0; k--) - { - getLevel(k).avgDown(); - } - - if (verbose) - { - // initSyncProject project d(u)/dt, so new velocity - // is actually the projected acceleration - // We don't actually care because initial velocity state will be - // recovered at the end of each iteration. - // However, we need to recover u_new from d(u)/dt if we want to print - // correct diagnostics - MultiFab& S_new = get_new_data(State_Type); - MultiFab& S_old = get_old_data(State_Type); - MultiFab::Xpay(S_new, dt_init, S_old, Xvel, Xvel, AMREX_SPACEDIM, 0); - - Print() << "After sync projection and avgDown:" << std::endl; - printMaxValues(); - } - - for (int k = 0; k <= finest_level; k++) - { - // - // Reset state variables to initial time, but - // do not reset pressure variable, only pressure time. - // do not reset dsdt variable, only dsdt time. - // - // The reset of data is ultimately achieved via a swap and swap back to - // preserve old_data. resetState ends up calling swap(old_data, new_data) - // but then advance_setup also ends up calling swap(old_data, new_data). - // Since pressure is not reset, after advance_setup, the next step will - // progress with p_old==p_new. - getLevel(k).resetState(strt_time, dt_init, dt_init); - } - - NavierStokes::initial_iter = false; - } - - NavierStokes::initial_step = false; - // - // Re-instate timestep. - // - for (int k = 0; k <= finest_level; k++) - { - getLevel(k).setTimeLevel(strt_time,dt_save[k],dt_save[k]); - } - - parent->setDtLevel(dt_save); - parent->setNCycle(nc_save); - - // Add space to output if verbose - if (verbose) - { - Print() << std::endl - << "post_init_press(): exiting after " << init_iter << " iterations" - << std::endl - << "After initial iterations: " - << std::endl; - printMaxValues(); - Print() << std::endl << std::endl; - } - -} - -// -// The Mac Sync correction function -// -void -NavierStokes::mac_sync () -{ - BL_PROFILE_REGION_START("R::NavierStokes::mac_sync()"); - BL_PROFILE("NavierStokes::mac_sync()"); - - if (!do_reflux) return; - - if (verbose) - { - Print() << std::endl - << "mac_sync() on level "<dtLevel(level); - MultiFab* DeltaSsync = nullptr;// hold (Delta rho)*q for conserved quantities - // does this have ghosts filled? - MultiFab& Rh = get_rho_half_time(); - -#ifdef AMREX_USE_EB - const int nghost = umac_n_grow; -#else - const int nghost = 0; -#endif - - Array Ucorr; - for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) - { - const BoxArray& edgeba = getEdgeBoxArray(idim); - - Ucorr[idim]= new MultiFab(edgeba,dmap,1,nghost,MFInfo(),Factory()); - } - - sync_setup(DeltaSsync); - // - // Compute the u_mac for the correction. - // - Vector rho_math_bc = fetchBCArray(State_Type,Density,1); - mac_projector->mac_sync_solve(level,dt,Rh,rho_math_bc[0],fine_ratio,Ucorr); - // - // Update coarse grid state by adding correction from mac_sync solve - // the correction is the advective tendency of the new velocities. - // - MultiFab& S_new = get_new_data(State_Type); - mac_projector->mac_sync_compute(level,Ucorr,Vsync,Ssync, - advectionType, prev_time,dt, - NUM_STATE,be_cn_theta, - do_mom_diff); - // - // Delete Ucorr; we're done with it. - // - for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) - delete Ucorr[idim]; - - - // - // For all conservative variables Q (other than density) - // Q is taken as rho*q and we increment sync by -(sync_for_rho)*q - // (See Pember, et. al., LBNL-41339, Jan. 1989) - // This increment will be added back after the diffusive sync. - // - int iconserved = -1; - for (int istate = AMREX_SPACEDIM; istate < NUM_STATE; istate++) - { - if (istate != Density && advectionType[istate] == Conservative) - { - iconserved++; -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(S_new,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - auto const& rho = S_new.array(mfi,Density); - auto const& Snew = S_new.array(mfi,istate); - auto const& dSsync = DeltaSsync->array(mfi); - auto const& drhosync = Ssync.array(mfi,Density-AMREX_SPACEDIM); - auto const& ssync = Ssync.array(mfi,istate-AMREX_SPACEDIM); - - amrex::ParallelFor(bx, [rho, Snew, dSsync, drhosync, ssync, iconserved ] - AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - dSsync(i,j,k,iconserved) = Snew(i,j,k) * drhosync(i,j,k) / rho(i,j,k); - ssync(i,j,k) -= dSsync(i,j,k,iconserved); - }); - } - } - } - - if (do_mom_diff == 1) - { -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(S_new, TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - auto const& rho_c = S_new.array(mfi,Density); - auto const& vsync = Vsync.array(mfi,Xvel); - amrex::ParallelFor(bx, [rho_c, vsync] - AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - for (int n = 0; n < AMREX_SPACEDIM; n++) { - vsync(i,j,k,n) /= rho_c(i,j,k); - } - }); - } - } - // - // Compute viscous sync. - // - if (is_diffusive[Xvel]) - { - int rho_flag = (do_mom_diff == 0) ? 1 : 3; - - MultiFab** loc_viscn = nullptr; - FluxBoxes fb_viscn; - - Real viscTime = state[State_Type].prevTime(); - loc_viscn = fb_viscn.define(this); - getViscosity(loc_viscn, viscTime); - - diffusion->diffuse_Vsync(Vsync,dt,be_cn_theta,Rh,rho_flag,loc_viscn,0); - } - - FluxBoxes fb_SC; - MultiFab** fluxSC = nullptr; - bool any_diffusive = false; - for (int sigma = 0; sigma < numscal; sigma++) - if (is_diffusive[AMREX_SPACEDIM+sigma]) - any_diffusive = true; - - if (any_diffusive) { - fluxSC = fb_SC.define(this); - } - - Vector diffuse_comp(1); - int ng=1; - const Real curr_time = state[State_Type].curTime(); - - // Diffusion solver switches - // implies that Diff solve does NOT need Sold - const bool add_old_time_divFlux = false; - - const int nlev = 1; - Vector Snp1(nlev,nullptr); - - MultiFab dSsync(grids,dmap,NUM_STATE,1,MFInfo(),Factory()); - Snp1[0] = &dSsync; - - Vector Rhonp1(nlev,nullptr); - Rhonp1[0] = &(get_new_data(State_Type)); - int Rho_comp = Density; - - FluxBoxes fb_fluxn (this); - MultiFab** fluxn = fb_fluxn.get(); - - const Vector& theBCs = AmrLevel::desc_lst[State_Type].getBCs(); - - for (int sigma = 0; sigmasetVal(0.,state_ind,1,ng); - - FluxBoxes fb_diffnp1; - MultiFab** cmp_diffnp1=nullptr, **cmp_diffn=nullptr; - - Real diffTime = state[State_Type].curTime(); - cmp_diffnp1 = fb_diffnp1.define(this); - getDiffusivity(cmp_diffnp1, diffTime, AMREX_SPACEDIM+sigma,0,1); - - int S_comp = state_ind; - const int num_comp = 1; - const int fluxComp = 0; - MultiFab *delta_rhs = &Ssync; - int rhsComp = sigma; - MultiFab *alpha_in = nullptr; - const int alphaComp = 0; - int betaComp = 0; - - diffuse_comp[0] = is_diffusive[AMREX_SPACEDIM+sigma]; - - diffusion->diffuse_scalar ({},{},Snp1,Rhonp1, - S_comp,num_comp,Rho_comp, - prev_time,curr_time,be_cn_theta, - Rh,rho_flag, - fluxn,fluxSC,fluxComp, - delta_rhs,rhsComp, - alpha_in,alphaComp, - cmp_diffn,cmp_diffnp1,betaComp, - crse_ratio,theBCs[state_ind],geom, - add_old_time_divFlux,diffuse_comp); - - delete alpha_in; - - MultiFab::Copy(Ssync,*Snp1[0],state_ind,sigma,1,0); - - // - // Increment the viscous flux registers - // - if (level > 0) - { - for (int d = 0; d < AMREX_SPACEDIM; d++) - { - getViscFluxReg().FineAdd(*fluxSC[d],d,0,state_ind,1,dt); - } - } - } - else // state component not diffusive - { - // - // The following used to be done in mac_sync_compute. Ssync is - // the source for a rate of change to S over the time step, so - // Ssync*dt is the source to the actual sync amount. - // - Ssync.mult(dt,sigma,1,Ssync.nGrow()); - } - } - - // - // For all conservative variables Q (other than density) - // increment sync by (sync_for_rho)*q_presync. - // (See Pember, et. al., LBNL-41339, Jan. 1989) - // - iconserved = -1; - for (int istate = AMREX_SPACEDIM; istate < NUM_STATE; istate++) - { - if (istate != Density && advectionType[istate] == Conservative) - { - iconserved++; - - // Must multiply by dt to agree with the factor of dt just put - // into Ssync above. - MultiFab::Saxpy(Ssync,dt,*DeltaSsync,iconserved,istate-AMREX_SPACEDIM,1,0); - } - } - // - // Add the sync correction to the state. - // - MultiFab::Add(S_new,Ssync,0,AMREX_SPACEDIM,numscal,0); - // - // Update rho_ctime after rho is updated with Ssync. - // - make_rho_curr_time(); - - if (level > 0) incrRhoAvg(Ssync,Density-AMREX_SPACEDIM,1.0); - // - // Get boundary conditions. - // - const auto N = int(grids.size()); - - Vector sync_bc(N); - Vector< Vector > sync_bc_array(N); - - for (int i = 0; i < N; i++) - { - sync_bc_array[i] = getBCArray(State_Type,i,Density,numscal); - sync_bc[i] = sync_bc_array[i].dataPtr(); - } - // - // Interpolate the sync correction to the finer levels, - // and update rho_ctime, rhoAvg at those levels. - // - IntVect ratio = IntVect::TheUnitVector(); - const Real mult = 1.0; - for (int lev = level+1; lev <= parent->finestLevel(); lev++) - { - ratio *= parent->refRatio(lev-1); - NavierStokes& fine_lev = getLevel(lev); - const BoxArray& fine_grids = fine_lev.boxArray(); - MultiFab sync_incr(fine_grids,fine_lev.DistributionMap(),numscal,0,MFInfo(),fine_lev.Factory()); - sync_incr.setVal(0.0); - - SyncInterp(Ssync,level,sync_incr,lev,ratio,0,0, - numscal,1,mult,sync_bc.dataPtr()); - - MultiFab& Sf_new = fine_lev.get_new_data(State_Type); - MultiFab::Add(Sf_new,sync_incr,0,Density,numscal,0); - - fine_lev.make_rho_curr_time(); - fine_lev.incrRhoAvg(sync_incr,Density-AMREX_SPACEDIM,1.0); - } - - sync_cleanup(DeltaSsync); - - BL_PROFILE_REGION_STOP("R::NavierStokes::mac_sync()"); -} - -// -// The reflux function -// -void -NavierStokes::reflux () -{ - if (level == parent->finestLevel()) - return; - - BL_PROFILE("NavierStokes::reflux()"); - - AMREX_ASSERT(do_reflux); - // - // First do refluxing step. - // - auto& fr_adv = getAdvFluxReg(level+1); - FluxRegister& fr_visc = getViscFluxReg(level+1); - const Real dt_crse = parent->dtLevel(level); - // - // It is important, for do_mom_diff == 0, to do the viscous - // refluxing first, since this will be divided by rho_half - // before the advective refluxing is added. In the case of - // do_mom_diff == 1, both components of the refluxing will - // be divided by rho^(n+1) in level_sync. - // - - fr_visc.Reflux(Vsync,volume,1.0,0,0,AMREX_SPACEDIM,geom); - fr_visc.Reflux(Ssync,volume,1.0,AMREX_SPACEDIM,0,NUM_STATE-AMREX_SPACEDIM,geom); - - const MultiFab& Rh = get_rho_half_time(); - - if (do_mom_diff == 0) - { -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(Vsync,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - auto const& vsync = Vsync.array(mfi); - auto const& rhohalf = Rh.array(mfi); - - amrex::ParallelFor(bx, AMREX_SPACEDIM, [vsync, rhohalf] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { - vsync(i,j,k,n) /= rhohalf(i,j,k); - }); - } - } - - for (int istate = AMREX_SPACEDIM; istate < NUM_STATE; istate++) - { - if (advectionType[istate] == NonConservative) - { - MultiFab::Divide(Ssync,Rh,0,istate-AMREX_SPACEDIM,1,0); - } - } - -#ifdef AMREX_USE_EB - fr_adv.Reflux(Vsync,*volfrac, 0, 0, AMREX_SPACEDIM); - fr_adv.Reflux(Ssync,*volfrac, AMREX_SPACEDIM, 0, NUM_STATE-AMREX_SPACEDIM); -#else - fr_adv.Reflux(Vsync, 0, 0, AMREX_SPACEDIM); - fr_adv.Reflux(Ssync, AMREX_SPACEDIM, 0,NUM_STATE-AMREX_SPACEDIM); -#endif - const Real scale = 1.0/dt_crse; - Vsync.mult(scale); - Ssync.mult(scale); - - const BoxArray& fine_boxes = getLevel(level+1).boxArray(); - // - // Zero out coarse grid cells which underlie fine grid cells. - // - BoxArray baf = fine_boxes; - - baf.coarsen(fine_ratio); - -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - { - std::vector< std::pair > isects; - for (MFIter mfi(Vsync,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.growntilebox(); - auto const& vsync = Vsync.array(mfi); - auto const& ssync = Ssync.array(mfi); - int nstate = NUM_STATE; - - baf.intersections(bx,isects); - - for (const auto& is : isects) - { - amrex::ParallelFor(is.second, [vsync, ssync, nstate] - AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - for (int n = 0; n < AMREX_SPACEDIM; n++) { - vsync(i,j,k,n) = 0.0; - } - for (int n = 0; n < nstate-AMREX_SPACEDIM; n++) { - ssync(i,j,k,n) = 0.0; - } - }); - } - } - } -} - -// -// Average fine information from the complete set of state types to coarse. -// - -void -NavierStokes::avgDown () -{ - if (level == parent->finestLevel()) - return; - - auto& fine_lev = getLevel(level+1); - // - // Average down the State and Pressure at the new time. - // - avgDown_StatePress(); - - // - // Next average down divu and dSdT at new time. - // - if (have_divu) - { - MultiFab& Divu_crse = get_new_data(Divu_Type); - MultiFab& Divu_fine = fine_lev.get_new_data(Divu_Type); - - average_down(Divu_fine, Divu_crse, 0, 1); - } - if (have_dsdt) - { - MultiFab& Dsdt_crse = get_new_data(Dsdt_Type); - MultiFab& Dsdt_fine = fine_lev.get_new_data(Dsdt_Type); - - average_down(Dsdt_fine, Dsdt_crse, 0, 1); - } -} - -// -// Default divU is set to zero. -// - -void -NavierStokes::calc_divu (Real time, - Real /*dt*/, - MultiFab& divu) -{ - BL_PROFILE("NavierStokes::calc_divu()"); - - if (have_divu) - { - // Don't think we need this here, but then ghost cells are uninitialized - // divu.setVal(0); - - if (do_temp && visc_coef[Temp] > 0.0) - { - // Compute Div(U) = Div(lambda * Grad(T))/(c_p*rho*T) - // = Div(temp_cond_coeff * Grad(T)) / (rho*T) - // where temp_cond_coef = lambda/cp - getViscTerms(divu,Temp,1,time); - - const MultiFab& rhotime = get_rho(time); - - FillPatchIterator temp_fpi(*this,divu,0,time,State_Type,Temp,1); - MultiFab& tmf = temp_fpi.get_mf(); - -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for ( MFIter rho_mfi(rhotime,TilingIfNotGPU()); rho_mfi.isValid(); ++rho_mfi) - { - const Box& bx = rho_mfi.tilebox(); - auto const& div = divu.array(rho_mfi); - auto const& rho = rhotime.array(rho_mfi); - auto const& temp = tmf.array(rho_mfi); -#ifdef AMREX_USE_EB - auto const& ebfactory = dynamic_cast(Factory()); - auto const& flagfab = ebfactory.getMultiEBCellFlagFab()[rho_mfi]; - - if (flagfab.getType(bx) == FabType::covered) - { - amrex::ParallelFor(bx, [div] - AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - div( i, j, k ) = COVERED_VAL; - }); - } - else if (flagfab.getType(bx) != FabType::regular) - { - auto vfrac = ebfactory.getVolFrac().const_array(rho_mfi); - - amrex::ParallelFor(bx, [div, rho, temp, vfrac] - AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - if ( vfrac(i,j,k) > 0.0 ) - { - div(i,j,k) /= ( rho(i,j,k)*temp(i,j,k) ); - } - else - { - div(i,j,k) = COVERED_VAL; - } - }); - } - else -#endif - { - amrex::ParallelFor(bx, [div, rho, temp] - AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - div(i,j,k) /= ( rho(i,j,k)*temp(i,j,k) ); - }); - } - } - } - else - { - divu.setVal(0); - } - } -} - -void -NavierStokes::getViscTerms (MultiFab& visc_terms, - int src_comp, - int ncomp, - Real time) -{ - BL_PROFILE("NavierStokes::getViscTerms()"); - // - // The logic below for selecting between scalar or tensor solves does - // not allow for calling NavierStokes::getViscTerms with src_comp=Yvel - // or Zvel - // -#ifdef AMREX_DEBUG - if (src_compgetTensorViscTerms(visc_terms,time,viscosity,viscosityCC,0); - } - // - // Get Scalar Diffusive Terms - // - const int first_scal = (src_comp==Xvel) ? AMREX_SPACEDIM : src_comp; - const int num_scal = (src_comp==Xvel) ? ncomp-AMREX_SPACEDIM : ncomp; - - if (num_scal > 0) - { - for (int icomp = first_scal; icomp < first_scal+num_scal; icomp++) - { - if (is_diffusive[icomp]) - { - diffusive = true; - - int rho_flag = Diffusion::set_rho_flag(diffusionType[icomp]); - - FluxBoxes fb; - MultiFab** cmp_diffn = nullptr; - - cmp_diffn = fb.define(this); - getDiffusivity(cmp_diffn, time, icomp, 0, 1); - - diffusion->getViscTerms(visc_terms,src_comp,icomp, - time,rho_flag,cmp_diffn,0); - } - else { - visc_terms.setVal(0.0,icomp-src_comp,1,nGrow); - } - } - } - // - // Ensure consistent grow cells - // - if (diffusive && nGrow > 0) - { - visc_terms.FillBoundary(0, ncomp, geom.periodicity()); - Extrapolater::FirstOrderExtrap(visc_terms, geom, 0, ncomp); - } -} - -// -// Functions calcViscosity/Diffusivity and getViscosity/Diffusivity are -// for calculating variable viscosity and diffusivity. Here we default to -// constant visc/diff and set the variable viscosity and diffusivity arrays -// to the values in visc_coef and diff_coef. -// For variable viscosity/diffusivity, (per MSD) calcViscosity/Diffusivity -// should compute the transport coefficients at cell centers (or cell centroids -// for EB) and getViscosity/Diffusivity should interpolate those to faces (or -// face-centroids for EB). -// -void -NavierStokes::calcViscosity (const Real time, - const Real /*dt*/, - const int /*iteration*/, - const int /*ncycle*/) -{ - if (is_diffusive[Xvel]) - { - if (visc_coef[Xvel] >= 0.0) - { - auto whichTime = which_time(State_Type,time); - AMREX_ASSERT(whichTime == AmrOldTime || whichTime == AmrNewTime); - - auto* visc = (whichTime == AmrOldTime ? viscn_cc : viscnp1_cc); - visc->setVal(visc_coef[Xvel], 0, visc->nComp(), visc->nGrow()); - } - else - { - Abort("NavierStokes::calcViscosity() : must have velocity visc_coef >= 0.0"); - } - } -} - -void -NavierStokes::calcDiffusivity (const Real time) -{ - // - // NOTE: In the diffusivity - // arrays, there is an offset since no diffusivity array - // is kept for the velocities or the density. So, the scalar - // component Density+1 in the state corresponds to component - // 0 in the arrays diffn and diffnp1. - // - int src_comp = Density+1; - int ncomp = NUM_STATE - AMREX_SPACEDIM -1; - - const TimeLevel whichTime = which_time(State_Type,time); - AMREX_ASSERT(whichTime == AmrOldTime || whichTime == AmrNewTime); - - MultiFab* diff = (whichTime == AmrOldTime ? diffn_cc : diffnp1_cc); - for (int comp=src_comp; comp= 0.0) - { - diff->setVal(visc_coef[comp], diff_comp, 1, diff->nGrow()); - } - else - { - Abort("NavierStokes::calcDiffusivity() : must have scalar diff_coefs >= 0.0"); - } - } - } -} - -void -NavierStokes::getViscosity (MultiFab* viscosity[AMREX_SPACEDIM], - const Real time) -{ - // // - // // Select time level to work with (N or N+1) - // // - // const TimeLevel whichTime = which_time(State_Type,time); - // AMREX_ASSERT(whichTime == AmrOldTime || whichTime == AmrNewTime); - - // MultiFab *visc = (whichTime == AmrOldTime ? viscn_cc : viscnp1_cc); - - // For non-const viscosity, uncomment above and add interp from - // cell-center/centroid to faces. - // But here we simply do constant viscosity. - - for (int dir=0; dirsetVal(visc_coef[Xvel], 0, viscosity[dir]->nComp(), viscosity[dir]->nGrow()); - } - - if (do_LES) - { - FluxBoxes mu_LES(this,1,0); - MultiFab** mu_LES_mf = mu_LES.get(); - for (int dir=0; dirsetVal(0., 0, mu_LES_mf[dir]->nComp(), mu_LES_mf[dir]->nGrow()); - } - - NavierStokesBase::calc_mut_LES(mu_LES_mf,time); - - for (int dir=0; dir Density); - // // - // // Pick correct component in the diffn/diffnp1 array - // // - // int diff_comp = state_comp - Density - 1; - // // - // // Select time level to work with (N or N+1) - // // - // const TimeLevel whichTime = which_time(State_Type,time); - // AMREX_ASSERT(whichTime == AmrOldTime || whichTime == AmrNewTime); - - // MultiFab *diff = (whichTime == AmrOldTime ? diffn_cc : diffnp1_cc); - - // For non-const diffusivity, uncomment above and add interp from - // cell-center/centroid to faces. - // But here we simply do constant diffusivity. - - for (int dir = 0; dir < AMREX_SPACEDIM; dir++) - { - for (int n = 0; n < ncomp; n++) - { - // Each scalar has it's own diffusivity in the visc_coef array, so must do 1 at a time - diffusivity[dir]->setVal(visc_coef[state_comp+n], dst_comp+n, 1, diffusivity[dir]->nGrow()); - } - } -} - - -// -// ls related -// -Real -NavierStokes::advance_semistaggered_twophase_ls (Real time, - Real dt, - int iteration, - int ncycle) -{ - BL_PROFILE("NavierStokes::advance_semistaggered_twophase_ls()"); - - // - // Calculate the time N viscosity and diffusivity - // Note: The viscosity and diffusivity at time N+1 are - // initialized here to the time N values just to - // have something reasonable. - // - const Real prev_time = state[State_Type].prevTime(); - const int num_diff = NUM_STATE-AMREX_SPACEDIM-1; - - calcViscosity(prev_time,dt,iteration,ncycle); - calcDiffusivity(prev_time); - MultiFab::Copy(*viscnp1_cc, *viscn_cc, 0, 0, 1, viscn_cc->nGrow()); - MultiFab::Copy(*diffnp1_cc, *diffn_cc, 0, 0, num_diff, diffn_cc->nGrow()); - - // Add this AFTER advance_setup() - if (verbose) - { - Print() << "NavierStokes::advance_semistaggered_twophase_ls(): before velocity update:" - << std::endl; - printMaxValues(false); - } - // - // Compute traced states for normal comp of velocity at half time level. - // Returns best estimate for new timestep. - // - Real dt_test = predict_velocity(dt); - // - // Do MAC projection and update edge velocities. - // - if (do_mac_proj) - { - // To enforce div constraint on coarse-fine boundary, need 1 ghost cell - int ng_rhs = 1; - - MultiFab mac_rhs(grids,dmap,1,ng_rhs,MFInfo(),Factory()); - create_mac_rhs(mac_rhs,ng_rhs,time,dt); - MultiFab& S_old = get_old_data(State_Type); - mac_project(time,dt,S_old,&mac_rhs,umac_n_grow,true); - - } else { - // Use interpolation from coarse to fill grow cells. - create_umac_grown(umac_n_grow, nullptr); - } - // - // Advect velocities. - // - if (do_mom_diff == 0) - velocity_advection(dt); - // - // Advect scalars. - // - const int first_scalar = Density; - const int last_scalar = first_scalar + NUM_SCALARS - 1; - scalar_advection(dt,first_scalar,last_scalar); - // - // ls related - // note: in the above scalar_advection function, we still advect rho. - // - if (do_phi) { - amrex::Print() << "After scalar_advection " << std::endl; - // const Real prev_time = state[State_Type].prevTime(); - // MultiFab& S_old = get_old_data(State_Type); - // int nScomp = S_old.nComp(); - // fill_allgts(S_old,State_Type,phicomp,1,prev_time); - // MultiFab::Copy(phi_ptime, S_old, phicomp, 0, 1, S_old.nGrow()); - - amrex::Print()<< "scalar_update phi " << std::endl; - amrex::Print()<< "phicomp " << phicomp << std::endl; - scalar_update(dt,phicomp,phicomp); - - // amrex::Print()<< std::endl; - // amrex::Print()<< "6 " << std::endl; - - const Real cur_time = state[State_Type].curTime(); - MultiFab& S_new = get_new_data(State_Type); - fill_allgts(S_new,State_Type,phicomp,1,cur_time); - MultiFab::Copy(phi_ctime, S_new, phicomp, 0, 1, S_new.nGrow()); - - // amrex::Print()<< "7 " << std::endl; - - // reinitialization - if (do_reinit == 1 && (parent->levelSteps(0)% lev0step_of_reinit == 0) ){ - amrex::Print() << "parent->levelSteps(0) " << parent->levelSteps(0) << std::endl; - reinit(); - } - - if (do_mom_diff == 0) { - // update the rho_ctime and density in S_new - phi_to_heavi(geom, epsilon, phi_ctime, heaviside); - heavi_to_rhoormu(heaviside, rho_w, rho_a, rho_ctime); - MultiFab::Copy(S_new, rho_ctime, 0, Density, 1, rho_ctime.nGrow()); - // update phi_half - MultiFab& phi_half_temp = get_phi_half_time(); - // update rho_half - phi_to_heavi(geom, epsilon, phi_half_temp, heaviside); - heavi_to_rhoormu(heaviside, rho_w, rho_a, rho_half); - - // update mu_half - MultiFab outmf_mu_half(grids, dmap, 1, 1, MFInfo(), Factory()); - heavi_to_rhoormu(heaviside, mu_w, mu_a, outmf_mu_half); - MultiFab::Copy(*viscn_cc, outmf_mu_half, 0, 0, 1, 1); - MultiFab::Copy(*viscnp1_cc, outmf_mu_half, 0, 0, 1, 1); - } - else { - // - // Update Rho. - // - scalar_update(dt,first_scalar,first_scalar); - make_rho_curr_time(); - - // update phi_half - MultiFab& phi_half_temp = get_phi_half_time(); - // update rho_half - phi_to_heavi(geom, epsilon, phi_half_temp, heaviside); - - // update mu_half - MultiFab outmf_mu_half(grids, dmap, 1, 1, MFInfo(), Factory()); - heavi_to_rhoormu(heaviside, mu_w, mu_a, outmf_mu_half); - MultiFab::Copy(*viscn_cc, outmf_mu_half, 0, 0, 1, 1); - MultiFab::Copy(*viscnp1_cc, outmf_mu_half, 0, 0, 1, 1); - } - } - else { - // - // Update Rho. - // - scalar_update(dt,first_scalar,first_scalar); - make_rho_curr_time(); - } - - if (prescribed_vel) - { - BL_ASSERT(do_phi==1); - dt_test = dt; - - // - // Create struct to hold initial conditions parameters - // - InitialConditions IC; - // Integer indices of the lower left and upper right corners of the - // valid region of the entire domain. - Box const& domain = geom.Domain(); - auto const& dx = geom.CellSizeArray(); - // Physical coordinates of the lower left corner of the domain - auto const& problo = geom.ProbLoArray(); - // Physical coordinates of the upper right corner of the domain - auto const& probhi = geom.ProbHiArray(); - - // Step 1: do the reinitialization - // which has been done before - - // Step 2: set vel of internal cells in S_new and fill the gts - MultiFab& S_new = get_new_data(State_Type); - - int ncomp = S_new.nComp(); -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(S_new,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.tilebox(); - set_rsv_vel(vbx, S_new.array(mfi, Xvel), domain, dx, problo, probhi, IC, time); - } - - // Step 3: copy vel in S_new back to S_old - MultiFab& S_old = get_old_data(State_Type); - MultiFab::Copy(S_old, S_new, 0, 0, ncomp, S_new.nGrow()); - - } - else { - // - // Advect momenta after rho^(n+1) has been created. - // - if (do_mom_diff == 1) - velocity_advection(dt); - // - // ls related - // - if (do_phi) { - // - // Add the advective and other terms to get scalars at t^{n+1} except - // the level set function. - scalar_update(dt,first_scalar+1,phicomp-1); - } - else { - // - // Add the advective and other terms to get scalars at t^{n+1}. - // - scalar_update(dt,first_scalar+1,last_scalar); - } - // - // S appears in rhs of the velocity update, so we better do it now. - // - if (have_divu) - { - calc_divu(time+dt,dt,get_new_data(Divu_Type)); - if (have_dsdt) - { - calc_dsdt(time,dt,get_new_data(Dsdt_Type)); - if (initial_step) - MultiFab::Copy(get_old_data(Dsdt_Type), - get_new_data(Dsdt_Type),0,0,1,0); - } - } - // - // Add the advective and other terms to get velocity at t^{n+1}. - // - velocity_update(dt); - - // - // Increment rho average. - // - if (!initial_step) - { - if (level > 0) - incrRhoAvg((iteration==ncycle ? 0.5 : 1.0) / Real(ncycle)); - - if (verbose) - { - Print() << "NavierStokes::advance_semistaggered_twophase_ls(): before nodal projection " << std::endl; - printMaxVel(); - // New P, Gp get updated in the projector (below). Check old here. - printMaxGp(false); - } - - // - // Do a level project to update the pressure and velocity fields. - // - if (projector) { - const int finest_level = parent->finestLevel(); - int solve_coarse_level = iteration % 2; - if (verbose) - { - // Print() << "solve_coarse_level " << solve_coarse_level << std::endl; - // Print() << "skip_level_projector " << skip_level_projector << std::endl; - // Print() << "level " << level << std::endl; - // Print() << "finest_level " << finest_level << std::endl; - } - if (skip_level_projector==0 || level==finest_level || solve_coarse_level) { - level_projector(dt,time,iteration); - } - else { - MultiFab& P_old = get_old_data(Press_Type); - MultiFab& P_new = get_new_data(Press_Type); - // Set P_new to be P_old - MultiFab::Copy(P_new,P_old,0,0,1,P_old.nGrow()); - } - } - if (level > 0 && iteration == 1) - p_avg.setVal(0); - } - -#ifdef AMREX_PARTICLES - if (theNSPC() != 0 and NavierStokes::initial_step != true) - { - theNSPC()->AdvectWithUmac(u_mac, level, dt); - } -#endif - } // end prescribed_vel - - return dt_test; // Return estimate of best new timestep. -} - -#ifdef AMREX_PARTICLES -Real -NavierStokes::advance_semistaggered_fsi_diffusedib (Real time, - Real dt, - int iteration, - int ncycle) -{ - BL_PROFILE("NavierStokes::advance_semistaggered_fsi_diffusedib()"); - - // - // Calculate the time N viscosity and diffusivity - // Note: The viscosity and diffusivity at time N+1 are - // initialized here to the time N values just to - // have something reasonable. - // - const Real prev_time = state[State_Type].prevTime(); - const int num_diff = NUM_STATE-AMREX_SPACEDIM-1; - - calcViscosity(prev_time,dt,iteration,ncycle); - calcDiffusivity(prev_time); - MultiFab::Copy(*viscnp1_cc, *viscn_cc, 0, 0, 1, viscn_cc->nGrow()); - MultiFab::Copy(*diffnp1_cc, *diffn_cc, 0, 0, num_diff, diffn_cc->nGrow()); - - // Add this AFTER advance_setup() - if (verbose) - { - Print() << "NavierStokes::advance_semistaggered_fsi_diffusedib(): before velocity update:" - << std::endl; - printMaxValues(false); - } - // - // Compute traced states for normal comp of velocity at half time level. - // Returns best estimate for new timestep. - // - Real dt_test = predict_velocity(dt); - // - // Do MAC projection and update edge velocities. - // - if (do_mac_proj) - { - // To enforce div constraint on coarse-fine boundary, need 1 ghost cell - int ng_rhs = 1; - - MultiFab mac_rhs(grids,dmap,1,ng_rhs,MFInfo(),Factory()); - create_mac_rhs(mac_rhs,ng_rhs,time,dt); - MultiFab& S_old = get_old_data(State_Type); - mac_project(time,dt,S_old,&mac_rhs,umac_n_grow,true); - - } else { - // Use interpolation from coarse to fill grow cells. - create_umac_grown(umac_n_grow, nullptr); - } - // - // Advect velocities. - // - if (do_mom_diff == 0) - velocity_advection(dt); - - // Copy fluid density from old to new and set old and new tracer to 0.0 - if (!advect_and_update_scalar) - { - MultiFab& S_new = get_new_data(State_Type); - MultiFab& S_old = get_old_data(State_Type); - S_old.setVal(fluid_rho, Density, 1, S_old.nGrow()); - S_new.setVal(fluid_rho, Density, 1, S_new.nGrow()); - S_old.setVal(0.0, Tracer, 1, S_old.nGrow()); - S_new.setVal(0.0, Tracer, 1, S_new.nGrow()); - } - // - // Advect scalars. - // - const int first_scalar = Density; - const int last_scalar = first_scalar + NUM_SCALARS - 1; - scalar_advection(dt,first_scalar,last_scalar); - // - // ls related - // note: in the above scalar_advection function, we still advect rho. - // - if (do_phi) { - amrex::Print() << "After scalar_advection " << std::endl; - // const Real prev_time = state[State_Type].prevTime(); - // MultiFab& S_old = get_old_data(State_Type); - // int nScomp = S_old.nComp(); - // fill_allgts(S_old,State_Type,phicomp,1,prev_time); - // MultiFab::Copy(phi_ptime, S_old, phicomp, 0, 1, S_old.nGrow()); - - amrex::Print()<< "scalar_update phi " << std::endl; - amrex::Print()<< "phicomp " << phicomp << std::endl; - scalar_update(dt,phicomp,phicomp); - - // amrex::Print()<< std::endl; - // amrex::Print()<< "6 " << std::endl; - - const Real cur_time = state[State_Type].curTime(); - MultiFab& S_new = get_new_data(State_Type); - fill_allgts(S_new,State_Type,phicomp,1,cur_time); - MultiFab::Copy(phi_ctime, S_new, phicomp, 0, 1, S_new.nGrow()); - - // amrex::Print()<< "7 " << std::endl; - - // reinitialization - if (do_reinit == 1 && (parent->levelSteps(0)% lev0step_of_reinit == 0) ){ - amrex::Print() << "parent->levelSteps(0) " << parent->levelSteps(0) << std::endl; - reinit(); - } - - if (do_mom_diff == 0) { - // update the rho_ctime and density in S_new - phi_to_heavi(geom, epsilon, phi_ctime, heaviside); - heavi_to_rhoormu(heaviside, rho_w, rho_a, rho_ctime); - MultiFab::Copy(S_new, rho_ctime, 0, Density, 1, rho_ctime.nGrow()); - // update phi_half - MultiFab& phi_half_temp = get_phi_half_time(); - // update rho_half - phi_to_heavi(geom, epsilon, phi_half_temp, heaviside); - heavi_to_rhoormu(heaviside, rho_w, rho_a, rho_half); - - // update mu_half - MultiFab outmf_mu_half(grids, dmap, 1, 1, MFInfo(), Factory()); - heavi_to_rhoormu(heaviside, mu_w, mu_a, outmf_mu_half); - MultiFab::Copy(*viscn_cc, outmf_mu_half, 0, 0, 1, 1); - MultiFab::Copy(*viscnp1_cc, outmf_mu_half, 0, 0, 1, 1); - } - else { - // - // Update Rho. - // - scalar_update(dt,first_scalar,first_scalar); - make_rho_curr_time(); - - // update phi_half - MultiFab& phi_half_temp = get_phi_half_time(); - // update rho_half - phi_to_heavi(geom, epsilon, phi_half_temp, heaviside); - - // update mu_half - MultiFab outmf_mu_half(grids, dmap, 1, 1, MFInfo(), Factory()); - heavi_to_rhoormu(heaviside, mu_w, mu_a, outmf_mu_half); - MultiFab::Copy(*viscn_cc, outmf_mu_half, 0, 0, 1, 1); - MultiFab::Copy(*viscnp1_cc, outmf_mu_half, 0, 0, 1, 1); - } - } - else { - // - // Update Rho. - // - scalar_update(dt,first_scalar,first_scalar); - make_rho_curr_time(); - } - - if (prescribed_vel) - { - dt_test = dt; - - amrex::Print() << "Begin the PVF test " << std::endl; - - // Step 1: initialize the nodal level set function - // Create struct to hold initial conditions parameters - // - InitialConditions IC; - ParmParse pp("prob"); - pp.query("blob_radius",IC.blob_radius); - Vector blob_center(AMREX_SPACEDIM, 0.); - pp.queryarr("blob_center",blob_center,0,AMREX_SPACEDIM); - AMREX_D_TERM(IC.blob_x = blob_center[0];, - IC.blob_y = blob_center[1];, - IC.blob_z = blob_center[2];); - // amrex::Print() << "check " << IC.blob_radius << " " - // << IC.blob_x << " " - // << IC.blob_y << " " - // << IC.blob_z << std::endl; - - // Integer indices of the lower left and upper right corners of the - // valid region of the entire domain. - Box const& domain = geom.Domain(); - auto const& dx = geom.CellSizeArray(); - // Physical coordinates of the lower left corner of the domain - auto const& problo = geom.ProbLoArray(); - // Physical coordinates of the upper right corner of the domain - auto const& probhi = geom.ProbHiArray(); - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi_nodal,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - set_initial_phi_nodal(bx, phi_nodal.array(mfi), domain, dx, problo, probhi, IC, time); - } - - // Step 2: calculate pvf from the nodal level set function (only for internal cells) - pvf.setVal(0.0); - nodal_phi_to_pvf(pvf, phi_nodal); - - // Step 3 (optional): copy for visualization - MultiFab& S_new = get_new_data(State_Type); - MultiFab::Copy(S_new, pvf, 0, Tracer, 1, pvf.nGrow()); - - // Step 4: calculate total volume - Real vol = dx[0]; - for (int d=1; dfinestLevel()) - { - MultiFab& S_new = get_new_data(State_Type); - // S_new.setVal(1.0, 0, 1, S_new.nGrow()); // u = 1 - // S_new.setVal(2.0, 1, 1, S_new.nGrow()); // v = 2 - // S_new.setVal(3.0, 2, 1, S_new.nGrow()); // w = 3 - MultiFab EulerForce(S_new.boxArray(), S_new.DistributionMap(), 3, S_new.nGrow()); - Particles::get_particles()->InteractWithEuler(S_new, EulerForce, dt); // parent->levelSteps(0), time - } - //amrex::Abort("Stop here!"); -#endif - // - // Increment rho average. - // - if (!initial_step) - { - if (level > 0) - incrRhoAvg((iteration==ncycle ? 0.5 : 1.0) / Real(ncycle)); - - if (verbose) - { - Print() << "NavierStokes::advance_semistaggered_fsi_diffusedib(): before nodal projection " << std::endl; - printMaxVel(); - // New P, Gp get updated in the projector (below). Check old here. - printMaxGp(false); - } - - // - // Do a level project to update the pressure and velocity fields. - // - if (projector) { - const int finest_level = parent->finestLevel(); - int solve_coarse_level = iteration % 2; - if (verbose) - { - Print() << "solve_coarse_level " << solve_coarse_level << std::endl; - // Print() << "skip_level_projector " << skip_level_projector << std::endl; - // Print() << "level " << level << std::endl; - // Print() << "finest_level " << finest_level << std::endl; - } - if (skip_level_projector==0 || level==finest_level || solve_coarse_level) { - level_projector(dt,time,iteration); - } - else { - MultiFab& P_old = get_old_data(Press_Type); - MultiFab& P_new = get_new_data(Press_Type); - // Set P_new to be P_old - MultiFab::Copy(P_new,P_old,0,0,1,P_old.nGrow()); - } - } - if (level > 0 && iteration == 1) - p_avg.setVal(0); - } -#ifdef AMREX_PARTICLES - if (level == Particles::ParticleFinestLevel())//parent->finestLevel()) - { - MultiFab& S_new = get_new_data(State_Type); - MultiFab& S_old = get_old_data(State_Type); - Particles::get_particles()->UpdateParticles(parent->levelSteps(0), time, S_old, S_new, phi_nodal, pvf, dt); - } -#endif - -#ifdef AMREX_PARTICLES - if (theNSPC() != 0 and NavierStokes::initial_step != true) - { - theNSPC()->AdvectWithUmac(u_mac, level, dt); - } -#endif - } // end prescribed_vel - - return dt_test; // Return estimate of best new timestep. -} -#endif - -// -// phase field method -// -Real -NavierStokes::advance_semistaggered_twophase_phasefield (Real time, - Real dt, - int iteration, - int ncycle) -{ - BL_PROFILE("NavierStokes::advance_semistaggered_twophase_phasefield()"); - - // - // Calculate the time N viscosity and diffusivity - // Note: The viscosity and diffusivity at time N+1 are - // initialized here to the time N values just to - // have something reasonable. - // - const Real prev_time = state[State_Type].prevTime(); - const int num_diff = NUM_STATE-AMREX_SPACEDIM-1; - - calcViscosity(prev_time,dt,iteration,ncycle); - calcDiffusivity(prev_time); - MultiFab::Copy(*viscnp1_cc, *viscn_cc, 0, 0, 1, viscn_cc->nGrow()); - MultiFab::Copy(*diffnp1_cc, *diffn_cc, 0, 0, num_diff, diffn_cc->nGrow()); - - // Add this AFTER advance_setup() - if (verbose) - { - Print() << "NavierStokes::advance_semistaggered_twophase_phasefield(): before velocity update:" - << std::endl; - printMaxValues(false); - } - // - // Compute traced states for normal comp of velocity at half time level. - // Returns best estimate for new timestep. - // - Real dt_test = predict_velocity(dt); - // - // Do MAC projection and update edge velocities. - // - if (do_mac_proj) - { - // To enforce div constraint on coarse-fine boundary, need 1 ghost cell - int ng_rhs = 1; - - MultiFab mac_rhs(grids,dmap,1,ng_rhs,MFInfo(),Factory()); - create_mac_rhs(mac_rhs,ng_rhs,time,dt); - MultiFab& S_old = get_old_data(State_Type); - mac_project(time,dt,S_old,&mac_rhs,umac_n_grow,true); - - } else { - // Use interpolation from coarse to fill grow cells. - create_umac_grown(umac_n_grow, nullptr); - } - // - // Advect velocities. - // - if (do_mom_diff == 0) - velocity_advection(dt); - // - // Advect scalars. - // - const int first_scalar = Density; - const int last_scalar = first_scalar + NUM_SCALARS - 1; - scalar_advection(dt,first_scalar,last_scalar); - // - // pm related - // note: in the above scalar_advection function, we still advect rho. - // - if (do_phi) { - - // SOLVE AND UPDATE THE PHASE FIELD EQUATION HERE - // BY REPLACING THE FOLLOWING LEVEL SET METHOD! - by ZDSJTU - - amrex::Print() << "After scalar_advection " << std::endl; - // const Real prev_time = state[State_Type].prevTime(); - // MultiFab& S_old = get_old_data(State_Type); - // int nScomp = S_old.nComp(); - // fill_allgts(S_old,State_Type,phicomp,1,prev_time); - // MultiFab::Copy(phi_ptime, S_old, phicomp, 0, 1, S_old.nGrow()); - - amrex::Print()<< "scalar_update phi " << std::endl; - amrex::Print()<< "phicomp " << phicomp << std::endl; - scalar_update(dt,phicomp,phicomp); - - // amrex::Print()<< std::endl; - // amrex::Print()<< "6 " << std::endl; - - const Real cur_time = state[State_Type].curTime(); - MultiFab& S_new = get_new_data(State_Type); - fill_allgts(S_new,State_Type,phicomp,1,cur_time); - MultiFab::Copy(phi_ctime, S_new, phicomp, 0, 1, S_new.nGrow()); - - // amrex::Print()<< "7 " << std::endl; - - // reinitialization - if (do_reinit == 1 && (parent->levelSteps(0)% lev0step_of_reinit == 0) ){ - amrex::Print() << "parent->levelSteps(0) " << parent->levelSteps(0) << std::endl; - reinit(); - } - - if (do_mom_diff == 0) { - // update the rho_ctime and density in S_new - phi_to_heavi(geom, epsilon, phi_ctime, heaviside); - heavi_to_rhoormu(heaviside, rho_w, rho_a, rho_ctime); - MultiFab::Copy(S_new, rho_ctime, 0, Density, 1, rho_ctime.nGrow()); - // update phi_half - MultiFab& phi_half_temp = get_phi_half_time(); - // update rho_half - phi_to_heavi(geom, epsilon, phi_half_temp, heaviside); - heavi_to_rhoormu(heaviside, rho_w, rho_a, rho_half); - - // update mu_half - MultiFab outmf_mu_half(grids, dmap, 1, 1, MFInfo(), Factory()); - heavi_to_rhoormu(heaviside, mu_w, mu_a, outmf_mu_half); - MultiFab::Copy(*viscn_cc, outmf_mu_half, 0, 0, 1, 1); - MultiFab::Copy(*viscnp1_cc, outmf_mu_half, 0, 0, 1, 1); - } - else { - amrex::Abort("Only do_mom_diff == 0 is considered now."); - } - } - else { - // - // Update Rho. - // - amrex::Abort("Rho is not updated by themselves."); - } - - // - // Advect momenta after rho^(n+1) has been created. - // - if (do_mom_diff == 1) - velocity_advection(dt); - // - // pm related - // - if (do_phi) { - // - // Add the advective and other terms to get scalars at t^{n+1} except - // the level set function. - scalar_update(dt,first_scalar+1,phicomp-1); - } - // - // S appears in rhs of the velocity update, so we better do it now. - // - if (have_divu) - { - calc_divu(time+dt,dt,get_new_data(Divu_Type)); - if (have_dsdt) - { - calc_dsdt(time,dt,get_new_data(Dsdt_Type)); - if (initial_step) - MultiFab::Copy(get_old_data(Dsdt_Type), - get_new_data(Dsdt_Type),0,0,1,0); - } - } - // - // Add the advective and other terms to get velocity at t^{n+1}. - // - velocity_update(dt); - - // - // Increment rho average. - // - if (!initial_step) - { - if (level > 0) - incrRhoAvg((iteration==ncycle ? 0.5 : 1.0) / Real(ncycle)); - - if (verbose) - { - Print() << "NavierStokes::advance_semistaggered_twophase_ls(): before nodal projection " << std::endl; - printMaxVel(); - // New P, Gp get updated in the projector (below). Check old here. - printMaxGp(false); - } - - // - // Do a level project to update the pressure and velocity fields. - // - if (projector) { - const int finest_level = parent->finestLevel(); - int solve_coarse_level = iteration % 2; - if (verbose) - { - // Print() << "solve_coarse_level " << solve_coarse_level << std::endl; - // Print() << "skip_level_projector " << skip_level_projector << std::endl; - // Print() << "level " << level << std::endl; - // Print() << "finest_level " << finest_level << std::endl; - } - if (skip_level_projector==0 || level==finest_level || solve_coarse_level) { - level_projector(dt,time,iteration); - } - else { - MultiFab& P_old = get_old_data(Press_Type); - MultiFab& P_new = get_new_data(Press_Type); - // Set P_new to be P_old - MultiFab::Copy(P_new,P_old,0,0,1,P_old.nGrow()); - } - } - if (level > 0 && iteration == 1) - p_avg.setVal(0); - } - -#ifdef AMREX_PARTICLES - if (theNSPC() != 0 and NavierStokes::initial_step != true) - { - theNSPC()->AdvectWithUmac(u_mac, level, dt); - } -#endif - - return dt_test; // Return estimate of best new timestep. +// SPDX-FileCopyrightText: 1997 - 2023 Berkeley Lab; 2023 - 2025 Yadong Zeng & ZhuXu Li<1246206018@qq.com> +// +// SPDX-License-Identifier: LicenseRef-OpenSource +// Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +// Original source: https://github.com/AMReX-Fluids/IAMR + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef AMREX_PARTICLES +#include +#endif + +#ifdef BL_USE_VELOCITY +#include +#include +#endif + +#ifdef AMREX_USE_EB +#include +#endif + + +using namespace amrex; + +int NavierStokes::set_plot_coveredCell_val = 1; + +namespace +{ + bool initialized = false; +} + +Vector NavierStokes::errtags; +GpuArray, AMREX_SPACEDIM*2> NavierStokes::m_bc_values; + +void +NavierStokes::Initialize () +{ + if (initialized) return; + + NavierStokesBase::Initialize(); + + // + // Set number of state variables. + // + NUM_STATE = Density + 1; + Tracer = NUM_STATE++; + if (do_trac2) + Tracer2 = NUM_STATE++; + if (do_temp) + Temp = NUM_STATE++; + + // + // ls related + // + if (do_phi) + phicomp = NUM_STATE++; + if (verbose) + amrex::Print() << "do_phi, phicomp, NUM_STATE " << do_phi << " " << phicomp << " " << NUM_STATE << std::endl; + + // + // ls related + // + // NUM_STATE_MAX is defined in NavierStokes.H + // to be AMREX_SPACEDIM + 5 (for Density, 2 scalars, Temp, ls) + AMREX_ALWAYS_ASSERT(NUM_STATE <= NUM_STATE_MAX); + + NUM_SCALARS = NUM_STATE - Density; + + NavierStokes::Initialize_bcs(); + + NavierStokes::Initialize_diffusivities(); + + amrex::ExecOnFinalize(NavierStokes::Finalize); + + initialized = true; +} + +void +NavierStokes::Initialize_bcs () +{ + // + // Default BC values + // + int ntrac = do_trac2 ? 2 : 1; + for (OrientationIter face; face; ++face) + { + int ori = int(face()); + AMREX_D_TERM(m_bc_values[ori][0] = 0.0;, + m_bc_values[ori][1] = 0.0;, + m_bc_values[ori][2] = 0.0;); + m_bc_values[ori][Density] = 1.0; + for ( int nc = 0; nc < ntrac; nc++ ) + m_bc_values[ori][Tracer+nc] = 0.0; + if (do_temp) + m_bc_values[ori][Temp] = 1.0; + // + // ls related + // + if (do_phi) + m_bc_values[ori][phicomp] = 0.0; + } + + ParmParse pp("ns"); + + // + // Check for integer BC type specification in inputs file (older style) + // + if ( pp.contains("lo_bc") ) + { + Vector lo_bc(AMREX_SPACEDIM), hi_bc(AMREX_SPACEDIM); + pp.getarr("lo_bc",lo_bc,0,AMREX_SPACEDIM); + pp.getarr("hi_bc",hi_bc,0,AMREX_SPACEDIM); + for (int i = 0; i < AMREX_SPACEDIM; i++) + { + phys_bc.setLo(i,lo_bc[i]); + phys_bc.setHi(i,hi_bc[i]); + } + } + + // + // Read string BC specifications and BC values + // + { + int bc_tmp[2*AMREX_SPACEDIM]; + + auto f = [&bc_tmp] (std::string const& bcid, Orientation ori) + { + ParmParse pbc(bcid); + std::string bc_type_in = "null"; + pbc.query("type", bc_type_in); + std::string bc_type = amrex::toLower(bc_type_in); + + if (bc_type == "no_slip_wall" or bc_type == "nsw" + or phys_bc.data()[ori] == PhysBCType::noslipwall) + { + amrex::Print() << bcid <<" set to no-slip wall.\n"; + + bc_tmp[ori] = PhysBCType::noslipwall; + + // Note that m_bc_velocity defaults to 0 above so we are ok if + // queryarr finds nothing + std::vector v; + if (pbc.queryarr("velocity", v, 0, AMREX_SPACEDIM)) { + // Here we make sure that we only use the tangential components + // of a specified velocity field -- the wall is not allowed + // to move in the normal direction + v[ori.coordDir()] = 0.0; + for (int i=0; i v; + if (pbc.queryarr("velocity", v, 0, AMREX_SPACEDIM)) { + for (int i=0; i 1 ) + amrex::Abort("NavierStokes::Initialize_specific: Please set tracer 2 inflow bc value with it's own entry in inputs file, e.g. xlo.tracer2 = bc_value"); + pbc.query("tracer2", m_bc_values[ori][Tracer2]); + } + if (do_temp) + pbc.query("temp", m_bc_values[ori][Temp]); + } + else if (bc_type == "pressure_inflow" or bc_type == "pi") + { + amrex::Abort("NavierStokes::Initialize_specific: Pressure inflow boundary condition not yet implemented. If needed for your simulation, please contact us."); + + // amrex::Print() << bcid << " set to pressure inflow.\n"; + + // bc_tmp[ori] = PhysBCType::pressure_inflow; + + // pbc.get("pressure", m_bc_pressure[ori]); + } + else if (bc_type == "pressure_outflow" or bc_type == "po" + or phys_bc.data()[ori] == PhysBCType::outflow) + { + amrex::Print() << bcid << " set to pressure outflow.\n"; + + bc_tmp[ori] = PhysBCType::outflow; + + //pbc.query("pressure", m_bc_pressure[ori]); + Real tmp = 0.; + pbc.query("pressure", tmp); + + if ( tmp != 0. ) + amrex::Abort("NavierStokes::Initialize_specific: Pressure outflow boundary condition != 0 not yet implemented. If needed for your simulation, please contact us."); + } + else if (bc_type == "symmetry" or bc_type == "sym") + { + amrex::Print() << bcid <<" set to symmetry.\n"; + + bc_tmp[ori] = PhysBCType::symmetry; + } + else + { + bc_tmp[ori] = BCType::bogus; + } + + if ( DefaultGeometry().isPeriodic(ori.coordDir()) ) { + if (bc_tmp[ori] == BCType::bogus || phys_bc.data()[ori] == PhysBCType::interior) { + bc_tmp[ori] = PhysBCType::interior; + } else { + std::cerr << " Wrong BC type for periodic boundary at " + << bcid << ". Please correct inputs file."< scal_diff_coefs(n_scal_diff_coefs); + pp.getarr("scal_diff_coefs",scal_diff_coefs,0,n_scal_diff_coefs); + + int scalId = Density; + + for (int i = 0; i < n_scal_diff_coefs; i++) + { + visc_coef[++scalId] = scal_diff_coefs[i]; + } + // + // Set the coefficient for temperature. + // + if (do_temp) + { + pp.get("temp_cond_coef",visc_coef[++scalId]); + } + // + // ls related + // + if (do_phi) + { + visc_coef[phicomp] = -1; + } +} + +void +NavierStokes::Finalize () +{ + initialized = false; +} + +NavierStokes::NavierStokes () = default; + +NavierStokes::NavierStokes (Amr& papa, + int lev, + const Geometry& level_geom, + const BoxArray& bl, + const DistributionMapping& dm, + Real time) + : + NavierStokesBase(papa,lev,level_geom,bl,dm,time) +{ } + +// +// This function initializes the State and Pressure with data. +// +void +NavierStokes::initData () +{ + // + // Initialize the state and the pressure. + // + prob_initData(); + + // + // Initialize GradP + // + computeGradP(state[Press_Type].curTime()); + + // + // Initialize averaging, if using + // + if (avg_interval > 0){ + MultiFab& Save_new = get_new_data(Average_Type); + Save_new.setVal(0.); + } + + +#ifdef BL_USE_VELOCITY + { + // + // We want to add the velocity from the supplied plotfile + // to what we already put into the velocity field via FORT_INITDATA. + // + // This code has a few drawbacks. It assumes that the physical + // domain size of the current problem is the same as that of the + // one that generated the pltfile. It also assumes that the pltfile + // has at least as many levels (with the same refinement ratios) as does + // the current problem. If either of these are false this code is + // likely to core dump. + // + + ParmParse pp("ns"); + + std::string velocity_plotfile; + pp.query("velocity_plotfile", velocity_plotfile); + + std::string velocity_plotfile_xvel_name = "x_velocity"; + pp.query("velocity_plotfile_xvel_name", velocity_plotfile_xvel_name); + + Real velocity_plotfile_scale(1.0); + pp.query("velocity_plotfile_scale",velocity_plotfile_scale); + + if (!velocity_plotfile.empty()) + { + Print() << "initData: reading data from: " << velocity_plotfile << " (" + << velocity_plotfile_xvel_name << ")" << '\n'; + + DataServices::SetBatchMode(); + Amrvis::FileType fileType(Amrvis::NEWPLT); + DataServices dataServices(velocity_plotfile, fileType); + + if (!dataServices.AmrDataOk()) + // + // This calls ParallelDescriptor::EndParallel() and exit() + // + DataServices::Dispatch(DataServices::ExitRequest, NULL); + + AmrData& amrData = dataServices.AmrDataRef(); + Vector plotnames = amrData.PlotVarNames(); + + int idX = -1; + for (int i = 0; i < plotnames.size(); ++i) + if (plotnames[i] == velocity_plotfile_xvel_name) idX = i; + + if (idX == -1) + Abort("Could not find velocity fields in supplied velocity_plotfile"); + else + Print() << "Found " << velocity_plotfile_xvel_name << ", idX = " << idX << '\n'; + + MultiFab& S_new = get_new_data(State_Type); + MultiFab tmp(S_new.boxArray(), S_new.DistributionMap(), 1, 0); + for (int i = 0; i < AMREX_SPACEDIM; i++) + { + amrData.FillVar(tmp, level, plotnames[idX+i], 0); + + MultiFab::Saxpy(S_new, velocity_plotfile_scale, tmp, 0, Xvel+i, 1, 0); + + amrData.FlushGrids(idX+i); + } + + Print() << "initData: finished init from velocity_plotfile" << '\n'; + } + } +#endif /*BL_USE_VELOCITY*/ + +#ifdef AMREX_USE_EB + // + // Perform redistribution on initial fields + // This changes the input velocity fields + // + if (redistribution_type == "StateRedist") { + InitialRedistribution(); + } + + // + // Make sure EB covered cell are set, and that it's not zero, as we + // sometimes divide by rho. + // + { + MultiFab& S_new = get_new_data(State_Type); + EB_set_covered(S_new, COVERED_VAL); + + // + // In some cases, it may be necessary for the covered cells to + // contain a value typical (or around the same order of magnitude) + // to the uncovered cells (e.g. if code to compute variable + // viscosity fails for COVERED_VAL). + // + // set_body_state(S_new); + } +#endif + + // + // Make rho MFs with filled ghost cells + // Not really sure why these are needed as opposed to just filling the + // the ghost cells in state and using that. + // + make_rho_prev_time(); + make_rho_curr_time(); + + // + // Initialize divU and dSdt. + // + if (have_divu) + { + const Real dt = 1.0; + const Real dtin = -1.0; // Dummy value denotes initialization. + const Real curTime = state[Divu_Type].curTime(); + MultiFab& Divu_new = get_new_data(Divu_Type); + + state[State_Type].setTimeLevel(curTime,dt,dt); + + //Make sure something reasonable is in diffn_ec + calcDiffusivity(curTime); + + calc_divu(curTime,dtin,Divu_new); + + if (have_dsdt) + get_new_data(Dsdt_Type).setVal(0); + } + +#ifdef AMREX_PARTICLES + if (do_nspc) { + initParticleData (); + } +#endif +} + +// +// Build/fill any additional data structures after restart. +// +void +NavierStokes::post_restart () +{ + NavierStokesBase::post_restart(); + + //Get probtype, ub, and shearrate; NS_bcfill.H may expect them. + ParmParse pp("prob"); + pp.query("probtype",probtype); + pp.query("ub",ub); + pp.query("shearrate",shearrate); +} + +// +// ADVANCE FUNCTIONS +// + +// +// This function ensures that the multifab registers and boundary +// flux registers needed for syncing the composite grid +// +// u_mac, Vsync, Ssync, rhoavg, fr_adv, fr_visc +// +// are initialized to zero. In general these quantities +// along with the pressure sync registers (sync_reg) and +// advective velocity registers (mac_reg) are compiled by first +// setting them to the coarse value acquired during a coarse timestep +// and then incrementing in the fine values acquired during the +// subcycled fine timesteps. This compilation procedure occurs in +// different parts for different quantities +// +// * u_mac is set in predict_velocity and mac_project. +// * fr_adv, fr_visc are set in velocity_advect and scalar_advect +// * Vsync, Ssync are set in subcycled calls to post_timestep +// * mac_reg is set in mac_project +// * sync_reg is set in level_project +// * rhoavg, pavg are set in advance_setup and advance +// +// After these quantities have been compiled during a coarse +// timestep and subcycled fine timesteps. The post_timestep function +// uses them to sync the fine and coarse levels. If the coarse level +// is not the base level, post_timestep modifies the next coarsest levels +// registers appropriately. +// +// Note :: There is a little ambiguity as to which level owns the +// boundary flux registers. The Multifab registers are quantities +// sized by the coarse level BoxArray and belong to the coarse level. +// The fine levels own the boundary registers, since they are sized by +// the boundaries of the fine level BoxArray. +// + +// +// Compute a timestep at a level. Return largest safe timestep. +// + +Real +NavierStokes::advance (Real time, + Real dt, + int iteration, + int ncycle) +{ + BL_PROFILE("NavierStokes::advance()"); + + //if (verbose) + //{ + Print() << "Advancing grids at level " << level + << " : starting time = " << time + << " with dt = " << dt + << std::endl; + //} + + advance_setup(time,dt,iteration,ncycle); + + amrex::Real dt_test = 0.0; + if (isolver==0) { + dt_test = advance_semistaggered_twophase_ls(time,dt,iteration,ncycle); + } + else if(isolver==1 && do_diffused_ib==1) { +#ifdef AMREX_PARTICLES + dt_test = advance_semistaggered_fsi_diffusedib(time,dt,iteration,ncycle); +#endif + } + else if (isolver==2) { // To be implemented + dt_test = advance_semistaggered_twophase_phasefield(time,dt,iteration,ncycle); + } + else{ + amrex::Abort("Wrong isolver"); + } + + // + // Clean up after the predicted value at t^n+1. + // Estimate new timestep from umac cfl. + // + advance_cleanup(iteration,ncycle); + + //if (verbose) + //{ + Print() << "NavierStokes::advance(): exiting." << std::endl; + printMaxValues(); + //} + + return dt_test; // Return estimate of best new timestep. +} + +// +// This routine advects the scalars +// + +void +NavierStokes::scalar_advection (Real dt, + int fscalar, + int lscalar) +{ + BL_PROFILE("NavierStokes::scalar_advection()"); + + if (advect_and_update_scalar) { + + if (verbose) Print() << "... advect scalars\n"; + // + // Get simulation parameters. + // + const int num_scalars = lscalar - fscalar + 1; + const Real prev_time = state[State_Type].prevTime(); + + // divu + std::unique_ptr divu_fp(getDivCond(nghost_force(),prev_time)); + + // + // Start FillPatchIterator block + // + MultiFab forcing_term( grids, dmap, num_scalars, nghost_force(),MFInfo(),Factory()); + + FillPatchIterator S_fpi(*this,forcing_term,nghost_state(),prev_time,State_Type,fscalar,num_scalars); + MultiFab& Smf=S_fpi.get_mf(); + + // Floor small values of states to be extrapolated + floor(Smf); + + if ( advection_scheme == "Godunov_PLM" || advection_scheme == "Godunov_PPM" || advection_scheme == "BDS") + { + MultiFab visc_terms(grids,dmap,num_scalars,nghost_force(),MFInfo(),Factory()); + FillPatchIterator U_fpi(*this,visc_terms,nghost_state(),prev_time,State_Type,Xvel,AMREX_SPACEDIM); + const MultiFab& Umf=U_fpi.get_mf(); + + { + std::unique_ptr dsdt(getDsdt(nghost_force(),prev_time)); + MultiFab::Saxpy(*divu_fp, 0.5*dt, *dsdt, 0, 0, 1, nghost_force()); + } + + // Compute viscous term + if (be_cn_theta != 1.0) + getViscTerms(visc_terms,fscalar,num_scalars,prev_time); + else + visc_terms.setVal(0.0,1); + + #ifdef _OPENMP + #pragma omp parallel if (Gpu::notInLaunchRegion()) + #endif + for (MFIter S_mfi(Smf,TilingIfNotGPU()); S_mfi.isValid(); ++S_mfi) + { + + // Box for forcing terms + auto const force_bx = S_mfi.growntilebox(nghost_force()); + + if (getForceVerbose) + { + Print() << "---" << '\n' << "C - scalar advection:" << '\n' + << " Calling getForce..." << '\n'; + } + + getForce(forcing_term[S_mfi],force_bx,fscalar,num_scalars, + prev_time,Umf[S_mfi],Smf[S_mfi],0,S_mfi); + + for (int n=0; n nghost_force. + + if ( do_temp && n+fscalar==Temp ) + { + // + // Solving + // dT/dt + U dot del T = ( del dot lambda grad T + H_T ) / (rho c_p) + // with tforces = H_T/c_p (since it's always density-weighted), and + // visc = del dot mu grad T, where mu = lambda/c_p + // + amrex::ParallelFor(force_bx, [tf, visc, rho] + AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { tf(i,j,k) = ( tf(i,j,k) + visc(i,j,k) ) / rho(i,j,k); }); + } + else + { + if (advectionType[fscalar+n] == Conservative) + { + // + // For tracers, Solving + // dS/dt + del dot (U S) = del dot beta grad (S/rho) + rho H_q + // where S = rho q, q is a concentration + // tforces = rho H_q (since it's always density-weighted) + // visc = del dot beta grad (S/rho) + // + amrex::ParallelFor(force_bx, [tf, visc] + AMREX_GPU_DEVICE (int i, int j, int k ) noexcept + { tf(i,j,k) += visc(i,j,k); }); + } + else + { + // + // Solving + // dS/dt + U dot del S = del dot beta grad S + H_q + // where S = q, q is a concentration + // tforces = rho H_q (since it's always density-weighted) + // visc = del dot beta grad S + // + amrex::ParallelFor(force_bx, [tf, visc, rho] + AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { tf(i,j,k) = tf(i,j,k) / rho(i,j,k) + visc(i,j,k); }); + } + } + } + } + } + + ComputeAofs(fscalar, num_scalars, Smf, 0, forcing_term, *divu_fp, false, dt); + + } +} + +// +// This subroutine updates the scalars, before the velocity update +// and the level projection +// +// AT this point in time, all we know is psi^n, rho^n+1/2, and the +// general forcing terms at t^n, and after solving in this routine +// viscous forcing at t^n+1/2. Note, unless more complicated logic +// is invoked earlier, we do not have any estimate of general forcing +// terms at t^n+1/2. +// + +void +NavierStokes::scalar_update (Real dt, + int first_scalar, + int last_scalar) +{ + BL_PROFILE("NavierStokes::scalar_update()"); + + if (advect_and_update_scalar) { + + if (verbose) Print() << "... update scalars\n"; + + scalar_advection_update(dt, first_scalar, last_scalar); + + bool do_any_diffuse = false; + for (int sigma = first_scalar; sigma <= last_scalar; sigma++) + if (is_diffusive[sigma]) do_any_diffuse = true; + + if (do_any_diffuse) + scalar_diffusion_update(dt, first_scalar, last_scalar); + + MultiFab& S_new = get_new_data(State_Type); + //#ifdef AMREX_USE_EB + // set_body_state(S_new); + //#endif + for (int sigma = first_scalar; sigma <= last_scalar; sigma++) + { + if (S_new.contains_nan(sigma,1,0)) + { + Print() << "New scalar " << sigma << " contains Nans" << '\n'; + exit(0); + } + } + } +} + +void +NavierStokes::scalar_diffusion_update (Real dt, + int first_scalar, + int last_scalar) +{ + BL_PROFILE("NavierStokes::scalar_diffusion_update()"); + + const MultiFab& Rh = get_rho_half_time(); + + int ng=1; + const Real prev_time = state[State_Type].prevTime(); + const Real curr_time = state[State_Type].curTime(); + + FillPatch(*this,get_old_data(State_Type),ng,prev_time,State_Type,Density,NUM_SCALARS,Density); + FillPatch(*this,get_new_data(State_Type),ng,curr_time,State_Type,Density,NUM_SCALARS,Density); + + auto Snc = std::make_unique(); + auto Snp1c = std::make_unique(); + + if (level > 0) { + auto& crselev = getLevel(level-1); + Snc->define(crselev.boxArray(), crselev.DistributionMap(), NUM_STATE, ng, MFInfo(), crselev.Factory()); + FillPatch(crselev,*Snc ,ng,prev_time,State_Type,0,NUM_STATE); + + Snp1c->define(crselev.boxArray(), crselev.DistributionMap(), NUM_STATE, ng, MFInfo(), crselev.Factory()); + FillPatch(crselev,*Snp1c,ng,curr_time,State_Type,0,NUM_STATE); + } + + const int nlev = (level ==0 ? 1 : 2); + Vector Sn(nlev,nullptr), Snp1(nlev,nullptr); + Sn[0] = &(get_old_data(State_Type)); + Snp1[0] = &(get_new_data(State_Type)); + + if (nlev>1) { + Sn[1] = Snc.get() ; + Snp1[1] = Snp1c.get() ; + } + + const Vector& theBCs = AmrLevel::desc_lst[State_Type].getBCs(); + + FluxBoxes fb_diffn, fb_diffnp1; + MultiFab **cmp_diffn = nullptr, **cmp_diffnp1 = nullptr; + + MultiFab *delta_rhs = nullptr; + MultiFab *alpha = nullptr; + const int rhsComp = 0, alphaComp = 0, fluxComp = 0; + + FluxBoxes fb_fluxn (this); + FluxBoxes fb_fluxnp1(this); + MultiFab** fluxn = fb_fluxn.get(); + MultiFab** fluxnp1 = fb_fluxnp1.get(); + + Vector diffuse_comp(1); + + for (int sigma = first_scalar; sigma <= last_scalar; sigma++) + { + if (verbose) { + Print()<<"scalar_diffusion_update "<diffuse_scalar (Sn, Sn, Snp1, Snp1, sigma, 1, Rho_comp, + prev_time,curr_time,be_cn_theta,Rh,rho_flag, + fluxn,fluxnp1,fluxComp,delta_rhs,rhsComp, + alpha,alphaComp, + cmp_diffn,cmp_diffnp1,betaComp, + crse_ratio,theBCs[bc_comp],geom, + add_old_time_divFlux, + diffuse_comp); + + delete alpha; + + // + // Increment the viscous flux registers + // + if (do_reflux) + { + FArrayBox fluxtot; + for (int d = 0; d < AMREX_SPACEDIM; d++) + { + MultiFab fluxes; + + if (level < parent->finestLevel()) + { + fluxes.define(fluxn[d]->boxArray(), fluxn[d]->DistributionMap(), 1, 0, MFInfo(), Factory()); + } + + for (MFIter fmfi(*fluxn[d]); fmfi.isValid(); ++fmfi) + { + const Box& ebox = (*fluxn[d])[fmfi].box(); + + fluxtot.resize(ebox,1); + Elixir fdata_i = fluxtot.elixir(); + + auto const& ftot = fluxtot.array(); + auto const& fn = fluxn[d]->array(fmfi); + auto const& fnp1 = fluxnp1[d]->array(fmfi); + + amrex::ParallelFor(ebox, [ftot, fn, fnp1 ] + AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + ftot(i,j,k) = fn(i,j,k) + fnp1(i,j,k); + }); + + if (level < parent->finestLevel()) { + fluxes[fmfi].copy(fluxtot); + } + + if (level > 0) { + getViscFluxReg().FineAdd(fluxtot,d,fmfi.index(),0,sigma,1,dt,RunOn::Gpu); + } + } // mfi + + if (level < parent->finestLevel()) { + getLevel(level+1).getViscFluxReg().CrseInit(fluxes,d,0,sigma,1,-dt); + } + + } // d + } // do_reflux + + if (be_cn_theta != 1) { + fb_diffn.clear(); + } + fb_diffnp1.clear(); + + }//end if(is_diffusive) + } +} +void +NavierStokes::velocity_diffusion_update (Real dt) +{ + BL_PROFILE("NavierStokes::velocity_diffusion_update()"); + + const Real strt_time = ParallelDescriptor::second(); + // + // Compute the viscous forcing. + // Do following except at initial iteration. + // + if (is_diffusive[Xvel]) + { + int rho_flag = (do_mom_diff == 0) ? 1 : 3; + + FluxBoxes fb_viscn, fb_viscnp1; + MultiFab** loc_viscn = nullptr; + MultiFab** loc_viscnp1 = nullptr; + + Real viscTime = state[State_Type].prevTime(); + loc_viscn = fb_viscn.define(this); + getViscosity(loc_viscn, viscTime); + + viscTime = state[State_Type].curTime(); + loc_viscnp1 = fb_viscnp1.define(this); + getViscosity(loc_viscnp1, viscTime); + + diffusion->diffuse_velocity(dt,be_cn_theta,get_rho_half_time(),rho_flag, + nullptr,loc_viscn,viscn_cc,loc_viscnp1,viscnp1_cc); + } + + if (verbose) + { + Real run_time = ParallelDescriptor::second() - strt_time; + const int IOProc = ParallelDescriptor::IOProcessorNumber(); + + ParallelDescriptor::ReduceRealMax(run_time,IOProc); + + Print() << "NavierStokes:velocity_diffusion_update(): lev: " << level + << ", time: " << run_time << '\n'; + } +} + +void +NavierStokes::sum_integrated_quantities () +{ + const int finest_level = parent->finestLevel(); + const Real time = state[State_Type].curTime(); + + Vector mf(finest_level+1); + + // Container to hold derived data + Vector> derived_mf(finest_level+1); + // Proper container for call to volumeWeightedSum + Vector derived_mf_ptrs(finest_level+1); + + for (int lev = 0; lev <= finest_level; lev++) + { + NavierStokes& ns_level = getLevel(lev); + + mf[lev] = &ns_level.get_new_data(State_Type); + derived_mf[lev] = ns_level.derive("energy",time,0); + derived_mf_ptrs[lev] = derived_mf[lev].get(); + } + + Real mass = volumeWeightedSum(mf, Density, + parent->Geom(), parent->refRatio()); + Real trac = volumeWeightedSum(mf, Tracer, + parent->Geom(), parent->refRatio()); + Real energy = volumeWeightedSum(derived_mf_ptrs, 0, + parent->Geom(), parent->refRatio()); + + Print() << '\n'; + Print().SetPrecision(12) << "TIME= " << time << " MASS= " << mass << '\n'; + Print().SetPrecision(12) << "TIME= " << time << " TRAC= " << trac << '\n'; + Print().SetPrecision(12) << "TIME= " << time << " KINETIC ENERGY= " << energy << '\n'; + + // + // ls related + // + if (ParallelDescriptor::IOProcessor()) { + std::ofstream ofs("mass.txt", std::ios::app); // append mode + // std::ofstream ofs("mass.txt", std::ios::out); // override mode + if (ofs.is_open()) + { + amrex::Print(ofs).SetPrecision(12) << time << " " << mass << " " << trac << " " << energy << '\n'; + ofs.close(); + } + else + { + amrex::Abort("Failed to open mass.txt for writing"); + } + } +} + +void +NavierStokes::setPlotVariables() +{ + AmrLevel::setPlotVariables(); +} + +void +NavierStokes::writePlotFilePre (const std::string& /*dir*/, + std::ostream& /*os*/) +{ +#ifdef AMREX_USE_EB + if ( set_plot_coveredCell_val ) + { + for (amrex::Long i =0; i < state.size(); i++) + { + auto& sdata = state[i].newData(); + // only cell-centered state data goes into plotfile + if ( sdata.ixType().cellCentered() ){ + // set covered values for ease of viewing + EB_set_covered(sdata, 0.0); + } + } + } +#endif +} + +void +NavierStokes::writePlotFilePost (const std::string& dir, + std::ostream& /*os*/) +{ + if (level == 0 && ParallelDescriptor::IOProcessor()) + { + // job_info file with details about the run + std::ofstream jobInfoFile; + std::string FullPathJobInfoFile = dir; + FullPathJobInfoFile += "/job_info"; + jobInfoFile.open(FullPathJobInfoFile.c_str(), std::ios::out); + + std::string PrettyLine = "===============================================================================\n"; + std::string OtherLine = "--------------------------------------------------------------------------------\n"; + std::string SkipSpace = " "; + + + // job information + jobInfoFile << PrettyLine; + jobInfoFile << " Job Information\n"; + jobInfoFile << PrettyLine; + + jobInfoFile << "number of MPI processes: " << ParallelDescriptor::NProcs() << '\n'; +#ifdef _OPENMP + jobInfoFile << "number of threads: " << omp_get_max_threads() << '\n'; +#endif + jobInfoFile << "\n\n"; + + // plotfile information + jobInfoFile << PrettyLine; + jobInfoFile << " Plotfile Information\n"; + jobInfoFile << PrettyLine; + + time_t now = time(nullptr); + + // Convert now to tm struct for local timezone + tm* localtm = localtime(&now); + jobInfoFile << "output data / time: " << asctime(localtm); + + char currentDir[FILENAME_MAX]; + if (getcwd(currentDir, FILENAME_MAX)) { + jobInfoFile << "output dir: " << currentDir << '\n'; + } + + jobInfoFile << "\n\n"; + + + // build information + jobInfoFile << PrettyLine; + jobInfoFile << " Build Information\n"; + jobInfoFile << PrettyLine; + + jobInfoFile << "build date: " << buildInfoGetBuildDate() << '\n'; + jobInfoFile << "build machine: " << buildInfoGetBuildMachine() << '\n'; + jobInfoFile << "build dir: " << buildInfoGetBuildDir() << '\n'; + jobInfoFile << "AMReX dir: " << buildInfoGetAMReXDir() << '\n'; + + jobInfoFile << '\n'; + + jobInfoFile << "COMP: " << buildInfoGetComp() << '\n'; + jobInfoFile << "COMP version: " << buildInfoGetCompVersion() << "\n"; + jobInfoFile << "FCOMP: " << buildInfoGetFcomp() << '\n'; + jobInfoFile << "FCOMP version: " << buildInfoGetFcompVersion() << "\n"; + + jobInfoFile << "\n"; + + const char* githash1 = buildInfoGetGitHash(1); + const char* githash2 = buildInfoGetGitHash(2); + if (strlen(githash1) > 0) { + jobInfoFile << "IAMR git hash: " << githash1 << "\n"; + } + if (strlen(githash2) > 0) { + jobInfoFile << "AMReX git hash: " << githash2 << "\n"; + } + + jobInfoFile << "\n\n"; + + + // runtime parameters + jobInfoFile << PrettyLine; + jobInfoFile << " Inputs File Parameters\n"; + jobInfoFile << PrettyLine; + + ParmParse::dumpTable(jobInfoFile, true); + + jobInfoFile.close(); + + } + + // + // Put particles in plotfile? + // Used in regression testing, but also useful if you want to use + // AMReX's tool particle_compare without writing a full checkpoint + // +#ifdef AMREX_PARTICLES + if (level == 0 && theNSPC() != 0 && particles_in_plotfile) + { + theNSPC()->Checkpoint(dir,"Particles"); + } +#endif + +#ifdef AMREX_PARTICLES + if(level == parent->finestLevel()){ + Particles::get_particles()->mContainer->Checkpoint(dir, "particles"); + } +#endif + +#ifdef AMREX_USE_EB + if ( set_plot_coveredCell_val ) + { + for (amrex::Long i =0; i < state.size(); i++) + { + auto& sdata = state[i].newData(); + // only cell-centered state data goes into plotfile + if ( sdata.ixType().cellCentered() ){ + // put COVERED_VAL back or set_body_state + EB_set_covered(sdata, COVERED_VAL); + } + } + } +#endif + +} + +std::unique_ptr +NavierStokes::derive (const std::string& name, + Real time, + int ngrow) +{ +#ifdef AMREX_PARTICLES + return ParticleDerive(name, time, ngrow); +#else + return AmrLevel::derive(name, time, ngrow); +#endif +} + +void +NavierStokes::derive (const std::string& name, + Real time, + MultiFab& mf, + int dcomp) +{ +#ifdef AMREX_PARTICLES + ParticleDerive(name,time,mf,dcomp); +#else + AmrLevel::derive(name,time,mf,dcomp); +#endif +} + +// +// Ensure state, and pressure are consistent. +// +void +NavierStokes::post_init (Real stop_time) +{ + + if (level > 0) + // + // Nothing to sync up at level > 0. + // + return; + + const int finest_level = parent->finestLevel(); + Real dt_init = 0.0; + Vector dt_save(finest_level+1); + Vector nc_save(finest_level+1); + // + // Ensure state is consistent, i.e. velocity field is non-divergent, + // pressure & Gradp have been initialized, Coarse levels are fine + // level averages. + // + post_init_state(); + // + // Estimate the initial timestepping. + // + post_init_estDT(dt_init, nc_save, dt_save, stop_time); + // + // Initialize the pressure by iterating the initial timestep. + // + post_init_press(dt_init, nc_save, dt_save); + // + // Compute the initial estimate of conservation. + // + if (sum_interval > 0) + sum_integrated_quantities(); + + if (NavierStokesBase::avg_interval > 0) + { + NavierStokesBase::time_avg.resize(finest_level+1); + NavierStokesBase::time_avg_fluct.resize(finest_level+1); + NavierStokesBase::dt_avg.resize(finest_level+1); + NavierStokesBase::time_avg[level] = 0.; + NavierStokesBase::time_avg_fluct[level] = 0.; + NavierStokesBase::dt_avg[level] = 0.; + const amrex::Real dt_level = parent->dtLevel(level); + time_average(NavierStokesBase::time_avg[level], NavierStokesBase::time_avg_fluct[level], NavierStokesBase::dt_avg[level], dt_level); + } + +} + +// +// Initialize the pressure by iterating the initial timestep +// + +void +NavierStokes::post_init_press (Real& dt_init, + Vector& nc_save, + Vector& dt_save) +{ + if ( init_iter <= 0 ) + { + parent->setDtLevel(dt_save); + parent->setNCycle(nc_save); + + NavierStokes::initial_step = false; + + Print()<< "WARNING! post_init_press(): exiting without doing initial iterations because init_iter <= 0."<finestLevel(); + NavierStokes::initial_iter = true; + + if (verbose) + { + Print() << std::endl + << "post_init_press(): " + << "doing initial pressure iterations with dt = " + << dt_init + << std::endl; + } + + // + // Iterate over the advance function. + // + for (int iter = 0; iter < init_iter; iter++) + { + + if (verbose) + { + Print() << std::endl + << "post_init_press(): iter = " << iter + << std::endl; + } + + for (int k = 0; k <= finest_level; k++ ) + { + getLevel(k).advance(strt_time,dt_init,1,1); + } + + // + // Constructs a guess at P. + // + Vector sig(finest_level+1, nullptr); + + for (int k = 0; k <= finest_level; k++) + { + sig[k] = &(getLevel(k).get_rho_half_time()); + } + + if (projector) + { + projector->initialSyncProject(0,sig,dt_init, + strt_time,have_divu); + } + + for (int k = finest_level-1; k >= 0; k--) + { + getLevel(k).avgDown(); + } + + if (verbose) + { + // initSyncProject project d(u)/dt, so new velocity + // is actually the projected acceleration + // We don't actually care because initial velocity state will be + // recovered at the end of each iteration. + // However, we need to recover u_new from d(u)/dt if we want to print + // correct diagnostics + MultiFab& S_new = get_new_data(State_Type); + MultiFab& S_old = get_old_data(State_Type); + MultiFab::Xpay(S_new, dt_init, S_old, Xvel, Xvel, AMREX_SPACEDIM, 0); + + Print() << "After sync projection and avgDown:" << std::endl; + printMaxValues(); + } + + for (int k = 0; k <= finest_level; k++) + { + // + // Reset state variables to initial time, but + // do not reset pressure variable, only pressure time. + // do not reset dsdt variable, only dsdt time. + // + // The reset of data is ultimately achieved via a swap and swap back to + // preserve old_data. resetState ends up calling swap(old_data, new_data) + // but then advance_setup also ends up calling swap(old_data, new_data). + // Since pressure is not reset, after advance_setup, the next step will + // progress with p_old==p_new. + getLevel(k).resetState(strt_time, dt_init, dt_init); + } + + NavierStokes::initial_iter = false; + } + + NavierStokes::initial_step = false; + // + // Re-instate timestep. + // + for (int k = 0; k <= finest_level; k++) + { + getLevel(k).setTimeLevel(strt_time,dt_save[k],dt_save[k]); + } + + parent->setDtLevel(dt_save); + parent->setNCycle(nc_save); + + // Add space to output if verbose + if (verbose) + { + Print() << std::endl + << "post_init_press(): exiting after " << init_iter << " iterations" + << std::endl + << "After initial iterations: " + << std::endl; + printMaxValues(); + Print() << std::endl << std::endl; + } + +} + +// +// The Mac Sync correction function +// +void +NavierStokes::mac_sync () +{ + BL_PROFILE_REGION_START("R::NavierStokes::mac_sync()"); + BL_PROFILE("NavierStokes::mac_sync()"); + + if (!do_reflux) return; + + if (verbose) + { + Print() << std::endl + << "mac_sync() on level "<dtLevel(level); + MultiFab* DeltaSsync = nullptr;// hold (Delta rho)*q for conserved quantities + // does this have ghosts filled? + MultiFab& Rh = get_rho_half_time(); + +#ifdef AMREX_USE_EB + const int nghost = umac_n_grow; +#else + const int nghost = 0; +#endif + + Array Ucorr; + for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) + { + const BoxArray& edgeba = getEdgeBoxArray(idim); + + Ucorr[idim]= new MultiFab(edgeba,dmap,1,nghost,MFInfo(),Factory()); + } + + sync_setup(DeltaSsync); + // + // Compute the u_mac for the correction. + // + Vector rho_math_bc = fetchBCArray(State_Type,Density,1); + mac_projector->mac_sync_solve(level,dt,Rh,rho_math_bc[0],fine_ratio,Ucorr); + // + // Update coarse grid state by adding correction from mac_sync solve + // the correction is the advective tendency of the new velocities. + // + MultiFab& S_new = get_new_data(State_Type); + mac_projector->mac_sync_compute(level,Ucorr,Vsync,Ssync, + advectionType, prev_time,dt, + NUM_STATE,be_cn_theta, + do_mom_diff); + // + // Delete Ucorr; we're done with it. + // + for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) + delete Ucorr[idim]; + + + // + // For all conservative variables Q (other than density) + // Q is taken as rho*q and we increment sync by -(sync_for_rho)*q + // (See Pember, et. al., LBNL-41339, Jan. 1989) + // This increment will be added back after the diffusive sync. + // + int iconserved = -1; + for (int istate = AMREX_SPACEDIM; istate < NUM_STATE; istate++) + { + if (istate != Density && advectionType[istate] == Conservative) + { + iconserved++; +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(S_new,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + auto const& rho = S_new.array(mfi,Density); + auto const& Snew = S_new.array(mfi,istate); + auto const& dSsync = DeltaSsync->array(mfi); + auto const& drhosync = Ssync.array(mfi,Density-AMREX_SPACEDIM); + auto const& ssync = Ssync.array(mfi,istate-AMREX_SPACEDIM); + + amrex::ParallelFor(bx, [rho, Snew, dSsync, drhosync, ssync, iconserved ] + AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + dSsync(i,j,k,iconserved) = Snew(i,j,k) * drhosync(i,j,k) / rho(i,j,k); + ssync(i,j,k) -= dSsync(i,j,k,iconserved); + }); + } + } + } + + if (do_mom_diff == 1) + { +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(S_new, TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + auto const& rho_c = S_new.array(mfi,Density); + auto const& vsync = Vsync.array(mfi,Xvel); + amrex::ParallelFor(bx, [rho_c, vsync] + AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + for (int n = 0; n < AMREX_SPACEDIM; n++) { + vsync(i,j,k,n) /= rho_c(i,j,k); + } + }); + } + } + // + // Compute viscous sync. + // + if (is_diffusive[Xvel]) + { + int rho_flag = (do_mom_diff == 0) ? 1 : 3; + + MultiFab** loc_viscn = nullptr; + FluxBoxes fb_viscn; + + Real viscTime = state[State_Type].prevTime(); + loc_viscn = fb_viscn.define(this); + getViscosity(loc_viscn, viscTime); + + diffusion->diffuse_Vsync(Vsync,dt,be_cn_theta,Rh,rho_flag,loc_viscn,0); + } + + FluxBoxes fb_SC; + MultiFab** fluxSC = nullptr; + bool any_diffusive = false; + for (int sigma = 0; sigma < numscal; sigma++) + if (is_diffusive[AMREX_SPACEDIM+sigma]) + any_diffusive = true; + + if (any_diffusive) { + fluxSC = fb_SC.define(this); + } + + Vector diffuse_comp(1); + int ng=1; + const Real curr_time = state[State_Type].curTime(); + + // Diffusion solver switches + // implies that Diff solve does NOT need Sold + const bool add_old_time_divFlux = false; + + const int nlev = 1; + Vector Snp1(nlev,nullptr); + + MultiFab dSsync(grids,dmap,NUM_STATE,1,MFInfo(),Factory()); + Snp1[0] = &dSsync; + + Vector Rhonp1(nlev,nullptr); + Rhonp1[0] = &(get_new_data(State_Type)); + int Rho_comp = Density; + + FluxBoxes fb_fluxn (this); + MultiFab** fluxn = fb_fluxn.get(); + + const Vector& theBCs = AmrLevel::desc_lst[State_Type].getBCs(); + + for (int sigma = 0; sigmasetVal(0.,state_ind,1,ng); + + FluxBoxes fb_diffnp1; + MultiFab** cmp_diffnp1=nullptr, **cmp_diffn=nullptr; + + Real diffTime = state[State_Type].curTime(); + cmp_diffnp1 = fb_diffnp1.define(this); + getDiffusivity(cmp_diffnp1, diffTime, AMREX_SPACEDIM+sigma,0,1); + + int S_comp = state_ind; + const int num_comp = 1; + const int fluxComp = 0; + MultiFab *delta_rhs = &Ssync; + int rhsComp = sigma; + MultiFab *alpha_in = nullptr; + const int alphaComp = 0; + int betaComp = 0; + + diffuse_comp[0] = is_diffusive[AMREX_SPACEDIM+sigma]; + + diffusion->diffuse_scalar ({},{},Snp1,Rhonp1, + S_comp,num_comp,Rho_comp, + prev_time,curr_time,be_cn_theta, + Rh,rho_flag, + fluxn,fluxSC,fluxComp, + delta_rhs,rhsComp, + alpha_in,alphaComp, + cmp_diffn,cmp_diffnp1,betaComp, + crse_ratio,theBCs[state_ind],geom, + add_old_time_divFlux,diffuse_comp); + + delete alpha_in; + + MultiFab::Copy(Ssync,*Snp1[0],state_ind,sigma,1,0); + + // + // Increment the viscous flux registers + // + if (level > 0) + { + for (int d = 0; d < AMREX_SPACEDIM; d++) + { + getViscFluxReg().FineAdd(*fluxSC[d],d,0,state_ind,1,dt); + } + } + } + else // state component not diffusive + { + // + // The following used to be done in mac_sync_compute. Ssync is + // the source for a rate of change to S over the time step, so + // Ssync*dt is the source to the actual sync amount. + // + Ssync.mult(dt,sigma,1,Ssync.nGrow()); + } + } + + // + // For all conservative variables Q (other than density) + // increment sync by (sync_for_rho)*q_presync. + // (See Pember, et. al., LBNL-41339, Jan. 1989) + // + iconserved = -1; + for (int istate = AMREX_SPACEDIM; istate < NUM_STATE; istate++) + { + if (istate != Density && advectionType[istate] == Conservative) + { + iconserved++; + + // Must multiply by dt to agree with the factor of dt just put + // into Ssync above. + MultiFab::Saxpy(Ssync,dt,*DeltaSsync,iconserved,istate-AMREX_SPACEDIM,1,0); + } + } + // + // Add the sync correction to the state. + // + MultiFab::Add(S_new,Ssync,0,AMREX_SPACEDIM,numscal,0); + // + // Update rho_ctime after rho is updated with Ssync. + // + make_rho_curr_time(); + + if (level > 0) incrRhoAvg(Ssync,Density-AMREX_SPACEDIM,1.0); + // + // Get boundary conditions. + // + const auto N = int(grids.size()); + + Vector sync_bc(N); + Vector< Vector > sync_bc_array(N); + + for (int i = 0; i < N; i++) + { + sync_bc_array[i] = getBCArray(State_Type,i,Density,numscal); + sync_bc[i] = sync_bc_array[i].dataPtr(); + } + // + // Interpolate the sync correction to the finer levels, + // and update rho_ctime, rhoAvg at those levels. + // + IntVect ratio = IntVect::TheUnitVector(); + const Real mult = 1.0; + for (int lev = level+1; lev <= parent->finestLevel(); lev++) + { + ratio *= parent->refRatio(lev-1); + NavierStokes& fine_lev = getLevel(lev); + const BoxArray& fine_grids = fine_lev.boxArray(); + MultiFab sync_incr(fine_grids,fine_lev.DistributionMap(),numscal,0,MFInfo(),fine_lev.Factory()); + sync_incr.setVal(0.0); + + SyncInterp(Ssync,level,sync_incr,lev,ratio,0,0, + numscal,1,mult,sync_bc.dataPtr()); + + MultiFab& Sf_new = fine_lev.get_new_data(State_Type); + MultiFab::Add(Sf_new,sync_incr,0,Density,numscal,0); + + fine_lev.make_rho_curr_time(); + fine_lev.incrRhoAvg(sync_incr,Density-AMREX_SPACEDIM,1.0); + } + + sync_cleanup(DeltaSsync); + + BL_PROFILE_REGION_STOP("R::NavierStokes::mac_sync()"); +} + +// +// The reflux function +// +void +NavierStokes::reflux () +{ + if (level == parent->finestLevel()) + return; + + BL_PROFILE("NavierStokes::reflux()"); + + AMREX_ASSERT(do_reflux); + // + // First do refluxing step. + // + auto& fr_adv = getAdvFluxReg(level+1); + FluxRegister& fr_visc = getViscFluxReg(level+1); + const Real dt_crse = parent->dtLevel(level); + // + // It is important, for do_mom_diff == 0, to do the viscous + // refluxing first, since this will be divided by rho_half + // before the advective refluxing is added. In the case of + // do_mom_diff == 1, both components of the refluxing will + // be divided by rho^(n+1) in level_sync. + // + + fr_visc.Reflux(Vsync,volume,1.0,0,0,AMREX_SPACEDIM,geom); + fr_visc.Reflux(Ssync,volume,1.0,AMREX_SPACEDIM,0,NUM_STATE-AMREX_SPACEDIM,geom); + + const MultiFab& Rh = get_rho_half_time(); + + if (do_mom_diff == 0) + { +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(Vsync,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + auto const& vsync = Vsync.array(mfi); + auto const& rhohalf = Rh.array(mfi); + + amrex::ParallelFor(bx, AMREX_SPACEDIM, [vsync, rhohalf] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { + vsync(i,j,k,n) /= rhohalf(i,j,k); + }); + } + } + + for (int istate = AMREX_SPACEDIM; istate < NUM_STATE; istate++) + { + if (advectionType[istate] == NonConservative) + { + MultiFab::Divide(Ssync,Rh,0,istate-AMREX_SPACEDIM,1,0); + } + } + +#ifdef AMREX_USE_EB + fr_adv.Reflux(Vsync,*volfrac, 0, 0, AMREX_SPACEDIM); + fr_adv.Reflux(Ssync,*volfrac, AMREX_SPACEDIM, 0, NUM_STATE-AMREX_SPACEDIM); +#else + fr_adv.Reflux(Vsync, 0, 0, AMREX_SPACEDIM); + fr_adv.Reflux(Ssync, AMREX_SPACEDIM, 0,NUM_STATE-AMREX_SPACEDIM); +#endif + const Real scale = 1.0/dt_crse; + Vsync.mult(scale); + Ssync.mult(scale); + + const BoxArray& fine_boxes = getLevel(level+1).boxArray(); + // + // Zero out coarse grid cells which underlie fine grid cells. + // + BoxArray baf = fine_boxes; + + baf.coarsen(fine_ratio); + +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + { + std::vector< std::pair > isects; + for (MFIter mfi(Vsync,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.growntilebox(); + auto const& vsync = Vsync.array(mfi); + auto const& ssync = Ssync.array(mfi); + int nstate = NUM_STATE; + + baf.intersections(bx,isects); + + for (const auto& is : isects) + { + amrex::ParallelFor(is.second, [vsync, ssync, nstate] + AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + for (int n = 0; n < AMREX_SPACEDIM; n++) { + vsync(i,j,k,n) = 0.0; + } + for (int n = 0; n < nstate-AMREX_SPACEDIM; n++) { + ssync(i,j,k,n) = 0.0; + } + }); + } + } + } +} + +// +// Average fine information from the complete set of state types to coarse. +// + +void +NavierStokes::avgDown () +{ + if (level == parent->finestLevel()) + return; + + auto& fine_lev = getLevel(level+1); + // + // Average down the State and Pressure at the new time. + // + avgDown_StatePress(); + + // + // Next average down divu and dSdT at new time. + // + if (have_divu) + { + MultiFab& Divu_crse = get_new_data(Divu_Type); + MultiFab& Divu_fine = fine_lev.get_new_data(Divu_Type); + + average_down(Divu_fine, Divu_crse, 0, 1); + } + if (have_dsdt) + { + MultiFab& Dsdt_crse = get_new_data(Dsdt_Type); + MultiFab& Dsdt_fine = fine_lev.get_new_data(Dsdt_Type); + + average_down(Dsdt_fine, Dsdt_crse, 0, 1); + } +} + +// +// Default divU is set to zero. +// + +void +NavierStokes::calc_divu (Real time, + Real /*dt*/, + MultiFab& divu) +{ + BL_PROFILE("NavierStokes::calc_divu()"); + + if (have_divu) + { + // Don't think we need this here, but then ghost cells are uninitialized + // divu.setVal(0); + + if (do_temp && visc_coef[Temp] > 0.0) + { + // Compute Div(U) = Div(lambda * Grad(T))/(c_p*rho*T) + // = Div(temp_cond_coeff * Grad(T)) / (rho*T) + // where temp_cond_coef = lambda/cp + getViscTerms(divu,Temp,1,time); + + const MultiFab& rhotime = get_rho(time); + + FillPatchIterator temp_fpi(*this,divu,0,time,State_Type,Temp,1); + MultiFab& tmf = temp_fpi.get_mf(); + +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for ( MFIter rho_mfi(rhotime,TilingIfNotGPU()); rho_mfi.isValid(); ++rho_mfi) + { + const Box& bx = rho_mfi.tilebox(); + auto const& div = divu.array(rho_mfi); + auto const& rho = rhotime.array(rho_mfi); + auto const& temp = tmf.array(rho_mfi); +#ifdef AMREX_USE_EB + auto const& ebfactory = dynamic_cast(Factory()); + auto const& flagfab = ebfactory.getMultiEBCellFlagFab()[rho_mfi]; + + if (flagfab.getType(bx) == FabType::covered) + { + amrex::ParallelFor(bx, [div] + AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + div( i, j, k ) = COVERED_VAL; + }); + } + else if (flagfab.getType(bx) != FabType::regular) + { + auto vfrac = ebfactory.getVolFrac().const_array(rho_mfi); + + amrex::ParallelFor(bx, [div, rho, temp, vfrac] + AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + if ( vfrac(i,j,k) > 0.0 ) + { + div(i,j,k) /= ( rho(i,j,k)*temp(i,j,k) ); + } + else + { + div(i,j,k) = COVERED_VAL; + } + }); + } + else +#endif + { + amrex::ParallelFor(bx, [div, rho, temp] + AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + div(i,j,k) /= ( rho(i,j,k)*temp(i,j,k) ); + }); + } + } + } + else + { + divu.setVal(0); + } + } +} + +void +NavierStokes::getViscTerms (MultiFab& visc_terms, + int src_comp, + int ncomp, + Real time) +{ + BL_PROFILE("NavierStokes::getViscTerms()"); + // + // The logic below for selecting between scalar or tensor solves does + // not allow for calling NavierStokes::getViscTerms with src_comp=Yvel + // or Zvel + // +#ifdef AMREX_DEBUG + if (src_compgetTensorViscTerms(visc_terms,time,viscosity,viscosityCC,0); + } + // + // Get Scalar Diffusive Terms + // + const int first_scal = (src_comp==Xvel) ? AMREX_SPACEDIM : src_comp; + const int num_scal = (src_comp==Xvel) ? ncomp-AMREX_SPACEDIM : ncomp; + + if (num_scal > 0) + { + for (int icomp = first_scal; icomp < first_scal+num_scal; icomp++) + { + if (is_diffusive[icomp]) + { + diffusive = true; + + int rho_flag = Diffusion::set_rho_flag(diffusionType[icomp]); + + FluxBoxes fb; + MultiFab** cmp_diffn = nullptr; + + cmp_diffn = fb.define(this); + getDiffusivity(cmp_diffn, time, icomp, 0, 1); + + diffusion->getViscTerms(visc_terms,src_comp,icomp, + time,rho_flag,cmp_diffn,0); + } + else { + visc_terms.setVal(0.0,icomp-src_comp,1,nGrow); + } + } + } + // + // Ensure consistent grow cells + // + if (diffusive && nGrow > 0) + { + visc_terms.FillBoundary(0, ncomp, geom.periodicity()); + Extrapolater::FirstOrderExtrap(visc_terms, geom, 0, ncomp); + } +} + +// +// Functions calcViscosity/Diffusivity and getViscosity/Diffusivity are +// for calculating variable viscosity and diffusivity. Here we default to +// constant visc/diff and set the variable viscosity and diffusivity arrays +// to the values in visc_coef and diff_coef. +// For variable viscosity/diffusivity, (per MSD) calcViscosity/Diffusivity +// should compute the transport coefficients at cell centers (or cell centroids +// for EB) and getViscosity/Diffusivity should interpolate those to faces (or +// face-centroids for EB). +// +void +NavierStokes::calcViscosity (const Real time, + const Real /*dt*/, + const int /*iteration*/, + const int /*ncycle*/) +{ + if (is_diffusive[Xvel]) + { + if (visc_coef[Xvel] >= 0.0) + { + auto whichTime = which_time(State_Type,time); + AMREX_ASSERT(whichTime == AmrOldTime || whichTime == AmrNewTime); + + auto* visc = (whichTime == AmrOldTime ? viscn_cc : viscnp1_cc); + visc->setVal(visc_coef[Xvel], 0, visc->nComp(), visc->nGrow()); + } + else + { + Abort("NavierStokes::calcViscosity() : must have velocity visc_coef >= 0.0"); + } + } +} + +void +NavierStokes::calcDiffusivity (const Real time) +{ + // + // NOTE: In the diffusivity + // arrays, there is an offset since no diffusivity array + // is kept for the velocities or the density. So, the scalar + // component Density+1 in the state corresponds to component + // 0 in the arrays diffn and diffnp1. + // + int src_comp = Density+1; + int ncomp = NUM_STATE - AMREX_SPACEDIM -1; + + const TimeLevel whichTime = which_time(State_Type,time); + AMREX_ASSERT(whichTime == AmrOldTime || whichTime == AmrNewTime); + + MultiFab* diff = (whichTime == AmrOldTime ? diffn_cc : diffnp1_cc); + for (int comp=src_comp; comp= 0.0) + { + diff->setVal(visc_coef[comp], diff_comp, 1, diff->nGrow()); + } + else + { + Abort("NavierStokes::calcDiffusivity() : must have scalar diff_coefs >= 0.0"); + } + } + } +} + +void +NavierStokes::getViscosity (MultiFab* viscosity[AMREX_SPACEDIM], + const Real time) +{ + // // + // // Select time level to work with (N or N+1) + // // + // const TimeLevel whichTime = which_time(State_Type,time); + // AMREX_ASSERT(whichTime == AmrOldTime || whichTime == AmrNewTime); + + // MultiFab *visc = (whichTime == AmrOldTime ? viscn_cc : viscnp1_cc); + + // For non-const viscosity, uncomment above and add interp from + // cell-center/centroid to faces. + // But here we simply do constant viscosity. + + for (int dir=0; dirsetVal(visc_coef[Xvel], 0, viscosity[dir]->nComp(), viscosity[dir]->nGrow()); + } + + if (do_LES) + { + FluxBoxes mu_LES(this,1,0); + MultiFab** mu_LES_mf = mu_LES.get(); + for (int dir=0; dirsetVal(0., 0, mu_LES_mf[dir]->nComp(), mu_LES_mf[dir]->nGrow()); + } + + NavierStokesBase::calc_mut_LES(mu_LES_mf,time); + + for (int dir=0; dir Density); + // // + // // Pick correct component in the diffn/diffnp1 array + // // + // int diff_comp = state_comp - Density - 1; + // // + // // Select time level to work with (N or N+1) + // // + // const TimeLevel whichTime = which_time(State_Type,time); + // AMREX_ASSERT(whichTime == AmrOldTime || whichTime == AmrNewTime); + + // MultiFab *diff = (whichTime == AmrOldTime ? diffn_cc : diffnp1_cc); + + // For non-const diffusivity, uncomment above and add interp from + // cell-center/centroid to faces. + // But here we simply do constant diffusivity. + + for (int dir = 0; dir < AMREX_SPACEDIM; dir++) + { + for (int n = 0; n < ncomp; n++) + { + // Each scalar has it's own diffusivity in the visc_coef array, so must do 1 at a time + diffusivity[dir]->setVal(visc_coef[state_comp+n], dst_comp+n, 1, diffusivity[dir]->nGrow()); + } + } +} + + +// +// ls related +// +Real +NavierStokes::advance_semistaggered_twophase_ls (Real time, + Real dt, + int iteration, + int ncycle) +{ + BL_PROFILE("NavierStokes::advance_semistaggered_twophase_ls()"); + + // + // Calculate the time N viscosity and diffusivity + // Note: The viscosity and diffusivity at time N+1 are + // initialized here to the time N values just to + // have something reasonable. + // + const Real prev_time = state[State_Type].prevTime(); + const int num_diff = NUM_STATE-AMREX_SPACEDIM-1; + + calcViscosity(prev_time,dt,iteration,ncycle); + calcDiffusivity(prev_time); + MultiFab::Copy(*viscnp1_cc, *viscn_cc, 0, 0, 1, viscn_cc->nGrow()); + MultiFab::Copy(*diffnp1_cc, *diffn_cc, 0, 0, num_diff, diffn_cc->nGrow()); + + // Add this AFTER advance_setup() + if (verbose) + { + Print() << "NavierStokes::advance_semistaggered_twophase_ls(): before velocity update:" + << std::endl; + printMaxValues(false); + } + // + // Compute traced states for normal comp of velocity at half time level. + // Returns best estimate for new timestep. + // + Real dt_test = predict_velocity(dt); + // + // Do MAC projection and update edge velocities. + // + if (do_mac_proj) + { + // To enforce div constraint on coarse-fine boundary, need 1 ghost cell + int ng_rhs = 1; + + MultiFab mac_rhs(grids,dmap,1,ng_rhs,MFInfo(),Factory()); + create_mac_rhs(mac_rhs,ng_rhs,time,dt); + MultiFab& S_old = get_old_data(State_Type); + mac_project(time,dt,S_old,&mac_rhs,umac_n_grow,true); + + } else { + // Use interpolation from coarse to fill grow cells. + create_umac_grown(umac_n_grow, nullptr); + } + // + // Advect velocities. + // + if (do_mom_diff == 0) + velocity_advection(dt); + // + // Advect scalars. + // + const int first_scalar = Density; + const int last_scalar = first_scalar + NUM_SCALARS - 1; + scalar_advection(dt,first_scalar,last_scalar); + // + // ls related + // note: in the above scalar_advection function, we still advect rho. + // + if (do_phi) { + amrex::Print() << "After scalar_advection " << std::endl; + // const Real prev_time = state[State_Type].prevTime(); + // MultiFab& S_old = get_old_data(State_Type); + // int nScomp = S_old.nComp(); + // fill_allgts(S_old,State_Type,phicomp,1,prev_time); + // MultiFab::Copy(phi_ptime, S_old, phicomp, 0, 1, S_old.nGrow()); + + amrex::Print()<< "scalar_update phi " << std::endl; + amrex::Print()<< "phicomp " << phicomp << std::endl; + scalar_update(dt,phicomp,phicomp); + + // amrex::Print()<< std::endl; + // amrex::Print()<< "6 " << std::endl; + + const Real cur_time = state[State_Type].curTime(); + MultiFab& S_new = get_new_data(State_Type); + fill_allgts(S_new,State_Type,phicomp,1,cur_time); + MultiFab::Copy(phi_ctime, S_new, phicomp, 0, 1, S_new.nGrow()); + + // amrex::Print()<< "7 " << std::endl; + + // reinitialization + if (do_reinit == 1 && (parent->levelSteps(0)% lev0step_of_reinit == 0) ){ + amrex::Print() << "parent->levelSteps(0) " << parent->levelSteps(0) << std::endl; + reinit(); + } + + if (do_mom_diff == 0) { + // update the rho_ctime and density in S_new + phi_to_heavi(geom, epsilon, phi_ctime, heaviside); + heavi_to_rhoormu(heaviside, rho_w, rho_a, rho_ctime); + MultiFab::Copy(S_new, rho_ctime, 0, Density, 1, rho_ctime.nGrow()); + // update phi_half + MultiFab& phi_half_temp = get_phi_half_time(); + // update rho_half + phi_to_heavi(geom, epsilon, phi_half_temp, heaviside); + heavi_to_rhoormu(heaviside, rho_w, rho_a, rho_half); + + // update mu_half + MultiFab outmf_mu_half(grids, dmap, 1, 1, MFInfo(), Factory()); + heavi_to_rhoormu(heaviside, mu_w, mu_a, outmf_mu_half); + MultiFab::Copy(*viscn_cc, outmf_mu_half, 0, 0, 1, 1); + MultiFab::Copy(*viscnp1_cc, outmf_mu_half, 0, 0, 1, 1); + } + else { + // + // Update Rho. + // + scalar_update(dt,first_scalar,first_scalar); + make_rho_curr_time(); + + // update phi_half + MultiFab& phi_half_temp = get_phi_half_time(); + // update rho_half + phi_to_heavi(geom, epsilon, phi_half_temp, heaviside); + + // update mu_half + MultiFab outmf_mu_half(grids, dmap, 1, 1, MFInfo(), Factory()); + heavi_to_rhoormu(heaviside, mu_w, mu_a, outmf_mu_half); + MultiFab::Copy(*viscn_cc, outmf_mu_half, 0, 0, 1, 1); + MultiFab::Copy(*viscnp1_cc, outmf_mu_half, 0, 0, 1, 1); + } + } + else { + // + // Update Rho. + // + scalar_update(dt,first_scalar,first_scalar); + make_rho_curr_time(); + } + + if (prescribed_vel) + { + BL_ASSERT(do_phi==1); + dt_test = dt; + + // + // Create struct to hold initial conditions parameters + // + InitialConditions IC; + // Integer indices of the lower left and upper right corners of the + // valid region of the entire domain. + Box const& domain = geom.Domain(); + auto const& dx = geom.CellSizeArray(); + // Physical coordinates of the lower left corner of the domain + auto const& problo = geom.ProbLoArray(); + // Physical coordinates of the upper right corner of the domain + auto const& probhi = geom.ProbHiArray(); + + // Step 1: do the reinitialization + // which has been done before + + // Step 2: set vel of internal cells in S_new and fill the gts + MultiFab& S_new = get_new_data(State_Type); + + int ncomp = S_new.nComp(); +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(S_new,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.tilebox(); + set_rsv_vel(vbx, S_new.array(mfi, Xvel), domain, dx, problo, probhi, IC, time); + } + + // Step 3: copy vel in S_new back to S_old + MultiFab& S_old = get_old_data(State_Type); + MultiFab::Copy(S_old, S_new, 0, 0, ncomp, S_new.nGrow()); + + } + else { + // + // Advect momenta after rho^(n+1) has been created. + // + if (do_mom_diff == 1) + velocity_advection(dt); + // + // ls related + // + if (do_phi) { + // + // Add the advective and other terms to get scalars at t^{n+1} except + // the level set function. + scalar_update(dt,first_scalar+1,phicomp-1); + } + else { + // + // Add the advective and other terms to get scalars at t^{n+1}. + // + scalar_update(dt,first_scalar+1,last_scalar); + } + // + // S appears in rhs of the velocity update, so we better do it now. + // + if (have_divu) + { + calc_divu(time+dt,dt,get_new_data(Divu_Type)); + if (have_dsdt) + { + calc_dsdt(time,dt,get_new_data(Dsdt_Type)); + if (initial_step) + MultiFab::Copy(get_old_data(Dsdt_Type), + get_new_data(Dsdt_Type),0,0,1,0); + } + } + // + // Add the advective and other terms to get velocity at t^{n+1}. + // + velocity_update(dt); + + // + // Increment rho average. + // + if (!initial_step) + { + if (level > 0) + incrRhoAvg((iteration==ncycle ? 0.5 : 1.0) / Real(ncycle)); + + if (verbose) + { + Print() << "NavierStokes::advance_semistaggered_twophase_ls(): before nodal projection " << std::endl; + printMaxVel(); + // New P, Gp get updated in the projector (below). Check old here. + printMaxGp(false); + } + + // + // Do a level project to update the pressure and velocity fields. + // + if (projector) { + const int finest_level = parent->finestLevel(); + int solve_coarse_level = iteration % 2; + if (verbose) + { + // Print() << "solve_coarse_level " << solve_coarse_level << std::endl; + // Print() << "skip_level_projector " << skip_level_projector << std::endl; + // Print() << "level " << level << std::endl; + // Print() << "finest_level " << finest_level << std::endl; + } + if (skip_level_projector==0 || level==finest_level || solve_coarse_level) { + level_projector(dt,time,iteration); + } + else { + MultiFab& P_old = get_old_data(Press_Type); + MultiFab& P_new = get_new_data(Press_Type); + // Set P_new to be P_old + MultiFab::Copy(P_new,P_old,0,0,1,P_old.nGrow()); + } + } + if (level > 0 && iteration == 1) + p_avg.setVal(0); + } + +#ifdef AMREX_PARTICLES + if (theNSPC() != 0 and NavierStokes::initial_step != true) + { + theNSPC()->AdvectWithUmac(u_mac, level, dt); + } +#endif + } // end prescribed_vel + + return dt_test; // Return estimate of best new timestep. +} + +#ifdef AMREX_PARTICLES +Real +NavierStokes::advance_semistaggered_fsi_diffusedib (Real time, + Real dt, + int iteration, + int ncycle) +{ + BL_PROFILE("NavierStokes::advance_semistaggered_fsi_diffusedib()"); + + // + // Calculate the time N viscosity and diffusivity + // Note: The viscosity and diffusivity at time N+1 are + // initialized here to the time N values just to + // have something reasonable. + // + const Real prev_time = state[State_Type].prevTime(); + const int num_diff = NUM_STATE-AMREX_SPACEDIM-1; + + calcViscosity(prev_time,dt,iteration,ncycle); + calcDiffusivity(prev_time); + MultiFab::Copy(*viscnp1_cc, *viscn_cc, 0, 0, 1, viscn_cc->nGrow()); + MultiFab::Copy(*diffnp1_cc, *diffn_cc, 0, 0, num_diff, diffn_cc->nGrow()); + + // Add this AFTER advance_setup() + if (verbose) + { + Print() << "NavierStokes::advance_semistaggered_fsi_diffusedib(): before velocity update:" + << std::endl; + printMaxValues(false); + } + // + // Compute traced states for normal comp of velocity at half time level. + // Returns best estimate for new timestep. + // + Real dt_test = predict_velocity(dt); + // + // Do MAC projection and update edge velocities. + // + if (do_mac_proj) + { + // To enforce div constraint on coarse-fine boundary, need 1 ghost cell + int ng_rhs = 1; + + MultiFab mac_rhs(grids,dmap,1,ng_rhs,MFInfo(),Factory()); + create_mac_rhs(mac_rhs,ng_rhs,time,dt); + MultiFab& S_old = get_old_data(State_Type); + mac_project(time,dt,S_old,&mac_rhs,umac_n_grow,true); + + } else { + // Use interpolation from coarse to fill grow cells. + create_umac_grown(umac_n_grow, nullptr); + } + // + // Advect velocities. + // + if (do_mom_diff == 0) + velocity_advection(dt); + + // Copy fluid density from old to new and set old and new tracer to 0.0 + if (!advect_and_update_scalar) + { + MultiFab& S_new = get_new_data(State_Type); + MultiFab& S_old = get_old_data(State_Type); + S_old.setVal(fluid_rho, Density, 1, S_old.nGrow()); + S_new.setVal(fluid_rho, Density, 1, S_new.nGrow()); + S_old.setVal(0.0, Tracer, 1, S_old.nGrow()); + S_new.setVal(0.0, Tracer, 1, S_new.nGrow()); + } + // + // Advect scalars. + // + const int first_scalar = Density; + const int last_scalar = first_scalar + NUM_SCALARS - 1; + scalar_advection(dt,first_scalar,last_scalar); + // + // ls related + // note: in the above scalar_advection function, we still advect rho. + // + if (do_phi) { + amrex::Print() << "After scalar_advection " << std::endl; + // const Real prev_time = state[State_Type].prevTime(); + // MultiFab& S_old = get_old_data(State_Type); + // int nScomp = S_old.nComp(); + // fill_allgts(S_old,State_Type,phicomp,1,prev_time); + // MultiFab::Copy(phi_ptime, S_old, phicomp, 0, 1, S_old.nGrow()); + + amrex::Print()<< "scalar_update phi " << std::endl; + amrex::Print()<< "phicomp " << phicomp << std::endl; + scalar_update(dt,phicomp,phicomp); + + // amrex::Print()<< std::endl; + // amrex::Print()<< "6 " << std::endl; + + const Real cur_time = state[State_Type].curTime(); + MultiFab& S_new = get_new_data(State_Type); + fill_allgts(S_new,State_Type,phicomp,1,cur_time); + MultiFab::Copy(phi_ctime, S_new, phicomp, 0, 1, S_new.nGrow()); + + // amrex::Print()<< "7 " << std::endl; + + // reinitialization + if (do_reinit == 1 && (parent->levelSteps(0)% lev0step_of_reinit == 0) ){ + amrex::Print() << "parent->levelSteps(0) " << parent->levelSteps(0) << std::endl; + reinit(); + } + + if (do_mom_diff == 0) { + // update the rho_ctime and density in S_new + phi_to_heavi(geom, epsilon, phi_ctime, heaviside); + heavi_to_rhoormu(heaviside, rho_w, rho_a, rho_ctime); + MultiFab::Copy(S_new, rho_ctime, 0, Density, 1, rho_ctime.nGrow()); + // update phi_half + MultiFab& phi_half_temp = get_phi_half_time(); + // update rho_half + phi_to_heavi(geom, epsilon, phi_half_temp, heaviside); + heavi_to_rhoormu(heaviside, rho_w, rho_a, rho_half); + + // update mu_half + MultiFab outmf_mu_half(grids, dmap, 1, 1, MFInfo(), Factory()); + heavi_to_rhoormu(heaviside, mu_w, mu_a, outmf_mu_half); + MultiFab::Copy(*viscn_cc, outmf_mu_half, 0, 0, 1, 1); + MultiFab::Copy(*viscnp1_cc, outmf_mu_half, 0, 0, 1, 1); + } + else { + // + // Update Rho. + // + scalar_update(dt,first_scalar,first_scalar); + make_rho_curr_time(); + + // update phi_half + MultiFab& phi_half_temp = get_phi_half_time(); + // update rho_half + phi_to_heavi(geom, epsilon, phi_half_temp, heaviside); + + // update mu_half + MultiFab outmf_mu_half(grids, dmap, 1, 1, MFInfo(), Factory()); + heavi_to_rhoormu(heaviside, mu_w, mu_a, outmf_mu_half); + MultiFab::Copy(*viscn_cc, outmf_mu_half, 0, 0, 1, 1); + MultiFab::Copy(*viscnp1_cc, outmf_mu_half, 0, 0, 1, 1); + } + } + else { + // + // Update Rho. + // + scalar_update(dt,first_scalar,first_scalar); + make_rho_curr_time(); + } + + if (prescribed_vel) + { + dt_test = dt; + + amrex::Print() << "Begin the PVF test " << std::endl; + + // Step 1: initialize the nodal level set function + // Create struct to hold initial conditions parameters + // + InitialConditions IC; + ParmParse pp("prob"); + pp.query("blob_radius",IC.blob_radius); + Vector blob_center(AMREX_SPACEDIM, 0.); + pp.queryarr("blob_center",blob_center,0,AMREX_SPACEDIM); + AMREX_D_TERM(IC.blob_x = blob_center[0];, + IC.blob_y = blob_center[1];, + IC.blob_z = blob_center[2];); + // amrex::Print() << "check " << IC.blob_radius << " " + // << IC.blob_x << " " + // << IC.blob_y << " " + // << IC.blob_z << std::endl; + + // Integer indices of the lower left and upper right corners of the + // valid region of the entire domain. + Box const& domain = geom.Domain(); + auto const& dx = geom.CellSizeArray(); + // Physical coordinates of the lower left corner of the domain + auto const& problo = geom.ProbLoArray(); + // Physical coordinates of the upper right corner of the domain + auto const& probhi = geom.ProbHiArray(); + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi_nodal,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + set_initial_phi_nodal(bx, phi_nodal.array(mfi), domain, dx, problo, probhi, IC, time); + } + + // Step 2: calculate pvf from the nodal level set function (only for internal cells) + pvf.setVal(0.0); + nodal_phi_to_pvf(pvf, phi_nodal); + + // Step 3 (optional): copy for visualization + MultiFab& S_new = get_new_data(State_Type); + MultiFab::Copy(S_new, pvf, 0, Tracer, 1, pvf.nGrow()); + + // Step 4: calculate total volume + Real vol = dx[0]; + for (int d=1; dfinestLevel()) + { + MultiFab& S_new = get_new_data(State_Type); + // S_new.setVal(1.0, 0, 1, S_new.nGrow()); // u = 1 + // S_new.setVal(2.0, 1, 1, S_new.nGrow()); // v = 2 + // S_new.setVal(3.0, 2, 1, S_new.nGrow()); // w = 3 + MultiFab EulerForce(S_new.boxArray(), S_new.DistributionMap(), 3, S_new.nGrow()); + Particles::get_particles()->InteractWithEuler(S_new, EulerForce, dt); // parent->levelSteps(0), time + } + //amrex::Abort("Stop here!"); +#endif + // + // Increment rho average. + // + if (!initial_step) + { + if (level > 0) + incrRhoAvg((iteration==ncycle ? 0.5 : 1.0) / Real(ncycle)); + + if (verbose) + { + Print() << "NavierStokes::advance_semistaggered_fsi_diffusedib(): before nodal projection " << std::endl; + printMaxVel(); + // New P, Gp get updated in the projector (below). Check old here. + printMaxGp(false); + } + + // + // Do a level project to update the pressure and velocity fields. + // + if (projector) { + const int finest_level = parent->finestLevel(); + int solve_coarse_level = iteration % 2; + if (verbose) + { + Print() << "solve_coarse_level " << solve_coarse_level << std::endl; + // Print() << "skip_level_projector " << skip_level_projector << std::endl; + // Print() << "level " << level << std::endl; + // Print() << "finest_level " << finest_level << std::endl; + } + if (skip_level_projector==0 || level==finest_level || solve_coarse_level) { + level_projector(dt,time,iteration); + } + else { + MultiFab& P_old = get_old_data(Press_Type); + MultiFab& P_new = get_new_data(Press_Type); + // Set P_new to be P_old + MultiFab::Copy(P_new,P_old,0,0,1,P_old.nGrow()); + } + } + if (level > 0 && iteration == 1) + p_avg.setVal(0); + } +#ifdef AMREX_PARTICLES + if (level == Particles::ParticleFinestLevel())//parent->finestLevel()) + { + MultiFab& S_new = get_new_data(State_Type); + MultiFab& S_old = get_old_data(State_Type); + Particles::get_particles()->UpdateParticles(parent->levelSteps(0), time, S_old, S_new, phi_nodal, pvf, dt); + } +#endif + +#ifdef AMREX_PARTICLES + if (theNSPC() != 0 and NavierStokes::initial_step != true) + { + theNSPC()->AdvectWithUmac(u_mac, level, dt); + } +#endif + } // end prescribed_vel + + return dt_test; // Return estimate of best new timestep. +} +#endif + +// +// phase field method +// +Real +NavierStokes::advance_semistaggered_twophase_phasefield (Real time, + Real dt, + int iteration, + int ncycle) +{ + BL_PROFILE("NavierStokes::advance_semistaggered_twophase_phasefield()"); + + // + // Calculate the time N viscosity and diffusivity + // Note: The viscosity and diffusivity at time N+1 are + // initialized here to the time N values just to + // have something reasonable. + // + const Real prev_time = state[State_Type].prevTime(); + const int num_diff = NUM_STATE-AMREX_SPACEDIM-1; + + calcViscosity(prev_time,dt,iteration,ncycle); + calcDiffusivity(prev_time); + MultiFab::Copy(*viscnp1_cc, *viscn_cc, 0, 0, 1, viscn_cc->nGrow()); + MultiFab::Copy(*diffnp1_cc, *diffn_cc, 0, 0, num_diff, diffn_cc->nGrow()); + + // Add this AFTER advance_setup() + if (verbose) + { + Print() << "NavierStokes::advance_semistaggered_twophase_phasefield(): before velocity update:" + << std::endl; + printMaxValues(false); + } + // + // Compute traced states for normal comp of velocity at half time level. + // Returns best estimate for new timestep. + // + Real dt_test = predict_velocity(dt); + // + // Do MAC projection and update edge velocities. + // + if (do_mac_proj) + { + // To enforce div constraint on coarse-fine boundary, need 1 ghost cell + int ng_rhs = 1; + + MultiFab mac_rhs(grids,dmap,1,ng_rhs,MFInfo(),Factory()); + create_mac_rhs(mac_rhs,ng_rhs,time,dt); + MultiFab& S_old = get_old_data(State_Type); + mac_project(time,dt,S_old,&mac_rhs,umac_n_grow,true); + + } else { + // Use interpolation from coarse to fill grow cells. + create_umac_grown(umac_n_grow, nullptr); + } + // + // Advect velocities. + // + if (do_mom_diff == 0) + velocity_advection(dt); + // + // Advect scalars. + // + const int first_scalar = Density; + const int last_scalar = first_scalar + NUM_SCALARS - 1; + scalar_advection(dt,first_scalar,last_scalar); + // + // pm related + // note: in the above scalar_advection function, we still advect rho. + // + if (do_phi) { + + // SOLVE AND UPDATE THE PHASE FIELD EQUATION HERE + // BY REPLACING THE FOLLOWING LEVEL SET METHOD! - by ZDSJTU + + amrex::Print() << "After scalar_advection " << std::endl; + // const Real prev_time = state[State_Type].prevTime(); + // MultiFab& S_old = get_old_data(State_Type); + // int nScomp = S_old.nComp(); + // fill_allgts(S_old,State_Type,phicomp,1,prev_time); + // MultiFab::Copy(phi_ptime, S_old, phicomp, 0, 1, S_old.nGrow()); + + amrex::Print()<< "scalar_update phi " << std::endl; + amrex::Print()<< "phicomp " << phicomp << std::endl; + scalar_update(dt,phicomp,phicomp); + + // amrex::Print()<< std::endl; + // amrex::Print()<< "6 " << std::endl; + + const Real cur_time = state[State_Type].curTime(); + MultiFab& S_new = get_new_data(State_Type); + fill_allgts(S_new,State_Type,phicomp,1,cur_time); + MultiFab::Copy(phi_ctime, S_new, phicomp, 0, 1, S_new.nGrow()); + + // amrex::Print()<< "7 " << std::endl; + + // reinitialization + if (do_reinit == 1 && (parent->levelSteps(0)% lev0step_of_reinit == 0) ){ + amrex::Print() << "parent->levelSteps(0) " << parent->levelSteps(0) << std::endl; + reinit(); + } + + if (do_mom_diff == 0) { + // update the rho_ctime and density in S_new + phi_to_heavi(geom, epsilon, phi_ctime, heaviside); + heavi_to_rhoormu(heaviside, rho_w, rho_a, rho_ctime); + MultiFab::Copy(S_new, rho_ctime, 0, Density, 1, rho_ctime.nGrow()); + // update phi_half + MultiFab& phi_half_temp = get_phi_half_time(); + // update rho_half + phi_to_heavi(geom, epsilon, phi_half_temp, heaviside); + heavi_to_rhoormu(heaviside, rho_w, rho_a, rho_half); + + // update mu_half + MultiFab outmf_mu_half(grids, dmap, 1, 1, MFInfo(), Factory()); + heavi_to_rhoormu(heaviside, mu_w, mu_a, outmf_mu_half); + MultiFab::Copy(*viscn_cc, outmf_mu_half, 0, 0, 1, 1); + MultiFab::Copy(*viscnp1_cc, outmf_mu_half, 0, 0, 1, 1); + } + else { + amrex::Abort("Only do_mom_diff == 0 is considered now."); + } + } + else { + // + // Update Rho. + // + amrex::Abort("Rho is not updated by themselves."); + } + + // + // Advect momenta after rho^(n+1) has been created. + // + if (do_mom_diff == 1) + velocity_advection(dt); + // + // pm related + // + if (do_phi) { + // + // Add the advective and other terms to get scalars at t^{n+1} except + // the level set function. + scalar_update(dt,first_scalar+1,phicomp-1); + } + // + // S appears in rhs of the velocity update, so we better do it now. + // + if (have_divu) + { + calc_divu(time+dt,dt,get_new_data(Divu_Type)); + if (have_dsdt) + { + calc_dsdt(time,dt,get_new_data(Dsdt_Type)); + if (initial_step) + MultiFab::Copy(get_old_data(Dsdt_Type), + get_new_data(Dsdt_Type),0,0,1,0); + } + } + // + // Add the advective and other terms to get velocity at t^{n+1}. + // + velocity_update(dt); + + // + // Increment rho average. + // + if (!initial_step) + { + if (level > 0) + incrRhoAvg((iteration==ncycle ? 0.5 : 1.0) / Real(ncycle)); + + if (verbose) + { + Print() << "NavierStokes::advance_semistaggered_twophase_ls(): before nodal projection " << std::endl; + printMaxVel(); + // New P, Gp get updated in the projector (below). Check old here. + printMaxGp(false); + } + + // + // Do a level project to update the pressure and velocity fields. + // + if (projector) { + const int finest_level = parent->finestLevel(); + int solve_coarse_level = iteration % 2; + if (verbose) + { + // Print() << "solve_coarse_level " << solve_coarse_level << std::endl; + // Print() << "skip_level_projector " << skip_level_projector << std::endl; + // Print() << "level " << level << std::endl; + // Print() << "finest_level " << finest_level << std::endl; + } + if (skip_level_projector==0 || level==finest_level || solve_coarse_level) { + level_projector(dt,time,iteration); + } + else { + MultiFab& P_old = get_old_data(Press_Type); + MultiFab& P_new = get_new_data(Press_Type); + // Set P_new to be P_old + MultiFab::Copy(P_new,P_old,0,0,1,P_old.nGrow()); + } + } + if (level > 0 && iteration == 1) + p_avg.setVal(0); + } + +#ifdef AMREX_PARTICLES + if (theNSPC() != 0 and NavierStokes::initial_step != true) + { + theNSPC()->AdvectWithUmac(u_mac, level, dt); + } +#endif + + return dt_test; // Return estimate of best new timestep. } \ No newline at end of file diff --git a/Source/NavierStokesBase.H b/Source/NavierStokesBase.H index fba9bef9..4edbdeb2 100644 --- a/Source/NavierStokesBase.H +++ b/Source/NavierStokesBase.H @@ -1,941 +1,948 @@ - -#ifndef IAMR_NavierStokesBase_H_ -#define IAMR_NavierStokesBase_H_ - -#ifdef _OPENMP -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef AMREX_PARTICLES -#include -#endif - -#ifdef AMREX_USE_EB -#include -#endif - -// -// Parameters used when we call BuildMask -// -// interior : interior cells (i.e., valid cells) -// covered : ghost cells covered by valid cells of this FabArray -// (including periodically shifted valid cells) -// notcovered: ghost cells not covered by valid cells -// (including ghost cells outside periodic boundaries where the -// periodically shifted cells don't exist at this level) -// physbnd : boundary cells outside the domain (excluding periodic boundaries) -static constexpr int level_mask_interior = 0; // valid cells -static constexpr int level_mask_covered = 1; // ghost cells covered by valid cells of this level -static constexpr int level_mask_notcovered = 2; // ghost cells not covered -static constexpr int level_mask_physbnd = 3; // outside domain - -// -// "Divu_Type" means S, where divergence U = S -// "Dsdt_Type" means pd S/pd t, where S is as above -// -// Determine what you want in the state -- Divu, Dsdt -- in -// NavierStokes::variableSetUp in NS_setup.cpp. -// -enum StateType {State_Type=0, Press_Type, Gradp_Type}; - -#if (AMREX_SPACEDIM == 2) -enum StateNames { Xvel=0, Yvel, Density}; -#else -enum StateNames { Xvel=0, Yvel, Zvel, Density}; -#endif - -enum PressureNames { Pressure=0 }; -#if (AMREX_SPACEDIM == 2) -enum GradpNames { Gradpx=0, Gradpy}; -#else -enum GradpNames { Gradpx=0, Gradpy, Gradpz}; -#endif -enum DivuNames { Divu=0}; -enum DsDtNames { Dsdt=0}; - -class NavierStokesBase - : - public amrex::AmrLevel -{ -public: - - friend class Projection; - friend class MacProj; - friend class Diffusion; - - ~NavierStokesBase () override; - - NavierStokesBase (NavierStokesBase const&) = delete; - NavierStokesBase (NavierStokesBase &&) = delete; - NavierStokesBase& operator= (NavierStokesBase const&) = delete; - NavierStokesBase& operator= (NavierStokesBase &&) = delete; - - void define_workspace (); - - //////////////////////////////////////////////////////////////////////////// - // AmrLevel virtual functions // - //////////////////////////////////////////////////////////////////////////// - - void checkPoint (const std::string& dir, - std::ostream& os, - amrex::VisMF::How how = amrex::VisMF::OneFilePerCPU, - bool dump_old = true) override; - - void computeInitialDt (int finest_level, - int sub_cycle, - amrex::Vector& n_cycle, - const amrex::Vector& ref_ratio, - amrex::Vector& dt_level, - amrex::Real stop_time) override; - - void computeNewDt (int finest_level, - int sub_cycle, - amrex::Vector& n_cycle, - const amrex::Vector& ref_ratio, - amrex::Vector& dt_min, - amrex::Vector& dt_level, - amrex::Real stop_time, - int post_regrid_flag) override; - // - // Error estimation for regridding. - // - void errorEst (amrex::TagBoxArray& tb, - int clearval, - int tagval, - amrex::Real time, - int n_error_buf = 0, - int ngrow = 0) override; - // - // This function fills a new level n with the best - // level n and coarser data available (usually during regrid). - // - void init (amrex::AmrLevel& old) override; - // - // Init data on this level after regridding if old level - // did not exist previously. - // - void init () override; - // - // Called in grid_places after other tagging routines to modify - // the list of tagged points - // - void manual_tags_placement (amrex::TagBoxArray& tags, - const amrex::Vector& bf_lev) override; - // - // Estimate the end of the simulation for amrLevel. - // - int okToContinue () override; - // - // Check whether simulation has reached steady state, i.e. whether the - // change from last iteration is below a prescribed threshold steady_tol. - // - virtual int steadyState (); - // - // Build any additional data structures after regrid. - // - void post_regrid (int lbase, int new_finest) override; - // - // Build any additional data structures after restart. - // - void post_restart () override; - // - // Sync state and pressure at the end of a composite timestep. - // - void post_timestep (int iteration) override; - // - void restart (amrex::Amr& papa, - std::istream& is, - bool bReadSpecial = false) override; - // - // Old checkpoint file may have different number of state types than the - // new source code. - // - void set_state_in_checkpoint (amrex::Vector& state_in_checkpoint) override; - // - // Set time levels of state data. - // - void setTimeLevel (amrex::Real time, - amrex::Real dt_old, - amrex::Real dt_new) override; - // - // A string written as the first item in writePlotFile() at level zero. - // It is so we can distinguish between different types of plot files. - // - // For NavierStokes it has the form: NavierStokes-Vnnn - // - std::string thePlotFileType () const override; - - //////////////////////////////////////////////////////////////////////////// - // NavierStokesBase public functions // - //////////////////////////////////////////////////////////////////////////// - - const amrex::MultiFab* Area () const { return area; } - const amrex::MultiFab& Area (int dir) const { return area[dir]; } - const amrex::MultiFab& Volume () const { return volume; } - // - // Get rho at time. - // Must be one of AmrOldTime, AmrHalfTime or AmrNewTime. - // Aborts if not one of the three above times. - // - const amrex::MultiFab& get_rho (amrex::Real time); - // - // Get divU from the state data. - // - amrex::MultiFab* getDivCond (int ngrow, amrex::Real time); - // - // Get pressure gradient data, fill-patch ghost cells. - // - void computeGradP(amrex::Real time); - -#ifdef AMREX_USE_EB - const amrex::MultiFab* VolFrac () const { return volfrac; } -#endif - // - // Boundary condition access functions. - // - amrex::Vector fetchBCArray (int State_Type, const amrex::Box& bx, - int scomp, int ncomp); - - amrex::Vector fetchBCArray (int State_Type, int scomp, int ncomp); - - // - // ls related - // - void fill_allgts (amrex::MultiFab& mf, int type, int scomp, int ncomp, amrex::Real time); - void reinit (); - void reinitialization_sussman (amrex::Real dt, int loop_iter); - void reinitialization_consls (amrex::Real dt, int loop_iter, amrex::Real epsG, amrex::Real epsG2); - void phi_to_sgn0 (amrex::MultiFab& phi); - amrex::MultiFab& get_phi_half_time (); - void rk_first_reinit (amrex::MultiFab& phi_ctime, - amrex::MultiFab& phi2, - amrex::MultiFab& phi3, - amrex::MultiFab& sgn0, - amrex::MultiFab& G0, - amrex::Real dt, - amrex::MultiFab& phi_ori); - void rk_second_reinit (amrex::MultiFab& phi_ctime, - amrex::MultiFab& phi2, - amrex::MultiFab& phi3, - amrex::MultiFab& sgn0, - amrex::MultiFab& G0, - amrex::Real dt, - amrex::MultiFab& phi_ori); - void mass_fix (amrex::MultiFab& phi_ctime, - amrex::MultiFab& phi_original, - amrex::MultiFab& phi2, - amrex::MultiFab& phi3, - amrex::MultiFab& ld, - amrex::MultiFab& lambdad, - amrex::MultiFab& deltafunc_alias, - amrex::Real delta_t, - int loop_iter); - - amrex::Vector const& get_bcrec_velocity () const noexcept { return m_bcrec_velocity; } - amrex::Vector const& get_bcrec_scalars () const noexcept { return m_bcrec_scalars; } - - amrex::BCRec const* get_bcrec_velocity_d_ptr () const noexcept { - return m_bcrec_velocity_d.dataPtr(); } - amrex::BCRec const* get_bcrec_scalars_d_ptr () const noexcept { - return m_bcrec_scalars_d.dataPtr(); } - - // - // Select appropriate AMReX average_down() based on EB/non-EB and dimensionality - // for use in derived classes and Projection sync fns and initial vel proj - // - void average_down(const amrex::MultiFab& S_fine, amrex::MultiFab& S_crse, - int scomp, int ncomp); - - void calc_mut_LES(amrex::MultiFab* mu_LES[AMREX_SPACEDIM], amrex::Real time); - - void time_average(amrex::Real& time_avg, amrex::Real& time_avg_fluct, amrex::Real& dt_avg, const amrex::Real& dt_level); - - //////////////////////////////////////////////////////////////////////////// - // NavierStokesBase public static functions // - //////////////////////////////////////////////////////////////////////////// - - // - // Returns the value of "gravity" for use in the projection outflow bcs. - // - static amrex::Real getGravity () { return gravity; } - - // - // Returns the value of "gravity" for use in the projection outflow bcs. - // -#ifdef AMREX_USE_EB - static std::string const& getRedistType () { return redistribution_type; } -#endif - - static int DoTrac2() { return NavierStokesBase::do_trac2; } - - static bool GodunovUseForcesInTrans () {return godunov_use_forces_in_trans;} - - ////////////////////////////////////////////////////////////////// - - NavierStokesBase (); - - NavierStokesBase (amrex::Amr& papa, - int lev, - const amrex::Geometry& level_geom, - const amrex::BoxArray& bl, - const amrex::DistributionMapping& dm, - amrex::Real time); - - ////////////////////////////////////////////////////////////////// - // NavierStokesBase functions // - ////////////////////////////////////////////////////////////////// - - void advance_cleanup (int iteration,int ncycle); - - static void diffuse_scalar_setup (int sigma, int& rho_flag); - // - // Get the forcing term. - // - virtual void getForce (amrex::FArrayBox& force, - const amrex::Box& bx, - int scomp, - int ncomp, - amrex::Real time, - const amrex::FArrayBox& State, - const amrex::FArrayBox& Aux, - int auxScomp, - const amrex::MFIter& mfi); - - auto& getAdvFluxReg () { - AMREX_ASSERT(advflux_reg); - return *advflux_reg; - } - auto& getAdvFluxReg (int lev) { - return getLevel(lev).getAdvFluxReg(); - } - - amrex::FluxRegister& getViscFluxReg () { - AMREX_ASSERT(viscflux_reg); - return *viscflux_reg; - } - amrex::FluxRegister& getViscFluxReg (int lev) { - return getLevel(lev).getViscFluxReg(); - } - // - // Get rho at time n+1/2 - // - amrex::MultiFab& get_rho_half_time (); - // - // Get dSdt from the state data. - // - [[nodiscard]] amrex::MultiFab* getDsdt (int ngrow, amrex::Real time); - // - void incrRhoAvg (amrex::Real alpha); - void incrRhoAvg (const amrex::MultiFab& rho_incr, - int sComp, - amrex::Real alpha); - - void initial_velocity_diffusion_update (amrex::Real dt); - // - // Compute level projection. - // - void level_projector (amrex::Real dt, - amrex::Real time, - int iteration); - // - // Compute the level sync correction. - // - void level_sync (int crse_iteration); - // - // Impose divergence constraint on MAC velocities. - // - void mac_project (amrex::Real time, - amrex::Real dt, - amrex::MultiFab& S_old, - amrex::MultiFab* divu, - int ngrow, - bool increment_vel_register); - // - // Make rho at time n. - // - void make_rho_prev_time (); - // - // Make rho at time n+1. - // - void make_rho_curr_time (); - // - // This function estimates the initial timesteping used by the model. - // - void post_init_estDT (amrex::Real& dt_init, - amrex::Vector& nc_save, - amrex::Vector& dt_save, - amrex::Real stop_time); - // - // Ensure state is consistent, i.e. velocity field is nondivergent, - // coarse level data are averages of fine level data, pressure is zero. - // - void post_init_state (); - // - // Interpolate cell-centered cync correction from coarse to fine. - // - enum SyncInterpType - { - PC_T, - CellCons_T, - CellConsLin_T, - CellConsProt_T - }; - // - void SyncInterp (amrex::MultiFab& CrseSync, - int c_lev, - amrex::MultiFab& FineSync, - int f_lev, - amrex::IntVect& ratio, - int src_comp, - int dest_comp, - int num_comp, - int increment, - amrex::Real dt_clev, - int** bc_orig_qty, - SyncInterpType which_interp = CellCons_T, - int state_comp = -1); - // - // Bilinear interpolate nodal pressures from coarse to fine. - // - void SyncProjInterp (amrex::MultiFab& phi, - int c_lev, - amrex::MultiFab& P_new, - amrex::MultiFab& P_old, - int f_lev, - amrex::IntVect& ratio); - - void sync_setup (amrex::MultiFab*& DeltaSsync); - static void sync_cleanup (amrex::MultiFab*& DeltaSsync); - // - // Grow by nGrow and fillpatch the MAC-projected velocities. - // - void create_umac_grown (int nGrow, - const amrex::MultiFab *a_divu); - // - // Predict face velocities (before projection), estimate current cfl - // from t^n cell-centered velocities (plus cfl and change_max) - // - amrex::Real predict_velocity (amrex::Real dt); - // - // Advect velocities. - // - void velocity_advection (amrex::Real dt); - // - // Update velocities (or momentum) with advection and diffusion terms. - // - void velocity_update (amrex::Real dt); - // - // Update velocities (or momentum) with advection terms. - // - void velocity_advection_update (amrex::Real dt); - // - // Average down State_Type and Press_Type. - // - void avgDown_StatePress (); - - void LES_setDomainBC (std::array& mlmg_lobc, - std::array& mlmg_hibc, - int src_comp); - - - ////////////////////////////////////////////////////////////////// - // NavierStokesBase virtual functions // - ////////////////////////////////////////////////////////////////// - - virtual void advance_setup (amrex::Real time, - amrex::Real dt, - int iteration, - int ncycle); - - virtual void avgDown () = 0; // Average down for all the state types. - - virtual void calc_divu (amrex::Real time, - amrex::Real dt, - amrex::MultiFab& fab) = 0; - // - // Calculate nonuniform viscosity and diffusivity - // - virtual void calcViscosity (amrex::Real time, - amrex::Real dt, - int iteration, - int ncycle) = 0; - virtual void calcDiffusivity (amrex::Real time) = 0; - // - // Create the RHS for the MAC projection. - // - virtual void create_mac_rhs (amrex::MultiFab& rhs, int nGrow, amrex::Real time, amrex::Real dt); - - // - // Timestep estimation functions follow. - // - virtual amrex::Real estTimeStep (); - - virtual void getViscosity (amrex::MultiFab* viscosity[AMREX_SPACEDIM], - amrex::Real time) = 0; - // - // Compute viscous terms. - // - virtual void getViscTerms (amrex::MultiFab& visc_terms, - int src_comp, - int num_comp, - amrex::Real time) = 0; - // - virtual void mac_sync () = 0; - // - virtual void reflux () = 0; - // - // Reset time levels for the initial iterations. - // - virtual void resetState (amrex::Real time, - amrex::Real dt_old, - amrex::Real dt_new); - - virtual void scalar_advection_update (amrex::Real dt, - int first_scalar, - int last_scalar); - // - virtual void sum_integrated_quantities () = 0; - - virtual void velocity_diffusion_update (amrex::Real dt) = 0; - - //////////////////////////////////////////////////////////////////////////// - // NavierStokesBase static functions // - //////////////////////////////////////////////////////////////////////////// - - // - // Cleanup data descriptors at end of run. - // - static void variableCleanUp (); - // - // Read input file - // - static void Initialize (); - static void Finalize (); - // - // Check for RZ geometry - // - static void read_geometry (); - - //////////////////////////////////////////////////////////////////////////// - // NavierStokesBase particle functions // - //////////////////////////////////////////////////////////////////////////// - -#ifdef AMREX_PARTICLES - static amrex::AmrTracerParticleContainer* theNSPC (); - static void read_particle_params (); - - void initParticleData (); - void post_restart_particle (); - - void post_timestep_particle (int iteration); - - virtual int timestamp_num_extras () { return 0; } - virtual void timestamp_add_extras (int lev, amrex::Real time, amrex::MultiFab& mf) { } - - std::unique_ptr ParticleDerive (const std::string& name, amrex::Real time, int ngrow); - void ParticleDerive (const std::string& name, amrex::Real time, amrex::MultiFab& mf, int dcomp); -#endif - - //////////////////////////////////////////////////////////////////////////// - // NavierStokesBase diagnostics functions // - //////////////////////////////////////////////////////////////////////////// - void printMaxVel (bool new_data = true); - - void printMaxGp (bool new_data = true); - - void printMaxValues (bool new_data = true); - - //////////////////////////////////////////////////////////////////////////// - - void buildMetrics (); // 1-D metric arrays for RZ - // - void calc_dsdt (amrex::Real time, - amrex::Real dt, - amrex::MultiFab& dsdt); - // - NavierStokesBase& getLevel (int lev) { - return dynamic_cast ( parent->getLevel(lev) ); - } - // - SyncRegister& getSyncReg () { - AMREX_ASSERT(sync_reg); - return *sync_reg; - } - // - static void getOutFlowFaces (amrex::Vector& outFaces); - // - // Get state data. - // - [[nodiscard]] amrex::MultiFab* getState (int ngrow, - int state_indx, - int strt_comp, - int num_comp, - amrex::Real time); - // - // Compile p_avg in advance. - // - void incrPAvg (); - void initOldFromNew (int type, int lev = -1); // Initialize old with new - // - // Compile rho_avg in advance. - // - void initRhoAvg (amrex::Real alpha); - // - static void init_additional_state_types (); - // - amrex::Real initialTimeStep (); - - // - // Correct a conservatively-advected scalar for under-over shoots. - // - void ConservativeScalMinMax ( amrex::MultiFab& Snew, int snew_comp, int new_density_comp, - amrex::MultiFab const& Sold, int sold_comp, int old_density_comp ); - - // - // Correct a convectively-advected scalar for under-over shoots. - // - void ConvectiveScalMinMax ( amrex::MultiFab& Snew, int snew_comp, - amrex::MultiFab const& Sold, int sold_comp ); - // - // Floor small values of states to be extrapolated - // - static void floor(amrex::MultiFab& mf); - -#ifdef AMREX_USE_EB - void init_eb (const amrex::Geometry& level_geom, const amrex::BoxArray& ba, const amrex::DistributionMapping& dm); - - void initialize_eb2_structs(); - void define_body_state(); - - void InitialRedistribution (); - - static bool ebInitialized(); - static bool eb_initialized; - static bool body_state_set; - static bool no_eb_in_domain; - static std::vector body_state; -#endif - - void ComputeAofs (int comp, int ncomp, - amrex::MultiFab const& state, - int S_comp, - amrex::MultiFab const& forcing_term, - amrex::MultiFab const& divu, - bool is_velocity, amrex::Real dt); - - void ComputeAofs (amrex::MultiFab& advc, int a_comp, - int state_indx, int ncomp, - amrex::MultiFab const& S, int S_comp, - amrex::MultiFab const* forcing, int f_comp, - amrex::MultiFab const* divu, - amrex::Array& cfluxes, int flux_comp, - amrex::Array& edgestate, int edge_comp, - bool known_edge_state, - bool is_velocity, amrex::Real dt, - bool is_sync, amrex::Array const& U_corr, - bool do_crse_add, bool do_fine_add); -// -// Data -// - - // volume and area are intentionally without EB knowledge - amrex::MultiFab volume; - amrex::MultiFab area[AMREX_SPACEDIM]; - - std::unique_ptr coarse_fine_mask; - -#ifdef AMREX_USE_EB - void set_body_state(amrex::MultiFab& S); - - const amrex::MultiFab* volfrac; - amrex::FabArray> ebmask; - - std::array areafrac; - std::array facecent; - -#endif - - - // - // MAC edge velocities. - // - amrex::MultiFab* u_mac = nullptr; - int umac_n_grow; - // - // Advective update terms. - // - amrex::MultiFab* aofs = nullptr; - // - // BC info for advection - // - amrex::Vector m_bcrec_velocity; - amrex::Vector m_bcrec_scalars; - // NOTE that DeviceVector reverts to amrex::Vector if !AMREX_USE_GPU - amrex::Gpu::DeviceVector m_bcrec_velocity_d; - amrex::Gpu::DeviceVector m_bcrec_scalars_d; - - std::unique_ptr diffusion; - // - // arrays for variable viscosity and diffusivity - // - amrex::MultiFab *diffn_cc, *diffnp1_cc; - amrex::MultiFab *viscn_cc, *viscnp1_cc; - // - // Sync update quantities. - // - // Average rho over a composite timestep. - // Used only in the multlilevel sync projection - // - amrex::MultiFab rho_avg; - // - // Average p over a composite timestep. - // Used only to average fine pressure data to coarse. - // - amrex::MultiFab p_avg; - - amrex::MultiFab Vsync; // Velocity sync update storage - amrex::MultiFab Ssync; // Scalar sync update storage - // - // Density at time n+1/2 (used in advance). - // - amrex::MultiFab rho_half; - amrex::MultiFab* rho_qtime = nullptr; - amrex::MultiFab* rho_tqtime = nullptr; - // - // Density at prev_time used in advance(). - // - amrex::MultiFab rho_ptime; - // - // Density at cur_time used in advance(). - // - amrex::MultiFab rho_ctime; - // - // Data structure used to compute RHS for sync project. - // - SyncRegister* sync_reg = nullptr; - // - // Data structures to store advective and viscous refluxing quantities - // on coarse-fine grid interfaces. - // -#ifdef AMREX_USE_EB - std::unique_ptr advflux_reg; -#else - std::unique_ptr advflux_reg; -#endif - amrex::FluxRegister* viscflux_reg = nullptr; - // - // Radii for r-z calculations. - // - amrex::Vector< amrex::Vector > radius; - // - // Static objects. - // - static amrex::BCRec phys_bc; - static Projection* projector; - static MacProj* mac_projector; - // - // Internal parameters for timestepping. - // - static amrex::Real init_shrink; // reduction factor of first estimated timestep - static int init_iter; // # of timestep iterations for initial pressure - static int init_vel_iter; // # of iterations for initial velocity projection - static amrex::Real cfl; // desired maximum cfl - static amrex::Real change_max; // maximum change in dt over a timestep - static amrex::Real fixed_dt; // set > 0 to specify dt - static amrex::Real init_dt; // set > 0 to specify initial dt at coarsest level - static bool stop_when_steady; // set to true if simulation should stop at steady-state - static amrex::Real steady_tol; // tolerance for assuming steady-state has been reached - static int initial_iter; // flag for initial pressure iterations - static int initial_step; // flag for initial iterations - static amrex::Real dt_cutoff; // minimum dt allowed - static int sum_interval; // number of timesteps for conservation stats - // - // Internal parameters for options. - // - static int radius_grow; - static int verbose; - static amrex::Real gravity; - static int NUM_SCALARS; // number of non-velocity components - static int NUM_STATE; // total number of state variables -#ifdef AMREX_USE_EB - static const int NUM_GROW=4; // number of ghost cells - static int refine_cutcells; -#else - // - // ls related - // change to two gts - // - static const int NUM_GROW=2; // number of ghost cells -#endif - // - // Controls over how the convective and diffusive terms are calculated - // for each state variable. - // - static amrex::Vector advectionType; - static amrex::Vector diffusionType; - // - // Viscosity parameters. - // - static amrex::Vector is_diffusive; // does variable diffuse? - static amrex::Vector visc_coef; // const coef viscosity terms - static amrex::Real visc_tol; - static amrex::Real visc_abs_tol; - static amrex::Real be_cn_theta; - // - // Internal switches. - // - static int Tracer; - static int Tracer2; - static int Temp; - static int do_trac2; - static int do_temp; - static int do_cons_trac; - static int do_cons_trac2; - static int do_sync_proj; - static int do_reflux; - static int do_mac_proj; - static int do_refine_outflow; // The following three items control - static int do_derefine_outflow; // how grids are treated at - static int Nbuf_outflow; // outflow boundaries. - static int do_denminmax; // The code for these was in NavierStokes.cpp, - static int do_scalminmax; // but the flags were not declared or read in. - static int getForceVerbose; // Does exactly what it says on the tin - // - // LES parameters - // - static int do_LES; // To activate LES modelling - static int getLESVerbose; // Does exactly what it says on the tin - static std::string LES_model; // To choose a LES model - static amrex::Real smago_Cs_cst; // A parameter for the Smagorinsky model, usually set to 0.18 - static amrex::Real sigma_Cs_cst; // A parameter for the Sigma model, usually set to 1.5 - // - // Parameters for averaging - // - static amrex::Vector time_avg; - static amrex::Vector time_avg_fluct; - static amrex::Vector dt_avg; - static int avg_interval; - static int compute_fluctuations; - // - // Members for non-zero divu. - // - static int additional_state_types_initialized; - static int Divu_Type; - static int Dsdt_Type; - static int Average_Type; - static int num_state_type; - static int have_divu; - static int have_dsdt; - static int do_init_vort_proj; - static int do_init_proj; - // - // Control velocity vs momentum update - // - static int do_mom_diff; - - // - // skip_level_projector - // - static int skip_level_projector; - - static int isolver; - - // - // ls related - // - static int do_phi; - static int phicomp; - static int epsilon; - amrex::MultiFab phi_half; - amrex::MultiFab phi_ptime; - amrex::MultiFab phi_ctime; - amrex::MultiFab heaviside; - - static amrex::Real mu_a; - static amrex::Real rho_a; - static amrex::Real mu_w; - static amrex::Real rho_w; - - static int do_reinit; - static int lev0step_of_reinit; - static int number_of_reinit; - static int reinit_levelset; - - // for reinit_sussman - amrex::MultiFab phi_original; - amrex::MultiFab sgn0; - - static int do_cons_phi; - static int prescribed_vel; - - // for cons_levelset - static int do_cons_levelset; - - // - // diffused ib - // - static int do_diffused_ib; - amrex::MultiFab phi_nodal; - amrex::MultiFab pvf; - static int advect_and_update_scalar; - static amrex::Real fluid_rho; - -// #ifdef AMREX_PARTICLES -// mParticle *mParticle_obj; -// #endif - int nghost_state () const; - static constexpr int nghost_force () { return 1; } - - // - // static integer constants - // - static const int GEOM_GROW = 1; -#ifdef AMREX_USE_EB - // This must be consistent with what nghost_force returns for - // godunov - static const int gradp_grow = 4; -#else - static const int gradp_grow = 1; -#endif - - // - // Controls advection scheme - // - static std::string advection_scheme; - static bool godunov_use_forces_in_trans; - -#ifdef AMREX_USE_EB - // Controls redistribution - static std::string redistribution_type; -#endif - - // - // For restart, is GradP in checkpoint file - // - static int gradp_in_checkpoint; - - static int average_in_checkpoint; - -#ifdef AMREX_PARTICLES - // - // Check in case different particle methods are being used - // - static bool do_nspc; - // - // Put particle info in plotfile (using ParticleContainer::Checkpoint)? - // - static bool particles_in_plotfile; -#endif -}; - -#endif +/* + * SPDX-FileCopyrightText: 1997 - 2023 Berkeley Lab; 2023 - 2025 Yadong Zeng & ZhuXu Li<1246206018@qq.com> + * + * SPDX-License-Identifier: LicenseRef-OpenSource + * Modified from IAMR, originally developed at Lawrence Berkeley National Lab. + * Original source: https://github.com/AMReX-Fluids/IAMR + */ + +#ifndef IAMR_NavierStokesBase_H_ +#define IAMR_NavierStokesBase_H_ + +#ifdef _OPENMP +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef AMREX_PARTICLES +#include +#endif + +#ifdef AMREX_USE_EB +#include +#endif + +// +// Parameters used when we call BuildMask +// +// interior : interior cells (i.e., valid cells) +// covered : ghost cells covered by valid cells of this FabArray +// (including periodically shifted valid cells) +// notcovered: ghost cells not covered by valid cells +// (including ghost cells outside periodic boundaries where the +// periodically shifted cells don't exist at this level) +// physbnd : boundary cells outside the domain (excluding periodic boundaries) +static constexpr int level_mask_interior = 0; // valid cells +static constexpr int level_mask_covered = 1; // ghost cells covered by valid cells of this level +static constexpr int level_mask_notcovered = 2; // ghost cells not covered +static constexpr int level_mask_physbnd = 3; // outside domain + +// +// "Divu_Type" means S, where divergence U = S +// "Dsdt_Type" means pd S/pd t, where S is as above +// +// Determine what you want in the state -- Divu, Dsdt -- in +// NavierStokes::variableSetUp in NS_setup.cpp. +// +enum StateType {State_Type=0, Press_Type, Gradp_Type}; + +#if (AMREX_SPACEDIM == 2) +enum StateNames { Xvel=0, Yvel, Density}; +#else +enum StateNames { Xvel=0, Yvel, Zvel, Density}; +#endif + +enum PressureNames { Pressure=0 }; +#if (AMREX_SPACEDIM == 2) +enum GradpNames { Gradpx=0, Gradpy}; +#else +enum GradpNames { Gradpx=0, Gradpy, Gradpz}; +#endif +enum DivuNames { Divu=0}; +enum DsDtNames { Dsdt=0}; + +class NavierStokesBase + : + public amrex::AmrLevel +{ +public: + + friend class Projection; + friend class MacProj; + friend class Diffusion; + + ~NavierStokesBase () override; + + NavierStokesBase (NavierStokesBase const&) = delete; + NavierStokesBase (NavierStokesBase &&) = delete; + NavierStokesBase& operator= (NavierStokesBase const&) = delete; + NavierStokesBase& operator= (NavierStokesBase &&) = delete; + + void define_workspace (); + + //////////////////////////////////////////////////////////////////////////// + // AmrLevel virtual functions // + //////////////////////////////////////////////////////////////////////////// + + void checkPoint (const std::string& dir, + std::ostream& os, + amrex::VisMF::How how = amrex::VisMF::OneFilePerCPU, + bool dump_old = true) override; + + void computeInitialDt (int finest_level, + int sub_cycle, + amrex::Vector& n_cycle, + const amrex::Vector& ref_ratio, + amrex::Vector& dt_level, + amrex::Real stop_time) override; + + void computeNewDt (int finest_level, + int sub_cycle, + amrex::Vector& n_cycle, + const amrex::Vector& ref_ratio, + amrex::Vector& dt_min, + amrex::Vector& dt_level, + amrex::Real stop_time, + int post_regrid_flag) override; + // + // Error estimation for regridding. + // + void errorEst (amrex::TagBoxArray& tb, + int clearval, + int tagval, + amrex::Real time, + int n_error_buf = 0, + int ngrow = 0) override; + // + // This function fills a new level n with the best + // level n and coarser data available (usually during regrid). + // + void init (amrex::AmrLevel& old) override; + // + // Init data on this level after regridding if old level + // did not exist previously. + // + void init () override; + // + // Called in grid_places after other tagging routines to modify + // the list of tagged points + // + void manual_tags_placement (amrex::TagBoxArray& tags, + const amrex::Vector& bf_lev) override; + // + // Estimate the end of the simulation for amrLevel. + // + int okToContinue () override; + // + // Check whether simulation has reached steady state, i.e. whether the + // change from last iteration is below a prescribed threshold steady_tol. + // + virtual int steadyState (); + // + // Build any additional data structures after regrid. + // + void post_regrid (int lbase, int new_finest) override; + // + // Build any additional data structures after restart. + // + void post_restart () override; + // + // Sync state and pressure at the end of a composite timestep. + // + void post_timestep (int iteration) override; + // + void restart (amrex::Amr& papa, + std::istream& is, + bool bReadSpecial = false) override; + // + // Old checkpoint file may have different number of state types than the + // new source code. + // + void set_state_in_checkpoint (amrex::Vector& state_in_checkpoint) override; + // + // Set time levels of state data. + // + void setTimeLevel (amrex::Real time, + amrex::Real dt_old, + amrex::Real dt_new) override; + // + // A string written as the first item in writePlotFile() at level zero. + // It is so we can distinguish between different types of plot files. + // + // For NavierStokes it has the form: NavierStokes-Vnnn + // + std::string thePlotFileType () const override; + + //////////////////////////////////////////////////////////////////////////// + // NavierStokesBase public functions // + //////////////////////////////////////////////////////////////////////////// + + const amrex::MultiFab* Area () const { return area; } + const amrex::MultiFab& Area (int dir) const { return area[dir]; } + const amrex::MultiFab& Volume () const { return volume; } + // + // Get rho at time. + // Must be one of AmrOldTime, AmrHalfTime or AmrNewTime. + // Aborts if not one of the three above times. + // + const amrex::MultiFab& get_rho (amrex::Real time); + // + // Get divU from the state data. + // + amrex::MultiFab* getDivCond (int ngrow, amrex::Real time); + // + // Get pressure gradient data, fill-patch ghost cells. + // + void computeGradP(amrex::Real time); + +#ifdef AMREX_USE_EB + const amrex::MultiFab* VolFrac () const { return volfrac; } +#endif + // + // Boundary condition access functions. + // + amrex::Vector fetchBCArray (int State_Type, const amrex::Box& bx, + int scomp, int ncomp); + + amrex::Vector fetchBCArray (int State_Type, int scomp, int ncomp); + + // + // ls related + // + void fill_allgts (amrex::MultiFab& mf, int type, int scomp, int ncomp, amrex::Real time); + void reinit (); + void reinitialization_sussman (amrex::Real dt, int loop_iter); + void reinitialization_consls (amrex::Real dt, int loop_iter, amrex::Real epsG, amrex::Real epsG2); + void phi_to_sgn0 (amrex::MultiFab& phi); + amrex::MultiFab& get_phi_half_time (); + void rk_first_reinit (amrex::MultiFab& phi_ctime, + amrex::MultiFab& phi2, + amrex::MultiFab& phi3, + amrex::MultiFab& sgn0, + amrex::MultiFab& G0, + amrex::Real dt, + amrex::MultiFab& phi_ori); + void rk_second_reinit (amrex::MultiFab& phi_ctime, + amrex::MultiFab& phi2, + amrex::MultiFab& phi3, + amrex::MultiFab& sgn0, + amrex::MultiFab& G0, + amrex::Real dt, + amrex::MultiFab& phi_ori); + void mass_fix (amrex::MultiFab& phi_ctime, + amrex::MultiFab& phi_original, + amrex::MultiFab& phi2, + amrex::MultiFab& phi3, + amrex::MultiFab& ld, + amrex::MultiFab& lambdad, + amrex::MultiFab& deltafunc_alias, + amrex::Real delta_t, + int loop_iter); + + amrex::Vector const& get_bcrec_velocity () const noexcept { return m_bcrec_velocity; } + amrex::Vector const& get_bcrec_scalars () const noexcept { return m_bcrec_scalars; } + + amrex::BCRec const* get_bcrec_velocity_d_ptr () const noexcept { + return m_bcrec_velocity_d.dataPtr(); } + amrex::BCRec const* get_bcrec_scalars_d_ptr () const noexcept { + return m_bcrec_scalars_d.dataPtr(); } + + // + // Select appropriate AMReX average_down() based on EB/non-EB and dimensionality + // for use in derived classes and Projection sync fns and initial vel proj + // + void average_down(const amrex::MultiFab& S_fine, amrex::MultiFab& S_crse, + int scomp, int ncomp); + + void calc_mut_LES(amrex::MultiFab* mu_LES[AMREX_SPACEDIM], amrex::Real time); + + void time_average(amrex::Real& time_avg, amrex::Real& time_avg_fluct, amrex::Real& dt_avg, const amrex::Real& dt_level); + + //////////////////////////////////////////////////////////////////////////// + // NavierStokesBase public static functions // + //////////////////////////////////////////////////////////////////////////// + + // + // Returns the value of "gravity" for use in the projection outflow bcs. + // + static amrex::Real getGravity () { return gravity; } + + // + // Returns the value of "gravity" for use in the projection outflow bcs. + // +#ifdef AMREX_USE_EB + static std::string const& getRedistType () { return redistribution_type; } +#endif + + static int DoTrac2() { return NavierStokesBase::do_trac2; } + + static bool GodunovUseForcesInTrans () {return godunov_use_forces_in_trans;} + + ////////////////////////////////////////////////////////////////// + + NavierStokesBase (); + + NavierStokesBase (amrex::Amr& papa, + int lev, + const amrex::Geometry& level_geom, + const amrex::BoxArray& bl, + const amrex::DistributionMapping& dm, + amrex::Real time); + + ////////////////////////////////////////////////////////////////// + // NavierStokesBase functions // + ////////////////////////////////////////////////////////////////// + + void advance_cleanup (int iteration,int ncycle); + + static void diffuse_scalar_setup (int sigma, int& rho_flag); + // + // Get the forcing term. + // + virtual void getForce (amrex::FArrayBox& force, + const amrex::Box& bx, + int scomp, + int ncomp, + amrex::Real time, + const amrex::FArrayBox& State, + const amrex::FArrayBox& Aux, + int auxScomp, + const amrex::MFIter& mfi); + + auto& getAdvFluxReg () { + AMREX_ASSERT(advflux_reg); + return *advflux_reg; + } + auto& getAdvFluxReg (int lev) { + return getLevel(lev).getAdvFluxReg(); + } + + amrex::FluxRegister& getViscFluxReg () { + AMREX_ASSERT(viscflux_reg); + return *viscflux_reg; + } + amrex::FluxRegister& getViscFluxReg (int lev) { + return getLevel(lev).getViscFluxReg(); + } + // + // Get rho at time n+1/2 + // + amrex::MultiFab& get_rho_half_time (); + // + // Get dSdt from the state data. + // + [[nodiscard]] amrex::MultiFab* getDsdt (int ngrow, amrex::Real time); + // + void incrRhoAvg (amrex::Real alpha); + void incrRhoAvg (const amrex::MultiFab& rho_incr, + int sComp, + amrex::Real alpha); + + void initial_velocity_diffusion_update (amrex::Real dt); + // + // Compute level projection. + // + void level_projector (amrex::Real dt, + amrex::Real time, + int iteration); + // + // Compute the level sync correction. + // + void level_sync (int crse_iteration); + // + // Impose divergence constraint on MAC velocities. + // + void mac_project (amrex::Real time, + amrex::Real dt, + amrex::MultiFab& S_old, + amrex::MultiFab* divu, + int ngrow, + bool increment_vel_register); + // + // Make rho at time n. + // + void make_rho_prev_time (); + // + // Make rho at time n+1. + // + void make_rho_curr_time (); + // + // This function estimates the initial timesteping used by the model. + // + void post_init_estDT (amrex::Real& dt_init, + amrex::Vector& nc_save, + amrex::Vector& dt_save, + amrex::Real stop_time); + // + // Ensure state is consistent, i.e. velocity field is nondivergent, + // coarse level data are averages of fine level data, pressure is zero. + // + void post_init_state (); + // + // Interpolate cell-centered cync correction from coarse to fine. + // + enum SyncInterpType + { + PC_T, + CellCons_T, + CellConsLin_T, + CellConsProt_T + }; + // + void SyncInterp (amrex::MultiFab& CrseSync, + int c_lev, + amrex::MultiFab& FineSync, + int f_lev, + amrex::IntVect& ratio, + int src_comp, + int dest_comp, + int num_comp, + int increment, + amrex::Real dt_clev, + int** bc_orig_qty, + SyncInterpType which_interp = CellCons_T, + int state_comp = -1); + // + // Bilinear interpolate nodal pressures from coarse to fine. + // + void SyncProjInterp (amrex::MultiFab& phi, + int c_lev, + amrex::MultiFab& P_new, + amrex::MultiFab& P_old, + int f_lev, + amrex::IntVect& ratio); + + void sync_setup (amrex::MultiFab*& DeltaSsync); + static void sync_cleanup (amrex::MultiFab*& DeltaSsync); + // + // Grow by nGrow and fillpatch the MAC-projected velocities. + // + void create_umac_grown (int nGrow, + const amrex::MultiFab *a_divu); + // + // Predict face velocities (before projection), estimate current cfl + // from t^n cell-centered velocities (plus cfl and change_max) + // + amrex::Real predict_velocity (amrex::Real dt); + // + // Advect velocities. + // + void velocity_advection (amrex::Real dt); + // + // Update velocities (or momentum) with advection and diffusion terms. + // + void velocity_update (amrex::Real dt); + // + // Update velocities (or momentum) with advection terms. + // + void velocity_advection_update (amrex::Real dt); + // + // Average down State_Type and Press_Type. + // + void avgDown_StatePress (); + + void LES_setDomainBC (std::array& mlmg_lobc, + std::array& mlmg_hibc, + int src_comp); + + + ////////////////////////////////////////////////////////////////// + // NavierStokesBase virtual functions // + ////////////////////////////////////////////////////////////////// + + virtual void advance_setup (amrex::Real time, + amrex::Real dt, + int iteration, + int ncycle); + + virtual void avgDown () = 0; // Average down for all the state types. + + virtual void calc_divu (amrex::Real time, + amrex::Real dt, + amrex::MultiFab& fab) = 0; + // + // Calculate nonuniform viscosity and diffusivity + // + virtual void calcViscosity (amrex::Real time, + amrex::Real dt, + int iteration, + int ncycle) = 0; + virtual void calcDiffusivity (amrex::Real time) = 0; + // + // Create the RHS for the MAC projection. + // + virtual void create_mac_rhs (amrex::MultiFab& rhs, int nGrow, amrex::Real time, amrex::Real dt); + + // + // Timestep estimation functions follow. + // + virtual amrex::Real estTimeStep (); + + virtual void getViscosity (amrex::MultiFab* viscosity[AMREX_SPACEDIM], + amrex::Real time) = 0; + // + // Compute viscous terms. + // + virtual void getViscTerms (amrex::MultiFab& visc_terms, + int src_comp, + int num_comp, + amrex::Real time) = 0; + // + virtual void mac_sync () = 0; + // + virtual void reflux () = 0; + // + // Reset time levels for the initial iterations. + // + virtual void resetState (amrex::Real time, + amrex::Real dt_old, + amrex::Real dt_new); + + virtual void scalar_advection_update (amrex::Real dt, + int first_scalar, + int last_scalar); + // + virtual void sum_integrated_quantities () = 0; + + virtual void velocity_diffusion_update (amrex::Real dt) = 0; + + //////////////////////////////////////////////////////////////////////////// + // NavierStokesBase static functions // + //////////////////////////////////////////////////////////////////////////// + + // + // Cleanup data descriptors at end of run. + // + static void variableCleanUp (); + // + // Read input file + // + static void Initialize (); + static void Finalize (); + // + // Check for RZ geometry + // + static void read_geometry (); + + //////////////////////////////////////////////////////////////////////////// + // NavierStokesBase particle functions // + //////////////////////////////////////////////////////////////////////////// + +#ifdef AMREX_PARTICLES + static amrex::AmrTracerParticleContainer* theNSPC (); + static void read_particle_params (); + + void initParticleData (); + void post_restart_particle (); + + void post_timestep_particle (int iteration); + + virtual int timestamp_num_extras () { return 0; } + virtual void timestamp_add_extras (int lev, amrex::Real time, amrex::MultiFab& mf) { } + + std::unique_ptr ParticleDerive (const std::string& name, amrex::Real time, int ngrow); + void ParticleDerive (const std::string& name, amrex::Real time, amrex::MultiFab& mf, int dcomp); +#endif + + //////////////////////////////////////////////////////////////////////////// + // NavierStokesBase diagnostics functions // + //////////////////////////////////////////////////////////////////////////// + void printMaxVel (bool new_data = true); + + void printMaxGp (bool new_data = true); + + void printMaxValues (bool new_data = true); + + //////////////////////////////////////////////////////////////////////////// + + void buildMetrics (); // 1-D metric arrays for RZ + // + void calc_dsdt (amrex::Real time, + amrex::Real dt, + amrex::MultiFab& dsdt); + // + NavierStokesBase& getLevel (int lev) { + return dynamic_cast ( parent->getLevel(lev) ); + } + // + SyncRegister& getSyncReg () { + AMREX_ASSERT(sync_reg); + return *sync_reg; + } + // + static void getOutFlowFaces (amrex::Vector& outFaces); + // + // Get state data. + // + [[nodiscard]] amrex::MultiFab* getState (int ngrow, + int state_indx, + int strt_comp, + int num_comp, + amrex::Real time); + // + // Compile p_avg in advance. + // + void incrPAvg (); + void initOldFromNew (int type, int lev = -1); // Initialize old with new + // + // Compile rho_avg in advance. + // + void initRhoAvg (amrex::Real alpha); + // + static void init_additional_state_types (); + // + amrex::Real initialTimeStep (); + + // + // Correct a conservatively-advected scalar for under-over shoots. + // + void ConservativeScalMinMax ( amrex::MultiFab& Snew, int snew_comp, int new_density_comp, + amrex::MultiFab const& Sold, int sold_comp, int old_density_comp ); + + // + // Correct a convectively-advected scalar for under-over shoots. + // + void ConvectiveScalMinMax ( amrex::MultiFab& Snew, int snew_comp, + amrex::MultiFab const& Sold, int sold_comp ); + // + // Floor small values of states to be extrapolated + // + static void floor(amrex::MultiFab& mf); + +#ifdef AMREX_USE_EB + void init_eb (const amrex::Geometry& level_geom, const amrex::BoxArray& ba, const amrex::DistributionMapping& dm); + + void initialize_eb2_structs(); + void define_body_state(); + + void InitialRedistribution (); + + static bool ebInitialized(); + static bool eb_initialized; + static bool body_state_set; + static bool no_eb_in_domain; + static std::vector body_state; +#endif + + void ComputeAofs (int comp, int ncomp, + amrex::MultiFab const& state, + int S_comp, + amrex::MultiFab const& forcing_term, + amrex::MultiFab const& divu, + bool is_velocity, amrex::Real dt); + + void ComputeAofs (amrex::MultiFab& advc, int a_comp, + int state_indx, int ncomp, + amrex::MultiFab const& S, int S_comp, + amrex::MultiFab const* forcing, int f_comp, + amrex::MultiFab const* divu, + amrex::Array& cfluxes, int flux_comp, + amrex::Array& edgestate, int edge_comp, + bool known_edge_state, + bool is_velocity, amrex::Real dt, + bool is_sync, amrex::Array const& U_corr, + bool do_crse_add, bool do_fine_add); +// +// Data +// + + // volume and area are intentionally without EB knowledge + amrex::MultiFab volume; + amrex::MultiFab area[AMREX_SPACEDIM]; + + std::unique_ptr coarse_fine_mask; + +#ifdef AMREX_USE_EB + void set_body_state(amrex::MultiFab& S); + + const amrex::MultiFab* volfrac; + amrex::FabArray> ebmask; + + std::array areafrac; + std::array facecent; + +#endif + + + // + // MAC edge velocities. + // + amrex::MultiFab* u_mac = nullptr; + int umac_n_grow; + // + // Advective update terms. + // + amrex::MultiFab* aofs = nullptr; + // + // BC info for advection + // + amrex::Vector m_bcrec_velocity; + amrex::Vector m_bcrec_scalars; + // NOTE that DeviceVector reverts to amrex::Vector if !AMREX_USE_GPU + amrex::Gpu::DeviceVector m_bcrec_velocity_d; + amrex::Gpu::DeviceVector m_bcrec_scalars_d; + + std::unique_ptr diffusion; + // + // arrays for variable viscosity and diffusivity + // + amrex::MultiFab *diffn_cc, *diffnp1_cc; + amrex::MultiFab *viscn_cc, *viscnp1_cc; + // + // Sync update quantities. + // + // Average rho over a composite timestep. + // Used only in the multlilevel sync projection + // + amrex::MultiFab rho_avg; + // + // Average p over a composite timestep. + // Used only to average fine pressure data to coarse. + // + amrex::MultiFab p_avg; + + amrex::MultiFab Vsync; // Velocity sync update storage + amrex::MultiFab Ssync; // Scalar sync update storage + // + // Density at time n+1/2 (used in advance). + // + amrex::MultiFab rho_half; + amrex::MultiFab* rho_qtime = nullptr; + amrex::MultiFab* rho_tqtime = nullptr; + // + // Density at prev_time used in advance(). + // + amrex::MultiFab rho_ptime; + // + // Density at cur_time used in advance(). + // + amrex::MultiFab rho_ctime; + // + // Data structure used to compute RHS for sync project. + // + SyncRegister* sync_reg = nullptr; + // + // Data structures to store advective and viscous refluxing quantities + // on coarse-fine grid interfaces. + // +#ifdef AMREX_USE_EB + std::unique_ptr advflux_reg; +#else + std::unique_ptr advflux_reg; +#endif + amrex::FluxRegister* viscflux_reg = nullptr; + // + // Radii for r-z calculations. + // + amrex::Vector< amrex::Vector > radius; + // + // Static objects. + // + static amrex::BCRec phys_bc; + static Projection* projector; + static MacProj* mac_projector; + // + // Internal parameters for timestepping. + // + static amrex::Real init_shrink; // reduction factor of first estimated timestep + static int init_iter; // # of timestep iterations for initial pressure + static int init_vel_iter; // # of iterations for initial velocity projection + static amrex::Real cfl; // desired maximum cfl + static amrex::Real change_max; // maximum change in dt over a timestep + static amrex::Real fixed_dt; // set > 0 to specify dt + static amrex::Real init_dt; // set > 0 to specify initial dt at coarsest level + static bool stop_when_steady; // set to true if simulation should stop at steady-state + static amrex::Real steady_tol; // tolerance for assuming steady-state has been reached + static int initial_iter; // flag for initial pressure iterations + static int initial_step; // flag for initial iterations + static amrex::Real dt_cutoff; // minimum dt allowed + static int sum_interval; // number of timesteps for conservation stats + // + // Internal parameters for options. + // + static int radius_grow; + static int verbose; + static amrex::Real gravity; + static int NUM_SCALARS; // number of non-velocity components + static int NUM_STATE; // total number of state variables +#ifdef AMREX_USE_EB + static const int NUM_GROW=4; // number of ghost cells + static int refine_cutcells; +#else + // + // ls related + // change to two gts + // + static const int NUM_GROW=2; // number of ghost cells +#endif + // + // Controls over how the convective and diffusive terms are calculated + // for each state variable. + // + static amrex::Vector advectionType; + static amrex::Vector diffusionType; + // + // Viscosity parameters. + // + static amrex::Vector is_diffusive; // does variable diffuse? + static amrex::Vector visc_coef; // const coef viscosity terms + static amrex::Real visc_tol; + static amrex::Real visc_abs_tol; + static amrex::Real be_cn_theta; + // + // Internal switches. + // + static int Tracer; + static int Tracer2; + static int Temp; + static int do_trac2; + static int do_temp; + static int do_cons_trac; + static int do_cons_trac2; + static int do_sync_proj; + static int do_reflux; + static int do_mac_proj; + static int do_refine_outflow; // The following three items control + static int do_derefine_outflow; // how grids are treated at + static int Nbuf_outflow; // outflow boundaries. + static int do_denminmax; // The code for these was in NavierStokes.cpp, + static int do_scalminmax; // but the flags were not declared or read in. + static int getForceVerbose; // Does exactly what it says on the tin + // + // LES parameters + // + static int do_LES; // To activate LES modelling + static int getLESVerbose; // Does exactly what it says on the tin + static std::string LES_model; // To choose a LES model + static amrex::Real smago_Cs_cst; // A parameter for the Smagorinsky model, usually set to 0.18 + static amrex::Real sigma_Cs_cst; // A parameter for the Sigma model, usually set to 1.5 + // + // Parameters for averaging + // + static amrex::Vector time_avg; + static amrex::Vector time_avg_fluct; + static amrex::Vector dt_avg; + static int avg_interval; + static int compute_fluctuations; + // + // Members for non-zero divu. + // + static int additional_state_types_initialized; + static int Divu_Type; + static int Dsdt_Type; + static int Average_Type; + static int num_state_type; + static int have_divu; + static int have_dsdt; + static int do_init_vort_proj; + static int do_init_proj; + // + // Control velocity vs momentum update + // + static int do_mom_diff; + + // + // skip_level_projector + // + static int skip_level_projector; + + static int isolver; + + // + // ls related + // + static int do_phi; + static int phicomp; + static int epsilon; + amrex::MultiFab phi_half; + amrex::MultiFab phi_ptime; + amrex::MultiFab phi_ctime; + amrex::MultiFab heaviside; + + static amrex::Real mu_a; + static amrex::Real rho_a; + static amrex::Real mu_w; + static amrex::Real rho_w; + + static int do_reinit; + static int lev0step_of_reinit; + static int number_of_reinit; + static int reinit_levelset; + + // for reinit_sussman + amrex::MultiFab phi_original; + amrex::MultiFab sgn0; + + static int do_cons_phi; + static int prescribed_vel; + + // for cons_levelset + static int do_cons_levelset; + + // + // diffused ib + // + static int do_diffused_ib; + amrex::MultiFab phi_nodal; + amrex::MultiFab pvf; + static int advect_and_update_scalar; + static amrex::Real fluid_rho; + +// #ifdef AMREX_PARTICLES +// mParticle *mParticle_obj; +// #endif + int nghost_state () const; + static constexpr int nghost_force () { return 1; } + + // + // static integer constants + // + static const int GEOM_GROW = 1; +#ifdef AMREX_USE_EB + // This must be consistent with what nghost_force returns for + // godunov + static const int gradp_grow = 4; +#else + static const int gradp_grow = 1; +#endif + + // + // Controls advection scheme + // + static std::string advection_scheme; + static bool godunov_use_forces_in_trans; + +#ifdef AMREX_USE_EB + // Controls redistribution + static std::string redistribution_type; +#endif + + // + // For restart, is GradP in checkpoint file + // + static int gradp_in_checkpoint; + + static int average_in_checkpoint; + +#ifdef AMREX_PARTICLES + // + // Check in case different particle methods are being used + // + static bool do_nspc; + // + // Put particle info in plotfile (using ParticleContainer::Checkpoint)? + // + static bool particles_in_plotfile; +#endif +}; + +#endif diff --git a/Source/NavierStokesBase.cpp b/Source/NavierStokesBase.cpp index 0097361f..089b2243 100644 --- a/Source/NavierStokesBase.cpp +++ b/Source/NavierStokesBase.cpp @@ -1,6291 +1,6296 @@ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef AMREX_PARTICLES -#include -#endif -#ifdef AMREX_USE_EB -#include -#include -#include -#include -#include -#include -#endif -#ifdef AMREX_USE_TURBULENT_FORCING -#include -#endif - - -using namespace amrex; - -// -// Set external dirichlet BC to zero -// -struct HomExtDirFill -{ - AMREX_GPU_DEVICE - void operator() (const IntVect& iv, Array4 const& dest, - const int dcomp, const int numcomp, - GeometryData const& geom, const Real /*time*/, - const BCRec* bcr, const int /*bcomp*/, - const int /*orig_comp*/) const - { - const int* domlo = geom.Domain().loVect(); - const int* domhi = geom.Domain().hiVect(); - for (int n = 0; n < numcomp; n++ ) { - const int* bc = bcr[n].data(); - for (int idir = 0; idir < AMREX_SPACEDIM; idir++) { - if ((bc[idir] == amrex::BCType::ext_dir) and (iv[idir] < domlo[idir])) { - dest(iv, dcomp+n) = 0.0; - } - if ((bc[idir + AMREX_SPACEDIM] == amrex::BCType::ext_dir) and (iv[idir] > domhi[idir])) { - dest(iv, dcomp+n) = 0.0; - } - } - } - } -}; - -// -// A dummy function because FillPatch requires something to exist for filling dirichlet boundary conditions, -// even if we know we cannot have an ext_dir BC. -// u_mac BCs are only either periodic (BCType::int_dir) or first order extrapolation (FOEXTRAP). -// -struct umacFill -{ - AMREX_GPU_DEVICE - void operator()( - const amrex::IntVect& /*iv*/, - amrex::Array4 const& /*dummy*/, - const int /*dcomp*/, - const int numcomp, - amrex::GeometryData const& /*geom*/, - const amrex::Real /*time*/, - const amrex::BCRec* bcr, - const int bcomp, - const int /*orig_comp*/) const - { - // Abort if this function is expected to fill an ext_dir BC. - for (int n = bcomp; n < bcomp+numcomp; ++n) { - const amrex::BCRec& bc = bcr[n]; - if ( AMREX_D_TERM( bc.lo(0) == amrex::BCType::ext_dir || bc.hi(0) == amrex::BCType::ext_dir, - || bc.lo(1) == amrex::BCType::ext_dir || bc.hi(1) == amrex::BCType::ext_dir, - || bc.lo(2) == amrex::BCType::ext_dir || bc.hi(2) == amrex::BCType::ext_dir ) ) { - amrex::Abort("NavierStokesBase::umacFill: umac should not have BCType::ext_dir"); - } - } - } -}; - - -BCRec NavierStokesBase::phys_bc; -Projection* NavierStokesBase::projector = nullptr; -MacProj* NavierStokesBase::mac_projector = nullptr; - -Real NavierStokesBase::init_shrink = 1.0; -int NavierStokesBase::init_iter = 2; -int NavierStokesBase::init_vel_iter = 1; -Real NavierStokesBase::cfl = 0.8; -Real NavierStokesBase::change_max = 1.1; -Real NavierStokesBase::init_dt = -1.0; -Real NavierStokesBase::fixed_dt = -1.0; -bool NavierStokesBase::stop_when_steady = false; -Real NavierStokesBase::steady_tol = 1.0e-10; -int NavierStokesBase::initial_iter = false; -int NavierStokesBase::initial_step = false; -Real NavierStokesBase::dt_cutoff = 0.0; -int NavierStokesBase::sum_interval = -1; - -int NavierStokesBase::radius_grow = 1; -int NavierStokesBase::verbose = 0; -Real NavierStokesBase::gravity = 0.0; -int NavierStokesBase::NUM_SCALARS = 0; -int NavierStokesBase::NUM_STATE = 0; - -Vector NavierStokesBase::advectionType; -Vector NavierStokesBase::diffusionType; - -Vector NavierStokesBase::is_diffusive; -Vector NavierStokesBase::visc_coef; -Real NavierStokesBase::visc_tol = 1.0e-10; -Real NavierStokesBase::visc_abs_tol = 1.0e-10; -Real NavierStokesBase::be_cn_theta = 0.5; - -int NavierStokesBase::Tracer = -1; -int NavierStokesBase::Tracer2 = -1; -int NavierStokesBase::Temp = -1; -int NavierStokesBase::do_trac2 = 0; -int NavierStokesBase::do_temp = 0; -int NavierStokesBase::do_cons_trac = 0; -int NavierStokesBase::do_cons_trac2 = 0; -int NavierStokesBase::do_sync_proj = 1; -int NavierStokesBase::do_reflux = 1; -int NavierStokesBase::do_mac_proj = 1; -int NavierStokesBase::do_refine_outflow = 0; -int NavierStokesBase::do_derefine_outflow = 1; -int NavierStokesBase::Nbuf_outflow = 1; -int NavierStokesBase::do_denminmax = 0; -int NavierStokesBase::do_scalminmax = 0; -int NavierStokesBase::getForceVerbose = 0; -int NavierStokesBase::do_LES = 0; -int NavierStokesBase::getLESVerbose = 0; -std::string NavierStokesBase::LES_model = "Smagorinsky"; -Real NavierStokesBase::smago_Cs_cst = 0.18; -Real NavierStokesBase::sigma_Cs_cst = 1.5; - -amrex::Vector NavierStokesBase::time_avg; -amrex::Vector NavierStokesBase::time_avg_fluct; -amrex::Vector NavierStokesBase::dt_avg; -int NavierStokesBase::avg_interval = 0; -int NavierStokesBase::compute_fluctuations = 0; -int NavierStokesBase::additional_state_types_initialized = 0; -// -// "Divu_Type" means S, where divergence U = S -// "Dsdt_Type" means pd S/pd t, where S is as above -// -int NavierStokesBase::Divu_Type = -1; -int NavierStokesBase::Dsdt_Type = -1; -int NavierStokesBase::Average_Type = -1; -int NavierStokesBase::num_state_type = 2; -int NavierStokesBase::have_divu = 0; -int NavierStokesBase::have_dsdt = 0; -int NavierStokesBase::do_init_vort_proj = 0; -int NavierStokesBase::do_init_proj = 1; - -int NavierStokesBase::do_mom_diff = 0; - -std::string NavierStokesBase::advection_scheme = "Godunov_PLM"; - -bool NavierStokesBase::godunov_use_forces_in_trans = false; - -#ifdef AMREX_USE_EB -int NavierStokesBase::refine_cutcells = 1; -bool NavierStokesBase::eb_initialized = false; -bool NavierStokesBase::no_eb_in_domain = true; -bool NavierStokesBase::body_state_set = false; -std::vector NavierStokesBase::body_state; -std::string NavierStokesBase::redistribution_type = "StateRedist"; -#endif - -// -// For restart, is GradP in checkpoint file -// -int NavierStokesBase::gradp_in_checkpoint = -1; - -// is Average in checkpoint file -int NavierStokesBase::average_in_checkpoint = -1; - -// -// skip_level_projector -// -int NavierStokesBase::skip_level_projector = 0; - -int NavierStokesBase::isolver = 0; - -// -// ls related -// -int NavierStokesBase::do_phi = 0; -int NavierStokesBase::phicomp = 0; -int NavierStokesBase::epsilon = 2; - -Real NavierStokesBase::mu_a = 0.00018; -Real NavierStokesBase::mu_w = 0.01; -Real NavierStokesBase::rho_a = 0.0012; -Real NavierStokesBase::rho_w = 1.0; - -int NavierStokesBase::do_reinit = 0; -int NavierStokesBase::lev0step_of_reinit = 1; -int NavierStokesBase::number_of_reinit = 4; -int NavierStokesBase::reinit_levelset = 1; - -int NavierStokesBase::do_cons_phi = 0; -int NavierStokesBase::prescribed_vel = 0; - -int NavierStokesBase::do_cons_levelset = 0; - -// -// diffused ib -// -int NavierStokesBase::do_diffused_ib = 0; -int NavierStokesBase::advect_and_update_scalar = 1; -Real NavierStokesBase::fluid_rho = 1.0; - -namespace -{ - bool initialized = false; - int dump_plane = -1; - std::string dump_plane_name("SLABS/vel-"); - bool benchmarking = false; -} - -#ifdef AMREX_PARTICLES -bool NavierStokesBase::do_nspc = true; -bool NavierStokesBase::particles_in_plotfile = false; - -namespace -{ - // - // Name of subdirectory in chk???? holding checkpointed particles. - // - const std::string the_ns_particle_file_name("Particles"); - // - // There's really only one of these. - // - AmrTracerParticleContainer* NSPC = 0; - - std::string timestamp_dir ("Timestamps"); - std::vector timestamp_indices; - std::string particle_init_file; - std::string particle_restart_file; - std::string particle_output_file; - bool restart_from_nonparticle_chkfile = false; - int pverbose = 0; -} - -AmrTracerParticleContainer* NavierStokesBase::theNSPC () { return NSPC; } -#endif - -NavierStokesBase::NavierStokesBase () -{ - if (!additional_state_types_initialized) { - init_additional_state_types(); - } -} - -NavierStokesBase::NavierStokesBase (Amr& papa, - int lev, - const Geometry& level_geom, - const BoxArray& bl, - const DistributionMapping& dm, - Real time) - : - AmrLevel(papa,lev,level_geom,bl,dm,time) -{ - - // - // 2/2022 - Only allow RZ if there's no visc. - // MLMG Tensor solver does not currently support RZ - // - if ( level_geom.IsRZ() ) - { -#ifdef AMREX_USE_EB - amrex::Abort("Embedded boundaries with RZ geometry is not currently supported."); -#endif - for ( int n = 0; n < AMREX_SPACEDIM; n++ ) { - if ( visc_coef[n] > 0 ) { - amrex::Abort("RZ geometry with viscosity is not currently supported. To use set ns.vel_visc_coef=0"); - } - } - } - - if(!additional_state_types_initialized) { - init_additional_state_types(); - } - - // - // Alloc old_time pressure. - // - state[Press_Type].allocOldData(); - state[Gradp_Type].allocOldData(); - - define_workspace(); -} - -void NavierStokesBase::define_workspace() -{ - // - // Alloc space for density and temporary pressure variables. - // - if (level > 0) - { - rho_avg.define(grids,dmap,1,1,MFInfo(),Factory()); - - const BoxArray& P_grids = state[Press_Type].boxArray(); - p_avg.define(P_grids,dmap,1,0,MFInfo(),Factory()); - } - - rho_half.define (grids,dmap,1,1,MFInfo(),Factory()); - rho_ptime.define(grids,dmap,1,1,MFInfo(),Factory()); - rho_ctime.define(grids,dmap,1,1,MFInfo(),Factory()); - rho_qtime = nullptr; - rho_tqtime = nullptr; - - // - // Build metric coefficients for RZ calculations. - // Build volume and areas. - // - buildMetrics(); - - // - // ls related - // 2 ghost cells - // - if (do_phi) { - phi_half.define(grids,dmap,1,2,MFInfo(),Factory()); - phi_ptime.define(grids,dmap,1,2,MFInfo(),Factory()); - phi_ctime.define(grids,dmap,1,2,MFInfo(),Factory()); - heaviside.define(grids,dmap,1,2,MFInfo(),Factory()); - sgn0.define(grids,dmap,1,2,MFInfo(),Factory()); - phi_original.define(grids,dmap,1,2,MFInfo(),Factory()); - } - - // - // diffused ib - // - if (do_diffused_ib) { - const BoxArray& nba = amrex::convert(grids,IntVect::TheNodeVector()); - phi_nodal.define(nba,dmap,1,2,MFInfo(),Factory()); - pvf.define(grids,dmap,1,2,MFInfo(),Factory()); -#ifdef AMREX_PARTICLES - amrex::Print() << "check level " << level << " " << Particles::ParticleFinestLevel() << std::endl; - if (level == Particles::ParticleFinestLevel()) { - if(!Particles::isInitial){ - //particles - Particles::init_particle(gravity, geom.CellSizeArray()[0]); - } - //largra - Particles::create_particles(geom, dmap, grids); // Class constructor - } -#endif - } - - // - // Set up reflux registers. - // - sync_reg = nullptr; - viscflux_reg = nullptr; - - AMREX_ASSERT(sync_reg == nullptr); - if (level > 0 && do_sync_proj) - { - sync_reg = new SyncRegister(grids,dmap,crse_ratio); - } - - if (level > 0 && do_reflux) - { -#ifdef AMREX_USE_EB - advflux_reg = std::make_unique(); -#else - advflux_reg = std::make_unique(); -#endif - - NavierStokesBase& clevel = getLevel(level-1); - advflux_reg->define(grids, clevel.boxArray(), dmap, clevel.DistributionMap(), - parent->Geom(level), parent->Geom(level-1), - parent->refRatio(level-1),level,NUM_STATE); - -#ifndef AMREX_USE_EB - if (parent->Geom(level-1).IsRZ()) { - advflux_reg->setCrseVolume(&(clevel.Volume())); - } -#endif - - AMREX_ASSERT(viscflux_reg == nullptr); - viscflux_reg = new FluxRegister(grids,dmap,crse_ratio,level,NUM_STATE); - } - - // - // Set up the level projector. - // - if (projector == nullptr) - { - projector = new Projection(parent,&phys_bc,do_sync_proj, - parent->finestLevel(),radius_grow); - } - projector->install_level(level,this,&radius); - - // - // Set up the mac projector. - // - if (mac_projector == nullptr) - { - mac_projector = new MacProj(parent,parent->finestLevel(), - &phys_bc,radius_grow); - } - mac_projector->install_level(level,this); - - // - // Set up diffusion. - // - diffusion = std::make_unique(parent,this, - (level > 0) ? getLevel(level-1).diffusion.get() - : nullptr, - NUM_STATE,viscflux_reg,is_diffusive); - // - // Allocate the storage for variable viscosity and diffusivity - // - diffn_cc = new MultiFab(grids, dmap, NUM_STATE-Density-1, 1, MFInfo(), Factory()); - diffnp1_cc = new MultiFab(grids, dmap, NUM_STATE-Density-1, 1, MFInfo(), Factory()); - viscn_cc = new MultiFab(grids, dmap, 1, 1, MFInfo(), Factory()); - viscnp1_cc = new MultiFab(grids, dmap, 1, 1, MFInfo(), Factory()); - - // - // Initialize BCRec for use with advection - // - m_bcrec_velocity.resize(AMREX_SPACEDIM); - m_bcrec_velocity = fetchBCArray(State_Type,Xvel,AMREX_SPACEDIM); - - m_bcrec_velocity_d.resize(AMREX_SPACEDIM); - m_bcrec_velocity_d = convertToDeviceVector(m_bcrec_velocity); - - m_bcrec_scalars.resize(NUM_SCALARS); - m_bcrec_scalars = fetchBCArray(State_Type,Density,NUM_SCALARS); - - m_bcrec_scalars_d.resize(NUM_SCALARS); - m_bcrec_scalars_d = convertToDeviceVector(m_bcrec_scalars); - -} - -NavierStokesBase::~NavierStokesBase () -{ - delete rho_qtime; - delete rho_tqtime; - delete sync_reg; - delete viscflux_reg; - delete [] u_mac; - - if (mac_projector != nullptr) { - mac_projector->cleanup(level); - } - // - // Remove the arrays for variable viscosity and diffusivity - // and delete the Diffusion object - // - delete viscn_cc; - delete viscnp1_cc; - delete diffn_cc; - delete diffnp1_cc; - - diffusion.reset(); -} - -void -NavierStokesBase::variableCleanUp () -{ - desc_lst.clear(); - derive_lst.clear(); - - delete projector; - projector = nullptr; - - delete mac_projector; - mac_projector = nullptr; - -#ifdef AMREX_PARTICLES - delete NSPC; - NSPC = nullptr; -#endif -} - -void -NavierStokesBase::Initialize () -{ - if (initialized) { - return; - } - - ParmParse pp("ns"); - - pp.query("dump_plane",dump_plane); - - pp.query("benchmarking",benchmarking); - - pp.query("v",verbose); - - // - // Get timestepping parameters. - // - pp.get("cfl",cfl); - pp.query("init_iter",init_iter); - pp.query("init_vel_iter",init_vel_iter); - pp.query("init_shrink",init_shrink); - pp.query("dt_cutoff",dt_cutoff); - pp.query("change_max",change_max); - pp.query("fixed_dt",fixed_dt); - pp.query("init_dt", init_dt); - pp.query("stop_when_steady",stop_when_steady); - pp.query("steady_tol",steady_tol); - pp.query("sum_interval",sum_interval); - pp.query("gravity",gravity); - // - // Get run options. - // - pp.query("do_temp", do_temp ); - pp.query("do_trac2", do_trac2 ); - pp.query("do_cons_trac", do_cons_trac ); - pp.query("do_cons_trac2", do_cons_trac2 ); - pp.query("do_sync_proj", do_sync_proj ); - pp.query("do_reflux", do_reflux ); - pp.query("do_init_vort_proj", do_init_vort_proj); - pp.query("do_init_proj", do_init_proj ); - pp.query("do_mac_proj", do_mac_proj ); - pp.query("do_denminmax", do_denminmax ); - pp.query("do_scalminmax", do_scalminmax ); - - if ( pp.contains("do_temp_ref") || - pp.contains("do_density_ref") || - pp.contains("do_tracer_ref") || - pp.contains("do_tracer2_ref") || - pp.contains("do_vorticity_ref") ) { - amrex::Abort("ns.do_*_ref no longer supported. Refinement now implemented using refinement_indicators. For help, see UsersGuide or examples in /Exec"); - } - - pp.query("visc_tol",visc_tol); - pp.query("visc_abs_tol",visc_abs_tol); - - pp.query("getForceVerbose", getForceVerbose ); - pp.query("do_LES", do_LES ); - pp.query("getLESVerbose", getLESVerbose ); - pp.query("LES_model", LES_model ); - pp.query("smago_Cs_cst", smago_Cs_cst ); - pp.query("sigma_Cs_cst", sigma_Cs_cst ); - - pp.query("avg_interval", avg_interval ); - pp.query("compute_fluctuations", compute_fluctuations ); - -#ifdef AMREX_USE_EB - pp.query("refine_cutcells", refine_cutcells); -#endif - - int do_scalar_update_in_order = 0; - pp.query("do_scalar_update_in_order",do_scalar_update_in_order ); - if (do_scalar_update_in_order) { - amrex::Abort("NavierStokesBase::Initialize(): do_scalar_update_in_order no longer supported. If needed, please open issue on github."); - } - - // Don't let init_shrink be greater than 1 - if (init_shrink > 1.0) { - amrex::Abort("NavierStokesBase::Initialize(): init_shrink cannot be greater than 1"); - } - - pp.query("be_cn_theta",be_cn_theta); - if (be_cn_theta > 1.0 || be_cn_theta < .5) { - amrex::Abort("NavierStokesBase::Initialize(): Must have be_cn_theta <= 1.0 && >= .5"); - } - // - // Set parameters dealing with how grids are treated at outflow boundaries. - // - pp.query("do_refine_outflow",do_refine_outflow); - pp.query("do_derefine_outflow",do_derefine_outflow); - if (do_derefine_outflow == 1 && do_refine_outflow == 1) { - amrex::Abort("NavierStokesBase::Initialize(): Cannot have both do_refine_outflow==1 and do_derefine_outflow==1"); - } - - pp.query("Nbuf_outflow",Nbuf_outflow); - AMREX_ASSERT(Nbuf_outflow >= 0); - AMREX_ASSERT(!(Nbuf_outflow <= 0 && do_derefine_outflow == 1)); - - // Provide error message for depreciated volume weighted sum over a sub-domain. - // NSB only ever supported cylinder sub-domains, so check for that one. - if (pp.contains("volWgtSum_sub_dz")) { - Abort("Computing volume weighted sum over sub-domains is no longer supported. If desired, submit an issue on github"); - }; - - // Are we going to do velocity or momentum update? - pp.query("do_mom_diff",do_mom_diff); - -#ifdef AMREX_PARTICLES - read_particle_params (); -#endif - - // - // Get checkpoint info - // - pp.query("gradp_in_checkpoint", gradp_in_checkpoint); - pp.query("avg_in_checkpoint", average_in_checkpoint); - - // - // Get advection scheme options - // - if ( pp.contains("use_godunov") ) { - Abort("ns.use_godunov is depreciated. Please use ns.advection_scheme instead. Options are Godunov_PLM (default), Godunov_PPM, or BDS"); - } - - pp.query("advection_scheme", advection_scheme); - if ( advection_scheme == "MOL" ) { - Abort("MOL advection scheme is no longer supported. Current options are Godunov_PLM (default), Godunov_PPM, or BDS"); - } - if (advection_scheme != "Godunov_PLM" && advection_scheme != "Godunov_PPM" && advection_scheme != "BDS") { - Abort("Invalid advection_scheme. Options are Godunov_PLM, Godunov_PPM, BDS"); - } - - ParmParse pp2("godunov"); - pp2.query("use_forces_in_trans", godunov_use_forces_in_trans); - -#ifdef AMREX_USE_EB - // - // Advection scheme restrictions - // - if ( advection_scheme == "Godunov_PPM" || advection_scheme == "BDS") { - amrex::Abort("This advection_scheme is not implemented for EB. Please use Godunov_PLM (default)"); - } - if ( godunov_use_forces_in_trans ) { - amrex::Abort("use_forces_in_trans not implemented within EB Godunov. Set godunov.use_forces_in_trans=0."); - } - - // - // Redistribution - // - pp.query("redistribution_type", redistribution_type); - if (redistribution_type != "NoRedist" && - redistribution_type != "FluxRedist" && - redistribution_type != "StateRedist" ) { - amrex::Abort("redistribution type must be NoRedist, FluxRedist, or StateRedist"); - } -#endif - - // - // composite time advancement - // - pp.query("skip_level_projector", skip_level_projector); - - // - // ls related - // - pp.query("do_phi", do_phi); - if (do_phi) { - pp.query("epsilon", epsilon); - pp.query("mu_a", mu_a); - pp.query("mu_w", mu_w); - pp.query("rho_a", rho_a); - pp.query("rho_w", rho_w); - - pp.query("do_reinit", do_reinit); - pp.query("lev0step_of_reinit", lev0step_of_reinit); - pp.query("number_of_reinit", number_of_reinit); - pp.query("reinit_levelset", reinit_levelset); - - pp.query("do_cons_phi", do_cons_phi); - - } - - pp.query("prescribed_vel", prescribed_vel); - pp.query("isolver", isolver); - pp.query("do_diffused_ib", do_diffused_ib); - advect_and_update_scalar = !(do_diffused_ib == 1); - pp.query("fluid_rho", fluid_rho); - - amrex::ExecOnFinalize(NavierStokesBase::Finalize); - -#ifdef AMREX_PARTICLES - Particles::Initialize(); -#endif - - initialized = true; -} - -void -NavierStokesBase::Finalize () -{ - initialized = false; -} - -void -NavierStokesBase::read_geometry () -{ -#if (AMREX_SPACEDIM == 2) - // - // Must load coord here because Geometry hasn't read it in yet. - // - ParmParse pp("geometry"); - - int coord; - pp.get("coord_sys",coord); - - if ((Geometry::CoordType) coord == Geometry::RZ && phys_bc.lo(0) != PhysBCType::symmetry) - { - phys_bc.setLo(0,PhysBCType::symmetry); - amrex::Print() << "\nWarning: Setting phys_bc at xlo to PhysBCType::symmetry\n\n"; - } -#endif -} - -void -NavierStokesBase::advance_setup (Real /*time*/, - Real dt, - int iteration, - int ncycle) -{ - BL_PROFILE("NavierStokesBase::advance_setup()"); - - const int finest_level = parent->finestLevel(); - - // Same for EB vs not. - umac_n_grow = 1; - -#ifdef AMREX_PARTICLES - if (ncycle > umac_n_grow && NSPC) { - umac_n_grow = ncycle; - } -#endif - - mac_projector->setup(level); - // - // Why are they defined here versus the constructor? - // - if (level < finest_level) - { -#ifdef AMREX_USE_EB - int ng_sync = (redistribution_type == "StateRedist") ? nghost_state() : 1; -#else - int ng_sync = 1; -#endif - - if (Vsync.empty()) { - Vsync.define(grids,dmap,AMREX_SPACEDIM,ng_sync,MFInfo(),Factory()); - } - if (Ssync.empty()) { - Ssync.define(grids,dmap,NUM_STATE-AMREX_SPACEDIM,ng_sync,MFInfo(),Factory()); - } - Vsync.setVal(0); - Ssync.setVal(0); - } - // - // Set reflux registers to zero. - // - if (do_reflux && level < finest_level) - { - getAdvFluxReg(level+1).reset(); - getViscFluxReg(level+1).setVal(0.); - } - // - // Alloc space for edge velocities (normal comp only). - // - if (u_mac == nullptr || u_mac[0].nGrow() < umac_n_grow) - { - delete [] u_mac; - - u_mac = new MultiFab[AMREX_SPACEDIM]; - - for (int dir = 0; dir < AMREX_SPACEDIM; dir++) - { - const BoxArray& edgeba = getEdgeBoxArray(dir); - u_mac[dir].define(edgeba,dmap,1,umac_n_grow,MFInfo(),Factory()); - u_mac[dir].setVal(1.e40); - } - } - // - // Alloc MultiFab to hold advective update terms. - // - AMREX_ASSERT(aofs == nullptr); - aofs = new MultiFab(grids,dmap,NUM_STATE,0,MFInfo(),Factory()); - - // - // Set rho_avg. - // - if (!initial_step && level > 0 && iteration == 1) { - initRhoAvg(0.5/Real(ncycle)); - } - // - // Set up state multifabs for the advance. - // - for (int k = 0; k < num_state_type; k++) - { - bool has_old_data = state[k].hasOldData(); - // does nothing if old_data!=null - state[k].allocOldData(); - if (! has_old_data) { - state[k].oldData().setVal(0.0); - } - // swaps pointers-- reuses space, but doesn't leave new with good data. - state[k].swapTimeLevels(dt); - } - - // - // ls related - // fill the gts of old state data in the beginning - // - if (do_phi) { - // amrex::Print() << "1 " << std::endl; - const Real prev_time = state[State_Type].prevTime(); - MultiFab& S_old = get_old_data(State_Type); - int nScomp = S_old.nComp(); - fill_allgts(S_old,State_Type,0,nScomp,prev_time); - } - - make_rho_prev_time(); - - // - // ls related - // update the rho_ptime - // - if (do_phi) { - // amrex::Print() << "2 " << std::endl; - MultiFab& S_old = get_old_data(State_Type); - MultiFab::Copy(phi_ptime, S_old, phicomp, 0, 1, S_old.nGrow()); - phi_to_heavi(geom, epsilon, phi_ptime, heaviside); - heavi_to_rhoormu(heaviside, rho_w, rho_a, rho_ptime); - MultiFab::Copy(S_old, rho_ptime, 0, Density, 1, rho_ptime.nGrow()); - - MultiFab outmf_mu_ptime(grids, dmap, 1, 1, MFInfo(), Factory()); - heavi_to_rhoormu(heaviside, mu_w, mu_a, outmf_mu_ptime); - MultiFab::Copy(*viscn_cc, outmf_mu_ptime, 0, 0, 1, 1); - } - - // refRatio==4 is not currently supported - // - // If refRatio==4 to the next level coarser, and we're going to diffuse - // scalars as SoverRho, we're going to need rho at 1/4 and 3/4 time there. - // Make these things if need be. - // - // if (level > 0) - // { - // bool needs_rho4 = false; - - // if (parent->nCycle(level) == 4) - // for (int i = 0; i < NUM_STATE && !needs_rho4; ++i) - // needs_rho4 = (diffusionType[i] == Laplacian_SoverRho); - - // if (needs_rho4) - // { - // NavierStokesBase& clevel = getLevel(level-1); - // const BoxArray& cgrids = clevel.boxArray(); - // const DistributionMapping& cdmap = clevel.DistributionMap(); - // const Real ptime = clevel.state[State_Type].prevTime(); - // const Real ctime = clevel.state[State_Type].curTime(); - - // if (clevel.rho_qtime == 0) - // { - // const Real qtime = ptime + 0.25*(ctime-ptime); - // clevel.rho_qtime = new MultiFab(cgrids,cdmap,1,1); - // FillPatch(clevel,*(clevel.rho_qtime),1,qtime,State_Type,Density,1,0); - // } - // if (clevel.rho_tqtime == 0) - // { - // const Real tqtime = ptime + 0.75*(ctime-ptime); - // clevel.rho_tqtime = new MultiFab(cgrids,cdmap,1,1); - // FillPatch(clevel, *(clevel.rho_tqtime), 1, tqtime, State_Type, Density, 1, 0); - // } - // } - // } -} - -// -// Clean up after the advance function. -// -void -NavierStokesBase::advance_cleanup (int /*iteration*/, int /*ncycle*/) -{ - delete aofs; - aofs = nullptr; -} - -void -NavierStokesBase::buildMetrics () -{ - // - // We "should" only need radius when we're RZ, but some 2-D code is written to - // access it first and then "use" if if RZ. It's easier to just always build - // it for 2D than try to fix the underlying Fortran calls that take radius. - // -#if (AMREX_SPACEDIM == 2) - radius.resize(grids.size()); - - const Real dxr = geom.CellSize()[0]; - - for (int i = 0; i < grids.size(); i++) - { - const int ilo = grids[i].smallEnd(0)-radius_grow; - const int ihi = grids[i].bigEnd(0)+radius_grow; - const int len = ihi - ilo + 1; - - radius[i].resize(len); - - RealBox gridloc = RealBox(grids[i],geom.CellSize(),geom.ProbLo()); - - const Real xlo = gridloc.lo(0) + (0.5 - radius_grow)*dxr; - for (int j = 0; j < len; j++) { - radius[i][j] = xlo + j*dxr; - } - } -#endif - - // volume and area are intentionally without EB knowledge - volume.clear(); - volume.define(grids,dmap,1,GEOM_GROW); - geom.GetVolume(volume); - - for (int dir = 0; dir < AMREX_SPACEDIM; ++dir) - { - area[dir].clear(); - area[dir].define(getEdgeBoxArray(dir),dmap,1,GEOM_GROW); - geom.GetFaceArea(area[dir],dir); - } - -#ifdef AMREX_USE_EB - // make sure dx == dy == dz - const Real* dx = geom.CellSize(); - for (int i = 1; i < AMREX_SPACEDIM; i++){ - if (std::abs(dx[i]-dx[i-1]) > 1.e-12*dx[0]){ - Print()<<"dx = " - <(Factory()); - volfrac = &(ebfactory.getVolFrac()); - areafrac = ebfactory.getAreaFrac(); - -#endif -} - -// -// Default dSdt is set to zero. -// -void -NavierStokesBase::calc_dsdt (Real /*time*/, - Real dt, - MultiFab& dsdt) -{ - if (have_divu && have_dsdt) - { - // Don't think we need this here. Instead, code will use FillPatch to - // fill ghosts. - //dsdt.setVal(0); - - if (do_temp) { - MultiFab& Divu_new = get_new_data(Divu_Type); - MultiFab& Divu_old = get_old_data(Divu_Type); -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(dsdt,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - auto const& div_new = Divu_new.array(mfi); - auto const& div_old = Divu_old.array(mfi); - auto const& dsdtarr = dsdt.array(mfi); - - amrex::ParallelFor(bx, [div_new, div_old, dsdtarr, dt] - AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - dsdtarr(i,j,k) = ( div_new(i,j,k) - div_old(i,j,k) )/ dt; - }); - } - } - else - { - dsdt.setVal(0); - } - } -} - -void -NavierStokesBase::checkPoint (const std::string& dir, - std::ostream& os, - VisMF::How how, - bool dump_old) -{ - AmrLevel::checkPoint(dir, os, how, dump_old); - - if (avg_interval > 0) - { - VisMF::IO_Buffer io_buffer(VisMF::IO_Buffer_Size); - - if (ParallelDescriptor::IOProcessor()) - { - std::ofstream TImeAverageFile; - TImeAverageFile.rdbuf()->pubsetbuf(io_buffer.dataPtr(), io_buffer.size()); - std::string TAFileName(dir + "/TimeAverage"); - TImeAverageFile.open(TAFileName.c_str(), std::ofstream::out | - std::ofstream::trunc | - std::ofstream::binary); - - if( !TImeAverageFile.good()) { - amrex::FileOpenFailed(TAFileName); - } - - TImeAverageFile.precision(17); - - // write out title line - TImeAverageFile << "Writing time_average to checkpoint\n"; - - TImeAverageFile << NavierStokesBase::time_avg[level] << "\n"; - TImeAverageFile << NavierStokesBase::time_avg_fluct[level] << "\n"; - } - } - -#ifdef AMREX_PARTICLES - if (level == 0) - { - if (NSPC != 0) - NSPC->Checkpoint(dir,the_ns_particle_file_name); - } -#endif -} - -void -NavierStokesBase::computeInitialDt (int finest_level, - int /*sub_cycle*/, - Vector& n_cycle, - const Vector& /*ref_ratio*/, - Vector& dt_level, - Real stop_time) -{ - // - // Grids have been constructed, compute dt for all levels. - // - if (level > 0) - return; - - int i; - - Real dt_0 = 1.0e+100; - int n_factor = 1; - ///TODO/DEBUG: This will need to change for optimal subcycling. - for (i = 0; i <= finest_level; i++) - { - dt_level[i] = getLevel(i).initialTimeStep(); - n_factor *= n_cycle[i]; - dt_0 = std::min(dt_0,n_factor*dt_level[i]); - } - - // - // Limit dt's by the value of stop_time. - // - if (stop_time >= 0.0) - { - const Real eps = 0.0001*dt_0; - const Real cur_time = state[State_Type].curTime(); - if ((cur_time + dt_0) > (stop_time - eps)) - dt_0 = stop_time - cur_time; - } - - n_factor = 1; - for (i = 0; i <= finest_level; i++) - { - n_factor *= n_cycle[i]; - dt_level[i] = dt_0/( (Real)n_factor ); - } -} - -void -NavierStokesBase::computeNewDt (int finest_level, - int /*sub_cycle*/, - Vector& n_cycle, - const Vector& /*ref_ratio*/, - Vector& dt_min, - Vector& dt_level, - Real stop_time, - int post_regrid_flag) -{ - // - // We are at the start of a coarse grid timecycle. - // Compute the timesteps for the next iteration. - // - if (level > 0) - return; - - int i; - - Real dt_0 = 1.0e+100; - int n_factor = 1; - for (i = 0; i <= finest_level; i++) - { - NavierStokesBase& adv_level = getLevel(i); - dt_min[i] = std::min(dt_min[i],adv_level.estTimeStep()); - } - - if (fixed_dt <= 0.0) - { - if (post_regrid_flag == 1) - { - // - // Limit dt's by pre-regrid dt - // - for (i = 0; i <= finest_level; i++) - { - dt_min[i] = std::min(dt_min[i],dt_level[i]); - } - } - else - { - // - // Limit dt's by change_max * old dt - // - for (i = 0; i <= finest_level; i++) - { - if (verbose) - if (dt_min[i] > change_max*dt_level[i]) - { - amrex::Print() << "NavierStokesBase::compute_new_dt : limiting dt at level " - << i << '\n'; - amrex::Print() << " ... new dt computed: " << dt_min[i] - << '\n'; - amrex::Print() << " ... but limiting to: " - << change_max * dt_level[i] << " = " << change_max - << " * " << dt_level[i] << '\n'; - } - dt_min[i] = std::min(dt_min[i],change_max*dt_level[i]); - } - } - } - - // - // Find the minimum over all levels - // - for (i = 0; i <= finest_level; i++) - { - n_factor *= n_cycle[i]; - dt_0 = std::min(dt_0,n_factor*dt_min[i]); - } - - // - // Limit dt's by the value of stop_time. - // - const Real eps = 0.0001*dt_0; - const Real cur_time = state[State_Type].curTime(); - if (stop_time >= 0.0) - { - if ((cur_time + dt_0) > (stop_time - eps)) - dt_0 = stop_time - cur_time; - } - - // - // Set dt at each level of refinement - // - n_factor = 1; - for (i = 0; i <= finest_level; i++) - { - n_factor *= n_cycle[i]; - dt_level[i] = dt_0/( (Real)n_factor ); - } -} - -void -NavierStokesBase::create_mac_rhs (MultiFab& rhs, int nGrow, Real time, Real dt) -{ - BL_PROFILE("NavierStokesBase::create_mac_rhs()"); - - AMREX_ASSERT(rhs.nGrow()>=nGrow); - AMREX_ASSERT(rhs.boxArray()==grids); - - const int sCompDivU = 0; - const int nCompDivU = 1; - const int sCompDsdt = 0; - const int nCompDsdt = 1; - - if (have_divu) - { - FillPatch(*this,rhs,nGrow,time,Divu_Type,sCompDivU,nCompDivU,sCompDivU); - } - else - { - rhs.setVal(0.); - } - - if (have_dsdt) - { - FillPatchIterator fpi(*this,rhs,nGrow,time,Dsdt_Type,sCompDsdt,nCompDsdt); - const MultiFab& mf = fpi.get_mf(); - MultiFab::Saxpy(rhs, 0.5*dt, mf, 0, sCompDsdt, nCompDsdt, nGrow); - } -} - -void -NavierStokesBase::create_umac_grown (int nGrow, - const MultiFab* a_divu) -{ - if ( nGrow <= 0 ) { return; } - if ( nGrow > 1 ) { Print()<<"\n\nWARNING!\n NSB::create_umac_grown currently only enforces the divergnece constraint on 1 ghost cell, but nGrow > 1\n\n"; } - - - Array u_mac_fine; - AMREX_D_TERM(u_mac_fine[0] = &u_mac[0];, - u_mac_fine[1] = &u_mac[1];, - u_mac_fine[2] = &u_mac[2];); - - Geometry *fine_geom = &geom; - - //Grab the velocity phys bc fill function from the StateData StateDescriptor - AMREX_D_TERM(StateDataPhysBCFunct fine_bndry_func_x(get_state_data(State_Type),0,geom);, - StateDataPhysBCFunct fine_bndry_func_y(get_state_data(State_Type),1,geom);, - StateDataPhysBCFunct fine_bndry_func_z(get_state_data(State_Type),2,geom);); - - Array fbndyFuncArr = {AMREX_D_DECL(fine_bndry_func_x, - fine_bndry_func_y, - fine_bndry_func_z)}; - - - if ( level == 0 ) - { - for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) - { - // - // BDS needs physical BCs filled. - // Godunov needs periodic and coarse-fine ghosts filled (and handles - // physical BCs internally). - // - Real fake_time = 0.; - amrex::FillPatchSingleLevel(u_mac[idim], IntVect(nGrow), fake_time, - {u_mac_fine[idim]}, {fake_time}, - 0, 0, 1, geom, - fbndyFuncArr[idim], 0); - } - } - else // level > 0 - { - Array u_mac_crse; - AMREX_D_TERM(u_mac_crse[0] = &getLevel(level-1).u_mac[0];, - u_mac_crse[1] = &getLevel(level-1).u_mac[1];, - u_mac_crse[2] = &getLevel(level-1).u_mac[2];); - - Geometry *crse_geom = &getLevel(level-1).geom; - - // - // First interpolate, ignoring divergence constraint. Then correct - // the 1-cell wide halo of ghosts cells we need to enforce the - // constraint. - // - - // Divergence preserving interp -- This is for case of MAC solve on - // composite grid; doesn't make sense to use it here. - //Interpolater* mapper = &face_divfree_interp; - // Use linear interpolation, which matches up with old create umac grown - Interpolater* mapper = &face_linear_interp; - - // This never actually gets used because the FaceLinear Interpolator doesn't use it. - // Inside FillPatchTwoLevels, it's only use is that it's passed to the interpolator. - // Fill it with the correct thing anyway. - Array,AMREX_SPACEDIM> bcrecArr = {AMREX_D_DECL(m_bcrec_velocity, - m_bcrec_velocity, - m_bcrec_velocity)}; - Array bc_idx = {AMREX_D_DECL(0,1,2)}; - - // Grab the velocity phys bc fill function from the StateData StateDescriptor - // This will use the BCRec for velocity stored in the StateDescriptor - AMREX_D_TERM( - StateDataPhysBCFunct crse_bndry_func_x(getLevel(level-1).get_state_data(State_Type),0,*crse_geom);, - StateDataPhysBCFunct crse_bndry_func_y(getLevel(level-1).get_state_data(State_Type),1,*crse_geom);, - StateDataPhysBCFunct crse_bndry_func_z(getLevel(level-1).get_state_data(State_Type),2,*crse_geom);); - Array bf_idx = {AMREX_D_DECL(0,0,0)}; - - Array cbndyFuncArr = {AMREX_D_DECL(crse_bndry_func_x, - crse_bndry_func_y, - crse_bndry_func_z)}; - - // Use piecewise constant interpolation in time, so create fictitious variable for time - Real fake_time = 0.; - - FillPatchTwoLevels(u_mac_fine, IntVect(nGrow), fake_time, - {u_mac_crse}, {fake_time}, - {u_mac_fine}, {fake_time}, - 0, 0, 1, - *crse_geom, *fine_geom, - cbndyFuncArr, bf_idx, fbndyFuncArr, bf_idx, - crse_ratio, mapper, bcrecArr, bc_idx); - - // - // Correct u_mac to enforce the divergence constraint in the ghost cells. - // Do this by adjusting only the outer face (wrt the valid region) of the ghost - // cell, i.e. for the hi-x face, adjust umac_x(i+1). - // NOTE that this does not fill grid edges or corners. - // - - // Need 2 ghost cells here so we can safely check the status of all faces of a - // u_mac ghost cell - if (coarse_fine_mask == nullptr) { - coarse_fine_mask = std::make_unique(grids, dmap, 1, 2, MFInfo(), DefaultFabFactory()); - coarse_fine_mask->BuildMask(geom.Domain(), geom.periodicity(), - level_mask_covered, level_mask_notcovered, level_mask_physbnd, level_mask_interior); - } - - const GpuArray dx = fine_geom->CellSizeArray(); - const GpuArray dxinv = fine_geom->InvCellSizeArray(); - - const bool is_rz = geom.IsRZ(); - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(*coarse_fine_mask,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& tbx = mfi.tilebox(); - auto const& maskarr = coarse_fine_mask->const_array(mfi); - auto const& divu = (a_divu) ? a_divu->const_array(mfi) : Array4 {}; - auto const& umac = u_mac_fine[0]->array(mfi); - auto const& vmac = u_mac_fine[1]->array(mfi); - auto const& wmac = (AMREX_SPACEDIM==3) ? u_mac_fine[2]->array(mfi) : Array4 {}; - - const auto& vol = (is_rz) ? volume.const_array(mfi): Array4 {}; - const auto& ax = (is_rz) ? area[0].const_array(mfi): Array4 {}; - const auto& ay = (is_rz) ? area[1].const_array(mfi): Array4 {}; -#if (AMREX_SPACEDIM == 2) - int ks = 0; - int ke = 0; -#else - int ks = -1; - int ke = 1; -#endif - - AMREX_HOST_DEVICE_FOR_3D(mfi.growntilebox(1), i, j, k, - { - if ( maskarr(i,j,k) == level_mask_notcovered ) - { - // - // Leave cells on grid edges/corners unaltered. - // This correction scheme doesn't work for concave edges where a cell - // has faces that are all either valid or touching another ghost cell - // because then there's no "free" face to absorb the divergence constraint - // error. - // There are (>=) 1 case that are treatable, but we don't implement here: - // 1. Convex grid edges (cells that don't have any valid faces), e.g. by - // dividing the divergence constraint error equally between each face - // not touching another ghost cell - // - - int count = 0; - for(int kk(ks); kk<=ke; kk++) - { - for(int jj(-1); jj<=1; jj++) { - for(int ii(-1); ii<=1; ii++) { - if ( Math::abs(ii)+Math::abs(jj)+Math::abs(kk) == 1 && - (maskarr(i+ii,j+jj,k+kk) == interior || maskarr(i+ii,j+jj,k+kk) == level_mask_covered) ) - { - count++; - } - } - } - } - - if ( count == 1 ) - { - Real div = (divu) ? divu(i,j,k) : 0.0; - - if (is_rz) - { - Real dux = (ax(i+1,j,k)*umac(i+1,j,k) - ax(i,j,k)*umac(i,j,k)); - Real duy = (ay(i,j+1,k)*vmac(i,j+1,k) - ay(i,j,k)*vmac(i,j,k)); - - // To avoid inconsistencies between boxes, we make sure to fix box - // corners (2D) or edges (3D) that are not grid corners/edges. - // The directional check ensures we only alter one face of these - // cells. - // It's unlikely there'd ever be a case of such ghost cells abutting the - // symmetry axis, but just in case, check here. - if ( i < tbx.smallEnd(0) && maskarr(i+1,j,k) != level_mask_notcovered && ax(i,j,k) != Real(0.0) ) - { - umac(i,j,k) = (ax(i+1,j,k)*umac(i+1,j,k) + (duy - vol(i,j,k)*div))/ax(i,j,k); - } - else if ( i > tbx.bigEnd(0) && maskarr(i-1,j,k) != level_mask_notcovered ) - { - umac(i+1,j,k) = (ax(i,j,k)*umac(i,j,k) - (duy - vol(i,j,k)*div))/ax(i+1,j,k); - } - - if ( j < tbx.smallEnd(1) && maskarr(i,j+1,k) != level_mask_notcovered ) - { - vmac(i,j,k) = (ay(i,j+1,k)*vmac(i,j+1,k) + (dux - vol(i,j,k)*div))/ay(i,j,k); - } - else if ( j > tbx.bigEnd(1) && maskarr(i,j-1,k) != level_mask_notcovered ) - { - vmac(i,j+1,k) = (ay(i,j,k)*vmac(i,j,k) - (dux - vol(i,j,k)*div))/ay(i,j+1,k); - } - } - else - { - Real dux = dxinv[0]*(umac(i+1,j,k) - umac(i,j,k)); - Real duy = dxinv[1]*(vmac(i,j+1,k) - vmac(i,j,k)); - Real duz = (wmac) ? dxinv[2]*(wmac(i,j,k+1) - wmac(i,j,k)) : 0.0; - - // To avoid inconsistencies between boxes, we make sure to fix box - // corners (2D) or edges (3D) that are not grid corners/edges. - // The directional check ensures we only alter one face of these - // cells. - if ( i < tbx.smallEnd(0) && maskarr(i+1,j,k) != level_mask_notcovered ) - { - umac(i,j,k) = umac(i+1,j,k) + dx[0] * (duy + duz - div); - } - else if ( i > tbx.bigEnd(0) && maskarr(i-1,j,k) != level_mask_notcovered ) - { - umac(i+1,j,k) = umac(i,j,k) - dx[0] * (duy + duz - div); - } - - if ( j < tbx.smallEnd(1) && maskarr(i,j+1,k) != level_mask_notcovered ) - { - vmac(i,j,k) = vmac(i,j+1,k) + dx[1] * (dux + duz - div); - } - else if ( j > tbx.bigEnd(1) && maskarr(i,j-1,k) != level_mask_notcovered ) - { - vmac(i,j+1,k) = vmac(i,j,k) - dx[1] * (dux + duz - div); - } - - if (wmac) - { - if ( k < tbx.smallEnd(2) && maskarr(i,j,k+1) != level_mask_notcovered ) - { - wmac(i,j,k) = wmac(i,j,k+1) + dx[2] * (dux + duy - div); - } - else if ( k > tbx.bigEnd(2) && maskarr(i,j,k-1) != level_mask_notcovered ) - { - wmac(i,j,k+1) = wmac(i,j,k) - dx[2] * (dux + duy - div); - } - } - } - } - } - }); - } - } -} - -void -NavierStokesBase::diffuse_scalar_setup (int sigma, int& rho_flag) -{ - rho_flag = Diffusion::set_rho_flag(diffusionType[sigma]); -} - -void -NavierStokesBase::errorEst (TagBoxArray& tb, - int /*clearval*/, - int /*tagval*/, - Real /*time*/, - int /*n_error_buf*/, - int /*ngrow*/) -{ -#ifdef AMREX_USE_EB - // Enforce that the EB not cross the coarse-fine boundary - const auto& ebfactory = dynamic_cast(Factory()); - if ( !ebfactory.isAllRegular() ) - { - if (!refine_cutcells) { - amrex::Warning("Partially refined EB is still under development. This is not guaranteed to work! Please use ns.refine_cutcells=1 for now."); - } - - // Refine on cut cells - if (refine_cutcells) - { - const MultiFab& S_new = get_new_data(State_Type); - amrex::TagCutCells(tb, S_new); - } - } -#else - amrex::ignore_unused(tb); -#endif -} - - -// -// Estimate the maximum allowable timestep at a cell center. -// -Real -NavierStokesBase::estTimeStep () -{ - BL_PROFILE("NavierStokesBase::estTimeStep()"); - - if (fixed_dt > 0.0) - { - Real factor = 1.0; - - if (!(level == 0)) - { - int ratio = 1; - for (int lev = 1; lev <= level; lev++) - { - ratio *= parent->nCycle(lev); - } - factor = 1.0/Real(ratio); - } - - return factor*fixed_dt; - } - - const Real small = 1.0e-8; - Real estdt = 1.0e+20; - - MultiFab& S_new = get_new_data(State_Type); - - Vector u_max(AMREX_SPACEDIM); - Vector f_max(AMREX_SPACEDIM); - - MultiFab& Gp = get_new_data(Gradp_Type); - - // - // Find local max of velocity - // - u_max = S_new.norm0({AMREX_D_DECL(0,1,2)},0,true,true); - - // - // Compute forcing terms: in this case this means external forces and grad(p) - // Viscous terms not included since Crack-Nicholson is unconditionally stable - // so no need to account for explicit part of viscous term - // - MultiFab tforces(grids,dmap,AMREX_SPACEDIM,0,MFInfo(),Factory()); - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(S_new,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const auto& bx = mfi.tilebox(); - const auto cur_time = state[State_Type].curTime(); - auto& tforces_fab = tforces[mfi]; - - if (getForceVerbose) { - amrex::Print() << "---" << '\n' - << "H - est Time Step:" << '\n' - << "Calling getForce..." << '\n'; - } - getForce(tforces_fab,bx,0,AMREX_SPACEDIM,cur_time,S_new[mfi],S_new[mfi],Density,mfi); - - const auto& rho = S_new.array(mfi,Density); - const auto& gradp = Gp.array(mfi); - const auto& force = tforces.array(mfi); - amrex::ParallelFor(bx, [rho, gradp, force] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - Real rho_inv = 1.0/rho(i,j,k); - for (int n = 0; n < AMREX_SPACEDIM; n++) { - force(i,j,k,n) -= gradp(i,j,k,n); - force(i,j,k,n) *= rho_inv; - } - }); - } - - // - // Find local max of tforces - // - f_max = tforces.norm0({AMREX_D_DECL(0,1,2)},0,true,true); - - // - // Compute local estdt - // - const Real* dx = geom.CellSize(); - - for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) - { - if (u_max[idim] > small) - { - estdt = std::min(estdt, dx[idim]/u_max[idim]); - } - - if (f_max[idim] > small) - { - estdt = std::min(estdt, std::sqrt(2.0*dx[idim]/f_max[idim])); - } - } - - // - // Reduce estimated dt by CFL factor and find global min - // - ParallelDescriptor::ReduceRealMin(estdt); - - if ( estdt < 1.0e+20) { - // - // timestep estimation successful - // - estdt = estdt * cfl; - } - else if (init_dt > 0 ) { - // - // use init_dt, scale for amr level - // - Real factor = 1.0; - - if (!(level == 0)) - { - int ratio = 1; - for (int lev = 1; lev <= level; lev++) - { - ratio *= parent->nCycle(lev); - } - factor = 1.0/Real(ratio); - } - - estdt = factor*init_dt; - } else { - Print()<<"\nNavierStokesBase::estTimeStep() failed to provide a good timestep " - <<"(probably because initial velocity field is zero with no external forcing).\n" - <<"Use ns.init_dt to provide a reasonable timestep on coarsest level.\n" - <<"Note that ns.init_shrink will be applied to init_dt."<setVal(0); - } - else - { - divu = getState(ngrow,Divu_Type,0,1,time); - } - - return divu; -} - -// -// Fill patch dSdt. -// -MultiFab* -NavierStokesBase::getDsdt (int ngrow, Real time) -{ - MultiFab* dsdt = nullptr; - - if (!(have_dsdt && have_divu)) - { - dsdt = new MultiFab(grids,dmap,1,ngrow,MFInfo(),Factory()); - - dsdt->setVal(0); - } - else - { - dsdt = getState(ngrow,Dsdt_Type,0,1,time); - } - - return dsdt; -} - -// -// Fill patch a state component. -// -MultiFab* -NavierStokesBase::getState (int ngrow, - int state_indx, - int strt_comp, - int num_comp, - Real time) -{ - BL_PROFILE("NavierStokesBase::getState()"); - - auto* mf = new MultiFab(state[state_indx].boxArray(), - state[state_indx].DistributionMap(), - num_comp,ngrow,MFInfo(),Factory()); - - FillPatch(*this,*mf,ngrow,time,state_indx,strt_comp,num_comp,0); - - return mf; -} - -void -NavierStokesBase::getOutFlowFaces (Vector& outFaces) -{ - outFaces.resize(0); - for (int idir = 0; idir < AMREX_SPACEDIM; idir++) - { - if (phys_bc.lo(idir) == PhysBCType::outflow) - { - auto len = outFaces.size(); - outFaces.resize(len+1); - outFaces[len] = Orientation(idir,Orientation::low); - } - - if (phys_bc.hi(idir) == PhysBCType::outflow) - { - auto len = outFaces.size(); - outFaces.resize(len+1); - outFaces[len] = Orientation(idir,Orientation::high); - } - } -} - -void -NavierStokesBase::incrPAvg () -{ - // - // Increment p_avg with 1/ncycle times current pressure - // - MultiFab& P_new = get_new_data(Press_Type); - - Real alpha = 1.0/Real(parent->nCycle(level)); - - MultiFab::Saxpy(p_avg,alpha,P_new,0,0,1,0); -} - -void -NavierStokesBase::initRhoAvg (Real alpha) -{ - const MultiFab& S_new = get_new_data(State_Type); - - // Set to a ridiculous number just for debugging -- shouldn't need this otherwise - rho_avg.setVal(1.e200); - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(rho_avg,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - auto const& rhoavg = rho_avg.array(mfi); - auto const& rho_new = S_new.array(mfi,Density); - amrex::ParallelFor(bx, [rhoavg,rho_new,alpha] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - rhoavg(i,j,k) = rho_new(i,j,k) * alpha; - }); - } -} - -void -NavierStokesBase::incrRhoAvg(const MultiFab& rho_incr, - int sComp, - Real alpha) -{ - MultiFab::Saxpy(rho_avg,alpha,rho_incr,sComp,0,1,0); -} - -void -NavierStokesBase::incrRhoAvg (Real alpha) -{ - const MultiFab& S_new = get_new_data(State_Type); - incrRhoAvg(S_new,Density,alpha); -} - -// -// Fills a new level n with best level n and coarser data available. -// -void -NavierStokesBase::init (AmrLevel &old) -{ - auto* oldns = dynamic_cast(&old); - const Real dt_new = parent->dtLevel(level); - const Real cur_time = oldns->state[State_Type].curTime(); - const Real prev_time = oldns->state[State_Type].prevTime(); - const Real dt_old = cur_time - prev_time; - MultiFab& S_new = get_new_data(State_Type); - MultiFab& P_new = get_new_data(Press_Type); - MultiFab& Gp_new = get_new_data(Gradp_Type); - - setTimeLevel(cur_time,dt_old,dt_new); - - const Real cur_pres_time = state[Press_Type].curTime(); - // - // Get best state and pressure data. - // - FillPatch(old,S_new,0,cur_time,State_Type,0,NUM_STATE); - FillPatch(old,P_new,0,cur_pres_time,Press_Type,0,1); - FillPatch(old,Gp_new,Gp_new.nGrow(),cur_pres_time,Gradp_Type,0,AMREX_SPACEDIM); - - if (avg_interval > 0){ - MultiFab& Save_new = get_new_data(Average_Type); - FillPatch(old,Save_new,0,cur_time,Average_Type,0,AMREX_SPACEDIM*2); - } - - // - // Get best divu and dSdt data. - // - if (have_divu) - { - MultiFab& Divu_new = get_new_data(Divu_Type); - FillPatch(old,Divu_new,0,cur_time,Divu_Type,0,1); - - if (have_dsdt) - { - MultiFab& Dsdt_new = get_new_data(Dsdt_Type); - FillPatch(old,Dsdt_new,0,cur_time,Dsdt_Type,0,1); - } - } -} - -// -// Fills a totally new level n with data interpolated from coarser level. -// -void -NavierStokesBase::init () -{ - MultiFab& S_new = get_new_data(State_Type); - MultiFab& P_new = get_new_data(Press_Type); - MultiFab& Gp_new = get_new_data(Gradp_Type); - - AMREX_ASSERT(level > 0); - - const Vector& dt_amr = parent->dtLevel(); - Vector dt_new(level+1); - - for (int lev = 0; lev < level; lev++) { - dt_new[lev] = dt_amr[lev]; - } - // - // Guess new dt from new data (interpolated from coarser level). - // - const Real dt = dt_new[level-1]/Real(parent->MaxRefRatio(level-1)); - dt_new[level] = dt; - - parent->setDtLevel(dt_new); - // - // Compute dt based on old data. - // - NavierStokesBase& old = getLevel(level-1); - const Real cur_time = old.state[State_Type].curTime(); - const Real prev_time = old.state[State_Type].prevTime(); - const Real dt_old = (cur_time-prev_time)/Real(parent->MaxRefRatio(level-1)); - - setTimeLevel(cur_time,dt_old,dt); - - Real cur_pres_time = state[Press_Type].curTime(); - // - // Get best coarse state and pressure data. - // - FillCoarsePatch(S_new,0,cur_time,State_Type,0,NUM_STATE); - FillCoarsePatch(P_new,0,cur_pres_time,Press_Type,0,1); - FillCoarsePatch(Gp_new,0,cur_pres_time,Gradp_Type,0,AMREX_SPACEDIM,Gp_new.nGrow()); - // - // Get best coarse divU and dSdt data. - // - if (have_divu) - { - FillCoarsePatch(get_new_data(Divu_Type),0,cur_time,Divu_Type,0,1); - if (have_dsdt) - FillCoarsePatch(get_new_data(Dsdt_Type),0,cur_time,Dsdt_Type,0,1); - } -} - -void -NavierStokesBase::init_additional_state_types () -{ - additional_state_types_initialized = 1; - // - // Set "Temp" from user's variable setup. - // - int dummy_State_Type; - int have_temp = isStateVariable("temp", dummy_State_Type, Temp); - have_temp &= (dummy_State_Type == State_Type); - amrex::ignore_unused(have_temp); - AMREX_ASSERT((do_temp && have_temp) || (!do_temp && !have_temp)); - - int i_Divu = -1; - int dummy_Divu_Type; - have_divu = 0; - have_divu = isStateVariable("divu", dummy_Divu_Type, i_Divu); - have_divu = have_divu && dummy_Divu_Type == Divu_Type; - if (verbose) - { - amrex::Print() << "NavierStokesBase::init_additional_state_types()::have_divu = " - << have_divu << '\n'; - } - if (have_divu && i_Divu!=Divu) - { - amrex::Print() << "divu must be 0-th Divu_Type component in the state\n"; - amrex::Abort("NavierStokesBase::init_additional_state_types()"); - } - - int i_Dsdt = -1; - int dummy_Dsdt_Type; - have_dsdt = 0; - have_dsdt = isStateVariable("dsdt", dummy_Dsdt_Type, i_Dsdt); - have_dsdt = have_dsdt && dummy_Dsdt_Type==Dsdt_Type; - if (verbose) - { - amrex::Print() << "NavierStokesBase::init_additional_state_types()::have_dsdt = " - << have_dsdt << '\n'; - } - if (have_dsdt && i_Dsdt!=Dsdt) - { - amrex::Print() << "dsdt must be 0-th Dsdt_Type component in the state\n"; - amrex::Abort("NavierStokesBase::init_additional_state_types()"); - } - if (have_dsdt && !have_divu) - { - amrex::Print() << "Must have divu in order to have dsdt\n"; - amrex::Abort("NavierStokesBase::init_additional_state_types()"); - } - - num_state_type = desc_lst.size(); - if (verbose && ParallelDescriptor::IOProcessor()) - { - amrex::Print() << "NavierStokesBase::init_additional_state_types: num_state_type = " - << num_state_type << '\n'; - } -} - -Real -NavierStokesBase::initialTimeStep () -{ - Real returnDt = init_shrink*estTimeStep(); - - if (verbose) amrex::Print() << "Multiplying dt by init_shrink: dt = " - << returnDt << '\n'; - return returnDt; -} - -// -// Since the pressure solver always stores its estimate of the -// pressure solver in Pnew, we need to copy it to Pold at the start. -// -void -NavierStokesBase::initOldFromNew (int type, int lev) -{ - if ( lev < 0 ) { - lev = level; - } - - MultiFab& new_t = getLevel(lev).get_new_data(type); - MultiFab& old_t = getLevel(lev).get_old_data(type); - - MultiFab::Copy(old_t, new_t, 0, 0, old_t.nComp(), old_t.nGrow()); -} - -void -NavierStokesBase::level_projector (Real dt, - Real time, - int iteration) -{ - BL_PROFILE_REGION_START("R::NavierStokesBase::level_projector()"); - BL_PROFILE("NavierStokesBase::level_projector()"); - - AMREX_ASSERT(iteration > 0); - - MultiFab& U_old = get_old_data(State_Type); - MultiFab& U_new = get_new_data(State_Type); - MultiFab& P_old = get_old_data(Press_Type); - MultiFab& P_new = get_new_data(Press_Type); - - SyncRegister* crse_ptr = nullptr; - - if (level < parent->finestLevel() && do_sync_proj) - { - crse_ptr = &(getLevel(level+1).getSyncReg()); - } - - int crse_dt_ratio = (level > 0) ? parent->nCycle(level) : -1; - const Real cur_pres_time = state[Press_Type].curTime(); - - projector->level_project(level,time,dt,cur_pres_time, - geom,U_old,U_new,P_old,P_new, - get_rho_half_time(),crse_ptr,sync_reg, - crse_dt_ratio,iteration,have_divu); - - BL_PROFILE_REGION_STOP("R::NavierStokesBase::level_projector()"); -} - -void -NavierStokesBase::level_sync (int crse_iteration) -{ - BL_PROFILE_REGION_START("R::NavierStokesBase::level_sync()"); - BL_PROFILE("NavierStokesBase::level_sync()"); - - IntVect ratio = parent->refRatio(level); - const int finest_level = parent->finestLevel(); - int crse_dt_ratio = parent->nCycle(level); - Real dt = parent->dtLevel(level); - MultiFab& pres = get_new_data(Press_Type); - MultiFab& vel = get_new_data(State_Type); - SyncRegister& rhs_sync_reg = getLevel(level+1).getSyncReg(); - SyncRegister* crsr_sync_ptr = nullptr; - NavierStokesBase& fine_level = getLevel(level+1); - MultiFab& pres_fine = fine_level.get_new_data(Press_Type); - MultiFab& vel_fine = fine_level.get_new_data(State_Type); - const BoxArray& finegrids = vel_fine.boxArray(); - const DistributionMapping& finedmap = vel_fine.DistributionMap(); - - if (level > 0) { - crsr_sync_ptr = &(getLevel(level).getSyncReg()); - } - // - // Get boundary conditions. - // - const auto N = int(grids.size()); - - Vector sync_bc(N); - Vector< Vector > sync_bc_array(N); - - for (int i = 0; i < N; i++) - { - sync_bc_array[i] = getBCArray(State_Type,i,Xvel,AMREX_SPACEDIM); - sync_bc[i] = sync_bc_array[i].dataPtr(); - } - - // - // Multilevel sync projection. - // - MultiFab& Rh = get_rho_half_time(); - MultiFab cc_rhs_crse, cc_rhs_fine; - - cc_rhs_crse.define( grids, dmap,1,1,MFInfo(), Factory()); - cc_rhs_fine.define(finegrids,finedmap,1,1,MFInfo(),fine_level.Factory()); - cc_rhs_crse.setVal(0); - cc_rhs_fine.setVal(0); - - MultiFab& v_fine = fine_level.get_new_data(State_Type); - MultiFab& rho_fine = fine_level.rho_avg; - const Geometry& crse_geom = parent->Geom(level); - const BoxArray& P_finegrids = pres_fine.boxArray(); - const DistributionMapping& P_finedmap = pres_fine.DistributionMap(); - - MultiFab phi(P_finegrids,P_finedmap,1,1,MFInfo(),fine_level.Factory()); - MultiFab V_corr(finegrids,finedmap,AMREX_SPACEDIM,1,MFInfo(),fine_level.Factory()); - - V_corr.setVal(0); - // - // If periodic, enforce periodicity on Vsync. - // - if (crse_geom.isAnyPeriodic()) { - Vsync.FillBoundary(0, AMREX_SPACEDIM, crse_geom.periodicity()); - } - // - // Interpolate Vsync to fine grid correction in Vcorr. - // - SyncInterp(Vsync, level, V_corr, level+1, ratio, - 0, 0, AMREX_SPACEDIM, 0 , dt, sync_bc.dataPtr()); - // - // The multilevel projection. This computes the projection and - // adds in its contribution to levels (level) and (level+1). - // - projector->MLsyncProject(level,pres,vel,cc_rhs_crse, - pres_fine,v_fine,cc_rhs_fine, - Rh,rho_fine,Vsync,V_corr, - phi,&rhs_sync_reg,crsr_sync_ptr, - dt,ratio,crse_iteration,crse_dt_ratio, - geom); - cc_rhs_crse.clear(); - cc_rhs_fine.clear(); - // - // Correct pressure and velocities after the projection. - // - const auto Nf = int(finegrids.size()); - - ratio = IntVect::TheUnitVector(); - - Vector fine_sync_bc(Nf); - Vector< Vector > fine_sync_bc_array(Nf); - - for (int i = 0; i < Nf; i++) - { - fine_sync_bc_array[i] = getLevel(level+1).getBCArray(State_Type, - i, - Xvel, - AMREX_SPACEDIM); - fine_sync_bc[i] = fine_sync_bc_array[i].dataPtr(); - } - - for (int lev = level+2; lev <= finest_level; lev++) - { - ratio *= parent->refRatio(lev-1); - NavierStokesBase& flev = getLevel(lev); - MultiFab& P_new = flev.get_new_data(Press_Type); - MultiFab& P_old = flev.get_old_data(Press_Type); - MultiFab& U_new = flev.get_new_data(State_Type); - - SyncInterp(V_corr, level+1, U_new, lev, ratio, - 0, 0, AMREX_SPACEDIM, 1 , dt, fine_sync_bc.dataPtr()); - SyncProjInterp(phi, level+1, P_new, P_old, lev, ratio); - - flev.computeGradP(flev.state[Gradp_Type].prevTime()); - flev.computeGradP(flev.state[Gradp_Type].curTime()); - - } - - BL_PROFILE_REGION_STOP("R::NavierStokesBase::level_sync()"); -} - -void -NavierStokesBase::make_rho_prev_time () -{ - const Real prev_time = state[State_Type].prevTime(); - - FillPatch(*this,rho_ptime,1,prev_time,State_Type,Density,1,0); - -#ifdef AMREX_USE_EB - EB_set_covered(rho_ptime,COVERED_VAL); -#endif -} - -void -NavierStokesBase::make_rho_curr_time () -{ - const Real curr_time = state[State_Type].curTime(); - FillPatch(*this,rho_ctime,1,curr_time,State_Type,Density,1,0); - -#ifdef AMREX_USE_EB - EB_set_covered(rho_ctime,COVERED_VAL); -#endif -} - -void -NavierStokesBase::mac_project (Real time, - Real dt, - MultiFab& S_old, - MultiFab* divu, - int ngrow, - bool increment_vel_register) -{ - BL_PROFILE_REGION_START("R::NavierStokesBase::mac_project()"); - BL_PROFILE("NavierStokesBase::mac_project()"); - - if (verbose) { - amrex::Print() << "... mac_projection\n"; - } - - if (verbose && benchmarking) { - ParallelDescriptor::Barrier(); - } - - const Real strt_time = ParallelDescriptor::second(); - - Vector density_math_bc = fetchBCArray(State_Type,Density,1); - - mac_projector->mac_project(level,u_mac,S_old,dt,time,*divu,have_divu, - density_math_bc[0], increment_vel_register); - - create_umac_grown(ngrow, divu); - - if (verbose) - { - Real run_time = ParallelDescriptor::second() - strt_time; - const int IOProc = ParallelDescriptor::IOProcessorNumber(); - - ParallelDescriptor::ReduceRealMax(run_time,IOProc); - - amrex::Print() << "NavierStokesBase:mac_project(): lev: " - << level - << ", time: " << run_time << '\n'; - } - BL_PROFILE_REGION_STOP("R::NavierStokesBase::mac_project()"); -} - -void -NavierStokesBase::manual_tags_placement (TagBoxArray& tags, - const Vector& bf_lev) -{ - Vector outFaces; - getOutFlowFaces(outFaces); - if (! outFaces.empty()) - { - for (int i=0; inProper(); - // - // Calculate the number of level 0 cells to be left uncovered - // at the outflow. The convoluted logic allows for the fact that - // the number of uncovered cells must be a multiple of the level - // blocking factor. So, when calculating the number of coarse - // cells below, we always round the division up. - // - int N_coarse_cells = Nbuf_outflow / bf_lev[0][oDir]; - if (Nbuf_outflow % bf_lev[0][oDir] != 0) - N_coarse_cells++; - - int N_level_cells = N_coarse_cells * bf_lev[0][oDir]; - - // - // Adjust this to get the number of cells to be left uncovered at - // levels higher than 0 - // - for (int j = 1; j <= level; ++j) - { - /*** Calculate the minimum cells at this level ***/ - - const int rat = (parent->refRatio(j-1))[oDir]; - N_level_cells = N_level_cells * rat + np; - - /*** Calculate the required number of coarse cells ***/ - - N_coarse_cells = N_level_cells / bf_lev[j][oDir]; - if (N_level_cells % bf_lev[j][oDir] != 0) - N_coarse_cells++; - - /*** Calculate the corresponding number of level cells ***/ - - N_level_cells = N_coarse_cells * bf_lev[j][oDir]; - } - // - // Untag the cells near the outflow - // - if (N_coarse_cells > 0) - { - // - // Generate box at the outflow and grow it in all directions - // other than the outflow. This forces outflow cells in the - // ghostcells in directions other that oDir to be cleared. - // - Box outflowBox = amrex::adjCell(crse_domain, outFace, 1); - for (int dir = 0; dir < AMREX_SPACEDIM; dir++) - if (dir != oDir) outflowBox.grow(dir, 1); - // - // Now, grow the box into the domain (opposite direction as - // outFace) the number of cells we need to clear. - // - if (outFace.isLow()) - outflowBox.growHi(oDir, N_coarse_cells); - else - outflowBox.growLo(oDir, N_coarse_cells); - - tags.setVal(BoxArray(&outflowBox,1),TagBox::CLEAR); - } - } - } - } -} - -int -NavierStokesBase::okToContinue () -{ - // - // Check that dt is OK across AMR levels - // - int okLevel = (level > 0) ? true : (parent->dtLevel(0) > dt_cutoff); - - if (stop_when_steady) - // - // If stop_when_steady is enabled, also check that we haven't reached - // steady-state. - // - return (okLevel && !steadyState()); - else - return okLevel; -} - -int -NavierStokesBase::steadyState() -{ - if (!get_state_data(State_Type).hasOldData()) { - return false; // If nothing to compare to, must not yet be steady :) - } - - MultiFab& u_old = get_old_data(State_Type); - MultiFab& u_new = get_new_data(State_Type); - - // - // Estimate the maximum change in velocity magnitude since previous - // iteration - // - Real max_change = 0.0; - - ReduceOps reduce_op; - ReduceData reduce_data(reduce_op); - using ReduceTuple = typename decltype(reduce_data)::Type; - - // Do not OpenMP-fy this loop for now - // Unclear how to keep OpenMP and GPU implementation - // from messing with each other - for (MFIter mfi(u_old,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const auto& bx = mfi.tilebox(); - const auto& uold = u_old[mfi].array(); - const auto& unew = u_new[mfi].array(); - - reduce_op.eval(bx, reduce_data, [uold, unew] - AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple - { - Real uold_mag = 0.0; - Real unew_mag = 0.0; - for (int d = 0; d < AMREX_SPACEDIM; ++d) - { - uold_mag += uold(i,j,k,d)*uold(i,j,k,d); - unew_mag += unew(i,j,k,d)*unew(i,j,k,d); - } - - uold_mag = std::sqrt(uold_mag); - unew_mag = std::sqrt(unew_mag); - - return std::abs(unew_mag-uold_mag); - }); - - max_change = std::max(amrex::get<0>(reduce_data.value()), - max_change); - } - - ParallelDescriptor::ReduceRealMax(max_change); - - // - // System is classified as steady if the maximum change is smaller than - // prescribed tolerance - // - bool steady = max_change < steady_tol; - - if (verbose) - { - amrex::Print() << "steadyState :: \n" << "LEV = " << level - << " MAX_CHANGE = " << max_change << std::endl; - - if (steady) - { - amrex::Print() - << "System reached steady-state, stopping simulation." - << std::endl; - } - } - - return steady; -} - -// -// This function estimates the initial timesteping used by the model. -// -void -NavierStokesBase::post_init_estDT (Real& dt_init, - Vector& nc_save, - Vector& dt_save, - Real stop_time) -{ - const Real strt_time = state[State_Type].curTime(); - const int finest_level = parent->finestLevel(); - - dt_init = 1.0e+100; - - int n_factor; - for (int k = 0; k <= finest_level; k++) - { - nc_save[k] = parent->nCycle(k); - dt_save[k] = getLevel(k).initialTimeStep(); - - n_factor = 1; - for (int m = finest_level; m > k; m--) - n_factor *= parent->nCycle(m); - dt_init = std::min( dt_init, dt_save[k]/((Real) n_factor) ); - } - - Vector dt_level(finest_level+1,dt_init); - Vector n_cycle(finest_level+1,1); - - Real dt0 = dt_save[0]; - n_factor = 1; - for (int k = 0; k <= finest_level; k++) - { - n_factor *= nc_save[k]; - dt0 = std::min(dt0,n_factor*dt_save[k]); - } - - if (stop_time >= 0.0) - { - const Real eps = 0.0001*dt0; - if ((strt_time + dt0) > (stop_time - eps)) - dt0 = stop_time - strt_time; - } - - n_factor = 1; - for (int k = 0; k <= finest_level; k++) - { - n_factor *= nc_save[k]; - dt_save[k] = dt0/( (Real) n_factor); - } - // - // Hack. - // - parent->setDtLevel(dt_level); - parent->setNCycle(n_cycle); - for (int k = 0; k <= finest_level; k++) - { - getLevel(k).setTimeLevel(strt_time,dt_init,dt_init); - } -} - -// -// This function ensures that the state is initially consistent -// with respect to the divergence condition and fields are initially consistent -// -void -NavierStokesBase::post_init_state () -{ - const int finest_level = parent->finestLevel(); - const Real divu_time = have_divu ? state[Divu_Type].curTime() - : state[Press_Type].curTime(); - - if (do_init_vort_proj) - { - amrex::Abort("NavierStokesBase::post_init_state(): initialVorticityProject not tested with new Gradp!!! See comments Projection::initialVorticityProject.\n"); - // - // NOTE: this assumes have_divu == 0. - // Only used if vorticity is used to initialize the velocity field. - // - AMREX_ASSERT(projector != nullptr); - - if (verbose) amrex::Print() << "calling initialVorticityProject" << std::endl; - - projector->initialVorticityProject(0); - - if (verbose) amrex::Print() << "done calling initialVorticityProject" << std::endl; - } - - if (do_init_proj && projector) - { - // - // Do sync project to define divergence free velocity field. - // - if (verbose) amrex::Print() << "calling initialVelocityProject" << std::endl; - - projector->initialVelocityProject(0,divu_time,have_divu,init_vel_iter); - - if (verbose) amrex::Print() << "done calling initialVelocityProject" << std::endl; - } - - NavierStokesBase::initial_step = true; - // - // Average velocity and scalar data down from finer levels - // so that conserved data is consistent between levels. - // This might not be the most efficient way of doing things - // (since initialVelocityProject will average down vel, P and Gradp), - // but it does ensure everything is averaged down for all cases - // (e.g. initialVelocityProject doesn't get called or init_vel_iter<=0). - // - for (int k = finest_level-1; k>= 0; k--) - { - getLevel(k).avgDown(); - } - - if (do_init_proj && projector && (std::fabs(gravity)) > 0.){ - // - // Do projection to establish initially hydrostatic pressure field. - // - if (verbose) amrex::Print() << "calling initialPressureProject" << std::endl; - - projector->initialPressureProject(0); - - if (verbose) amrex::Print() << "done calling initialPressureProject" << std::endl; - } - // - // Make sure there's not NANs in old pressure field. - // End up with P_old = P_new as is the case when exiting initialPressureProject - // - if(!do_init_proj) - { - for (int k = finest_level; k>= 0; k--) - { - initOldFromNew(Press_Type, k); - initOldFromNew(Gradp_Type, k); - } - } -} - -// -// Build any additional data structures after regrid. -// -void -NavierStokesBase::post_regrid (int lbase, - int /*new_finest*/) -{ -#ifdef AMREX_PARTICLES - if (NSPC && level == lbase) - { - NSPC->Redistribute(lbase); - } -#else - amrex::ignore_unused(lbase); -#endif -} - -// -// Build any additional data structures after restart. -// -void -NavierStokesBase::post_restart () -{ - make_rho_prev_time(); - make_rho_curr_time(); - - if (avg_interval > 0){ - - const int finest_level = parent->finestLevel(); - NavierStokesBase::time_avg.resize(finest_level+1); - NavierStokesBase::time_avg_fluct.resize(finest_level+1); - NavierStokesBase::dt_avg.resize(finest_level+1); - - // - // We assume that if Average_Type is not present, we have just activated - // the start of averaging - // - if ( average_in_checkpoint==0 ) - { - Print()<<"WARNING! Average not found in checkpoint file. Creating data" - <theRestartFile(); - - std::string File(file + "/TimeAverage"); - Vector fileCharPtr; - ParallelDescriptor::ReadAndBcastFile(File, fileCharPtr); - std::string fileCharPtrString(fileCharPtr.dataPtr()); - std::istringstream isp(fileCharPtrString, std::istringstream::in); - - // read in title line - std::getline(isp, line); - - isp >> NavierStokesBase::time_avg[level]; - isp >> NavierStokesBase::time_avg_fluct[level]; - NavierStokesBase::dt_avg[level] = 0; - - } - } - -#ifdef AMREX_USE_TURBULENT_FORCING - // - // Initialize data structures used for homogeneous isentropic forced turbulence. - // Only need to do it once. - if (level == 0) - TurbulentForcing::init_turbulent_forcing(geom.ProbLoArray(),geom.ProbHiArray()); -#endif - -#ifdef AMREX_PARTICLES - post_restart_particle (); -#endif -} - -// -// Integration cycle on fine level grids is complete . -// post_timestep() is responsible for syncing levels together. -// -// The registers used for level syncing are initialized in the -// coarse level advance and incremented in the fine level advance. -// These quantities are described in comments above advance_setup. -// -void -NavierStokesBase::post_timestep (int crse_iteration) -{ - BL_PROFILE("NavierStokesBase::post_timestep()"); - - const int finest_level = parent->finestLevel(); - -#ifdef AMREX_PARTICLES - post_timestep_particle (crse_iteration); -#endif - - if (level == parent->finestLevel()) - { - delete [] u_mac; - u_mac = nullptr; - } - - if (do_reflux && level < finest_level) - reflux(); - - // - // Average everything down, including P and Gradp. - // Even though the multilevel projections average down, only - // single level projections have been done for current timestep. - // The linearity of the average ensures that if we average down P - // and Gp here, then we may simply add the incremental correction - // (which get averaged down in amrex) during the sync projection. - // - // avgDown also updates rho_ctime since it's needed for rho_half, - // which is used in the sync projection. - // - if (level < finest_level) - avgDown(); - - if (do_mac_proj && level < finest_level) - mac_sync(); - - // set Density to fluid_rho on all regions - if (do_diffused_ib) { - MultiFab& S_new = get_new_data(State_Type); - S_new.setVal(fluid_rho, Density, 1, S_new.nGrow()); - if (level < parent->finestLevel()) { - auto& fine_lev = getLevel(level+1); - MultiFab& S_fine = fine_lev.get_new_data(State_Type); - S_fine.setVal(fluid_rho, Density, 1, S_fine.nGrow()); - } - } - - if (do_sync_proj && (level < finest_level)) - level_sync(crse_iteration); - - - // - // Test for conservation. - // - if (level==0 && sum_interval>0 && (parent->levelSteps(0)%sum_interval == 0)) - { - sum_integrated_quantities(); - } - - if (level > 0) incrPAvg(); - - // Copy pvf to Tracer before writing Tracer into plt files on the finest level, - // or set Tracer to zero on the coarser/coarsest levels - if (do_diffused_ib) { - MultiFab& S_new = get_new_data(State_Type); - if (level == parent->finestLevel()) { - MultiFab::Copy(S_new, pvf, 0, Tracer, 1, pvf.nGrow()); // Note: the ghost cell region of pvf is zero. - } - else { - S_new.setVal(0.0, Tracer, 1, S_new.nGrow()); - // We need to average the Tracer here since we use it for refinement/de-refinement - auto& fine_lev = getLevel(level+1); - MultiFab& S_fine = fine_lev.get_new_data(State_Type); - average_down(S_fine, S_new, Tracer, 1); - } - } - - if (level == 0 && dump_plane >= 0) - { - Box bx = geom.Domain(); - - AMREX_ASSERT(bx.bigEnd(AMREX_SPACEDIM-1) >= dump_plane); - - bx.setSmall(AMREX_SPACEDIM-1, dump_plane); - bx.setBig (AMREX_SPACEDIM-1, dump_plane); - - BoxArray ba(bx); - DistributionMapping dm{ba}; - - MultiFab mf(ba, dm, AMREX_SPACEDIM, 0, MFInfo(), Factory()); - - mf.ParallelCopy(get_new_data(State_Type), Xvel, 0, AMREX_SPACEDIM); - - if (ParallelDescriptor::MyProc() == mf.DistributionMap()[0]) - { - char buf[64]; - sprintf(buf, "%14.12e", state[State_Type].curTime()); - - std::string name(dump_plane_name); - name += buf; - name += ".fab"; - - std::ofstream ofs; - ofs.open(name.c_str(),std::ios::out|std::ios::trunc|std::ios::binary); - if (!ofs.good()) - amrex::FileOpenFailed(name); - - mf[0].writeOn(ofs); - } - } - - if (avg_interval > 0) - { - const amrex::Real dt_level = parent->dtLevel(level); - time_average(time_avg[level], time_avg_fluct[level], dt_avg[level], dt_level); - } - -} - -// -// Reset the time levels to time (time) and timestep dt. -// This is done at the end of the timestep in the pressure iteration section. -// -void -NavierStokesBase::resetState (Real time, - Real dt_old, - Real dt_new) -{ - // - // Reset state types. - // - state[State_Type].reset(); - state[State_Type].setTimeLevel(time,dt_old,dt_new); - - // - // Set P & gradP old = new. This way we retain new after - // advance_setup() does swap(old,new). - // - initOldFromNew(Press_Type); - state[Press_Type].setTimeLevel(time-dt_old,dt_old,dt_new); - - initOldFromNew(Gradp_Type); - state[Gradp_Type].setTimeLevel(time-dt_old,dt_old,dt_new); - // - // Reset state types for divu not equal to zero. - // - if (have_divu) - { - state[Divu_Type].reset(); - state[Divu_Type].setTimeLevel(time,dt_old,dt_new); - if (have_dsdt) - { - // - // Dont do this, we want to improve dsdt with press iters - // but we do need to make sure time is set correctly.. - // state[Dsdt_Type].reset(); - state[Dsdt_Type].setTimeLevel(time,dt_old,dt_new); - } - } -} - -// -// Old checkpoint files may not have Gradp_Type and/or Average_Type. -// -void -NavierStokesBase::set_state_in_checkpoint (Vector& state_in_checkpoint) -{ - // - // Abort if any of the NSB::*_in_checkpoint variables haven't been set by user. - // - if ( gradp_in_checkpoint<0 || average_in_checkpoint<0 ) - Abort("\n\n Checkpoint file is missing one or more state types. Set both\n ns.gradp_in_checkpoint and ns.avg_in_checkpoint to identify missing\n data. Set to 1 if present in checkpoint, 0 if not present. If unsure,\n try setting both to 0.\n\n If you just activated Time Averaging, you should add \n ns.avg_in_checkpoint=0 ns.gradp_in_checkpoint=1 \n\n"); - - // - // Tell AmrLevel which types are in the checkpoint, so it knows what to copy. - // state_in_checkpoint is initialized to all true. - // - if ( gradp_in_checkpoint==0 ) - state_in_checkpoint[Gradp_Type] = 0; - - if ( average_in_checkpoint==0 && avg_interval>0 ) - state_in_checkpoint[Average_Type] = 0; -} - -void -NavierStokesBase::restart (Amr& papa, - std::istream& is, - bool bReadSpecial) -{ - Print()<<"\nWARNING! Note that you can't drop data from the checkpoint file.\n" - <<" If your checkpoint file contains Average_Type, then your inputs\n" - <<" must also specify ns.avg_interval>0.\n"<levelSteps(0)); - ParallelDescriptor::Barrier(); - } -#endif - - define_workspace(); -} - -void -NavierStokesBase::scalar_advection_update (Real dt, - int first_scalar, - int last_scalar) -{ - BL_PROFILE("NavierStokesBase::scalar_advection_update()"); - - MultiFab& S_old = get_old_data(State_Type); - MultiFab& S_new = get_new_data(State_Type); - MultiFab& Aofs = *aofs; - - const Real prev_time = state[State_Type].prevTime(); - - - // - // Compute inviscid estimate of scalars. - // Do rho separately, as rho does not have forcing terms and is always conservative. - // - int sComp = first_scalar; - - if (sComp == Density) - { -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(S_old,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - const auto& Snew = S_new[mfi].array(Density); - const auto& Sold = S_old[mfi].const_array(Density); - const auto& advc = Aofs[mfi].const_array(Density); - - amrex::ParallelFor(bx, [ Snew, Sold, advc, dt] - AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Snew(i,j,k) = Sold(i,j,k) - dt * advc(i,j,k); - }); - } - - // - // Call ScalMinMax to avoid overshoots in density. - // - if (do_denminmax) - { - // - // Must do FillPatch here instead of MF iterator because we need the - // boundary values in the old data (especially at inflow) - // - const int index_new_s = Density; - const int index_new_rho = Density; - const int index_old_s = index_new_s - Density; - const int index_old_rho = index_new_rho - Density; - - FillPatchIterator S_fpi(*this,S_old,1,prev_time,State_Type,Density,1); - MultiFab& Smf=S_fpi.get_mf(); - - ConservativeScalMinMax(S_new, index_new_s, index_new_rho, - Smf, index_old_s, index_old_rho); - - } - - ++sComp; - } - - // - // Advective update of other scalars - // - if (sComp <= last_scalar) - { - // - // Average mac face velocity to cell-centers for use in generating external - // forcing term in getForce() - // - // NOTE that default getForce() does not use Vel or Scal, user must supply the - // forcing function for that case. - // - MultiFab Vel(grids, dmap, AMREX_SPACEDIM, 0, MFInfo(), Factory()); -#ifdef AMREX_USE_EB - // This isn't quite right because it's face-centers to cell-centers - // what's really wanted is face-centroid to cell-centroid - EB_average_face_to_cellcenter(Vel, 0, Array{{AMREX_D_DECL(&u_mac[0],&u_mac[1],&u_mac[2])}}); -#else - average_face_to_cellcenter(Vel, 0, Array{{AMREX_D_DECL(&u_mac[0],&u_mac[1],&u_mac[2])}}); -#endif - -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - { - FArrayBox tforces; - - for (MFIter mfi(S_old,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - if (getForceVerbose) { - amrex::Print() << "---" << '\n' << "E - scalar advection update (half time):" << '\n'; - } - - // - // Create an estimate for time n+1 using advection term only; it's the best - // we've got at this point. Then, average the new and old time to get - // Crank-Nicholson half time approximation. - // - const Box& bx = mfi.tilebox(); - // getForce() expects all scalars to be present in Scal, and may need them - // (particularly density) to make forcing term. - FArrayBox Scal(bx,NUM_SCALARS); - // Scal protected from early destruction by Gpu::synchronize at end of loop. - const auto& Sn = S_old[mfi].const_array(Density); - const auto& Sarr = Scal.array(); - const auto& aofs_dens = Aofs[mfi].const_array(Density); - // Create a local copy for lambda capture - int numscal = NUM_SCALARS; - - amrex::ParallelFor(bx, [ Sn, Sarr, aofs_dens, dt, numscal] - AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - int n = 0; - // For density, we can create the Crank-Nicholson half-time approximation: - // Snew = Sold - dt*adv - // Shalftime = Sarr = (Snew + Sold)/2 - Sarr(i,j,k,n) = Sn(i,j,k,n) - 0.5 * dt * aofs_dens(i,j,k,n); - - // For other scalars, which may have diffusive or forcing terms, this is - // a safe choice. - for ( n = 1; n < numscal; n++ ) - { - Sarr(i,j,k,n) = Sn(i,j,k,n); - } - }); - - const Real halftime = 0.5 * ( state[State_Type].curTime() + - state[State_Type].prevTime() ); - FArrayBox& Vel_fab = Vel[mfi]; - - int num_comp = last_scalar - sComp + 1; - // Note that in general, num_comp != NUM_SCALAR - tforces.resize(bx,num_comp); - // tforces protected from early destruction by Gpu::synchronize at end of loop. - getForce(tforces,bx,sComp,num_comp,halftime,Vel_fab,Scal,0,mfi); - - const auto& Snew = S_new[mfi].array(sComp); - const auto& Sold = S_old[mfi].const_array(sComp); - const auto& advc = Aofs[mfi].const_array(sComp); - const auto& tf = tforces.const_array(); - const auto& rho = Scal.const_array(); - - // Advection type - amrex::Vector iconserv_h; - iconserv_h.resize(num_comp); - for (int i = 0; i < num_comp; ++i) { - iconserv_h[i] = (advectionType[sComp+i] == Conservative) ? 1 : 0; - } - amrex::Gpu::DeviceVector iconserv_d; - iconserv_d.resize(num_comp); - Gpu::copy(Gpu::hostToDevice, iconserv_h.begin(), iconserv_h.end(), iconserv_d.begin()); - const int* iconserv = iconserv_d.data(); - - // Recall tforces is always density-weighted - amrex::ParallelFor(bx, num_comp, [ Snew, Sold, advc, tf, dt, rho, iconserv] - AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept - { - if ( iconserv[n] == 1 ) { - Snew(i,j,k,n) = Sold(i,j,k,n) + dt * ( - advc(i,j,k,n) + tf(i,j,k,n) ); - } - else { - Snew(i,j,k,n) = Sold(i,j,k,n) + dt * ( - advc(i,j,k,n) + tf(i,j,k,n)/rho(i,j,k) ); - } - }); - - // Either need this synchronize here, or elixirs. Not sure if it matters which - amrex::Gpu::synchronize(); - } - } - } - - // - // Call ScalMinMax to avoid overshoots in the scalars. - // - if ( do_scalminmax && (sComp <= last_scalar) ) - { - const int num_scalars = last_scalar - Density + 1; - - // - // Must do FillPatch here instead of MF iterator because we need the - // boundary values in the old data (especially at inflow). - // - FillPatchIterator S_fpi(*this,S_old,1,prev_time,State_Type,Density,num_scalars); - MultiFab& Smf=S_fpi.get_mf(); - - for (int sigma = sComp; sigma <= last_scalar; sigma++) - { - const int index_new_s = sigma; - const int index_new_rho = Density; - const int index_old_s = index_new_s - Density; - const int index_old_rho = index_new_rho - Density; - - if (advectionType[sigma] == Conservative) - { - ConservativeScalMinMax(S_new, index_new_s, index_new_rho, - Smf, index_old_s, index_old_rho); - } - else if (advectionType[sigma] == NonConservative) - { - ConvectiveScalMinMax(S_new, index_new_s, Smf, index_old_s); - } - } - } - - // - // Check the max of Snew and for NANs in solution - // - // static int count=0; count++; - // VisMF::Write(S_new,"sn_"+std::to_string(count)); - // for (int sigma = first_scalar; sigma <= last_scalar; sigma++) - // { - // std::cout << count <<" , comp = " << sigma << ", max(S_new) = " - // << S_new.norm0( sigma, 0, false, true ) - // << std::endl; - // } - - // for (int sigma = first_scalar; sigma <= last_scalar; sigma++) - // { - // if (S_old.contains_nan(sigma,1,0)) - // { - // amrex::Print() << "SAU: Old scalar " << sigma << " contains Nans" << std::endl; - - // IntVect mpt(AMREX_D_DECL(-100,100,-100)); - // for (MFIter mfi(S_old); mfi.isValid(); ++mfi){ - // if ( S_old[mfi].contains_nan(mpt) ) - // amrex::Print() << " Nans at " << mpt << std::endl; - // } - // } - // if (S_new.contains_nan(sigma,1,0)) - // { - // amrex::Print() << "SAU: New scalar " << sigma << " contains Nans" << std::endl; - - // IntVect mpt(AMREX_D_DECL(-100,100,-100)); - // for (MFIter mfi(S_new); mfi.isValid(); ++mfi){ - // if ( S_new[mfi].contains_nan(mpt) ) - // amrex::Print() << " Nans at " << mpt << std::endl; - // } - // } - // } -} - -// -// Set the time levels to time (time) and timestep dt. -// -void -NavierStokesBase::setTimeLevel (Real time, - Real dt_old, - Real dt_new) -{ - state[State_Type].setTimeLevel(time,dt_old,dt_new); - - if (have_divu) - { - state[Divu_Type].setTimeLevel(time,dt_old,dt_new); - if (have_dsdt) - { - state[Dsdt_Type].setTimeLevel(time,dt_old,dt_new); - } - } - - state[Press_Type].setTimeLevel(time-dt_old,dt_old,dt_old); - - state[Gradp_Type].setTimeLevel(time-dt_old,dt_old,dt_old); -} - -void -NavierStokesBase::sync_setup (MultiFab*& DeltaSsync) -{ - AMREX_ASSERT(DeltaSsync == nullptr); - - int nconserved = 0; - - for (int comp = AMREX_SPACEDIM; comp < NUM_STATE; ++comp) - { - if (advectionType[comp] == Conservative) - ++nconserved; - } - - if (nconserved > 0 && level < parent->finestLevel()) - { - DeltaSsync = new MultiFab(grids, dmap, nconserved, 0, MFInfo(), Factory()); - DeltaSsync->setVal(0); - } -} - -void -NavierStokesBase::sync_cleanup (MultiFab*& DeltaSsync) -{ - delete DeltaSsync; - DeltaSsync = nullptr; -} - -// -// Helper function for NavierStokesBase::SyncInterp(). -// -static -void -set_bcrec_new (Vector &bcrec, - int ncomp, - int src_comp, - const Box& box, - const Box& domain, - const BoxArray& cgrids, - int** bc_orig_qty) - -{ - for (int n = 0; n < ncomp; n++) { - for (int dir = 0; dir < AMREX_SPACEDIM; dir++) - { - int bc_index = (src_comp+n)*(2*AMREX_SPACEDIM) + dir; - bcrec[n].setLo(dir,BCType::int_dir); - bcrec[n].setHi(dir,BCType::int_dir); - if ( ( box.smallEnd(dir) < domain.smallEnd(dir) ) || - ( box.bigEnd(dir) > domain.bigEnd(dir) ) ) { - for (int crse = 0; crse < cgrids.size(); crse++) { - const Box& crsebx = cgrids[crse]; - if ( ( box.smallEnd(dir) < domain.smallEnd(dir) ) && ( crsebx.smallEnd(dir) == domain.smallEnd(dir) ) ) { - bcrec[n].setLo(dir,bc_orig_qty[crse][bc_index]); - } - if ( ( box.bigEnd(dir) > domain.bigEnd(dir) ) && ( crsebx.bigEnd(dir) == domain.bigEnd(dir) ) ) { - bcrec[n].setHi(dir,bc_orig_qty[crse][bc_index+AMREX_SPACEDIM]); - } - } - } - } - } -} - -// -// Interpolate A cell centered Sync correction from a -// coarse level (c_lev) to a fine level (f_lev). -// -// This routine interpolates the num_comp components of CrseSync -// (starting at src_comp) and either increments or puts the result into -// the num_comp components of FineSync (starting at dest_comp) -// The components of bc_orig_qty correspond to the quantities of CrseSync. -// -void -NavierStokesBase::SyncInterp (MultiFab& CrseSync, - int c_lev, - MultiFab& FineSync, - int f_lev, - IntVect& ratio, - int src_comp, - int dest_comp, - int num_comp, - int increment, - Real dt_clev, - int** bc_orig_qty, - SyncInterpType which_interp, - int state_comp) -{ - BL_PROFILE("NavierStokesBase::SyncInterp()"); - - Interpolater* interpolater = nullptr; - -#ifdef AMREX_USE_EB - switch (which_interp) - { - // As with the non-EB case, both of these point to the same interpolater - case CellCons_T: interpolater = &eb_cell_cons_interp; break; - case CellConsLin_T: interpolater = &eb_lincc_interp; break; - default: - amrex::Abort("NavierStokesBase::SyncInterp(): EB currently requires Cell Conservative interpolater. \n"); - } -#else - switch (which_interp) - { - case PC_T: interpolater = &pc_interp; break; - case CellCons_T: interpolater = &cell_cons_interp; break; - case CellConsLin_T: interpolater = &lincc_interp; break; - case CellConsProt_T: interpolater = &protected_interp; break; - default: - amrex::Abort("NavierStokesBase::SyncInterp(): how did this happen \n"); - } -#endif - - NavierStokesBase& fine_level = getLevel(f_lev); - const BoxArray& fgrids = fine_level.boxArray(); - const DistributionMapping& fdmap = fine_level.DistributionMap(); - const Geometry& fgeom = parent->Geom(f_lev); - const BoxArray& cgrids = getLevel(c_lev).boxArray(); - const Geometry& cgeom = parent->Geom(c_lev); - Box cdomain = amrex::coarsen(fgeom.Domain(),ratio); - const auto N = int(fgrids.size()); - - BoxArray cdataBA(N); - - for (int i = 0; i < N; i++) { - cdataBA.set(i,interpolater->CoarseBox(fgrids[i],ratio)); - } - // - // Note: The boxes in cdataBA may NOT be disjoint !!! - // -#ifdef AMREX_USE_EB - // I am unsure of EBSupport and ng (set to zero here) - auto factory = makeEBFabFactory(cgeom,cdataBA,fdmap,{0,0,0},EBSupport::basic); - MultiFab cdataMF(cdataBA,fdmap,num_comp,0,MFInfo(),*factory); -#else - // ,MFInfo(),getLevel(c_lev).Factory()); - MultiFab cdataMF(cdataBA,fdmap,num_comp,0); -#endif - - cdataMF.ParallelCopy(CrseSync, src_comp, 0, num_comp, cgeom.periodicity()); - - // - // Set physical boundary conditions in cdataMF. - // - ////////// - // Should be fine for EB for now, since EB doesn't intersect Phys BC - // Not sure about what happens if EB intersects Phys BC - /////// - - // tiling may not be needed here, but what the hey - GpuBndryFuncFab gpu_bndry_func(HomExtDirFill{}); -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(cdataMF,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - FArrayBox& data = cdataMF[mfi]; - - Vector bx_bcrec(num_comp); - set_bcrec_new(bx_bcrec,num_comp,src_comp,bx,cdomain,cgrids,bc_orig_qty); - gpu_bndry_func(bx,data,0,num_comp,cgeom,0.0,bx_bcrec,0,0); - } - - // - // Interpolate from cdataMF to fdata and update FineSync. - // Note that FineSync and cdataMF will have the same distribution - // since the length of their BoxArrays are equal. - // - MultiFab* fine_stateMF = nullptr; - if (interpolater == &protected_interp) - { - fine_stateMF = &(getLevel(f_lev).get_new_data(State_Type)); - } - - -#ifdef AMREX_USE_EB - const FabArray& flags = dynamic_cast(getLevel(f_lev).Factory()).getMultiEBCellFlagFab(); -#endif - -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - { - for (MFIter mfi(FineSync,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - FArrayBox& cdata = cdataMF[mfi]; - const Box& bx = mfi.tilebox(); - const Box cbx = interpolater->CoarseBox(bx,ratio); - -#ifdef AMREX_USE_EB - EBFArrayBox fdata(flags[mfi],bx,num_comp,FineSync[mfi].arena()); -#else - FArrayBox fdata(bx, num_comp); -#endif - Elixir fdata_i = fdata.elixir(); - - // - // Set the boundary condition array for interpolation. - // - Vector bx_bcrec(num_comp); - set_bcrec_new(bx_bcrec,num_comp,src_comp,cbx,cdomain,cgrids,bc_orig_qty); - - //ScaleCrseSyncInterp(cdata, c_lev, num_comp); - - interpolater->interp(cdata,0,fdata,0,num_comp,bx,ratio, - cgeom,fgeom,bx_bcrec,src_comp,State_Type,RunOn::Gpu); - - //reScaleFineSyncInterp(fdata, f_lev, num_comp); - - if (increment) - { - auto const& finedata = fdata.array(); - auto const& coarsedata = cdata.array(); - int scale_coarse = (interpolater == &protected_interp) ? 1 : 0; - amrex::ParallelFor(bx, num_comp, [finedata,dt_clev] - AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept - { - finedata(i,j,k,n) *= dt_clev; - }); - - if ( scale_coarse ) { - amrex::ParallelFor(cbx, num_comp, [coarsedata,dt_clev] - AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept - { - coarsedata(i,j,k,n) *= dt_clev; - }); - } - - - if (interpolater == &protected_interp) - { - FArrayBox& fine_state = (*fine_stateMF)[mfi]; - interpolater->protect(cdata,0,fdata,0,fine_state,state_comp, - num_comp,bx,ratio, - cgeom,fgeom,bx_bcrec,RunOn::Gpu); - } - - auto const& fsync = FineSync.array(mfi,dest_comp); - amrex::ParallelFor(bx, num_comp, [finedata,fsync] - AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept - { - fsync(i,j,k,n) += finedata(i,j,k,n); - }); - - if ( scale_coarse ) { - amrex::ParallelFor(cbx, num_comp, [coarsedata,dt_clev] - AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept - { - coarsedata(i,j,k,n) /= dt_clev; - }); - } - - - } - else - { - auto const& finedata = fdata.array(); - auto const& fsync = FineSync.array(mfi,dest_comp); - amrex::ParallelFor(bx, num_comp, [finedata,fsync] - AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept - { - fsync(i,j,k,n) = finedata(i,j,k,n); - }); - } - } - } -} - -// -// Interpolate sync pressure correction to a finer level. -// -void -NavierStokesBase::SyncProjInterp (MultiFab& phi, - int c_lev, - MultiFab& P_new, - MultiFab& P_old, - int f_lev, - IntVect& ratio) -{ - BL_PROFILE("NavierStokesBase:::SyncProjInterp()"); - - const BoxArray& P_grids = P_new.boxArray(); - const auto N = int(P_grids.size()); - - BoxArray crse_ba(N); - -#ifdef _OPENMP -#pragma omp parallel for -#endif - for (int i = 0; i < N; i++) - crse_ba.set(i,node_bilinear_interp.CoarseBox(P_grids[i],ratio)); - - // None of these 3 are actually used by node_bilinear_interp() - Vector bc(AMREX_SPACEDIM); - const Geometry& fgeom = parent->Geom(f_lev); - const Geometry& cgeom = parent->Geom(c_lev); - -#ifdef AMREX_USE_EB - // I am unsure of EBSupport and ng (set to 1 here) - // need 1 ghost cell to use EB_set_covered on nodal MF - // Factory is always CC, regardless of status of crse_ba - auto factory = makeEBFabFactory(cgeom,crse_ba,P_new.DistributionMap(),{1,1,1},EBSupport::basic); - MultiFab crse_phi(crse_ba,P_new.DistributionMap(),1,0,MFInfo(),*factory); - -#else - MultiFab crse_phi(crse_ba,P_new.DistributionMap(),1,0); -#endif - - crse_phi.setVal(1.e200); - crse_phi.ParallelCopy(phi,0,0,1); - -#ifdef AMREX_USE_EB - EB_set_covered(crse_phi,0.); -#endif - -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(P_new,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - FArrayBox fine_phi(bx,1); - Elixir fine_phi_i = fine_phi.elixir(); - node_bilinear_interp.interp(crse_phi[mfi],0,fine_phi,0,1, - fine_phi.box(),ratio,cgeom,fgeom,bc, - 0,Press_Type,RunOn::Gpu); - - auto const& f_phi = fine_phi.array(); - auto const& p_new = P_new.array(mfi); - auto const& p_old = P_old.array(mfi); - amrex::ParallelFor(bx, [f_phi, p_old, p_new] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - p_new(i,j,k) += f_phi(i,j,k); - p_old(i,j,k) += f_phi(i,j,k); - }); - } - -#ifdef AMREX_USE_EB - EB_set_covered(P_new,0.); - EB_set_covered(P_old,0.); -#endif - -} - -std::string -NavierStokesBase::thePlotFileType () const -{ - // - // Increment this whenever the writePlotFile() format changes. - // - static const std::string the_plot_file_type("NavierStokes-V1.1"); - - return the_plot_file_type; -} - -// -// This routine advects the velocities -// -void -NavierStokesBase::velocity_advection (Real dt) -{ - BL_PROFILE("NavierStokesBase::velocity_advection()"); - - if (verbose) - { - if (do_mom_diff == 0) - { - - amrex::Print() << "... advect velocities\n"; - } - else - { - amrex::Print() << "... advect momenta\n"; - } - } - - const Real prev_time = state[State_Type].prevTime(); - - std::unique_ptr divu_fp(getDivCond(nghost_force(),prev_time)); - - MultiFab forcing_term( grids, dmap, AMREX_SPACEDIM, nghost_force(), MFInfo(),Factory()); - forcing_term.setVal(0.0); - - FillPatchIterator U_fpi(*this,forcing_term, nghost_state(),prev_time,State_Type,Xvel,AMREX_SPACEDIM); - MultiFab& Umf=U_fpi.get_mf(); - - // - // S_term is the state we are solving for: either velocity or momentum - // - MultiFab raii; - MultiFab* S_term; - if (do_mom_diff) { - raii.define(grids, dmap, AMREX_SPACEDIM, nghost_state(), MFInfo(), Factory()); - S_term = &raii; - } else { - S_term = &Umf; - } - - if (do_mom_diff) - { - FillPatchIterator Rho_fpi(*this,forcing_term,nghost_state(),prev_time,State_Type,Density,1); - MultiFab& Rmf=Rho_fpi.get_mf(); - - for (MFIter U_mfi(Umf,TilingIfNotGPU()); U_mfi.isValid(); ++U_mfi) - { - auto const state_bx = U_mfi.growntilebox(nghost_state()); - - auto const& dens = Rmf.const_array(U_mfi); //Previous time, nghost_state() grow cells filled - auto const& vel = Umf.const_array(U_mfi); - auto const& st = S_term->array(U_mfi); - - amrex::ParallelFor(state_bx, AMREX_SPACEDIM, [ dens, vel, st ] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { st(i,j,k,n) = vel(i,j,k,n) * dens(i,j,k); }); - } - } - - MultiFab& Gp = get_old_data(Gradp_Type); - - FillPatchIterator S_fpi(*this,forcing_term,nghost_force(),prev_time,State_Type,Density,NUM_SCALARS); - MultiFab& Smf=S_fpi.get_mf(); - - // Get divu to time n+1/2 - { - std::unique_ptr dsdt(getDsdt(nghost_force(),prev_time)); - MultiFab::Saxpy(*divu_fp, 0.5*dt, *dsdt, 0, 0, 1, nghost_force()); - } - - MultiFab visc_terms(grids,dmap,AMREX_SPACEDIM,nghost_force(),MFInfo(),Factory()); - if (be_cn_theta != 1.0) - getViscTerms(visc_terms,Xvel,AMREX_SPACEDIM,prev_time); - else - visc_terms.setVal(0.0); - - // - // ls related - // may add some surface tension subroutines later - // - -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter U_mfi(Umf,TilingIfNotGPU()); U_mfi.isValid(); ++U_mfi) - { - - auto const force_bx = U_mfi.growntilebox(nghost_force()); // Box for forcing term - - if (getForceVerbose) - { - amrex::Print() << "---" << '\n' - << "B - velocity advection:" << '\n' - << "Calling getForce..." << '\n'; - } - // - // ls related - // may consider the surface tension in a new getForce later - // - getForce(forcing_term[U_mfi],force_bx,Xvel,AMREX_SPACEDIM, - prev_time,Umf[U_mfi],Smf[U_mfi],0,U_mfi); - - // - // Compute the total forcing. - // - auto const& tf = forcing_term.array(U_mfi,Xvel); - auto const& visc = visc_terms.const_array(U_mfi,Xvel); - auto const& gp = Gp.const_array(U_mfi); - auto const& rho = Smf.const_array(U_mfi); //Previous time, nghost_force() grow cells filled - - bool is_convective = do_mom_diff ? false : true; - amrex::ParallelFor(force_bx, AMREX_SPACEDIM, [ tf, visc, gp, rho, is_convective] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { - tf(i,j,k,n) = ( tf(i,j,k,n) + visc(i,j,k,n) - gp(i,j,k,n) ); - if (is_convective) - tf(i,j,k,n) /= rho(i,j,k); - }); - } - - ComputeAofs( Xvel, AMREX_SPACEDIM, *S_term, 0, forcing_term, *divu_fp, true, dt ); -} - -// -// This subroutine updates the velocity field before the level projection. -// -// At this point in time, all we know is u^n, rho^n+1/2, and the -// general forcing terms at t^n, and after solving in this routine -// viscous forcing at t^n+1/2. Except for a simple buoyancy term, -// b = -rho^n+1/2 g, it is usually not possible to estimate more -// general forcing terms at t^n+1/2. Since the default getForce, handles -// this case automatically, F_new and F_old have been replaced by a single -// tforces FArrayBox. -// -// We assume that if one component of velocity is viscous that all must be. -// - -void -NavierStokesBase::velocity_update (Real dt) -{ - BL_PROFILE("NavierStokesBase::velocity_update()"); - - if (verbose) - { - if (do_mom_diff == 0) - { - amrex::Print() << "... update velocities \n"; - } - else - { - amrex::Print() << "... update momenta \n"; - } - } - - velocity_advection_update(dt); - - if (!initial_iter) - velocity_diffusion_update(dt); - else - initial_velocity_diffusion_update(dt); - - MultiFab& S_new = get_new_data(State_Type); - - for (int sigma = 0; sigma < AMREX_SPACEDIM; sigma++) - { - if (S_new.contains_nan(sigma,1,0)) - { - amrex::Print() << "New velocity " << sigma << " contains Nans" << '\n'; - exit(0); - } - } -} - -void -NavierStokesBase::velocity_advection_update (Real dt) -{ - BL_PROFILE("NavierStokesBase::velocity_advection_update()"); - - MultiFab& U_old = get_old_data(State_Type); - MultiFab& U_new = get_new_data(State_Type); - MultiFab& Aofs = *aofs; - MultiFab& Gp = get_old_data(Gradp_Type); - MultiFab& Rh = get_rho_half_time(); - - MultiFab Vel(grids, dmap, AMREX_SPACEDIM, 0, MFInfo(), Factory()); - // - // Average mac face velocity to cell-centers for use in generating external - // forcing term in getForce() - // NOTE that default getForce() does not use Vel or Scal, user must supply the - // forcing function for that case. - // -#ifdef AMREX_USE_EB - // This isn't quite right because it's face-centers to cell-centers - // what's really wanted is face-centroid to cell-centroid - EB_average_face_to_cellcenter(Vel, 0, Array{{AMREX_D_DECL(&u_mac[0],&u_mac[1],&u_mac[2])}}); -#else - average_face_to_cellcenter(Vel, 0, Array{{AMREX_D_DECL(&u_mac[0],&u_mac[1],&u_mac[2])}}); -#endif - -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif -{ - FArrayBox tforces, ScalFAB; - - for (MFIter mfi(Rh,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - FArrayBox& VelFAB = Vel[mfi]; - ScalFAB.resize(bx,NUM_SCALARS); - Elixir scal_i = ScalFAB.elixir(); - - // - // Need to do some funky half-time stuff. - // - if (getForceVerbose) - amrex::Print() << "---" << '\n' << "F - velocity advection update (half time):" << '\n'; - // - // Average the new and old time to get Crank-Nicholson half time approximation. - // Scalars always get updated before velocity (see NavierStokes::advance), so - // this is guaranteed to be good. - // - auto const& scal = ScalFAB.array(); - auto const& scal_o = U_old.array(mfi,Density); - auto const& scal_n = U_new.array(mfi,Density); - amrex::ParallelFor(bx, NUM_SCALARS, [scal, scal_o, scal_n] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { - scal(i,j,k,n) = 0.5 * ( scal_o(i,j,k,n) + scal_n(i,j,k,n) ); - }); - - const Real half_time = 0.5*(state[State_Type].prevTime()+state[State_Type].curTime()); - tforces.resize(bx,AMREX_SPACEDIM); - Elixir tf_i = tforces.elixir(); - getForce(tforces,bx,Xvel,AMREX_SPACEDIM,half_time,VelFAB,ScalFAB,0,mfi); - - // - // Do following only at initial iteration--per JBB. - // - if (initial_iter && is_diffusive[Xvel]) { - auto const& force = tforces.array(); - amrex::ParallelFor(bx, AMREX_SPACEDIM, [force] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { - force(i,j,k,n) = 0.0; - }); - } - - // Update velocity - auto const& vel_old = U_old.array(mfi); - auto const& vel_new = U_new.array(mfi); - auto const& gradp = Gp.array(mfi); - auto const& force = tforces.array(); - auto const& advec = Aofs.array(mfi); - auto const& rho_old = U_old.array(mfi, Density); - auto const& rho_new = U_new.array(mfi, Density); - auto const& rho_Half = Rh.array(mfi); - int mom_diff = do_mom_diff; - amrex::ParallelFor(bx, AMREX_SPACEDIM, [vel_old,vel_new,gradp,force,advec,rho_old,rho_new,rho_Half,mom_diff,dt] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { - Real velold = vel_old(i,j,k,n); - - if ( mom_diff ) { - velold *= rho_old(i,j,k); - vel_new(i,j,k,n) = velold - dt * advec(i,j,k,n) - + dt * force(i,j,k,n) - - dt * gradp(i,j,k,n); - - vel_new(i,j,k,n) /= rho_new(i,j,k); - } - else - { - vel_new(i,j,k,n) = velold - dt * advec(i,j,k,n) - + dt * force(i,j,k,n) / rho_Half(i,j,k) - - dt * gradp(i,j,k,n) / rho_Half(i,j,k); - } - }); - } -} - - for (int sigma = 0; sigma < AMREX_SPACEDIM; sigma++) - { - if (U_old.contains_nan(sigma,1,0)) - { - amrex::Print() << "VAU: Old velocity " << sigma << " contains Nans" << std::endl; - - IntVect mpt(AMREX_D_DECL(-100,100,-100)); - for (MFIter mfi(U_old); mfi.isValid(); ++mfi){ - const Box& bx = mfi.tilebox(); - if ( U_old[mfi].contains_nan(bx, sigma, 1, mpt) ) - amrex::Print() << " Nans at " << mpt << std::endl; - } - } - if (U_new.contains_nan(sigma,1,0)) - { - amrex::Print() << "VAU: New velocity " << sigma << " contains Nans" << std::endl; - - IntVect mpt(AMREX_D_DECL(-100,100,-100)); - for (MFIter mfi(U_new); mfi.isValid(); ++mfi){ - const Box& bx = mfi.tilebox(); - if ( U_new[mfi].contains_nan(bx, sigma, 1, mpt) ) - amrex::Print() << " Nans at " << mpt << std::endl; - } - } - } -} - -void -NavierStokesBase::initial_velocity_diffusion_update (Real dt) -{ - // - // Do following only at initial iteration. - // - if (is_diffusive[Xvel]) - { - MultiFab& U_old = get_old_data(State_Type); - MultiFab& U_new = get_new_data(State_Type); - MultiFab& Rh = get_rho_half_time(); - const Real prev_time = state[State_Type].prevTime(); - - int ngrow = 0; - MultiFab visc_terms(grids,dmap,AMREX_SPACEDIM,ngrow,MFInfo(),Factory()); - MultiFab tforces(grids,dmap,AMREX_SPACEDIM,ngrow,MFInfo(),Factory()); - - // - // Get grad(p) - // - MultiFab& Gp = get_old_data(Gradp_Type); - - // - // Compute additional forcing terms - // - tforces.setVal(0.0); -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(tforces,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const auto& bx = mfi.tilebox(); - auto& tforces_fab = tforces[mfi]; - if (getForceVerbose) - { - amrex::Print() << "---" << '\n' - << "G - initial velocity diffusion update:" << '\n' - << "Calling getForce..." << '\n'; - } - getForce(tforces_fab,bx,Xvel,AMREX_SPACEDIM,prev_time,U_old[mfi],U_old[mfi],Density,mfi); - } - - // - // Compute viscous terms - // - if (be_cn_theta != 1.0) - { - getViscTerms(visc_terms,Xvel,AMREX_SPACEDIM,prev_time); - } - else - { - visc_terms.setVal(0.0); - } - - // - // Assemble RHS - // -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(tforces,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - auto const& force = tforces.array(mfi); - auto const& viscT = visc_terms.array(mfi); - auto const& gradp = Gp.array(mfi); - auto const& rhohalf = Rh.array(mfi); - auto const& rho_old = U_old.array(mfi,Density); - auto const& rho_new = U_new.array(mfi,Density); - auto const& vel_old = U_old.array(mfi,Xvel); - auto const& vel_new = U_new.array(mfi,Xvel); - auto const& advT = aofs->array(mfi,Xvel); - int mom_diff = do_mom_diff; - amrex::ParallelFor(bx, AMREX_SPACEDIM, [force,viscT,gradp,rhohalf,advT,rho_old,rho_new,vel_old,vel_new,mom_diff,dt] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { - // Set force += (visc - Gp) / rho_half - aofs - force(i,j,k,n) += viscT(i,j,k,n) - gradp(i,j,k,n); - if ( !mom_diff ) { - force(i,j,k,n) /= rhohalf(i,j,k); - } - force(i,j,k,n) -= advT(i,j,k,n); - // if mom_diff : U_new = (force* dt + U_old * rho_old) / rho_new - // else : U_new = U_old + force* dt - if ( mom_diff ) { - vel_new(i,j,k,n) = (force(i,j,k,n) * dt + vel_old(i,j,k,n) * rho_old(i,j,k)) / rho_new(i,j,k); - } else { - vel_new(i,j,k,n) = vel_old(i,j,k,n) + force(i,j,k,n) * dt; - } - }); - } - } -} - -#ifdef AMREX_PARTICLES - -void -NavierStokesBase::read_particle_params () -{ - ParmParse ppp("particles"); - // - // Ensure other particle methods aren't being used, like sprays - // - ppp.query("do_nspc_particles", do_nspc); - if (!do_nspc) return; - // - // The directory in which to store timestamp files. - // - ppp.query("timestamp_dir", timestamp_dir); - // - // Only the I/O processor makes the directory if it doesn't already exist. - // - if (ParallelDescriptor::IOProcessor()) - if (!amrex::UtilCreateDirectory(timestamp_dir, 0755)) - amrex::CreateDirectoryFailed(timestamp_dir); - // - // Force other processors to wait till directory is built. - // - ParallelDescriptor::Barrier(); - - if (int nc = ppp.countval("timestamp_indices")) - { - timestamp_indices.resize(nc); - - ppp.getarr("timestamp_indices", timestamp_indices, 0, nc); - } - - ppp.query("verbose",pverbose); - if ( ppp.countname("pverbose") > 0) { - amrex::Abort("particles.pverbose found in inputs. Please use particles.verbose"); - } - // - // Used in initData() on startup to read in a file of particles. - // - ppp.query("particle_init_file", particle_init_file); - // - // Used in post_restart() to read in a file of particles. - // - ppp.query("particle_restart_file", particle_restart_file); - // - // This must be true the first time you try to restart from a checkpoint - // that was written with USE_PARTICLES=FALSE; i.e. one that doesn't have - // the particle checkpoint stuff (even if there are no active particles). - // Otherwise the code will fail when trying to read the checkpointed particles. - // - ppp.query("restart_from_nonparticle_chkfile", restart_from_nonparticle_chkfile); - // - // Used in post_restart() to write out the file of particles. - // - ppp.query("particle_output_file", particle_output_file); - // - // Put particle info in plotfile (using ParticleContainer::Checkpoint)? - // - ppp.query("particles_in_plotfile", particles_in_plotfile); -} - -void -NavierStokesBase::initParticleData () -{ - - if (!do_nspc) { return; } - - if (level == 0) - { - if (NSPC == 0) - { - NSPC = new AmrTracerParticleContainer(parent); - } - - NSPC->SetVerbose(pverbose); - - if (!particle_init_file.empty()) - { - NSPC->InitFromAsciiFile(particle_init_file,0); - } - } -} - -void -NavierStokesBase::post_restart_particle () -{ - if (level == 0 && do_nspc) - { - AMREX_ASSERT(NSPC == 0); - - NSPC = new AmrTracerParticleContainer(parent); - - NSPC->SetVerbose(pverbose); - // - // We want to be able to add new particles on a restart. - // As well as the ability to write the particles out to an ascii file. - // - if (!restart_from_nonparticle_chkfile) - { - NSPC->Restart(parent->theRestartFile(), the_ns_particle_file_name); - } - - if (!particle_restart_file.empty()) - { - NSPC->InitFromAsciiFile(particle_restart_file,0); - } - - if (!particle_output_file.empty()) - { - NSPC->WriteAsciiFile(particle_output_file); - } - } -} - -void -NavierStokesBase::post_timestep_particle (int crse_iteration) -{ - const int ncycle = parent->nCycle(level); - const int finest_level = parent->finestLevel(); - // - // Don't redistribute/timestamp on the final subiteration except on the coarsest grid. - // - if (NSPC != 0 && (crse_iteration < ncycle || level == 0)) - { - const Real curr_time = state[State_Type].curTime(); - - int ngrow = (level == 0) ? 0 : crse_iteration; - - NSPC->Redistribute(level, finest_level, ngrow); - - if (!timestamp_dir.empty()) - { - std::string basename = timestamp_dir; - - if (basename[basename.length()-1] != '/') basename += '/'; - - basename += "Timestamp"; - - static bool first = true; - static int n, nextras; - static std::vector tindices; - - if (first) - { - first = false; - - n = timestamp_indices.size(); - nextras = timestamp_num_extras(); - - int sz = n + nextras; - tindices.reserve(sz); - - for (int i = 0; i < sz; ++i) { - tindices.push_back(i); - } - } - - for (int lev = level; lev <= finest_level; lev++) - { - if (NSPC->NumberOfParticlesAtLevel(lev) <= 0) continue; - - int ng = (lev == level) ? ngrow+1 : 1; - - AmrLevel& amr_level = parent->getLevel(lev); - MultiFab& S_new = amr_level.get_new_data(State_Type); - - MultiFab tmf; - - if (tindices.size() > 0) - { - tmf.define(S_new.boxArray(), S_new.DistributionMap(), tindices.size(), ng, MFInfo(), Factory()); - - if (n > 0) - { - FillPatchIterator fpi(parent->getLevel(lev), S_new, - ng, curr_time, State_Type, 0, NUM_STATE); - const MultiFab& S = fpi.get_mf(); - -#ifdef _OPENMP -#pragma omp parallel -#endif - for (MFIter mfi(tmf,true); mfi.isValid(); ++mfi) - { - FArrayBox& tfab = tmf[mfi]; - const FArrayBox& sfab = S[mfi]; - const Box& box = mfi.growntilebox(); - for (int i = 0; i < n; ++i) - { - tfab.copy(sfab, box, timestamp_indices[i], box, i, 1); - } - } - } - - if (nextras > 0) - { - timestamp_add_extras(lev, curr_time, tmf); - } - } - - NSPC->Timestamp(basename, tmf, lev, curr_time, tindices); - } - } - } -} - -std::unique_ptr -NavierStokesBase::ParticleDerive (const std::string& name, - Real time, - int ngrow) -{ - if ((name == "particle_count" || name == "total_particle_count") && do_nspc) { - int ncomp = 1; - const DeriveRec* rec = derive_lst.get(name); - if (rec) - { - ncomp = rec->numDerive(); - } - - MultiFab* ret = new MultiFab(grids, dmap, ncomp, ngrow, MFInfo(), Factory()); - ParticleDerive(name,time,*ret,0); - return std::unique_ptr{ret}; - } - else { - return AmrLevel::derive(name, time, ngrow); - } -} - -void -NavierStokesBase::ParticleDerive (const std::string& name, - Real time, - MultiFab& mf, - int dcomp) -{ - if (NSPC == 0 || !(name == "particle_count" || name == "total_particle_count")) - { - AmrLevel::derive(name,time,mf,dcomp); - } - else { - if (name == "particle_count") - { - MultiFab temp_dat(grids,dmap,1,0, MFInfo(), Factory()); - temp_dat.setVal(0); - NSPC->Increment(temp_dat,level); - MultiFab::Copy(mf,temp_dat,0,dcomp,1,0); - } - else if (name == "total_particle_count") - { - // - // We want the total particle count at this level or higher. - // - ParticleDerive("particle_count",time,mf,dcomp); - - IntVect trr(AMREX_D_DECL(1,1,1)); - - for (int lev = level+1; lev <= parent->finestLevel(); lev++) - { - BoxArray ba = parent->boxArray(lev); - - MultiFab temp_dat(ba,parent->DistributionMap(lev),1,0,MFInfo(),Factory()); - - trr *= parent->refRatio(lev-1); - - ba.coarsen(trr); - - MultiFab ctemp_dat(ba,parent->DistributionMap(lev),1,0); - - temp_dat.setVal(0); - ctemp_dat.setVal(0); - - NSPC->Increment(temp_dat,lev); - -#ifdef _OPENMP -#pragma omp parallel -#endif - for (MFIter mfi(temp_dat,true); mfi.isValid(); ++mfi) - { - const FArrayBox& ffab = temp_dat[mfi]; - FArrayBox& cfab = ctemp_dat[mfi]; - const Box& fbx = mfi.tilebox(); - - AMREX_ASSERT(cfab.box() == amrex::coarsen(fbx,trr)); - - for (IntVect p = fbx.smallEnd(); p <= fbx.bigEnd(); fbx.next(p)) - { - const Real val = ffab(p); - if (val > 0) - cfab(amrex::coarsen(p,trr)) += val; - } - } - - temp_dat.clear(); - - MultiFab dat(grids,dmap,1,0,MFInfo(),Factory()); - dat.setVal(0); - dat.ParallelCopy(ctemp_dat); - - MultiFab::Add(mf,dat,0,dcomp,1,0); - } - } - else - { - amrex::Abort("NavierStokesBase::ParticleDerive: how did this happen?"); - } - } -} - -#endif // AMREX_PARTICLES - -// Boundary condition access function. -Vector -NavierStokesBase::fetchBCArray (int State_Type, const Box& bx, int scomp, int ncomp) -{ - Vector bc(2*AMREX_SPACEDIM*ncomp); - BCRec bcr; - const StateDescriptor* stDesc; - const Box& domain = geom.Domain(); - - for (int n = 0; n < ncomp; n++) - { - stDesc=state[State_Type].descriptor(); - setBC(bx,domain,stDesc->getBC(scomp+n),bcr); - - const int* b_rec = bcr.vect(); - for (int m = 0; m < 2*AMREX_SPACEDIM; m++) { - bc[2*AMREX_SPACEDIM*n + m] = b_rec[m]; - } - } - - return bc; -} - -Vector -NavierStokesBase::fetchBCArray (int State_Type, int scomp, int ncomp) -{ - Vector bc(ncomp); - const StateDescriptor* stDesc; - const Box& domain = geom.Domain(); - - for (int n(0); n < ncomp; ++n) - { - stDesc=state[State_Type].descriptor(); - setBC(domain,domain,stDesc->getBC(scomp+n), bc[n] ); - } - - return bc; -} - -// -// Compute gradient of P and fill ghost cells with FillPatch -// -void -NavierStokesBase::computeGradP(Real time) -{ - LPInfo info; - info.setMaxCoarseningLevel(0); - MLNodeLaplacian linop({geom}, {grids}, {dmap}, info, {&Factory()}); -#ifdef AMREX_USE_EB - linop.buildIntegral(); -#endif - - // No call to set BCs because we're only calling compGrad(), which - // doesn't use them. P already exists on surroundingNodes(Gp.validbox()), - // and compGrad() does not fill ghost cells - - MultiFab& Press = get_data(Press_Type, time); - MultiFab& Gp = get_data(Gradp_Type, time); - - linop.compGrad(0, Gp, Press); - - // Now fill ghost cells - FillPatch(*this,Gp,Gp.nGrow(),time,Gradp_Type,0,AMREX_SPACEDIM); -} - -void -NavierStokesBase::avgDown_StatePress() -{ - auto& fine_lev = getLevel(level+1); - - // - // Average down the states at the new time. - // - MultiFab& S_crse = get_new_data(State_Type); - MultiFab& S_fine = fine_lev.get_new_data(State_Type); - - average_down(S_fine, S_crse, 0, S_crse.nComp()); - - // - // Fill rho_ctime at the current and finer levels with the correct data. - // - for (int lev = level; lev <= parent->finestLevel(); lev++) - { - getLevel(lev).make_rho_curr_time(); - } - - // - // Now average down pressure over time n-(n+1) interval. - // - MultiFab& P_crse = get_new_data(Press_Type); - MultiFab& P_fine_init = fine_lev.get_new_data(Press_Type); - MultiFab& P_fine_avg = fine_lev.p_avg; - MultiFab& P_fine = initial_step ? P_fine_init : P_fine_avg; - - // NOTE: this fills ghost cells, but amrex::average_down does not. - amrex::average_down_nodal(P_fine,P_crse,fine_ratio); - - // - // Average down Gradp - // - MultiFab& Gp_crse = get_new_data(Gradp_Type); - MultiFab& Gp_fine = fine_lev.get_new_data(Gradp_Type); - - average_down(Gp_fine, Gp_crse, 0, Gp_crse.nComp()); -} - -void -NavierStokesBase::average_down(const MultiFab& S_fine, MultiFab& S_crse, - int scomp, int ncomp) -{ - // - // Choose the appropriate AMReX average_down() based on - // whether EB or non-EB, and dimensionality - // - -#ifdef AMREX_USE_EB -#if (AMREX_SPACEDIM == 3) - // Don't need volume weighting for EB -- EB is only used in Cartesian - amrex::EB_average_down(S_fine, S_crse, scomp, ncomp, fine_ratio); -#else - // Volume weighting - amrex::EB_average_down(S_fine, S_crse, this->getLevel(level+1).Volume(), - *(this->getLevel(level+1).VolFrac()), - scomp, ncomp, fine_ratio); -#endif - -#else - // - // non-EB aware, uses volume weighting for 1D,2D but no volume weighting for 3D - // - amrex::average_down(S_fine, S_crse, - this->getLevel(level+1).geom, this->getLevel(level).geom, - scomp, ncomp, fine_ratio); -#endif -} - - -// -// Diagnostics functions -// -void -NavierStokesBase::printMaxVel (bool new_data) -{ - - MultiFab& S = new_data? get_new_data(State_Type) : get_old_data(State_Type); - -#if (AMREX_SPACEDIM==3) - amrex::Print() << "max(abs(u/v/w)) = " -#else - amrex::Print() << "max(abs(u/v)) = " -#endif - << S.norm0( Xvel, 0, false, true ) - << " " - << S.norm0( Xvel+1, 0, false, true ) -#if (AMREX_SPACEDIM==3) - << " " - << S.norm0( Xvel+2, 0, false, true ) -#endif - << std::endl; -} - - -void -NavierStokesBase::printMaxGp (bool new_data) -{ - MultiFab& Gp = new_data? get_new_data(Gradp_Type) : get_old_data(Gradp_Type); - MultiFab& P = new_data? get_new_data(Press_Type) : get_old_data(Press_Type); - -#if (AMREX_SPACEDIM==3) - amrex::Print() << "max(abs(gpx/gpy/gpz/p)) = " -#else - amrex::Print() << "max(abs(gpx/gpy/p)) = " -#endif - << Gp.norm0( 0, 0, false, true ) - << " " - << Gp.norm0( 1, 0, false, true ) -#if (AMREX_SPACEDIM==3) - << " " - << Gp.norm0( 2, 0, false, true ) -#endif - << " " - << P.norm0(0, 0, false, true ) - << std::endl; -} - -void -NavierStokesBase::printMaxValues (bool new_data) -{ - printMaxVel(new_data); - printMaxGp(new_data); -} - - -// -// Correct a conservatively-advected scalar for under-over shoots. -// -void -NavierStokesBase::ConservativeScalMinMax ( amrex::MultiFab& Snew, const int snew_comp, const int new_density_comp, - amrex::MultiFab const& Sold, const int sold_comp, const int old_density_comp ) -{ - amrex::ignore_unused(this); -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(Snew,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - - const auto& bx = mfi.tilebox(); - - const auto& sn = Snew.array(mfi,snew_comp); - const auto& so = Sold.const_array(mfi,sold_comp); - const auto& rhon = Snew.const_array(mfi,new_density_comp); - const auto& rhoo = Sold.const_array(mfi,old_density_comp); -#ifdef AMREX_USE_EB - const auto& ebfactory = dynamic_cast(Factory()); - const auto& vfrac = ebfactory.getVolFrac().const_array(mfi); -#endif - - amrex::ParallelFor(bx, [=] - AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Real smn = std::numeric_limits::max(); - Real smx = std::numeric_limits::min(); - -#if (AMREX_SPACEDIM==3) - int ks = -1; - int ke = 1; -#else - int ks = 0; - int ke = 0; -#endif - - for (int kk = ks; kk <= ke; ++kk) - { - for (int jj = -1; jj <= 1; ++jj) - { - for (int ii = -1; ii <= 1; ++ii) - { -#ifdef AMREX_USE_EB - if ( vfrac (i+ii,j+jj,k+kk) > 0. ) -#endif - { - smn = amrex::min(smn, so(i+ii,j+jj,k+kk)/rhoo(i+ii,j+jj,k+kk)); - smx = amrex::max(smx, so(i+ii,j+jj,k+kk)/rhoo(i+ii,j+jj,k+kk)); - } - } - } - } - sn(i,j,k) = amrex::min( amrex::max(sn(i,j,k)/rhon(i,j,k), smn), smx ) * rhon(i,j,k); - }); - } -} - -// -// Correct a convectively-advected scalar for under-over shoots. -// -void -NavierStokesBase::ConvectiveScalMinMax ( amrex::MultiFab& Snew, const int snew_comp, - amrex::MultiFab const& Sold, const int sold_comp ) -{ - amrex::ignore_unused(this); -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(Snew,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - - const auto& bx = mfi.tilebox(); - - const auto& sn = Snew.array(mfi,snew_comp); - const auto& so = Sold.const_array(mfi,sold_comp); -#ifdef AMREX_USE_EB - const auto& ebfactory = dynamic_cast(Factory()); - const auto& vfrac = ebfactory.getVolFrac().const_array(mfi); -#endif - - amrex::ParallelFor(bx, [=] - AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Real smn = std::numeric_limits::max(); - Real smx = std::numeric_limits::min(); - -#if (AMREX_SPACEDIM==3) - int ks = -1; - int ke = 1; -#else - int ks = 0; - int ke = 0; -#endif - - for (int kk = ks; kk <= ke; ++kk) - { - for (int jj = -1; jj <= 1; ++jj) - { - for (int ii = -1; ii <= 1; ++ii) - { -#ifdef AMREX_USE_EB - if ( vfrac (i+ii,j+jj,k+kk) > 0. ) -#endif - { - smn = amrex::min(smn, so(i+ii,j+jj,k+kk)); - smx = amrex::max(smx, so(i+ii,j+jj,k+kk)); - } - } - } - } - sn(i,j,k) = amrex::min( amrex::max(sn(i,j,k), smn), smx ); - }); - } -} - - -// -// Predict the edge velocities which go into forming u_mac. This -// function also returns an estimate of dt for use in variable timesteping. -// -Real -NavierStokesBase::predict_velocity (Real dt) -{ - BL_PROFILE("NavierStokesBase::predict_velocity()"); - if (verbose) { - amrex::Print() << "... predict edge velocities\n"; - } - // - // Get simulation parameters. - // - const int nComp = AMREX_SPACEDIM; - const Real* dx = geom.CellSize(); - const Real prev_time = state[State_Type].prevTime(); - const Real prev_pres_time = state[Press_Type].prevTime(); - const Real strt_time = ParallelDescriptor::second(); - - // - // Compute viscous terms at level n. - // Ensure reasonable values in 1 grow cell. Here, do extrap for - // c-f/phys boundary, since we have no interpolator fn, also, - // preserve extrap for corners at periodic/non-periodic intersections. - // - MultiFab visc_terms(grids,dmap,nComp,nghost_force(),MFInfo(), Factory()); - - FillPatchIterator U_fpi(*this,visc_terms,nghost_state(),prev_time,State_Type,Xvel,AMREX_SPACEDIM); - MultiFab& Umf=U_fpi.get_mf(); - - // Floor small values of states to be extrapolated - floor(Umf); - - // - // Compute "grid cfl number" based on cell-centered time-n velocities - // - auto umax = Umf.norm0({AMREX_D_DECL(0,1,2)},Umf.nGrow(), /*local = */false, /*ignore_covered = */true); - Real cflmax = dt*umax[0]/dx[0]; - for (int d=1; d0 and do it - // once the first time it's needed, which is presumably here... - if ( level > 0 ) - FillPatch(*this,Gp,Gp.nGrow(),prev_pres_time,Gradp_Type,0,AMREX_SPACEDIM); - - if (be_cn_theta != 1.0) - { - getViscTerms(visc_terms,Xvel,nComp,prev_time); - } - else - { - visc_terms.setVal(0.0); - } - - // - // ls related - // may add some surface tension subroutines later - // - - FillPatchIterator S_fpi(*this,visc_terms,nghost_state(),prev_time,State_Type,Density,NUM_SCALARS); - MultiFab& Smf=S_fpi.get_mf(); - - MultiFab forcing_term( grids, dmap, AMREX_SPACEDIM, nghost_force() ); - - // - // Compute forcing - // -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - { - for (MFIter U_mfi(Umf,TilingIfNotGPU()); U_mfi.isValid(); ++U_mfi) - { - FArrayBox& Ufab = Umf[U_mfi]; - auto const gbx = U_mfi.growntilebox(nghost_force()); - - if (getForceVerbose) { - Print() << "---\nA - Predict velocity:\n Calling getForce...\n"; - } - - // - // ls related - // may consider the surface tension in a new getForce later - // - getForce(forcing_term[U_mfi],gbx,Xvel,AMREX_SPACEDIM,prev_time,Ufab,Smf[U_mfi],0,U_mfi); - - // - // Compute the total forcing. - // - auto const& tf = forcing_term.array(U_mfi,Xvel); - auto const& visc = visc_terms.const_array(U_mfi,Xvel); - auto const& gp = Gp.const_array(U_mfi); - auto const& rho = Smf.const_array(U_mfi); - - amrex::ParallelFor(gbx, AMREX_SPACEDIM, [tf, visc, gp, rho] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { - tf(i,j,k,n) = ( tf(i,j,k,n) + visc(i,j,k,n) - gp(i,j,k,n) ) / rho(i,j,k); - }); - } - } - -#ifdef AMREX_USE_EB - if (!EBFactory().isAllRegular()) - { - EBGodunov::ExtrapVelToFaces( Umf, forcing_term, - AMREX_D_DECL(u_mac[0], u_mac[1], u_mac[2]), - m_bcrec_velocity, m_bcrec_velocity_d.dataPtr(), - geom, dt ); - } - else -#endif - { - bool godunov_use_ppm = ( advection_scheme == "Godunov_PPM" ? true : false ); - - Godunov::ExtrapVelToFaces( Umf, forcing_term, - AMREX_D_DECL(u_mac[0], u_mac[1], u_mac[2]), - m_bcrec_velocity, m_bcrec_velocity_d.dataPtr(), - geom, dt, - godunov_use_ppm, godunov_use_forces_in_trans ); - } - - } - else - { - Abort("NSB::predict_velocity: Unknown advection_scheme"); - } - - if (verbose > 1) - { - const int IOProc = ParallelDescriptor::IOProcessorNumber(); - Real run_time = ParallelDescriptor::second() - strt_time; - - ParallelDescriptor::ReduceRealMax(run_time,IOProc); - - Print() << "NavierStokesBase::predict_velocity(): lev: " << level - << ", time: " << run_time << '\n'; - } - - return dt*tempdt; -} - - -// -// Floor small values of states to be extrapolated -// -void -NavierStokesBase::floor(MultiFab& mf){ - - int ncomp = mf.nComp(); - -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(mf,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - Box gbx=mfi.growntilebox(mf.nGrow()); - auto const& fab_a = mf.array(mfi); - AMREX_PARALLEL_FOR_4D ( gbx, ncomp, i, j, k, n, - { - auto& val = fab_a(i,j,k,n); - val = amrex::Math::abs(val) > 1.e-20 ? val : 0; - }); - } -} - -int -NavierStokesBase::nghost_state () const -{ - amrex::ignore_unused(this); -#ifdef AMREX_USE_EB - if (!EBFactory().isAllRegular()) - { - return 4; - } - else -#endif - { - return 3; - } -} - -void -NavierStokesBase::ComputeAofs ( int comp, int ncomp, - MultiFab const& S, - int S_comp, - MultiFab const& forcing_term, - MultiFab const& divu, - bool is_velocity, Real dt) -{ - Array cfluxes; - Array edgestate; - - // - // Advection needs S to have 2-3 ghost cells. - // Advection routines call slopes on cells i & i+1, and then - // 2nd order slopes use i+/-1 => S needs 2 ghost cells (MOL) - // 4th order slopes use i+/-2 => S needs 3 ghost cells (Godunov) - // - int nghost = 0; - for (int i = 0; i < AMREX_SPACEDIM; ++i) - { - const BoxArray& ba = getEdgeBoxArray(i); - cfluxes[i].define(ba, dmap, ncomp, nghost, MFInfo(), Factory()); - edgestate[i].define(ba, dmap, ncomp, nghost, MFInfo(), Factory()); - } - - bool do_crse_add = true; - bool do_fine_add = true; - - ComputeAofs(*aofs, /*aofs_comp*/ comp, /*state_indx*/ comp, ncomp, - S, S_comp, - &forcing_term, /*forcing_term_comp*/ 0, - &divu, - cfluxes, /*flux_comp*/ 0, - edgestate, /*edge_comp*/ 0, /*known_edgestate*/ false, - is_velocity, dt, - /*is_sync*/ false, /*sync fluxing velocity Ucorr*/ {}, - do_crse_add, do_fine_add); -} - -void -NavierStokesBase::ComputeAofs ( MultiFab& advc, int a_comp, // Advection term "Aofs" held here - int state_indx, // Index of first component in AmrLevel.state corresponding to quantity to advect - int ncomp, - MultiFab const& S, int S_comp, // State for computing edgestates, may have gotten massaged - // a bit compared to AmrLevel.state. Must have filled ghost cells. - MultiFab const* forcing, int f_comp, - MultiFab const* divu, // Constraint divu=Source, not div(Umac) - Array& cfluxes, int flux_comp, - Array& edgestate, int edge_comp, - bool known_edge_state, - bool is_velocity, Real dt, - bool is_sync, Array const& U_corr, - bool do_crse_add, bool do_fine_add) -{ - BL_PROFILE("NSB::ComputeAofs_kernel"); - - amrex::ignore_unused(do_fine_add); - - // Need U_corr to be defined for sync. - AMREX_ASSERT( (is_sync && !U_corr.empty()) || !is_sync ); - - // Advection type conservative or non? - // Maybe there's something better than DeviceVector now... - amrex::Gpu::DeviceVector iconserv; - Vector iconserv_h; - iconserv.resize(ncomp, 0); - iconserv_h.resize(ncomp, 0); - - // Will we do any convective differencing? - bool any_convective = false; - for (int i = 0; i < ncomp; ++i) { - iconserv_h[i] = (advectionType[state_indx+i] == Conservative) ? 1 : 0; - if (!iconserv_h[i]) any_convective = true; - } - Gpu::copy(Gpu::hostToDevice,iconserv_h.begin(),iconserv_h.end(), iconserv.begin()); - int const* iconserv_ptr = iconserv.data(); - - // As code is currently written, ComputeAofs is always called separately for - // velocity vs scalars. May be called with an individual scalar. - auto const& bcrec_h = fetchBCArray(State_Type, state_indx, ncomp); - auto* const bcrec_d = is_velocity ? m_bcrec_velocity_d.dataPtr() - : &m_bcrec_scalars_d.dataPtr()[state_indx-AMREX_SPACEDIM]; - -#ifdef AMREX_USE_EB - auto const& ebfact= dynamic_cast(Factory()); - - // Always need a temporary MF to hold advective update before redistribution. - MultiFab update_MF(advc.boxArray(),advc.DistributionMap(),ncomp,3,MFInfo(),Factory()); - - // Must initialize to zero because not all values may be set, e.g. outside the domain. - update_MF.setVal(0.); -#endif - - // - // Define some parameters for hydro routines - // - - bool fluxes_are_area_weighted = true; - - // AMReX_Hydro only recognizes Godunov scheme and then uses ppm switch. - std::string scheme = (advection_scheme=="Godunov_PLM" || advection_scheme=="Godunov_PPM") - ? "Godunov" : advection_scheme; - bool godunov_use_ppm = (advection_scheme == "Godunov_PPM") ? true : false ; - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(advc,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - - const auto& S_arr = S.const_array(mfi, S_comp); - AMREX_D_TERM( const auto& fx = cfluxes[0].array(mfi,flux_comp);, - const auto& fy = cfluxes[1].array(mfi,flux_comp);, - const auto& fz = cfluxes[2].array(mfi,flux_comp);); - AMREX_D_TERM( const auto& xed = edgestate[0].array(mfi,edge_comp);, - const auto& yed = edgestate[1].array(mfi,edge_comp);, - const auto& zed = edgestate[2].array(mfi,edge_comp);); - AMREX_D_TERM( const auto& umac = u_mac[0].const_array(mfi);, - const auto& vmac = u_mac[1].const_array(mfi);, - const auto& wmac = u_mac[2].const_array(mfi);); - AMREX_D_TERM( const auto& uflux = (is_sync) ? U_corr[0]->const_array(mfi) : u_mac[0].const_array(mfi);, - const auto& vflux = (is_sync) ? U_corr[1]->const_array(mfi) : u_mac[1].const_array(mfi);, - const auto& wflux = (is_sync) ? U_corr[2]->const_array(mfi) : u_mac[2].const_array(mfi);); - -#ifdef AMREX_USE_EB - const auto& flagfab = ebfact.getMultiEBCellFlagFab()[mfi]; - const auto fabtyp = flagfab.getType(bx); - - if (fabtyp == FabType::covered) - { - // - // Set advection term and move on to next iteration. - // Old ComputeAofs also set fluxes (=0) and edgestates (=covered_val) here. - // - auto const& aofs_arr = advc.array(mfi, a_comp); - amrex::ParallelFor(bx, ncomp, [aofs_arr] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { aofs_arr( i, j, k, n ) = COVERED_VAL;}); - - continue; - } -#endif - - // - // 1. Compute fluxes - // - HydroUtils::ComputeFluxesOnBoxFromState(bx, ncomp, mfi, S_arr, - AMREX_D_DECL(fx, fy, fz), - AMREX_D_DECL(xed, yed, zed), - known_edge_state, - AMREX_D_DECL(umac, vmac, wmac), //used to create edge state - AMREX_D_DECL(uflux, vflux, wflux), //used to create flux - (divu) ? divu->const_array(mfi) : Array4{}, - (forcing) ? forcing->const_array(mfi, f_comp) : Array4{}, - geom, dt, - bcrec_h, bcrec_d, iconserv_ptr, -#ifdef AMREX_USE_EB - ebfact, - /*values_on_eb_inflow*/ Array4 {}, -#endif - godunov_use_ppm, godunov_use_forces_in_trans, - is_velocity, fluxes_are_area_weighted, - scheme); - - - // - // 2. Get the right container to hold the advective update - // - FArrayBox* update_fab; - int update_comp = 0; - -#ifdef AMREX_USE_EB - // Recall that for EB we always use a temporary MF for redistribution. - update_fab = &update_MF[mfi]; -#else - FArrayBox tmp; - if (is_sync) - { - // For the sync, we need a temporary FAB to hold the update because - // we add the update to what's already in advc. - tmp.resize(bx, ncomp, The_Async_Arena()); - update_fab = &tmp; - } - else - { - // Otherwise, we can overwrite advc. - update_fab = &advc[mfi]; - update_comp = a_comp; - } -#endif - auto const& update_arr = update_fab->array(update_comp); - - - // - // 3. Compute flux divergence - // - // We compute -div here for consistency with the way we HAVE to do it for EB - // (because redistribution operates on -div rather than div) - Real mult = -1.0; -#ifdef AMREX_USE_EB - const auto& vfrac = ebfact.getVolFrac().const_array(mfi); - - if (fabtyp != FabType::regular) - { - HydroUtils::EB_ComputeDivergence( bx, update_arr, - AMREX_D_DECL( fx, fy, fz ), - vfrac, - ncomp, geom, - mult, fluxes_are_area_weighted); - } - else -#endif - { - HydroUtils::ComputeDivergence( bx, update_arr, - AMREX_D_DECL( fx, fy, fz ), - ncomp, geom, - mult, fluxes_are_area_weighted); - } - - // - // 4. Formulate convective term, if needed - // - if (any_convective && !is_sync) // Recall sync is always a conservative update - { - // Compute div(u_mac) first - FArrayBox div_umac(bx, 1, The_Async_Arena()); - auto const& divum_arr = div_umac.array(); - -#ifdef AMREX_USE_EB - const GpuArray dxinv = geom.InvCellSizeArray(); - - if (fabtyp != FabType::regular) - { - // Need AMReX routine here. Hydro version takes a flux (which always has area-fraction - // already included). - bool already_on_centroids = true; - AMREX_D_TERM(Array4 const& apx = ebfact.getAreaFrac()[0]->const_array(mfi);, - Array4 const& apy = ebfact.getAreaFrac()[1]->const_array(mfi);, - Array4 const& apz = ebfact.getAreaFrac()[2]->const_array(mfi)); - Array4 const& flagarr = flagfab.const_array(); - AMREX_HOST_DEVICE_FOR_4D(bx,div_umac.nComp(),i,j,k,n, - { - eb_compute_divergence(i,j,k,n,divum_arr,AMREX_D_DECL(umac,vmac,wmac), - Array4{}, flagarr, vfrac, - AMREX_D_DECL(apx,apy,apz), - AMREX_D_DECL(Array4{}, - Array4{}, - Array4{}), - dxinv, already_on_centroids); - }); - } - else -#endif - { - HydroUtils::ComputeDivergence(bx, divum_arr, AMREX_D_DECL(umac,vmac,wmac), - 1, geom, Real(1.0), false ); - } - - HydroUtils::ComputeConvectiveTerm(bx, ncomp, mfi, S_arr, - AMREX_D_DECL( xed, yed, zed ), - div_umac.array(), update_arr, - iconserv_ptr, -#ifdef AMREX_USE_EB - ebfact, -#endif - scheme); - } - - -#ifndef AMREX_USE_EB - // - // non-EB step 5: - // - // Recall we computed -div above, because redistribution operates - // on -div. Thus, we use -update here. - // - auto const& aofs_arr = advc.array(mfi,a_comp); - if (is_sync) - { - amrex::ParallelFor(bx, ncomp, [aofs_arr, update_arr] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { aofs_arr( i, j, k, n ) -= update_arr(i,j,k,n); }); - } - else - { - amrex::ParallelFor(bx, ncomp, [aofs_arr, update_arr] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { aofs_arr( i, j, k, n ) = -update_arr(i,j,k,n); }); - } -#endif - } - // - // The non-EB computation is complete. - // - - // EB step 5: Redistribute the advective update stashed in update_MF. - // -#ifdef AMREX_USE_EB - update_MF.FillBoundary(geom.periodicity()); - - // - // Define the "state" for StateRedistribution. - // - MultiFab rstate_tmp; - if (is_sync && redistribution_type == "StateRedist") - { - // For the sync, use the Sync data passed in via advc as the "state". - // WARNING: This choice may lead to oversmoothing. - // - // Must create a temporary copy so we're not overwriting this "state" as - // we go through the redistribution process. - rstate_tmp.define(S.boxArray(),S.DistributionMap(),ncomp,S.nGrow(), - MFInfo(),ebfact); - MultiFab::Copy(rstate_tmp,advc,a_comp,0,ncomp,S.nGrow()); - } - MultiFab const* rstate = (is_sync && redistribution_type == "StateRedist") - ? &rstate_tmp : &S; - int rstate_comp = (is_sync && redistribution_type == "StateRedist") - ? 0 : S_comp; -#endif - - const auto& dx = geom.CellSizeArray(); - - // ********************************************************************************** - // We use this hack to allow CrseAdd/FineAdd to divide area-weighted fluxes by volume - // instead of needing to un-area-weight the fluxes then divide just by dx - // ********************************************************************************** - AMREX_ALWAYS_ASSERT(fluxes_are_area_weighted); - Real dx1 = dx[0]; - for (int dir = 1; dir < AMREX_SPACEDIM; ++dir) { - dx1 *= dx[dir]; - } - - std::array dxD = {{AMREX_D_DECL(dx1, dx1, dx1)}}; - const Real* dxDp = &(dxD[0]); - - // ********************************************************************************** - // Build mask to find the ghost cells we need to correct - // ********************************************************************************** - if (coarse_fine_mask == nullptr) { - coarse_fine_mask = std::make_unique(grids, dmap, 1, 2, MFInfo(), DefaultFabFactory()); - coarse_fine_mask->BuildMask(geom.Domain(), geom.periodicity(), - level_mask_covered, level_mask_notcovered, level_mask_physbnd, level_mask_interior); - } - -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - // for (MFIter mfi(advc, TilingIfNotGPU()); mfi.isValid(); ++mfi) - for (MFIter mfi(advc, false); mfi.isValid(); ++mfi) - { - AMREX_D_TERM( const auto& fx_fab = (cfluxes[0])[mfi];, - const auto& fy_fab = (cfluxes[1])[mfi];, - const auto& fz_fab = (cfluxes[2])[mfi];); - -#ifdef AMREX_USE_EB - auto const& bx = mfi.tilebox(); - - auto const& flagfab = ebfact.getMultiEBCellFlagFab()[mfi]; - auto const& flags_arr = flagfab.const_array(); - - if (flagfab.getType(bx) != FabType::covered ) - { - auto const& aofs_arr = advc.array(mfi, a_comp); - auto const& update_arr = update_MF.array(mfi); - - FArrayBox dm_as_fine(Box::TheUnitBox(),ncomp); - FArrayBox fab_drho_as_crse(Box::TheUnitBox(),ncomp); - IArrayBox fab_rrflag_as_crse(Box::TheUnitBox()); - - if (flagfab.getType(grow(bx,4)) != FabType::regular) - { - AMREX_D_TERM( auto apx = ebfact.getAreaFrac()[0]->const_array(mfi);, - auto apy = ebfact.getAreaFrac()[1]->const_array(mfi);, - auto apz = ebfact.getAreaFrac()[2]->const_array(mfi); ); - - AMREX_D_TERM( Array4 fcx = ebfact.getFaceCent()[0]->const_array(mfi);, - Array4 fcy = ebfact.getFaceCent()[1]->const_array(mfi);, - Array4 fcz = ebfact.getFaceCent()[2]->const_array(mfi);); - - Array4 ccent_arr = ebfact.getCentroid().const_array(mfi); - Array4 const& vfrac_arr = ebfact.getVolFrac().const_array(mfi); - - // This is scratch space if calling StateRedistribute, - // but is used as the weights (here set to 1) if calling - // FluxRedistribute - Box gbx = bx; - - if (redistribution_type == "StateRedist") - gbx.grow(3); - else if (redistribution_type == "FluxRedist") - gbx.grow(2); - - int tmpfab_comp = (is_sync) ? ncomp*2 : ncomp; - FArrayBox tmpfab(gbx, tmpfab_comp, The_Async_Arena()); - Array4 scratch = tmpfab.array(0); - if (redistribution_type == "FluxRedist") - { - amrex::ParallelFor(Box(scratch), - [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { scratch(i,j,k) = 1.;}); - } - - Array4 redist_arr = (is_sync) ? tmpfab.array(ncomp) : aofs_arr; - - EBFluxRegister* fr_as_crse = nullptr; - if (do_reflux && level < parent->finestLevel()) { - NavierStokesBase& flevel = getLevel(level+1); - fr_as_crse = flevel.advflux_reg.get(); - } - - EBFluxRegister* fr_as_fine = nullptr; - if (do_reflux && level > 0) { - fr_as_fine = advflux_reg.get(); - } - - int as_crse = (fr_as_crse != nullptr); - int as_fine = (fr_as_fine != nullptr); - - FArrayBox* p_drho_as_crse = (fr_as_crse) ? - fr_as_crse->getCrseData(mfi) : &fab_drho_as_crse; - const IArrayBox* p_rrflag_as_crse = (fr_as_crse) ? - fr_as_crse->getCrseFlag(mfi) : &fab_rrflag_as_crse; - - if (fr_as_fine) { - dm_as_fine.resize(amrex::grow(bx,1),ncomp,The_Async_Arena()); - dm_as_fine.template setVal(0.0); - } - - if (redistribution_type == "FluxRedist") { - bool use_wts_in_divnc = true; - ApplyMLRedistribution( bx, ncomp, redist_arr, update_arr, - rstate->const_array(mfi, rstate_comp), scratch, flags_arr, - AMREX_D_DECL(apx,apy,apz), vfrac_arr, - AMREX_D_DECL(fcx,fcy,fcz), ccent_arr, bcrec_d, - geom, dt, redistribution_type, - as_crse, p_drho_as_crse->array(), p_rrflag_as_crse->array(), - as_fine, dm_as_fine.array(), coarse_fine_mask->const_array(mfi), - level_mask_notcovered, use_wts_in_divnc); - } else { - bool use_wts_in_divnc = true; - ApplyRedistribution( bx, ncomp, redist_arr, update_arr, - rstate->const_array(mfi, rstate_comp), scratch, flags_arr, - AMREX_D_DECL(apx,apy,apz), vfrac_arr, - AMREX_D_DECL(fcx,fcy,fcz), ccent_arr, bcrec_d, - geom, dt, redistribution_type, use_wts_in_divnc ); - } - - if (is_sync) - { - amrex::ParallelFor(bx, ncomp, [aofs_arr, redist_arr] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { aofs_arr( i, j, k, n ) -= redist_arr( i, j, k, n ); }); - } - else - { - amrex::ParallelFor(bx, ncomp, [aofs_arr, redist_arr] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { aofs_arr( i, j, k, n ) = -redist_arr( i, j, k, n ); }); - } - } - else // bx is EB regular - { - // Recall that we computed -div in previous MFIter, because - // redistribution operates on -div. Thus, we use -update here. - if (is_sync) - { - amrex::ParallelFor(bx, ncomp, [aofs_arr, update_arr] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { aofs_arr( i, j, k, n ) -= update_arr(i,j,k,n); }); - } - else - { - amrex::ParallelFor(bx, ncomp, [aofs_arr, update_arr] - AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { aofs_arr( i, j, k, n ) = -update_arr(i,j,k,n); }); - } - } - - AMREX_D_TERM(FArrayBox fx_fr_fab(fx_fab,amrex::make_alias,flux_comp,ncomp);, - FArrayBox fy_fr_fab(fy_fab,amrex::make_alias,flux_comp,ncomp);, - FArrayBox fz_fr_fab(fz_fab,amrex::make_alias,flux_comp,ncomp);); - - // Now update the flux registers (inside test on AMREX_USE_EB) - if ( do_reflux && do_crse_add && (level < parent->finestLevel()) ) { - if (flagfab.getType(amrex::grow(bx,1)) == FabType::regular) - { - getAdvFluxReg(level+1).CrseAdd(mfi, - {AMREX_D_DECL(&fx_fr_fab,&fy_fr_fab,&fz_fr_fab)}, - dxDp, dt, 0, state_indx, ncomp, amrex::RunOn::Device); - - } else if (flagfab.getType(bx) != FabType::covered ) { - getAdvFluxReg(level + 1).CrseAdd(mfi, - {AMREX_D_DECL(&fx_fr_fab,&fy_fr_fab,&fz_fr_fab)}, - dxDp, dt, (*volfrac)[mfi], - {AMREX_D_DECL(&(*areafrac[0])[mfi], &(*areafrac[1])[mfi], &(*areafrac[2])[mfi])}, - 0, state_indx, ncomp, amrex::RunOn::Device); - } - } // do_reflux && level < finest_level - - // This is a hack-y way of testing whether this ComputeAofs call - // came from the mac_sync (do_crse_add = false) - // or from the regular advance (do_crse_add = true). When the call - // comes from the mac_sync, the multiplier in FineAdd needs to have - // the opposite sign - Real sync_factor = do_crse_add ? 1.0 : -1.0; - - if ( do_reflux && do_fine_add && (level > 0)) { - if (flagfab.getType(amrex::grow(bx,1)) == FabType::regular) - { - advflux_reg->FineAdd(mfi, - {AMREX_D_DECL(&fx_fr_fab,&fy_fr_fab,&fz_fr_fab)}, - dxDp, sync_factor*dt, 0, state_indx, ncomp, amrex::RunOn::Device); - } else if (flagfab.getType(bx) != FabType::covered ) { - advflux_reg->FineAdd(mfi, - {AMREX_D_DECL(&fx_fr_fab,&fy_fr_fab,&fz_fr_fab)}, - dxDp, sync_factor*dt, (*volfrac)[mfi], - {AMREX_D_DECL(&(*areafrac[0])[mfi], &(*areafrac[1])[mfi], &(*areafrac[2])[mfi])}, - dm_as_fine, 0, state_indx, ncomp, amrex::RunOn::Device); - } - } // do_reflux && (level > 0) - } // not covered -#else - // This is a hack-y way of testing whether this ComputeAofs call - // came from the mac_sync (do_crse_add = false) - // or from the regular advance (do_crse_add = true). When the call - // comes from the mac_sync, the multiplier in FineAdd needs to have - // the opposite sign - Real sync_factor = do_crse_add ? 1.0 : -1.0; - - // Update the flux registers when no EB - if ( do_reflux && (level < parent->finestLevel()) ) { - getAdvFluxReg(level+1).CrseAdd(mfi, - {AMREX_D_DECL(&fx_fab,&fy_fab,&fz_fab)}, - dxDp, sync_factor*dt, flux_comp, state_indx, ncomp, amrex::RunOn::Device); - } // do_reflux && level < finest_level - - if ( do_reflux && (level > 0) ) { - advflux_reg->FineAdd(mfi, - {AMREX_D_DECL(&fx_fab,&fy_fab,&fz_fab)}, - dxDp, sync_factor*dt, flux_comp, state_indx, ncomp, amrex::RunOn::Device); - } // do_reflux && (level > 0) -#endif - } // mfi -} - - -#ifdef AMREX_USE_EB -void -NavierStokesBase::InitialRedistribution () -{ - // Next we must redistribute the initial solution if we are going to use - // MergeRedist or StateRedist redistribution schemes - if ( redistribution_type != "StateRedist" ) { - return; - } - - if (verbose) { - amrex::Print() << "Doing initial redistribution... " << std::endl; - } - - // Initial data are set at new time step - MultiFab& S_new = get_new_data(State_Type); - // We must fill internal ghost values before calling redistribution - // We also need any physical boundary conditions imposed if we are - // calling state redistribution (because that calls the slope routine) - FillPatchIterator S_fpi(*this, S_new, nghost_state(), state[State_Type].curTime(), - State_Type, 0, NUM_STATE); - MultiFab& Smf=S_fpi.get_mf(); - - MultiFab tmp( grids, dmap, NUM_STATE, nghost_state(), MFInfo(), Factory() ); - MultiFab::Copy(tmp, Smf, 0, 0, NUM_STATE, nghost_state()); - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(S_new,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - - auto const& fact = dynamic_cast(S_new.Factory()); - - EBCellFlagFab const& flagfab = fact.getMultiEBCellFlagFab()[mfi]; - Array4 const& flag = flagfab.const_array(); - - if ( (flagfab.getType(bx) != FabType::covered) && - (flagfab.getType(amrex::grow(bx,4)) != FabType::regular) ) - { - Array4 AMREX_D_DECL(fcx, fcy, fcz), ccc, vfrac, AMREX_D_DECL(apx, apy, apz); - - AMREX_D_TERM(fcx = fact.getFaceCent()[0]->const_array(mfi);, - fcy = fact.getFaceCent()[1]->const_array(mfi);, - fcz = fact.getFaceCent()[2]->const_array(mfi);); - - ccc = fact.getCentroid().const_array(mfi); - - AMREX_D_TERM(apx = fact.getAreaFrac()[0]->const_array(mfi);, - apy = fact.getAreaFrac()[1]->const_array(mfi);, - apz = fact.getAreaFrac()[2]->const_array(mfi);); - - vfrac = fact.getVolFrac().const_array(mfi); - - ApplyInitialRedistribution( bx, AMREX_SPACEDIM, - Smf.array(mfi), tmp.array(mfi), - flag, AMREX_D_DECL(apx, apy, apz), vfrac, - AMREX_D_DECL(fcx, fcy, fcz), - ccc, m_bcrec_velocity_d.dataPtr(), - geom, redistribution_type); - ApplyInitialRedistribution( bx, NUM_SCALARS, - Smf.array(mfi,Density), tmp.array(mfi,Density), - flag, AMREX_D_DECL(apx, apy, apz), vfrac, - AMREX_D_DECL(fcx, fcy, fcz), - ccc,m_bcrec_scalars_d.dataPtr(), - geom, redistribution_type); - } - } - - MultiFab::Copy(S_new, Smf, 0, 0, NUM_STATE, 0); -} -#endif - -// -// ls related -// -void -NavierStokesBase::fill_allgts(MultiFab& mf, int type, int scomp, int ncomp, Real time) -{ - // Fill phys bc ,ff bc, cf bc - int ngrow = mf.nGrow(); - FillPatchIterator mf_fpi(*this, mf, ngrow, time, type, scomp, ncomp); - MultiFab& mf_temp = mf_fpi.get_mf(); - // MultiFab::Copy(mfdst, mfsrc, sc, dc, nc, ng); // Copy from mfsrc to mfdst - MultiFab::Copy(mf, mf_temp, 0, scomp, ncomp, ngrow); -} - -void -NavierStokesBase::reinit() -{ - - if(verbose) amrex::Print() << "In the NavierStokesBase::reinit() " << std::endl; - - const Real* dx = geom.CellSize(); - Real dxmin = dx[0]; - for (int d=1; d,AMREX_SPACEDIM> phi_normal; - int normalize = 1; - cc_to_cc_grad(phi_normal, phi_ctime, geom, normalize); - - // Step 5: calculate diffs (phi2) and comp (phi1), add them to diffs_comp (override phi_ctime) - MultiFab phi1(grids,dmap,1,2); - MultiFab phi2(grids,dmap,1,2); - phi1.setVal(0.0); phi2.setVal(0.0); - levelset_diffcomp(phi_normal, phi_ctime, phi1, phi2, epsG, epsG2); - - // Step 6: update the level set - phi_ctime.mult(dt, 0); - MultiFab::Add(phi_ctime, phi_original, 0, 0, 1, 0); - - // Step 7: same as the Step 3 - MultiFab::Copy(S_new, phi_ctime, 0, phicomp, 1, phi_ctime.nGrow()); - fill_allgts(S_new,State_Type,phicomp,1,cur_time); - MultiFab::Copy(phi_ctime, S_new, phicomp, 0, 1, phi_ctime.nGrow()); - - } - -} - -void -NavierStokesBase::reinitialization_sussman (Real dt, - int loop_iter) -{ - - if (verbose) amrex::Print() << "In the NavierStokesBase::reinitialization_sussman() " << std::endl; - if (verbose) amrex::Print() << "loop_iter " << loop_iter << std::endl; - - // Step 1: get sgn, similar to heaviside - if (loop_iter==1) { - phi_to_sgn0(phi_original); - } - - // Step 2: RK2 - // phi2, phi3, and G0 have 2 ghost cells, initialize them as 0, - // and these multifabs only influence the minmod function at the boundary; - MultiFab phi2(grids,dmap,1,2); - MultiFab phi3(grids,dmap,1,2); - MultiFab G0(grids,dmap,1,2); - phi2.setVal(0.0); phi3.setVal(0.0); G0.setVal(0.0); - rk_first_reinit(phi_ctime, phi2, phi3, sgn0, G0, dt, phi_original); - - // Step 3: copy phi_ctime back to phi in S_new, fill phi's bc data in S_new, then - // copy it to phi_ctime - const Real cur_time = state[State_Type].curTime(); - MultiFab& S_new = get_new_data(State_Type); - MultiFab::Copy(S_new, phi_ctime, 0, phicomp, 1, phi_ctime.nGrow()); - fill_allgts(S_new,State_Type,phicomp,1,cur_time); - MultiFab::Copy(phi_ctime, S_new, phicomp, 0, 1, phi_ctime.nGrow()); - - // Step 4: RK2 - rk_second_reinit(phi_ctime, phi2, phi3, sgn0, G0, dt, phi_original); - - // Step 5: same as the Step 3 - MultiFab::Copy(S_new, phi_ctime, 0, phicomp, 1, phi_ctime.nGrow()); - fill_allgts(S_new,State_Type,phicomp,1,cur_time); - MultiFab::Copy(phi_ctime, S_new, phicomp, 0, 1, phi_ctime.nGrow()); - - // Step 6: Fix mass - // Step 6-1: set inputs variables as 0.0 - MultiFab ld(grids,dmap,1,2); - MultiFab lambdad(grids,dmap,1,2); - MultiFab deltafunc(grids,dmap,1,2); - phi2.setVal(0.0); phi3.setVal(0.0); ld.setVal(0.0); lambdad.setVal(0.0); deltafunc.setVal(0.0); - - // Step 6-2: mass_fix - mass_fix(phi_ctime, phi_original, phi2, phi3, ld, lambdad, deltafunc, dt, loop_iter); - - // Step 6-3: same as Step 5 - MultiFab::Copy(S_new, phi_ctime, 0, phicomp, 1, phi_ctime.nGrow()); - fill_allgts(S_new,State_Type,phicomp,1,cur_time); - MultiFab::Copy(phi_ctime, S_new, phicomp, 0, 1, phi_ctime.nGrow()); -} - -void -NavierStokesBase::phi_to_sgn0 (MultiFab& phi) -{ - - if(verbose) amrex::Print() << "In the NavierStokesBase::phi_to_sgn0 " << std::endl; - - sgn0.setVal(0.0); - - const Real pi = 3.141592653589793238462643383279502884197; - Real eps = calculate_eps(geom, epsilon); - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phifab = phi.array(mfi); - auto const& sgn0fab = sgn0.array(mfi); - amrex::ParallelFor(vbx, [phifab, sgn0fab, pi, eps] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - - if (phifab(i,j,k) > eps) { - sgn0fab(i,j,k) = 1.0; - } else if (phifab(i,j,k) > -eps) { - sgn0fab(i,j,k) = phifab(i,j,k) / eps + 1.0 / pi * std::sin(phifab(i,j,k) * pi / eps); - } else { - sgn0fab(i,j,k) = -1.0; - } - - }); - } - -} - -void -NavierStokesBase::rk_first_reinit (MultiFab& phi_ctime, - MultiFab& phi2, - MultiFab& phi3, - MultiFab& sgn0, - MultiFab& G0, - Real delta_t, - MultiFab& phi_ori) -{ - - if(verbose) amrex::Print() << "NavierStokesBase::rk_first_reinit " << std::endl; - - Real eps = calculate_eps(geom, epsilon); - const GpuArray dxGpu = geom.CellSizeArray(); - - // MultiFab phi1_xface(amrex::convert(grids, IntVect(AMREX_D_DECL(1,0,0))), dmap, 1, 1); - MultiFab phi1_face(amrex::convert(grids, IntVect(AMREX_D_DECL(1,1,1))), dmap, 1, 1); // A node-based mf actually - phi1_face.setVal(0.0); - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi1_face,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - Box bx = mfi.growntilebox(); - // std::cout << "bx " << bx < 0.0 && dxp * sgn0fab(i, j, k) > -dxm * sgn0fab(i, j, k)) { - ddx = dxm; - } else { - ddx = (dxp + dxm) / 2.0; - } - phi3fab(i, j, k) = pow(ddx, 2); - }); - } - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi1_face,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - Box bx = mfi.growntilebox(); - auto const& phifab = phi_ctime.array(mfi); - auto const& phi1fab = phi1_face.array(mfi); - amrex::ParallelFor(bx, [phifab, phi1fab, dxGpu] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - phi1fab(i,j,k) = ( phifab(i,j,k) - phifab(i,j-1,k) )/dxGpu[1]; - }); - } - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - Box bx = mfi.growntilebox(1); - auto const& phi1fab = phi1_face.array(mfi); - auto const& phi2fab = phi2.array(mfi); - amrex::ParallelFor(bx, [phi1fab, phi2fab, dxGpu] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - phi2fab(i,j,k) = ( phi1fab(i,j+1,k) - phi1fab(i,j,k) )/dxGpu[1]; - }); - } - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phi1fab = phi1_face.array(mfi); - auto const& phi2fab = phi2.array(mfi); - auto const& phi3fab = phi3.array(mfi); - auto const& sgn0fab = sgn0.array(mfi); - amrex::ParallelFor(vbx, [phi1fab, phi2fab, phi3fab, sgn0fab, dxGpu] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - Real dym = phi1fab(i, j, k) + minmod(phi2fab(i, j - 1, k), phi2fab(i, j, k)) * dxGpu[1] / 2.0; - Real dyp = phi1fab(i, j + 1, k) - minmod(phi2fab(i, j, k), phi2fab(i, j + 1, k)) * dxGpu[1] / 2.0; - Real ddy = 0.0; - if (dyp * sgn0fab(i, j, k) < 0.0 && dym * sgn0fab(i, j, k) < -dyp * sgn0fab(i, j, k)) { - ddy = dyp; - } else if (dym * sgn0fab(i, j, k) > 0.0 && dyp * sgn0fab(i, j, k) > -dym * sgn0fab(i, j, k)) { - ddy = dym; - } else { - ddy = (dyp + dym) / 2.0; - } - phi3fab(i, j, k) += pow(ddy, 2); - if (AMREX_SPACEDIM==2) { - phi3fab(i, j, k) = std::sqrt(phi3fab(i, j, k)); - } - }); - } - -#if (AMREX_SPACEDIM==3) - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi1_face,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - Box bx = mfi.growntilebox(); - auto const& phifab = phi_ctime.array(mfi); - auto const& phi1fab = phi1_face.array(mfi); - amrex::ParallelFor(bx, [phifab, phi1fab, dxGpu] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - phi1fab(i,j,k) = ( phifab(i,j,k) - phifab(i,j,k-1) )/dxGpu[2]; - }); - } - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - Box bx = mfi.growntilebox(1); - auto const& phi1fab = phi1_face.array(mfi); - auto const& phi2fab = phi2.array(mfi); - amrex::ParallelFor(bx, [phi1fab, phi2fab, dxGpu] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - phi2fab(i,j,k) = ( phi1fab(i,j,k+1) - phi1fab(i,j,k) )/dxGpu[2]; - }); - } - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phi1fab = phi1_face.array(mfi); - auto const& phi2fab = phi2.array(mfi); - auto const& phi3fab = phi3.array(mfi); - auto const& sgn0fab = sgn0.array(mfi); - amrex::ParallelFor(vbx, [phi1fab, phi2fab, phi3fab, sgn0fab, dxGpu] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - Real dzm = phi1fab(i, j, k) + minmod(phi2fab(i, j, k - 1), phi2fab(i, j, k)) * dxGpu[2] / 2.0; - Real dzp = phi1fab(i, j, k + 1) - minmod(phi2fab(i, j, k), phi2fab(i, j, k + 1)) * dxGpu[2] / 2.0; - Real ddz = 0.0; - if (dzp * sgn0fab(i, j, k) < 0.0 && dzm * sgn0fab(i, j, k) < -dzp * sgn0fab(i, j, k)) { - ddz = dzp; - } else if (dzm * sgn0fab(i, j, k) > 0.0 && dzp * sgn0fab(i, j, k) > -dzm * sgn0fab(i, j, k)) { - ddz = dzm; - } else { - ddz = (dzp + dzm) / 2.0; - } - phi3fab(i, j, k) += pow(ddz, 2); - phi3fab(i, j, k) = std::sqrt(phi3fab(i, j, k)); - }); - } - -#endif - - MultiFab::Copy(G0, phi3, 0, 0, 1, 1); // 1 gt - G0.plus(-1.0, 1); // 1 gt - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phifab = phi_ctime.array(mfi); - auto const& phi2fab = phi2.array(mfi); - auto const& phi3fab = phi3.array(mfi); - auto const& G0fab = G0.array(mfi); - amrex::ParallelFor(vbx, [phifab, phi2fab, phi3fab, G0fab, delta_t] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - Real sgntmp = phifab(i, j, k) / - std::sqrt( pow(phifab(i, j, k), 2) + pow(phi3fab(i, j, k)*2.0*delta_t,2) ); - phi2fab(i, j, k) = phifab(i,j,k) - delta_t*sgntmp*G0fab(i,j,k); - }); - } - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phifab = phi_ctime.array(mfi); - auto const& phi2fab = phi2.array(mfi); - amrex::ParallelFor(vbx, [phifab, phi2fab, eps] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - if (phi2fab(i,j,k)*phifab(i,j,k) < 0.0) { - if (std::abs(phifab(i,j,k)) <= eps) { - phi2fab(i, j, k) = phifab(i,j,k) * 0.1; - } - else { - amrex::Abort("sign change in rk1 bulk flow!"); - } - } - }); - } - - MultiFab::Copy(phi_ctime, phi2, 0, 0, 1, 0); // only copy interior cells -} - -void -NavierStokesBase::rk_second_reinit (MultiFab& phi_ctime, - MultiFab& phi2, - MultiFab& phi3, - MultiFab& sgn0, - MultiFab& G0, - Real delta_t, - MultiFab& phi_ori) -{ - - if(verbose) amrex::Print() << "In the NavierStokesBase::rk_second_reinit " << std::endl; - - Real eps = calculate_eps(geom, epsilon); - const GpuArray dxGpu = geom.CellSizeArray(); - - // MultiFab phi1_xface(amrex::convert(grids, IntVect(AMREX_D_DECL(1,0,0))), dmap, 1, 1); - MultiFab phi1_face(amrex::convert(grids, IntVect(AMREX_D_DECL(1,1,1))), dmap, 1, 1); // A node-based mf actually - phi1_face.setVal(0.0); - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi1_face,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - Box bx = mfi.growntilebox(); - auto const& phifab = phi_ctime.array(mfi); - auto const& phi1fab = phi1_face.array(mfi); - amrex::ParallelFor(bx, [phifab, phi1fab, dxGpu] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - phi1fab(i,j,k) = ( phifab(i,j,k) - phifab(i-1,j,k) )/dxGpu[0]; - }); - } - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - Box bx = mfi.growntilebox(1); - auto const& phi1fab = phi1_face.array(mfi); - auto const& phi2fab = phi2.array(mfi); - amrex::ParallelFor(bx, [phi1fab, phi2fab, dxGpu] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - phi2fab(i,j,k) = ( phi1fab(i+1,j,k) - phi1fab(i,j,k) )/dxGpu[0]; - }); - } - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phi1fab = phi1_face.array(mfi); - auto const& phi2fab = phi2.array(mfi); - auto const& phi3fab = phi3.array(mfi); - auto const& sgn0fab = sgn0.array(mfi); - amrex::ParallelFor(vbx, [phi1fab, phi2fab, phi3fab, sgn0fab, dxGpu] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - Real dxm = phi1fab(i, j, k) + minmod(phi2fab(i - 1, j, k), phi2fab(i, j, k)) * dxGpu[0] / 2.0; - Real dxp = phi1fab(i + 1, j, k) - minmod(phi2fab(i, j, k), phi2fab(i + 1, j, k)) * dxGpu[0] / 2.0; - Real ddx = 0.0; - if (dxp * sgn0fab(i, j, k) < 0.0 && dxm * sgn0fab(i, j, k) < -dxp * sgn0fab(i, j, k)) { - ddx = dxp; - } else if (dxm * sgn0fab(i, j, k) > 0.0 && dxp * sgn0fab(i, j, k) > -dxm * sgn0fab(i, j, k)) { - ddx = dxm; - } else { - ddx = (dxp + dxm) / 2.0; - } - phi3fab(i, j, k) = pow(ddx, 2); - }); - } - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi1_face,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - Box bx = mfi.growntilebox(); - auto const& phifab = phi_ctime.array(mfi); - auto const& phi1fab = phi1_face.array(mfi); - amrex::ParallelFor(bx, [phifab, phi1fab, dxGpu] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - phi1fab(i,j,k) = ( phifab(i,j,k) - phifab(i,j-1,k) )/dxGpu[1]; - }); - } - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - Box bx = mfi.growntilebox(1); - auto const& phi1fab = phi1_face.array(mfi); - auto const& phi2fab = phi2.array(mfi); - amrex::ParallelFor(bx, [phi1fab, phi2fab, dxGpu] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - phi2fab(i,j,k) = ( phi1fab(i,j+1,k) - phi1fab(i,j,k) )/dxGpu[1]; - }); - } - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phi1fab = phi1_face.array(mfi); - auto const& phi2fab = phi2.array(mfi); - auto const& phi3fab = phi3.array(mfi); - auto const& sgn0fab = sgn0.array(mfi); - amrex::ParallelFor(vbx, [phi1fab, phi2fab, phi3fab, sgn0fab, dxGpu] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - Real dym = phi1fab(i, j, k) + minmod(phi2fab(i, j - 1, k), phi2fab(i, j, k)) * dxGpu[1] / 2.0; - Real dyp = phi1fab(i, j + 1, k) - minmod(phi2fab(i, j, k), phi2fab(i, j + 1, k)) * dxGpu[1] / 2.0; - Real ddy = 0.0; - if (dyp * sgn0fab(i, j, k) < 0.0 && dym * sgn0fab(i, j, k) < -dyp * sgn0fab(i, j, k)) { - ddy = dyp; - } else if (dym * sgn0fab(i, j, k) > 0.0 && dyp * sgn0fab(i, j, k) > -dym * sgn0fab(i, j, k)) { - ddy = dym; - } else { - ddy = (dyp + dym) / 2.0; - } - phi3fab(i, j, k) += pow(ddy, 2); - if (AMREX_SPACEDIM==2) { - phi3fab(i, j, k) = std::sqrt(phi3fab(i, j, k)); - } - }); - } - -#if (AMREX_SPACEDIM==3) - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi1_face,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - Box bx = mfi.growntilebox(); - auto const& phifab = phi_ctime.array(mfi); - auto const& phi1fab = phi1_face.array(mfi); - amrex::ParallelFor(bx, [phifab, phi1fab, dxGpu] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - phi1fab(i,j,k) = ( phifab(i,j,k) - phifab(i,j,k-1) )/dxGpu[2]; - }); - } - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - Box bx = mfi.growntilebox(1); - auto const& phi1fab = phi1_face.array(mfi); - auto const& phi2fab = phi2.array(mfi); - amrex::ParallelFor(bx, [phi1fab, phi2fab, dxGpu] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - phi2fab(i,j,k) = ( phi1fab(i,j,k+1) - phi1fab(i,j,k) )/dxGpu[2]; - }); - } - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phi1fab = phi1_face.array(mfi); - auto const& phi2fab = phi2.array(mfi); - auto const& phi3fab = phi3.array(mfi); - auto const& sgn0fab = sgn0.array(mfi); - amrex::ParallelFor(vbx, [phi1fab, phi2fab, phi3fab, sgn0fab, dxGpu] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - Real dzm = phi1fab(i, j, k) + minmod(phi2fab(i, j, k - 1), phi2fab(i, j, k)) * dxGpu[2] / 2.0; - Real dzp = phi1fab(i, j, k + 1) - minmod(phi2fab(i, j, k), phi2fab(i, j, k + 1)) * dxGpu[2] / 2.0; - Real ddz = 0.0; - if (dzp * sgn0fab(i, j, k) < 0.0 && dzm * sgn0fab(i, j, k) < -dzp * sgn0fab(i, j, k)) { - ddz = dzp; - } else if (dzm * sgn0fab(i, j, k) > 0.0 && dzp * sgn0fab(i, j, k) > -dzm * sgn0fab(i, j, k)) { - ddz = dzm; - } else { - ddz = (dzp + dzm) / 2.0; - } - phi3fab(i, j, k) += pow(ddz, 2); - phi3fab(i, j, k) = std::sqrt(phi3fab(i, j, k)); - }); - } - -#endif - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phifab = phi_ctime.array(mfi); - auto const& phi2fab = phi2.array(mfi); - auto const& phi3fab = phi3.array(mfi); - auto const& G0fab = G0.array(mfi); - amrex::ParallelFor(vbx, [phifab, phi2fab, phi3fab, G0fab, delta_t] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - Real sgntmp = phifab(i, j, k) / - std::sqrt( pow(phifab(i, j, k), 2) + pow(phi3fab(i, j, k)*2.0*delta_t,2) ); - phi2fab(i, j, k) = phifab(i,j,k) - 0.5*delta_t*sgntmp*( - phi3fab(i,j,k) - 1.0 - G0fab(i,j,k)); - }); - } - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phifab = phi_ctime.array(mfi); - auto const& phi2fab = phi2.array(mfi); - amrex::ParallelFor(vbx, [phifab, phi2fab, eps] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - if (phi2fab(i,j,k)*phifab(i,j,k) < 0.0) { - if (std::abs(phifab(i,j,k)) <= eps) { - phi2fab(i, j, k) = phifab(i,j,k) * 0.1; - } - else { - amrex::Abort("sign change in rk2 bulk flow!"); - } - } - }); - } - - MultiFab::Copy(phi_ctime, phi2, 0, 0, 1, 0); // only copy interior cells - - // { - // // amrex::Gpu::LaunchSafeGuard lsg(false); // no needed here! - // int idx = 0; - // amrex::Print() << "phi_ctime " << " " << phi_ctime.max(idx,0) << " " << phi_ctime.min(idx,0) << " " << phi_ctime.norm2(0) << "\n"; - // } - // amrex::Abort("stop here"); - -} - -void -NavierStokesBase::mass_fix (MultiFab& phi_ctime, - MultiFab& phi_original, - MultiFab& phi2, - MultiFab& phi3, - MultiFab& ld, - MultiFab& la, - MultiFab& deltafunc, - Real delta_t, - int loop_iter) -{ - if(verbose) amrex::Print() << "NavierStokesBase::mass_fix " << std::endl; - - const Real pi = 3.141592653589793238462643383279502884197; - Real eps = calculate_eps(geom, epsilon); - Real tao = loop_iter * delta_t; - - // calculate ld and delta -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi_ctime,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.growntilebox(); - auto const& phifab = phi_ctime.array(mfi); - auto const& phiorifab = phi_original.array(mfi); - auto const& deltafab = deltafunc.array(mfi); - auto const& ldfab = ld.array(mfi); - amrex::ParallelFor(bx, [phifab, phiorifab, deltafab, ldfab, pi, eps, tao] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - ldfab(i,j,k) = (phifab(i,j,k) - phiorifab(i,j,k)) / tao; - if (phifab(i,j,k) > eps) { - deltafab(i,j,k) = 0.0; - } else if (phifab(i,j,k) > -eps) { - deltafab(i,j,k) = 0.5 * (1.0 + std::cos(phiorifab(i,j,k) * pi / eps)) / eps; - } else { - deltafab(i,j,k) = 0.0; - } - }); - } - - // get grid value of numerator (phi_2) and denominator (phi_3) -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.growntilebox(); - auto const& phi2fab = phi2.array(mfi); - auto const& phi3fab = phi3.array(mfi); - auto const& deltafab = deltafunc.array(mfi); - auto const& ldfab = ld.array(mfi); - amrex::ParallelFor(bx, [phi2fab, phi3fab, deltafab, ldfab] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - phi2fab(i,j,k) = -1.0 * deltafab(i,j,k) * ldfab(i,j,k); - phi3fab(i,j,k) = deltafab(i,j,k) * deltafab(i,j,k); - }); - } - -#if (AMREX_SPACEDIM==2) - // numerical integration -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phi2fab = phi2.array(mfi); - auto const& lafab = la.array(mfi); - amrex::ParallelFor(vbx, [phi2fab, lafab] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - Real temp_n = 0.0; - for(int jj=-1; jj<=1; jj++) { - for(int ii=-1; ii<=1; ii++) { - temp_n += phi2fab(i+ii,j+jj,k); - } - } - lafab(i,j,k) = 15.0 * phi2fab(i,j,k) + temp_n; - }); - } -#else - // numerical integration -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phi2fab = phi2.array(mfi); - auto const& lafab = la.array(mfi); - amrex::ParallelFor(vbx, [phi2fab, lafab] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - Real temp_n = 0.0; - for(int kk=-1; kk<=1; kk++) { - for(int jj=-1; jj<=1; jj++) { - for(int ii=-1; ii<=1; ii++) { - temp_n += phi2fab(i+ii,j+jj,k+kk); - } - } - } - lafab(i,j,k) = 51.0 * phi2fab(i,j,k) + temp_n; - }); - } -#endif - - // copy - MultiFab::Copy(phi2, la, 0, 0, 1, 0); // only copy interior cells - -#if (AMREX_SPACEDIM==2) - // numerical integration -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phi3fab = phi3.array(mfi); - auto const& lafab = la.array(mfi); - amrex::ParallelFor(vbx, [phi3fab, lafab] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - Real temp_d = 0.0; - for(int jj=-1; jj<=1; jj++) { - for(int ii=-1; ii<=1; ii++) { - temp_d += phi3fab(i+ii,j+jj,k); - } - } - lafab(i,j,k) = 15.0 * phi3fab(i,j,k) + temp_d; - }); - } -#else - // numerical integration -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phi3fab = phi3.array(mfi); - auto const& lafab = la.array(mfi); - amrex::ParallelFor(vbx, [phi3fab, lafab] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - Real temp_d = 0.0; - for(int kk=-1; kk<=1; kk++) { - for(int jj=-1; jj<=1; jj++) { - for(int ii=-1; ii<=1; ii++) { - temp_d += phi3fab(i+ii,j+jj,k+kk); - } - } - } - lafab(i,j,k) = 51.0 * phi3fab(i,j,k) + temp_d; - }); - } -#endif - - // copy - MultiFab::Copy(phi3, la, 0, 0, 1, 0); // only copy interior cells - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phi2fab = phi2.array(mfi); - auto const& phi3fab = phi3.array(mfi); - auto const& lafab = la.array(mfi); - amrex::ParallelFor(vbx, [phi2fab, phi3fab, lafab] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - lafab(i,j,k) = phi2fab(i,j,k) / (phi3fab(i,j,k) + 1.e-12); - }); - } - -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi_ctime,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.validbox(); - auto const& phifab = phi_ctime.array(mfi); - auto const& lafab = la.array(mfi); - auto const& deltafab = deltafunc.array(mfi); - amrex::ParallelFor(vbx, [phifab, lafab, deltafab, tao] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - phifab(i,j,k) += tao * lafab(i,j,k) * deltafab(i,j,k); - }); - } - - // { - // // amrex::Gpu::LaunchSafeGuard lsg(false); // no needed here! - // int idx = 0; - // amrex::Print() << "phi_ctime " << " " << phi_ctime.max(idx,0) << " " << phi_ctime.min(idx,0) << " " << phi_ctime.norm2(0) << "\n"; - // } - // amrex::Abort("stop here"); - -} - -MultiFab& -NavierStokesBase::get_phi_half_time () -{ - // - // Fill it in when needed ... - // -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(phi_half,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.growntilebox(); - auto const& phi_h = phi_half.array(mfi); - auto const& phi_p = phi_ptime.array(mfi); - auto const& phi_c = phi_ctime.array(mfi); - amrex::ParallelFor(bx, [phi_h, phi_p, phi_c] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - phi_h(i,j,k) = 0.5 * (phi_p(i,j,k) + phi_c(i,j,k)); - }); - } - return phi_half; +// SPDX-FileCopyrightText: 2016 - 2023 Berkeley Lab; 2023 - 2025 Yadong Zeng & ZhuXu Li<1246206018@qq.com> +// +// SPDX-License-Identifier: LicenseRef-OpenSource +// Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +// Original source: https://github.com/AMReX-Fluids/IAMR + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef AMREX_PARTICLES +#include +#endif +#ifdef AMREX_USE_EB +#include +#include +#include +#include +#include +#include +#endif +#ifdef AMREX_USE_TURBULENT_FORCING +#include +#endif + + +using namespace amrex; + +// +// Set external dirichlet BC to zero +// +struct HomExtDirFill +{ + AMREX_GPU_DEVICE + void operator() (const IntVect& iv, Array4 const& dest, + const int dcomp, const int numcomp, + GeometryData const& geom, const Real /*time*/, + const BCRec* bcr, const int /*bcomp*/, + const int /*orig_comp*/) const + { + const int* domlo = geom.Domain().loVect(); + const int* domhi = geom.Domain().hiVect(); + for (int n = 0; n < numcomp; n++ ) { + const int* bc = bcr[n].data(); + for (int idir = 0; idir < AMREX_SPACEDIM; idir++) { + if ((bc[idir] == amrex::BCType::ext_dir) and (iv[idir] < domlo[idir])) { + dest(iv, dcomp+n) = 0.0; + } + if ((bc[idir + AMREX_SPACEDIM] == amrex::BCType::ext_dir) and (iv[idir] > domhi[idir])) { + dest(iv, dcomp+n) = 0.0; + } + } + } + } +}; + +// +// A dummy function because FillPatch requires something to exist for filling dirichlet boundary conditions, +// even if we know we cannot have an ext_dir BC. +// u_mac BCs are only either periodic (BCType::int_dir) or first order extrapolation (FOEXTRAP). +// +struct umacFill +{ + AMREX_GPU_DEVICE + void operator()( + const amrex::IntVect& /*iv*/, + amrex::Array4 const& /*dummy*/, + const int /*dcomp*/, + const int numcomp, + amrex::GeometryData const& /*geom*/, + const amrex::Real /*time*/, + const amrex::BCRec* bcr, + const int bcomp, + const int /*orig_comp*/) const + { + // Abort if this function is expected to fill an ext_dir BC. + for (int n = bcomp; n < bcomp+numcomp; ++n) { + const amrex::BCRec& bc = bcr[n]; + if ( AMREX_D_TERM( bc.lo(0) == amrex::BCType::ext_dir || bc.hi(0) == amrex::BCType::ext_dir, + || bc.lo(1) == amrex::BCType::ext_dir || bc.hi(1) == amrex::BCType::ext_dir, + || bc.lo(2) == amrex::BCType::ext_dir || bc.hi(2) == amrex::BCType::ext_dir ) ) { + amrex::Abort("NavierStokesBase::umacFill: umac should not have BCType::ext_dir"); + } + } + } +}; + + +BCRec NavierStokesBase::phys_bc; +Projection* NavierStokesBase::projector = nullptr; +MacProj* NavierStokesBase::mac_projector = nullptr; + +Real NavierStokesBase::init_shrink = 1.0; +int NavierStokesBase::init_iter = 2; +int NavierStokesBase::init_vel_iter = 1; +Real NavierStokesBase::cfl = 0.8; +Real NavierStokesBase::change_max = 1.1; +Real NavierStokesBase::init_dt = -1.0; +Real NavierStokesBase::fixed_dt = -1.0; +bool NavierStokesBase::stop_when_steady = false; +Real NavierStokesBase::steady_tol = 1.0e-10; +int NavierStokesBase::initial_iter = false; +int NavierStokesBase::initial_step = false; +Real NavierStokesBase::dt_cutoff = 0.0; +int NavierStokesBase::sum_interval = -1; + +int NavierStokesBase::radius_grow = 1; +int NavierStokesBase::verbose = 0; +Real NavierStokesBase::gravity = 0.0; +int NavierStokesBase::NUM_SCALARS = 0; +int NavierStokesBase::NUM_STATE = 0; + +Vector NavierStokesBase::advectionType; +Vector NavierStokesBase::diffusionType; + +Vector NavierStokesBase::is_diffusive; +Vector NavierStokesBase::visc_coef; +Real NavierStokesBase::visc_tol = 1.0e-10; +Real NavierStokesBase::visc_abs_tol = 1.0e-10; +Real NavierStokesBase::be_cn_theta = 0.5; + +int NavierStokesBase::Tracer = -1; +int NavierStokesBase::Tracer2 = -1; +int NavierStokesBase::Temp = -1; +int NavierStokesBase::do_trac2 = 0; +int NavierStokesBase::do_temp = 0; +int NavierStokesBase::do_cons_trac = 0; +int NavierStokesBase::do_cons_trac2 = 0; +int NavierStokesBase::do_sync_proj = 1; +int NavierStokesBase::do_reflux = 1; +int NavierStokesBase::do_mac_proj = 1; +int NavierStokesBase::do_refine_outflow = 0; +int NavierStokesBase::do_derefine_outflow = 1; +int NavierStokesBase::Nbuf_outflow = 1; +int NavierStokesBase::do_denminmax = 0; +int NavierStokesBase::do_scalminmax = 0; +int NavierStokesBase::getForceVerbose = 0; +int NavierStokesBase::do_LES = 0; +int NavierStokesBase::getLESVerbose = 0; +std::string NavierStokesBase::LES_model = "Smagorinsky"; +Real NavierStokesBase::smago_Cs_cst = 0.18; +Real NavierStokesBase::sigma_Cs_cst = 1.5; + +amrex::Vector NavierStokesBase::time_avg; +amrex::Vector NavierStokesBase::time_avg_fluct; +amrex::Vector NavierStokesBase::dt_avg; +int NavierStokesBase::avg_interval = 0; +int NavierStokesBase::compute_fluctuations = 0; +int NavierStokesBase::additional_state_types_initialized = 0; +// +// "Divu_Type" means S, where divergence U = S +// "Dsdt_Type" means pd S/pd t, where S is as above +// +int NavierStokesBase::Divu_Type = -1; +int NavierStokesBase::Dsdt_Type = -1; +int NavierStokesBase::Average_Type = -1; +int NavierStokesBase::num_state_type = 2; +int NavierStokesBase::have_divu = 0; +int NavierStokesBase::have_dsdt = 0; +int NavierStokesBase::do_init_vort_proj = 0; +int NavierStokesBase::do_init_proj = 1; + +int NavierStokesBase::do_mom_diff = 0; + +std::string NavierStokesBase::advection_scheme = "Godunov_PLM"; + +bool NavierStokesBase::godunov_use_forces_in_trans = false; + +#ifdef AMREX_USE_EB +int NavierStokesBase::refine_cutcells = 1; +bool NavierStokesBase::eb_initialized = false; +bool NavierStokesBase::no_eb_in_domain = true; +bool NavierStokesBase::body_state_set = false; +std::vector NavierStokesBase::body_state; +std::string NavierStokesBase::redistribution_type = "StateRedist"; +#endif + +// +// For restart, is GradP in checkpoint file +// +int NavierStokesBase::gradp_in_checkpoint = -1; + +// is Average in checkpoint file +int NavierStokesBase::average_in_checkpoint = -1; + +// +// skip_level_projector +// +int NavierStokesBase::skip_level_projector = 0; + +int NavierStokesBase::isolver = 0; + +// +// ls related +// +int NavierStokesBase::do_phi = 0; +int NavierStokesBase::phicomp = 0; +int NavierStokesBase::epsilon = 2; + +Real NavierStokesBase::mu_a = 0.00018; +Real NavierStokesBase::mu_w = 0.01; +Real NavierStokesBase::rho_a = 0.0012; +Real NavierStokesBase::rho_w = 1.0; + +int NavierStokesBase::do_reinit = 0; +int NavierStokesBase::lev0step_of_reinit = 1; +int NavierStokesBase::number_of_reinit = 4; +int NavierStokesBase::reinit_levelset = 1; + +int NavierStokesBase::do_cons_phi = 0; +int NavierStokesBase::prescribed_vel = 0; + +int NavierStokesBase::do_cons_levelset = 0; + +// +// diffused ib +// +int NavierStokesBase::do_diffused_ib = 0; +int NavierStokesBase::advect_and_update_scalar = 1; +Real NavierStokesBase::fluid_rho = 1.0; + +namespace +{ + bool initialized = false; + int dump_plane = -1; + std::string dump_plane_name("SLABS/vel-"); + bool benchmarking = false; +} + +#ifdef AMREX_PARTICLES +bool NavierStokesBase::do_nspc = true; +bool NavierStokesBase::particles_in_plotfile = false; + +namespace +{ + // + // Name of subdirectory in chk???? holding checkpointed particles. + // + const std::string the_ns_particle_file_name("Particles"); + // + // There's really only one of these. + // + AmrTracerParticleContainer* NSPC = 0; + + std::string timestamp_dir ("Timestamps"); + std::vector timestamp_indices; + std::string particle_init_file; + std::string particle_restart_file; + std::string particle_output_file; + bool restart_from_nonparticle_chkfile = false; + int pverbose = 0; +} + +AmrTracerParticleContainer* NavierStokesBase::theNSPC () { return NSPC; } +#endif + +NavierStokesBase::NavierStokesBase () +{ + if (!additional_state_types_initialized) { + init_additional_state_types(); + } +} + +NavierStokesBase::NavierStokesBase (Amr& papa, + int lev, + const Geometry& level_geom, + const BoxArray& bl, + const DistributionMapping& dm, + Real time) + : + AmrLevel(papa,lev,level_geom,bl,dm,time) +{ + + // + // 2/2022 - Only allow RZ if there's no visc. + // MLMG Tensor solver does not currently support RZ + // + if ( level_geom.IsRZ() ) + { +#ifdef AMREX_USE_EB + amrex::Abort("Embedded boundaries with RZ geometry is not currently supported."); +#endif + for ( int n = 0; n < AMREX_SPACEDIM; n++ ) { + if ( visc_coef[n] > 0 ) { + amrex::Abort("RZ geometry with viscosity is not currently supported. To use set ns.vel_visc_coef=0"); + } + } + } + + if(!additional_state_types_initialized) { + init_additional_state_types(); + } + + // + // Alloc old_time pressure. + // + state[Press_Type].allocOldData(); + state[Gradp_Type].allocOldData(); + + define_workspace(); +} + +void NavierStokesBase::define_workspace() +{ + // + // Alloc space for density and temporary pressure variables. + // + if (level > 0) + { + rho_avg.define(grids,dmap,1,1,MFInfo(),Factory()); + + const BoxArray& P_grids = state[Press_Type].boxArray(); + p_avg.define(P_grids,dmap,1,0,MFInfo(),Factory()); + } + + rho_half.define (grids,dmap,1,1,MFInfo(),Factory()); + rho_ptime.define(grids,dmap,1,1,MFInfo(),Factory()); + rho_ctime.define(grids,dmap,1,1,MFInfo(),Factory()); + rho_qtime = nullptr; + rho_tqtime = nullptr; + + // + // Build metric coefficients for RZ calculations. + // Build volume and areas. + // + buildMetrics(); + + // + // ls related + // 2 ghost cells + // + if (do_phi) { + phi_half.define(grids,dmap,1,2,MFInfo(),Factory()); + phi_ptime.define(grids,dmap,1,2,MFInfo(),Factory()); + phi_ctime.define(grids,dmap,1,2,MFInfo(),Factory()); + heaviside.define(grids,dmap,1,2,MFInfo(),Factory()); + sgn0.define(grids,dmap,1,2,MFInfo(),Factory()); + phi_original.define(grids,dmap,1,2,MFInfo(),Factory()); + } + + // + // diffused ib + // + if (do_diffused_ib) { + const BoxArray& nba = amrex::convert(grids,IntVect::TheNodeVector()); + phi_nodal.define(nba,dmap,1,2,MFInfo(),Factory()); + pvf.define(grids,dmap,1,2,MFInfo(),Factory()); +#ifdef AMREX_PARTICLES + amrex::Print() << "check level " << level << " " << Particles::ParticleFinestLevel() << std::endl; + if (level == Particles::ParticleFinestLevel()) { + if(!Particles::isInitial){ + //particles + Particles::init_particle(gravity, geom.CellSizeArray()[0]); + } + //largra + Particles::create_particles(geom, dmap, grids); // Class constructor + } +#endif + } + + // + // Set up reflux registers. + // + sync_reg = nullptr; + viscflux_reg = nullptr; + + AMREX_ASSERT(sync_reg == nullptr); + if (level > 0 && do_sync_proj) + { + sync_reg = new SyncRegister(grids,dmap,crse_ratio); + } + + if (level > 0 && do_reflux) + { +#ifdef AMREX_USE_EB + advflux_reg = std::make_unique(); +#else + advflux_reg = std::make_unique(); +#endif + + NavierStokesBase& clevel = getLevel(level-1); + advflux_reg->define(grids, clevel.boxArray(), dmap, clevel.DistributionMap(), + parent->Geom(level), parent->Geom(level-1), + parent->refRatio(level-1),level,NUM_STATE); + +#ifndef AMREX_USE_EB + if (parent->Geom(level-1).IsRZ()) { + advflux_reg->setCrseVolume(&(clevel.Volume())); + } +#endif + + AMREX_ASSERT(viscflux_reg == nullptr); + viscflux_reg = new FluxRegister(grids,dmap,crse_ratio,level,NUM_STATE); + } + + // + // Set up the level projector. + // + if (projector == nullptr) + { + projector = new Projection(parent,&phys_bc,do_sync_proj, + parent->finestLevel(),radius_grow); + } + projector->install_level(level,this,&radius); + + // + // Set up the mac projector. + // + if (mac_projector == nullptr) + { + mac_projector = new MacProj(parent,parent->finestLevel(), + &phys_bc,radius_grow); + } + mac_projector->install_level(level,this); + + // + // Set up diffusion. + // + diffusion = std::make_unique(parent,this, + (level > 0) ? getLevel(level-1).diffusion.get() + : nullptr, + NUM_STATE,viscflux_reg,is_diffusive); + // + // Allocate the storage for variable viscosity and diffusivity + // + diffn_cc = new MultiFab(grids, dmap, NUM_STATE-Density-1, 1, MFInfo(), Factory()); + diffnp1_cc = new MultiFab(grids, dmap, NUM_STATE-Density-1, 1, MFInfo(), Factory()); + viscn_cc = new MultiFab(grids, dmap, 1, 1, MFInfo(), Factory()); + viscnp1_cc = new MultiFab(grids, dmap, 1, 1, MFInfo(), Factory()); + + // + // Initialize BCRec for use with advection + // + m_bcrec_velocity.resize(AMREX_SPACEDIM); + m_bcrec_velocity = fetchBCArray(State_Type,Xvel,AMREX_SPACEDIM); + + m_bcrec_velocity_d.resize(AMREX_SPACEDIM); + m_bcrec_velocity_d = convertToDeviceVector(m_bcrec_velocity); + + m_bcrec_scalars.resize(NUM_SCALARS); + m_bcrec_scalars = fetchBCArray(State_Type,Density,NUM_SCALARS); + + m_bcrec_scalars_d.resize(NUM_SCALARS); + m_bcrec_scalars_d = convertToDeviceVector(m_bcrec_scalars); + +} + +NavierStokesBase::~NavierStokesBase () +{ + delete rho_qtime; + delete rho_tqtime; + delete sync_reg; + delete viscflux_reg; + delete [] u_mac; + + if (mac_projector != nullptr) { + mac_projector->cleanup(level); + } + // + // Remove the arrays for variable viscosity and diffusivity + // and delete the Diffusion object + // + delete viscn_cc; + delete viscnp1_cc; + delete diffn_cc; + delete diffnp1_cc; + + diffusion.reset(); +} + +void +NavierStokesBase::variableCleanUp () +{ + desc_lst.clear(); + derive_lst.clear(); + + delete projector; + projector = nullptr; + + delete mac_projector; + mac_projector = nullptr; + +#ifdef AMREX_PARTICLES + delete NSPC; + NSPC = nullptr; +#endif +} + +void +NavierStokesBase::Initialize () +{ + if (initialized) { + return; + } + + ParmParse pp("ns"); + + pp.query("dump_plane",dump_plane); + + pp.query("benchmarking",benchmarking); + + pp.query("v",verbose); + + // + // Get timestepping parameters. + // + pp.get("cfl",cfl); + pp.query("init_iter",init_iter); + pp.query("init_vel_iter",init_vel_iter); + pp.query("init_shrink",init_shrink); + pp.query("dt_cutoff",dt_cutoff); + pp.query("change_max",change_max); + pp.query("fixed_dt",fixed_dt); + pp.query("init_dt", init_dt); + pp.query("stop_when_steady",stop_when_steady); + pp.query("steady_tol",steady_tol); + pp.query("sum_interval",sum_interval); + pp.query("gravity",gravity); + // + // Get run options. + // + pp.query("do_temp", do_temp ); + pp.query("do_trac2", do_trac2 ); + pp.query("do_cons_trac", do_cons_trac ); + pp.query("do_cons_trac2", do_cons_trac2 ); + pp.query("do_sync_proj", do_sync_proj ); + pp.query("do_reflux", do_reflux ); + pp.query("do_init_vort_proj", do_init_vort_proj); + pp.query("do_init_proj", do_init_proj ); + pp.query("do_mac_proj", do_mac_proj ); + pp.query("do_denminmax", do_denminmax ); + pp.query("do_scalminmax", do_scalminmax ); + + if ( pp.contains("do_temp_ref") || + pp.contains("do_density_ref") || + pp.contains("do_tracer_ref") || + pp.contains("do_tracer2_ref") || + pp.contains("do_vorticity_ref") ) { + amrex::Abort("ns.do_*_ref no longer supported. Refinement now implemented using refinement_indicators. For help, see UsersGuide or examples in /Exec"); + } + + pp.query("visc_tol",visc_tol); + pp.query("visc_abs_tol",visc_abs_tol); + + pp.query("getForceVerbose", getForceVerbose ); + pp.query("do_LES", do_LES ); + pp.query("getLESVerbose", getLESVerbose ); + pp.query("LES_model", LES_model ); + pp.query("smago_Cs_cst", smago_Cs_cst ); + pp.query("sigma_Cs_cst", sigma_Cs_cst ); + + pp.query("avg_interval", avg_interval ); + pp.query("compute_fluctuations", compute_fluctuations ); + +#ifdef AMREX_USE_EB + pp.query("refine_cutcells", refine_cutcells); +#endif + + int do_scalar_update_in_order = 0; + pp.query("do_scalar_update_in_order",do_scalar_update_in_order ); + if (do_scalar_update_in_order) { + amrex::Abort("NavierStokesBase::Initialize(): do_scalar_update_in_order no longer supported. If needed, please open issue on github."); + } + + // Don't let init_shrink be greater than 1 + if (init_shrink > 1.0) { + amrex::Abort("NavierStokesBase::Initialize(): init_shrink cannot be greater than 1"); + } + + pp.query("be_cn_theta",be_cn_theta); + if (be_cn_theta > 1.0 || be_cn_theta < .5) { + amrex::Abort("NavierStokesBase::Initialize(): Must have be_cn_theta <= 1.0 && >= .5"); + } + // + // Set parameters dealing with how grids are treated at outflow boundaries. + // + pp.query("do_refine_outflow",do_refine_outflow); + pp.query("do_derefine_outflow",do_derefine_outflow); + if (do_derefine_outflow == 1 && do_refine_outflow == 1) { + amrex::Abort("NavierStokesBase::Initialize(): Cannot have both do_refine_outflow==1 and do_derefine_outflow==1"); + } + + pp.query("Nbuf_outflow",Nbuf_outflow); + AMREX_ASSERT(Nbuf_outflow >= 0); + AMREX_ASSERT(!(Nbuf_outflow <= 0 && do_derefine_outflow == 1)); + + // Provide error message for depreciated volume weighted sum over a sub-domain. + // NSB only ever supported cylinder sub-domains, so check for that one. + if (pp.contains("volWgtSum_sub_dz")) { + Abort("Computing volume weighted sum over sub-domains is no longer supported. If desired, submit an issue on github"); + }; + + // Are we going to do velocity or momentum update? + pp.query("do_mom_diff",do_mom_diff); + +#ifdef AMREX_PARTICLES + read_particle_params (); +#endif + + // + // Get checkpoint info + // + pp.query("gradp_in_checkpoint", gradp_in_checkpoint); + pp.query("avg_in_checkpoint", average_in_checkpoint); + + // + // Get advection scheme options + // + if ( pp.contains("use_godunov") ) { + Abort("ns.use_godunov is depreciated. Please use ns.advection_scheme instead. Options are Godunov_PLM (default), Godunov_PPM, or BDS"); + } + + pp.query("advection_scheme", advection_scheme); + if ( advection_scheme == "MOL" ) { + Abort("MOL advection scheme is no longer supported. Current options are Godunov_PLM (default), Godunov_PPM, or BDS"); + } + if (advection_scheme != "Godunov_PLM" && advection_scheme != "Godunov_PPM" && advection_scheme != "BDS") { + Abort("Invalid advection_scheme. Options are Godunov_PLM, Godunov_PPM, BDS"); + } + + ParmParse pp2("godunov"); + pp2.query("use_forces_in_trans", godunov_use_forces_in_trans); + +#ifdef AMREX_USE_EB + // + // Advection scheme restrictions + // + if ( advection_scheme == "Godunov_PPM" || advection_scheme == "BDS") { + amrex::Abort("This advection_scheme is not implemented for EB. Please use Godunov_PLM (default)"); + } + if ( godunov_use_forces_in_trans ) { + amrex::Abort("use_forces_in_trans not implemented within EB Godunov. Set godunov.use_forces_in_trans=0."); + } + + // + // Redistribution + // + pp.query("redistribution_type", redistribution_type); + if (redistribution_type != "NoRedist" && + redistribution_type != "FluxRedist" && + redistribution_type != "StateRedist" ) { + amrex::Abort("redistribution type must be NoRedist, FluxRedist, or StateRedist"); + } +#endif + + // + // composite time advancement + // + pp.query("skip_level_projector", skip_level_projector); + + // + // ls related + // + pp.query("do_phi", do_phi); + if (do_phi) { + pp.query("epsilon", epsilon); + pp.query("mu_a", mu_a); + pp.query("mu_w", mu_w); + pp.query("rho_a", rho_a); + pp.query("rho_w", rho_w); + + pp.query("do_reinit", do_reinit); + pp.query("lev0step_of_reinit", lev0step_of_reinit); + pp.query("number_of_reinit", number_of_reinit); + pp.query("reinit_levelset", reinit_levelset); + + pp.query("do_cons_phi", do_cons_phi); + + } + + pp.query("prescribed_vel", prescribed_vel); + pp.query("isolver", isolver); + pp.query("do_diffused_ib", do_diffused_ib); + advect_and_update_scalar = !(do_diffused_ib == 1); + pp.query("fluid_rho", fluid_rho); + + amrex::ExecOnFinalize(NavierStokesBase::Finalize); + +#ifdef AMREX_PARTICLES + Particles::Initialize(); +#endif + + initialized = true; +} + +void +NavierStokesBase::Finalize () +{ + initialized = false; +} + +void +NavierStokesBase::read_geometry () +{ +#if (AMREX_SPACEDIM == 2) + // + // Must load coord here because Geometry hasn't read it in yet. + // + ParmParse pp("geometry"); + + int coord; + pp.get("coord_sys",coord); + + if ((Geometry::CoordType) coord == Geometry::RZ && phys_bc.lo(0) != PhysBCType::symmetry) + { + phys_bc.setLo(0,PhysBCType::symmetry); + amrex::Print() << "\nWarning: Setting phys_bc at xlo to PhysBCType::symmetry\n\n"; + } +#endif +} + +void +NavierStokesBase::advance_setup (Real /*time*/, + Real dt, + int iteration, + int ncycle) +{ + BL_PROFILE("NavierStokesBase::advance_setup()"); + + const int finest_level = parent->finestLevel(); + + // Same for EB vs not. + umac_n_grow = 1; + +#ifdef AMREX_PARTICLES + if (ncycle > umac_n_grow && NSPC) { + umac_n_grow = ncycle; + } +#endif + + mac_projector->setup(level); + // + // Why are they defined here versus the constructor? + // + if (level < finest_level) + { +#ifdef AMREX_USE_EB + int ng_sync = (redistribution_type == "StateRedist") ? nghost_state() : 1; +#else + int ng_sync = 1; +#endif + + if (Vsync.empty()) { + Vsync.define(grids,dmap,AMREX_SPACEDIM,ng_sync,MFInfo(),Factory()); + } + if (Ssync.empty()) { + Ssync.define(grids,dmap,NUM_STATE-AMREX_SPACEDIM,ng_sync,MFInfo(),Factory()); + } + Vsync.setVal(0); + Ssync.setVal(0); + } + // + // Set reflux registers to zero. + // + if (do_reflux && level < finest_level) + { + getAdvFluxReg(level+1).reset(); + getViscFluxReg(level+1).setVal(0.); + } + // + // Alloc space for edge velocities (normal comp only). + // + if (u_mac == nullptr || u_mac[0].nGrow() < umac_n_grow) + { + delete [] u_mac; + + u_mac = new MultiFab[AMREX_SPACEDIM]; + + for (int dir = 0; dir < AMREX_SPACEDIM; dir++) + { + const BoxArray& edgeba = getEdgeBoxArray(dir); + u_mac[dir].define(edgeba,dmap,1,umac_n_grow,MFInfo(),Factory()); + u_mac[dir].setVal(1.e40); + } + } + // + // Alloc MultiFab to hold advective update terms. + // + AMREX_ASSERT(aofs == nullptr); + aofs = new MultiFab(grids,dmap,NUM_STATE,0,MFInfo(),Factory()); + + // + // Set rho_avg. + // + if (!initial_step && level > 0 && iteration == 1) { + initRhoAvg(0.5/Real(ncycle)); + } + // + // Set up state multifabs for the advance. + // + for (int k = 0; k < num_state_type; k++) + { + bool has_old_data = state[k].hasOldData(); + // does nothing if old_data!=null + state[k].allocOldData(); + if (! has_old_data) { + state[k].oldData().setVal(0.0); + } + // swaps pointers-- reuses space, but doesn't leave new with good data. + state[k].swapTimeLevels(dt); + } + + // + // ls related + // fill the gts of old state data in the beginning + // + if (do_phi) { + // amrex::Print() << "1 " << std::endl; + const Real prev_time = state[State_Type].prevTime(); + MultiFab& S_old = get_old_data(State_Type); + int nScomp = S_old.nComp(); + fill_allgts(S_old,State_Type,0,nScomp,prev_time); + } + + make_rho_prev_time(); + + // + // ls related + // update the rho_ptime + // + if (do_phi) { + // amrex::Print() << "2 " << std::endl; + MultiFab& S_old = get_old_data(State_Type); + MultiFab::Copy(phi_ptime, S_old, phicomp, 0, 1, S_old.nGrow()); + phi_to_heavi(geom, epsilon, phi_ptime, heaviside); + heavi_to_rhoormu(heaviside, rho_w, rho_a, rho_ptime); + MultiFab::Copy(S_old, rho_ptime, 0, Density, 1, rho_ptime.nGrow()); + + MultiFab outmf_mu_ptime(grids, dmap, 1, 1, MFInfo(), Factory()); + heavi_to_rhoormu(heaviside, mu_w, mu_a, outmf_mu_ptime); + MultiFab::Copy(*viscn_cc, outmf_mu_ptime, 0, 0, 1, 1); + } + + // refRatio==4 is not currently supported + // + // If refRatio==4 to the next level coarser, and we're going to diffuse + // scalars as SoverRho, we're going to need rho at 1/4 and 3/4 time there. + // Make these things if need be. + // + // if (level > 0) + // { + // bool needs_rho4 = false; + + // if (parent->nCycle(level) == 4) + // for (int i = 0; i < NUM_STATE && !needs_rho4; ++i) + // needs_rho4 = (diffusionType[i] == Laplacian_SoverRho); + + // if (needs_rho4) + // { + // NavierStokesBase& clevel = getLevel(level-1); + // const BoxArray& cgrids = clevel.boxArray(); + // const DistributionMapping& cdmap = clevel.DistributionMap(); + // const Real ptime = clevel.state[State_Type].prevTime(); + // const Real ctime = clevel.state[State_Type].curTime(); + + // if (clevel.rho_qtime == 0) + // { + // const Real qtime = ptime + 0.25*(ctime-ptime); + // clevel.rho_qtime = new MultiFab(cgrids,cdmap,1,1); + // FillPatch(clevel,*(clevel.rho_qtime),1,qtime,State_Type,Density,1,0); + // } + // if (clevel.rho_tqtime == 0) + // { + // const Real tqtime = ptime + 0.75*(ctime-ptime); + // clevel.rho_tqtime = new MultiFab(cgrids,cdmap,1,1); + // FillPatch(clevel, *(clevel.rho_tqtime), 1, tqtime, State_Type, Density, 1, 0); + // } + // } + // } +} + +// +// Clean up after the advance function. +// +void +NavierStokesBase::advance_cleanup (int /*iteration*/, int /*ncycle*/) +{ + delete aofs; + aofs = nullptr; +} + +void +NavierStokesBase::buildMetrics () +{ + // + // We "should" only need radius when we're RZ, but some 2-D code is written to + // access it first and then "use" if if RZ. It's easier to just always build + // it for 2D than try to fix the underlying Fortran calls that take radius. + // +#if (AMREX_SPACEDIM == 2) + radius.resize(grids.size()); + + const Real dxr = geom.CellSize()[0]; + + for (int i = 0; i < grids.size(); i++) + { + const int ilo = grids[i].smallEnd(0)-radius_grow; + const int ihi = grids[i].bigEnd(0)+radius_grow; + const int len = ihi - ilo + 1; + + radius[i].resize(len); + + RealBox gridloc = RealBox(grids[i],geom.CellSize(),geom.ProbLo()); + + const Real xlo = gridloc.lo(0) + (0.5 - radius_grow)*dxr; + for (int j = 0; j < len; j++) { + radius[i][j] = xlo + j*dxr; + } + } +#endif + + // volume and area are intentionally without EB knowledge + volume.clear(); + volume.define(grids,dmap,1,GEOM_GROW); + geom.GetVolume(volume); + + for (int dir = 0; dir < AMREX_SPACEDIM; ++dir) + { + area[dir].clear(); + area[dir].define(getEdgeBoxArray(dir),dmap,1,GEOM_GROW); + geom.GetFaceArea(area[dir],dir); + } + +#ifdef AMREX_USE_EB + // make sure dx == dy == dz + const Real* dx = geom.CellSize(); + for (int i = 1; i < AMREX_SPACEDIM; i++){ + if (std::abs(dx[i]-dx[i-1]) > 1.e-12*dx[0]){ + Print()<<"dx = " + <(Factory()); + volfrac = &(ebfactory.getVolFrac()); + areafrac = ebfactory.getAreaFrac(); + +#endif +} + +// +// Default dSdt is set to zero. +// +void +NavierStokesBase::calc_dsdt (Real /*time*/, + Real dt, + MultiFab& dsdt) +{ + if (have_divu && have_dsdt) + { + // Don't think we need this here. Instead, code will use FillPatch to + // fill ghosts. + //dsdt.setVal(0); + + if (do_temp) { + MultiFab& Divu_new = get_new_data(Divu_Type); + MultiFab& Divu_old = get_old_data(Divu_Type); +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(dsdt,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + auto const& div_new = Divu_new.array(mfi); + auto const& div_old = Divu_old.array(mfi); + auto const& dsdtarr = dsdt.array(mfi); + + amrex::ParallelFor(bx, [div_new, div_old, dsdtarr, dt] + AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + dsdtarr(i,j,k) = ( div_new(i,j,k) - div_old(i,j,k) )/ dt; + }); + } + } + else + { + dsdt.setVal(0); + } + } +} + +void +NavierStokesBase::checkPoint (const std::string& dir, + std::ostream& os, + VisMF::How how, + bool dump_old) +{ + AmrLevel::checkPoint(dir, os, how, dump_old); + + if (avg_interval > 0) + { + VisMF::IO_Buffer io_buffer(VisMF::IO_Buffer_Size); + + if (ParallelDescriptor::IOProcessor()) + { + std::ofstream TImeAverageFile; + TImeAverageFile.rdbuf()->pubsetbuf(io_buffer.dataPtr(), io_buffer.size()); + std::string TAFileName(dir + "/TimeAverage"); + TImeAverageFile.open(TAFileName.c_str(), std::ofstream::out | + std::ofstream::trunc | + std::ofstream::binary); + + if( !TImeAverageFile.good()) { + amrex::FileOpenFailed(TAFileName); + } + + TImeAverageFile.precision(17); + + // write out title line + TImeAverageFile << "Writing time_average to checkpoint\n"; + + TImeAverageFile << NavierStokesBase::time_avg[level] << "\n"; + TImeAverageFile << NavierStokesBase::time_avg_fluct[level] << "\n"; + } + } + +#ifdef AMREX_PARTICLES + if (level == 0) + { + if (NSPC != 0) + NSPC->Checkpoint(dir,the_ns_particle_file_name); + } +#endif +} + +void +NavierStokesBase::computeInitialDt (int finest_level, + int /*sub_cycle*/, + Vector& n_cycle, + const Vector& /*ref_ratio*/, + Vector& dt_level, + Real stop_time) +{ + // + // Grids have been constructed, compute dt for all levels. + // + if (level > 0) + return; + + int i; + + Real dt_0 = 1.0e+100; + int n_factor = 1; + ///TODO/DEBUG: This will need to change for optimal subcycling. + for (i = 0; i <= finest_level; i++) + { + dt_level[i] = getLevel(i).initialTimeStep(); + n_factor *= n_cycle[i]; + dt_0 = std::min(dt_0,n_factor*dt_level[i]); + } + + // + // Limit dt's by the value of stop_time. + // + if (stop_time >= 0.0) + { + const Real eps = 0.0001*dt_0; + const Real cur_time = state[State_Type].curTime(); + if ((cur_time + dt_0) > (stop_time - eps)) + dt_0 = stop_time - cur_time; + } + + n_factor = 1; + for (i = 0; i <= finest_level; i++) + { + n_factor *= n_cycle[i]; + dt_level[i] = dt_0/( (Real)n_factor ); + } +} + +void +NavierStokesBase::computeNewDt (int finest_level, + int /*sub_cycle*/, + Vector& n_cycle, + const Vector& /*ref_ratio*/, + Vector& dt_min, + Vector& dt_level, + Real stop_time, + int post_regrid_flag) +{ + // + // We are at the start of a coarse grid timecycle. + // Compute the timesteps for the next iteration. + // + if (level > 0) + return; + + int i; + + Real dt_0 = 1.0e+100; + int n_factor = 1; + for (i = 0; i <= finest_level; i++) + { + NavierStokesBase& adv_level = getLevel(i); + dt_min[i] = std::min(dt_min[i],adv_level.estTimeStep()); + } + + if (fixed_dt <= 0.0) + { + if (post_regrid_flag == 1) + { + // + // Limit dt's by pre-regrid dt + // + for (i = 0; i <= finest_level; i++) + { + dt_min[i] = std::min(dt_min[i],dt_level[i]); + } + } + else + { + // + // Limit dt's by change_max * old dt + // + for (i = 0; i <= finest_level; i++) + { + if (verbose) + if (dt_min[i] > change_max*dt_level[i]) + { + amrex::Print() << "NavierStokesBase::compute_new_dt : limiting dt at level " + << i << '\n'; + amrex::Print() << " ... new dt computed: " << dt_min[i] + << '\n'; + amrex::Print() << " ... but limiting to: " + << change_max * dt_level[i] << " = " << change_max + << " * " << dt_level[i] << '\n'; + } + dt_min[i] = std::min(dt_min[i],change_max*dt_level[i]); + } + } + } + + // + // Find the minimum over all levels + // + for (i = 0; i <= finest_level; i++) + { + n_factor *= n_cycle[i]; + dt_0 = std::min(dt_0,n_factor*dt_min[i]); + } + + // + // Limit dt's by the value of stop_time. + // + const Real eps = 0.0001*dt_0; + const Real cur_time = state[State_Type].curTime(); + if (stop_time >= 0.0) + { + if ((cur_time + dt_0) > (stop_time - eps)) + dt_0 = stop_time - cur_time; + } + + // + // Set dt at each level of refinement + // + n_factor = 1; + for (i = 0; i <= finest_level; i++) + { + n_factor *= n_cycle[i]; + dt_level[i] = dt_0/( (Real)n_factor ); + } +} + +void +NavierStokesBase::create_mac_rhs (MultiFab& rhs, int nGrow, Real time, Real dt) +{ + BL_PROFILE("NavierStokesBase::create_mac_rhs()"); + + AMREX_ASSERT(rhs.nGrow()>=nGrow); + AMREX_ASSERT(rhs.boxArray()==grids); + + const int sCompDivU = 0; + const int nCompDivU = 1; + const int sCompDsdt = 0; + const int nCompDsdt = 1; + + if (have_divu) + { + FillPatch(*this,rhs,nGrow,time,Divu_Type,sCompDivU,nCompDivU,sCompDivU); + } + else + { + rhs.setVal(0.); + } + + if (have_dsdt) + { + FillPatchIterator fpi(*this,rhs,nGrow,time,Dsdt_Type,sCompDsdt,nCompDsdt); + const MultiFab& mf = fpi.get_mf(); + MultiFab::Saxpy(rhs, 0.5*dt, mf, 0, sCompDsdt, nCompDsdt, nGrow); + } +} + +void +NavierStokesBase::create_umac_grown (int nGrow, + const MultiFab* a_divu) +{ + if ( nGrow <= 0 ) { return; } + if ( nGrow > 1 ) { Print()<<"\n\nWARNING!\n NSB::create_umac_grown currently only enforces the divergnece constraint on 1 ghost cell, but nGrow > 1\n\n"; } + + + Array u_mac_fine; + AMREX_D_TERM(u_mac_fine[0] = &u_mac[0];, + u_mac_fine[1] = &u_mac[1];, + u_mac_fine[2] = &u_mac[2];); + + Geometry *fine_geom = &geom; + + //Grab the velocity phys bc fill function from the StateData StateDescriptor + AMREX_D_TERM(StateDataPhysBCFunct fine_bndry_func_x(get_state_data(State_Type),0,geom);, + StateDataPhysBCFunct fine_bndry_func_y(get_state_data(State_Type),1,geom);, + StateDataPhysBCFunct fine_bndry_func_z(get_state_data(State_Type),2,geom);); + + Array fbndyFuncArr = {AMREX_D_DECL(fine_bndry_func_x, + fine_bndry_func_y, + fine_bndry_func_z)}; + + + if ( level == 0 ) + { + for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) + { + // + // BDS needs physical BCs filled. + // Godunov needs periodic and coarse-fine ghosts filled (and handles + // physical BCs internally). + // + Real fake_time = 0.; + amrex::FillPatchSingleLevel(u_mac[idim], IntVect(nGrow), fake_time, + {u_mac_fine[idim]}, {fake_time}, + 0, 0, 1, geom, + fbndyFuncArr[idim], 0); + } + } + else // level > 0 + { + Array u_mac_crse; + AMREX_D_TERM(u_mac_crse[0] = &getLevel(level-1).u_mac[0];, + u_mac_crse[1] = &getLevel(level-1).u_mac[1];, + u_mac_crse[2] = &getLevel(level-1).u_mac[2];); + + Geometry *crse_geom = &getLevel(level-1).geom; + + // + // First interpolate, ignoring divergence constraint. Then correct + // the 1-cell wide halo of ghosts cells we need to enforce the + // constraint. + // + + // Divergence preserving interp -- This is for case of MAC solve on + // composite grid; doesn't make sense to use it here. + //Interpolater* mapper = &face_divfree_interp; + // Use linear interpolation, which matches up with old create umac grown + Interpolater* mapper = &face_linear_interp; + + // This never actually gets used because the FaceLinear Interpolator doesn't use it. + // Inside FillPatchTwoLevels, it's only use is that it's passed to the interpolator. + // Fill it with the correct thing anyway. + Array,AMREX_SPACEDIM> bcrecArr = {AMREX_D_DECL(m_bcrec_velocity, + m_bcrec_velocity, + m_bcrec_velocity)}; + Array bc_idx = {AMREX_D_DECL(0,1,2)}; + + // Grab the velocity phys bc fill function from the StateData StateDescriptor + // This will use the BCRec for velocity stored in the StateDescriptor + AMREX_D_TERM( + StateDataPhysBCFunct crse_bndry_func_x(getLevel(level-1).get_state_data(State_Type),0,*crse_geom);, + StateDataPhysBCFunct crse_bndry_func_y(getLevel(level-1).get_state_data(State_Type),1,*crse_geom);, + StateDataPhysBCFunct crse_bndry_func_z(getLevel(level-1).get_state_data(State_Type),2,*crse_geom);); + Array bf_idx = {AMREX_D_DECL(0,0,0)}; + + Array cbndyFuncArr = {AMREX_D_DECL(crse_bndry_func_x, + crse_bndry_func_y, + crse_bndry_func_z)}; + + // Use piecewise constant interpolation in time, so create fictitious variable for time + Real fake_time = 0.; + + FillPatchTwoLevels(u_mac_fine, IntVect(nGrow), fake_time, + {u_mac_crse}, {fake_time}, + {u_mac_fine}, {fake_time}, + 0, 0, 1, + *crse_geom, *fine_geom, + cbndyFuncArr, bf_idx, fbndyFuncArr, bf_idx, + crse_ratio, mapper, bcrecArr, bc_idx); + + // + // Correct u_mac to enforce the divergence constraint in the ghost cells. + // Do this by adjusting only the outer face (wrt the valid region) of the ghost + // cell, i.e. for the hi-x face, adjust umac_x(i+1). + // NOTE that this does not fill grid edges or corners. + // + + // Need 2 ghost cells here so we can safely check the status of all faces of a + // u_mac ghost cell + if (coarse_fine_mask == nullptr) { + coarse_fine_mask = std::make_unique(grids, dmap, 1, 2, MFInfo(), DefaultFabFactory()); + coarse_fine_mask->BuildMask(geom.Domain(), geom.periodicity(), + level_mask_covered, level_mask_notcovered, level_mask_physbnd, level_mask_interior); + } + + const GpuArray dx = fine_geom->CellSizeArray(); + const GpuArray dxinv = fine_geom->InvCellSizeArray(); + + const bool is_rz = geom.IsRZ(); + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(*coarse_fine_mask,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& tbx = mfi.tilebox(); + auto const& maskarr = coarse_fine_mask->const_array(mfi); + auto const& divu = (a_divu) ? a_divu->const_array(mfi) : Array4 {}; + auto const& umac = u_mac_fine[0]->array(mfi); + auto const& vmac = u_mac_fine[1]->array(mfi); + auto const& wmac = (AMREX_SPACEDIM==3) ? u_mac_fine[2]->array(mfi) : Array4 {}; + + const auto& vol = (is_rz) ? volume.const_array(mfi): Array4 {}; + const auto& ax = (is_rz) ? area[0].const_array(mfi): Array4 {}; + const auto& ay = (is_rz) ? area[1].const_array(mfi): Array4 {}; +#if (AMREX_SPACEDIM == 2) + int ks = 0; + int ke = 0; +#else + int ks = -1; + int ke = 1; +#endif + + AMREX_HOST_DEVICE_FOR_3D(mfi.growntilebox(1), i, j, k, + { + if ( maskarr(i,j,k) == level_mask_notcovered ) + { + // + // Leave cells on grid edges/corners unaltered. + // This correction scheme doesn't work for concave edges where a cell + // has faces that are all either valid or touching another ghost cell + // because then there's no "free" face to absorb the divergence constraint + // error. + // There are (>=) 1 case that are treatable, but we don't implement here: + // 1. Convex grid edges (cells that don't have any valid faces), e.g. by + // dividing the divergence constraint error equally between each face + // not touching another ghost cell + // + + int count = 0; + for(int kk(ks); kk<=ke; kk++) + { + for(int jj(-1); jj<=1; jj++) { + for(int ii(-1); ii<=1; ii++) { + if ( Math::abs(ii)+Math::abs(jj)+Math::abs(kk) == 1 && + (maskarr(i+ii,j+jj,k+kk) == interior || maskarr(i+ii,j+jj,k+kk) == level_mask_covered) ) + { + count++; + } + } + } + } + + if ( count == 1 ) + { + Real div = (divu) ? divu(i,j,k) : 0.0; + + if (is_rz) + { + Real dux = (ax(i+1,j,k)*umac(i+1,j,k) - ax(i,j,k)*umac(i,j,k)); + Real duy = (ay(i,j+1,k)*vmac(i,j+1,k) - ay(i,j,k)*vmac(i,j,k)); + + // To avoid inconsistencies between boxes, we make sure to fix box + // corners (2D) or edges (3D) that are not grid corners/edges. + // The directional check ensures we only alter one face of these + // cells. + // It's unlikely there'd ever be a case of such ghost cells abutting the + // symmetry axis, but just in case, check here. + if ( i < tbx.smallEnd(0) && maskarr(i+1,j,k) != level_mask_notcovered && ax(i,j,k) != Real(0.0) ) + { + umac(i,j,k) = (ax(i+1,j,k)*umac(i+1,j,k) + (duy - vol(i,j,k)*div))/ax(i,j,k); + } + else if ( i > tbx.bigEnd(0) && maskarr(i-1,j,k) != level_mask_notcovered ) + { + umac(i+1,j,k) = (ax(i,j,k)*umac(i,j,k) - (duy - vol(i,j,k)*div))/ax(i+1,j,k); + } + + if ( j < tbx.smallEnd(1) && maskarr(i,j+1,k) != level_mask_notcovered ) + { + vmac(i,j,k) = (ay(i,j+1,k)*vmac(i,j+1,k) + (dux - vol(i,j,k)*div))/ay(i,j,k); + } + else if ( j > tbx.bigEnd(1) && maskarr(i,j-1,k) != level_mask_notcovered ) + { + vmac(i,j+1,k) = (ay(i,j,k)*vmac(i,j,k) - (dux - vol(i,j,k)*div))/ay(i,j+1,k); + } + } + else + { + Real dux = dxinv[0]*(umac(i+1,j,k) - umac(i,j,k)); + Real duy = dxinv[1]*(vmac(i,j+1,k) - vmac(i,j,k)); + Real duz = (wmac) ? dxinv[2]*(wmac(i,j,k+1) - wmac(i,j,k)) : 0.0; + + // To avoid inconsistencies between boxes, we make sure to fix box + // corners (2D) or edges (3D) that are not grid corners/edges. + // The directional check ensures we only alter one face of these + // cells. + if ( i < tbx.smallEnd(0) && maskarr(i+1,j,k) != level_mask_notcovered ) + { + umac(i,j,k) = umac(i+1,j,k) + dx[0] * (duy + duz - div); + } + else if ( i > tbx.bigEnd(0) && maskarr(i-1,j,k) != level_mask_notcovered ) + { + umac(i+1,j,k) = umac(i,j,k) - dx[0] * (duy + duz - div); + } + + if ( j < tbx.smallEnd(1) && maskarr(i,j+1,k) != level_mask_notcovered ) + { + vmac(i,j,k) = vmac(i,j+1,k) + dx[1] * (dux + duz - div); + } + else if ( j > tbx.bigEnd(1) && maskarr(i,j-1,k) != level_mask_notcovered ) + { + vmac(i,j+1,k) = vmac(i,j,k) - dx[1] * (dux + duz - div); + } + + if (wmac) + { + if ( k < tbx.smallEnd(2) && maskarr(i,j,k+1) != level_mask_notcovered ) + { + wmac(i,j,k) = wmac(i,j,k+1) + dx[2] * (dux + duy - div); + } + else if ( k > tbx.bigEnd(2) && maskarr(i,j,k-1) != level_mask_notcovered ) + { + wmac(i,j,k+1) = wmac(i,j,k) - dx[2] * (dux + duy - div); + } + } + } + } + } + }); + } + } +} + +void +NavierStokesBase::diffuse_scalar_setup (int sigma, int& rho_flag) +{ + rho_flag = Diffusion::set_rho_flag(diffusionType[sigma]); +} + +void +NavierStokesBase::errorEst (TagBoxArray& tb, + int /*clearval*/, + int /*tagval*/, + Real /*time*/, + int /*n_error_buf*/, + int /*ngrow*/) +{ +#ifdef AMREX_USE_EB + // Enforce that the EB not cross the coarse-fine boundary + const auto& ebfactory = dynamic_cast(Factory()); + if ( !ebfactory.isAllRegular() ) + { + if (!refine_cutcells) { + amrex::Warning("Partially refined EB is still under development. This is not guaranteed to work! Please use ns.refine_cutcells=1 for now."); + } + + // Refine on cut cells + if (refine_cutcells) + { + const MultiFab& S_new = get_new_data(State_Type); + amrex::TagCutCells(tb, S_new); + } + } +#else + amrex::ignore_unused(tb); +#endif +} + + +// +// Estimate the maximum allowable timestep at a cell center. +// +Real +NavierStokesBase::estTimeStep () +{ + BL_PROFILE("NavierStokesBase::estTimeStep()"); + + if (fixed_dt > 0.0) + { + Real factor = 1.0; + + if (!(level == 0)) + { + int ratio = 1; + for (int lev = 1; lev <= level; lev++) + { + ratio *= parent->nCycle(lev); + } + factor = 1.0/Real(ratio); + } + + return factor*fixed_dt; + } + + const Real small = 1.0e-8; + Real estdt = 1.0e+20; + + MultiFab& S_new = get_new_data(State_Type); + + Vector u_max(AMREX_SPACEDIM); + Vector f_max(AMREX_SPACEDIM); + + MultiFab& Gp = get_new_data(Gradp_Type); + + // + // Find local max of velocity + // + u_max = S_new.norm0({AMREX_D_DECL(0,1,2)},0,true,true); + + // + // Compute forcing terms: in this case this means external forces and grad(p) + // Viscous terms not included since Crack-Nicholson is unconditionally stable + // so no need to account for explicit part of viscous term + // + MultiFab tforces(grids,dmap,AMREX_SPACEDIM,0,MFInfo(),Factory()); + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(S_new,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const auto& bx = mfi.tilebox(); + const auto cur_time = state[State_Type].curTime(); + auto& tforces_fab = tforces[mfi]; + + if (getForceVerbose) { + amrex::Print() << "---" << '\n' + << "H - est Time Step:" << '\n' + << "Calling getForce..." << '\n'; + } + getForce(tforces_fab,bx,0,AMREX_SPACEDIM,cur_time,S_new[mfi],S_new[mfi],Density,mfi); + + const auto& rho = S_new.array(mfi,Density); + const auto& gradp = Gp.array(mfi); + const auto& force = tforces.array(mfi); + amrex::ParallelFor(bx, [rho, gradp, force] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + Real rho_inv = 1.0/rho(i,j,k); + for (int n = 0; n < AMREX_SPACEDIM; n++) { + force(i,j,k,n) -= gradp(i,j,k,n); + force(i,j,k,n) *= rho_inv; + } + }); + } + + // + // Find local max of tforces + // + f_max = tforces.norm0({AMREX_D_DECL(0,1,2)},0,true,true); + + // + // Compute local estdt + // + const Real* dx = geom.CellSize(); + + for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) + { + if (u_max[idim] > small) + { + estdt = std::min(estdt, dx[idim]/u_max[idim]); + } + + if (f_max[idim] > small) + { + estdt = std::min(estdt, std::sqrt(2.0*dx[idim]/f_max[idim])); + } + } + + // + // Reduce estimated dt by CFL factor and find global min + // + ParallelDescriptor::ReduceRealMin(estdt); + + if ( estdt < 1.0e+20) { + // + // timestep estimation successful + // + estdt = estdt * cfl; + } + else if (init_dt > 0 ) { + // + // use init_dt, scale for amr level + // + Real factor = 1.0; + + if (!(level == 0)) + { + int ratio = 1; + for (int lev = 1; lev <= level; lev++) + { + ratio *= parent->nCycle(lev); + } + factor = 1.0/Real(ratio); + } + + estdt = factor*init_dt; + } else { + Print()<<"\nNavierStokesBase::estTimeStep() failed to provide a good timestep " + <<"(probably because initial velocity field is zero with no external forcing).\n" + <<"Use ns.init_dt to provide a reasonable timestep on coarsest level.\n" + <<"Note that ns.init_shrink will be applied to init_dt."<setVal(0); + } + else + { + divu = getState(ngrow,Divu_Type,0,1,time); + } + + return divu; +} + +// +// Fill patch dSdt. +// +MultiFab* +NavierStokesBase::getDsdt (int ngrow, Real time) +{ + MultiFab* dsdt = nullptr; + + if (!(have_dsdt && have_divu)) + { + dsdt = new MultiFab(grids,dmap,1,ngrow,MFInfo(),Factory()); + + dsdt->setVal(0); + } + else + { + dsdt = getState(ngrow,Dsdt_Type,0,1,time); + } + + return dsdt; +} + +// +// Fill patch a state component. +// +MultiFab* +NavierStokesBase::getState (int ngrow, + int state_indx, + int strt_comp, + int num_comp, + Real time) +{ + BL_PROFILE("NavierStokesBase::getState()"); + + auto* mf = new MultiFab(state[state_indx].boxArray(), + state[state_indx].DistributionMap(), + num_comp,ngrow,MFInfo(),Factory()); + + FillPatch(*this,*mf,ngrow,time,state_indx,strt_comp,num_comp,0); + + return mf; +} + +void +NavierStokesBase::getOutFlowFaces (Vector& outFaces) +{ + outFaces.resize(0); + for (int idir = 0; idir < AMREX_SPACEDIM; idir++) + { + if (phys_bc.lo(idir) == PhysBCType::outflow) + { + auto len = outFaces.size(); + outFaces.resize(len+1); + outFaces[len] = Orientation(idir,Orientation::low); + } + + if (phys_bc.hi(idir) == PhysBCType::outflow) + { + auto len = outFaces.size(); + outFaces.resize(len+1); + outFaces[len] = Orientation(idir,Orientation::high); + } + } +} + +void +NavierStokesBase::incrPAvg () +{ + // + // Increment p_avg with 1/ncycle times current pressure + // + MultiFab& P_new = get_new_data(Press_Type); + + Real alpha = 1.0/Real(parent->nCycle(level)); + + MultiFab::Saxpy(p_avg,alpha,P_new,0,0,1,0); +} + +void +NavierStokesBase::initRhoAvg (Real alpha) +{ + const MultiFab& S_new = get_new_data(State_Type); + + // Set to a ridiculous number just for debugging -- shouldn't need this otherwise + rho_avg.setVal(1.e200); + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(rho_avg,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + auto const& rhoavg = rho_avg.array(mfi); + auto const& rho_new = S_new.array(mfi,Density); + amrex::ParallelFor(bx, [rhoavg,rho_new,alpha] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + rhoavg(i,j,k) = rho_new(i,j,k) * alpha; + }); + } +} + +void +NavierStokesBase::incrRhoAvg(const MultiFab& rho_incr, + int sComp, + Real alpha) +{ + MultiFab::Saxpy(rho_avg,alpha,rho_incr,sComp,0,1,0); +} + +void +NavierStokesBase::incrRhoAvg (Real alpha) +{ + const MultiFab& S_new = get_new_data(State_Type); + incrRhoAvg(S_new,Density,alpha); +} + +// +// Fills a new level n with best level n and coarser data available. +// +void +NavierStokesBase::init (AmrLevel &old) +{ + auto* oldns = dynamic_cast(&old); + const Real dt_new = parent->dtLevel(level); + const Real cur_time = oldns->state[State_Type].curTime(); + const Real prev_time = oldns->state[State_Type].prevTime(); + const Real dt_old = cur_time - prev_time; + MultiFab& S_new = get_new_data(State_Type); + MultiFab& P_new = get_new_data(Press_Type); + MultiFab& Gp_new = get_new_data(Gradp_Type); + + setTimeLevel(cur_time,dt_old,dt_new); + + const Real cur_pres_time = state[Press_Type].curTime(); + // + // Get best state and pressure data. + // + FillPatch(old,S_new,0,cur_time,State_Type,0,NUM_STATE); + FillPatch(old,P_new,0,cur_pres_time,Press_Type,0,1); + FillPatch(old,Gp_new,Gp_new.nGrow(),cur_pres_time,Gradp_Type,0,AMREX_SPACEDIM); + + if (avg_interval > 0){ + MultiFab& Save_new = get_new_data(Average_Type); + FillPatch(old,Save_new,0,cur_time,Average_Type,0,AMREX_SPACEDIM*2); + } + + // + // Get best divu and dSdt data. + // + if (have_divu) + { + MultiFab& Divu_new = get_new_data(Divu_Type); + FillPatch(old,Divu_new,0,cur_time,Divu_Type,0,1); + + if (have_dsdt) + { + MultiFab& Dsdt_new = get_new_data(Dsdt_Type); + FillPatch(old,Dsdt_new,0,cur_time,Dsdt_Type,0,1); + } + } +} + +// +// Fills a totally new level n with data interpolated from coarser level. +// +void +NavierStokesBase::init () +{ + MultiFab& S_new = get_new_data(State_Type); + MultiFab& P_new = get_new_data(Press_Type); + MultiFab& Gp_new = get_new_data(Gradp_Type); + + AMREX_ASSERT(level > 0); + + const Vector& dt_amr = parent->dtLevel(); + Vector dt_new(level+1); + + for (int lev = 0; lev < level; lev++) { + dt_new[lev] = dt_amr[lev]; + } + // + // Guess new dt from new data (interpolated from coarser level). + // + const Real dt = dt_new[level-1]/Real(parent->MaxRefRatio(level-1)); + dt_new[level] = dt; + + parent->setDtLevel(dt_new); + // + // Compute dt based on old data. + // + NavierStokesBase& old = getLevel(level-1); + const Real cur_time = old.state[State_Type].curTime(); + const Real prev_time = old.state[State_Type].prevTime(); + const Real dt_old = (cur_time-prev_time)/Real(parent->MaxRefRatio(level-1)); + + setTimeLevel(cur_time,dt_old,dt); + + Real cur_pres_time = state[Press_Type].curTime(); + // + // Get best coarse state and pressure data. + // + FillCoarsePatch(S_new,0,cur_time,State_Type,0,NUM_STATE); + FillCoarsePatch(P_new,0,cur_pres_time,Press_Type,0,1); + FillCoarsePatch(Gp_new,0,cur_pres_time,Gradp_Type,0,AMREX_SPACEDIM,Gp_new.nGrow()); + // + // Get best coarse divU and dSdt data. + // + if (have_divu) + { + FillCoarsePatch(get_new_data(Divu_Type),0,cur_time,Divu_Type,0,1); + if (have_dsdt) + FillCoarsePatch(get_new_data(Dsdt_Type),0,cur_time,Dsdt_Type,0,1); + } +} + +void +NavierStokesBase::init_additional_state_types () +{ + additional_state_types_initialized = 1; + // + // Set "Temp" from user's variable setup. + // + int dummy_State_Type; + int have_temp = isStateVariable("temp", dummy_State_Type, Temp); + have_temp &= (dummy_State_Type == State_Type); + amrex::ignore_unused(have_temp); + AMREX_ASSERT((do_temp && have_temp) || (!do_temp && !have_temp)); + + int i_Divu = -1; + int dummy_Divu_Type; + have_divu = 0; + have_divu = isStateVariable("divu", dummy_Divu_Type, i_Divu); + have_divu = have_divu && dummy_Divu_Type == Divu_Type; + if (verbose) + { + amrex::Print() << "NavierStokesBase::init_additional_state_types()::have_divu = " + << have_divu << '\n'; + } + if (have_divu && i_Divu!=Divu) + { + amrex::Print() << "divu must be 0-th Divu_Type component in the state\n"; + amrex::Abort("NavierStokesBase::init_additional_state_types()"); + } + + int i_Dsdt = -1; + int dummy_Dsdt_Type; + have_dsdt = 0; + have_dsdt = isStateVariable("dsdt", dummy_Dsdt_Type, i_Dsdt); + have_dsdt = have_dsdt && dummy_Dsdt_Type==Dsdt_Type; + if (verbose) + { + amrex::Print() << "NavierStokesBase::init_additional_state_types()::have_dsdt = " + << have_dsdt << '\n'; + } + if (have_dsdt && i_Dsdt!=Dsdt) + { + amrex::Print() << "dsdt must be 0-th Dsdt_Type component in the state\n"; + amrex::Abort("NavierStokesBase::init_additional_state_types()"); + } + if (have_dsdt && !have_divu) + { + amrex::Print() << "Must have divu in order to have dsdt\n"; + amrex::Abort("NavierStokesBase::init_additional_state_types()"); + } + + num_state_type = desc_lst.size(); + if (verbose && ParallelDescriptor::IOProcessor()) + { + amrex::Print() << "NavierStokesBase::init_additional_state_types: num_state_type = " + << num_state_type << '\n'; + } +} + +Real +NavierStokesBase::initialTimeStep () +{ + Real returnDt = init_shrink*estTimeStep(); + + if (verbose) amrex::Print() << "Multiplying dt by init_shrink: dt = " + << returnDt << '\n'; + return returnDt; +} + +// +// Since the pressure solver always stores its estimate of the +// pressure solver in Pnew, we need to copy it to Pold at the start. +// +void +NavierStokesBase::initOldFromNew (int type, int lev) +{ + if ( lev < 0 ) { + lev = level; + } + + MultiFab& new_t = getLevel(lev).get_new_data(type); + MultiFab& old_t = getLevel(lev).get_old_data(type); + + MultiFab::Copy(old_t, new_t, 0, 0, old_t.nComp(), old_t.nGrow()); +} + +void +NavierStokesBase::level_projector (Real dt, + Real time, + int iteration) +{ + BL_PROFILE_REGION_START("R::NavierStokesBase::level_projector()"); + BL_PROFILE("NavierStokesBase::level_projector()"); + + AMREX_ASSERT(iteration > 0); + + MultiFab& U_old = get_old_data(State_Type); + MultiFab& U_new = get_new_data(State_Type); + MultiFab& P_old = get_old_data(Press_Type); + MultiFab& P_new = get_new_data(Press_Type); + + SyncRegister* crse_ptr = nullptr; + + if (level < parent->finestLevel() && do_sync_proj) + { + crse_ptr = &(getLevel(level+1).getSyncReg()); + } + + int crse_dt_ratio = (level > 0) ? parent->nCycle(level) : -1; + const Real cur_pres_time = state[Press_Type].curTime(); + + projector->level_project(level,time,dt,cur_pres_time, + geom,U_old,U_new,P_old,P_new, + get_rho_half_time(),crse_ptr,sync_reg, + crse_dt_ratio,iteration,have_divu); + + BL_PROFILE_REGION_STOP("R::NavierStokesBase::level_projector()"); +} + +void +NavierStokesBase::level_sync (int crse_iteration) +{ + BL_PROFILE_REGION_START("R::NavierStokesBase::level_sync()"); + BL_PROFILE("NavierStokesBase::level_sync()"); + + IntVect ratio = parent->refRatio(level); + const int finest_level = parent->finestLevel(); + int crse_dt_ratio = parent->nCycle(level); + Real dt = parent->dtLevel(level); + MultiFab& pres = get_new_data(Press_Type); + MultiFab& vel = get_new_data(State_Type); + SyncRegister& rhs_sync_reg = getLevel(level+1).getSyncReg(); + SyncRegister* crsr_sync_ptr = nullptr; + NavierStokesBase& fine_level = getLevel(level+1); + MultiFab& pres_fine = fine_level.get_new_data(Press_Type); + MultiFab& vel_fine = fine_level.get_new_data(State_Type); + const BoxArray& finegrids = vel_fine.boxArray(); + const DistributionMapping& finedmap = vel_fine.DistributionMap(); + + if (level > 0) { + crsr_sync_ptr = &(getLevel(level).getSyncReg()); + } + // + // Get boundary conditions. + // + const auto N = int(grids.size()); + + Vector sync_bc(N); + Vector< Vector > sync_bc_array(N); + + for (int i = 0; i < N; i++) + { + sync_bc_array[i] = getBCArray(State_Type,i,Xvel,AMREX_SPACEDIM); + sync_bc[i] = sync_bc_array[i].dataPtr(); + } + + // + // Multilevel sync projection. + // + MultiFab& Rh = get_rho_half_time(); + MultiFab cc_rhs_crse, cc_rhs_fine; + + cc_rhs_crse.define( grids, dmap,1,1,MFInfo(), Factory()); + cc_rhs_fine.define(finegrids,finedmap,1,1,MFInfo(),fine_level.Factory()); + cc_rhs_crse.setVal(0); + cc_rhs_fine.setVal(0); + + MultiFab& v_fine = fine_level.get_new_data(State_Type); + MultiFab& rho_fine = fine_level.rho_avg; + const Geometry& crse_geom = parent->Geom(level); + const BoxArray& P_finegrids = pres_fine.boxArray(); + const DistributionMapping& P_finedmap = pres_fine.DistributionMap(); + + MultiFab phi(P_finegrids,P_finedmap,1,1,MFInfo(),fine_level.Factory()); + MultiFab V_corr(finegrids,finedmap,AMREX_SPACEDIM,1,MFInfo(),fine_level.Factory()); + + V_corr.setVal(0); + // + // If periodic, enforce periodicity on Vsync. + // + if (crse_geom.isAnyPeriodic()) { + Vsync.FillBoundary(0, AMREX_SPACEDIM, crse_geom.periodicity()); + } + // + // Interpolate Vsync to fine grid correction in Vcorr. + // + SyncInterp(Vsync, level, V_corr, level+1, ratio, + 0, 0, AMREX_SPACEDIM, 0 , dt, sync_bc.dataPtr()); + // + // The multilevel projection. This computes the projection and + // adds in its contribution to levels (level) and (level+1). + // + projector->MLsyncProject(level,pres,vel,cc_rhs_crse, + pres_fine,v_fine,cc_rhs_fine, + Rh,rho_fine,Vsync,V_corr, + phi,&rhs_sync_reg,crsr_sync_ptr, + dt,ratio,crse_iteration,crse_dt_ratio, + geom); + cc_rhs_crse.clear(); + cc_rhs_fine.clear(); + // + // Correct pressure and velocities after the projection. + // + const auto Nf = int(finegrids.size()); + + ratio = IntVect::TheUnitVector(); + + Vector fine_sync_bc(Nf); + Vector< Vector > fine_sync_bc_array(Nf); + + for (int i = 0; i < Nf; i++) + { + fine_sync_bc_array[i] = getLevel(level+1).getBCArray(State_Type, + i, + Xvel, + AMREX_SPACEDIM); + fine_sync_bc[i] = fine_sync_bc_array[i].dataPtr(); + } + + for (int lev = level+2; lev <= finest_level; lev++) + { + ratio *= parent->refRatio(lev-1); + NavierStokesBase& flev = getLevel(lev); + MultiFab& P_new = flev.get_new_data(Press_Type); + MultiFab& P_old = flev.get_old_data(Press_Type); + MultiFab& U_new = flev.get_new_data(State_Type); + + SyncInterp(V_corr, level+1, U_new, lev, ratio, + 0, 0, AMREX_SPACEDIM, 1 , dt, fine_sync_bc.dataPtr()); + SyncProjInterp(phi, level+1, P_new, P_old, lev, ratio); + + flev.computeGradP(flev.state[Gradp_Type].prevTime()); + flev.computeGradP(flev.state[Gradp_Type].curTime()); + + } + + BL_PROFILE_REGION_STOP("R::NavierStokesBase::level_sync()"); +} + +void +NavierStokesBase::make_rho_prev_time () +{ + const Real prev_time = state[State_Type].prevTime(); + + FillPatch(*this,rho_ptime,1,prev_time,State_Type,Density,1,0); + +#ifdef AMREX_USE_EB + EB_set_covered(rho_ptime,COVERED_VAL); +#endif +} + +void +NavierStokesBase::make_rho_curr_time () +{ + const Real curr_time = state[State_Type].curTime(); + FillPatch(*this,rho_ctime,1,curr_time,State_Type,Density,1,0); + +#ifdef AMREX_USE_EB + EB_set_covered(rho_ctime,COVERED_VAL); +#endif +} + +void +NavierStokesBase::mac_project (Real time, + Real dt, + MultiFab& S_old, + MultiFab* divu, + int ngrow, + bool increment_vel_register) +{ + BL_PROFILE_REGION_START("R::NavierStokesBase::mac_project()"); + BL_PROFILE("NavierStokesBase::mac_project()"); + + if (verbose) { + amrex::Print() << "... mac_projection\n"; + } + + if (verbose && benchmarking) { + ParallelDescriptor::Barrier(); + } + + const Real strt_time = ParallelDescriptor::second(); + + Vector density_math_bc = fetchBCArray(State_Type,Density,1); + + mac_projector->mac_project(level,u_mac,S_old,dt,time,*divu,have_divu, + density_math_bc[0], increment_vel_register); + + create_umac_grown(ngrow, divu); + + if (verbose) + { + Real run_time = ParallelDescriptor::second() - strt_time; + const int IOProc = ParallelDescriptor::IOProcessorNumber(); + + ParallelDescriptor::ReduceRealMax(run_time,IOProc); + + amrex::Print() << "NavierStokesBase:mac_project(): lev: " + << level + << ", time: " << run_time << '\n'; + } + BL_PROFILE_REGION_STOP("R::NavierStokesBase::mac_project()"); +} + +void +NavierStokesBase::manual_tags_placement (TagBoxArray& tags, + const Vector& bf_lev) +{ + Vector outFaces; + getOutFlowFaces(outFaces); + if (! outFaces.empty()) + { + for (int i=0; inProper(); + // + // Calculate the number of level 0 cells to be left uncovered + // at the outflow. The convoluted logic allows for the fact that + // the number of uncovered cells must be a multiple of the level + // blocking factor. So, when calculating the number of coarse + // cells below, we always round the division up. + // + int N_coarse_cells = Nbuf_outflow / bf_lev[0][oDir]; + if (Nbuf_outflow % bf_lev[0][oDir] != 0) + N_coarse_cells++; + + int N_level_cells = N_coarse_cells * bf_lev[0][oDir]; + + // + // Adjust this to get the number of cells to be left uncovered at + // levels higher than 0 + // + for (int j = 1; j <= level; ++j) + { + /*** Calculate the minimum cells at this level ***/ + + const int rat = (parent->refRatio(j-1))[oDir]; + N_level_cells = N_level_cells * rat + np; + + /*** Calculate the required number of coarse cells ***/ + + N_coarse_cells = N_level_cells / bf_lev[j][oDir]; + if (N_level_cells % bf_lev[j][oDir] != 0) + N_coarse_cells++; + + /*** Calculate the corresponding number of level cells ***/ + + N_level_cells = N_coarse_cells * bf_lev[j][oDir]; + } + // + // Untag the cells near the outflow + // + if (N_coarse_cells > 0) + { + // + // Generate box at the outflow and grow it in all directions + // other than the outflow. This forces outflow cells in the + // ghostcells in directions other that oDir to be cleared. + // + Box outflowBox = amrex::adjCell(crse_domain, outFace, 1); + for (int dir = 0; dir < AMREX_SPACEDIM; dir++) + if (dir != oDir) outflowBox.grow(dir, 1); + // + // Now, grow the box into the domain (opposite direction as + // outFace) the number of cells we need to clear. + // + if (outFace.isLow()) + outflowBox.growHi(oDir, N_coarse_cells); + else + outflowBox.growLo(oDir, N_coarse_cells); + + tags.setVal(BoxArray(&outflowBox,1),TagBox::CLEAR); + } + } + } + } +} + +int +NavierStokesBase::okToContinue () +{ + // + // Check that dt is OK across AMR levels + // + int okLevel = (level > 0) ? true : (parent->dtLevel(0) > dt_cutoff); + + if (stop_when_steady) + // + // If stop_when_steady is enabled, also check that we haven't reached + // steady-state. + // + return (okLevel && !steadyState()); + else + return okLevel; +} + +int +NavierStokesBase::steadyState() +{ + if (!get_state_data(State_Type).hasOldData()) { + return false; // If nothing to compare to, must not yet be steady :) + } + + MultiFab& u_old = get_old_data(State_Type); + MultiFab& u_new = get_new_data(State_Type); + + // + // Estimate the maximum change in velocity magnitude since previous + // iteration + // + Real max_change = 0.0; + + ReduceOps reduce_op; + ReduceData reduce_data(reduce_op); + using ReduceTuple = typename decltype(reduce_data)::Type; + + // Do not OpenMP-fy this loop for now + // Unclear how to keep OpenMP and GPU implementation + // from messing with each other + for (MFIter mfi(u_old,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const auto& bx = mfi.tilebox(); + const auto& uold = u_old[mfi].array(); + const auto& unew = u_new[mfi].array(); + + reduce_op.eval(bx, reduce_data, [uold, unew] + AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple + { + Real uold_mag = 0.0; + Real unew_mag = 0.0; + for (int d = 0; d < AMREX_SPACEDIM; ++d) + { + uold_mag += uold(i,j,k,d)*uold(i,j,k,d); + unew_mag += unew(i,j,k,d)*unew(i,j,k,d); + } + + uold_mag = std::sqrt(uold_mag); + unew_mag = std::sqrt(unew_mag); + + return std::abs(unew_mag-uold_mag); + }); + + max_change = std::max(amrex::get<0>(reduce_data.value()), + max_change); + } + + ParallelDescriptor::ReduceRealMax(max_change); + + // + // System is classified as steady if the maximum change is smaller than + // prescribed tolerance + // + bool steady = max_change < steady_tol; + + if (verbose) + { + amrex::Print() << "steadyState :: \n" << "LEV = " << level + << " MAX_CHANGE = " << max_change << std::endl; + + if (steady) + { + amrex::Print() + << "System reached steady-state, stopping simulation." + << std::endl; + } + } + + return steady; +} + +// +// This function estimates the initial timesteping used by the model. +// +void +NavierStokesBase::post_init_estDT (Real& dt_init, + Vector& nc_save, + Vector& dt_save, + Real stop_time) +{ + const Real strt_time = state[State_Type].curTime(); + const int finest_level = parent->finestLevel(); + + dt_init = 1.0e+100; + + int n_factor; + for (int k = 0; k <= finest_level; k++) + { + nc_save[k] = parent->nCycle(k); + dt_save[k] = getLevel(k).initialTimeStep(); + + n_factor = 1; + for (int m = finest_level; m > k; m--) + n_factor *= parent->nCycle(m); + dt_init = std::min( dt_init, dt_save[k]/((Real) n_factor) ); + } + + Vector dt_level(finest_level+1,dt_init); + Vector n_cycle(finest_level+1,1); + + Real dt0 = dt_save[0]; + n_factor = 1; + for (int k = 0; k <= finest_level; k++) + { + n_factor *= nc_save[k]; + dt0 = std::min(dt0,n_factor*dt_save[k]); + } + + if (stop_time >= 0.0) + { + const Real eps = 0.0001*dt0; + if ((strt_time + dt0) > (stop_time - eps)) + dt0 = stop_time - strt_time; + } + + n_factor = 1; + for (int k = 0; k <= finest_level; k++) + { + n_factor *= nc_save[k]; + dt_save[k] = dt0/( (Real) n_factor); + } + // + // Hack. + // + parent->setDtLevel(dt_level); + parent->setNCycle(n_cycle); + for (int k = 0; k <= finest_level; k++) + { + getLevel(k).setTimeLevel(strt_time,dt_init,dt_init); + } +} + +// +// This function ensures that the state is initially consistent +// with respect to the divergence condition and fields are initially consistent +// +void +NavierStokesBase::post_init_state () +{ + const int finest_level = parent->finestLevel(); + const Real divu_time = have_divu ? state[Divu_Type].curTime() + : state[Press_Type].curTime(); + + if (do_init_vort_proj) + { + amrex::Abort("NavierStokesBase::post_init_state(): initialVorticityProject not tested with new Gradp!!! See comments Projection::initialVorticityProject.\n"); + // + // NOTE: this assumes have_divu == 0. + // Only used if vorticity is used to initialize the velocity field. + // + AMREX_ASSERT(projector != nullptr); + + if (verbose) amrex::Print() << "calling initialVorticityProject" << std::endl; + + projector->initialVorticityProject(0); + + if (verbose) amrex::Print() << "done calling initialVorticityProject" << std::endl; + } + + if (do_init_proj && projector) + { + // + // Do sync project to define divergence free velocity field. + // + if (verbose) amrex::Print() << "calling initialVelocityProject" << std::endl; + + projector->initialVelocityProject(0,divu_time,have_divu,init_vel_iter); + + if (verbose) amrex::Print() << "done calling initialVelocityProject" << std::endl; + } + + NavierStokesBase::initial_step = true; + // + // Average velocity and scalar data down from finer levels + // so that conserved data is consistent between levels. + // This might not be the most efficient way of doing things + // (since initialVelocityProject will average down vel, P and Gradp), + // but it does ensure everything is averaged down for all cases + // (e.g. initialVelocityProject doesn't get called or init_vel_iter<=0). + // + for (int k = finest_level-1; k>= 0; k--) + { + getLevel(k).avgDown(); + } + + if (do_init_proj && projector && (std::fabs(gravity)) > 0.){ + // + // Do projection to establish initially hydrostatic pressure field. + // + if (verbose) amrex::Print() << "calling initialPressureProject" << std::endl; + + projector->initialPressureProject(0); + + if (verbose) amrex::Print() << "done calling initialPressureProject" << std::endl; + } + // + // Make sure there's not NANs in old pressure field. + // End up with P_old = P_new as is the case when exiting initialPressureProject + // + if(!do_init_proj) + { + for (int k = finest_level; k>= 0; k--) + { + initOldFromNew(Press_Type, k); + initOldFromNew(Gradp_Type, k); + } + } +} + +// +// Build any additional data structures after regrid. +// +void +NavierStokesBase::post_regrid (int lbase, + int /*new_finest*/) +{ +#ifdef AMREX_PARTICLES + if (NSPC && level == lbase) + { + NSPC->Redistribute(lbase); + } +#else + amrex::ignore_unused(lbase); +#endif +} + +// +// Build any additional data structures after restart. +// +void +NavierStokesBase::post_restart () +{ + make_rho_prev_time(); + make_rho_curr_time(); + + if (avg_interval > 0){ + + const int finest_level = parent->finestLevel(); + NavierStokesBase::time_avg.resize(finest_level+1); + NavierStokesBase::time_avg_fluct.resize(finest_level+1); + NavierStokesBase::dt_avg.resize(finest_level+1); + + // + // We assume that if Average_Type is not present, we have just activated + // the start of averaging + // + if ( average_in_checkpoint==0 ) + { + Print()<<"WARNING! Average not found in checkpoint file. Creating data" + <theRestartFile(); + + std::string File(file + "/TimeAverage"); + Vector fileCharPtr; + ParallelDescriptor::ReadAndBcastFile(File, fileCharPtr); + std::string fileCharPtrString(fileCharPtr.dataPtr()); + std::istringstream isp(fileCharPtrString, std::istringstream::in); + + // read in title line + std::getline(isp, line); + + isp >> NavierStokesBase::time_avg[level]; + isp >> NavierStokesBase::time_avg_fluct[level]; + NavierStokesBase::dt_avg[level] = 0; + + } + } + +#ifdef AMREX_USE_TURBULENT_FORCING + // + // Initialize data structures used for homogeneous isentropic forced turbulence. + // Only need to do it once. + if (level == 0) + TurbulentForcing::init_turbulent_forcing(geom.ProbLoArray(),geom.ProbHiArray()); +#endif + +#ifdef AMREX_PARTICLES + post_restart_particle (); +#endif +} + +// +// Integration cycle on fine level grids is complete . +// post_timestep() is responsible for syncing levels together. +// +// The registers used for level syncing are initialized in the +// coarse level advance and incremented in the fine level advance. +// These quantities are described in comments above advance_setup. +// +void +NavierStokesBase::post_timestep (int crse_iteration) +{ + BL_PROFILE("NavierStokesBase::post_timestep()"); + + const int finest_level = parent->finestLevel(); + +#ifdef AMREX_PARTICLES + post_timestep_particle (crse_iteration); +#endif + + if (level == parent->finestLevel()) + { + delete [] u_mac; + u_mac = nullptr; + } + + if (do_reflux && level < finest_level) + reflux(); + + // + // Average everything down, including P and Gradp. + // Even though the multilevel projections average down, only + // single level projections have been done for current timestep. + // The linearity of the average ensures that if we average down P + // and Gp here, then we may simply add the incremental correction + // (which get averaged down in amrex) during the sync projection. + // + // avgDown also updates rho_ctime since it's needed for rho_half, + // which is used in the sync projection. + // + if (level < finest_level) + avgDown(); + + if (do_mac_proj && level < finest_level) + mac_sync(); + + // set Density to fluid_rho on all regions + if (do_diffused_ib) { + MultiFab& S_new = get_new_data(State_Type); + S_new.setVal(fluid_rho, Density, 1, S_new.nGrow()); + if (level < parent->finestLevel()) { + auto& fine_lev = getLevel(level+1); + MultiFab& S_fine = fine_lev.get_new_data(State_Type); + S_fine.setVal(fluid_rho, Density, 1, S_fine.nGrow()); + } + } + + if (do_sync_proj && (level < finest_level)) + level_sync(crse_iteration); + + + // + // Test for conservation. + // + if (level==0 && sum_interval>0 && (parent->levelSteps(0)%sum_interval == 0)) + { + sum_integrated_quantities(); + } + + if (level > 0) incrPAvg(); + + // Copy pvf to Tracer before writing Tracer into plt files on the finest level, + // or set Tracer to zero on the coarser/coarsest levels + if (do_diffused_ib) { + MultiFab& S_new = get_new_data(State_Type); + if (level == parent->finestLevel()) { + MultiFab::Copy(S_new, pvf, 0, Tracer, 1, pvf.nGrow()); // Note: the ghost cell region of pvf is zero. + } + else { + S_new.setVal(0.0, Tracer, 1, S_new.nGrow()); + // We need to average the Tracer here since we use it for refinement/de-refinement + auto& fine_lev = getLevel(level+1); + MultiFab& S_fine = fine_lev.get_new_data(State_Type); + average_down(S_fine, S_new, Tracer, 1); + } + } + + if (level == 0 && dump_plane >= 0) + { + Box bx = geom.Domain(); + + AMREX_ASSERT(bx.bigEnd(AMREX_SPACEDIM-1) >= dump_plane); + + bx.setSmall(AMREX_SPACEDIM-1, dump_plane); + bx.setBig (AMREX_SPACEDIM-1, dump_plane); + + BoxArray ba(bx); + DistributionMapping dm{ba}; + + MultiFab mf(ba, dm, AMREX_SPACEDIM, 0, MFInfo(), Factory()); + + mf.ParallelCopy(get_new_data(State_Type), Xvel, 0, AMREX_SPACEDIM); + + if (ParallelDescriptor::MyProc() == mf.DistributionMap()[0]) + { + char buf[64]; + sprintf(buf, "%14.12e", state[State_Type].curTime()); + + std::string name(dump_plane_name); + name += buf; + name += ".fab"; + + std::ofstream ofs; + ofs.open(name.c_str(),std::ios::out|std::ios::trunc|std::ios::binary); + if (!ofs.good()) + amrex::FileOpenFailed(name); + + mf[0].writeOn(ofs); + } + } + + if (avg_interval > 0) + { + const amrex::Real dt_level = parent->dtLevel(level); + time_average(time_avg[level], time_avg_fluct[level], dt_avg[level], dt_level); + } + +} + +// +// Reset the time levels to time (time) and timestep dt. +// This is done at the end of the timestep in the pressure iteration section. +// +void +NavierStokesBase::resetState (Real time, + Real dt_old, + Real dt_new) +{ + // + // Reset state types. + // + state[State_Type].reset(); + state[State_Type].setTimeLevel(time,dt_old,dt_new); + + // + // Set P & gradP old = new. This way we retain new after + // advance_setup() does swap(old,new). + // + initOldFromNew(Press_Type); + state[Press_Type].setTimeLevel(time-dt_old,dt_old,dt_new); + + initOldFromNew(Gradp_Type); + state[Gradp_Type].setTimeLevel(time-dt_old,dt_old,dt_new); + // + // Reset state types for divu not equal to zero. + // + if (have_divu) + { + state[Divu_Type].reset(); + state[Divu_Type].setTimeLevel(time,dt_old,dt_new); + if (have_dsdt) + { + // + // Dont do this, we want to improve dsdt with press iters + // but we do need to make sure time is set correctly.. + // state[Dsdt_Type].reset(); + state[Dsdt_Type].setTimeLevel(time,dt_old,dt_new); + } + } +} + +// +// Old checkpoint files may not have Gradp_Type and/or Average_Type. +// +void +NavierStokesBase::set_state_in_checkpoint (Vector& state_in_checkpoint) +{ + // + // Abort if any of the NSB::*_in_checkpoint variables haven't been set by user. + // + if ( gradp_in_checkpoint<0 || average_in_checkpoint<0 ) + Abort("\n\n Checkpoint file is missing one or more state types. Set both\n ns.gradp_in_checkpoint and ns.avg_in_checkpoint to identify missing\n data. Set to 1 if present in checkpoint, 0 if not present. If unsure,\n try setting both to 0.\n\n If you just activated Time Averaging, you should add \n ns.avg_in_checkpoint=0 ns.gradp_in_checkpoint=1 \n\n"); + + // + // Tell AmrLevel which types are in the checkpoint, so it knows what to copy. + // state_in_checkpoint is initialized to all true. + // + if ( gradp_in_checkpoint==0 ) + state_in_checkpoint[Gradp_Type] = 0; + + if ( average_in_checkpoint==0 && avg_interval>0 ) + state_in_checkpoint[Average_Type] = 0; +} + +void +NavierStokesBase::restart (Amr& papa, + std::istream& is, + bool bReadSpecial) +{ + Print()<<"\nWARNING! Note that you can't drop data from the checkpoint file.\n" + <<" If your checkpoint file contains Average_Type, then your inputs\n" + <<" must also specify ns.avg_interval>0.\n"<levelSteps(0)); + ParallelDescriptor::Barrier(); + } +#endif + + define_workspace(); +} + +void +NavierStokesBase::scalar_advection_update (Real dt, + int first_scalar, + int last_scalar) +{ + BL_PROFILE("NavierStokesBase::scalar_advection_update()"); + + MultiFab& S_old = get_old_data(State_Type); + MultiFab& S_new = get_new_data(State_Type); + MultiFab& Aofs = *aofs; + + const Real prev_time = state[State_Type].prevTime(); + + + // + // Compute inviscid estimate of scalars. + // Do rho separately, as rho does not have forcing terms and is always conservative. + // + int sComp = first_scalar; + + if (sComp == Density) + { +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(S_old,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + const auto& Snew = S_new[mfi].array(Density); + const auto& Sold = S_old[mfi].const_array(Density); + const auto& advc = Aofs[mfi].const_array(Density); + + amrex::ParallelFor(bx, [ Snew, Sold, advc, dt] + AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Snew(i,j,k) = Sold(i,j,k) - dt * advc(i,j,k); + }); + } + + // + // Call ScalMinMax to avoid overshoots in density. + // + if (do_denminmax) + { + // + // Must do FillPatch here instead of MF iterator because we need the + // boundary values in the old data (especially at inflow) + // + const int index_new_s = Density; + const int index_new_rho = Density; + const int index_old_s = index_new_s - Density; + const int index_old_rho = index_new_rho - Density; + + FillPatchIterator S_fpi(*this,S_old,1,prev_time,State_Type,Density,1); + MultiFab& Smf=S_fpi.get_mf(); + + ConservativeScalMinMax(S_new, index_new_s, index_new_rho, + Smf, index_old_s, index_old_rho); + + } + + ++sComp; + } + + // + // Advective update of other scalars + // + if (sComp <= last_scalar) + { + // + // Average mac face velocity to cell-centers for use in generating external + // forcing term in getForce() + // + // NOTE that default getForce() does not use Vel or Scal, user must supply the + // forcing function for that case. + // + MultiFab Vel(grids, dmap, AMREX_SPACEDIM, 0, MFInfo(), Factory()); +#ifdef AMREX_USE_EB + // This isn't quite right because it's face-centers to cell-centers + // what's really wanted is face-centroid to cell-centroid + EB_average_face_to_cellcenter(Vel, 0, Array{{AMREX_D_DECL(&u_mac[0],&u_mac[1],&u_mac[2])}}); +#else + average_face_to_cellcenter(Vel, 0, Array{{AMREX_D_DECL(&u_mac[0],&u_mac[1],&u_mac[2])}}); +#endif + +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + { + FArrayBox tforces; + + for (MFIter mfi(S_old,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + if (getForceVerbose) { + amrex::Print() << "---" << '\n' << "E - scalar advection update (half time):" << '\n'; + } + + // + // Create an estimate for time n+1 using advection term only; it's the best + // we've got at this point. Then, average the new and old time to get + // Crank-Nicholson half time approximation. + // + const Box& bx = mfi.tilebox(); + // getForce() expects all scalars to be present in Scal, and may need them + // (particularly density) to make forcing term. + FArrayBox Scal(bx,NUM_SCALARS); + // Scal protected from early destruction by Gpu::synchronize at end of loop. + const auto& Sn = S_old[mfi].const_array(Density); + const auto& Sarr = Scal.array(); + const auto& aofs_dens = Aofs[mfi].const_array(Density); + // Create a local copy for lambda capture + int numscal = NUM_SCALARS; + + amrex::ParallelFor(bx, [ Sn, Sarr, aofs_dens, dt, numscal] + AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + int n = 0; + // For density, we can create the Crank-Nicholson half-time approximation: + // Snew = Sold - dt*adv + // Shalftime = Sarr = (Snew + Sold)/2 + Sarr(i,j,k,n) = Sn(i,j,k,n) - 0.5 * dt * aofs_dens(i,j,k,n); + + // For other scalars, which may have diffusive or forcing terms, this is + // a safe choice. + for ( n = 1; n < numscal; n++ ) + { + Sarr(i,j,k,n) = Sn(i,j,k,n); + } + }); + + const Real halftime = 0.5 * ( state[State_Type].curTime() + + state[State_Type].prevTime() ); + FArrayBox& Vel_fab = Vel[mfi]; + + int num_comp = last_scalar - sComp + 1; + // Note that in general, num_comp != NUM_SCALAR + tforces.resize(bx,num_comp); + // tforces protected from early destruction by Gpu::synchronize at end of loop. + getForce(tforces,bx,sComp,num_comp,halftime,Vel_fab,Scal,0,mfi); + + const auto& Snew = S_new[mfi].array(sComp); + const auto& Sold = S_old[mfi].const_array(sComp); + const auto& advc = Aofs[mfi].const_array(sComp); + const auto& tf = tforces.const_array(); + const auto& rho = Scal.const_array(); + + // Advection type + amrex::Vector iconserv_h; + iconserv_h.resize(num_comp); + for (int i = 0; i < num_comp; ++i) { + iconserv_h[i] = (advectionType[sComp+i] == Conservative) ? 1 : 0; + } + amrex::Gpu::DeviceVector iconserv_d; + iconserv_d.resize(num_comp); + Gpu::copy(Gpu::hostToDevice, iconserv_h.begin(), iconserv_h.end(), iconserv_d.begin()); + const int* iconserv = iconserv_d.data(); + + // Recall tforces is always density-weighted + amrex::ParallelFor(bx, num_comp, [ Snew, Sold, advc, tf, dt, rho, iconserv] + AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept + { + if ( iconserv[n] == 1 ) { + Snew(i,j,k,n) = Sold(i,j,k,n) + dt * ( - advc(i,j,k,n) + tf(i,j,k,n) ); + } + else { + Snew(i,j,k,n) = Sold(i,j,k,n) + dt * ( - advc(i,j,k,n) + tf(i,j,k,n)/rho(i,j,k) ); + } + }); + + // Either need this synchronize here, or elixirs. Not sure if it matters which + amrex::Gpu::synchronize(); + } + } + } + + // + // Call ScalMinMax to avoid overshoots in the scalars. + // + if ( do_scalminmax && (sComp <= last_scalar) ) + { + const int num_scalars = last_scalar - Density + 1; + + // + // Must do FillPatch here instead of MF iterator because we need the + // boundary values in the old data (especially at inflow). + // + FillPatchIterator S_fpi(*this,S_old,1,prev_time,State_Type,Density,num_scalars); + MultiFab& Smf=S_fpi.get_mf(); + + for (int sigma = sComp; sigma <= last_scalar; sigma++) + { + const int index_new_s = sigma; + const int index_new_rho = Density; + const int index_old_s = index_new_s - Density; + const int index_old_rho = index_new_rho - Density; + + if (advectionType[sigma] == Conservative) + { + ConservativeScalMinMax(S_new, index_new_s, index_new_rho, + Smf, index_old_s, index_old_rho); + } + else if (advectionType[sigma] == NonConservative) + { + ConvectiveScalMinMax(S_new, index_new_s, Smf, index_old_s); + } + } + } + + // + // Check the max of Snew and for NANs in solution + // + // static int count=0; count++; + // VisMF::Write(S_new,"sn_"+std::to_string(count)); + // for (int sigma = first_scalar; sigma <= last_scalar; sigma++) + // { + // std::cout << count <<" , comp = " << sigma << ", max(S_new) = " + // << S_new.norm0( sigma, 0, false, true ) + // << std::endl; + // } + + // for (int sigma = first_scalar; sigma <= last_scalar; sigma++) + // { + // if (S_old.contains_nan(sigma,1,0)) + // { + // amrex::Print() << "SAU: Old scalar " << sigma << " contains Nans" << std::endl; + + // IntVect mpt(AMREX_D_DECL(-100,100,-100)); + // for (MFIter mfi(S_old); mfi.isValid(); ++mfi){ + // if ( S_old[mfi].contains_nan(mpt) ) + // amrex::Print() << " Nans at " << mpt << std::endl; + // } + // } + // if (S_new.contains_nan(sigma,1,0)) + // { + // amrex::Print() << "SAU: New scalar " << sigma << " contains Nans" << std::endl; + + // IntVect mpt(AMREX_D_DECL(-100,100,-100)); + // for (MFIter mfi(S_new); mfi.isValid(); ++mfi){ + // if ( S_new[mfi].contains_nan(mpt) ) + // amrex::Print() << " Nans at " << mpt << std::endl; + // } + // } + // } +} + +// +// Set the time levels to time (time) and timestep dt. +// +void +NavierStokesBase::setTimeLevel (Real time, + Real dt_old, + Real dt_new) +{ + state[State_Type].setTimeLevel(time,dt_old,dt_new); + + if (have_divu) + { + state[Divu_Type].setTimeLevel(time,dt_old,dt_new); + if (have_dsdt) + { + state[Dsdt_Type].setTimeLevel(time,dt_old,dt_new); + } + } + + state[Press_Type].setTimeLevel(time-dt_old,dt_old,dt_old); + + state[Gradp_Type].setTimeLevel(time-dt_old,dt_old,dt_old); +} + +void +NavierStokesBase::sync_setup (MultiFab*& DeltaSsync) +{ + AMREX_ASSERT(DeltaSsync == nullptr); + + int nconserved = 0; + + for (int comp = AMREX_SPACEDIM; comp < NUM_STATE; ++comp) + { + if (advectionType[comp] == Conservative) + ++nconserved; + } + + if (nconserved > 0 && level < parent->finestLevel()) + { + DeltaSsync = new MultiFab(grids, dmap, nconserved, 0, MFInfo(), Factory()); + DeltaSsync->setVal(0); + } +} + +void +NavierStokesBase::sync_cleanup (MultiFab*& DeltaSsync) +{ + delete DeltaSsync; + DeltaSsync = nullptr; +} + +// +// Helper function for NavierStokesBase::SyncInterp(). +// +static +void +set_bcrec_new (Vector &bcrec, + int ncomp, + int src_comp, + const Box& box, + const Box& domain, + const BoxArray& cgrids, + int** bc_orig_qty) + +{ + for (int n = 0; n < ncomp; n++) { + for (int dir = 0; dir < AMREX_SPACEDIM; dir++) + { + int bc_index = (src_comp+n)*(2*AMREX_SPACEDIM) + dir; + bcrec[n].setLo(dir,BCType::int_dir); + bcrec[n].setHi(dir,BCType::int_dir); + if ( ( box.smallEnd(dir) < domain.smallEnd(dir) ) || + ( box.bigEnd(dir) > domain.bigEnd(dir) ) ) { + for (int crse = 0; crse < cgrids.size(); crse++) { + const Box& crsebx = cgrids[crse]; + if ( ( box.smallEnd(dir) < domain.smallEnd(dir) ) && ( crsebx.smallEnd(dir) == domain.smallEnd(dir) ) ) { + bcrec[n].setLo(dir,bc_orig_qty[crse][bc_index]); + } + if ( ( box.bigEnd(dir) > domain.bigEnd(dir) ) && ( crsebx.bigEnd(dir) == domain.bigEnd(dir) ) ) { + bcrec[n].setHi(dir,bc_orig_qty[crse][bc_index+AMREX_SPACEDIM]); + } + } + } + } + } +} + +// +// Interpolate A cell centered Sync correction from a +// coarse level (c_lev) to a fine level (f_lev). +// +// This routine interpolates the num_comp components of CrseSync +// (starting at src_comp) and either increments or puts the result into +// the num_comp components of FineSync (starting at dest_comp) +// The components of bc_orig_qty correspond to the quantities of CrseSync. +// +void +NavierStokesBase::SyncInterp (MultiFab& CrseSync, + int c_lev, + MultiFab& FineSync, + int f_lev, + IntVect& ratio, + int src_comp, + int dest_comp, + int num_comp, + int increment, + Real dt_clev, + int** bc_orig_qty, + SyncInterpType which_interp, + int state_comp) +{ + BL_PROFILE("NavierStokesBase::SyncInterp()"); + + Interpolater* interpolater = nullptr; + +#ifdef AMREX_USE_EB + switch (which_interp) + { + // As with the non-EB case, both of these point to the same interpolater + case CellCons_T: interpolater = &eb_cell_cons_interp; break; + case CellConsLin_T: interpolater = &eb_lincc_interp; break; + default: + amrex::Abort("NavierStokesBase::SyncInterp(): EB currently requires Cell Conservative interpolater. \n"); + } +#else + switch (which_interp) + { + case PC_T: interpolater = &pc_interp; break; + case CellCons_T: interpolater = &cell_cons_interp; break; + case CellConsLin_T: interpolater = &lincc_interp; break; + case CellConsProt_T: interpolater = &protected_interp; break; + default: + amrex::Abort("NavierStokesBase::SyncInterp(): how did this happen \n"); + } +#endif + + NavierStokesBase& fine_level = getLevel(f_lev); + const BoxArray& fgrids = fine_level.boxArray(); + const DistributionMapping& fdmap = fine_level.DistributionMap(); + const Geometry& fgeom = parent->Geom(f_lev); + const BoxArray& cgrids = getLevel(c_lev).boxArray(); + const Geometry& cgeom = parent->Geom(c_lev); + Box cdomain = amrex::coarsen(fgeom.Domain(),ratio); + const auto N = int(fgrids.size()); + + BoxArray cdataBA(N); + + for (int i = 0; i < N; i++) { + cdataBA.set(i,interpolater->CoarseBox(fgrids[i],ratio)); + } + // + // Note: The boxes in cdataBA may NOT be disjoint !!! + // +#ifdef AMREX_USE_EB + // I am unsure of EBSupport and ng (set to zero here) + auto factory = makeEBFabFactory(cgeom,cdataBA,fdmap,{0,0,0},EBSupport::basic); + MultiFab cdataMF(cdataBA,fdmap,num_comp,0,MFInfo(),*factory); +#else + // ,MFInfo(),getLevel(c_lev).Factory()); + MultiFab cdataMF(cdataBA,fdmap,num_comp,0); +#endif + + cdataMF.ParallelCopy(CrseSync, src_comp, 0, num_comp, cgeom.periodicity()); + + // + // Set physical boundary conditions in cdataMF. + // + ////////// + // Should be fine for EB for now, since EB doesn't intersect Phys BC + // Not sure about what happens if EB intersects Phys BC + /////// + + // tiling may not be needed here, but what the hey + GpuBndryFuncFab gpu_bndry_func(HomExtDirFill{}); +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(cdataMF,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + FArrayBox& data = cdataMF[mfi]; + + Vector bx_bcrec(num_comp); + set_bcrec_new(bx_bcrec,num_comp,src_comp,bx,cdomain,cgrids,bc_orig_qty); + gpu_bndry_func(bx,data,0,num_comp,cgeom,0.0,bx_bcrec,0,0); + } + + // + // Interpolate from cdataMF to fdata and update FineSync. + // Note that FineSync and cdataMF will have the same distribution + // since the length of their BoxArrays are equal. + // + MultiFab* fine_stateMF = nullptr; + if (interpolater == &protected_interp) + { + fine_stateMF = &(getLevel(f_lev).get_new_data(State_Type)); + } + + +#ifdef AMREX_USE_EB + const FabArray& flags = dynamic_cast(getLevel(f_lev).Factory()).getMultiEBCellFlagFab(); +#endif + +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + { + for (MFIter mfi(FineSync,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + FArrayBox& cdata = cdataMF[mfi]; + const Box& bx = mfi.tilebox(); + const Box cbx = interpolater->CoarseBox(bx,ratio); + +#ifdef AMREX_USE_EB + EBFArrayBox fdata(flags[mfi],bx,num_comp,FineSync[mfi].arena()); +#else + FArrayBox fdata(bx, num_comp); +#endif + Elixir fdata_i = fdata.elixir(); + + // + // Set the boundary condition array for interpolation. + // + Vector bx_bcrec(num_comp); + set_bcrec_new(bx_bcrec,num_comp,src_comp,cbx,cdomain,cgrids,bc_orig_qty); + + //ScaleCrseSyncInterp(cdata, c_lev, num_comp); + + interpolater->interp(cdata,0,fdata,0,num_comp,bx,ratio, + cgeom,fgeom,bx_bcrec,src_comp,State_Type,RunOn::Gpu); + + //reScaleFineSyncInterp(fdata, f_lev, num_comp); + + if (increment) + { + auto const& finedata = fdata.array(); + auto const& coarsedata = cdata.array(); + int scale_coarse = (interpolater == &protected_interp) ? 1 : 0; + amrex::ParallelFor(bx, num_comp, [finedata,dt_clev] + AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept + { + finedata(i,j,k,n) *= dt_clev; + }); + + if ( scale_coarse ) { + amrex::ParallelFor(cbx, num_comp, [coarsedata,dt_clev] + AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept + { + coarsedata(i,j,k,n) *= dt_clev; + }); + } + + + if (interpolater == &protected_interp) + { + FArrayBox& fine_state = (*fine_stateMF)[mfi]; + interpolater->protect(cdata,0,fdata,0,fine_state,state_comp, + num_comp,bx,ratio, + cgeom,fgeom,bx_bcrec,RunOn::Gpu); + } + + auto const& fsync = FineSync.array(mfi,dest_comp); + amrex::ParallelFor(bx, num_comp, [finedata,fsync] + AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept + { + fsync(i,j,k,n) += finedata(i,j,k,n); + }); + + if ( scale_coarse ) { + amrex::ParallelFor(cbx, num_comp, [coarsedata,dt_clev] + AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept + { + coarsedata(i,j,k,n) /= dt_clev; + }); + } + + + } + else + { + auto const& finedata = fdata.array(); + auto const& fsync = FineSync.array(mfi,dest_comp); + amrex::ParallelFor(bx, num_comp, [finedata,fsync] + AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept + { + fsync(i,j,k,n) = finedata(i,j,k,n); + }); + } + } + } +} + +// +// Interpolate sync pressure correction to a finer level. +// +void +NavierStokesBase::SyncProjInterp (MultiFab& phi, + int c_lev, + MultiFab& P_new, + MultiFab& P_old, + int f_lev, + IntVect& ratio) +{ + BL_PROFILE("NavierStokesBase:::SyncProjInterp()"); + + const BoxArray& P_grids = P_new.boxArray(); + const auto N = int(P_grids.size()); + + BoxArray crse_ba(N); + +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (int i = 0; i < N; i++) + crse_ba.set(i,node_bilinear_interp.CoarseBox(P_grids[i],ratio)); + + // None of these 3 are actually used by node_bilinear_interp() + Vector bc(AMREX_SPACEDIM); + const Geometry& fgeom = parent->Geom(f_lev); + const Geometry& cgeom = parent->Geom(c_lev); + +#ifdef AMREX_USE_EB + // I am unsure of EBSupport and ng (set to 1 here) + // need 1 ghost cell to use EB_set_covered on nodal MF + // Factory is always CC, regardless of status of crse_ba + auto factory = makeEBFabFactory(cgeom,crse_ba,P_new.DistributionMap(),{1,1,1},EBSupport::basic); + MultiFab crse_phi(crse_ba,P_new.DistributionMap(),1,0,MFInfo(),*factory); + +#else + MultiFab crse_phi(crse_ba,P_new.DistributionMap(),1,0); +#endif + + crse_phi.setVal(1.e200); + crse_phi.ParallelCopy(phi,0,0,1); + +#ifdef AMREX_USE_EB + EB_set_covered(crse_phi,0.); +#endif + +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(P_new,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + FArrayBox fine_phi(bx,1); + Elixir fine_phi_i = fine_phi.elixir(); + node_bilinear_interp.interp(crse_phi[mfi],0,fine_phi,0,1, + fine_phi.box(),ratio,cgeom,fgeom,bc, + 0,Press_Type,RunOn::Gpu); + + auto const& f_phi = fine_phi.array(); + auto const& p_new = P_new.array(mfi); + auto const& p_old = P_old.array(mfi); + amrex::ParallelFor(bx, [f_phi, p_old, p_new] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + p_new(i,j,k) += f_phi(i,j,k); + p_old(i,j,k) += f_phi(i,j,k); + }); + } + +#ifdef AMREX_USE_EB + EB_set_covered(P_new,0.); + EB_set_covered(P_old,0.); +#endif + +} + +std::string +NavierStokesBase::thePlotFileType () const +{ + // + // Increment this whenever the writePlotFile() format changes. + // + static const std::string the_plot_file_type("NavierStokes-V1.1"); + + return the_plot_file_type; +} + +// +// This routine advects the velocities +// +void +NavierStokesBase::velocity_advection (Real dt) +{ + BL_PROFILE("NavierStokesBase::velocity_advection()"); + + if (verbose) + { + if (do_mom_diff == 0) + { + + amrex::Print() << "... advect velocities\n"; + } + else + { + amrex::Print() << "... advect momenta\n"; + } + } + + const Real prev_time = state[State_Type].prevTime(); + + std::unique_ptr divu_fp(getDivCond(nghost_force(),prev_time)); + + MultiFab forcing_term( grids, dmap, AMREX_SPACEDIM, nghost_force(), MFInfo(),Factory()); + forcing_term.setVal(0.0); + + FillPatchIterator U_fpi(*this,forcing_term, nghost_state(),prev_time,State_Type,Xvel,AMREX_SPACEDIM); + MultiFab& Umf=U_fpi.get_mf(); + + // + // S_term is the state we are solving for: either velocity or momentum + // + MultiFab raii; + MultiFab* S_term; + if (do_mom_diff) { + raii.define(grids, dmap, AMREX_SPACEDIM, nghost_state(), MFInfo(), Factory()); + S_term = &raii; + } else { + S_term = &Umf; + } + + if (do_mom_diff) + { + FillPatchIterator Rho_fpi(*this,forcing_term,nghost_state(),prev_time,State_Type,Density,1); + MultiFab& Rmf=Rho_fpi.get_mf(); + + for (MFIter U_mfi(Umf,TilingIfNotGPU()); U_mfi.isValid(); ++U_mfi) + { + auto const state_bx = U_mfi.growntilebox(nghost_state()); + + auto const& dens = Rmf.const_array(U_mfi); //Previous time, nghost_state() grow cells filled + auto const& vel = Umf.const_array(U_mfi); + auto const& st = S_term->array(U_mfi); + + amrex::ParallelFor(state_bx, AMREX_SPACEDIM, [ dens, vel, st ] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { st(i,j,k,n) = vel(i,j,k,n) * dens(i,j,k); }); + } + } + + MultiFab& Gp = get_old_data(Gradp_Type); + + FillPatchIterator S_fpi(*this,forcing_term,nghost_force(),prev_time,State_Type,Density,NUM_SCALARS); + MultiFab& Smf=S_fpi.get_mf(); + + // Get divu to time n+1/2 + { + std::unique_ptr dsdt(getDsdt(nghost_force(),prev_time)); + MultiFab::Saxpy(*divu_fp, 0.5*dt, *dsdt, 0, 0, 1, nghost_force()); + } + + MultiFab visc_terms(grids,dmap,AMREX_SPACEDIM,nghost_force(),MFInfo(),Factory()); + if (be_cn_theta != 1.0) + getViscTerms(visc_terms,Xvel,AMREX_SPACEDIM,prev_time); + else + visc_terms.setVal(0.0); + + // + // ls related + // may add some surface tension subroutines later + // + +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter U_mfi(Umf,TilingIfNotGPU()); U_mfi.isValid(); ++U_mfi) + { + + auto const force_bx = U_mfi.growntilebox(nghost_force()); // Box for forcing term + + if (getForceVerbose) + { + amrex::Print() << "---" << '\n' + << "B - velocity advection:" << '\n' + << "Calling getForce..." << '\n'; + } + // + // ls related + // may consider the surface tension in a new getForce later + // + getForce(forcing_term[U_mfi],force_bx,Xvel,AMREX_SPACEDIM, + prev_time,Umf[U_mfi],Smf[U_mfi],0,U_mfi); + + // + // Compute the total forcing. + // + auto const& tf = forcing_term.array(U_mfi,Xvel); + auto const& visc = visc_terms.const_array(U_mfi,Xvel); + auto const& gp = Gp.const_array(U_mfi); + auto const& rho = Smf.const_array(U_mfi); //Previous time, nghost_force() grow cells filled + + bool is_convective = do_mom_diff ? false : true; + amrex::ParallelFor(force_bx, AMREX_SPACEDIM, [ tf, visc, gp, rho, is_convective] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { + tf(i,j,k,n) = ( tf(i,j,k,n) + visc(i,j,k,n) - gp(i,j,k,n) ); + if (is_convective) + tf(i,j,k,n) /= rho(i,j,k); + }); + } + + ComputeAofs( Xvel, AMREX_SPACEDIM, *S_term, 0, forcing_term, *divu_fp, true, dt ); +} + +// +// This subroutine updates the velocity field before the level projection. +// +// At this point in time, all we know is u^n, rho^n+1/2, and the +// general forcing terms at t^n, and after solving in this routine +// viscous forcing at t^n+1/2. Except for a simple buoyancy term, +// b = -rho^n+1/2 g, it is usually not possible to estimate more +// general forcing terms at t^n+1/2. Since the default getForce, handles +// this case automatically, F_new and F_old have been replaced by a single +// tforces FArrayBox. +// +// We assume that if one component of velocity is viscous that all must be. +// + +void +NavierStokesBase::velocity_update (Real dt) +{ + BL_PROFILE("NavierStokesBase::velocity_update()"); + + if (verbose) + { + if (do_mom_diff == 0) + { + amrex::Print() << "... update velocities \n"; + } + else + { + amrex::Print() << "... update momenta \n"; + } + } + + velocity_advection_update(dt); + + if (!initial_iter) + velocity_diffusion_update(dt); + else + initial_velocity_diffusion_update(dt); + + MultiFab& S_new = get_new_data(State_Type); + + for (int sigma = 0; sigma < AMREX_SPACEDIM; sigma++) + { + if (S_new.contains_nan(sigma,1,0)) + { + amrex::Print() << "New velocity " << sigma << " contains Nans" << '\n'; + exit(0); + } + } +} + +void +NavierStokesBase::velocity_advection_update (Real dt) +{ + BL_PROFILE("NavierStokesBase::velocity_advection_update()"); + + MultiFab& U_old = get_old_data(State_Type); + MultiFab& U_new = get_new_data(State_Type); + MultiFab& Aofs = *aofs; + MultiFab& Gp = get_old_data(Gradp_Type); + MultiFab& Rh = get_rho_half_time(); + + MultiFab Vel(grids, dmap, AMREX_SPACEDIM, 0, MFInfo(), Factory()); + // + // Average mac face velocity to cell-centers for use in generating external + // forcing term in getForce() + // NOTE that default getForce() does not use Vel or Scal, user must supply the + // forcing function for that case. + // +#ifdef AMREX_USE_EB + // This isn't quite right because it's face-centers to cell-centers + // what's really wanted is face-centroid to cell-centroid + EB_average_face_to_cellcenter(Vel, 0, Array{{AMREX_D_DECL(&u_mac[0],&u_mac[1],&u_mac[2])}}); +#else + average_face_to_cellcenter(Vel, 0, Array{{AMREX_D_DECL(&u_mac[0],&u_mac[1],&u_mac[2])}}); +#endif + +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif +{ + FArrayBox tforces, ScalFAB; + + for (MFIter mfi(Rh,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + FArrayBox& VelFAB = Vel[mfi]; + ScalFAB.resize(bx,NUM_SCALARS); + Elixir scal_i = ScalFAB.elixir(); + + // + // Need to do some funky half-time stuff. + // + if (getForceVerbose) + amrex::Print() << "---" << '\n' << "F - velocity advection update (half time):" << '\n'; + // + // Average the new and old time to get Crank-Nicholson half time approximation. + // Scalars always get updated before velocity (see NavierStokes::advance), so + // this is guaranteed to be good. + // + auto const& scal = ScalFAB.array(); + auto const& scal_o = U_old.array(mfi,Density); + auto const& scal_n = U_new.array(mfi,Density); + amrex::ParallelFor(bx, NUM_SCALARS, [scal, scal_o, scal_n] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { + scal(i,j,k,n) = 0.5 * ( scal_o(i,j,k,n) + scal_n(i,j,k,n) ); + }); + + const Real half_time = 0.5*(state[State_Type].prevTime()+state[State_Type].curTime()); + tforces.resize(bx,AMREX_SPACEDIM); + Elixir tf_i = tforces.elixir(); + getForce(tforces,bx,Xvel,AMREX_SPACEDIM,half_time,VelFAB,ScalFAB,0,mfi); + + // + // Do following only at initial iteration--per JBB. + // + if (initial_iter && is_diffusive[Xvel]) { + auto const& force = tforces.array(); + amrex::ParallelFor(bx, AMREX_SPACEDIM, [force] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { + force(i,j,k,n) = 0.0; + }); + } + + // Update velocity + auto const& vel_old = U_old.array(mfi); + auto const& vel_new = U_new.array(mfi); + auto const& gradp = Gp.array(mfi); + auto const& force = tforces.array(); + auto const& advec = Aofs.array(mfi); + auto const& rho_old = U_old.array(mfi, Density); + auto const& rho_new = U_new.array(mfi, Density); + auto const& rho_Half = Rh.array(mfi); + int mom_diff = do_mom_diff; + amrex::ParallelFor(bx, AMREX_SPACEDIM, [vel_old,vel_new,gradp,force,advec,rho_old,rho_new,rho_Half,mom_diff,dt] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { + Real velold = vel_old(i,j,k,n); + + if ( mom_diff ) { + velold *= rho_old(i,j,k); + vel_new(i,j,k,n) = velold - dt * advec(i,j,k,n) + + dt * force(i,j,k,n) + - dt * gradp(i,j,k,n); + + vel_new(i,j,k,n) /= rho_new(i,j,k); + } + else + { + vel_new(i,j,k,n) = velold - dt * advec(i,j,k,n) + + dt * force(i,j,k,n) / rho_Half(i,j,k) + - dt * gradp(i,j,k,n) / rho_Half(i,j,k); + } + }); + } +} + + for (int sigma = 0; sigma < AMREX_SPACEDIM; sigma++) + { + if (U_old.contains_nan(sigma,1,0)) + { + amrex::Print() << "VAU: Old velocity " << sigma << " contains Nans" << std::endl; + + IntVect mpt(AMREX_D_DECL(-100,100,-100)); + for (MFIter mfi(U_old); mfi.isValid(); ++mfi){ + const Box& bx = mfi.tilebox(); + if ( U_old[mfi].contains_nan(bx, sigma, 1, mpt) ) + amrex::Print() << " Nans at " << mpt << std::endl; + } + } + if (U_new.contains_nan(sigma,1,0)) + { + amrex::Print() << "VAU: New velocity " << sigma << " contains Nans" << std::endl; + + IntVect mpt(AMREX_D_DECL(-100,100,-100)); + for (MFIter mfi(U_new); mfi.isValid(); ++mfi){ + const Box& bx = mfi.tilebox(); + if ( U_new[mfi].contains_nan(bx, sigma, 1, mpt) ) + amrex::Print() << " Nans at " << mpt << std::endl; + } + } + } +} + +void +NavierStokesBase::initial_velocity_diffusion_update (Real dt) +{ + // + // Do following only at initial iteration. + // + if (is_diffusive[Xvel]) + { + MultiFab& U_old = get_old_data(State_Type); + MultiFab& U_new = get_new_data(State_Type); + MultiFab& Rh = get_rho_half_time(); + const Real prev_time = state[State_Type].prevTime(); + + int ngrow = 0; + MultiFab visc_terms(grids,dmap,AMREX_SPACEDIM,ngrow,MFInfo(),Factory()); + MultiFab tforces(grids,dmap,AMREX_SPACEDIM,ngrow,MFInfo(),Factory()); + + // + // Get grad(p) + // + MultiFab& Gp = get_old_data(Gradp_Type); + + // + // Compute additional forcing terms + // + tforces.setVal(0.0); +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(tforces,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const auto& bx = mfi.tilebox(); + auto& tforces_fab = tforces[mfi]; + if (getForceVerbose) + { + amrex::Print() << "---" << '\n' + << "G - initial velocity diffusion update:" << '\n' + << "Calling getForce..." << '\n'; + } + getForce(tforces_fab,bx,Xvel,AMREX_SPACEDIM,prev_time,U_old[mfi],U_old[mfi],Density,mfi); + } + + // + // Compute viscous terms + // + if (be_cn_theta != 1.0) + { + getViscTerms(visc_terms,Xvel,AMREX_SPACEDIM,prev_time); + } + else + { + visc_terms.setVal(0.0); + } + + // + // Assemble RHS + // +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(tforces,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + auto const& force = tforces.array(mfi); + auto const& viscT = visc_terms.array(mfi); + auto const& gradp = Gp.array(mfi); + auto const& rhohalf = Rh.array(mfi); + auto const& rho_old = U_old.array(mfi,Density); + auto const& rho_new = U_new.array(mfi,Density); + auto const& vel_old = U_old.array(mfi,Xvel); + auto const& vel_new = U_new.array(mfi,Xvel); + auto const& advT = aofs->array(mfi,Xvel); + int mom_diff = do_mom_diff; + amrex::ParallelFor(bx, AMREX_SPACEDIM, [force,viscT,gradp,rhohalf,advT,rho_old,rho_new,vel_old,vel_new,mom_diff,dt] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { + // Set force += (visc - Gp) / rho_half - aofs + force(i,j,k,n) += viscT(i,j,k,n) - gradp(i,j,k,n); + if ( !mom_diff ) { + force(i,j,k,n) /= rhohalf(i,j,k); + } + force(i,j,k,n) -= advT(i,j,k,n); + // if mom_diff : U_new = (force* dt + U_old * rho_old) / rho_new + // else : U_new = U_old + force* dt + if ( mom_diff ) { + vel_new(i,j,k,n) = (force(i,j,k,n) * dt + vel_old(i,j,k,n) * rho_old(i,j,k)) / rho_new(i,j,k); + } else { + vel_new(i,j,k,n) = vel_old(i,j,k,n) + force(i,j,k,n) * dt; + } + }); + } + } +} + +#ifdef AMREX_PARTICLES + +void +NavierStokesBase::read_particle_params () +{ + ParmParse ppp("particles"); + // + // Ensure other particle methods aren't being used, like sprays + // + ppp.query("do_nspc_particles", do_nspc); + if (!do_nspc) return; + // + // The directory in which to store timestamp files. + // + ppp.query("timestamp_dir", timestamp_dir); + // + // Only the I/O processor makes the directory if it doesn't already exist. + // + if (ParallelDescriptor::IOProcessor()) + if (!amrex::UtilCreateDirectory(timestamp_dir, 0755)) + amrex::CreateDirectoryFailed(timestamp_dir); + // + // Force other processors to wait till directory is built. + // + ParallelDescriptor::Barrier(); + + if (int nc = ppp.countval("timestamp_indices")) + { + timestamp_indices.resize(nc); + + ppp.getarr("timestamp_indices", timestamp_indices, 0, nc); + } + + ppp.query("verbose",pverbose); + if ( ppp.countname("pverbose") > 0) { + amrex::Abort("particles.pverbose found in inputs. Please use particles.verbose"); + } + // + // Used in initData() on startup to read in a file of particles. + // + ppp.query("particle_init_file", particle_init_file); + // + // Used in post_restart() to read in a file of particles. + // + ppp.query("particle_restart_file", particle_restart_file); + // + // This must be true the first time you try to restart from a checkpoint + // that was written with USE_PARTICLES=FALSE; i.e. one that doesn't have + // the particle checkpoint stuff (even if there are no active particles). + // Otherwise the code will fail when trying to read the checkpointed particles. + // + ppp.query("restart_from_nonparticle_chkfile", restart_from_nonparticle_chkfile); + // + // Used in post_restart() to write out the file of particles. + // + ppp.query("particle_output_file", particle_output_file); + // + // Put particle info in plotfile (using ParticleContainer::Checkpoint)? + // + ppp.query("particles_in_plotfile", particles_in_plotfile); +} + +void +NavierStokesBase::initParticleData () +{ + + if (!do_nspc) { return; } + + if (level == 0) + { + if (NSPC == 0) + { + NSPC = new AmrTracerParticleContainer(parent); + } + + NSPC->SetVerbose(pverbose); + + if (!particle_init_file.empty()) + { + NSPC->InitFromAsciiFile(particle_init_file,0); + } + } +} + +void +NavierStokesBase::post_restart_particle () +{ + if (level == 0 && do_nspc) + { + AMREX_ASSERT(NSPC == 0); + + NSPC = new AmrTracerParticleContainer(parent); + + NSPC->SetVerbose(pverbose); + // + // We want to be able to add new particles on a restart. + // As well as the ability to write the particles out to an ascii file. + // + if (!restart_from_nonparticle_chkfile) + { + NSPC->Restart(parent->theRestartFile(), the_ns_particle_file_name); + } + + if (!particle_restart_file.empty()) + { + NSPC->InitFromAsciiFile(particle_restart_file,0); + } + + if (!particle_output_file.empty()) + { + NSPC->WriteAsciiFile(particle_output_file); + } + } +} + +void +NavierStokesBase::post_timestep_particle (int crse_iteration) +{ + const int ncycle = parent->nCycle(level); + const int finest_level = parent->finestLevel(); + // + // Don't redistribute/timestamp on the final subiteration except on the coarsest grid. + // + if (NSPC != 0 && (crse_iteration < ncycle || level == 0)) + { + const Real curr_time = state[State_Type].curTime(); + + int ngrow = (level == 0) ? 0 : crse_iteration; + + NSPC->Redistribute(level, finest_level, ngrow); + + if (!timestamp_dir.empty()) + { + std::string basename = timestamp_dir; + + if (basename[basename.length()-1] != '/') basename += '/'; + + basename += "Timestamp"; + + static bool first = true; + static int n, nextras; + static std::vector tindices; + + if (first) + { + first = false; + + n = timestamp_indices.size(); + nextras = timestamp_num_extras(); + + int sz = n + nextras; + tindices.reserve(sz); + + for (int i = 0; i < sz; ++i) { + tindices.push_back(i); + } + } + + for (int lev = level; lev <= finest_level; lev++) + { + if (NSPC->NumberOfParticlesAtLevel(lev) <= 0) continue; + + int ng = (lev == level) ? ngrow+1 : 1; + + AmrLevel& amr_level = parent->getLevel(lev); + MultiFab& S_new = amr_level.get_new_data(State_Type); + + MultiFab tmf; + + if (tindices.size() > 0) + { + tmf.define(S_new.boxArray(), S_new.DistributionMap(), tindices.size(), ng, MFInfo(), Factory()); + + if (n > 0) + { + FillPatchIterator fpi(parent->getLevel(lev), S_new, + ng, curr_time, State_Type, 0, NUM_STATE); + const MultiFab& S = fpi.get_mf(); + +#ifdef _OPENMP +#pragma omp parallel +#endif + for (MFIter mfi(tmf,true); mfi.isValid(); ++mfi) + { + FArrayBox& tfab = tmf[mfi]; + const FArrayBox& sfab = S[mfi]; + const Box& box = mfi.growntilebox(); + for (int i = 0; i < n; ++i) + { + tfab.copy(sfab, box, timestamp_indices[i], box, i, 1); + } + } + } + + if (nextras > 0) + { + timestamp_add_extras(lev, curr_time, tmf); + } + } + + NSPC->Timestamp(basename, tmf, lev, curr_time, tindices); + } + } + } +} + +std::unique_ptr +NavierStokesBase::ParticleDerive (const std::string& name, + Real time, + int ngrow) +{ + if ((name == "particle_count" || name == "total_particle_count") && do_nspc) { + int ncomp = 1; + const DeriveRec* rec = derive_lst.get(name); + if (rec) + { + ncomp = rec->numDerive(); + } + + MultiFab* ret = new MultiFab(grids, dmap, ncomp, ngrow, MFInfo(), Factory()); + ParticleDerive(name,time,*ret,0); + return std::unique_ptr{ret}; + } + else { + return AmrLevel::derive(name, time, ngrow); + } +} + +void +NavierStokesBase::ParticleDerive (const std::string& name, + Real time, + MultiFab& mf, + int dcomp) +{ + if (NSPC == 0 || !(name == "particle_count" || name == "total_particle_count")) + { + AmrLevel::derive(name,time,mf,dcomp); + } + else { + if (name == "particle_count") + { + MultiFab temp_dat(grids,dmap,1,0, MFInfo(), Factory()); + temp_dat.setVal(0); + NSPC->Increment(temp_dat,level); + MultiFab::Copy(mf,temp_dat,0,dcomp,1,0); + } + else if (name == "total_particle_count") + { + // + // We want the total particle count at this level or higher. + // + ParticleDerive("particle_count",time,mf,dcomp); + + IntVect trr(AMREX_D_DECL(1,1,1)); + + for (int lev = level+1; lev <= parent->finestLevel(); lev++) + { + BoxArray ba = parent->boxArray(lev); + + MultiFab temp_dat(ba,parent->DistributionMap(lev),1,0,MFInfo(),Factory()); + + trr *= parent->refRatio(lev-1); + + ba.coarsen(trr); + + MultiFab ctemp_dat(ba,parent->DistributionMap(lev),1,0); + + temp_dat.setVal(0); + ctemp_dat.setVal(0); + + NSPC->Increment(temp_dat,lev); + +#ifdef _OPENMP +#pragma omp parallel +#endif + for (MFIter mfi(temp_dat,true); mfi.isValid(); ++mfi) + { + const FArrayBox& ffab = temp_dat[mfi]; + FArrayBox& cfab = ctemp_dat[mfi]; + const Box& fbx = mfi.tilebox(); + + AMREX_ASSERT(cfab.box() == amrex::coarsen(fbx,trr)); + + for (IntVect p = fbx.smallEnd(); p <= fbx.bigEnd(); fbx.next(p)) + { + const Real val = ffab(p); + if (val > 0) + cfab(amrex::coarsen(p,trr)) += val; + } + } + + temp_dat.clear(); + + MultiFab dat(grids,dmap,1,0,MFInfo(),Factory()); + dat.setVal(0); + dat.ParallelCopy(ctemp_dat); + + MultiFab::Add(mf,dat,0,dcomp,1,0); + } + } + else + { + amrex::Abort("NavierStokesBase::ParticleDerive: how did this happen?"); + } + } +} + +#endif // AMREX_PARTICLES + +// Boundary condition access function. +Vector +NavierStokesBase::fetchBCArray (int State_Type, const Box& bx, int scomp, int ncomp) +{ + Vector bc(2*AMREX_SPACEDIM*ncomp); + BCRec bcr; + const StateDescriptor* stDesc; + const Box& domain = geom.Domain(); + + for (int n = 0; n < ncomp; n++) + { + stDesc=state[State_Type].descriptor(); + setBC(bx,domain,stDesc->getBC(scomp+n),bcr); + + const int* b_rec = bcr.vect(); + for (int m = 0; m < 2*AMREX_SPACEDIM; m++) { + bc[2*AMREX_SPACEDIM*n + m] = b_rec[m]; + } + } + + return bc; +} + +Vector +NavierStokesBase::fetchBCArray (int State_Type, int scomp, int ncomp) +{ + Vector bc(ncomp); + const StateDescriptor* stDesc; + const Box& domain = geom.Domain(); + + for (int n(0); n < ncomp; ++n) + { + stDesc=state[State_Type].descriptor(); + setBC(domain,domain,stDesc->getBC(scomp+n), bc[n] ); + } + + return bc; +} + +// +// Compute gradient of P and fill ghost cells with FillPatch +// +void +NavierStokesBase::computeGradP(Real time) +{ + LPInfo info; + info.setMaxCoarseningLevel(0); + MLNodeLaplacian linop({geom}, {grids}, {dmap}, info, {&Factory()}); +#ifdef AMREX_USE_EB + linop.buildIntegral(); +#endif + + // No call to set BCs because we're only calling compGrad(), which + // doesn't use them. P already exists on surroundingNodes(Gp.validbox()), + // and compGrad() does not fill ghost cells + + MultiFab& Press = get_data(Press_Type, time); + MultiFab& Gp = get_data(Gradp_Type, time); + + linop.compGrad(0, Gp, Press); + + // Now fill ghost cells + FillPatch(*this,Gp,Gp.nGrow(),time,Gradp_Type,0,AMREX_SPACEDIM); +} + +void +NavierStokesBase::avgDown_StatePress() +{ + auto& fine_lev = getLevel(level+1); + + // + // Average down the states at the new time. + // + MultiFab& S_crse = get_new_data(State_Type); + MultiFab& S_fine = fine_lev.get_new_data(State_Type); + + average_down(S_fine, S_crse, 0, S_crse.nComp()); + + // + // Fill rho_ctime at the current and finer levels with the correct data. + // + for (int lev = level; lev <= parent->finestLevel(); lev++) + { + getLevel(lev).make_rho_curr_time(); + } + + // + // Now average down pressure over time n-(n+1) interval. + // + MultiFab& P_crse = get_new_data(Press_Type); + MultiFab& P_fine_init = fine_lev.get_new_data(Press_Type); + MultiFab& P_fine_avg = fine_lev.p_avg; + MultiFab& P_fine = initial_step ? P_fine_init : P_fine_avg; + + // NOTE: this fills ghost cells, but amrex::average_down does not. + amrex::average_down_nodal(P_fine,P_crse,fine_ratio); + + // + // Average down Gradp + // + MultiFab& Gp_crse = get_new_data(Gradp_Type); + MultiFab& Gp_fine = fine_lev.get_new_data(Gradp_Type); + + average_down(Gp_fine, Gp_crse, 0, Gp_crse.nComp()); +} + +void +NavierStokesBase::average_down(const MultiFab& S_fine, MultiFab& S_crse, + int scomp, int ncomp) +{ + // + // Choose the appropriate AMReX average_down() based on + // whether EB or non-EB, and dimensionality + // + +#ifdef AMREX_USE_EB +#if (AMREX_SPACEDIM == 3) + // Don't need volume weighting for EB -- EB is only used in Cartesian + amrex::EB_average_down(S_fine, S_crse, scomp, ncomp, fine_ratio); +#else + // Volume weighting + amrex::EB_average_down(S_fine, S_crse, this->getLevel(level+1).Volume(), + *(this->getLevel(level+1).VolFrac()), + scomp, ncomp, fine_ratio); +#endif + +#else + // + // non-EB aware, uses volume weighting for 1D,2D but no volume weighting for 3D + // + amrex::average_down(S_fine, S_crse, + this->getLevel(level+1).geom, this->getLevel(level).geom, + scomp, ncomp, fine_ratio); +#endif +} + + +// +// Diagnostics functions +// +void +NavierStokesBase::printMaxVel (bool new_data) +{ + + MultiFab& S = new_data? get_new_data(State_Type) : get_old_data(State_Type); + +#if (AMREX_SPACEDIM==3) + amrex::Print() << "max(abs(u/v/w)) = " +#else + amrex::Print() << "max(abs(u/v)) = " +#endif + << S.norm0( Xvel, 0, false, true ) + << " " + << S.norm0( Xvel+1, 0, false, true ) +#if (AMREX_SPACEDIM==3) + << " " + << S.norm0( Xvel+2, 0, false, true ) +#endif + << std::endl; +} + + +void +NavierStokesBase::printMaxGp (bool new_data) +{ + MultiFab& Gp = new_data? get_new_data(Gradp_Type) : get_old_data(Gradp_Type); + MultiFab& P = new_data? get_new_data(Press_Type) : get_old_data(Press_Type); + +#if (AMREX_SPACEDIM==3) + amrex::Print() << "max(abs(gpx/gpy/gpz/p)) = " +#else + amrex::Print() << "max(abs(gpx/gpy/p)) = " +#endif + << Gp.norm0( 0, 0, false, true ) + << " " + << Gp.norm0( 1, 0, false, true ) +#if (AMREX_SPACEDIM==3) + << " " + << Gp.norm0( 2, 0, false, true ) +#endif + << " " + << P.norm0(0, 0, false, true ) + << std::endl; +} + +void +NavierStokesBase::printMaxValues (bool new_data) +{ + printMaxVel(new_data); + printMaxGp(new_data); +} + + +// +// Correct a conservatively-advected scalar for under-over shoots. +// +void +NavierStokesBase::ConservativeScalMinMax ( amrex::MultiFab& Snew, const int snew_comp, const int new_density_comp, + amrex::MultiFab const& Sold, const int sold_comp, const int old_density_comp ) +{ + amrex::ignore_unused(this); +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(Snew,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + + const auto& bx = mfi.tilebox(); + + const auto& sn = Snew.array(mfi,snew_comp); + const auto& so = Sold.const_array(mfi,sold_comp); + const auto& rhon = Snew.const_array(mfi,new_density_comp); + const auto& rhoo = Sold.const_array(mfi,old_density_comp); +#ifdef AMREX_USE_EB + const auto& ebfactory = dynamic_cast(Factory()); + const auto& vfrac = ebfactory.getVolFrac().const_array(mfi); +#endif + + amrex::ParallelFor(bx, [=] + AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Real smn = std::numeric_limits::max(); + Real smx = std::numeric_limits::min(); + +#if (AMREX_SPACEDIM==3) + int ks = -1; + int ke = 1; +#else + int ks = 0; + int ke = 0; +#endif + + for (int kk = ks; kk <= ke; ++kk) + { + for (int jj = -1; jj <= 1; ++jj) + { + for (int ii = -1; ii <= 1; ++ii) + { +#ifdef AMREX_USE_EB + if ( vfrac (i+ii,j+jj,k+kk) > 0. ) +#endif + { + smn = amrex::min(smn, so(i+ii,j+jj,k+kk)/rhoo(i+ii,j+jj,k+kk)); + smx = amrex::max(smx, so(i+ii,j+jj,k+kk)/rhoo(i+ii,j+jj,k+kk)); + } + } + } + } + sn(i,j,k) = amrex::min( amrex::max(sn(i,j,k)/rhon(i,j,k), smn), smx ) * rhon(i,j,k); + }); + } +} + +// +// Correct a convectively-advected scalar for under-over shoots. +// +void +NavierStokesBase::ConvectiveScalMinMax ( amrex::MultiFab& Snew, const int snew_comp, + amrex::MultiFab const& Sold, const int sold_comp ) +{ + amrex::ignore_unused(this); +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(Snew,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + + const auto& bx = mfi.tilebox(); + + const auto& sn = Snew.array(mfi,snew_comp); + const auto& so = Sold.const_array(mfi,sold_comp); +#ifdef AMREX_USE_EB + const auto& ebfactory = dynamic_cast(Factory()); + const auto& vfrac = ebfactory.getVolFrac().const_array(mfi); +#endif + + amrex::ParallelFor(bx, [=] + AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Real smn = std::numeric_limits::max(); + Real smx = std::numeric_limits::min(); + +#if (AMREX_SPACEDIM==3) + int ks = -1; + int ke = 1; +#else + int ks = 0; + int ke = 0; +#endif + + for (int kk = ks; kk <= ke; ++kk) + { + for (int jj = -1; jj <= 1; ++jj) + { + for (int ii = -1; ii <= 1; ++ii) + { +#ifdef AMREX_USE_EB + if ( vfrac (i+ii,j+jj,k+kk) > 0. ) +#endif + { + smn = amrex::min(smn, so(i+ii,j+jj,k+kk)); + smx = amrex::max(smx, so(i+ii,j+jj,k+kk)); + } + } + } + } + sn(i,j,k) = amrex::min( amrex::max(sn(i,j,k), smn), smx ); + }); + } +} + + +// +// Predict the edge velocities which go into forming u_mac. This +// function also returns an estimate of dt for use in variable timesteping. +// +Real +NavierStokesBase::predict_velocity (Real dt) +{ + BL_PROFILE("NavierStokesBase::predict_velocity()"); + if (verbose) { + amrex::Print() << "... predict edge velocities\n"; + } + // + // Get simulation parameters. + // + const int nComp = AMREX_SPACEDIM; + const Real* dx = geom.CellSize(); + const Real prev_time = state[State_Type].prevTime(); + const Real prev_pres_time = state[Press_Type].prevTime(); + const Real strt_time = ParallelDescriptor::second(); + + // + // Compute viscous terms at level n. + // Ensure reasonable values in 1 grow cell. Here, do extrap for + // c-f/phys boundary, since we have no interpolator fn, also, + // preserve extrap for corners at periodic/non-periodic intersections. + // + MultiFab visc_terms(grids,dmap,nComp,nghost_force(),MFInfo(), Factory()); + + FillPatchIterator U_fpi(*this,visc_terms,nghost_state(),prev_time,State_Type,Xvel,AMREX_SPACEDIM); + MultiFab& Umf=U_fpi.get_mf(); + + // Floor small values of states to be extrapolated + floor(Umf); + + // + // Compute "grid cfl number" based on cell-centered time-n velocities + // + auto umax = Umf.norm0({AMREX_D_DECL(0,1,2)},Umf.nGrow(), /*local = */false, /*ignore_covered = */true); + Real cflmax = dt*umax[0]/dx[0]; + for (int d=1; d0 and do it + // once the first time it's needed, which is presumably here... + if ( level > 0 ) + FillPatch(*this,Gp,Gp.nGrow(),prev_pres_time,Gradp_Type,0,AMREX_SPACEDIM); + + if (be_cn_theta != 1.0) + { + getViscTerms(visc_terms,Xvel,nComp,prev_time); + } + else + { + visc_terms.setVal(0.0); + } + + // + // ls related + // may add some surface tension subroutines later + // + + FillPatchIterator S_fpi(*this,visc_terms,nghost_state(),prev_time,State_Type,Density,NUM_SCALARS); + MultiFab& Smf=S_fpi.get_mf(); + + MultiFab forcing_term( grids, dmap, AMREX_SPACEDIM, nghost_force() ); + + // + // Compute forcing + // +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + { + for (MFIter U_mfi(Umf,TilingIfNotGPU()); U_mfi.isValid(); ++U_mfi) + { + FArrayBox& Ufab = Umf[U_mfi]; + auto const gbx = U_mfi.growntilebox(nghost_force()); + + if (getForceVerbose) { + Print() << "---\nA - Predict velocity:\n Calling getForce...\n"; + } + + // + // ls related + // may consider the surface tension in a new getForce later + // + getForce(forcing_term[U_mfi],gbx,Xvel,AMREX_SPACEDIM,prev_time,Ufab,Smf[U_mfi],0,U_mfi); + + // + // Compute the total forcing. + // + auto const& tf = forcing_term.array(U_mfi,Xvel); + auto const& visc = visc_terms.const_array(U_mfi,Xvel); + auto const& gp = Gp.const_array(U_mfi); + auto const& rho = Smf.const_array(U_mfi); + + amrex::ParallelFor(gbx, AMREX_SPACEDIM, [tf, visc, gp, rho] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { + tf(i,j,k,n) = ( tf(i,j,k,n) + visc(i,j,k,n) - gp(i,j,k,n) ) / rho(i,j,k); + }); + } + } + +#ifdef AMREX_USE_EB + if (!EBFactory().isAllRegular()) + { + EBGodunov::ExtrapVelToFaces( Umf, forcing_term, + AMREX_D_DECL(u_mac[0], u_mac[1], u_mac[2]), + m_bcrec_velocity, m_bcrec_velocity_d.dataPtr(), + geom, dt ); + } + else +#endif + { + bool godunov_use_ppm = ( advection_scheme == "Godunov_PPM" ? true : false ); + + Godunov::ExtrapVelToFaces( Umf, forcing_term, + AMREX_D_DECL(u_mac[0], u_mac[1], u_mac[2]), + m_bcrec_velocity, m_bcrec_velocity_d.dataPtr(), + geom, dt, + godunov_use_ppm, godunov_use_forces_in_trans ); + } + + } + else + { + Abort("NSB::predict_velocity: Unknown advection_scheme"); + } + + if (verbose > 1) + { + const int IOProc = ParallelDescriptor::IOProcessorNumber(); + Real run_time = ParallelDescriptor::second() - strt_time; + + ParallelDescriptor::ReduceRealMax(run_time,IOProc); + + Print() << "NavierStokesBase::predict_velocity(): lev: " << level + << ", time: " << run_time << '\n'; + } + + return dt*tempdt; +} + + +// +// Floor small values of states to be extrapolated +// +void +NavierStokesBase::floor(MultiFab& mf){ + + int ncomp = mf.nComp(); + +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(mf,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + Box gbx=mfi.growntilebox(mf.nGrow()); + auto const& fab_a = mf.array(mfi); + AMREX_PARALLEL_FOR_4D ( gbx, ncomp, i, j, k, n, + { + auto& val = fab_a(i,j,k,n); + val = amrex::Math::abs(val) > 1.e-20 ? val : 0; + }); + } +} + +int +NavierStokesBase::nghost_state () const +{ + amrex::ignore_unused(this); +#ifdef AMREX_USE_EB + if (!EBFactory().isAllRegular()) + { + return 4; + } + else +#endif + { + return 3; + } +} + +void +NavierStokesBase::ComputeAofs ( int comp, int ncomp, + MultiFab const& S, + int S_comp, + MultiFab const& forcing_term, + MultiFab const& divu, + bool is_velocity, Real dt) +{ + Array cfluxes; + Array edgestate; + + // + // Advection needs S to have 2-3 ghost cells. + // Advection routines call slopes on cells i & i+1, and then + // 2nd order slopes use i+/-1 => S needs 2 ghost cells (MOL) + // 4th order slopes use i+/-2 => S needs 3 ghost cells (Godunov) + // + int nghost = 0; + for (int i = 0; i < AMREX_SPACEDIM; ++i) + { + const BoxArray& ba = getEdgeBoxArray(i); + cfluxes[i].define(ba, dmap, ncomp, nghost, MFInfo(), Factory()); + edgestate[i].define(ba, dmap, ncomp, nghost, MFInfo(), Factory()); + } + + bool do_crse_add = true; + bool do_fine_add = true; + + ComputeAofs(*aofs, /*aofs_comp*/ comp, /*state_indx*/ comp, ncomp, + S, S_comp, + &forcing_term, /*forcing_term_comp*/ 0, + &divu, + cfluxes, /*flux_comp*/ 0, + edgestate, /*edge_comp*/ 0, /*known_edgestate*/ false, + is_velocity, dt, + /*is_sync*/ false, /*sync fluxing velocity Ucorr*/ {}, + do_crse_add, do_fine_add); +} + +void +NavierStokesBase::ComputeAofs ( MultiFab& advc, int a_comp, // Advection term "Aofs" held here + int state_indx, // Index of first component in AmrLevel.state corresponding to quantity to advect + int ncomp, + MultiFab const& S, int S_comp, // State for computing edgestates, may have gotten massaged + // a bit compared to AmrLevel.state. Must have filled ghost cells. + MultiFab const* forcing, int f_comp, + MultiFab const* divu, // Constraint divu=Source, not div(Umac) + Array& cfluxes, int flux_comp, + Array& edgestate, int edge_comp, + bool known_edge_state, + bool is_velocity, Real dt, + bool is_sync, Array const& U_corr, + bool do_crse_add, bool do_fine_add) +{ + BL_PROFILE("NSB::ComputeAofs_kernel"); + + amrex::ignore_unused(do_fine_add); + + // Need U_corr to be defined for sync. + AMREX_ASSERT( (is_sync && !U_corr.empty()) || !is_sync ); + + // Advection type conservative or non? + // Maybe there's something better than DeviceVector now... + amrex::Gpu::DeviceVector iconserv; + Vector iconserv_h; + iconserv.resize(ncomp, 0); + iconserv_h.resize(ncomp, 0); + + // Will we do any convective differencing? + bool any_convective = false; + for (int i = 0; i < ncomp; ++i) { + iconserv_h[i] = (advectionType[state_indx+i] == Conservative) ? 1 : 0; + if (!iconserv_h[i]) any_convective = true; + } + Gpu::copy(Gpu::hostToDevice,iconserv_h.begin(),iconserv_h.end(), iconserv.begin()); + int const* iconserv_ptr = iconserv.data(); + + // As code is currently written, ComputeAofs is always called separately for + // velocity vs scalars. May be called with an individual scalar. + auto const& bcrec_h = fetchBCArray(State_Type, state_indx, ncomp); + auto* const bcrec_d = is_velocity ? m_bcrec_velocity_d.dataPtr() + : &m_bcrec_scalars_d.dataPtr()[state_indx-AMREX_SPACEDIM]; + +#ifdef AMREX_USE_EB + auto const& ebfact= dynamic_cast(Factory()); + + // Always need a temporary MF to hold advective update before redistribution. + MultiFab update_MF(advc.boxArray(),advc.DistributionMap(),ncomp,3,MFInfo(),Factory()); + + // Must initialize to zero because not all values may be set, e.g. outside the domain. + update_MF.setVal(0.); +#endif + + // + // Define some parameters for hydro routines + // + + bool fluxes_are_area_weighted = true; + + // AMReX_Hydro only recognizes Godunov scheme and then uses ppm switch. + std::string scheme = (advection_scheme=="Godunov_PLM" || advection_scheme=="Godunov_PPM") + ? "Godunov" : advection_scheme; + bool godunov_use_ppm = (advection_scheme == "Godunov_PPM") ? true : false ; + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(advc,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + + const auto& S_arr = S.const_array(mfi, S_comp); + AMREX_D_TERM( const auto& fx = cfluxes[0].array(mfi,flux_comp);, + const auto& fy = cfluxes[1].array(mfi,flux_comp);, + const auto& fz = cfluxes[2].array(mfi,flux_comp);); + AMREX_D_TERM( const auto& xed = edgestate[0].array(mfi,edge_comp);, + const auto& yed = edgestate[1].array(mfi,edge_comp);, + const auto& zed = edgestate[2].array(mfi,edge_comp);); + AMREX_D_TERM( const auto& umac = u_mac[0].const_array(mfi);, + const auto& vmac = u_mac[1].const_array(mfi);, + const auto& wmac = u_mac[2].const_array(mfi);); + AMREX_D_TERM( const auto& uflux = (is_sync) ? U_corr[0]->const_array(mfi) : u_mac[0].const_array(mfi);, + const auto& vflux = (is_sync) ? U_corr[1]->const_array(mfi) : u_mac[1].const_array(mfi);, + const auto& wflux = (is_sync) ? U_corr[2]->const_array(mfi) : u_mac[2].const_array(mfi);); + +#ifdef AMREX_USE_EB + const auto& flagfab = ebfact.getMultiEBCellFlagFab()[mfi]; + const auto fabtyp = flagfab.getType(bx); + + if (fabtyp == FabType::covered) + { + // + // Set advection term and move on to next iteration. + // Old ComputeAofs also set fluxes (=0) and edgestates (=covered_val) here. + // + auto const& aofs_arr = advc.array(mfi, a_comp); + amrex::ParallelFor(bx, ncomp, [aofs_arr] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { aofs_arr( i, j, k, n ) = COVERED_VAL;}); + + continue; + } +#endif + + // + // 1. Compute fluxes + // + HydroUtils::ComputeFluxesOnBoxFromState(bx, ncomp, mfi, S_arr, + AMREX_D_DECL(fx, fy, fz), + AMREX_D_DECL(xed, yed, zed), + known_edge_state, + AMREX_D_DECL(umac, vmac, wmac), //used to create edge state + AMREX_D_DECL(uflux, vflux, wflux), //used to create flux + (divu) ? divu->const_array(mfi) : Array4{}, + (forcing) ? forcing->const_array(mfi, f_comp) : Array4{}, + geom, dt, + bcrec_h, bcrec_d, iconserv_ptr, +#ifdef AMREX_USE_EB + ebfact, + /*values_on_eb_inflow*/ Array4 {}, +#endif + godunov_use_ppm, godunov_use_forces_in_trans, + is_velocity, fluxes_are_area_weighted, + scheme); + + + // + // 2. Get the right container to hold the advective update + // + FArrayBox* update_fab; + int update_comp = 0; + +#ifdef AMREX_USE_EB + // Recall that for EB we always use a temporary MF for redistribution. + update_fab = &update_MF[mfi]; +#else + FArrayBox tmp; + if (is_sync) + { + // For the sync, we need a temporary FAB to hold the update because + // we add the update to what's already in advc. + tmp.resize(bx, ncomp, The_Async_Arena()); + update_fab = &tmp; + } + else + { + // Otherwise, we can overwrite advc. + update_fab = &advc[mfi]; + update_comp = a_comp; + } +#endif + auto const& update_arr = update_fab->array(update_comp); + + + // + // 3. Compute flux divergence + // + // We compute -div here for consistency with the way we HAVE to do it for EB + // (because redistribution operates on -div rather than div) + Real mult = -1.0; +#ifdef AMREX_USE_EB + const auto& vfrac = ebfact.getVolFrac().const_array(mfi); + + if (fabtyp != FabType::regular) + { + HydroUtils::EB_ComputeDivergence( bx, update_arr, + AMREX_D_DECL( fx, fy, fz ), + vfrac, + ncomp, geom, + mult, fluxes_are_area_weighted); + } + else +#endif + { + HydroUtils::ComputeDivergence( bx, update_arr, + AMREX_D_DECL( fx, fy, fz ), + ncomp, geom, + mult, fluxes_are_area_weighted); + } + + // + // 4. Formulate convective term, if needed + // + if (any_convective && !is_sync) // Recall sync is always a conservative update + { + // Compute div(u_mac) first + FArrayBox div_umac(bx, 1, The_Async_Arena()); + auto const& divum_arr = div_umac.array(); + +#ifdef AMREX_USE_EB + const GpuArray dxinv = geom.InvCellSizeArray(); + + if (fabtyp != FabType::regular) + { + // Need AMReX routine here. Hydro version takes a flux (which always has area-fraction + // already included). + bool already_on_centroids = true; + AMREX_D_TERM(Array4 const& apx = ebfact.getAreaFrac()[0]->const_array(mfi);, + Array4 const& apy = ebfact.getAreaFrac()[1]->const_array(mfi);, + Array4 const& apz = ebfact.getAreaFrac()[2]->const_array(mfi)); + Array4 const& flagarr = flagfab.const_array(); + AMREX_HOST_DEVICE_FOR_4D(bx,div_umac.nComp(),i,j,k,n, + { + eb_compute_divergence(i,j,k,n,divum_arr,AMREX_D_DECL(umac,vmac,wmac), + Array4{}, flagarr, vfrac, + AMREX_D_DECL(apx,apy,apz), + AMREX_D_DECL(Array4{}, + Array4{}, + Array4{}), + dxinv, already_on_centroids); + }); + } + else +#endif + { + HydroUtils::ComputeDivergence(bx, divum_arr, AMREX_D_DECL(umac,vmac,wmac), + 1, geom, Real(1.0), false ); + } + + HydroUtils::ComputeConvectiveTerm(bx, ncomp, mfi, S_arr, + AMREX_D_DECL( xed, yed, zed ), + div_umac.array(), update_arr, + iconserv_ptr, +#ifdef AMREX_USE_EB + ebfact, +#endif + scheme); + } + + +#ifndef AMREX_USE_EB + // + // non-EB step 5: + // + // Recall we computed -div above, because redistribution operates + // on -div. Thus, we use -update here. + // + auto const& aofs_arr = advc.array(mfi,a_comp); + if (is_sync) + { + amrex::ParallelFor(bx, ncomp, [aofs_arr, update_arr] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { aofs_arr( i, j, k, n ) -= update_arr(i,j,k,n); }); + } + else + { + amrex::ParallelFor(bx, ncomp, [aofs_arr, update_arr] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { aofs_arr( i, j, k, n ) = -update_arr(i,j,k,n); }); + } +#endif + } + // + // The non-EB computation is complete. + // + + // EB step 5: Redistribute the advective update stashed in update_MF. + // +#ifdef AMREX_USE_EB + update_MF.FillBoundary(geom.periodicity()); + + // + // Define the "state" for StateRedistribution. + // + MultiFab rstate_tmp; + if (is_sync && redistribution_type == "StateRedist") + { + // For the sync, use the Sync data passed in via advc as the "state". + // WARNING: This choice may lead to oversmoothing. + // + // Must create a temporary copy so we're not overwriting this "state" as + // we go through the redistribution process. + rstate_tmp.define(S.boxArray(),S.DistributionMap(),ncomp,S.nGrow(), + MFInfo(),ebfact); + MultiFab::Copy(rstate_tmp,advc,a_comp,0,ncomp,S.nGrow()); + } + MultiFab const* rstate = (is_sync && redistribution_type == "StateRedist") + ? &rstate_tmp : &S; + int rstate_comp = (is_sync && redistribution_type == "StateRedist") + ? 0 : S_comp; +#endif + + const auto& dx = geom.CellSizeArray(); + + // ********************************************************************************** + // We use this hack to allow CrseAdd/FineAdd to divide area-weighted fluxes by volume + // instead of needing to un-area-weight the fluxes then divide just by dx + // ********************************************************************************** + AMREX_ALWAYS_ASSERT(fluxes_are_area_weighted); + Real dx1 = dx[0]; + for (int dir = 1; dir < AMREX_SPACEDIM; ++dir) { + dx1 *= dx[dir]; + } + + std::array dxD = {{AMREX_D_DECL(dx1, dx1, dx1)}}; + const Real* dxDp = &(dxD[0]); + + // ********************************************************************************** + // Build mask to find the ghost cells we need to correct + // ********************************************************************************** + if (coarse_fine_mask == nullptr) { + coarse_fine_mask = std::make_unique(grids, dmap, 1, 2, MFInfo(), DefaultFabFactory()); + coarse_fine_mask->BuildMask(geom.Domain(), geom.periodicity(), + level_mask_covered, level_mask_notcovered, level_mask_physbnd, level_mask_interior); + } + +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + // for (MFIter mfi(advc, TilingIfNotGPU()); mfi.isValid(); ++mfi) + for (MFIter mfi(advc, false); mfi.isValid(); ++mfi) + { + AMREX_D_TERM( const auto& fx_fab = (cfluxes[0])[mfi];, + const auto& fy_fab = (cfluxes[1])[mfi];, + const auto& fz_fab = (cfluxes[2])[mfi];); + +#ifdef AMREX_USE_EB + auto const& bx = mfi.tilebox(); + + auto const& flagfab = ebfact.getMultiEBCellFlagFab()[mfi]; + auto const& flags_arr = flagfab.const_array(); + + if (flagfab.getType(bx) != FabType::covered ) + { + auto const& aofs_arr = advc.array(mfi, a_comp); + auto const& update_arr = update_MF.array(mfi); + + FArrayBox dm_as_fine(Box::TheUnitBox(),ncomp); + FArrayBox fab_drho_as_crse(Box::TheUnitBox(),ncomp); + IArrayBox fab_rrflag_as_crse(Box::TheUnitBox()); + + if (flagfab.getType(grow(bx,4)) != FabType::regular) + { + AMREX_D_TERM( auto apx = ebfact.getAreaFrac()[0]->const_array(mfi);, + auto apy = ebfact.getAreaFrac()[1]->const_array(mfi);, + auto apz = ebfact.getAreaFrac()[2]->const_array(mfi); ); + + AMREX_D_TERM( Array4 fcx = ebfact.getFaceCent()[0]->const_array(mfi);, + Array4 fcy = ebfact.getFaceCent()[1]->const_array(mfi);, + Array4 fcz = ebfact.getFaceCent()[2]->const_array(mfi);); + + Array4 ccent_arr = ebfact.getCentroid().const_array(mfi); + Array4 const& vfrac_arr = ebfact.getVolFrac().const_array(mfi); + + // This is scratch space if calling StateRedistribute, + // but is used as the weights (here set to 1) if calling + // FluxRedistribute + Box gbx = bx; + + if (redistribution_type == "StateRedist") + gbx.grow(3); + else if (redistribution_type == "FluxRedist") + gbx.grow(2); + + int tmpfab_comp = (is_sync) ? ncomp*2 : ncomp; + FArrayBox tmpfab(gbx, tmpfab_comp, The_Async_Arena()); + Array4 scratch = tmpfab.array(0); + if (redistribution_type == "FluxRedist") + { + amrex::ParallelFor(Box(scratch), + [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { scratch(i,j,k) = 1.;}); + } + + Array4 redist_arr = (is_sync) ? tmpfab.array(ncomp) : aofs_arr; + + EBFluxRegister* fr_as_crse = nullptr; + if (do_reflux && level < parent->finestLevel()) { + NavierStokesBase& flevel = getLevel(level+1); + fr_as_crse = flevel.advflux_reg.get(); + } + + EBFluxRegister* fr_as_fine = nullptr; + if (do_reflux && level > 0) { + fr_as_fine = advflux_reg.get(); + } + + int as_crse = (fr_as_crse != nullptr); + int as_fine = (fr_as_fine != nullptr); + + FArrayBox* p_drho_as_crse = (fr_as_crse) ? + fr_as_crse->getCrseData(mfi) : &fab_drho_as_crse; + const IArrayBox* p_rrflag_as_crse = (fr_as_crse) ? + fr_as_crse->getCrseFlag(mfi) : &fab_rrflag_as_crse; + + if (fr_as_fine) { + dm_as_fine.resize(amrex::grow(bx,1),ncomp,The_Async_Arena()); + dm_as_fine.template setVal(0.0); + } + + if (redistribution_type == "FluxRedist") { + bool use_wts_in_divnc = true; + ApplyMLRedistribution( bx, ncomp, redist_arr, update_arr, + rstate->const_array(mfi, rstate_comp), scratch, flags_arr, + AMREX_D_DECL(apx,apy,apz), vfrac_arr, + AMREX_D_DECL(fcx,fcy,fcz), ccent_arr, bcrec_d, + geom, dt, redistribution_type, + as_crse, p_drho_as_crse->array(), p_rrflag_as_crse->array(), + as_fine, dm_as_fine.array(), coarse_fine_mask->const_array(mfi), + level_mask_notcovered, use_wts_in_divnc); + } else { + bool use_wts_in_divnc = true; + ApplyRedistribution( bx, ncomp, redist_arr, update_arr, + rstate->const_array(mfi, rstate_comp), scratch, flags_arr, + AMREX_D_DECL(apx,apy,apz), vfrac_arr, + AMREX_D_DECL(fcx,fcy,fcz), ccent_arr, bcrec_d, + geom, dt, redistribution_type, use_wts_in_divnc ); + } + + if (is_sync) + { + amrex::ParallelFor(bx, ncomp, [aofs_arr, redist_arr] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { aofs_arr( i, j, k, n ) -= redist_arr( i, j, k, n ); }); + } + else + { + amrex::ParallelFor(bx, ncomp, [aofs_arr, redist_arr] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { aofs_arr( i, j, k, n ) = -redist_arr( i, j, k, n ); }); + } + } + else // bx is EB regular + { + // Recall that we computed -div in previous MFIter, because + // redistribution operates on -div. Thus, we use -update here. + if (is_sync) + { + amrex::ParallelFor(bx, ncomp, [aofs_arr, update_arr] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { aofs_arr( i, j, k, n ) -= update_arr(i,j,k,n); }); + } + else + { + amrex::ParallelFor(bx, ncomp, [aofs_arr, update_arr] + AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { aofs_arr( i, j, k, n ) = -update_arr(i,j,k,n); }); + } + } + + AMREX_D_TERM(FArrayBox fx_fr_fab(fx_fab,amrex::make_alias,flux_comp,ncomp);, + FArrayBox fy_fr_fab(fy_fab,amrex::make_alias,flux_comp,ncomp);, + FArrayBox fz_fr_fab(fz_fab,amrex::make_alias,flux_comp,ncomp);); + + // Now update the flux registers (inside test on AMREX_USE_EB) + if ( do_reflux && do_crse_add && (level < parent->finestLevel()) ) { + if (flagfab.getType(amrex::grow(bx,1)) == FabType::regular) + { + getAdvFluxReg(level+1).CrseAdd(mfi, + {AMREX_D_DECL(&fx_fr_fab,&fy_fr_fab,&fz_fr_fab)}, + dxDp, dt, 0, state_indx, ncomp, amrex::RunOn::Device); + + } else if (flagfab.getType(bx) != FabType::covered ) { + getAdvFluxReg(level + 1).CrseAdd(mfi, + {AMREX_D_DECL(&fx_fr_fab,&fy_fr_fab,&fz_fr_fab)}, + dxDp, dt, (*volfrac)[mfi], + {AMREX_D_DECL(&(*areafrac[0])[mfi], &(*areafrac[1])[mfi], &(*areafrac[2])[mfi])}, + 0, state_indx, ncomp, amrex::RunOn::Device); + } + } // do_reflux && level < finest_level + + // This is a hack-y way of testing whether this ComputeAofs call + // came from the mac_sync (do_crse_add = false) + // or from the regular advance (do_crse_add = true). When the call + // comes from the mac_sync, the multiplier in FineAdd needs to have + // the opposite sign + Real sync_factor = do_crse_add ? 1.0 : -1.0; + + if ( do_reflux && do_fine_add && (level > 0)) { + if (flagfab.getType(amrex::grow(bx,1)) == FabType::regular) + { + advflux_reg->FineAdd(mfi, + {AMREX_D_DECL(&fx_fr_fab,&fy_fr_fab,&fz_fr_fab)}, + dxDp, sync_factor*dt, 0, state_indx, ncomp, amrex::RunOn::Device); + } else if (flagfab.getType(bx) != FabType::covered ) { + advflux_reg->FineAdd(mfi, + {AMREX_D_DECL(&fx_fr_fab,&fy_fr_fab,&fz_fr_fab)}, + dxDp, sync_factor*dt, (*volfrac)[mfi], + {AMREX_D_DECL(&(*areafrac[0])[mfi], &(*areafrac[1])[mfi], &(*areafrac[2])[mfi])}, + dm_as_fine, 0, state_indx, ncomp, amrex::RunOn::Device); + } + } // do_reflux && (level > 0) + } // not covered +#else + // This is a hack-y way of testing whether this ComputeAofs call + // came from the mac_sync (do_crse_add = false) + // or from the regular advance (do_crse_add = true). When the call + // comes from the mac_sync, the multiplier in FineAdd needs to have + // the opposite sign + Real sync_factor = do_crse_add ? 1.0 : -1.0; + + // Update the flux registers when no EB + if ( do_reflux && (level < parent->finestLevel()) ) { + getAdvFluxReg(level+1).CrseAdd(mfi, + {AMREX_D_DECL(&fx_fab,&fy_fab,&fz_fab)}, + dxDp, sync_factor*dt, flux_comp, state_indx, ncomp, amrex::RunOn::Device); + } // do_reflux && level < finest_level + + if ( do_reflux && (level > 0) ) { + advflux_reg->FineAdd(mfi, + {AMREX_D_DECL(&fx_fab,&fy_fab,&fz_fab)}, + dxDp, sync_factor*dt, flux_comp, state_indx, ncomp, amrex::RunOn::Device); + } // do_reflux && (level > 0) +#endif + } // mfi +} + + +#ifdef AMREX_USE_EB +void +NavierStokesBase::InitialRedistribution () +{ + // Next we must redistribute the initial solution if we are going to use + // MergeRedist or StateRedist redistribution schemes + if ( redistribution_type != "StateRedist" ) { + return; + } + + if (verbose) { + amrex::Print() << "Doing initial redistribution... " << std::endl; + } + + // Initial data are set at new time step + MultiFab& S_new = get_new_data(State_Type); + // We must fill internal ghost values before calling redistribution + // We also need any physical boundary conditions imposed if we are + // calling state redistribution (because that calls the slope routine) + FillPatchIterator S_fpi(*this, S_new, nghost_state(), state[State_Type].curTime(), + State_Type, 0, NUM_STATE); + MultiFab& Smf=S_fpi.get_mf(); + + MultiFab tmp( grids, dmap, NUM_STATE, nghost_state(), MFInfo(), Factory() ); + MultiFab::Copy(tmp, Smf, 0, 0, NUM_STATE, nghost_state()); + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(S_new,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + + auto const& fact = dynamic_cast(S_new.Factory()); + + EBCellFlagFab const& flagfab = fact.getMultiEBCellFlagFab()[mfi]; + Array4 const& flag = flagfab.const_array(); + + if ( (flagfab.getType(bx) != FabType::covered) && + (flagfab.getType(amrex::grow(bx,4)) != FabType::regular) ) + { + Array4 AMREX_D_DECL(fcx, fcy, fcz), ccc, vfrac, AMREX_D_DECL(apx, apy, apz); + + AMREX_D_TERM(fcx = fact.getFaceCent()[0]->const_array(mfi);, + fcy = fact.getFaceCent()[1]->const_array(mfi);, + fcz = fact.getFaceCent()[2]->const_array(mfi);); + + ccc = fact.getCentroid().const_array(mfi); + + AMREX_D_TERM(apx = fact.getAreaFrac()[0]->const_array(mfi);, + apy = fact.getAreaFrac()[1]->const_array(mfi);, + apz = fact.getAreaFrac()[2]->const_array(mfi);); + + vfrac = fact.getVolFrac().const_array(mfi); + + ApplyInitialRedistribution( bx, AMREX_SPACEDIM, + Smf.array(mfi), tmp.array(mfi), + flag, AMREX_D_DECL(apx, apy, apz), vfrac, + AMREX_D_DECL(fcx, fcy, fcz), + ccc, m_bcrec_velocity_d.dataPtr(), + geom, redistribution_type); + ApplyInitialRedistribution( bx, NUM_SCALARS, + Smf.array(mfi,Density), tmp.array(mfi,Density), + flag, AMREX_D_DECL(apx, apy, apz), vfrac, + AMREX_D_DECL(fcx, fcy, fcz), + ccc,m_bcrec_scalars_d.dataPtr(), + geom, redistribution_type); + } + } + + MultiFab::Copy(S_new, Smf, 0, 0, NUM_STATE, 0); +} +#endif + +// +// ls related +// +void +NavierStokesBase::fill_allgts(MultiFab& mf, int type, int scomp, int ncomp, Real time) +{ + // Fill phys bc ,ff bc, cf bc + int ngrow = mf.nGrow(); + FillPatchIterator mf_fpi(*this, mf, ngrow, time, type, scomp, ncomp); + MultiFab& mf_temp = mf_fpi.get_mf(); + // MultiFab::Copy(mfdst, mfsrc, sc, dc, nc, ng); // Copy from mfsrc to mfdst + MultiFab::Copy(mf, mf_temp, 0, scomp, ncomp, ngrow); +} + +void +NavierStokesBase::reinit() +{ + + if(verbose) amrex::Print() << "In the NavierStokesBase::reinit() " << std::endl; + + const Real* dx = geom.CellSize(); + Real dxmin = dx[0]; + for (int d=1; d,AMREX_SPACEDIM> phi_normal; + int normalize = 1; + cc_to_cc_grad(phi_normal, phi_ctime, geom, normalize); + + // Step 5: calculate diffs (phi2) and comp (phi1), add them to diffs_comp (override phi_ctime) + MultiFab phi1(grids,dmap,1,2); + MultiFab phi2(grids,dmap,1,2); + phi1.setVal(0.0); phi2.setVal(0.0); + levelset_diffcomp(phi_normal, phi_ctime, phi1, phi2, epsG, epsG2); + + // Step 6: update the level set + phi_ctime.mult(dt, 0); + MultiFab::Add(phi_ctime, phi_original, 0, 0, 1, 0); + + // Step 7: same as the Step 3 + MultiFab::Copy(S_new, phi_ctime, 0, phicomp, 1, phi_ctime.nGrow()); + fill_allgts(S_new,State_Type,phicomp,1,cur_time); + MultiFab::Copy(phi_ctime, S_new, phicomp, 0, 1, phi_ctime.nGrow()); + + } + +} + +void +NavierStokesBase::reinitialization_sussman (Real dt, + int loop_iter) +{ + + if (verbose) amrex::Print() << "In the NavierStokesBase::reinitialization_sussman() " << std::endl; + if (verbose) amrex::Print() << "loop_iter " << loop_iter << std::endl; + + // Step 1: get sgn, similar to heaviside + if (loop_iter==1) { + phi_to_sgn0(phi_original); + } + + // Step 2: RK2 + // phi2, phi3, and G0 have 2 ghost cells, initialize them as 0, + // and these multifabs only influence the minmod function at the boundary; + MultiFab phi2(grids,dmap,1,2); + MultiFab phi3(grids,dmap,1,2); + MultiFab G0(grids,dmap,1,2); + phi2.setVal(0.0); phi3.setVal(0.0); G0.setVal(0.0); + rk_first_reinit(phi_ctime, phi2, phi3, sgn0, G0, dt, phi_original); + + // Step 3: copy phi_ctime back to phi in S_new, fill phi's bc data in S_new, then + // copy it to phi_ctime + const Real cur_time = state[State_Type].curTime(); + MultiFab& S_new = get_new_data(State_Type); + MultiFab::Copy(S_new, phi_ctime, 0, phicomp, 1, phi_ctime.nGrow()); + fill_allgts(S_new,State_Type,phicomp,1,cur_time); + MultiFab::Copy(phi_ctime, S_new, phicomp, 0, 1, phi_ctime.nGrow()); + + // Step 4: RK2 + rk_second_reinit(phi_ctime, phi2, phi3, sgn0, G0, dt, phi_original); + + // Step 5: same as the Step 3 + MultiFab::Copy(S_new, phi_ctime, 0, phicomp, 1, phi_ctime.nGrow()); + fill_allgts(S_new,State_Type,phicomp,1,cur_time); + MultiFab::Copy(phi_ctime, S_new, phicomp, 0, 1, phi_ctime.nGrow()); + + // Step 6: Fix mass + // Step 6-1: set inputs variables as 0.0 + MultiFab ld(grids,dmap,1,2); + MultiFab lambdad(grids,dmap,1,2); + MultiFab deltafunc(grids,dmap,1,2); + phi2.setVal(0.0); phi3.setVal(0.0); ld.setVal(0.0); lambdad.setVal(0.0); deltafunc.setVal(0.0); + + // Step 6-2: mass_fix + mass_fix(phi_ctime, phi_original, phi2, phi3, ld, lambdad, deltafunc, dt, loop_iter); + + // Step 6-3: same as Step 5 + MultiFab::Copy(S_new, phi_ctime, 0, phicomp, 1, phi_ctime.nGrow()); + fill_allgts(S_new,State_Type,phicomp,1,cur_time); + MultiFab::Copy(phi_ctime, S_new, phicomp, 0, 1, phi_ctime.nGrow()); +} + +void +NavierStokesBase::phi_to_sgn0 (MultiFab& phi) +{ + + if(verbose) amrex::Print() << "In the NavierStokesBase::phi_to_sgn0 " << std::endl; + + sgn0.setVal(0.0); + + const Real pi = 3.141592653589793238462643383279502884197; + Real eps = calculate_eps(geom, epsilon); + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phifab = phi.array(mfi); + auto const& sgn0fab = sgn0.array(mfi); + amrex::ParallelFor(vbx, [phifab, sgn0fab, pi, eps] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + + if (phifab(i,j,k) > eps) { + sgn0fab(i,j,k) = 1.0; + } else if (phifab(i,j,k) > -eps) { + sgn0fab(i,j,k) = phifab(i,j,k) / eps + 1.0 / pi * std::sin(phifab(i,j,k) * pi / eps); + } else { + sgn0fab(i,j,k) = -1.0; + } + + }); + } + +} + +void +NavierStokesBase::rk_first_reinit (MultiFab& phi_ctime, + MultiFab& phi2, + MultiFab& phi3, + MultiFab& sgn0, + MultiFab& G0, + Real delta_t, + MultiFab& phi_ori) +{ + + if(verbose) amrex::Print() << "NavierStokesBase::rk_first_reinit " << std::endl; + + Real eps = calculate_eps(geom, epsilon); + const GpuArray dxGpu = geom.CellSizeArray(); + + // MultiFab phi1_xface(amrex::convert(grids, IntVect(AMREX_D_DECL(1,0,0))), dmap, 1, 1); + MultiFab phi1_face(amrex::convert(grids, IntVect(AMREX_D_DECL(1,1,1))), dmap, 1, 1); // A node-based mf actually + phi1_face.setVal(0.0); + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi1_face,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + Box bx = mfi.growntilebox(); + // std::cout << "bx " << bx < 0.0 && dxp * sgn0fab(i, j, k) > -dxm * sgn0fab(i, j, k)) { + ddx = dxm; + } else { + ddx = (dxp + dxm) / 2.0; + } + phi3fab(i, j, k) = pow(ddx, 2); + }); + } + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi1_face,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + Box bx = mfi.growntilebox(); + auto const& phifab = phi_ctime.array(mfi); + auto const& phi1fab = phi1_face.array(mfi); + amrex::ParallelFor(bx, [phifab, phi1fab, dxGpu] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + phi1fab(i,j,k) = ( phifab(i,j,k) - phifab(i,j-1,k) )/dxGpu[1]; + }); + } + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + Box bx = mfi.growntilebox(1); + auto const& phi1fab = phi1_face.array(mfi); + auto const& phi2fab = phi2.array(mfi); + amrex::ParallelFor(bx, [phi1fab, phi2fab, dxGpu] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + phi2fab(i,j,k) = ( phi1fab(i,j+1,k) - phi1fab(i,j,k) )/dxGpu[1]; + }); + } + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phi1fab = phi1_face.array(mfi); + auto const& phi2fab = phi2.array(mfi); + auto const& phi3fab = phi3.array(mfi); + auto const& sgn0fab = sgn0.array(mfi); + amrex::ParallelFor(vbx, [phi1fab, phi2fab, phi3fab, sgn0fab, dxGpu] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + Real dym = phi1fab(i, j, k) + minmod(phi2fab(i, j - 1, k), phi2fab(i, j, k)) * dxGpu[1] / 2.0; + Real dyp = phi1fab(i, j + 1, k) - minmod(phi2fab(i, j, k), phi2fab(i, j + 1, k)) * dxGpu[1] / 2.0; + Real ddy = 0.0; + if (dyp * sgn0fab(i, j, k) < 0.0 && dym * sgn0fab(i, j, k) < -dyp * sgn0fab(i, j, k)) { + ddy = dyp; + } else if (dym * sgn0fab(i, j, k) > 0.0 && dyp * sgn0fab(i, j, k) > -dym * sgn0fab(i, j, k)) { + ddy = dym; + } else { + ddy = (dyp + dym) / 2.0; + } + phi3fab(i, j, k) += pow(ddy, 2); + if (AMREX_SPACEDIM==2) { + phi3fab(i, j, k) = std::sqrt(phi3fab(i, j, k)); + } + }); + } + +#if (AMREX_SPACEDIM==3) + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi1_face,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + Box bx = mfi.growntilebox(); + auto const& phifab = phi_ctime.array(mfi); + auto const& phi1fab = phi1_face.array(mfi); + amrex::ParallelFor(bx, [phifab, phi1fab, dxGpu] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + phi1fab(i,j,k) = ( phifab(i,j,k) - phifab(i,j,k-1) )/dxGpu[2]; + }); + } + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + Box bx = mfi.growntilebox(1); + auto const& phi1fab = phi1_face.array(mfi); + auto const& phi2fab = phi2.array(mfi); + amrex::ParallelFor(bx, [phi1fab, phi2fab, dxGpu] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + phi2fab(i,j,k) = ( phi1fab(i,j,k+1) - phi1fab(i,j,k) )/dxGpu[2]; + }); + } + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phi1fab = phi1_face.array(mfi); + auto const& phi2fab = phi2.array(mfi); + auto const& phi3fab = phi3.array(mfi); + auto const& sgn0fab = sgn0.array(mfi); + amrex::ParallelFor(vbx, [phi1fab, phi2fab, phi3fab, sgn0fab, dxGpu] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + Real dzm = phi1fab(i, j, k) + minmod(phi2fab(i, j, k - 1), phi2fab(i, j, k)) * dxGpu[2] / 2.0; + Real dzp = phi1fab(i, j, k + 1) - minmod(phi2fab(i, j, k), phi2fab(i, j, k + 1)) * dxGpu[2] / 2.0; + Real ddz = 0.0; + if (dzp * sgn0fab(i, j, k) < 0.0 && dzm * sgn0fab(i, j, k) < -dzp * sgn0fab(i, j, k)) { + ddz = dzp; + } else if (dzm * sgn0fab(i, j, k) > 0.0 && dzp * sgn0fab(i, j, k) > -dzm * sgn0fab(i, j, k)) { + ddz = dzm; + } else { + ddz = (dzp + dzm) / 2.0; + } + phi3fab(i, j, k) += pow(ddz, 2); + phi3fab(i, j, k) = std::sqrt(phi3fab(i, j, k)); + }); + } + +#endif + + MultiFab::Copy(G0, phi3, 0, 0, 1, 1); // 1 gt + G0.plus(-1.0, 1); // 1 gt + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phifab = phi_ctime.array(mfi); + auto const& phi2fab = phi2.array(mfi); + auto const& phi3fab = phi3.array(mfi); + auto const& G0fab = G0.array(mfi); + amrex::ParallelFor(vbx, [phifab, phi2fab, phi3fab, G0fab, delta_t] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + Real sgntmp = phifab(i, j, k) / + std::sqrt( pow(phifab(i, j, k), 2) + pow(phi3fab(i, j, k)*2.0*delta_t,2) ); + phi2fab(i, j, k) = phifab(i,j,k) - delta_t*sgntmp*G0fab(i,j,k); + }); + } + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phifab = phi_ctime.array(mfi); + auto const& phi2fab = phi2.array(mfi); + amrex::ParallelFor(vbx, [phifab, phi2fab, eps] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + if (phi2fab(i,j,k)*phifab(i,j,k) < 0.0) { + if (std::abs(phifab(i,j,k)) <= eps) { + phi2fab(i, j, k) = phifab(i,j,k) * 0.1; + } + else { + amrex::Abort("sign change in rk1 bulk flow!"); + } + } + }); + } + + MultiFab::Copy(phi_ctime, phi2, 0, 0, 1, 0); // only copy interior cells +} + +void +NavierStokesBase::rk_second_reinit (MultiFab& phi_ctime, + MultiFab& phi2, + MultiFab& phi3, + MultiFab& sgn0, + MultiFab& G0, + Real delta_t, + MultiFab& phi_ori) +{ + + if(verbose) amrex::Print() << "In the NavierStokesBase::rk_second_reinit " << std::endl; + + Real eps = calculate_eps(geom, epsilon); + const GpuArray dxGpu = geom.CellSizeArray(); + + // MultiFab phi1_xface(amrex::convert(grids, IntVect(AMREX_D_DECL(1,0,0))), dmap, 1, 1); + MultiFab phi1_face(amrex::convert(grids, IntVect(AMREX_D_DECL(1,1,1))), dmap, 1, 1); // A node-based mf actually + phi1_face.setVal(0.0); + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi1_face,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + Box bx = mfi.growntilebox(); + auto const& phifab = phi_ctime.array(mfi); + auto const& phi1fab = phi1_face.array(mfi); + amrex::ParallelFor(bx, [phifab, phi1fab, dxGpu] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + phi1fab(i,j,k) = ( phifab(i,j,k) - phifab(i-1,j,k) )/dxGpu[0]; + }); + } + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + Box bx = mfi.growntilebox(1); + auto const& phi1fab = phi1_face.array(mfi); + auto const& phi2fab = phi2.array(mfi); + amrex::ParallelFor(bx, [phi1fab, phi2fab, dxGpu] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + phi2fab(i,j,k) = ( phi1fab(i+1,j,k) - phi1fab(i,j,k) )/dxGpu[0]; + }); + } + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phi1fab = phi1_face.array(mfi); + auto const& phi2fab = phi2.array(mfi); + auto const& phi3fab = phi3.array(mfi); + auto const& sgn0fab = sgn0.array(mfi); + amrex::ParallelFor(vbx, [phi1fab, phi2fab, phi3fab, sgn0fab, dxGpu] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + Real dxm = phi1fab(i, j, k) + minmod(phi2fab(i - 1, j, k), phi2fab(i, j, k)) * dxGpu[0] / 2.0; + Real dxp = phi1fab(i + 1, j, k) - minmod(phi2fab(i, j, k), phi2fab(i + 1, j, k)) * dxGpu[0] / 2.0; + Real ddx = 0.0; + if (dxp * sgn0fab(i, j, k) < 0.0 && dxm * sgn0fab(i, j, k) < -dxp * sgn0fab(i, j, k)) { + ddx = dxp; + } else if (dxm * sgn0fab(i, j, k) > 0.0 && dxp * sgn0fab(i, j, k) > -dxm * sgn0fab(i, j, k)) { + ddx = dxm; + } else { + ddx = (dxp + dxm) / 2.0; + } + phi3fab(i, j, k) = pow(ddx, 2); + }); + } + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi1_face,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + Box bx = mfi.growntilebox(); + auto const& phifab = phi_ctime.array(mfi); + auto const& phi1fab = phi1_face.array(mfi); + amrex::ParallelFor(bx, [phifab, phi1fab, dxGpu] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + phi1fab(i,j,k) = ( phifab(i,j,k) - phifab(i,j-1,k) )/dxGpu[1]; + }); + } + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + Box bx = mfi.growntilebox(1); + auto const& phi1fab = phi1_face.array(mfi); + auto const& phi2fab = phi2.array(mfi); + amrex::ParallelFor(bx, [phi1fab, phi2fab, dxGpu] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + phi2fab(i,j,k) = ( phi1fab(i,j+1,k) - phi1fab(i,j,k) )/dxGpu[1]; + }); + } + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phi1fab = phi1_face.array(mfi); + auto const& phi2fab = phi2.array(mfi); + auto const& phi3fab = phi3.array(mfi); + auto const& sgn0fab = sgn0.array(mfi); + amrex::ParallelFor(vbx, [phi1fab, phi2fab, phi3fab, sgn0fab, dxGpu] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + Real dym = phi1fab(i, j, k) + minmod(phi2fab(i, j - 1, k), phi2fab(i, j, k)) * dxGpu[1] / 2.0; + Real dyp = phi1fab(i, j + 1, k) - minmod(phi2fab(i, j, k), phi2fab(i, j + 1, k)) * dxGpu[1] / 2.0; + Real ddy = 0.0; + if (dyp * sgn0fab(i, j, k) < 0.0 && dym * sgn0fab(i, j, k) < -dyp * sgn0fab(i, j, k)) { + ddy = dyp; + } else if (dym * sgn0fab(i, j, k) > 0.0 && dyp * sgn0fab(i, j, k) > -dym * sgn0fab(i, j, k)) { + ddy = dym; + } else { + ddy = (dyp + dym) / 2.0; + } + phi3fab(i, j, k) += pow(ddy, 2); + if (AMREX_SPACEDIM==2) { + phi3fab(i, j, k) = std::sqrt(phi3fab(i, j, k)); + } + }); + } + +#if (AMREX_SPACEDIM==3) + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi1_face,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + Box bx = mfi.growntilebox(); + auto const& phifab = phi_ctime.array(mfi); + auto const& phi1fab = phi1_face.array(mfi); + amrex::ParallelFor(bx, [phifab, phi1fab, dxGpu] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + phi1fab(i,j,k) = ( phifab(i,j,k) - phifab(i,j,k-1) )/dxGpu[2]; + }); + } + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + Box bx = mfi.growntilebox(1); + auto const& phi1fab = phi1_face.array(mfi); + auto const& phi2fab = phi2.array(mfi); + amrex::ParallelFor(bx, [phi1fab, phi2fab, dxGpu] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + phi2fab(i,j,k) = ( phi1fab(i,j,k+1) - phi1fab(i,j,k) )/dxGpu[2]; + }); + } + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phi1fab = phi1_face.array(mfi); + auto const& phi2fab = phi2.array(mfi); + auto const& phi3fab = phi3.array(mfi); + auto const& sgn0fab = sgn0.array(mfi); + amrex::ParallelFor(vbx, [phi1fab, phi2fab, phi3fab, sgn0fab, dxGpu] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + Real dzm = phi1fab(i, j, k) + minmod(phi2fab(i, j, k - 1), phi2fab(i, j, k)) * dxGpu[2] / 2.0; + Real dzp = phi1fab(i, j, k + 1) - minmod(phi2fab(i, j, k), phi2fab(i, j, k + 1)) * dxGpu[2] / 2.0; + Real ddz = 0.0; + if (dzp * sgn0fab(i, j, k) < 0.0 && dzm * sgn0fab(i, j, k) < -dzp * sgn0fab(i, j, k)) { + ddz = dzp; + } else if (dzm * sgn0fab(i, j, k) > 0.0 && dzp * sgn0fab(i, j, k) > -dzm * sgn0fab(i, j, k)) { + ddz = dzm; + } else { + ddz = (dzp + dzm) / 2.0; + } + phi3fab(i, j, k) += pow(ddz, 2); + phi3fab(i, j, k) = std::sqrt(phi3fab(i, j, k)); + }); + } + +#endif + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phifab = phi_ctime.array(mfi); + auto const& phi2fab = phi2.array(mfi); + auto const& phi3fab = phi3.array(mfi); + auto const& G0fab = G0.array(mfi); + amrex::ParallelFor(vbx, [phifab, phi2fab, phi3fab, G0fab, delta_t] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + Real sgntmp = phifab(i, j, k) / + std::sqrt( pow(phifab(i, j, k), 2) + pow(phi3fab(i, j, k)*2.0*delta_t,2) ); + phi2fab(i, j, k) = phifab(i,j,k) - 0.5*delta_t*sgntmp*( + phi3fab(i,j,k) - 1.0 - G0fab(i,j,k)); + }); + } + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phifab = phi_ctime.array(mfi); + auto const& phi2fab = phi2.array(mfi); + amrex::ParallelFor(vbx, [phifab, phi2fab, eps] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + if (phi2fab(i,j,k)*phifab(i,j,k) < 0.0) { + if (std::abs(phifab(i,j,k)) <= eps) { + phi2fab(i, j, k) = phifab(i,j,k) * 0.1; + } + else { + amrex::Abort("sign change in rk2 bulk flow!"); + } + } + }); + } + + MultiFab::Copy(phi_ctime, phi2, 0, 0, 1, 0); // only copy interior cells + + // { + // // amrex::Gpu::LaunchSafeGuard lsg(false); // no needed here! + // int idx = 0; + // amrex::Print() << "phi_ctime " << " " << phi_ctime.max(idx,0) << " " << phi_ctime.min(idx,0) << " " << phi_ctime.norm2(0) << "\n"; + // } + // amrex::Abort("stop here"); + +} + +void +NavierStokesBase::mass_fix (MultiFab& phi_ctime, + MultiFab& phi_original, + MultiFab& phi2, + MultiFab& phi3, + MultiFab& ld, + MultiFab& la, + MultiFab& deltafunc, + Real delta_t, + int loop_iter) +{ + if(verbose) amrex::Print() << "NavierStokesBase::mass_fix " << std::endl; + + const Real pi = 3.141592653589793238462643383279502884197; + Real eps = calculate_eps(geom, epsilon); + Real tao = loop_iter * delta_t; + + // calculate ld and delta +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi_ctime,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.growntilebox(); + auto const& phifab = phi_ctime.array(mfi); + auto const& phiorifab = phi_original.array(mfi); + auto const& deltafab = deltafunc.array(mfi); + auto const& ldfab = ld.array(mfi); + amrex::ParallelFor(bx, [phifab, phiorifab, deltafab, ldfab, pi, eps, tao] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + ldfab(i,j,k) = (phifab(i,j,k) - phiorifab(i,j,k)) / tao; + if (phifab(i,j,k) > eps) { + deltafab(i,j,k) = 0.0; + } else if (phifab(i,j,k) > -eps) { + deltafab(i,j,k) = 0.5 * (1.0 + std::cos(phiorifab(i,j,k) * pi / eps)) / eps; + } else { + deltafab(i,j,k) = 0.0; + } + }); + } + + // get grid value of numerator (phi_2) and denominator (phi_3) +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.growntilebox(); + auto const& phi2fab = phi2.array(mfi); + auto const& phi3fab = phi3.array(mfi); + auto const& deltafab = deltafunc.array(mfi); + auto const& ldfab = ld.array(mfi); + amrex::ParallelFor(bx, [phi2fab, phi3fab, deltafab, ldfab] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + phi2fab(i,j,k) = -1.0 * deltafab(i,j,k) * ldfab(i,j,k); + phi3fab(i,j,k) = deltafab(i,j,k) * deltafab(i,j,k); + }); + } + +#if (AMREX_SPACEDIM==2) + // numerical integration +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phi2fab = phi2.array(mfi); + auto const& lafab = la.array(mfi); + amrex::ParallelFor(vbx, [phi2fab, lafab] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + Real temp_n = 0.0; + for(int jj=-1; jj<=1; jj++) { + for(int ii=-1; ii<=1; ii++) { + temp_n += phi2fab(i+ii,j+jj,k); + } + } + lafab(i,j,k) = 15.0 * phi2fab(i,j,k) + temp_n; + }); + } +#else + // numerical integration +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi2,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phi2fab = phi2.array(mfi); + auto const& lafab = la.array(mfi); + amrex::ParallelFor(vbx, [phi2fab, lafab] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + Real temp_n = 0.0; + for(int kk=-1; kk<=1; kk++) { + for(int jj=-1; jj<=1; jj++) { + for(int ii=-1; ii<=1; ii++) { + temp_n += phi2fab(i+ii,j+jj,k+kk); + } + } + } + lafab(i,j,k) = 51.0 * phi2fab(i,j,k) + temp_n; + }); + } +#endif + + // copy + MultiFab::Copy(phi2, la, 0, 0, 1, 0); // only copy interior cells + +#if (AMREX_SPACEDIM==2) + // numerical integration +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phi3fab = phi3.array(mfi); + auto const& lafab = la.array(mfi); + amrex::ParallelFor(vbx, [phi3fab, lafab] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + Real temp_d = 0.0; + for(int jj=-1; jj<=1; jj++) { + for(int ii=-1; ii<=1; ii++) { + temp_d += phi3fab(i+ii,j+jj,k); + } + } + lafab(i,j,k) = 15.0 * phi3fab(i,j,k) + temp_d; + }); + } +#else + // numerical integration +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phi3fab = phi3.array(mfi); + auto const& lafab = la.array(mfi); + amrex::ParallelFor(vbx, [phi3fab, lafab] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + Real temp_d = 0.0; + for(int kk=-1; kk<=1; kk++) { + for(int jj=-1; jj<=1; jj++) { + for(int ii=-1; ii<=1; ii++) { + temp_d += phi3fab(i+ii,j+jj,k+kk); + } + } + } + lafab(i,j,k) = 51.0 * phi3fab(i,j,k) + temp_d; + }); + } +#endif + + // copy + MultiFab::Copy(phi3, la, 0, 0, 1, 0); // only copy interior cells + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi3,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phi2fab = phi2.array(mfi); + auto const& phi3fab = phi3.array(mfi); + auto const& lafab = la.array(mfi); + amrex::ParallelFor(vbx, [phi2fab, phi3fab, lafab] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + lafab(i,j,k) = phi2fab(i,j,k) / (phi3fab(i,j,k) + 1.e-12); + }); + } + +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi_ctime,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.validbox(); + auto const& phifab = phi_ctime.array(mfi); + auto const& lafab = la.array(mfi); + auto const& deltafab = deltafunc.array(mfi); + amrex::ParallelFor(vbx, [phifab, lafab, deltafab, tao] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + phifab(i,j,k) += tao * lafab(i,j,k) * deltafab(i,j,k); + }); + } + + // { + // // amrex::Gpu::LaunchSafeGuard lsg(false); // no needed here! + // int idx = 0; + // amrex::Print() << "phi_ctime " << " " << phi_ctime.max(idx,0) << " " << phi_ctime.min(idx,0) << " " << phi_ctime.norm2(0) << "\n"; + // } + // amrex::Abort("stop here"); + +} + +MultiFab& +NavierStokesBase::get_phi_half_time () +{ + // + // Fill it in when needed ... + // +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(phi_half,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.growntilebox(); + auto const& phi_h = phi_half.array(mfi); + auto const& phi_p = phi_ptime.array(mfi); + auto const& phi_c = phi_ctime.array(mfi); + amrex::ParallelFor(bx, [phi_h, phi_p, phi_c] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + phi_h(i,j,k) = 0.5 * (phi_p(i,j,k) + phi_c(i,j,k)); + }); + } + return phi_half; } \ No newline at end of file diff --git a/Source/OutFlowBC.H b/Source/OutFlowBC.H index 85f82211..458e6a34 100644 --- a/Source/OutFlowBC.H +++ b/Source/OutFlowBC.H @@ -1,33 +1,38 @@ - -#ifndef IAMR_OUTFLOWBC_H_ -#define IAMR_OUTFLOWBC_H_ - -#include -#include -#include -#include - -// -// The baseclass for MacOutFlowBC and ProjOutFlowBC. -// - -class OutFlowBC -{ -public: - static amrex::Box SemiGrow (const amrex::Box& baseBox, - int nGrow, - int direction); - - static amrex::Box SemiCoarsen (const amrex::Box& baseBox, - int ref_factor, - int direction); - - static void GetOutFlowFaces (bool& haveOutFlow, - amrex::Orientation* outFaces, - amrex::BCRec* _phys_bc, - int& numOutFlowBC); - - static bool HasOutFlowBC (amrex::BCRec* _phys_bc); -}; - -#endif /*_OUTFLOWBC_H_*/ +/* + * SPDX-FileCopyrightText: 2000 - 2023 Berkeley Lab + * + * SPDX-License-Identifier: LicenseRef-OpenSource + */ + +#ifndef IAMR_OUTFLOWBC_H_ +#define IAMR_OUTFLOWBC_H_ + +#include +#include +#include +#include + +// +// The baseclass for MacOutFlowBC and ProjOutFlowBC. +// + +class OutFlowBC +{ +public: + static amrex::Box SemiGrow (const amrex::Box& baseBox, + int nGrow, + int direction); + + static amrex::Box SemiCoarsen (const amrex::Box& baseBox, + int ref_factor, + int direction); + + static void GetOutFlowFaces (bool& haveOutFlow, + amrex::Orientation* outFaces, + amrex::BCRec* _phys_bc, + int& numOutFlowBC); + + static bool HasOutFlowBC (amrex::BCRec* _phys_bc); +}; + +#endif /*_OUTFLOWBC_H_*/ diff --git a/Source/OutFlowBC.cpp b/Source/OutFlowBC.cpp index cf39ff99..16710b6e 100644 --- a/Source/OutFlowBC.cpp +++ b/Source/OutFlowBC.cpp @@ -1,4 +1,6 @@ - +// SPDX-FileCopyrightText: 2000 - 2023 Berkeley Lab +// +// SPDX-License-Identifier: LicenseRef-OpenSource #include #include diff --git a/Source/Projection.H b/Source/Projection.H index 8623606e..dcf77410 100644 --- a/Source/Projection.H +++ b/Source/Projection.H @@ -1,262 +1,269 @@ - -#ifndef IAMR_Projection_H_ -#define IAMR_Projection_H_ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef AMREX_USE_EB -#include -#endif - -class Projection -{ -protected: - static const int maxlev = 10; - static const int LEVEL_PROJ = 1001; - static const int INITIAL_VEL = 1002; - static const int INITIAL_PRESS = 1003; - static const int INITIAL_SYNC = 1004; - static const int SYNC_PROJ = 1005; - static const int FILTER_P = 1006; - -public: - - Projection (amrex::Amr* _parent, - amrex::BCRec* _phys_bc, - int _do_sync_proj, - int /*_finest_level*/, - int _radius_grow ); - - // - // Set a level in the projector. - // - void install_level (int level, - amrex::AmrLevel* level_data, - amrex::Vector< amrex::Vector >* _radius); -#ifdef AMREX_USE_EB - void install_level (int level, - amrex::AmrLevel* level_data, - amrex::Vector< amrex::Vector >* _radius, - const amrex::EBFArrayBoxFactory& _ebfactory); - -#endif - // - // Compute the level projection in NavierStokes::advance. - // - void level_project (int level, - amrex::Real time, - amrex::Real dt, - amrex::Real cur_pres_time, - const amrex::Geometry& geom, - amrex::MultiFab& U_old, - amrex::MultiFab& U_new, - amrex::MultiFab& P_old, - amrex::MultiFab& P_new, - amrex::MultiFab& rho_half, - SyncRegister* crse_sync_reg, - SyncRegister* fine_sync_reg, - int crse_dt_ratio, - int iteration, - int have_divu); - - // solve DG(correction to P_new) = -D G^perp p^(n-half) - // or DG(correction to P_new) = -D G^perp p^(n-half) - D(U^n /dt) - void filterP(int level, - const amrex::Geometry& geom, - amrex::MultiFab &P_old, - amrex::MultiFab &P_new, - amrex::MultiFab &U_old, - amrex::MultiFab &rho_half, - int ** bc, - amrex::Real time, - amrex::Real dt, - int have_divu); - // - // A sync project involving the coarse and fine level of a 2 level system. - // - void MLsyncProject (int c_lev, - amrex::MultiFab& pres_crse, - amrex::MultiFab& vel_crse, - amrex::MultiFab& cc_rhs_crse, - amrex::MultiFab& pres_fine, - amrex::MultiFab& vel_fine, - amrex::MultiFab& cc_rhs_fine, - amrex::MultiFab& rho_crse, - amrex::MultiFab& rho_fine, - amrex::MultiFab& Vsync, - amrex::MultiFab& V_corr, - amrex::MultiFab& phi, - SyncRegister* rhs_sync_reg, - SyncRegister* crsr_sync_reg, - amrex::Real dt_crse, - amrex::IntVect& ratio, - int crse_iteration, - int crse_dt_ratio, - const amrex::Geometry& crse_geom); - // - // This projects an initial vorticity field to define a velocity field. - // - void initialVorticityProject (int c_lev); - // - // This computes the stream function, given the velocity field - // *AND ASSUMING* no-flow boundaries on all physical boundaries. - // - void getStreamFunction (amrex::Vector >&); - // - // The initial velocity projection in post_init. - // This function ensures that the velocities are nondivergent. - // - void initialVelocityProject (int c_lev, - amrex::Real divu_time, - int have_divu, - int init_vel_iter = 1 ); - - // - // This function creates an initially hydrostatic pressure field - // in the case of nonzero gravity. - // - void initialPressureProject (int c_lev); - // - // The velocity projection in post_init, which computes the initial - // pressure used in the timestepping. - // - void initialSyncProject (int c_lev, - const amrex::Vector& sig, - amrex::Real dt, - amrex::Real strt_time, - int have_divu); - // - // Multiply a MultiFab by radius for r-z coordinates. - // These should really be protected. - // - void radMultScal (int level, amrex::MultiFab& mf) const; - - // - // Read parameters from the input file. - // - static void Initialize (); - - static void Finalize (); - - // - // Convert U to an Acceleration like quantity - // Unew = (Unew - Uold)/alpha - // - static void ConvertUnew (amrex::MultiFab& Unew, - amrex::MultiFab& Uold, - amrex::Real alpha, - const amrex::BoxArray& grids ); - // - // Convert U to an Acceleration like quantity. - // Unew = (Unew - Uold)/alpha - // - static void ConvertUnew (amrex::FArrayBox& Unew, - amrex::FArrayBox& Uold, - amrex::Real alpha, - const amrex::Box& grd); - // - // This function scales variables at the start of a projection. - // - void scaleVar (amrex::MultiFab* sig, - int sig_nghosts, - amrex::MultiFab* vel, - int level) const; - // - // This function rescales variables at the end of a projection. - // - void rescaleVar (amrex::MultiFab* sig, - int sig_nghosts, - amrex::MultiFab* vel, - int level) const; - - void set_outflow_bcs (int which_call, - const amrex::Vector& phi, - const amrex::Vector& Vel_in, - const amrex::Vector& Divu_in, - const amrex::Vector& Sig_in, - int c_lev, - int f_lev, - int have_divu); - - void set_outflow_bcs_at_level (int which_call, - int lev, - int c_lev, - amrex::Box* state_strip, - amrex::Orientation* outFacesAtThisLevel, - int numOutFlowFaces, - const amrex::Vector& phi, - amrex::MultiFab* Vel_in, - amrex::MultiFab* Divu_in, - amrex::MultiFab* Sig_in, - int have_divu, - amrex::Real gravity); - - void computeRhoG (amrex::FArrayBox* rhoFab, - amrex::FArrayBox* phiFab, - const amrex::Geometry& geom, - amrex::Orientation* outFaces, - int numOutFlowFaces, - amrex::Real gravity); - - void putDown (const amrex::Vector& phi, - amrex::FArrayBox* phi_fine_strip, - int c_lev, int f_lev, const amrex::Orientation* outFaces, - int numOutFlowFaces, int ncStripWidth) const; - // - // Pointers to amrlevel and amr. - // - amrex::Amr* parent; - amrex::Vector LevelData; -#ifdef AMREX_USE_EB - // pointer to eb factory on each level - // could potentially do away with this and use LevelData to get ebFactory... - amrex::Vector ebfactory; -#endif - // - // The array of Radii, and number of radii ghost cells. - // - int radius_grow; - amrex::Vector< amrex::Vector< amrex::Vector > * > radius; - - // - // Boundary objects. - // - amrex::BCRec* phys_bc; - - int do_sync_proj; - - static int verbose; - static amrex::Real proj_tol; - static amrex::Real sync_tol; - static amrex::Real proj_abs_tol; - static int proj_2; - static int rho_wgt_vel_proj; - static int do_outflow_bcs; - static int add_vort_proj; - - void doMLMGNodalProjection (int c_lev, int nlevel, - const amrex::Vector& vel, - const amrex::Vector& phi, - const amrex::Vector& sig, - const amrex::Vector& rhcc, - const amrex::Vector& rhnd, - amrex::Real rel_tol, amrex::Real abs_tol, - bool increment_gp, - amrex::MultiFab* sync_resid_crse=nullptr, - amrex::MultiFab* sync_resid_fine=nullptr, - bool doing_initial_vortproj=false); - - // set velocity in ghost cells to zero except for inflow - void set_boundary_velocity (int c_lev, int nlevel, - const amrex::Vector& vel, - bool inflowCorner) const; - -}; -#endif +/* + * SPDX-FileCopyrightText: 1997 - 2023 Berkeley Lab; 2023 - 2025 Yadong Zeng + * + * SPDX-License-Identifier: LicenseRef-OpenSource + * Modified from IAMR, originally developed at Lawrence Berkeley National Lab. + * Original source: https://github.com/AMReX-Fluids/IAMR + */ + +#ifndef IAMR_Projection_H_ +#define IAMR_Projection_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef AMREX_USE_EB +#include +#endif + +class Projection +{ +protected: + static const int maxlev = 10; + static const int LEVEL_PROJ = 1001; + static const int INITIAL_VEL = 1002; + static const int INITIAL_PRESS = 1003; + static const int INITIAL_SYNC = 1004; + static const int SYNC_PROJ = 1005; + static const int FILTER_P = 1006; + +public: + + Projection (amrex::Amr* _parent, + amrex::BCRec* _phys_bc, + int _do_sync_proj, + int /*_finest_level*/, + int _radius_grow ); + + // + // Set a level in the projector. + // + void install_level (int level, + amrex::AmrLevel* level_data, + amrex::Vector< amrex::Vector >* _radius); +#ifdef AMREX_USE_EB + void install_level (int level, + amrex::AmrLevel* level_data, + amrex::Vector< amrex::Vector >* _radius, + const amrex::EBFArrayBoxFactory& _ebfactory); + +#endif + // + // Compute the level projection in NavierStokes::advance. + // + void level_project (int level, + amrex::Real time, + amrex::Real dt, + amrex::Real cur_pres_time, + const amrex::Geometry& geom, + amrex::MultiFab& U_old, + amrex::MultiFab& U_new, + amrex::MultiFab& P_old, + amrex::MultiFab& P_new, + amrex::MultiFab& rho_half, + SyncRegister* crse_sync_reg, + SyncRegister* fine_sync_reg, + int crse_dt_ratio, + int iteration, + int have_divu); + + // solve DG(correction to P_new) = -D G^perp p^(n-half) + // or DG(correction to P_new) = -D G^perp p^(n-half) - D(U^n /dt) + void filterP(int level, + const amrex::Geometry& geom, + amrex::MultiFab &P_old, + amrex::MultiFab &P_new, + amrex::MultiFab &U_old, + amrex::MultiFab &rho_half, + int ** bc, + amrex::Real time, + amrex::Real dt, + int have_divu); + // + // A sync project involving the coarse and fine level of a 2 level system. + // + void MLsyncProject (int c_lev, + amrex::MultiFab& pres_crse, + amrex::MultiFab& vel_crse, + amrex::MultiFab& cc_rhs_crse, + amrex::MultiFab& pres_fine, + amrex::MultiFab& vel_fine, + amrex::MultiFab& cc_rhs_fine, + amrex::MultiFab& rho_crse, + amrex::MultiFab& rho_fine, + amrex::MultiFab& Vsync, + amrex::MultiFab& V_corr, + amrex::MultiFab& phi, + SyncRegister* rhs_sync_reg, + SyncRegister* crsr_sync_reg, + amrex::Real dt_crse, + amrex::IntVect& ratio, + int crse_iteration, + int crse_dt_ratio, + const amrex::Geometry& crse_geom); + // + // This projects an initial vorticity field to define a velocity field. + // + void initialVorticityProject (int c_lev); + // + // This computes the stream function, given the velocity field + // *AND ASSUMING* no-flow boundaries on all physical boundaries. + // + void getStreamFunction (amrex::Vector >&); + // + // The initial velocity projection in post_init. + // This function ensures that the velocities are nondivergent. + // + void initialVelocityProject (int c_lev, + amrex::Real divu_time, + int have_divu, + int init_vel_iter = 1 ); + + // + // This function creates an initially hydrostatic pressure field + // in the case of nonzero gravity. + // + void initialPressureProject (int c_lev); + // + // The velocity projection in post_init, which computes the initial + // pressure used in the timestepping. + // + void initialSyncProject (int c_lev, + const amrex::Vector& sig, + amrex::Real dt, + amrex::Real strt_time, + int have_divu); + // + // Multiply a MultiFab by radius for r-z coordinates. + // These should really be protected. + // + void radMultScal (int level, amrex::MultiFab& mf) const; + + // + // Read parameters from the input file. + // + static void Initialize (); + + static void Finalize (); + + // + // Convert U to an Acceleration like quantity + // Unew = (Unew - Uold)/alpha + // + static void ConvertUnew (amrex::MultiFab& Unew, + amrex::MultiFab& Uold, + amrex::Real alpha, + const amrex::BoxArray& grids ); + // + // Convert U to an Acceleration like quantity. + // Unew = (Unew - Uold)/alpha + // + static void ConvertUnew (amrex::FArrayBox& Unew, + amrex::FArrayBox& Uold, + amrex::Real alpha, + const amrex::Box& grd); + // + // This function scales variables at the start of a projection. + // + void scaleVar (amrex::MultiFab* sig, + int sig_nghosts, + amrex::MultiFab* vel, + int level) const; + // + // This function rescales variables at the end of a projection. + // + void rescaleVar (amrex::MultiFab* sig, + int sig_nghosts, + amrex::MultiFab* vel, + int level) const; + + void set_outflow_bcs (int which_call, + const amrex::Vector& phi, + const amrex::Vector& Vel_in, + const amrex::Vector& Divu_in, + const amrex::Vector& Sig_in, + int c_lev, + int f_lev, + int have_divu); + + void set_outflow_bcs_at_level (int which_call, + int lev, + int c_lev, + amrex::Box* state_strip, + amrex::Orientation* outFacesAtThisLevel, + int numOutFlowFaces, + const amrex::Vector& phi, + amrex::MultiFab* Vel_in, + amrex::MultiFab* Divu_in, + amrex::MultiFab* Sig_in, + int have_divu, + amrex::Real gravity); + + void computeRhoG (amrex::FArrayBox* rhoFab, + amrex::FArrayBox* phiFab, + const amrex::Geometry& geom, + amrex::Orientation* outFaces, + int numOutFlowFaces, + amrex::Real gravity); + + void putDown (const amrex::Vector& phi, + amrex::FArrayBox* phi_fine_strip, + int c_lev, int f_lev, const amrex::Orientation* outFaces, + int numOutFlowFaces, int ncStripWidth) const; + // + // Pointers to amrlevel and amr. + // + amrex::Amr* parent; + amrex::Vector LevelData; +#ifdef AMREX_USE_EB + // pointer to eb factory on each level + // could potentially do away with this and use LevelData to get ebFactory... + amrex::Vector ebfactory; +#endif + // + // The array of Radii, and number of radii ghost cells. + // + int radius_grow; + amrex::Vector< amrex::Vector< amrex::Vector > * > radius; + + // + // Boundary objects. + // + amrex::BCRec* phys_bc; + + int do_sync_proj; + + static int verbose; + static amrex::Real proj_tol; + static amrex::Real sync_tol; + static amrex::Real proj_abs_tol; + static int proj_2; + static int rho_wgt_vel_proj; + static int do_outflow_bcs; + static int add_vort_proj; + + void doMLMGNodalProjection (int c_lev, int nlevel, + const amrex::Vector& vel, + const amrex::Vector& phi, + const amrex::Vector& sig, + const amrex::Vector& rhcc, + const amrex::Vector& rhnd, + amrex::Real rel_tol, amrex::Real abs_tol, + bool increment_gp, + amrex::MultiFab* sync_resid_crse=nullptr, + amrex::MultiFab* sync_resid_fine=nullptr, + bool doing_initial_vortproj=false); + + // set velocity in ghost cells to zero except for inflow + void set_boundary_velocity (int c_lev, int nlevel, + const amrex::Vector& vel, + bool inflowCorner) const; + +}; +#endif diff --git a/Source/Projection.cpp b/Source/Projection.cpp index 67b1ed5b..5e928ac3 100644 --- a/Source/Projection.cpp +++ b/Source/Projection.cpp @@ -1,3 +1,9 @@ +// SPDX-FileCopyrightText: 1997 - 2023 Berkeley Lab; 2023 - 2025 Yadong Zeng +// +// SPDX-License-Identifier: LicenseRef-OpenSource +// Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +// Original source: https://github.com/AMReX-Fluids/IAMR + #include #include #include diff --git a/Source/RegType.H b/Source/RegType.H index b4af3faf..25f29c11 100644 --- a/Source/RegType.H +++ b/Source/RegType.H @@ -1,8 +1,15 @@ - -#ifndef IAMR_RegType_H_ -#define IAMR_RegType_H_ - -enum RegType { interior, exterior, periodic, refWall, inflow, - outflow, REG_TYPE_SIZE}; - -#endif +/* + * SPDX-FileCopyrightText: 1997 - 2023 Berkeley Lab; 2023 - 2025 Yadong Zeng + * + * SPDX-License-Identifier: LicenseRef-OpenSource + * Modified from IAMR, originally developed at Lawrence Berkeley National Lab. + * Original source: https://github.com/AMReX-Fluids/IAMR + */ + +#ifndef IAMR_RegType_H_ +#define IAMR_RegType_H_ + +enum RegType { interior, exterior, periodic, refWall, inflow, + outflow, REG_TYPE_SIZE}; + +#endif diff --git a/Source/SyncRegister.H b/Source/SyncRegister.H index f25b91a2..c374be32 100644 --- a/Source/SyncRegister.H +++ b/Source/SyncRegister.H @@ -1,65 +1,70 @@ - -#ifndef IAMR_SYNCREGISTER_H_ -#define IAMR_SYNCREGISTER_H_ - -#include -#include -#include -#include -#include -#include - -class SyncRegister - : - public amrex::BndryRegister -{ -public: - - /** - * \brief The default constructor. - */ - SyncRegister (); - - /** - * \brief The constructor. This version allows setting the DistributionMapping. - * - * - * \param fine_boxes - * \param dmap - * \param ref_ratio - */ - SyncRegister (const amrex::BoxArray& fine_boxes, - const amrex::DistributionMapping& dmap, - const amrex::IntVect& ref_ratio); - - /** - * \brief The destructor. - */ - ~SyncRegister () = default; - - void CrseInit (amrex::MultiFab& Sync_resid_crse, const amrex::Geometry& crse_geom, amrex::Real mult); - - void FineAdd (amrex::MultiFab& Sync_resid_fine, const amrex::Geometry& crse_geom, amrex::Real mult); - - void CompAdd (amrex::MultiFab& Sync_resid_fine, - const amrex::Geometry& fine_geom, - const amrex::Geometry& crse_geom, - const amrex::BoxArray& Pgrids, amrex::Real mult); - - void InitRHS (amrex::MultiFab& rhs, const amrex::Geometry& geom, const amrex::BCRec& phys_bc); - - SyncRegister (SyncRegister&& rhs) noexcept = default; - - SyncRegister (const SyncRegister& rhs) = delete; - SyncRegister& operator= (const SyncRegister& rhs) = delete; - SyncRegister& operator= ( SyncRegister&& rhs) = delete; - - void clear (); - -private: - - amrex::FabSet bndry_mask[2*AMREX_SPACEDIM]; - amrex::IntVect ratio; -}; - -#endif /*_SYNCREGISTER_H_*/ +/* + * SPDX-FileCopyrightText: 1997 - 2023 Berkeley Lab + * + * SPDX-License-Identifier: LicenseRef-OpenSource + */ + +#ifndef IAMR_SYNCREGISTER_H_ +#define IAMR_SYNCREGISTER_H_ + +#include +#include +#include +#include +#include +#include + +class SyncRegister + : + public amrex::BndryRegister +{ +public: + + /** + * \brief The default constructor. + */ + SyncRegister (); + + /** + * \brief The constructor. This version allows setting the DistributionMapping. + * + * + * \param fine_boxes + * \param dmap + * \param ref_ratio + */ + SyncRegister (const amrex::BoxArray& fine_boxes, + const amrex::DistributionMapping& dmap, + const amrex::IntVect& ref_ratio); + + /** + * \brief The destructor. + */ + ~SyncRegister () = default; + + void CrseInit (amrex::MultiFab& Sync_resid_crse, const amrex::Geometry& crse_geom, amrex::Real mult); + + void FineAdd (amrex::MultiFab& Sync_resid_fine, const amrex::Geometry& crse_geom, amrex::Real mult); + + void CompAdd (amrex::MultiFab& Sync_resid_fine, + const amrex::Geometry& fine_geom, + const amrex::Geometry& crse_geom, + const amrex::BoxArray& Pgrids, amrex::Real mult); + + void InitRHS (amrex::MultiFab& rhs, const amrex::Geometry& geom, const amrex::BCRec& phys_bc); + + SyncRegister (SyncRegister&& rhs) noexcept = default; + + SyncRegister (const SyncRegister& rhs) = delete; + SyncRegister& operator= (const SyncRegister& rhs) = delete; + SyncRegister& operator= ( SyncRegister&& rhs) = delete; + + void clear (); + +private: + + amrex::FabSet bndry_mask[2*AMREX_SPACEDIM]; + amrex::IntVect ratio; +}; + +#endif /*_SYNCREGISTER_H_*/ diff --git a/Source/SyncRegister.cpp b/Source/SyncRegister.cpp index e96d1944..5fa0c9aa 100644 --- a/Source/SyncRegister.cpp +++ b/Source/SyncRegister.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: 1997 - 2023 Berkeley Lab +// +// SPDX-License-Identifier: LicenseRef-OpenSource #include #include diff --git a/Source/Utilities/Make.package b/Source/Utilities/Make.package index 88340c7e..d03c1546 100644 --- a/Source/Utilities/Make.package +++ b/Source/Utilities/Make.package @@ -1,2 +1,2 @@ -CEXE_headers += Utilities.H -CEXE_sources += Utilities.cpp +CEXE_headers += Utilities.H +CEXE_sources += Utilities.cpp diff --git a/Source/Utilities/Utilities.H b/Source/Utilities/Utilities.H index 9aa9b61d..9780f2bb 100644 --- a/Source/Utilities/Utilities.H +++ b/Source/Utilities/Utilities.H @@ -1,74 +1,78 @@ -#ifndef IAMR_UTILITIES_H_ -#define IAMR_UTILITIES_H_ - -#include - - -AMREX_FORCE_INLINE -std::string -read_file(std::ifstream& in) -{ - return static_cast( - std::stringstream() << in.rdbuf()) - .str(); -} - -void read_binary( - const std::string& iname, - size_t nx, - size_t ny, - size_t nz, - size_t ncol, - amrex::Vector& data); - -void read_csv( - const std::string& iname, - size_t nx, - size_t ny, - size_t nz, - amrex::Vector& data); - -// ----------------------------------------------------------- -// Search for the closest index in an array to a given value -// using the bisection technique. -// INPUTS/OUTPUTS: -// xtable(0:n-1) => array to search in (ascending order) -// n => array size -// x => x location -// idxlo <=> output st. xtable(idxlo) <= x < xtable(idxlo+1) -// ----------------------------------------------------------- -AMREX_GPU_DEVICE -AMREX_FORCE_INLINE -void -locate(const amrex::Real* xtable, const int n, const amrex::Real& x, int& idxlo) -{ - // If x is out of bounds, return boundary index - if (x >= xtable[n - 1]) { - idxlo = n - 1; - return; - } - if (x <= xtable[0]) { - idxlo = 0; - return; - } - - // Do the bisection - idxlo = 0; - int idxhi = n - 1; - bool notdone = true; - while (notdone) { - if (idxhi - idxlo <= 1) { - notdone = false; - } else { - const int idxmid = (idxhi + idxlo) / 2; - if (x >= xtable[idxmid]) { - idxlo = idxmid; - } else { - idxhi = idxmid; - } - } - } -} - - -#endif +// SPDX-FileCopyrightText: 2021 - 2023 Berkeley Lab +// +// SPDX-License-Identifier: LicenseRef-OpenSource + +#ifndef IAMR_UTILITIES_H_ +#define IAMR_UTILITIES_H_ + +#include + + +AMREX_FORCE_INLINE +std::string +read_file(std::ifstream& in) +{ + return static_cast( + std::stringstream() << in.rdbuf()) + .str(); +} + +void read_binary( + const std::string& iname, + size_t nx, + size_t ny, + size_t nz, + size_t ncol, + amrex::Vector& data); + +void read_csv( + const std::string& iname, + size_t nx, + size_t ny, + size_t nz, + amrex::Vector& data); + +// ----------------------------------------------------------- +// Search for the closest index in an array to a given value +// using the bisection technique. +// INPUTS/OUTPUTS: +// xtable(0:n-1) => array to search in (ascending order) +// n => array size +// x => x location +// idxlo <=> output st. xtable(idxlo) <= x < xtable(idxlo+1) +// ----------------------------------------------------------- +AMREX_GPU_DEVICE +AMREX_FORCE_INLINE +void +locate(const amrex::Real* xtable, const int n, const amrex::Real& x, int& idxlo) +{ + // If x is out of bounds, return boundary index + if (x >= xtable[n - 1]) { + idxlo = n - 1; + return; + } + if (x <= xtable[0]) { + idxlo = 0; + return; + } + + // Do the bisection + idxlo = 0; + int idxhi = n - 1; + bool notdone = true; + while (notdone) { + if (idxhi - idxlo <= 1) { + notdone = false; + } else { + const int idxmid = (idxhi + idxlo) / 2; + if (x >= xtable[idxmid]) { + idxlo = idxmid; + } else { + idxhi = idxmid; + } + } + } +} + + +#endif diff --git a/Source/Utilities/Utilities.cpp b/Source/Utilities/Utilities.cpp index 6468fb9f..31241435 100644 --- a/Source/Utilities/Utilities.cpp +++ b/Source/Utilities/Utilities.cpp @@ -1,87 +1,91 @@ -#include "Utilities.H" - -// ----------------------------------------------------------- -// Read a binary file -// INPUTS/OUTPUTS: -// iname => filename -// nx => input resolution -// ny => input resolution -// nz => input resolution -// data <= output data -// ----------------------------------------------------------- -void -read_binary( - const std::string& iname, - const size_t nx, - const size_t ny, - const size_t nz, - const size_t ncol, - amrex::Vector& data /*needs to be double*/) -{ - std::ifstream infile(iname, std::ios::in | std::ios::binary); - if (not infile.is_open()) { - amrex::Abort("Unable to open input file " + iname); - } - - for (size_t i = 0; i < nx * ny * nz * ncol; i++) { - infile.read(reinterpret_cast(&data[i]), sizeof(data[i])); - } - infile.close(); -} - -// ----------------------------------------------------------- -// Read a csv file -// INPUTS/OUTPUTS: -// iname => filename -// nx => input resolution -// ny => input resolution -// nz => input resolution -// data <= output data -// ----------------------------------------------------------- -void -read_csv( - const std::string& iname, - const size_t nx, - const size_t ny, - const size_t nz, - amrex::Vector& data) -{ - std::ifstream infile(iname, std::ios::in); - const std::string memfile = read_file(infile); - if (not infile.is_open()) { - amrex::Abort("Unable to open input file " + iname); - } - infile.close(); - std::istringstream iss(memfile); - - // Read the file - size_t nlines = 0; - std::string firstline; - std::string line; - std::getline(iss, firstline); // skip header - while (getline(iss, line)) { - ++nlines; - } - - // Quick sanity check - if (nlines != nx * ny * nz) { - amrex::Abort( - "Number of lines in the input file (= " + std::to_string(nlines) + - ") does not match the input resolution (=" + std::to_string(nx) + ")"); - } - - // Read the data from the file - iss.clear(); - iss.seekg(0, std::ios::beg); - std::getline(iss, firstline); // skip header - int cnt = 0; - while (std::getline(iss, line)) { - std::istringstream linestream(line); - std::string value; - while (getline(linestream, value, ',')) { - std::istringstream sinput(value); - sinput >> data[cnt]; - cnt++; - } - } -} +// SPDX-FileCopyrightText: 2021 - 2023 Berkeley Lab +// +// SPDX-License-Identifier: LicenseRef-OpenSource + +#include "Utilities.H" + +// ----------------------------------------------------------- +// Read a binary file +// INPUTS/OUTPUTS: +// iname => filename +// nx => input resolution +// ny => input resolution +// nz => input resolution +// data <= output data +// ----------------------------------------------------------- +void +read_binary( + const std::string& iname, + const size_t nx, + const size_t ny, + const size_t nz, + const size_t ncol, + amrex::Vector& data /*needs to be double*/) +{ + std::ifstream infile(iname, std::ios::in | std::ios::binary); + if (not infile.is_open()) { + amrex::Abort("Unable to open input file " + iname); + } + + for (size_t i = 0; i < nx * ny * nz * ncol; i++) { + infile.read(reinterpret_cast(&data[i]), sizeof(data[i])); + } + infile.close(); +} + +// ----------------------------------------------------------- +// Read a csv file +// INPUTS/OUTPUTS: +// iname => filename +// nx => input resolution +// ny => input resolution +// nz => input resolution +// data <= output data +// ----------------------------------------------------------- +void +read_csv( + const std::string& iname, + const size_t nx, + const size_t ny, + const size_t nz, + amrex::Vector& data) +{ + std::ifstream infile(iname, std::ios::in); + const std::string memfile = read_file(infile); + if (not infile.is_open()) { + amrex::Abort("Unable to open input file " + iname); + } + infile.close(); + std::istringstream iss(memfile); + + // Read the file + size_t nlines = 0; + std::string firstline; + std::string line; + std::getline(iss, firstline); // skip header + while (getline(iss, line)) { + ++nlines; + } + + // Quick sanity check + if (nlines != nx * ny * nz) { + amrex::Abort( + "Number of lines in the input file (= " + std::to_string(nlines) + + ") does not match the input resolution (=" + std::to_string(nx) + ")"); + } + + // Read the data from the file + iss.clear(); + iss.seekg(0, std::ios::beg); + std::getline(iss, firstline); // skip header + int cnt = 0; + while (std::getline(iss, line)) { + std::istringstream linestream(line); + std::string value; + while (getline(linestream, value, ',')) { + std::istringstream sinput(value); + sinput >> data[cnt]; + cnt++; + } + } +} diff --git a/Source/codingtips b/Source/codingtips index 34867cf2..78289b63 100644 --- a/Source/codingtips +++ b/Source/codingtips @@ -1,304 +1,310 @@ -template -void -MLCellLinOpT::compGrad (int amrlev, const Array& grad, - MF& sol, Location /*loc*/) const -{ - BL_PROFILE("MLCellLinOp::compGrad()"); - - if (sol.nComp() > 1) { - amrex::Abort("MLCellLinOp::compGrad called, but only works for single-component solves"); - } - - const int mglev = 0; - applyBC(amrlev, mglev, sol, BCMode::Inhomogeneous, StateMode::Solution, - m_bndry_sol[amrlev].get()); - - const int ncomp = this->getNComp(); - - AMREX_D_TERM(const RT dxi = static_cast(this->m_geom[amrlev][mglev].InvCellSize(0));, - const RT dyi = static_cast(this->m_geom[amrlev][mglev].InvCellSize(1));, - const RT dzi = static_cast(this->m_geom[amrlev][mglev].InvCellSize(2));); -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(sol, TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - AMREX_D_TERM(const Box& xbx = mfi.nodaltilebox(0);, - const Box& ybx = mfi.nodaltilebox(1);, - const Box& zbx = mfi.nodaltilebox(2);); - const auto& s = sol.array(mfi); - AMREX_D_TERM(const auto& gx = grad[0]->array(mfi);, - const auto& gy = grad[1]->array(mfi);, - const auto& gz = grad[2]->array(mfi);); - - AMREX_HOST_DEVICE_PARALLEL_FOR_4D ( xbx, ncomp, i, j, k, n, - { - gx(i,j,k,n) = dxi*(s(i,j,k,n) - s(i-1,j,k,n)); - }); -#if (AMREX_SPACEDIM >= 2) - AMREX_HOST_DEVICE_PARALLEL_FOR_4D ( ybx, ncomp, i, j, k, n, - { - gy(i,j,k,n) = dyi*(s(i,j,k,n) - s(i,j-1,k,n)); - }); -#endif -#if (AMREX_SPACEDIM == 3) - AMREX_HOST_DEVICE_PARALLEL_FOR_4D ( zbx, ncomp, i, j, k, n, - { - gz(i,j,k,n) = dzi*(s(i,j,k,n) - s(i,j,k-1,n)); - }); -#endif - } - - addInhomogNeumannFlux(amrlev, grad, sol, false); -} - - -// void -// NavierStokesBase::phi_to_delta(MultiFab& phi) -// { - -// if (verbose) amrex::Print() << "In the NavierStokesBase::phi_to_delta " << std::endl; -// const Real* dx = geom.CellSize(); -// const Real pi = 3.141592653589793238462643383279502884197; -// const int eps_in = epsilon; -// Real dxmin = dx[0]; -// for (int d=1; d eps) { -// deltafab(i,j,k) = 0.0; -// } else if (phifab(i,j,k) > -eps) { -// deltafab(i,j,k) = 0.5 * (1.0 + std::cos(phifab(i,j,k) * pi / eps)) / eps; -// } else { -// deltafab(i,j,k) = 0.0; -// } - -// }); -// } -// } - -// void phi_to_delta(amrex::MultiFab& phi); - - - -// amrex::Print() << "1 " <minmod(phi2fab(i - 1, j, k), phi2fab(i, j, k)) * dx[0] / 2.0; -// Real dxp = phi1fab(i + 1, j, k) - -// this->minmod(phi2fab(i, j, k), phi2fab(i + 1, j, k)) * dx[0] / 2.0; -// Real ddx = 0.0; -// if (dxp * sgn0fab(i, j, k) < 0.0 && dxm * sgn0fab(i, j, k) < -dxp * sgn0fab(i, j, k)) { -// ddx = dxp; -// } else if (dxm * sgn0fab(i, j, k) > 0.0 && dxp * sgn0fab(i, j, k) > -dxm * sgn0fab(i, j, k)) { -// ddx = dxm; -// } else { -// ddx = (dxp + dxm) / 2.0; -// } -// phi3fab(i, j, k) = pow(ddx, 2); -// }); -// } - - - -// rk2_reinit - -// #ifdef AMREX_USE_OMP -// #pragma omp parallel if (Gpu::notInLaunchRegion()) -// #endif -// for (MFIter mfi(phi_ctime,TilingIfNotGPU()); mfi.isValid(); ++mfi) -// { -// Box bx = mfi.validbox(); -// bx.growLo(0,1).growHi(0,2); -// auto const& phifab = phi_ctime.array(mfi); -// auto const& phi1fab = phi1.array(mfi); -// amrex::ParallelFor(bx, [phifab, phi1fab, dx] -// AMREX_GPU_DEVICE(int i, int j, int k) noexcept -// { -// phi1fab(i,j,k) = ( phifab(i,j,k) - phifab(i-1,j,k) )/dx[0]; -// }); -// } - -// #ifdef AMREX_USE_OMP -// #pragma omp parallel if (Gpu::notInLaunchRegion()) -// #endif -// for (MFIter mfi(phi1,TilingIfNotGPU()); mfi.isValid(); ++mfi) -// { -// Box bx = mfi.validbox(); -// bx.growLo(0,1).growHi(0,1); -// auto const& phi1fab = phi1.array(mfi); -// auto const& phi2fab = phi2.array(mfi); -// amrex::ParallelFor(bx, [phi1fab, phi2fab, dx] -// AMREX_GPU_DEVICE(int i, int j, int k) noexcept -// { -// phi2fab(i,j,k) = ( phi1fab(i+1,j,k) - phi1fab(i,j,k) )/dx[0]; -// }); -// } - -// #ifdef AMREX_USE_OMP -// #pragma omp parallel if (Gpu::notInLaunchRegion()) -// #endif -// for (MFIter mfi(phi1,TilingIfNotGPU()); mfi.isValid(); ++mfi) -// { -// const Box& vbx = mfi.validbox(); -// auto const& phi1fab = phi1.array(mfi); -// auto const& phi2fab = phi2.array(mfi); -// auto const& phi3fab = phi3.array(mfi); -// auto const& sgn0fab = sgn0.array(mfi); -// amrex::ParallelFor(vbx, [phi1fab, phi2fab, phi3fab, sgn0fab, dx] -// AMREX_GPU_DEVICE(int i, int j, int k) noexcept -// { -// Real dxm = phi1fab(i, j, k) + minmod(phi2fab(i - 1, j, k), phi2fab(i, j, k)) * dx[0] / 2.0; -// Real dxp = phi1fab(i + 1, j, k) - minmod(phi2fab(i, j, k), phi2fab(i + 1, j, k)) * dx[0] / 2.0; -// Real ddx = 0.0; -// if (dxp * sgn0fab(i, j, k) < 0.0 && dxm * sgn0fab(i, j, k) < -dxp * sgn0fab(i, j, k)) { -// ddx = dxp; -// } else if (dxm * sgn0fab(i, j, k) > 0.0 && dxp * sgn0fab(i, j, k) > -dxm * sgn0fab(i, j, k)) { -// ddx = dxm; -// } else { -// ddx = (dxp + dxm) / 2.0; -// } -// phi3fab(i, j, k) = pow(ddx, 2); -// }); -// } - -// #ifdef AMREX_USE_OMP -// #pragma omp parallel if (Gpu::notInLaunchRegion()) -// #endif -// for (MFIter mfi(phi_ctime,TilingIfNotGPU()); mfi.isValid(); ++mfi) -// { -// Box bx = mfi.validbox(); -// bx.growLo(1,1).growHi(1,2); -// auto const& phifab = phi_ctime.array(mfi); -// auto const& phi1fab = phi1.array(mfi); -// amrex::ParallelFor(bx, [phifab, phi1fab, dx] -// AMREX_GPU_DEVICE(int i, int j, int k) noexcept -// { -// phi1fab(i,j,k) = ( phifab(i,j,k) - phifab(i,j-1,k) )/dx[1]; -// }); -// } - -// #ifdef AMREX_USE_OMP -// #pragma omp parallel if (Gpu::notInLaunchRegion()) -// #endif -// for (MFIter mfi(phi1,TilingIfNotGPU()); mfi.isValid(); ++mfi) -// { -// Box bx = mfi.validbox(); -// bx.growLo(1,1).growHi(1,1); -// auto const& phi1fab = phi1.array(mfi); -// auto const& phi2fab = phi2.array(mfi); -// amrex::ParallelFor(bx, [phi1fab, phi2fab, dx] -// AMREX_GPU_DEVICE(int i, int j, int k) noexcept -// { -// phi2fab(i,j,k) = ( phi1fab(i,j+1,k) - phi1fab(i,j,k) )/dx[1]; -// }); -// } - -// #ifdef AMREX_USE_OMP -// #pragma omp parallel if (Gpu::notInLaunchRegion()) -// #endif -// for (MFIter mfi(phi1,TilingIfNotGPU()); mfi.isValid(); ++mfi) -// { -// const Box& vbx = mfi.validbox(); -// auto const& phi1fab = phi1.array(mfi); -// auto const& phi2fab = phi2.array(mfi); -// auto const& phi3fab = phi3.array(mfi); -// auto const& sgn0fab = sgn0.array(mfi); -// amrex::ParallelFor(vbx, [phi1fab, phi2fab, phi3fab, sgn0fab, dx] -// AMREX_GPU_DEVICE(int i, int j, int k) noexcept -// { -// Real dym = phi1fab(i, j, k) + minmod(phi2fab(i, j - 1, k), phi2fab(i, j, k)) * dx[1] / 2.0; -// Real dyp = phi1fab(i, j + 1, k) - minmod(phi2fab(i, j, k), phi2fab(i, j + 1, k)) * dx[1] / 2.0; -// Real ddy = 0.0; -// if (dyp * sgn0fab(i, j, k) < 0.0 && dym * sgn0fab(i, j, k) < -dyp * sgn0fab(i, j, k)) { -// ddy = dyp; -// } else if (dym * sgn0fab(i, j, k) > 0.0 && dyp * sgn0fab(i, j, k) > -dym * sgn0fab(i, j, k)) { -// ddy = dym; -// } else { -// ddy = (dyp + dym) / 2.0; -// } -// phi3fab(i, j, k) += pow(ddy, 2); -// if (AMREX_SPACEDIM==2) { -// phi3fab(i, j, k) = std::sqrt(phi3fab(i, j, k)); -// } -// }); -// } - - - amrex::Print() << "Box details: " << bx << "\n"; - amrex::Print() << "Data array dimensions: " << data.box() << "\n"; - amrex::Print() << "Data starting component index: " << dcomp << "\n"; - amrex::Print() << "Number of components: " << numcomp << "\n"; - amrex::Print() << "Geometry details: " << geom.ProbDomain() << "\n"; - amrex::Print() << "Simulation time: " << time << "\n"; - for (const auto& bc : bcr) { - amrex::Print() << "Boundary condition: " << bc << "\n"; // 需要实现BCRec的打印支持 - } - amrex::Print() << "Boundary component index: " << bcomp << "\n"; - amrex::Print() << "Source component index: " << scomp << "\n"; - +// SPDX-FileCopyrightText: 2023 Berkeley Lab; 2023 - 2025 Yadong Zeng +// +// SPDX-License-Identifier: LicenseRef-OpenSource +// Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +// Original source: https://github.com/AMReX-Fluids/IAMR + +template +void +MLCellLinOpT::compGrad (int amrlev, const Array& grad, + MF& sol, Location /*loc*/) const +{ + BL_PROFILE("MLCellLinOp::compGrad()"); + + if (sol.nComp() > 1) { + amrex::Abort("MLCellLinOp::compGrad called, but only works for single-component solves"); + } + + const int mglev = 0; + applyBC(amrlev, mglev, sol, BCMode::Inhomogeneous, StateMode::Solution, + m_bndry_sol[amrlev].get()); + + const int ncomp = this->getNComp(); + + AMREX_D_TERM(const RT dxi = static_cast(this->m_geom[amrlev][mglev].InvCellSize(0));, + const RT dyi = static_cast(this->m_geom[amrlev][mglev].InvCellSize(1));, + const RT dzi = static_cast(this->m_geom[amrlev][mglev].InvCellSize(2));); +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(sol, TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + AMREX_D_TERM(const Box& xbx = mfi.nodaltilebox(0);, + const Box& ybx = mfi.nodaltilebox(1);, + const Box& zbx = mfi.nodaltilebox(2);); + const auto& s = sol.array(mfi); + AMREX_D_TERM(const auto& gx = grad[0]->array(mfi);, + const auto& gy = grad[1]->array(mfi);, + const auto& gz = grad[2]->array(mfi);); + + AMREX_HOST_DEVICE_PARALLEL_FOR_4D ( xbx, ncomp, i, j, k, n, + { + gx(i,j,k,n) = dxi*(s(i,j,k,n) - s(i-1,j,k,n)); + }); +#if (AMREX_SPACEDIM >= 2) + AMREX_HOST_DEVICE_PARALLEL_FOR_4D ( ybx, ncomp, i, j, k, n, + { + gy(i,j,k,n) = dyi*(s(i,j,k,n) - s(i,j-1,k,n)); + }); +#endif +#if (AMREX_SPACEDIM == 3) + AMREX_HOST_DEVICE_PARALLEL_FOR_4D ( zbx, ncomp, i, j, k, n, + { + gz(i,j,k,n) = dzi*(s(i,j,k,n) - s(i,j,k-1,n)); + }); +#endif + } + + addInhomogNeumannFlux(amrlev, grad, sol, false); +} + + +// void +// NavierStokesBase::phi_to_delta(MultiFab& phi) +// { + +// if (verbose) amrex::Print() << "In the NavierStokesBase::phi_to_delta " << std::endl; +// const Real* dx = geom.CellSize(); +// const Real pi = 3.141592653589793238462643383279502884197; +// const int eps_in = epsilon; +// Real dxmin = dx[0]; +// for (int d=1; d eps) { +// deltafab(i,j,k) = 0.0; +// } else if (phifab(i,j,k) > -eps) { +// deltafab(i,j,k) = 0.5 * (1.0 + std::cos(phifab(i,j,k) * pi / eps)) / eps; +// } else { +// deltafab(i,j,k) = 0.0; +// } + +// }); +// } +// } + +// void phi_to_delta(amrex::MultiFab& phi); + + + +// amrex::Print() << "1 " <minmod(phi2fab(i - 1, j, k), phi2fab(i, j, k)) * dx[0] / 2.0; +// Real dxp = phi1fab(i + 1, j, k) - +// this->minmod(phi2fab(i, j, k), phi2fab(i + 1, j, k)) * dx[0] / 2.0; +// Real ddx = 0.0; +// if (dxp * sgn0fab(i, j, k) < 0.0 && dxm * sgn0fab(i, j, k) < -dxp * sgn0fab(i, j, k)) { +// ddx = dxp; +// } else if (dxm * sgn0fab(i, j, k) > 0.0 && dxp * sgn0fab(i, j, k) > -dxm * sgn0fab(i, j, k)) { +// ddx = dxm; +// } else { +// ddx = (dxp + dxm) / 2.0; +// } +// phi3fab(i, j, k) = pow(ddx, 2); +// }); +// } + + + +// rk2_reinit + +// #ifdef AMREX_USE_OMP +// #pragma omp parallel if (Gpu::notInLaunchRegion()) +// #endif +// for (MFIter mfi(phi_ctime,TilingIfNotGPU()); mfi.isValid(); ++mfi) +// { +// Box bx = mfi.validbox(); +// bx.growLo(0,1).growHi(0,2); +// auto const& phifab = phi_ctime.array(mfi); +// auto const& phi1fab = phi1.array(mfi); +// amrex::ParallelFor(bx, [phifab, phi1fab, dx] +// AMREX_GPU_DEVICE(int i, int j, int k) noexcept +// { +// phi1fab(i,j,k) = ( phifab(i,j,k) - phifab(i-1,j,k) )/dx[0]; +// }); +// } + +// #ifdef AMREX_USE_OMP +// #pragma omp parallel if (Gpu::notInLaunchRegion()) +// #endif +// for (MFIter mfi(phi1,TilingIfNotGPU()); mfi.isValid(); ++mfi) +// { +// Box bx = mfi.validbox(); +// bx.growLo(0,1).growHi(0,1); +// auto const& phi1fab = phi1.array(mfi); +// auto const& phi2fab = phi2.array(mfi); +// amrex::ParallelFor(bx, [phi1fab, phi2fab, dx] +// AMREX_GPU_DEVICE(int i, int j, int k) noexcept +// { +// phi2fab(i,j,k) = ( phi1fab(i+1,j,k) - phi1fab(i,j,k) )/dx[0]; +// }); +// } + +// #ifdef AMREX_USE_OMP +// #pragma omp parallel if (Gpu::notInLaunchRegion()) +// #endif +// for (MFIter mfi(phi1,TilingIfNotGPU()); mfi.isValid(); ++mfi) +// { +// const Box& vbx = mfi.validbox(); +// auto const& phi1fab = phi1.array(mfi); +// auto const& phi2fab = phi2.array(mfi); +// auto const& phi3fab = phi3.array(mfi); +// auto const& sgn0fab = sgn0.array(mfi); +// amrex::ParallelFor(vbx, [phi1fab, phi2fab, phi3fab, sgn0fab, dx] +// AMREX_GPU_DEVICE(int i, int j, int k) noexcept +// { +// Real dxm = phi1fab(i, j, k) + minmod(phi2fab(i - 1, j, k), phi2fab(i, j, k)) * dx[0] / 2.0; +// Real dxp = phi1fab(i + 1, j, k) - minmod(phi2fab(i, j, k), phi2fab(i + 1, j, k)) * dx[0] / 2.0; +// Real ddx = 0.0; +// if (dxp * sgn0fab(i, j, k) < 0.0 && dxm * sgn0fab(i, j, k) < -dxp * sgn0fab(i, j, k)) { +// ddx = dxp; +// } else if (dxm * sgn0fab(i, j, k) > 0.0 && dxp * sgn0fab(i, j, k) > -dxm * sgn0fab(i, j, k)) { +// ddx = dxm; +// } else { +// ddx = (dxp + dxm) / 2.0; +// } +// phi3fab(i, j, k) = pow(ddx, 2); +// }); +// } + +// #ifdef AMREX_USE_OMP +// #pragma omp parallel if (Gpu::notInLaunchRegion()) +// #endif +// for (MFIter mfi(phi_ctime,TilingIfNotGPU()); mfi.isValid(); ++mfi) +// { +// Box bx = mfi.validbox(); +// bx.growLo(1,1).growHi(1,2); +// auto const& phifab = phi_ctime.array(mfi); +// auto const& phi1fab = phi1.array(mfi); +// amrex::ParallelFor(bx, [phifab, phi1fab, dx] +// AMREX_GPU_DEVICE(int i, int j, int k) noexcept +// { +// phi1fab(i,j,k) = ( phifab(i,j,k) - phifab(i,j-1,k) )/dx[1]; +// }); +// } + +// #ifdef AMREX_USE_OMP +// #pragma omp parallel if (Gpu::notInLaunchRegion()) +// #endif +// for (MFIter mfi(phi1,TilingIfNotGPU()); mfi.isValid(); ++mfi) +// { +// Box bx = mfi.validbox(); +// bx.growLo(1,1).growHi(1,1); +// auto const& phi1fab = phi1.array(mfi); +// auto const& phi2fab = phi2.array(mfi); +// amrex::ParallelFor(bx, [phi1fab, phi2fab, dx] +// AMREX_GPU_DEVICE(int i, int j, int k) noexcept +// { +// phi2fab(i,j,k) = ( phi1fab(i,j+1,k) - phi1fab(i,j,k) )/dx[1]; +// }); +// } + +// #ifdef AMREX_USE_OMP +// #pragma omp parallel if (Gpu::notInLaunchRegion()) +// #endif +// for (MFIter mfi(phi1,TilingIfNotGPU()); mfi.isValid(); ++mfi) +// { +// const Box& vbx = mfi.validbox(); +// auto const& phi1fab = phi1.array(mfi); +// auto const& phi2fab = phi2.array(mfi); +// auto const& phi3fab = phi3.array(mfi); +// auto const& sgn0fab = sgn0.array(mfi); +// amrex::ParallelFor(vbx, [phi1fab, phi2fab, phi3fab, sgn0fab, dx] +// AMREX_GPU_DEVICE(int i, int j, int k) noexcept +// { +// Real dym = phi1fab(i, j, k) + minmod(phi2fab(i, j - 1, k), phi2fab(i, j, k)) * dx[1] / 2.0; +// Real dyp = phi1fab(i, j + 1, k) - minmod(phi2fab(i, j, k), phi2fab(i, j + 1, k)) * dx[1] / 2.0; +// Real ddy = 0.0; +// if (dyp * sgn0fab(i, j, k) < 0.0 && dym * sgn0fab(i, j, k) < -dyp * sgn0fab(i, j, k)) { +// ddy = dyp; +// } else if (dym * sgn0fab(i, j, k) > 0.0 && dyp * sgn0fab(i, j, k) > -dym * sgn0fab(i, j, k)) { +// ddy = dym; +// } else { +// ddy = (dyp + dym) / 2.0; +// } +// phi3fab(i, j, k) += pow(ddy, 2); +// if (AMREX_SPACEDIM==2) { +// phi3fab(i, j, k) = std::sqrt(phi3fab(i, j, k)); +// } +// }); +// } + + + amrex::Print() << "Box details: " << bx << "\n"; + amrex::Print() << "Data array dimensions: " << data.box() << "\n"; + amrex::Print() << "Data starting component index: " << dcomp << "\n"; + amrex::Print() << "Number of components: " << numcomp << "\n"; + amrex::Print() << "Geometry details: " << geom.ProbDomain() << "\n"; + amrex::Print() << "Simulation time: " << time << "\n"; + for (const auto& bc : bcr) { + amrex::Print() << "Boundary condition: " << bc << "\n"; // 需要实现BCRec的打印支持 + } + amrex::Print() << "Boundary component index: " << bcomp << "\n"; + amrex::Print() << "Source component index: " << scomp << "\n"; + diff --git a/Source/iamr_constants.H b/Source/iamr_constants.H index 8e53d136..b13ff53f 100644 --- a/Source/iamr_constants.H +++ b/Source/iamr_constants.H @@ -1,12 +1,18 @@ -#ifndef IAMR_CONSTANTS_H_ -#define IAMR_CONSTANTS_H_ - -#include - -// Value to use in covered cells -static constexpr amrex::Real COVERED_VAL = 1.0e40; - -static constexpr amrex::Real Pi = 3.141592653589793238462643383279502884197; -static constexpr amrex::Real TwoPi = 2.0 * 3.141592653589793238462643383279502884197; - -#endif +/* + * SPDX-FileCopyrightText: 2020 - 2023 Berkeley Lab + * + * SPDX-License-Identifier: LicenseRef-OpenSource + */ + +#ifndef IAMR_CONSTANTS_H_ +#define IAMR_CONSTANTS_H_ + +#include + +// Value to use in covered cells +static constexpr amrex::Real COVERED_VAL = 1.0e40; + +static constexpr amrex::Real Pi = 3.141592653589793238462643383279502884197; +static constexpr amrex::Real TwoPi = 2.0 * 3.141592653589793238462643383279502884197; + +#endif diff --git a/Source/ls.py b/Source/ls.py index 8e699935..804b1c8e 100644 --- a/Source/ls.py +++ b/Source/ls.py @@ -1,80 +1,84 @@ -import numpy as np -import math -import sympy as sp - -dx = 1 # Replace with your value -dy = 1 # Replace with your value - -matrix = np.array([ - [1, -dx, -dy, dx*dy, 0.5*dx*dx, 0.5*dy*dy], - [1, 0, -dy, 0, 0, 0.5*dy*dy], - [1, dx, -dy, -dx*dy, 0.5*dx*dx, 0.5*dy*dy], - [1, -dx, 0, 0, 0.5*dx*dx, 0], - [1, 0, 0, 0, 0, 0], - [1, dx, 0, 0, 0.5*dx*dx, 0], - [1, -dx, dy, -dx*dy, 0.5*dx*dx, 0.5*dy*dy], - [1, 0, dy, 0, 0, 0.5*dy*dy], - [1, dx, dy, dx*dy, 0.5*dx*dx, 0.5*dy*dy] -]) - -print(matrix) - -dis = math.sqrt(2)/2 -rhs = [-dis, 0, -dis, 0, dis, 0, -dis, 0, -dis] -print(rhs) - -# Let us say wanna use the least square method to solver matrix * x = rhs, in which x is a 6 by 1 array. - -# Solve using least squares -x, residuals, rank, s = np.linalg.lstsq(matrix, rhs, rcond=None) - -print("\nSolution (x):") -print(x) - -# If you're interested in the residuals -print("\nResiduals:") -print(residuals) - -# Enable pretty printing -sp.init_printing(use_unicode=True, wrap_line=False) - -# Define symbolic variables -dx, dy = sp.symbols('dx dy') -half = sp.Rational(1,2) - -matrixsp = sp.Matrix([ - [1, -dx, -dy, dx*dy, half*dx*dx, half*dy*dy], - [1, 0, -dy, 0, 0, half*dy*dy], - [1, dx, -dy, -dx*dy, half*dx*dx, half*dy*dy], - [1, -dx, 0, 0, half*dx*dx, 0], - [1, 0, 0, 0, 0, 0], - [1, dx, 0, 0, half*dx*dx, 0], - [1, -dx, dy, -dx*dy, half*dx*dx, half*dy*dy], - [1, 0, dy, 0, 0, half*dy*dy], - [1, dx, dy, dx*dy, half*dx*dx, half*dy*dy] -]) - -result = matrixsp.transpose() * matrixsp -# sp.pprint(result) - -# Compute the inverse of the result matrix -inverse_result = result.inv() - -# Display the inverse matrix -# sp.pprint(inverse_result) - -# Compute the product of the inverse of the result matrix and matrixsp -product = result.inv() * matrixsp.transpose() -sp.pprint(product) - -# Substitute in the values for dx and dy -dx_val = 1 # replace with your value if different -dy_val = 1 # replace with your value if different -result_num = result.subs({dx: dx_val, dy: dy_val}) - -# Convert the SymPy matrix to a numpy array -result_np = np.array(result_num.tolist(), dtype=float) -print(result_np) - -x_cal = np.linalg.inv(result_np) @ matrix.T @ rhs -print(x_cal) +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng +# +# SPDX-License-Identifier: BSD-3-Clause + +import numpy as np +import math +import sympy as sp + +dx = 1 # Replace with your value +dy = 1 # Replace with your value + +matrix = np.array([ + [1, -dx, -dy, dx*dy, 0.5*dx*dx, 0.5*dy*dy], + [1, 0, -dy, 0, 0, 0.5*dy*dy], + [1, dx, -dy, -dx*dy, 0.5*dx*dx, 0.5*dy*dy], + [1, -dx, 0, 0, 0.5*dx*dx, 0], + [1, 0, 0, 0, 0, 0], + [1, dx, 0, 0, 0.5*dx*dx, 0], + [1, -dx, dy, -dx*dy, 0.5*dx*dx, 0.5*dy*dy], + [1, 0, dy, 0, 0, 0.5*dy*dy], + [1, dx, dy, dx*dy, 0.5*dx*dx, 0.5*dy*dy] +]) + +print(matrix) + +dis = math.sqrt(2)/2 +rhs = [-dis, 0, -dis, 0, dis, 0, -dis, 0, -dis] +print(rhs) + +# Let us say wanna use the least square method to solver matrix * x = rhs, in which x is a 6 by 1 array. + +# Solve using least squares +x, residuals, rank, s = np.linalg.lstsq(matrix, rhs, rcond=None) + +print("\nSolution (x):") +print(x) + +# If you're interested in the residuals +print("\nResiduals:") +print(residuals) + +# Enable pretty printing +sp.init_printing(use_unicode=True, wrap_line=False) + +# Define symbolic variables +dx, dy = sp.symbols('dx dy') +half = sp.Rational(1,2) + +matrixsp = sp.Matrix([ + [1, -dx, -dy, dx*dy, half*dx*dx, half*dy*dy], + [1, 0, -dy, 0, 0, half*dy*dy], + [1, dx, -dy, -dx*dy, half*dx*dx, half*dy*dy], + [1, -dx, 0, 0, half*dx*dx, 0], + [1, 0, 0, 0, 0, 0], + [1, dx, 0, 0, half*dx*dx, 0], + [1, -dx, dy, -dx*dy, half*dx*dx, half*dy*dy], + [1, 0, dy, 0, 0, half*dy*dy], + [1, dx, dy, dx*dy, half*dx*dx, half*dy*dy] +]) + +result = matrixsp.transpose() * matrixsp +# sp.pprint(result) + +# Compute the inverse of the result matrix +inverse_result = result.inv() + +# Display the inverse matrix +# sp.pprint(inverse_result) + +# Compute the product of the inverse of the result matrix and matrixsp +product = result.inv() * matrixsp.transpose() +sp.pprint(product) + +# Substitute in the values for dx and dy +dx_val = 1 # replace with your value if different +dy_val = 1 # replace with your value if different +result_num = result.subs({dx: dx_val, dy: dy_val}) + +# Convert the SymPy matrix to a numpy array +result_np = np.array(result_num.tolist(), dtype=float) +print(result_np) + +x_cal = np.linalg.inv(result_np) @ matrix.T @ rhs +print(x_cal) diff --git a/Source/main.cpp b/Source/main.cpp index a8dba077..272e32fa 100644 --- a/Source/main.cpp +++ b/Source/main.cpp @@ -1,156 +1,159 @@ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef AMREX_USE_EB -#include -#include -#endif - -using namespace amrex; - -#ifdef AMREX_USE_EB -//skipping header file and just declaring eb2 init fn here as in CNS for now -void initialize_EB2 (const Geometry& geom, int required_level, int max_level); -#endif - -amrex::LevelBld* getLevelBld (); - -int -main (int argc, - char* argv[]) -{ - amrex::Initialize(argc,argv); - - BL_PROFILE_REGION_START("main()"); - BL_PROFILE_VAR("main()", pmain); - - const Real run_strt = ParallelDescriptor::second(); - - int max_step; - int num_steps; - Real strt_time; - Real stop_time; - Real stop_interval; - - ParmParse pp; - - max_step = -1; - num_steps = -1; - strt_time = 0.0; - stop_time = -1.0; - stop_interval = 0.; - - pp.query("max_step", max_step); - pp.query("num_steps", num_steps); - pp.query("strt_time", strt_time); - pp.query("stop_time", stop_time); - pp.query("stop_interval", stop_interval); - - if (strt_time < 0.0) - { - amrex::Abort("MUST SPECIFY a non-negative strt_time"); - } - - if (max_step < 0 && stop_time < 0) - { - amrex::Abort("Exiting because neither max_step nor stop_time is non-negative."); - } - - Amr* amrptr = new Amr(getLevelBld()); - // Amr amr; -#ifdef AMREX_USE_EB - // EB should calculate centroids as well as volume and area fractions - AmrLevel::SetEBSupportLevel(EBSupport::full); - - // Set grow cells for basic, volume, full - // Look in weighted SRSD paper for explanation for why this is 5 - AmrLevel::SetEBMaxGrowCells(5,5,5); - - int max_coarsening_level = 100; - pp.query("max_coarsening_level", max_coarsening_level); - initialize_EB2(amrptr->Geom(amrptr->maxLevel()), amrptr->maxLevel(), - max_coarsening_level); -#endif - - amrptr->init(strt_time,stop_time); - - // This feature stop the simulation at a specific time - // after the physical time of the checkpoint file - if (stop_interval > 0.) stop_time = amrptr->cumTime() + stop_interval; - - if (num_steps > 0) - { - if (max_step < 0) - { - max_step = num_steps + amrptr->levelSteps(0); - } - else - { - max_step = std::min(max_step, num_steps + amrptr->levelSteps(0)); - } - - amrex::Print() << "Using effective max_step = " << max_step << '\n'; - } - // - // If we set the regrid_on_restart flag and if we are *not* going to take - // a time step then we want to go ahead and regrid here. - // - if (Amr::RegridOnRestart()) - { - if ( (amrptr->levelSteps(0) >= max_step ) || - ( (stop_time >= 0.0) && - (amrptr->cumTime() >= stop_time) ) ) - { - // - // Regrid only! - // - amrptr->RegridOnly(amrptr->cumTime()); - } - } - - while ( amrptr->okToContinue() && - (amrptr->levelSteps(0) < max_step || max_step < 0) && - (amrptr->cumTime() < stop_time || stop_time < 0.0) ) - { - amrptr->coarseTimeStep(stop_time); - } - // - // Write final checkpoint and plotfile. - // - if (amrptr->stepOfLastCheckPoint() < amrptr->levelSteps(0)) - { - amrptr->checkPoint(); - } - - if (amrptr->stepOfLastPlotFile() < amrptr->levelSteps(0)) - { - amrptr->writePlotFile(); - } - - delete amrptr; - - const int IOProc = ParallelDescriptor::IOProcessorNumber(); - Real run_stop = ParallelDescriptor::second() - run_strt; - - ParallelDescriptor::ReduceRealMax(run_stop,IOProc); - - amrex::Print() << "Run time = " << run_stop << std::endl; - - BL_PROFILE_VAR_STOP(pmain); - BL_PROFILE_REGION_STOP("main()"); - BL_PROFILE_SET_RUN_TIME(run_stop); - BL_PROFILE_FINALIZE(); - - - amrex::Finalize(); - - return 0; -} +// SPDX-FileCopyrightText: 1997 - 2023 Berkeley Lab +// +// SPDX-License-Identifier: LicenseRef-OpenSource + +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef AMREX_USE_EB +#include +#include +#endif + +using namespace amrex; + +#ifdef AMREX_USE_EB +//skipping header file and just declaring eb2 init fn here as in CNS for now +void initialize_EB2 (const Geometry& geom, int required_level, int max_level); +#endif + +amrex::LevelBld* getLevelBld (); + +int +main (int argc, + char* argv[]) +{ + amrex::Initialize(argc,argv); + + BL_PROFILE_REGION_START("main()"); + BL_PROFILE_VAR("main()", pmain); + + const Real run_strt = ParallelDescriptor::second(); + + int max_step; + int num_steps; + Real strt_time; + Real stop_time; + Real stop_interval; + + ParmParse pp; + + max_step = -1; + num_steps = -1; + strt_time = 0.0; + stop_time = -1.0; + stop_interval = 0.; + + pp.query("max_step", max_step); + pp.query("num_steps", num_steps); + pp.query("strt_time", strt_time); + pp.query("stop_time", stop_time); + pp.query("stop_interval", stop_interval); + + if (strt_time < 0.0) + { + amrex::Abort("MUST SPECIFY a non-negative strt_time"); + } + + if (max_step < 0 && stop_time < 0) + { + amrex::Abort("Exiting because neither max_step nor stop_time is non-negative."); + } + + Amr* amrptr = new Amr(getLevelBld()); + // Amr amr; +#ifdef AMREX_USE_EB + // EB should calculate centroids as well as volume and area fractions + AmrLevel::SetEBSupportLevel(EBSupport::full); + + // Set grow cells for basic, volume, full + // Look in weighted SRSD paper for explanation for why this is 5 + AmrLevel::SetEBMaxGrowCells(5,5,5); + + int max_coarsening_level = 100; + pp.query("max_coarsening_level", max_coarsening_level); + initialize_EB2(amrptr->Geom(amrptr->maxLevel()), amrptr->maxLevel(), + max_coarsening_level); +#endif + + amrptr->init(strt_time,stop_time); + + // This feature stop the simulation at a specific time + // after the physical time of the checkpoint file + if (stop_interval > 0.) stop_time = amrptr->cumTime() + stop_interval; + + if (num_steps > 0) + { + if (max_step < 0) + { + max_step = num_steps + amrptr->levelSteps(0); + } + else + { + max_step = std::min(max_step, num_steps + amrptr->levelSteps(0)); + } + + amrex::Print() << "Using effective max_step = " << max_step << '\n'; + } + // + // If we set the regrid_on_restart flag and if we are *not* going to take + // a time step then we want to go ahead and regrid here. + // + if (Amr::RegridOnRestart()) + { + if ( (amrptr->levelSteps(0) >= max_step ) || + ( (stop_time >= 0.0) && + (amrptr->cumTime() >= stop_time) ) ) + { + // + // Regrid only! + // + amrptr->RegridOnly(amrptr->cumTime()); + } + } + + while ( amrptr->okToContinue() && + (amrptr->levelSteps(0) < max_step || max_step < 0) && + (amrptr->cumTime() < stop_time || stop_time < 0.0) ) + { + amrptr->coarseTimeStep(stop_time); + } + // + // Write final checkpoint and plotfile. + // + if (amrptr->stepOfLastCheckPoint() < amrptr->levelSteps(0)) + { + amrptr->checkPoint(); + } + + if (amrptr->stepOfLastPlotFile() < amrptr->levelSteps(0)) + { + amrptr->writePlotFile(); + } + + delete amrptr; + + const int IOProc = ParallelDescriptor::IOProcessorNumber(); + Real run_stop = ParallelDescriptor::second() - run_strt; + + ParallelDescriptor::ReduceRealMax(run_stop,IOProc); + + amrex::Print() << "Run time = " << run_stop << std::endl; + + BL_PROFILE_VAR_STOP(pmain); + BL_PROFILE_REGION_STOP("main()"); + BL_PROFILE_SET_RUN_TIME(run_stop); + BL_PROFILE_FINALIZE(); + + + amrex::Finalize(); + + return 0; +} diff --git a/Source/prob/Make.package b/Source/prob/Make.package index e70bad79..482aa6ae 100644 --- a/Source/prob/Make.package +++ b/Source/prob/Make.package @@ -1,2 +1,2 @@ -CEXE_headers += prob_init.H -CEXE_sources += prob_init.cpp +CEXE_headers += prob_init.H +CEXE_sources += prob_init.cpp diff --git a/Source/prob/prob_init.H b/Source/prob/prob_init.H index d6ca1b58..9e47db2c 100644 --- a/Source/prob/prob_init.H +++ b/Source/prob/prob_init.H @@ -1,275 +1,281 @@ -#ifndef PROB_INIT_H_ -#define PROB_INIT_H_ - -// This header is included by NavierStokes.H. These are members of NavierStokes - -// -// struct to hold initial conditions parameters -// -struct InitialConditions -{ - amrex::Real density = 1.0; - - amrex::Real v_x = 0.; - amrex::Real v_y = 0.; - amrex::Real v_z = 0.; - - amrex::Real blob_radius = 0.1; - - amrex::Real blob_x = 0.; - amrex::Real blob_y = 0.; - amrex::Real blob_z = 0.; - - amrex::Real interface_width = 1.0; - - // Parameters for use in multiple setups - amrex::Real a = 1.0; - amrex::Real b = 1.0; - amrex::Real c = 1.0; - - // for DoubleShearLayer - int direction = 0; - - // for Rayleigh-Taylor - amrex::Real rho_1 = 1.0; - amrex::Real rho_2 = 2.0; - amrex::Real tra_1 = 0.0; - amrex::Real tra_2 = 1.0; - amrex::Real pertamp = 1.0; - - // for convected vortex - int meanFlowDir = 0; - amrex::Real meanFlowMag = 0.0; - amrex::Real forcevort = 6.0; - - // - // ls related - // total time for rsv problem - amrex::Real totalTimeRsv = 4.0; - - // - // ls related - // - int do_phi = 0; - int Density = 0; - int phicomp = 0; - amrex::Real rho_w = 3.0; - amrex::Real rho_a = 1.0; - -}; - -// -// Problem initialization functions -// -void prob_initData(); - -static void init_bubble (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -// -// ls related -// initialize velocity for the rsv problem -static void init_rsv (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -static void init_constant_vel_rho (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -static void init_channel (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -static void init_jump (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -static void init_DoubleShearLayer (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -static void init_RayleighTaylor (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -// -// ls related -// -static void init_RayleighTaylor_LS (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -static void init_BreakingWave (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -static void init_TaylorGreen (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -// -// diffused ib -// -static void init_particles (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -static void init_Euler (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -static void init_ConvectedVortex (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -// -// Problems parameters, to be read from inputs file -// -static int probtype; -static amrex::Real ub; -static amrex::Real shearrate; - -// -// ls related -// perform prescribed velocity -// -static void set_rsv_vel (amrex::Box const& vbx, - amrex::Array4 const& vel, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC, - amrex::Real time); - -// -// diffused ib -// set initial phi nodal -// -static void set_initial_phi_nodal (amrex::Box const& bx, - amrex::Array4 const& phi_nodal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC, - amrex::Real time); - -// Sphere near the channel wall -static void SphereNearWall (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -// Falling Sphere -static void FallingSphere (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -#endif +// SPDX-FileCopyrightText: 2021 - 2023 Berkeley Lab; 2023 - 2025 Yadong Zeng +// +// SPDX-License-Identifier: LicenseRef-OpenSource +// Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +// Original source: https://github.com/AMReX-Fluids/IAMR + +#ifndef PROB_INIT_H_ +#define PROB_INIT_H_ + +// This header is included by NavierStokes.H. These are members of NavierStokes + +// +// struct to hold initial conditions parameters +// +struct InitialConditions +{ + amrex::Real density = 1.0; + + amrex::Real v_x = 0.; + amrex::Real v_y = 0.; + amrex::Real v_z = 0.; + + amrex::Real blob_radius = 0.1; + + amrex::Real blob_x = 0.; + amrex::Real blob_y = 0.; + amrex::Real blob_z = 0.; + + amrex::Real interface_width = 1.0; + + // Parameters for use in multiple setups + amrex::Real a = 1.0; + amrex::Real b = 1.0; + amrex::Real c = 1.0; + + // for DoubleShearLayer + int direction = 0; + + // for Rayleigh-Taylor + amrex::Real rho_1 = 1.0; + amrex::Real rho_2 = 2.0; + amrex::Real tra_1 = 0.0; + amrex::Real tra_2 = 1.0; + amrex::Real pertamp = 1.0; + + // for convected vortex + int meanFlowDir = 0; + amrex::Real meanFlowMag = 0.0; + amrex::Real forcevort = 6.0; + + // + // ls related + // total time for rsv problem + amrex::Real totalTimeRsv = 4.0; + + // + // ls related + // + int do_phi = 0; + int Density = 0; + int phicomp = 0; + amrex::Real rho_w = 3.0; + amrex::Real rho_a = 1.0; + +}; + +// +// Problem initialization functions +// +void prob_initData(); + +static void init_bubble (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +// +// ls related +// initialize velocity for the rsv problem +static void init_rsv (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +static void init_constant_vel_rho (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +static void init_channel (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +static void init_jump (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +static void init_DoubleShearLayer (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +static void init_RayleighTaylor (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +// +// ls related +// +static void init_RayleighTaylor_LS (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +static void init_BreakingWave (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +static void init_TaylorGreen (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +// +// diffused ib +// +static void init_particles (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +static void init_Euler (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +static void init_ConvectedVortex (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +// +// Problems parameters, to be read from inputs file +// +static int probtype; +static amrex::Real ub; +static amrex::Real shearrate; + +// +// ls related +// perform prescribed velocity +// +static void set_rsv_vel (amrex::Box const& vbx, + amrex::Array4 const& vel, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC, + amrex::Real time); + +// +// diffused ib +// set initial phi nodal +// +static void set_initial_phi_nodal (amrex::Box const& bx, + amrex::Array4 const& phi_nodal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC, + amrex::Real time); + +// Sphere near the channel wall +static void SphereNearWall (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +// Falling Sphere +static void FallingSphere (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +#endif diff --git a/Source/prob/prob_init.cpp b/Source/prob/prob_init.cpp index 1d744428..8b726501 100644 --- a/Source/prob/prob_init.cpp +++ b/Source/prob/prob_init.cpp @@ -1,1155 +1,1161 @@ -#include -#include - -using namespace amrex; - -int NavierStokes::probtype = -1; -amrex::Real NavierStokes::ub = 2.0; -amrex::Real NavierStokes::shearrate = 3.0; - -// For now, define pi here, but maybe later make iamr_constants.H -namespace { - constexpr Real Pi = 3.141592653589793238462643383279502884197; - constexpr Real TwoPi = 2.0 * 3.141592653589793238462643383279502884197; -} - -// -// Initialize state and pressure with problem-specific data -// -void NavierStokes::prob_initData () -{ - - // - // Create struct to hold initial conditions parameters - // - InitialConditions IC; - - // - // Read problem parameters from inputs file - // - ParmParse pp("prob"); - ParmParse pp2("ns"); - - pp.query("probtype",probtype); - pp.query("ub",ub); - pp.query("shearrate",shearrate); - pp2.query("fluid_rho",IC.density); - pp.query("direction",IC.direction); - pp.query("interface_width",IC.interface_width); - - Vector velocity(AMREX_SPACEDIM, 0.); - pp.queryarr("velocity_ic",velocity,0,AMREX_SPACEDIM); - AMREX_D_TERM(IC.v_x = velocity[0];, - IC.v_y = velocity[1];, - IC.v_z = velocity[2];); - - pp.query("blob_radius",IC.blob_radius); - Vector blob_center(AMREX_SPACEDIM, 0.); - pp.queryarr("blob_center",blob_center,0,AMREX_SPACEDIM); - AMREX_D_TERM(IC.blob_x = blob_center[0];, - IC.blob_y = blob_center[1];, - IC.blob_z = blob_center[2];); - - // For Rayleigh-Taylor problem - pp.query("rho_1",IC.rho_1); - pp.query("rho_2",IC.rho_2); - pp.query("tra_1",IC.tra_1); - pp.query("tra_2",IC.tra_2); - pp.query("perturbation_amplitude",IC.pertamp); - - // for Taylor-Green - pp.query("velocity_factor",IC.v_x); - pp.query("a", IC.a); - pp.query("b", IC.b); - pp.query("c", IC.c); - - // for Convected Vortex - if (probtype == 8 ) - { - IC.a = 0.5; // x-position of vortex - IC.b = 0.5; // y-position of vortex - IC.c = 0.07;// radius of vortex - - pp.query("xvort", IC.a); - pp.query("yvort", IC.b); - pp.query("rvort", IC.c); - pp.query("forcevort", IC.forcevort); - pp.query("meanFlowDir", IC.meanFlowDir); - pp.query("meanFlowMag", IC.meanFlowMag); - } - - // - // ls related - // - IC.do_phi = do_phi; - if (do_phi) { - IC.Density = Density; // Bug to be fixed: IC.Density is density value, yet Density is the scomp. - IC.phicomp = phicomp; - IC.rho_w = rho_w; - IC.rho_a = rho_a; - } - - // - // Fill state and, optionally, pressure - // - MultiFab& P_new = get_new_data(Press_Type); - MultiFab& S_new = get_new_data(State_Type); - const int nscal = NUM_STATE-Density; - - S_new.setVal(0.0); - P_new.setVal(0.0); - - // Integer indices of the lower left and upper right corners of the - // valid region of the entire domain. - Box const& domain = geom.Domain(); - auto const& dx = geom.CellSizeArray(); - // Physical coordinates of the lower left corner of the domain - auto const& problo = geom.ProbLoArray(); - // Physical coordinates of the upper right corner of the domain - auto const& probhi = geom.ProbHiArray(); - -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(S_new,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.tilebox(); - - if ( 1 == probtype ) - { - // - // Start from rest, constant density of 1 - // Introduced for LidDrivenCavity problem - // - S_new[mfi].setVal(1.0,Density); - } - else if ( 2 == probtype || 6 == probtype ) - { - init_bubble(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - else if ( 3 == probtype ) - { - init_jump(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - else if ( 4 == probtype ) - { - init_constant_vel_rho(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - - else if ( 97 == probtype ) - { - init_channel(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - - else if ( 5 == probtype ) - { - init_DoubleShearLayer(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - else if ( 7 == probtype ) - { - init_Euler(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - else if ( 8 == probtype ) - { - init_ConvectedVortex(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - else if ( 10 == probtype ) - { - init_RayleighTaylor(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - else if ( 11 == probtype ) - { - init_TaylorGreen(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - else if ( 98 == probtype ) // for PVF case - { - init_particles(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - else if ( 99 == probtype ) // ls related - { - init_rsv(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - else if ( 100 == probtype ) - { - init_RayleighTaylor_LS(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - else if ( 101 == probtype ) - { - init_BreakingWave(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - else if ( 102 == probtype || 103 == probtype ) // Sphere near the channel wall - { - SphereNearWall(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - else if ( 104 == probtype ) // Falling Sphere - { - FallingSphere(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - else - { - amrex::Abort("NavierStokes::prob_init: unknown probtype"); - } - } -} - -void NavierStokes::init_bubble (Box const& vbx, - Array4 const& /*press*/, - Array4 const& vel, - Array4 const& scal, - const int nscal, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& /*probhi*/, - InitialConditions IC) -{ - const auto domlo = amrex::lbound(domain); - - // Make local copy capturable by device lambda - bool have_temp = probtype == 6; - - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; - Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; - - // - // Fill Velocity - // - vel(i,j,k,0) = IC.v_x; - vel(i,j,k,1) = IC.v_y; - -#if (AMREX_SPACEDIM == 3) - Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; - - vel(i,j,k,2) = IC.v_z; -#endif - - Real dist = std::sqrt( (x-IC.blob_x)*(x-IC.blob_x) - + (y-IC.blob_y)*(y-IC.blob_y) -#if (AMREX_SPACEDIM == 3) - + (z-IC.blob_z)*(z-IC.blob_z) -#endif - ); - // - // Scalars, ordered as Density, Tracer(s), Temp (if using) - // - - // Tracers - scal(i,j,k,1) = dist < IC.blob_radius ? 1.0 : 0.0; - for ( int nt=2; nt 1 - scal(i,j,k,0) = 1.0/IC.density + 0.5*(1.0 - 1.0/IC.density)*(1.0 + std::tanh(40.*(dist - IC.blob_radius)/IC.interface_width)); - //Temp - scal(i,j,k,nscal-1) = 1/scal(i,j,k,0); - } - else - { - // Density for dense bubble falling, assuming IC.density > 1 - scal(i,j,k,0) = 1.0 + 0.5*(IC.density-1.0)*(1.0-std::tanh(30.*(dist-IC.blob_radius)/IC.interface_width)); - // No Temperature field - } - - }); -} - -// -// ls related -// -void NavierStokes::init_rsv (Box const& vbx, - Array4 const& /*press*/, - Array4 const& vel, - Array4 const& scal, - const int nscal, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& /*probhi*/, - InitialConditions IC) -{ - - BL_ASSERT(IC.do_phi==1); - - const auto domlo = amrex::lbound(domain); - - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; - Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; - - // - // Fill Velocity - // - vel(i,j,k,0) = - std::sin(Pi*x)*std::sin(Pi*x)*std::sin(2*Pi*y); - vel(i,j,k,1) = std::sin(2*Pi*x)*std::sin(Pi*y)*std::sin(Pi*y); - -#if (AMREX_SPACEDIM == 3) - vel(i,j,k,2) = 0.0; -#endif - - // - // Scalars, ordered as Density, Tracer(s), Temp (if using), ls - // - - // All Tracers are set here - for ( int nt=0; nt const& vel, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& /*probhi*/, - InitialConditions IC, - Real time) -{ - const auto domlo = amrex::lbound(domain); - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; - Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; - - // - // Fill Velocity - // - vel(i,j,k,0) = - std::sin(Pi*x)*std::sin(Pi*x)*std::sin(2*Pi*y)*std::cos(Pi*time/IC.totalTimeRsv); - vel(i,j,k,1) = std::sin(2*Pi*x)*std::sin(Pi*y)*std::sin(Pi*y)*std::cos(Pi*time/IC.totalTimeRsv); - -#if (AMREX_SPACEDIM == 3) - vel(i,j,k,2) = 0.0; -#endif - - }); -} - -// -// diffused ib -// -void NavierStokes::set_initial_phi_nodal (Box const& bx, - Array4 const& phi_nodal, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& /*probhi*/, - InitialConditions IC, - Real time) -{ - - BL_ASSERT(AMREX_SPACEDIM == 3); - BL_ASSERT(probtype == 98); - - const auto domlo = amrex::lbound(domain); - amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Real x = problo[0] + (i - domlo.x)*dx[0]; - Real y = problo[1] + (j - domlo.y)*dx[1]; - Real z = problo[2] + (k - domlo.z)*dx[2]; - - phi_nodal(i,j,k) = std::sqrt( (x-IC.blob_x)*(x-IC.blob_x) - + (y-IC.blob_y)*(y-IC.blob_y) + (z-IC.blob_z)*(z-IC.blob_z)) - IC.blob_radius;; - phi_nodal(i,j,k) = phi_nodal(i,j,k) / IC.blob_radius; - - }); - -} - -// Sphere near the channel wall -void NavierStokes::SphereNearWall (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC) -{ - BL_ASSERT(AMREX_SPACEDIM == 3); - const auto domlo = amrex::lbound(domain); - // Initial velocity of flow field - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - - // - // Scalars, ordered as Density, Tracer(s), Temp (if using) - // - - vel(i,j,k,0) = 0.0; - vel(i,j,k,1) = 0.0; - vel(i,j,k,2) = 0.0; - - scal(i,j,k,0) = IC.density; - - // Tracers - scal(i,j,k,1) = 0.0; - - - }); -} - -// Falling Sphere -void NavierStokes::FallingSphere (amrex::Box const& vbx, - amrex::Array4 const& press, - amrex::Array4 const& vel, - amrex::Array4 const& scal, - int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC) -{ - BL_ASSERT(AMREX_SPACEDIM == 3); - const auto domlo = amrex::lbound(domain); - // Initial velocity of flow field - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - - // - // Scalars, ordered as Density, Tracer(s), Temp (if using) - // - - vel(i,j,k,0) = 0.0; - vel(i,j,k,1) = 0.0; - vel(i,j,k,2) = 0.0; - - scal(i,j,k,0) = IC.density; - - // Tracers - scal(i,j,k,1) = 0.0; - - - }); -} - -void NavierStokes::init_constant_vel_rho (Box const& vbx, - Array4 const& /*press*/, - Array4 const& vel, - Array4 const& scal, - const int nscal, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& /*probhi*/, - InitialConditions IC) -{ - const auto domlo = amrex::lbound(domain); - - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; - Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; - - // - // Fill Velocity - // - vel(i,j,k,0) = IC.v_x; - vel(i,j,k,1) = IC.v_y; - -#if (AMREX_SPACEDIM == 3) - Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; - - vel(i,j,k,2) = IC.v_z; -#endif - - Real dist = std::sqrt( (x-IC.blob_x)*(x-IC.blob_x) - + (y-IC.blob_y)*(y-IC.blob_y) -#if (AMREX_SPACEDIM == 3) - + (z-IC.blob_z)*(z-IC.blob_z) -#endif - ); - // - // Scalars, ordered as Density, Tracer(s), Temp (if using) - // - scal(i,j,k,0) = IC.density; - - // Tracers - scal(i,j,k,1) = 0.5*(1.0-std::tanh(25.*(dist-IC.blob_radius)/IC.interface_width)); - for ( int nt=2; nt const& /*press*/, - Array4 const& vel, - Array4 const& scal, - const int nscal, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& probhi, - InitialConditions IC) -{ - - BL_ASSERT(AMREX_SPACEDIM == 3); - const auto domlo = amrex::lbound(domain); - - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - // Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; - Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; - // Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; - - // - // Fill Velocity - // - vel(i,j,k,0) = 0.0; - vel(i,j,k,1) = 0.0; - - Real w_b = 18.5; - const Real Ly = (probhi[1] - problo[1]); - vel(i,j,k,2) = w_b * (1.0 - std::pow((y/Ly - 1.0),2.0)); - - // - // Scalars, ordered as Density, Tracer(s), Temp (if using) - // - scal(i,j,k,0) = 1.0; - - // Tracers - scal(i,j,k,1) = 0.0; - - }); -} - -void NavierStokes::init_jump (Box const& vbx, - Array4 const& /*press*/, - Array4 const& vel, - Array4 const& scal, - const int nscal, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& /*probhi*/, - InitialConditions IC) -{ - const auto domlo = amrex::lbound(domain); - - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; - Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; - - // - // Fill Velocity - // - vel(i,j,k,0) = IC.v_x; - vel(i,j,k,1) = IC.v_y; - -#if (AMREX_SPACEDIM == 3) - Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; - - vel(i,j,k,2) = IC.v_z; -#endif - - Real dist = std::sqrt( (x-IC.blob_x)*(x-IC.blob_x) - + (y-IC.blob_y)*(y-IC.blob_y) -#if (AMREX_SPACEDIM == 3) - + (z-IC.blob_z)*(z-IC.blob_z) -#endif - ); - // - // Scalars, ordered as Density, Tracer(s), Temp (if using) - // - - Real x_jump = -0.1; - - // Smooth the density interface just a bit - scal(i,j,k,0) = //dens1 * (2. + std::tanh(100.*(-.2-x)/IC.interface_width) ) / 2.; - IC.rho_1 + ((IC.rho_2-IC.rho_1)/2.0)*(1.0+std::tanh(-(x_jump-x)/IC.interface_width)); - - if (x <= x_jump ) { - //scal(i,j,k,0) = IC.rho_1; - scal(i,j,k,1) = IC.tra_1; - } else { - //scal(i,j,k,0) = IC.rho_2; - scal(i,j,k,1) = IC.tra_2; - } - - for ( int nt=2; nt const& /*press*/, - Array4 const& vel, - Array4 const& scal, - const int nscal, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& /*probhi*/, - InitialConditions IC) -{ - const auto domlo = amrex::lbound(domain); - - if ( !(IC.direction == 0 || IC.direction == 1) ) - amrex::Abort("\n init_DoubleShearLayer: Must set a direction with prob.direction = 0 or 1\n in the inputs file. Shear layer along the z-direction not yet written"); - - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; - Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; -#if (AMREX_SPACEDIM == 3) - Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; -#endif - - // - // Fill Velocity - // - if ( IC.direction == 1 ) - { - // shear layer in y-dir - vel(i,j,k,0) = -.05*std::sin(Pi*y); - vel(i,j,k,1) = std::tanh(30.*(.5-amrex::Math::abs(x))/IC.interface_width); - } - else - { - // shear layer in x-dir - vel(i,j,k,0) = std::tanh(30.*(.5-amrex::Math::abs(y))/IC.interface_width); - vel(i,j,k,1) = .05*std::sin(Pi*x); - } - - Real dist = std::sqrt( (x-IC.blob_x)*(x-IC.blob_x) - + (y-IC.blob_y)*(y-IC.blob_y) -#if (AMREX_SPACEDIM == 3) - + (z-IC.blob_z)*(z-IC.blob_z) -#endif - ); - - // - // Scalars, ordered as Density, Tracer(s) - // - scal(i,j,k,0) = IC.density; - - // Tracers - scal(i,j,k,1) = dist < IC.blob_radius ? 1.0 : 0.0; - for ( int nt=2; nt const& /*press*/, - Array4 const& /*vel*/, - Array4 const& scal, - const int nscal, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& probhi, - InitialConditions IC) -{ - const auto domlo = amrex::lbound(domain); - - // - // Velocity already initialized to 0 - // - - // - // Scalars, ordered as Density, Tracer(s), Temp (if using) - // - const Real Lx = (probhi[0] - problo[0]); - -#if (AMREX_SPACEDIM == 2) - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; - Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; - - const Real pertheight = 0.5 + IC.pertamp*(std::cos(2.0*Pi*x/Lx) - + std::cos(2.0*Pi*(Lx-x)/Lx)); - - scal(i,j,k,0) = IC.rho_1 + ((IC.rho_2-IC.rho_1)/2.0)*(1.0+std::tanh((y-pertheight)/IC.interface_width)); - scal(i,j,k,1) = IC.tra_1 + ((IC.tra_2-IC.tra_1)/2.0)*(1.0+std::tanh((y-pertheight)/IC.interface_width)); - for ( int nt=2; nt const& /*press*/, - Array4 const& /*vel*/, - Array4 const& scal, - const int nscal, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& probhi, - InitialConditions IC) -{ - const auto domlo = amrex::lbound(domain); - - // - // Velocity already initialized to 0 - // - - BL_ASSERT(AMREX_SPACEDIM==2); - // - // Scalars, ordered as Density, Tracer(s), Temp (if using), LS - // - const Real Lx = (probhi[0] - problo[0]); - -#if (AMREX_SPACEDIM == 2) - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; - Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; - - const Real pertheight = 2.0 + IC.pertamp*(std::cos(2.0*Pi*x/Lx)); - - scal(i,j,k,0) = IC.rho_2 + ((IC.rho_1-IC.rho_2)/2.0)*(1.0+std::tanh((y-pertheight)/IC.interface_width)); - for ( int nt=1; nt const& /*press*/, - Array4 const& vel, - Array4 const& scal, - const int nscal, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& probhi, - InitialConditions IC) -{ - const auto domlo = amrex::lbound(domain); - - BL_ASSERT(AMREX_SPACEDIM==2); - // - // Scalars, ordered as Density, Tracer(s), Temp (if using), LS - // - const Real Lx = (probhi[0] - problo[0]); - - // wave parameters - const Real WAVE_LENGTH = Lx; - const Real KA = 0.55; - const Real K_WAVE = 2.0*Pi/WAVE_LENGTH; - const Real O_WAVE = std::sqrt((K_WAVE*9.81)*(1.0+KA*KA/2.0)); - // amrex::Print() << "IC.rho_w IC.rho_a " << IC.rho_w << " " << IC.rho_a << std::endl; - -#if (AMREX_SPACEDIM == 2) - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; - Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; - - const Real eta = KA/K_WAVE*std::cos(K_WAVE*x) - + 0.5 *std::pow(KA,2.0)/K_WAVE*std::cos(2.0*K_WAVE*x) - + 3.0/8.0*std::pow(KA,3.0)/K_WAVE*std::cos(3.0*K_WAVE*x); - - const Real ufs = O_WAVE*KA/K_WAVE*std::exp(K_WAVE*eta)*std::cos(K_WAVE*x); - const Real vfs = O_WAVE*KA/K_WAVE*std::exp(K_WAVE*eta)*std::sin(K_WAVE*x); - - // - // Fill Velocity - // - if ( y <= eta ) - { - vel(i,j,k,0) = O_WAVE*KA/K_WAVE*std::exp(K_WAVE*y)*std::cos(K_WAVE*x); - vel(i,j,k,1) = O_WAVE*KA/K_WAVE*std::exp(K_WAVE*y)*std::sin(K_WAVE*x); - scal(i,j,k,0) = IC.rho_w; - } - else - { - vel(i,j,k,0) = ufs*std::exp(-100.0*(y-eta)); - vel(i,j,k,1) = vfs*std::exp(-100.0*(y-eta)); - scal(i,j,k,0) = IC.rho_a; - } - - for ( int nt=1; nt const& /*press*/, - Array4 const& vel, - Array4 const& scal, - const int nscal, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& /*probhi*/, - InitialConditions IC) -{ - const auto domlo = amrex::lbound(domain); - - if ( IC.v_x == 0.0 ) - amrex::Abort("NavierStokes::init_TaylorGreen: Must provide prob.velocity_factor. If unsure, prob.velocity_factor = 1.0 is a good choice."); - - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; - Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; -#if (AMREX_SPACEDIM == 3) - Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; -#else - constexpr Real z = 0.0; -#endif - - // - // Fill Velocity - // - AMREX_D_TERM(vel(i,j,k,0) = IC.v_x*std::sin(IC.a*TwoPi*x) * std::cos(IC.b*TwoPi*y) * std::cos(IC.c*TwoPi*z);, - vel(i,j,k,1) = -IC.v_x*std::cos(IC.a*TwoPi*x) * std::sin(IC.b*TwoPi*y) * std::cos(IC.c*TwoPi*z);, - vel(i,j,k,2) = 0.0;); - - // - // Scalars, ordered as Density, Tracer(s) - // - scal(i,j,k,0) = IC.density; - - // The theoretical pressure perturbation from p_0 -#if ( AMREX_SPACEDIM == 2 ) - scal(i,j,k,1) = (IC.density*IC.v_x*IC.v_x/4.0)*(cos(2.0*IC.a*TwoPi*x)+cos(2.0*IC.b*TwoPi*y)); -#else - scal(i,j,k,1) = (IC.density*IC.v_x*IC.v_x/16.0)*(2.0+cos(2.0*IC.c*TwoPi*z))*(cos(2.0*IC.a*TwoPi*x)+cos(2.0*IC.b*TwoPi*y)); -#endif - - // Tracers - for ( int nt=2; nt const& press, - Array4 const& vel, - Array4 const& scal, - const int nscal, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& /*probhi*/, - InitialConditions IC) -{ - - const auto domlo = amrex::lbound(domain); - - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - // Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; - // Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; - // Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; - - // - // Fill Velocity - // - vel(i,j,k,0) = 0.0; - vel(i,j,k,1) = 0.0; - -#if (AMREX_SPACEDIM == 3) - vel(i,j,k,2) = 0.0; -#endif - - // - // Scalars, ordered as Density, Tracer(s), Temp (if using) - // - - // All Tracers are set here - for ( int nt=0; nt const& /*press*/, - Array4 const& vel, - Array4 const& scal, - const int nscal, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& /*probhi*/, - InitialConditions IC) -{ - const auto domlo = amrex::lbound(domain); - -#if (AMREX_SPACEDIM != 3) - amrex::Abort("NavierStokes::init_Euler: This is a 3D problem, please recompile with DIM=3 in makefile"); -#endif - - constexpr Real eps_input=0.05, rho_input=0.15; - constexpr Real beta_input=15.0, delta_input=0.0333; - constexpr Real kappa_input=500.0; - - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Real x = problo[0] + (i - domlo.x + 0.5)*dx[0] - 0.5; - Real y = problo[1] + (j - domlo.y + 0.5)*dx[1] - 0.5; - Real z = problo[2] + (k - domlo.z + 0.5)*dx[2] - 0.5; - - Real r_yz = std::sqrt(y*y+z*z); - - // - // Fill Velocity - // - vel(i,j,k,0) = tanh( (rho_input - r_yz) / delta_input); - vel(i,j,k,1) = 0.0; - vel(i,j,k,2) = eps_input * std::exp(-beta_input * (x*x + y*y) ); - - // - // Scalars, ordered as Density, Tracer(s) - // - scal(i,j,k,0) = IC.density; - scal(i,j,k,1) = std::exp( -kappa_input * (rho_input - r_yz)*(rho_input - r_yz) ); - - // Additional Tracer, if using - for ( int nt=2; nt const& /*press*/, - Array4 const& vel, - Array4 const& scal, - const int nscal, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& /*probhi*/, - InitialConditions IC) -{ - const auto domlo = amrex::lbound(domain); - - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - AMREX_D_TERM(Real x = problo[0] + (i - domlo.x + 0.5)*dx[0];, - Real y = problo[1] + (j - domlo.y + 0.5)*dx[1];, - /*Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]*/); - - amrex::Real deltax = x - IC.a; // x-distance from vortex center - amrex::Real deltay = y - IC.b; // y-distance form vortex center - amrex::Real d_sq = deltax*deltax + deltay*deltay; - amrex::Real r_sq = IC.c * IC.c; // square of vortex radius - amrex::Real u_vort = -IC.forcevort*deltay/r_sq * exp(-d_sq/r_sq/2.); - amrex::Real v_vort = IC.forcevort*deltax/r_sq * exp(-d_sq/r_sq/2.); -#if (AMREX_SPACEDIM == 3) - amrex::Real w_vort = 0.; -#endif - - // - // Fill Velocity - // - switch(IC.meanFlowDir) { - case 1 : - AMREX_D_TERM(vel(i,j,k,0) = IC.meanFlowMag + u_vort;, - vel(i,j,k,1) = v_vort;, - vel(i,j,k,2) = w_vort); - break; - case -1 : - AMREX_D_TERM(vel(i,j,k,0) = -IC.meanFlowMag + u_vort;, - vel(i,j,k,1) = v_vort;, - vel(i,j,k,2) = w_vort); - break; - case 2 : - AMREX_D_TERM(vel(i,j,k,0) = v_vort;, - vel(i,j,k,1) = IC.meanFlowMag + u_vort;, - vel(i,j,k,2) = w_vort); - break; - case -2 : - AMREX_D_TERM(vel(i,j,k,0) = v_vort;, - vel(i,j,k,1) = -IC.meanFlowMag + u_vort;, - vel(i,j,k,2) = w_vort); - break; - case 3 : - AMREX_D_TERM(vel(i,j,k,0) = IC.meanFlowMag + u_vort;, - vel(i,j,k,1) = IC.meanFlowMag + v_vort;, - vel(i,j,k,2) = w_vort); - break; - case -3 : - AMREX_D_TERM(vel(i,j,k,0) = -IC.meanFlowMag + u_vort;, - vel(i,j,k,1) = -IC.meanFlowMag + v_vort;, - vel(i,j,k,2) = w_vort); - break; - } - - // - // Scalars, ordered as Density, Tracer(s) - // - scal(i,j,k,0) = IC.density; - - // Additional Tracer, if using - for ( int nt=1; nt +// +// SPDX-License-Identifier: LicenseRef-OpenSource +// Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +// Original source: https://github.com/AMReX-Fluids/IAMR + +#include +#include + +using namespace amrex; + +int NavierStokes::probtype = -1; +amrex::Real NavierStokes::ub = 2.0; +amrex::Real NavierStokes::shearrate = 3.0; + +// For now, define pi here, but maybe later make iamr_constants.H +namespace { + constexpr Real Pi = 3.141592653589793238462643383279502884197; + constexpr Real TwoPi = 2.0 * 3.141592653589793238462643383279502884197; +} + +// +// Initialize state and pressure with problem-specific data +// +void NavierStokes::prob_initData () +{ + + // + // Create struct to hold initial conditions parameters + // + InitialConditions IC; + + // + // Read problem parameters from inputs file + // + ParmParse pp("prob"); + ParmParse pp2("ns"); + + pp.query("probtype",probtype); + pp.query("ub",ub); + pp.query("shearrate",shearrate); + pp2.query("fluid_rho",IC.density); + pp.query("direction",IC.direction); + pp.query("interface_width",IC.interface_width); + + Vector velocity(AMREX_SPACEDIM, 0.); + pp.queryarr("velocity_ic",velocity,0,AMREX_SPACEDIM); + AMREX_D_TERM(IC.v_x = velocity[0];, + IC.v_y = velocity[1];, + IC.v_z = velocity[2];); + + pp.query("blob_radius",IC.blob_radius); + Vector blob_center(AMREX_SPACEDIM, 0.); + pp.queryarr("blob_center",blob_center,0,AMREX_SPACEDIM); + AMREX_D_TERM(IC.blob_x = blob_center[0];, + IC.blob_y = blob_center[1];, + IC.blob_z = blob_center[2];); + + // For Rayleigh-Taylor problem + pp.query("rho_1",IC.rho_1); + pp.query("rho_2",IC.rho_2); + pp.query("tra_1",IC.tra_1); + pp.query("tra_2",IC.tra_2); + pp.query("perturbation_amplitude",IC.pertamp); + + // for Taylor-Green + pp.query("velocity_factor",IC.v_x); + pp.query("a", IC.a); + pp.query("b", IC.b); + pp.query("c", IC.c); + + // for Convected Vortex + if (probtype == 8 ) + { + IC.a = 0.5; // x-position of vortex + IC.b = 0.5; // y-position of vortex + IC.c = 0.07;// radius of vortex + + pp.query("xvort", IC.a); + pp.query("yvort", IC.b); + pp.query("rvort", IC.c); + pp.query("forcevort", IC.forcevort); + pp.query("meanFlowDir", IC.meanFlowDir); + pp.query("meanFlowMag", IC.meanFlowMag); + } + + // + // ls related + // + IC.do_phi = do_phi; + if (do_phi) { + IC.Density = Density; // Bug to be fixed: IC.Density is density value, yet Density is the scomp. + IC.phicomp = phicomp; + IC.rho_w = rho_w; + IC.rho_a = rho_a; + } + + // + // Fill state and, optionally, pressure + // + MultiFab& P_new = get_new_data(Press_Type); + MultiFab& S_new = get_new_data(State_Type); + const int nscal = NUM_STATE-Density; + + S_new.setVal(0.0); + P_new.setVal(0.0); + + // Integer indices of the lower left and upper right corners of the + // valid region of the entire domain. + Box const& domain = geom.Domain(); + auto const& dx = geom.CellSizeArray(); + // Physical coordinates of the lower left corner of the domain + auto const& problo = geom.ProbLoArray(); + // Physical coordinates of the upper right corner of the domain + auto const& probhi = geom.ProbHiArray(); + +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(S_new,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.tilebox(); + + if ( 1 == probtype ) + { + // + // Start from rest, constant density of 1 + // Introduced for LidDrivenCavity problem + // + S_new[mfi].setVal(1.0,Density); + } + else if ( 2 == probtype || 6 == probtype ) + { + init_bubble(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + else if ( 3 == probtype ) + { + init_jump(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + else if ( 4 == probtype ) + { + init_constant_vel_rho(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + + else if ( 97 == probtype ) + { + init_channel(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + + else if ( 5 == probtype ) + { + init_DoubleShearLayer(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + else if ( 7 == probtype ) + { + init_Euler(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + else if ( 8 == probtype ) + { + init_ConvectedVortex(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + else if ( 10 == probtype ) + { + init_RayleighTaylor(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + else if ( 11 == probtype ) + { + init_TaylorGreen(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + else if ( 98 == probtype ) // for PVF case + { + init_particles(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + else if ( 99 == probtype ) // ls related + { + init_rsv(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + else if ( 100 == probtype ) + { + init_RayleighTaylor_LS(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + else if ( 101 == probtype ) + { + init_BreakingWave(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + else if ( 102 == probtype || 103 == probtype ) // Sphere near the channel wall + { + SphereNearWall(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + else if ( 104 == probtype ) // Falling Sphere + { + FallingSphere(vbx, P_new.array(mfi), S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + else + { + amrex::Abort("NavierStokes::prob_init: unknown probtype"); + } + } +} + +void NavierStokes::init_bubble (Box const& vbx, + Array4 const& /*press*/, + Array4 const& vel, + Array4 const& scal, + const int nscal, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& /*probhi*/, + InitialConditions IC) +{ + const auto domlo = amrex::lbound(domain); + + // Make local copy capturable by device lambda + bool have_temp = probtype == 6; + + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; + Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; + + // + // Fill Velocity + // + vel(i,j,k,0) = IC.v_x; + vel(i,j,k,1) = IC.v_y; + +#if (AMREX_SPACEDIM == 3) + Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; + + vel(i,j,k,2) = IC.v_z; +#endif + + Real dist = std::sqrt( (x-IC.blob_x)*(x-IC.blob_x) + + (y-IC.blob_y)*(y-IC.blob_y) +#if (AMREX_SPACEDIM == 3) + + (z-IC.blob_z)*(z-IC.blob_z) +#endif + ); + // + // Scalars, ordered as Density, Tracer(s), Temp (if using) + // + + // Tracers + scal(i,j,k,1) = dist < IC.blob_radius ? 1.0 : 0.0; + for ( int nt=2; nt 1 + scal(i,j,k,0) = 1.0/IC.density + 0.5*(1.0 - 1.0/IC.density)*(1.0 + std::tanh(40.*(dist - IC.blob_radius)/IC.interface_width)); + //Temp + scal(i,j,k,nscal-1) = 1/scal(i,j,k,0); + } + else + { + // Density for dense bubble falling, assuming IC.density > 1 + scal(i,j,k,0) = 1.0 + 0.5*(IC.density-1.0)*(1.0-std::tanh(30.*(dist-IC.blob_radius)/IC.interface_width)); + // No Temperature field + } + + }); +} + +// +// ls related +// +void NavierStokes::init_rsv (Box const& vbx, + Array4 const& /*press*/, + Array4 const& vel, + Array4 const& scal, + const int nscal, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& /*probhi*/, + InitialConditions IC) +{ + + BL_ASSERT(IC.do_phi==1); + + const auto domlo = amrex::lbound(domain); + + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; + Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; + + // + // Fill Velocity + // + vel(i,j,k,0) = - std::sin(Pi*x)*std::sin(Pi*x)*std::sin(2*Pi*y); + vel(i,j,k,1) = std::sin(2*Pi*x)*std::sin(Pi*y)*std::sin(Pi*y); + +#if (AMREX_SPACEDIM == 3) + vel(i,j,k,2) = 0.0; +#endif + + // + // Scalars, ordered as Density, Tracer(s), Temp (if using), ls + // + + // All Tracers are set here + for ( int nt=0; nt const& vel, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& /*probhi*/, + InitialConditions IC, + Real time) +{ + const auto domlo = amrex::lbound(domain); + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; + Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; + + // + // Fill Velocity + // + vel(i,j,k,0) = - std::sin(Pi*x)*std::sin(Pi*x)*std::sin(2*Pi*y)*std::cos(Pi*time/IC.totalTimeRsv); + vel(i,j,k,1) = std::sin(2*Pi*x)*std::sin(Pi*y)*std::sin(Pi*y)*std::cos(Pi*time/IC.totalTimeRsv); + +#if (AMREX_SPACEDIM == 3) + vel(i,j,k,2) = 0.0; +#endif + + }); +} + +// +// diffused ib +// +void NavierStokes::set_initial_phi_nodal (Box const& bx, + Array4 const& phi_nodal, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& /*probhi*/, + InitialConditions IC, + Real time) +{ + + BL_ASSERT(AMREX_SPACEDIM == 3); + BL_ASSERT(probtype == 98); + + const auto domlo = amrex::lbound(domain); + amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Real x = problo[0] + (i - domlo.x)*dx[0]; + Real y = problo[1] + (j - domlo.y)*dx[1]; + Real z = problo[2] + (k - domlo.z)*dx[2]; + + phi_nodal(i,j,k) = std::sqrt( (x-IC.blob_x)*(x-IC.blob_x) + + (y-IC.blob_y)*(y-IC.blob_y) + (z-IC.blob_z)*(z-IC.blob_z)) - IC.blob_radius;; + phi_nodal(i,j,k) = phi_nodal(i,j,k) / IC.blob_radius; + + }); + +} + +// Sphere near the channel wall +void NavierStokes::SphereNearWall (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC) +{ + BL_ASSERT(AMREX_SPACEDIM == 3); + const auto domlo = amrex::lbound(domain); + // Initial velocity of flow field + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + + // + // Scalars, ordered as Density, Tracer(s), Temp (if using) + // + + vel(i,j,k,0) = 0.0; + vel(i,j,k,1) = 0.0; + vel(i,j,k,2) = 0.0; + + scal(i,j,k,0) = IC.density; + + // Tracers + scal(i,j,k,1) = 0.0; + + + }); +} + +// Falling Sphere +void NavierStokes::FallingSphere (amrex::Box const& vbx, + amrex::Array4 const& press, + amrex::Array4 const& vel, + amrex::Array4 const& scal, + int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC) +{ + BL_ASSERT(AMREX_SPACEDIM == 3); + const auto domlo = amrex::lbound(domain); + // Initial velocity of flow field + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + + // + // Scalars, ordered as Density, Tracer(s), Temp (if using) + // + + vel(i,j,k,0) = 0.0; + vel(i,j,k,1) = 0.0; + vel(i,j,k,2) = 0.0; + + scal(i,j,k,0) = IC.density; + + // Tracers + scal(i,j,k,1) = 0.0; + + + }); +} + +void NavierStokes::init_constant_vel_rho (Box const& vbx, + Array4 const& /*press*/, + Array4 const& vel, + Array4 const& scal, + const int nscal, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& /*probhi*/, + InitialConditions IC) +{ + const auto domlo = amrex::lbound(domain); + + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; + Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; + + // + // Fill Velocity + // + vel(i,j,k,0) = IC.v_x; + vel(i,j,k,1) = IC.v_y; + +#if (AMREX_SPACEDIM == 3) + Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; + + vel(i,j,k,2) = IC.v_z; +#endif + + Real dist = std::sqrt( (x-IC.blob_x)*(x-IC.blob_x) + + (y-IC.blob_y)*(y-IC.blob_y) +#if (AMREX_SPACEDIM == 3) + + (z-IC.blob_z)*(z-IC.blob_z) +#endif + ); + // + // Scalars, ordered as Density, Tracer(s), Temp (if using) + // + scal(i,j,k,0) = IC.density; + + // Tracers + scal(i,j,k,1) = 0.5*(1.0-std::tanh(25.*(dist-IC.blob_radius)/IC.interface_width)); + for ( int nt=2; nt const& /*press*/, + Array4 const& vel, + Array4 const& scal, + const int nscal, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& probhi, + InitialConditions IC) +{ + + BL_ASSERT(AMREX_SPACEDIM == 3); + const auto domlo = amrex::lbound(domain); + + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + // Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; + Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; + // Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; + + // + // Fill Velocity + // + vel(i,j,k,0) = 0.0; + vel(i,j,k,1) = 0.0; + + Real w_b = 18.5; + const Real Ly = (probhi[1] - problo[1]); + vel(i,j,k,2) = w_b * (1.0 - std::pow((y/Ly - 1.0),2.0)); + + // + // Scalars, ordered as Density, Tracer(s), Temp (if using) + // + scal(i,j,k,0) = 1.0; + + // Tracers + scal(i,j,k,1) = 0.0; + + }); +} + +void NavierStokes::init_jump (Box const& vbx, + Array4 const& /*press*/, + Array4 const& vel, + Array4 const& scal, + const int nscal, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& /*probhi*/, + InitialConditions IC) +{ + const auto domlo = amrex::lbound(domain); + + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; + Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; + + // + // Fill Velocity + // + vel(i,j,k,0) = IC.v_x; + vel(i,j,k,1) = IC.v_y; + +#if (AMREX_SPACEDIM == 3) + Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; + + vel(i,j,k,2) = IC.v_z; +#endif + + Real dist = std::sqrt( (x-IC.blob_x)*(x-IC.blob_x) + + (y-IC.blob_y)*(y-IC.blob_y) +#if (AMREX_SPACEDIM == 3) + + (z-IC.blob_z)*(z-IC.blob_z) +#endif + ); + // + // Scalars, ordered as Density, Tracer(s), Temp (if using) + // + + Real x_jump = -0.1; + + // Smooth the density interface just a bit + scal(i,j,k,0) = //dens1 * (2. + std::tanh(100.*(-.2-x)/IC.interface_width) ) / 2.; + IC.rho_1 + ((IC.rho_2-IC.rho_1)/2.0)*(1.0+std::tanh(-(x_jump-x)/IC.interface_width)); + + if (x <= x_jump ) { + //scal(i,j,k,0) = IC.rho_1; + scal(i,j,k,1) = IC.tra_1; + } else { + //scal(i,j,k,0) = IC.rho_2; + scal(i,j,k,1) = IC.tra_2; + } + + for ( int nt=2; nt const& /*press*/, + Array4 const& vel, + Array4 const& scal, + const int nscal, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& /*probhi*/, + InitialConditions IC) +{ + const auto domlo = amrex::lbound(domain); + + if ( !(IC.direction == 0 || IC.direction == 1) ) + amrex::Abort("\n init_DoubleShearLayer: Must set a direction with prob.direction = 0 or 1\n in the inputs file. Shear layer along the z-direction not yet written"); + + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; + Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; +#if (AMREX_SPACEDIM == 3) + Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; +#endif + + // + // Fill Velocity + // + if ( IC.direction == 1 ) + { + // shear layer in y-dir + vel(i,j,k,0) = -.05*std::sin(Pi*y); + vel(i,j,k,1) = std::tanh(30.*(.5-amrex::Math::abs(x))/IC.interface_width); + } + else + { + // shear layer in x-dir + vel(i,j,k,0) = std::tanh(30.*(.5-amrex::Math::abs(y))/IC.interface_width); + vel(i,j,k,1) = .05*std::sin(Pi*x); + } + + Real dist = std::sqrt( (x-IC.blob_x)*(x-IC.blob_x) + + (y-IC.blob_y)*(y-IC.blob_y) +#if (AMREX_SPACEDIM == 3) + + (z-IC.blob_z)*(z-IC.blob_z) +#endif + ); + + // + // Scalars, ordered as Density, Tracer(s) + // + scal(i,j,k,0) = IC.density; + + // Tracers + scal(i,j,k,1) = dist < IC.blob_radius ? 1.0 : 0.0; + for ( int nt=2; nt const& /*press*/, + Array4 const& /*vel*/, + Array4 const& scal, + const int nscal, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& probhi, + InitialConditions IC) +{ + const auto domlo = amrex::lbound(domain); + + // + // Velocity already initialized to 0 + // + + // + // Scalars, ordered as Density, Tracer(s), Temp (if using) + // + const Real Lx = (probhi[0] - problo[0]); + +#if (AMREX_SPACEDIM == 2) + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; + Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; + + const Real pertheight = 0.5 + IC.pertamp*(std::cos(2.0*Pi*x/Lx) + + std::cos(2.0*Pi*(Lx-x)/Lx)); + + scal(i,j,k,0) = IC.rho_1 + ((IC.rho_2-IC.rho_1)/2.0)*(1.0+std::tanh((y-pertheight)/IC.interface_width)); + scal(i,j,k,1) = IC.tra_1 + ((IC.tra_2-IC.tra_1)/2.0)*(1.0+std::tanh((y-pertheight)/IC.interface_width)); + for ( int nt=2; nt const& /*press*/, + Array4 const& /*vel*/, + Array4 const& scal, + const int nscal, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& probhi, + InitialConditions IC) +{ + const auto domlo = amrex::lbound(domain); + + // + // Velocity already initialized to 0 + // + + BL_ASSERT(AMREX_SPACEDIM==2); + // + // Scalars, ordered as Density, Tracer(s), Temp (if using), LS + // + const Real Lx = (probhi[0] - problo[0]); + +#if (AMREX_SPACEDIM == 2) + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; + Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; + + const Real pertheight = 2.0 + IC.pertamp*(std::cos(2.0*Pi*x/Lx)); + + scal(i,j,k,0) = IC.rho_2 + ((IC.rho_1-IC.rho_2)/2.0)*(1.0+std::tanh((y-pertheight)/IC.interface_width)); + for ( int nt=1; nt const& /*press*/, + Array4 const& vel, + Array4 const& scal, + const int nscal, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& probhi, + InitialConditions IC) +{ + const auto domlo = amrex::lbound(domain); + + BL_ASSERT(AMREX_SPACEDIM==2); + // + // Scalars, ordered as Density, Tracer(s), Temp (if using), LS + // + const Real Lx = (probhi[0] - problo[0]); + + // wave parameters + const Real WAVE_LENGTH = Lx; + const Real KA = 0.55; + const Real K_WAVE = 2.0*Pi/WAVE_LENGTH; + const Real O_WAVE = std::sqrt((K_WAVE*9.81)*(1.0+KA*KA/2.0)); + // amrex::Print() << "IC.rho_w IC.rho_a " << IC.rho_w << " " << IC.rho_a << std::endl; + +#if (AMREX_SPACEDIM == 2) + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; + Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; + + const Real eta = KA/K_WAVE*std::cos(K_WAVE*x) + + 0.5 *std::pow(KA,2.0)/K_WAVE*std::cos(2.0*K_WAVE*x) + + 3.0/8.0*std::pow(KA,3.0)/K_WAVE*std::cos(3.0*K_WAVE*x); + + const Real ufs = O_WAVE*KA/K_WAVE*std::exp(K_WAVE*eta)*std::cos(K_WAVE*x); + const Real vfs = O_WAVE*KA/K_WAVE*std::exp(K_WAVE*eta)*std::sin(K_WAVE*x); + + // + // Fill Velocity + // + if ( y <= eta ) + { + vel(i,j,k,0) = O_WAVE*KA/K_WAVE*std::exp(K_WAVE*y)*std::cos(K_WAVE*x); + vel(i,j,k,1) = O_WAVE*KA/K_WAVE*std::exp(K_WAVE*y)*std::sin(K_WAVE*x); + scal(i,j,k,0) = IC.rho_w; + } + else + { + vel(i,j,k,0) = ufs*std::exp(-100.0*(y-eta)); + vel(i,j,k,1) = vfs*std::exp(-100.0*(y-eta)); + scal(i,j,k,0) = IC.rho_a; + } + + for ( int nt=1; nt const& /*press*/, + Array4 const& vel, + Array4 const& scal, + const int nscal, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& /*probhi*/, + InitialConditions IC) +{ + const auto domlo = amrex::lbound(domain); + + if ( IC.v_x == 0.0 ) + amrex::Abort("NavierStokes::init_TaylorGreen: Must provide prob.velocity_factor. If unsure, prob.velocity_factor = 1.0 is a good choice."); + + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; + Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; +#if (AMREX_SPACEDIM == 3) + Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; +#else + constexpr Real z = 0.0; +#endif + + // + // Fill Velocity + // + AMREX_D_TERM(vel(i,j,k,0) = IC.v_x*std::sin(IC.a*TwoPi*x) * std::cos(IC.b*TwoPi*y) * std::cos(IC.c*TwoPi*z);, + vel(i,j,k,1) = -IC.v_x*std::cos(IC.a*TwoPi*x) * std::sin(IC.b*TwoPi*y) * std::cos(IC.c*TwoPi*z);, + vel(i,j,k,2) = 0.0;); + + // + // Scalars, ordered as Density, Tracer(s) + // + scal(i,j,k,0) = IC.density; + + // The theoretical pressure perturbation from p_0 +#if ( AMREX_SPACEDIM == 2 ) + scal(i,j,k,1) = (IC.density*IC.v_x*IC.v_x/4.0)*(cos(2.0*IC.a*TwoPi*x)+cos(2.0*IC.b*TwoPi*y)); +#else + scal(i,j,k,1) = (IC.density*IC.v_x*IC.v_x/16.0)*(2.0+cos(2.0*IC.c*TwoPi*z))*(cos(2.0*IC.a*TwoPi*x)+cos(2.0*IC.b*TwoPi*y)); +#endif + + // Tracers + for ( int nt=2; nt const& press, + Array4 const& vel, + Array4 const& scal, + const int nscal, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& /*probhi*/, + InitialConditions IC) +{ + + const auto domlo = amrex::lbound(domain); + + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + // Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; + // Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; + // Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; + + // + // Fill Velocity + // + vel(i,j,k,0) = 0.0; + vel(i,j,k,1) = 0.0; + +#if (AMREX_SPACEDIM == 3) + vel(i,j,k,2) = 0.0; +#endif + + // + // Scalars, ordered as Density, Tracer(s), Temp (if using) + // + + // All Tracers are set here + for ( int nt=0; nt const& /*press*/, + Array4 const& vel, + Array4 const& scal, + const int nscal, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& /*probhi*/, + InitialConditions IC) +{ + const auto domlo = amrex::lbound(domain); + +#if (AMREX_SPACEDIM != 3) + amrex::Abort("NavierStokes::init_Euler: This is a 3D problem, please recompile with DIM=3 in makefile"); +#endif + + constexpr Real eps_input=0.05, rho_input=0.15; + constexpr Real beta_input=15.0, delta_input=0.0333; + constexpr Real kappa_input=500.0; + + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Real x = problo[0] + (i - domlo.x + 0.5)*dx[0] - 0.5; + Real y = problo[1] + (j - domlo.y + 0.5)*dx[1] - 0.5; + Real z = problo[2] + (k - domlo.z + 0.5)*dx[2] - 0.5; + + Real r_yz = std::sqrt(y*y+z*z); + + // + // Fill Velocity + // + vel(i,j,k,0) = tanh( (rho_input - r_yz) / delta_input); + vel(i,j,k,1) = 0.0; + vel(i,j,k,2) = eps_input * std::exp(-beta_input * (x*x + y*y) ); + + // + // Scalars, ordered as Density, Tracer(s) + // + scal(i,j,k,0) = IC.density; + scal(i,j,k,1) = std::exp( -kappa_input * (rho_input - r_yz)*(rho_input - r_yz) ); + + // Additional Tracer, if using + for ( int nt=2; nt const& /*press*/, + Array4 const& vel, + Array4 const& scal, + const int nscal, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& /*probhi*/, + InitialConditions IC) +{ + const auto domlo = amrex::lbound(domain); + + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + AMREX_D_TERM(Real x = problo[0] + (i - domlo.x + 0.5)*dx[0];, + Real y = problo[1] + (j - domlo.y + 0.5)*dx[1];, + /*Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]*/); + + amrex::Real deltax = x - IC.a; // x-distance from vortex center + amrex::Real deltay = y - IC.b; // y-distance form vortex center + amrex::Real d_sq = deltax*deltax + deltay*deltay; + amrex::Real r_sq = IC.c * IC.c; // square of vortex radius + amrex::Real u_vort = -IC.forcevort*deltay/r_sq * exp(-d_sq/r_sq/2.); + amrex::Real v_vort = IC.forcevort*deltax/r_sq * exp(-d_sq/r_sq/2.); +#if (AMREX_SPACEDIM == 3) + amrex::Real w_vort = 0.; +#endif + + // + // Fill Velocity + // + switch(IC.meanFlowDir) { + case 1 : + AMREX_D_TERM(vel(i,j,k,0) = IC.meanFlowMag + u_vort;, + vel(i,j,k,1) = v_vort;, + vel(i,j,k,2) = w_vort); + break; + case -1 : + AMREX_D_TERM(vel(i,j,k,0) = -IC.meanFlowMag + u_vort;, + vel(i,j,k,1) = v_vort;, + vel(i,j,k,2) = w_vort); + break; + case 2 : + AMREX_D_TERM(vel(i,j,k,0) = v_vort;, + vel(i,j,k,1) = IC.meanFlowMag + u_vort;, + vel(i,j,k,2) = w_vort); + break; + case -2 : + AMREX_D_TERM(vel(i,j,k,0) = v_vort;, + vel(i,j,k,1) = -IC.meanFlowMag + u_vort;, + vel(i,j,k,2) = w_vort); + break; + case 3 : + AMREX_D_TERM(vel(i,j,k,0) = IC.meanFlowMag + u_vort;, + vel(i,j,k,1) = IC.meanFlowMag + v_vort;, + vel(i,j,k,2) = w_vort); + break; + case -3 : + AMREX_D_TERM(vel(i,j,k,0) = -IC.meanFlowMag + u_vort;, + vel(i,j,k,1) = -IC.meanFlowMag + v_vort;, + vel(i,j,k,2) = w_vort); + break; + } + + // + // Scalars, ordered as Density, Tracer(s) + // + scal(i,j,k,0) = IC.density; + + // Additional Tracer, if using + for ( int nt=1; nt + # IAMR Regression Tests Regression tests for IAMR are managed using the regression testing diff --git a/Test_IAMReX/README.md b/Test_IAMReX/README.md index 3af638e8..167fa066 100644 --- a/Test_IAMReX/README.md +++ b/Test_IAMReX/README.md @@ -1,3 +1,9 @@ + + Test_IAMReX is a custom set of Python scripts designed to check the completeness of the code and verify the correctness of the results it produces. We provided some test cases, including lidDrivenCanvity, RSV, DraftingKissingTumbling, FlowPastCylinder, FlowPastSphere and RayleighTaylor. These tests cover various aspects and involve multiple modules. Additionally, you can follow the provided examples to create tests for yourself. Meanwhile, with the help of GitHub Actions, we have set up a CI pipeline to automatically run and validate these tests, ensuring continuous integration and testing of the codebase. diff --git a/Test_IAMReX/test_IAMReX.py b/Test_IAMReX/test_IAMReX.py index 94641584..bdaf5faf 100755 --- a/Test_IAMReX/test_IAMReX.py +++ b/Test_IAMReX/test_IAMReX.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2025 Shuai He +# +# SPDX-License-Identifier: BSD-3-Clause + import os import subprocess diff --git a/Tools/DIBM/DomainFill.F90 b/Tools/DIBM/DomainFill.F90 index 8e94e2b9..8191d0a6 100644 --- a/Tools/DIBM/DomainFill.F90 +++ b/Tools/DIBM/DomainFill.F90 @@ -1,3 +1,7 @@ +! SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & ZhuXu Li<1246206018@qq.com> +! +! SPDX-License-Identifier: BSD-3-Clause + PROGRAM SANDBED real*8,parameter:: Pi = 3.141592653589793238462643383279502884 ! how many particle diff --git a/Tools/plotfile/GNUmakefile b/Tools/plotfile/GNUmakefile index 3c9fd788..b1e82432 100644 --- a/Tools/plotfile/GNUmakefile +++ b/Tools/plotfile/GNUmakefile @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & ZhuXu Li<1246206018@qq.com> +# +# SPDX-License-Identifier: BSD-3-Clause + AMREX_HOME ?= ../../../amrex DEBUG = FALSE diff --git a/Tools/plotfile/fcompare_r.cpp b/Tools/plotfile/fcompare_r.cpp index 1ca8c930..f11070aa 100644 --- a/Tools/plotfile/fcompare_r.cpp +++ b/Tools/plotfile/fcompare_r.cpp @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & ZhuXu Li<1246206018@qq.com> +// +// SPDX-License-Identifier: BSD-3-Clause + #include #include #include diff --git a/Tools/plt_to_numpyArray/plt_to_numpyArray.py b/Tools/plt_to_numpyArray/plt_to_numpyArray.py index abfd6944..8405fe4a 100644 --- a/Tools/plt_to_numpyArray/plt_to_numpyArray.py +++ b/Tools/plt_to_numpyArray/plt_to_numpyArray.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng +# +# SPDX-License-Identifier: BSD-3-Clause + import os import numpy as np import yt diff --git a/Tools/plt_to_numpyArray/post_ml/utils/config.py b/Tools/plt_to_numpyArray/post_ml/utils/config.py index 6d05c570..8bfbee59 100644 --- a/Tools/plt_to_numpyArray/post_ml/utils/config.py +++ b/Tools/plt_to_numpyArray/post_ml/utils/config.py @@ -1,2 +1,6 @@ +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng +# +# SPDX-License-Identifier: BSD-3-Clause + simulations_path = '/Users/haorancheng/Desktop/data_etl/Data/' experiments_path = '/Users/haorancheng/Desktop/data_etl/Data/' diff --git a/Tools/plt_to_numpyArray/requirements.txt b/Tools/plt_to_numpyArray/requirements.txt index 6c94d912..b76fa66e 100644 --- a/Tools/plt_to_numpyArray/requirements.txt +++ b/Tools/plt_to_numpyArray/requirements.txt @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & ZhuXu Li<1246206018@qq.com> +# +# SPDX-License-Identifier: BSD-3-Clause + numpy>=1.23.0 yt>=4.0.1 matplotlib>=3.5.1 diff --git a/Tools/plt_to_numpyArray/run.sh b/Tools/plt_to_numpyArray/run.sh index 2426365e..aa4b5390 100644 --- a/Tools/plt_to_numpyArray/run.sh +++ b/Tools/plt_to_numpyArray/run.sh @@ -1,5 +1,9 @@ #!/bin/bash +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & ZhuXu Li<1246206018@qq.com> +# +# SPDX-License-Identifier: BSD-3-Clause + rm -rf output/* python3 plt_to_numpyArray.py -v experiment000019 y_velocity 3 yes diff --git a/Tutorials/BreakingWave_LS/GNUmakefile b/Tutorials/BreakingWave_LS/GNUmakefile index edccef1c..6552b280 100644 --- a/Tutorials/BreakingWave_LS/GNUmakefile +++ b/Tutorials/BreakingWave_LS/GNUmakefile @@ -1,30 +1,30 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 -COMP = gnu - -DEBUG = FALSE -USE_MPI = TRUE -USE_OMP = FALSE -PROFILE = FALSE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 +COMP = gnu + +DEBUG = FALSE +USE_MPI = TRUE +USE_OMP = FALSE +PROFILE = FALSE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/BreakingWave_LS/inputs.2d.breakingwave b/Tutorials/BreakingWave_LS/inputs.2d.breakingwave index 01747043..fba5a71a 100644 --- a/Tutorials/BreakingWave_LS/inputs.2d.breakingwave +++ b/Tutorials/BreakingWave_LS/inputs.2d.breakingwave @@ -1,161 +1,161 @@ - -#******************************************************************************* -# INPUTS.2D.BW -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 1000 # 10000 # 10 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 2.5 -ns.fixed_dt = 0.00008 - - -# Refinement criterion, use vorticity -amr.refinement_indicators = vorticity - -amr.vorticity.vorticity_greater = 0.1 -#amr.vorticity.start_time = 0.001 -#amr.vorticity.end_name = 0.002 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 256 256 -amr.max_grid_size = 32 - -amr.grid_eff = 0.95 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -nodal_proj.verbose = 1 -mac_proj.verbose = 1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 200 -#amr.restart = chk02000 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 200 -ns.sum_interval = 200 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 0.1 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.001 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = -9.81 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = -0.135 -0.135 - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 0.135 0.135 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 4 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 4 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -prob.probtype= 101 -#prob.rho_1 = 1000.0 -#prob.rho_2 = 1.25 - -#******************************************************************************* - -# Factor by which grids must be coarsenable. -amr.blocking_factor = 8 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort diveru avg_pressure - -#******************************************************************************* - -ns.do_mom_diff = 0 -ns.do_denminmax = 1 -ns.do_phi = 1 -ns.do_cons_phi = 1 -ns.do_reinit = 1 -ns.lev0step_of_reinit = 1 -ns.number_of_reinit = 4 -ns.reinit_sussman = 1 -ns.prescribed_vel = 0 - -# Re = 4.4 * 10^(5) -ns.mu_a = 0.00004 -ns.mu_w = 0.001 - -ns.rho_a = 1.25 -ns.rho_w = 1000.0 - -#ns.getForceVerbose = 1 + +#******************************************************************************* +# INPUTS.2D.BW +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 1000 # 10000 # 10 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 2.5 +ns.fixed_dt = 0.00008 + + +# Refinement criterion, use vorticity +amr.refinement_indicators = vorticity + +amr.vorticity.vorticity_greater = 0.1 +#amr.vorticity.start_time = 0.001 +#amr.vorticity.end_name = 0.002 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 256 256 +amr.max_grid_size = 32 + +amr.grid_eff = 0.95 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +nodal_proj.verbose = 1 +mac_proj.verbose = 1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 200 +#amr.restart = chk02000 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 200 +ns.sum_interval = 200 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 0.1 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.001 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = -9.81 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = -0.135 -0.135 + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 0.135 0.135 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 4 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 4 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +prob.probtype= 101 +#prob.rho_1 = 1000.0 +#prob.rho_2 = 1.25 + +#******************************************************************************* + +# Factor by which grids must be coarsenable. +amr.blocking_factor = 8 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort diveru avg_pressure + +#******************************************************************************* + +ns.do_mom_diff = 0 +ns.do_denminmax = 1 +ns.do_phi = 1 +ns.do_cons_phi = 1 +ns.do_reinit = 1 +ns.lev0step_of_reinit = 1 +ns.number_of_reinit = 4 +ns.reinit_sussman = 1 +ns.prescribed_vel = 0 + +# Re = 4.4 * 10^(5) +ns.mu_a = 0.00004 +ns.mu_w = 0.001 + +ns.rho_a = 1.25 +ns.rho_w = 1000.0 + +#ns.getForceVerbose = 1 diff --git a/Tutorials/Bubble/inputs.2d.bubble b/Tutorials/Bubble/inputs.2d.bubble index 7ab4adaa..0ba89f0d 100644 --- a/Tutorials/Bubble/inputs.2d.bubble +++ b/Tutorials/Bubble/inputs.2d.bubble @@ -1,150 +1,150 @@ - -#******************************************************************************* -# INPUTS.2D.BUBBLE -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 10 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 1.0 - -# Refinement criterion, use vorticity and presence of tracer -amr.refinement_indicators = tracer vorticity - -amr.tracer.value_greater = 0.1 -amr.tracer.field_name = tracer - -amr.vorticity.vorticity_greater = 1.0 -#amr.vorticity.start_time = 0.001 -#amr.vorticity.end_name = 0.002 - - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 64 -amr.max_grid_size = 16 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 # regrid_int - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = -1 -# amr.restart = chk00010 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 1 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 0.3 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.001 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.001 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = -9.8 - -#******************************************************************************* - -# skip level_projector -ns.skip_level_projector = 0 - -#******************************************************************************* - -# subcycling vs. non-subcycling -amr.subcycling_mode = Auto - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = -1. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 2. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 4 4 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 4 4 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 2 -prob.blob_center = 0.0 1.5 -prob.blob_radius = 0.2 -# Background density is 1. Density is increased by a factor of density_ic inside -# the bubble -prob.density_ic = 2.0 -# Can also set up a flow, defaults to zero -#prob.velocity_ic = 0. 0. 0. - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort diveru avg_pressure - -#******************************************************************************* + +#******************************************************************************* +# INPUTS.2D.BUBBLE +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 10 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 1.0 + +# Refinement criterion, use vorticity and presence of tracer +amr.refinement_indicators = tracer vorticity + +amr.tracer.value_greater = 0.1 +amr.tracer.field_name = tracer + +amr.vorticity.vorticity_greater = 1.0 +#amr.vorticity.start_time = 0.001 +#amr.vorticity.end_name = 0.002 + + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 64 +amr.max_grid_size = 16 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 # regrid_int + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = -1 +# amr.restart = chk00010 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 1 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 0.3 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.001 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.001 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = -9.8 + +#******************************************************************************* + +# skip level_projector +ns.skip_level_projector = 0 + +#******************************************************************************* + +# subcycling vs. non-subcycling +amr.subcycling_mode = Auto + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = -1. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 2. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 4 4 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 4 4 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 2 +prob.blob_center = 0.0 1.5 +prob.blob_radius = 0.2 +# Background density is 1. Density is increased by a factor of density_ic inside +# the bubble +prob.density_ic = 2.0 +# Can also set up a flow, defaults to zero +#prob.velocity_ic = 0. 0. 0. + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort diveru avg_pressure + +#******************************************************************************* diff --git a/Tutorials/Channel/GNUmakefile b/Tutorials/Channel/GNUmakefile index 9264b7fb..6a9d1ffe 100644 --- a/Tutorials/Channel/GNUmakefile +++ b/Tutorials/Channel/GNUmakefile @@ -1,31 +1,31 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 3 -COMP = gnu - -DEBUG = FALSE -USE_MPI = TRUE -USE_OMP = FALSE -PROFILE = FALSE - -USE_CUDA = FALSE -USE_HYPRE = TRUE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 3 +COMP = gnu + +DEBUG = FALSE +USE_MPI = TRUE +USE_OMP = FALSE +PROFILE = FALSE + +USE_CUDA = FALSE +USE_HYPRE = TRUE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/Channel/inputs.3d.channel b/Tutorials/Channel/inputs.3d.channel index 9591ae88..e12e8cf0 100644 --- a/Tutorials/Channel/inputs.3d.channel +++ b/Tutorials/Channel/inputs.3d.channel @@ -1,80 +1,80 @@ -#******************************************************************************* -# INPUTS.3D.CHANNEL -#******************************************************************************* - -max_step = 20 - -stop_time = -1 - -ns.stop_when_steady = 1 -ns.steady_tol = 1.0e-4 - -amr.n_cell = 96 96 144 - -amr.max_level = 0 - -# Refinement criterion, presence of tracer -amr.refinement_indicators = tracer -amr.tracer.value_greater = 0.1 -amr.tracer.field_name = tracer - -ns.v = 1 -amr.v = 1 - -amr.check_int = 1000 - -amr.plot_int = 1 - -ns.cfl = 0.5 # CFL number used to set dt - -ns.init_shrink = 0.3 # factor which multiplies the very first time step -ns.init_iter = 0 # number of initial iterations - -ns.vel_visc_coef = 0.00555 -ns.scal_diff_coefs = 0.0 - -geometry.coord_sys = 0 - -geometry.prob_lo = 0. 0. 0. -geometry.prob_hi = 9.42 1. 25.12 - -geometry.is_periodic = 1 0 1 - -ns.gravity = 1.0 - -ns.lo_bc = 0 5 0 -ns.hi_bc = 0 4 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# PROBLEM PARAMETERS -prob.probtype = 97 - -amr.derive_plot_vars = avg_pressure - -# hypre -nodal_proj.verbose = 1 -nodal_proj.proj_tol = 1.e-8 -nodal_proj.proj_abs_tol = 1.e-10 -nodal_proj.max_fmg_iter = 0 -nodal_proj.mg_max_coarsening_level = 0 -nodal_proj.bottom_solver = hypre -nodal_proj.agglomeration = 1 # Do agglomeration on AMR Level 0? -nodal_proj.consolidation = 1 # Do consolidation? - -mac_proj.verbose = 1 -mac_proj.bottom_solver = hypre -mac_proj.bottom_verbose = 2 -mac_proj.mg_max_coarsening_level = 0 # No. of GMG coarsening level before calling hypre -mac_proj.mac_tol = 1.e-8 -mac_proj.mac_abs_tol = 1.e-10 -mac_proj.max_fmg_iter = 0 # # of F-cycles before switching to V. To do pure V-cycle, set to 0 -mac_proj.agglomeration = 1 # Do agglomeration on AMR Level 0? -mac_proj.consolidation = 1 # Do consolidation? - -hypre.hypre_solver = BoomerAMG -hypre.adjust_singular_matrix = 1 - - +#******************************************************************************* +# INPUTS.3D.CHANNEL +#******************************************************************************* + +max_step = 20 + +stop_time = -1 + +ns.stop_when_steady = 1 +ns.steady_tol = 1.0e-4 + +amr.n_cell = 96 96 144 + +amr.max_level = 0 + +# Refinement criterion, presence of tracer +amr.refinement_indicators = tracer +amr.tracer.value_greater = 0.1 +amr.tracer.field_name = tracer + +ns.v = 1 +amr.v = 1 + +amr.check_int = 1000 + +amr.plot_int = 1 + +ns.cfl = 0.5 # CFL number used to set dt + +ns.init_shrink = 0.3 # factor which multiplies the very first time step +ns.init_iter = 0 # number of initial iterations + +ns.vel_visc_coef = 0.00555 +ns.scal_diff_coefs = 0.0 + +geometry.coord_sys = 0 + +geometry.prob_lo = 0. 0. 0. +geometry.prob_hi = 9.42 1. 25.12 + +geometry.is_periodic = 1 0 1 + +ns.gravity = 1.0 + +ns.lo_bc = 0 5 0 +ns.hi_bc = 0 4 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# PROBLEM PARAMETERS +prob.probtype = 97 + +amr.derive_plot_vars = avg_pressure + +# hypre +nodal_proj.verbose = 1 +nodal_proj.proj_tol = 1.e-8 +nodal_proj.proj_abs_tol = 1.e-10 +nodal_proj.max_fmg_iter = 0 +nodal_proj.mg_max_coarsening_level = 0 +nodal_proj.bottom_solver = hypre +nodal_proj.agglomeration = 1 # Do agglomeration on AMR Level 0? +nodal_proj.consolidation = 1 # Do consolidation? + +mac_proj.verbose = 1 +mac_proj.bottom_solver = hypre +mac_proj.bottom_verbose = 2 +mac_proj.mg_max_coarsening_level = 0 # No. of GMG coarsening level before calling hypre +mac_proj.mac_tol = 1.e-8 +mac_proj.mac_abs_tol = 1.e-10 +mac_proj.max_fmg_iter = 0 # # of F-cycles before switching to V. To do pure V-cycle, set to 0 +mac_proj.agglomeration = 1 # Do agglomeration on AMR Level 0? +mac_proj.consolidation = 1 # Do consolidation? + +hypre.hypre_solver = BoomerAMG +hypre.adjust_singular_matrix = 1 + + diff --git a/Tutorials/ConvectedVortex/GNUmakefile b/Tutorials/ConvectedVortex/GNUmakefile index ec7c9ade..b6cbd784 100644 --- a/Tutorials/ConvectedVortex/GNUmakefile +++ b/Tutorials/ConvectedVortex/GNUmakefile @@ -1,30 +1,30 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 -COMP = gnu - -DEBUG = FALSE -USE_MPI = FALSE -USE_OMP = FALSE -PROFILE = FALSE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 +COMP = gnu + +DEBUG = FALSE +USE_MPI = FALSE +USE_OMP = FALSE +PROFILE = FALSE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/ConvectedVortex/inputs.2d.convectedvortex b/Tutorials/ConvectedVortex/inputs.2d.convectedvortex index 06419c60..4efcdb39 100644 --- a/Tutorials/ConvectedVortex/inputs.2d.convectedvortex +++ b/Tutorials/ConvectedVortex/inputs.2d.convectedvortex @@ -1,138 +1,138 @@ - -#******************************************************************************* -# INPUTS -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. -#NOTE: this input file can be used in combination with the Util/multiRuns.py -#and Util/pprocConvOrder.py in order to compute the convergence order of the velocity -# advection schemes in IAMR. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 10000 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 0.04 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 64 64 -amr.max_grid_size = 1024 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 2 2 2 2 2 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -ns.sum_interval = 1 -ns.init_iter = 2 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = -5 -amr.check_file = chk - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 100 -amr.plot_file = plt - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.7 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 1.0 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0. - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0.0 0.0 0.0 - -# Physical dimensions of the high end of the domain. -#geometry.prob_hi = 6.28318530717959 6.28318530717959A -geometry.prob_hi = 1.0 1.0 1.0 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 8 -prob.rvort = 0.07 -prob.xvort = 0.5 -prob.yvort = 0.5 -prob.forcevort = 6.0 -prob.meanFlowDir = 1 -prob.meanFlowMag = 50.0 - -#******************************************************************************* - -# Factor by which grids must be coarsenable. -amr.blocking_factor = 8 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort - -#******************************************************************************* -nodal_proj.verbose=4 -nodal_proj.proj_tol = 1.e-10 -nodal_proj.sync_tol = 1.e-8 + +#******************************************************************************* +# INPUTS +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. +#NOTE: this input file can be used in combination with the Util/multiRuns.py +#and Util/pprocConvOrder.py in order to compute the convergence order of the velocity +# advection schemes in IAMR. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 10000 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 0.04 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 64 64 +amr.max_grid_size = 1024 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 2 2 2 2 2 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +ns.sum_interval = 1 +ns.init_iter = 2 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = -5 +amr.check_file = chk + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 100 +amr.plot_file = plt + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.7 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 1.0 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0. + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0.0 0.0 0.0 + +# Physical dimensions of the high end of the domain. +#geometry.prob_hi = 6.28318530717959 6.28318530717959A +geometry.prob_hi = 1.0 1.0 1.0 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 8 +prob.rvort = 0.07 +prob.xvort = 0.5 +prob.yvort = 0.5 +prob.forcevort = 6.0 +prob.meanFlowDir = 1 +prob.meanFlowMag = 50.0 + +#******************************************************************************* + +# Factor by which grids must be coarsenable. +amr.blocking_factor = 8 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort + +#******************************************************************************* +nodal_proj.verbose=4 +nodal_proj.proj_tol = 1.e-10 +nodal_proj.sync_tol = 1.e-8 diff --git a/Tutorials/ConvectedVortex/inputs.3d.convectedvortex b/Tutorials/ConvectedVortex/inputs.3d.convectedvortex index 8f7d1ca3..9e58083a 100644 --- a/Tutorials/ConvectedVortex/inputs.3d.convectedvortex +++ b/Tutorials/ConvectedVortex/inputs.3d.convectedvortex @@ -1,136 +1,136 @@ - -#******************************************************************************* -# inputs.3d.convectedVortex -# Convecting an isentropic vortex aligned in Z in a periodic 3D box -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 10000 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 0.04 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 64 16 -amr.max_grid_size = 1024 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 2 2 2 2 2 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -ns.sum_interval = 1 -ns.init_iter = 2 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = -5 -amr.check_file = chk - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 100 -amr.plot_file = plt - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.7 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 1.0 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0. - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0.0 0.0 0.0 - -# Physical dimensions of the high end of the domain. -#geometry.prob_hi = 6.28318530717959 6.28318530717959A -geometry.prob_hi = 1.0 1.0 0.25 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 8 -prob.rvort = 0.07 -prob.xvort = 0.5 -prob.yvort = 0.5 -prob.forcevort = 6.0 -prob.meanFlowDir = 1 -prob.meanFlowMag = 50.0 - -#******************************************************************************* - -# Factor by which grids must be coarsenable. -amr.blocking_factor = 8 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort - -#******************************************************************************* -nodal_proj.verbose = 4 -nodal_proj.proj_tol = 1.e-10 -nodal_proj.sync_tol = 1.e-8 + +#******************************************************************************* +# inputs.3d.convectedVortex +# Convecting an isentropic vortex aligned in Z in a periodic 3D box +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 10000 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 0.04 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 64 16 +amr.max_grid_size = 1024 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 2 2 2 2 2 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +ns.sum_interval = 1 +ns.init_iter = 2 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = -5 +amr.check_file = chk + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 100 +amr.plot_file = plt + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.7 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 1.0 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0. + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0.0 0.0 0.0 + +# Physical dimensions of the high end of the domain. +#geometry.prob_hi = 6.28318530717959 6.28318530717959A +geometry.prob_hi = 1.0 1.0 0.25 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 8 +prob.rvort = 0.07 +prob.xvort = 0.5 +prob.yvort = 0.5 +prob.forcevort = 6.0 +prob.meanFlowDir = 1 +prob.meanFlowMag = 50.0 + +#******************************************************************************* + +# Factor by which grids must be coarsenable. +amr.blocking_factor = 8 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort + +#******************************************************************************* +nodal_proj.verbose = 4 +nodal_proj.proj_tol = 1.e-10 +nodal_proj.sync_tol = 1.e-8 diff --git a/Tutorials/DoubleShearLayer/GNUmakefile b/Tutorials/DoubleShearLayer/GNUmakefile index 4bf6fd40..0b9c1e14 100644 --- a/Tutorials/DoubleShearLayer/GNUmakefile +++ b/Tutorials/DoubleShearLayer/GNUmakefile @@ -1,30 +1,30 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 -COMP = gnu - -DEBUG = FALSE -USE_MPI = FALSE -USE_OMP = TRUE -PROFILE = FALSE - -USE_EB = TRUE - -USE_VELOCITY = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 +COMP = gnu + +DEBUG = FALSE +USE_MPI = FALSE +USE_OMP = TRUE +PROFILE = FALSE + +USE_EB = TRUE + +USE_VELOCITY = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/DoubleShearLayer/inputs.2d.double_shear_layer-rotate b/Tutorials/DoubleShearLayer/inputs.2d.double_shear_layer-rotate index 44ead9a8..095dfb07 100644 --- a/Tutorials/DoubleShearLayer/inputs.2d.double_shear_layer-rotate +++ b/Tutorials/DoubleShearLayer/inputs.2d.double_shear_layer-rotate @@ -1,141 +1,141 @@ -#******************************************************************************* -# INPUTS.2D.PERIODIC_SHEAR_LAYER -#******************************************************************************* - -#******************************************************************************* -# WHEN SHOULD THE SIMULATION STOP? -#******************************************************************************* -# Maximum number of timesteps to be taken, if stop_time is not reached first. -max_step = 10 -# Time at which calculation stops, if max_step is not reached first. -stop_time = 2.0 -# Stop simulation when we reach steady-state? -ns.stop_when_steady = 0 -ns.steady_tol = 1.0e-5 - -#******************************************************************************* -# CFL -#******************************************************************************* - -ns.cfl = 0.5 # CFL number used to set dt -ns.init_shrink = 1.0 # factor which multiplies the very first time step -#ns.change_max = 1.1 # maximum change for dt - -# Turn off IAMR's initialization procedure to check initial conditions -#ns.init_iter = 0 # number of initial iterations -#ns.do_init_proj = 0 # do initial projection - -#******************************************************************************* -# FLUID PROPERTIES -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.0 #0.001 -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 0.0 -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* -# GRID AND GEOMETRY -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 64 -amr.max_grid_size = 64 - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 -# Physical dimensions of the low end of the domain. -geometry.prob_lo = -1.0 -1.0 -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1.0 1.0 -# Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 - -# Embedded Boundary options -#eb2.geom_type = all_regular # No EB -eb2.geom_type = sphere -eb2.sphere_radius = 0.25 -#eb2.sphere_center = 0.5 0.5 # don't forget prob.direction = 0 -eb2.sphere_center = -0.5 0.5 # don't forget prob.direction = 1 -eb2.sphere_has_fluid_inside = 0 - -#******************************************************************************* -# BOUNDARY CONDITIONS -#******************************************************************************* - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 - -#******************************************************************************* -# Problem parameters -#******************************************************************************* - -prob.probtype = 5 -# set up shear layer along y-direction -prob.direction = 1 -prob.blob_center = 0.0 0.0 -prob.blob_radius = 0.4 -prob.density_ic = 1.0 - -#******************************************************************************* -# AMR -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 -# Refinement criterion, presence of tracer -amr.refinement_indicators = tracer -amr.tracer.value_greater = 0.5 -amr.tracer.field_name = tracer -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 1 -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 -# Factor by which grids must be coarsenable. -amr.blocking_factor = 8 -# Grid efficiency (defaults to .70) -amr.grid_eff = 0.75 - -#******************************************************************************* -# PLOTTING AND CHECKPOINTS -#******************************************************************************* - -# Choose which quantities to write to plot file -amr.plot_vars = ALL -amr.derive_plot_vars = mag_vort - -# Interval (in number of coarse timesteps) between plot files -amr.plot_file = plt -amr.plot_int = 1 -#amr.plot_per = 0.2 - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_file = chk -amr.check_int = 10 -# Continue from checkpoint -# amr.restart = chk01000 - -#******************************************************************************* -# VERBOSITY -#******************************************************************************* - -amr.v = 1 # AMR (top-level) -ns.v = 1 # NavierStokes -diffuse.v = 0 # Diffusion -nodal_proj.verbose = 0 # Projection - -#******************************************************************************* -# PROJECTION SETTINGS -#******************************************************************************* - -# Usually default values work well -#nodal_proj.proj_tol = 1.e-12 -#nodal_proj.proj_abs_tol = 1.e-15 +#******************************************************************************* +# INPUTS.2D.PERIODIC_SHEAR_LAYER +#******************************************************************************* + +#******************************************************************************* +# WHEN SHOULD THE SIMULATION STOP? +#******************************************************************************* +# Maximum number of timesteps to be taken, if stop_time is not reached first. +max_step = 10 +# Time at which calculation stops, if max_step is not reached first. +stop_time = 2.0 +# Stop simulation when we reach steady-state? +ns.stop_when_steady = 0 +ns.steady_tol = 1.0e-5 + +#******************************************************************************* +# CFL +#******************************************************************************* + +ns.cfl = 0.5 # CFL number used to set dt +ns.init_shrink = 1.0 # factor which multiplies the very first time step +#ns.change_max = 1.1 # maximum change for dt + +# Turn off IAMR's initialization procedure to check initial conditions +#ns.init_iter = 0 # number of initial iterations +#ns.do_init_proj = 0 # do initial projection + +#******************************************************************************* +# FLUID PROPERTIES +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.0 #0.001 +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 0.0 +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* +# GRID AND GEOMETRY +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 64 +amr.max_grid_size = 64 + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 +# Physical dimensions of the low end of the domain. +geometry.prob_lo = -1.0 -1.0 +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1.0 1.0 +# Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 + +# Embedded Boundary options +#eb2.geom_type = all_regular # No EB +eb2.geom_type = sphere +eb2.sphere_radius = 0.25 +#eb2.sphere_center = 0.5 0.5 # don't forget prob.direction = 0 +eb2.sphere_center = -0.5 0.5 # don't forget prob.direction = 1 +eb2.sphere_has_fluid_inside = 0 + +#******************************************************************************* +# BOUNDARY CONDITIONS +#******************************************************************************* + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 + +#******************************************************************************* +# Problem parameters +#******************************************************************************* + +prob.probtype = 5 +# set up shear layer along y-direction +prob.direction = 1 +prob.blob_center = 0.0 0.0 +prob.blob_radius = 0.4 +prob.density_ic = 1.0 + +#******************************************************************************* +# AMR +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 +# Refinement criterion, presence of tracer +amr.refinement_indicators = tracer +amr.tracer.value_greater = 0.5 +amr.tracer.field_name = tracer +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 1 +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 +# Factor by which grids must be coarsenable. +amr.blocking_factor = 8 +# Grid efficiency (defaults to .70) +amr.grid_eff = 0.75 + +#******************************************************************************* +# PLOTTING AND CHECKPOINTS +#******************************************************************************* + +# Choose which quantities to write to plot file +amr.plot_vars = ALL +amr.derive_plot_vars = mag_vort + +# Interval (in number of coarse timesteps) between plot files +amr.plot_file = plt +amr.plot_int = 1 +#amr.plot_per = 0.2 + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_file = chk +amr.check_int = 10 +# Continue from checkpoint +# amr.restart = chk01000 + +#******************************************************************************* +# VERBOSITY +#******************************************************************************* + +amr.v = 1 # AMR (top-level) +ns.v = 1 # NavierStokes +diffuse.v = 0 # Diffusion +nodal_proj.verbose = 0 # Projection + +#******************************************************************************* +# PROJECTION SETTINGS +#******************************************************************************* + +# Usually default values work well +#nodal_proj.proj_tol = 1.e-12 +#nodal_proj.proj_abs_tol = 1.e-15 diff --git a/Tutorials/DraftingKissingTumbling/GNUmakefile b/Tutorials/DraftingKissingTumbling/GNUmakefile index eac06bfc..d1b5d4da 100644 --- a/Tutorials/DraftingKissingTumbling/GNUmakefile +++ b/Tutorials/DraftingKissingTumbling/GNUmakefile @@ -1,31 +1,31 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 3 -COMP = gnu - -DEBUG = TRUE -USE_MPI = TRUE -USE_OMP = FALSE -PROFILE = FALSE -USE_PARTICLES = TRUE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 3 +COMP = gnu + +DEBUG = TRUE +USE_MPI = TRUE +USE_OMP = FALSE +PROFILE = FALSE +USE_PARTICLES = TRUE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/DraftingKissingTumbling/inputs.3d.DKT b/Tutorials/DraftingKissingTumbling/inputs.3d.DKT index a8a26bc1..8a43cce3 100644 --- a/Tutorials/DraftingKissingTumbling/inputs.3d.DKT +++ b/Tutorials/DraftingKissingTumbling/inputs.3d.DKT @@ -1,212 +1,212 @@ - -#******************************************************************************* -# INPUTS.3D.DKT -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 3000 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 1.0 - -ns.fixed_dt = 0.0002 -ns.cfl = 0.3 -ns.init_iter = 0 - -# Diffused IB input file -particle.input = particle_inputs - -# Refinement criterion, use vorticity and presence of tracer -amr.refinement_indicators = tracer box - -amr.max_level = 1 # maximum number of levels of refinement - -amr.tracer.field_name = tracer -amr.tracer.value_greater = 0.001 - -amr.box.in_box_lo = 0.0033 0.0033 0.03 -amr.box.in_box_hi = 0.0072 0.0072 0.037 -amr.box.start_time = 0.0 -amr.box.end_time = 0.0001 - -amr.n_error_buf = 3 -amr.blocking_factor = 8 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -# amr.n_cell = 16 8 8 -# amr.n_cell = 288 128 128 -amr.n_cell = 48 48 192 #96 96 384 -amr.max_grid_size = 16 -# amr.max_grid_size = 32 - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 1 # regrid_int - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -nodal_proj.verbose = 1 -mac_proj.verbose = 1 - -# mac_proj.mac_tol = 0.1 -# mac_proj.mac_abs_tol = 0.1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files - -amr.check_int = 5000 - -#amr.restart = chk01400 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 500 - - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.001 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.00 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = -9.81 - -#******************************************************************************* - -# skip level_projector -ns.skip_level_projector = 0 - -#******************************************************************************* - -# subcycling vs. non-subcycling -amr.subcycling_mode = None - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. 0.0 - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 0.010020 0.010020 0.040080 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 5 5 5 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 5 5 5 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 104 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -# amr.derive_plot_vars = avg_pressure - -#******************************************************************************* -ns.isolver = 1 -ns.do_diffused_ib = 1 -ns.fluid_rho = 1000 - -#ns.sum_interval = 1 - -particles.do_nspc_particles = 0 - -nodal_proj.proj_tol = 1.e-8 -nodal_proj.proj_abs_tol = 1.e-9 - -mac_proj.mac_tol = 1.e-8 -mac_proj.mac_abs_tol = 1.e-9 - - -############################ -# # -# Diffused IB cfg file # -# # -############################ - -# particle's location -# x = p1x p2x p3x ... -particle_inputs.x = 0.0049599 0.0050601 -particle_inputs.y = 0.0049599 0.0050601 -particle_inputs.z = 0.0316632 0.03507 - -# particle's density -# rho = p1r p2r p3r ... -particle_inputs.rho = 1140 1140 - -# particle's radius -# single -particle_inputs.radius = 0.000835 0.000835 - -# particle's velocity -# vx = p1vx p2vx p3vx ... -particle_inputs.velocity_x = 0.0 0.0 -particle_inputs.velocity_y = 0.0 0.0 -particle_inputs.velocity_z = 0.0 0.0 - -# particles's omega -# ox = p1ox p2ox p3ox -particle_inputs.omega_x = 0.0 0.0 -particle_inputs.omega_y = 0.0 0.0 -particle_inputs.omega_z = 0.0 0.0 - -# particle's 6DOF -# TLX = p1tl p2tl ... -particle_inputs.TLX = 2 2 -particle_inputs.TLY = 2 2 -particle_inputs.TLZ = 2 2 -particle_inputs.RLX = 2 2 -particle_inputs.RLY = 2 2 -particle_inputs.RLZ = 2 2 - -# collision model -particle_inputs.collision_model = 1 - -# msg print -particle_inputs.verbose = 1 + +#******************************************************************************* +# INPUTS.3D.DKT +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 3000 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 1.0 + +ns.fixed_dt = 0.0002 +ns.cfl = 0.3 +ns.init_iter = 0 + +# Diffused IB input file +particle.input = particle_inputs + +# Refinement criterion, use vorticity and presence of tracer +amr.refinement_indicators = tracer box + +amr.max_level = 1 # maximum number of levels of refinement + +amr.tracer.field_name = tracer +amr.tracer.value_greater = 0.001 + +amr.box.in_box_lo = 0.0033 0.0033 0.03 +amr.box.in_box_hi = 0.0072 0.0072 0.037 +amr.box.start_time = 0.0 +amr.box.end_time = 0.0001 + +amr.n_error_buf = 3 +amr.blocking_factor = 8 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +# amr.n_cell = 16 8 8 +# amr.n_cell = 288 128 128 +amr.n_cell = 48 48 192 #96 96 384 +amr.max_grid_size = 16 +# amr.max_grid_size = 32 + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 1 # regrid_int + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +nodal_proj.verbose = 1 +mac_proj.verbose = 1 + +# mac_proj.mac_tol = 0.1 +# mac_proj.mac_abs_tol = 0.1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files + +amr.check_int = 5000 + +#amr.restart = chk01400 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 500 + + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.001 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.00 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = -9.81 + +#******************************************************************************* + +# skip level_projector +ns.skip_level_projector = 0 + +#******************************************************************************* + +# subcycling vs. non-subcycling +amr.subcycling_mode = None + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. 0.0 + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 0.010020 0.010020 0.040080 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 5 5 5 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 5 5 5 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 104 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +# amr.derive_plot_vars = avg_pressure + +#******************************************************************************* +ns.isolver = 1 +ns.do_diffused_ib = 1 +ns.fluid_rho = 1000 + +#ns.sum_interval = 1 + +particles.do_nspc_particles = 0 + +nodal_proj.proj_tol = 1.e-8 +nodal_proj.proj_abs_tol = 1.e-9 + +mac_proj.mac_tol = 1.e-8 +mac_proj.mac_abs_tol = 1.e-9 + + +############################ +# # +# Diffused IB cfg file # +# # +############################ + +# particle's location +# x = p1x p2x p3x ... +particle_inputs.x = 0.0049599 0.0050601 +particle_inputs.y = 0.0049599 0.0050601 +particle_inputs.z = 0.0316632 0.03507 + +# particle's density +# rho = p1r p2r p3r ... +particle_inputs.rho = 1140 1140 + +# particle's radius +# single +particle_inputs.radius = 0.000835 0.000835 + +# particle's velocity +# vx = p1vx p2vx p3vx ... +particle_inputs.velocity_x = 0.0 0.0 +particle_inputs.velocity_y = 0.0 0.0 +particle_inputs.velocity_z = 0.0 0.0 + +# particles's omega +# ox = p1ox p2ox p3ox +particle_inputs.omega_x = 0.0 0.0 +particle_inputs.omega_y = 0.0 0.0 +particle_inputs.omega_z = 0.0 0.0 + +# particle's 6DOF +# TLX = p1tl p2tl ... +particle_inputs.TLX = 2 2 +particle_inputs.TLY = 2 2 +particle_inputs.TLZ = 2 2 +particle_inputs.RLX = 2 2 +particle_inputs.RLY = 2 2 +particle_inputs.RLZ = 2 2 + +# collision model +particle_inputs.collision_model = 1 + +# msg print +particle_inputs.verbose = 1 diff --git a/Tutorials/FallingSphere/GNUmakefile b/Tutorials/FallingSphere/GNUmakefile index eac06bfc..d1b5d4da 100644 --- a/Tutorials/FallingSphere/GNUmakefile +++ b/Tutorials/FallingSphere/GNUmakefile @@ -1,31 +1,31 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 3 -COMP = gnu - -DEBUG = TRUE -USE_MPI = TRUE -USE_OMP = FALSE -PROFILE = FALSE -USE_PARTICLES = TRUE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 3 +COMP = gnu + +DEBUG = TRUE +USE_MPI = TRUE +USE_OMP = FALSE +PROFILE = FALSE +USE_PARTICLES = TRUE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/FallingSphere/inputs.3d.FallingSphere b/Tutorials/FallingSphere/inputs.3d.FallingSphere index aa158a92..de0fba52 100644 --- a/Tutorials/FallingSphere/inputs.3d.FallingSphere +++ b/Tutorials/FallingSphere/inputs.3d.FallingSphere @@ -1,214 +1,214 @@ - -#******************************************************************************* -# INPUTS.3D.FallingSphere -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 4000 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 10.0 - -ns.fixed_dt = 0.001 -ns.cfl = 0.3 -ns.init_iter = 0 - -# Diffused IB input file -particle.input = particle_inputs - -# Refinement criterion, use vorticity and presence of tracer -amr.refinement_indicators = tracer box - -amr.max_level = 1 # maximum number of levels of refinement - -amr.tracer.field_name = tracer -amr.tracer.value_greater = 0.001 - -amr.box.in_box_lo = 0.035 0.035 0.11 -amr.box.in_box_hi = 0.065 0.065 0.14 -amr.box.start_time = 0.0 -amr.box.end_time = 0.01 - -amr.n_error_buf = 3 -amr.blocking_factor = 8 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -# amr.n_cell = 16 8 8 -# amr.n_cell = 288 128 128 -amr.n_cell = 64 64 128 -amr.max_grid_size = 16 -# amr.max_grid_size = 32 - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 1 # regrid_int - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -nodal_proj.verbose = 1 -mac_proj.verbose = 1 - -# mac_proj.mac_tol = 0.1 -# mac_proj.mac_abs_tol = 0.1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files - -amr.check_int = 100 - -#amr.restart = chk01400 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 1 - - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.372965 -# this parameter is dunamic viscosity -# Re1.5 fluid rho : 970 u 0.372965 -# Re4.1 fluid rho : 965 u 0.2120105 -# Re11.6 fluid rho : 962 u 0.113035 -# Re32.2 fluid rho : 960 u 0.0580032 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.00 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = -9.81 - -#******************************************************************************* - -# skip level_projector -ns.skip_level_projector = 0 - -#******************************************************************************* - -# subcycling vs. non-subcycling -amr.subcycling_mode = None - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 0.1 0.1 0.2 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 5 5 5 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 5 5 4 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 104 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -# amr.derive_plot_vars = avg_pressure - -#******************************************************************************* -ns.isolver = 1 -ns.do_diffused_ib = 1 -ns.fluid_rho = 970 - -#ns.sum_interval = 1 - -particles.do_nspc_particles = 0 - -nodal_proj.proj_tol = 1.e-8 -nodal_proj.proj_abs_tol = 1.e-9 - -mac_proj.mac_tol = 1.e-8 -mac_proj.mac_abs_tol = 1.e-9 - - -############################ -# # -# Diffused IB cfg file # -# # -############################ - -# particle's location -# x = p1x p2x p3x ... -particle_inputs.x = 0.05 -particle_inputs.y = 0.05 -particle_inputs.z = 0.125 - -# particle's density -# rho = p1r p2r p3r ... -particle_inputs.rho = 1120 - -# particle's radius -# single -particle_inputs.radius = 0.0075 - -# particle's velocity -# vx = p1vx p2vx p3vx ... -particle_inputs.velocity_x = 0.0 -particle_inputs.velocity_y = 0.0 -particle_inputs.velocity_z = 0.0 - -# particles's omega -# ox = p1ox p2ox p3ox -particle_inputs.omega_x = 0.0 -particle_inputs.omega_y = 0.0 -particle_inputs.omega_z = 0.0 - -# particle's 6DOF -# TLX = p1tl p2tl ... -particle_inputs.TLX = 2 -particle_inputs.TLY = 2 -particle_inputs.TLZ = 2 -particle_inputs.RLX = 2 -particle_inputs.RLY = 2 -particle_inputs.RLZ = 2 - -# msg print -particle_inputs.verbose = 1 + +#******************************************************************************* +# INPUTS.3D.FallingSphere +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 4000 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 10.0 + +ns.fixed_dt = 0.001 +ns.cfl = 0.3 +ns.init_iter = 0 + +# Diffused IB input file +particle.input = particle_inputs + +# Refinement criterion, use vorticity and presence of tracer +amr.refinement_indicators = tracer box + +amr.max_level = 1 # maximum number of levels of refinement + +amr.tracer.field_name = tracer +amr.tracer.value_greater = 0.001 + +amr.box.in_box_lo = 0.035 0.035 0.11 +amr.box.in_box_hi = 0.065 0.065 0.14 +amr.box.start_time = 0.0 +amr.box.end_time = 0.01 + +amr.n_error_buf = 3 +amr.blocking_factor = 8 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +# amr.n_cell = 16 8 8 +# amr.n_cell = 288 128 128 +amr.n_cell = 64 64 128 +amr.max_grid_size = 16 +# amr.max_grid_size = 32 + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 1 # regrid_int + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +nodal_proj.verbose = 1 +mac_proj.verbose = 1 + +# mac_proj.mac_tol = 0.1 +# mac_proj.mac_abs_tol = 0.1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files + +amr.check_int = 100 + +#amr.restart = chk01400 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 1 + + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.372965 +# this parameter is dunamic viscosity +# Re1.5 fluid rho : 970 u 0.372965 +# Re4.1 fluid rho : 965 u 0.2120105 +# Re11.6 fluid rho : 962 u 0.113035 +# Re32.2 fluid rho : 960 u 0.0580032 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.00 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = -9.81 + +#******************************************************************************* + +# skip level_projector +ns.skip_level_projector = 0 + +#******************************************************************************* + +# subcycling vs. non-subcycling +amr.subcycling_mode = None + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 0.1 0.1 0.2 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 5 5 5 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 5 5 4 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 104 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +# amr.derive_plot_vars = avg_pressure + +#******************************************************************************* +ns.isolver = 1 +ns.do_diffused_ib = 1 +ns.fluid_rho = 970 + +#ns.sum_interval = 1 + +particles.do_nspc_particles = 0 + +nodal_proj.proj_tol = 1.e-8 +nodal_proj.proj_abs_tol = 1.e-9 + +mac_proj.mac_tol = 1.e-8 +mac_proj.mac_abs_tol = 1.e-9 + + +############################ +# # +# Diffused IB cfg file # +# # +############################ + +# particle's location +# x = p1x p2x p3x ... +particle_inputs.x = 0.05 +particle_inputs.y = 0.05 +particle_inputs.z = 0.125 + +# particle's density +# rho = p1r p2r p3r ... +particle_inputs.rho = 1120 + +# particle's radius +# single +particle_inputs.radius = 0.0075 + +# particle's velocity +# vx = p1vx p2vx p3vx ... +particle_inputs.velocity_x = 0.0 +particle_inputs.velocity_y = 0.0 +particle_inputs.velocity_z = 0.0 + +# particles's omega +# ox = p1ox p2ox p3ox +particle_inputs.omega_x = 0.0 +particle_inputs.omega_y = 0.0 +particle_inputs.omega_z = 0.0 + +# particle's 6DOF +# TLX = p1tl p2tl ... +particle_inputs.TLX = 2 +particle_inputs.TLY = 2 +particle_inputs.TLZ = 2 +particle_inputs.RLX = 2 +particle_inputs.RLY = 2 +particle_inputs.RLZ = 2 + +# msg print +particle_inputs.verbose = 1 diff --git a/Tutorials/FallingSphere/inputs.3d.FallingSphereUhlmann b/Tutorials/FallingSphere/inputs.3d.FallingSphereUhlmann index a5fc59d8..7a9888af 100644 --- a/Tutorials/FallingSphere/inputs.3d.FallingSphereUhlmann +++ b/Tutorials/FallingSphere/inputs.3d.FallingSphereUhlmann @@ -1,216 +1,216 @@ - -#******************************************************************************* -# INPUTS.3D.FallingSphere -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 2000 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 10.0 - -ns.fixed_dt = 0.002 -ns.cfl = 0.3 -ns.init_iter = 0 - -# Diffused IB input file -particle.input = particle_inputs - -# Refinement criterion, use vorticity and presence of tracer -amr.refinement_indicators = tracer box - -amr.max_level = 1 # maximum number of levels of refinement - -amr.tracer.field_name = tracer -amr.tracer.value_greater = 0.001 - -amr.box.in_box_lo = 0.38 0.38 9.1 -amr.box.in_box_hi = 0.58 0.58 9.3 -amr.box.start_time = 0.0 -amr.box.end_time = 0.01 - -amr.n_error_buf = 4 -amr.blocking_factor = 8 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -# amr.n_cell = 16 8 8 -# amr.n_cell = 288 128 128 -amr.n_cell = 48 48 480 -amr.max_grid_size = 16 -# amr.max_grid_size = 32 - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 1 # regrid_int - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -nodal_proj.verbose = 1 -mac_proj.verbose = 1 - -# mac_proj.mac_tol = 0.1 -# mac_proj.mac_abs_tol = 0.1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files - -amr.check_int = 1000 - -#amr.restart = chk01400 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 200 - - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.005416368 -# this parameter is dunamic viscosity -# rho_ratio 2.56 u=0.00541638 -# rho_ratio 2.56 u=0.00104238 -# rho_ratio 7.71 u=0.00267626 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.00 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = -9.81 - -#******************************************************************************* - -# skip level_projector -ns.skip_level_projector = 0 - -#******************************************************************************* - -# subcycling vs. non-subcycling -amr.subcycling_mode = None - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 0.96 0.96 9.6 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 5 5 5 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 5 5 4 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 104 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -# amr.derive_plot_vars = avg_pressure - -#******************************************************************************* -ns.isolver = 1 -ns.do_diffused_ib = 1 -ns.fluid_rho = 1 - -#ns.sum_interval = 1 - -particles.do_nspc_particles = 0 - -nodal_proj.proj_tol = 1.e-8 -nodal_proj.proj_abs_tol = 1.e-9 - -mac_proj.mac_tol = 1.e-8 -mac_proj.mac_abs_tol = 1.e-9 - - -############################ -# # -# Diffused IB cfg file # -# # -############################ - -# particle's location -# x = p1x p2x p3x ... -particle_inputs.x = 0.48 -particle_inputs.y = 0.48 -particle_inputs.z = 9.2 - -# particle's density -# rho = p1r p2r p3r ... -particle_inputs.rho = 2.56 - -# particle's radius -# single -particle_inputs.radius = 0.08333 - -# particle's velocity -# vx = p1vx p2vx p3vx ... -particle_inputs.velocity_x = 0.0 -particle_inputs.velocity_y = 0.0 -particle_inputs.velocity_z = 0.0 - -# particles's omega -# ox = p1ox p2ox p3ox -particle_inputs.omega_x = 0.0 -particle_inputs.omega_y = 0.0 -particle_inputs.omega_z = 0.0 - -# particle's 6DOF -# TLX = p1tl p2tl ... -particle_inputs.TLX = 2 -particle_inputs.TLY = 2 -particle_inputs.TLZ = 2 -particle_inputs.RLX = 2 -particle_inputs.RLY = 2 -particle_inputs.RLZ = 2 - -# Uhlmann FallingSphere -particle_inputs.Uhlmann = 1 - -# msg print -particle_inputs.verbose = 1 + +#******************************************************************************* +# INPUTS.3D.FallingSphere +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 2000 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 10.0 + +ns.fixed_dt = 0.002 +ns.cfl = 0.3 +ns.init_iter = 0 + +# Diffused IB input file +particle.input = particle_inputs + +# Refinement criterion, use vorticity and presence of tracer +amr.refinement_indicators = tracer box + +amr.max_level = 1 # maximum number of levels of refinement + +amr.tracer.field_name = tracer +amr.tracer.value_greater = 0.001 + +amr.box.in_box_lo = 0.38 0.38 9.1 +amr.box.in_box_hi = 0.58 0.58 9.3 +amr.box.start_time = 0.0 +amr.box.end_time = 0.01 + +amr.n_error_buf = 4 +amr.blocking_factor = 8 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +# amr.n_cell = 16 8 8 +# amr.n_cell = 288 128 128 +amr.n_cell = 48 48 480 +amr.max_grid_size = 16 +# amr.max_grid_size = 32 + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 1 # regrid_int + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +nodal_proj.verbose = 1 +mac_proj.verbose = 1 + +# mac_proj.mac_tol = 0.1 +# mac_proj.mac_abs_tol = 0.1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files + +amr.check_int = 1000 + +#amr.restart = chk01400 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 200 + + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.005416368 +# this parameter is dunamic viscosity +# rho_ratio 2.56 u=0.00541638 +# rho_ratio 2.56 u=0.00104238 +# rho_ratio 7.71 u=0.00267626 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.00 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = -9.81 + +#******************************************************************************* + +# skip level_projector +ns.skip_level_projector = 0 + +#******************************************************************************* + +# subcycling vs. non-subcycling +amr.subcycling_mode = None + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 0.96 0.96 9.6 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 5 5 5 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 5 5 4 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 104 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +# amr.derive_plot_vars = avg_pressure + +#******************************************************************************* +ns.isolver = 1 +ns.do_diffused_ib = 1 +ns.fluid_rho = 1 + +#ns.sum_interval = 1 + +particles.do_nspc_particles = 0 + +nodal_proj.proj_tol = 1.e-8 +nodal_proj.proj_abs_tol = 1.e-9 + +mac_proj.mac_tol = 1.e-8 +mac_proj.mac_abs_tol = 1.e-9 + + +############################ +# # +# Diffused IB cfg file # +# # +############################ + +# particle's location +# x = p1x p2x p3x ... +particle_inputs.x = 0.48 +particle_inputs.y = 0.48 +particle_inputs.z = 9.2 + +# particle's density +# rho = p1r p2r p3r ... +particle_inputs.rho = 2.56 + +# particle's radius +# single +particle_inputs.radius = 0.08333 + +# particle's velocity +# vx = p1vx p2vx p3vx ... +particle_inputs.velocity_x = 0.0 +particle_inputs.velocity_y = 0.0 +particle_inputs.velocity_z = 0.0 + +# particles's omega +# ox = p1ox p2ox p3ox +particle_inputs.omega_x = 0.0 +particle_inputs.omega_y = 0.0 +particle_inputs.omega_z = 0.0 + +# particle's 6DOF +# TLX = p1tl p2tl ... +particle_inputs.TLX = 2 +particle_inputs.TLY = 2 +particle_inputs.TLZ = 2 +particle_inputs.RLX = 2 +particle_inputs.RLY = 2 +particle_inputs.RLZ = 2 + +# Uhlmann FallingSphere +particle_inputs.Uhlmann = 1 + +# msg print +particle_inputs.verbose = 1 diff --git a/Tutorials/FlowPastCylinder/GNUmakefile b/Tutorials/FlowPastCylinder/GNUmakefile index 5c918e67..2030df4d 100644 --- a/Tutorials/FlowPastCylinder/GNUmakefile +++ b/Tutorials/FlowPastCylinder/GNUmakefile @@ -1,32 +1,32 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -# running 2d inputs files requires a 2d executable set here -DIM = 3 -COMP = gnu - -DEBUG = FALSE -USE_MPI = TRUE -USE_OMP = FALSE -PROFILE = FALSE - - -USE_VELOCITY = FALSE - -USE_EB = TRUE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +# running 2d inputs files requires a 2d executable set here +DIM = 3 +COMP = gnu + +DEBUG = FALSE +USE_MPI = TRUE +USE_OMP = FALSE +PROFILE = FALSE + + +USE_VELOCITY = FALSE + +USE_EB = TRUE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/FlowPastCylinder/inputs.2d.flow_past_cylinder-x b/Tutorials/FlowPastCylinder/inputs.2d.flow_past_cylinder-x index 2d4e872e..beba1992 100644 --- a/Tutorials/FlowPastCylinder/inputs.2d.flow_past_cylinder-x +++ b/Tutorials/FlowPastCylinder/inputs.2d.flow_past_cylinder-x @@ -1,93 +1,93 @@ -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SIMULATION STOP # -#.......................................# -stop_time = 0.02 # Max (simulated) time to evolve -max_step = -1 # Max number of time steps - -ns.stop_when_steady = 0 # Steady-state solver? -ns.steady_tol = 1.e-8 - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SOLVER SETTINGS # -#.......................................# -ns.init_shrink = 1.0 # Multiply initial dt by this factor - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# TIME STEP COMPUTATION # -#.......................................# -ns.fixed_dt = -1.0 # If fixed_dt > 0, use this constant dt -ns.cfl = 0.45 # CFL factor - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# INPUT AND OUTPUT # -#.......................................# -amr.plot_int = 20 # Steps between plot files -amr.plot_per = 0.1 # Steps between plot files -amr.check_int = 1000 # Steps between checkpoint files -amr.derive_plot_vars = mag_vort avg_pressure # Derived quantities to include in plotfiles - -amr.restart = "" # Checkpoint to restart from - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PHYSICS # -#.......................................# -ns.gravity = 0. - -ns.vel_visc_coef = 0.00001 -ns.scal_diff_coefs = 1.0 - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# ADAPTIVE MESH REFINEMENT # -#.......................................# -amr.n_cell = 64 64 16 # Grid cells at coarsest AMRlevel -amr.max_level = 1 # Max AMR level in hierarchy - -# Refinement criterion, use vorticity -amr.refinement_indicators = vorticity -amr.vorticity.vorticity_greater = 1.0 - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# GEOMETRY # -#.......................................# -geometry.prob_lo = -0.04 -0.04 -0.005 # Lo corner coordinates -geometry.prob_hi = 0.04 0.04 0.005 # Hi corner coordinates -geometry.is_periodic = 0 1 1 # Periodicity x y z (0/1) -geometry.coord_sys = 0 # 0 for Cartesian, 1 for RZ - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWal -# Boundary conditions on the low end of the domain. -ns.lo_bc = 1 0 0 -# Boundary conditions on the high end of the domain. -ns.hi_bc = 2 0 0 - -# inflow velocity -xlo.velocity = 1. 0. 0. - -# Add cylinder -#eb2.geom_type = all_regular # for no EB -eb2.geom_type = sphere -eb2.sphere_radius = 0.0021 -eb2.sphere_center = -0.025 0.0 -eb2.sphere_has_fluid_inside=0 - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PROBLEM PARAMETERS # -#.......................................# -prob.probtype = 4 -prob.blob_center = -0.55 0.05 0.5 -prob.blob_radius = 0.04 -# Constant density initial condition -prob.density_ic = 1.0 -# Set up a flow, defaults to zero -prob.velocity_ic = 1. 0. 0. - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# VERBOSITY # -#.......................................# -ns.v = 1 # NS solver -nodal_proj.verbose = 0 # Nodal projection -mac_proj.verbose = 0 # MacProjector -diffuse.v = 0 # Diffusion solver - +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SIMULATION STOP # +#.......................................# +stop_time = 0.02 # Max (simulated) time to evolve +max_step = -1 # Max number of time steps + +ns.stop_when_steady = 0 # Steady-state solver? +ns.steady_tol = 1.e-8 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SOLVER SETTINGS # +#.......................................# +ns.init_shrink = 1.0 # Multiply initial dt by this factor + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# TIME STEP COMPUTATION # +#.......................................# +ns.fixed_dt = -1.0 # If fixed_dt > 0, use this constant dt +ns.cfl = 0.45 # CFL factor + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# INPUT AND OUTPUT # +#.......................................# +amr.plot_int = 20 # Steps between plot files +amr.plot_per = 0.1 # Steps between plot files +amr.check_int = 1000 # Steps between checkpoint files +amr.derive_plot_vars = mag_vort avg_pressure # Derived quantities to include in plotfiles + +amr.restart = "" # Checkpoint to restart from + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PHYSICS # +#.......................................# +ns.gravity = 0. + +ns.vel_visc_coef = 0.00001 +ns.scal_diff_coefs = 1.0 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# ADAPTIVE MESH REFINEMENT # +#.......................................# +amr.n_cell = 64 64 16 # Grid cells at coarsest AMRlevel +amr.max_level = 1 # Max AMR level in hierarchy + +# Refinement criterion, use vorticity +amr.refinement_indicators = vorticity +amr.vorticity.vorticity_greater = 1.0 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# GEOMETRY # +#.......................................# +geometry.prob_lo = -0.04 -0.04 -0.005 # Lo corner coordinates +geometry.prob_hi = 0.04 0.04 0.005 # Hi corner coordinates +geometry.is_periodic = 0 1 1 # Periodicity x y z (0/1) +geometry.coord_sys = 0 # 0 for Cartesian, 1 for RZ + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWal +# Boundary conditions on the low end of the domain. +ns.lo_bc = 1 0 0 +# Boundary conditions on the high end of the domain. +ns.hi_bc = 2 0 0 + +# inflow velocity +xlo.velocity = 1. 0. 0. + +# Add cylinder +#eb2.geom_type = all_regular # for no EB +eb2.geom_type = sphere +eb2.sphere_radius = 0.0021 +eb2.sphere_center = -0.025 0.0 +eb2.sphere_has_fluid_inside=0 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PROBLEM PARAMETERS # +#.......................................# +prob.probtype = 4 +prob.blob_center = -0.55 0.05 0.5 +prob.blob_radius = 0.04 +# Constant density initial condition +prob.density_ic = 1.0 +# Set up a flow, defaults to zero +prob.velocity_ic = 1. 0. 0. + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# VERBOSITY # +#.......................................# +ns.v = 1 # NS solver +nodal_proj.verbose = 0 # Nodal projection +mac_proj.verbose = 0 # MacProjector +diffuse.v = 0 # Diffusion solver + diff --git a/Tutorials/FlowPastCylinder/inputs.3d.flow_past_cylinder-x b/Tutorials/FlowPastCylinder/inputs.3d.flow_past_cylinder-x index 14ec59e6..326b2d66 100644 --- a/Tutorials/FlowPastCylinder/inputs.3d.flow_past_cylinder-x +++ b/Tutorials/FlowPastCylinder/inputs.3d.flow_past_cylinder-x @@ -1,78 +1,78 @@ -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SIMULATION STOP # -#.......................................# -stop_time = 0.2 # Max (simulated) time to evolve -max_step = -1 # Max number of time steps -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SOLVER SETTINGS # -#.......................................# -ns.init_iter = 3 # How many initial pressure iterations -ns.init_vel_iter = 5 # How many initial projeciton iterations to ensure velocity satisfies divergence constraint -ns.visc_tol = 1.0e-11 # tolerance for viscous solve -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# TIME STEP COMPUTATION # -#.......................................# -ns.cfl = 0.45 -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# INPUT AND OUTPUT # -#.......................................# -amr.plot_int = 20 # Steps between plot files -amr.plot_per = 0.1 # Steps between plot files -amr.check_int = 1000 # Steps between checkpoint files -amr.restart = "" # Checkpoint to restart from -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PHYSICS # -#.......................................# -ns.gravity = 0. -ns.vel_visc_coef = 0.001 -ns.scal_diff_coefs = 1.0 -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# ADAPTIVE MESH REFINEMENT # -#.......................................# -amr.n_cell = 96 32 8 # Grid cells at coarsest AMRlevel -amr.max_level = 1 # Max AMR level in hierarchy -# Refinement around the EB by default -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# GEOMETRY # -#.......................................# -geometry.prob_lo = 0. 0. 0. # Lo corner coordinates -geometry.prob_hi = 1.2 0.4 0.1 # Hi corner coordinates -geometry.is_periodic = 0 0 1 # Periodicity x y z (0/1) - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWal -# Boundary conditions on the low end of the domain. -ns.lo_bc = 1 5 0 -# Boundary conditions on the high end of the domain. -ns.hi_bc = 2 5 0 - -xlo.velocity = 1. 0. 0. - -# Add cylinder -eb2.geom_type = cylinder -eb2.cylinder_has_fluid_inside = 0 -eb2.cylinder_radius = 0.05 -eb2.cylinder_direction = 2 -eb2.cylinder_center = 0.15 0.2 0.0 - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PROBLEM PARAMETERS # -#.......................................# - -prob.probtype = 4 -prob.blob_center = -0.55 0.05 0.0 -prob.blob_radius = 0.04 -# Constant density initial condition -prob.density_ic = 1.0 -# Set up a flow, defaults to zero -prob.velocity_ic = 1. 0. 0. - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# VERBOSITY # -#.......................................# -ns.v = 1 # NS solver -nodal_proj.verbose = 0 # Nodal projection -mac_proj.verbose = 0 # MacProjector -diffuse.v = 0 # Diffusion operator - +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SIMULATION STOP # +#.......................................# +stop_time = 0.2 # Max (simulated) time to evolve +max_step = -1 # Max number of time steps +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SOLVER SETTINGS # +#.......................................# +ns.init_iter = 3 # How many initial pressure iterations +ns.init_vel_iter = 5 # How many initial projeciton iterations to ensure velocity satisfies divergence constraint +ns.visc_tol = 1.0e-11 # tolerance for viscous solve +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# TIME STEP COMPUTATION # +#.......................................# +ns.cfl = 0.45 +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# INPUT AND OUTPUT # +#.......................................# +amr.plot_int = 20 # Steps between plot files +amr.plot_per = 0.1 # Steps between plot files +amr.check_int = 1000 # Steps between checkpoint files +amr.restart = "" # Checkpoint to restart from +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PHYSICS # +#.......................................# +ns.gravity = 0. +ns.vel_visc_coef = 0.001 +ns.scal_diff_coefs = 1.0 +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# ADAPTIVE MESH REFINEMENT # +#.......................................# +amr.n_cell = 96 32 8 # Grid cells at coarsest AMRlevel +amr.max_level = 1 # Max AMR level in hierarchy +# Refinement around the EB by default +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# GEOMETRY # +#.......................................# +geometry.prob_lo = 0. 0. 0. # Lo corner coordinates +geometry.prob_hi = 1.2 0.4 0.1 # Hi corner coordinates +geometry.is_periodic = 0 0 1 # Periodicity x y z (0/1) + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWal +# Boundary conditions on the low end of the domain. +ns.lo_bc = 1 5 0 +# Boundary conditions on the high end of the domain. +ns.hi_bc = 2 5 0 + +xlo.velocity = 1. 0. 0. + +# Add cylinder +eb2.geom_type = cylinder +eb2.cylinder_has_fluid_inside = 0 +eb2.cylinder_radius = 0.05 +eb2.cylinder_direction = 2 +eb2.cylinder_center = 0.15 0.2 0.0 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PROBLEM PARAMETERS # +#.......................................# + +prob.probtype = 4 +prob.blob_center = -0.55 0.05 0.0 +prob.blob_radius = 0.04 +# Constant density initial condition +prob.density_ic = 1.0 +# Set up a flow, defaults to zero +prob.velocity_ic = 1. 0. 0. + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# VERBOSITY # +#.......................................# +ns.v = 1 # NS solver +nodal_proj.verbose = 0 # Nodal projection +mac_proj.verbose = 0 # MacProjector +diffuse.v = 0 # Diffusion operator + diff --git a/Tutorials/FlowPastCylinder/inputs.3d.flow_past_cylinder-y b/Tutorials/FlowPastCylinder/inputs.3d.flow_past_cylinder-y index 8a254275..856615e0 100644 --- a/Tutorials/FlowPastCylinder/inputs.3d.flow_past_cylinder-y +++ b/Tutorials/FlowPastCylinder/inputs.3d.flow_past_cylinder-y @@ -1,78 +1,78 @@ -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SIMULATION STOP # -#.......................................# -stop_time = 0.2 # Max (simulated) time to evolve -max_step = -1 # Max number of time steps -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SOLVER SETTINGS # -#.......................................# -ns.init_iter = 3 # How many initial pressure iterations -ns.init_vel_iter = 5 # How many initial projeciton iterations to ensure velocity satisfies divergence constraint -ns.visc_tol = 1.0e-11 # tolerance for viscous solve -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# TIME STEP COMPUTATION # -#.......................................# -ns.cfl = 0.45 -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# INPUT AND OUTPUT # -#.......................................# -amr.plot_int = 20 # Steps between plot files -amr.plot_per = 0.1 # Steps between plot files -amr.check_int = 1000 # Steps between checkpoint files -amr.restart = "" # Checkpoint to restart from -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PHYSICS # -#.......................................# -ns.gravity = 0. -ns.vel_visc_coef = 0.001 -ns.scal_diff_coefs = 1.0 -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# ADAPTIVE MESH REFINEMENT # -#.......................................# -amr.n_cell = 8 96 32 # Grid cells at coarsest AMRlevel -amr.max_level = 0 # Max AMR level in hierarchy - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# GEOMETRY # -#.......................................# -geometry.prob_lo = 0. 0. 0. # Lo corner coordinates -geometry.prob_hi = 0.1 1.2 0.4 # Hi corner coordinates -geometry.is_periodic = 1 0 0 # Periodicity x y z (0/1) - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWal -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 1 5 -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 2 5 - -ylo.velocity = 0. 1. 0. - -# Add cylinder -eb2.geom_type = cylinder -eb2.cylinder_has_fluid_inside = 0 -eb2.cylinder_radius = 0.05 -eb2.cylinder_direction = 0 -eb2.cylinder_center = 0.0 0.15 0.2 - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PROBLEM PARAMETERS # -#.......................................# - -prob.probtype = 4 -prob.blob_center = 0.0 -0.55 0.05 -prob.blob_radius = 0.04 -# Constant density initial condition -prob.density_ic = 1.0 -# Set up a flow, defaults to zero -prob.velocity_ic = 0. 1. 0. - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# VERBOSITY # -#.......................................# -ns.v = 1 # NS solver -nodal_proj.verbose = 0 # Nodal projection -mac_proj.verbose = 0 # MacProjector -diffuse.v = 0 # Diffusion operator - +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SIMULATION STOP # +#.......................................# +stop_time = 0.2 # Max (simulated) time to evolve +max_step = -1 # Max number of time steps +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SOLVER SETTINGS # +#.......................................# +ns.init_iter = 3 # How many initial pressure iterations +ns.init_vel_iter = 5 # How many initial projeciton iterations to ensure velocity satisfies divergence constraint +ns.visc_tol = 1.0e-11 # tolerance for viscous solve +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# TIME STEP COMPUTATION # +#.......................................# +ns.cfl = 0.45 +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# INPUT AND OUTPUT # +#.......................................# +amr.plot_int = 20 # Steps between plot files +amr.plot_per = 0.1 # Steps between plot files +amr.check_int = 1000 # Steps between checkpoint files +amr.restart = "" # Checkpoint to restart from +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PHYSICS # +#.......................................# +ns.gravity = 0. +ns.vel_visc_coef = 0.001 +ns.scal_diff_coefs = 1.0 +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# ADAPTIVE MESH REFINEMENT # +#.......................................# +amr.n_cell = 8 96 32 # Grid cells at coarsest AMRlevel +amr.max_level = 0 # Max AMR level in hierarchy + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# GEOMETRY # +#.......................................# +geometry.prob_lo = 0. 0. 0. # Lo corner coordinates +geometry.prob_hi = 0.1 1.2 0.4 # Hi corner coordinates +geometry.is_periodic = 1 0 0 # Periodicity x y z (0/1) + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWal +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 1 5 +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 2 5 + +ylo.velocity = 0. 1. 0. + +# Add cylinder +eb2.geom_type = cylinder +eb2.cylinder_has_fluid_inside = 0 +eb2.cylinder_radius = 0.05 +eb2.cylinder_direction = 0 +eb2.cylinder_center = 0.0 0.15 0.2 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PROBLEM PARAMETERS # +#.......................................# + +prob.probtype = 4 +prob.blob_center = 0.0 -0.55 0.05 +prob.blob_radius = 0.04 +# Constant density initial condition +prob.density_ic = 1.0 +# Set up a flow, defaults to zero +prob.velocity_ic = 0. 1. 0. + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# VERBOSITY # +#.......................................# +ns.v = 1 # NS solver +nodal_proj.verbose = 0 # Nodal projection +mac_proj.verbose = 0 # MacProjector +diffuse.v = 0 # Diffusion operator + diff --git a/Tutorials/FlowPastCylinder/inputs.3d.flow_past_cylinder-z b/Tutorials/FlowPastCylinder/inputs.3d.flow_past_cylinder-z index 528ee029..6b1157b6 100644 --- a/Tutorials/FlowPastCylinder/inputs.3d.flow_past_cylinder-z +++ b/Tutorials/FlowPastCylinder/inputs.3d.flow_past_cylinder-z @@ -1,78 +1,78 @@ -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SIMULATION STOP # -#.......................................# -stop_time = 0.2 # Max (simulated) time to evolve -max_step = -1 # Max number of time steps -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SOLVER SETTINGS # -#.......................................# -ns.init_iter = 3 # How many initial pressure iterations -ns.init_vel_iter = 5 # How many initial projeciton iterations to ensure velocity satisfies divergence constraint -ns.visc_tol = 1.0e-11 # tolerance for viscous solve -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# TIME STEP COMPUTATION # -#.......................................# -ns.cfl = 0.45 -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# INPUT AND OUTPUT # -#.......................................# -amr.plot_int = 20 # Steps between plot files -amr.plot_per = 0.1 # Steps between plot files -amr.check_int = 1000 # Steps between checkpoint files -amr.restart = "" # Checkpoint to restart from -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PHYSICS # -#.......................................# -ns.gravity = 0. -ns.vel_visc_coef = 0.001 -ns.scal_diff_coefs = 1.0 -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# ADAPTIVE MESH REFINEMENT # -#.......................................# -amr.n_cell = 32 8 96 # Grid cells at coarsest AMRlevel -amr.max_level = 0 # Max AMR level in hierarchy - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# GEOMETRY # -#.......................................# -geometry.prob_lo = 0. 0. 0. # Lo corner coordinates -geometry.prob_hi = 0.4 0.1 1.2 # Hi corner coordinates -geometry.is_periodic = 0 1 0 # Periodicity x y z (0/1) - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWal -# Boundary conditions on the low end of the domain. -ns.lo_bc = 5 0 1 -# Boundary conditions on the high end of the domain. -ns.hi_bc = 5 0 2 - -zlo.velocity = 0. 0. 1. - -# Add cylinder -eb2.geom_type = cylinder -eb2.cylinder_has_fluid_inside = 0 -eb2.cylinder_radius = 0.05 -eb2.cylinder_direction = 1 -eb2.cylinder_center = 0.2 0.0 0.15 - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PROBLEM PARAMETERS # -#.......................................# - -prob.probtype = 4 -prob.blob_center = 0.05 0.0 -0.55 -prob.blob_radius = 0.04 -# Constant density initial condition -prob.density_ic = 1.0 -# Set up a flow, defaults to zero -prob.velocity_ic = 0. 0. 1. - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# VERBOSITY # -#.......................................# -ns.v = 1 # NS solver -nodal_proj.verbose = 0 # Nodal projection -mac_proj.verbose = 0 # MacProjector -diffuse.v = 0 # Diffusion operator - +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SIMULATION STOP # +#.......................................# +stop_time = 0.2 # Max (simulated) time to evolve +max_step = -1 # Max number of time steps +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SOLVER SETTINGS # +#.......................................# +ns.init_iter = 3 # How many initial pressure iterations +ns.init_vel_iter = 5 # How many initial projeciton iterations to ensure velocity satisfies divergence constraint +ns.visc_tol = 1.0e-11 # tolerance for viscous solve +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# TIME STEP COMPUTATION # +#.......................................# +ns.cfl = 0.45 +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# INPUT AND OUTPUT # +#.......................................# +amr.plot_int = 20 # Steps between plot files +amr.plot_per = 0.1 # Steps between plot files +amr.check_int = 1000 # Steps between checkpoint files +amr.restart = "" # Checkpoint to restart from +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PHYSICS # +#.......................................# +ns.gravity = 0. +ns.vel_visc_coef = 0.001 +ns.scal_diff_coefs = 1.0 +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# ADAPTIVE MESH REFINEMENT # +#.......................................# +amr.n_cell = 32 8 96 # Grid cells at coarsest AMRlevel +amr.max_level = 0 # Max AMR level in hierarchy + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# GEOMETRY # +#.......................................# +geometry.prob_lo = 0. 0. 0. # Lo corner coordinates +geometry.prob_hi = 0.4 0.1 1.2 # Hi corner coordinates +geometry.is_periodic = 0 1 0 # Periodicity x y z (0/1) + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWal +# Boundary conditions on the low end of the domain. +ns.lo_bc = 5 0 1 +# Boundary conditions on the high end of the domain. +ns.hi_bc = 5 0 2 + +zlo.velocity = 0. 0. 1. + +# Add cylinder +eb2.geom_type = cylinder +eb2.cylinder_has_fluid_inside = 0 +eb2.cylinder_radius = 0.05 +eb2.cylinder_direction = 1 +eb2.cylinder_center = 0.2 0.0 0.15 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PROBLEM PARAMETERS # +#.......................................# + +prob.probtype = 4 +prob.blob_center = 0.05 0.0 -0.55 +prob.blob_radius = 0.04 +# Constant density initial condition +prob.density_ic = 1.0 +# Set up a flow, defaults to zero +prob.velocity_ic = 0. 0. 1. + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# VERBOSITY # +#.......................................# +ns.v = 1 # NS solver +nodal_proj.verbose = 0 # Nodal projection +mac_proj.verbose = 0 # MacProjector +diffuse.v = 0 # Diffusion operator + diff --git a/Tutorials/FlowPastSphere/GNUmakefile b/Tutorials/FlowPastSphere/GNUmakefile index eac06bfc..d1b5d4da 100644 --- a/Tutorials/FlowPastSphere/GNUmakefile +++ b/Tutorials/FlowPastSphere/GNUmakefile @@ -1,31 +1,31 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 3 -COMP = gnu - -DEBUG = TRUE -USE_MPI = TRUE -USE_OMP = FALSE -PROFILE = FALSE -USE_PARTICLES = TRUE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 3 +COMP = gnu + +DEBUG = TRUE +USE_MPI = TRUE +USE_OMP = FALSE +PROFILE = FALSE +USE_PARTICLES = TRUE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/FlowPastSphere/inputs.3d.flow_past_sphere b/Tutorials/FlowPastSphere/inputs.3d.flow_past_sphere index 49a02a8a..0e98bfe7 100644 --- a/Tutorials/FlowPastSphere/inputs.3d.flow_past_sphere +++ b/Tutorials/FlowPastSphere/inputs.3d.flow_past_sphere @@ -1,212 +1,212 @@ - -#******************************************************************************* -# INPUTS.3D.FLOW_PAST_SPHERE -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 2 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 100.0 - -ns.fixed_dt = 0.01 -ns.cfl = 0.3 -ns.init_iter = 0 - -# Diffused IB input file -particle.input = particle_inputs - -# Refinement criterion, use vorticity and presence of tracer -amr.refinement_indicators = tracer - -amr.max_level = 0 # maximum number of levels of refinement -# amr.tracer.value_greater = 0.1 -# amr.tracer.value_less = 1.1 -amr.tracer.field_name = tracer -amr.tracer.in_box_lo = 0.5 0.5 0.5 -amr.tracer.in_box_hi = 1.5 1.5 1.5 - -amr.blocking_factor = 8 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -# amr.n_cell = 16 8 8 -amr.n_cell = 256 128 128 -# amr.n_cell = 288 128 128 -amr.max_grid_size = 16 -# amr.max_grid_size = 32 - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 1 # regrid_int - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -nodal_proj.verbose = 1 -mac_proj.verbose = 1 - -# mac_proj.mac_tol = 0.1 -# mac_proj.mac_abs_tol = 0.1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files - -amr.check_int = 4000 - -#amr.restart = chk01400 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 1 - - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.01 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 0.0 # -9.8 - -#******************************************************************************* - -# skip level_projector -ns.skip_level_projector = 0 - -#******************************************************************************* - -# subcycling vs. non-subcycling -amr.subcycling_mode = None - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 20. 10. 10. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 1 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 2 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary condition -xlo.velocity = 1. 0. 0. - -#******************************************************************************* - -# Problem parameters -prob.probtype = 1 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -# amr.derive_plot_vars = avg_pressure - -#******************************************************************************* -ns.isolver = 1 -ns.do_diffused_ib = 1 -ns.fluid_rho = 1.0 - -#ns.sum_interval = 1 - -particles.do_nspc_particles = 0 - -nodal_proj.proj_tol = 1.e-8 -nodal_proj.proj_abs_tol = 1.e-9 - -nodal_proj.maxiter = 200 -nodal_proj.bottom_maxiter = 200 - -mac_proj.mac_tol = 1.e-8 -mac_proj.mac_abs_tol = 1.e-9 - - -############################ -# # -# Diffused IB cfg file # -# # -############################ - -# particle's location -# x = p1x p2x p3x ... -particle_inputs.x = 5.0 -particle_inputs.y = 5.0 -particle_inputs.z = 5.0 - -# particle's density -# rho = p1r p2r p3r ... -particle_inputs.rho = 1.0 - -# particle's radius -# single -particle_inputs.radius = 0.5 - -# particle's velocity -# vx = p1vx p2vx p3vx ... -particle_inputs.velocity_x = 0.0 -particle_inputs.velocity_y = 0.0 -particle_inputs.velocity_z = 0.0 - -# particle's omega -# omega = p1omega_x p2omega_x p3omega_x ... -particle_inputs.omega_x = 0.0 -particle_inputs.omega_y = 0.0 -particle_inputs.omega_z = 0.0 - -# particle's 6DOF -# TLX = p1tl p2tl ... -particle_inputs.TLX = 0 -particle_inputs.TLY = 0 -particle_inputs.TLZ = 0 -particle_inputs.RLX = 0 -particle_inputs.RLY = 0 -particle_inputs.RLZ = 0 - - -# msg print -particle_inputs.verbose = 1 + +#******************************************************************************* +# INPUTS.3D.FLOW_PAST_SPHERE +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 2 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 100.0 + +ns.fixed_dt = 0.01 +ns.cfl = 0.3 +ns.init_iter = 0 + +# Diffused IB input file +particle.input = particle_inputs + +# Refinement criterion, use vorticity and presence of tracer +amr.refinement_indicators = tracer + +amr.max_level = 0 # maximum number of levels of refinement +# amr.tracer.value_greater = 0.1 +# amr.tracer.value_less = 1.1 +amr.tracer.field_name = tracer +amr.tracer.in_box_lo = 0.5 0.5 0.5 +amr.tracer.in_box_hi = 1.5 1.5 1.5 + +amr.blocking_factor = 8 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +# amr.n_cell = 16 8 8 +amr.n_cell = 256 128 128 +# amr.n_cell = 288 128 128 +amr.max_grid_size = 16 +# amr.max_grid_size = 32 + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 1 # regrid_int + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +nodal_proj.verbose = 1 +mac_proj.verbose = 1 + +# mac_proj.mac_tol = 0.1 +# mac_proj.mac_abs_tol = 0.1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files + +amr.check_int = 4000 + +#amr.restart = chk01400 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 1 + + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.01 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 0.0 # -9.8 + +#******************************************************************************* + +# skip level_projector +ns.skip_level_projector = 0 + +#******************************************************************************* + +# subcycling vs. non-subcycling +amr.subcycling_mode = None + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 20. 10. 10. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 1 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 2 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary condition +xlo.velocity = 1. 0. 0. + +#******************************************************************************* + +# Problem parameters +prob.probtype = 1 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +# amr.derive_plot_vars = avg_pressure + +#******************************************************************************* +ns.isolver = 1 +ns.do_diffused_ib = 1 +ns.fluid_rho = 1.0 + +#ns.sum_interval = 1 + +particles.do_nspc_particles = 0 + +nodal_proj.proj_tol = 1.e-8 +nodal_proj.proj_abs_tol = 1.e-9 + +nodal_proj.maxiter = 200 +nodal_proj.bottom_maxiter = 200 + +mac_proj.mac_tol = 1.e-8 +mac_proj.mac_abs_tol = 1.e-9 + + +############################ +# # +# Diffused IB cfg file # +# # +############################ + +# particle's location +# x = p1x p2x p3x ... +particle_inputs.x = 5.0 +particle_inputs.y = 5.0 +particle_inputs.z = 5.0 + +# particle's density +# rho = p1r p2r p3r ... +particle_inputs.rho = 1.0 + +# particle's radius +# single +particle_inputs.radius = 0.5 + +# particle's velocity +# vx = p1vx p2vx p3vx ... +particle_inputs.velocity_x = 0.0 +particle_inputs.velocity_y = 0.0 +particle_inputs.velocity_z = 0.0 + +# particle's omega +# omega = p1omega_x p2omega_x p3omega_x ... +particle_inputs.omega_x = 0.0 +particle_inputs.omega_y = 0.0 +particle_inputs.omega_z = 0.0 + +# particle's 6DOF +# TLX = p1tl p2tl ... +particle_inputs.TLX = 0 +particle_inputs.TLY = 0 +particle_inputs.TLZ = 0 +particle_inputs.RLX = 0 +particle_inputs.RLY = 0 +particle_inputs.RLZ = 0 + + +# msg print +particle_inputs.verbose = 1 diff --git a/Tutorials/HotSpot/GNUmakefile b/Tutorials/HotSpot/GNUmakefile index ec7c9ade..b6cbd784 100644 --- a/Tutorials/HotSpot/GNUmakefile +++ b/Tutorials/HotSpot/GNUmakefile @@ -1,30 +1,30 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 -COMP = gnu - -DEBUG = FALSE -USE_MPI = FALSE -USE_OMP = FALSE -PROFILE = FALSE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 +COMP = gnu + +DEBUG = FALSE +USE_MPI = FALSE +USE_OMP = FALSE +PROFILE = FALSE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/HotSpot/inputs.2d.average_hotspot b/Tutorials/HotSpot/inputs.2d.average_hotspot index e2b7851e..fde3c00d 100644 --- a/Tutorials/HotSpot/inputs.2d.average_hotspot +++ b/Tutorials/HotSpot/inputs.2d.average_hotspot @@ -1,148 +1,148 @@ - -#******************************************************************************* -# INPUTS.2D.HOTSPOT -#******************************************************************************* - -# Compute averages and add to plotfile -ns.avg_interval = 1 - -ns.do_temp=1 -ns.temp_cond_coef=1.e-8 - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 30 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 1.0 - -# Refinement criterion, use temperature -amr.refinement_indicators = hi_temp gradT - -amr.hi_temp.max_level = 1 -amr.hi_temp.value_greater = 1.01 -amr.hi_temp.field_name = temp - -amr.gradT.adjacent_difference_greater = 0.005 -amr.gradT.field_name = temp -#amr.gradT.start_time = 0.001 -#amr.gradT.end_name = 0.002 - - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 32 32 -amr.max_grid_size = 32 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 1 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 1 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 0.3 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.001 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.001 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = -9.8 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = -1. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 2. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 4 4 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 4 4 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 6 -prob.blob_center = 0.0 0.65 -prob.blob_radius = 0.2 -# Background density is 1. Density is reduced by a factor of density_ic inside -# the bubble -prob.density_ic = 2.0 -# Can also set up a flow, defaults to zero -#prob.velocity_ic = 0. 0. 0. - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort diveru avg_pressure velocity_average -amr.plot_vars = x_velocity y_velocity density tracer temp -#******************************************************************************* - + +#******************************************************************************* +# INPUTS.2D.HOTSPOT +#******************************************************************************* + +# Compute averages and add to plotfile +ns.avg_interval = 1 + +ns.do_temp=1 +ns.temp_cond_coef=1.e-8 + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 30 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 1.0 + +# Refinement criterion, use temperature +amr.refinement_indicators = hi_temp gradT + +amr.hi_temp.max_level = 1 +amr.hi_temp.value_greater = 1.01 +amr.hi_temp.field_name = temp + +amr.gradT.adjacent_difference_greater = 0.005 +amr.gradT.field_name = temp +#amr.gradT.start_time = 0.001 +#amr.gradT.end_name = 0.002 + + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 32 32 +amr.max_grid_size = 32 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 1 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 1 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 0.3 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.001 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.001 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = -9.8 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = -1. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 2. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 4 4 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 4 4 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 6 +prob.blob_center = 0.0 0.65 +prob.blob_radius = 0.2 +# Background density is 1. Density is reduced by a factor of density_ic inside +# the bubble +prob.density_ic = 2.0 +# Can also set up a flow, defaults to zero +#prob.velocity_ic = 0. 0. 0. + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort diveru avg_pressure velocity_average +amr.plot_vars = x_velocity y_velocity density tracer temp +#******************************************************************************* + diff --git a/Tutorials/HotSpot/inputs.3d.LES_hotspot b/Tutorials/HotSpot/inputs.3d.LES_hotspot index 41f83759..e1658364 100644 --- a/Tutorials/HotSpot/inputs.3d.LES_hotspot +++ b/Tutorials/HotSpot/inputs.3d.LES_hotspot @@ -1,162 +1,162 @@ - -#******************************************************************************* -# INPUTS.3D.HOTSPOT - hot bubble rising -#******************************************************************************* - -ns.do_temp=1 -ns.temp_cond_coef=1.e-8 - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 10 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 1.0 - -# Refinement criterion, use temperature -amr.refinement_indicators = hi_temp gradT - -amr.hi_temp.max_level = 1 -amr.hi_temp.value_greater = 1.01 -amr.hi_temp.field_name = temp - -amr.gradT.adjacent_difference_greater = 0.005 -amr.gradT.field_name = temp -#amr.gradT.start_time = 0.001 -#amr.gradT.end_name = 0.002 - -# allow refinement at outflow boundary -ns.do_refine_outflow = 1 -ns.do_derefine_outflow = 0 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 32 32 32 -amr.max_grid_size = 16 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -diffuse.v = 0 -mac_proj.verbose =0 -nodal_proj.verbose=1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 0 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 1 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 0.3 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.001 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.001 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = -9.8 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = -1. -1. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 1. 2. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 5 5 5 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 5 5 2 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Factor by which grids must be coarsenable. -amr.blocking_factor = 4 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort diveru avg_pressure - -#******************************************************************************* - -# Problem parameters -prob.probtype = 6 -prob.blob_center = 0.0 0.0 1.7 -prob.blob_radius = 0.2 -# Background density is 1. Density is reduced by a factor of density_ic inside -# the bubble -prob.density_ic = 2.0 -# Can also set up a flow, defaults to zero -#prob.velocity_ic = 0. 0. 0. - -#******************************************************************************* - -ns.getLESVerbose = 1 -ns.do_LES = 1 -#ns.LES_model = Smagorinsky -ns.LES_model = Sigma -ns.smago_Cs_cst = 0.18 - + +#******************************************************************************* +# INPUTS.3D.HOTSPOT - hot bubble rising +#******************************************************************************* + +ns.do_temp=1 +ns.temp_cond_coef=1.e-8 + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 10 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 1.0 + +# Refinement criterion, use temperature +amr.refinement_indicators = hi_temp gradT + +amr.hi_temp.max_level = 1 +amr.hi_temp.value_greater = 1.01 +amr.hi_temp.field_name = temp + +amr.gradT.adjacent_difference_greater = 0.005 +amr.gradT.field_name = temp +#amr.gradT.start_time = 0.001 +#amr.gradT.end_name = 0.002 + +# allow refinement at outflow boundary +ns.do_refine_outflow = 1 +ns.do_derefine_outflow = 0 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 32 32 32 +amr.max_grid_size = 16 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +diffuse.v = 0 +mac_proj.verbose =0 +nodal_proj.verbose=1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 0 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 1 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 0.3 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.001 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.001 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = -9.8 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = -1. -1. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 1. 2. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 5 5 5 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 5 5 2 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Factor by which grids must be coarsenable. +amr.blocking_factor = 4 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort diveru avg_pressure + +#******************************************************************************* + +# Problem parameters +prob.probtype = 6 +prob.blob_center = 0.0 0.0 1.7 +prob.blob_radius = 0.2 +# Background density is 1. Density is reduced by a factor of density_ic inside +# the bubble +prob.density_ic = 2.0 +# Can also set up a flow, defaults to zero +#prob.velocity_ic = 0. 0. 0. + +#******************************************************************************* + +ns.getLESVerbose = 1 +ns.do_LES = 1 +#ns.LES_model = Smagorinsky +ns.LES_model = Sigma +ns.smago_Cs_cst = 0.18 + diff --git a/Tutorials/InletShearFlowValidation/GNUmakefile b/Tutorials/InletShearFlowValidation/GNUmakefile index b3878ff8..4add0932 100644 --- a/Tutorials/InletShearFlowValidation/GNUmakefile +++ b/Tutorials/InletShearFlowValidation/GNUmakefile @@ -1,31 +1,31 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 3 -COMP = gnu - -DEBUG = TRUE -USE_MPI = TRUE -USE_OMP = FALSE -PROFILE = FALSE -USE_PARTICLES = FALSE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 3 +COMP = gnu + +DEBUG = TRUE +USE_MPI = TRUE +USE_OMP = FALSE +PROFILE = FALSE +USE_PARTICLES = FALSE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/InletShearFlowValidation/inputs.3d.inlet_shear_flow b/Tutorials/InletShearFlowValidation/inputs.3d.inlet_shear_flow index bfcaca85..c22a7529 100644 --- a/Tutorials/InletShearFlowValidation/inputs.3d.inlet_shear_flow +++ b/Tutorials/InletShearFlowValidation/inputs.3d.inlet_shear_flow @@ -1,143 +1,143 @@ - -#******************************************************************************* -# INPUTS.3D.INLET_SHEAR_FLOW -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 2000 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 10.0 - -ns.fixed_dt = 0.1 -ns.cfl = 0.3 -ns.init_iter = 0 - -amr.max_level = 0 # maximum number of levels of refinement - -amr.blocking_factor = 8 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 16 8 8 -amr.max_grid_size = 16 - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 1 # regrid_int - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -nodal_proj.verbose = 1 -mac_proj.verbose = 1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 5 -#amr.restart = chk01400 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 5 - - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.01 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.001 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 0.0 # -9.8 - -#******************************************************************************* - -# skip level_projector -ns.skip_level_projector = 0 - -#******************************************************************************* - -# subcycling vs. non-subcycling -amr.subcycling_mode = None - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 16. 8. 8. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 1 4 4 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 2 4 4 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary condition -xlo.velocity = 0. 0. 0. - -#******************************************************************************* - -# Problem parameters -prob.probtype = 1 -prob.ub = 1.2 -prob.shearrate = 0.01 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = avg_pressure - -#******************************************************************************* -ns.isolver = 0 -ns.do_diffused_ib = 0 - -particles.do_nspc_particles = 0 - -nodal_proj.proj_tol = 1.e-4 -nodal_proj.proj_abs_tol = 1.e-5 - -mac_proj.mac_tol = 1.e-4 -mac_proj.mac_abs_tol = 1.e-5 + +#******************************************************************************* +# INPUTS.3D.INLET_SHEAR_FLOW +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 2000 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 10.0 + +ns.fixed_dt = 0.1 +ns.cfl = 0.3 +ns.init_iter = 0 + +amr.max_level = 0 # maximum number of levels of refinement + +amr.blocking_factor = 8 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 16 8 8 +amr.max_grid_size = 16 + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 1 # regrid_int + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +nodal_proj.verbose = 1 +mac_proj.verbose = 1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 5 +#amr.restart = chk01400 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 5 + + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.01 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.001 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 0.0 # -9.8 + +#******************************************************************************* + +# skip level_projector +ns.skip_level_projector = 0 + +#******************************************************************************* + +# subcycling vs. non-subcycling +amr.subcycling_mode = None + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 16. 8. 8. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 1 4 4 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 2 4 4 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary condition +xlo.velocity = 0. 0. 0. + +#******************************************************************************* + +# Problem parameters +prob.probtype = 1 +prob.ub = 1.2 +prob.shearrate = 0.01 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = avg_pressure + +#******************************************************************************* +ns.isolver = 0 +ns.do_diffused_ib = 0 + +particles.do_nspc_particles = 0 + +nodal_proj.proj_tol = 1.e-4 +nodal_proj.proj_abs_tol = 1.e-5 + +mac_proj.mac_tol = 1.e-4 +mac_proj.mac_abs_tol = 1.e-5 diff --git a/Tutorials/LidDrivenCavity/GNUmakefile b/Tutorials/LidDrivenCavity/GNUmakefile index ec7c9ade..b6cbd784 100644 --- a/Tutorials/LidDrivenCavity/GNUmakefile +++ b/Tutorials/LidDrivenCavity/GNUmakefile @@ -1,30 +1,30 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 -COMP = gnu - -DEBUG = FALSE -USE_MPI = FALSE -USE_OMP = FALSE -PROFILE = FALSE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 +COMP = gnu + +DEBUG = FALSE +USE_MPI = FALSE +USE_OMP = FALSE +PROFILE = FALSE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/LidDrivenCavity/inputs.2d.lid_driven_cavity b/Tutorials/LidDrivenCavity/inputs.2d.lid_driven_cavity index df7cbc34..17cfdb67 100644 --- a/Tutorials/LidDrivenCavity/inputs.2d.lid_driven_cavity +++ b/Tutorials/LidDrivenCavity/inputs.2d.lid_driven_cavity @@ -1,125 +1,125 @@ -#******************************************************************************* -# INPUTS.2D.LID_DRIVEN_CAVITY -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 100000 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = -1 - -# Stop simulation when we reach steady-state -ns.stop_when_steady = 1 -ns.steady_tol = 1.0e-5 - -# Specify initial dt to get going -ns.init_dt = 0.0140625 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 64 -#amr.max_grid_size = 32 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Sets the "NavierStokes" code to not be verbose -ns.v = 0 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 1000 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 100 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 0.3 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.001 - -#******************************************************************************* - -# Diffusion coefficient for tracer -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 1. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 5 5 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 5 5 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary condition -yhi.velocity = 1. 0. 0. - -#******************************************************************************* - -# Initialize from rest with constant density = 1 -prob.probtype = 1 - -#******************************************************************************* - -# Continue from checkpoint -# amr.restart = chk02607 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = ALL - -#******************************************************************************* +#******************************************************************************* +# INPUTS.2D.LID_DRIVEN_CAVITY +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 100000 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = -1 + +# Stop simulation when we reach steady-state +ns.stop_when_steady = 1 +ns.steady_tol = 1.0e-5 + +# Specify initial dt to get going +ns.init_dt = 0.0140625 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 64 +#amr.max_grid_size = 32 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Sets the "NavierStokes" code to not be verbose +ns.v = 0 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 1000 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 100 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 0.3 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.001 + +#******************************************************************************* + +# Diffusion coefficient for tracer +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 1. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 5 5 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 5 5 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary condition +yhi.velocity = 1. 0. 0. + +#******************************************************************************* + +# Initialize from rest with constant density = 1 +prob.probtype = 1 + +#******************************************************************************* + +# Continue from checkpoint +# amr.restart = chk02607 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = ALL + +#******************************************************************************* diff --git a/Tutorials/LidDrivenCavity/inputs.3d.lid_driven_cavity b/Tutorials/LidDrivenCavity/inputs.3d.lid_driven_cavity index 4b434a38..4fb50e17 100644 --- a/Tutorials/LidDrivenCavity/inputs.3d.lid_driven_cavity +++ b/Tutorials/LidDrivenCavity/inputs.3d.lid_driven_cavity @@ -1,55 +1,55 @@ -#******************************************************************************* -# INPUTS.3D.LID_DRIVEN_CAVITY -#******************************************************************************* - -max_step = 1 - -stop_time = 10.0 - -ns.stop_when_steady = 1 -ns.steady_tol = 1.0e-4 - -amr.n_cell = 64 64 64 - -amr.max_level = 0 - -ns.v = 1 -amr.v = 1 - -amr.check_int = 50 - -amr.plot_int = 5 - -ns.cfl = 0.7 # CFL number used to set dt - -ns.init_dt = 0.0140625 # initial dt to get simulation going -ns.init_shrink = 0.3 # factor which multiplies the very first time step -ns.init_iter = 3 # number of initial iterations - -ns.vel_visc_coef = 0.01 -ns.scal_diff_coefs = 0.0 - -geometry.coord_sys = 0 - -geometry.prob_lo = 0. 0. 0. -geometry.prob_hi = 1. 1. 1. - -geometry.is_periodic = 0 0 0 - -ns.gravity = 0.0 - -ns.lo_bc = 5 5 5 -ns.hi_bc = 5 5 5 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary condition -zhi.velocity = 1. 0. 0. - -# Initialize from rest with constant density = 1 -prob.probtype = 1 - -amr.derive_plot_vars = mag_vort -nodal_proj.verbose = 0 +#******************************************************************************* +# INPUTS.3D.LID_DRIVEN_CAVITY +#******************************************************************************* + +max_step = 1 + +stop_time = 10.0 + +ns.stop_when_steady = 1 +ns.steady_tol = 1.0e-4 + +amr.n_cell = 64 64 64 + +amr.max_level = 0 + +ns.v = 1 +amr.v = 1 + +amr.check_int = 50 + +amr.plot_int = 5 + +ns.cfl = 0.7 # CFL number used to set dt + +ns.init_dt = 0.0140625 # initial dt to get simulation going +ns.init_shrink = 0.3 # factor which multiplies the very first time step +ns.init_iter = 3 # number of initial iterations + +ns.vel_visc_coef = 0.01 +ns.scal_diff_coefs = 0.0 + +geometry.coord_sys = 0 + +geometry.prob_lo = 0. 0. 0. +geometry.prob_hi = 1. 1. 1. + +geometry.is_periodic = 0 0 0 + +ns.gravity = 0.0 + +ns.lo_bc = 5 5 5 +ns.hi_bc = 5 5 5 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary condition +zhi.velocity = 1. 0. 0. + +# Initialize from rest with constant density = 1 +prob.probtype = 1 + +amr.derive_plot_vars = mag_vort +nodal_proj.verbose = 0 diff --git a/Tutorials/LidDrivenCavitySphere/GNUmakefile b/Tutorials/LidDrivenCavitySphere/GNUmakefile index 4b53270a..ce589cb1 100644 --- a/Tutorials/LidDrivenCavitySphere/GNUmakefile +++ b/Tutorials/LidDrivenCavitySphere/GNUmakefile @@ -1,31 +1,31 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 3 -COMP = gnu - -DEBUG = FALSE -USE_MPI = TRUE -USE_OMP = FALSE -PROFILE = FALSE -USE_PARTICLES = TRUE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 3 +COMP = gnu + +DEBUG = FALSE +USE_MPI = TRUE +USE_OMP = FALSE +PROFILE = FALSE +USE_PARTICLES = TRUE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/LidDrivenCavitySphere/inputs.3d.lid_driven_cavity_particle b/Tutorials/LidDrivenCavitySphere/inputs.3d.lid_driven_cavity_particle index 3039a759..00a18199 100644 --- a/Tutorials/LidDrivenCavitySphere/inputs.3d.lid_driven_cavity_particle +++ b/Tutorials/LidDrivenCavitySphere/inputs.3d.lid_driven_cavity_particle @@ -1,213 +1,213 @@ -#******************************************************************************* -# INPUTS.3D.LID_DRIVEN_CAVITY_SPHERE -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 200 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 100.0 - -ns.fixed_dt = 0.01 -ns.cfl = 0.3 -ns.init_iter = 0 - -# Diffused IB input file -particle.input = particle_inputs - -# Refinement criterion, use vorticity and presence of tracer -amr.refinement_indicators = tracer - -amr.max_level = 0 # maximum number of levels of refinement -# amr.tracer.value_greater = 0.1 -# amr.tracer.value_less = 1.1 -amr.tracer.field_name = tracer -amr.tracer.in_box_lo = 0.3 0.3 0.3 -amr.tracer.in_box_hi = 0.7 0.7 0.7 - -amr.blocking_factor = 8 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -# amr.n_cell = 16 8 8 -amr.n_cell = 32 32 32 -# amr.n_cell = 288 128 128 -amr.max_grid_size = 16 -# amr.max_grid_size = 32 - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -# amr.regrid_int = 1 # regrid_int - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -nodal_proj.verbose = 1 -mac_proj.verbose = 1 - -# mac_proj.mac_tol = 0.1 -# mac_proj.mac_abs_tol = 0.1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files - -amr.check_int = 4000 - -#amr.restart = chk00010 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 10 - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.000625 -# 0.25 Rep=1 -# 0.0025 Rep=100 -# 0.000625 Rep=400 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 0.0 # -9.8 - -#******************************************************************************* - -# skip level_projector -ns.skip_level_projector = 0 - -#******************************************************************************* - -# subcycling vs. non-subcycling -amr.subcycling_mode = None - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 1. 1. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 5 5 5 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 5 5 5 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary condition -zhi.velocity = 1. 0. 0. - -#******************************************************************************* - -# Initialize from rest with constant density = 1 -prob.probtype = 1 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -# amr.derive_plot_vars = avg_pressure - -#******************************************************************************* -ns.isolver = 1 -ns.do_diffused_ib = 1 -ns.fluid_rho = 1.0 - -#ns.sum_interval = 1 - -particles.do_nspc_particles = 0 - -nodal_proj.proj_tol = 1.e-8 -nodal_proj.proj_abs_tol = 1.e-9 - -nodal_proj.maxiter = 200 -nodal_proj.bottom_maxiter = 200 - -mac_proj.mac_tol = 1.e-8 -mac_proj.mac_abs_tol = 1.e-9 - - -############################ -# # -# Diffused IB cfg file # -# # -############################ - -# particle's location -# x = p1x p2x p3x ... -particle_inputs.x = 0.5 -particle_inputs.y = 0.5 -particle_inputs.z = 0.5 - -# particle's density -# rho = p1r p2r p3r ... -particle_inputs.rho = 0.001 - -# particle's radius -# single -particle_inputs.radius = 0.125 - -# particle's velocity -# vx = p1vx p2vx p3vx ... -particle_inputs.velocity_x = 0.0 -particle_inputs.velocity_y = 0.0 -particle_inputs.velocity_z = 0.0 - -# particle's omega -# omega = p1omega_x p2omega_x p3omega_x ... -particle_inputs.omega_x = 0.0 -particle_inputs.omega_y = 0.0 -particle_inputs.omega_z = 0.0 - -# particle's 6DOF -# TLX = p1tl p2tl ... -particle_inputs.TLX = 0 -particle_inputs.TLY = 0 -particle_inputs.TLZ = 0 -particle_inputs.RLX = 0 -particle_inputs.RLY = 0 -particle_inputs.RLZ = 0 - - -# msg print -particle_inputs.verbose = 1 +#******************************************************************************* +# INPUTS.3D.LID_DRIVEN_CAVITY_SPHERE +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 200 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 100.0 + +ns.fixed_dt = 0.01 +ns.cfl = 0.3 +ns.init_iter = 0 + +# Diffused IB input file +particle.input = particle_inputs + +# Refinement criterion, use vorticity and presence of tracer +amr.refinement_indicators = tracer + +amr.max_level = 0 # maximum number of levels of refinement +# amr.tracer.value_greater = 0.1 +# amr.tracer.value_less = 1.1 +amr.tracer.field_name = tracer +amr.tracer.in_box_lo = 0.3 0.3 0.3 +amr.tracer.in_box_hi = 0.7 0.7 0.7 + +amr.blocking_factor = 8 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +# amr.n_cell = 16 8 8 +amr.n_cell = 32 32 32 +# amr.n_cell = 288 128 128 +amr.max_grid_size = 16 +# amr.max_grid_size = 32 + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +# amr.regrid_int = 1 # regrid_int + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +nodal_proj.verbose = 1 +mac_proj.verbose = 1 + +# mac_proj.mac_tol = 0.1 +# mac_proj.mac_abs_tol = 0.1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files + +amr.check_int = 4000 + +#amr.restart = chk00010 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 10 + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.000625 +# 0.25 Rep=1 +# 0.0025 Rep=100 +# 0.000625 Rep=400 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 0.0 # -9.8 + +#******************************************************************************* + +# skip level_projector +ns.skip_level_projector = 0 + +#******************************************************************************* + +# subcycling vs. non-subcycling +amr.subcycling_mode = None + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 1. 1. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 5 5 5 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 5 5 5 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary condition +zhi.velocity = 1. 0. 0. + +#******************************************************************************* + +# Initialize from rest with constant density = 1 +prob.probtype = 1 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +# amr.derive_plot_vars = avg_pressure + +#******************************************************************************* +ns.isolver = 1 +ns.do_diffused_ib = 1 +ns.fluid_rho = 1.0 + +#ns.sum_interval = 1 + +particles.do_nspc_particles = 0 + +nodal_proj.proj_tol = 1.e-8 +nodal_proj.proj_abs_tol = 1.e-9 + +nodal_proj.maxiter = 200 +nodal_proj.bottom_maxiter = 200 + +mac_proj.mac_tol = 1.e-8 +mac_proj.mac_abs_tol = 1.e-9 + + +############################ +# # +# Diffused IB cfg file # +# # +############################ + +# particle's location +# x = p1x p2x p3x ... +particle_inputs.x = 0.5 +particle_inputs.y = 0.5 +particle_inputs.z = 0.5 + +# particle's density +# rho = p1r p2r p3r ... +particle_inputs.rho = 0.001 + +# particle's radius +# single +particle_inputs.radius = 0.125 + +# particle's velocity +# vx = p1vx p2vx p3vx ... +particle_inputs.velocity_x = 0.0 +particle_inputs.velocity_y = 0.0 +particle_inputs.velocity_z = 0.0 + +# particle's omega +# omega = p1omega_x p2omega_x p3omega_x ... +particle_inputs.omega_x = 0.0 +particle_inputs.omega_y = 0.0 +particle_inputs.omega_z = 0.0 + +# particle's 6DOF +# TLX = p1tl p2tl ... +particle_inputs.TLX = 0 +particle_inputs.TLY = 0 +particle_inputs.TLZ = 0 +particle_inputs.RLX = 0 +particle_inputs.RLY = 0 +particle_inputs.RLZ = 0 + + +# msg print +particle_inputs.verbose = 1 diff --git a/Tutorials/Monodisperse/GNUmakefile b/Tutorials/Monodisperse/GNUmakefile index eac06bfc..d1b5d4da 100644 --- a/Tutorials/Monodisperse/GNUmakefile +++ b/Tutorials/Monodisperse/GNUmakefile @@ -1,31 +1,31 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 3 -COMP = gnu - -DEBUG = TRUE -USE_MPI = TRUE -USE_OMP = FALSE -PROFILE = FALSE -USE_PARTICLES = TRUE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 3 +COMP = gnu + +DEBUG = TRUE +USE_MPI = TRUE +USE_OMP = FALSE +PROFILE = FALSE +USE_PARTICLES = TRUE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/Monodisperse/inputs.random_particle b/Tutorials/Monodisperse/inputs.random_particle index 1cb469d8..fac0f1c6 100644 --- a/Tutorials/Monodisperse/inputs.random_particle +++ b/Tutorials/Monodisperse/inputs.random_particle @@ -1,214 +1,214 @@ - -#******************************************************************************* -# INPUTS.3D.FLOW_PAST_SPHERE -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 1000 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 100.0 - -ns.fixed_dt = 0.005 -ns.cfl = 0.3 -ns.init_iter = 0 - -# Diffused IB input file -particle.input = particle_inputs - -# Refinement criterion, use vorticity and presence of tracer -amr.refinement_indicators = tracer box - -amr.max_level = 2 # maximum number of levels of refinement -amr.tracer.field_name = tracer -amr.tracer.value_greater = 0.01 - -amr.box.in_box_lo = 1. 2. 1. -amr.box.in_box_hi = 9. 18. 9. -amr.box.start_time = 0.0 -amr.box.end_time = 0.01 - -amr.n_error_buf = 2 -amr.blocking_factor = 4 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -# amr.n_cell = 16 8 8 -amr.n_cell = 32 64 32 -# amr.n_cell = 288 128 128 -amr.max_grid_size = 8 -# amr.max_grid_size = 32 - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 10 # regrid_int - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -nodal_proj.verbose = 1 -mac_proj.verbose = 1 - -# mac_proj.mac_tol = 0.1 -# mac_proj.mac_abs_tol = 0.1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files - -amr.check_int = 1000 - -#amr.restart = chk01400 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 100 - - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.01 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = -1.0 - -#******************************************************************************* - -# skip level_projector -ns.skip_level_projector = 0 - -#******************************************************************************* - -# subcycling vs. non-subcycling -amr.subcycling_mode = None - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 10 20 10 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 0 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 4 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 4 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 1 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -# amr.derive_plot_vars = avg_pressure - -#******************************************************************************* -ns.isolver = 1 -ns.do_diffused_ib = 1 -ns.fluid_rho = 1.0 - -#ns.sum_interval = 1 - -particles.do_nspc_particles = 0 - -nodal_proj.proj_tol = 1.e-8 -nodal_proj.proj_abs_tol = 1.e-9 - -nodal_proj.maxiter = 200 -nodal_proj.bottom_maxiter = 200 - -mac_proj.mac_tol = 1.e-8 -mac_proj.mac_abs_tol = 1.e-9 - - -############################ -# # -# Diffused IB cfg file # -# # -############################ - -particle_inputs.init = particle_init - -# particle's location -# x = p1x p2x p3x ... -particle_inputs.x = 0.0 -particle_inputs.y = 0.0 -particle_inputs.z = 0.0 - -# particle's density -# rho = p1r p2r p3r ... -particle_inputs.rho = 1.0 - -# particle's radius -# single -particle_inputs.radius = 0.5 - -# particle's velocity -# vx = p1vx p2vx p3vx ... -particle_inputs.velocity_x = 0.0 -particle_inputs.velocity_y = 0.0 -particle_inputs.velocity_z = 0.0 - -# particle's omega -# omega = p1omega_x p2omega_x p3omega_x ... -particle_inputs.omega_x = 0.0 -particle_inputs.omega_y = 0.0 -particle_inputs.omega_z = 0.0 - -# particle's 6DOF -# TLX = p1tl p2tl ... -particle_inputs.TLX = 0 -particle_inputs.TLY = 0 -particle_inputs.TLZ = 0 -particle_inputs.RLX = 0 -particle_inputs.RLY = 0 -particle_inputs.RLZ = 0 - - -# msg print -particle_inputs.verbose = 0 + +#******************************************************************************* +# INPUTS.3D.FLOW_PAST_SPHERE +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 1000 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 100.0 + +ns.fixed_dt = 0.005 +ns.cfl = 0.3 +ns.init_iter = 0 + +# Diffused IB input file +particle.input = particle_inputs + +# Refinement criterion, use vorticity and presence of tracer +amr.refinement_indicators = tracer box + +amr.max_level = 2 # maximum number of levels of refinement +amr.tracer.field_name = tracer +amr.tracer.value_greater = 0.01 + +amr.box.in_box_lo = 1. 2. 1. +amr.box.in_box_hi = 9. 18. 9. +amr.box.start_time = 0.0 +amr.box.end_time = 0.01 + +amr.n_error_buf = 2 +amr.blocking_factor = 4 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +# amr.n_cell = 16 8 8 +amr.n_cell = 32 64 32 +# amr.n_cell = 288 128 128 +amr.max_grid_size = 8 +# amr.max_grid_size = 32 + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 10 # regrid_int + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +nodal_proj.verbose = 1 +mac_proj.verbose = 1 + +# mac_proj.mac_tol = 0.1 +# mac_proj.mac_abs_tol = 0.1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files + +amr.check_int = 1000 + +#amr.restart = chk01400 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 100 + + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.01 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = -1.0 + +#******************************************************************************* + +# skip level_projector +ns.skip_level_projector = 0 + +#******************************************************************************* + +# subcycling vs. non-subcycling +amr.subcycling_mode = None + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 10 20 10 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 0 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 4 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 4 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 1 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +# amr.derive_plot_vars = avg_pressure + +#******************************************************************************* +ns.isolver = 1 +ns.do_diffused_ib = 1 +ns.fluid_rho = 1.0 + +#ns.sum_interval = 1 + +particles.do_nspc_particles = 0 + +nodal_proj.proj_tol = 1.e-8 +nodal_proj.proj_abs_tol = 1.e-9 + +nodal_proj.maxiter = 200 +nodal_proj.bottom_maxiter = 200 + +mac_proj.mac_tol = 1.e-8 +mac_proj.mac_abs_tol = 1.e-9 + + +############################ +# # +# Diffused IB cfg file # +# # +############################ + +particle_inputs.init = particle_init + +# particle's location +# x = p1x p2x p3x ... +particle_inputs.x = 0.0 +particle_inputs.y = 0.0 +particle_inputs.z = 0.0 + +# particle's density +# rho = p1r p2r p3r ... +particle_inputs.rho = 1.0 + +# particle's radius +# single +particle_inputs.radius = 0.5 + +# particle's velocity +# vx = p1vx p2vx p3vx ... +particle_inputs.velocity_x = 0.0 +particle_inputs.velocity_y = 0.0 +particle_inputs.velocity_z = 0.0 + +# particle's omega +# omega = p1omega_x p2omega_x p3omega_x ... +particle_inputs.omega_x = 0.0 +particle_inputs.omega_y = 0.0 +particle_inputs.omega_z = 0.0 + +# particle's 6DOF +# TLX = p1tl p2tl ... +particle_inputs.TLX = 0 +particle_inputs.TLY = 0 +particle_inputs.TLZ = 0 +particle_inputs.RLX = 0 +particle_inputs.RLY = 0 +particle_inputs.RLZ = 0 + + +# msg print +particle_inputs.verbose = 0 diff --git a/Tutorials/PVF/GNUmakefile b/Tutorials/PVF/GNUmakefile index 02b3d6a4..e2313491 100644 --- a/Tutorials/PVF/GNUmakefile +++ b/Tutorials/PVF/GNUmakefile @@ -1,30 +1,30 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 3 -COMP = gnu - -DEBUG = TRUE -USE_MPI = TRUE -USE_OMP = FALSE -PROFILE = FALSE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 3 +COMP = gnu + +DEBUG = TRUE +USE_MPI = TRUE +USE_OMP = FALSE +PROFILE = FALSE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/PVF/inputs.3d.pvf b/Tutorials/PVF/inputs.3d.pvf index c77ecc5f..cd67a314 100644 --- a/Tutorials/PVF/inputs.3d.pvf +++ b/Tutorials/PVF/inputs.3d.pvf @@ -1,148 +1,148 @@ - -#******************************************************************************* -# INPUTS.3D.PVF -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 1 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 4.0 - -ns.fixed_dt = 0.001 -ns.cfl = 0.3 -ns.init_iter = 0 - -# Refinement criterion, use vorticity and presence of tracer -amr.refinement_indicators = tracer - -amr.max_level = 2 # maximum number of levels of refinement -# amr.tracer.value_greater = 0.1 -# amr.tracer.value_less = 1.1 -amr.tracer.field_name = tracer -amr.tracer.in_box_lo = 0.5 0.5 0.5 -amr.tracer.in_box_hi = 1.5 1.5 1.5 - -amr.blocking_factor = 8 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -# amr.n_cell = 16 16 16 -amr.n_cell = 32 32 32 - -amr.max_grid_size = 128 - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 1 # regrid_int - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 0 -nodal_proj.verbose = 0 -mac_proj.verbose = 0 - -# mac_proj.mac_tol = 0.1 -# mac_proj.mac_abs_tol = 0.1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 1 -#amr.restart = chk01400 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 1 - - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.001 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.001 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 0.0 # -9.8 - -#******************************************************************************* - -# skip level_projector -ns.skip_level_projector = 0 - -#******************************************************************************* - -# subcycling vs. non-subcycling -amr.subcycling_mode = None - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 2. 2. 2. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 98 -prob.blob_center = 1. 1. 1. -prob.blob_radius = 0.4 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -# amr.derive_plot_vars = avg_pressure - -#******************************************************************************* -ns.isolver = 1 -ns.do_diffused_ib = 1 -ns.prescribed_vel = 1 - -ns.sum_interval = 1 + +#******************************************************************************* +# INPUTS.3D.PVF +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 1 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 4.0 + +ns.fixed_dt = 0.001 +ns.cfl = 0.3 +ns.init_iter = 0 + +# Refinement criterion, use vorticity and presence of tracer +amr.refinement_indicators = tracer + +amr.max_level = 2 # maximum number of levels of refinement +# amr.tracer.value_greater = 0.1 +# amr.tracer.value_less = 1.1 +amr.tracer.field_name = tracer +amr.tracer.in_box_lo = 0.5 0.5 0.5 +amr.tracer.in_box_hi = 1.5 1.5 1.5 + +amr.blocking_factor = 8 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +# amr.n_cell = 16 16 16 +amr.n_cell = 32 32 32 + +amr.max_grid_size = 128 + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 1 # regrid_int + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 0 +nodal_proj.verbose = 0 +mac_proj.verbose = 0 + +# mac_proj.mac_tol = 0.1 +# mac_proj.mac_abs_tol = 0.1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 1 +#amr.restart = chk01400 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 1 + + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.001 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.001 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 0.0 # -9.8 + +#******************************************************************************* + +# skip level_projector +ns.skip_level_projector = 0 + +#******************************************************************************* + +# subcycling vs. non-subcycling +amr.subcycling_mode = None + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 2. 2. 2. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 98 +prob.blob_center = 1. 1. 1. +prob.blob_radius = 0.4 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +# amr.derive_plot_vars = avg_pressure + +#******************************************************************************* +ns.isolver = 1 +ns.do_diffused_ib = 1 +ns.prescribed_vel = 1 + +ns.sum_interval = 1 diff --git a/Tutorials/Particles/GNUmakefile b/Tutorials/Particles/GNUmakefile index d83e404b..f47eeb8d 100644 --- a/Tutorials/Particles/GNUmakefile +++ b/Tutorials/Particles/GNUmakefile @@ -1,29 +1,29 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DEBUG = TRUE -DEBUG = FALSE - -DIM = 2 - -COMP = g++ - -USE_PARTICLES = TRUE - -USE_MPI = TRUE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DEBUG = TRUE +DEBUG = FALSE + +DIM = 2 + +COMP = g++ + +USE_PARTICLES = TRUE + +USE_MPI = TRUE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/Particles/fixed_grids_ml b/Tutorials/Particles/fixed_grids_ml index e01ab821..af2854d6 100644 --- a/Tutorials/Particles/fixed_grids_ml +++ b/Tutorials/Particles/fixed_grids_ml @@ -1,9 +1,9 @@ -2 -2 -((4,4) (32,32) (0,0)) -((36,40) (40,48) (0,0)) -1 -((16,20) (32,32) (0,0)) - - - +2 +2 +((4,4) (32,32) (0,0)) +((36,40) (40,48) (0,0)) +1 +((16,20) (32,32) (0,0)) + + + diff --git a/Tutorials/Particles/inputs_ml b/Tutorials/Particles/inputs_ml index 5918a016..edd0e96c 100644 --- a/Tutorials/Particles/inputs_ml +++ b/Tutorials/Particles/inputs_ml @@ -1,157 +1,157 @@ - -#******************************************************************************* -# INPUTS -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 0 -max_step = 800 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 5.0 - -#******************************************************************************* -# PARTICLE INPUTS - -particles.particle_init_file = particle_file_ml -particles.verbose = 1 -particles.timestamp_dir = particle_dir -particles.timestamp_indices = 1 - -#******************************************************************************* - -# Grid File - test this code with fixed grids -amr.regrid_file = fixed_grids_ml -# Grid efficiency (defaults to .70) -#amr.grid_eff = 0.75 - -#******************************************************************************* -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 64 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 2 # maximum number of levels of refinement - -# Refinement criterion, use vorticity -amr.refinement_indicators = vorticity -amr.vorticity.vorticity_greater = 5.0 - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 0 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 0 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 50 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 10 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 1.0 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.001 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs("gravity") "down" -ns.gravity = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 1. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 5 -# set up shear layer along x-direction -prob.direction = 0 -prob.interface_width = 2 -prob.blob_center = 0.25 0.25 -prob.blob_radius = 0.1 -prob.density_ic = 1.0 - -#******************************************************************************* - -# Factor by which grids must be coarsenable. -amr.blocking_factor = 4 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort particle_count - -#******************************************************************************* - -nodal_proj.verbose = 2 -nodal_proj.verbose = 1 -nodal_proj.proj_tol = 1.e-12 -nodal_proj.proj_abs_tol = 1.e-15 - -mg.v = 0 + +#******************************************************************************* +# INPUTS +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 0 +max_step = 800 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 5.0 + +#******************************************************************************* +# PARTICLE INPUTS + +particles.particle_init_file = particle_file_ml +particles.verbose = 1 +particles.timestamp_dir = particle_dir +particles.timestamp_indices = 1 + +#******************************************************************************* + +# Grid File - test this code with fixed grids +amr.regrid_file = fixed_grids_ml +# Grid efficiency (defaults to .70) +#amr.grid_eff = 0.75 + +#******************************************************************************* +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 64 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 2 # maximum number of levels of refinement + +# Refinement criterion, use vorticity +amr.refinement_indicators = vorticity +amr.vorticity.vorticity_greater = 5.0 + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 0 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 0 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 50 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 10 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 1.0 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.001 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs("gravity") "down" +ns.gravity = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 1. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 5 +# set up shear layer along x-direction +prob.direction = 0 +prob.interface_width = 2 +prob.blob_center = 0.25 0.25 +prob.blob_radius = 0.1 +prob.density_ic = 1.0 + +#******************************************************************************* + +# Factor by which grids must be coarsenable. +amr.blocking_factor = 4 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort particle_count + +#******************************************************************************* + +nodal_proj.verbose = 2 +nodal_proj.verbose = 1 +nodal_proj.proj_tol = 1.e-12 +nodal_proj.proj_abs_tol = 1.e-15 + +mg.v = 0 diff --git a/Tutorials/Particles/particle_file_ml b/Tutorials/Particles/particle_file_ml index 502e0919..7dfba012 100644 --- a/Tutorials/Particles/particle_file_ml +++ b/Tutorials/Particles/particle_file_ml @@ -1,5 +1,5 @@ -4 -0.4 0.4 -0.4 0.6 -0.4 0.8 -0.4 0.2 +4 +0.4 0.4 +0.4 0.6 +0.4 0.8 +0.4 0.2 diff --git a/Tutorials/Poiseuille/GNUmakefile b/Tutorials/Poiseuille/GNUmakefile index ec7c9ade..b6cbd784 100644 --- a/Tutorials/Poiseuille/GNUmakefile +++ b/Tutorials/Poiseuille/GNUmakefile @@ -1,30 +1,30 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 -COMP = gnu - -DEBUG = FALSE -USE_MPI = FALSE -USE_OMP = FALSE -PROFILE = FALSE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 +COMP = gnu + +DEBUG = FALSE +USE_MPI = FALSE +USE_OMP = FALSE +PROFILE = FALSE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/Poiseuille/inputs.2d.poiseuille b/Tutorials/Poiseuille/inputs.2d.poiseuille index e058ce21..e45c8d38 100644 --- a/Tutorials/Poiseuille/inputs.2d.poiseuille +++ b/Tutorials/Poiseuille/inputs.2d.poiseuille @@ -1,142 +1,142 @@ -#******************************************************************************* -# INPUTS.2D.POISEUILLE -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 1000 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = -1 - -# Tolerance for assuming system has reached steady-state -ns.stop_when_steady = 1 -ns.steady_tol = 1.0e-5 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 128 64 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 1 # maximum number of levels of refinement - -# Refinement criterion, use temperature -amr.refinement_indicators = tracer - -amr.tracer.value_greater = .01 -amr.tracer.field_name = tracer - -#******************************************************************************* - -# Set verbosity -ns.v = 10 -nodal_proj.verbose = 0 -nodal_proj.verbose = 0 -diffuse.v = 0 -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = -1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 10 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.5 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 0.3 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 1.0 - -#******************************************************************************* - -# Diffusion coefficient for tracer -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 1.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 2. 1. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -#ns.lo_bc = 1 5 - -# Boundary conditions on the high end of the domain. -#ns.hi_bc = 2 5 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary conditions -ylo.type = "nsw" -ylo.velocity = 0. 0. 0. -yhi.type = "nsw" -yhi.velocity = 0. 0. 0. -xlo.type = "mass_inflow" -xlo.velocity = 1. 0. 0. -xlo.density = 1. -xlo.tracer = 0. -xhi.type = "pressure_outflow" -xhi.pressure = 0.0 - - -#******************************************************************************* - -# PROBLEM PARAMETERS -prob.probtype = 4 -prob.blob_center = 0.15 0.5 0.5 -prob.blob_radius = 0.1 -# Constant density initial condition -prob.density_ic = 1.0 -# Set up constant flow -prob.velocity_ic = 1.0 0. 0. - -#******************************************************************************* - -# Continue from checkpoint -# amr.restart = chk00000 - -#******************************************************************************* - -# Write all derived quantities to plot files -amr.derive_plot_vars = ALL - -#******************************************************************************* +#******************************************************************************* +# INPUTS.2D.POISEUILLE +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 1000 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = -1 + +# Tolerance for assuming system has reached steady-state +ns.stop_when_steady = 1 +ns.steady_tol = 1.0e-5 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 128 64 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 1 # maximum number of levels of refinement + +# Refinement criterion, use temperature +amr.refinement_indicators = tracer + +amr.tracer.value_greater = .01 +amr.tracer.field_name = tracer + +#******************************************************************************* + +# Set verbosity +ns.v = 10 +nodal_proj.verbose = 0 +nodal_proj.verbose = 0 +diffuse.v = 0 +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = -1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 10 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.5 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 0.3 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 1.0 + +#******************************************************************************* + +# Diffusion coefficient for tracer +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 1.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 2. 1. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +#ns.lo_bc = 1 5 + +# Boundary conditions on the high end of the domain. +#ns.hi_bc = 2 5 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary conditions +ylo.type = "nsw" +ylo.velocity = 0. 0. 0. +yhi.type = "nsw" +yhi.velocity = 0. 0. 0. +xlo.type = "mass_inflow" +xlo.velocity = 1. 0. 0. +xlo.density = 1. +xlo.tracer = 0. +xhi.type = "pressure_outflow" +xhi.pressure = 0.0 + + +#******************************************************************************* + +# PROBLEM PARAMETERS +prob.probtype = 4 +prob.blob_center = 0.15 0.5 0.5 +prob.blob_radius = 0.1 +# Constant density initial condition +prob.density_ic = 1.0 +# Set up constant flow +prob.velocity_ic = 1.0 0. 0. + +#******************************************************************************* + +# Continue from checkpoint +# amr.restart = chk00000 + +#******************************************************************************* + +# Write all derived quantities to plot files +amr.derive_plot_vars = ALL + +#******************************************************************************* diff --git a/Tutorials/Poiseuille/inputs.3d.poiseuille b/Tutorials/Poiseuille/inputs.3d.poiseuille index 3c07af16..11fc8ad3 100644 --- a/Tutorials/Poiseuille/inputs.3d.poiseuille +++ b/Tutorials/Poiseuille/inputs.3d.poiseuille @@ -1,66 +1,66 @@ -#******************************************************************************* -# INPUTS.3D.POISEUILLE -#******************************************************************************* - -max_step = 1000 - -stop_time = -1 - -ns.stop_when_steady = 1 -ns.steady_tol = 1.0e-4 - -amr.n_cell = 32 16 16 - -amr.max_level = 2 - -# Refinement criterion, presence of tracer -amr.refinement_indicators = tracer -amr.tracer.value_greater = 0.1 -amr.tracer.field_name = tracer - -ns.v = 1 -amr.v = 1 - -amr.check_int = 1000 - -amr.plot_int = 10 - -ns.cfl = 0.5 # CFL number used to set dt - -ns.init_shrink = 0.3 # factor which multiplies the very first time step -ns.init_iter = 3 # number of initial iterations - -ns.vel_visc_coef = 1.0 -ns.scal_diff_coefs = 0.0 - -geometry.coord_sys = 0 - -geometry.prob_lo = 0. 0. 0. -geometry.prob_hi = 2. 1. 1. - -geometry.is_periodic = 0 0 0 - -ns.gravity = 1.0 - -ns.lo_bc = 1 5 5 -ns.hi_bc = 2 5 5 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary condition -xlo.velocity = 1. 0. 0. - -# PROBLEM PARAMETERS -prob.probtype = 4 -prob.blob_center = 0.15 0.5 0.5 -prob.blob_radius = 0.1 -prob.interface_width = 0.001 -# Constant density initial condition -prob.density_ic = 1.0 -# Set up constant flow -prob.velocity_ic = 1.0 0. 0. - -amr.derive_plot_vars = mag_vort -nodal_proj.verbose = 0 +#******************************************************************************* +# INPUTS.3D.POISEUILLE +#******************************************************************************* + +max_step = 1000 + +stop_time = -1 + +ns.stop_when_steady = 1 +ns.steady_tol = 1.0e-4 + +amr.n_cell = 32 16 16 + +amr.max_level = 2 + +# Refinement criterion, presence of tracer +amr.refinement_indicators = tracer +amr.tracer.value_greater = 0.1 +amr.tracer.field_name = tracer + +ns.v = 1 +amr.v = 1 + +amr.check_int = 1000 + +amr.plot_int = 10 + +ns.cfl = 0.5 # CFL number used to set dt + +ns.init_shrink = 0.3 # factor which multiplies the very first time step +ns.init_iter = 3 # number of initial iterations + +ns.vel_visc_coef = 1.0 +ns.scal_diff_coefs = 0.0 + +geometry.coord_sys = 0 + +geometry.prob_lo = 0. 0. 0. +geometry.prob_hi = 2. 1. 1. + +geometry.is_periodic = 0 0 0 + +ns.gravity = 1.0 + +ns.lo_bc = 1 5 5 +ns.hi_bc = 2 5 5 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary condition +xlo.velocity = 1. 0. 0. + +# PROBLEM PARAMETERS +prob.probtype = 4 +prob.blob_center = 0.15 0.5 0.5 +prob.blob_radius = 0.1 +prob.interface_width = 0.001 +# Constant density initial condition +prob.density_ic = 1.0 +# Set up constant flow +prob.velocity_ic = 1.0 0. 0. + +amr.derive_plot_vars = mag_vort +nodal_proj.verbose = 0 diff --git a/Tutorials/RSV/GNUmakefile b/Tutorials/RSV/GNUmakefile index dd3d1915..11d2e2a4 100644 --- a/Tutorials/RSV/GNUmakefile +++ b/Tutorials/RSV/GNUmakefile @@ -1,30 +1,30 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 -COMP = gnu - -DEBUG = FALSE -USE_MPI = TRUE -USE_OMP = FALSE -PROFILE = FALSE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 +COMP = gnu + +DEBUG = FALSE +USE_MPI = TRUE +USE_OMP = FALSE +PROFILE = FALSE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/RSV/inputs.2d.rsv b/Tutorials/RSV/inputs.2d.rsv index ea192452..b29997b6 100644 --- a/Tutorials/RSV/inputs.2d.rsv +++ b/Tutorials/RSV/inputs.2d.rsv @@ -1,155 +1,155 @@ - -#******************************************************************************* -# INPUTS.2D.RSV -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 1000 # 40000 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 4.0 - -ns.fixed_dt = 0.001953125 -#ns.fixed_dt = 0.0009765625 -#ns.fixed_dt = 0.00048828125 -ns.cfl = 0.3 - -# Refinement criterion, use vorticity and presence of tracer -amr.refinement_indicators = tracer vorticity - -amr.tracer.value_greater = 0.1 -amr.tracer.field_name = tracer - -amr.vorticity.vorticity_greater = 1.0 -#amr.vorticity.start_time = 0.001 -#amr.vorticity.end_name = 0.002 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 64 -#amr.n_cell = 128 128 -#amr.n_cell = 256 256 -amr.max_grid_size = 16 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 # regrid_int - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -nodal_proj.verbose = 1 -mac_proj.verbose = 1 - -# mac_proj.mac_tol = 0.1 -# mac_proj.mac_abs_tol = 0.1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 500 -#amr.restart = chk01400 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 500 -ns.sum_interval = 200 - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.001 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.001 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 0.0 # -9.8 - -#******************************************************************************* - -# skip level_projector -ns.skip_level_projector = 0 - -#******************************************************************************* - -# subcycling vs. non-subcycling -amr.subcycling_mode = Auto - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 1. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 99 -prob.blob_center = 0.5 0.75 -prob.blob_radius = 0.15 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -# amr.derive_plot_vars = mag_vort diveru avg_pressure - -#******************************************************************************* -ns.do_mom_diff = 0 -ns.do_phi = 1 -ns.do_cons_phi = 0 -ns.do_reinit = 1 -ns.lev0step_of_reinit = 1 -ns.number_of_reinit = 4 -ns.reinit_sussman = 1 -ns.prescribed_vel = 1 + +#******************************************************************************* +# INPUTS.2D.RSV +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 1000 # 40000 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 4.0 + +ns.fixed_dt = 0.001953125 +#ns.fixed_dt = 0.0009765625 +#ns.fixed_dt = 0.00048828125 +ns.cfl = 0.3 + +# Refinement criterion, use vorticity and presence of tracer +amr.refinement_indicators = tracer vorticity + +amr.tracer.value_greater = 0.1 +amr.tracer.field_name = tracer + +amr.vorticity.vorticity_greater = 1.0 +#amr.vorticity.start_time = 0.001 +#amr.vorticity.end_name = 0.002 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 64 +#amr.n_cell = 128 128 +#amr.n_cell = 256 256 +amr.max_grid_size = 16 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 # regrid_int + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +nodal_proj.verbose = 1 +mac_proj.verbose = 1 + +# mac_proj.mac_tol = 0.1 +# mac_proj.mac_abs_tol = 0.1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 500 +#amr.restart = chk01400 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 500 +ns.sum_interval = 200 + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.001 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.001 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 0.0 # -9.8 + +#******************************************************************************* + +# skip level_projector +ns.skip_level_projector = 0 + +#******************************************************************************* + +# subcycling vs. non-subcycling +amr.subcycling_mode = Auto + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 1. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 99 +prob.blob_center = 0.5 0.75 +prob.blob_radius = 0.15 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +# amr.derive_plot_vars = mag_vort diveru avg_pressure + +#******************************************************************************* +ns.do_mom_diff = 0 +ns.do_phi = 1 +ns.do_cons_phi = 0 +ns.do_reinit = 1 +ns.lev0step_of_reinit = 1 +ns.number_of_reinit = 4 +ns.reinit_sussman = 1 +ns.prescribed_vel = 1 diff --git a/Tutorials/RayleighTaylor/GNUmakefile b/Tutorials/RayleighTaylor/GNUmakefile index ec7c9ade..b6cbd784 100644 --- a/Tutorials/RayleighTaylor/GNUmakefile +++ b/Tutorials/RayleighTaylor/GNUmakefile @@ -1,30 +1,30 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 -COMP = gnu - -DEBUG = FALSE -USE_MPI = FALSE -USE_OMP = FALSE -PROFILE = FALSE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 +COMP = gnu + +DEBUG = FALSE +USE_MPI = FALSE +USE_OMP = FALSE +PROFILE = FALSE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/RayleighTaylor/inputs.2d.rayleightaylor b/Tutorials/RayleighTaylor/inputs.2d.rayleightaylor index c2848a45..0936c721 100644 --- a/Tutorials/RayleighTaylor/inputs.2d.rayleightaylor +++ b/Tutorials/RayleighTaylor/inputs.2d.rayleightaylor @@ -1,138 +1,138 @@ - -#******************************************************************************* -# INPUTS.2D.RT -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 5 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 2.5 - -# Refinement criterion, use vorticity -amr.refinement_indicators = vorticity - -amr.vorticity.vorticity_greater = 0.1 -#amr.vorticity.start_time = 0.001 -#amr.vorticity.end_name = 0.002 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 128 -amr.max_grid_size = 32 - -amr.grid_eff = 0.95 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 2 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 1 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 0.1 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.0 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = -1.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 0.5 1.0 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 4 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 2 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -prob.probtype= 10 -prob.interface_width = 0.01 -prob.perturbation_amplitude = 0.005 - -#******************************************************************************* - -# Factor by which grids must be coarsenable. -amr.blocking_factor = 8 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort diveru avg_pressure - -#******************************************************************************* - - + +#******************************************************************************* +# INPUTS.2D.RT +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 5 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 2.5 + +# Refinement criterion, use vorticity +amr.refinement_indicators = vorticity + +amr.vorticity.vorticity_greater = 0.1 +#amr.vorticity.start_time = 0.001 +#amr.vorticity.end_name = 0.002 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 128 +amr.max_grid_size = 32 + +amr.grid_eff = 0.95 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 2 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 1 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 0.1 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.0 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = -1.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 0.5 1.0 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 4 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 2 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +prob.probtype= 10 +prob.interface_width = 0.01 +prob.perturbation_amplitude = 0.005 + +#******************************************************************************* + +# Factor by which grids must be coarsenable. +amr.blocking_factor = 8 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort diveru avg_pressure + +#******************************************************************************* + + diff --git a/Tutorials/RayleighTaylor_LS/GNUmakefile b/Tutorials/RayleighTaylor_LS/GNUmakefile index 5f1504d2..a2cf7762 100644 --- a/Tutorials/RayleighTaylor_LS/GNUmakefile +++ b/Tutorials/RayleighTaylor_LS/GNUmakefile @@ -1,32 +1,32 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 # 3 -COMP = gnu - -DEBUG = FALSE -USE_MPI = TRUE -USE_OMP = FALSE -PROFILE = FALSE - -USE_CUDA = FALSE -#CUDA_ARCH = 80 -#CUDA_LAUNCH_BLOCK_BLOCKING=1 - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 # 3 +COMP = gnu + +DEBUG = FALSE +USE_MPI = TRUE +USE_OMP = FALSE +PROFILE = FALSE + +USE_CUDA = FALSE +#CUDA_ARCH = 80 +#CUDA_LAUNCH_BLOCK_BLOCKING=1 + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/RayleighTaylor_LS/inputs.2d.rayleightaylor_rt b/Tutorials/RayleighTaylor_LS/inputs.2d.rayleightaylor_rt index 43a1c7d5..79ee8a8f 100644 --- a/Tutorials/RayleighTaylor_LS/inputs.2d.rayleightaylor_rt +++ b/Tutorials/RayleighTaylor_LS/inputs.2d.rayleightaylor_rt @@ -1,167 +1,167 @@ - -#******************************************************************************* -# INPUTS.2D.RT_LS -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 500 # 10 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 2.5 # 2.5 -ns.fixed_dt = 0.0005 - -amr.subcycling_mode = None - -# Refinement criterion, use vorticity -amr.refinement_indicators = vorticity - -amr.vorticity.vorticity_greater = 0.1 # 10 -#amr.vorticity.start_time = 0.001 -#amr.vorticity.end_name = 0.002 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 128 512 -amr.max_grid_size = 32 - -#amr.n_cell = 32 128 -#amr.max_grid_size = 128 - -amr.grid_eff = 0.95 - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -nodal_proj.verbose = 1 -mac_proj.verbose = 1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 100 -#amr.restart = chk02000 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 50 # 200 -ns.sum_interval = 50 # 200 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 0.1 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.003132 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = -9.81 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 4. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 4 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 2 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -prob.probtype= 100 -prob.interface_width = 0.0078125 -prob.perturbation_amplitude = 0.1 -prob.rho_1 = 3.0 -prob.rho_2 = 1.0 - -#******************************************************************************* - -# Factor by which grids must be coarsenable. -amr.blocking_factor = 8 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort diveru avg_pressure - -#******************************************************************************* - -ns.do_mom_diff = 0 -ns.do_denminmax = 1 -ns.do_phi = 1 -ns.do_cons_phi = 1 -ns.do_reinit = 1 -ns.lev0step_of_reinit = 1 -ns.number_of_reinit = 4 -ns.reinit_sussman = 1 -ns.prescribed_vel = 0 - -ns.mu_a = 0.003132 -ns.mu_w = 0.003132 -#ns.mu_a = 0.0376 -#ns.mu_w = 0.0376 -ns.rho_a = 1.0 -ns.rho_w = 3.0 - -#ns.getForceVerbose = 1 -amrex.abort_on_out_of_gpu_memory = 1 -ns.isolver = 0 + +#******************************************************************************* +# INPUTS.2D.RT_LS +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 500 # 10 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 2.5 # 2.5 +ns.fixed_dt = 0.0005 + +amr.subcycling_mode = None + +# Refinement criterion, use vorticity +amr.refinement_indicators = vorticity + +amr.vorticity.vorticity_greater = 0.1 # 10 +#amr.vorticity.start_time = 0.001 +#amr.vorticity.end_name = 0.002 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 128 512 +amr.max_grid_size = 32 + +#amr.n_cell = 32 128 +#amr.max_grid_size = 128 + +amr.grid_eff = 0.95 + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +nodal_proj.verbose = 1 +mac_proj.verbose = 1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 100 +#amr.restart = chk02000 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 50 # 200 +ns.sum_interval = 50 # 200 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 0.1 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.003132 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = -9.81 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 4. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 4 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 2 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +prob.probtype= 100 +prob.interface_width = 0.0078125 +prob.perturbation_amplitude = 0.1 +prob.rho_1 = 3.0 +prob.rho_2 = 1.0 + +#******************************************************************************* + +# Factor by which grids must be coarsenable. +amr.blocking_factor = 8 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort diveru avg_pressure + +#******************************************************************************* + +ns.do_mom_diff = 0 +ns.do_denminmax = 1 +ns.do_phi = 1 +ns.do_cons_phi = 1 +ns.do_reinit = 1 +ns.lev0step_of_reinit = 1 +ns.number_of_reinit = 4 +ns.reinit_sussman = 1 +ns.prescribed_vel = 0 + +ns.mu_a = 0.003132 +ns.mu_w = 0.003132 +#ns.mu_a = 0.0376 +#ns.mu_w = 0.0376 +ns.rho_a = 1.0 +ns.rho_w = 3.0 + +#ns.getForceVerbose = 1 +amrex.abort_on_out_of_gpu_memory = 1 +ns.isolver = 0 diff --git a/Tutorials/SphereNearWall/GNUmakefile b/Tutorials/SphereNearWall/GNUmakefile index eac06bfc..d1b5d4da 100644 --- a/Tutorials/SphereNearWall/GNUmakefile +++ b/Tutorials/SphereNearWall/GNUmakefile @@ -1,31 +1,31 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 3 -COMP = gnu - -DEBUG = TRUE -USE_MPI = TRUE -USE_OMP = FALSE -PROFILE = FALSE -USE_PARTICLES = TRUE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 3 +COMP = gnu + +DEBUG = TRUE +USE_MPI = TRUE +USE_OMP = FALSE +PROFILE = FALSE +USE_PARTICLES = TRUE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/SphereNearWall/inputs.3d.SphereNearWall b/Tutorials/SphereNearWall/inputs.3d.SphereNearWall index 00a5c903..f8010824 100644 --- a/Tutorials/SphereNearWall/inputs.3d.SphereNearWall +++ b/Tutorials/SphereNearWall/inputs.3d.SphereNearWall @@ -1,213 +1,213 @@ - -#******************************************************************************* -# INPUTS.3D.SphereNearWall -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 10 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 10.0 - -ns.fixed_dt =0.01 -ns.cfl = 0.3 -ns.init_iter = 0 - -# Diffused IB input file -particle.input = particle_inputs - -# Refinement criterion, use vorticity and presence of tracer -amr.refinement_indicators = tracer - -amr.max_level = 0 # maximum number of levels of refinement -# amr.tracer.value_greater = 0.1 -# amr.tracer.value_less = 1.1 -amr.tracer.field_name = tracer -amr.tracer.in_box_lo = 0. 0. 0. -amr.tracer.in_box_hi = 50 8.505 14 - -amr.blocking_factor = 8 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -# amr.n_cell = 16 8 8 -amr.n_cell = 96 16 32 -# amr.n_cell = 288 128 128 -amr.max_grid_size = 16 -# amr.max_grid_size = 32 - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 1 # regrid_int - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -nodal_proj.verbose = 1 -mac_proj.verbose = 1 - -# mac_proj.mac_tol = 0.1 -# mac_proj.mac_abs_tol = 0.1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files - -amr.check_int = 100 - -#amr.restart = chk01400 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 1 - - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.01 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.00 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 0.0 # -9.8 - -#******************************************************************************* - -# skip level_projector -ns.skip_level_projector = 0 - -#******************************************************************************* - -# subcycling vs. non-subcycling -amr.subcycling_mode = None - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 50 8.505 14 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 1 4 4 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 2 4 4 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary condition -xlo.velocity = 1. 0. 0. - -#******************************************************************************* - -# Problem parameters -prob.probtype = 102 -prob.ub = 1 -prob.shearrate = 0.15 -prob.density_ic = 1.0 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -# amr.derive_plot_vars = avg_pressure - -#******************************************************************************* -ns.isolver = 1 -ns.do_diffused_ib = 1 - -#ns.sum_interval = 1 - -particles.do_nspc_particles = 0 - -nodal_proj.proj_tol = 1.e-8 -nodal_proj.proj_abs_tol = 1.e-9 - -mac_proj.mac_tol = 1.e-8 -mac_proj.mac_abs_tol = 1.e-9 - - -############################ -# # -# Diffused IB cfg file # -# # -############################ - -# particle's location -# x = p1x p2x p3x ... -particle_inputs.x = 25 -particle_inputs.y = 0.505 -particle_inputs.z = 7 - -# particle's density -# rho = p1r p2r p3r ... -particle_inputs.rho = 1.0 - -# particle's radius -# single -particle_inputs.radius = 0.5 - -# particle's velocity -# vx = p1vx p2vx p3vx ... -particle_inputs.velocity_x = 0.0 -particle_inputs.velocity_y = 0.0 -particle_inputs.velocity_z = 0.0 - -# particle's 6DOF -# TLX = p1tl p2tl ... -particle_inputs.TLX = 0 -particle_inputs.TLY = 0 -particle_inputs.TLZ = 0 -particle_inputs.RLX = 0 -particle_inputs.RLY = 0 -particle_inputs.RLZ = 0 - -# Ns loop time -particle_inputs.LOOP = 2 - - -# msg print -particle_inputs.verbose = 1 - -# Euler cfg -particle_inputs.euler_velocity_index = 0 -particle_inputs.euler_force_index = 0 -particle_inputs.euler_fluid_rho = 1.0 + +#******************************************************************************* +# INPUTS.3D.SphereNearWall +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 10 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 10.0 + +ns.fixed_dt =0.01 +ns.cfl = 0.3 +ns.init_iter = 0 + +# Diffused IB input file +particle.input = particle_inputs + +# Refinement criterion, use vorticity and presence of tracer +amr.refinement_indicators = tracer + +amr.max_level = 0 # maximum number of levels of refinement +# amr.tracer.value_greater = 0.1 +# amr.tracer.value_less = 1.1 +amr.tracer.field_name = tracer +amr.tracer.in_box_lo = 0. 0. 0. +amr.tracer.in_box_hi = 50 8.505 14 + +amr.blocking_factor = 8 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +# amr.n_cell = 16 8 8 +amr.n_cell = 96 16 32 +# amr.n_cell = 288 128 128 +amr.max_grid_size = 16 +# amr.max_grid_size = 32 + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 1 # regrid_int + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +nodal_proj.verbose = 1 +mac_proj.verbose = 1 + +# mac_proj.mac_tol = 0.1 +# mac_proj.mac_abs_tol = 0.1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files + +amr.check_int = 100 + +#amr.restart = chk01400 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 1 + + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.01 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.00 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 0.0 # -9.8 + +#******************************************************************************* + +# skip level_projector +ns.skip_level_projector = 0 + +#******************************************************************************* + +# subcycling vs. non-subcycling +amr.subcycling_mode = None + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 50 8.505 14 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 1 4 4 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 2 4 4 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary condition +xlo.velocity = 1. 0. 0. + +#******************************************************************************* + +# Problem parameters +prob.probtype = 102 +prob.ub = 1 +prob.shearrate = 0.15 +prob.density_ic = 1.0 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +# amr.derive_plot_vars = avg_pressure + +#******************************************************************************* +ns.isolver = 1 +ns.do_diffused_ib = 1 + +#ns.sum_interval = 1 + +particles.do_nspc_particles = 0 + +nodal_proj.proj_tol = 1.e-8 +nodal_proj.proj_abs_tol = 1.e-9 + +mac_proj.mac_tol = 1.e-8 +mac_proj.mac_abs_tol = 1.e-9 + + +############################ +# # +# Diffused IB cfg file # +# # +############################ + +# particle's location +# x = p1x p2x p3x ... +particle_inputs.x = 25 +particle_inputs.y = 0.505 +particle_inputs.z = 7 + +# particle's density +# rho = p1r p2r p3r ... +particle_inputs.rho = 1.0 + +# particle's radius +# single +particle_inputs.radius = 0.5 + +# particle's velocity +# vx = p1vx p2vx p3vx ... +particle_inputs.velocity_x = 0.0 +particle_inputs.velocity_y = 0.0 +particle_inputs.velocity_z = 0.0 + +# particle's 6DOF +# TLX = p1tl p2tl ... +particle_inputs.TLX = 0 +particle_inputs.TLY = 0 +particle_inputs.TLZ = 0 +particle_inputs.RLX = 0 +particle_inputs.RLY = 0 +particle_inputs.RLZ = 0 + +# Ns loop time +particle_inputs.LOOP = 2 + + +# msg print +particle_inputs.verbose = 1 + +# Euler cfg +particle_inputs.euler_velocity_index = 0 +particle_inputs.euler_force_index = 0 +particle_inputs.euler_fluid_rho = 1.0 diff --git a/Tutorials/SphereNearWall_Kempe/GNUmakefile b/Tutorials/SphereNearWall_Kempe/GNUmakefile index eac06bfc..d1b5d4da 100644 --- a/Tutorials/SphereNearWall_Kempe/GNUmakefile +++ b/Tutorials/SphereNearWall_Kempe/GNUmakefile @@ -1,31 +1,31 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 3 -COMP = gnu - -DEBUG = TRUE -USE_MPI = TRUE -USE_OMP = FALSE -PROFILE = FALSE -USE_PARTICLES = TRUE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 3 +COMP = gnu + +DEBUG = TRUE +USE_MPI = TRUE +USE_OMP = FALSE +PROFILE = FALSE +USE_PARTICLES = TRUE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/SphereNearWall_Kempe/inputs.3d.Shear_flow_sphere_rotation b/Tutorials/SphereNearWall_Kempe/inputs.3d.Shear_flow_sphere_rotation index 65271e3b..27f603b3 100644 --- a/Tutorials/SphereNearWall_Kempe/inputs.3d.Shear_flow_sphere_rotation +++ b/Tutorials/SphereNearWall_Kempe/inputs.3d.Shear_flow_sphere_rotation @@ -1,231 +1,231 @@ -#******************************************************************************* -# INPUTS.3D.SHEAR_FLOW_SPHERE_ROTATION -#******************************************************************************* - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 200000 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = -1 - -ns.fixed_dt = 0.001 -ns.cfl = 0.1 -ns.init_iter = 0 - -ns.fluid_rho = 1 - -# Diffused IB input file -particle.input = particle_inputs - -# Refinement criterion, use vorticity and presence of tracer -amr.refinement_indicators = tracer - -amr.max_level = 2 # maximum number of levels of refinement -# amr.tracer.value_greater = 0.1 -# amr.tracer.value_less = 1.1 -amr.tracer.field_name = tracer -amr.tracer.in_box_lo = 14.0 6.5 6.5 -amr.tracer.in_box_hi = 16.0 8.5 8.5 - -amr.n_error_buf = 5 -amr.blocking_factor = 8 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -# amr.n_cell = 16 8 8 -# amr.n_cell = 128 64 64 -amr.n_cell = 128 64 64 -# amr.n_cell = 512 256 256 -amr.max_grid_size = 16 -# amr.max_grid_size = 32 - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 200 # regrid_int - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -nodal_proj.verbose = 1 -mac_proj.verbose = 1 - -# mac_proj.mac_tol = 0.1 -# mac_proj.mac_abs_tol = 0.1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 10000 -# amr.restart = chk100000 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 2000 - - -#******************************************************************************* - -# Viscosity coefficient -# Re = 20, 100, 200 -ns.vel_visc_coef = 0.05 # Re = 20 -# ns.vel_visc_coef = 0.01 # Re = 100 -# ns.vel_visc_coef = 0.005 # Re = 200 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 0.0 # -9.8 - -#******************************************************************************* - -# skip level_projector -ns.skip_level_projector = 0 - -#******************************************************************************* - -# subcycling vs. non-subcycling -amr.subcycling_mode = None - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#************vel_visc_coef****************************************************************** - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 30. 15. 15. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 0 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 5 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 5 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary condition -ylo.velocity = -0.5 0. 0. -yhi.velocity = 2.5 0. 0. - -#******************************************************************************* - -# Problem parameters -prob.probtype = 102 -prob.ub = -0.5 -prob.shearrate = 0.2 -# prob.density_ic = 1.0 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -# amr.derive_plot_vars = avg_pressure - -#******************************************************************************* -ns.isolver = 1 -ns.do_diffused_ib = 1 - -#ns.sum_interval = 1 - -particles.do_nspc_particles = 0 - -nodal_proj.proj_tol = 1.e-8 -nodal_proj.proj_abs_tol = 1.e-9 - -nodal_proj.maxiter = 200 -nodal_proj.bottom_maxiter =200 - -mac_proj.mac_tol = 1.e-8 -mac_proj.mac_abs_tol = 1.e-9 - - - -############################ -# # -# Diffused IB cfg file # -# # -############################ - -# particle's location -# x = p1x p2x p3x ... -particle_inputs.x = 15.0 -particle_inputs.y = 7.5 -particle_inputs.z = 7.5 - -# particle's density -# rho = p1r p2r p3r ... -particle_inputs.rho = 1.05 -# particle_inputs.rho = 5.0 - -# particle's radius -# single -particle_inputs.radius = 0.5 - -# particle's velocity -# vx = p1vx p2vx p3vx ... -particle_inputs.velocity_x = 0.0 -particle_inputs.velocity_y = 0.0 -particle_inputs.velocity_z = 0.0 - - -particle_inputs.omega_x = 0.0 -particle_inputs.omega_y = 0.0 -particle_inputs.omega_z = 0.0 - - -# particle's 6DOF -# TLX = p1tl p2tl ... -particle_inputs.TLX = 0 -particle_inputs.TLY = 0 -particle_inputs.TLZ = 0 -particle_inputs.RLX = 0 -particle_inputs.RLY = 0 -particle_inputs.RLZ = 2 - -# Ns loop time -particle_inputs.LOOP_NS = 2 -particle_inputs.LOOP_SOLID = 2 -particle_inputs.start_step = 100000 - -# msg print -particle_inputs.verbose = 0 - -# Euler cfg -# particle_inputs.euler_velocity_index = 0 -# particle_inputs.euler_force_index = 0 -# particle_inputs.euler_fluid_rho = 1.0 - - - +#******************************************************************************* +# INPUTS.3D.SHEAR_FLOW_SPHERE_ROTATION +#******************************************************************************* + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 200000 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = -1 + +ns.fixed_dt = 0.001 +ns.cfl = 0.1 +ns.init_iter = 0 + +ns.fluid_rho = 1 + +# Diffused IB input file +particle.input = particle_inputs + +# Refinement criterion, use vorticity and presence of tracer +amr.refinement_indicators = tracer + +amr.max_level = 2 # maximum number of levels of refinement +# amr.tracer.value_greater = 0.1 +# amr.tracer.value_less = 1.1 +amr.tracer.field_name = tracer +amr.tracer.in_box_lo = 14.0 6.5 6.5 +amr.tracer.in_box_hi = 16.0 8.5 8.5 + +amr.n_error_buf = 5 +amr.blocking_factor = 8 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +# amr.n_cell = 16 8 8 +# amr.n_cell = 128 64 64 +amr.n_cell = 128 64 64 +# amr.n_cell = 512 256 256 +amr.max_grid_size = 16 +# amr.max_grid_size = 32 + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 200 # regrid_int + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +nodal_proj.verbose = 1 +mac_proj.verbose = 1 + +# mac_proj.mac_tol = 0.1 +# mac_proj.mac_abs_tol = 0.1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 10000 +# amr.restart = chk100000 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 2000 + + +#******************************************************************************* + +# Viscosity coefficient +# Re = 20, 100, 200 +ns.vel_visc_coef = 0.05 # Re = 20 +# ns.vel_visc_coef = 0.01 # Re = 100 +# ns.vel_visc_coef = 0.005 # Re = 200 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 0.0 # -9.8 + +#******************************************************************************* + +# skip level_projector +ns.skip_level_projector = 0 + +#******************************************************************************* + +# subcycling vs. non-subcycling +amr.subcycling_mode = None + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#************vel_visc_coef****************************************************************** + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 30. 15. 15. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 0 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 5 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 5 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary condition +ylo.velocity = -0.5 0. 0. +yhi.velocity = 2.5 0. 0. + +#******************************************************************************* + +# Problem parameters +prob.probtype = 102 +prob.ub = -0.5 +prob.shearrate = 0.2 +# prob.density_ic = 1.0 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +# amr.derive_plot_vars = avg_pressure + +#******************************************************************************* +ns.isolver = 1 +ns.do_diffused_ib = 1 + +#ns.sum_interval = 1 + +particles.do_nspc_particles = 0 + +nodal_proj.proj_tol = 1.e-8 +nodal_proj.proj_abs_tol = 1.e-9 + +nodal_proj.maxiter = 200 +nodal_proj.bottom_maxiter =200 + +mac_proj.mac_tol = 1.e-8 +mac_proj.mac_abs_tol = 1.e-9 + + + +############################ +# # +# Diffused IB cfg file # +# # +############################ + +# particle's location +# x = p1x p2x p3x ... +particle_inputs.x = 15.0 +particle_inputs.y = 7.5 +particle_inputs.z = 7.5 + +# particle's density +# rho = p1r p2r p3r ... +particle_inputs.rho = 1.05 +# particle_inputs.rho = 5.0 + +# particle's radius +# single +particle_inputs.radius = 0.5 + +# particle's velocity +# vx = p1vx p2vx p3vx ... +particle_inputs.velocity_x = 0.0 +particle_inputs.velocity_y = 0.0 +particle_inputs.velocity_z = 0.0 + + +particle_inputs.omega_x = 0.0 +particle_inputs.omega_y = 0.0 +particle_inputs.omega_z = 0.0 + + +# particle's 6DOF +# TLX = p1tl p2tl ... +particle_inputs.TLX = 0 +particle_inputs.TLY = 0 +particle_inputs.TLZ = 0 +particle_inputs.RLX = 0 +particle_inputs.RLY = 0 +particle_inputs.RLZ = 2 + +# Ns loop time +particle_inputs.LOOP_NS = 2 +particle_inputs.LOOP_SOLID = 2 +particle_inputs.start_step = 100000 + +# msg print +particle_inputs.verbose = 0 + +# Euler cfg +# particle_inputs.euler_velocity_index = 0 +# particle_inputs.euler_force_index = 0 +# particle_inputs.euler_fluid_rho = 1.0 + + + diff --git a/Tutorials/SphereNearWall_Kempe/inputs.3d.Uniform_flow_spherical_translation b/Tutorials/SphereNearWall_Kempe/inputs.3d.Uniform_flow_spherical_translation index 1faaa62f..fddde86b 100644 --- a/Tutorials/SphereNearWall_Kempe/inputs.3d.Uniform_flow_spherical_translation +++ b/Tutorials/SphereNearWall_Kempe/inputs.3d.Uniform_flow_spherical_translation @@ -1,233 +1,233 @@ -#******************************************************************************* -# INPUTS.3D.UNIFORM_FLOW_SPHERICAL_TRANSLATION -#******************************************************************************* - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 200000 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = -1 - -ns.fixed_dt = 0.001 -ns.cfl = 0.1 -ns.init_iter = 0 - -ns.fluid_rho = 1 - -# Diffused IB input file -particle.input = particle_inputs - -# Refinement criterion, use vorticity and presence of tracer -amr.refinement_indicators = tracer - -amr.max_level = 2 # maximum number of levels of refinement -amr.tracer.field_name = tracer -amr.tracer.value_greater = 0.001 -# amr.tracer.value_less = 1.1 - -amr.tracer.in_box_lo = 14.0 6.5 6.5 -amr.tracer.in_box_hi = 16.0 8.5 8.5 - -amr.n_error_buf = 5 -amr.blocking_factor = 8 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -# amr.n_cell = 16 8 8 -# amr.n_cell = 128 64 64 -amr.n_cell = 128 64 64 -# amr.n_cell = 512 256 256 -amr.max_grid_size = 16 -# amr.max_grid_size = 32 - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 100 # regrid_int - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -nodal_proj.verbose = 1 -mac_proj.verbose = 1 - -# mac_proj.mac_tol = 0.1 -# mac_proj.mac_abs_tol = 0.1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 10000 -# amr.restart = chk100000 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 2000 - - -#******************************************************************************* - -# Viscosity coefficient -# Re = 20, 100, 200 -ns.vel_visc_coef = 0.05 # Re = 20 -# ns.vel_visc_coef = 0.01 # Re = 100 -# ns.vel_visc_coef = 0.005 # Re = 200 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 0.0 # -9.8 - -#******************************************************************************* - -# skip level_projector -ns.skip_level_projector = 0 - -#******************************************************************************* - -# subcycling vs. non-subcycling -amr.subcycling_mode = None - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#************vel_visc_coef****************************************************************** - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 30. 15. 15. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 0 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 5 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 5 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary condition -ylo.velocity = 1.0 0. 0. -yhi.velocity = 1.0 0. 0. - -#******************************************************************************* - -# Problem parameters -prob.probtype = 102 -prob.ub = 1.0 -prob.shearrate = 0.0 -# prob.density_ic = 1.0 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -# amr.derive_plot_vars = avg_pressure - -#******************************************************************************* -ns.isolver = 1 -ns.do_diffused_ib = 1 - -#ns.sum_interval = 1 - -particles.do_nspc_particles = 0 - -nodal_proj.proj_tol = 1.e-8 -nodal_proj.proj_abs_tol = 1.e-9 - -nodal_proj.maxiter = 200 -nodal_proj.bottom_maxiter =200 - -mac_proj.mac_tol = 1.e-8 -mac_proj.mac_abs_tol = 1.e-9 - - - -############################ -# # -# Diffused IB cfg file # -# # -############################ - -# particle's location -# x = p1x p2x p3x ... -particle_inputs.x = 15.0 -particle_inputs.y = 7.5 -particle_inputs.z = 7.5 - -# particle's density -# rho = p1r p2r p3r ... -particle_inputs.rho = 1.05 -# particle_inputs.rho = 5.0 - - -# particle's radius -# single -particle_inputs.radius = 0.5 - -# particle's velocity -# vx = p1vx p2vx p3vx ... -particle_inputs.velocity_x = 0.0 -particle_inputs.velocity_y = 0.0 -particle_inputs.velocity_z = 0.0 - - -particle_inputs.omega_x = 0.0 -particle_inputs.omega_y = 0.0 -particle_inputs.omega_z = 0.0 - - -# particle's 6DOF -# TLX = p1tl p2tl ... -particle_inputs.TLX = 2 -particle_inputs.TLY = 0 -particle_inputs.TLZ = 0 -particle_inputs.RLX = 0 -particle_inputs.RLY = 0 -particle_inputs.RLZ = 0 - -# Ns loop time -particle_inputs.LOOP_NS = 2 -particle_inputs.LOOP_SOLID = 2 -particle_inputs.start_step = 100000 - -# msg print -particle_inputs.verbose = 0 - -# Euler cfg -# particle_inputs.euler_velocity_index = 0 -# particle_inputs.euler_force_index = 0 -# particle_inputs.euler_fluid_rho = 1.0 - - - +#******************************************************************************* +# INPUTS.3D.UNIFORM_FLOW_SPHERICAL_TRANSLATION +#******************************************************************************* + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 200000 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = -1 + +ns.fixed_dt = 0.001 +ns.cfl = 0.1 +ns.init_iter = 0 + +ns.fluid_rho = 1 + +# Diffused IB input file +particle.input = particle_inputs + +# Refinement criterion, use vorticity and presence of tracer +amr.refinement_indicators = tracer + +amr.max_level = 2 # maximum number of levels of refinement +amr.tracer.field_name = tracer +amr.tracer.value_greater = 0.001 +# amr.tracer.value_less = 1.1 + +amr.tracer.in_box_lo = 14.0 6.5 6.5 +amr.tracer.in_box_hi = 16.0 8.5 8.5 + +amr.n_error_buf = 5 +amr.blocking_factor = 8 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +# amr.n_cell = 16 8 8 +# amr.n_cell = 128 64 64 +amr.n_cell = 128 64 64 +# amr.n_cell = 512 256 256 +amr.max_grid_size = 16 +# amr.max_grid_size = 32 + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 100 # regrid_int + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +nodal_proj.verbose = 1 +mac_proj.verbose = 1 + +# mac_proj.mac_tol = 0.1 +# mac_proj.mac_abs_tol = 0.1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 10000 +# amr.restart = chk100000 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 2000 + + +#******************************************************************************* + +# Viscosity coefficient +# Re = 20, 100, 200 +ns.vel_visc_coef = 0.05 # Re = 20 +# ns.vel_visc_coef = 0.01 # Re = 100 +# ns.vel_visc_coef = 0.005 # Re = 200 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 0.0 # -9.8 + +#******************************************************************************* + +# skip level_projector +ns.skip_level_projector = 0 + +#******************************************************************************* + +# subcycling vs. non-subcycling +amr.subcycling_mode = None + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#************vel_visc_coef****************************************************************** + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 30. 15. 15. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 0 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 5 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 5 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary condition +ylo.velocity = 1.0 0. 0. +yhi.velocity = 1.0 0. 0. + +#******************************************************************************* + +# Problem parameters +prob.probtype = 102 +prob.ub = 1.0 +prob.shearrate = 0.0 +# prob.density_ic = 1.0 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +# amr.derive_plot_vars = avg_pressure + +#******************************************************************************* +ns.isolver = 1 +ns.do_diffused_ib = 1 + +#ns.sum_interval = 1 + +particles.do_nspc_particles = 0 + +nodal_proj.proj_tol = 1.e-8 +nodal_proj.proj_abs_tol = 1.e-9 + +nodal_proj.maxiter = 200 +nodal_proj.bottom_maxiter =200 + +mac_proj.mac_tol = 1.e-8 +mac_proj.mac_abs_tol = 1.e-9 + + + +############################ +# # +# Diffused IB cfg file # +# # +############################ + +# particle's location +# x = p1x p2x p3x ... +particle_inputs.x = 15.0 +particle_inputs.y = 7.5 +particle_inputs.z = 7.5 + +# particle's density +# rho = p1r p2r p3r ... +particle_inputs.rho = 1.05 +# particle_inputs.rho = 5.0 + + +# particle's radius +# single +particle_inputs.radius = 0.5 + +# particle's velocity +# vx = p1vx p2vx p3vx ... +particle_inputs.velocity_x = 0.0 +particle_inputs.velocity_y = 0.0 +particle_inputs.velocity_z = 0.0 + + +particle_inputs.omega_x = 0.0 +particle_inputs.omega_y = 0.0 +particle_inputs.omega_z = 0.0 + + +# particle's 6DOF +# TLX = p1tl p2tl ... +particle_inputs.TLX = 2 +particle_inputs.TLY = 0 +particle_inputs.TLZ = 0 +particle_inputs.RLX = 0 +particle_inputs.RLY = 0 +particle_inputs.RLZ = 0 + +# Ns loop time +particle_inputs.LOOP_NS = 2 +particle_inputs.LOOP_SOLID = 2 +particle_inputs.start_step = 100000 + +# msg print +particle_inputs.verbose = 0 + +# Euler cfg +# particle_inputs.euler_velocity_index = 0 +# particle_inputs.euler_force_index = 0 +# particle_inputs.euler_fluid_rho = 1.0 + + + diff --git a/Tutorials/TaylorGreen/GNUmakefile b/Tutorials/TaylorGreen/GNUmakefile index edccef1c..6552b280 100644 --- a/Tutorials/TaylorGreen/GNUmakefile +++ b/Tutorials/TaylorGreen/GNUmakefile @@ -1,30 +1,30 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 -COMP = gnu - -DEBUG = FALSE -USE_MPI = TRUE -USE_OMP = FALSE -PROFILE = FALSE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 +COMP = gnu + +DEBUG = FALSE +USE_MPI = TRUE +USE_OMP = FALSE +PROFILE = FALSE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/TaylorGreen/inputs.2d.taylorgreen b/Tutorials/TaylorGreen/inputs.2d.taylorgreen index 8281d58a..0497337f 100644 --- a/Tutorials/TaylorGreen/inputs.2d.taylorgreen +++ b/Tutorials/TaylorGreen/inputs.2d.taylorgreen @@ -1,115 +1,115 @@ - -#******************************************************************************* -# INPUTS.2D.TAYLORGREEN -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 10000 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 6.0 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 64 64 -amr.max_grid_size = 1024 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 2 2 2 2 2 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -ns.sum_interval = 1 -ns.init_iter = 2 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = -5 -amr.check_file = chk - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 100 -amr.plot_file = plt - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.7 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 1.0 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 1.e-2 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0.0 0.0 0.0 - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1.0 1.0 1.0 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 11 -prob.velocity_factor = 1.0 - + +#******************************************************************************* +# INPUTS.2D.TAYLORGREEN +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 10000 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 6.0 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 64 64 +amr.max_grid_size = 1024 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 2 2 2 2 2 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +ns.sum_interval = 1 +ns.init_iter = 2 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = -5 +amr.check_file = chk + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 100 +amr.plot_file = plt + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.7 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 1.0 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 1.e-2 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0.0 0.0 0.0 + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1.0 1.0 1.0 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 11 +prob.velocity_factor = 1.0 + diff --git a/Tutorials/TaylorGreen/inputs.3d.taylorgreen b/Tutorials/TaylorGreen/inputs.3d.taylorgreen index 27b00511..d2bb527a 100644 --- a/Tutorials/TaylorGreen/inputs.3d.taylorgreen +++ b/Tutorials/TaylorGreen/inputs.3d.taylorgreen @@ -1,121 +1,121 @@ - -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 1000 -stop_time = 0.1 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 64 64 -amr.max_grid_size = 1024 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 2 2 2 2 2 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 100 -amr.check_file = chk - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 100 -amr.plot_file = plt - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.7 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 1.0 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 1.e-4 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0.0 0.0 0.0 - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1.0 1.0 1.0 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 11 -prob.velocity_factor = 1.0 -prob.c = 0 - -#******************************************************************************* - -# Factor by which grids must be coarsenable. -amr.blocking_factor = 8 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = NONE - -#******************************************************************************* + +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 1000 +stop_time = 0.1 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 64 64 +amr.max_grid_size = 1024 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 2 2 2 2 2 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 100 +amr.check_file = chk + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 100 +amr.plot_file = plt + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.7 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 1.0 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 1.e-4 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0.0 0.0 0.0 + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1.0 1.0 1.0 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 11 +prob.velocity_factor = 1.0 +prob.c = 0 + +#******************************************************************************* + +# Factor by which grids must be coarsenable. +amr.blocking_factor = 8 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = NONE + +#******************************************************************************* diff --git a/Tutorials/TracerAdvection/GNUmakefile b/Tutorials/TracerAdvection/GNUmakefile index ec7c9ade..b6cbd784 100644 --- a/Tutorials/TracerAdvection/GNUmakefile +++ b/Tutorials/TracerAdvection/GNUmakefile @@ -1,30 +1,30 @@ -#AMREX_HOME defines the directory in which we will find the AMReX directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 -COMP = gnu - -DEBUG = FALSE -USE_MPI = FALSE -USE_OMP = FALSE -PROFILE = FALSE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the AMReX directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 +COMP = gnu + +DEBUG = FALSE +USE_MPI = FALSE +USE_OMP = FALSE +PROFILE = FALSE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials/TracerAdvection/inputs.2d.traceradvect b/Tutorials/TracerAdvection/inputs.2d.traceradvect index 2e0c1aec..bf21fb42 100644 --- a/Tutorials/TracerAdvection/inputs.2d.traceradvect +++ b/Tutorials/TracerAdvection/inputs.2d.traceradvect @@ -1,120 +1,120 @@ - -#******************************************************************************* -# INPUTS.2D.TRACERADVECT -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 50 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 10000 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 64 -amr.max_grid_size = 64 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 10 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 10 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 1.0 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.0 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 1. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 4 -prob.velocity_ic = 1.0 2.0 -prob.density_ic = 1.0 -prob.blob_center = 0.5 0.5 - -#******************************************************************************* - + +#******************************************************************************* +# INPUTS.2D.TRACERADVECT +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 50 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 10000 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 64 +amr.max_grid_size = 64 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 10 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 10 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 1.0 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.0 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 1. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 4 +prob.velocity_ic = 1.0 2.0 +prob.density_ic = 1.0 +prob.blob_center = 0.5 0.5 + +#******************************************************************************* + diff --git a/Tutorials/TracerAdvection/inputs.3d.traceradvect b/Tutorials/TracerAdvection/inputs.3d.traceradvect index a1de5187..a074cc0a 100644 --- a/Tutorials/TracerAdvection/inputs.3d.traceradvect +++ b/Tutorials/TracerAdvection/inputs.3d.traceradvect @@ -1,117 +1,117 @@ - -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 10 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 100 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 32 32 32 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 2 2 2 2 2 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -ns.sum_interval = 1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 5 -amr.check_file = chk - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 1 -amr.plot_file = plt - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 1.0 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 1.0 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.0 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1.0 1.0 1.0 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 4 -prob.velocity_ic = 1.0 2.0 3.0 -prob.density_ic = 1.0 -prob.blob_center = 0.5 0.5 0.5 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort + +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 10 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 100 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 32 32 32 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 2 2 2 2 2 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +ns.sum_interval = 1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 5 +amr.check_file = chk + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 1 +amr.plot_file = plt + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 1.0 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 1.0 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.0 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1.0 1.0 1.0 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 4 +prob.velocity_ic = 1.0 2.0 3.0 +prob.density_ic = 1.0 +prob.blob_center = 0.5 0.5 0.5 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort diff --git a/Tutorials_profiling/Bubble/GNUmakefile b/Tutorials_profiling/Bubble/GNUmakefile index 68fd8801..50084856 100644 --- a/Tutorials_profiling/Bubble/GNUmakefile +++ b/Tutorials_profiling/Bubble/GNUmakefile @@ -1,30 +1,37 @@ -#AMREX_HOME defines the directory in which we will find the BoxLib directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 # DIM -COMP = gnu - -DEBUG = FALSE -USE_MPI = TRUE # MPI -USE_OMP = TRUE # OMP -PROFILE = TRUE - -USE_CUDA = FALSE # CUDA - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#AMREX_HOME defines the directory in which we will find the BoxLib directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 # DIM +COMP = gnu + +DEBUG = FALSE +USE_MPI = TRUE # MPI +USE_OMP = TRUE # OMP +PROFILE = TRUE + +USE_CUDA = FALSE # CUDA + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials_profiling/Bubble/inputs.2d.bubble b/Tutorials_profiling/Bubble/inputs.2d.bubble index 0cced333..d9bb561d 100644 --- a/Tutorials_profiling/Bubble/inputs.2d.bubble +++ b/Tutorials_profiling/Bubble/inputs.2d.bubble @@ -1,149 +1,155 @@ - -#******************************************************************************* -# INPUTS.2D.BUBBLE -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 200 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 5.0 - -# Refinement criterion, use vorticity and presence of tracer -amr.refinement_indicators = tracer vorticity - -amr.tracer.value_greater = 0.1 -amr.tracer.field_name = tracer - -amr.vorticity.vorticity_greater = 1.0 -#amr.vorticity.start_time = 0.001 -#amr.vorticity.end_name = 0.002 - - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 128 128 # n_cell -amr.max_grid_size = 8 # max_grid_size - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # max_level - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 4 # regrid_int - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 0 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 0 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 50 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 50 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 0.3 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.001 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.001 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = -9.8 - -#******************************************************************************* - -# skip level_projector -ns.skip_level_projector = 0 # skip_level_projector - -#******************************************************************************* - -# subcycling vs. non-subcycling -amr.subcycling_mode = Auto # subcycling_mode - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = -1. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 2. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 4 4 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 4 4 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 2 -prob.blob_center = 0.0 1.5 -prob.blob_radius = 0.2 -# Background density is 1. Density is increased by a factor of density_ic inside -# the bubble -prob.density_ic = 2.0 -# Can also set up a flow, defaults to zero -#prob.velocity_ic = 0. 0. 0. - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort diveru avg_pressure - -#******************************************************************************* +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# INPUTS.2D.BUBBLE +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 200 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 5.0 + +# Refinement criterion, use vorticity and presence of tracer +amr.refinement_indicators = tracer vorticity + +amr.tracer.value_greater = 0.1 +amr.tracer.field_name = tracer + +amr.vorticity.vorticity_greater = 1.0 +#amr.vorticity.start_time = 0.001 +#amr.vorticity.end_name = 0.002 + + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 128 128 # n_cell +amr.max_grid_size = 8 # max_grid_size + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # max_level + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 4 # regrid_int + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 0 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 0 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 50 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 50 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 0.3 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.001 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.001 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = -9.8 + +#******************************************************************************* + +# skip level_projector +ns.skip_level_projector = 0 # skip_level_projector + +#******************************************************************************* + +# subcycling vs. non-subcycling +amr.subcycling_mode = Auto # subcycling_mode + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = -1. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 2. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 4 4 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 4 4 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 2 +prob.blob_center = 0.0 1.5 +prob.blob_radius = 0.2 +# Background density is 1. Density is increased by a factor of density_ic inside +# the bubble +prob.density_ic = 2.0 +# Can also set up a flow, defaults to zero +#prob.velocity_ic = 0. 0. 0. + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort diveru avg_pressure + +#******************************************************************************* diff --git a/Tutorials_profiling/Bubble/inputs.2d.bubble_rz b/Tutorials_profiling/Bubble/inputs.2d.bubble_rz index 409fe8a5..9a8af2d8 100644 --- a/Tutorials_profiling/Bubble/inputs.2d.bubble_rz +++ b/Tutorials_profiling/Bubble/inputs.2d.bubble_rz @@ -1,125 +1,131 @@ - -#******************************************************************************* -# INPUTS.2D.BUBBLE_RZ -#******************************************************************************* - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 10 - -# Refinement criterion, use vorticity and presence of tracer -amr.refinement_indicators = tracer vorticity - -amr.tracer.value_greater = 0.1 -amr.tracer.field_name = tracer - -amr.vorticity.vorticity_greater = 1.0 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 128 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 2 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 50 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 50 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 0.3 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0. #001 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.001 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = -9.8 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 1 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 2. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 3 4 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 4 4 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 2 -prob.blob_center = 0.0 1.5 -prob.blob_radius = 0.2 -# Background density is 1. Density is increased by a factor of density_ic inside -# the bubble -prob.density_ic = 2.0 -# Can also set up a flow, defaults to zero -#prob.velocity_ic = 0. 0. 0. - -#******************************************************************************* +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# INPUTS.2D.BUBBLE_RZ +#******************************************************************************* + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 10 + +# Refinement criterion, use vorticity and presence of tracer +amr.refinement_indicators = tracer vorticity + +amr.tracer.value_greater = 0.1 +amr.tracer.field_name = tracer + +amr.vorticity.vorticity_greater = 1.0 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 128 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 2 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 50 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 50 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 0.3 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0. #001 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.001 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = -9.8 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 1 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 2. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 3 4 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 4 4 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 2 +prob.blob_center = 0.0 1.5 +prob.blob_radius = 0.2 +# Background density is 1. Density is increased by a factor of density_ic inside +# the bubble +prob.density_ic = 2.0 +# Can also set up a flow, defaults to zero +#prob.velocity_ic = 0. 0. 0. + +#******************************************************************************* diff --git a/Tutorials_profiling/ConvectedVortex/AMReX_buildInfo.cpp b/Tutorials_profiling/ConvectedVortex/AMReX_buildInfo.cpp index 80241919..e0bb11c3 100644 --- a/Tutorials_profiling/ConvectedVortex/AMReX_buildInfo.cpp +++ b/Tutorials_profiling/ConvectedVortex/AMReX_buildInfo.cpp @@ -1,179 +1,179 @@ - -namespace amrex { - -const char* buildInfoGetBuildDate() { - - static const char BUILD_DATE[] = "2023-07-04 17:02:53.812793"; - return BUILD_DATE; -} - -const char* buildInfoGetBuildDir() { - - static const char BUILD_DIR[] = "/scratch1/jordan/amr_cycling_paper/IAMR/Tutorials_profiling/ConvectedVortex"; - return BUILD_DIR; -} - -const char* buildInfoGetBuildMachine() { - - static const char BUILD_MACHINE[] = "Linux mirror 5.14.21-150400.24.46-default #1 SMP PREEMPT_DYNAMIC Thu Feb 9 08:38:18 UTC 2023 (2d95137) x86_64 x86_64 x86_64 GNU/Linux"; - return BUILD_MACHINE; -} - -const char* buildInfoGetAMReXDir() { - - static const char AMREX_DIR[] = "../../../amrex"; - return AMREX_DIR; -} - -const char* buildInfoGetComp() { - - static const char COMP[] = "gnu"; - return COMP; -} - -const char* buildInfoGetCompVersion() { - - static const char COMP_VERSION[] = "9.3.1"; - return COMP_VERSION; -} - -// deprecated -const char* buildInfoGetFcomp() { - - static const char FCOMP[] = ""; - return FCOMP; -} - -// deprecated -const char* buildInfoGetFcompVersion() { - - static const char FCOMP_VERSION[] = ""; - return FCOMP_VERSION; -} - -const char* buildInfoGetCXXName() { - - static const char CXX_comp_name[] = ""; - return CXX_comp_name; -} - -const char* buildInfoGetFName() { - - static const char F_comp_name[] = ""; - return F_comp_name; -} - -const char* buildInfoGetCXXFlags() { - - static const char CXX_flags[] = ""; - return CXX_flags; -} - -const char* buildInfoGetFFlags() { - - static const char F_flags[] = ""; - return F_flags; -} - -const char* buildInfoGetLinkFlags() { - - static const char link_flags[] = ""; - return link_flags; -} - -const char* buildInfoGetLibraries() { - - static const char libraries[] = ""; - return libraries; -} - -const char* buildInfoGetAux(int i) { - - //static const char AUX1[] = "${AUX[1]}"; - - static const char EMPT[] = ""; - - switch(i) - { - - default: return EMPT; - } -} - -int buildInfoGetNumModules() { - // int num_modules = X; - int num_modules = 0; - - return num_modules; -} - -const char* buildInfoGetModuleName(int i) { - - //static const char MNAME1[] = "${MNAME[1]}"; - - static const char EMPT[] = ""; - - switch(i) - { - - default: return EMPT; - } -} - -const char* buildInfoGetModuleVal(int i) { - - //static const char MVAL1[] = "${MVAL[1]}"; - - static const char EMPT[] = ""; - - switch(i) - { - - default: return EMPT; - } -} - -const char* buildInfoGetGitHash(int i) { - - //static const char HASH1[] = "${GIT[1]}"; - static const char HASH1[] = "22.12-18-g9832c557-dirty"; - static const char HASH2[] = "20.06-1908-gdce19d534"; - - static const char EMPT[] = ""; - - switch(i) - { - case 1: return HASH1; - case 2: return HASH2; - - default: return EMPT; - } -} - -const char* buildInfoGetBuildGitHash() { - - //static const char HASH[] = "${GIT}"; - static const char HASH[] = ""; - - - return HASH; -} - -const char* buildInfoGetBuildGitName() { - - //static const char NAME[] = ""; - static const char NAME[] = ""; - - - return NAME; -} - -#ifdef AMREX_USE_CUDA -const char* buildInfoGetCUDAVersion() { - - static const char CUDA_VERSION[] = ""; - return CUDA_VERSION; -} -#endif - -} + +namespace amrex { + +const char* buildInfoGetBuildDate() { + + static const char BUILD_DATE[] = "2023-07-04 17:02:53.812793"; + return BUILD_DATE; +} + +const char* buildInfoGetBuildDir() { + + static const char BUILD_DIR[] = "/scratch1/jordan/amr_cycling_paper/IAMR/Tutorials_profiling/ConvectedVortex"; + return BUILD_DIR; +} + +const char* buildInfoGetBuildMachine() { + + static const char BUILD_MACHINE[] = "Linux mirror 5.14.21-150400.24.46-default #1 SMP PREEMPT_DYNAMIC Thu Feb 9 08:38:18 UTC 2023 (2d95137) x86_64 x86_64 x86_64 GNU/Linux"; + return BUILD_MACHINE; +} + +const char* buildInfoGetAMReXDir() { + + static const char AMREX_DIR[] = "../../../amrex"; + return AMREX_DIR; +} + +const char* buildInfoGetComp() { + + static const char COMP[] = "gnu"; + return COMP; +} + +const char* buildInfoGetCompVersion() { + + static const char COMP_VERSION[] = "9.3.1"; + return COMP_VERSION; +} + +// deprecated +const char* buildInfoGetFcomp() { + + static const char FCOMP[] = ""; + return FCOMP; +} + +// deprecated +const char* buildInfoGetFcompVersion() { + + static const char FCOMP_VERSION[] = ""; + return FCOMP_VERSION; +} + +const char* buildInfoGetCXXName() { + + static const char CXX_comp_name[] = ""; + return CXX_comp_name; +} + +const char* buildInfoGetFName() { + + static const char F_comp_name[] = ""; + return F_comp_name; +} + +const char* buildInfoGetCXXFlags() { + + static const char CXX_flags[] = ""; + return CXX_flags; +} + +const char* buildInfoGetFFlags() { + + static const char F_flags[] = ""; + return F_flags; +} + +const char* buildInfoGetLinkFlags() { + + static const char link_flags[] = ""; + return link_flags; +} + +const char* buildInfoGetLibraries() { + + static const char libraries[] = ""; + return libraries; +} + +const char* buildInfoGetAux(int i) { + + //static const char AUX1[] = "${AUX[1]}"; + + static const char EMPT[] = ""; + + switch(i) + { + + default: return EMPT; + } +} + +int buildInfoGetNumModules() { + // int num_modules = X; + int num_modules = 0; + + return num_modules; +} + +const char* buildInfoGetModuleName(int i) { + + //static const char MNAME1[] = "${MNAME[1]}"; + + static const char EMPT[] = ""; + + switch(i) + { + + default: return EMPT; + } +} + +const char* buildInfoGetModuleVal(int i) { + + //static const char MVAL1[] = "${MVAL[1]}"; + + static const char EMPT[] = ""; + + switch(i) + { + + default: return EMPT; + } +} + +const char* buildInfoGetGitHash(int i) { + + //static const char HASH1[] = "${GIT[1]}"; + static const char HASH1[] = "22.12-18-g9832c557-dirty"; + static const char HASH2[] = "20.06-1908-gdce19d534"; + + static const char EMPT[] = ""; + + switch(i) + { + case 1: return HASH1; + case 2: return HASH2; + + default: return EMPT; + } +} + +const char* buildInfoGetBuildGitHash() { + + //static const char HASH[] = "${GIT}"; + static const char HASH[] = ""; + + + return HASH; +} + +const char* buildInfoGetBuildGitName() { + + //static const char NAME[] = ""; + static const char NAME[] = ""; + + + return NAME; +} + +#ifdef AMREX_USE_CUDA +const char* buildInfoGetCUDAVersion() { + + static const char CUDA_VERSION[] = ""; + return CUDA_VERSION; +} +#endif + +} diff --git a/Tutorials_profiling/ConvectedVortex/Backtrace.0 b/Tutorials_profiling/ConvectedVortex/Backtrace.0 index 0c053a49..fc26ba3e 100644 --- a/Tutorials_profiling/ConvectedVortex/Backtrace.0 +++ b/Tutorials_profiling/ConvectedVortex/Backtrace.0 @@ -1,102 +1,102 @@ -Host Name: mirror -=== If no file names and line numbers are shown below, one can run - addr2line -Cpfie my_exefile my_line_address - to convert `my_line_address` (e.g., 0x4a6b) into file name and line number. - Or one can use amrex/Tools/Backtrace/parse_bt.py. - -=== Please note that the line number reported by addr2line may not be accurate. - One can use - readelf -wl my_exefile | grep my_line_address' - to find out the offset for that line. - - 0: ./amr2d.gnu.PROF.CUDA.ex() [0x684c56] - _ZN5amrex11BLBackTrace20print_backtrace_infoEP8_IO_FILE -../../../amrex/Src/Base/AMReX_BLBackTrace.cpp:196:28 - - 1: ./amr2d.gnu.PROF.CUDA.ex() [0x686878] - _ZN5amrex11BLBackTrace7handlerEi -../../../amrex/Src/Base/AMReX_BLBackTrace.cpp:96:7 - - 2: /lib64/libc.so.6(+0x4ad50) [0x7f6624826d50] - - 3: /usr/lib64/libstdc++.so.6(_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base+0x17) [0x7f6625202f27] - ?? ??:0 - - 4: ./amr2d.gnu.PROF.CUDA.ex() [0x5a6320] - _ZNSt23_Rb_tree_const_iteratorIN5amrex6CArena4NodeEEppEv inlined at ../../../amrex/Src/Base/AMReX_CArena.cpp:64:43 in _ZN5amrex6CArena5allocEm -/usr/include/c++/9/bits/stl_tree.h:366:31 -_ZN5amrex6CArena5allocEm -../../../amrex/Src/Base/AMReX_CArena.cpp:64:43 - - 5: ./amr2d.gnu.PROF.CUDA.ex() [0x5dedf2] - _ZNK5amrex3Box6lengthEi inlined at ../../../amrex/Src/Base/AMReX_Box.H:341:40 in _ZN5amrex7BaseFabIdE6defineEv -../../../amrex/Src/Base/AMReX_Box.H:154:56 -_ZNK5amrex3Box6numPtsEv -../../../amrex/Src/Base/AMReX_Box.H:341:40 -_ZN5amrex7BaseFabIdE6defineEv -../../../amrex/Src/Base/AMReX_BaseFab.H:1907:24 - - 6: ./amr2d.gnu.PROF.CUDA.ex() [0x5dd32e] - _ZN5amrex9FArrayBoxC2ERKNS_3BoxEibbPNS_5ArenaE -../../../amrex/Src/Base/AMReX_FArrayBox.cpp:123:129 - - 7: ./amr2d.gnu.PROF.CUDA.ex() [0x4ce840] - _ZN5amrex8FabArrayINS_9FArrayBoxEE9AllocFabsERKNS_10FabFactoryIS1_EEPNS_5ArenaERKNS_6VectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISF_EEE -../../../amrex/Src/Base/AMReX_FabArray.H:2037:1 - - 8: ./amr2d.gnu.PROF.CUDA.ex() [0x5eb45a] - _ZN5amrex8MultiFab6defineERKNS_8BoxArrayERKNS_19DistributionMappingEiRKNS_7IntVectERKNS_6MFInfoERKNS_10FabFactoryINS_9FArrayBoxEEE inlined at ../../../amrex/Src/Base/AMReX_MultiFab.cpp:557:13 in _ZN5amrex8MultiFab6defineERKNS_8BoxArrayERKNS_19DistributionMappingEiiRKNS_6MFInfoERKNS_10FabFactoryINS_9FArrayBoxEEE -../../../amrex/Src/Base/AMReX_MultiFab.cpp:570:26 -_ZN5amrex8MultiFab6defineERKNS_8BoxArrayERKNS_19DistributionMappingEiiRKNS_6MFInfoERKNS_10FabFactoryINS_9FArrayBoxEEE -../../../amrex/Src/Base/AMReX_MultiFab.cpp:557:13 - - 9: ./amr2d.gnu.PROF.CUDA.ex() [0x72f7ea] - _ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EED4Ev inlined at ../../../amrex/Src/Base/AMReX_Vector.H:25:7 in _ZN5amrex17FillPatchIterator10InitializeEidiii -/usr/include/c++/9/bits/stl_vector.h:677:14 -_ZN5amrex6VectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS6_EED4Ev -../../../amrex/Src/Base/AMReX_Vector.H:25:7 -_ZN5amrex6MFInfoD4Ev -../../../amrex/Src/Base/AMReX_FabArray.H:116:8 -_ZN5amrex17FillPatchIterator10InitializeEidiii -../../../amrex/Src/Amr/AMReX_AmrLevel.cpp:998:94 - -10: ./amr2d.gnu.PROF.CUDA.ex() [0x730a31] - _ZN5amrex8AmrLevel9FillPatchERS0_RNS_8MultiFabEidiiii -../../../amrex/Src/Amr/AMReX_AmrLevel.cpp:2172:15 - -11: ./amr2d.gnu.PROF.CUDA.ex() [0x49d86d] - _ZN16NavierStokesBase16predict_velocityEd -../../Source/NavierStokesBase.cpp:4721:10 - -12: ./amr2d.gnu.PROF.CUDA.ex() [0x47697d] - _ZN12NavierStokes7advanceEddii -../../Source/NavierStokes.cpp:634:1 - -13: ./amr2d.gnu.PROF.CUDA.ex() [0x71834d] - _ZN5amrex3Amr8timeStepEidiid -../../../amrex/Src/Amr/AMReX_Amr.cpp:1988:30 - -14: ./amr2d.gnu.PROF.CUDA.ex() [0x718618] - _ZN5amrex3Amr8timeStepEidiid -../../../amrex/Src/Amr/AMReX_Amr.cpp:2033:1 - -15: ./amr2d.gnu.PROF.CUDA.ex() [0x718618] - _ZN5amrex3Amr8timeStepEidiid -../../../amrex/Src/Amr/AMReX_Amr.cpp:2033:1 - -16: ./amr2d.gnu.PROF.CUDA.ex() [0x714c69] - _ZNKSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv inlined at ../../../amrex/Src/Amr/AMReX_Amr.cpp:2095:43 in _ZN5amrex3Amr14coarseTimeStepEd -/usr/include/c++/9/sstream:832:29 -_ZN5amrex3Amr14coarseTimeStepEd -../../../amrex/Src/Amr/AMReX_Amr.cpp:2095:43 - -17: ./amr2d.gnu.PROF.CUDA.ex() [0x427dcb] - main -../../Source/main.cpp:127:29 - -18: /lib64/libc.so.6(__libc_start_main+0xef) [0x7f662481129d] - -19: ./amr2d.gnu.PROF.CUDA.ex() [0x42e3da] - _start -../sysdeps/x86_64/start.S:122 - +Host Name: mirror +=== If no file names and line numbers are shown below, one can run + addr2line -Cpfie my_exefile my_line_address + to convert `my_line_address` (e.g., 0x4a6b) into file name and line number. + Or one can use amrex/Tools/Backtrace/parse_bt.py. + +=== Please note that the line number reported by addr2line may not be accurate. + One can use + readelf -wl my_exefile | grep my_line_address' + to find out the offset for that line. + + 0: ./amr2d.gnu.PROF.CUDA.ex() [0x684c56] + _ZN5amrex11BLBackTrace20print_backtrace_infoEP8_IO_FILE +../../../amrex/Src/Base/AMReX_BLBackTrace.cpp:196:28 + + 1: ./amr2d.gnu.PROF.CUDA.ex() [0x686878] + _ZN5amrex11BLBackTrace7handlerEi +../../../amrex/Src/Base/AMReX_BLBackTrace.cpp:96:7 + + 2: /lib64/libc.so.6(+0x4ad50) [0x7f6624826d50] + + 3: /usr/lib64/libstdc++.so.6(_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base+0x17) [0x7f6625202f27] + ?? ??:0 + + 4: ./amr2d.gnu.PROF.CUDA.ex() [0x5a6320] + _ZNSt23_Rb_tree_const_iteratorIN5amrex6CArena4NodeEEppEv inlined at ../../../amrex/Src/Base/AMReX_CArena.cpp:64:43 in _ZN5amrex6CArena5allocEm +/usr/include/c++/9/bits/stl_tree.h:366:31 +_ZN5amrex6CArena5allocEm +../../../amrex/Src/Base/AMReX_CArena.cpp:64:43 + + 5: ./amr2d.gnu.PROF.CUDA.ex() [0x5dedf2] + _ZNK5amrex3Box6lengthEi inlined at ../../../amrex/Src/Base/AMReX_Box.H:341:40 in _ZN5amrex7BaseFabIdE6defineEv +../../../amrex/Src/Base/AMReX_Box.H:154:56 +_ZNK5amrex3Box6numPtsEv +../../../amrex/Src/Base/AMReX_Box.H:341:40 +_ZN5amrex7BaseFabIdE6defineEv +../../../amrex/Src/Base/AMReX_BaseFab.H:1907:24 + + 6: ./amr2d.gnu.PROF.CUDA.ex() [0x5dd32e] + _ZN5amrex9FArrayBoxC2ERKNS_3BoxEibbPNS_5ArenaE +../../../amrex/Src/Base/AMReX_FArrayBox.cpp:123:129 + + 7: ./amr2d.gnu.PROF.CUDA.ex() [0x4ce840] + _ZN5amrex8FabArrayINS_9FArrayBoxEE9AllocFabsERKNS_10FabFactoryIS1_EEPNS_5ArenaERKNS_6VectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISF_EEE +../../../amrex/Src/Base/AMReX_FabArray.H:2037:1 + + 8: ./amr2d.gnu.PROF.CUDA.ex() [0x5eb45a] + _ZN5amrex8MultiFab6defineERKNS_8BoxArrayERKNS_19DistributionMappingEiRKNS_7IntVectERKNS_6MFInfoERKNS_10FabFactoryINS_9FArrayBoxEEE inlined at ../../../amrex/Src/Base/AMReX_MultiFab.cpp:557:13 in _ZN5amrex8MultiFab6defineERKNS_8BoxArrayERKNS_19DistributionMappingEiiRKNS_6MFInfoERKNS_10FabFactoryINS_9FArrayBoxEEE +../../../amrex/Src/Base/AMReX_MultiFab.cpp:570:26 +_ZN5amrex8MultiFab6defineERKNS_8BoxArrayERKNS_19DistributionMappingEiiRKNS_6MFInfoERKNS_10FabFactoryINS_9FArrayBoxEEE +../../../amrex/Src/Base/AMReX_MultiFab.cpp:557:13 + + 9: ./amr2d.gnu.PROF.CUDA.ex() [0x72f7ea] + _ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EED4Ev inlined at ../../../amrex/Src/Base/AMReX_Vector.H:25:7 in _ZN5amrex17FillPatchIterator10InitializeEidiii +/usr/include/c++/9/bits/stl_vector.h:677:14 +_ZN5amrex6VectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS6_EED4Ev +../../../amrex/Src/Base/AMReX_Vector.H:25:7 +_ZN5amrex6MFInfoD4Ev +../../../amrex/Src/Base/AMReX_FabArray.H:116:8 +_ZN5amrex17FillPatchIterator10InitializeEidiii +../../../amrex/Src/Amr/AMReX_AmrLevel.cpp:998:94 + +10: ./amr2d.gnu.PROF.CUDA.ex() [0x730a31] + _ZN5amrex8AmrLevel9FillPatchERS0_RNS_8MultiFabEidiiii +../../../amrex/Src/Amr/AMReX_AmrLevel.cpp:2172:15 + +11: ./amr2d.gnu.PROF.CUDA.ex() [0x49d86d] + _ZN16NavierStokesBase16predict_velocityEd +../../Source/NavierStokesBase.cpp:4721:10 + +12: ./amr2d.gnu.PROF.CUDA.ex() [0x47697d] + _ZN12NavierStokes7advanceEddii +../../Source/NavierStokes.cpp:634:1 + +13: ./amr2d.gnu.PROF.CUDA.ex() [0x71834d] + _ZN5amrex3Amr8timeStepEidiid +../../../amrex/Src/Amr/AMReX_Amr.cpp:1988:30 + +14: ./amr2d.gnu.PROF.CUDA.ex() [0x718618] + _ZN5amrex3Amr8timeStepEidiid +../../../amrex/Src/Amr/AMReX_Amr.cpp:2033:1 + +15: ./amr2d.gnu.PROF.CUDA.ex() [0x718618] + _ZN5amrex3Amr8timeStepEidiid +../../../amrex/Src/Amr/AMReX_Amr.cpp:2033:1 + +16: ./amr2d.gnu.PROF.CUDA.ex() [0x714c69] + _ZNKSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv inlined at ../../../amrex/Src/Amr/AMReX_Amr.cpp:2095:43 in _ZN5amrex3Amr14coarseTimeStepEd +/usr/include/c++/9/sstream:832:29 +_ZN5amrex3Amr14coarseTimeStepEd +../../../amrex/Src/Amr/AMReX_Amr.cpp:2095:43 + +17: ./amr2d.gnu.PROF.CUDA.ex() [0x427dcb] + main +../../Source/main.cpp:127:29 + +18: /lib64/libc.so.6(__libc_start_main+0xef) [0x7f662481129d] + +19: ./amr2d.gnu.PROF.CUDA.ex() [0x42e3da] + _start +../sysdeps/x86_64/start.S:122 + diff --git a/Tutorials_profiling/ConvectedVortex/GNUmakefile b/Tutorials_profiling/ConvectedVortex/GNUmakefile index 06e275f4..e702cb2b 100644 --- a/Tutorials_profiling/ConvectedVortex/GNUmakefile +++ b/Tutorials_profiling/ConvectedVortex/GNUmakefile @@ -1,30 +1,37 @@ -#AMREX_HOME defines the directory in which we will find the BoxLib directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 # DIM -COMP = gnu - -DEBUG = FALSE -USE_MPI = FALSE # MPI -USE_OMP = FALSE # OMP -PROFILE = TRUE - -USE_CUDA = TRUE # CUDA - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#AMREX_HOME defines the directory in which we will find the BoxLib directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 # DIM +COMP = gnu + +DEBUG = FALSE +USE_MPI = FALSE # MPI +USE_OMP = FALSE # OMP +PROFILE = TRUE + +USE_CUDA = TRUE # CUDA + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials_profiling/ConvectedVortex/GNUmakefile.temp b/Tutorials_profiling/ConvectedVortex/GNUmakefile.temp index 68fd8801..50084856 100644 --- a/Tutorials_profiling/ConvectedVortex/GNUmakefile.temp +++ b/Tutorials_profiling/ConvectedVortex/GNUmakefile.temp @@ -1,30 +1,37 @@ -#AMREX_HOME defines the directory in which we will find the BoxLib directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 # DIM -COMP = gnu - -DEBUG = FALSE -USE_MPI = TRUE # MPI -USE_OMP = TRUE # OMP -PROFILE = TRUE - -USE_CUDA = FALSE # CUDA - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#AMREX_HOME defines the directory in which we will find the BoxLib directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 # DIM +COMP = gnu + +DEBUG = FALSE +USE_MPI = TRUE # MPI +USE_OMP = TRUE # OMP +PROFILE = TRUE + +USE_CUDA = FALSE # CUDA + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials_profiling/ConvectedVortex/inputs.2d.convectedvortex b/Tutorials_profiling/ConvectedVortex/inputs.2d.convectedvortex index b6761600..a69b2766 100644 --- a/Tutorials_profiling/ConvectedVortex/inputs.2d.convectedvortex +++ b/Tutorials_profiling/ConvectedVortex/inputs.2d.convectedvortex @@ -1,139 +1,145 @@ - -#******************************************************************************* -# INPUTS -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. -#NOTE: this input file can be used in combination with the Util/multiRuns.py -#and Util/pprocConvOrder.py in order to compute the convergence order of the velocity -# advection schemes in IAMR. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 25000 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 0.2 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 64 64 - -#******************************************************************************* - -amr.max_grid_size = 8 # max_grid_size -amr.max_level = 0 # max_level -amr.regrid_int = 4 # regrid_int -ns.skip_level_projector = 0 # skip_level_projector -amr.subcycling_mode = Auto # subcycling_mode - -# Refinement criterion, use vorticity -amr.refinement_indicators = vorticity -amr.vorticity.vorticity_greater = 1200.0 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 0 -ns.sum_interval = 0 -ns.init_iter = 2 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 0 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = -5 -amr.check_file = chk - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 50 -amr.plot_file = plt - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.7 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 1.0 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0. - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0.0 0.0 0.0 - -# Physical dimensions of the high end of the domain. -#geometry.prob_hi = 6.28318530717959 6.28318530717959A -geometry.prob_hi = 1.0 1.0 1.0 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 8 -prob.rvort = 0.07 -prob.xvort = 0.5 -prob.yvort = 0.5 -prob.forcevort = 6.0 -prob.meanFlowDir = 1 -prob.meanFlowMag = 50.0 - -#******************************************************************************* - -# Factor by which grids must be coarsenable. -amr.blocking_factor = 8 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort - -#******************************************************************************* -nodal_proj.verbose=4 -nodal_proj.proj_tol = 1.e-10 -nodal_proj.sync_tol = 1.e-8 +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# INPUTS +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. +#NOTE: this input file can be used in combination with the Util/multiRuns.py +#and Util/pprocConvOrder.py in order to compute the convergence order of the velocity +# advection schemes in IAMR. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 25000 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 0.2 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 64 64 + +#******************************************************************************* + +amr.max_grid_size = 8 # max_grid_size +amr.max_level = 0 # max_level +amr.regrid_int = 4 # regrid_int +ns.skip_level_projector = 0 # skip_level_projector +amr.subcycling_mode = Auto # subcycling_mode + +# Refinement criterion, use vorticity +amr.refinement_indicators = vorticity +amr.vorticity.vorticity_greater = 1200.0 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 0 +ns.sum_interval = 0 +ns.init_iter = 2 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 0 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = -5 +amr.check_file = chk + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 50 +amr.plot_file = plt + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.7 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 1.0 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0. + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0.0 0.0 0.0 + +# Physical dimensions of the high end of the domain. +#geometry.prob_hi = 6.28318530717959 6.28318530717959A +geometry.prob_hi = 1.0 1.0 1.0 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 8 +prob.rvort = 0.07 +prob.xvort = 0.5 +prob.yvort = 0.5 +prob.forcevort = 6.0 +prob.meanFlowDir = 1 +prob.meanFlowMag = 50.0 + +#******************************************************************************* + +# Factor by which grids must be coarsenable. +amr.blocking_factor = 8 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort + +#******************************************************************************* +nodal_proj.verbose=4 +nodal_proj.proj_tol = 1.e-10 +nodal_proj.sync_tol = 1.e-8 diff --git a/Tutorials_profiling/ConvectedVortex/inputs.2d.convectedvortex.temp b/Tutorials_profiling/ConvectedVortex/inputs.2d.convectedvortex.temp index b6761600..a69b2766 100644 --- a/Tutorials_profiling/ConvectedVortex/inputs.2d.convectedvortex.temp +++ b/Tutorials_profiling/ConvectedVortex/inputs.2d.convectedvortex.temp @@ -1,139 +1,145 @@ - -#******************************************************************************* -# INPUTS -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. -#NOTE: this input file can be used in combination with the Util/multiRuns.py -#and Util/pprocConvOrder.py in order to compute the convergence order of the velocity -# advection schemes in IAMR. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 25000 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 0.2 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 64 64 - -#******************************************************************************* - -amr.max_grid_size = 8 # max_grid_size -amr.max_level = 0 # max_level -amr.regrid_int = 4 # regrid_int -ns.skip_level_projector = 0 # skip_level_projector -amr.subcycling_mode = Auto # subcycling_mode - -# Refinement criterion, use vorticity -amr.refinement_indicators = vorticity -amr.vorticity.vorticity_greater = 1200.0 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 0 -ns.sum_interval = 0 -ns.init_iter = 2 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 0 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = -5 -amr.check_file = chk - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 50 -amr.plot_file = plt - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.7 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 1.0 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0. - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0.0 0.0 0.0 - -# Physical dimensions of the high end of the domain. -#geometry.prob_hi = 6.28318530717959 6.28318530717959A -geometry.prob_hi = 1.0 1.0 1.0 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 8 -prob.rvort = 0.07 -prob.xvort = 0.5 -prob.yvort = 0.5 -prob.forcevort = 6.0 -prob.meanFlowDir = 1 -prob.meanFlowMag = 50.0 - -#******************************************************************************* - -# Factor by which grids must be coarsenable. -amr.blocking_factor = 8 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort - -#******************************************************************************* -nodal_proj.verbose=4 -nodal_proj.proj_tol = 1.e-10 -nodal_proj.sync_tol = 1.e-8 +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# INPUTS +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. +#NOTE: this input file can be used in combination with the Util/multiRuns.py +#and Util/pprocConvOrder.py in order to compute the convergence order of the velocity +# advection schemes in IAMR. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 25000 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 0.2 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 64 64 + +#******************************************************************************* + +amr.max_grid_size = 8 # max_grid_size +amr.max_level = 0 # max_level +amr.regrid_int = 4 # regrid_int +ns.skip_level_projector = 0 # skip_level_projector +amr.subcycling_mode = Auto # subcycling_mode + +# Refinement criterion, use vorticity +amr.refinement_indicators = vorticity +amr.vorticity.vorticity_greater = 1200.0 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 0 +ns.sum_interval = 0 +ns.init_iter = 2 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 0 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = -5 +amr.check_file = chk + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 50 +amr.plot_file = plt + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.7 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 1.0 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0. + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0.0 0.0 0.0 + +# Physical dimensions of the high end of the domain. +#geometry.prob_hi = 6.28318530717959 6.28318530717959A +geometry.prob_hi = 1.0 1.0 1.0 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 8 +prob.rvort = 0.07 +prob.xvort = 0.5 +prob.yvort = 0.5 +prob.forcevort = 6.0 +prob.meanFlowDir = 1 +prob.meanFlowMag = 50.0 + +#******************************************************************************* + +# Factor by which grids must be coarsenable. +amr.blocking_factor = 8 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort + +#******************************************************************************* +nodal_proj.verbose=4 +nodal_proj.proj_tol = 1.e-10 +nodal_proj.sync_tol = 1.e-8 diff --git a/Tutorials_profiling/ConvectedVortex/inputs.3d.convectedvortex b/Tutorials_profiling/ConvectedVortex/inputs.3d.convectedvortex index d85235e2..7d4b96b3 100644 --- a/Tutorials_profiling/ConvectedVortex/inputs.3d.convectedvortex +++ b/Tutorials_profiling/ConvectedVortex/inputs.3d.convectedvortex @@ -1,135 +1,141 @@ - -#******************************************************************************* -# inputs.3d.convectedVortex -# Convecting an isentropic vortex aligned in Z in a periodic 3D box -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 200 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 0.06 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 64 16 - -amr.max_grid_size = 8 # max_grid_size -amr.max_level = 0 # max_level -amr.regrid_int = 4 # regrid_int -ns.skip_level_projector = 0 # skip_level_projector -amr.subcycling_mode = Auto # subcycling_mode - -# Refinement criterion, use vorticity -amr.refinement_indicators = vorticity -amr.vorticity.vorticity_greater = 1200.0 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 0 -ns.sum_interval = 0 -ns.init_iter = 2 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 0 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = -5 -amr.check_file = chk - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 50 -amr.plot_file = plt - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.7 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 1.0 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0. - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0.0 0.0 0.0 - -# Physical dimensions of the high end of the domain. -#geometry.prob_hi = 6.28318530717959 6.28318530717959A -geometry.prob_hi = 1.0 1.0 0.25 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 8 -prob.rvort = 0.07 -prob.xvort = 0.5 -prob.yvort = 0.5 -prob.forcevort = 6.0 -prob.meanFlowDir = 1 -prob.meanFlowMag = 50.0 - -#******************************************************************************* - -# Factor by which grids must be coarsenable. -amr.blocking_factor = 8 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort - -#******************************************************************************* -nodal_proj.verbose=4 -nodal_proj.proj_tol = 1.e-10 -nodal_proj.sync_tol = 1.e-8 +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# inputs.3d.convectedVortex +# Convecting an isentropic vortex aligned in Z in a periodic 3D box +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 200 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 0.06 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 64 16 + +amr.max_grid_size = 8 # max_grid_size +amr.max_level = 0 # max_level +amr.regrid_int = 4 # regrid_int +ns.skip_level_projector = 0 # skip_level_projector +amr.subcycling_mode = Auto # subcycling_mode + +# Refinement criterion, use vorticity +amr.refinement_indicators = vorticity +amr.vorticity.vorticity_greater = 1200.0 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 0 +ns.sum_interval = 0 +ns.init_iter = 2 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 0 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = -5 +amr.check_file = chk + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 50 +amr.plot_file = plt + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.7 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 1.0 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0. + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0.0 0.0 0.0 + +# Physical dimensions of the high end of the domain. +#geometry.prob_hi = 6.28318530717959 6.28318530717959A +geometry.prob_hi = 1.0 1.0 0.25 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 8 +prob.rvort = 0.07 +prob.xvort = 0.5 +prob.yvort = 0.5 +prob.forcevort = 6.0 +prob.meanFlowDir = 1 +prob.meanFlowMag = 50.0 + +#******************************************************************************* + +# Factor by which grids must be coarsenable. +amr.blocking_factor = 8 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort + +#******************************************************************************* +nodal_proj.verbose=4 +nodal_proj.proj_tol = 1.e-10 +nodal_proj.sync_tol = 1.e-8 diff --git a/Tutorials_profiling/DoubleShearLayer/GNUmakefile b/Tutorials_profiling/DoubleShearLayer/GNUmakefile index 9af26041..8ef6b2b2 100644 --- a/Tutorials_profiling/DoubleShearLayer/GNUmakefile +++ b/Tutorials_profiling/DoubleShearLayer/GNUmakefile @@ -1,32 +1,39 @@ -#AMREX_HOME defines the directory in which we will find the BoxLib directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 # DIM -COMP = gnu - -DEBUG = FALSE -USE_MPI = FALSE # MPI -USE_OMP = FALSE # OMP -PROFILE = TRUE - -USE_CUDA = TRUE # CUDA - -USE_EB = TRUE - -USE_VELOCITY = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#AMREX_HOME defines the directory in which we will find the BoxLib directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 # DIM +COMP = gnu + +DEBUG = FALSE +USE_MPI = FALSE # MPI +USE_OMP = FALSE # OMP +PROFILE = TRUE + +USE_CUDA = TRUE # CUDA + +USE_EB = TRUE + +USE_VELOCITY = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials_profiling/DoubleShearLayer/GNUmakefile.temp b/Tutorials_profiling/DoubleShearLayer/GNUmakefile.temp index 9af26041..8ef6b2b2 100644 --- a/Tutorials_profiling/DoubleShearLayer/GNUmakefile.temp +++ b/Tutorials_profiling/DoubleShearLayer/GNUmakefile.temp @@ -1,32 +1,39 @@ -#AMREX_HOME defines the directory in which we will find the BoxLib directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 # DIM -COMP = gnu - -DEBUG = FALSE -USE_MPI = FALSE # MPI -USE_OMP = FALSE # OMP -PROFILE = TRUE - -USE_CUDA = TRUE # CUDA - -USE_EB = TRUE - -USE_VELOCITY = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#AMREX_HOME defines the directory in which we will find the BoxLib directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 # DIM +COMP = gnu + +DEBUG = FALSE +USE_MPI = FALSE # MPI +USE_OMP = FALSE # OMP +PROFILE = TRUE + +USE_CUDA = TRUE # CUDA + +USE_EB = TRUE + +USE_VELOCITY = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials_profiling/DoubleShearLayer/inputs.2d.double_shear_layer-rotate b/Tutorials_profiling/DoubleShearLayer/inputs.2d.double_shear_layer-rotate index 4c4cc58c..da61ec50 100644 --- a/Tutorials_profiling/DoubleShearLayer/inputs.2d.double_shear_layer-rotate +++ b/Tutorials_profiling/DoubleShearLayer/inputs.2d.double_shear_layer-rotate @@ -1,147 +1,154 @@ -#******************************************************************************* -# INPUTS.2D.PERIODIC_SHEAR_LAYER -#******************************************************************************* - -#******************************************************************************* -# WHEN SHOULD THE SIMULATION STOP? -#******************************************************************************* -# Maximum number of timesteps to be taken, if stop_time is not reached first. -max_step = 200 -# Time at which calculation stops, if max_step is not reached first. -stop_time = 10.0 -# Stop simulation when we reach steady-state? -ns.stop_when_steady = 0 -ns.steady_tol = 1.0e-5 - -#******************************************************************************* -# CFL -#******************************************************************************* - -ns.cfl = 0.5 # CFL number used to set dt -ns.init_shrink = 1.0 # factor which multiplies the very first time step -#ns.change_max = 1.1 # maximum change for dt - -# Turn off IAMR's initialization procedure to check initial conditions -#ns.init_iter = 0 # number of initial iterations -#ns.do_init_proj = 0 # do initial projection - -#******************************************************************************* -# FLUID PROPERTIES -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.0 #0.001 -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 0.0 -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* -# GRID AND GEOMETRY -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 128 128 - -amr.max_grid_size = 8 # max_grid_size -amr.max_level = 0 # max_level -amr.regrid_int = 4 # regrid_int -ns.skip_level_projector = 0 # skip_level_projector -amr.subcycling_mode = Auto # subcycling_mode - -# Refinement criterion, use presence of tracer -# amr.refinement_indicators = tracer - -# amr.tracer.value_greater = 0.2 -# amr.tracer.field_name = tracer - -amr.refinement_indicators = vorticity -amr.vorticity.vorticity_greater = 10.0 - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 -# Physical dimensions of the low end of the domain. -geometry.prob_lo = -1.0 -1.0 -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1.0 1.0 -# Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 - -# Embedded Boundary options -#eb2.geom_type = all_regular # No EB -eb2.geom_type = sphere -eb2.sphere_radius = 0.25 -#eb2.sphere_center = 0.5 0.5 # don't forget prob.direction = 0 -eb2.sphere_center = -0.5 0.5 # don't forget prob.direction = 1 -eb2.sphere_has_fluid_inside = 0 - -#******************************************************************************* -# BOUNDARY CONDITIONS -#******************************************************************************* - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 - -#******************************************************************************* -# Problem parameters -#******************************************************************************* - -prob.probtype = 5 -# set up shear layer along y-direction -prob.direction = 1 -prob.blob_center = 0.0 0.0 -prob.blob_radius = 0.4 -prob.density_ic = 1.0 - -#******************************************************************************* -# AMR -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 -# Factor by which grids must be coarsenable. -amr.blocking_factor = 8 -# Grid efficiency (defaults to .70) -amr.grid_eff = 0.75 - -#******************************************************************************* -# PLOTTING AND CHECKPOINTS -#******************************************************************************* - -# Choose which quantities to write to plot file -amr.plot_vars = ALL -amr.derive_plot_vars = mag_vort - -# Interval (in number of coarse timesteps) between plot files -amr.plot_file = plt -amr.plot_int = 50 -#amr.plot_per = 0.2 - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_file = chk -amr.check_int = 100 -# Continue from checkpoint -# amr.restart = chk01000 - -#******************************************************************************* -# VERBOSITY -#******************************************************************************* - -amr.v = 0 # AMR (top-level) -ns.v = 0 # NavierStokes -diffuse.v = 0 # Diffusion -nodal_proj.verbose = 0 # Projection - -#******************************************************************************* -# PROJECTION SETTINGS -#******************************************************************************* - -# Usually default values work well -#nodal_proj.proj_tol = 1.e-12 -#nodal_proj.proj_abs_tol = 1.e-15 +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# INPUTS.2D.PERIODIC_SHEAR_LAYER +#******************************************************************************* + +#******************************************************************************* +# WHEN SHOULD THE SIMULATION STOP? +#******************************************************************************* +# Maximum number of timesteps to be taken, if stop_time is not reached first. +max_step = 200 +# Time at which calculation stops, if max_step is not reached first. +stop_time = 10.0 +# Stop simulation when we reach steady-state? +ns.stop_when_steady = 0 +ns.steady_tol = 1.0e-5 + +#******************************************************************************* +# CFL +#******************************************************************************* + +ns.cfl = 0.5 # CFL number used to set dt +ns.init_shrink = 1.0 # factor which multiplies the very first time step +#ns.change_max = 1.1 # maximum change for dt + +# Turn off IAMR's initialization procedure to check initial conditions +#ns.init_iter = 0 # number of initial iterations +#ns.do_init_proj = 0 # do initial projection + +#******************************************************************************* +# FLUID PROPERTIES +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.0 #0.001 +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 0.0 +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* +# GRID AND GEOMETRY +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 128 128 + +amr.max_grid_size = 8 # max_grid_size +amr.max_level = 0 # max_level +amr.regrid_int = 4 # regrid_int +ns.skip_level_projector = 0 # skip_level_projector +amr.subcycling_mode = Auto # subcycling_mode + +# Refinement criterion, use presence of tracer +# amr.refinement_indicators = tracer + +# amr.tracer.value_greater = 0.2 +# amr.tracer.field_name = tracer + +amr.refinement_indicators = vorticity +amr.vorticity.vorticity_greater = 10.0 + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 +# Physical dimensions of the low end of the domain. +geometry.prob_lo = -1.0 -1.0 +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1.0 1.0 +# Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 + +# Embedded Boundary options +#eb2.geom_type = all_regular # No EB +eb2.geom_type = sphere +eb2.sphere_radius = 0.25 +#eb2.sphere_center = 0.5 0.5 # don't forget prob.direction = 0 +eb2.sphere_center = -0.5 0.5 # don't forget prob.direction = 1 +eb2.sphere_has_fluid_inside = 0 + +#******************************************************************************* +# BOUNDARY CONDITIONS +#******************************************************************************* + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 + +#******************************************************************************* +# Problem parameters +#******************************************************************************* + +prob.probtype = 5 +# set up shear layer along y-direction +prob.direction = 1 +prob.blob_center = 0.0 0.0 +prob.blob_radius = 0.4 +prob.density_ic = 1.0 + +#******************************************************************************* +# AMR +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 +# Factor by which grids must be coarsenable. +amr.blocking_factor = 8 +# Grid efficiency (defaults to .70) +amr.grid_eff = 0.75 + +#******************************************************************************* +# PLOTTING AND CHECKPOINTS +#******************************************************************************* + +# Choose which quantities to write to plot file +amr.plot_vars = ALL +amr.derive_plot_vars = mag_vort + +# Interval (in number of coarse timesteps) between plot files +amr.plot_file = plt +amr.plot_int = 50 +#amr.plot_per = 0.2 + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_file = chk +amr.check_int = 100 +# Continue from checkpoint +# amr.restart = chk01000 + +#******************************************************************************* +# VERBOSITY +#******************************************************************************* + +amr.v = 0 # AMR (top-level) +ns.v = 0 # NavierStokes +diffuse.v = 0 # Diffusion +nodal_proj.verbose = 0 # Projection + +#******************************************************************************* +# PROJECTION SETTINGS +#******************************************************************************* + +# Usually default values work well +#nodal_proj.proj_tol = 1.e-12 +#nodal_proj.proj_abs_tol = 1.e-15 diff --git a/Tutorials_profiling/DoubleShearLayer/inputs.2d.double_shear_layer-rotate.temp b/Tutorials_profiling/DoubleShearLayer/inputs.2d.double_shear_layer-rotate.temp index b7e2ae38..b7227937 100644 --- a/Tutorials_profiling/DoubleShearLayer/inputs.2d.double_shear_layer-rotate.temp +++ b/Tutorials_profiling/DoubleShearLayer/inputs.2d.double_shear_layer-rotate.temp @@ -1,147 +1,154 @@ -#******************************************************************************* -# INPUTS.2D.PERIODIC_SHEAR_LAYER -#******************************************************************************* - -#******************************************************************************* -# WHEN SHOULD THE SIMULATION STOP? -#******************************************************************************* -# Maximum number of timesteps to be taken, if stop_time is not reached first. -max_step = 1000 -# Time at which calculation stops, if max_step is not reached first. -stop_time = 10.0 -# Stop simulation when we reach steady-state? -ns.stop_when_steady = 0 -ns.steady_tol = 1.0e-5 - -#******************************************************************************* -# CFL -#******************************************************************************* - -ns.cfl = 0.5 # CFL number used to set dt -ns.init_shrink = 1.0 # factor which multiplies the very first time step -#ns.change_max = 1.1 # maximum change for dt - -# Turn off IAMR's initialization procedure to check initial conditions -#ns.init_iter = 0 # number of initial iterations -#ns.do_init_proj = 0 # do initial projection - -#******************************************************************************* -# FLUID PROPERTIES -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.0 #0.001 -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 0.0 -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* -# GRID AND GEOMETRY -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 128 128 - -amr.max_grid_size = 8 # max_grid_size -amr.max_level = 0 -amr.regrid_int = 4 # regrid_int -ns.skip_level_projector = 0 # skip_level_projector -amr.subcycling_mode = Auto # subcycling_mode - -# Refinement criterion, use presence of tracer -# amr.refinement_indicators = tracer - -# amr.tracer.value_greater = 0.2 -# amr.tracer.field_name = tracer - -amr.refinement_indicators = vorticity -amr.vorticity.vorticity_greater = 10.0 - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 -# Physical dimensions of the low end of the domain. -geometry.prob_lo = -1.0 -1.0 -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1.0 1.0 -# Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 - -# Embedded Boundary options -#eb2.geom_type = all_regular # No EB -eb2.geom_type = sphere -eb2.sphere_radius = 0.25 -#eb2.sphere_center = 0.5 0.5 # don't forget prob.direction = 0 -eb2.sphere_center = -0.5 0.5 # don't forget prob.direction = 1 -eb2.sphere_has_fluid_inside = 0 - -#******************************************************************************* -# BOUNDARY CONDITIONS -#******************************************************************************* - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 - -#******************************************************************************* -# Problem parameters -#******************************************************************************* - -prob.probtype = 5 -# set up shear layer along y-direction -prob.direction = 1 -prob.blob_center = 0.0 0.0 -prob.blob_radius = 0.4 -prob.density_ic = 1.0 - -#******************************************************************************* -# AMR -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 -# Factor by which grids must be coarsenable. -amr.blocking_factor = 8 -# Grid efficiency (defaults to .70) -amr.grid_eff = 0.75 - -#******************************************************************************* -# PLOTTING AND CHECKPOINTS -#******************************************************************************* - -# Choose which quantities to write to plot file -amr.plot_vars = ALL -amr.derive_plot_vars = mag_vort - -# Interval (in number of coarse timesteps) between plot files -amr.plot_file = plt -amr.plot_int = 50 -#amr.plot_per = 0.2 - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_file = chk -amr.check_int = 100 -# Continue from checkpoint -# amr.restart = chk01000 - -#******************************************************************************* -# VERBOSITY -#******************************************************************************* - -amr.v = 0 # AMR (top-level) -ns.v = 0 # NavierStokes -diffuse.v = 0 # Diffusion -nodal_proj.verbose = 0 # Projection - -#******************************************************************************* -# PROJECTION SETTINGS -#******************************************************************************* - -# Usually default values work well -#nodal_proj.proj_tol = 1.e-12 -#nodal_proj.proj_abs_tol = 1.e-15 +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# INPUTS.2D.PERIODIC_SHEAR_LAYER +#******************************************************************************* + +#******************************************************************************* +# WHEN SHOULD THE SIMULATION STOP? +#******************************************************************************* +# Maximum number of timesteps to be taken, if stop_time is not reached first. +max_step = 1000 +# Time at which calculation stops, if max_step is not reached first. +stop_time = 10.0 +# Stop simulation when we reach steady-state? +ns.stop_when_steady = 0 +ns.steady_tol = 1.0e-5 + +#******************************************************************************* +# CFL +#******************************************************************************* + +ns.cfl = 0.5 # CFL number used to set dt +ns.init_shrink = 1.0 # factor which multiplies the very first time step +#ns.change_max = 1.1 # maximum change for dt + +# Turn off IAMR's initialization procedure to check initial conditions +#ns.init_iter = 0 # number of initial iterations +#ns.do_init_proj = 0 # do initial projection + +#******************************************************************************* +# FLUID PROPERTIES +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.0 #0.001 +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 0.0 +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* +# GRID AND GEOMETRY +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 128 128 + +amr.max_grid_size = 8 # max_grid_size +amr.max_level = 0 +amr.regrid_int = 4 # regrid_int +ns.skip_level_projector = 0 # skip_level_projector +amr.subcycling_mode = Auto # subcycling_mode + +# Refinement criterion, use presence of tracer +# amr.refinement_indicators = tracer + +# amr.tracer.value_greater = 0.2 +# amr.tracer.field_name = tracer + +amr.refinement_indicators = vorticity +amr.vorticity.vorticity_greater = 10.0 + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 +# Physical dimensions of the low end of the domain. +geometry.prob_lo = -1.0 -1.0 +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1.0 1.0 +# Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 + +# Embedded Boundary options +#eb2.geom_type = all_regular # No EB +eb2.geom_type = sphere +eb2.sphere_radius = 0.25 +#eb2.sphere_center = 0.5 0.5 # don't forget prob.direction = 0 +eb2.sphere_center = -0.5 0.5 # don't forget prob.direction = 1 +eb2.sphere_has_fluid_inside = 0 + +#******************************************************************************* +# BOUNDARY CONDITIONS +#******************************************************************************* + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 + +#******************************************************************************* +# Problem parameters +#******************************************************************************* + +prob.probtype = 5 +# set up shear layer along y-direction +prob.direction = 1 +prob.blob_center = 0.0 0.0 +prob.blob_radius = 0.4 +prob.density_ic = 1.0 + +#******************************************************************************* +# AMR +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 +# Factor by which grids must be coarsenable. +amr.blocking_factor = 8 +# Grid efficiency (defaults to .70) +amr.grid_eff = 0.75 + +#******************************************************************************* +# PLOTTING AND CHECKPOINTS +#******************************************************************************* + +# Choose which quantities to write to plot file +amr.plot_vars = ALL +amr.derive_plot_vars = mag_vort + +# Interval (in number of coarse timesteps) between plot files +amr.plot_file = plt +amr.plot_int = 50 +#amr.plot_per = 0.2 + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_file = chk +amr.check_int = 100 +# Continue from checkpoint +# amr.restart = chk01000 + +#******************************************************************************* +# VERBOSITY +#******************************************************************************* + +amr.v = 0 # AMR (top-level) +ns.v = 0 # NavierStokes +diffuse.v = 0 # Diffusion +nodal_proj.verbose = 0 # Projection + +#******************************************************************************* +# PROJECTION SETTINGS +#******************************************************************************* + +# Usually default values work well +#nodal_proj.proj_tol = 1.e-12 +#nodal_proj.proj_abs_tol = 1.e-15 diff --git a/Tutorials_profiling/FlowPastCylinder/GNUmakefile b/Tutorials_profiling/FlowPastCylinder/GNUmakefile index adc9e564..8f217d0c 100644 --- a/Tutorials_profiling/FlowPastCylinder/GNUmakefile +++ b/Tutorials_profiling/FlowPastCylinder/GNUmakefile @@ -1,34 +1,41 @@ -#AMREX_HOME defines the directory in which we will find the BoxLib director -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -# running 2d inputs files requires a 2d executable set here -DIM = 2 # DIM -COMP = gnu - -DEBUG = FALSE -USE_MPI = TRUE # MPI -USE_OMP = TRUE # OMP -PROFILE = TRUE - -USE_CUDA = FALSE # CUDA - - -USE_VELOCITY = FALSE - -USE_EB = TRUE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#AMREX_HOME defines the directory in which we will find the BoxLib director +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +# running 2d inputs files requires a 2d executable set here +DIM = 2 # DIM +COMP = gnu + +DEBUG = FALSE +USE_MPI = TRUE # MPI +USE_OMP = TRUE # OMP +PROFILE = TRUE + +USE_CUDA = FALSE # CUDA + + +USE_VELOCITY = FALSE + +USE_EB = TRUE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials_profiling/FlowPastCylinder/inputs.2d.flow_past_cylinder-x b/Tutorials_profiling/FlowPastCylinder/inputs.2d.flow_past_cylinder-x index d7a4df51..dde020cd 100644 --- a/Tutorials_profiling/FlowPastCylinder/inputs.2d.flow_past_cylinder-x +++ b/Tutorials_profiling/FlowPastCylinder/inputs.2d.flow_past_cylinder-x @@ -1,97 +1,104 @@ -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SIMULATION STOP # -#.......................................# -stop_time = 0.8 # Max (simulated) time to evolve -max_step = 200 # Max number of time steps - -ns.stop_when_steady = 0 # Steady-state solver? -ns.steady_tol = 1.e-8 - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SOLVER SETTINGS # -#.......................................# -ns.init_shrink = 1.0 # Multiply initial dt by this factor - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# TIME STEP COMPUTATION # -#.......................................# -ns.fixed_dt = -1.0 # If fixed_dt > 0, use this constant dt -ns.cfl = 0.45 # CFL factor - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# INPUT AND OUTPUT # -#.......................................# -amr.plot_int = 50 # Steps between plot files -amr.check_int = 1000 # Steps between checkpoint files -amr.derive_plot_vars = mag_vort avg_pressure # Derived quantities to include in plotfiles - -amr.restart = "" # Checkpoint to restart from - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PHYSICS # -#.......................................# -ns.gravity = 0. - -ns.vel_visc_coef = 0.00001 -ns.scal_diff_coefs = 1.0 - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# ADAPTIVE MESH REFINEMENT # -#.......................................# -amr.n_cell = 128 128 # Grid cells at coarsest AMRlevel - -amr.max_grid_size = 8 # max_grid_size -amr.max_level = 0 # max_level -amr.regrid_int = 4 # regrid_int -ns.skip_level_projector = 0 # skip_level_projector -amr.subcycling_mode = Auto # subcycling_mode - -# Refinement criterion, use vorticity -amr.refinement_indicators = vorticity -amr.vorticity.vorticity_greater = 1000.0 - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# GEOMETRY # -#.......................................# -geometry.prob_lo = -0.04 -0.04 # Lo corner coordinates -geometry.prob_hi = 0.04 0.04 # Hi corner coordinates -geometry.is_periodic = 0 0 # Periodicity x y z (0/1) -geometry.coord_sys = 0 # 0 for Cartesian, 1 for RZ - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWal -# Boundary conditions on the low end of the domain. -ns.lo_bc = 1 4 -# Boundary conditions on the high end of the domain. -ns.hi_bc = 2 4 - -# inflow velocity -xlo.velocity = 1. 0. - -# Add cylinder -#eb2.geom_type = all_regular # for no EB -eb2.geom_type = sphere -eb2.sphere_radius = 0.0021 -eb2.sphere_center = -0.025 0.0 -eb2.sphere_has_fluid_inside=0 - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PROBLEM PARAMETERS # -#.......................................# -prob.probtype = 4 -prob.blob_center = -0.55 0.05 -prob.blob_radius = 0.04 -# Constant density initial condition -prob.density_ic = 1.0 -# Set up a flow, defaults to zero -prob.velocity_ic = 1. 0. - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# VERBOSITY # -#.......................................# -ns.v = 0 # NS solver -nodal_proj.verbose = 0 # Nodal projection -mac_proj.verbose = 0 # MacProjector -diffuse.v = 0 # Diffusion solver - +# SPDX-FileCopyrightText: 2019 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SIMULATION STOP # +#.......................................# +stop_time = 0.8 # Max (simulated) time to evolve +max_step = 200 # Max number of time steps + +ns.stop_when_steady = 0 # Steady-state solver? +ns.steady_tol = 1.e-8 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SOLVER SETTINGS # +#.......................................# +ns.init_shrink = 1.0 # Multiply initial dt by this factor + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# TIME STEP COMPUTATION # +#.......................................# +ns.fixed_dt = -1.0 # If fixed_dt > 0, use this constant dt +ns.cfl = 0.45 # CFL factor + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# INPUT AND OUTPUT # +#.......................................# +amr.plot_int = 50 # Steps between plot files +amr.check_int = 1000 # Steps between checkpoint files +amr.derive_plot_vars = mag_vort avg_pressure # Derived quantities to include in plotfiles + +amr.restart = "" # Checkpoint to restart from + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PHYSICS # +#.......................................# +ns.gravity = 0. + +ns.vel_visc_coef = 0.00001 +ns.scal_diff_coefs = 1.0 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# ADAPTIVE MESH REFINEMENT # +#.......................................# +amr.n_cell = 128 128 # Grid cells at coarsest AMRlevel + +amr.max_grid_size = 8 # max_grid_size +amr.max_level = 0 # max_level +amr.regrid_int = 4 # regrid_int +ns.skip_level_projector = 0 # skip_level_projector +amr.subcycling_mode = Auto # subcycling_mode + +# Refinement criterion, use vorticity +amr.refinement_indicators = vorticity +amr.vorticity.vorticity_greater = 1000.0 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# GEOMETRY # +#.......................................# +geometry.prob_lo = -0.04 -0.04 # Lo corner coordinates +geometry.prob_hi = 0.04 0.04 # Hi corner coordinates +geometry.is_periodic = 0 0 # Periodicity x y z (0/1) +geometry.coord_sys = 0 # 0 for Cartesian, 1 for RZ + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWal +# Boundary conditions on the low end of the domain. +ns.lo_bc = 1 4 +# Boundary conditions on the high end of the domain. +ns.hi_bc = 2 4 + +# inflow velocity +xlo.velocity = 1. 0. + +# Add cylinder +#eb2.geom_type = all_regular # for no EB +eb2.geom_type = sphere +eb2.sphere_radius = 0.0021 +eb2.sphere_center = -0.025 0.0 +eb2.sphere_has_fluid_inside=0 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PROBLEM PARAMETERS # +#.......................................# +prob.probtype = 4 +prob.blob_center = -0.55 0.05 +prob.blob_radius = 0.04 +# Constant density initial condition +prob.density_ic = 1.0 +# Set up a flow, defaults to zero +prob.velocity_ic = 1. 0. + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# VERBOSITY # +#.......................................# +ns.v = 0 # NS solver +nodal_proj.verbose = 0 # Nodal projection +mac_proj.verbose = 0 # MacProjector +diffuse.v = 0 # Diffusion solver + diff --git a/Tutorials_profiling/FlowPastCylinder/inputs.3d.flow_past_cylinder-x b/Tutorials_profiling/FlowPastCylinder/inputs.3d.flow_past_cylinder-x index fb67f571..c0a14632 100644 --- a/Tutorials_profiling/FlowPastCylinder/inputs.3d.flow_past_cylinder-x +++ b/Tutorials_profiling/FlowPastCylinder/inputs.3d.flow_past_cylinder-x @@ -1,88 +1,95 @@ -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SIMULATION STOP # -#.......................................# -stop_time = 8.0 # Max (simulated) time to evolve -max_step = 50 # Max number of time steps -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SOLVER SETTINGS # -#.......................................# -ns.init_iter = 3 # How many initial pressure iterations -ns.init_vel_iter = 5 # How many initial projeciton iterations to ensure velocity satisfies divergence constraint -ns.visc_tol = 1.0e-11 # tolerance for viscous solve -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# TIME STEP COMPUTATION # -#.......................................# -ns.cfl = 0.45 -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# INPUT AND OUTPUT # -#.......................................# -amr.plot_int = 50 # Steps between plot files -amr.check_int = 1000 # Steps between checkpoint files -amr.restart = "" # Checkpoint to restart from -amr.derive_plot_vars = mag_vort avg_pressure # Derived quantities to include in plotfiles -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PHYSICS # -#.......................................# -ns.gravity = 0. -ns.vel_visc_coef = 0.001 -ns.scal_diff_coefs = 1.0 -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# ADAPTIVE MESH REFINEMENT # -#.......................................# -amr.n_cell = 96 32 8 # Grid cells at coarsest AMRlevel - -amr.max_grid_size = 8 # max_grid_size -amr.max_level = 0 # max_level -amr.regrid_int = 4 # regrid_int -ns.skip_level_projector = 0 # skip_level_projector -amr.subcycling_mode = Auto # subcycling_mode - -# Refinement criterion, use vorticity -amr.refinement_indicators = vorticity -amr.vorticity.vorticity_greater = 20.0 - -# Refinement around the EB by default -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# GEOMETRY # -#.......................................# -geometry.prob_lo = 0. 0. 0. # Lo corner coordinates -geometry.prob_hi = 1.2 0.4 0.1 # Hi corner coordinates -geometry.is_periodic = 0 0 1 # Periodicity x y z (0/1) - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWal -# Boundary conditions on the low end of the domain. -ns.lo_bc = 1 4 0 -# Boundary conditions on the high end of the domain. -ns.hi_bc = 2 4 0 - -xlo.velocity = 1. 0. 0. - -# Add cylinder -eb2.geom_type = cylinder -eb2.cylinder_has_fluid_inside = 0 -eb2.cylinder_radius = 0.05 -eb2.cylinder_direction = 2 -eb2.cylinder_center = 0.15 0.2 0.0 - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PROBLEM PARAMETERS # -#.......................................# - -prob.probtype = 4 -prob.blob_center = -0.55 0.05 0.0 -prob.blob_radius = 0.04 -# Constant density initial condition -prob.density_ic = 1.0 -# Set up a flow, defaults to zero -prob.velocity_ic = 1. 0. 0. - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# VERBOSITY # -#.......................................# -ns.v = 1 # NS solver -nodal_proj.verbose = 0 # Nodal projection -mac_proj.verbose = 0 # MacProjector -diffuse.v = 0 # Diffusion operator - +# SPDX-FileCopyrightText: 2019 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SIMULATION STOP # +#.......................................# +stop_time = 8.0 # Max (simulated) time to evolve +max_step = 50 # Max number of time steps +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SOLVER SETTINGS # +#.......................................# +ns.init_iter = 3 # How many initial pressure iterations +ns.init_vel_iter = 5 # How many initial projeciton iterations to ensure velocity satisfies divergence constraint +ns.visc_tol = 1.0e-11 # tolerance for viscous solve +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# TIME STEP COMPUTATION # +#.......................................# +ns.cfl = 0.45 +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# INPUT AND OUTPUT # +#.......................................# +amr.plot_int = 50 # Steps between plot files +amr.check_int = 1000 # Steps between checkpoint files +amr.restart = "" # Checkpoint to restart from +amr.derive_plot_vars = mag_vort avg_pressure # Derived quantities to include in plotfiles +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PHYSICS # +#.......................................# +ns.gravity = 0. +ns.vel_visc_coef = 0.001 +ns.scal_diff_coefs = 1.0 +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# ADAPTIVE MESH REFINEMENT # +#.......................................# +amr.n_cell = 96 32 8 # Grid cells at coarsest AMRlevel + +amr.max_grid_size = 8 # max_grid_size +amr.max_level = 0 # max_level +amr.regrid_int = 4 # regrid_int +ns.skip_level_projector = 0 # skip_level_projector +amr.subcycling_mode = Auto # subcycling_mode + +# Refinement criterion, use vorticity +amr.refinement_indicators = vorticity +amr.vorticity.vorticity_greater = 20.0 + +# Refinement around the EB by default +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# GEOMETRY # +#.......................................# +geometry.prob_lo = 0. 0. 0. # Lo corner coordinates +geometry.prob_hi = 1.2 0.4 0.1 # Hi corner coordinates +geometry.is_periodic = 0 0 1 # Periodicity x y z (0/1) + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWal +# Boundary conditions on the low end of the domain. +ns.lo_bc = 1 4 0 +# Boundary conditions on the high end of the domain. +ns.hi_bc = 2 4 0 + +xlo.velocity = 1. 0. 0. + +# Add cylinder +eb2.geom_type = cylinder +eb2.cylinder_has_fluid_inside = 0 +eb2.cylinder_radius = 0.05 +eb2.cylinder_direction = 2 +eb2.cylinder_center = 0.15 0.2 0.0 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PROBLEM PARAMETERS # +#.......................................# + +prob.probtype = 4 +prob.blob_center = -0.55 0.05 0.0 +prob.blob_radius = 0.04 +# Constant density initial condition +prob.density_ic = 1.0 +# Set up a flow, defaults to zero +prob.velocity_ic = 1. 0. 0. + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# VERBOSITY # +#.......................................# +ns.v = 1 # NS solver +nodal_proj.verbose = 0 # Nodal projection +mac_proj.verbose = 0 # MacProjector +diffuse.v = 0 # Diffusion operator + diff --git a/Tutorials_profiling/FlowPastCylinder/inputs.3d.flow_past_cylinder-y b/Tutorials_profiling/FlowPastCylinder/inputs.3d.flow_past_cylinder-y index e319c94e..8ecbfcea 100644 --- a/Tutorials_profiling/FlowPastCylinder/inputs.3d.flow_past_cylinder-y +++ b/Tutorials_profiling/FlowPastCylinder/inputs.3d.flow_past_cylinder-y @@ -1,78 +1,85 @@ -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SIMULATION STOP # -#.......................................# -stop_time = 0.2 # Max (simulated) time to evolve -max_step = -1 # Max number of time steps -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SOLVER SETTINGS # -#.......................................# -ns.init_iter = 3 # How many initial pressure iterations -ns.init_vel_iter = 5 # How many initial projeciton iterations to ensure velocity satisfies divergence constraint -ns.visc_tol = 1.0e-11 # tolerance for viscous solve -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# TIME STEP COMPUTATION # -#.......................................# -ns.cfl = 0.45 -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# INPUT AND OUTPUT # -#.......................................# -amr.plot_int = 50 # Steps between plot files -amr.plot_per = 0.1 # Steps between plot files -amr.check_int = 1000 # Steps between checkpoint files -amr.restart = "" # Checkpoint to restart from -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PHYSICS # -#.......................................# -ns.gravity = 0. -ns.vel_visc_coef = 0.001 -ns.scal_diff_coefs = 1.0 -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# ADAPTIVE MESH REFINEMENT # -#.......................................# -amr.n_cell = 8 96 32 # Grid cells at coarsest AMRlevel -amr.max_level = 0 # Max AMR level in hierarchy - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# GEOMETRY # -#.......................................# -geometry.prob_lo = 0. 0. 0. # Lo corner coordinates -geometry.prob_hi = 0.1 1.2 0.4 # Hi corner coordinates -geometry.is_periodic = 1 0 0 # Periodicity x y z (0/1) - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWal -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 1 5 -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 2 5 - -ylo.velocity = 0. 1. 0. - -# Add cylinder -eb2.geom_type = cylinder -eb2.cylinder_has_fluid_inside = 0 -eb2.cylinder_radius = 0.05 -eb2.cylinder_direction = 0 -eb2.cylinder_center = 0.0 0.15 0.2 - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PROBLEM PARAMETERS # -#.......................................# - -prob.probtype = 4 -prob.blob_center = 0.0 -0.55 0.05 -prob.blob_radius = 0.04 -# Constant density initial condition -prob.density_ic = 1.0 -# Set up a flow, defaults to zero -prob.velocity_ic = 0. 1. 0. - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# VERBOSITY # -#.......................................# -ns.v = 1 # NS solver -nodal_proj.verbose = 0 # Nodal projection -mac_proj.verbose = 0 # MacProjector -diffuse.v = 0 # Diffusion operator - +# SPDX-FileCopyrightText: 2019 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SIMULATION STOP # +#.......................................# +stop_time = 0.2 # Max (simulated) time to evolve +max_step = -1 # Max number of time steps +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SOLVER SETTINGS # +#.......................................# +ns.init_iter = 3 # How many initial pressure iterations +ns.init_vel_iter = 5 # How many initial projeciton iterations to ensure velocity satisfies divergence constraint +ns.visc_tol = 1.0e-11 # tolerance for viscous solve +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# TIME STEP COMPUTATION # +#.......................................# +ns.cfl = 0.45 +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# INPUT AND OUTPUT # +#.......................................# +amr.plot_int = 50 # Steps between plot files +amr.plot_per = 0.1 # Steps between plot files +amr.check_int = 1000 # Steps between checkpoint files +amr.restart = "" # Checkpoint to restart from +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PHYSICS # +#.......................................# +ns.gravity = 0. +ns.vel_visc_coef = 0.001 +ns.scal_diff_coefs = 1.0 +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# ADAPTIVE MESH REFINEMENT # +#.......................................# +amr.n_cell = 8 96 32 # Grid cells at coarsest AMRlevel +amr.max_level = 0 # Max AMR level in hierarchy + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# GEOMETRY # +#.......................................# +geometry.prob_lo = 0. 0. 0. # Lo corner coordinates +geometry.prob_hi = 0.1 1.2 0.4 # Hi corner coordinates +geometry.is_periodic = 1 0 0 # Periodicity x y z (0/1) + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWal +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 1 5 +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 2 5 + +ylo.velocity = 0. 1. 0. + +# Add cylinder +eb2.geom_type = cylinder +eb2.cylinder_has_fluid_inside = 0 +eb2.cylinder_radius = 0.05 +eb2.cylinder_direction = 0 +eb2.cylinder_center = 0.0 0.15 0.2 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PROBLEM PARAMETERS # +#.......................................# + +prob.probtype = 4 +prob.blob_center = 0.0 -0.55 0.05 +prob.blob_radius = 0.04 +# Constant density initial condition +prob.density_ic = 1.0 +# Set up a flow, defaults to zero +prob.velocity_ic = 0. 1. 0. + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# VERBOSITY # +#.......................................# +ns.v = 1 # NS solver +nodal_proj.verbose = 0 # Nodal projection +mac_proj.verbose = 0 # MacProjector +diffuse.v = 0 # Diffusion operator + diff --git a/Tutorials_profiling/FlowPastCylinder/inputs.3d.flow_past_cylinder-z b/Tutorials_profiling/FlowPastCylinder/inputs.3d.flow_past_cylinder-z index cfb2e314..c242a40f 100644 --- a/Tutorials_profiling/FlowPastCylinder/inputs.3d.flow_past_cylinder-z +++ b/Tutorials_profiling/FlowPastCylinder/inputs.3d.flow_past_cylinder-z @@ -1,78 +1,85 @@ -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SIMULATION STOP # -#.......................................# -stop_time = 0.2 # Max (simulated) time to evolve -max_step = -1 # Max number of time steps -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# SOLVER SETTINGS # -#.......................................# -ns.init_iter = 3 # How many initial pressure iterations -ns.init_vel_iter = 5 # How many initial projeciton iterations to ensure velocity satisfies divergence constraint -ns.visc_tol = 1.0e-11 # tolerance for viscous solve -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# TIME STEP COMPUTATION # -#.......................................# -ns.cfl = 0.45 -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# INPUT AND OUTPUT # -#.......................................# -amr.plot_int = 50 # Steps between plot files -amr.plot_per = 0.1 # Steps between plot files -amr.check_int = 1000 # Steps between checkpoint files -amr.restart = "" # Checkpoint to restart from -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PHYSICS # -#.......................................# -ns.gravity = 0. -ns.vel_visc_coef = 0.001 -ns.scal_diff_coefs = 1.0 -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# ADAPTIVE MESH REFINEMENT # -#.......................................# -amr.n_cell = 32 8 96 # Grid cells at coarsest AMRlevel -amr.max_level = 0 # Max AMR level in hierarchy - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# GEOMETRY # -#.......................................# -geometry.prob_lo = 0. 0. 0. # Lo corner coordinates -geometry.prob_hi = 0.4 0.1 1.2 # Hi corner coordinates -geometry.is_periodic = 0 1 0 # Periodicity x y z (0/1) - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWal -# Boundary conditions on the low end of the domain. -ns.lo_bc = 5 0 1 -# Boundary conditions on the high end of the domain. -ns.hi_bc = 5 0 2 - -zlo.velocity = 0. 0. 1. - -# Add cylinder -eb2.geom_type = cylinder -eb2.cylinder_has_fluid_inside = 0 -eb2.cylinder_radius = 0.05 -eb2.cylinder_direction = 1 -eb2.cylinder_center = 0.2 0.0 0.15 - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# PROBLEM PARAMETERS # -#.......................................# - -prob.probtype = 4 -prob.blob_center = 0.05 0.0 -0.55 -prob.blob_radius = 0.04 -# Constant density initial condition -prob.density_ic = 1.0 -# Set up a flow, defaults to zero -prob.velocity_ic = 0. 0. 1. - -#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# -# VERBOSITY # -#.......................................# -ns.v = 1 # NS solver -nodal_proj.verbose = 0 # Nodal projection -mac_proj.verbose = 0 # MacProjector -diffuse.v = 0 # Diffusion operator - +# SPDX-FileCopyrightText: 2019 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SIMULATION STOP # +#.......................................# +stop_time = 0.2 # Max (simulated) time to evolve +max_step = -1 # Max number of time steps +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# SOLVER SETTINGS # +#.......................................# +ns.init_iter = 3 # How many initial pressure iterations +ns.init_vel_iter = 5 # How many initial projeciton iterations to ensure velocity satisfies divergence constraint +ns.visc_tol = 1.0e-11 # tolerance for viscous solve +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# TIME STEP COMPUTATION # +#.......................................# +ns.cfl = 0.45 +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# INPUT AND OUTPUT # +#.......................................# +amr.plot_int = 50 # Steps between plot files +amr.plot_per = 0.1 # Steps between plot files +amr.check_int = 1000 # Steps between checkpoint files +amr.restart = "" # Checkpoint to restart from +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PHYSICS # +#.......................................# +ns.gravity = 0. +ns.vel_visc_coef = 0.001 +ns.scal_diff_coefs = 1.0 +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# ADAPTIVE MESH REFINEMENT # +#.......................................# +amr.n_cell = 32 8 96 # Grid cells at coarsest AMRlevel +amr.max_level = 0 # Max AMR level in hierarchy + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# GEOMETRY # +#.......................................# +geometry.prob_lo = 0. 0. 0. # Lo corner coordinates +geometry.prob_hi = 0.4 0.1 1.2 # Hi corner coordinates +geometry.is_periodic = 0 1 0 # Periodicity x y z (0/1) + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWal +# Boundary conditions on the low end of the domain. +ns.lo_bc = 5 0 1 +# Boundary conditions on the high end of the domain. +ns.hi_bc = 5 0 2 + +zlo.velocity = 0. 0. 1. + +# Add cylinder +eb2.geom_type = cylinder +eb2.cylinder_has_fluid_inside = 0 +eb2.cylinder_radius = 0.05 +eb2.cylinder_direction = 1 +eb2.cylinder_center = 0.2 0.0 0.15 + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# PROBLEM PARAMETERS # +#.......................................# + +prob.probtype = 4 +prob.blob_center = 0.05 0.0 -0.55 +prob.blob_radius = 0.04 +# Constant density initial condition +prob.density_ic = 1.0 +# Set up a flow, defaults to zero +prob.velocity_ic = 0. 0. 1. + +#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# +# VERBOSITY # +#.......................................# +ns.v = 1 # NS solver +nodal_proj.verbose = 0 # Nodal projection +mac_proj.verbose = 0 # MacProjector +diffuse.v = 0 # Diffusion operator + diff --git a/Tutorials_profiling/HIT/.gitignore b/Tutorials_profiling/HIT/.gitignore index abbed0cd..b7beb871 100644 --- a/Tutorials_profiling/HIT/.gitignore +++ b/Tutorials_profiling/HIT/.gitignore @@ -1 +1 @@ -*.0.0 +*.0.0 diff --git a/Tutorials_profiling/HIT/GNUmakefile b/Tutorials_profiling/HIT/GNUmakefile index e25abc63..d9224c88 100644 --- a/Tutorials_profiling/HIT/GNUmakefile +++ b/Tutorials_profiling/HIT/GNUmakefile @@ -1,56 +1,56 @@ -#AMREX_HOME defines the directory in which we will find the BoxLib directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -DIM = 3 -COMP = gcc -DEBUG = FALSE -USE_MPI = TRUE -USE_OMP = FALSE - -USE_CUDA = FALSE - -USE_TURBULENT_FORCING = TRUE -USE_FAST_FORCE = FALSE - -#TEST=TRUE -#USE_ASSERTION=TRUE - -PRECISION = DOUBLE - -USE_HYPRE = FALSE -USE_METIS = FALSE - -USE_VELOCITY = TRUE -USE_VELOCITY = FALSE - -USE_XBLAS = TRUE -USE_XBLAS = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -ifeq (${USE_XBLAS}, TRUE) - XTRADEFS += -DXBLAS - XTRAINCLOC += $(HOME)/tmp/xblas-1.0.248/src - XTRALIBLOC += $(HOME)/tmp/xblas-1.0.248/src - XTRALIBS += -lxblas -endif - -ifeq (${USE_VELOCITY}, TRUE) - #AMRVIS_DIR defines the directory in which we will find pAmrvis (e.g. DataServices, AmrData and FABUTIL) - AMRVIS_DIR = $(AMREX_HOME)/Src/Extern/amrdata -endif - -Blocs := . - -include ./Make.package -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the BoxLib directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +DIM = 3 +COMP = gcc +DEBUG = FALSE +USE_MPI = TRUE +USE_OMP = FALSE + +USE_CUDA = FALSE + +USE_TURBULENT_FORCING = TRUE +USE_FAST_FORCE = FALSE + +#TEST=TRUE +#USE_ASSERTION=TRUE + +PRECISION = DOUBLE + +USE_HYPRE = FALSE +USE_METIS = FALSE + +USE_VELOCITY = TRUE +USE_VELOCITY = FALSE + +USE_XBLAS = TRUE +USE_XBLAS = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +ifeq (${USE_XBLAS}, TRUE) + XTRADEFS += -DXBLAS + XTRAINCLOC += $(HOME)/tmp/xblas-1.0.248/src + XTRALIBLOC += $(HOME)/tmp/xblas-1.0.248/src + XTRALIBS += -lxblas +endif + +ifeq (${USE_VELOCITY}, TRUE) + #AMRVIS_DIR defines the directory in which we will find pAmrvis (e.g. DataServices, AmrData and FABUTIL) + AMRVIS_DIR = $(AMREX_HOME)/Src/Extern/amrdata +endif + +Blocs := . + +include ./Make.package +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials_profiling/HIT/Make.package b/Tutorials_profiling/HIT/Make.package index eaa3438c..026272b0 100644 --- a/Tutorials_profiling/HIT/Make.package +++ b/Tutorials_profiling/HIT/Make.package @@ -1,10 +1,10 @@ -ifeq ($(USE_VELOCITY), TRUE) - CEXE_headers += DataServices.H AmrData.H XYPlotDataList.H AmrvisConstants.H - CEXE_sources += DataServices.cpp AmrData.cpp - FEXE_sources += FABUTIL_$(DIM)D.F -endif - -ifeq ($(USE_TURBULENT_FORCING), TRUE) - CEXE_headers += TurbulentForcing_params.H TurbulentForcing_def.H depRand.H - CEXE_sources += depRand.cpp -endif +ifeq ($(USE_VELOCITY), TRUE) + CEXE_headers += DataServices.H AmrData.H XYPlotDataList.H AmrvisConstants.H + CEXE_sources += DataServices.cpp AmrData.cpp + FEXE_sources += FABUTIL_$(DIM)D.F +endif + +ifeq ($(USE_TURBULENT_FORCING), TRUE) + CEXE_headers += TurbulentForcing_params.H TurbulentForcing_def.H depRand.H + CEXE_sources += depRand.cpp +endif diff --git a/Tutorials_profiling/HIT/NS_getForce.cpp b/Tutorials_profiling/HIT/NS_getForce.cpp index 990f28f7..6de6fd67 100644 --- a/Tutorials_profiling/HIT/NS_getForce.cpp +++ b/Tutorials_profiling/HIT/NS_getForce.cpp @@ -1,786 +1,789 @@ - -#include -#ifdef AMREX_USE_TURBULENT_FORCING -#include -#include -#endif - - -using namespace amrex; - -// -// Virtual access function for getting the forcing terms for the -// velocities and scalars. The base version computes a buoyancy. -// -// NOTE: This function returns a rho weighted source term. -// -// For conservative (i.e. do_mom_diff=1, do_cons_trac=1), velocities -// are integrated according to the equation -// -// ui_t + uj ui_j = S_ui ===> tforces = rho S_ui -// -// and scalars psi where (psi = rho q = Scal) as -// -// psi_t + (uj psi)_j = S_psi ===> tforces = S_psi = rho S_q -// -// For non-conservative, this rho-weighted source term will get divided -// by rho in the predict_velocity, velocity_advection, scalar_advection, -// and advection_update routines. -// -// For temperature (which is always non-conservative), we evolve -// -// dT/dt - U dot grad T = [del dot lambda grad T + S_T] / (rho*c_p) -// ===> tforces = S_T/c_p -// -// -// For user-defined forcing, this means -// - For conservative variables, the force term computed here gets used -// as-is -// - For non-conservative variables, the force term computed here is -// divided by rho before use -// - -void -NavierStokesBase::getForce (FArrayBox& force, - const Box& bx, - int scomp, - int ncomp, - const Real time, - const FArrayBox& Vel, - const FArrayBox& Scal, - int scalScomp, - const MFIter& mfi) -{ - - const Real* VelDataPtr = Vel.dataPtr(); - const Real* ScalDataPtr = Scal.dataPtr(scalScomp); - - const Real grav = gravity; - const int* f_lo = force.loVect(); - const int* f_hi = force.hiVect(); - const int* v_lo = Vel.loVect(); - const int* v_hi = Vel.hiVect(); - const int* s_lo = Scal.loVect(); - const int* s_hi = Scal.hiVect(); - - if (ParallelDescriptor::IOProcessor() && getForceVerbose) { - amrex::Print() << "NavierStokesBase::getForce(): Entered..." << std::endl - << "time = " << time << std::endl - << "scomp = " << scomp << std::endl - << "ncomp = " << ncomp << std::endl - << "scalScomp = " << scalScomp << std::endl; - - if (scomp==0) - if (ncomp==3) amrex::Print() << "Doing velocities only" << std::endl; - else amrex::Print() << "Doing all components" << std::endl; - else if (scomp==3) - if (ncomp==1) amrex::Print() << "Doing density only" << std::endl; - else amrex::Print() << "Doing all scalars" << std::endl; - else if (scomp==4) amrex::Print() << "Doing tracer only" << std::endl; - else amrex::Print() << "Doing individual scalar" << std::endl; - - amrex::Print() << "NavierStokesBase::getForce(): Filling Force on box:" - << bx << std::endl; -#if (AMREX_SPACEDIM == 3) - amrex::Print() << "NavierStokesBase::getForce(): Force Domain:" << std::endl; - amrex::Print() << "(" << f_lo[0] << "," << f_lo[1] << "," << f_lo[2] << ") - " - << "(" << f_hi[0] << "," << f_hi[1] << "," << f_hi[2] << ")" << std::endl; - amrex::Print() << "NavierStokesBase::getForce(): Vel Domain:" << std::endl; - amrex::Print() << "(" << v_lo[0] << "," << v_lo[1] << "," << v_lo[2] << ") - " - << "(" << v_hi[0] << "," << v_hi[1] << "," << v_hi[2] << ")" << std::endl; - amrex::Print() << "NavierStokesBase::getForce(): Scal Domain:" << std::endl; - amrex::Print() << "(" << s_lo[0] << "," << s_lo[1] << "," << s_lo[2] << ") - " - << "(" << s_hi[0] << "," << s_hi[1] << "," << s_hi[2] << ")" << std::endl; -#else - amrex::Print() << "NavierStokesBase::getForce(): Force Domain:" << std::endl; - amrex::Print() << "(" << f_lo[0] << "," << f_lo[1] << ") - " - << "(" << f_hi[0] << "," << f_hi[1] << ")" << std::endl; - amrex::Print() << "NavierStokesBase::getForce(): Vel Domain:" << std::endl; - amrex::Print() << "(" << v_lo[0] << "," << v_lo[1] << ") - " - << "(" << v_hi[0] << "," << v_hi[1] << ")" << std::endl; - amrex::Print() << "NavierStokesBase::getForce(): Scal Domain:" << std::endl; - amrex::Print() << "(" << s_lo[0] << "," << s_lo[1] << ") - " - << "(" << s_hi[0] << "," << s_hi[1] << ")" << std::endl; -#endif - - Vector velmin(AMREX_SPACEDIM), velmax(AMREX_SPACEDIM); - Vector scalmin(NUM_SCALARS), scalmax(NUM_SCALARS); - for (int n=0; nvelmax[n]) velmax[n] = v; - } - } - } -#if (AMREX_SPACEDIM == 3) - } -#endif - for (int n=0; nscalmax[n]) scalmax[n] = s; - } - } - } -#if (AMREX_SPACEDIM == 3) - } -#endif - for (int n=0; n=AMREX_SPACEDIM); - } - - if ( scomp==Xvel ){ - // - // TODO: add some switch for user-supplied/problem-dependent forcing - // - auto const& frc = force.array(scomp); - auto const& scal = Scal.array(scalScomp); - - if ( std::abs(grav) > 0.0001) { - amrex::ParallelFor(bx, [frc, scal, grav] - AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - frc(i,j,k,0) = Real(0.0); -#if ( AMREX_SPACEDIM == 2 ) - frc(i,j,k,1) = grav*scal(i,j,k,0); -#elif ( AMREX_SPACEDIM == 3 ) - frc(i,j,k,1) = Real(0.0); - frc(i,j,k,2) = grav*scal(i,j,k,0); -#endif - }); - } - else { - force.setVal(0.0, bx, Xvel, AMREX_SPACEDIM); - } - -#ifdef AMREX_USE_TURBULENT_FORCING - // - // Homogeneous Isotropic Forced Turbulence - // - - // Physical coordinates of the lower left corner of the domain - auto const& problo = geom.ProbLoArray(); - // Physical coordinates of the upper right corner of the domain - auto const& probhi = geom.ProbHiArray(); - - Real Lx = probhi[0]-problo[0]; - Real Ly = probhi[1]-problo[1]; - Real Lz = probhi[2]-problo[2]; - Real Lmin = min(Lx,Ly,Lz); - - - // For now, only works in 3D and without tiling - AMREX_ALWAYS_ASSERT(bx==force.box()); - AMREX_ASSERT(AMREX_SPACEDIM==3); - - int xstep = static_cast(Lx/Lmin+0.5); - int ystep = static_cast(Ly/Lmin+0.5); - int zstep = static_cast(Lz/Lmin+0.5); - - Real kappaMax = TurbulentForcing::nmodes/Lmin + 1.0e-8; - - // force array bounds - // FIXME -- think about how bx (the box we want to fill) may not be the same as the force box! - int ilo = f_lo[0]; - int jlo = f_lo[1]; - int klo = f_lo[2]; - - auto const& dx = geom.CellSizeArray(); - Real hx = dx[0]; - Real hy = dx[1]; - Real hz = dx[2]; - - // Separate out forcing data into individual Array4's - int i_arr = 0; - int fd_ncomp = 1; - int num_elmts=TurbulentForcing::array_size*TurbulentForcing::array_size*TurbulentForcing::array_size; - Dim3 fd_begin{0,0,0}; - Dim3 fd_end{TurbulentForcing::array_size,TurbulentForcing::array_size,TurbulentForcing::array_size}; - - Array4 FTX(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 TAT(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 FPX(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 FPY(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 FPZ(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 FAX(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 FAY(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 FAZ(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 FPXX(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 FPXY(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 FPXZ(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 FPYX(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 FPYY(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 FPYZ(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 FPZX(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 FPZY(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - i_arr++; - Array4 FPZZ(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); - -//fixme -// check the arrays - // { - // int i = 0; - // int j = 0; - // int k = 0; - - // Print()<<"FTX, TAT: "< xlo = {AMREX_D_DECL(loc_lo[0],loc_lo[1],loc_lo[2])}; - - -#ifdef AMREX_USE_FAST_FORCE - // - // Construct force at fewer points and then interpolate. - // This is much faster on CPU. - // - - int ihi = f_hi[0]; - int jhi = f_hi[1]; - int khi = f_hi[2]; - - // coarse cell size - Real ff_hx = hx*TurbulentForcing::ff_factor; - Real ff_hy = hy*TurbulentForcing::ff_factor; - Real ff_hz = hz*TurbulentForcing::ff_factor; - - // coarse bounds (without accounting for ghost cells) - // FIXME -- think about how bx (the box we want to fill) may not be the same as the force box! - int ff_ilo = ilo/TurbulentForcing::ff_factor; - int ff_jlo = jlo/TurbulentForcing::ff_factor; - int ff_klo = klo/TurbulentForcing::ff_factor; - - int ff_ihi = (ihi+1)/TurbulentForcing::ff_factor; - int ff_jhi = (jhi+1)/TurbulentForcing::ff_factor; - int ff_khi = (khi+1)/TurbulentForcing::ff_factor; - - // adjust for ghost cells - if (ilo < (ff_ilo*TurbulentForcing::ff_factor)) { - ff_ilo=ff_ilo-1; - } - if (jlo < (ff_jlo*TurbulentForcing::ff_factor)) { - ff_jlo=ff_jlo-1; - } - if (klo < (ff_klo*TurbulentForcing::ff_factor)) { - ff_klo=ff_klo-1; - } - if (ihi == (ff_ihi*TurbulentForcing::ff_factor)) { - ff_ihi=ff_ihi+1; - } - if (jhi == (ff_jhi*TurbulentForcing::ff_factor)) { - ff_jhi=ff_jhi+1; - } - if (khi == (ff_khi*TurbulentForcing::ff_factor)) { - ff_khi=ff_khi+1; - } - - // allocate coarse force array - Box ffbx(IntVect(ff_ilo, ff_jlo, ff_klo), IntVect(ff_ihi, ff_jhi, ff_khi)); - // not sure if want elixir, gpu::sync, or async_arena here... - FArrayBox ff_force(ffbx,AMREX_SPACEDIM); - const auto& ffarr = ff_force.array(); - - // Construct node-based coarse forcing - amrex::ParallelFor(ffbx, [ = ] - AMREX_GPU_DEVICE (int i, int j, int k ) noexcept - { - Real z = xlo[2] + ff_hz*(k-ff_klo); - Real y = xlo[1] + ff_hy*(j-ff_jlo); - Real x = xlo[0] + ff_hx*(i-ff_ilo); - - for (int n = 0; n < AMREX_SPACEDIM; n++) - ffarr(i,j,k,n) = 0.0; - - // forcedata (and Array4) has column-major layout - for (int kz = TurbulentForcing::mode_start*zstep; kz <= TurbulentForcing::nmodes*zstep; kz += zstep) { - for (int ky = TurbulentForcing::mode_start*ystep; ky <= TurbulentForcing::nmodes*ystep; ky += ystep) { - for (int kx = TurbulentForcing::mode_start*xstep; kx <= TurbulentForcing::nmodes*xstep; kx += xstep) - { - Real kappa = sqrt( (kx*kx)/(Lx*Lx) + (ky*ky)/(Ly*Ly) + (kz*kz)/(Lz*Lz) ); - - if (kappa <= kappaMax) - { - Real xT = cos(FTX(kx,ky,kz)*time + TAT(kx,ky,kz)); - - if ( TurbulentForcing::div_free_force ) - { - ffarr(i,j,k,0) += xT * - ( FAZ(kx,ky,kz)*TwoPi*(ky/Ly) - * sin(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) - * cos(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) - - FAY(kx,ky,kz)*TwoPi*(kz/Lz) - * sin(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) - * cos(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) ); - - ffarr(i,j,k,1) += xT * - ( FAX(kx,ky,kz)*TwoPi*(kz/Lz) - * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) - * cos(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) - - FAZ(kx,ky,kz)*TwoPi*(kx/Lx) - * cos(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) ); - - ffarr(i,j,k,2) += xT * - ( FAY(kx,ky,kz)*TwoPi*(kx/Lx) - * cos(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) - - FAX(kx,ky,kz)*TwoPi*(ky/Ly) - * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) - * cos(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) ); - } - else - { - - ffarr(i,j,k,0) += xT*FAX(kx,ky,kz)*cos(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); - - ffarr(i,j,k,1) += xT*FAY(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) - * cos(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); - - ffarr(i,j,k,2) += xT*FAZ(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) - * cos(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); - } - } - } - } - } - - // - // For high aspect ratio domain, add more modes to break symmetry at a low level. - // We assume Lz is longer, Lx = Ly. - // - for ( int kz = 1; kz <= zstep-1; kz++) { - for ( int ky = TurbulentForcing::mode_start; ky <= TurbulentForcing::nmodes*ystep; ky++) { - for ( int kx = TurbulentForcing::mode_start; kx <= TurbulentForcing::nmodes*xstep; kx++) - { - Real kappa = sqrt( (kx*kx)/(Lx*Lx) + (ky*ky)/(Ly*Ly) + (kz*kz)/(Lz*Lz) ); - - if (kappa <= kappaMax) - { - Real xT = cos(FTX(kx,ky,kz)*time + TAT(kx,ky,kz)); - - if ( TurbulentForcing::div_free_force ) - { - ffarr(i,j,k,0) += xT * - ( FAZ(kx,ky,kz)*TwoPi*(ky/Ly) - * sin(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) - * cos(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) - - FAY(kx,ky,kz)*TwoPi*(kz/Lz) - * sin(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) - * cos(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) ); - - ffarr(i,j,k,1) += xT * - ( FAX(kx,ky,kz)*TwoPi*(kz/Lz) - * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) - * cos(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) - - FAZ(kx,ky,kz)*TwoPi*(kx/Lx) - * cos(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) ); - - ffarr(i,j,k,2) += xT * - ( FAY(kx,ky,kz)*TwoPi*(kx/Lx) - * cos(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) - - FAX(kx,ky,kz)*TwoPi*(ky/Ly) - * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) - * cos(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) ); - } - else - { - - ffarr(i,j,k,0) += xT*FAX(kx,ky,kz)*cos(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); - - ffarr(i,j,k,1) += xT*FAY(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) - * cos(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); - - ffarr(i,j,k,2) += xT*FAZ(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) - * cos(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); - } - } - } - } - } - - }); - - // Need all of ffarr filled for next lambda - amrex::Gpu::synchronize(); - - // Now interpolate onto fine grid - // bx is the box we want to fill and may be smaller than force - auto const& dens = Scal.array(scalScomp); - - amrex::ParallelFor(bx, AMREX_SPACEDIM, [ = ] - AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept - { - int ff_k = k/TurbulentForcing::ff_factor; - int ff_j = j/TurbulentForcing::ff_factor; - int ff_i = i/TurbulentForcing::ff_factor; - - Real zd = ( hz*(k-klo + 0.5) - ff_hz*(ff_k-ff_klo) )/ff_hz; - Real yd = ( hy*(j-jlo + 0.5) - ff_hy*(ff_j-ff_jlo) )/ff_hy; - Real xd = ( hx*(i-ilo + 0.5) - ff_hx*(ff_i-ff_ilo) )/ff_hx; - - Real ff00 = ffarr(ff_i ,ff_j ,ff_k ,n) * (1. - xd) - + ffarr(ff_i+1,ff_j ,ff_k ,n) * xd; - Real ff01 = ffarr(ff_i ,ff_j ,ff_k+1,n) * (1. - xd) - + ffarr(ff_i+1,ff_j ,ff_k+1,n) * xd; - Real ff10 = ffarr(ff_i ,ff_j+1,ff_k ,n) * (1. - xd) - + ffarr(ff_i+1,ff_j+1,ff_k ,n) * xd; - Real ff11 = ffarr(ff_i ,ff_j+1,ff_k+1,n) * (1. - xd) - + ffarr(ff_i+1,ff_j+1,ff_k+1,n) * xd; - - Real ff = ( ff00*(1.-yd)+ff10*yd ) * (1. - zd) - + ( ff01*(1.-yd)+ff11*yd ) * zd; - - frc(i,j,k,n) += dens(i,j,k,0) * ff; - - // if ( i==0 && j==0 && k==0 ){ - // printf("%15.13e %15.13e %15.13e %15.13e %15.13e\n", - // FTX(1,0,0), TAT(0,0,0),FAY(9,8,7), FPX(3,4,5), FPZZ(12,4,7) ); - // } - }); - -#else - - // - // Original implementation using all 33 points in k-space. - // May be fast enough on GPU. - // - - auto const& dens = Scal.array(scalScomp); - - // Construct cell-centered forcing - amrex::ParallelFor(bx, [ = ] - AMREX_GPU_DEVICE (int i, int j, int k ) noexcept - { - Real z = xlo[2] + hz*(k-klo + 0.5); - Real y = xlo[1] + hy*(j-jlo + 0.5); - Real x = xlo[0] + hx*(i-ilo + 0.5); - - Real f1 = 0; - Real f2 = 0; - Real f3 = 0; - - // forcedata (and Array4) has column-major layout - for (int kz = TurbulentForcing::mode_start*zstep; kz <= TurbulentForcing::nmodes*zstep; kz += zstep) { - for (int ky = TurbulentForcing::mode_start*ystep; ky <= TurbulentForcing::nmodes*ystep; ky += ystep) { - for (int kx = TurbulentForcing::mode_start*xstep; kx <= TurbulentForcing::nmodes*xstep; kx += xstep) - { - Real kappa = sqrt( (kx*kx)/(Lx*Lx) + (ky*ky)/(Ly*Ly) + (kz*kz)/(Lz*Lz) ); - - if (kappa <= kappaMax) - { - Real xT = cos(FTX(kx,ky,kz)*time + TAT(kx,ky,kz)); - - // if ( i==0 && j==0 && k==0 && kx==0 && ky==0 && kx==0){ - // printf("(0,0,0) : xT : %15.13e %15.13e %15.13e %15.13e\n", - // FTX(kx,ky,kz), time, TAT(kx,ky,kz), xT); - // Abort(); - // } - - - if ( TurbulentForcing::div_free_force ) - { - f1 += xT * - ( FAZ(kx,ky,kz)*TwoPi*(ky/Ly) - * sin(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) - * cos(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) - - FAY(kx,ky,kz)*TwoPi*(kz/Lz) - * sin(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) - * cos(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) ); - - f2 += xT * - ( FAX(kx,ky,kz)*TwoPi*(kz/Lz) - * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) - * cos(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) - - FAZ(kx,ky,kz)*TwoPi*(kx/Lx) - * cos(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) ); - - f3 += xT * - ( FAY(kx,ky,kz)*TwoPi*(kx/Lx) - * cos(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) - - FAX(kx,ky,kz)*TwoPi*(ky/Ly) - * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) - * cos(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) ); - } - else - { - - f1 += xT*FAX(kx,ky,kz)*cos(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); - - f2 += xT*FAY(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) - * cos(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); - - f3 += xT*FAZ(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) - * cos(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); - } - } - } - } - } - - // - // For high aspect ratio domain, add more modes to break symmetry at a low level. - // We assume Lz is longer, Lx = Ly. - // - for ( int kz = 1; kz <= zstep-1; kz++) { - for ( int ky = TurbulentForcing::mode_start; ky <= TurbulentForcing::nmodes*ystep; ky++) { - for ( int kx = TurbulentForcing::mode_start; kx <= TurbulentForcing::nmodes*xstep; kx++) - { - Real kappa = sqrt( (kx*kx)/(Lx*Lx) + (ky*ky)/(Ly*Ly) + (kz*kz)/(Lz*Lz) ); - - if (kappa <= kappaMax) - { - Real xT = cos(FTX(kx,ky,kz)*time + TAT(kx,ky,kz)); - - if ( TurbulentForcing::div_free_force ) - { - f1 += xT * - ( FAZ(kx,ky,kz)*TwoPi*(ky/Ly) - * sin(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) - * cos(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) - - FAY(kx,ky,kz)*TwoPi*(kz/Lz) - * sin(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) - * cos(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) ); - - f2 += xT * - ( FAX(kx,ky,kz)*TwoPi*(kz/Lz) - * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) - * cos(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) - - FAZ(kx,ky,kz)*TwoPi*(kx/Lx) - * cos(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) ); - - f3 += xT * - ( FAY(kx,ky,kz)*TwoPi*(kx/Lx) - * cos(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) - - FAX(kx,ky,kz)*TwoPi*(ky/Ly) - * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) - * cos(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) ); - } - else - { - - f1 += xT*FAX(kx,ky,kz)*cos(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); - - f2 += xT*FAY(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) - * cos(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) - * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); - - f3 += xT*FAZ(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) - * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) - * cos(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); - } - } - } - } - } - - frc(i,j,k,0) += dens(i,j,k,0) * f1; - frc(i,j,k,1) += dens(i,j,k,0) * f2; - frc(i,j,k,2) += dens(i,j,k,0) * f3; - - // if ( i==0 && j==0 && k==0 ){ - // printf("(0,0,0) : %15.13e %15.13e %15.13e\n", - // f1, f2, f3); - // } - // if ( i==16 && j==16 && k==16 ){ - // printf("(16,16,16) : %15.13e %15.13e %15.13e\n", - // f1, f2, f3); - // } - // if ( i==25 && j==12 && k==3 ){ - // printf("(25,12,3) : %15.13e %15.13e %15.13e\n", - // f1, f2, f3); - // } - - }); -#endif // Fast Force -#endif // Turbulent forcing - - } - - - // - // Scalar forcing - // - if ( scomp >= AMREX_SPACEDIM ) { - // Doing only scalars - force.setVal(0.0, bx, 0, ncomp); - - // - // Or create user-defined forcing. - // Recall we compute a density-weighted forcing term. - // - // auto const& frc = force.array(); - // amrex::ParallelFor(bx, ncomp, [frc] - // AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept - // { - // frc(i,j,k,n) = ; - // frc(i,j,k,n) *= rho; - // }); - } - else if ( scomp+ncomp > AMREX_SPACEDIM) { - // Doing scalars with vel - force.setVal(0.0, bx, Density, ncomp-Density); - - // - // Or create user-defined forcing. - // Recall we compute a density-weighted forcing term. - // - // auto const& frc = force.array(Density); - // amrex::ParallelFor(bx, ncomp-Density, [frc] - // AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept - // { - // frc(i,j,k,n) = ; - // frc(i,j,k,n) *= rho; - // }); - } - - if (ParallelDescriptor::IOProcessor() && getForceVerbose) { - Vector forcemin(ncomp); - Vector forcemax(ncomp); - for (int n=0; nforcemax[n]) forcemax[n] = f; - } - } - } -#if (AMREX_SPACEDIM == 3) - } -#endif - for (int n=0; n +#ifdef AMREX_USE_TURBULENT_FORCING +#include +#include +#endif + + +using namespace amrex; + +// +// Virtual access function for getting the forcing terms for the +// velocities and scalars. The base version computes a buoyancy. +// +// NOTE: This function returns a rho weighted source term. +// +// For conservative (i.e. do_mom_diff=1, do_cons_trac=1), velocities +// are integrated according to the equation +// +// ui_t + uj ui_j = S_ui ===> tforces = rho S_ui +// +// and scalars psi where (psi = rho q = Scal) as +// +// psi_t + (uj psi)_j = S_psi ===> tforces = S_psi = rho S_q +// +// For non-conservative, this rho-weighted source term will get divided +// by rho in the predict_velocity, velocity_advection, scalar_advection, +// and advection_update routines. +// +// For temperature (which is always non-conservative), we evolve +// +// dT/dt - U dot grad T = [del dot lambda grad T + S_T] / (rho*c_p) +// ===> tforces = S_T/c_p +// +// +// For user-defined forcing, this means +// - For conservative variables, the force term computed here gets used +// as-is +// - For non-conservative variables, the force term computed here is +// divided by rho before use +// + +void +NavierStokesBase::getForce (FArrayBox& force, + const Box& bx, + int scomp, + int ncomp, + const Real time, + const FArrayBox& Vel, + const FArrayBox& Scal, + int scalScomp, + const MFIter& mfi) +{ + + const Real* VelDataPtr = Vel.dataPtr(); + const Real* ScalDataPtr = Scal.dataPtr(scalScomp); + + const Real grav = gravity; + const int* f_lo = force.loVect(); + const int* f_hi = force.hiVect(); + const int* v_lo = Vel.loVect(); + const int* v_hi = Vel.hiVect(); + const int* s_lo = Scal.loVect(); + const int* s_hi = Scal.hiVect(); + + if (ParallelDescriptor::IOProcessor() && getForceVerbose) { + amrex::Print() << "NavierStokesBase::getForce(): Entered..." << std::endl + << "time = " << time << std::endl + << "scomp = " << scomp << std::endl + << "ncomp = " << ncomp << std::endl + << "scalScomp = " << scalScomp << std::endl; + + if (scomp==0) + if (ncomp==3) amrex::Print() << "Doing velocities only" << std::endl; + else amrex::Print() << "Doing all components" << std::endl; + else if (scomp==3) + if (ncomp==1) amrex::Print() << "Doing density only" << std::endl; + else amrex::Print() << "Doing all scalars" << std::endl; + else if (scomp==4) amrex::Print() << "Doing tracer only" << std::endl; + else amrex::Print() << "Doing individual scalar" << std::endl; + + amrex::Print() << "NavierStokesBase::getForce(): Filling Force on box:" + << bx << std::endl; +#if (AMREX_SPACEDIM == 3) + amrex::Print() << "NavierStokesBase::getForce(): Force Domain:" << std::endl; + amrex::Print() << "(" << f_lo[0] << "," << f_lo[1] << "," << f_lo[2] << ") - " + << "(" << f_hi[0] << "," << f_hi[1] << "," << f_hi[2] << ")" << std::endl; + amrex::Print() << "NavierStokesBase::getForce(): Vel Domain:" << std::endl; + amrex::Print() << "(" << v_lo[0] << "," << v_lo[1] << "," << v_lo[2] << ") - " + << "(" << v_hi[0] << "," << v_hi[1] << "," << v_hi[2] << ")" << std::endl; + amrex::Print() << "NavierStokesBase::getForce(): Scal Domain:" << std::endl; + amrex::Print() << "(" << s_lo[0] << "," << s_lo[1] << "," << s_lo[2] << ") - " + << "(" << s_hi[0] << "," << s_hi[1] << "," << s_hi[2] << ")" << std::endl; +#else + amrex::Print() << "NavierStokesBase::getForce(): Force Domain:" << std::endl; + amrex::Print() << "(" << f_lo[0] << "," << f_lo[1] << ") - " + << "(" << f_hi[0] << "," << f_hi[1] << ")" << std::endl; + amrex::Print() << "NavierStokesBase::getForce(): Vel Domain:" << std::endl; + amrex::Print() << "(" << v_lo[0] << "," << v_lo[1] << ") - " + << "(" << v_hi[0] << "," << v_hi[1] << ")" << std::endl; + amrex::Print() << "NavierStokesBase::getForce(): Scal Domain:" << std::endl; + amrex::Print() << "(" << s_lo[0] << "," << s_lo[1] << ") - " + << "(" << s_hi[0] << "," << s_hi[1] << ")" << std::endl; +#endif + + Vector velmin(AMREX_SPACEDIM), velmax(AMREX_SPACEDIM); + Vector scalmin(NUM_SCALARS), scalmax(NUM_SCALARS); + for (int n=0; nvelmax[n]) velmax[n] = v; + } + } + } +#if (AMREX_SPACEDIM == 3) + } +#endif + for (int n=0; nscalmax[n]) scalmax[n] = s; + } + } + } +#if (AMREX_SPACEDIM == 3) + } +#endif + for (int n=0; n=AMREX_SPACEDIM); + } + + if ( scomp==Xvel ){ + // + // TODO: add some switch for user-supplied/problem-dependent forcing + // + auto const& frc = force.array(scomp); + auto const& scal = Scal.array(scalScomp); + + if ( std::abs(grav) > 0.0001) { + amrex::ParallelFor(bx, [frc, scal, grav] + AMREX_GPU_DEVICE(int i, int j, int k) noexcept + { + frc(i,j,k,0) = Real(0.0); +#if ( AMREX_SPACEDIM == 2 ) + frc(i,j,k,1) = grav*scal(i,j,k,0); +#elif ( AMREX_SPACEDIM == 3 ) + frc(i,j,k,1) = Real(0.0); + frc(i,j,k,2) = grav*scal(i,j,k,0); +#endif + }); + } + else { + force.setVal(0.0, bx, Xvel, AMREX_SPACEDIM); + } + +#ifdef AMREX_USE_TURBULENT_FORCING + // + // Homogeneous Isotropic Forced Turbulence + // + + // Physical coordinates of the lower left corner of the domain + auto const& problo = geom.ProbLoArray(); + // Physical coordinates of the upper right corner of the domain + auto const& probhi = geom.ProbHiArray(); + + Real Lx = probhi[0]-problo[0]; + Real Ly = probhi[1]-problo[1]; + Real Lz = probhi[2]-problo[2]; + Real Lmin = min(Lx,Ly,Lz); + + + // For now, only works in 3D and without tiling + AMREX_ALWAYS_ASSERT(bx==force.box()); + AMREX_ASSERT(AMREX_SPACEDIM==3); + + int xstep = static_cast(Lx/Lmin+0.5); + int ystep = static_cast(Ly/Lmin+0.5); + int zstep = static_cast(Lz/Lmin+0.5); + + Real kappaMax = TurbulentForcing::nmodes/Lmin + 1.0e-8; + + // force array bounds + // FIXME -- think about how bx (the box we want to fill) may not be the same as the force box! + int ilo = f_lo[0]; + int jlo = f_lo[1]; + int klo = f_lo[2]; + + auto const& dx = geom.CellSizeArray(); + Real hx = dx[0]; + Real hy = dx[1]; + Real hz = dx[2]; + + // Separate out forcing data into individual Array4's + int i_arr = 0; + int fd_ncomp = 1; + int num_elmts=TurbulentForcing::array_size*TurbulentForcing::array_size*TurbulentForcing::array_size; + Dim3 fd_begin{0,0,0}; + Dim3 fd_end{TurbulentForcing::array_size,TurbulentForcing::array_size,TurbulentForcing::array_size}; + + Array4 FTX(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 TAT(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 FPX(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 FPY(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 FPZ(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 FAX(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 FAY(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 FAZ(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 FPXX(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 FPXY(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 FPXZ(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 FPYX(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 FPYY(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 FPYZ(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 FPZX(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 FPZY(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + i_arr++; + Array4 FPZZ(&TurbulentForcing::forcedata[i_arr*num_elmts], fd_begin, fd_end, fd_ncomp); + +//fixme +// check the arrays + // { + // int i = 0; + // int j = 0; + // int k = 0; + + // Print()<<"FTX, TAT: "< xlo = {AMREX_D_DECL(loc_lo[0],loc_lo[1],loc_lo[2])}; + + +#ifdef AMREX_USE_FAST_FORCE + // + // Construct force at fewer points and then interpolate. + // This is much faster on CPU. + // + + int ihi = f_hi[0]; + int jhi = f_hi[1]; + int khi = f_hi[2]; + + // coarse cell size + Real ff_hx = hx*TurbulentForcing::ff_factor; + Real ff_hy = hy*TurbulentForcing::ff_factor; + Real ff_hz = hz*TurbulentForcing::ff_factor; + + // coarse bounds (without accounting for ghost cells) + // FIXME -- think about how bx (the box we want to fill) may not be the same as the force box! + int ff_ilo = ilo/TurbulentForcing::ff_factor; + int ff_jlo = jlo/TurbulentForcing::ff_factor; + int ff_klo = klo/TurbulentForcing::ff_factor; + + int ff_ihi = (ihi+1)/TurbulentForcing::ff_factor; + int ff_jhi = (jhi+1)/TurbulentForcing::ff_factor; + int ff_khi = (khi+1)/TurbulentForcing::ff_factor; + + // adjust for ghost cells + if (ilo < (ff_ilo*TurbulentForcing::ff_factor)) { + ff_ilo=ff_ilo-1; + } + if (jlo < (ff_jlo*TurbulentForcing::ff_factor)) { + ff_jlo=ff_jlo-1; + } + if (klo < (ff_klo*TurbulentForcing::ff_factor)) { + ff_klo=ff_klo-1; + } + if (ihi == (ff_ihi*TurbulentForcing::ff_factor)) { + ff_ihi=ff_ihi+1; + } + if (jhi == (ff_jhi*TurbulentForcing::ff_factor)) { + ff_jhi=ff_jhi+1; + } + if (khi == (ff_khi*TurbulentForcing::ff_factor)) { + ff_khi=ff_khi+1; + } + + // allocate coarse force array + Box ffbx(IntVect(ff_ilo, ff_jlo, ff_klo), IntVect(ff_ihi, ff_jhi, ff_khi)); + // not sure if want elixir, gpu::sync, or async_arena here... + FArrayBox ff_force(ffbx,AMREX_SPACEDIM); + const auto& ffarr = ff_force.array(); + + // Construct node-based coarse forcing + amrex::ParallelFor(ffbx, [ = ] + AMREX_GPU_DEVICE (int i, int j, int k ) noexcept + { + Real z = xlo[2] + ff_hz*(k-ff_klo); + Real y = xlo[1] + ff_hy*(j-ff_jlo); + Real x = xlo[0] + ff_hx*(i-ff_ilo); + + for (int n = 0; n < AMREX_SPACEDIM; n++) + ffarr(i,j,k,n) = 0.0; + + // forcedata (and Array4) has column-major layout + for (int kz = TurbulentForcing::mode_start*zstep; kz <= TurbulentForcing::nmodes*zstep; kz += zstep) { + for (int ky = TurbulentForcing::mode_start*ystep; ky <= TurbulentForcing::nmodes*ystep; ky += ystep) { + for (int kx = TurbulentForcing::mode_start*xstep; kx <= TurbulentForcing::nmodes*xstep; kx += xstep) + { + Real kappa = sqrt( (kx*kx)/(Lx*Lx) + (ky*ky)/(Ly*Ly) + (kz*kz)/(Lz*Lz) ); + + if (kappa <= kappaMax) + { + Real xT = cos(FTX(kx,ky,kz)*time + TAT(kx,ky,kz)); + + if ( TurbulentForcing::div_free_force ) + { + ffarr(i,j,k,0) += xT * + ( FAZ(kx,ky,kz)*TwoPi*(ky/Ly) + * sin(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) + * cos(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) + - FAY(kx,ky,kz)*TwoPi*(kz/Lz) + * sin(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) + * cos(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) ); + + ffarr(i,j,k,1) += xT * + ( FAX(kx,ky,kz)*TwoPi*(kz/Lz) + * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) + * cos(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) + - FAZ(kx,ky,kz)*TwoPi*(kx/Lx) + * cos(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) ); + + ffarr(i,j,k,2) += xT * + ( FAY(kx,ky,kz)*TwoPi*(kx/Lx) + * cos(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) + - FAX(kx,ky,kz)*TwoPi*(ky/Ly) + * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) + * cos(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) ); + } + else + { + + ffarr(i,j,k,0) += xT*FAX(kx,ky,kz)*cos(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); + + ffarr(i,j,k,1) += xT*FAY(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) + * cos(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); + + ffarr(i,j,k,2) += xT*FAZ(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) + * cos(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); + } + } + } + } + } + + // + // For high aspect ratio domain, add more modes to break symmetry at a low level. + // We assume Lz is longer, Lx = Ly. + // + for ( int kz = 1; kz <= zstep-1; kz++) { + for ( int ky = TurbulentForcing::mode_start; ky <= TurbulentForcing::nmodes*ystep; ky++) { + for ( int kx = TurbulentForcing::mode_start; kx <= TurbulentForcing::nmodes*xstep; kx++) + { + Real kappa = sqrt( (kx*kx)/(Lx*Lx) + (ky*ky)/(Ly*Ly) + (kz*kz)/(Lz*Lz) ); + + if (kappa <= kappaMax) + { + Real xT = cos(FTX(kx,ky,kz)*time + TAT(kx,ky,kz)); + + if ( TurbulentForcing::div_free_force ) + { + ffarr(i,j,k,0) += xT * + ( FAZ(kx,ky,kz)*TwoPi*(ky/Ly) + * sin(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) + * cos(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) + - FAY(kx,ky,kz)*TwoPi*(kz/Lz) + * sin(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) + * cos(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) ); + + ffarr(i,j,k,1) += xT * + ( FAX(kx,ky,kz)*TwoPi*(kz/Lz) + * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) + * cos(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) + - FAZ(kx,ky,kz)*TwoPi*(kx/Lx) + * cos(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) ); + + ffarr(i,j,k,2) += xT * + ( FAY(kx,ky,kz)*TwoPi*(kx/Lx) + * cos(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) + - FAX(kx,ky,kz)*TwoPi*(ky/Ly) + * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) + * cos(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) ); + } + else + { + + ffarr(i,j,k,0) += xT*FAX(kx,ky,kz)*cos(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); + + ffarr(i,j,k,1) += xT*FAY(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) + * cos(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); + + ffarr(i,j,k,2) += xT*FAZ(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) + * cos(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); + } + } + } + } + } + + }); + + // Need all of ffarr filled for next lambda + amrex::Gpu::synchronize(); + + // Now interpolate onto fine grid + // bx is the box we want to fill and may be smaller than force + auto const& dens = Scal.array(scalScomp); + + amrex::ParallelFor(bx, AMREX_SPACEDIM, [ = ] + AMREX_GPU_DEVICE (int i, int j, int k, int n ) noexcept + { + int ff_k = k/TurbulentForcing::ff_factor; + int ff_j = j/TurbulentForcing::ff_factor; + int ff_i = i/TurbulentForcing::ff_factor; + + Real zd = ( hz*(k-klo + 0.5) - ff_hz*(ff_k-ff_klo) )/ff_hz; + Real yd = ( hy*(j-jlo + 0.5) - ff_hy*(ff_j-ff_jlo) )/ff_hy; + Real xd = ( hx*(i-ilo + 0.5) - ff_hx*(ff_i-ff_ilo) )/ff_hx; + + Real ff00 = ffarr(ff_i ,ff_j ,ff_k ,n) * (1. - xd) + + ffarr(ff_i+1,ff_j ,ff_k ,n) * xd; + Real ff01 = ffarr(ff_i ,ff_j ,ff_k+1,n) * (1. - xd) + + ffarr(ff_i+1,ff_j ,ff_k+1,n) * xd; + Real ff10 = ffarr(ff_i ,ff_j+1,ff_k ,n) * (1. - xd) + + ffarr(ff_i+1,ff_j+1,ff_k ,n) * xd; + Real ff11 = ffarr(ff_i ,ff_j+1,ff_k+1,n) * (1. - xd) + + ffarr(ff_i+1,ff_j+1,ff_k+1,n) * xd; + + Real ff = ( ff00*(1.-yd)+ff10*yd ) * (1. - zd) + + ( ff01*(1.-yd)+ff11*yd ) * zd; + + frc(i,j,k,n) += dens(i,j,k,0) * ff; + + // if ( i==0 && j==0 && k==0 ){ + // printf("%15.13e %15.13e %15.13e %15.13e %15.13e\n", + // FTX(1,0,0), TAT(0,0,0),FAY(9,8,7), FPX(3,4,5), FPZZ(12,4,7) ); + // } + }); + +#else + + // + // Original implementation using all 33 points in k-space. + // May be fast enough on GPU. + // + + auto const& dens = Scal.array(scalScomp); + + // Construct cell-centered forcing + amrex::ParallelFor(bx, [ = ] + AMREX_GPU_DEVICE (int i, int j, int k ) noexcept + { + Real z = xlo[2] + hz*(k-klo + 0.5); + Real y = xlo[1] + hy*(j-jlo + 0.5); + Real x = xlo[0] + hx*(i-ilo + 0.5); + + Real f1 = 0; + Real f2 = 0; + Real f3 = 0; + + // forcedata (and Array4) has column-major layout + for (int kz = TurbulentForcing::mode_start*zstep; kz <= TurbulentForcing::nmodes*zstep; kz += zstep) { + for (int ky = TurbulentForcing::mode_start*ystep; ky <= TurbulentForcing::nmodes*ystep; ky += ystep) { + for (int kx = TurbulentForcing::mode_start*xstep; kx <= TurbulentForcing::nmodes*xstep; kx += xstep) + { + Real kappa = sqrt( (kx*kx)/(Lx*Lx) + (ky*ky)/(Ly*Ly) + (kz*kz)/(Lz*Lz) ); + + if (kappa <= kappaMax) + { + Real xT = cos(FTX(kx,ky,kz)*time + TAT(kx,ky,kz)); + + // if ( i==0 && j==0 && k==0 && kx==0 && ky==0 && kx==0){ + // printf("(0,0,0) : xT : %15.13e %15.13e %15.13e %15.13e\n", + // FTX(kx,ky,kz), time, TAT(kx,ky,kz), xT); + // Abort(); + // } + + + if ( TurbulentForcing::div_free_force ) + { + f1 += xT * + ( FAZ(kx,ky,kz)*TwoPi*(ky/Ly) + * sin(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) + * cos(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) + - FAY(kx,ky,kz)*TwoPi*(kz/Lz) + * sin(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) + * cos(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) ); + + f2 += xT * + ( FAX(kx,ky,kz)*TwoPi*(kz/Lz) + * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) + * cos(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) + - FAZ(kx,ky,kz)*TwoPi*(kx/Lx) + * cos(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) ); + + f3 += xT * + ( FAY(kx,ky,kz)*TwoPi*(kx/Lx) + * cos(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) + - FAX(kx,ky,kz)*TwoPi*(ky/Ly) + * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) + * cos(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) ); + } + else + { + + f1 += xT*FAX(kx,ky,kz)*cos(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); + + f2 += xT*FAY(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) + * cos(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); + + f3 += xT*FAZ(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) + * cos(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); + } + } + } + } + } + + // + // For high aspect ratio domain, add more modes to break symmetry at a low level. + // We assume Lz is longer, Lx = Ly. + // + for ( int kz = 1; kz <= zstep-1; kz++) { + for ( int ky = TurbulentForcing::mode_start; ky <= TurbulentForcing::nmodes*ystep; ky++) { + for ( int kx = TurbulentForcing::mode_start; kx <= TurbulentForcing::nmodes*xstep; kx++) + { + Real kappa = sqrt( (kx*kx)/(Lx*Lx) + (ky*ky)/(Ly*Ly) + (kz*kz)/(Lz*Lz) ); + + if (kappa <= kappaMax) + { + Real xT = cos(FTX(kx,ky,kz)*time + TAT(kx,ky,kz)); + + if ( TurbulentForcing::div_free_force ) + { + f1 += xT * + ( FAZ(kx,ky,kz)*TwoPi*(ky/Ly) + * sin(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) + * cos(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) + - FAY(kx,ky,kz)*TwoPi*(kz/Lz) + * sin(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) + * cos(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) ); + + f2 += xT * + ( FAX(kx,ky,kz)*TwoPi*(kz/Lz) + * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) + * cos(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) + - FAZ(kx,ky,kz)*TwoPi*(kx/Lx) + * cos(TwoPi*kx*x/Lx+FPZX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPZY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZZ(kx,ky,kz)) ); + + f3 += xT * + ( FAY(kx,ky,kz)*TwoPi*(kx/Lx) + * cos(TwoPi*kx*x/Lx+FPYX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPYY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPYZ(kx,ky,kz)) + - FAX(kx,ky,kz)*TwoPi*(ky/Ly) + * sin(TwoPi*kx*x/Lx+FPXX(kx,ky,kz)) + * cos(TwoPi*ky*y/Ly+FPXY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPXZ(kx,ky,kz)) ); + } + else + { + + f1 += xT*FAX(kx,ky,kz)*cos(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); + + f2 += xT*FAY(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) + * cos(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) + * sin(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); + + f3 += xT*FAZ(kx,ky,kz)*sin(TwoPi*kx*x/Lx+FPX(kx,ky,kz)) + * sin(TwoPi*ky*y/Ly+FPY(kx,ky,kz)) + * cos(TwoPi*kz*z/Lz+FPZ(kx,ky,kz)); + } + } + } + } + } + + frc(i,j,k,0) += dens(i,j,k,0) * f1; + frc(i,j,k,1) += dens(i,j,k,0) * f2; + frc(i,j,k,2) += dens(i,j,k,0) * f3; + + // if ( i==0 && j==0 && k==0 ){ + // printf("(0,0,0) : %15.13e %15.13e %15.13e\n", + // f1, f2, f3); + // } + // if ( i==16 && j==16 && k==16 ){ + // printf("(16,16,16) : %15.13e %15.13e %15.13e\n", + // f1, f2, f3); + // } + // if ( i==25 && j==12 && k==3 ){ + // printf("(25,12,3) : %15.13e %15.13e %15.13e\n", + // f1, f2, f3); + // } + + }); +#endif // Fast Force +#endif // Turbulent forcing + + } + + + // + // Scalar forcing + // + if ( scomp >= AMREX_SPACEDIM ) { + // Doing only scalars + force.setVal(0.0, bx, 0, ncomp); + + // + // Or create user-defined forcing. + // Recall we compute a density-weighted forcing term. + // + // auto const& frc = force.array(); + // amrex::ParallelFor(bx, ncomp, [frc] + // AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept + // { + // frc(i,j,k,n) = ; + // frc(i,j,k,n) *= rho; + // }); + } + else if ( scomp+ncomp > AMREX_SPACEDIM) { + // Doing scalars with vel + force.setVal(0.0, bx, Density, ncomp-Density); + + // + // Or create user-defined forcing. + // Recall we compute a density-weighted forcing term. + // + // auto const& frc = force.array(Density); + // amrex::ParallelFor(bx, ncomp-Density, [frc] + // AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept + // { + // frc(i,j,k,n) = ; + // frc(i,j,k,n) *= rho; + // }); + } + + if (ParallelDescriptor::IOProcessor() && getForceVerbose) { + Vector forcemin(ncomp); + Vector forcemax(ncomp); + for (int n=0; nforcemax[n]) forcemax[n] = f; + } + } + } +#if (AMREX_SPACEDIM == 3) + } +#endif + for (int n=0; n -#include -#include -#include -#include - -// factor by which to reduce sampling for faster performance -AMREX_GPU_MANAGED int TurbulentForcing::ff_factor; -// make the forcing divergence free? -AMREX_GPU_MANAGED bool TurbulentForcing::div_free_force; -// how many modes to use -AMREX_GPU_MANAGED int TurbulentForcing::nmodes; -// don't use any modes below mode_start. We probably don't need this -AMREX_GPU_MANAGED int TurbulentForcing::mode_start; -// Diagnostic print outs -AMREX_GPU_MANAGED int TurbulentForcing::verbose; - -amrex::Real* TurbulentForcing::forcedata; - - -void -TurbulentForcing::init_turbulent_forcing (const amrex::GpuArray& problo, const amrex::GpuArray& probhi) -{ - using namespace amrex; - - // Start with checks. - // This is for 3D only. - AMREX_ALWAYS_ASSERT(AMREX_SPACEDIM==3); - - // Forcing requires that Lx==Ly, Lz can be longer - Real Lx = probhi[0]-problo[0]; - Real Ly = probhi[1]-problo[1]; - Real Lz = probhi[2]-problo[2]; - AMREX_ALWAYS_ASSERT(Lx==Ly); - - // Read in parameters - ParmParse pp("turb"); - - nmodes = 4; - pp.get("nmodes", nmodes); - - div_free_force = true; - pp.query("div_free_force", div_free_force); - - ff_factor = 4; - pp.query("ff_factor", ff_factor); - - mode_start = 0; - pp.query("mode_start", mode_start); - - verbose = 0; - pp.query("verbose", verbose); - - // Inputs not yet defined. Could make runtime parameters if desired. - int hack_lz(0), spectrum_type(2), moderate_zero_modes(1); - Real forcing_time_scale_min(0.5), forcing_time_scale_max(1.0), force_scale(1.0); - - // tmp CPU storage that holds everything in one flat array - const int num_elmts=array_size*array_size*array_size; - const int tmp_size = num_fdarray*num_elmts; - Real tmp[tmp_size]; - - // Separate out forcing data into individual Array4's - int i_arr = 0; - int fd_ncomp = 1; - Dim3 fd_begin{0,0,0}; - Dim3 fd_end{array_size,array_size,array_size}; - - Array4 FTX(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 TAT(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 FPX(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 FPY(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 FPZ(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 FAX(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 FAY(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 FAZ(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 FPXX(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 FPXY(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 FPXZ(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 FPYX(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 FPYY(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 FPYZ(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 FPZX(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 FPZY(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - Array4 FPZZ(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); - - if (hack_lz>0) { - if (hack_lz==1) { - Lz = Lz/2.0; - } else { - Lz = Lz/hack_lz; - } - } - - if (verbose) - { - Print() << "Lx = " << Lx << std::endl; - Print() << "Ly = " << Ly << std::endl; - Print() << "Lz = " << Lz << std::endl; - } - - Real Lmin = std::min(Lx,std::min(Ly,Lz)); - Real kappaMax = ((Real)nmodes)/Lmin + 1.0e-8; - int nxmodes = nmodes*(int)(0.5+Lx/Lmin); - int nymodes = nmodes*(int)(0.5+Ly/Lmin); - int nzmodes = nmodes*(int)(0.5+Lz/Lmin); - - if (verbose) - { - Print() << "Lmin = " << Lmin << std::endl; - Print() << "kappaMax = " << kappaMax << std::endl; - Print() << "nxmodes = " << nxmodes << std::endl; - Print() << "nymodes = " << nxmodes << std::endl; - Print() << "nzmodes = " << nxmodes << std::endl; - } - - Real freqMin = 1.0/forcing_time_scale_max; - Real freqMax = 1.0/forcing_time_scale_min; - Real freqDiff= freqMax-freqMin; - - if (verbose) - { - Print() << "forcing_time_scale_min = " << forcing_time_scale_min << std::endl; - Print() << "forcing_time_scale_max = " << forcing_time_scale_max << std::endl; - Print() << "freqMin = " << freqMin << std::endl; - Print() << "freqMax = " << freqMax << std::endl; - Print() << "freqDiff = " << freqDiff << std::endl; - } - - // initiate the magic - DepRand::InitRandom((unsigned long)111397); - - int mode_count = 0; - - int xstep = (int)(Lx/Lmin+0.5); - int ystep = (int)(Ly/Lmin+0.5); - int zstep = (int)(Lz/Lmin+0.5); - - if (verbose) - Print() << "Mode step = " << xstep << " " << ystep << " " << zstep << std::endl; - - for (int kz = mode_start*zstep; kz <= nzmodes; kz += zstep ) { - Real kzd = (Real)kz; - for (int ky = mode_start*ystep; ky <= nymodes; ky += ystep ) { - Real kyd = (Real)ky; - for (int kx = mode_start*xstep; kx <= nxmodes; kx += xstep ) { - Real kxd = (Real)kx; - - Real kappa = sqrt( (kxd*kxd)/(Lx*Lx) + (kyd*kyd)/(Ly*Ly) + (kzd*kzd)/(Lz*Lz) ); - - if (kappa<=kappaMax) { - FTX(kx,ky,kz) = (freqMin + freqDiff*DepRand::Random() )*TwoPi; - // Translation angles, theta=0..2Pi and phi=0..Pi - TAT(kx,ky,kz) = DepRand::Random()*TwoPi; - // Phases - FPX(kx,ky,kz) = DepRand::Random()*TwoPi; - FPY(kx,ky,kz) = DepRand::Random()*TwoPi; - FPZ(kx,ky,kz) = DepRand::Random()*TwoPi; - if (div_free_force==1) { - FPXX(kx,ky,kz) = DepRand::Random()*TwoPi; - FPYX(kx,ky,kz) = DepRand::Random()*TwoPi; - FPZX(kx,ky,kz) = DepRand::Random()*TwoPi; - FPXY(kx,ky,kz) = DepRand::Random()*TwoPi; - FPYY(kx,ky,kz) = DepRand::Random()*TwoPi; - FPZY(kx,ky,kz) = DepRand::Random()*TwoPi; - FPXZ(kx,ky,kz) = DepRand::Random()*TwoPi; - FPYZ(kx,ky,kz) = DepRand::Random()*TwoPi; - FPZZ(kx,ky,kz) = DepRand::Random()*TwoPi; - } - // Amplitudes (alpha) - Real thetaTmp = DepRand::Random()*TwoPi; - Real cosThetaTmp = cos(thetaTmp); - Real sinThetaTmp = sin(thetaTmp); - - Real phiTmp = DepRand::Random()*Pi; - Real cosPhiTmp = cos(phiTmp); - Real sinPhiTmp = sin(phiTmp); - - Real px = cosThetaTmp * sinPhiTmp; - Real py = sinThetaTmp * sinPhiTmp; - Real pz = cosPhiTmp; - - Real mp2 = px*px + py*py + pz*pz; - if (kappa < 0.000001) { - Print() << "ZERO AMPLITUDE MODE " << kx << ky << kz << std::endl; - FAX(kx,ky,kz) = 0.; - FAY(kx,ky,kz) = 0.; - FAZ(kx,ky,kz) = 0.; - } else { - // Count modes that contribute - mode_count++; - // Set amplitudes - Real Ekh; - if (spectrum_type==1) { - Ekh = 1. / kappa; - } else if (spectrum_type==2) { - Ekh = 1. / (kappa*kappa); - } else { - Ekh = 1.; - } - if (div_free_force==1) { - Ekh /= kappa; - } - if (moderate_zero_modes==1) { - if (kx==0) Ekh /= 2.; - if (ky==0) Ekh /= 2.; - if (kz==0) Ekh /= 2.; - } - if (force_scale>0.) { - FAX(kx,ky,kz) = force_scale * px * Ekh / mp2; - FAY(kx,ky,kz) = force_scale * py * Ekh / mp2; - FAZ(kx,ky,kz) = force_scale * pz * Ekh / mp2; - } else { - FAX(kx,ky,kz) = px * Ekh / mp2; - FAY(kx,ky,kz) = py * Ekh / mp2; - FAZ(kx,ky,kz) = pz * Ekh / mp2; - } - - if (verbose) - { - Print() << "Mode"; - Print() << "kappa = " << kx << " " << ky << " " << kz << " " << kappa << " " - << sqrt(FAX(kx,ky,kz)*FAX(kx,ky,kz)+FAY(kx,ky,kz)*FAY(kx,ky,kz)+FAZ(kx,ky,kz)*FAZ(kx,ky,kz)) << std::endl; - Print() << "Amplitudes - A" << std::endl; - Print() << FAX(kx,ky,kz) << " " << FAY(kx,ky,kz) << " " << FAZ(kx,ky,kz) << std::endl; - Print() << "Frequencies" << std::endl; - Print() << FTX(kx,ky,kz) << std::endl; - Print() << "TAT" << std::endl; - Print() << TAT(kx,ky,kz) << std::endl; - Print() << "Amplitudes - AA" << std::endl; - Print() << FPXX(kx,ky,kz) << " " << FPYX(kx,ky,kz) << " " << FPZX(kx,ky,kz) << std::endl; - Print() << FPXY(kx,ky,kz) << " " << FPYY(kx,ky,kz) << " " << FPZY(kx,ky,kz) << std::endl; - Print() << FPXZ(kx,ky,kz) << " " << FPYZ(kx,ky,kz) << " " << FPZZ(kx,ky,kz) << std::endl; - } - } - } - } - } - } - - // Now let's break symmetry, have to assume high aspect ratio in z for now - int reduced_mode_count = 0; - - for (int kz = 1; kz < zstep; kz++ ) { - Real kzd = (Real)kz; - for (int ky = mode_start; ky <= nymodes; ky += ystep ) { - Real kyd = (Real)ky; - for (int kx = mode_start; kx <= nxmodes; kx += xstep ) { - Real kxd = (Real)kx; - - Real kappa = sqrt( (kxd*kxd)/(Lx*Lx) + (kyd*kyd)/(Ly*Ly) + (kzd*kzd)/(Lz*Lz) ); - - if (kappa<=kappaMax) { - FTX(kx,ky,kz) = (freqMin + freqDiff*DepRand::Random() )*TwoPi; - // Translation angles, theta=0..2Pi and phi=0..Pi - TAT(kx,ky,kz) = DepRand::Random()*TwoPi; - // Phases - FPX(kx,ky,kz) = DepRand::Random()*TwoPi; - FPY(kx,ky,kz) = DepRand::Random()*TwoPi; - FPZ(kx,ky,kz) = DepRand::Random()*TwoPi; - if (div_free_force==1) { - FPXX(kx,ky,kz) = DepRand::Random()*TwoPi; - FPYX(kx,ky,kz) = DepRand::Random()*TwoPi; - FPZX(kx,ky,kz) = DepRand::Random()*TwoPi; - FPXY(kx,ky,kz) = DepRand::Random()*TwoPi; - FPYY(kx,ky,kz) = DepRand::Random()*TwoPi; - FPZY(kx,ky,kz) = DepRand::Random()*TwoPi; - FPXZ(kx,ky,kz) = DepRand::Random()*TwoPi; - FPYZ(kx,ky,kz) = DepRand::Random()*TwoPi; - FPZZ(kx,ky,kz) = DepRand::Random()*TwoPi; - } - // Amplitudes (alpha) - Real thetaTmp = DepRand::Random()*TwoPi; - Real cosThetaTmp = cos(thetaTmp); - Real sinThetaTmp = sin(thetaTmp); - - Real phiTmp = DepRand::Random()*Pi; - Real cosPhiTmp = cos(phiTmp); - Real sinPhiTmp = sin(phiTmp); - - Real px = cosThetaTmp * sinPhiTmp; - Real py = sinThetaTmp * sinPhiTmp; - Real pz = cosPhiTmp; - - Real mp2 = px*px + py*py + pz*pz; - if (kappa < 0.000001) { - Print() << "ZERO AMPLITUDE MODE " << kx << ky << kz << std::endl; - FAX(kx,ky,kz) = 0.; - FAY(kx,ky,kz) = 0.; - FAZ(kx,ky,kz) = 0.; - } else { - // Count modes that contribute - reduced_mode_count++; - // Set amplitudes - Real Ekh; - if (spectrum_type==1) { - Ekh = 1. / kappa; - } else if (spectrum_type==2) { - Ekh = 1. / (kappa*kappa); - } else { - Ekh = 1.; - } - if (div_free_force==1) { - Ekh /= kappa; - } - if (moderate_zero_modes==1) { - if (kx==0) Ekh /= 2.; - if (ky==0) Ekh /= 2.; - if (kz==0) Ekh /= 2.; - } - if (force_scale>0.) { - FAX(kx,ky,kz) = force_scale * px * Ekh / mp2; - FAY(kx,ky,kz) = force_scale * py * Ekh / mp2; - FAZ(kx,ky,kz) = force_scale * pz * Ekh / mp2; - } else { - FAX(kx,ky,kz) = px * Ekh / mp2; - FAY(kx,ky,kz) = py * Ekh / mp2; - FAZ(kx,ky,kz) = pz * Ekh / mp2; - } - - if (verbose) - { - Print() << "Mode"; - Print() << "kappa = " << kx << " " << ky << " " << kz << " " << kappa << " " - << sqrt(FAX(kx,ky,kz)*FAX(kx,ky,kz)+FAY(kx,ky,kz)*FAY(kx,ky,kz)+FAZ(kx,ky,kz)*FAZ(kx,ky,kz)) << std::endl; - Print() << "Amplitudes - A" << std::endl; - Print() << FAX(kx,ky,kz) << " " << FAY(kx,ky,kz) << " " << FAZ(kx,ky,kz) << std::endl; - Print() << "Frequencies" << std::endl; - Print() << FTX(kx,ky,kz) << std::endl; - Print() << "TAT" << std::endl; - Print() << TAT(kx,ky,kz) << std::endl; - Print() << "Amplitudes - AA" << std::endl; - Print() << FPXX(kx,ky,kz) << " " << FPYX(kx,ky,kz) << " " << FPZX(kx,ky,kz) << std::endl; - Print() << FPXY(kx,ky,kz) << " " << FPYY(kx,ky,kz) << " " << FPZY(kx,ky,kz) << std::endl; - Print() << FPXZ(kx,ky,kz) << " " << FPYZ(kx,ky,kz) << " " << FPZZ(kx,ky,kz) << std::endl; - } - } - } - } - } - } - - Print() << "mode_count = " << mode_count << std::endl; - Print() << "reduced_mode_count = " << reduced_mode_count << std::endl; - if (spectrum_type==1) { - Print() << "Spectrum type 1" << std::endl; - } else if (spectrum_type==2) { - Print() << "Spectrum type 2" << std::endl; - } else { - Print() << "Spectrum type OTHER" << std::endl; - } - -// Now allocate forcedata and copy in tmp array. -#ifdef AMREX_USE_GPU - if (Gpu::inLaunchRegion()) - { - forcedata = static_cast(The_Arena()->alloc(tmp_size*sizeof(Real))); - Gpu::htod_memcpy_async(forcedata, tmp, tmp_size*sizeof(Real)); - } - else -#endif - { - forcedata = static_cast(The_Pinned_Arena()->alloc(tmp_size*sizeof(Real))); - std::memcpy(forcedata, tmp, tmp_size*sizeof(Real)); - } -} +/* + * SPDX-FileCopyrightText: 2022 - 2023 Berkeley Lab + * + * SPDX-License-Identifier: LicenseRef-OpenSource + */ + +#include +#include +#include +#include +#include + +// factor by which to reduce sampling for faster performance +AMREX_GPU_MANAGED int TurbulentForcing::ff_factor; +// make the forcing divergence free? +AMREX_GPU_MANAGED bool TurbulentForcing::div_free_force; +// how many modes to use +AMREX_GPU_MANAGED int TurbulentForcing::nmodes; +// don't use any modes below mode_start. We probably don't need this +AMREX_GPU_MANAGED int TurbulentForcing::mode_start; +// Diagnostic print outs +AMREX_GPU_MANAGED int TurbulentForcing::verbose; + +amrex::Real* TurbulentForcing::forcedata; + + +void +TurbulentForcing::init_turbulent_forcing (const amrex::GpuArray& problo, const amrex::GpuArray& probhi) +{ + using namespace amrex; + + // Start with checks. + // This is for 3D only. + AMREX_ALWAYS_ASSERT(AMREX_SPACEDIM==3); + + // Forcing requires that Lx==Ly, Lz can be longer + Real Lx = probhi[0]-problo[0]; + Real Ly = probhi[1]-problo[1]; + Real Lz = probhi[2]-problo[2]; + AMREX_ALWAYS_ASSERT(Lx==Ly); + + // Read in parameters + ParmParse pp("turb"); + + nmodes = 4; + pp.get("nmodes", nmodes); + + div_free_force = true; + pp.query("div_free_force", div_free_force); + + ff_factor = 4; + pp.query("ff_factor", ff_factor); + + mode_start = 0; + pp.query("mode_start", mode_start); + + verbose = 0; + pp.query("verbose", verbose); + + // Inputs not yet defined. Could make runtime parameters if desired. + int hack_lz(0), spectrum_type(2), moderate_zero_modes(1); + Real forcing_time_scale_min(0.5), forcing_time_scale_max(1.0), force_scale(1.0); + + // tmp CPU storage that holds everything in one flat array + const int num_elmts=array_size*array_size*array_size; + const int tmp_size = num_fdarray*num_elmts; + Real tmp[tmp_size]; + + // Separate out forcing data into individual Array4's + int i_arr = 0; + int fd_ncomp = 1; + Dim3 fd_begin{0,0,0}; + Dim3 fd_end{array_size,array_size,array_size}; + + Array4 FTX(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 TAT(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 FPX(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 FPY(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 FPZ(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 FAX(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 FAY(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 FAZ(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 FPXX(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 FPXY(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 FPXZ(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 FPYX(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 FPYY(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 FPYZ(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 FPZX(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 FPZY(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + Array4 FPZZ(&tmp[(i_arr++)*num_elmts], fd_begin, fd_end, fd_ncomp); + + if (hack_lz>0) { + if (hack_lz==1) { + Lz = Lz/2.0; + } else { + Lz = Lz/hack_lz; + } + } + + if (verbose) + { + Print() << "Lx = " << Lx << std::endl; + Print() << "Ly = " << Ly << std::endl; + Print() << "Lz = " << Lz << std::endl; + } + + Real Lmin = std::min(Lx,std::min(Ly,Lz)); + Real kappaMax = ((Real)nmodes)/Lmin + 1.0e-8; + int nxmodes = nmodes*(int)(0.5+Lx/Lmin); + int nymodes = nmodes*(int)(0.5+Ly/Lmin); + int nzmodes = nmodes*(int)(0.5+Lz/Lmin); + + if (verbose) + { + Print() << "Lmin = " << Lmin << std::endl; + Print() << "kappaMax = " << kappaMax << std::endl; + Print() << "nxmodes = " << nxmodes << std::endl; + Print() << "nymodes = " << nxmodes << std::endl; + Print() << "nzmodes = " << nxmodes << std::endl; + } + + Real freqMin = 1.0/forcing_time_scale_max; + Real freqMax = 1.0/forcing_time_scale_min; + Real freqDiff= freqMax-freqMin; + + if (verbose) + { + Print() << "forcing_time_scale_min = " << forcing_time_scale_min << std::endl; + Print() << "forcing_time_scale_max = " << forcing_time_scale_max << std::endl; + Print() << "freqMin = " << freqMin << std::endl; + Print() << "freqMax = " << freqMax << std::endl; + Print() << "freqDiff = " << freqDiff << std::endl; + } + + // initiate the magic + DepRand::InitRandom((unsigned long)111397); + + int mode_count = 0; + + int xstep = (int)(Lx/Lmin+0.5); + int ystep = (int)(Ly/Lmin+0.5); + int zstep = (int)(Lz/Lmin+0.5); + + if (verbose) + Print() << "Mode step = " << xstep << " " << ystep << " " << zstep << std::endl; + + for (int kz = mode_start*zstep; kz <= nzmodes; kz += zstep ) { + Real kzd = (Real)kz; + for (int ky = mode_start*ystep; ky <= nymodes; ky += ystep ) { + Real kyd = (Real)ky; + for (int kx = mode_start*xstep; kx <= nxmodes; kx += xstep ) { + Real kxd = (Real)kx; + + Real kappa = sqrt( (kxd*kxd)/(Lx*Lx) + (kyd*kyd)/(Ly*Ly) + (kzd*kzd)/(Lz*Lz) ); + + if (kappa<=kappaMax) { + FTX(kx,ky,kz) = (freqMin + freqDiff*DepRand::Random() )*TwoPi; + // Translation angles, theta=0..2Pi and phi=0..Pi + TAT(kx,ky,kz) = DepRand::Random()*TwoPi; + // Phases + FPX(kx,ky,kz) = DepRand::Random()*TwoPi; + FPY(kx,ky,kz) = DepRand::Random()*TwoPi; + FPZ(kx,ky,kz) = DepRand::Random()*TwoPi; + if (div_free_force==1) { + FPXX(kx,ky,kz) = DepRand::Random()*TwoPi; + FPYX(kx,ky,kz) = DepRand::Random()*TwoPi; + FPZX(kx,ky,kz) = DepRand::Random()*TwoPi; + FPXY(kx,ky,kz) = DepRand::Random()*TwoPi; + FPYY(kx,ky,kz) = DepRand::Random()*TwoPi; + FPZY(kx,ky,kz) = DepRand::Random()*TwoPi; + FPXZ(kx,ky,kz) = DepRand::Random()*TwoPi; + FPYZ(kx,ky,kz) = DepRand::Random()*TwoPi; + FPZZ(kx,ky,kz) = DepRand::Random()*TwoPi; + } + // Amplitudes (alpha) + Real thetaTmp = DepRand::Random()*TwoPi; + Real cosThetaTmp = cos(thetaTmp); + Real sinThetaTmp = sin(thetaTmp); + + Real phiTmp = DepRand::Random()*Pi; + Real cosPhiTmp = cos(phiTmp); + Real sinPhiTmp = sin(phiTmp); + + Real px = cosThetaTmp * sinPhiTmp; + Real py = sinThetaTmp * sinPhiTmp; + Real pz = cosPhiTmp; + + Real mp2 = px*px + py*py + pz*pz; + if (kappa < 0.000001) { + Print() << "ZERO AMPLITUDE MODE " << kx << ky << kz << std::endl; + FAX(kx,ky,kz) = 0.; + FAY(kx,ky,kz) = 0.; + FAZ(kx,ky,kz) = 0.; + } else { + // Count modes that contribute + mode_count++; + // Set amplitudes + Real Ekh; + if (spectrum_type==1) { + Ekh = 1. / kappa; + } else if (spectrum_type==2) { + Ekh = 1. / (kappa*kappa); + } else { + Ekh = 1.; + } + if (div_free_force==1) { + Ekh /= kappa; + } + if (moderate_zero_modes==1) { + if (kx==0) Ekh /= 2.; + if (ky==0) Ekh /= 2.; + if (kz==0) Ekh /= 2.; + } + if (force_scale>0.) { + FAX(kx,ky,kz) = force_scale * px * Ekh / mp2; + FAY(kx,ky,kz) = force_scale * py * Ekh / mp2; + FAZ(kx,ky,kz) = force_scale * pz * Ekh / mp2; + } else { + FAX(kx,ky,kz) = px * Ekh / mp2; + FAY(kx,ky,kz) = py * Ekh / mp2; + FAZ(kx,ky,kz) = pz * Ekh / mp2; + } + + if (verbose) + { + Print() << "Mode"; + Print() << "kappa = " << kx << " " << ky << " " << kz << " " << kappa << " " + << sqrt(FAX(kx,ky,kz)*FAX(kx,ky,kz)+FAY(kx,ky,kz)*FAY(kx,ky,kz)+FAZ(kx,ky,kz)*FAZ(kx,ky,kz)) << std::endl; + Print() << "Amplitudes - A" << std::endl; + Print() << FAX(kx,ky,kz) << " " << FAY(kx,ky,kz) << " " << FAZ(kx,ky,kz) << std::endl; + Print() << "Frequencies" << std::endl; + Print() << FTX(kx,ky,kz) << std::endl; + Print() << "TAT" << std::endl; + Print() << TAT(kx,ky,kz) << std::endl; + Print() << "Amplitudes - AA" << std::endl; + Print() << FPXX(kx,ky,kz) << " " << FPYX(kx,ky,kz) << " " << FPZX(kx,ky,kz) << std::endl; + Print() << FPXY(kx,ky,kz) << " " << FPYY(kx,ky,kz) << " " << FPZY(kx,ky,kz) << std::endl; + Print() << FPXZ(kx,ky,kz) << " " << FPYZ(kx,ky,kz) << " " << FPZZ(kx,ky,kz) << std::endl; + } + } + } + } + } + } + + // Now let's break symmetry, have to assume high aspect ratio in z for now + int reduced_mode_count = 0; + + for (int kz = 1; kz < zstep; kz++ ) { + Real kzd = (Real)kz; + for (int ky = mode_start; ky <= nymodes; ky += ystep ) { + Real kyd = (Real)ky; + for (int kx = mode_start; kx <= nxmodes; kx += xstep ) { + Real kxd = (Real)kx; + + Real kappa = sqrt( (kxd*kxd)/(Lx*Lx) + (kyd*kyd)/(Ly*Ly) + (kzd*kzd)/(Lz*Lz) ); + + if (kappa<=kappaMax) { + FTX(kx,ky,kz) = (freqMin + freqDiff*DepRand::Random() )*TwoPi; + // Translation angles, theta=0..2Pi and phi=0..Pi + TAT(kx,ky,kz) = DepRand::Random()*TwoPi; + // Phases + FPX(kx,ky,kz) = DepRand::Random()*TwoPi; + FPY(kx,ky,kz) = DepRand::Random()*TwoPi; + FPZ(kx,ky,kz) = DepRand::Random()*TwoPi; + if (div_free_force==1) { + FPXX(kx,ky,kz) = DepRand::Random()*TwoPi; + FPYX(kx,ky,kz) = DepRand::Random()*TwoPi; + FPZX(kx,ky,kz) = DepRand::Random()*TwoPi; + FPXY(kx,ky,kz) = DepRand::Random()*TwoPi; + FPYY(kx,ky,kz) = DepRand::Random()*TwoPi; + FPZY(kx,ky,kz) = DepRand::Random()*TwoPi; + FPXZ(kx,ky,kz) = DepRand::Random()*TwoPi; + FPYZ(kx,ky,kz) = DepRand::Random()*TwoPi; + FPZZ(kx,ky,kz) = DepRand::Random()*TwoPi; + } + // Amplitudes (alpha) + Real thetaTmp = DepRand::Random()*TwoPi; + Real cosThetaTmp = cos(thetaTmp); + Real sinThetaTmp = sin(thetaTmp); + + Real phiTmp = DepRand::Random()*Pi; + Real cosPhiTmp = cos(phiTmp); + Real sinPhiTmp = sin(phiTmp); + + Real px = cosThetaTmp * sinPhiTmp; + Real py = sinThetaTmp * sinPhiTmp; + Real pz = cosPhiTmp; + + Real mp2 = px*px + py*py + pz*pz; + if (kappa < 0.000001) { + Print() << "ZERO AMPLITUDE MODE " << kx << ky << kz << std::endl; + FAX(kx,ky,kz) = 0.; + FAY(kx,ky,kz) = 0.; + FAZ(kx,ky,kz) = 0.; + } else { + // Count modes that contribute + reduced_mode_count++; + // Set amplitudes + Real Ekh; + if (spectrum_type==1) { + Ekh = 1. / kappa; + } else if (spectrum_type==2) { + Ekh = 1. / (kappa*kappa); + } else { + Ekh = 1.; + } + if (div_free_force==1) { + Ekh /= kappa; + } + if (moderate_zero_modes==1) { + if (kx==0) Ekh /= 2.; + if (ky==0) Ekh /= 2.; + if (kz==0) Ekh /= 2.; + } + if (force_scale>0.) { + FAX(kx,ky,kz) = force_scale * px * Ekh / mp2; + FAY(kx,ky,kz) = force_scale * py * Ekh / mp2; + FAZ(kx,ky,kz) = force_scale * pz * Ekh / mp2; + } else { + FAX(kx,ky,kz) = px * Ekh / mp2; + FAY(kx,ky,kz) = py * Ekh / mp2; + FAZ(kx,ky,kz) = pz * Ekh / mp2; + } + + if (verbose) + { + Print() << "Mode"; + Print() << "kappa = " << kx << " " << ky << " " << kz << " " << kappa << " " + << sqrt(FAX(kx,ky,kz)*FAX(kx,ky,kz)+FAY(kx,ky,kz)*FAY(kx,ky,kz)+FAZ(kx,ky,kz)*FAZ(kx,ky,kz)) << std::endl; + Print() << "Amplitudes - A" << std::endl; + Print() << FAX(kx,ky,kz) << " " << FAY(kx,ky,kz) << " " << FAZ(kx,ky,kz) << std::endl; + Print() << "Frequencies" << std::endl; + Print() << FTX(kx,ky,kz) << std::endl; + Print() << "TAT" << std::endl; + Print() << TAT(kx,ky,kz) << std::endl; + Print() << "Amplitudes - AA" << std::endl; + Print() << FPXX(kx,ky,kz) << " " << FPYX(kx,ky,kz) << " " << FPZX(kx,ky,kz) << std::endl; + Print() << FPXY(kx,ky,kz) << " " << FPYY(kx,ky,kz) << " " << FPZY(kx,ky,kz) << std::endl; + Print() << FPXZ(kx,ky,kz) << " " << FPYZ(kx,ky,kz) << " " << FPZZ(kx,ky,kz) << std::endl; + } + } + } + } + } + } + + Print() << "mode_count = " << mode_count << std::endl; + Print() << "reduced_mode_count = " << reduced_mode_count << std::endl; + if (spectrum_type==1) { + Print() << "Spectrum type 1" << std::endl; + } else if (spectrum_type==2) { + Print() << "Spectrum type 2" << std::endl; + } else { + Print() << "Spectrum type OTHER" << std::endl; + } + +// Now allocate forcedata and copy in tmp array. +#ifdef AMREX_USE_GPU + if (Gpu::inLaunchRegion()) + { + forcedata = static_cast(The_Arena()->alloc(tmp_size*sizeof(Real))); + Gpu::htod_memcpy_async(forcedata, tmp, tmp_size*sizeof(Real)); + } + else +#endif + { + forcedata = static_cast(The_Pinned_Arena()->alloc(tmp_size*sizeof(Real))); + std::memcpy(forcedata, tmp, tmp_size*sizeof(Real)); + } +} diff --git a/Tutorials_profiling/HIT/TurbulentForcing_params.H b/Tutorials_profiling/HIT/TurbulentForcing_params.H index fc105441..87cc19f6 100644 --- a/Tutorials_profiling/HIT/TurbulentForcing_params.H +++ b/Tutorials_profiling/HIT/TurbulentForcing_params.H @@ -1,24 +1,30 @@ -#ifndef _TurbulentForcing_params_H_ -#define _TurbulentForcing_params_H_ - -namespace TurbulentForcing { - - // function to generate the parameters - void init_turbulent_forcing (const amrex::GpuArray& problo, const amrex::GpuArray& probhi); - - extern AMREX_GPU_MANAGED int verbose; - // factor by which to reduce sampling for faster performance - extern AMREX_GPU_MANAGED int ff_factor; - // make the forcing divergence free? - extern AMREX_GPU_MANAGED bool div_free_force; - // how many modes to use - extern AMREX_GPU_MANAGED int nmodes; - // don't use any modes below mode_start. We probably don't need this - extern AMREX_GPU_MANAGED int mode_start; - - constexpr int array_size = 33; - constexpr int num_fdarray = 17; - // forcedata will contain num_fdarray arrays of size (0,0,0)(array_size-1,array_size-1,array_size-1) - extern amrex::Real* forcedata; -} -#endif +/* + * SPDX-FileCopyrightText: 2022 - 2023 Berkeley Lab + * + * SPDX-License-Identifier: LicenseRef-OpenSource + */ + +#ifndef _TurbulentForcing_params_H_ +#define _TurbulentForcing_params_H_ + +namespace TurbulentForcing { + + // function to generate the parameters + void init_turbulent_forcing (const amrex::GpuArray& problo, const amrex::GpuArray& probhi); + + extern AMREX_GPU_MANAGED int verbose; + // factor by which to reduce sampling for faster performance + extern AMREX_GPU_MANAGED int ff_factor; + // make the forcing divergence free? + extern AMREX_GPU_MANAGED bool div_free_force; + // how many modes to use + extern AMREX_GPU_MANAGED int nmodes; + // don't use any modes below mode_start. We probably don't need this + extern AMREX_GPU_MANAGED int mode_start; + + constexpr int array_size = 33; + constexpr int num_fdarray = 17; + // forcedata will contain num_fdarray arrays of size (0,0,0)(array_size-1,array_size-1,array_size-1) + extern amrex::Real* forcedata; +} +#endif diff --git a/Tutorials_profiling/HIT/depRand.H b/Tutorials_profiling/HIT/depRand.H index 1268e226..af9bf2e0 100644 --- a/Tutorials_profiling/HIT/depRand.H +++ b/Tutorials_profiling/HIT/depRand.H @@ -1,113 +1,112 @@ - -#ifndef _depRand_H_ -#define _depRand_H_ - -#include - -namespace DepRand -{ - // - // The Mersenne twistor : - // - class mt19937 - { - public: - typedef unsigned long seed_type; - - explicit mt19937 (seed_type seed = 4357UL); - mt19937 (seed_type seed, int numprocs); - mt19937 (seed_type array[], int array_len); - void rewind(); - void reset(unsigned long seed); - - double d_value (); // [0,1] random numbers - double d1_value (); // [0,1) random numbers - double d2_value (); // (0,1) random numbers - - long l_value (); // [0,2^31-1] random numbers - unsigned long u_value (); // [0,2^32-1] random numbers - - void save (amrex::Vector& state) const; - int RNGstatesize() const; - void restore (const amrex::Vector& state); - private: - enum { N = 624 }; - static unsigned long init_seed; - static unsigned long mt[N]; // the array for the state vector - static int mti; // mti==N+1 means mt[N] is not initialized -#ifdef _OPENMP -#pragma omp threadprivate(init_seed,mt,mti) -#endif - private: - void sgenrand (unsigned long seed); - void sgenrand (seed_type seed_array[], int len); - unsigned long igenrand (); - void reload (); - }; - - /* - Mersenne Twister pseudo-random number generator. - - Generates one pseudorandom real number (double) which is - uniformly distributed on [0,1]-interval for each call. - - Accepts any 32-bit integer as a seed -- uses 4357 as the default. - - Has a period of 2**19937. - - Mersenne Twister Home Page: http://www.math.keio.ac.jp/matumoto/emt.html - - There is also an entry point for Fortran callable as: - - REAL_T rn - call blutilrand(rn) - - Internally, blutilrand() calls a static Mersenne Twister object (the - same one used by BoxLib::Random()) to get a value in [0,1] and then - sets "rn" to that value. - */ - double Random (); // [0,1] - double Random1 (); // [0,1) - double Random2 (); // (0,1) - unsigned long Random_int(unsigned long n); // [0,n-1], where n<=2^32-1 - /* Set the seed of the random number generator. - - There is also an entry point for Fortran callable as: - - INTEGER seed - call blutilinitrand(seed) - - or - - INTEGER seed - call blinitrand(seed) - */ - void InitRandom (unsigned long seed); - void InitRandom (unsigned long seed, int numprocs); - - void ResetRandomSeed(unsigned long seed); - // - // Save and restore random state. - // - // state.size() == 626 on return from Save & on entry to Restore. - // - void SaveRandomState (amrex::Vector& state); - - int sizeofRandomState (); - - void RestoreRandomState (const amrex::Vector& state); - // - // Create a unique subset of random numbers from a pool - // of integers in the range [0, poolSize - 1] - // the set will be in the order they are found - // setSize must be <= poolSize - // uSet will be resized to setSize - // if you want all processors to have the same set, - // call this on one processor and broadcast the array - // - void UniqueRandomSubset (amrex::Vector &uSet, int setSize, int poolSize, - bool printSet = false); - -} - -#endif +#ifndef _depRand_H_ +#define _depRand_H_ + +#include + +namespace DepRand +{ + // + // The Mersenne twistor : + // + class mt19937 + { + public: + typedef unsigned long seed_type; + + explicit mt19937 (seed_type seed = 4357UL); + mt19937 (seed_type seed, int numprocs); + mt19937 (seed_type array[], int array_len); + void rewind(); + void reset(unsigned long seed); + + double d_value (); // [0,1] random numbers + double d1_value (); // [0,1) random numbers + double d2_value (); // (0,1) random numbers + + long l_value (); // [0,2^31-1] random numbers + unsigned long u_value (); // [0,2^32-1] random numbers + + void save (amrex::Vector& state) const; + int RNGstatesize() const; + void restore (const amrex::Vector& state); + private: + enum { N = 624 }; + static unsigned long init_seed; + static unsigned long mt[N]; // the array for the state vector + static int mti; // mti==N+1 means mt[N] is not initialized +#ifdef _OPENMP +#pragma omp threadprivate(init_seed,mt,mti) +#endif + private: + void sgenrand (unsigned long seed); + void sgenrand (seed_type seed_array[], int len); + unsigned long igenrand (); + void reload (); + }; + + /* + Mersenne Twister pseudo-random number generator. + + Generates one pseudorandom real number (double) which is + uniformly distributed on [0,1]-interval for each call. + + Accepts any 32-bit integer as a seed -- uses 4357 as the default. + + Has a period of 2**19937. + + Mersenne Twister Home Page: http://www.math.keio.ac.jp/matumoto/emt.html + + There is also an entry point for Fortran callable as: + + REAL_T rn + call blutilrand(rn) + + Internally, blutilrand() calls a static Mersenne Twister object (the + same one used by BoxLib::Random()) to get a value in [0,1] and then + sets "rn" to that value. + */ + double Random (); // [0,1] + double Random1 (); // [0,1) + double Random2 (); // (0,1) + unsigned long Random_int(unsigned long n); // [0,n-1], where n<=2^32-1 + /* Set the seed of the random number generator. + + There is also an entry point for Fortran callable as: + + INTEGER seed + call blutilinitrand(seed) + + or + + INTEGER seed + call blinitrand(seed) + */ + void InitRandom (unsigned long seed); + void InitRandom (unsigned long seed, int numprocs); + + void ResetRandomSeed(unsigned long seed); + // + // Save and restore random state. + // + // state.size() == 626 on return from Save & on entry to Restore. + // + void SaveRandomState (amrex::Vector& state); + + int sizeofRandomState (); + + void RestoreRandomState (const amrex::Vector& state); + // + // Create a unique subset of random numbers from a pool + // of integers in the range [0, poolSize - 1] + // the set will be in the order they are found + // setSize must be <= poolSize + // uSet will be resized to setSize + // if you want all processors to have the same set, + // call this on one processor and broadcast the array + // + void UniqueRandomSubset (amrex::Vector &uSet, int setSize, int poolSize, + bool printSet = false); + +} + +#endif diff --git a/Tutorials_profiling/HIT/depRand.cpp b/Tutorials_profiling/HIT/depRand.cpp index f518bab2..2131649e 100644 --- a/Tutorials_profiling/HIT/depRand.cpp +++ b/Tutorials_profiling/HIT/depRand.cpp @@ -1,371 +1,372 @@ -#include -#include - -#include - -using namespace amrex; - -// -// BoxLib Interface to Mersenne Twistor -// - -/* A C-program for MT19937: Real number version (1999/10/28) */ -/* genrand() generates one pseudorandom real number (double) */ -/* which is uniformly distributed on [0,1]-interval, for each */ -/* call. sgenrand(seed) sets initial values to the working area */ -/* of 624 words. Before genrand(), sgenrand(seed) must be */ -/* called once. (seed is any 32-bit integer.) */ -/* Integer generator is obtained by modifying two lines. */ -/* Coded by Takuji Nishimura, considering the suggestions by */ -/* Topher Cooper and Marc Rieffel in July-Aug. 1997. */ - -/* This library is free software under the Artistic license: */ -/* see the file COPYING distributed together with this code. */ -/* For the verification of the code, its output sequence file */ -/* mt19937-1.out is attached (2001/4/2) */ - -/* Copyright (C) 1997, 1999 Makoto Matsumoto and Takuji Nishimura. */ -/* Any feedback is very welcome. For any question, comments, */ -/* see http://www.math.keio.ac.jp/matumoto/emt.html or email */ -/* matumoto@math.keio.ac.jp */ - -/* REFERENCE */ -/* M. Matsumoto and T. Nishimura, */ -/* "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform */ -/* Pseudo-Random Number Generator", */ -/* ACM Transactions on Modeling and Computer Simulation, */ -/* Vol. 8, No. 1, January 1998, pp 3--30. */ - -unsigned long DepRand::mt19937::init_seed; -unsigned long DepRand::mt19937::mt[DepRand::mt19937::N]; -int DepRand::mt19937::mti; - -// -// initializing with a NONZERO seed. -// -void -DepRand::mt19937::sgenrand(unsigned long seed) -{ - mt[0]= seed & 0xffffffffUL; - for ( mti=1; mti> 30L)) + mti); - /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ - /* In the previous versions, MSBs of the seed affect */ - /* only MSBs of the array mt[]. */ - /* 2002/01/09 modified by Makoto Matsumoto */ - mt[mti] &= 0xffffffffUL; /* for >32 bit machines */ - } -} - -/* initialize by an array with array-length */ -/* init_key is the array for initializing keys */ -/* key_length is its length */ -void -DepRand::mt19937::sgenrand(unsigned long init_key[], int key_length) -{ - int i, j, k; - sgenrand(19650218UL); - i=1; j=0; - k = (N>key_length ? N : key_length); - for ( ; k; k-- ) - { - mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) + init_key[j] + j; /* non linear */ - mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ - i++; j++; - if (i>=N) { mt[0] = mt[N-1]; i=1; } - if (j>=key_length) j=0; - } - for ( k=N-1; k; k-- ) - { - mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) - i; /* non linear */ - mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ - i++; - if (i>=N) { mt[0] = mt[N-1]; i=1; } - } - - mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ -} - -void -DepRand::mt19937::reload() -{ - unsigned long y; - int kk; - - const int M = 397; - -#define MATRIX_A 0x9908B0DFUL // Constant vector a -#define UPPER_MASK 0x80000000UL // Most significant w-r bits -#define LOWER_MASK 0x7FFFFFFFUL // least significant r bits - // - // mag01[x] = x * MATRIX_A for x=0,1 - // - static unsigned long mag01[2]={0x0UL, MATRIX_A}; - for ( kk=0; kk> 1L) ^ mag01[y & 0x1UL]; - } - for ( ; kk> 1L) ^ mag01[y & 0x1UL]; - } - y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); - mt[N-1] = mt[M-1] ^ (y >> 1L) ^ mag01[y & 0x1UL]; - - mti = 0; - -#undef MATRIX_A -#undef UPPER_MASK -#undef LOWER_MASK -} - -unsigned long -DepRand::mt19937::igenrand() -{ - // - // Generate N words at one time. - // - if ( mti >= N ) reload(); - - unsigned long y = mt[mti++]; - - /* Tempering */ - y ^= (y >> 11); - y ^= (y << 7) & 0x9d2c5680UL; - y ^= (y << 15) & 0xefc60000UL; - y ^= (y >> 18); - - return y; -} - -DepRand::mt19937::mt19937(unsigned long seed) -{ - init_seed = seed; - mti = N; - sgenrand(seed); -} - -DepRand::mt19937::mt19937(unsigned long seed, int numprocs) -{ -#ifdef _OPENMP -#pragma omp parallel - { - init_seed = seed + omp_get_thread_num() * numprocs; - mti = N; - sgenrand(init_seed); - } -#else - init_seed = seed; - mti = N; - sgenrand(init_seed); -#endif -} - -DepRand::mt19937::mt19937 (unsigned long seed_array[], int len) -{ - sgenrand(seed_array, len); -} - -void -DepRand::mt19937::rewind() -{ - sgenrand(init_seed); -} - -void -DepRand::mt19937::reset(unsigned long seed) -{ - sgenrand(seed); -} - -// -// [0,1] random numbers -// -double -DepRand::mt19937::d_value() -{ - return double(igenrand()) * (1.0/4294967295.0); // divided by 2^32-1 -} - -// -// [0,1) random numbers -// -double -DepRand::mt19937::d1_value() -{ - return double(igenrand()) * (1.0/4294967296.0); // divided by 2^32 -} - -// -// (0,1) random numbers -// -double -DepRand::mt19937::d2_value() -{ - return (double(igenrand()) + .5) * (1.0/4294967296.0); // divided by 2^32 -} - -long -DepRand::mt19937::l_value() -{ - return (long)(igenrand()>>1); -} - -unsigned long -DepRand::mt19937::u_value() -{ - return igenrand(); -} - -void -DepRand::mt19937::save (Vector& state) const -{ - state.resize(N+2); - state[0] = init_seed; - for (int i = 0; i < N; i++) - state[i+1] = mt[i]; - state[N+1] = mti; -} - -int -DepRand::mt19937::RNGstatesize () const -{ - return N+2; -} - -void -DepRand::mt19937::restore (const Vector& state) -{ - if (state.size() != N+2) - Error("mt19937::restore(): incorrectly sized state vector"); - - init_seed = state[0]; - for (int i = 0; i < N; i++) - mt[i] = state[i+1]; - mti = state[N+1]; - - if (mti < 0 || mti > N) - Error("mt19937::restore(): mti out-of-bounds"); -} - -namespace -{ - DepRand::mt19937 the_generator; -} - -void -DepRand::InitRandom (unsigned long seed) -{ - the_generator = mt19937(seed); -} - -void -DepRand::InitRandom (unsigned long seed, int numprocs) -{ - the_generator = mt19937(seed, numprocs); -} - -void DepRand::ResetRandomSeed(unsigned long seed) -{ - the_generator.reset(seed); -} - -double -DepRand::Random () -{ - return the_generator.d_value(); -} - -double -DepRand::Random1 () -{ - return the_generator.d1_value(); -} - -double -DepRand::Random2 () -{ - return the_generator.d2_value(); -} - -unsigned long -DepRand::Random_int(unsigned long n) -{ - const unsigned long umax = 4294967295UL; // 2^32-1 - BL_ASSERT( n > 0 && n <= umax ); - unsigned long scale = umax/n; - unsigned long r; - do { - r = the_generator.u_value() / scale; - } while (r >= n); - return r; -} - -void -DepRand::SaveRandomState (Vector& state) -{ - the_generator.save(state); -} - -int -DepRand::sizeofRandomState () -{ - return the_generator.RNGstatesize(); -} - -void -DepRand::RestoreRandomState (const Vector& state) -{ - the_generator.restore(state); -} - -void -DepRand::UniqueRandomSubset (Vector &uSet, int setSize, int poolSize, - bool printSet) -{ - if(setSize > poolSize) { - Abort("**** Error in UniqueRandomSubset: setSize > poolSize."); - } - std::set copySet; - Vector uSetTemp; - while(copySet.size() < (unsigned long)setSize) { - int r(DepRand::Random_int(poolSize)); - if(copySet.find(r) == copySet.end()) { - copySet.insert(r); - uSetTemp.push_back(r); - } - } - uSet = uSetTemp; - if(printSet) { - for(int i(0); i < uSet.size(); ++i) { - std::cout << "uSet[" << i << "] = " << uSet[i] << std::endl; - } - } -} - - -#if 0 -// -// Fortran entry points for DepRand::Random(). -// - -BL_FORT_PROC_DECL(BLUTILINITRAND,blutilinitrand)(const int* sd) -{ - unsigned long seed = *sd; - DepRand::InitRandom(seed); -} - -BL_FORT_PROC_DECL(BLINITRAND,blinitrand)(const int* sd) -{ - unsigned long seed = *sd; - DepRand::InitRandom(seed); -} - -BL_FORT_PROC_DECL(BLUTILRAND,blutilrand)(Real* rn) -{ - *rn = DepRand::Random(); -} -#endif +#include +#include + +#include + +using namespace amrex; + +// +// BoxLib Interface to Mersenne Twistor +// + +/* A C-program for MT19937: Real number version (1999/10/28) */ +/* genrand() generates one pseudorandom real number (double) */ +/* which is uniformly distributed on [0,1]-interval, for each */ +/* call. sgenrand(seed) sets initial values to the working area */ +/* of 624 words. Before genrand(), sgenrand(seed) must be */ +/* called once. (seed is any 32-bit integer.) */ +/* Integer generator is obtained by modifying two lines. */ +/* Coded by Takuji Nishimura, considering the suggestions by */ +/* Topher Cooper and Marc Rieffel in July-Aug. 1997. */ + +/* This library is free software under the Artistic license: */ +/* see the file COPYING distributed together with this code. */ +/* For the verification of the code, its output sequence file */ +/* mt19937-1.out is attached (2001/4/2) */ + +// Copyright (C) 1997, 1999 Makoto Matsumoto and Takuji Nishimura. + +/* Any feedback is very welcome. For any question, comments, */ +/* see http://www.math.keio.ac.jp/matumoto/emt.html or email */ +/* matumoto@math.keio.ac.jp */ + +/* REFERENCE */ +/* M. Matsumoto and T. Nishimura, */ +/* "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform */ +/* Pseudo-Random Number Generator", */ +/* ACM Transactions on Modeling and Computer Simulation, */ +/* Vol. 8, No. 1, January 1998, pp 3--30. */ + +unsigned long DepRand::mt19937::init_seed; +unsigned long DepRand::mt19937::mt[DepRand::mt19937::N]; +int DepRand::mt19937::mti; + +// +// initializing with a NONZERO seed. +// +void +DepRand::mt19937::sgenrand(unsigned long seed) +{ + mt[0]= seed & 0xffffffffUL; + for ( mti=1; mti> 30L)) + mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffUL; /* for >32 bit machines */ + } +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +void +DepRand::mt19937::sgenrand(unsigned long init_key[], int key_length) +{ + int i, j, k; + sgenrand(19650218UL); + i=1; j=0; + k = (N>key_length ? N : key_length); + for ( ; k; k-- ) + { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) + init_key[j] + j; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; j++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + if (j>=key_length) j=0; + } + for ( k=N-1; k; k-- ) + { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) - i; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + } + + mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ +} + +void +DepRand::mt19937::reload() +{ + unsigned long y; + int kk; + + const int M = 397; + +#define MATRIX_A 0x9908B0DFUL // Constant vector a +#define UPPER_MASK 0x80000000UL // Most significant w-r bits +#define LOWER_MASK 0x7FFFFFFFUL // least significant r bits + // + // mag01[x] = x * MATRIX_A for x=0,1 + // + static unsigned long mag01[2]={0x0UL, MATRIX_A}; + for ( kk=0; kk> 1L) ^ mag01[y & 0x1UL]; + } + for ( ; kk> 1L) ^ mag01[y & 0x1UL]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1L) ^ mag01[y & 0x1UL]; + + mti = 0; + +#undef MATRIX_A +#undef UPPER_MASK +#undef LOWER_MASK +} + +unsigned long +DepRand::mt19937::igenrand() +{ + // + // Generate N words at one time. + // + if ( mti >= N ) reload(); + + unsigned long y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + +DepRand::mt19937::mt19937(unsigned long seed) +{ + init_seed = seed; + mti = N; + sgenrand(seed); +} + +DepRand::mt19937::mt19937(unsigned long seed, int numprocs) +{ +#ifdef _OPENMP +#pragma omp parallel + { + init_seed = seed + omp_get_thread_num() * numprocs; + mti = N; + sgenrand(init_seed); + } +#else + init_seed = seed; + mti = N; + sgenrand(init_seed); +#endif +} + +DepRand::mt19937::mt19937 (unsigned long seed_array[], int len) +{ + sgenrand(seed_array, len); +} + +void +DepRand::mt19937::rewind() +{ + sgenrand(init_seed); +} + +void +DepRand::mt19937::reset(unsigned long seed) +{ + sgenrand(seed); +} + +// +// [0,1] random numbers +// +double +DepRand::mt19937::d_value() +{ + return double(igenrand()) * (1.0/4294967295.0); // divided by 2^32-1 +} + +// +// [0,1) random numbers +// +double +DepRand::mt19937::d1_value() +{ + return double(igenrand()) * (1.0/4294967296.0); // divided by 2^32 +} + +// +// (0,1) random numbers +// +double +DepRand::mt19937::d2_value() +{ + return (double(igenrand()) + .5) * (1.0/4294967296.0); // divided by 2^32 +} + +long +DepRand::mt19937::l_value() +{ + return (long)(igenrand()>>1); +} + +unsigned long +DepRand::mt19937::u_value() +{ + return igenrand(); +} + +void +DepRand::mt19937::save (Vector& state) const +{ + state.resize(N+2); + state[0] = init_seed; + for (int i = 0; i < N; i++) + state[i+1] = mt[i]; + state[N+1] = mti; +} + +int +DepRand::mt19937::RNGstatesize () const +{ + return N+2; +} + +void +DepRand::mt19937::restore (const Vector& state) +{ + if (state.size() != N+2) + Error("mt19937::restore(): incorrectly sized state vector"); + + init_seed = state[0]; + for (int i = 0; i < N; i++) + mt[i] = state[i+1]; + mti = state[N+1]; + + if (mti < 0 || mti > N) + Error("mt19937::restore(): mti out-of-bounds"); +} + +namespace +{ + DepRand::mt19937 the_generator; +} + +void +DepRand::InitRandom (unsigned long seed) +{ + the_generator = mt19937(seed); +} + +void +DepRand::InitRandom (unsigned long seed, int numprocs) +{ + the_generator = mt19937(seed, numprocs); +} + +void DepRand::ResetRandomSeed(unsigned long seed) +{ + the_generator.reset(seed); +} + +double +DepRand::Random () +{ + return the_generator.d_value(); +} + +double +DepRand::Random1 () +{ + return the_generator.d1_value(); +} + +double +DepRand::Random2 () +{ + return the_generator.d2_value(); +} + +unsigned long +DepRand::Random_int(unsigned long n) +{ + const unsigned long umax = 4294967295UL; // 2^32-1 + BL_ASSERT( n > 0 && n <= umax ); + unsigned long scale = umax/n; + unsigned long r; + do { + r = the_generator.u_value() / scale; + } while (r >= n); + return r; +} + +void +DepRand::SaveRandomState (Vector& state) +{ + the_generator.save(state); +} + +int +DepRand::sizeofRandomState () +{ + return the_generator.RNGstatesize(); +} + +void +DepRand::RestoreRandomState (const Vector& state) +{ + the_generator.restore(state); +} + +void +DepRand::UniqueRandomSubset (Vector &uSet, int setSize, int poolSize, + bool printSet) +{ + if(setSize > poolSize) { + Abort("**** Error in UniqueRandomSubset: setSize > poolSize."); + } + std::set copySet; + Vector uSetTemp; + while(copySet.size() < (unsigned long)setSize) { + int r(DepRand::Random_int(poolSize)); + if(copySet.find(r) == copySet.end()) { + copySet.insert(r); + uSetTemp.push_back(r); + } + } + uSet = uSetTemp; + if(printSet) { + for(int i(0); i < uSet.size(); ++i) { + std::cout << "uSet[" << i << "] = " << uSet[i] << std::endl; + } + } +} + + +#if 0 +// +// Fortran entry points for DepRand::Random(). +// + +BL_FORT_PROC_DECL(BLUTILINITRAND,blutilinitrand)(const int* sd) +{ + unsigned long seed = *sd; + DepRand::InitRandom(seed); +} + +BL_FORT_PROC_DECL(BLINITRAND,blinitrand)(const int* sd) +{ + unsigned long seed = *sd; + DepRand::InitRandom(seed); +} + +BL_FORT_PROC_DECL(BLUTILRAND,blutilrand)(Real* rn) +{ + *rn = DepRand::Random(); +} +#endif diff --git a/Tutorials_profiling/HIT/derivespect-inputs b/Tutorials_profiling/HIT/derivespect-inputs index b3e0bd21..0d9fdfaa 100644 --- a/Tutorials_profiling/HIT/derivespect-inputs +++ b/Tutorials_profiling/HIT/derivespect-inputs @@ -1,42 +1,42 @@ -##----------------------------------------------------------- -## INPUT PARAMETERS FOR AMRDERIVESPECTRUM PROBLEM -##----------------------------------------------------------- - -# Verbose flag -verbose = 1 - -# List of input plotfiles to process -infile = tmp_plotfile - -# Variables to read from the input plotfiles -vars = density x_vort y_vort z_vort x_velocity y_velocity z_velocity divu - -# Flag determining whether div_free -div_free = 0 - -# Flag determining whether or not to transpose spatial indices -transpose_dp = 0 - -# Flag sets whether or not to weight by density^(1/3) -density_weighting = 0 - -# Density field -density = density - -# Flag sets whether or not to apply cutoff density -use_cutoff_density = 0 - -# Cutoff density below which to zero the velocities -cutoff_density = 0.000 - -# Flag determining whether or not to read a list of -# wavenumbers to filter on. -do_filter = 0 - -# List of wavenumbers to filter on -# filterWN = 0.0 0.0 0.0 - -# This sets the finest level to do the FFT -finestLevel = 2 - - +##----------------------------------------------------------- +## INPUT PARAMETERS FOR AMRDERIVESPECTRUM PROBLEM +##----------------------------------------------------------- + +# Verbose flag +verbose = 1 + +# List of input plotfiles to process +infile = tmp_plotfile + +# Variables to read from the input plotfiles +vars = density x_vort y_vort z_vort x_velocity y_velocity z_velocity divu + +# Flag determining whether div_free +div_free = 0 + +# Flag determining whether or not to transpose spatial indices +transpose_dp = 0 + +# Flag sets whether or not to weight by density^(1/3) +density_weighting = 0 + +# Density field +density = density + +# Flag sets whether or not to apply cutoff density +use_cutoff_density = 0 + +# Cutoff density below which to zero the velocities +cutoff_density = 0.000 + +# Flag determining whether or not to read a list of +# wavenumbers to filter on. +do_filter = 0 + +# List of wavenumbers to filter on +# filterWN = 0.0 0.0 0.0 + +# This sets the finest level to do the FFT +finestLevel = 2 + + diff --git a/Tutorials_profiling/HIT/gen_hit_ic.py b/Tutorials_profiling/HIT/gen_hit_ic.py index ecaa1f02..75c321f1 100755 --- a/Tutorials_profiling/HIT/gen_hit_ic.py +++ b/Tutorials_profiling/HIT/gen_hit_ic.py @@ -1,463 +1,468 @@ -#!/usr/bin/env python -# -# Generate a table of the velocity fluctuations for the homogeneous -# isotropic turbulence case at a specific k0 (default to 4) -# -# Order of operations: -# 1. velocity fluctuations generated on a 512^3 grid in wavenumber space -# 2. Coefficients associated to wavenumbers that cannot be represented on -# the desired grid are set to 0 (sharp wavenumber cutoff) -# 3. inverse Fourier transform of the velocity fluctuations (512^3 grid) -# 4. velocity fluctuations resampled on the desired grid (N^3) -# -# The velocity fluctuations are normalized by urms0 so to get the -# actual velocity fluctuations, one must multiply these velocities by -# the appropriate urms0. -# -# - -# ======================================================================== -# -# Imports -# -# ======================================================================== -import argparse -import sys -import time -from datetime import timedelta -import numpy as np -import scipy.interpolate as spi -import matplotlib as mpl - -mpl.use("Agg") -import matplotlib.pyplot as plt - - -# ======================================================================== -# -# Parse arguments -# -# ======================================================================== -parser = argparse.ArgumentParser( - description="Generate the velocity fluctuations for the HIT IC" -) -parser.add_argument( - "-k0", help="Wave number containing highest energy", type=float, default=4.0 -) -parser.add_argument("-N", help="Resolution", type=int, default=16) -parser.add_argument( - "-s", "--seed", help="Random number generator seed", type=int, default=42 -) -parser.add_argument( - "-p", "--plot", help="Save a plot of the x-velocity", action="store_true" -) -args = parser.parse_args() - -# =============================================================================== -# -# Some defaults variables -# -# =============================================================================== -plt.rc("text", usetex=True) -plt.rc("font", family="serif", serif="Times") -cmap_med = [ - "#F15A60", - "#7AC36A", - "#5A9BD4", - "#FAA75B", - "#9E67AB", - "#CE7058", - "#D77FB4", - "#737373", -] -cmap = [ - "#EE2E2F", - "#008C48", - "#185AA9", - "#F47D23", - "#662C91", - "#A21D21", - "#B43894", - "#010202", -] -dashseq = [ - (None, None), - [10, 5], - [10, 4, 3, 4], - [3, 3], - [10, 4, 3, 4, 3, 4], - [3, 3], - [3, 3], -] -markertype = ["s", "d", "o", "p", "h"] - -# ======================================================================== -# -# Function definitions -# -# ======================================================================== -def div0(a, b): - """ Ignore division by 0, just replace it by 0, - - From: http://stackoverflow.com/questions/26248654/numpy-return-0-with-divide-by-zero - e.g. div0( [-1, 0, 1], 0 ) -> [0, 0, 0] - """ - with np.errstate(divide="ignore", invalid="ignore"): - c = np.true_divide(a, b) - c[~np.isfinite(c)] = 0 # -inf inf NaN - return c - - -# ======================================================================== -def abs2(x): - """This is equivalent to np.abs(x)**2 or x*np.conj(x) - - To make it faster, add this right before the function definition - import numba - @numba.vectorize([numba.float64(numba.complex128),numba.float32(numba.complex64)]) - """ - return x.real ** 2 + x.imag ** 2 - - -# ======================================================================== -# -# Main -# -# ======================================================================== - -# Timer -start = time.time() - -# ======================================================================== -# 1. velocity fluctuations generated on a 512^3 grid in wavenumber space - -# Dimension of the large cube -N = 512 -halfN = int(round(0.5 * N)) -xs = 0 -xe = 2.0 * np.pi -L = xe - xs -dx = L / N - -# Only work if N and args.N are even -if not ((args.N % 2 == 0) and N % 2 == 0): - print("N or args.N is not even. Exiting") - sys.exit(1) - -# Get cell centered values and meshed grid -x = np.linspace(xs, xe, N + 1) -xc = (x[1:] + x[:-1]) / 2 # get cell center coordinates -X, Y, Z = np.meshgrid(xc, xc, xc, indexing="ij") - -# Get the wave numbers and associated quantities -k = np.concatenate((np.arange(halfN), np.arange(-halfN, 0, 1)), axis=0) -khalf = np.arange(halfN + 1) -k1, k2, k3 = np.meshgrid(k, k, khalf, indexing="ij") -kmag = np.sqrt(k1 ** 2 + k2 ** 2 + k3 ** 2) -k12 = np.sqrt(k1 ** 2 + k2 ** 2) -k1k12 = div0(k1, k12) -k2k12 = div0(k2, k12) -k3kmag = div0(k3, kmag) -k12kmag = div0(k12, kmag) - -# Generate data - -# # Toy Fourier data corresponding to uo = cos(X) * cos(2*Y) * cos(3*Z) -# uo = np.cos(X) * np.cos(2*Y) * np.cos(3*Z) -# uf = np.fft.rfftn(uo) -# vf = np.copy(uf) -# wf = np.copy(uf) - -# Energy spectrum -Ek = ( - 16.0 - * np.sqrt(2.0 / np.pi) - * (kmag ** 4) - / (args.k0 ** 5) - * np.exp(-2.0 * (kmag ** 2) / (args.k0 ** 2)) -) - -# Draw random numbers -np.random.seed(args.seed) -phi1 = np.random.uniform(0, 2 * np.pi, np.shape(kmag)) -phi2 = np.random.uniform(0, 2 * np.pi, np.shape(kmag)) -phi3 = np.random.uniform(0, 2 * np.pi, np.shape(kmag)) - -# the random quantities -prefix = np.sqrt(2.0 * div0(Ek, 4.0 * np.pi * (kmag ** 2))) -a = prefix * np.exp(1j * phi1) * np.cos(phi3) -b = prefix * np.exp(1j * phi2) * np.sin(phi3) - -# the random velocities -uf = k2k12 * a + k1k12 * k3kmag * b -vf = k2k12 * k3kmag * b - k1k12 * a -wf = -k12kmag * b - -# Impose the 3D spherical symmetry (to ensure we have a real signal) -# equiv: uf[-l,-m,0] = np.conj(uf[ l, m,0]) for l=0..N/2 and m=0..N/2 -uf[N:halfN:-1, N:halfN:-1, 0] = np.conj(uf[1:halfN, 1:halfN, 0]) -# symmetry on first column -uf[N:halfN:-1, 0, 0] = np.conj(uf[1:halfN, 0, 0]) -# symmetry on first row -uf[0, N:halfN:-1, 0] = np.conj(uf[0, 1:halfN, 0]) -# symmetry about the (halfN,halfN) element -uf[halfN - 1 : 0 : -1, N : halfN - 1 : -1, 0] = np.conj( - uf[halfN + 1 : N, 1 : halfN + 1, 0] -) - -vf[N:halfN:-1, N:halfN:-1, 0] = np.conj(vf[1:halfN, 1:halfN, 0]) -vf[halfN - 1 : 0 : -1, N : halfN - 1 : -1, 0] = np.conj( - vf[halfN + 1 : N, 1 : halfN + 1, 0] -) -vf[N:halfN:-1, 0, 0] = np.conj(vf[1:halfN, 0, 0]) -vf[0, N:halfN:-1, 0] = np.conj(vf[0, 1:halfN, 0]) - -wf[N:halfN:-1, N:halfN:-1, 0] = np.conj(wf[1:halfN, 1:halfN, 0]) -wf[halfN - 1 : 0 : -1, N : halfN - 1 : -1, 0] = np.conj( - wf[halfN + 1 : N, 1 : halfN + 1, 0] -) -wf[N:halfN:-1, 0, 0] = np.conj(wf[1:halfN, 0, 0]) -wf[0, N:halfN:-1, 0] = np.conj(wf[0, 1:halfN, 0]) - -# Normalize. Because we are generating the data in wavenumber space, -# we have to multiply by N**3 because in the definition of the numpy -# ifftn there is a 1/N**n. -uf = uf * N ** 3 -vf = vf * N ** 3 -wf = wf * N ** 3 - -# # Quick check on energy content (make sure you add both the current -# # contribution and the one we are neglecting because we are assuming -# # real input data) -# print('Energy = int E(k) dk = 0.5 * int (uf**2 + vf**2 wf**2) dk1 dk2 dk3 = {0:.10f} ~= 3/2'.format( -# (np.sum(abs2(uf ) + abs2(vf ) + abs2(wf )) + -# np.sum(abs2(uf[:,:,1:-1]) + abs2(vf[:,:,1:-1]) + abs2(wf[:,:,1:-1]))) -# * 0.5 / N**6)) - -# if plotting, save the original field (before filtering) -if args.plot: - uo = np.fft.irfftn(uf) - Eko = ( - 16.0 - * np.sqrt(2.0 / np.pi) - * (khalf ** 4) - / (args.k0 ** 5) - * np.exp(-2.0 * (khalf ** 2) / (args.k0 ** 2)) - ) - - # Get the spectrum from 3D velocity field - kbins = np.arange(1, halfN + 1) - Nbins = len(kbins) - whichbin = np.digitize(kmag.flat, kbins) - ncount = np.bincount(whichbin) - - KI = (abs2(uf) + abs2(vf) + abs2(wf)) * 0.5 / N ** 6 - KI[:, :, 1:-1] += ( - (abs2(uf[:, :, 1:-1]) + abs2(vf[:, :, 1:-1]) + abs2(wf[:, :, 1:-1])) - * 0.5 - / N ** 6 - ) - - Eku = np.zeros(len(ncount) - 1) - for n in range(1, len(ncount)): - Eku[n - 1] = np.sum(KI.flat[whichbin == n]) - - ku = 0.5 * (kbins[0 : Nbins - 1] + kbins[1:Nbins]) + 1 - Eku = Eku[1:Nbins] - - -# ======================================================================== -# 2. Coefficients associated to wavenumbers that cannot be represented -# on the desired grid are set to 0 (sharp wavenumber cutoff) -kmagc = 0.5 * args.N -uf[kmag > kmagc] = 0.0 -vf[kmag > kmagc] = 0.0 -wf[kmag > kmagc] = 0.0 - - -# ======================================================================== -# 3. inverse Fourier transform of the velocity fluctuations (512^3 grid) -u = np.fft.irfftn(uf, s=(N, N, N)) -v = np.fft.irfftn(vf, s=(N, N, N)) -w = np.fft.irfftn(wf, s=(N, N, N)) - -# Another energy content check -print( - "Energy = 1/V * int E(x,y,z) dV = 0.5/V * int (u**2 + v**2 + w**2) dx dy dz = {0:.10f} ~= 3/2".format( - np.sum(u ** 2 + v ** 2 + w ** 2) * 0.5 * (dx / L) ** 3 - ) -) - -# # Enstrophy check -# _, dudy, dudz = np.gradient(u, dx) -# dvdx, _, dvdz = np.gradient(v, dx) -# dwdx, dwdy, _ = np.gradient(w, dx) -# wx = dwdy-dvdz -# wy = dudz-dwdx -# wz = dvdx-dudy -# lambda0 = 2.0/args.k0 -# print('Enstrophy = 0.5/V * int (wx**2 + wy**2 + wz**2) dx dy dz= -# {0:.10f} ~= '.format(np.sum(wx**2+wy**2+wz**2) * 0.5 * (dx/L)**3 * -# lambda0**2)) - -# ======================================================================== -# 4. velocity fluctuations re-sampled on the desired grid (N^3) -xr = np.linspace(xs, xe, args.N + 1) -xrc = (xr[1:] + xr[:-1]) / 2 -Xr, Yr, Zr = np.meshgrid(xrc, xrc, xrc, indexing="ij") - -Xr = Xr.reshape(-1, order="F") -Yr = Yr.reshape(-1, order="F") -Zr = Zr.reshape(-1, order="F") - -ur = spi.interpn((xc, xc, xc), u, (Xr, Yr, Zr), method="linear") -vr = spi.interpn((xc, xc, xc), v, (Xr, Yr, Zr), method="linear") -wr = spi.interpn((xc, xc, xc), w, (Xr, Yr, Zr), method="linear") - - -# ======================================================================== -# Save the data in Fortran ordering -fname = "hit_ic_{0:d}_{1:d}.dat".format(int(args.k0), args.N) -data = np.vstack((Xr, Yr, Zr, ur, vr, wr)).T -np.savetxt(fname, data, fmt="%.18e", delimiter=",", header="x, y, z, u, v, w") - - -# ======================================================================== -# plot (only u fluctuations) -if args.plot: - import matplotlib as mpl - - mpl.use("Agg") - import matplotlib.pyplot as plt - - datmin = u.min() - datmax = u.max() - # print("min/max u =",datmin,datmax) - - # Original data - # transpose and origin change bc I used meshgrid with ij and not xy - fig, ax = plt.subplots(nrows=3, ncols=3, figsize=(14, 14)) - ax[0, 0].imshow( - uo[:, :, 0].T, - origin="lower", - extent=[xs, xe, xs, xe], - cmap="RdBu_r", - vmin=datmin, - vmax=datmax, - ) - ax[0, 0].set_title("Original data (x,y)") - ax[0, 1].imshow( - uo[:, 0, :].T, - origin="lower", - extent=[xs, xe, xs, xe], - cmap="RdBu_r", - vmin=datmin, - vmax=datmax, - ) - ax[0, 1].set_title("Original data (x,z)") - ax[0, 2].imshow( - uo[0, :, :].T, - origin="lower", - extent=[xs, xe, xs, xe], - cmap="RdBu_r", - vmin=datmin, - vmax=datmax, - ) - ax[0, 2].set_title("Original data (y,z)") - - # Filtered original data - ax[1, 0].imshow( - u[:, :, 0].T, - origin="lower", - extent=[xs, xe, xs, xe], - cmap="RdBu_r", - vmin=datmin, - vmax=datmax, - ) - ax[1, 0].set_title("Filtered original data (x,y)") - ax[1, 1].imshow( - u[:, 0, :].T, - origin="lower", - extent=[xs, xe, xs, xe], - cmap="RdBu_r", - vmin=datmin, - vmax=datmax, - ) - ax[1, 1].set_title("Filtered original data (x,z)") - ax[1, 2].imshow( - u[0, :, :].T, - origin="lower", - extent=[xs, xe, xs, xe], - cmap="RdBu_r", - vmin=datmin, - vmax=datmax, - ) - ax[1, 2].set_title("Filtered original data (y,z)") - - # Downsampled filtered data - ur = ur.reshape(args.N, args.N, args.N, order="F") - ax[2, 0].imshow( - ur[:, :, 0].T, - origin="lower", - extent=[xs, xe, xs, xe], - cmap="RdBu_r", - vmin=datmin, - vmax=datmax, - ) - ax[2, 0].set_title("Downsampled data (x,y)") - ax[2, 1].imshow( - ur[:, 0, :].T, - origin="lower", - extent=[xs, xe, xs, xe], - cmap="RdBu_r", - vmin=datmin, - vmax=datmax, - ) - ax[2, 1].set_title("Downsampled data (x,z)") - ax[2, 2].imshow( - ur[0, :, :].T, - origin="lower", - extent=[xs, xe, xs, xe], - cmap="RdBu_r", - vmin=datmin, - vmax=datmax, - ) - ax[2, 2].set_title("Downsampled data (y,z)") - - plt.savefig("hit_ic_u_{0:d}_{1:d}.png".format(int(args.k0), args.N), format="png") - - # Fourier coefficients of original data - fig, ax = plt.subplots(nrows=2, ncols=3, figsize=(14, 8)) - ax[0, 0].imshow(np.real(uf[:, :, 0].T), origin="lower", cmap="RdBu_r") - ax[0, 0].set_title("Real Fourier coefficients (x,y)") - ax[0, 1].imshow(np.real(uf[:, 0, :].T), origin="lower", cmap="RdBu_r") - ax[0, 1].set_title("Real Fourier coefficients (x,z)") - ax[0, 2].imshow(np.real(uf[0, :, :].T), origin="lower", cmap="RdBu_r") - ax[0, 2].set_title("Real Fourier coefficients (y,z)") - ax[1, 0].imshow(np.imag(uf[:, :, 0].T), origin="lower", cmap="RdBu_r") - ax[1, 0].set_title("Imag Fourier coefficients (x,y)") - ax[1, 1].imshow(np.imag(uf[:, 0, :].T), origin="lower", cmap="RdBu_r") - ax[1, 1].set_title("Imag Fourier coefficients (x,z)") - ax[1, 2].imshow(np.imag(uf[0, :, :].T), origin="lower", cmap="RdBu_r") - ax[1, 2].set_title("Imag Fourier coefficients (y,z)") - plt.savefig("hit_ic_uf_{0:d}_{1:d}.png".format(int(args.k0), args.N), format="png") - - # Spectrum - plt.figure(20) - ax = plt.gca() - p = plt.loglog(khalf, Eko, color=cmap[-1], lw=2) - p[0].set_dashes(dashseq[0]) - p = plt.loglog(ku, Eku, color=cmap[0], lw=2) - p[0].set_dashes(dashseq[1]) - plt.ylim([1e-16, 10]) - plt.xlabel(r"$k$", fontsize=22, fontweight="bold") - plt.ylabel(r"$E(k)$", fontsize=22, fontweight="bold") - plt.setp(ax.get_xmajorticklabels(), fontsize=18, fontweight="bold") - plt.setp(ax.get_ymajorticklabels(), fontsize=18, fontweight="bold") - plt.savefig( - "hit_ic_spectrum_{0:d}_{1:d}.png".format(int(args.k0), args.N), format="png" - ) - -# output timer -end = time.time() - start -print("Elapsed time " + str(timedelta(seconds=end)) + " (or {0:f} seconds)".format(end)) +#!/usr/bin/env python + +# SPDX-FileCopyrightText: 2021 - 2023 Berkeley Lab +# +# SPDX-License-Identifier: LicenseRef-OpenSource + +# +# Generate a table of the velocity fluctuations for the homogeneous +# isotropic turbulence case at a specific k0 (default to 4) +# +# Order of operations: +# 1. velocity fluctuations generated on a 512^3 grid in wavenumber space +# 2. Coefficients associated to wavenumbers that cannot be represented on +# the desired grid are set to 0 (sharp wavenumber cutoff) +# 3. inverse Fourier transform of the velocity fluctuations (512^3 grid) +# 4. velocity fluctuations resampled on the desired grid (N^3) +# +# The velocity fluctuations are normalized by urms0 so to get the +# actual velocity fluctuations, one must multiply these velocities by +# the appropriate urms0. +# +# + +# ======================================================================== +# +# Imports +# +# ======================================================================== +import argparse +import sys +import time +from datetime import timedelta +import numpy as np +import scipy.interpolate as spi +import matplotlib as mpl + +mpl.use("Agg") +import matplotlib.pyplot as plt + + +# ======================================================================== +# +# Parse arguments +# +# ======================================================================== +parser = argparse.ArgumentParser( + description="Generate the velocity fluctuations for the HIT IC" +) +parser.add_argument( + "-k0", help="Wave number containing highest energy", type=float, default=4.0 +) +parser.add_argument("-N", help="Resolution", type=int, default=16) +parser.add_argument( + "-s", "--seed", help="Random number generator seed", type=int, default=42 +) +parser.add_argument( + "-p", "--plot", help="Save a plot of the x-velocity", action="store_true" +) +args = parser.parse_args() + +# =============================================================================== +# +# Some defaults variables +# +# =============================================================================== +plt.rc("text", usetex=True) +plt.rc("font", family="serif", serif="Times") +cmap_med = [ + "#F15A60", + "#7AC36A", + "#5A9BD4", + "#FAA75B", + "#9E67AB", + "#CE7058", + "#D77FB4", + "#737373", +] +cmap = [ + "#EE2E2F", + "#008C48", + "#185AA9", + "#F47D23", + "#662C91", + "#A21D21", + "#B43894", + "#010202", +] +dashseq = [ + (None, None), + [10, 5], + [10, 4, 3, 4], + [3, 3], + [10, 4, 3, 4, 3, 4], + [3, 3], + [3, 3], +] +markertype = ["s", "d", "o", "p", "h"] + +# ======================================================================== +# +# Function definitions +# +# ======================================================================== +def div0(a, b): + """ Ignore division by 0, just replace it by 0, + + From: http://stackoverflow.com/questions/26248654/numpy-return-0-with-divide-by-zero + e.g. div0( [-1, 0, 1], 0 ) -> [0, 0, 0] + """ + with np.errstate(divide="ignore", invalid="ignore"): + c = np.true_divide(a, b) + c[~np.isfinite(c)] = 0 # -inf inf NaN + return c + + +# ======================================================================== +def abs2(x): + """This is equivalent to np.abs(x)**2 or x*np.conj(x) + + To make it faster, add this right before the function definition + import numba + @numba.vectorize([numba.float64(numba.complex128),numba.float32(numba.complex64)]) + """ + return x.real ** 2 + x.imag ** 2 + + +# ======================================================================== +# +# Main +# +# ======================================================================== + +# Timer +start = time.time() + +# ======================================================================== +# 1. velocity fluctuations generated on a 512^3 grid in wavenumber space + +# Dimension of the large cube +N = 512 +halfN = int(round(0.5 * N)) +xs = 0 +xe = 2.0 * np.pi +L = xe - xs +dx = L / N + +# Only work if N and args.N are even +if not ((args.N % 2 == 0) and N % 2 == 0): + print("N or args.N is not even. Exiting") + sys.exit(1) + +# Get cell centered values and meshed grid +x = np.linspace(xs, xe, N + 1) +xc = (x[1:] + x[:-1]) / 2 # get cell center coordinates +X, Y, Z = np.meshgrid(xc, xc, xc, indexing="ij") + +# Get the wave numbers and associated quantities +k = np.concatenate((np.arange(halfN), np.arange(-halfN, 0, 1)), axis=0) +khalf = np.arange(halfN + 1) +k1, k2, k3 = np.meshgrid(k, k, khalf, indexing="ij") +kmag = np.sqrt(k1 ** 2 + k2 ** 2 + k3 ** 2) +k12 = np.sqrt(k1 ** 2 + k2 ** 2) +k1k12 = div0(k1, k12) +k2k12 = div0(k2, k12) +k3kmag = div0(k3, kmag) +k12kmag = div0(k12, kmag) + +# Generate data + +# # Toy Fourier data corresponding to uo = cos(X) * cos(2*Y) * cos(3*Z) +# uo = np.cos(X) * np.cos(2*Y) * np.cos(3*Z) +# uf = np.fft.rfftn(uo) +# vf = np.copy(uf) +# wf = np.copy(uf) + +# Energy spectrum +Ek = ( + 16.0 + * np.sqrt(2.0 / np.pi) + * (kmag ** 4) + / (args.k0 ** 5) + * np.exp(-2.0 * (kmag ** 2) / (args.k0 ** 2)) +) + +# Draw random numbers +np.random.seed(args.seed) +phi1 = np.random.uniform(0, 2 * np.pi, np.shape(kmag)) +phi2 = np.random.uniform(0, 2 * np.pi, np.shape(kmag)) +phi3 = np.random.uniform(0, 2 * np.pi, np.shape(kmag)) + +# the random quantities +prefix = np.sqrt(2.0 * div0(Ek, 4.0 * np.pi * (kmag ** 2))) +a = prefix * np.exp(1j * phi1) * np.cos(phi3) +b = prefix * np.exp(1j * phi2) * np.sin(phi3) + +# the random velocities +uf = k2k12 * a + k1k12 * k3kmag * b +vf = k2k12 * k3kmag * b - k1k12 * a +wf = -k12kmag * b + +# Impose the 3D spherical symmetry (to ensure we have a real signal) +# equiv: uf[-l,-m,0] = np.conj(uf[ l, m,0]) for l=0..N/2 and m=0..N/2 +uf[N:halfN:-1, N:halfN:-1, 0] = np.conj(uf[1:halfN, 1:halfN, 0]) +# symmetry on first column +uf[N:halfN:-1, 0, 0] = np.conj(uf[1:halfN, 0, 0]) +# symmetry on first row +uf[0, N:halfN:-1, 0] = np.conj(uf[0, 1:halfN, 0]) +# symmetry about the (halfN,halfN) element +uf[halfN - 1 : 0 : -1, N : halfN - 1 : -1, 0] = np.conj( + uf[halfN + 1 : N, 1 : halfN + 1, 0] +) + +vf[N:halfN:-1, N:halfN:-1, 0] = np.conj(vf[1:halfN, 1:halfN, 0]) +vf[halfN - 1 : 0 : -1, N : halfN - 1 : -1, 0] = np.conj( + vf[halfN + 1 : N, 1 : halfN + 1, 0] +) +vf[N:halfN:-1, 0, 0] = np.conj(vf[1:halfN, 0, 0]) +vf[0, N:halfN:-1, 0] = np.conj(vf[0, 1:halfN, 0]) + +wf[N:halfN:-1, N:halfN:-1, 0] = np.conj(wf[1:halfN, 1:halfN, 0]) +wf[halfN - 1 : 0 : -1, N : halfN - 1 : -1, 0] = np.conj( + wf[halfN + 1 : N, 1 : halfN + 1, 0] +) +wf[N:halfN:-1, 0, 0] = np.conj(wf[1:halfN, 0, 0]) +wf[0, N:halfN:-1, 0] = np.conj(wf[0, 1:halfN, 0]) + +# Normalize. Because we are generating the data in wavenumber space, +# we have to multiply by N**3 because in the definition of the numpy +# ifftn there is a 1/N**n. +uf = uf * N ** 3 +vf = vf * N ** 3 +wf = wf * N ** 3 + +# # Quick check on energy content (make sure you add both the current +# # contribution and the one we are neglecting because we are assuming +# # real input data) +# print('Energy = int E(k) dk = 0.5 * int (uf**2 + vf**2 wf**2) dk1 dk2 dk3 = {0:.10f} ~= 3/2'.format( +# (np.sum(abs2(uf ) + abs2(vf ) + abs2(wf )) + +# np.sum(abs2(uf[:,:,1:-1]) + abs2(vf[:,:,1:-1]) + abs2(wf[:,:,1:-1]))) +# * 0.5 / N**6)) + +# if plotting, save the original field (before filtering) +if args.plot: + uo = np.fft.irfftn(uf) + Eko = ( + 16.0 + * np.sqrt(2.0 / np.pi) + * (khalf ** 4) + / (args.k0 ** 5) + * np.exp(-2.0 * (khalf ** 2) / (args.k0 ** 2)) + ) + + # Get the spectrum from 3D velocity field + kbins = np.arange(1, halfN + 1) + Nbins = len(kbins) + whichbin = np.digitize(kmag.flat, kbins) + ncount = np.bincount(whichbin) + + KI = (abs2(uf) + abs2(vf) + abs2(wf)) * 0.5 / N ** 6 + KI[:, :, 1:-1] += ( + (abs2(uf[:, :, 1:-1]) + abs2(vf[:, :, 1:-1]) + abs2(wf[:, :, 1:-1])) + * 0.5 + / N ** 6 + ) + + Eku = np.zeros(len(ncount) - 1) + for n in range(1, len(ncount)): + Eku[n - 1] = np.sum(KI.flat[whichbin == n]) + + ku = 0.5 * (kbins[0 : Nbins - 1] + kbins[1:Nbins]) + 1 + Eku = Eku[1:Nbins] + + +# ======================================================================== +# 2. Coefficients associated to wavenumbers that cannot be represented +# on the desired grid are set to 0 (sharp wavenumber cutoff) +kmagc = 0.5 * args.N +uf[kmag > kmagc] = 0.0 +vf[kmag > kmagc] = 0.0 +wf[kmag > kmagc] = 0.0 + + +# ======================================================================== +# 3. inverse Fourier transform of the velocity fluctuations (512^3 grid) +u = np.fft.irfftn(uf, s=(N, N, N)) +v = np.fft.irfftn(vf, s=(N, N, N)) +w = np.fft.irfftn(wf, s=(N, N, N)) + +# Another energy content check +print( + "Energy = 1/V * int E(x,y,z) dV = 0.5/V * int (u**2 + v**2 + w**2) dx dy dz = {0:.10f} ~= 3/2".format( + np.sum(u ** 2 + v ** 2 + w ** 2) * 0.5 * (dx / L) ** 3 + ) +) + +# # Enstrophy check +# _, dudy, dudz = np.gradient(u, dx) +# dvdx, _, dvdz = np.gradient(v, dx) +# dwdx, dwdy, _ = np.gradient(w, dx) +# wx = dwdy-dvdz +# wy = dudz-dwdx +# wz = dvdx-dudy +# lambda0 = 2.0/args.k0 +# print('Enstrophy = 0.5/V * int (wx**2 + wy**2 + wz**2) dx dy dz= +# {0:.10f} ~= '.format(np.sum(wx**2+wy**2+wz**2) * 0.5 * (dx/L)**3 * +# lambda0**2)) + +# ======================================================================== +# 4. velocity fluctuations re-sampled on the desired grid (N^3) +xr = np.linspace(xs, xe, args.N + 1) +xrc = (xr[1:] + xr[:-1]) / 2 +Xr, Yr, Zr = np.meshgrid(xrc, xrc, xrc, indexing="ij") + +Xr = Xr.reshape(-1, order="F") +Yr = Yr.reshape(-1, order="F") +Zr = Zr.reshape(-1, order="F") + +ur = spi.interpn((xc, xc, xc), u, (Xr, Yr, Zr), method="linear") +vr = spi.interpn((xc, xc, xc), v, (Xr, Yr, Zr), method="linear") +wr = spi.interpn((xc, xc, xc), w, (Xr, Yr, Zr), method="linear") + + +# ======================================================================== +# Save the data in Fortran ordering +fname = "hit_ic_{0:d}_{1:d}.dat".format(int(args.k0), args.N) +data = np.vstack((Xr, Yr, Zr, ur, vr, wr)).T +np.savetxt(fname, data, fmt="%.18e", delimiter=",", header="x, y, z, u, v, w") + + +# ======================================================================== +# plot (only u fluctuations) +if args.plot: + import matplotlib as mpl + + mpl.use("Agg") + import matplotlib.pyplot as plt + + datmin = u.min() + datmax = u.max() + # print("min/max u =",datmin,datmax) + + # Original data + # transpose and origin change bc I used meshgrid with ij and not xy + fig, ax = plt.subplots(nrows=3, ncols=3, figsize=(14, 14)) + ax[0, 0].imshow( + uo[:, :, 0].T, + origin="lower", + extent=[xs, xe, xs, xe], + cmap="RdBu_r", + vmin=datmin, + vmax=datmax, + ) + ax[0, 0].set_title("Original data (x,y)") + ax[0, 1].imshow( + uo[:, 0, :].T, + origin="lower", + extent=[xs, xe, xs, xe], + cmap="RdBu_r", + vmin=datmin, + vmax=datmax, + ) + ax[0, 1].set_title("Original data (x,z)") + ax[0, 2].imshow( + uo[0, :, :].T, + origin="lower", + extent=[xs, xe, xs, xe], + cmap="RdBu_r", + vmin=datmin, + vmax=datmax, + ) + ax[0, 2].set_title("Original data (y,z)") + + # Filtered original data + ax[1, 0].imshow( + u[:, :, 0].T, + origin="lower", + extent=[xs, xe, xs, xe], + cmap="RdBu_r", + vmin=datmin, + vmax=datmax, + ) + ax[1, 0].set_title("Filtered original data (x,y)") + ax[1, 1].imshow( + u[:, 0, :].T, + origin="lower", + extent=[xs, xe, xs, xe], + cmap="RdBu_r", + vmin=datmin, + vmax=datmax, + ) + ax[1, 1].set_title("Filtered original data (x,z)") + ax[1, 2].imshow( + u[0, :, :].T, + origin="lower", + extent=[xs, xe, xs, xe], + cmap="RdBu_r", + vmin=datmin, + vmax=datmax, + ) + ax[1, 2].set_title("Filtered original data (y,z)") + + # Downsampled filtered data + ur = ur.reshape(args.N, args.N, args.N, order="F") + ax[2, 0].imshow( + ur[:, :, 0].T, + origin="lower", + extent=[xs, xe, xs, xe], + cmap="RdBu_r", + vmin=datmin, + vmax=datmax, + ) + ax[2, 0].set_title("Downsampled data (x,y)") + ax[2, 1].imshow( + ur[:, 0, :].T, + origin="lower", + extent=[xs, xe, xs, xe], + cmap="RdBu_r", + vmin=datmin, + vmax=datmax, + ) + ax[2, 1].set_title("Downsampled data (x,z)") + ax[2, 2].imshow( + ur[0, :, :].T, + origin="lower", + extent=[xs, xe, xs, xe], + cmap="RdBu_r", + vmin=datmin, + vmax=datmax, + ) + ax[2, 2].set_title("Downsampled data (y,z)") + + plt.savefig("hit_ic_u_{0:d}_{1:d}.png".format(int(args.k0), args.N), format="png") + + # Fourier coefficients of original data + fig, ax = plt.subplots(nrows=2, ncols=3, figsize=(14, 8)) + ax[0, 0].imshow(np.real(uf[:, :, 0].T), origin="lower", cmap="RdBu_r") + ax[0, 0].set_title("Real Fourier coefficients (x,y)") + ax[0, 1].imshow(np.real(uf[:, 0, :].T), origin="lower", cmap="RdBu_r") + ax[0, 1].set_title("Real Fourier coefficients (x,z)") + ax[0, 2].imshow(np.real(uf[0, :, :].T), origin="lower", cmap="RdBu_r") + ax[0, 2].set_title("Real Fourier coefficients (y,z)") + ax[1, 0].imshow(np.imag(uf[:, :, 0].T), origin="lower", cmap="RdBu_r") + ax[1, 0].set_title("Imag Fourier coefficients (x,y)") + ax[1, 1].imshow(np.imag(uf[:, 0, :].T), origin="lower", cmap="RdBu_r") + ax[1, 1].set_title("Imag Fourier coefficients (x,z)") + ax[1, 2].imshow(np.imag(uf[0, :, :].T), origin="lower", cmap="RdBu_r") + ax[1, 2].set_title("Imag Fourier coefficients (y,z)") + plt.savefig("hit_ic_uf_{0:d}_{1:d}.png".format(int(args.k0), args.N), format="png") + + # Spectrum + plt.figure(20) + ax = plt.gca() + p = plt.loglog(khalf, Eko, color=cmap[-1], lw=2) + p[0].set_dashes(dashseq[0]) + p = plt.loglog(ku, Eku, color=cmap[0], lw=2) + p[0].set_dashes(dashseq[1]) + plt.ylim([1e-16, 10]) + plt.xlabel(r"$k$", fontsize=22, fontweight="bold") + plt.ylabel(r"$E(k)$", fontsize=22, fontweight="bold") + plt.setp(ax.get_xmajorticklabels(), fontsize=18, fontweight="bold") + plt.setp(ax.get_ymajorticklabels(), fontsize=18, fontweight="bold") + plt.savefig( + "hit_ic_spectrum_{0:d}_{1:d}.png".format(int(args.k0), args.N), format="png" + ) + +# output timer +end = time.time() - start +print("Elapsed time " + str(timedelta(seconds=end)) + " (or {0:f} seconds)".format(end)) diff --git a/Tutorials_profiling/HIT/inputs.3d.forced b/Tutorials_profiling/HIT/inputs.3d.forced index a8d60723..4ff3a799 100644 --- a/Tutorials_profiling/HIT/inputs.3d.forced +++ b/Tutorials_profiling/HIT/inputs.3d.forced @@ -1,129 +1,129 @@ - -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 2000 -stop_time = 8 -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 128 128 128 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 2 2 2 2 2 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 100 -amr.check_file = chk - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 50 -amr.plot_file = plt - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.7 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 1.0 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 1.e-4 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = -0.5 -0.5 -0.5 - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 0.5 0.5 0.5 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 100 - -#******************************************************************************* - -# Turbulent forcing parameters -turb.nmodes = 4 -turb.force_file = forcedata.dat - -# Turn off tiling. Turbulent forcing doesn't work with tiling for now -fabarray.mfiter_tile_size = 1024 1024 1024 - - -#******************************************************************************* - -# Factor by which grids must be coarsenable. -#amr.blocking_factor = 8 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -#amr.derive_plot_vars = NONE -amr.derive_plot_vars = mag_vort diveru avg_pressure - -#******************************************************************************* -nodal_proj.proj_tol = 1.e-10 + +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 2000 +stop_time = 8 +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 128 128 128 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 2 2 2 2 2 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 100 +amr.check_file = chk + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 50 +amr.plot_file = plt + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.7 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 1.0 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 1.e-4 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = -0.5 -0.5 -0.5 + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 0.5 0.5 0.5 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 100 + +#******************************************************************************* + +# Turbulent forcing parameters +turb.nmodes = 4 +turb.force_file = forcedata.dat + +# Turn off tiling. Turbulent forcing doesn't work with tiling for now +fabarray.mfiter_tile_size = 1024 1024 1024 + + +#******************************************************************************* + +# Factor by which grids must be coarsenable. +#amr.blocking_factor = 8 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +#amr.derive_plot_vars = NONE +amr.derive_plot_vars = mag_vort diveru avg_pressure + +#******************************************************************************* +nodal_proj.proj_tol = 1.e-10 diff --git a/Tutorials_profiling/HIT/prob_init.H b/Tutorials_profiling/HIT/prob_init.H index fdd61707..3fbfacdb 100644 --- a/Tutorials_profiling/HIT/prob_init.H +++ b/Tutorials_profiling/HIT/prob_init.H @@ -1,41 +1,47 @@ -#ifndef PROB_INIT_H_ -#define PROB_INIT_H_ - - -// This header is included by NavierStokes.H. These are members of NavierStokes - -// -// struct to hold initial conditions parameters -// -struct InitialConditions -{ - // - // For initializing with random combination of cosine waves, used with forced - // turbulence, where ICs are less important as the forcing takes over with time. - // - amrex::Real turb_scale = 1.0; - amrex::Real density = 1.0; -}; - -// -// Problem initialization functions -// -void prob_initData(); - -void init_forced (amrex::Box const& vbx, - /* amrex::Array4 const& press, */ - amrex::Array4 const& vel, - amrex::Array4 const& scal, - const int nscal, - amrex::Box const& domain, - amrex::GpuArray const& dx, - amrex::GpuArray const& problo, - amrex::GpuArray const& probhi, - InitialConditions IC); - -// -// Problems parameters, to be read from inputs file -// -static int probtype; - -#endif +/* + * SPDX-FileCopyrightText: 2021 - 2023 Berkeley Lab + * + * SPDX-License-Identifier: LicenseRef-OpenSource + */ + +#ifndef PROB_INIT_H_ +#define PROB_INIT_H_ + + +// This header is included by NavierStokes.H. These are members of NavierStokes + +// +// struct to hold initial conditions parameters +// +struct InitialConditions +{ + // + // For initializing with random combination of cosine waves, used with forced + // turbulence, where ICs are less important as the forcing takes over with time. + // + amrex::Real turb_scale = 1.0; + amrex::Real density = 1.0; +}; + +// +// Problem initialization functions +// +void prob_initData(); + +void init_forced (amrex::Box const& vbx, + /* amrex::Array4 const& press, */ + amrex::Array4 const& vel, + amrex::Array4 const& scal, + const int nscal, + amrex::Box const& domain, + amrex::GpuArray const& dx, + amrex::GpuArray const& problo, + amrex::GpuArray const& probhi, + InitialConditions IC); + +// +// Problems parameters, to be read from inputs file +// +static int probtype; + +#endif diff --git a/Tutorials_profiling/HIT/prob_init.cpp b/Tutorials_profiling/HIT/prob_init.cpp index 54dc5f5c..18f3cbd4 100644 --- a/Tutorials_profiling/HIT/prob_init.cpp +++ b/Tutorials_profiling/HIT/prob_init.cpp @@ -1,134 +1,138 @@ -#include -#include -#include - -#ifdef AMREX_USE_TURBULENT_FORCING -#include -#endif - -using namespace amrex; - -int NavierStokes::probtype = -1; - - -// -// Initialize state and pressure with problem-specific data -// -void NavierStokes::prob_initData () -{ - // - // Fill state and, optionally, pressure - // - MultiFab& P_new = get_new_data(Press_Type); - MultiFab& S_new = get_new_data(State_Type); - const int nscal = NUM_STATE-Density; - - S_new.setVal(0.0); - P_new.setVal(0.0); - - // Integer indices of the lower left and upper right corners of the - // valid region of the entire domain. - Box const& domain = geom.Domain(); - auto const& dx = geom.CellSizeArray(); - // Physical coordinates of the lower left corner of the domain - auto const& problo = geom.ProbLoArray(); - auto const& probhi = geom.ProbHiArray(); - -// FIXME - should remove ifdef and use runtime parameter instead... -#ifdef AMREX_USE_TURBULENT_FORCING - // - // Initialize data structures used for homogeneous isentropic forced turbulence. - // Only need to do it once. - if (level == 0) - TurbulentForcing::init_turbulent_forcing(problo,probhi); -#endif - - // - // Create struct to hold initial conditions parameters - // - InitialConditions IC; - - // - // Read problem parameters from inputs file - // - ParmParse pp("prob"); - - pp.query("probtype",probtype); - - if ( probtype == 100 ) - { - // - // Random combination of cosine waves to be used with forced turbulence, - // where ICs are less important as the forcing takes over with time. - // - - pp.query("turb_scale",IC.turb_scale); - pp.query("density_ic",IC.density); - -#ifdef _OPENMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (MFIter mfi(S_new,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& vbx = mfi.tilebox(); - - init_forced(vbx, /*P_new.array(mfi),*/ S_new.array(mfi, Xvel), - S_new.array(mfi, Density), nscal, - domain, dx, problo, probhi, IC); - } - } - else - { - amrex::Abort("NavierStokes::prob_init: unknown probtype"); - } -} - -void NavierStokes::init_forced (Box const& vbx, - /* Array4 const& press, */ - Array4 const& vel, - Array4 const& scal, - const int nscal, - Box const& domain, - GpuArray const& dx, - GpuArray const& problo, - GpuArray const& probhi, - InitialConditions IC) -{ - const auto domlo = amrex::lbound(domain); - - amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; - Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; -#if (AMREX_SPACEDIM == 3) - Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; -#else - constexpr Real z = 0.0; -#endif - - const Real Lx = (probhi[0] - problo[0]); - const Real Ly = (probhi[1] - problo[1]); -#if (AMREX_SPACEDIM == 3) - const Real Lz = (probhi[2] - problo[1]); -#else - const Real Lz = 1.0; -#endif - // - // Fill Velocity - // - AMREX_D_TERM(vel(i,j,k,0) = IC.turb_scale * std::cos(TwoPi*y/Ly) * std::cos(TwoPi*z/Lz);, - vel(i,j,k,1) = IC.turb_scale * std::cos(TwoPi*x/Lx) * std::cos(TwoPi*z/Lz);, - vel(i,j,k,2) = IC.turb_scale * std::cos(TwoPi*x/Lx) * std::cos(TwoPi*y/Ly);); - - // - // Scalars, ordered as Density, Tracer(s) - // - scal(i,j,k,0) = IC.density; - - // Tracers - for ( int nt=1; nt +#include +#include + +#ifdef AMREX_USE_TURBULENT_FORCING +#include +#endif + +using namespace amrex; + +int NavierStokes::probtype = -1; + + +// +// Initialize state and pressure with problem-specific data +// +void NavierStokes::prob_initData () +{ + // + // Fill state and, optionally, pressure + // + MultiFab& P_new = get_new_data(Press_Type); + MultiFab& S_new = get_new_data(State_Type); + const int nscal = NUM_STATE-Density; + + S_new.setVal(0.0); + P_new.setVal(0.0); + + // Integer indices of the lower left and upper right corners of the + // valid region of the entire domain. + Box const& domain = geom.Domain(); + auto const& dx = geom.CellSizeArray(); + // Physical coordinates of the lower left corner of the domain + auto const& problo = geom.ProbLoArray(); + auto const& probhi = geom.ProbHiArray(); + +// FIXME - should remove ifdef and use runtime parameter instead... +#ifdef AMREX_USE_TURBULENT_FORCING + // + // Initialize data structures used for homogeneous isentropic forced turbulence. + // Only need to do it once. + if (level == 0) + TurbulentForcing::init_turbulent_forcing(problo,probhi); +#endif + + // + // Create struct to hold initial conditions parameters + // + InitialConditions IC; + + // + // Read problem parameters from inputs file + // + ParmParse pp("prob"); + + pp.query("probtype",probtype); + + if ( probtype == 100 ) + { + // + // Random combination of cosine waves to be used with forced turbulence, + // where ICs are less important as the forcing takes over with time. + // + + pp.query("turb_scale",IC.turb_scale); + pp.query("density_ic",IC.density); + +#ifdef _OPENMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (MFIter mfi(S_new,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& vbx = mfi.tilebox(); + + init_forced(vbx, /*P_new.array(mfi),*/ S_new.array(mfi, Xvel), + S_new.array(mfi, Density), nscal, + domain, dx, problo, probhi, IC); + } + } + else + { + amrex::Abort("NavierStokes::prob_init: unknown probtype"); + } +} + +void NavierStokes::init_forced (Box const& vbx, + /* Array4 const& press, */ + Array4 const& vel, + Array4 const& scal, + const int nscal, + Box const& domain, + GpuArray const& dx, + GpuArray const& problo, + GpuArray const& probhi, + InitialConditions IC) +{ + const auto domlo = amrex::lbound(domain); + + amrex::ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + { + Real x = problo[0] + (i - domlo.x + 0.5)*dx[0]; + Real y = problo[1] + (j - domlo.y + 0.5)*dx[1]; +#if (AMREX_SPACEDIM == 3) + Real z = problo[2] + (k - domlo.z + 0.5)*dx[2]; +#else + constexpr Real z = 0.0; +#endif + + const Real Lx = (probhi[0] - problo[0]); + const Real Ly = (probhi[1] - problo[1]); +#if (AMREX_SPACEDIM == 3) + const Real Lz = (probhi[2] - problo[1]); +#else + const Real Lz = 1.0; +#endif + // + // Fill Velocity + // + AMREX_D_TERM(vel(i,j,k,0) = IC.turb_scale * std::cos(TwoPi*y/Ly) * std::cos(TwoPi*z/Lz);, + vel(i,j,k,1) = IC.turb_scale * std::cos(TwoPi*x/Lx) * std::cos(TwoPi*z/Lz);, + vel(i,j,k,2) = IC.turb_scale * std::cos(TwoPi*x/Lx) * std::cos(TwoPi*y/Ly);); + + // + // Scalars, ordered as Density, Tracer(s) + // + scal(i,j,k,0) = IC.density; + + // Tracers + for ( int nt=1; nt & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#AMREX_HOME defines the directory in which we will find the BoxLib directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 +COMP = gnu + +DEBUG = FALSE +USE_MPI = FALSE +USE_OMP = FALSE +PROFILE = FALSE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials_profiling/HotSpot/inputs.2d.average_hotspot b/Tutorials_profiling/HotSpot/inputs.2d.average_hotspot index e2b7851e..e8e4d21c 100644 --- a/Tutorials_profiling/HotSpot/inputs.2d.average_hotspot +++ b/Tutorials_profiling/HotSpot/inputs.2d.average_hotspot @@ -1,148 +1,154 @@ - -#******************************************************************************* -# INPUTS.2D.HOTSPOT -#******************************************************************************* - -# Compute averages and add to plotfile -ns.avg_interval = 1 - -ns.do_temp=1 -ns.temp_cond_coef=1.e-8 - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 30 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 1.0 - -# Refinement criterion, use temperature -amr.refinement_indicators = hi_temp gradT - -amr.hi_temp.max_level = 1 -amr.hi_temp.value_greater = 1.01 -amr.hi_temp.field_name = temp - -amr.gradT.adjacent_difference_greater = 0.005 -amr.gradT.field_name = temp -#amr.gradT.start_time = 0.001 -#amr.gradT.end_name = 0.002 - - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 32 32 -amr.max_grid_size = 32 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 1 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 1 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 0.3 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.001 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.001 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = -9.8 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = -1. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 2. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 4 4 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 4 4 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 6 -prob.blob_center = 0.0 0.65 -prob.blob_radius = 0.2 -# Background density is 1. Density is reduced by a factor of density_ic inside -# the bubble -prob.density_ic = 2.0 -# Can also set up a flow, defaults to zero -#prob.velocity_ic = 0. 0. 0. - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort diveru avg_pressure velocity_average -amr.plot_vars = x_velocity y_velocity density tracer temp -#******************************************************************************* - +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# INPUTS.2D.HOTSPOT +#******************************************************************************* + +# Compute averages and add to plotfile +ns.avg_interval = 1 + +ns.do_temp=1 +ns.temp_cond_coef=1.e-8 + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 30 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 1.0 + +# Refinement criterion, use temperature +amr.refinement_indicators = hi_temp gradT + +amr.hi_temp.max_level = 1 +amr.hi_temp.value_greater = 1.01 +amr.hi_temp.field_name = temp + +amr.gradT.adjacent_difference_greater = 0.005 +amr.gradT.field_name = temp +#amr.gradT.start_time = 0.001 +#amr.gradT.end_name = 0.002 + + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 32 32 +amr.max_grid_size = 32 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 1 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 1 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 0.3 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.001 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.001 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = -9.8 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = -1. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 2. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 4 4 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 4 4 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 6 +prob.blob_center = 0.0 0.65 +prob.blob_radius = 0.2 +# Background density is 1. Density is reduced by a factor of density_ic inside +# the bubble +prob.density_ic = 2.0 +# Can also set up a flow, defaults to zero +#prob.velocity_ic = 0. 0. 0. + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort diveru avg_pressure velocity_average +amr.plot_vars = x_velocity y_velocity density tracer temp +#******************************************************************************* + diff --git a/Tutorials_profiling/HotSpot/inputs.3d.LES_hotspot b/Tutorials_profiling/HotSpot/inputs.3d.LES_hotspot index fbf57c1b..6f319049 100644 --- a/Tutorials_profiling/HotSpot/inputs.3d.LES_hotspot +++ b/Tutorials_profiling/HotSpot/inputs.3d.LES_hotspot @@ -1,162 +1,168 @@ - -#******************************************************************************* -# INPUTS.3D.HOTSPOT - hot bubble rising -#******************************************************************************* - -ns.do_temp=1 -ns.temp_cond_coef=1.e-8 - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 10 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 1.0 - -# Refinement criterion, use temperature -amr.refinement_indicators = hi_temp gradT - -amr.hi_temp.max_level = 1 -amr.hi_temp.value_greater = 1.01 -amr.hi_temp.field_name = temp - -amr.gradT.adjacent_difference_greater = 0.005 -amr.gradT.field_name = temp -#amr.gradT.start_time = 0.001 -#amr.gradT.end_name = 0.002 - -# allow refinement at outflow boundary -ns.do_refine_outflow = 1 -ns.do_derefine_outflow = 0 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 32 32 32 -amr.max_grid_size = 16 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -diffuse.v = 0 -mac_proj.verbose =0 -nodal_proj.verbose=1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 0 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 50 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 0.3 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.001 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.001 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = -9.8 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = -1. -1. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 1. 2. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 5 5 5 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 5 5 2 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Factor by which grids must be coarsenable. -amr.blocking_factor = 4 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort diveru avg_pressure - -#******************************************************************************* - -# Problem parameters -prob.probtype = 6 -prob.blob_center = 0.0 0.0 1.7 -prob.blob_radius = 0.2 -# Background density is 1. Density is reduced by a factor of density_ic inside -# the bubble -prob.density_ic = 2.0 -# Can also set up a flow, defaults to zero -#prob.velocity_ic = 0. 0. 0. - -#******************************************************************************* - -ns.getLESVerbose = 1 -ns.do_LES = 1 -#ns.LES_model = Smagorinsky -ns.LES_model = Sigma -ns.smago_Cs_cst = 0.18 - +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# INPUTS.3D.HOTSPOT - hot bubble rising +#******************************************************************************* + +ns.do_temp=1 +ns.temp_cond_coef=1.e-8 + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 10 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 1.0 + +# Refinement criterion, use temperature +amr.refinement_indicators = hi_temp gradT + +amr.hi_temp.max_level = 1 +amr.hi_temp.value_greater = 1.01 +amr.hi_temp.field_name = temp + +amr.gradT.adjacent_difference_greater = 0.005 +amr.gradT.field_name = temp +#amr.gradT.start_time = 0.001 +#amr.gradT.end_name = 0.002 + +# allow refinement at outflow boundary +ns.do_refine_outflow = 1 +ns.do_derefine_outflow = 0 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 32 32 32 +amr.max_grid_size = 16 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +diffuse.v = 0 +mac_proj.verbose =0 +nodal_proj.verbose=1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 0 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 50 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 0.3 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.001 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.001 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = -9.8 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = -1. -1. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 1. 2. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 5 5 5 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 5 5 2 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Factor by which grids must be coarsenable. +amr.blocking_factor = 4 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort diveru avg_pressure + +#******************************************************************************* + +# Problem parameters +prob.probtype = 6 +prob.blob_center = 0.0 0.0 1.7 +prob.blob_radius = 0.2 +# Background density is 1. Density is reduced by a factor of density_ic inside +# the bubble +prob.density_ic = 2.0 +# Can also set up a flow, defaults to zero +#prob.velocity_ic = 0. 0. 0. + +#******************************************************************************* + +ns.getLESVerbose = 1 +ns.do_LES = 1 +#ns.LES_model = Smagorinsky +ns.LES_model = Sigma +ns.smago_Cs_cst = 0.18 + diff --git a/Tutorials_profiling/LidDrivenCavity/GNUmakefile b/Tutorials_profiling/LidDrivenCavity/GNUmakefile index 68fd8801..50084856 100644 --- a/Tutorials_profiling/LidDrivenCavity/GNUmakefile +++ b/Tutorials_profiling/LidDrivenCavity/GNUmakefile @@ -1,30 +1,37 @@ -#AMREX_HOME defines the directory in which we will find the BoxLib directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 # DIM -COMP = gnu - -DEBUG = FALSE -USE_MPI = TRUE # MPI -USE_OMP = TRUE # OMP -PROFILE = TRUE - -USE_CUDA = FALSE # CUDA - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#AMREX_HOME defines the directory in which we will find the BoxLib directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 # DIM +COMP = gnu + +DEBUG = FALSE +USE_MPI = TRUE # MPI +USE_OMP = TRUE # OMP +PROFILE = TRUE + +USE_CUDA = FALSE # CUDA + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials_profiling/LidDrivenCavity/inputs.2d.lid_driven_cavity b/Tutorials_profiling/LidDrivenCavity/inputs.2d.lid_driven_cavity index d43b097f..623b1ea7 100644 --- a/Tutorials_profiling/LidDrivenCavity/inputs.2d.lid_driven_cavity +++ b/Tutorials_profiling/LidDrivenCavity/inputs.2d.lid_driven_cavity @@ -1,132 +1,139 @@ -#******************************************************************************* -# INPUTS.2D.LID_DRIVEN_CAVITY -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 200 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = -1 - -# Stop simulation when we reach steady-state -ns.stop_when_steady = 1 -ns.steady_tol = 1.0e-6 - -# Specify initial dt to get going -ns.init_dt = 0.0140625 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 64 -amr.max_grid_size = 8 # max_grid_size - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # max_level -amr.regrid_int = 4 # regrid_int -ns.skip_level_projector = 0 # skip_level_projector -amr.subcycling_mode = Auto # subcycling_mode - -# Refinement criterion, use vorticity -amr.refinement_indicators = vorticity -amr.vorticity.vorticity_greater = 10.0 - -#******************************************************************************* - -# Sets the "NavierStokes" code to not be verbose -ns.v = 1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 1000 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 50 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 0.3 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.001 - -#******************************************************************************* - -# Diffusion coefficient for tracer -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 1. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 5 5 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 5 5 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary condition -yhi.velocity = 1. 0. 0. - -#******************************************************************************* - -# Initialize from rest with constant density = 1 -prob.probtype = 1 - -#******************************************************************************* - -# Continue from checkpoint -# amr.restart = chk02607 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort diveru avg_pressure - -#******************************************************************************* +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# INPUTS.2D.LID_DRIVEN_CAVITY +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 200 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = -1 + +# Stop simulation when we reach steady-state +ns.stop_when_steady = 1 +ns.steady_tol = 1.0e-6 + +# Specify initial dt to get going +ns.init_dt = 0.0140625 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 64 +amr.max_grid_size = 8 # max_grid_size + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # max_level +amr.regrid_int = 4 # regrid_int +ns.skip_level_projector = 0 # skip_level_projector +amr.subcycling_mode = Auto # subcycling_mode + +# Refinement criterion, use vorticity +amr.refinement_indicators = vorticity +amr.vorticity.vorticity_greater = 10.0 + +#******************************************************************************* + +# Sets the "NavierStokes" code to not be verbose +ns.v = 1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 1000 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 50 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 0.3 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.001 + +#******************************************************************************* + +# Diffusion coefficient for tracer +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 1. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 5 5 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 5 5 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary condition +yhi.velocity = 1. 0. 0. + +#******************************************************************************* + +# Initialize from rest with constant density = 1 +prob.probtype = 1 + +#******************************************************************************* + +# Continue from checkpoint +# amr.restart = chk02607 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort diveru avg_pressure + +#******************************************************************************* diff --git a/Tutorials_profiling/LidDrivenCavity/inputs.3d.lid_driven_cavity b/Tutorials_profiling/LidDrivenCavity/inputs.3d.lid_driven_cavity index ea7bc84f..70c6f861 100644 --- a/Tutorials_profiling/LidDrivenCavity/inputs.3d.lid_driven_cavity +++ b/Tutorials_profiling/LidDrivenCavity/inputs.3d.lid_driven_cavity @@ -1,63 +1,70 @@ -#******************************************************************************* -# INPUTS.3D.LID_DRIVEN_CAVITY -#******************************************************************************* - -max_step = 50 - -stop_time = -1 - -ns.stop_when_steady = 1 -ns.steady_tol = 1.0e-6 - -amr.n_cell = 64 64 64 - -amr.max_grid_size = 8 # max_grid_size -amr.max_level = 0 # max_level -amr.regrid_int = 4 # regrid_int -ns.skip_level_projector = 0 # skip_level_projector -amr.subcycling_mode = Auto # subcycling_mode - -# Refinement criterion, use vorticity -amr.refinement_indicators = vorticity -amr.vorticity.vorticity_greater = 10.0 - -ns.v = 1 -amr.v = 1 - -amr.check_int = 100 - -amr.plot_int = 50 - -ns.cfl = 0.7 # CFL number used to set dt - -ns.init_dt = 0.0140625 # initial dt to get simulation going -ns.init_shrink = 0.3 # factor which multiplies the very first time step -ns.init_iter = 3 # number of initial iterations - -ns.vel_visc_coef = 0.01 -ns.scal_diff_coefs = 0.0 - -geometry.coord_sys = 0 - -geometry.prob_lo = 0. 0. 0. -geometry.prob_hi = 1. 1. 1. - -geometry.is_periodic = 0 0 0 - -ns.gravity = 0.0 - -ns.lo_bc = 5 5 5 -ns.hi_bc = 5 5 5 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary condition -zhi.velocity = 1. 0. 0. - -# Initialize from rest with constant density = 1 -prob.probtype = 1 - -amr.derive_plot_vars = mag_vort -nodal_proj.verbose = 0 +# SPDX-FileCopyrightText: 2017 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# INPUTS.3D.LID_DRIVEN_CAVITY +#******************************************************************************* + +max_step = 50 + +stop_time = -1 + +ns.stop_when_steady = 1 +ns.steady_tol = 1.0e-6 + +amr.n_cell = 64 64 64 + +amr.max_grid_size = 8 # max_grid_size +amr.max_level = 0 # max_level +amr.regrid_int = 4 # regrid_int +ns.skip_level_projector = 0 # skip_level_projector +amr.subcycling_mode = Auto # subcycling_mode + +# Refinement criterion, use vorticity +amr.refinement_indicators = vorticity +amr.vorticity.vorticity_greater = 10.0 + +ns.v = 1 +amr.v = 1 + +amr.check_int = 100 + +amr.plot_int = 50 + +ns.cfl = 0.7 # CFL number used to set dt + +ns.init_dt = 0.0140625 # initial dt to get simulation going +ns.init_shrink = 0.3 # factor which multiplies the very first time step +ns.init_iter = 3 # number of initial iterations + +ns.vel_visc_coef = 0.01 +ns.scal_diff_coefs = 0.0 + +geometry.coord_sys = 0 + +geometry.prob_lo = 0. 0. 0. +geometry.prob_hi = 1. 1. 1. + +geometry.is_periodic = 0 0 0 + +ns.gravity = 0.0 + +ns.lo_bc = 5 5 5 +ns.hi_bc = 5 5 5 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary condition +zhi.velocity = 1. 0. 0. + +# Initialize from rest with constant density = 1 +prob.probtype = 1 + +amr.derive_plot_vars = mag_vort +nodal_proj.verbose = 0 diff --git a/Tutorials_profiling/Particles/GNUmakefile b/Tutorials_profiling/Particles/GNUmakefile index bcd5fc91..06f8d97f 100644 --- a/Tutorials_profiling/Particles/GNUmakefile +++ b/Tutorials_profiling/Particles/GNUmakefile @@ -1,30 +1,37 @@ -#AMREX_HOME defines the directory in which we will find the BoxLib directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DEBUG = FALSE - -USE_MPI = TRUE -USE_OMP = TRUE -PROFILE = TRUE - -DIM = 2 # DIM - -COMP = g++ - -USE_PARTICLES = TRUE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#AMREX_HOME defines the directory in which we will find the BoxLib directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DEBUG = FALSE + +USE_MPI = TRUE +USE_OMP = TRUE +PROFILE = TRUE + +DIM = 2 # DIM + +COMP = g++ + +USE_PARTICLES = TRUE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials_profiling/Particles/fixed_grids_ml b/Tutorials_profiling/Particles/fixed_grids_ml index e01ab821..af2854d6 100644 --- a/Tutorials_profiling/Particles/fixed_grids_ml +++ b/Tutorials_profiling/Particles/fixed_grids_ml @@ -1,9 +1,9 @@ -2 -2 -((4,4) (32,32) (0,0)) -((36,40) (40,48) (0,0)) -1 -((16,20) (32,32) (0,0)) - - - +2 +2 +((4,4) (32,32) (0,0)) +((36,40) (40,48) (0,0)) +1 +((16,20) (32,32) (0,0)) + + + diff --git a/Tutorials_profiling/Particles/inputs_ml b/Tutorials_profiling/Particles/inputs_ml index 1689e101..ef377004 100644 --- a/Tutorials_profiling/Particles/inputs_ml +++ b/Tutorials_profiling/Particles/inputs_ml @@ -1,149 +1,155 @@ - -#******************************************************************************* -# INPUTS -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 200 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 10.0 - -#******************************************************************************* -# PARTICLE INPUTS - -particles.particle_init_file = particle_file_ml -particles.verbose = 1 -particles.timestamp_dir = particle_dir -particles.timestamp_indices = 1 - -#******************************************************************************* - -# Grid File - test this code with fixed grids -amr.regrid_file = fixed_grids_ml -# Grid efficiency (defaults to .70) -#amr.grid_eff = 0.75 - -#******************************************************************************* -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 128 128 - -#******************************************************************************* - -amr.max_grid_size = 8 # max_grid_size -amr.max_level = 0 - -#******************************************************************************* - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 0 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 0 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 100 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 50 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 1.0 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.001 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs("gravity") "down" -ns.gravity = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 1. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 5 -# set up shear layer along x-direction -prob.direction = 0 -prob.interface_width = 2 -prob.blob_center = 0.25 0.25 -prob.blob_radius = 0.1 -prob.density_ic = 1.0 - -#******************************************************************************* - -# Factor by which grids must be coarsenable. -amr.blocking_factor = 4 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort particle_count - -#******************************************************************************* - -nodal_proj.verbose = 2 -nodal_proj.verbose = 1 -nodal_proj.proj_tol = 1.e-12 -nodal_proj.proj_abs_tol = 1.e-15 - -mg.v = 0 +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# INPUTS +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 200 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 10.0 + +#******************************************************************************* +# PARTICLE INPUTS + +particles.particle_init_file = particle_file_ml +particles.verbose = 1 +particles.timestamp_dir = particle_dir +particles.timestamp_indices = 1 + +#******************************************************************************* + +# Grid File - test this code with fixed grids +amr.regrid_file = fixed_grids_ml +# Grid efficiency (defaults to .70) +#amr.grid_eff = 0.75 + +#******************************************************************************* +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 128 128 + +#******************************************************************************* + +amr.max_grid_size = 8 # max_grid_size +amr.max_level = 0 + +#******************************************************************************* + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 0 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 0 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 100 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 50 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 1.0 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.001 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs("gravity") "down" +ns.gravity = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 1. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 5 +# set up shear layer along x-direction +prob.direction = 0 +prob.interface_width = 2 +prob.blob_center = 0.25 0.25 +prob.blob_radius = 0.1 +prob.density_ic = 1.0 + +#******************************************************************************* + +# Factor by which grids must be coarsenable. +amr.blocking_factor = 4 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort particle_count + +#******************************************************************************* + +nodal_proj.verbose = 2 +nodal_proj.verbose = 1 +nodal_proj.proj_tol = 1.e-12 +nodal_proj.proj_abs_tol = 1.e-15 + +mg.v = 0 diff --git a/Tutorials_profiling/Particles/particle_file_ml b/Tutorials_profiling/Particles/particle_file_ml index 502e0919..7dfba012 100644 --- a/Tutorials_profiling/Particles/particle_file_ml +++ b/Tutorials_profiling/Particles/particle_file_ml @@ -1,5 +1,5 @@ -4 -0.4 0.4 -0.4 0.6 -0.4 0.8 -0.4 0.2 +4 +0.4 0.4 +0.4 0.6 +0.4 0.8 +0.4 0.2 diff --git a/Tutorials_profiling/Poiseuille/GNUmakefile b/Tutorials_profiling/Poiseuille/GNUmakefile index 6594cb94..92b9b99b 100644 --- a/Tutorials_profiling/Poiseuille/GNUmakefile +++ b/Tutorials_profiling/Poiseuille/GNUmakefile @@ -1,30 +1,37 @@ -#AMREX_HOME defines the directory in which we will find the BoxLib directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 -COMP = gnu - -DEBUG = FALSE -USE_MPI = FALSE -USE_OMP = FALSE -PROFILE = FALSE - -USE_CUDA = FALSE - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#AMREX_HOME defines the directory in which we will find the BoxLib directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 +COMP = gnu + +DEBUG = FALSE +USE_MPI = FALSE +USE_OMP = FALSE +PROFILE = FALSE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials_profiling/Poiseuille/inputs.2d.poiseuille b/Tutorials_profiling/Poiseuille/inputs.2d.poiseuille index 0986f212..c11c5d8b 100644 --- a/Tutorials_profiling/Poiseuille/inputs.2d.poiseuille +++ b/Tutorials_profiling/Poiseuille/inputs.2d.poiseuille @@ -1,142 +1,149 @@ -#******************************************************************************* -# INPUTS.2D.POISEUILLE -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 200 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = -1 - -# Tolerance for assuming system has reached steady-state -ns.stop_when_steady = 1 -ns.steady_tol = 1.0e-5 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 128 64 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 1 # maximum number of levels of refinement - -# Refinement criterion, use temperature -amr.refinement_indicators = tracer - -amr.tracer.value_greater = .01 -amr.tracer.field_name = tracer - -#******************************************************************************* - -# Set verbosity -ns.v = 10 -nodal_proj.verbose = 0 -nodal_proj.verbose = 0 -diffuse.v = 0 -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = -1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 50 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.5 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 0.3 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 1.0 - -#******************************************************************************* - -# Diffusion coefficient for tracer -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 1.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 2. 1. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 0 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -#ns.lo_bc = 1 5 - -# Boundary conditions on the high end of the domain. -#ns.hi_bc = 2 5 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary conditions -ylo.type = "nsw" -ylo.velocity = 0. 0. 0. -yhi.type = "nsw" -yhi.velocity = 0. 0. 0. -xlo.type = "mass_inflow" -xlo.velocity = 1. 0. 0. -xlo.density = 1. -xlo.tracer = 0. -xhi.type = "pressure_outflow" -xhi.pressure = 0.0 - - -#******************************************************************************* - -# PROBLEM PARAMETERS -prob.probtype = 4 -prob.blob_center = 0.15 0.5 0.5 -prob.blob_radius = 0.1 -# Constant density initial condition -prob.density_ic = 1.0 -# Set up constant flow -prob.velocity_ic = 1.0 0. 0. - -#******************************************************************************* - -# Continue from checkpoint -# amr.restart = chk00000 - -#******************************************************************************* - -# Write all derived quantities to plot files -amr.derive_plot_vars = ALL - -#******************************************************************************* +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# INPUTS.2D.POISEUILLE +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 200 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = -1 + +# Tolerance for assuming system has reached steady-state +ns.stop_when_steady = 1 +ns.steady_tol = 1.0e-5 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 128 64 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 1 # maximum number of levels of refinement + +# Refinement criterion, use temperature +amr.refinement_indicators = tracer + +amr.tracer.value_greater = .01 +amr.tracer.field_name = tracer + +#******************************************************************************* + +# Set verbosity +ns.v = 10 +nodal_proj.verbose = 0 +nodal_proj.verbose = 0 +diffuse.v = 0 +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = -1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 50 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.5 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 0.3 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 1.0 + +#******************************************************************************* + +# Diffusion coefficient for tracer +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 1.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 2. 1. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 0 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +#ns.lo_bc = 1 5 + +# Boundary conditions on the high end of the domain. +#ns.hi_bc = 2 5 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary conditions +ylo.type = "nsw" +ylo.velocity = 0. 0. 0. +yhi.type = "nsw" +yhi.velocity = 0. 0. 0. +xlo.type = "mass_inflow" +xlo.velocity = 1. 0. 0. +xlo.density = 1. +xlo.tracer = 0. +xhi.type = "pressure_outflow" +xhi.pressure = 0.0 + + +#******************************************************************************* + +# PROBLEM PARAMETERS +prob.probtype = 4 +prob.blob_center = 0.15 0.5 0.5 +prob.blob_radius = 0.1 +# Constant density initial condition +prob.density_ic = 1.0 +# Set up constant flow +prob.velocity_ic = 1.0 0. 0. + +#******************************************************************************* + +# Continue from checkpoint +# amr.restart = chk00000 + +#******************************************************************************* + +# Write all derived quantities to plot files +amr.derive_plot_vars = ALL + +#******************************************************************************* diff --git a/Tutorials_profiling/Poiseuille/inputs.3d.poiseuille b/Tutorials_profiling/Poiseuille/inputs.3d.poiseuille index edb562d1..bb415131 100644 --- a/Tutorials_profiling/Poiseuille/inputs.3d.poiseuille +++ b/Tutorials_profiling/Poiseuille/inputs.3d.poiseuille @@ -1,66 +1,73 @@ -#******************************************************************************* -# INPUTS.3D.POISEUILLE -#******************************************************************************* - -max_step = 200 - -stop_time = -1 - -ns.stop_when_steady = 1 -ns.steady_tol = 1.0e-4 - -amr.n_cell = 32 16 16 - -amr.max_level = 2 - -# Refinement criterion, presence of tracer -amr.refinement_indicators = tracer -amr.tracer.value_greater = 0.1 -amr.tracer.field_name = tracer - -ns.v = 1 -amr.v = 1 - -amr.check_int = 1000 - -amr.plot_int = 50 - -ns.cfl = 0.5 # CFL number used to set dt - -ns.init_shrink = 0.3 # factor which multiplies the very first time step -ns.init_iter = 3 # number of initial iterations - -ns.vel_visc_coef = 1.0 -ns.scal_diff_coefs = 0.0 - -geometry.coord_sys = 0 - -geometry.prob_lo = 0. 0. 0. -geometry.prob_hi = 2. 1. 1. - -geometry.is_periodic = 0 0 0 - -ns.gravity = 1.0 - -ns.lo_bc = 1 5 5 -ns.hi_bc = 2 5 5 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -# Boundary condition -xlo.velocity = 1. 0. 0. - -# PROBLEM PARAMETERS -prob.probtype = 4 -prob.blob_center = 0.15 0.5 0.5 -prob.blob_radius = 0.1 -prob.interface_width = 0.001 -# Constant density initial condition -prob.density_ic = 1.0 -# Set up constant flow -prob.velocity_ic = 1.0 0. 0. - -amr.derive_plot_vars = mag_vort -nodal_proj.verbose = 0 +# SPDX-FileCopyrightText: 2017 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# INPUTS.3D.POISEUILLE +#******************************************************************************* + +max_step = 200 + +stop_time = -1 + +ns.stop_when_steady = 1 +ns.steady_tol = 1.0e-4 + +amr.n_cell = 32 16 16 + +amr.max_level = 2 + +# Refinement criterion, presence of tracer +amr.refinement_indicators = tracer +amr.tracer.value_greater = 0.1 +amr.tracer.field_name = tracer + +ns.v = 1 +amr.v = 1 + +amr.check_int = 1000 + +amr.plot_int = 50 + +ns.cfl = 0.5 # CFL number used to set dt + +ns.init_shrink = 0.3 # factor which multiplies the very first time step +ns.init_iter = 3 # number of initial iterations + +ns.vel_visc_coef = 1.0 +ns.scal_diff_coefs = 0.0 + +geometry.coord_sys = 0 + +geometry.prob_lo = 0. 0. 0. +geometry.prob_hi = 2. 1. 1. + +geometry.is_periodic = 0 0 0 + +ns.gravity = 1.0 + +ns.lo_bc = 1 5 5 +ns.hi_bc = 2 5 5 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +# Boundary condition +xlo.velocity = 1. 0. 0. + +# PROBLEM PARAMETERS +prob.probtype = 4 +prob.blob_center = 0.15 0.5 0.5 +prob.blob_radius = 0.1 +prob.interface_width = 0.001 +# Constant density initial condition +prob.density_ic = 1.0 +# Set up constant flow +prob.velocity_ic = 1.0 0. 0. + +amr.derive_plot_vars = mag_vort +nodal_proj.verbose = 0 diff --git a/Tutorials_profiling/README.md b/Tutorials_profiling/README.md index 1d98cf82..da0d69e6 100644 --- a/Tutorials_profiling/README.md +++ b/Tutorials_profiling/README.md @@ -1,55 +1,55 @@ -In addition to the Tutorial, we provide four shell scripts to help you easily modify parameters and evaluate the performance of AMR (Adaptive Mesh Refinement) technology on different problems and platforms. - -Take **jobiamr2dcpu** as an example: - -This script supports several test cases, including: *Bubble, ConvectedVortex, DoubleShearLayer, FlowPastCylinder, LidDrivenCavity, RayleighTaylor, TaylorGreen.* - -To run a specific case, simply uncomment the corresponding line within the script and you can execute multiple test cases at once. - -For each case, the script allows you to configure different combinations of the following parameters: - -``` -skip_level_projector = [0,1] -cycling = [Auto, None] -max_level = [1, 2, ...] -max_grid_size = [8, 16, ...] -regrid_int = [4, 8, ...] -``` -You can configure a series of parameter combinations, execute them at once and collect the results efficiently. - -The results are organized into a structured directory format as follows: -``` -Bubble -├── case_results_cpu2d -│ ├── cpu2d_skip0_Auto_mgs16_1_regrid4 -│ │ ├── inputs.2d.lid_driven_cavity -│ │ └── log.txt -│ ├── cpu2d_skip0_Auto_mgs16_1_regrid8 -│ │ ├── inputs.2d.lid_driven_cavity -│ │ └── log.txt -│ ├── cpu2d_skip0_Auto_mgs16_2_regrid4 -│ │ ... -├── case_results_gpu2 -│ │ ... -├── case_results_cpu3d -│ │ ... -├── case_results_gpu3d -│ │ ... - -``` - - -* bubble is the case name, -* cpu/gpu is the running platform, -* 2d/3d is the case dimension. -* The inputs file contains the configuration and parameter combinations of the simulation, which is of course indicated by the name of the directory (cpu2d_skip0_Auto_mgs16_1_regrid4). -* The log contains the runtime and function calls, memory and other information, which is the main object of our analysis. - -The other scripts correspond to different situation, such as 2D/3D and CPU/GPU, which can be easily identified by their names. - -we present a small study we conducted, [ -IAMReX_Tutorial_Profiling_Results -](https://github.com/hswind4/IAMR_Tutorial_Profiling_Results), which can help you better understand the tutorial profiling and its results. - - - +In addition to the Tutorial, we provide four shell scripts to help you easily modify parameters and evaluate the performance of AMR (Adaptive Mesh Refinement) technology on different problems and platforms. + +Take **jobiamr2dcpu** as an example: + +This script supports several test cases, including: *Bubble, ConvectedVortex, DoubleShearLayer, FlowPastCylinder, LidDrivenCavity, RayleighTaylor, TaylorGreen.* + +To run a specific case, simply uncomment the corresponding line within the script and you can execute multiple test cases at once. + +For each case, the script allows you to configure different combinations of the following parameters: + +``` +skip_level_projector = [0,1] +cycling = [Auto, None] +max_level = [1, 2, ...] +max_grid_size = [8, 16, ...] +regrid_int = [4, 8, ...] +``` +You can configure a series of parameter combinations, execute them at once and collect the results efficiently. + +The results are organized into a structured directory format as follows: +``` +Bubble +├── case_results_cpu2d +│ ├── cpu2d_skip0_Auto_mgs16_1_regrid4 +│ │ ├── inputs.2d.lid_driven_cavity +│ │ └── log.txt +│ ├── cpu2d_skip0_Auto_mgs16_1_regrid8 +│ │ ├── inputs.2d.lid_driven_cavity +│ │ └── log.txt +│ ├── cpu2d_skip0_Auto_mgs16_2_regrid4 +│ │ ... +├── case_results_gpu2 +│ │ ... +├── case_results_cpu3d +│ │ ... +├── case_results_gpu3d +│ │ ... + +``` + + +* bubble is the case name, +* cpu/gpu is the running platform, +* 2d/3d is the case dimension. +* The inputs file contains the configuration and parameter combinations of the simulation, which is of course indicated by the name of the directory (cpu2d_skip0_Auto_mgs16_1_regrid4). +* The log contains the runtime and function calls, memory and other information, which is the main object of our analysis. + +The other scripts correspond to different situation, such as 2D/3D and CPU/GPU, which can be easily identified by their names. + +we present a small study we conducted, [ +IAMReX_Tutorial_Profiling_Results +](https://github.com/hswind4/IAMR_Tutorial_Profiling_Results), which can help you better understand the tutorial profiling and its results. + + + diff --git a/Tutorials_profiling/RayleighTaylor/GNUmakefile b/Tutorials_profiling/RayleighTaylor/GNUmakefile index 68fd8801..50084856 100644 --- a/Tutorials_profiling/RayleighTaylor/GNUmakefile +++ b/Tutorials_profiling/RayleighTaylor/GNUmakefile @@ -1,30 +1,37 @@ -#AMREX_HOME defines the directory in which we will find the BoxLib directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 # DIM -COMP = gnu - -DEBUG = FALSE -USE_MPI = TRUE # MPI -USE_OMP = TRUE # OMP -PROFILE = TRUE - -USE_CUDA = FALSE # CUDA - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#AMREX_HOME defines the directory in which we will find the BoxLib directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 # DIM +COMP = gnu + +DEBUG = FALSE +USE_MPI = TRUE # MPI +USE_OMP = TRUE # OMP +PROFILE = TRUE + +USE_CUDA = FALSE # CUDA + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials_profiling/RayleighTaylor/inputs.2d.rayleightaylor b/Tutorials_profiling/RayleighTaylor/inputs.2d.rayleightaylor index b8fa67f0..464e7035 100644 --- a/Tutorials_profiling/RayleighTaylor/inputs.2d.rayleightaylor +++ b/Tutorials_profiling/RayleighTaylor/inputs.2d.rayleightaylor @@ -1,136 +1,142 @@ - -#******************************************************************************* -# INPUTS.2D.RT -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 200 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 4.0 - -# Refinement criterion, use vorticity -amr.refinement_indicators = vorticity - -amr.vorticity.vorticity_greater = 0.1 -#amr.vorticity.start_time = 0.001 -#amr.vorticity.end_name = 0.002 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 128 - - -amr.grid_eff = 0.95 - -#******************************************************************************* - -amr.max_grid_size = 8 # max_grid_size -amr.max_level = 0 # max_level -amr.regrid_int = 4 # regrid_int -ns.skip_level_projector = 0 # skip_level_projector -amr.subcycling_mode = Auto # subcycling_mode - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 0 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 0 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 40 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 50 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 0.1 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.0 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = -1.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 0.5 1.0 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 0 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 4 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 2 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -prob.probtype= 10 -prob.interface_width = 0.01 -prob.perturbation_amplitude = 0.005 - -#******************************************************************************* - -# Factor by which grids must be coarsenable. -amr.blocking_factor = 8 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort diveru avg_pressure - -#******************************************************************************* - - +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# INPUTS.2D.RT +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 200 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 4.0 + +# Refinement criterion, use vorticity +amr.refinement_indicators = vorticity + +amr.vorticity.vorticity_greater = 0.1 +#amr.vorticity.start_time = 0.001 +#amr.vorticity.end_name = 0.002 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 128 + + +amr.grid_eff = 0.95 + +#******************************************************************************* + +amr.max_grid_size = 8 # max_grid_size +amr.max_level = 0 # max_level +amr.regrid_int = 4 # regrid_int +ns.skip_level_projector = 0 # skip_level_projector +amr.subcycling_mode = Auto # subcycling_mode + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 0 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 0 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 40 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 50 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 0.1 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.0 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = -1.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 0.5 1.0 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 0 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 4 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 2 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +prob.probtype= 10 +prob.interface_width = 0.01 +prob.perturbation_amplitude = 0.005 + +#******************************************************************************* + +# Factor by which grids must be coarsenable. +amr.blocking_factor = 8 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort diveru avg_pressure + +#******************************************************************************* + + diff --git a/Tutorials_profiling/TaylorGreen/GNUmakefile b/Tutorials_profiling/TaylorGreen/GNUmakefile index 68fd8801..22ddb34b 100644 --- a/Tutorials_profiling/TaylorGreen/GNUmakefile +++ b/Tutorials_profiling/TaylorGreen/GNUmakefile @@ -1,30 +1,30 @@ -#AMREX_HOME defines the directory in which we will find the BoxLib directory -AMREX_HOME ?= ../../../amrex -AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro - -#TOP defines the directory in which we will find Source, Exec, etc. -TOP = ../.. - -# -# Variables for the user to set ... -# - -PRECISION = DOUBLE - -DIM = 2 # DIM -COMP = gnu - -DEBUG = FALSE -USE_MPI = TRUE # MPI -USE_OMP = TRUE # OMP -PROFILE = TRUE - -USE_CUDA = FALSE # CUDA - -USE_SENSEI_INSITU = FALSE - -EBASE = amr - -Blocs := . - -include $(TOP)/Exec/Make.IAMR +#AMREX_HOME defines the directory in which we will find the BoxLib directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 # DIM +COMP = gnu + +DEBUG = FALSE +USE_MPI = TRUE # MPI +USE_OMP = TRUE # OMP +PROFILE = TRUE + +USE_CUDA = FALSE # CUDA + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials_profiling/TaylorGreen/benchmarks/EXACT_2D.F b/Tutorials_profiling/TaylorGreen/benchmarks/EXACT_2D.F index 163c25cf..da526620 100644 --- a/Tutorials_profiling/TaylorGreen/benchmarks/EXACT_2D.F +++ b/Tutorials_profiling/TaylorGreen/benchmarks/EXACT_2D.F @@ -1,71 +1,74 @@ - -#undef BL_LANG_CC -#ifndef BL_LANG_FORT -#define BL_LANG_FORT -#endif - -#include -#include -#include -#include - -#define SDIM 2 -c -c ::: ----------------------------------------------------------- -c ::: This case is an unsteady viscous benchmark for which the -c ::: exact solution is, -c ::: u(x,y,t) = - Cos(Pi x) Sin(Pi y) Exp(-2 Pi^2 Nu t) -c ::: v(x,y,t) = Sin(Pi x) Cos(Pi y) Exp(-2 Pi^2 Nu t) -c ::: p(x,y,t) = - {Cos(2 Pi x) + Cos(2 Pi y)} Exp(-4 Pi^2 Nu t) / 4 -c ::: In this directory, ViscBench2d.cpp, reads a plot file and compares -c ::: the solution against this exact solution. This benchmark was -c ::: originally derived by G.I. Taylor (Phil. Mag., Vol. 46, No. 274, -c ::: pp. 671-674, 1923) and Ethier and Steinman -c ::: (Intl. J. Num. Meth. Fluids, Vol. 19, pp. 369-375, 1994) give -c ::: the pressure field. -c - subroutine FORT_VISCBENCH(time, nu, lo, hi, - & ncomp, state, DIMS(state), - & dx, xlo, xhi) - - implicit none - - integer ncomp - integer lo(SDIM), hi(SDIM) - integer DIMDEC(state) - REAL_T time, nu, dx(SDIM) - REAL_T xlo(SDIM), xhi(SDIM) - REAL_T state(DIMV(state),ncomp) -c -c ::::: local variables -c - integer i, j - REAL_T x, y - REAL_T hx, hy - REAL_T spx, spy, cpx, cpy - REAL_T expterm - - hx = dx(1) - hy = dx(2) - - expterm = exp(-two*four*Pi**2*nu*time) - - do j = lo(2), hi(2) - y = xlo(2) + hy*(float(j-lo(2)) + half) - spy = sin(two*Pi*y) - cpy = cos(two*Pi*y) - - do i = lo(1), hi(1) - x = xlo(1) + hx*(float(i-lo(1)) + half) - - spx = sin(two*Pi*x) - cpx = cos(two*Pi*x) - - state(i,j,1) = spx*cpy * expterm - state(i,j,2) = - cpx*spy * expterm - state(i,j,3) = one - end do - end do - - end - +c SPDX-FileCopyrightText: 1999 - 2023 Berkeley Lab +c +c SPDX-License-Identifier: LicenseRef-OpenSource + +#undef BL_LANG_CC +#ifndef BL_LANG_FORT +#define BL_LANG_FORT +#endif + +#include +#include +#include +#include + +#define SDIM 2 +c +c ::: ----------------------------------------------------------- +c ::: This case is an unsteady viscous benchmark for which the +c ::: exact solution is, +c ::: u(x,y,t) = - Cos(Pi x) Sin(Pi y) Exp(-2 Pi^2 Nu t) +c ::: v(x,y,t) = Sin(Pi x) Cos(Pi y) Exp(-2 Pi^2 Nu t) +c ::: p(x,y,t) = - {Cos(2 Pi x) + Cos(2 Pi y)} Exp(-4 Pi^2 Nu t) / 4 +c ::: In this directory, ViscBench2d.cpp, reads a plot file and compares +c ::: the solution against this exact solution. This benchmark was +c ::: originally derived by G.I. Taylor (Phil. Mag., Vol. 46, No. 274, +c ::: pp. 671-674, 1923) and Ethier and Steinman +c ::: (Intl. J. Num. Meth. Fluids, Vol. 19, pp. 369-375, 1994) give +c ::: the pressure field. +c + subroutine FORT_VISCBENCH(time, nu, lo, hi, + & ncomp, state, DIMS(state), + & dx, xlo, xhi) + + implicit none + + integer ncomp + integer lo(SDIM), hi(SDIM) + integer DIMDEC(state) + REAL_T time, nu, dx(SDIM) + REAL_T xlo(SDIM), xhi(SDIM) + REAL_T state(DIMV(state),ncomp) +c +c ::::: local variables +c + integer i, j + REAL_T x, y + REAL_T hx, hy + REAL_T spx, spy, cpx, cpy + REAL_T expterm + + hx = dx(1) + hy = dx(2) + + expterm = exp(-two*four*Pi**2*nu*time) + + do j = lo(2), hi(2) + y = xlo(2) + hy*(float(j-lo(2)) + half) + spy = sin(two*Pi*y) + cpy = cos(two*Pi*y) + + do i = lo(1), hi(1) + x = xlo(1) + hx*(float(i-lo(1)) + half) + + spx = sin(two*Pi*x) + cpx = cos(two*Pi*x) + + state(i,j,1) = spx*cpy * expterm + state(i,j,2) = - cpx*spy * expterm + state(i,j,3) = one + end do + end do + + end + diff --git a/Tutorials_profiling/TaylorGreen/benchmarks/EXACT_3D.F b/Tutorials_profiling/TaylorGreen/benchmarks/EXACT_3D.F index 4201fb6e..c55eb1f2 100644 --- a/Tutorials_profiling/TaylorGreen/benchmarks/EXACT_3D.F +++ b/Tutorials_profiling/TaylorGreen/benchmarks/EXACT_3D.F @@ -1,102 +1,105 @@ - -#undef BL_LANG_CC -#ifndef BL_LANG_FORT -#define BL_LANG_FORT -#endif - -#include -#include -#include -#include - -#define SDIM 3 -c -c ::: ----------------------------------------------------------- -c ::: This case is an unsteady viscous benchmark for which the -c ::: exact solution is, -c ::: u(x,y,t) = - Cos(Pi x) Sin(Pi y) Exp(-2 Pi^2 Nu t) -c ::: v(x,y,t) = Sin(Pi x) Cos(Pi y) Exp(-2 Pi^2 Nu t) -c ::: p(x,y,t) = - {Cos(2 Pi x) + Cos(2 Pi y)} Exp(-4 Pi^2 Nu t) / 4 -c ::: In this directory, ViscBench3d.cpp, reads a plot file and compares -c ::: the solution against this exact solution. This benchmark was -c ::: originally derived by G.I. Taylor (Phil. Mag., Vol. 46, No. 274, -c ::: pp. 671-674, 1923) and Ethier and Steinman -c ::: (Intl. J. Num. Meth. Fluids, Vol. 19, pp. 369-375, 1994) give -c ::: the pressure field. -c - subroutine FORT_VISCBENCH(time, nu, unifdir, lo, hi, - & ncomp, state, DIMS(state), - & dx, xlo, xhi) - - implicit none - - integer ncomp, unifdir - integer lo(SDIM), hi(SDIM) - integer DIMDEC(state) - REAL_T time, nu, dx(SDIM) - REAL_T xlo(SDIM), xhi(SDIM) - REAL_T state(DIMV(state),ncomp) -c -c ::::: local variables -c - integer i, j, k, n - REAL_T x, y, z - REAL_T hx, hy, hz - REAL_T spx, spy, spz, cpx, cpy, cpz - REAL_T expterm - - hx = dx(1) - hy = dx(2) - hz = dx(3) - - expterm = exp(-two*four*Pi**2*nu*time) - - do k = lo(3), hi(3) - z = xlo(3) + hz*(float(k-lo(3)) + half) - spz = sin(two*Pi*z) - cpz = cos(two*Pi*z) - - do j = lo(2), hi(2) - y = xlo(2) + hy*(float(j-lo(2)) + half) - spy = sin(two*Pi*y) - cpy = cos(two*Pi*y) - - do i = lo(1), hi(1) - x = xlo(1) + hx*(float(i-lo(1)) + half) - - spx = sin(two*Pi*x) - cpx = cos(two*Pi*x) - -c -c Uniform in the X-direction -c - if (unifdir .eq. 0) then - state(i,j,k,1) = zero - state(i,j,k,2) = spz*cpy * expterm - state(i,j,k,3) = - cpz*spy * expterm - state(i,j,k,4) = one - -c -c Uniform in the Y-direction -c - elseif (unifdir .eq. 1) then - state(i,j,k,1) = - cpx*spz * expterm - state(i,j,k,2) = zero - state(i,j,k,3) = spx*cpz * expterm - state(i,j,k,4) = one - -c -c Uniform in the Z-direction -c - elseif (unifdir .eq. 2) then - state(i,j,k,1) = spx*cpy * expterm - state(i,j,k,2) = - cpx*spy * expterm - state(i,j,k,3) = zero - state(i,j,k,4) = one - endif - end do - end do - end do - - end - +c SPDX-FileCopyrightText: 1999 - 2023 Berkeley Lab +c +c SPDX-License-Identifier: LicenseRef-OpenSource + +#undef BL_LANG_CC +#ifndef BL_LANG_FORT +#define BL_LANG_FORT +#endif + +#include +#include +#include +#include + +#define SDIM 3 +c +c ::: ----------------------------------------------------------- +c ::: This case is an unsteady viscous benchmark for which the +c ::: exact solution is, +c ::: u(x,y,t) = - Cos(Pi x) Sin(Pi y) Exp(-2 Pi^2 Nu t) +c ::: v(x,y,t) = Sin(Pi x) Cos(Pi y) Exp(-2 Pi^2 Nu t) +c ::: p(x,y,t) = - {Cos(2 Pi x) + Cos(2 Pi y)} Exp(-4 Pi^2 Nu t) / 4 +c ::: In this directory, ViscBench3d.cpp, reads a plot file and compares +c ::: the solution against this exact solution. This benchmark was +c ::: originally derived by G.I. Taylor (Phil. Mag., Vol. 46, No. 274, +c ::: pp. 671-674, 1923) and Ethier and Steinman +c ::: (Intl. J. Num. Meth. Fluids, Vol. 19, pp. 369-375, 1994) give +c ::: the pressure field. +c + subroutine FORT_VISCBENCH(time, nu, unifdir, lo, hi, + & ncomp, state, DIMS(state), + & dx, xlo, xhi) + + implicit none + + integer ncomp, unifdir + integer lo(SDIM), hi(SDIM) + integer DIMDEC(state) + REAL_T time, nu, dx(SDIM) + REAL_T xlo(SDIM), xhi(SDIM) + REAL_T state(DIMV(state),ncomp) +c +c ::::: local variables +c + integer i, j, k, n + REAL_T x, y, z + REAL_T hx, hy, hz + REAL_T spx, spy, spz, cpx, cpy, cpz + REAL_T expterm + + hx = dx(1) + hy = dx(2) + hz = dx(3) + + expterm = exp(-two*four*Pi**2*nu*time) + + do k = lo(3), hi(3) + z = xlo(3) + hz*(float(k-lo(3)) + half) + spz = sin(two*Pi*z) + cpz = cos(two*Pi*z) + + do j = lo(2), hi(2) + y = xlo(2) + hy*(float(j-lo(2)) + half) + spy = sin(two*Pi*y) + cpy = cos(two*Pi*y) + + do i = lo(1), hi(1) + x = xlo(1) + hx*(float(i-lo(1)) + half) + + spx = sin(two*Pi*x) + cpx = cos(two*Pi*x) + +c +c Uniform in the X-direction +c + if (unifdir .eq. 0) then + state(i,j,k,1) = zero + state(i,j,k,2) = spz*cpy * expterm + state(i,j,k,3) = - cpz*spy * expterm + state(i,j,k,4) = one + +c +c Uniform in the Y-direction +c + elseif (unifdir .eq. 1) then + state(i,j,k,1) = - cpx*spz * expterm + state(i,j,k,2) = zero + state(i,j,k,3) = spx*cpz * expterm + state(i,j,k,4) = one + +c +c Uniform in the Z-direction +c + elseif (unifdir .eq. 2) then + state(i,j,k,1) = spx*cpy * expterm + state(i,j,k,2) = - cpx*spy * expterm + state(i,j,k,3) = zero + state(i,j,k,4) = one + endif + end do + end do + end do + + end + diff --git a/Tutorials_profiling/TaylorGreen/benchmarks/EXACT_F.H b/Tutorials_profiling/TaylorGreen/benchmarks/EXACT_F.H index e75a53e4..56db2647 100644 --- a/Tutorials_profiling/TaylorGreen/benchmarks/EXACT_F.H +++ b/Tutorials_profiling/TaylorGreen/benchmarks/EXACT_F.H @@ -1,48 +1,54 @@ -#ifndef _FORT_INTERFACE_ -#define _FORT_INTERFACE_ - -#ifdef BL_LANG_FORT -c -c ------------------------- -c ::: Fortran Interface ::: -c ------------------------- -c -# define FORT_VISCBENCH viscbench -#else -// -// --------------------------------------- -// ::: C Interface to Fortran Routines ::: -// --------------------------------------- -// - -#ifdef BL_FORT_USE_UNDERSCORE -# define FORT_VISCBENCH viscbench_ -#else -# define FORT_VISCBENCH VISCBENCH -#endif - -// -// Use ARLIM in the following. -// - -extern "C" -{ -#if (BL_SPACEDIM==3) - void FORT_VISCBENCH(const amrex::Real *time, const amrex::Real *nu, const int *unifdir, - const int *lo, const int *hi, - const int *ncomp, - const amrex::Real *state, ARLIM_P(lo), ARLIM_P(hi), - const amrex::Real *delta, - const amrex::Real *xlo, const amrex::Real *xhi); -#else - void FORT_VISCBENCH(const amrex::Real *time, const amrex::Real *nu, - const int *lo, const int *hi, - const int *ncomp, - const amrex::Real *state, ARLIM_P(lo), ARLIM_P(hi), - const amrex::Real *delta, - const amrex::Real *xlo, const amrex::Real *xhi); -#endif - -} -#endif -#endif +/* + * SPDX-FileCopyrightText: 1999 - 2023 Berkeley Lab + * + * SPDX-License-Identifier: LicenseRef-OpenSource + */ + +#ifndef _FORT_INTERFACE_ +#define _FORT_INTERFACE_ + +#ifdef BL_LANG_FORT +c +c ------------------------- +c ::: Fortran Interface ::: +c ------------------------- +c +# define FORT_VISCBENCH viscbench +#else +// +// --------------------------------------- +// ::: C Interface to Fortran Routines ::: +// --------------------------------------- +// + +#ifdef BL_FORT_USE_UNDERSCORE +# define FORT_VISCBENCH viscbench_ +#else +# define FORT_VISCBENCH VISCBENCH +#endif + +// +// Use ARLIM in the following. +// + +extern "C" +{ +#if (BL_SPACEDIM==3) + void FORT_VISCBENCH(const amrex::Real *time, const amrex::Real *nu, const int *unifdir, + const int *lo, const int *hi, + const int *ncomp, + const amrex::Real *state, ARLIM_P(lo), ARLIM_P(hi), + const amrex::Real *delta, + const amrex::Real *xlo, const amrex::Real *xhi); +#else + void FORT_VISCBENCH(const amrex::Real *time, const amrex::Real *nu, + const int *lo, const int *hi, + const int *ncomp, + const amrex::Real *state, ARLIM_P(lo), ARLIM_P(hi), + const amrex::Real *delta, + const amrex::Real *xlo, const amrex::Real *xhi); +#endif + +} +#endif +#endif diff --git a/Tutorials_profiling/TaylorGreen/benchmarks/ExSoln_2dIncNS.nb b/Tutorials_profiling/TaylorGreen/benchmarks/ExSoln_2dIncNS.nb index 332bb645..8c5c7486 100644 --- a/Tutorials_profiling/TaylorGreen/benchmarks/ExSoln_2dIncNS.nb +++ b/Tutorials_profiling/TaylorGreen/benchmarks/ExSoln_2dIncNS.nb @@ -1,9466 +1,9466 @@ -(*********************************************************************** - - Mathematica-Compatible Notebook - -This notebook can be used on any computer system with Mathematica 3.0, -MathReader 3.0, or any compatible application. The data for the notebook -starts with the line of stars above. - -To get the notebook into a Mathematica-compatible application, do one of -the following: - -* Save the data starting with the line of stars above into a file - with a name ending in .nb, then open the file inside the application; - -* Copy the data starting with the line of stars above to the - clipboard, then use the Paste menu command inside the application. - -Data for notebooks contains only printable 7-bit ASCII and can be -sent directly in email or through ftp in text mode. Newlines can be -CR, LF or CRLF (Unix, Macintosh or MS-DOS style). - -NOTE: If you modify the data for this notebook not in a Mathematica- -compatible application, you must delete the line below containing the -word CacheID, otherwise Mathematica-compatible applications may try to -use invalid cache data. - -For more information on notebooks and Mathematica-compatible -applications, contact Wolfram Research: - web: http://www.wolfram.com - email: info@wolfram.com - phone: +1-217-398-0700 (U.S.) - -Notebook reader applications are available free of charge from -Wolfram Research. -***********************************************************************) - -(*CacheID: 232*) - - -(*NotebookFileLineBreakTest -NotebookFileLineBreakTest*) -(*NotebookOptionsPosition[ 358257, 9342]*) -(*NotebookOutlinePosition[ 359033, 9369]*) -(* CellTagsIndexPosition[ 358989, 9365]*) -(*WindowFrame->Normal*) - - - -Notebook[{ - -Cell[CellGroupData[{ -Cell["\<\ -Evaluation of a 2-d Exact Solution for the Viscous, Incompressible \ -Navier-Stokes Equations\ -\>", "Title", - TextAlignment->Center], - -Cell[CellGroupData[{ - -Cell["Define Velocity, Pressure and Scalar Fields", "Section"], - -Cell[CellGroupData[{ - -Cell[BoxData[ - \(u\ = \ \(-Cos[Pi\ x]\)\ Sin[Pi\ y]\ Exp[\(-2\)\ Pi^2\ nu\ t]\)], - "Input"], - -Cell[BoxData[ - \(\(-E\^\(\(-2\)\ nu\ \[Pi]\^2\ t\)\)\ Cos[\[Pi]\ x]\ Sin[\[Pi]\ y]\)], - "Output"] -}, Open ]], - -Cell[CellGroupData[{ - -Cell[BoxData[ - \(v\ = \ Sin[Pi\ x]\ Cos[Pi\ y]\ Exp[\(-2\)\ Pi^2\ nu\ t]\)], "Input"], - -Cell[BoxData[ - \(E\^\(\(-2\)\ nu\ \[Pi]\^2\ t\)\ Cos[\[Pi]\ y]\ Sin[\[Pi]\ x]\)], - "Output"] -}, Open ]], - -Cell[CellGroupData[{ - -Cell[BoxData[ - \(p\ = \ - \(-\ \((Cos[2\ Pi\ x]\ + \ Cos[2\ Pi\ y])\)\)/4\ - Exp[\(-4\)\ Pi^2\ nu\ t]\)], "Input"], - -Cell[BoxData[ - \(1\/4\ E\^\(\(-4\)\ nu\ \[Pi]\^2\ t\)\ - \((\(-Cos[2\ \[Pi]\ x]\) - Cos[2\ \[Pi]\ y])\)\)], "Output"] -}, Open ]], - -Cell[CellGroupData[{ - -Cell[BoxData[ - \(Y\ = \ Cos[Pi\ x]\ Cos[Pi\ y] Exp[\(-\ 2\)\ Pi^2\ d\ t]\)], "Input"], - -Cell[BoxData[ - \(E\^\(\(-2\)\ d\ \[Pi]\^2\ t\)\ Cos[\[Pi]\ x]\ Cos[\[Pi]\ y]\)], "Output"] -}, Open ]] -}, Open ]], - -Cell[CellGroupData[{ - -Cell["Check Governing Equations", "Section"], - -Cell[CellGroupData[{ - -Cell[BoxData[ - \(D[u, x]\ + \ D[v, y]\ == \ 0\)], "Input"], - -Cell[BoxData[ - \(True\)], "Output"] -}, Open ]], - -Cell[CellGroupData[{ - -Cell[BoxData[ - \(Simplify[ - D[u, t]\ + \ u\ D[u, x]\ + \ v\ D[u, y]\ == \ - \(-\ D[p, x]\)\ + \ nu\ D[u, \ {x, 2}] + \ nu\ D[u, \ {y, 2}]]\)], - "Input"], - -Cell[BoxData[ - \(True\)], "Output"] -}, Open ]], - -Cell[CellGroupData[{ - -Cell[BoxData[ - \(Simplify[ - D[v, t]\ + \ u\ D[v, x]\ + \ v\ D[v, y]\ == \ - \(-\ D[p, y]\)\ + \ nu\ D[v, \ {x, 2}] + \ nu\ D[v, \ {y, 2}]]\)], - "Input"], - -Cell[BoxData[ - \(True\)], "Output"] -}, Open ]], - -Cell[CellGroupData[{ - -Cell[BoxData[ - \(Simplify[ - D[Y, t]\ + \ u\ D[Y, x]\ + \ v\ D[Y, y]\ == \ - d\ D[Y, {x, 2}]\ + \ d\ D[Y, {y, 2}]]\)], "Input"], - -Cell[BoxData[ - \(True\)], "Output"] -}, Open ]], - -Cell[CellGroupData[{ - -Cell[BoxData[ - \(t\ = \ 0\)], "Input"], - -Cell[BoxData[ - \(0\)], "Output"] -}, Open ]], - -Cell[CellGroupData[{ - -Cell[BoxData[ - \(ContourPlot[u, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"], - -Cell[GraphicsData["PostScript", "\<\ -%! -%%Creator: Mathematica -%%AspectRatio: 1 -MathPictureStart -/Mabs { -Mgmatrix idtransform -Mtmatrix dtransform -} bind def -/Mabsadd { Mabs -3 -1 roll add -3 1 roll add -exch } bind def -%% ContourGraphics -%%IncludeResource: font Courier -%%IncludeFont: Courier -/Courier findfont 10 scalefont setfont -% Scaling calculations -0.0192308 0.480769 0.0192308 0.480769 [ -[.01923 -0.0125 -3 -9 ] -[.01923 -0.0125 3 0 ] -[.25962 -0.0125 -9 -9 ] -[.25962 -0.0125 9 0 ] -[.5 -0.0125 -3 -9 ] -[.5 -0.0125 3 0 ] -[.74038 -0.0125 -9 -9 ] -[.74038 -0.0125 9 0 ] -[.98077 -0.0125 -3 -9 ] -[.98077 -0.0125 3 0 ] -[ 0 0 -0.125 0 ] -[-0.0125 .01923 -6 -4.5 ] -[-0.0125 .01923 0 4.5 ] -[-0.0125 .25962 -18 -4.5 ] -[-0.0125 .25962 0 4.5 ] -[-0.0125 .5 -6 -4.5 ] -[-0.0125 .5 0 4.5 ] -[-0.0125 .74038 -18 -4.5 ] -[-0.0125 .74038 0 4.5 ] -[-0.0125 .98077 -6 -4.5 ] -[-0.0125 .98077 0 4.5 ] -[ 0 0 -0.125 0 ] -[ 0 1 .125 0 ] -[ 1 0 .125 0 ] -[ 0 0 0 0 ] -[ 1 1 0 0 ] -] MathScale -% Start of Graphics -1 setlinecap -1 setlinejoin -newpath -0 g -.25 Mabswid -.01923 0 m -.01923 .00625 L -s -[(0)] .01923 -0.0125 0 1 Mshowa -.25962 0 m -.25962 .00625 L -s -[(0.5)] .25962 -0.0125 0 1 Mshowa -.5 0 m -.5 .00625 L -s -[(1)] .5 -0.0125 0 1 Mshowa -.74038 0 m -.74038 .00625 L -s -[(1.5)] .74038 -0.0125 0 1 Mshowa -.98077 0 m -.98077 .00625 L -s -[(2)] .98077 -0.0125 0 1 Mshowa -.125 Mabswid -.06731 0 m -.06731 .00375 L -s -.11538 0 m -.11538 .00375 L -s -.16346 0 m -.16346 .00375 L -s -.21154 0 m -.21154 .00375 L -s -.30769 0 m -.30769 .00375 L -s -.35577 0 m -.35577 .00375 L -s -.40385 0 m -.40385 .00375 L -s -.45192 0 m -.45192 .00375 L -s -.54808 0 m -.54808 .00375 L -s -.59615 0 m -.59615 .00375 L -s -.64423 0 m -.64423 .00375 L -s -.69231 0 m -.69231 .00375 L -s -.78846 0 m -.78846 .00375 L -s -.83654 0 m -.83654 .00375 L -s -.88462 0 m -.88462 .00375 L -s -.93269 0 m -.93269 .00375 L -s -.25 Mabswid -0 0 m -1 0 L -s -0 .01923 m -.00625 .01923 L -s -[(0)] -0.0125 .01923 1 0 Mshowa -0 .25962 m -.00625 .25962 L -s -[(0.5)] -0.0125 .25962 1 0 Mshowa -0 .5 m -.00625 .5 L -s -[(1)] -0.0125 .5 1 0 Mshowa -0 .74038 m -.00625 .74038 L -s -[(1.5)] -0.0125 .74038 1 0 Mshowa -0 .98077 m -.00625 .98077 L -s -[(2)] -0.0125 .98077 1 0 Mshowa -.125 Mabswid -0 .06731 m -.00375 .06731 L -s -0 .11538 m -.00375 .11538 L -s -0 .16346 m -.00375 .16346 L -s -0 .21154 m -.00375 .21154 L -s -0 .30769 m -.00375 .30769 L -s -0 .35577 m -.00375 .35577 L -s -0 .40385 m -.00375 .40385 L -s -0 .45192 m -.00375 .45192 L -s -0 .54808 m -.00375 .54808 L -s -0 .59615 m -.00375 .59615 L -s -0 .64423 m -.00375 .64423 L -s -0 .69231 m -.00375 .69231 L -s -0 .78846 m -.00375 .78846 L -s -0 .83654 m -.00375 .83654 L -s -0 .88462 m -.00375 .88462 L -s -0 .93269 m -.00375 .93269 L -s -.25 Mabswid -0 0 m -0 1 L -s -.01923 .99375 m -.01923 1 L -s -.25962 .99375 m -.25962 1 L -s -.5 .99375 m -.5 1 L -s -.74038 .99375 m -.74038 1 L -s -.98077 .99375 m -.98077 1 L -s -.125 Mabswid -.06731 .99625 m -.06731 1 L -s -.11538 .99625 m -.11538 1 L -s -.16346 .99625 m -.16346 1 L -s -.21154 .99625 m -.21154 1 L -s -.30769 .99625 m -.30769 1 L -s -.35577 .99625 m -.35577 1 L -s -.40385 .99625 m -.40385 1 L -s -.45192 .99625 m -.45192 1 L -s -.54808 .99625 m -.54808 1 L -s -.59615 .99625 m -.59615 1 L -s -.64423 .99625 m -.64423 1 L -s -.69231 .99625 m -.69231 1 L -s -.78846 .99625 m -.78846 1 L -s -.83654 .99625 m -.83654 1 L -s -.88462 .99625 m -.88462 1 L -s -.93269 .99625 m -.93269 1 L -s -.25 Mabswid -0 1 m -1 1 L -s -.99375 .01923 m -1 .01923 L -s -.99375 .25962 m -1 .25962 L -s -.99375 .5 m -1 .5 L -s -.99375 .74038 m -1 .74038 L -s -.99375 .98077 m -1 .98077 L -s -.125 Mabswid -.99625 .06731 m -1 .06731 L -s -.99625 .11538 m -1 .11538 L -s -.99625 .16346 m -1 .16346 L -s -.99625 .21154 m -1 .21154 L -s -.99625 .30769 m -1 .30769 L -s -.99625 .35577 m -1 .35577 L -s -.99625 .40385 m -1 .40385 L -s -.99625 .45192 m -1 .45192 L -s -.99625 .54808 m -1 .54808 L -s -.99625 .59615 m -1 .59615 L -s -.99625 .64423 m -1 .64423 L -s -.99625 .69231 m -1 .69231 L -s -.99625 .78846 m -1 .78846 L -s -.99625 .83654 m -1 .83654 L -s -.99625 .88462 m -1 .88462 L -s -.99625 .93269 m -1 .93269 L -s -.25 Mabswid -1 0 m -1 1 L -s -0 0 m -1 0 L -1 1 L -0 1 L -closepath -clip -newpath -.5 g -.01923 .98077 m -.98077 .98077 L -.98077 .01923 L -.01923 .01923 L -F -0 g -.5 Mabswid -.4 g -.01923 .48596 m -.08791 .4844 L -.15659 .47739 L -.22527 .43403 L -.22654 .43132 L -.24138 .36264 L -.24501 .29396 L -.24501 .22527 L -.24138 .15659 L -.22654 .08791 L -.22527 .0857 L -.15659 .04742 L -.08791 .03964 L -.01923 .03781 L -F -0 g -.01923 .48596 m -.08791 .4844 L -.15659 .47739 L -.22527 .43403 L -.22654 .43132 L -.24138 .36264 L -.24501 .29396 L -.24501 .22527 L -.24138 .15659 L -.22654 .08791 L -.22527 .0857 L -.15659 .04742 L -.08791 .03964 L -.01923 .03781 L -s -.6 g -.01923 .96219 m -.08791 .96036 L -.15659 .95258 L -.22527 .9143 L -.22654 .91209 L -.24138 .84341 L -.24501 .77473 L -.24501 .70604 L -.24138 .63736 L -.22654 .56868 L -.22527 .56597 L -.15659 .52261 L -.08791 .5156 L -.01923 .51404 L -F -0 g -.01923 .96219 m -.08791 .96036 L -.15659 .95258 L -.22527 .9143 L -.22654 .91209 L -.24138 .84341 L -.24501 .77473 L -.24501 .70604 L -.24138 .63736 L -.22654 .56868 L -.22527 .56597 L -.15659 .52261 L -.08791 .5156 L -.01923 .51404 L -s -.7 g -.01923 .93333 m -.08791 .92913 L -.15521 .91209 L -.15659 .91009 L -.20465 .84341 L -.21567 .77473 L -.21567 .70604 L -.20465 .63736 L -.15659 .57067 L -.15521 .56868 L -.08791 .54788 L -.01923 .54293 L -F -0 g -.01923 .93333 m -.08791 .92913 L -.15521 .91209 L -.15659 .91009 L -.20465 .84341 L -.21567 .77473 L -.21567 .70604 L -.20465 .63736 L -.15659 .57067 L -.15521 .56868 L -.08791 .54788 L -.01923 .54293 L -s -.3 g -.01923 .45707 m -.08791 .45212 L -.15521 .43132 L -.15659 .42933 L -.20465 .36264 L -.21567 .29396 L -.21567 .22527 L -.20465 .15659 L -.15659 .08991 L -.15521 .08791 L -.08791 .07087 L -.01923 .06667 L -F -0 g -.01923 .45707 m -.08791 .45212 L -.15521 .43132 L -.15659 .42933 L -.20465 .36264 L -.21567 .29396 L -.21567 .22527 L -.20465 .15659 L -.15659 .08991 L -.15521 .08791 L -.08791 .07087 L -.01923 .06667 L -s -.8 g -.01923 .90753 m -.08791 .8997 L -.15659 .85304 L -.16237 .84341 L -.18453 .77473 L -.18453 .70604 L -.16237 .63736 L -.15659 .62773 L -.08791 .58107 L -.01923 .57324 L -F -0 g -.01923 .90753 m -.08791 .8997 L -.15659 .85304 L -.16237 .84341 L -.18453 .77473 L -.18453 .70604 L -.16237 .63736 L -.15659 .62773 L -.08791 .58107 L -.01923 .57324 L -s -.2 g -.01923 .42676 m -.08791 .41893 L -.15659 .37227 L -.16237 .36264 L -.18453 .29396 L -.18453 .22527 L -.16237 .15659 L -.15659 .14696 L -.08791 .1003 L -.01923 .09247 L -F -0 g -.01923 .42676 m -.08791 .41893 L -.15659 .37227 L -.16237 .36264 L -.18453 .29396 L -.18453 .22527 L -.16237 .15659 L -.15659 .14696 L -.08791 .1003 L -.01923 .09247 L -s -.9 g -.01923 .87516 m -.08791 .85892 L -.11825 .84341 L -.15309 .77473 L -.15309 .70604 L -.11825 .63736 L -.08791 .62185 L -.01923 .60561 L -F -0 g -.01923 .87516 m -.08791 .85892 L -.11825 .84341 L -.15309 .77473 L -.15309 .70604 L -.11825 .63736 L -.08791 .62185 L -.01923 .60561 L -s -.1 g -.01923 .39439 m -.08791 .37815 L -.11825 .36264 L -.15309 .29396 L -.15309 .22527 L -.11825 .15659 L -.08791 .14108 L -.01923 .12484 L -F -0 g -.01923 .39439 m -.08791 .37815 L -.11825 .36264 L -.15309 .29396 L -.15309 .22527 L -.11825 .15659 L -.08791 .14108 L -.01923 .12484 L -s -1 g -.01923 .82869 m -.08791 .79783 L -.10805 .77473 L -.10805 .70604 L -.08791 .68294 L -.01923 .65208 L -F -0 g -.01923 .82869 m -.08791 .79783 L -.10805 .77473 L -.10805 .70604 L -.08791 .68294 L -.01923 .65208 L -s -.01923 .34792 m -.08791 .31706 L -.10805 .29396 L -.10805 .22527 L -.08791 .20217 L -.01923 .17131 L -F -.01923 .34792 m -.08791 .31706 L -.10805 .29396 L -.10805 .22527 L -.08791 .20217 L -.01923 .17131 L -s -.6 g -.29396 .0857 m -.36264 .04742 L -.43132 .03964 L -.5 .03781 L -.56868 .03964 L -.63736 .04742 L -.70604 .0857 L -.70731 .08791 L -.72215 .15659 L -.72578 .22527 L -.72578 .29396 L -.72215 .36264 L -.70731 .43132 L -.70604 .43403 L -.63736 .47739 L -.56868 .4844 L -.5 .48596 L -.43132 .4844 L -.36264 .47739 L -.29396 .43403 L -.29269 .43132 L -.27785 .36264 L -.27422 .29396 L -.27422 .22527 L -.27785 .15659 L -.29269 .08791 L -F -0 g -.29396 .0857 m -.36264 .04742 L -.43132 .03964 L -.5 .03781 L -.56868 .03964 L -.63736 .04742 L -.70604 .0857 L -.70731 .08791 L -.72215 .15659 L -.72578 .22527 L -.72578 .29396 L -.72215 .36264 L -.70731 .43132 L -.70604 .43403 L -.63736 .47739 L -.56868 .4844 L -.5 .48596 L -.43132 .4844 L -.36264 .47739 L -.29396 .43403 L -.29269 .43132 L -.27785 .36264 L -.27422 .29396 L -.27422 .22527 L -.27785 .15659 L -.29269 .08791 L -.29396 .0857 L -s -.4 g -.29396 .56597 m -.36264 .52261 L -.43132 .5156 L -.5 .51404 L -.56868 .5156 L -.63736 .52261 L -.70604 .56597 L -.70731 .56868 L -.72215 .63736 L -.72578 .70604 L -.72578 .77473 L -.72215 .84341 L -.70731 .91209 L -.70604 .9143 L -.63736 .95258 L -.56868 .96036 L -.5 .96219 L -.43132 .96036 L -.36264 .95258 L -.29396 .9143 L -.29269 .91209 L -.27785 .84341 L -.27422 .77473 L -.27422 .70604 L -.27785 .63736 L -.29269 .56868 L -F -0 g -.29396 .56597 m -.36264 .52261 L -.43132 .5156 L -.5 .51404 L -.56868 .5156 L -.63736 .52261 L -.70604 .56597 L -.70731 .56868 L -.72215 .63736 L -.72578 .70604 L -.72578 .77473 L -.72215 .84341 L -.70731 .91209 L -.70604 .9143 L -.63736 .95258 L -.56868 .96036 L -.5 .96219 L -.43132 .96036 L -.36264 .95258 L -.29396 .9143 L -.29269 .91209 L -.27785 .84341 L -.27422 .77473 L -.27422 .70604 L -.27785 .63736 L -.29269 .56868 L -.29396 .56597 L -s -.3 g -.43132 .54788 m -.5 .54293 L -.56868 .54788 L -.63598 .56868 L -.63736 .57067 L -.68542 .63736 L -.69644 .70604 L -.69644 .77473 L -.68542 .84341 L -.63736 .91009 L -.63598 .91209 L -.56868 .92913 L -.5 .93333 L -.43132 .92913 L -.36402 .91209 L -.36264 .91009 L -.31458 .84341 L -.30356 .77473 L -.30356 .70604 L -.31458 .63736 L -.36264 .57067 L -.36402 .56868 L -F -0 g -.43132 .54788 m -.5 .54293 L -.56868 .54788 L -.63598 .56868 L -.63736 .57067 L -.68542 .63736 L -.69644 .70604 L -.69644 .77473 L -.68542 .84341 L -.63736 .91009 L -.63598 .91209 L -.56868 .92913 L -.5 .93333 L -.43132 .92913 L -.36402 .91209 L -.36264 .91009 L -.31458 .84341 L -.30356 .77473 L -.30356 .70604 L -.31458 .63736 L -.36264 .57067 L -.36402 .56868 L -.43132 .54788 L -s -.7 g -.43132 .07087 m -.5 .06667 L -.56868 .07087 L -.63598 .08791 L -.63736 .08991 L -.68542 .15659 L -.69644 .22527 L -.69644 .29396 L -.68542 .36264 L -.63736 .42933 L -.63598 .43132 L -.56868 .45212 L -.5 .45707 L -.43132 .45212 L -.36402 .43132 L -.36264 .42933 L -.31458 .36264 L -.30356 .29396 L -.30356 .22527 L -.31458 .15659 L -.36264 .08991 L -.36402 .08791 L -F -0 g -.43132 .07087 m -.5 .06667 L -.56868 .07087 L -.63598 .08791 L -.63736 .08991 L -.68542 .15659 L -.69644 .22527 L -.69644 .29396 L -.68542 .36264 L -.63736 .42933 L -.63598 .43132 L -.56868 .45212 L -.5 .45707 L -.43132 .45212 L -.36402 .43132 L -.36264 .42933 L -.31458 .36264 L -.30356 .29396 L -.30356 .22527 L -.31458 .15659 L -.36264 .08991 L -.36402 .08791 L -.43132 .07087 L -s -.2 g -.36264 .62773 m -.43132 .58107 L -.5 .57324 L -.56868 .58107 L -.63736 .62773 L -.64314 .63736 L -.6653 .70604 L -.6653 .77473 L -.64314 .84341 L -.63736 .85304 L -.56868 .8997 L -.5 .90753 L -.43132 .8997 L -.36264 .85304 L -.35686 .84341 L -.3347 .77473 L -.3347 .70604 L -.35686 .63736 L -F -0 g -.36264 .62773 m -.43132 .58107 L -.5 .57324 L -.56868 .58107 L -.63736 .62773 L -.64314 .63736 L -.6653 .70604 L -.6653 .77473 L -.64314 .84341 L -.63736 .85304 L -.56868 .8997 L -.5 .90753 L -.43132 .8997 L -.36264 .85304 L -.35686 .84341 L -.3347 .77473 L -.3347 .70604 L -.35686 .63736 L -.36264 .62773 L -s -.8 g -.36264 .14696 m -.43132 .1003 L -.5 .09247 L -.56868 .1003 L -.63736 .14696 L -.64314 .15659 L -.6653 .22527 L -.6653 .29396 L -.64314 .36264 L -.63736 .37227 L -.56868 .41893 L -.5 .42676 L -.43132 .41893 L -.36264 .37227 L -.35686 .36264 L -.3347 .29396 L -.3347 .22527 L -.35686 .15659 L -F -0 g -.36264 .14696 m -.43132 .1003 L -.5 .09247 L -.56868 .1003 L -.63736 .14696 L -.64314 .15659 L -.6653 .22527 L -.6653 .29396 L -.64314 .36264 L -.63736 .37227 L -.56868 .41893 L -.5 .42676 L -.43132 .41893 L -.36264 .37227 L -.35686 .36264 L -.3347 .29396 L -.3347 .22527 L -.35686 .15659 L -.36264 .14696 L -s -.1 g -.43132 .62185 m -.5 .60561 L -.56868 .62185 L -.59902 .63736 L -.63386 .70604 L -.63386 .77473 L -.59902 .84341 L -.56868 .85892 L -.5 .87516 L -.43132 .85892 L -.40098 .84341 L -.36614 .77473 L -.36614 .70604 L -.40098 .63736 L -F -0 g -.43132 .62185 m -.5 .60561 L -.56868 .62185 L -.59902 .63736 L -.63386 .70604 L -.63386 .77473 L -.59902 .84341 L -.56868 .85892 L -.5 .87516 L -.43132 .85892 L -.40098 .84341 L -.36614 .77473 L -.36614 .70604 L -.40098 .63736 L -.43132 .62185 L -s -.9 g -.43132 .14108 m -.5 .12484 L -.56868 .14108 L -.59902 .15659 L -.63386 .22527 L -.63386 .29396 L -.59902 .36264 L -.56868 .37815 L -.5 .39439 L -.43132 .37815 L -.40098 .36264 L -.36614 .29396 L -.36614 .22527 L -.40098 .15659 L -F -0 g -.43132 .14108 m -.5 .12484 L -.56868 .14108 L -.59902 .15659 L -.63386 .22527 L -.63386 .29396 L -.59902 .36264 L -.56868 .37815 L -.5 .39439 L -.43132 .37815 L -.40098 .36264 L -.36614 .29396 L -.36614 .22527 L -.40098 .15659 L -.43132 .14108 L -s -.43132 .68294 m -.5 .65208 L -.56868 .68294 L -.58882 .70604 L -.58882 .77473 L -.56868 .79783 L -.5 .82869 L -.43132 .79783 L -.41118 .77473 L -.41118 .70604 L -F -.43132 .68294 m -.5 .65208 L -.56868 .68294 L -.58882 .70604 L -.58882 .77473 L -.56868 .79783 L -.5 .82869 L -.43132 .79783 L -.41118 .77473 L -.41118 .70604 L -.43132 .68294 L -s -1 g -.43132 .20217 m -.5 .17131 L -.56868 .20217 L -.58882 .22527 L -.58882 .29396 L -.56868 .31706 L -.5 .34792 L -.43132 .31706 L -.41118 .29396 L -.41118 .22527 L -F -0 g -.43132 .20217 m -.5 .17131 L -.56868 .20217 L -.58882 .22527 L -.58882 .29396 L -.56868 .31706 L -.5 .34792 L -.43132 .31706 L -.41118 .29396 L -.41118 .22527 L -.43132 .20217 L -s -.4 g -.98077 .48596 m -.91209 .4844 L -.84341 .47739 L -.77473 .43403 L -.77346 .43132 L -.75862 .36264 L -.75499 .29396 L -.75499 .22527 L -.75862 .15659 L -.77346 .08791 L -.77473 .0857 L -.84341 .04742 L -.91209 .03964 L -.98077 .03781 L -F -0 g -.98077 .48596 m -.91209 .4844 L -.84341 .47739 L -.77473 .43403 L -.77346 .43132 L -.75862 .36264 L -.75499 .29396 L -.75499 .22527 L -.75862 .15659 L -.77346 .08791 L -.77473 .0857 L -.84341 .04742 L -.91209 .03964 L -.98077 .03781 L -s -.6 g -.98077 .96219 m -.91209 .96036 L -.84341 .95258 L -.77473 .9143 L -.77346 .91209 L -.75862 .84341 L -.75499 .77473 L -.75499 .70604 L -.75862 .63736 L -.77346 .56868 L -.77473 .56597 L -.84341 .52261 L -.91209 .5156 L -.98077 .51404 L -F -0 g -.98077 .96219 m -.91209 .96036 L -.84341 .95258 L -.77473 .9143 L -.77346 .91209 L -.75862 .84341 L -.75499 .77473 L -.75499 .70604 L -.75862 .63736 L -.77346 .56868 L -.77473 .56597 L -.84341 .52261 L -.91209 .5156 L -.98077 .51404 L -s -.7 g -.98077 .93333 m -.91209 .92913 L -.84479 .91209 L -.84341 .91009 L -.79535 .84341 L -.78433 .77473 L -.78433 .70604 L -.79535 .63736 L -.84341 .57067 L -.84479 .56868 L -.91209 .54788 L -.98077 .54293 L -F -0 g -.98077 .93333 m -.91209 .92913 L -.84479 .91209 L -.84341 .91009 L -.79535 .84341 L -.78433 .77473 L -.78433 .70604 L -.79535 .63736 L -.84341 .57067 L -.84479 .56868 L -.91209 .54788 L -.98077 .54293 L -s -.3 g -.98077 .45707 m -.91209 .45212 L -.84479 .43132 L -.84341 .42933 L -.79535 .36264 L -.78433 .29396 L -.78433 .22527 L -.79535 .15659 L -.84341 .08991 L -.84479 .08791 L -.91209 .07087 L -.98077 .06667 L -F -0 g -.98077 .45707 m -.91209 .45212 L -.84479 .43132 L -.84341 .42933 L -.79535 .36264 L -.78433 .29396 L -.78433 .22527 L -.79535 .15659 L -.84341 .08991 L -.84479 .08791 L -.91209 .07087 L -.98077 .06667 L -s -.2 g -.98077 .42676 m -.91209 .41893 L -.84341 .37227 L -.83763 .36264 L -.81547 .29396 L -.81547 .22527 L -.83763 .15659 L -.84341 .14696 L -.91209 .1003 L -.98077 .09247 L -F -0 g -.98077 .42676 m -.91209 .41893 L -.84341 .37227 L -.83763 .36264 L -.81547 .29396 L -.81547 .22527 L -.83763 .15659 L -.84341 .14696 L -.91209 .1003 L -.98077 .09247 L -s -.8 g -.98077 .90753 m -.91209 .8997 L -.84341 .85304 L -.83763 .84341 L -.81547 .77473 L -.81547 .70604 L -.83763 .63736 L -.84341 .62773 L -.91209 .58107 L -.98077 .57324 L -F -0 g -.98077 .90753 m -.91209 .8997 L -.84341 .85304 L -.83763 .84341 L -.81547 .77473 L -.81547 .70604 L -.83763 .63736 L -.84341 .62773 L -.91209 .58107 L -.98077 .57324 L -s -.1 g -.98077 .39439 m -.91209 .37815 L -.88175 .36264 L -.84691 .29396 L -.84691 .22527 L -.88175 .15659 L -.91209 .14108 L -.98077 .12484 L -F -0 g -.98077 .39439 m -.91209 .37815 L -.88175 .36264 L -.84691 .29396 L -.84691 .22527 L -.88175 .15659 L -.91209 .14108 L -.98077 .12484 L -s -.9 g -.98077 .87516 m -.91209 .85892 L -.88175 .84341 L -.84691 .77473 L -.84691 .70604 L -.88175 .63736 L -.91209 .62185 L -.98077 .60561 L -F -0 g -.98077 .87516 m -.91209 .85892 L -.88175 .84341 L -.84691 .77473 L -.84691 .70604 L -.88175 .63736 L -.91209 .62185 L -.98077 .60561 L -s -1 g -.98077 .82869 m -.91209 .79783 L -.89195 .77473 L -.89195 .70604 L -.91209 .68294 L -.98077 .65208 L -F -0 g -.98077 .82869 m -.91209 .79783 L -.89195 .77473 L -.89195 .70604 L -.91209 .68294 L -.98077 .65208 L -s -.98077 .34792 m -.91209 .31706 L -.89195 .29396 L -.89195 .22527 L -.91209 .20217 L -.98077 .17131 L -F -.98077 .34792 m -.91209 .31706 L -.89195 .29396 L -.89195 .22527 L -.91209 .20217 L -.98077 .17131 L -s -% End of Graphics -MathPictureEnd -\ -\>"], "Graphics", - ImageSize->{288, 288}, - ImageMargins->{{43, 0}, {0, 0}}, - ImageRegion->{{0, 1}, {0, 1}}, - ImageCache->GraphicsData["Bitmap", "\<\ -CF5dJ6E]HGAYHf4PAg9QL6QYHgon6Ykno_hn?S`2ook>c/mWIfGmoOol005E[;lC4a000<`00IP00V@00c000 -o`0c000c<`0cIP0cV@0cc00co`1V001V<`1VIP1VV@1Vc01Vo`2I002I<`2IIP2IV@2Ic02Io`3<003< -<`3I03>IIIS>IVC>Ic3>Ioc?<03?<@000`40000f00030@0000L00`4i0003 -0@0000@0000H00040@000CH000@1000120000`40000i00030@0003H000<100001`000`40000j0003 -0@0000<0000H00040@000CH000@1000120000`40000g00<1=P030@T000<10000=`00104000450000 -6@020CP00P4900@1>0000`40000f00030@0000L0104g00811P000?l08@0001D0o`4;0@40000E0003 -0@00008000<100002P000`40000900030@0000X000<100002P000`40000:00030@0000X000<10000 -2@000`40000:00030@0000X000<100002P000`40000900030@0000X000<100002P000`40000:0003 -0@0000T000<100002P000`40000:00030@0000X000<100002P000`40000900030@0000800@410000 -5@000`40000200030@0003d000<10000?@000`40000l00030@0003d000<100000P010@40000E0003 -0@000?l01`010@40000>00811@000`40003o00L00@4100003@00104000440081o`0700810@0000d0 -00@1000110000`400002003oY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00D00@4100003@001040004400030@000080 -0?l9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`T01@010@40000=00040@000@@000<100000P00ojL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`0500410@0000d000@1000110000`400002003o2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900D00@4100003P020@D0 -00<100000P090@1^2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JLB0@1]2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@0:0@@0 -0@4100005@000`40000200T93P40DZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T>0A:W3P40DZL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`T=0@T91@010@40000E00030@0000805`T90@10Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@T1;ZL90@10Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@T1 -5PT500410@0001D000<100000P0P2@D103JW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T50D2W1@40=ZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@D17`T500410@0001D000<100000P0U2@810389Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`81BZL20@0b2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL20B@91@010@40000E00030@000080 -9`T20@0^Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@81CZL20@0^ -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@819PT500410@0001D0 -00<100000P0Y2@8102X9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL20E:W -0P40:PVW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`81:0T500410@0001D0 -00<100000P0[2@8102JW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@81EZL20@0V -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T20BX91@010@40000E00810`090B@9 -0P4090VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90BBW4P4TY`0V0JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@4S2@X10`020@40000E00030@00008000UB2E89DPUB2E80 -2`4K2@8101nW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00816ZL;0@0B2:L8Y`RW2:L8Y`RW -2:L8Y`RW2`4JY`810209Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`816PT:0@09DPUB2E89 -DPUB00D00@4100005@000`400002000D2E89DPUB2E89DPUB2E89DPUB2E840AT90P406`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2@020ARW1040:0RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L40ARW0P407:L9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T20AP910404`UB2E89DPUB -2E89DPUB2E89DPT01@010@40000E00030@00008001QB2E89DPUB2E89DPUB2E89DPUB2E89DPT30AP9 -0P405jL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00815ZL40@0`Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80`4GY`8101P9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL20AH9 -10405e89DPUB2E89DPUB2E89DPUB2E89DPUB00D00@4100005@000`400002000K2E89DPUB2E89DPUB -2E89DPUB2E89DPUB2E8900@15PT20@0C2JL9Y`VW2JL9Y`VW2JL9Y`VW2@020AFW0`40=`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P0104EY`8101BW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2@815@T30@0K2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E8900D00@410000 -5@000`400002000ODPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP040A@901<12JL9Y`VW2JL9 -Y`VW2JL9Y`T101>W1040?PRW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW104CY`0D0JL9Y`VW2JL9Y`VW2JL9Y`VW2@4C2@@101h9DPUB2E89DPUB -2E89DPUB2E89DPUB2E89DPUB2E8500410@0001D000<100000P008`UB2E89DPUB2E89DPUB2E89DPUB -2E89DPUB2E89DPUB2E8900814PT04`6W2JL9Y`VW2JL9Y`VW2JL9Y`404JL20@16Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2081 -4ZL04P6W2JL9Y`VW2JL9Y`VW2JL90A890P408U89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPT500410@0001D000<100000P050@0Q2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E810149 -01<12JL9Y`VW2JL9Y`VW2JL9Y`T1012W02812:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -2@408@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@0AY`0B0@VW2JL9Y`VW2JL9Y`VW2JL1 -4@T08@49DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP050@@00@4100005@000`40000200EB -2@4060UB2E89DPUB2E89DPUB2E89DPUB2E890A4901<1Y`VW2JL9Y`VW2JL9Y`VW2JL1012W01P1Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L:0@T82@4060RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80A6W0181Y`VW -2JL9Y`VW2JL9Y`VW2@4A2@0H0E89DPUB2E89DPUB2E89DPUB2E89DPUB2@44DPD00@4100005@000`40 -000200iB1@4050UB2E89DPUB2E89DPUB2E89DPT14@T04@6W2JL9Y`VW2JL9Y`VW2JL1012W01@1Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`D170P50@0D2:L8Y`RW2:L8Y`RW2:L8Y`RW204AY`0@0JL9Y`VW2JL9Y`VW -2JL90A4901@1DPUB2E89DPUB2E89DPUB2E89DPD13E8500410@0001D000<100000P0CDP8101=B2E89 -DPUB2E89DPUB2E89DPT1010901412JL9Y`VW2JL9Y`VW2JL90@0?Y`0C0JL8Y`RW2:L8Y`RW2:L8Y`RW -20020BH80P404jL8Y`RW2:L8Y`RW2:L8Y`RW20404:L04049Y`VW2JL9Y`VW2JL9Y`4@2@0C0E89DPUB -2E89DPUB2E89DPUB2@020A9B1@010@40000E00030@0000805E80505B2E89DPUB2E89DPUB2E89DPT1 -3`T04@6W2JL9Y`VW2JL9Y`VW2JL100jW01@1Y`RW2:L8Y`RW2:L8Y`RW2:L80BX801@1Y`RW2:L8Y`RW -2:L8Y`RW2:L80@nW0101Y`VW2JL9Y`VW2JL9Y`T13`T0505B2E89DPUB2E89DPUB2E89DPT155850041 -0@0001D000<100000P0FDP810149DPUB2E89DPUB2E89DPUB0@0?2@0A0@VW2JL9Y`VW2JL9Y`VW2@40 -3ZL04@48Y`RW2:L8Y`RW2:L8Y`RW0081;0P20@0A2:L8Y`RW2:L8Y`RW2:L8Y`403jL04049Y`VW2JL9 -Y`VW2JL9Y`4?2@0A0@UB2E89DPUB2E89DPUB2E800P4EDPD00@4100005@020@<065804P49DPUB2E89 -DPUB2E89DPUB0@l900l12JL9Y`VW2JL9Y`VW2@403ZL04P48Y`RW2:L8Y`RW2:L8Y`RW0C0801812:L8 -Y`RW2:L8Y`RW2:L8Y`4?Y`0>0@VW2JL9Y`VW2JL9Y`4?2@0B0@UB2E89DPUB2E89DPUB2E815e840081 -0@0001D000<100000P0IDP81011B2E89DPUB2E89DPUB2E813PT03`6W2JL9Y`VW2JL9Y`VW0@0=Y`0@ -0@RW2:L8Y`RW2:L8Y`RW20810JL8Y`RW2:L8Y`RW -2:L20AX81@4I208100h8Y`RW2:L8Y`RW2:L80@fW00h1Y`VW2JL9Y`VW2JL90@d900h1DPUB2E89DPUB -2E89DP816E830@@00@4100005@000`40000200030E8100@15e803`49DPUB2E89DPUB2E890@0<2@0? -0@VW2JL9Y`VW2JL9Y`T100^W00l1Y`RW2:L8Y`RW2:L8Y`405`P50@05200800P0104G200?0@RW2:L8 -Y`RW2:L8Y`P100bW00h12JL9Y`VW2JL9Y`VW0@`900l1DPUB2E89DPUB2E89DP405e840@03DP4000@0 -0@4100005@000`4000020007DP5B0E81DP050A=B0P403E89DPUB2E89DPUB2@4030T03@49Y`VW2JL9 -Y`VW2@402jL03@6W2:L8Y`RW2:L8Y`P00P4D20@100h800P0200800P0200800D14`P20@0=Y`RW2:L8 -Y`RW2:L80@0DP@100mB0E81DP5B0E81DP5B0E801@010@40000E00030@0000800181DP5B0E81DP5B -0E81DP5B0E830@mB00`12E89DPUB2E89DP4:2@0=0JL9Y`VW2JL9Y`VW0@09Y`0<0@RW2:L8Y`RW2:L1 -3PP20@0W200800P0200800P0200800P0200800P0200800P0200800P0200800813`P03048Y`RW2:L8 -Y`RW0@ZW00`1Y`VW2JL9Y`VW2@4:2@0<0@UB2E89DPUB2E813U830@0BDP5B0E81DP5B0E81DP5B0E81 -1@010@40000E00030@00008001EB0E81DP5B0E81DP5B0E81DP5B0E800P4>DP0<0@UB2E89DPUB2E81 -2PT02`6W2JL9Y`VW2JL100VW00d12:L8Y`RW2:L8Y`P100`80P40:`0800P0200800P0200800P02008 -00P0200800P0200800P0200800P020000P4>200<0@RW2:L8Y`RW2:L12ZL02P6W2JL9Y`VW2@4:2@0< -0@UB2E89DPUB2E813E820@0EDP5B0E81DP5B0E81DP5B0E81DP5B00D00@4100005@000`400002000F -0E81DP5B0E81DP5B0E81DP5B0E81DP<13580305B2E89DPUB2E890@X900/12JL9Y`VW2JL90@09Y`0< -0JL8Y`RW2:L8Y`P12`P20@0_200800P0200800P0200800P0200800P0200800P0200800P0200800P0 -200800P00P4<200<0JL8Y`RW2:L8Y`P12ZL02P49Y`VW2JL9Y`4:2@0<0E89DPUB2E89DPT12e830@0F -DP5B0E81DP5B0E81DP5B0E81DP5B0@D00@4100005@000`400002000IDP5B0E81DP5B0E81DP5B0E81 -DP5B0E81DP020@]B00`1DPUB2E89DPUB2@492@0;0JL9Y`VW2JL9Y`402:L03@6W2:L8Y`RW2:L8Y`40 -2PP0=040200800P0200800P0200800P0200800P0200800P0200800P0200800P0200800P020020@/8 -00`1Y`RW2:L8Y`RW2049Y`0:0JL9Y`VW2JL90@T900`1DPUB2E89DPUB2@4;DP0J0E81DP5B0E81DP5B -0E81DP5B0E81DP5B0E8500410@0001D000<100000P006P5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B -0P4:DP0<0@UB2E89DPUB2E812@T02`49Y`VW2JL9Y`T100RW00d12:L8Y`RW2:L8Y`P100X803L12008 -00P0200800P0200800P0200800P0200800P0200800P0200800P0200800P0200800P100X800`12:L8 -Y`RW2:L8Y`49Y`0:0@VW2JL9Y`VW0@T900`12E89DPUB2E89DP4;DP8101QB0E81DP5B0E81DP5B0E81 -DP5B0E81DP4500410@0001D00P43000LDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0@]B00/12E89 -DPUB2E890@092@0;0JL9Y`VW2JL9Y`402:L0306W2:L8Y`RW2:L80@X803P1200800P0200800P02008 -00P0200800P0200800P0200800P0200800P0200800P0200800P00@/800/12:L8Y`RW2:L80@09Y`0: -0JL9Y`VW2JL90@T900/1DPUB2E89DPUB0@0;DP8101UB0E81DP5B0E81DP5B0E81DP5B0E81DP5B00@0 -0P4100005@000`400002000M0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP402U80305B2E89DPUB -2E890@P900/12JL9Y`VW2JL90@08Y`0<0@RW2:L8Y`RW2:L12PP0>@40200800P0200800P0200800P0 -200800P0200800P0200800P0200800P0200800P0200800P00@0:200<0JL8Y`RW2:L8Y`P12:L02P49 -Y`VW2JL9Y`492@0;0@UB2E89DPUB2@402e806`5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0@050041 -0@0001D000<100000P020@0IDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@YB00`12E89DPUB2E89 -DP482@0;0JL9Y`VW2JL9Y`401jL03@48Y`RW2:L8Y`RW20402@P07040200800P0200800P0200800P0 -200800P020030@0K00P0200800P0200800P0200800P0200800P100X800`12:L8Y`RW2:L8Y`48Y`0: -0JL9Y`VW2JL90@P900`12E89DPUB2E89DP4:DP0J0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E830@@0 -0@4100005@000`40000200D101MB0E81DP5B0E81DP5B0E81DP5B0E81DP020@YB00/12E89DPUB2E89 -0@082@0;0@VW2JL9Y`VW2@401jL0306W2:L8Y`RW2:L80@X801X1200800P0200800P0200800P02008 -00P020810`020@0J200800P0200800P0200800P0200800P02049200<0JL8Y`RW2:L8Y`P12:L02P49 -Y`VW2JL9Y`482@0;0E89DPUB2E89DP402e820@0GDP5B0E81DP5B0E81DP5B0E81DP5B0E800`450041 -0@0001D000<100000P060@0HDP5B0E81DP5B0E81DP5B0E81DP5B0E812U802`5B2E89DPUB2E8100P9 -00/1Y`VW2JL9Y`VW0@07Y`0<0@RW2:L8Y`RW2:L12@P06@4800P0200800P0200800P0200800P02000 -0P47008101P0200800P0200800P0200800P02008004:200;0JL8Y`RW2:L8Y`402:L02P6W2JL9Y`VW -2@482@0;0@UB2E89DPUB2@402U820@0EDP5B0E81DP5B0E81DP5B0E81DP5B00H11@010@40000E0003 -0@0000802@405U81DP5B0E81DP5B0E81DP5B0E81DP49DP0;0@UB2E89DPUB2@4020T02`49Y`VW2JL9 -Y`T100NW00`1Y`RW2:L8Y`RW2049200F0@0800P0200800P0200800P0200800<12`020@0G200800P0 -200800P0200800P0200800402@P02`48Y`RW2:L8Y`P100RW00X12JL9Y`VW2JL120T02`5B2E89DPUB -2E8100YB01H1DP5B0E81DP5B0E81DP5B0E81DP5B1`4500410@0001D000<100000P0<0@0ADP5B0E81 -DP5B0E81DP5B0E800P4:DP0:0@UB2E89DPUB0@P900/1Y`VW2JL9Y`VW0@07Y`0;0@RW2:L8Y`RW2040 -2@P05@40200800P0200800P0200800P020020A000`4050P0200800P0200800P0200800P12@P02`6W -2:L8Y`RW2:L100RW00X1Y`VW2JL9Y`T120T02P49DPUB2E89DP4:DP0D0E81DP5B0E81DP5B0E81DP5B -0E8:0@D00@4100005@000`40000200d1015B0E81DP5B0E81DP5B0E81DP020@UB00/1DPUB2E89DPUB -0@082@0:0JL9Y`VW2JL90@NW00/1Y`RW2:L8Y`RW0@09200B0@P0200800P0200800P020080`4E0081 -01<0200800P0200800P0200800P100T800/1Y`RW2:L8Y`RW0@08Y`090JL9Y`VW2JL100P900X1DPUB -2E89DPT12U820@0?DP5B0E81DP5B0E81DP5B00d11@010@40000E00030@00008040404581DP5B0E81 -DP5B0E81DP49DP0;0@UB2E89DPUB2@4020T02@49Y`VW2JL90@07Y`0<0JL8Y`RW2:L8Y`P120P04@48 -00P0200800P0200800P000816P020@0A200800P0200800P0200800402@P02`48Y`RW2:L8Y`P100RW -00P12JL9Y`VW0@P900/1DPUB2E89DPUB0@09DP8100mB0E81DP5B0E81DP5B0E803P4500410@0001D0 -00<100000P0A0@0@DP5B0E81DP5B0E81DP5B0@UB00X12E89DPUB2E8120T02@6W2JL9Y`VW0@07Y`0; -0@RW2:L8Y`RW20402@P03`40200800P0200800P020020Ah00P40400800P0200800P020080048200; -0JL8Y`RW2:L8Y`402:L0206W2JL9Y`T120T02P49DPUB2E89DP4:DP0>0E81DP5B0E81DP5B0E8A0@D0 -0@4100005@000`40000201@100]B0E81DP5B0E81DP020@UB00X1DPUB2E89DPT120T02@49Y`VW2JL9 -0@07Y`0;0JL8Y`RW2:L8Y`4020P03P40200800P0200800P00P4R008100h800P0200800P020080@P8 -00/12:L8Y`RW2:L80@08Y`080@VW2JL9Y`482@0:0E89DPUB2E890@UB00h1DP5B0E81DP5B0E81DQ81 -1@010@40000E00030@0000805@402e81DP5B0E81DP5B008125802P49DPUB2E89DP482@090JL9Y`VW -2JL100NW00/12:L8Y`RW2:L80@08200>0@P0200800P02008004V000?0@P0200800P0200800P100P8 -00X12:L8Y`RW2:L12:L0206W2JL9Y`T120T02P49DPUB2E89DP49DP8100]B0E81DP5B0E81DP0C0@D0 -0@4100005@000`40000201H100aB0E81DP5B0E81DP49DP090@UB2E89DPT100P900T12JL9Y`VW2@40 -1jL02P6W2:L8Y`RW2048200>0@P0200800P02008004X000>0@P0200800P020080048200:0JL8Y`RW -2:L80@RW00P12JL9Y`VW0@P900T1DPUB2E89DP402E820@0;DP5B0E81DP5B0E80504500410@0001D0 -0P4301L100aB0E81DP5B0E81DP48DP0:0E89DPUB2E890@L900T1Y`VW2JL9Y`401jL02P48Y`RW2:L8 -Y`48200>0@0800P0200800P0204Y000>0@P0200800P020080047200;0@RW2:L8Y`RW20401jL0206W -2JL9Y`T120T02@49DPUB2E890@09DP0<0E81DP5B0E81DP5B5@4400810@0001D000<100000P0H0@09 -DP5B0E81DP5B008125802P49DPUB2E89DP472@090@VW2JL9Y`T100JW00/12:L8Y`RW2:L80@07200> -0@0800P0200800P0204Z000>0@0800P0200800P02047200;0JL8Y`RW2:L8Y`401jL02049Y`VW2JL1 -1`T02P49DPUB2E89DP48DP0<0E81DP5B0E81DP5B5P4500410@0001D000<100000P0I0@09DP5B0E81 -DP5B008125802@49DPUB2E890@072@090JL9Y`VW2JL100JW00X1Y`RW2:L8Y`P120P03@4800P02008 -00P02040;0003P40200800P0200800P11`P02P6W2:L8Y`RW2047Y`080JL9Y`VW2@472@090E89DPUB -2E8100UB0P402E81DP5B0E81DP0G0@D00@4100005@000`40000201X100YB0E81DP5B0E8125802@5B -2E89DPUB0@072@090@VW2JL9Y`T100JW00X12:L8Y`RW2:L11`P03@4800P0200800P02040;P003@40 -200800P0200800401`P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@090@UB2E89DPT100QB0P402E81 -DP5B0E81DP0H0@D00@4100005@000`40000201T100UB0E81DP5B0E800P48DP090@UB2E89DPT100L9 -00T1Y`VW2JL9Y`401ZL02P6W2:L8Y`RW2047200=0@0800P0200800P00@0^000=0@P0200800P02008 -0@07200:0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900T1DPUB2E89DP402580305B0E81DP5B0E81DQL1 -1@010@40000E00030@0000806P402U81DP5B0E81DP48DP090E89DPUB2E8100L900T12JL9Y`VW2@40 -1ZL02P48Y`RW2:L8Y`47200=0@P0200800P020080@0^000=0@0800P0200800P00@07200:0@RW2:L8 -Y`RW0@NW00P12JL9Y`VW0@L900T12E89DPUB2@4025820@09DP5B0E81DP5B01P11@010@40000E0003 -0@0000806@402E81DP5B0E81DP020@QB00T12E89DPUB2@401`T02@6W2JL9Y`VW0@06Y`0:0JL8Y`RW -2:L80@L800d100P0200800P0200102h000d1200800P0200800P100L800X1Y`RW2:L8Y`P11jL0206W -2JL9Y`T11`T02@5B2E89DPUB0@08DP0<0E81DP5B0E81DP5B5`4500410@0001D000<100000P0J0@0: -DP5B0E81DP5B0@QB00T1DPUB2E89DP401`T02@49Y`VW2JL90@06Y`0:0@RW2:L8Y`RW0@L800d12008 -00P0200800P102h000d100P0200800P0200100L800X12:L8Y`RW2:L11jL02049Y`VW2JL11`T02@49 -DPUB2E890@08DP8100UB0E81DP5B0E80604500410@0001D000<100000P0I0@09DP5B0E81DP5B0081 -25802@49DPUB2E890@072@090JL9Y`VW2JL100JW00X1Y`RW2:L8Y`P11`P03@40200800P020080040 -;P003@4800P0200800P020401`P02P6W2:L8Y`RW2047Y`080JL9Y`VW2@472@090E89DPUB2E8100QB -00`1DP5B0E81DP5B0E8G0@D00@4100005@000`40000201X100YB0E81DP5B0E8125802@5B2E89DPUB -0@072@090@VW2JL9Y`T100JW00X12:L8Y`RW2:L11`P03@4800P0200800P02040;P003@40200800P0 -200800401`P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@090@UB2E89DPT100QB0P402E81DP5B0E81 -DP0H0@D00@4100005@000`40000201T100UB0E81DP5B0E800P48DP090@UB2E89DPT100L900T1Y`VW -2JL9Y`401ZL02P6W2:L8Y`RW2047200=0@0800P0200800P00@0^000=0@P0200800P020080@07200: -0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900T1DPUB2E89DP402580305B0E81DP5B0E81DQL11@010@40 -0002008110000`40000200<11@000`40000201X100YB0E81DP5B0E8125802@5B2E89DPUB0@072@09 -0@VW2JL9Y`T100JW00X12:L8Y`RW2:L11`P03@4800P0200800P02040;P003@40200800P020080040 -1`P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@090@UB2E89DPT100QB0P402E81DP5B0E81DP0H0@D0 -0@41000000D00@000@0;00030@0000800P4301T100UB0E81DP5B0E800P48DP090@UB2E89DPT100L9 -00T1Y`VW2JL9Y`401ZL02P6W2:L8Y`RW2047200=0@0800P0200800P00@0^000=0@P0200800P02008 -0@07200:0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900T1DPUB2E89DP402580305B0E81DP5B0E81DQL1 -10020@4000001@01000100/000<100000P000`40000201X100YB0E81DP5B0E8125802@5B2E89DPUB -0@072@090@VW2JL9Y`T100JW00X12:L8Y`RW2:L11`P03@4800P0200800P02040;P003@40200800P0 -200800401`P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@090@UB2E89DPT100QB0P402E81DP5B0E81 -DP0H0@D00@41000000D00@000@0800<11@000`40000201T100UB0E81DP5B0E800P48DP090@UB2E89 -DPT100L900T1Y`VW2JL9Y`401ZL02P6W2:L8Y`RW2047200=0@0800P0200800P00@0^000=0@P02008 -00P020080@07200:0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900T1DPUB2E89DP402580305B0E81DP5B -0E81DQL11@010@4000001@01000100P000<100001@000`40000201X100YB0E81DP5B0E8125802@5B -2E89DPUB0@072@090@VW2JL9Y`T100JW00X12:L8Y`RW2:L11`P03@4800P0200800P02040;P003@40 -200800P0200800401`P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@090@UB2E89DPT100QB0P402E81 -DP5B0E81DP0H0@D00@41000000D00@000@0800030@0000D000<100000P0I0@09DP5B0E81DP5B0081 -25802@49DPUB2E890@072@090JL9Y`VW2JL100JW00X1Y`RW2:L8Y`P11`P03@40200800P020080040 -;P003@4800P0200800P020401`P02P6W2:L8Y`RW2047Y`080JL9Y`VW2@472@090E89DPUB2E8100QB -00`1DP5B0E81DP5B0E8G0@D00@4100000P020@T0104400030@0000806P402U81DP5B0E81DP48DP09 -0E89DPUB2E8100L900T12JL9Y`VW2@401ZL02P48Y`RW2:L8Y`47200=0@P0200800P020080@0^000= -0@0800P0200800P00@07200:0@RW2:L8Y`RW0@NW00P12JL9Y`VW0@L900T12E89DPUB2@4025820@09 -DP5B0E81DP5B01P11@010@40000E00030@0000806@402E81DP5B0E81DP020@QB00T12E89DPUB2@40 -1`T02@6W2JL9Y`VW0@06Y`0:0JL8Y`RW2:L80@L800d100P0200800P0200102h000d1200800P02008 -00P100L800X1Y`RW2:L8Y`P11jL0206W2JL9Y`T11`T02@5B2E89DPUB0@08DP0<0E81DP5B0E81DP5B -5`4500410@0001D000<100000P0J0@0:DP5B0E81DP5B0@QB00T1DPUB2E89DP401`T02@49Y`VW2JL9 -0@06Y`0:0@RW2:L8Y`RW0@L800d1200800P0200800P102h000d100P0200800P0200100L800X12:L8 -Y`RW2:L11jL02049Y`VW2JL11`T02@49DPUB2E890@08DP8100UB0E81DP5B0E80604500410@0001D0 -00<100000P0I0@09DP5B0E81DP5B008125802@49DPUB2E890@072@090JL9Y`VW2JL100JW00X1Y`RW -2:L8Y`P11`P03@40200800P020080040;P003@4800P0200800P020401`P02P6W2:L8Y`RW2047Y`08 -0JL9Y`VW2@472@090E89DPUB2E8100QB00`1DP5B0E81DP5B0E8G0@D00@4100005@000`40000201X1 -00YB0E81DP5B0E8125802@5B2E89DPUB0@072@090@VW2JL9Y`T100JW00X12:L8Y`RW2:L11`P03@48 -00P0200800P02040;P003@40200800P0200800401`P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@09 -0@UB2E89DPT100QB0P402E81DP5B0E81DP0H0@D00@4100005@000`40000201T100UB0E81DP5B0E80 -0P48DP090@UB2E89DPT100L900T1Y`VW2JL9Y`401ZL02P6W2:L8Y`RW2047200>0@0800P0200800P0 -204/000>0@0800P0200800P02047200:0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900T1DPUB2E89DP40 -2580305B0E81DP5B0E81DQL11@010@40000E00030@00008060402E81DP5B0E81DP020@QB00X12E89 -DPUB2E811`T02@49Y`VW2JL90@06Y`0;0@RW2:L8Y`RW20401`P03@40200800P020080040;0003@48 -00P0200800P020401`P02`6W2:L8Y`RW2:L100NW00P12JL9Y`VW0@L900X12E89DPUB2E812580305B -0E81DP5B0E81DQH11@010@40000E00030@0000805`403581DP5B0E81DP5B0@QB00X1DPUB2E89DPT1 -1`T02@6W2JL9Y`VW0@06Y`0;0JL8Y`RW2:L8Y`401`P03P4800P0200800P02001:P003P4800P02008 -00P020011`P02`48Y`RW2:L8Y`P100NW00P1Y`VW2JL90@L900X1DPUB2E89DPT125820@0;DP5B0E81 -DP5B0E805@4500410@0001D00P4301H100aB0E81DP5B0E81DP49DP090@UB2E89DPT100P900T12JL9 -Y`VW2@401jL02P6W2:L8Y`RW2048200>0@P0200800P02008004X000>0@P0200800P020080048200: -0JL8Y`RW2:L80@RW00P12JL9Y`VW0@P900T1DPUB2E89DP402E820@0;DP5B0E81DP5B0E8050440081 -0@0001D000<100000P0E0@0;DP5B0E81DP5B0E800P48DP0:0@UB2E89DPUB0@P900T1Y`VW2JL9Y`40 -1jL02`48Y`RW2:L8Y`P100L800l100P0200800P0200800409P003`4800P0200800P020080@08200: -0@RW2:L8Y`RW0@RW00P1Y`VW2JL90@P900X12E89DPUB2E8125803P5B0E81DP5B0E81DP5B4`450041 -0@0001D000<100000P0D0@0;DP5B0E81DP5B0E800P49DP0:0E89DPUB2E890@P900T12JL9Y`VW2@40 -1jL02`6W2:L8Y`RW2:L100P800h100P0200800P020080BH000h100P0200800P020080@P800/12:L8 -Y`RW2:L80@08Y`080@VW2JL9Y`482@0:0E89DPUB2E890@UB00`1DP5B0E81DP5B0E8D0@D00@410000 -5@000`40000201<100iB0E81DP5B0E81DP5B0@UB00X12E89DPUB2E8120T02@6W2JL9Y`VW0@07Y`0; -0@RW2:L8Y`RW204020P03P4800P0200800P020080P4R008100h0200800P0200800P00@P800/1Y`RW -2:L8Y`RW0@08Y`080JL9Y`VW2@482@0:0@UB2E89DPUB0@UB0P402e81DP5B0E81DP5B01<11@010@40 -000E00030@0000804P403U81DP5B0E81DP5B0E812E802`49DPUB2E89DPT100P900T12JL9Y`VW2@40 -1jL0306W2:L8Y`RW2:L80@P800l1200800P0200800P020000P4N008100l800P0200800P020080040 -2@P02`48Y`RW2:L8Y`P100RW00P12JL9Y`VW0@P900/1DPUB2E89DPUB0@09DP8100eB0E81DP5B0E81 -DP5B01011@010@40000E00030@0000803`403e81DP5B0E81DP5B0E81DP020@UB00/1DPUB2E89DPUB -0@082@090JL9Y`VW2JL100NW00`12:L8Y`RW2:L8Y`48200A0@0800P0200800P0200800P00P4J0081 -0140200800P0200800P020080@09200;0JL8Y`RW2:L8Y`402:L0206W2JL9Y`T120T02`49DPUB2E89 -DPT100UB0101DP5B0E81DP5B0E81DP5B3`4500410@0001D000<100000P0>0@0?DP5B0E81DP5B0E81 -DP5B00812U802P49DPUB2E89DP482@0;0JL9Y`VW2JL9Y`401jL02`48Y`RW2:L8Y`P100T8018100P0 -200800P0200800P020030AD00P404PP0200800P0200800P020080@T800/1Y`RW2:L8Y`RW0@08Y`0: -0JL9Y`VW2JL90@P900X12E89DPUB2E812U804P5B0E81DP5B0E81DP5B0E81DP`11@010@40000E0003 -0@0000802`405581DP5B0E81DP5B0E81DP5B0E812U802P5B2E89DPUB2@482@0;0@VW2JL9Y`VW2@40 -1jL02`6W2:L8Y`RW2:L100T801D1200800P0200800P0200800P020000P4@00<101@0200800P02008 -00P0200800P00@T800/12:L8Y`RW2:L80@08Y`0:0@VW2JL9Y`VW0@P900X1DPUB2E89DPT12U820@0A -DP5B0E81DP5B0E81DP5B0E802`4500410@0001D000<100000P080@0FDP5B0E81DP5B0E81DP5B0E81 -DP5B0@YB00/1DPUB2E89DPUB0@082@0;0JL9Y`VW2JL9Y`401jL03048Y`RW2:L8Y`RW0@T801H12008 -00P0200800P0200800P020080`4;008101H0200800P0200800P0200800P020012PP02`6W2:L8Y`RW -2:L100RW00X1Y`VW2JL9Y`T120T02`49DPUB2E89DPT100YB0P404e81DP5B0E81DP5B0E81DP5B0E80 -204500410@0001D000<100000P070@0EDP5B0E81DP5B0E81DP5B0E81DP5B00812U802`49DPUB2E89 -DPT100P900/12JL9Y`VW2JL90@07Y`0<0JL8Y`RW2:L8Y`P12@P06@40200800P0200800P0200800P0 -200800P00P47008101P800P0200800P0200800P0200800P0204:200;0@RW2:L8Y`RW20402:L02P49 -Y`VW2JL9Y`482@0;0E89DPUB2E89DP402U80605B0E81DP5B0E81DP5B0E81DP5B0E81DPD11@010@40 -000E00030@00008010405e81DP5B0E81DP5B0E81DP5B0E81DP5B00812e802`5B2E89DPUB2E8100P9 -00/1Y`VW2JL9Y`VW0@07Y`0<0@RW2:L8Y`RW2:L12PP06P40200800P0200800P0200800P0200800P0 -0P43008101T0200800P0200800P0200800P0200800P100X800`12:L8Y`RW2:L8Y`48Y`0:0JL9Y`VW -2JL90@P900/12E89DPUB2E890@0;DP0H0E81DP5B0E81DP5B0E81DP5B0E81DP5B104500410@0001D0 -00<100000P030@0JDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP4:DP0<0E89DPUB2E89DPT120T02`49 -Y`VW2JL9Y`T100NW00d1Y`RW2:L8Y`RW2:L100T801`1200800P0200800P0200800P0200800P02008 -0`406`P0200800P0200800P0200800P0200800P00@0:200<0JL8Y`RW2:L8Y`P12:L02P49Y`VW2JL9 -Y`482@0<0E89DPUB2E89DPT12U820@0IDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@@00@410000 -5@000`400002000LDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0@]B00/12E89DPUB2E890@092@0; -0JL9Y`VW2JL9Y`402:L0306W2:L8Y`RW2:L80@X803P1200800P0200800P0200800P0200800P02008 -00P0200800P0200800P0200800P0200800P00@/800/12:L8Y`RW2:L80@09Y`0:0JL9Y`VW2JL90@T9 -00/1DPUB2E89DPUB0@0;DP8101UB0E81DP5B0E81DP5B0E81DP5B0E81DP5B00D00@4100005@020@<0 -01X1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP812e802`5B2E89DPUB2E8100T900/12JL9Y`VW2JL9 -0@08Y`0<0@RW2:L8Y`RW2:L12PP0>040200800P0200800P0200800P0200800P0200800P0200800P0 -200800P0200800P0200800P12`P02`6W2:L8Y`RW2:L100VW00X12JL9Y`VW2JL12@T02`49DPUB2E89 -DPT100]B01/1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP4010020@40000E00030@00008001UB0E81 -DP5B0E81DP5B0E81DP5B0E81DP5B00812e80305B2E89DPUB2E890@T900/1Y`VW2JL9Y`VW0@08Y`0= -0JL8Y`RW2:L8Y`RW0@0:200f0@0800P0200800P0200800P0200800P0200800P0200800P0200800P0 -200800P0200800P12`P0306W2:L8Y`RW2:L80@VW00X1Y`VW2JL9Y`T12@T0305B2E89DPUB2E890@]B -01X1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DPD00@4100005@000`400002000H0E81DP5B0E81DP5B -0E81DP5B0E81DP5B0`4;DP0<0@UB2E89DPUB2E812@T02`49Y`VW2JL9Y`T100RW00d12:L8Y`RW2:L8 -Y`P100X803@1200800P0200800P0200800P0200800P0200800P0200800P0200800P0200800P02008 -0P4;200<0@RW2:L8Y`RW2:L12JL02P49Y`VW2JL9Y`492@0<0@UB2E89DPUB2E812e820@0HDP5B0E81 -DP5B0E81DP5B0E81DP5B0E811@010@40000E00030@00008001MB0E81DP5B0E81DP5B0E81DP5B0E81 -DP020@aB00`12E89DPUB2E89DP4:2@0;0JL9Y`VW2JL9Y`402JL03@48Y`RW2:L8Y`RW20402PP20@0_ -00P0200800P0200800P0200800P0200800P0200800P0200800P0200800P020000P4<200<0@RW2:L8 -Y`RW2:L12ZL02P6W2JL9Y`VW2@4:2@0<0@UB2E89DPUB2E812e820@0GDP5B0E81DP5B0E81DP5B0E81 -DP5B0E801@010@40000E00030@00008001@1DP5B0E81DP5B0E81DP5B0E81DP<13E803049DPUB2E89 -DPUB0@/900/12JL9Y`VW2JL90@0:Y`0<0@RW2:L8Y`RW2:L130P20@0[200800P0200800P0200800P0 -200800P0200800P0200800P0200800P020020@d800`12:L8Y`RW2:L8Y`4;Y`0:0@VW2JL9Y`VW0@/9 -00`12E89DPUB2E89DP40E89DPUB2E89DPUB2@4=DPD100iB0E81DP5B0E81DP5B0@D00@4100005@000`40 -0002000;DP5B0E81DP5B0E801@4@DP0>0E89DPUB2E89DPUB2@4<2@0=0@VW2JL9Y`VW2JL90@0;Y`0> -0JL8Y`RW2:L8Y`RW204@20D101L800P0200800P0200800P0200800P020040A0800h1Y`RW2:L8Y`RW -2:L80@bW00`12JL9Y`VW2JL9Y`4<2@0>0E89DPUB2E89DPUB2@4@DP@100]B0E81DP5B0E81DP050041 -0@0001D000<100000P001P5B0E81DPH14U820@0=DPUB2E89DPUB2E890@0=2@0=0JL9Y`VW2JL9Y`VW -0@02@0?0JL9Y`VW -2JL9Y`VW2JL100fW00l12:L8Y`RW2:L8Y`RW2:L00P4d200A0JL8Y`RW2:L8Y`RW2:L8Y`403ZL03P6W -2JL9Y`VW2JL9Y`T13PT03`49DPUB2E89DPUB2E89DP020AUB1@010@40000E00030@0000806E804@5B -2E89DPUB2E89DPUB2E8100l900l12JL9Y`VW2JL9Y`VW2@403ZL04@48Y`RW2:L8Y`RW2:L8Y`P10388 -0141Y`RW2:L8Y`RW2:L8Y`RW0@0?Y`0>0@VW2JL9Y`VW2JL9Y`4?2@0A0@UB2E89DPUB2E89DPUB2@40 -658500410@0001D00P4301MB0P404E89DPUB2E89DPUB2E89DPT100l900l1Y`VW2JL9Y`VW2JL9Y`40 -3ZL04@6W2:L8Y`RW2:L8Y`RW2:L80081;PP20@0AY`RW2:L8Y`RW2:L8Y`RW20403jL03P6W2JL9Y`VW -2JL9Y`T13`T04@5B2E89DPUB2E89DPUB2E8900815U8400810@0001D000<100000P0FDP0C0@UB2E89 -DPUB2E89DPUB2E890@0?2@0A0JL9Y`VW2JL9Y`VW2JL9Y`403ZL04`6W2:L8Y`RW2:L8Y`RW2:L8Y`40 -;0P04`48Y`RW2:L8Y`RW2:L8Y`RW20403jL0406W2JL9Y`VW2JL9Y`VW2@4?2@0C0E89DPUB2E89DPUB -2E89DPUB0@0EDPD00@4100005@000`40000201EB01<12E89DPUB2E89DPUB2E89DPT1010901412JL9 -Y`VW2JL9Y`VW2JL90@0?Y`0C0JL8Y`RW2:L8Y`RW2:L8Y`RW0@0Z200C0@RW2:L8Y`RW2:L8Y`RW2:L8 -0@0@Y`0@0@VW2JL9Y`VW2JL9Y`VW0A0901<1DPUB2E89DPUB2E89DPUB2E8101AB1@010@40000E0003 -0@0000804e820@0B2E89DPUB2E89DPUB2E89DPT14@T04@6W2JL9Y`VW2JL9Y`VW2JL1012W0181Y`RW -2:L8Y`RW2:L8Y`RW2:L20BH80P404PRW2:L8Y`RW2:L8Y`RW2:L80A6W0101Y`VW2JL9Y`VW2JL9Y`T1 -4@T04P5B2E89DPUB2E89DPUB2E89DP814U8500410@0001D000<100000P0>DPD101AB2E89DPUB2E89 -DPUB2E89DPUB0A4901412JL9Y`VW2JL9Y`VW2JL90@0@Y`0D0@RW2:L8Y`RW2:L8Y`RW2:L8Y`P50A`8 -1@405:L8Y`RW2:L8Y`RW2:L8Y`RW2:L14JL04049Y`VW2JL9Y`VW2JL9Y`4A2@0D0@UB2E89DPUB2E89 -DPUB2E89DPT50@eB1@010@40000E00030@0000801E890@0HDPUB2E89DPUB2E89DPUB2E89DPUB2E81 -4@T04`49Y`VW2JL9Y`VW2JL9Y`VW2@404:L06048Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20X12@P90@0H -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L14JL04P49Y`VW2JL9Y`VW2JL9Y`VW0A4901P12E89DPUB2E89 -DPUB2E89DPUB2E89DPT90@AB1@010@40000E00030@0000801@408589DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E814PT04`6W2JL9Y`VW2JL9Y`VW2JL9Y`404JL08@48Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`090@0PY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`4BY`0B0JL9Y`VW -2JL9Y`VW2JL9Y`T14PT08049DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E891@4400410@0001D0 -00<100000P008e89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB00814PT04`49Y`VW2JL9 -Y`VW2JL9Y`VW2@404JL20@162:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`814ZL04P49Y`VW2JL9Y`VW2JL9Y`VW0A890P408PUB -2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E8500410@0001D000<100000P007`UB2E89DPUB -2E89DPUB2E89DPUB2E89DPUB2E89DPT0104D2@0C0JL9Y`VW2JL9Y`VW2JL9Y`VW0@0CY`@103jW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20@1 -4jL05049Y`VW2JL9Y`VW2JL9Y`VW2JL14`T40@0NDPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -1@010@40000E00030@00008001]B2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E80104F2@8101>W2JL9 -Y`VW2JL9Y`VW2JL9Y`VW00815JL30@0gY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`040AFW0P4050VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0P4E2@<101]B2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E801@010@40000E00030@00008001P9DPUB2E89DPUB2E89DPUB -2E89DPUB2E830AP90P405`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900815ZL40@0`2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0`4GY`8101RW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`T20AH910405`UB2E89DPUB2E89DPUB2E89DPUB2E8900D00@4100005@000`400002000D -DPUB2E89DPUB2E89DPUB2E89DPT40AT90P407:L9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4IY`@1 -02RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8104IY`0N0@VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL16@T40@0CDPUB2E89DPUB2E89DPUB2E89DP0500410@0001D00P43000> -2E89DPUB2E89DPUB2E860A`901l12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00816jL60@0L -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`H16jL20@0N2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW0P4K2@H100d9DPUB2E89DPUB2E8900@00P4100005@000`4000020005DPUB2E802@4P2@81 -0289Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T18:L:0@09Y`RW2:L8Y`RW00T17jL20@0S -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@4080T90@042E89DPD00@4100005@000`40 -000200D19`T20@0TY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90P4XY`T19jL09P49 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90P4W2@D110010@40000E00030@000080 -:`T0:@49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0081E:L20@0X2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`81:@T500410@0001D000<100000P0Y2@81 -02`9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90E:W02h1Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T1:0T500410@0001D000<100000P0W2@81 -02jW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90P5>Y`8102jW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90P4V2@D00@4100005@000`40 -000202D90P40W2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`020A:W01<12JL9Y`VW2JL9 -Y`VW2JL9Y`T101490P40APUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB -2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E820A490P4040VW2JL9Y`VW2JL9Y`VW2JL20A6W0P408PRW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L500410@0001D000<100000P009@RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`404ZL04`6W2JL9Y`VW2JL9Y`VW2JL9Y`404@T0BP49 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E814PT04P6W2JL9Y`VW2JL9Y`VW2JL90A:W02@12:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`P500410@0001D000<100000P050@0Q2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L1016W01<12JL9Y`VW2JL9Y`VW2JL9Y`T1010902812E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E892@408@UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB0@0A2@0B0@VW2JL9 -Y`VW2JL9Y`VW2JL14JL08@48Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`050@@00@410000 -5@000`40000200D82@4060RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80A:W01412JL9Y`VW2JL9Y`VW2JL9 -0@0A2@0H0E89DPUB2E89DPUB2E89DPUB2E89DPUB2P49DPT101P9DPUB2E89DPUB2E89DPUB2E89DPUB -2@4B2@0@0@VW2JL9Y`VW2JL9Y`VW0A:W01P1Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L90@@81@010@40 -000E00030@0000803PP50@0D2:L8Y`RW2:L8Y`RW2:L8Y`RW204AY`0A0JL9Y`VW2JL9Y`VW2JL9Y`40 -40T0505B2E89DPUB2E89DPUB2E89DPUB1@4LDPD101@9DPUB2E89DPUB2E89DPUB2E890A490101Y`VW -2JL9Y`VW2JL9Y`T14JL0506W2:L8Y`RW2:L8Y`RW2:L8Y`RW1@4=20D00@4100005@000`40000201<8 -0P404jL8Y`RW2:L8Y`RW2:L8Y`RW20404:L04@49Y`VW2JL9Y`VW2JL9Y`T100l901<1DPUB2E89DPUB -2E89DPUB2E8900819U820@0CDPUB2E89DPUB2E89DPUB2E890@0@2@0@0@VW2JL9Y`VW2JL9Y`VW0A2W -01<1Y`RW2:L8Y`RW2:L8Y`RW2:L800814PP500410@0001D000<100000P0E200D0JL8Y`RW2:L8Y`RW -2:L8Y`RW204?Y`0A0JL9Y`VW2JL9Y`VW2JL9Y`403PT0505B2E89DPUB2E89DPUB2E89DPT1:U80505B -2E89DPUB2E89DPUB2E89DPT13`T0406W2JL9Y`VW2JL9Y`VW2@4?Y`0D0JL8Y`RW2:L8Y`RW2:L8Y`RW -204D20D00@4100005@000`40000201H80P404@RW2:L8Y`RW2:L8Y`RW2:L100nW01412JL9Y`VW2JL9 -Y`VW2JL90@0>2@0A0@UB2E89DPUB2E89DPUB2E800P4/DP810149DPUB2E89DPUB2E89DPUB0@0?2@0@ -0@VW2JL9Y`VW2JL9Y`VW0@nW01412:L8Y`RW2:L8Y`RW2:L8Y`020AD81@010@40000E00810`0H200B -0@RW2:L8Y`RW2:L8Y`RW2:L13jL03`49Y`VW2JL9Y`VW2JL90@0>2@0B0@UB2E89DPUB2E89DPUB2E81 -<5804P49DPUB2E89DPUB2E89DPUB0@l900h12JL9Y`VW2JL9Y`VW0@nW01812:L8Y`RW2:L8Y`RW2:L8 -Y`4G20@00P4100005@000`40000201T80P404:L8Y`RW2:L8Y`RW2:L8Y`4>Y`0?0JL9Y`VW2JL9Y`VW -2JL100d901012E89DPUB2E89DPUB2E890P4bDP81011B2E89DPUB2E89DPUB2E813PT03P6W2JL9Y`VW -2JL9Y`T13ZL04048Y`RW2:L8Y`RW2:L8Y`P20AP81@010@40000E00030@0000800P4I200A0JL8Y`RW -2:L8Y`RW2:L8Y`403JL03`49Y`VW2JL9Y`VW2JL90@0=2@0@0E89DPUB2E89DPUB2E890AYB0`4IDP0A -0E89DPUB2E89DPUB2E89DP403@T03P49Y`VW2JL9Y`VW2JL13ZL0406W2:L8Y`RW2:L8Y`RW204I2081 -10010@40000E00030@0000<000<80@400P4F208100h8Y`RW2:L8Y`RW2:L80@fW00l1Y`VW2JL9Y`VW -2JL9Y`4030T03P5B2E89DPUB2E89DPUB0P4GDPD100=B0@400`4FDP8100h9DPUB2E89DPUB2E890@d9 -00h1Y`VW2JL9Y`VW2JL90@fW00h1Y`RW2:L8Y`RW2:L8Y`815PP40@H00@4100005@000`4000020006 -200800P00`4E200?0@RW2:L8Y`RW2:L8Y`P100fW00d1Y`VW2JL9Y`VW2JL100`900l1DPUB2E89DPUB -2E89DP405E840@0;DP5B0E81DP5B0E800`4EDP0?0@UB2E89DPUB2E89DPT100d900`1Y`VW2JL9Y`VW -2@4=Y`0?0JL8Y`RW2:L8Y`RW2:L101@810401@P0200800D00@4100005@000`4000030008200800P0 -20040A880P403JL8Y`RW2:L8Y`RW20403:L03@49Y`VW2JL9Y`VW2@402`T03@5B2E89DPUB2E89DPT0 -0P4BDPD1015B0E81DP5B0E81DP5B0E81DP040A9B0P403E89DPUB2E89DPUB2@4030T03049Y`VW2JL9 -Y`VW0@bW00d1Y`RW2:L8Y`RW2:L800814PP30@0800P0200800P600410@0001D000<100000P003@P0 -200800P0200800P0104@200=0JL8Y`RW2:L8Y`RW0@0208101<800P0200800P0200800P0200800D00@410000 -5@000`400003000D200800P0200800P0200800P020020@h800`12:L8Y`RW2:L8Y`4:Y`0;0JL9Y`VW -2JL9Y`402@T03@49DPUB2E89DPUB2@4035820@0[DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81 -DP5B0E81DP5B0E81DP020@iB00`12E89DPUB2E89DP4:2@0:0JL9Y`VW2JL90@ZW00`12:L8Y`RW2:L8 -Y`4=208101@0200800P0200800P0200800P020H00@4100005@000`400002000G200800P0200800P0 -200800P0200800P00P4<200<0JL8Y`RW2:L8Y`P12ZL02`49Y`VW2JL9Y`T100T900`1DPUB2E89DPUB -2@4;DP<102eB0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E800`40@P02008 -00P02008004G00410@0001D00P4G000>0@P0200800P02008004920090@RW2:L8Y`P100RW00T12JL9 -Y`VW2@401`T02P5B2E89DPUB2@48DP8100]B0E81DP5B0E81DP0[0@00@P0200800P020080048200:0JL8Y`RW2:L80@NW00T1Y`VW2JL9Y`401`T02P49 -DPUB2E89DP48DP0<0E81DP5B0E81DP5B;@403581DP5B0E81DP5B0@MB00/12E89DPUB2E890@072@08 -0JL9Y`VW2@48Y`090@RW2:L8Y`P100T800h100P0200800P020080AP00@4100005@000`40000H000= -0@P0200800P020080@08200:0@RW2:L8Y`RW0@NW00T12JL9Y`VW2@401PT02`49DPUB2E89DPT100MB -00`1DP5B0E81DP5B0E8]0@0;DP5B0E81DP5B0E800P47DP0;0E89DPUB2E89DP401`T02049Y`VW2JL1 -1jL02P48Y`RW2:L8Y`48200>0@0800P0200800P0204I00410@0001D000<100006@003@4800P02008 -00P0204020P02@48Y`RW2:L80@07Y`090JL9Y`VW2JL100H900X1DPUB2E89DPT125820@09DP5B0E81 -DP5B02l100]B0E81DP5B0E81DP020@MB00X1DPUB2E89DPT11`T0206W2JL9Y`T11jL02@6W2:L8Y`RW -0@09200=0@P0200800P020080@0J00410@0001D000<100006P00304800P0200800P00@P800T1Y`RW -2:L8Y`401jL02@49Y`VW2JL90@062@0:0@UB2E89DPUB0@MB0P402E81DP5B0E81DP0a0@00@0800P0200800P0204I00410@0001D000<100005`003P48 -00P0200800P0200120P02P6W2:L8Y`RW2047Y`090JL9Y`VW2JL100L900X12E89DPUB2E812580305B -0E81DP5B0E81DRd100aB0E81DP5B0E81DP47DP0;0@UB2E89DPUB2@401`T0206W2JL9Y`T12:L02@48 -Y`RW2:L80@09200>0@0800P0200800P0204H00410@0001D00P4G000>0@P0200800P0200800492009 -0@RW2:L8Y`P100RW00T12JL9Y`VW2@401`T02P5B2E89DPUB2@48DP8100]B0E81DP5B0E81DP0[0@0< -DP5B0E81DP5B0E8125802P5B2E89DPUB2@482@080@VW2JL9Y`48Y`090JL8Y`RW2:L100T800h12008 -00P0200800P00AL00P4100005@000`40000E000?0@P0200800P0200800P100P800X12:L8Y`RW2:L1 -2:L02@6W2JL9Y`VW0@072@0;0@UB2E89DPUB2@4025820@0;DP5B0E81DP5B0E80:@402e81DP5B0E81 -DP5B008125802P49DPUB2E89DP482@080JL9Y`VW2@48Y`0:0@RW2:L8Y`RW0@T800h1200800P02008 -00P00AL00@4100005@000`40000C008100h800P0200800P020080@T800X1Y`RW2:L8Y`P12:L02@49 -Y`VW2JL90@072@0;0E89DPUB2E89DP4025803P5B0E81DP5B0E81DP5B9`402e81DP5B0E81DP5B0081 -25802`49DPUB2E89DPT100P900P12JL9Y`VW0@RW00X1Y`RW2:L8Y`P12@P03P40200800P0200800P0 -0P4E00410@0001D000<100004@020@0@00P0200800P0200800P00@T800X12:L8Y`RW2:L12:L02@6W -2JL9Y`VW0@072@0;0@UB2E89DPUB2@402E803P5B0E81DP5B0E81DP5B8`404581DP5B0E81DP5B0E81 -DP48DP0;0E89DPUB2E89DP4020T0206W2JL9Y`T12:L02P48Y`RW2:L8Y`4:200?0@0800P0200800P0 -200800814`010@40000E00030@0000l00P404@P0200800P0200800P0200100T800/12:L8Y`RW2:L8 -0@08Y`090@VW2JL9Y`T100L900`1DPUB2E89DPUB2@48DP8100mB0E81DP5B0E81DP5B0E807`404581 -DP5B0E81DP5B0E81DP49DP0;0@UB2E89DPUB2@4020T02049Y`VW2JL12:L02`6W2:L8Y`RW2:L100T8 -0141200800P0200800P0200800020A400@4100005@000`40000=008101<0200800P0200800P02008 -00P100T800/1Y`RW2:L8Y`RW0@08Y`0:0JL9Y`VW2JL90@L900/1DPUB2E89DPUB0@09DP8100mB0E81 -DP5B0E81DP5B0E806`404E81DP5B0E81DP5B0E81DP5B00812E802`5B2E89DPUB2E8100P900T1Y`VW -2JL9Y`402:L02P6W2:L8Y`RW204:200B0@P0200800P0200800P020080P4?00410@0001D000<10000 -2P030@0D200800P0200800P0200800P0204:200:0@RW2:L8Y`RW0@RW00/1Y`VW2JL9Y`VW0@072@0; -0@UB2E89DPUB2@402E80505B0E81DP5B0E81DP5B0E81DP5B5`404E81DP5B0E81DP5B0E81DP5B0081 -2E802`5B2E89DPUB2E8100P900X1Y`VW2JL9Y`T12:L02P48Y`RW2:L8Y`4:200D0@0800P0200800P0 -200800P020030@`00@4100005@000`400008008101L800P0200800P0200800P0200800P00@09200; -0@RW2:L8Y`RW20402:L02`49Y`VW2JL9Y`T100L900`1DPUB2E89DPUB2@49DP0F0E81DP5B0E81DP5B -0E81DP5B0E81DQ4101IB0E81DP5B0E81DP5B0E81DP5B0E812E802`49DPUB2E89DPT100P900X12JL9 -Y`VW2JL12:L02`6W2:L8Y`RW2:L100X801H100P0200800P0200800P0200800P00P4:00410@0001D0 -00<100001P020@0H00P0200800P0200800P0200800P020012PP02`6W2:L8Y`RW2:L100RW00/1Y`VW -2JL9Y`VW0@072@0<0@UB2E89DPUB2E812E820@0GDP5B0E81DP5B0E81DP5B0E81DP5B0E802`406581 -DP5B0E81DP5B0E81DP5B0E81DP5B0@YB00/1DPUB2E89DPUB0@082@0:0JL9Y`VW2JL90@RW00/12:L8 -Y`RW2:L80@0:200H0@P0200800P0200800P0200800P020080P4800410@0001D000<1000010020@0J -200800P0200800P0200800P0200800P0204:200;0@RW2:L8Y`RW20402:L02`49Y`VW2JL9Y`T100L9 -00`1DPUB2E89DPUB2@4:DP8101MB0E81DP5B0E81DP5B0E81DP5B0E81DP090@0GDP5B0E81DP5B0E81 -DP5B0E81DP5B0E800P49DP0<0E89DPUB2E89DPT120T02P49Y`VW2JL9Y`48Y`0;0JL8Y`RW2:L8Y`40 -2`P06@4800P0200800P0200800P0200800P020000P4600410@0001D000<100000P020@0K00P02008 -00P0200800P0200800P0200800P100X800`12:L8Y`RW2:L8Y`48Y`0;0JL9Y`VW2JL9Y`401`T03@49 -DPUB2E89DPUB2@402E80705B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E830@0IDP5B0E81DP5B0E81 -DP5B0E81DP5B0E81DP020@YB00`12E89DPUB2E89DP482@0:0JL9Y`VW2JL90@RW00`12:L8Y`RW2:L8 -Y`4:200K0@0800P0200800P0200800P0200800P02008008110010@40000E00030@00008001d800P0 -200800P0200800P0200800P0200800P00@0:200<0JL8Y`RW2:L8Y`P12:L02`49Y`VW2JL9Y`T100P9 -00`12E89DPUB2E89DP4:DP0i0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B -0E81DP5B0E81DP5B0E8100YB00`1DPUB2E89DPUB2@482@0:0@VW2JL9Y`VW0@VW00/12:L8Y`RW2:L8 -0@0;200K0@0800P0200800P0200800P0200800P0200800D00@4100005@000`400003000K200800P0 -200800P0200800P0200800P0200100/800/12:L8Y`RW2:L80@09Y`0;0JL9Y`VW2JL9Y`4020T0305B -2E89DPUB2E890@YB0P40=U81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81 -DP5B0E81DP5B0@]B00/12E89DPUB2E890@092@0:0JL9Y`VW2JL90@VW00/1Y`RW2:L8Y`RW0@0;200J -0@P0200800P0200800P0200800P0200800P600410@0001D00P43000L200800P0200800P0200800P0 -200800P020080@X800`12:L8Y`RW2:L8Y`49Y`0;0@VW2JL9Y`VW2@4020T03@49DPUB2E89DPUB2@40 -2U820@0cDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0081 -2U803049DPUB2E89DPUB0@T900X12JL9Y`VW2JL12JL03048Y`RW2:L8Y`RW0@/801X1200800P02008 -00P0200800P0200800P020@00P4100005@000`400003000H200800P0200800P0200800P0200800P0 -0P4;200<0JL8Y`RW2:L8Y`P12JL02`6W2JL9Y`VW2JL100P900d1DPUB2E89DPUB2E8100YB03@1DP5B -0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0P4;DP0<0E89DPUB -2E89DPT12@T02P6W2JL9Y`VW2@49Y`0<0JL8Y`RW2:L8Y`P12`P06@40200800P0200800P0200800P0 -200800P01P010@40000E00030@00008001L800P0200800P0200800P0200800P020020@`800`1Y`RW -2:L8Y`RW204:Y`0;0@VW2JL9Y`VW2@402@T0305B2E89DPUB2E890@]B0`40;E81DP5B0E81DP5B0E81 -DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP030@aB00`1DPUB2E89DPUB2@4:2@0:0@VW2JL9 -Y`VW0@ZW00`1Y`RW2:L8Y`RW204;208101L800P0200800P0200800P0200800P0200500410@0001D0 -00<100000`0050P0200800P0200800P0200800P00P4>200<0@RW2:L8Y`RW2:L12ZL02`6W2JL9Y`VW -2JL100T900d12E89DPUB2E89DPT100aB0P40:e81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81 -DP5B0E81DP5B0E800P4>DP0<0@UB2E89DPUB2E812PT02P6W2JL9Y`VW2@4:Y`0<0@RW2:L8Y`RW2:L1 -3@P20@0D00P0200800P0200800P0200800P600410@0001D000<100000P004`P0200800P0200800P0 -200800P00P4?200<0@RW2:L8Y`RW2:L12ZL03@6W2JL9Y`VW2JL9Y`402@T03049DPUB2E89DPUB0@iB -0`409E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E800`4?DP0<0@UB2E89DPUB2E81 -2PT0306W2JL9Y`VW2JL90@ZW00`12:L8Y`RW2:L8Y`4>208101<800P0200800P0200800P0200800D0 -0@4100005@000`400003000@200800P0200800P0200800813`P20@0;2:L8Y`RW2:L8Y`402jL03@49 -Y`VW2JL9Y`VW2@402PT02`49DPUB2E89DPUB00813U840@0QDP5B0E81DP5B0E81DP5B0E81DP5B0E81 -DP5B0E81DP5B00813e820@0;2E89DPUB2E89DP402`T03049Y`VW2JL9Y`VW0@^W00/12:L8Y`RW2:L8 -Y`020@h80`403`P0200800P0200800P0200600410@0001D000<100000P003@P0200800P0200800P0 -104@200=0JL8Y`RW2:L8Y`RW0@00E89DPUB2E89DPUB -2E820AMB1@400e810@030AIB0P403PUB2E89DPUB2E89DPT13@T03P6W2JL9Y`VW2JL9Y`T13JL03P6W -2:L8Y`RW2:L8Y`RW0P4F20@11P010@40000E00030@0000800P4I200A0JL8Y`RW2:L8Y`RW2:L8Y`40 -3JL03`49Y`VW2JL9Y`VW2JL90@0=2@0@0E89DPUB2E89DPUB2E890AYB0`4IDP0A0E89DPUB2E89DPUB -2E89DP403@T03P49Y`VW2JL9Y`VW2JL13ZL0406W2:L8Y`RW2:L8Y`RW204I208110010@40000E0003 -0@0000806@P20@0@Y`RW2:L8Y`RW2:L8Y`RW0@jW00l1Y`VW2JL9Y`VW2JL9Y`403@T04049DPUB2E89 -DPUB2E89DPT20C9B0P404589DPUB2E89DPUB2E89DP4>2@0>0JL9Y`VW2JL9Y`VW2@4>Y`0@0@RW2:L8 -Y`RW2:L8Y`RW208160P500410@0001D00P4301P801812:L8Y`RW2:L8Y`RW2:L8Y`4?Y`0?0@VW2JL9 -Y`VW2JL9Y`T100h901812E89DPUB2E89DPUB2E89DP4`DP0B0@UB2E89DPUB2E89DPUB2E813`T03P49 -Y`VW2JL9Y`VW2JL13jL04P48Y`RW2:L8Y`RW2:L8Y`RW0AL810020@40000E00030@0000805PP20@0A -2:L8Y`RW2:L8Y`RW2:L8Y`403jL04@49Y`VW2JL9Y`VW2JL9Y`T100h901412E89DPUB2E89DPUB2E89 -DP020BaB0P404@UB2E89DPUB2E89DPUB2E8100l901012JL9Y`VW2JL9Y`VW2JL13jL04@48Y`RW2:L8 -Y`RW2:L8Y`RW00815@P500410@0001D000<100000P0E200D0JL8Y`RW2:L8Y`RW2:L8Y`RW204?Y`0A -0JL9Y`VW2JL9Y`VW2JL9Y`403PT0505B2E89DPUB2E89DPUB2E89DPT1:U80505B2E89DPUB2E89DPUB -2E89DPT13`T0406W2JL9Y`VW2JL9Y`VW2@4?Y`0D0JL8Y`RW2:L8Y`RW2:L8Y`RW204D20D00@410000 -5@000`40000201<80P404jL8Y`RW2:L8Y`RW2:L8Y`RW20404:L04@49Y`VW2JL9Y`VW2JL9Y`T100l9 -01<1DPUB2E89DPUB2E89DPUB2E8900819U820@0CDPUB2E89DPUB2E89DPUB2E890@0@2@0@0@VW2JL9 -Y`VW2JL9Y`VW0A2W01<1Y`RW2:L8Y`RW2:L8Y`RW2:L800814PP500410@0001D000<100000P0>20D1 -01@8Y`RW2:L8Y`RW2:L8Y`RW2:L80A6W0141Y`VW2JL9Y`VW2JL9Y`VW0@0@2@0D0E89DPUB2E89DPUB -2E89DPUB2E850AaB1@4050UB2E89DPUB2E89DPUB2E89DPT14@T0406W2JL9Y`VW2JL9Y`VW2@4AY`0D -0JL8Y`RW2:L8Y`RW2:L8Y`RW2:L50@d81@010@40000E00030@0000801@P90@0H2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`P14ZL04@49Y`VW2JL9Y`VW2JL9Y`T1014901P1DPUB2E89DPUB2E89DPUB2E89DPUB -2E8:0@UB2@4060UB2E89DPUB2E89DPUB2E89DPUB2E890A8901012JL9Y`VW2JL9Y`VW2JL14ZL0606W -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`T110P500410@0001D000<100000P050@0Q2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L1016W01<12JL9Y`VW2JL9Y`VW2JL9Y`T1010902812E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E892@408@UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB -0@0A2@0B0@VW2JL9Y`VW2JL9Y`VW2JL14JL08@48Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`050@@00@4100005@000`400002000U2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -0@0BY`0C0JL9Y`VW2JL9Y`VW2JL9Y`VW0@0A2@1:0@UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP4B2@0B0JL9Y`VW2JL9Y`VW -2JL9Y`T14ZL09048Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20D00@4100005@000`40 -0002000RY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20<14ZL04`49Y`VW2JL9Y`VW2JL9 -Y`VW2@404@T30@14DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPT30A490P4040VW2JL9Y`VW2JL9Y`VW2JL20A6W0`408JL8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`0500410@0001D000<100000P007PRW2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`@14jL20@0C2JL9Y`VW2JL9Y`VW2JL9Y`VW2@020A891040?0UB2E89DPUB -2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP@14PT20@0D -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T20A:W10407@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L800D0 -0@4100005@000`400002000IY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`050AFW0P405jL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW008150T50@0b2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB -2E89DPUB2E89DPUB2E850A@90P4060VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`815:L50@0H2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW1@010@40000E00030@00008001D8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P0 -104HY`8101/9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T00P4G2@@102YB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT40AL90P407:L9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`T20ANW10405:L8Y`RW2:L8Y`RW2:L8Y`RW2:L81@010@40000E00030@00008000VW2:L8Y`RW2:L0 -304JY`8101nW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00816@T<0@0B2E89DPUB2E89DPUB -2E89DPUB304I2@810209Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`816JL;0@09Y`RW2:L8 -Y`RW00D00@4100005@020@<02@4TY`8102@9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2@4T2A8190T09P6W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T18jL:0@<00P410000 -5@000`40000202^W0P409ZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90P5F2@81 -02JW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@81:ZL500410@0001D000<10000 -0P0YY`8102X9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL20E890P40:PVW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`81::L500410@0001D000<10000 -0P0WY`8102jW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90P5>2@81 -02jW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90P4VY`D00@410000 -5@000`40000202FW0P400A893P40DZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T=0@VW1@010@40000E00030@0000802@40KPVW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW4P40K@VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T02P4400410@0001D000<10000 -0P00o`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2@0500410@0001D000<100000P00ojL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`050041 -0@0001D000<100000P00o`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@0500410@0000d0104400030@0000800?nW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL01@010@40000=00030@0000D00P43003o2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900@00P410000 -3P000`40000400030@000?l01`010@40000?00030@0000<000<10000o`0700410@00010000<10000 -0P000`40000200030@0003d000<10000?@000`40000l00030@0003d000<100000P010@40000=0004 -0@000@@000<100000P000`40000:00030@0000T000<100002P000`40000:00030@0000X000<10000 -2P000`40000900030@0000X000<100002P000`40000:00030@0000T000<100002P000`40000:0003 -0@0000X000<100002@000`40000:00030@0000X000<100002P000`40000:00030@0000T000<10000 -0P010@40000>00811@3o0@/10@000?l08@000?l08@000?l08@000?l08@000001\ -\>"], - ImageRangeCache->{{{0, 287}, {287, 0}} -> {-0.207, -0.172242, 0.00783272, - 0.00783272}}], - -Cell[BoxData[ - TagBox[\(\[SkeletonIndicator] ContourGraphics \[SkeletonIndicator]\), - False, - Editable->False]], "Output"] -}, Open ]], - -Cell[CellGroupData[{ - -Cell[BoxData[ - \(ContourPlot[v, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"], - -Cell[GraphicsData["PostScript", "\<\ -%! -%%Creator: Mathematica -%%AspectRatio: 1 -MathPictureStart -/Mabs { -Mgmatrix idtransform -Mtmatrix dtransform -} bind def -/Mabsadd { Mabs -3 -1 roll add -3 1 roll add -exch } bind def -%% ContourGraphics -%%IncludeResource: font Courier -%%IncludeFont: Courier -/Courier findfont 10 scalefont setfont -% Scaling calculations -0.0192308 0.480769 0.0192308 0.480769 [ -[.01923 -0.0125 -3 -9 ] -[.01923 -0.0125 3 0 ] -[.25962 -0.0125 -9 -9 ] -[.25962 -0.0125 9 0 ] -[.5 -0.0125 -3 -9 ] -[.5 -0.0125 3 0 ] -[.74038 -0.0125 -9 -9 ] -[.74038 -0.0125 9 0 ] -[.98077 -0.0125 -3 -9 ] -[.98077 -0.0125 3 0 ] -[ 0 0 -0.125 0 ] -[-0.0125 .01923 -6 -4.5 ] -[-0.0125 .01923 0 4.5 ] -[-0.0125 .25962 -18 -4.5 ] -[-0.0125 .25962 0 4.5 ] -[-0.0125 .5 -6 -4.5 ] -[-0.0125 .5 0 4.5 ] -[-0.0125 .74038 -18 -4.5 ] -[-0.0125 .74038 0 4.5 ] -[-0.0125 .98077 -6 -4.5 ] -[-0.0125 .98077 0 4.5 ] -[ 0 0 -0.125 0 ] -[ 0 1 .125 0 ] -[ 1 0 .125 0 ] -[ 0 0 0 0 ] -[ 1 1 0 0 ] -] MathScale -% Start of Graphics -1 setlinecap -1 setlinejoin -newpath -0 g -.25 Mabswid -.01923 0 m -.01923 .00625 L -s -[(0)] .01923 -0.0125 0 1 Mshowa -.25962 0 m -.25962 .00625 L -s -[(0.5)] .25962 -0.0125 0 1 Mshowa -.5 0 m -.5 .00625 L -s -[(1)] .5 -0.0125 0 1 Mshowa -.74038 0 m -.74038 .00625 L -s -[(1.5)] .74038 -0.0125 0 1 Mshowa -.98077 0 m -.98077 .00625 L -s -[(2)] .98077 -0.0125 0 1 Mshowa -.125 Mabswid -.06731 0 m -.06731 .00375 L -s -.11538 0 m -.11538 .00375 L -s -.16346 0 m -.16346 .00375 L -s -.21154 0 m -.21154 .00375 L -s -.30769 0 m -.30769 .00375 L -s -.35577 0 m -.35577 .00375 L -s -.40385 0 m -.40385 .00375 L -s -.45192 0 m -.45192 .00375 L -s -.54808 0 m -.54808 .00375 L -s -.59615 0 m -.59615 .00375 L -s -.64423 0 m -.64423 .00375 L -s -.69231 0 m -.69231 .00375 L -s -.78846 0 m -.78846 .00375 L -s -.83654 0 m -.83654 .00375 L -s -.88462 0 m -.88462 .00375 L -s -.93269 0 m -.93269 .00375 L -s -.25 Mabswid -0 0 m -1 0 L -s -0 .01923 m -.00625 .01923 L -s -[(0)] -0.0125 .01923 1 0 Mshowa -0 .25962 m -.00625 .25962 L -s -[(0.5)] -0.0125 .25962 1 0 Mshowa -0 .5 m -.00625 .5 L -s -[(1)] -0.0125 .5 1 0 Mshowa -0 .74038 m -.00625 .74038 L -s -[(1.5)] -0.0125 .74038 1 0 Mshowa -0 .98077 m -.00625 .98077 L -s -[(2)] -0.0125 .98077 1 0 Mshowa -.125 Mabswid -0 .06731 m -.00375 .06731 L -s -0 .11538 m -.00375 .11538 L -s -0 .16346 m -.00375 .16346 L -s -0 .21154 m -.00375 .21154 L -s -0 .30769 m -.00375 .30769 L -s -0 .35577 m -.00375 .35577 L -s -0 .40385 m -.00375 .40385 L -s -0 .45192 m -.00375 .45192 L -s -0 .54808 m -.00375 .54808 L -s -0 .59615 m -.00375 .59615 L -s -0 .64423 m -.00375 .64423 L -s -0 .69231 m -.00375 .69231 L -s -0 .78846 m -.00375 .78846 L -s -0 .83654 m -.00375 .83654 L -s -0 .88462 m -.00375 .88462 L -s -0 .93269 m -.00375 .93269 L -s -.25 Mabswid -0 0 m -0 1 L -s -.01923 .99375 m -.01923 1 L -s -.25962 .99375 m -.25962 1 L -s -.5 .99375 m -.5 1 L -s -.74038 .99375 m -.74038 1 L -s -.98077 .99375 m -.98077 1 L -s -.125 Mabswid -.06731 .99625 m -.06731 1 L -s -.11538 .99625 m -.11538 1 L -s -.16346 .99625 m -.16346 1 L -s -.21154 .99625 m -.21154 1 L -s -.30769 .99625 m -.30769 1 L -s -.35577 .99625 m -.35577 1 L -s -.40385 .99625 m -.40385 1 L -s -.45192 .99625 m -.45192 1 L -s -.54808 .99625 m -.54808 1 L -s -.59615 .99625 m -.59615 1 L -s -.64423 .99625 m -.64423 1 L -s -.69231 .99625 m -.69231 1 L -s -.78846 .99625 m -.78846 1 L -s -.83654 .99625 m -.83654 1 L -s -.88462 .99625 m -.88462 1 L -s -.93269 .99625 m -.93269 1 L -s -.25 Mabswid -0 1 m -1 1 L -s -.99375 .01923 m -1 .01923 L -s -.99375 .25962 m -1 .25962 L -s -.99375 .5 m -1 .5 L -s -.99375 .74038 m -1 .74038 L -s -.99375 .98077 m -1 .98077 L -s -.125 Mabswid -.99625 .06731 m -1 .06731 L -s -.99625 .11538 m -1 .11538 L -s -.99625 .16346 m -1 .16346 L -s -.99625 .21154 m -1 .21154 L -s -.99625 .30769 m -1 .30769 L -s -.99625 .35577 m -1 .35577 L -s -.99625 .40385 m -1 .40385 L -s -.99625 .45192 m -1 .45192 L -s -.99625 .54808 m -1 .54808 L -s -.99625 .59615 m -1 .59615 L -s -.99625 .64423 m -1 .64423 L -s -.99625 .69231 m -1 .69231 L -s -.99625 .78846 m -1 .78846 L -s -.99625 .83654 m -1 .83654 L -s -.99625 .88462 m -1 .88462 L -s -.99625 .93269 m -1 .93269 L -s -.25 Mabswid -1 0 m -1 1 L -s -0 0 m -1 0 L -1 1 L -0 1 L -closepath -clip -newpath -.5 g -.01923 .98077 m -.98077 .98077 L -.98077 .01923 L -.01923 .01923 L -F -0 g -.5 Mabswid -.6 g -.48596 .01923 m -.4844 .08791 L -.47739 .15659 L -.43403 .22527 L -.43132 .22654 L -.36264 .24138 L -.29396 .24501 L -.22527 .24501 L -.15659 .24138 L -.08791 .22654 L -.0857 .22527 L -.04742 .15659 L -.03964 .08791 L -.03781 .01923 L -F -0 g -.48596 .01923 m -.4844 .08791 L -.47739 .15659 L -.43403 .22527 L -.43132 .22654 L -.36264 .24138 L -.29396 .24501 L -.22527 .24501 L -.15659 .24138 L -.08791 .22654 L -.0857 .22527 L -.04742 .15659 L -.03964 .08791 L -.03781 .01923 L -s -.4 g -.08791 .29269 m -.15659 .27785 L -.22527 .27422 L -.29396 .27422 L -.36264 .27785 L -.43132 .29269 L -.43403 .29396 L -.47739 .36264 L -.4844 .43132 L -.48596 .5 L -.4844 .56868 L -.47739 .63736 L -.43403 .70604 L -.43132 .70731 L -.36264 .72215 L -.29396 .72578 L -.22527 .72578 L -.15659 .72215 L -.08791 .70731 L -.0857 .70604 L -.04742 .63736 L -.03964 .56868 L -.03781 .5 L -.03964 .43132 L -.04742 .36264 L -.0857 .29396 L -F -0 g -.08791 .29269 m -.15659 .27785 L -.22527 .27422 L -.29396 .27422 L -.36264 .27785 L -.43132 .29269 L -.43403 .29396 L -.47739 .36264 L -.4844 .43132 L -.48596 .5 L -.4844 .56868 L -.47739 .63736 L -.43403 .70604 L -.43132 .70731 L -.36264 .72215 L -.29396 .72578 L -.22527 .72578 L -.15659 .72215 L -.08791 .70731 L -.0857 .70604 L -.04742 .63736 L -.03964 .56868 L -.03781 .5 L -.03964 .43132 L -.04742 .36264 L -.0857 .29396 L -.08791 .29269 L -s -.6 g -.48596 .98077 m -.4844 .91209 L -.47739 .84341 L -.43403 .77473 L -.43132 .77346 L -.36264 .75862 L -.29396 .75499 L -.22527 .75499 L -.15659 .75862 L -.08791 .77346 L -.0857 .77473 L -.04742 .84341 L -.03964 .91209 L -.03781 .98077 L -F -0 g -.48596 .98077 m -.4844 .91209 L -.47739 .84341 L -.43403 .77473 L -.43132 .77346 L -.36264 .75862 L -.29396 .75499 L -.22527 .75499 L -.15659 .75862 L -.08791 .77346 L -.0857 .77473 L -.04742 .84341 L -.03964 .91209 L -.03781 .98077 L -s -.7 g -.45707 .01923 m -.45212 .08791 L -.43132 .15521 L -.42933 .15659 L -.36264 .20465 L -.29396 .21567 L -.22527 .21567 L -.15659 .20465 L -.08991 .15659 L -.08791 .15521 L -.07087 .08791 L -.06667 .01923 L -F -0 g -.45707 .01923 m -.45212 .08791 L -.43132 .15521 L -.42933 .15659 L -.36264 .20465 L -.29396 .21567 L -.22527 .21567 L -.15659 .20465 L -.08991 .15659 L -.08791 .15521 L -.07087 .08791 L -.06667 .01923 L -s -.3 g -.15659 .31458 m -.22527 .30356 L -.29396 .30356 L -.36264 .31458 L -.42933 .36264 L -.43132 .36402 L -.45212 .43132 L -.45707 .5 L -.45212 .56868 L -.43132 .63598 L -.42933 .63736 L -.36264 .68542 L -.29396 .69644 L -.22527 .69644 L -.15659 .68542 L -.08991 .63736 L -.08791 .63598 L -.07087 .56868 L -.06667 .5 L -.07087 .43132 L -.08791 .36402 L -.08991 .36264 L -F -0 g -.15659 .31458 m -.22527 .30356 L -.29396 .30356 L -.36264 .31458 L -.42933 .36264 L -.43132 .36402 L -.45212 .43132 L -.45707 .5 L -.45212 .56868 L -.43132 .63598 L -.42933 .63736 L -.36264 .68542 L -.29396 .69644 L -.22527 .69644 L -.15659 .68542 L -.08991 .63736 L -.08791 .63598 L -.07087 .56868 L -.06667 .5 L -.07087 .43132 L -.08791 .36402 L -.08991 .36264 L -.15659 .31458 L -s -.7 g -.45707 .98077 m -.45212 .91209 L -.43132 .84479 L -.42933 .84341 L -.36264 .79535 L -.29396 .78433 L -.22527 .78433 L -.15659 .79535 L -.08991 .84341 L -.08791 .84479 L -.07087 .91209 L -.06667 .98077 L -F -0 g -.45707 .98077 m -.45212 .91209 L -.43132 .84479 L -.42933 .84341 L -.36264 .79535 L -.29396 .78433 L -.22527 .78433 L -.15659 .79535 L -.08991 .84341 L -.08791 .84479 L -.07087 .91209 L -.06667 .98077 L -s -.8 g -.42676 .01923 m -.41893 .08791 L -.37227 .15659 L -.36264 .16237 L -.29396 .18453 L -.22527 .18453 L -.15659 .16237 L -.14696 .15659 L -.1003 .08791 L -.09247 .01923 L -F -0 g -.42676 .01923 m -.41893 .08791 L -.37227 .15659 L -.36264 .16237 L -.29396 .18453 L -.22527 .18453 L -.15659 .16237 L -.14696 .15659 L -.1003 .08791 L -.09247 .01923 L -s -.2 g -.15659 .35686 m -.22527 .3347 L -.29396 .3347 L -.36264 .35686 L -.37227 .36264 L -.41893 .43132 L -.42676 .5 L -.41893 .56868 L -.37227 .63736 L -.36264 .64314 L -.29396 .6653 L -.22527 .6653 L -.15659 .64314 L -.14696 .63736 L -.1003 .56868 L -.09247 .5 L -.1003 .43132 L -.14696 .36264 L -F -0 g -.15659 .35686 m -.22527 .3347 L -.29396 .3347 L -.36264 .35686 L -.37227 .36264 L -.41893 .43132 L -.42676 .5 L -.41893 .56868 L -.37227 .63736 L -.36264 .64314 L -.29396 .6653 L -.22527 .6653 L -.15659 .64314 L -.14696 .63736 L -.1003 .56868 L -.09247 .5 L -.1003 .43132 L -.14696 .36264 L -.15659 .35686 L -s -.8 g -.42676 .98077 m -.41893 .91209 L -.37227 .84341 L -.36264 .83763 L -.29396 .81547 L -.22527 .81547 L -.15659 .83763 L -.14696 .84341 L -.1003 .91209 L -.09247 .98077 L -F -0 g -.42676 .98077 m -.41893 .91209 L -.37227 .84341 L -.36264 .83763 L -.29396 .81547 L -.22527 .81547 L -.15659 .83763 L -.14696 .84341 L -.1003 .91209 L -.09247 .98077 L -s -.9 g -.39439 .01923 m -.37815 .08791 L -.36264 .11825 L -.29396 .15309 L -.22527 .15309 L -.15659 .11825 L -.14108 .08791 L -.12484 .01923 L -F -0 g -.39439 .01923 m -.37815 .08791 L -.36264 .11825 L -.29396 .15309 L -.22527 .15309 L -.15659 .11825 L -.14108 .08791 L -.12484 .01923 L -s -.1 g -.15659 .40098 m -.22527 .36614 L -.29396 .36614 L -.36264 .40098 L -.37815 .43132 L -.39439 .5 L -.37815 .56868 L -.36264 .59902 L -.29396 .63386 L -.22527 .63386 L -.15659 .59902 L -.14108 .56868 L -.12484 .5 L -.14108 .43132 L -F -0 g -.15659 .40098 m -.22527 .36614 L -.29396 .36614 L -.36264 .40098 L -.37815 .43132 L -.39439 .5 L -.37815 .56868 L -.36264 .59902 L -.29396 .63386 L -.22527 .63386 L -.15659 .59902 L -.14108 .56868 L -.12484 .5 L -.14108 .43132 L -.15659 .40098 L -s -.9 g -.39439 .98077 m -.37815 .91209 L -.36264 .88175 L -.29396 .84691 L -.22527 .84691 L -.15659 .88175 L -.14108 .91209 L -.12484 .98077 L -F -0 g -.39439 .98077 m -.37815 .91209 L -.36264 .88175 L -.29396 .84691 L -.22527 .84691 L -.15659 .88175 L -.14108 .91209 L -.12484 .98077 L -s -1 g -.34792 .01923 m -.31706 .08791 L -.29396 .10805 L -.22527 .10805 L -.20217 .08791 L -.17131 .01923 L -F -0 g -.34792 .01923 m -.31706 .08791 L -.29396 .10805 L -.22527 .10805 L -.20217 .08791 L -.17131 .01923 L -s -.22527 .41118 m -.29396 .41118 L -.31706 .43132 L -.34792 .5 L -.31706 .56868 L -.29396 .58882 L -.22527 .58882 L -.20217 .56868 L -.17131 .5 L -.20217 .43132 L -F -.22527 .41118 m -.29396 .41118 L -.31706 .43132 L -.34792 .5 L -.31706 .56868 L -.29396 .58882 L -.22527 .58882 L -.20217 .56868 L -.17131 .5 L -.20217 .43132 L -.22527 .41118 L -s -1 g -.34792 .98077 m -.31706 .91209 L -.29396 .89195 L -.22527 .89195 L -.20217 .91209 L -.17131 .98077 L -F -0 g -.34792 .98077 m -.31706 .91209 L -.29396 .89195 L -.22527 .89195 L -.20217 .91209 L -.17131 .98077 L -s -.4 g -.96219 .01923 m -.96036 .08791 L -.95258 .15659 L -.9143 .22527 L -.91209 .22654 L -.84341 .24138 L -.77473 .24501 L -.70604 .24501 L -.63736 .24138 L -.56868 .22654 L -.56597 .22527 L -.52261 .15659 L -.5156 .08791 L -.51404 .01923 L -F -0 g -.96219 .01923 m -.96036 .08791 L -.95258 .15659 L -.9143 .22527 L -.91209 .22654 L -.84341 .24138 L -.77473 .24501 L -.70604 .24501 L -.63736 .24138 L -.56868 .22654 L -.56597 .22527 L -.52261 .15659 L -.5156 .08791 L -.51404 .01923 L -s -.6 g -.56868 .29269 m -.63736 .27785 L -.70604 .27422 L -.77473 .27422 L -.84341 .27785 L -.91209 .29269 L -.9143 .29396 L -.95258 .36264 L -.96036 .43132 L -.96219 .5 L -.96036 .56868 L -.95258 .63736 L -.9143 .70604 L -.91209 .70731 L -.84341 .72215 L -.77473 .72578 L -.70604 .72578 L -.63736 .72215 L -.56868 .70731 L -.56597 .70604 L -.52261 .63736 L -.5156 .56868 L -.51404 .5 L -.5156 .43132 L -.52261 .36264 L -.56597 .29396 L -F -0 g -.56868 .29269 m -.63736 .27785 L -.70604 .27422 L -.77473 .27422 L -.84341 .27785 L -.91209 .29269 L -.9143 .29396 L -.95258 .36264 L -.96036 .43132 L -.96219 .5 L -.96036 .56868 L -.95258 .63736 L -.9143 .70604 L -.91209 .70731 L -.84341 .72215 L -.77473 .72578 L -.70604 .72578 L -.63736 .72215 L -.56868 .70731 L -.56597 .70604 L -.52261 .63736 L -.5156 .56868 L -.51404 .5 L -.5156 .43132 L -.52261 .36264 L -.56597 .29396 L -.56868 .29269 L -s -.4 g -.96219 .98077 m -.96036 .91209 L -.95258 .84341 L -.9143 .77473 L -.91209 .77346 L -.84341 .75862 L -.77473 .75499 L -.70604 .75499 L -.63736 .75862 L -.56868 .77346 L -.56597 .77473 L -.52261 .84341 L -.5156 .91209 L -.51404 .98077 L -F -0 g -.96219 .98077 m -.96036 .91209 L -.95258 .84341 L -.9143 .77473 L -.91209 .77346 L -.84341 .75862 L -.77473 .75499 L -.70604 .75499 L -.63736 .75862 L -.56868 .77346 L -.56597 .77473 L -.52261 .84341 L -.5156 .91209 L -.51404 .98077 L -s -.3 g -.93333 .01923 m -.92913 .08791 L -.91209 .15521 L -.91009 .15659 L -.84341 .20465 L -.77473 .21567 L -.70604 .21567 L -.63736 .20465 L -.57067 .15659 L -.56868 .15521 L -.54788 .08791 L -.54293 .01923 L -F -0 g -.93333 .01923 m -.92913 .08791 L -.91209 .15521 L -.91009 .15659 L -.84341 .20465 L -.77473 .21567 L -.70604 .21567 L -.63736 .20465 L -.57067 .15659 L -.56868 .15521 L -.54788 .08791 L -.54293 .01923 L -s -.7 g -.63736 .31458 m -.70604 .30356 L -.77473 .30356 L -.84341 .31458 L -.91009 .36264 L -.91209 .36402 L -.92913 .43132 L -.93333 .5 L -.92913 .56868 L -.91209 .63598 L -.91009 .63736 L -.84341 .68542 L -.77473 .69644 L -.70604 .69644 L -.63736 .68542 L -.57067 .63736 L -.56868 .63598 L -.54788 .56868 L -.54293 .5 L -.54788 .43132 L -.56868 .36402 L -.57067 .36264 L -F -0 g -.63736 .31458 m -.70604 .30356 L -.77473 .30356 L -.84341 .31458 L -.91009 .36264 L -.91209 .36402 L -.92913 .43132 L -.93333 .5 L -.92913 .56868 L -.91209 .63598 L -.91009 .63736 L -.84341 .68542 L -.77473 .69644 L -.70604 .69644 L -.63736 .68542 L -.57067 .63736 L -.56868 .63598 L -.54788 .56868 L -.54293 .5 L -.54788 .43132 L -.56868 .36402 L -.57067 .36264 L -.63736 .31458 L -s -.3 g -.93333 .98077 m -.92913 .91209 L -.91209 .84479 L -.91009 .84341 L -.84341 .79535 L -.77473 .78433 L -.70604 .78433 L -.63736 .79535 L -.57067 .84341 L -.56868 .84479 L -.54788 .91209 L -.54293 .98077 L -F -0 g -.93333 .98077 m -.92913 .91209 L -.91209 .84479 L -.91009 .84341 L -.84341 .79535 L -.77473 .78433 L -.70604 .78433 L -.63736 .79535 L -.57067 .84341 L -.56868 .84479 L -.54788 .91209 L -.54293 .98077 L -s -.2 g -.90753 .01923 m -.8997 .08791 L -.85304 .15659 L -.84341 .16237 L -.77473 .18453 L -.70604 .18453 L -.63736 .16237 L -.62773 .15659 L -.58107 .08791 L -.57324 .01923 L -F -0 g -.90753 .01923 m -.8997 .08791 L -.85304 .15659 L -.84341 .16237 L -.77473 .18453 L -.70604 .18453 L -.63736 .16237 L -.62773 .15659 L -.58107 .08791 L -.57324 .01923 L -s -.8 g -.63736 .35686 m -.70604 .3347 L -.77473 .3347 L -.84341 .35686 L -.85304 .36264 L -.8997 .43132 L -.90753 .5 L -.8997 .56868 L -.85304 .63736 L -.84341 .64314 L -.77473 .6653 L -.70604 .6653 L -.63736 .64314 L -.62773 .63736 L -.58107 .56868 L -.57324 .5 L -.58107 .43132 L -.62773 .36264 L -F -0 g -.63736 .35686 m -.70604 .3347 L -.77473 .3347 L -.84341 .35686 L -.85304 .36264 L -.8997 .43132 L -.90753 .5 L -.8997 .56868 L -.85304 .63736 L -.84341 .64314 L -.77473 .6653 L -.70604 .6653 L -.63736 .64314 L -.62773 .63736 L -.58107 .56868 L -.57324 .5 L -.58107 .43132 L -.62773 .36264 L -.63736 .35686 L -s -.2 g -.90753 .98077 m -.8997 .91209 L -.85304 .84341 L -.84341 .83763 L -.77473 .81547 L -.70604 .81547 L -.63736 .83763 L -.62773 .84341 L -.58107 .91209 L -.57324 .98077 L -F -0 g -.90753 .98077 m -.8997 .91209 L -.85304 .84341 L -.84341 .83763 L -.77473 .81547 L -.70604 .81547 L -.63736 .83763 L -.62773 .84341 L -.58107 .91209 L -.57324 .98077 L -s -.1 g -.87516 .01923 m -.85892 .08791 L -.84341 .11825 L -.77473 .15309 L -.70604 .15309 L -.63736 .11825 L -.62185 .08791 L -.60561 .01923 L -F -0 g -.87516 .01923 m -.85892 .08791 L -.84341 .11825 L -.77473 .15309 L -.70604 .15309 L -.63736 .11825 L -.62185 .08791 L -.60561 .01923 L -s -.9 g -.63736 .40098 m -.70604 .36614 L -.77473 .36614 L -.84341 .40098 L -.85892 .43132 L -.87516 .5 L -.85892 .56868 L -.84341 .59902 L -.77473 .63386 L -.70604 .63386 L -.63736 .59902 L -.62185 .56868 L -.60561 .5 L -.62185 .43132 L -F -0 g -.63736 .40098 m -.70604 .36614 L -.77473 .36614 L -.84341 .40098 L -.85892 .43132 L -.87516 .5 L -.85892 .56868 L -.84341 .59902 L -.77473 .63386 L -.70604 .63386 L -.63736 .59902 L -.62185 .56868 L -.60561 .5 L -.62185 .43132 L -.63736 .40098 L -s -.1 g -.87516 .98077 m -.85892 .91209 L -.84341 .88175 L -.77473 .84691 L -.70604 .84691 L -.63736 .88175 L -.62185 .91209 L -.60561 .98077 L -F -0 g -.87516 .98077 m -.85892 .91209 L -.84341 .88175 L -.77473 .84691 L -.70604 .84691 L -.63736 .88175 L -.62185 .91209 L -.60561 .98077 L -s -.82869 .01923 m -.79783 .08791 L -.77473 .10805 L -.70604 .10805 L -.68294 .08791 L -.65208 .01923 L -F -.82869 .01923 m -.79783 .08791 L -.77473 .10805 L -.70604 .10805 L -.68294 .08791 L -.65208 .01923 L -s -1 g -.70604 .41118 m -.77473 .41118 L -.79783 .43132 L -.82869 .5 L -.79783 .56868 L -.77473 .58882 L -.70604 .58882 L -.68294 .56868 L -.65208 .5 L -.68294 .43132 L -F -0 g -.70604 .41118 m -.77473 .41118 L -.79783 .43132 L -.82869 .5 L -.79783 .56868 L -.77473 .58882 L -.70604 .58882 L -.68294 .56868 L -.65208 .5 L -.68294 .43132 L -.70604 .41118 L -s -.82869 .98077 m -.79783 .91209 L -.77473 .89195 L -.70604 .89195 L -.68294 .91209 L -.65208 .98077 L -F -.82869 .98077 m -.79783 .91209 L -.77473 .89195 L -.70604 .89195 L -.68294 .91209 L -.65208 .98077 L -s -% End of Graphics -MathPictureEnd -\ -\>"], "Graphics", - ImageSize->{288, 288}, - ImageMargins->{{43, 0}, {0, 0}}, - ImageRegion->{{0, 1}, {0, 1}}, - ImageCache->GraphicsData["Bitmap", "\<\ -CF5dJ6E]HGAYHf4PAg9QL6QYHgon6Ykno_hn?S`2ook>c/mWIfGmoOol005E[;lC4a000<`00IP00V@00c000 -o`0c000c<`0cIP0cV@0cc00co`1V001V<`1VIP1VV@1Vc01Vo`2I002I<`2IIP2IV@2Ic02Io`3<003< -<`3I03>IIIS>IVC>Ic3>Ioc?<03?<@000`40000f00030@0000L00`4i0003 -0@0000@0000H00040@000CH000@1000120000`40000i00030@0003H000<100001`000`40000j0003 -0@0000<0000H00040@000CH000@1000120000`40000g00<1=P030@T000<10000=`00104000450000 -6@020CP00P4900@1>0000`40000f00030@0000L0104g00811P000?l08@0001D0o`4;0@40000E0003 -0@00008000<100002P000`40000900030@0000X000<100002P000`40000:00030@0000X000<10000 -2@000`40000:00030@0000X000<100002P000`40000900030@0000X000<100002P000`40000:0003 -0@0000T000<100002P000`40000:00030@0000X000<100002P000`40000900030@0000800@410000 -5@000`40000200030@0003d000<10000?@000`40000l00030@0003d000<100000P010@40000E0003 -0@000?l01`010@40000>00811@000`40003o00L00@4100003@0010400044008120000`4000050003 -0@0000<000<100001P000`40000900030@0002`000<100002P000`40000500030@0000D000<10000 -1@000`40000400030@0000D000<100001@000`40000600030@0000T000<10000;0000`4000090003 -0@0000H000<1000010000`40000400030@0000H00P4100003@001040004400030@00008000JW2JL9 -Y`47Y`070@RW2:L80@08200=0@P0200800P020080@0^000>0@0800P0200800P0204720090JL8Y`RW -2:L100NW00P12JL9Y`VW0@L900T12E89DPUB2@4025820@09DP5B0E81DP5B034100aB0E81DP5B0E81 -DP48DP080E89DPUB2@462@050@VW2JL01@010@40000=00040@000@@000<100000P001PVW2JL90@NW -00L1Y`RW2:L100P800h100P0200800P020080B`000h100P0200800P020080@P800T12:L8Y`RW2040 -1jL0206W2JL9Y`T11`T02@5B2E89DPUB0@08DP0<0E81DP5B0E81DP5B;`402e81DP5B0E81DP5B0081 -25802049DPUB2E811PT01@6W2JL900D00@4100003@001040004400030@00008000JW2JL9Y`47Y`07 -0@RW2:L80@09200=0@0800P0200800P00@0/000>0@P0200800P02008004820090JL8Y`RW2:L100NW -00P12JL9Y`VW0@L900T12E89DPUB2@402E80305B0E81DP5B0E81DRl100UB0E81DP5B0E800P49DP08 -0E89DPUB2@462@050@VW2JL01@010@40000=00040@000@@000<100000P001PVW2JL90@NW00L1Y`RW -2:L100T800h1200800P0200800P00BX000l1200800P0200800P0204020P02@48Y`RW2:L80@07Y`08 -0JL9Y`VW2@472@090E89DPUB2E8100UB0P402e81DP5B0E81DP5B02d100aB0E81DP5B0E81DP49DP08 -0@UB2E89DP462@050JL9Y`T01@010@40000>00811@000`4000020006Y`VW2JL11jL02048Y`RW2:L1 -20P03P40200800P0200800P1:P003`40200800P0200800P00@07200:0@RW2:L8Y`RW0@NW00P12JL9 -Y`VW0@L900X12E89DPUB2E812580305B0E81DP5B0E81DRd100]B0E81DP5B0E81DP020@QB00T12E89 -DPUB2@401PT01@49Y`VW00D00@4100005@000`40000200062JL9Y`T11jL0206W2:L8Y`P120P03`48 -00P0200800P020080@0X000?0@0800P0200800P0200100P800X1Y`RW2:L8Y`P11jL0206W2JL9Y`T1 -1`T02P5B2E89DPUB2@48DP8100]B0E81DP5B0E81DP0[0@0>DP5B0E81DP5B0E81DP48DP090E89DPUB -2E8100H900D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@NW00P12:L8Y`RW0@P800l100P0 -200800P020080040:0003`4800P0200800P020080@08200:0@RW2:L8Y`RW0@NW00P12JL9Y`VW0@L9 -00X12E89DPUB2E8125803P5B0E81DP5B0E81DP5B:`402e81DP5B0E81DP5B008125802@49DPUB2E89 -0@062@050@VW2JL01@010@40000E00030@00008000H9Y`VW2@47Y`080JL8Y`RW2049200?0@0800P0 -200800P0200102L000l100P0200800P02008004020P02P6W2:L8Y`RW2047Y`080JL9Y`VW2@472@0: -0E89DPUB2E890@UB00`1DP5B0E81DP5B0E8[0@0;DP5B0E81DP5B0E800P49DP090E89DPUB2E8100H9 -00D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@NW00P12:L8Y`RW0@T800l1200800P02008 -00P020409P004040200800P0200800P02048200:0@RW2:L8Y`RW0@NW00P12JL9Y`VW0@L900X12E89 -DPUB2E812E820@0;DP5B0E81DP5B0E80:@403U81DP5B0E81DP5B0E812E802@49DPUB2E890@062@05 -0@VW2JL01@010@40000E00030@00008000H9Y`VW2@48Y`070@RW2:L80@09200@0@0800P0200800P0 -20080BD000l1200800P0200800P020402@P02@6W2:L8Y`RW0@07Y`0:0@VW2JL9Y`VW0@L900T12E89 -DPUB2@402E803P5B0E81DP5B0E81DP5B:@402e81DP5B0E81DP5B00812E80205B2E89DPT11`T01@6W -2JL900D00@4100005@000`4000020006Y`VW2JL12:L01`6W2:L8Y`402@P0404800P0200800P02008 -004T000@0@P0200800P0200800P00@T800T12:L8Y`RW20401jL02P6W2JL9Y`VW2@472@090E89DPUB -2E8100UB0P403E81DP5B0E81DP5B0E809`403U81DP5B0E81DP5B0E812E802049DPUB2E811`T01@49 -Y`VW00D00@4100005@000`40000200062JL9Y`T12:L01`48Y`RW20402PP0404800P0200800P02008 -004S000@0@0800P0200800P020080@T800T1Y`RW2:L8Y`401jL02P49Y`VW2JL9Y`472@090@UB2E89 -DPT100YB0P402e81DP5B0E81DP5B02L100iB0E81DP5B0E81DP5B0@YB00P1DPUB2E890@L900D1Y`VW -2@0500410@0001D00P430006Y`VW2JL12:L01`6W2:L8Y`402PP04040200800P0200800P0204S000@ -0@P0200800P0200800P00@T800T12:L8Y`RW20401jL02P6W2JL9Y`VW2@472@090E89DPUB2E8100YB -00h1DP5B0E81DP5B0E81DRL100]B0E81DP5B0E81DP020@YB00P12E89DPUB0@L900D12JL9Y`040081 -0@0001D000<100000P001PVW2JL90@RW00L12:L8Y`P100X80141200800P0200800P020080@0Q000@ -0@P0200800P0200800P00@X800T1Y`RW2:L8Y`401jL02P49Y`VW2JL9Y`472@090@UB2E89DPT100YB -0P403E81DP5B0E81DP5B0E809@403U81DP5B0E81DP5B0E812U80205B2E89DPT11`T01@6W2JL900D0 -0@4100005@000`4000020006Y`VW2JL12:L0206W2:L8Y`P12@P04@40200800P0200800P020010240 -010100P0200800P0200800P12@P02P6W2:L8Y`RW2047Y`0:0JL9Y`VW2JL90@L900X1DPUB2E89DPT1 -2E803P5B0E81DP5B0E81DP5B9@403E81DP5B0E81DP5B0E800P49DP090E89DPUB2E8100L900D12JL9 -Y`0500410@0001D000<100000P001PVW2JL90@RW00P12:L8Y`RW0@T80181200800P0200800P02008 -004O000A0@0800P0200800P0200800402@P02P48Y`RW2:L8Y`47Y`0:0@VW2JL9Y`VW0@L900X12E89 -DPUB2E812E820@0=DP5B0E81DP5B0E81DP0S0@0@DP5B0E81DP5B0E81DP5B0@UB00T12E89DPUB2@40 -1`T01@6W2JL900D00@4100005@000`4000020006Y`VW2JL12:L0206W2:L8Y`P12PP04@4800P02008 -00P0200800P101l00141200800P0200800P020080@09200:0JL8Y`RW2:L80@NW00X1Y`VW2JL9Y`T1 -1`T02P5B2E89DPUB2@4:DP8100eB0E81DP5B0E81DP5B02<100iB0E81DP5B0E81DP5B0@YB00T1DPUB -2E89DP401`T01@49Y`VW00D00@4100005@000`40000200062JL9Y`T12:L02048Y`RW2:L12PP04P40 -200800P0200800P020080Ad00141200800P0200800P020080@0:200:0@RW2:L8Y`RW0@NW00X12JL9 -Y`VW2JL11`T02P49DPUB2E89DP4:DP0@0E81DP5B0E81DP5B0E81DR4100eB0E81DP5B0E81DP5B0081 -2U802@49DPUB2E890@072@050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`48Y`080JL8Y`RW -204:200B0@P0200800P0200800P020017@004@40200800P0200800P0200100X800X1Y`RW2:L8Y`P1 -1jL02P6W2JL9Y`VW2@472@0:0E89DPUB2E890@YB0P403E81DP5B0E81DP5B0E808@404581DP5B0E81 -DP5B0E81DP4:DP090E89DPUB2E8100L900D12JL9Y`0500410@0001D000<100000P001PVW2JL90@RW -00T12:L8Y`RW20402PP04P4800P0200800P0200800P00A/0018100P0200800P0200800P02049200; -0JL8Y`RW2:L8Y`401jL02P49Y`VW2JL9Y`472@0;0@UB2E89DPUB2@402U820@0=DP5B0E81DP5B0E81 -DP0O0@0?DP5B0E81DP5B0E81DP5B00812E802P5B2E89DPUB2@472@050JL9Y`T01@010@40000E0003 -0@00008000JW2JL9Y`48Y`090JL8Y`RW2:L100X801<100P0200800P0200800P0200101P00P404@08 -00P0200800P0200800P100X800X12:L8Y`RW2:L12:L02P6W2JL9Y`VW2@482@0:0@UB2E89DPUB0@YB -0101DP5B0E81DP5B0E81DP5B7@403e81DP5B0E81DP5B0E81DP020@YB00T12E89DPUB2@4020T01@49 -Y`VW00D00@4100005@000`40000200062JL9Y`T12JL02@6W2:L8Y`RW0@0:200B0@0800P0200800P0 -200800P00P4E000D0@P0200800P0200800P020080049200;0@RW2:L8Y`RW20402:L02P49Y`VW2JL9 -Y`482@0;0E89DPUB2E89DP402U80405B0E81DP5B0E81DP5B0E8K0@0BDP5B0E81DP5B0E81DP5B0E81 -2E802P49DPUB2E89DP482@050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`49Y`0:0@RW2:L8 -Y`RW0@T801D1200800P0200800P0200800P020404`00504800P0200800P0200800P020012@P03048 -Y`RW2:L8Y`RW0@RW00X1Y`VW2JL9Y`T120T03049DPUB2E89DPUB0@UB0P404E81DP5B0E81DP5B0E81 -DP5B01L1019B0E81DP5B0E81DP5B0E81DP49DP0;0@UB2E89DPUB2@4020T01@49Y`VW00D00@410000 -5@000`40000200072JL9Y`VW0@08Y`0;0JL8Y`RW2:L8Y`402@P0504800P0200800P0200800P02008 -4`4050P0200800P0200800P0200800P12@P02`6W2:L8Y`RW2:L100VW00/12JL9Y`VW2JL90@082@0< -0@UB2E89DPUB2E812E820@0ADP5B0E81DP5B0E81DP5B0E805@404E81DP5B0E81DP5B0E81DP5B0081 -25803049DPUB2E89DPUB0@L900H12JL9Y`T500410@0001D000<100000P001jL9Y`VW2@402:L02`48 -Y`RW2:L8Y`P100T803X100P0200800P0200800P0200800P0200800P0200800P0200800P0200800P0 -200800P0200800P12@P0306W2:L8Y`RW2:L80@VW00/1Y`VW2JL9Y`VW0@082@0<0E89DPUB2E89DPT1 -2E80>05B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B -0P49DP0;0E89DPUB2E89DP4020T01P6W2JL9Y`D00@4100005@020@<000L9Y`VW2JL100VW00/12:L8 -Y`RW2:L80@09200i0@0800P0200800P0200800P0200800P0200800P0200800P0200800P0200800P0 -200800P0200100P800d1Y`RW2:L8Y`RW2:L100VW00/12JL9Y`VW2JL90@082@0=0@UB2E89DPUB2E89 -0@09DP0i0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B -0E8100QB00`1DPUB2E89DPUB2@482@060@VW2JL910020@40000E00030@00008000NW2JL9Y`T100VW -00`1Y`RW2:L8Y`RW2048208103@0200800P0200800P0200800P0200800P0200800P0200800P02008 -00P0200800P020080P49200<0@RW2:L8Y`RW2:L12ZL02`6W2JL9Y`VW2JL100T900d12E89DPUB2E89 -DPT100QB0P400@UB2E89DPUB2E89 -DP4:DP<102]B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00<12e803@49 -DPUB2E89DPUB2@402@T01P6W2JL9Y`D00@4100005@000`40000200072JL9Y`VW0@09Y`0>0@RW2:L8 -Y`RW2:L8Y`4<208102P800P0200800P0200800P0200800P0200800P0200800P0200800P00P4=200= -0JL8Y`RW2:L8Y`RW0@0:Y`0<0JL9Y`VW2JL9Y`T12PT03P49DPUB2E89DPUB2E812e820@0YDP5B0E81 -DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E800P40@UB2E89DPUB2E89DP492@06 -0@VW2JL91@010@40000E00030@00008000NW2JL9Y`T100ZW00h12:L8Y`RW2:L8Y`RW0@d80P409008 -00P0200800P0200800P0200800P0200800P0200800P020813PP03P6W2:L8Y`RW2:L8Y`P12ZL03049 -Y`VW2JL9Y`VW0@X900l1DPUB2E89DPUB2E89DP4035830@0SDP5B0E81DP5B0E81DP5B0E81DP5B0E81 -DP5B0E81DP5B0E800`4=DP0?0@UB2E89DPUB2E89DPT100T900H1Y`VW2JL500410@0001D000<10000 -0P001`VW2JL9Y`402ZL03P6W2:L8Y`RW2:L8Y`P13`P20@0P200800P0200800P0200800P0200800P0 -200800P020020@l800l1Y`RW2:L8Y`RW2:L8Y`402ZL0306W2JL9Y`VW2JL90@X900l12E89DPUB2E89 -DPUB2@403U820@0QDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00813e803P5B2E89DPUB -2E89DPT12PT01P49Y`VW2@D00@4100005@000`4000020008Y`VW2JL9Y`49Y`0?0@RW2:L8Y`RW2:L8 -Y`P101080P40700800P0200800P0200800P0200800P0200800P20A4800h12:L8Y`RW2:L8Y`RW0@^W -00d12JL9Y`VW2JL9Y`T100X900l12E89DPUB2E89DPUB2@403e830@0KDP5B0E81DP5B0E81DP5B0E81 -DP5B0E81DP5B00<145803`5B2E89DPUB2E89DPUB0@092@070@VW2JL9Y`0500410@0001D000<10000 -0P0020VW2JL9Y`T12JL0406W2:L8Y`RW2:L8Y`RW204A208101P800P0200800P0200800P0200800P0 -20020A8800l12:L8Y`RW2:L8Y`RW20402jL03@6W2JL9Y`VW2JL9Y`402PT0405B2E89DPUB2E89DPUB -2@4@DP8101UB0E81DP5B0E81DP5B0E81DP5B0E81DP5B00814E80405B2E89DPUB2E89DPUB2@492@07 -0JL9Y`VW2@0500410@0001D000<100000P002:L9Y`VW2JL12ZL0406W2:L8Y`RW2:L8Y`RW204B2081 -01@0200800P0200800P0200800P020814`P04048Y`RW2:L8Y`RW2:L8Y`4;Y`0=0@VW2JL9Y`VW2JL9 -0@0:2@0A0@UB2E89DPUB2E89DPUB2@404E830@0CDP5B0E81DP5B0E81DP5B0E81DP030A9B0141DPUB -2E89DPUB2E89DPUB0@092@070@VW2JL9Y`0500410@0001D000<100000P0020VW2JL9Y`T12ZL04048 -Y`RW2:L8Y`RW2:L8Y`4D21@15@P03`6W2:L8Y`RW2:L8Y`RW0@0PP20@0?Y`RW2:L8Y`RW2:L8 -Y`P100bW00d12JL9Y`VW2JL9Y`T100/90141DPUB2E89DPUB2E89DPUB0@0iDP8100h9DPUB2E89DPUB -2E89DP812PT01`49Y`VW2JL01@010@40000E00030@00008000T9Y`VW2JL9Y`402jL03`48Y`RW2:L8 -Y`RW2:L8Y`030C@80`403PRW2:L8Y`RW2:L8Y`RW0P4Y`0?0JL9Y`VW2JL9Y`VW2JL100d901412E89DPUB2E89DPUB2E89DP030BiB0`403`UB2E89DPUB -2E89DPUB2@020@`900P1Y`VW2JL9Y`@00P4100005@000`400002000:2JL9Y`VW2JL90@fW0181Y`RW -2:L8Y`RW2:L8Y`RW2:L30BP80`404`RW2:L8Y`RW2:L8Y`RW2:L8Y`403ZL04@6W2JL9Y`VW2JL9Y`VW -2JL100d901<12E89DPUB2E89DPUB2E89DPUB00<1:5830@0B2E89DPUB2E89DPUB2E89DPT13@T02@6W -2JL9Y`VW2@0500410@0001D000<100000P002ZL9Y`VW2JL9Y`4>Y`0D0JL8Y`RW2:L8Y`RW2:L8Y`RW -2:L40B480`404`RW2:L8Y`RW2:L8Y`RW2:L8Y`P00P4>Y`0B0JL9Y`VW2JL9Y`VW2JL9Y`T13PT20@0C -DPUB2E89DPUB2E89DPUB2E89DP030B9B0`4050UB2E89DPUB2E89DPUB2E89DPT13PT02@49Y`VW2JL9 -Y`0500410@0001D000<100000P002`VW2JL9Y`VW2JL100jW0P405@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -20030A/80`405PRW2:L8Y`RW2:L8Y`RW2:L8Y`RW204@Y`0C0@VW2JL9Y`VW2JL9Y`VW2JL90@0?2@0F -0E89DPUB2E89DPUB2E89DPUB2E89DP<175830@0D2E89DPUB2E89DPUB2E89DPUB2E820@h900X12JL9 -Y`VW2JL91@010@40000E00030@00008000bW2JL9Y`VW2JL9Y`4?Y`0H0@RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L80`4E20<101H8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0P4@Y`0E0@VW2JL9Y`VW2JL9Y`VW2JL9 -Y`T100l901P1DPUB2E89DPUB2E89DPUB2E89DPUB2E830AIB0`405`UB2E89DPUB2E89DPUB2E89DPUB -2E81010900X1Y`VW2JL9Y`VW1@010@40000E00030@00008000`9Y`VW2JL9Y`VW2@4@Y`0J0@RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`PE0@0I2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@0AY`0F0@VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW0A090P4060UB2E89DPUB2E89DPUB2E89DPUB2E89DQH101T9DPUB2E89DPUB -2E89DPUB2E89DPUB2E81010900/1Y`VW2JL9Y`VW2@0500410@0001D000<100000P003JL9Y`VW2JL9 -Y`VW2@404:L20@14Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`4BY`0G0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`404@T0A049DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -0P4A2@0;0@VW2JL9Y`VW2JL01@010@40000E00030@00008000h9Y`VW2JL9Y`VW2JL90A6W0441Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -20020A:W01T1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL101490P40@E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT1018900`12JL9Y`VW2JL9 -Y`T500410@0001D000<100000P003ZL9Y`VW2JL9Y`VW2JL14ZL0@06W2:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW204CY`0J0JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2@4C2@100E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB -2E89DPUB2E89DPUB2E89DPUB2E890A8900d12JL9Y`VW2JL9Y`VW00D00@4100005@000`400002000? -2JL9Y`VW2JL9Y`VW2JL101:W0P40?0RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80ABW01/12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@404`T0?05B -2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP81 -4`T03@6W2JL9Y`VW2JL9Y`T01@010@40000E00030@00008000nW2JL9Y`VW2JL9Y`VW2@405:L0>@48 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`020ABW -01`12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL150T20@0i2E89DPUB2E89DPUB2E89DPUB2E89DPUB -2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E8101@900h1Y`VW2JL9Y`VW2JL9Y`D00@410000 -5@000`400002000@2JL9Y`VW2JL9Y`VW2JL90ABW1040<:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20@15JL07P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0AD9 -0`40<@UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT0104E2@0> -0@VW2JL9Y`VW2JL9Y`T500410@0001D000<100000P004JL9Y`VW2JL9Y`VW2JL9Y`T101NW1P4090RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`H16JL07`6W2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`405`T60@0UDPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP060AP9 -00l12JL9Y`VW2JL9Y`VW2JL01@010@40000E00810`004@VW2JL9Y`VW2JL9Y`VW2JL101fW1P406:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20H17ZL0806W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T1 -7@T60@0I2E89DPUB2E89DPUB2E89DPUB2E89DPUB2@060Ah900l1Y`VW2JL9Y`VW2JL9Y`T010020@40 -000E00030@00008001:W2JL9Y`VW2JL9Y`VW2JL9Y`4RYaP18jL08P6W2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2@4R2AT18`T0406W2JL9Y`VW2JL9Y`VW2JL500410@0001D000<100000P004PVW -2JL9Y`VW2JL9Y`VW2JL90EfW02812JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1GPT04049 -Y`VW2JL9Y`VW2JL9Y`T500410@0001D000<100000P004jL9Y`VW2JL9Y`VW2JL9Y`VW2@40FjL09049 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0E`901412JL9Y`VW2JL9Y`VW2JL9Y`050041 -0@0001D000<100000P004PVW2JL9Y`VW2JL9Y`VW2JL9Y`<1EJL40@0T2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW0`5E2@@10149Y`VW2JL9Y`VW2JL9Y`VW2@0500410@0001D000<10000 -0P005JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`060DVW1P40:jL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL01P592@H101FW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL01@010@40000E0003 -0@00008001/9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T01P4mY`H103L9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900H1?@T60@0K2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL900D00@4100005@000`400002000QY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW00d19:L<0@13Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`0<0BD930408JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`0500410@0001D000<100000P00;PVW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JLT0@1K2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@0U0@0]2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900D00@4100005@000`400002003o -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW00D00@4100005@000`400002003o2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900D00@410000 -0P020@@000<100000P030@D000<100000P00ojL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`0500410@00000500400040 -2`000`40000200810`00o`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@0400810@000005004000402`000`4000020003 -0@0000800?nW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL01@010@4000001@01000100P00`4500030@0000800?l9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`T01@010@4000001@01000100P000<100001@000`400002003oY`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW00D00@41000000D00@000@0800030@0000D000<100000P00;PVW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JLT0@1K2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2@0U0@0]2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900D00@410000 -0P020@T0104400030@00008002:W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9304T2@`1 -04BW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2@/19JL<0@0QY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00D00@410000 -5@000`400002000N2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW104l2@@103`9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL40CbW10407@VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900D00@4100005@000`400002000IY`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`050D@91@40W -6@4TY`0?0JL9Y`VW2JL9Y`VW2JL900D00@4100005@020@<0016W2JL9Y`VW2JL9Y`VW2JL90@0M2@H1 -01P9DPUB2E89DPUB2E89DPUB2E89DPUB2E860Al901l1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL101fW1P406JL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L01P4NY`0?0@VW2JL9Y`VW2JL9Y`VW00@0 -0P4100005@000`400002000@2JL9Y`VW2JL9Y`VW2JL90AP91P409589DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2@H16@T07P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0ARW1P409@RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P01P4IY`0>0@VW2JL9Y`VW2JL9Y`T50041 -0@0001D000<100000P004:L9Y`VW2JL9Y`VW2JL9Y`4D2@@10309DPUB2E89DPUB2E89DPUB2E89DPUB -2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E840AH901d12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -0@0EY`<1036W2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW00@1 -5JL03P6W2JL9Y`VW2JL9Y`VW1@010@40000E00030@00008000l9Y`VW2JL9Y`VW2JL9Y`4050T0>@5B -2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2@020A@9 -01`1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T15:L20@0iY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P101FW00d1Y`VW2JL9Y`VW2JL900D00@410000 -5@000`400002000>Y`VW2JL9Y`VW2JL9Y`4C2@8103aB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP4D2@0J0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2@4DY`0l0@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L80P4CY`0=0@VW2JL9Y`VW2JL9Y`0500410@0001D000<100000P003PVW2JL9Y`VW2JL9Y`T1 -4PT0@049DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DP4D2@0I0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@0CY`100@RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0A>W00`12JL9Y`VW2JL9 -Y`T500410@0001D000<100000P003JL9Y`VW2JL9Y`VW2@404PT0@@49DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB00814PT06049Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW0A:W0P40@@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L101:W00`1Y`VW2JL9Y`VW2JL500410@0001D000<10000 -0P003@VW2JL9Y`VW2JL9Y`4040T20@0G2E89DPUB2E89DPUB2E89DPUB2E89DPT05@4060UB2E89DPUB -2E89DPUB2E89DPUB2E890A8901L12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@0AY`0H0JL8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW5P405PRW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L20A6W00/1Y`VW2JL9Y`VW2@050041 -0@0001D000<100000P003:L9Y`VW2JL9Y`VW0A0901L1DPUB2E89DPUB2E89DPUB2E89DPUB2@030AEB -0`405PUB2E89DPUB2E89DPUB2E89DPUB2@4B2@0E0@VW2JL9Y`VW2JL9Y`VW2JL9Y`T1012W0P405JL8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`030AH80`405PRW2:L8Y`RW2:L8Y`RW2:L8Y`RW204@Y`0;0@VW2JL9 -Y`VW2JL01@010@40000E00030@00008000/9Y`VW2JL9Y`VW0@0@2@0E0E89DPUB2E89DPUB2E89DPUB -2E8900<16e830@0C2E89DPUB2E89DPUB2E89DPUB2@020A0901@1Y`VW2JL9Y`VW2JL9Y`VW2JL90A2W -01D12:L8Y`RW2:L8Y`RW2:L8Y`RW2:L00`4L20<101@8Y`RW2:L8Y`RW2:L8Y`RW2:L80A2W00X12JL9 -Y`VW2JL91@010@40000E00030@00008000^W2JL9Y`VW2JL90@0>2@81015B2E89DPUB2E89DPUB2E89 -DP040B5B0`404`UB2E89DPUB2E89DPUB2E89DP4040T04`6W2JL9Y`VW2JL9Y`VW2JL9Y`403jL04`48 -Y`RW2:L8Y`RW2:L8Y`RW2:L00`4R20<10148Y`RW2:L8Y`RW2:L8Y`RW20020@jW00X1Y`VW2JL9Y`VW -1@010@40000E00030@00008000X9Y`VW2JL9Y`T13PT04@49DPUB2E89DPUB2E89DPUB00<1:5830@0@ -2E89DPUB2E89DPUB2E89DP813PT04P49Y`VW2JL9Y`VW2JL9Y`VW0@jW0P4040RW2:L8Y`RW2:L8Y`RW -2:L30BP80`404@RW2:L8Y`RW2:L8Y`RW2:L100jW00T1Y`VW2JL9Y`T01@010@40000E00030@000080 -00ZW2JL9Y`VW2JL13@T03`49DPUB2E89DPUB2E89DP030BiB0`4040UB2E89DPUB2E89DPUB2@4>2@0A -0@VW2JL9Y`VW2JL9Y`VW2@403JL0406W2:L8Y`RW2:L8Y`RW2:L30Bh80`403`RW2:L8Y`RW2:L8Y`RW -0@0=Y`090@VW2JL9Y`VW00D00@4100005@020@<000T9Y`VW2JL9Y`4030T20@0=2E89DPUB2E89DPUB -2@020CAB0P403e89DPUB2E89DPUB2E890@0>2@0?0@VW2JL9Y`VW2JL9Y`T100fW00l1Y`RW2:L8Y`RW -2:L8Y`P00P4d208100fW2:L8Y`RW2:L8Y`RW00813:L02049Y`VW2JL910020@40000E00030@000080 -00VW2JL9Y`VW2@402`T0405B2E89DPUB2E89DPUB2@4hDP8100d9DPUB2E89DPUB2E89008130T03`6W -2JL9Y`VW2JL9Y`VW0@0;Y`8100nW2:L8Y`RW2:L8Y`RW2040>0P0406W2:L8Y`RW2:L8Y`RW204;Y`08 -0JL9Y`VW2JL500410@0001D000<100000P0020VW2JL9Y`T12PT20@0?DPUB2E89DPUB2E89DPT103]B -01012E89DPUB2E89DPUB2E8130T03@6W2JL9Y`VW2JL9Y`402jL04@48Y`RW2:L8Y`RW2:L8Y`P103X8 -00l1Y`RW2:L8Y`RW2:L8Y`P00P4:Y`070JL9Y`VW2@0500410@0001D000<100000P002:L9Y`VW2JL1 -2PT0405B2E89DPUB2E89DPUB2@4DDQ@15E803`49DPUB2E89DPUB2E890@0<2@0=0@VW2JL9Y`VW2JL9 -0@0;Y`0@0JL8Y`RW2:L8Y`RW2:L80A<85@4D200@0JL8Y`RW2:L8Y`RW2:L80@ZW00L12JL9Y`VW00D0 -0@4100005@000`40000200082JL9Y`VW2@4:2@0@0@UB2E89DPUB2E89DPUB0A9B0`404e81DP5B0E81 -DP5B0E81DP5B0E800P4CDP0@0E89DPUB2E89DPUB2E890@/900d1Y`VW2JL9Y`VW2JL100ZW0141Y`RW -2:L8Y`RW2:L8Y`RW0@0A208101D0200800P0200800P0200800P020000P4B200A0@RW2:L8Y`RW2:L8 -Y`RW20402JL01`6W2JL9Y`T01@010@40000E00030@00008000RW2JL9Y`VW0@T901012E89DPUB2E89 -DPUB2E814E820@0GDP5B0E81DP5B0E81DP5B0E81DP5B0E800`4BDP0?0E89DPUB2E89DPUB2E8100/9 -00d12JL9Y`VW2JL9Y`T100ZW01012:L8Y`RW2:L8Y`RW2:L140P20@0I200800P0200800P0200800P0 -200800P020020A4801012:L8Y`RW2:L8Y`RW2:L12JL01`49Y`VW2JL01@010@40000E00030@000080 -00P9Y`VW2JL90@T900l1DPUB2E89DPUB2E89DP4045830@0KDP5B0E81DP5B0E81DP5B0E81DP5B0E81 -DP5B00814E803P5B2E89DPUB2E89DPT12`T03@6W2JL9Y`VW2JL9Y`402ZL03`6W2:L8Y`RW2:L8Y`RW -0@0?208101d0200800P0200800P0200800P0200800P0200800020A0800l12:L8Y`RW2:L8Y`RW2040 -2JL01`6W2JL9Y`T01@010@40000E00030@00008000NW2JL9Y`T100X900h12E89DPUB2E89DPUB0@mB -0P407e81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E800`4?DP0?0@UB2E89DPUB2E89DPT100X9 -00`12JL9Y`VW2JL9Y`4:Y`0?0JL8Y`RW2:L8Y`RW2:L100h80P408@P0200800P0200800P0200800P0 -200800P0200800P020020@l800h12:L8Y`RW2:L8Y`RW0@ZW00H1Y`VW2JL500410@0001D000<10000 -0P001`VW2JL9Y`402PT03P5B2E89DPUB2E89DPT13E830@0SDP5B0E81DP5B0E81DP5B0E81DP5B0E81 -DP5B0E81DP5B0E800P4>DP0>0@UB2E89DPUB2E89DP4:2@0<0JL9Y`VW2JL9Y`T12ZL03`48Y`RW2:L8 -Y`RW2:L80@0<208102D0200800P0200800P0200800P0200800P0200800P0200800P000813@P03`6W -2:L8Y`RW2:L8Y`RW0@09Y`060@VW2JL91@010@40000E00030@00008000NW2JL9Y`T100T900h1DPUB -2E89DPUB2E890@aB0P409e81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP030@eB -00d12E89DPUB2E89DPT100X900`12JL9Y`VW2JL9Y`4:Y`0>0JL8Y`RW2:L8Y`RW204;208102T800P0 -200800P0200800P0200800P0200800P0200800P0200800P020020@`800h1Y`RW2:L8Y`RW2:L80@VW -00H1Y`VW2JL500410@0001D000<100000P001`VW2JL9Y`402@T03@49DPUB2E89DPUB2@402e830@0[ -DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@]B00h1DPUB2E89DPUB -2E890@T900`1Y`VW2JL9Y`VW2@49Y`0>0JL8Y`RW2:L8Y`RW204:208102d0200800P0200800P02008 -00P0200800P0200800P0200800P0200800P020000P4;200=0JL8Y`RW2:L8Y`RW0@09Y`060@VW2JL9 -1@010@40000E00030@00008000NW2JL9Y`T100T900d1DPUB2E89DPUB2E8100UB0P40;e81DP5B0E81 -DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00<12U803@5B2E89DPUB2E89DP40 -2PT02`6W2JL9Y`VW2JL100VW00h12:L8Y`RW2:L8Y`RW0@P80P40<@P0200800P0200800P0200800P0 -200800P0200800P0200800P0200800P0200800P00P4:200=0JL8Y`RW2:L8Y`RW0@08Y`060JL9Y`VW -1@010@40000E00030@00008000L9Y`VW2JL100T900`12E89DPUB2E89DP48DP<103=B0E81DP5B0E81 -DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E800P49DP0<0E89DPUB2E89DPT1 -2PT02`49Y`VW2JL9Y`T100VW00d1Y`RW2:L8Y`RW2:L100P803H100P0200800P0200800P0200800P0 -200800P0200800P0200800P0200800P0200800P020020@P800d12:L8Y`RW2:L8Y`P100RW00H12JL9 -Y`T500410@0001D00P430007Y`VW2JL90@092@0;0E89DPUB2E89DP402E820@0eDP5B0E81DP5B0E81 -DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E800P48DP0=0@UB2E89DPUB2E89 -0@092@0;0JL9Y`VW2JL9Y`402:L03@6W2:L8Y`RW2:L8Y`402@P0>@4800P0200800P0200800P02008 -00P0200800P0200800P0200800P0200800P0200800P020080@08200<0@RW2:L8Y`RW2:L12:L01P6W -2JL9Y`@00P4100005@000`40000200072JL9Y`VW0@082@0;0E89DPUB2E89DP402E820@0hDP5B0E81 -DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP49DP0<0@UB2E89 -DPUB2E812@T02`49Y`VW2JL9Y`T100RW00`12:L8Y`RW2:L8Y`49200j0@P0200800P0200800P02008 -00P0200800P0200800P0200800P0200800P0200800P0200800P00@T800/12:L8Y`RW2:L80@08Y`06 -0@VW2JL91@010@40000E00030@00008000NW2JL9Y`T100P900/12E89DPUB2E890@09DP0D0E81DP5B -0E81DP5B0E81DP5B0E8C0@0DDP5B0E81DP5B0E81DP5B0E81DP49DP0;0@UB2E89DPUB2@402@T02`6W -2JL9Y`VW2JL100RW00`1Y`RW2:L8Y`RW2049200C0@0800P0200800P0200800P0200D0@0D00P02008 -00P0200800P020080048200<0JL8Y`RW2:L8Y`P11jL01P6W2JL9Y`D00@4100005@000`4000020006 -2JL9Y`T12@T02P5B2E89DPUB2@49DP0D0E81DP5B0E81DP5B0E81DP5B0E8E0@0ADP5B0E81DP5B0E81 -DP5B0E800P49DP0<0E89DPUB2E89DPT120T02P49Y`VW2JL9Y`48Y`0<0JL8Y`RW2:L8Y`P12@P05040 -200800P0200800P0200800P150005040200800P0200800P0200800P12@P02`6W2:L8Y`RW2:L100RW -00D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@T900T12E89DPUB2@402U820@0?DP5B0E81 -DP5B0E81DP5B01T1015B0E81DP5B0E81DP5B0E81DP020@UB00/1DPUB2E89DPUB0@082@0:0JL9Y`VW -2JL90@RW00/12:L8Y`RW2:L80@0:200A0@P0200800P0200800P020000P4F000D0@0800P0200800P0 -200800P02049200:0JL8Y`RW2:L80@RW00D12JL9Y`0500410@0001D000<100000P001PVW2JL90@P9 -00T12E89DPUB2@402U820@0?DP5B0E81DP5B0E81DP5B01d1011B0E81DP5B0E81DP5B0E812U802P5B -2E89DPUB2@482@0:0@VW2JL9Y`VW0@RW00X1Y`RW2:L8Y`P12PP04P4800P0200800P0200800P00AT0 -0P404@P0200800P0200800P0200100X800T1Y`RW2:L8Y`402:L01@6W2JL900D00@4100005@000`40 -00020006Y`VW2JL120T02@5B2E89DPUB0@0:DP0@0E81DP5B0E81DP5B0E81DQl1011B0E81DP5B0E81 -DP5B0E812E802`49DPUB2E89DPT100L900X1Y`VW2JL9Y`T11jL02`6W2:L8Y`RW2:L100X8014100P0 -200800P0200800P00@0L000B0@P0200800P0200800P020012@P02P48Y`RW2:L8Y`47Y`050@VW2JL0 -1@010@40000E00030@00008000H9Y`VW2@482@080@UB2E89DP4:DP0@0E81DP5B0E81DP5B0E81DR41 -00eB0E81DP5B0E81DP5B00812U802P49DPUB2E89DP472@0:0@VW2JL9Y`VW0@NW00X12:L8Y`RW2:L1 -2PP04@40200800P0200800P0200101h00141200800P0200800P020080@0:20090@RW2:L8Y`P100NW -00D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@P900P1DPUB2E890@YB0P403e81DP5B0E81 -DP5B0E81DP0O0@0@DP5B0E81DP5B0E81DP5B0@YB00X1DPUB2E89DPT11`T02P6W2JL9Y`VW2@47Y`0: -0JL8Y`RW2:L80@X80141200800P0200800P020080@0N000A0@0800P0200800P0200800402PP02@6W -2:L8Y`RW0@07Y`050@VW2JL01@010@40000E00030@00008000H9Y`VW2@482@080@UB2E89DP4:DP0@ -0E81DP5B0E81DP5B0E81DR41011B0E81DP5B0E81DP5B0E812E802P49DPUB2E89DP472@0:0@VW2JL9 -Y`VW0@NW00X12:L8Y`RW2:L12PP04040200800P0200800P0204P000@0@0800P0200800P020080@X8 -00T12:L8Y`RW20401jL01@6W2JL900D00@4100005@000`4000020006Y`VW2JL120T0205B2E89DPT1 -2E80405B0E81DP5B0E81DP5B0E8S0@0=DP5B0E81DP5B0E81DP020@UB00X1DPUB2E89DPT11`T02P6W -2JL9Y`VW2@47Y`0:0JL8Y`RW2:L80@T8014100P0200800P0200800P00@0P000A0@P0200800P02008 -00P020402@P02@6W2:L8Y`RW0@07Y`050@VW2JL01@010@40000E00030@00008000H9Y`VW2@482@08 -0@UB2E89DP49DP8100eB0E81DP5B0E81DP5B02D100iB0E81DP5B0E81DP5B0@UB00X12E89DPUB2E81 -1`T02P49Y`VW2JL9Y`47Y`0:0@RW2:L8Y`RW0@T80101200800P0200800P020018P00404800P02008 -00P02008004920090@RW2:L8Y`P100NW00D1Y`VW2@0500410@0001D00P430006Y`VW2JL120T01`5B -2E89DP402U80405B0E81DP5B0E81DP5B0E8S0@0=DP5B0E81DP5B0E81DP020@YB00T12E89DPUB2@40 -1`T02P6W2JL9Y`VW2@47Y`090JL8Y`RW2:L100X8010100P0200800P0200800P18P004040200800P0 -200800P0204:20080@RW2:L8Y`47Y`050@VW2JL010020@40000E00030@00008000H9Y`VW2@482@07 -0@UB2E890@0:DP8100eB0E81DP5B0E81DP5B02D100eB0E81DP5B0E81DP5B00812E802@5B2E89DPUB -0@072@0:0@VW2JL9Y`VW0@NW00T12:L8Y`RW20402PP03`4800P0200800P020080@0T000?0@0800P0 -200800P0200100X800P1Y`RW2:L80@NW00D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@P9 -00L1DPUB2E8100UB0P403E81DP5B0E81DP5B0E809`403U81DP5B0E81DP5B0E812E802@49DPUB2E89 -0@072@0:0JL9Y`VW2JL90@NW00T1Y`RW2:L8Y`402@P0404800P0200800P02008004T000@0@P02008 -00P0200800P00@T800P12:L8Y`RW0@NW00D12JL9Y`0500410@0001D000<100000P001PVW2JL90@P9 -00L12E89DPT100UB00h1DP5B0E81DP5B0E81DRT100]B0E81DP5B0E81DP020@UB00T1DPUB2E89DP40 -1`T02P49Y`VW2JL9Y`47Y`090@RW2:L8Y`P100T800l100P0200800P0200800409P003`4800P02008 -00P020080@0920080JL8Y`RW2047Y`050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`482@07 -0E89DPUB0@09DP8100eB0E81DP5B0E81DP5B02L100eB0E81DP5B0E81DP5B008125802P49DPUB2E89 -DP472@090@VW2JL9Y`T100NW00T1Y`RW2:L8Y`402@P03`4800P0200800P020080@0V000?0@0800P0 -200800P0200100T800T12:L8Y`RW20401ZL01@49Y`VW00D00@4100005@000`40000200062JL9Y`T1 -1`T0205B2E89DPT12E803P5B0E81DP5B0E81DP5B:@403U81DP5B0E81DP5B0E8125802P5B2E89DPUB -2@472@080JL9Y`VW2@47Y`0:0JL8Y`RW2:L80@T800l100P0200800P0200800409P003`4800P02008 -00P020080@0920090JL8Y`RW2:L100JW00D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@L9 -00P12E89DPUB0@UB0P402e81DP5B0E81DP5B02/100]B0E81DP5B0E81DP020@QB00X12E89DPUB2E81 -1`T02049Y`VW2JL11jL02P48Y`RW2:L8Y`49200>0@P0200800P02008004X000>0@P0200800P02008 -004920090@RW2:L8Y`P100JW00D12JL9Y`0500410@0001D000<100000P001PVW2JL90@L900P1DPUB -2E890@QB0P402e81DP5B0E81DP5B02/100iB0E81DP5B0E81DP5B0@QB00X1DPUB2E89DPT11`T0206W -2JL9Y`T11jL02P6W2:L8Y`RW2048200?0@P0200800P0200800P102P000l100P0200800P020080040 -20P02@6W2:L8Y`RW0@06Y`050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`472@080@UB2E89 -DP48DP0>0E81DP5B0E81DP5B0E8[0@0>DP5B0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@L900P12JL9 -Y`VW0@NW00X12:L8Y`RW2:L120P03P40200800P0200800P1:P003P40200800P0200800P120P02@48 -Y`RW2:L80@06Y`050@VW2JL01@010@40000E00030@00008000H9Y`VW2@472@070E89DPUB0@09DP81 -00]B0E81DP5B0E81DP0]0@0;DP5B0E81DP5B0E800P48DP090@UB2E89DPT100L900P1Y`VW2JL90@NW -00T1Y`RW2:L8Y`402@P03P4800P0200800P02001:P003P4800P0200800P020012@P02048Y`RW2:L1 -1ZL01@6W2JL900D00@4100005@000`4000020006Y`VW2JL11`T01`49DPUB2@402E80305B0E81DP5B -0E81DRl100aB0E81DP5B0E81DP48DP090E89DPUB2E8100L900P12JL9Y`VW0@NW00T12:L8Y`RW2040 -2@P03@40200800P020080040;0003@4800P0200800P020402@P0206W2:L8Y`P11ZL01@49Y`VW00D0 -0@4100005@000`40000200062JL9Y`T11`T01`5B2E89DP402580305B0E81DP5B0E81DRl100]B0E81 -DP5B0E81DP020@QB00T12E89DPUB2@401`T0206W2JL9Y`T11jL02@6W2:L8Y`RW0@08200>0@0800P0 -200800P0204/000>0@0800P0200800P0204820080@RW2:L8Y`46Y`050JL9Y`T01@010@40000=00@1 -10000`4000020006Y`VW2JL11`T01`49DPUB2@4025820@0;DP5B0E81DP5B0E80;`402e81DP5B0E81 -DP5B00811e802@5B2E89DPUB0@072@080@VW2JL9Y`47Y`090@RW2:L8Y`P100P800d1200800P02008 -00P102h000d100P0200800P0200100P800P1Y`RW2:L80@JW00D12JL9Y`0500410@0000l000<10000 -0`020@<000H9Y`VW2@472@070E89DPUB0@08DP0<0E81DP5B0E81DP5B<@403581DP5B0E81DP5B0@MB -00T12E89DPUB2@401`T0206W2JL9Y`T11jL02@6W2:L8Y`RW0@08200=0@0800P0200800P00@0^000= -0@P0200800P020080@0820080@RW2:L8Y`46Y`050JL9Y`T010020@40000?00030@0000<000<10000 -0P001ZL9Y`VW0@L900L12E89DPT100QB0P402e81DP5B0E81DP5B02l100]B0E81DP5B0E81DP020@MB -00T1DPUB2E89DP401`T02049Y`VW2JL11jL02@48Y`RW2:L80@08200=0@P0200800P020080@0^000= -0@0800P0200800P00@0820080JL8Y`RW2046Y`050@VW2JL01@010@40000?00030@0000<000<10000 -0P001PVW2JL90@L900L1DPUB2E8100QB00`1DP5B0E81DP5B0E8_0@0;DP5B0E81DP5B0E800P48DP09 -0@UB2E89DPT100L900P1Y`VW2JL90@NW00T1Y`RW2:L8Y`4020P03P40200800P0200800P1;0003P40 -200800P0200800P120P02048Y`RW2:L11ZL01@6W2JL900D00@4100003`000`40000300030@000080 -00JW2JL9Y`472@070@UB2E890@09DP0<0E81DP5B0E81DP5B;`403581DP5B0E81DP5B0@QB00T1DPUB -2E89DP401`T02049Y`VW2JL11jL02@48Y`RW2:L80@09200=0@0800P0200800P00@0/000=0@P02008 -00P020080@0920080JL8Y`RW2046Y`050@VW2JL01@010@40000=00<11@000`40000200062JL9Y`T1 -1`T01`5B2E89DP402E820@0;DP5B0E81DP5B0E80;@402e81DP5B0E81DP5B008125802@49DPUB2E89 -0@072@080JL9Y`VW2@47Y`090JL8Y`RW2:L100T800h1200800P0200800P00BX000h1200800P02008 -00P00@T800P12:L8Y`RW0@JW00D1Y`VW2@0500410@0000l000<100000`000`4000020006Y`VW2JL1 -1`T02049DPUB2E8125803P5B0E81DP5B0E81DP5B:`403U81DP5B0E81DP5B0E811e802P49DPUB2E89 -DP472@080@VW2JL9Y`47Y`0:0@RW2:L8Y`RW0@P800h100P0200800P020080BX000h100P0200800P0 -20080@P800T12:L8Y`RW20401ZL01@49Y`VW00D00@4100005@000`40000200062JL9Y`T11`T0205B -2E89DPT125820@0;DP5B0E81DP5B0E80:`403U81DP5B0E81DP5B0E8125802P5B2E89DPUB2@472@08 -0JL9Y`VW2@47Y`0:0JL8Y`RW2:L80@P800l1200800P0200800P02040:0003`40200800P0200800P0 -0@0820090JL8Y`RW2:L100JW00D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@L900P12E89 -DPUB0@UB0P402e81DP5B0E81DP5B02/100]B0E81DP5B0E81DP020@QB00X12E89DPUB2E811`T02049 -Y`VW2JL11jL02P48Y`RW2:L8Y`49200>0@P0200800P02008004X000>0@P0200800P0200800492009 -0@RW2:L8Y`P100JW00D12JL9Y`0500410@0001D000<100000P001PVW2JL90@L900P1DPUB2E890@UB -00h1DP5B0E81DP5B0E81DRT100iB0E81DP5B0E81DP5B0@QB00X1DPUB2E89DPT11`T0206W2JL9Y`T1 -1jL02P6W2:L8Y`RW2049200?0@0800P0200800P0200102H000l1200800P0200800P020402@P02@6W -2:L8Y`RW0@06Y`050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`482@070E89DPUB0@09DP81 -00eB0E81DP5B0E81DP5B02L100eB0E81DP5B0E81DP5B008125802P49DPUB2E89DP472@090@VW2JL9 -Y`T100NW00T1Y`RW2:L8Y`402@P03`4800P0200800P020080@0V000?0@0800P0200800P0200100T8 -00T12:L8Y`RW20401ZL01@49Y`VW00D00@4100005@000`40000200062JL9Y`T120T01`49DPUB2@40 -2E803P5B0E81DP5B0E81DP5B:@402e81DP5B0E81DP5B00812E802@5B2E89DPUB0@072@0:0@VW2JL9 -Y`VW0@NW00T12:L8Y`RW20402@P03`40200800P0200800P00@0V000?0@P0200800P0200800P100T8 -00P1Y`RW2:L80@NW00D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@P900L1DPUB2E8100UB -0P403E81DP5B0E81DP5B0E809`403U81DP5B0E81DP5B0E812E802@49DPUB2E890@072@0:0JL9Y`VW -2JL90@NW00T1Y`RW2:L8Y`402@P0404800P0200800P02008004T000@0@P0200800P0200800P00@T8 -00P12:L8Y`RW0@NW00D12JL9Y`0500410@0001D000<100000P001PVW2JL90@P900L12E89DPT100YB -0P403E81DP5B0E81DP5B0E809@403E81DP5B0E81DP5B0E800P49DP090E89DPUB2E8100L900X12JL9 -Y`VW2JL11jL02@48Y`RW2:L80@0:200?0@P0200800P0200800P102@000l100P0200800P020080040 -2PP0206W2:L8Y`P11jL01@6W2JL900D00@4100005@020@<000JW2JL9Y`482@070E89DPUB0@0:DP0@ -0E81DP5B0E81DP5B0E81DR<100eB0E81DP5B0E81DP5B00812U802@49DPUB2E890@072@0:0JL9Y`VW -2JL90@NW00T1Y`RW2:L8Y`402PP04040200800P0200800P0204R000@0@0800P0200800P020080@X8 -00P12:L8Y`RW0@NW00D12JL9Y`0400810@0001D000<100000P001PVW2JL90@P900P12E89DPUB0@UB -0P403E81DP5B0E81DP5B0E809@403U81DP5B0E81DP5B0E812E802P49DPUB2E89DP472@0:0@VW2JL9 -Y`VW0@NW00X12:L8Y`RW2:L12@P0404800P0200800P02008004R000@0@P0200800P0200800P00@T8 -00T12:L8Y`RW20401jL01@6W2JL900D00@4100005@000`4000020006Y`VW2JL120T0205B2E89DPT1 -2E80405B0E81DP5B0E81DP5B0E8S0@0=DP5B0E81DP5B0E81DP020@UB00X1DPUB2E89DPT11`T02P6W -2JL9Y`VW2@47Y`0:0JL8Y`RW2:L80@T8014100P0200800P0200800P00@0P000A0@P0200800P02008 -00P020402@P02@6W2:L8Y`RW0@07Y`050@VW2JL01@010@40000E00030@00008000H9Y`VW2@482@08 -0@UB2E89DP4:DP0@0E81DP5B0E81DP5B0E81DR41011B0E81DP5B0E81DP5B0E812E802P49DPUB2E89 -DP472@0:0@VW2JL9Y`VW0@NW00X12:L8Y`RW2:L12PP04040200800P0200800P0204P000@0@0800P0 -200800P020080@X800T12:L8Y`RW20401jL01@6W2JL900D00@4100005@000`4000020006Y`VW2JL1 -20T0205B2E89DPT12U820@0?DP5B0E81DP5B0E81DP5B01l1011B0E81DP5B0E81DP5B0E812U802P5B -2E89DPUB2@472@0:0JL9Y`VW2JL90@NW00X1Y`RW2:L8Y`P12PP04@4800P0200800P0200800P101h0 -014100P0200800P0200800P00@0:20090JL8Y`RW2:L100NW00D12JL9Y`0500410@0001D000<10000 -0P001PVW2JL90@P900P12E89DPUB0@YB0101DP5B0E81DP5B0E81DP5B8@403E81DP5B0E81DP5B0E80 -0P4:DP0:0@UB2E89DPUB0@L900X12JL9Y`VW2JL11jL02P48Y`RW2:L8Y`4:200A0@0800P0200800P0 -200800407P004@4800P0200800P0200800P100X800T12:L8Y`RW20401jL01@6W2JL900D00@410000 -5@000`4000020006Y`VW2JL120T02@5B2E89DPUB0@0:DP0@0E81DP5B0E81DP5B0E81DQl1011B0E81 -DP5B0E81DP5B0E812E802`49DPUB2E89DPT100L900X1Y`VW2JL9Y`T11jL02`6W2:L8Y`RW2:L100X8 -014100P0200800P0200800P00@0L000B0@P0200800P0200800P020012@P02P48Y`RW2:L8Y`47Y`05 -0@VW2JL01@010@40000E00030@00008000H9Y`VW2@482@090@UB2E89DPT100YB0P403e81DP5B0E81 -DP5B0E81DP0M0@0@DP5B0E81DP5B0E81DP5B0@YB00X1DPUB2E89DPT120T02P49Y`VW2JL9Y`48Y`0: -0JL8Y`RW2:L80@X80181200800P0200800P02008004J000B0@P0200800P0200800P020012PP02@6W -2:L8Y`RW0@08Y`050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`492@090@UB2E89DPT100YB -0P403e81DP5B0E81DP5B0E81DP0K0@0?DP5B0E81DP5B0E81DP5B00812E802`5B2E89DPUB2E8100P9 -00X1Y`VW2JL9Y`T12:L02`48Y`RW2:L8Y`P100X80181200800P0200800P02008004H000C0@P02008 -00P0200800P020080@09200:0JL8Y`RW2:L80@RW00D12JL9Y`0500410@0001D000<100000P001PVW -2JL90@T900X1DPUB2E89DPT12E804P5B0E81DP5B0E81DP5B0E81DQT100mB0E81DP5B0E81DP5B0E80 -0P49DP0<0E89DPUB2E89DPT120T02P49Y`VW2JL9Y`48Y`0<0JL8Y`RW2:L8Y`P12@P04`40200800P0 -200800P0200800405P004`4800P0200800P0200800P020402@P02`6W2:L8Y`RW2:L100RW00D1Y`VW -2@0500410@0001D000<100000P001jL9Y`VW2@4020T02P49DPUB2E89DP4:DP0B0E81DP5B0E81DP5B -0E81DP5B5`404U81DP5B0E81DP5B0E81DP5B0@UB00/12E89DPUB2E890@092@0;0JL9Y`VW2JL9Y`40 -2:L02`6W2:L8Y`RW2:L100X801<100P0200800P0200800P0200101@001@1200800P0200800P02008 -00P00@T800/12:L8Y`RW2:L80@07Y`060JL9Y`VW1@010@40000E00030@00008000L9Y`VW2JL100P9 -00/1DPUB2E89DPUB0@09DP81015B0E81DP5B0E81DP5B0E81DP0E0@0BDP5B0E81DP5B0E81DP5B0E81 -2E803049DPUB2E89DPUB0@T900/12JL9Y`VW2JL90@08Y`0<0@RW2:L8Y`RW2:L12@P04`4800P02008 -00P0200800P0200050404`P0200800P0200800P0200800402@P02`48Y`RW2:L8Y`P100RW00H12JL9 -Y`T500410@0001D000<100000P001jL9Y`VW2@402@T02`5B2E89DPUB2E8100UB0P40=E81DP5B0E81 -DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00812E80305B2E89DPUB -2E890@T900/1Y`VW2JL9Y`VW0@08Y`0=0JL8Y`RW2:L8Y`RW0@09200i0@P0200800P0200800P02008 -00P0200800P0200800P0200800P0200800P0200800P0200800P100P800`12:L8Y`RW2:L8Y`48Y`06 -0JL9Y`VW1@010@40000E00810`001`VW2JL9Y`402@T02`49DPUB2E89DPT100UB03H1DP5B0E81DP5B -0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E820@UB00`1DPUB2E89DPUB -2@4:2@0;0@VW2JL9Y`VW2@402JL0306W2:L8Y`RW2:L80@T803P100P0200800P0200800P0200800P0 -200800P0200800P0200800P0200800P0200800P020080@T800`1Y`RW2:L8Y`RW2048Y`060@VW2JL9 -10020@40000E00030@00008000NW2JL9Y`T100T900`1DPUB2E89DPUB2@49DP<1035B0E81DP5B0E81 -DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00812E803@5B2E89DPUB2E89DP40 -2PT02`6W2JL9Y`VW2JL100VW00d12:L8Y`RW2:L8Y`P100T80P400JL8Y`RW2:L8Y`RW204:208102h0200800P0200800P0200800P02008 -00P0200800P0200800P0200800P020080P4:200=0JL8Y`RW2:L8Y`RW0@09Y`060@VW2JL91@010@40 -000E00030@00008000NW2JL9Y`T100T900h1DPUB2E89DPUB2E890@]B0`40:E81DP5B0E81DP5B0E81 -DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B008135803@49DPUB2E89DPUB2@402PT03049Y`VW2JL9 -Y`VW0@ZW00h1Y`RW2:L8Y`RW2:L80@/80P40:PP0200800P0200800P0200800P0200800P0200800P0 -200800P0200800812`P03P6W2:L8Y`RW2:L8Y`P12JL01P6W2JL9Y`D00@4100005@000`4000020007 -2JL9Y`VW0@0:2@0=0E89DPUB2E89DPUB0@0=DP8102EB0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81 -DP5B0E81DP5B00<13E803P49DPUB2E89DPUB2E812PT0306W2JL9Y`VW2JL90@ZW00h12:L8Y`RW2:L8 -Y`RW0@d80P409P0800P0200800P0200800P0200800P0200800P0200800P020080P4=200>0@RW2:L8 -Y`RW2:L8Y`49Y`060@VW2JL91@010@40000E00030@00008000NW2JL9Y`T100X900h12E89DPUB2E89 -DPUB0@iB0`408E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@mB00h1DPUB2E89DPUB -2E890@X900`12JL9Y`VW2JL9Y`4:Y`0?0JL8Y`RW2:L8Y`RW2:L100h802H100P0200800P0200800P0 -200800P0200800P0200800P020080@h800h12:L8Y`RW2:L8Y`RW0@ZW00H1Y`VW2JL500410@0001D0 -00<100000P001`VW2JL9Y`402PT03`5B2E89DPUB2E89DPUB0@0?DP8101mB0E81DP5B0E81DP5B0E81 -DP5B0E81DP5B0E81DP5B00813e803P5B2E89DPUB2E89DPT12`T0306W2JL9Y`VW2JL90@^W00l1Y`RW -2:L8Y`RW2:L8Y`403PP20@0P200800P0200800P0200800P0200800P0200800P020020@h800l12:L8 -Y`RW2:L8Y`RW20402ZL01P49Y`VW2@D00@4100005@000`4000020008Y`VW2JL9Y`492@0?0@UB2E89 -DPUB2E89DPT1015B0`406E81DP5B0E81DP5B0E81DP5B0E81DP5B0E800`4ADP0>0@UB2E89DPUB2E89 -DP4;2@0=0@VW2JL9Y`VW2JL90@0:Y`0?0@RW2:L8Y`RW2:L8Y`P101080P40700800P0200800P02008 -00P0200800P0200800P20A0800l1Y`RW2:L8Y`RW2:L8Y`402JL01`49Y`VW2JL01@010@40000E0003 -0@00008000P9Y`VW2JL90@X900l12E89DPUB2E89DPUB2@404U820@0GDP5B0E81DP5B0E81DP5B0E81 -DP5B0E800P4BDP0?0@UB2E89DPUB2E89DPT100/900d1Y`VW2JL9Y`VW2JL100ZW0101Y`RW2:L8Y`RW -2:L8Y`P14@P20@0H200800P0200800P0200800P0200800P00P4A200@0JL8Y`RW2:L8Y`RW2:L80@VW -00L1Y`VW2JL900D00@4100005@000`4000020008Y`VW2JL9Y`4:2@0@0E89DPUB2E89DPUB2E890A=B -0`404E81DP5B0E81DP5B0E81DP5B00<14e803`49DPUB2E89DPUB2E890@0<2@0=0@VW2JL9Y`VW2JL9 -0@0;Y`0@0JL8Y`RW2:L8Y`RW2:L80A880P40500800P0200800P0200800P020080P4B200@0JL8Y`RW -2:L8Y`RW2:L80@ZW00L12JL9Y`VW00D00@4100005@000`40000200082JL9Y`VW2@4:2@0@0@UB2E89 -DPUB2E89DPUB0AEB4`4EDP0?0E89DPUB2E89DPUB2E8100`900d1Y`VW2JL9Y`VW2JL100^W01012:L8 -Y`RW2:L8Y`RW2:L150PD0A@801012:L8Y`RW2:L8Y`RW2:L12ZL01`6W2JL9Y`T01@010@40000E0003 -0@00008000RW2JL9Y`VW0@/901012E89DPUB2E89DPUB2E81>U820@0?DPUB2E89DPUB2E89DPT100`9 -00d12JL9Y`VW2JL9Y`T100^W0141Y`RW2:L8Y`RW2:L8Y`RW0@0i208100l8Y`RW2:L8Y`RW2:L8Y`40 -2jL01`49Y`VW2JL01@010@40000E00810`002@VW2JL9Y`VW0@0;2@8100eB2E89DPUB2E89DPUB00<1 -=5830@0>2E89DPUB2E89DPUB2E820@`900l12JL9Y`VW2JL9Y`VW2@402jL20@0>2:L8Y`RW2:L8Y`RW -2:L30C@80P403ZL8Y`RW2:L8Y`RW2:L80P4;Y`080@VW2JL9Y`T400810@0001D000<100000P002JL9 -Y`VW2JL90@0=2@0@0E89DPUB2E89DPUB2E89DP<1;U830@0A2E89DPUB2E89DPUB2E89DP403PT03`6W -2JL9Y`VW2JL9Y`VW0@0=Y`0A0@RW2:L8Y`RW2:L8Y`RW2:L00`4^20<10108Y`RW2:L8Y`RW2:L8Y`P1 -3JL0206W2JL9Y`VW1@010@40000E00030@00008000X9Y`VW2JL9Y`T13@T04P5B2E89DPUB2E89DPUB -2E89DP<1:5830@0A2E89DPUB2E89DPUB2E89DPT00P4>2@0A0JL9Y`VW2JL9Y`VW2JL9Y`403JL20@0A -Y`RW2:L8Y`RW2:L8Y`RW2:L00`4X20<10188Y`RW2:L8Y`RW2:L8Y`RW204=Y`090JL9Y`VW2JL900D0 -0@4100005@000`400002000:Y`VW2JL9Y`VW0@h90P404PUB2E89DPUB2E89DPUB2E89DP@18E830@0D -2E89DPUB2E89DPUB2E89DPUB2@4?2@0B0JL9Y`VW2JL9Y`VW2JL9Y`T13jL0506W2:L8Y`RW2:L8Y`RW -2:L8Y`RW0`4R20<10188Y`RW2:L8Y`RW2:L8Y`RW2:L20@jW00T12JL9Y`VW2JL01@010@40000E0003 -0@00008000/9Y`VW2JL9Y`VW0@0?2@0F0@UB2E89DPUB2E89DPUB2E89DPUB2@<16e830@0D2E89DPUB -2E89DPUB2E89DPUB2E820A0901<12JL9Y`VW2JL9Y`VW2JL9Y`T100nW0P4050RW2:L8Y`RW2:L8Y`RW -2:L8Y`RW0`4L20<101D8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`403jL02P49Y`VW2JL9Y`T500410@0001D0 -00<100000P003:L9Y`VW2JL9Y`VW0@l90P405U89DPUB2E89DPUB2E89DPUB2E89DPT30AEB0`405`UB -2E89DPUB2E89DPUB2E89DPUB2E81014901D12JL9Y`VW2JL9Y`VW2JL9Y`VW2@404:L05`48Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW00<15PP30@0E2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L800814:L02P6W2JL9Y`VW -2JL500410@0001D000<100000P0030VW2JL9Y`VW2JL90A4901T1DPUB2E89DPUB2E89DPUB2E89DPUB -2E8901D101L9DPUB2E89DPUB2E89DPUB2E89DPUB2@020A4901H12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1 -4JL20@0GY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L05P4060RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80A6W -00/1Y`VW2JL9Y`VW2@0500410@0001D000<100000P003JL9Y`VW2JL9Y`VW2@404@T20@122E89DPUB -2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT1 -4`T05`6W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL101:W0481Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L20A:W00/12JL9Y`VW2JL9Y`050041 -0@0001D000<100000P003PVW2JL9Y`VW2JL9Y`T14PT0?`49DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP020A<901T1Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL101:W0P40?`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW0@0CY`0<0@VW2JL9Y`VW2JL91@010@40000E00030@00008000jW2JL9 -Y`VW2JL9Y`VW0A<903h12E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB0A@901X1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90ABW03h12:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0A>W00d12JL9 -Y`VW2JL9Y`VW00D00@4100005@000`400002000?2JL9Y`VW2JL9Y`VW2JL101<90P40>589DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E890P4E2@0K0@VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T101BW0P40>:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80P4DY`0=0JL9Y`VW2JL9Y`VW2@0500410@0001D000<10000 -0P003jL9Y`VW2JL9Y`VW2JL90@0E2@@10309DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB -2E89DPUB2E89DPUB2E840AH901`12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL15ZL30@0aY`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`040AFW00h1Y`VW2JL9Y`VW -2JL9Y`D00@4100005@000`400002000@2JL9Y`VW2JL9Y`VW2JL90AP91P409589DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2@H16@T07P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0ARW -1P409@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P01P4IY`0>0@VW2JL9Y`VW2JL9 -Y`T500410@0001D00P43000AY`VW2JL9Y`VW2JL9Y`VW2@407@T60@0H2E89DPUB2E89DPUB2E89DPUB -2E89DPUB1P4O2@0O0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@0MY`H101VW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW00H17ZL03`49Y`VW2JL9Y`VW2JL9Y`0400810@0001D000<100000P004@VW -2JL9Y`VW2JL9Y`VW2JL102<9604T2@0P0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@4SYaT1 -9:L03`6W2JL9Y`VW2JL9Y`VW2@0500410@0001D000<100000P004ZL9Y`VW2JL9Y`VW2JL9Y`VW0Ed9 -0281Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T1GZL0406W2JL9Y`VW2JL9Y`VW2JL50041 -0@0001D000<100000P004PVW2JL9Y`VW2JL9Y`VW2JL90Ed902812JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL1GZL04049Y`VW2JL9Y`VW2JL9Y`T500410@0001D000<100000P004ZL9Y`VW2JL9 -Y`VW2JL9Y`VW2@<1EPT40@0R2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`@1EZL40@0@ -2JL9Y`VW2JL9Y`VW2JL9Y`D00@4100005@000`400002000E2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900@1 -CPT40@0ZY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9105>Y`@101BW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2@D00@4100005@000`400002000IY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`050D@91@40Y`@102ZW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`T40Dh910405:L9Y`VW2JL9Y`VW2JL9Y`VW2JL91@010@40000E00030@000080 -01:W2JL9Y`VW2JL9Y`VW2JL9Y`T30EJW10408PVW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL40EH9104040VW2JL9Y`VW2JL9Y`VW2JL500410@0001D000<100000P004PVW2JL9Y`VW2JL9Y`VW -2JL90EfW02812JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1GPT04049Y`VW2JL9Y`VW2JL9 -Y`T500410@0001D000<100000P004ZL9Y`VW2JL9Y`VW2JL9Y`VW0EfW0281Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`T1GPT0406W2JL9Y`VW2JL9Y`VW2JL500410@0001D000<100000P004@VW -2JL9Y`VW2JL9Y`VW2JL102>W604TY`0P0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@4S2AT1 -90T03`6W2JL9Y`VW2JL9Y`VW2@0500410@0001D00P43000AY`VW2JL9Y`VW2JL9Y`VW2@407JL60@0H -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW1P4OY`0O0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -0@0M2@H101UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB00H17PT03`49Y`VW2JL9Y`VW2JL9Y`040081 -0@0001D000<100000P0040VW2JL9Y`VW2JL9Y`VW2@4HY`H102BW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`P60AVW01h12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4H2@H102D9DPUB -2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E8900H16@T03P49Y`VW2JL9Y`VW2JL91@010@40 -000E00030@00008000nW2JL9Y`VW2JL9Y`VW2@405JL40@0`2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW104FY`0L0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0AH9 -0`40 -0JL9Y`VW2JL9Y`VW2JL500410@0001D000<100000P003`VW2JL9Y`VW2JL9Y`VW0@0CY`8103RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20815JL06`49 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@0D2@8103QB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2@8150T03@6W2JL9Y`VW2JL9Y`T01@010@40000E0003 -0@00008000jW2JL9Y`VW2JL9Y`VW0A>W03h12:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0ABW01X1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90A@9 -03h12E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB0A<900d12JL9Y`VW2JL9Y`VW00D00@4100005@000`400002000>2JL9Y`VW2JL9Y`VW2@4BY`0o -0@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW00814jL06@6W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`404PT20@0o2E89DPUB2E89DPUB2E89DPUB -2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E8101<900`12JL9Y`VW2JL9 -Y`T500410@0001D000<100000P003JL9Y`VW2JL9Y`VW2@404JL20@122:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P14jL05`6W2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL101890481DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB -2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E820A8900/12JL9Y`VW2JL9Y`0500410@0001D000<10000 -0P0030VW2JL9Y`VW2JL90A6W01T1Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L801D101L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW20020A6W01H12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL14@T20@0GDPUB2E89DPUB2E89 -DPUB2E89DPUB2E805P4060UB2E89DPUB2E89DPUB2E89DPUB2E890A4900/1Y`VW2JL9Y`VW2@050041 -0@0001D000<100000P003:L9Y`VW2JL9Y`VW0@nW0P405ZL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P30AD8 -0`405`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L1016W01D12JL9Y`VW2JL9Y`VW2JL9Y`VW2@4040T05`49 -DPUB2E89DPUB2E89DPUB2E89DPUB00<15U830@0E2E89DPUB2E89DPUB2E89DPUB2E89008140T02P6W -2JL9Y`VW2JL500410@0001D000<100000P002`VW2JL9Y`VW2JL100nW01H12:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L80`4K20<101@8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`814:L04`49Y`VW2JL9Y`VW2JL9Y`VW2@40 -3`T20@0D2E89DPUB2E89DPUB2E89DPUB2E830AaB0`405@UB2E89DPUB2E89DPUB2E89DPUB0@0?2@0: -0@VW2JL9Y`VW2@D00@4100005@000`400002000:Y`VW2JL9Y`VW0@jW0P404PRW2:L8Y`RW2:L8Y`RW -2:L8Y`@18@P30@0D2:L8Y`RW2:L8Y`RW2:L8Y`RW204?Y`0B0JL9Y`VW2JL9Y`VW2JL9Y`T13`T0505B -2E89DPUB2E89DPUB2E89DPUB0`4RDP<10189DPUB2E89DPUB2E89DPUB2E820@h900T12JL9Y`VW2JL0 -1@010@40000E00030@00008000X9Y`VW2JL9Y`T13JL04P6W2:L8Y`RW2:L8Y`RW2:L8Y`<1:0P30@0A -2:L8Y`RW2:L8Y`RW2:L8Y`P00P4>Y`0A0JL9Y`VW2JL9Y`VW2JL9Y`403@T20@0ADPUB2E89DPUB2E89 -DPUB2E800`4XDP<10189DPUB2E89DPUB2E89DPUB2@4=2@090JL9Y`VW2JL900D00@4100005@000`40 -00020009Y`VW2JL9Y`T100fW0101Y`RW2:L8Y`RW2:L8Y`RW0`4^20<10148Y`RW2:L8Y`RW2:L8Y`RW -0@0>Y`0?0JL9Y`VW2JL9Y`VW2JL100d901412E89DPUB2E89DPUB2E89DP030BiB0`4040UB2E89DPUB -2E89DPUB2@4=2@080JL9Y`VW2JL500410@0001D00P4300092JL9Y`VW2JL100^W0P403JL8Y`RW2:L8 -Y`RW2:L00`4d20<100h8Y`RW2:L8Y`RW2:L8Y`813:L03`49Y`VW2JL9Y`VW2JL90@0;2@8100h9DPUB -2E89DPUB2E89DP<1=5820@0>DPUB2E89DPUB2E89DPT20@/900P12JL9Y`VW2@@00P4100005@000`40 -00020008Y`VW2JL9Y`4;Y`0@0@RW2:L8Y`RW2:L8Y`RW0CX80P403jL8Y`RW2:L8Y`RW2:L80@0E820@0?2E89DPUB2E89DPUB2E8100/9 -00L12JL9Y`VW00D00@4100005@000`40000200082JL9Y`VW2@4:Y`0@0@RW2:L8Y`RW2:L8Y`RW0AD8 -4`4E200?0JL8Y`RW2:L8Y`RW2:L100bW00d1Y`VW2JL9Y`VW2JL100/901012E89DPUB2E89DPUB2E81 -558D0AAB01012E89DPUB2E89DPUB2E812PT01`6W2JL9Y`T01@010@40000E00030@00008000RW2JL9 -Y`VW0@ZW0101Y`RW2:L8Y`RW2:L8Y`P14`P20@0C200800P0200800P0200800P020020A<800l12:L8 -Y`RW2:L8Y`RW20403:L03@49Y`VW2JL9Y`VW2@402`T0405B2E89DPUB2E89DPUB2@4BDP8101=B0E81 -DP5B0E81DP5B0E81DP5B00<14U80405B2E89DPUB2E89DPUB2@4:2@070@VW2JL9Y`0500410@0001D0 -00<100000P0020VW2JL9Y`T12ZL03`48Y`RW2:L8Y`RW2:L80@0B208101L0200800P0200800P02008 -00P0200800020A8800l12:L8Y`RW2:L8Y`RW20402jL03@6W2JL9Y`VW2JL9Y`402PT0405B2E89DPUB -2E89DPUB2@4ADP<101MB0E81DP5B0E81DP5B0E81DP5B0E81DP020A5B0101DPUB2E89DPUB2E89DPT1 -2@T01`6W2JL9Y`T01@010@40000E00030@00008000RW2JL9Y`VW0@VW00l12:L8Y`RW2:L8Y`RW2040 -4@P20@0K200800P0200800P0200800P0200800P0200800814@P03P48Y`RW2:L8Y`RW2:L12jL03@49 -Y`VW2JL9Y`VW2@402PT03`49DPUB2E89DPUB2E890@0@DP8101]B0E81DP5B0E81DP5B0E81DP5B0E81 -DP5B0E800`4@DP0?0E89DPUB2E89DPUB2E8100T900L12JL9Y`VW00D00@4100005@000`4000020007 -2JL9Y`VW0@0:Y`0?0JL8Y`RW2:L8Y`RW2:L100l80P407`0800P0200800P0200800P0200800P02008 -00P020000P4?200>0JL8Y`RW2:L8Y`RW204;Y`0<0JL9Y`VW2JL9Y`T12`T03`5B2E89DPUB2E89DPUB -0@0>DP<101mB0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00813U803`49DPUB2E89DPUB2E89 -0@0:2@060@VW2JL91@010@40000E00030@00008000NW2JL9Y`T100ZW00h12:L8Y`RW2:L8Y`RW0@h8 -0P4090P0200800P0200800P0200800P0200800P0200800P020080@l800h1Y`RW2:L8Y`RW2:L80@ZW -00`12JL9Y`VW2JL9Y`4:2@0?0E89DPUB2E89DPUB2E8100iB02@1DP5B0E81DP5B0E81DP5B0E81DP5B -0E81DP5B0E81DP5B0E820@iB00h12E89DPUB2E89DPUB0@X900H1Y`VW2JL500410@0001D000<10000 -0P001`VW2JL9Y`402ZL03@6W2:L8Y`RW2:L8Y`403@P20@0V00P0200800P0200800P0200800P02008 -00P0200800P0200800P20@d800h12:L8Y`RW2:L8Y`RW0@ZW00`1Y`VW2JL9Y`VW2@4:2@0>0@UB2E89 -DPUB2E89DP4=DP8102EB0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00<13E803P49 -DPUB2E89DPUB2E812@T01P49Y`VW2@D00@4100005@000`4000020007Y`VW2JL90@09Y`0>0JL8Y`RW -2:L8Y`RW204;208102X800P0200800P0200800P0200800P0200800P0200800P0200800P020020@`8 -00d12:L8Y`RW2:L8Y`P100ZW00`12JL9Y`VW2JL9Y`4:2@0>0E89DPUB2E89DPUB2@4;DP<102UB0E81 -DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@]B00h1DPUB2E89DPUB2E890@T9 -00H1Y`VW2JL500410@0001D000<100000P001`VW2JL9Y`402JL03@48Y`RW2:L8Y`RW20402PP20@0^ -00P0200800P0200800P0200800P0200800P0200800P0200800P0200800P020812`P03@48Y`RW2:L8 -Y`RW20402JL0306W2JL9Y`VW2JL90@T900h1DPUB2E89DPUB2E890@YB0P40;E81DP5B0E81DP5B0E81 -DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP030@YB00d1DPUB2E89DPUB2E8100T900H12JL9 -Y`T500410@0001D000<100000P001jL9Y`VW2@402JL0306W2:L8Y`RW2:L80@T80P40040200800P0200800P0 -200800P0200800P0200800P0200800P0200800P0200800P0200800P12@P0306W2:L8Y`RW2:L80@ZW -00/12JL9Y`VW2JL90@092@0<0E89DPUB2E89DPT12E80=P5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B -0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP812E80305B2E89DPUB2E890@P900H12JL9Y`T40081 -0@0001D000<100000P001jL9Y`VW2@402JL02`6W2:L8Y`RW2:L100T803T1200800P0200800P02008 -00P0200800P0200800P0200800P0200800P0200800P0200800P020402@P0306W2:L8Y`RW2:L80@VW -00/1Y`VW2JL9Y`VW0@082@0=0E89DPUB2E89DPUB0@09DP8103EB0E81DP5B0E81DP5B0E81DP5B0E81 -DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@QB00`12E89DPUB2E89DP482@060JL9Y`VW -1@010@40000E00030@00008000L9Y`VW2JL100RW00/1Y`RW2:L8Y`RW0@09200D0@P0200800P02008 -00P0200800PC0@0C200800P0200800P0200800P00@09200<0@RW2:L8Y`RW2:L12JL02`49Y`VW2JL9 -Y`T100P900`12E89DPUB2E89DP49DP81015B0E81DP5B0E81DP5B0E81DP0E0@0BDP5B0E81DP5B0E81 -DP5B0E812E802`49DPUB2E89DPT100P900H12JL9Y`T500410@0001D000<100000P001jL9Y`VW2@40 -2:L02P48Y`RW2:L8Y`4:200D0@0800P0200800P0200800P0204C000D0@P0200800P0200800P02008 -0049200;0@RW2:L8Y`RW20402JL02`6W2JL9Y`VW2JL100P900/1DPUB2E89DPUB0@0:DP0B0E81DP5B -0E81DP5B0E81DP5B5`404U81DP5B0E81DP5B0E81DP5B0@UB00/12E89DPUB2E890@072@060JL9Y`VW -1@010@40000E00030@00008000H9Y`VW2@49Y`0:0JL8Y`RW2:L80@T801@100P0200800P0200800P0 -20080AD001<1200800P0200800P0200800P100T800`1Y`RW2:L8Y`RW2048Y`0:0@VW2JL9Y`VW0@P9 -00`1DPUB2E89DPUB2@49DP0B0E81DP5B0E81DP5B0E81DP5B6@403e81DP5B0E81DP5B0E81DP020@UB -00/1DPUB2E89DPUB0@082@050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`49Y`090@RW2:L8 -Y`P100X801<1200800P0200800P0200800P101L001<1200800P0200800P0200800P100T800/1Y`RW -2:L8Y`RW0@08Y`0:0JL9Y`VW2JL90@P900/12E89DPUB2E890@0:DP8100mB0E81DP5B0E81DP5B0E80 -6`403e81DP5B0E81DP5B0E81DP020@UB00X1DPUB2E89DPT120T01@49Y`VW00D00@4100005@000`40 -000200062JL9Y`T12:L02@48Y`RW2:L80@0:200C0@P0200800P0200800P020080@0I000B0@P02008 -00P0200800P020012PP02P6W2:L8Y`RW2048Y`0:0@VW2JL9Y`VW0@P900X1DPUB2E89DPT12U820@0? -DP5B0E81DP5B0E81DP5B01d1011B0E81DP5B0E81DP5B0E812U802@5B2E89DPUB0@082@050JL9Y`T0 -1@010@40000E00030@00008000JW2JL9Y`48Y`090JL8Y`RW2:L100X8018100P0200800P0200800P0 -204K000B0@P0200800P0200800P020012@P02`48Y`RW2:L8Y`P100NW00X1Y`VW2JL9Y`T11`T02`5B -2E89DPUB2E8100YB0101DP5B0E81DP5B0E81DP5B7`404581DP5B0E81DP5B0E81DP49DP0:0@UB2E89 -DPUB0@L900D12JL9Y`0500410@0001D000<100000P001PVW2JL90@RW00P12:L8Y`RW0@X8018100P0 -200800P0200800P0204M000A0@P0200800P0200800P020402PP02P48Y`RW2:L8Y`47Y`0:0@VW2JL9 -Y`VW0@L900X12E89DPUB2E812U80405B0E81DP5B0E81DP5B0E8Q0@0=DP5B0E81DP5B0E81DP020@YB -00T12E89DPUB2@401`T01@6W2JL900D00@4100005@000`4000020006Y`VW2JL12:L0206W2:L8Y`P1 -2PP04P4800P0200800P0200800P00Ad0014100P0200800P0200800P00@0:200:0JL8Y`RW2:L80@NW -00X1Y`VW2JL9Y`T11`T02P5B2E89DPUB2@4:DP8100eB0E81DP5B0E81DP5B0241011B0E81DP5B0E81 -DP5B0E812U802@5B2E89DPUB0@072@050@VW2JL01@010@40000E00030@00008000H9Y`VW2@48Y`08 -0@RW2:L8Y`4:200A0@0800P0200800P0200800407`004@40200800P0200800P0200100T800X12:L8 -Y`RW2:L11jL02P49Y`VW2JL9Y`472@0:0@UB2E89DPUB0@YB00h1DP5B0E81DP5B0E81DR<100eB0E81 -DP5B0E81DP5B00812U802@49DPUB2E890@072@050JL9Y`T01@010@40000E00030@00008000JW2JL9 -Y`48Y`080JL8Y`RW2049200B0@0800P0200800P0200800P17`004@4800P0200800P0200800P100T8 -00X1Y`RW2:L8Y`P11jL02P6W2JL9Y`VW2@472@0:0E89DPUB2E890@UB0101DP5B0E81DP5B0E81DP5B -8`403E81DP5B0E81DP5B0E800P49DP090E89DPUB2E8100L900D12JL9Y`0500410@0001D000<10000 -0P001PVW2JL90@RW00P12:L8Y`RW0@T80141200800P0200800P020080@0Q000@0@P0200800P02008 -00P00@T800X12:L8Y`RW2:L11jL02P49Y`VW2JL9Y`472@0:0@UB2E89DPUB0@UB0P403E81DP5B0E81 -DP5B0E809@403U81DP5B0E81DP5B0E812E802@49DPUB2E890@072@050JL9Y`T01@010@40000E0081 -0`001ZL9Y`VW0@RW00L1Y`RW2:L100X8014100P0200800P0200800P00@0Q000@0@0800P0200800P0 -20080@X800T12:L8Y`RW20401jL02P6W2JL9Y`VW2@472@090E89DPUB2E8100YB00h1DP5B0E81DP5B -0E81DRD100eB0E81DP5B0E81DP5B00812U802049DPUB2E811`T01@49Y`VW00@00P4100005@000`40 -000200062JL9Y`T12:L01`48Y`RW20402PP0404800P0200800P02008004S000@0@0800P0200800P0 -20080@T800T1Y`RW2:L8Y`401jL02P49Y`VW2JL9Y`472@090@UB2E89DPT100YB0P402e81DP5B0E81 -DP5B02L100iB0E81DP5B0E81DP5B0@YB00P1DPUB2E890@L900D1Y`VW2@0500410@0001D000<10000 -0P001ZL9Y`VW0@RW00L1Y`RW2:L100T80141200800P0200800P020080@0S000@0@P0200800P02008 -00P00@T800T12:L8Y`RW20401jL02P6W2JL9Y`VW2@472@090E89DPUB2E8100UB0P403E81DP5B0E81 -DP5B0E809`403U81DP5B0E81DP5B0E812E802049DPUB2E811`T01@49Y`VW00D00@4100005@000`40 -000200062JL9Y`T12:L01`48Y`RW20402@P04040200800P0200800P0204U000?0@P0200800P02008 -00P100T800T1Y`RW2:L8Y`401jL02P49Y`VW2JL9Y`472@090@UB2E89DPT100UB00h1DP5B0E81DP5B -0E81DRT100]B0E81DP5B0E81DP020@UB00P1DPUB2E890@L900D1Y`VW2@0500410@0001D000<10000 -0P001ZL9Y`VW0@RW00L1Y`RW2:L100T80101200800P0200800P020019@004040200800P0200800P0 -2048200:0@RW2:L8Y`RW0@NW00T12JL9Y`VW2@401`T02@5B2E89DPUB0@09DP8100]B0E81DP5B0E81 -DP0Y0@0>DP5B0E81DP5B0E81DP49DP090@UB2E89DPT100H900D12JL9Y`0500410@0001D000<10000 -0P001PVW2JL90@NW00P1Y`RW2:L80@T800l100P0200800P0200800409P00404800P0200800P02008 -0048200:0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900X1DPUB2E89DPT12E803P5B0E81DP5B0E81DP5B -:@402e81DP5B0E81DP5B00812E802@5B2E89DPUB0@062@050JL9Y`T01@010@40000E00030@000080 -00JW2JL9Y`47Y`080@RW2:L8Y`49200?0@P0200800P0200800P102L000l1200800P0200800P02040 -20P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@0:0@UB2E89DPUB0@UB0P402e81DP5B0E81DP5B02/1 -00aB0E81DP5B0E81DP49DP090@UB2E89DPT100H900D12JL9Y`0500410@0001D000<100000P001PVW -2JL90@NW00P1Y`RW2:L80@P800l1200800P0200800P02040:0003`40200800P0200800P00@08200: -0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900X1DPUB2E89DPT125820@0;DP5B0E81DP5B0E80:`403U81 -DP5B0E81DP5B0E8125802@5B2E89DPUB0@062@050JL9Y`T01@010@40000E00030@00008000JW2JL9 -Y`47Y`080@RW2:L8Y`48200?0@0800P0200800P0200102T000l100P0200800P0200800401`P02P48 -Y`RW2:L8Y`47Y`080@VW2JL9Y`472@0:0@UB2E89DPUB0@QB00`1DP5B0E81DP5B0E8]0@0;DP5B0E81 -DP5B0E800P48DP090@UB2E89DPT100H900D12JL9Y`0500410@0001D000<100000P001PVW2JL90@NW -00L1Y`RW2:L100T800h1200800P0200800P00BX000l1200800P0200800P0204020P02@48Y`RW2:L8 -0@07Y`080JL9Y`VW2@472@090E89DPUB2E8100UB0P402e81DP5B0E81DP5B02d100aB0E81DP5B0E81 -DP49DP080@UB2E89DP462@050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`47Y`070@RW2:L8 -0@09200>0@0800P0200800P0204[000>0@P0200800P02008004820090JL8Y`RW2:L100NW00P12JL9 -Y`VW0@L900T12E89DPUB2@402E80305B0E81DP5B0E81DRl100UB0E81DP5B0E800P49DP080E89DPUB -2@462@050@VW2JL01@010@40000E00030@00008000H9Y`VW2@47Y`070JL8Y`RW0@08200>0@0800P0 -200800P0204/000>0@0800P0200800P0204820090@RW2:L8Y`P100NW00P1Y`VW2JL90@L900T1DPUB -2E89DP402580305B0E81DP5B0E81DRl100]B0E81DP5B0E81DP020@QB00P12E89DPUB0@H900D1Y`VW -2@0500410@0000d0104400030@00008000JW2JL9Y`47Y`070@RW2:L80@08200>0@P0200800P02008 -004]000>0@0800P0200800P0204720090JL8Y`RW2:L100NW00P12JL9Y`VW0@L900T12E89DPUB2@40 -25820@09DP5B0E81DP5B034100aB0E81DP5B0E81DP48DP080E89DPUB2@462@050@VW2JL01@010@40 -000=00030@0000D00P4300062JL9Y`T11jL01`6W2:L8Y`4020P03@40200800P020080040;P003P48 -00P0200800P020011`P02@48Y`RW2:L80@07Y`080JL9Y`VW2@472@090E89DPUB2E8100QB00`1DP5B -0E81DP5B0E8a0@09DP5B0E81DP5B008125802049DPUB2E811PT01@6W2JL900@00P4100003P000`40 -000400030@000?l01`010@40000?00030@0000<000<10000o`0700410@00010000<100000P000`40 -000200030@0003d000<10000?@000`40000l00030@0003d000<100000P010@40000=00040@000@@0 -00<100000P000`40000:00030@0000T000<100002P000`40000:00030@0000X000<100002P000`40 -000900030@0000X000<100002P000`40000:00030@0000T000<100002P000`40000:00030@0000X0 -00<100002@000`40000:00030@0000X000<100002P000`40000:00030@0000T000<100000P010@40 -000>00811@3o0@/10@000?l08@000?l08@000?l08@000?l08@000001\ -\>"], - ImageRangeCache->{{{0, 287}, {287, 0}} -> {-0.207, -0.172242, 0.00783272, - 0.00783272}}], - -Cell[BoxData[ - TagBox[\(\[SkeletonIndicator] ContourGraphics \[SkeletonIndicator]\), - False, - Editable->False]], "Output"] -}, Open ]], - -Cell[CellGroupData[{ - -Cell[BoxData[ - \(ContourPlot[p, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"], - -Cell[GraphicsData["PostScript", "\<\ -%! -%%Creator: Mathematica -%%AspectRatio: 1 -MathPictureStart -/Mabs { -Mgmatrix idtransform -Mtmatrix dtransform -} bind def -/Mabsadd { Mabs -3 -1 roll add -3 1 roll add -exch } bind def -%% ContourGraphics -%%IncludeResource: font Courier -%%IncludeFont: Courier -/Courier findfont 10 scalefont setfont -% Scaling calculations -0.0192308 0.480769 0.0192308 0.480769 [ -[.01923 -0.0125 -3 -9 ] -[.01923 -0.0125 3 0 ] -[.25962 -0.0125 -9 -9 ] -[.25962 -0.0125 9 0 ] -[.5 -0.0125 -3 -9 ] -[.5 -0.0125 3 0 ] -[.74038 -0.0125 -9 -9 ] -[.74038 -0.0125 9 0 ] -[.98077 -0.0125 -3 -9 ] -[.98077 -0.0125 3 0 ] -[ 0 0 -0.125 0 ] -[-0.0125 .01923 -6 -4.5 ] -[-0.0125 .01923 0 4.5 ] -[-0.0125 .25962 -18 -4.5 ] -[-0.0125 .25962 0 4.5 ] -[-0.0125 .5 -6 -4.5 ] -[-0.0125 .5 0 4.5 ] -[-0.0125 .74038 -18 -4.5 ] -[-0.0125 .74038 0 4.5 ] -[-0.0125 .98077 -6 -4.5 ] -[-0.0125 .98077 0 4.5 ] -[ 0 0 -0.125 0 ] -[ 0 1 .125 0 ] -[ 1 0 .125 0 ] -[ 0 0 0 0 ] -[ 1 1 0 0 ] -] MathScale -% Start of Graphics -1 setlinecap -1 setlinejoin -newpath -0 g -.25 Mabswid -.01923 0 m -.01923 .00625 L -s -[(0)] .01923 -0.0125 0 1 Mshowa -.25962 0 m -.25962 .00625 L -s -[(0.5)] .25962 -0.0125 0 1 Mshowa -.5 0 m -.5 .00625 L -s -[(1)] .5 -0.0125 0 1 Mshowa -.74038 0 m -.74038 .00625 L -s -[(1.5)] .74038 -0.0125 0 1 Mshowa -.98077 0 m -.98077 .00625 L -s -[(2)] .98077 -0.0125 0 1 Mshowa -.125 Mabswid -.06731 0 m -.06731 .00375 L -s -.11538 0 m -.11538 .00375 L -s -.16346 0 m -.16346 .00375 L -s -.21154 0 m -.21154 .00375 L -s -.30769 0 m -.30769 .00375 L -s -.35577 0 m -.35577 .00375 L -s -.40385 0 m -.40385 .00375 L -s -.45192 0 m -.45192 .00375 L -s -.54808 0 m -.54808 .00375 L -s -.59615 0 m -.59615 .00375 L -s -.64423 0 m -.64423 .00375 L -s -.69231 0 m -.69231 .00375 L -s -.78846 0 m -.78846 .00375 L -s -.83654 0 m -.83654 .00375 L -s -.88462 0 m -.88462 .00375 L -s -.93269 0 m -.93269 .00375 L -s -.25 Mabswid -0 0 m -1 0 L -s -0 .01923 m -.00625 .01923 L -s -[(0)] -0.0125 .01923 1 0 Mshowa -0 .25962 m -.00625 .25962 L -s -[(0.5)] -0.0125 .25962 1 0 Mshowa -0 .5 m -.00625 .5 L -s -[(1)] -0.0125 .5 1 0 Mshowa -0 .74038 m -.00625 .74038 L -s -[(1.5)] -0.0125 .74038 1 0 Mshowa -0 .98077 m -.00625 .98077 L -s -[(2)] -0.0125 .98077 1 0 Mshowa -.125 Mabswid -0 .06731 m -.00375 .06731 L -s -0 .11538 m -.00375 .11538 L -s -0 .16346 m -.00375 .16346 L -s -0 .21154 m -.00375 .21154 L -s -0 .30769 m -.00375 .30769 L -s -0 .35577 m -.00375 .35577 L -s -0 .40385 m -.00375 .40385 L -s -0 .45192 m -.00375 .45192 L -s -0 .54808 m -.00375 .54808 L -s -0 .59615 m -.00375 .59615 L -s -0 .64423 m -.00375 .64423 L -s -0 .69231 m -.00375 .69231 L -s -0 .78846 m -.00375 .78846 L -s -0 .83654 m -.00375 .83654 L -s -0 .88462 m -.00375 .88462 L -s -0 .93269 m -.00375 .93269 L -s -.25 Mabswid -0 0 m -0 1 L -s -.01923 .99375 m -.01923 1 L -s -.25962 .99375 m -.25962 1 L -s -.5 .99375 m -.5 1 L -s -.74038 .99375 m -.74038 1 L -s -.98077 .99375 m -.98077 1 L -s -.125 Mabswid -.06731 .99625 m -.06731 1 L -s -.11538 .99625 m -.11538 1 L -s -.16346 .99625 m -.16346 1 L -s -.21154 .99625 m -.21154 1 L -s -.30769 .99625 m -.30769 1 L -s -.35577 .99625 m -.35577 1 L -s -.40385 .99625 m -.40385 1 L -s -.45192 .99625 m -.45192 1 L -s -.54808 .99625 m -.54808 1 L -s -.59615 .99625 m -.59615 1 L -s -.64423 .99625 m -.64423 1 L -s -.69231 .99625 m -.69231 1 L -s -.78846 .99625 m -.78846 1 L -s -.83654 .99625 m -.83654 1 L -s -.88462 .99625 m -.88462 1 L -s -.93269 .99625 m -.93269 1 L -s -.25 Mabswid -0 1 m -1 1 L -s -.99375 .01923 m -1 .01923 L -s -.99375 .25962 m -1 .25962 L -s -.99375 .5 m -1 .5 L -s -.99375 .74038 m -1 .74038 L -s -.99375 .98077 m -1 .98077 L -s -.125 Mabswid -.99625 .06731 m -1 .06731 L -s -.99625 .11538 m -1 .11538 L -s -.99625 .16346 m -1 .16346 L -s -.99625 .21154 m -1 .21154 L -s -.99625 .30769 m -1 .30769 L -s -.99625 .35577 m -1 .35577 L -s -.99625 .40385 m -1 .40385 L -s -.99625 .45192 m -1 .45192 L -s -.99625 .54808 m -1 .54808 L -s -.99625 .59615 m -1 .59615 L -s -.99625 .64423 m -1 .64423 L -s -.99625 .69231 m -1 .69231 L -s -.99625 .78846 m -1 .78846 L -s -.99625 .83654 m -1 .83654 L -s -.99625 .88462 m -1 .88462 L -s -.99625 .93269 m -1 .93269 L -s -.25 Mabswid -1 0 m -1 1 L -s -0 0 m -1 0 L -1 1 L -0 1 L -closepath -clip -newpath -.5 g -.01923 .98077 m -.98077 .98077 L -.98077 .01923 L -.01923 .01923 L -F -0 g -.5 Mabswid -.4 g -.01923 .20178 m -.08791 .16652 L -.10274 .15659 L -.15659 .10274 L -.16652 .08791 L -.20178 .01923 L -.01923 .01923 L -F -0 g -.01923 .20178 m -.08791 .16652 L -.10274 .15659 L -.15659 .10274 L -.16652 .08791 L -.20178 .01923 L -s -.4 g -.01923 .68255 m -.08791 .64729 L -.10274 .63736 L -.15659 .58351 L -.16652 .56868 L -.20178 .5 L -.16652 .43132 L -.15659 .41649 L -.10274 .36264 L -.08791 .35271 L -.01923 .31745 L -F -0 g -.01923 .68255 m -.08791 .64729 L -.10274 .63736 L -.15659 .58351 L -.16652 .56868 L -.20178 .5 L -.16652 .43132 L -.15659 .41649 L -.10274 .36264 L -.08791 .35271 L -.01923 .31745 L -s -.4 g -.01923 .79822 m -.08791 .83348 L -.10274 .84341 L -.15659 .89726 L -.16652 .91209 L -.20178 .98077 L -.01923 .98077 L -F -0 g -.01923 .79822 m -.08791 .83348 L -.10274 .84341 L -.15659 .89726 L -.16652 .91209 L -.20178 .98077 L -s -.3 g -.01923 .16767 m -.04817 .15659 L -.08791 .14179 L -.14179 .08791 L -.15659 .04817 L -.16767 .01923 L -.01923 .01923 L -F -0 g -.01923 .16767 m -.04817 .15659 L -.08791 .14179 L -.14179 .08791 L -.15659 .04817 L -.16767 .01923 L -s -.3 g -.01923 .64844 m -.04817 .63736 L -.08791 .62256 L -.14179 .56868 L -.15659 .53811 L -.16767 .5 L -.15659 .46189 L -.14179 .43132 L -.08791 .37744 L -.04817 .36264 L -.01923 .35156 L -F -0 g -.01923 .64844 m -.04817 .63736 L -.08791 .62256 L -.14179 .56868 L -.15659 .53811 L -.16767 .5 L -.15659 .46189 L -.14179 .43132 L -.08791 .37744 L -.04817 .36264 L -.01923 .35156 L -s -.3 g -.01923 .83233 m -.04817 .84341 L -.08791 .85821 L -.14179 .91209 L -.15659 .95183 L -.16767 .98077 L -.01923 .98077 L -F -0 g -.01923 .83233 m -.04817 .84341 L -.08791 .85821 L -.14179 .91209 L -.15659 .95183 L -.16767 .98077 L -s -.2 g -.01923 .14263 m -.08791 .11498 L -.11498 .08791 L -.14263 .01923 L -.01923 .01923 L -F -0 g -.01923 .14263 m -.08791 .11498 L -.11498 .08791 L -.14263 .01923 L -s -.2 g -.01923 .6234 m -.08791 .59574 L -.11498 .56868 L -.14263 .5 L -.11498 .43132 L -.08791 .40426 L -.01923 .3766 L -F -0 g -.01923 .6234 m -.08791 .59574 L -.11498 .56868 L -.14263 .5 L -.11498 .43132 L -.08791 .40426 L -.01923 .3766 L -s -.2 g -.01923 .85737 m -.08791 .88502 L -.11498 .91209 L -.14263 .98077 L -.01923 .98077 L -F -0 g -.01923 .85737 m -.08791 .88502 L -.11498 .91209 L -.14263 .98077 L -s -.1 g -.01923 .11622 m -.06971 .08791 L -.08791 .06971 L -.11622 .01923 L -.01923 .01923 L -F -0 g -.01923 .11622 m -.06971 .08791 L -.08791 .06971 L -.11622 .01923 L -s -.1 g -.01923 .59699 m -.06971 .56868 L -.08791 .55491 L -.11622 .5 L -.08791 .44509 L -.06971 .43132 L -.01923 .40301 L -F -0 g -.01923 .59699 m -.06971 .56868 L -.08791 .55491 L -.11622 .5 L -.08791 .44509 L -.06971 .43132 L -.01923 .40301 L -s -.1 g -.01923 .88378 m -.06971 .91209 L -.08791 .93029 L -.11622 .98077 L -.01923 .98077 L -F -0 g -.01923 .88378 m -.06971 .91209 L -.08791 .93029 L -.11622 .98077 L -s -.01923 .07191 m -.07191 .01923 L -.01923 .01923 L -F -.01923 .07191 m -.07191 .01923 L -s -.01923 .55656 m -.07191 .5 L -.01923 .44344 L -F -.01923 .55656 m -.07191 .5 L -.01923 .44344 L -s -.01923 .92809 m -.07191 .98077 L -.01923 .98077 L -F -.01923 .92809 m -.07191 .98077 L -s -.6 g -.22527 .54531 m -.29396 .54531 L -.31893 .56868 L -.36264 .61483 L -.38517 .63736 L -.43132 .68107 L -.45469 .70604 L -.45469 .77473 L -.43132 .7997 L -.38517 .84341 L -.36264 .86594 L -.31893 .91209 L -.29396 .94288 L -.22527 .94288 L -.2003 .91209 L -.15659 .86594 L -.13406 .84341 L -.08791 .7997 L -.05712 .77473 L -.05712 .70604 L -.08791 .68107 L -.13406 .63736 L -.15659 .61483 L -.2003 .56868 L -F -0 g -.22527 .54531 m -.29396 .54531 L -.31893 .56868 L -.36264 .61483 L -.38517 .63736 L -.43132 .68107 L -.45469 .70604 L -.45469 .77473 L -.43132 .7997 L -.38517 .84341 L -.36264 .86594 L -.31893 .91209 L -.29396 .94288 L -.22527 .94288 L -.2003 .91209 L -.15659 .86594 L -.13406 .84341 L -.08791 .7997 L -.05712 .77473 L -.05712 .70604 L -.08791 .68107 L -.13406 .63736 L -.15659 .61483 L -.2003 .56868 L -.22527 .54531 L -s -.6 g -.22527 .05712 m -.29396 .05712 L -.31893 .08791 L -.36264 .13406 L -.38517 .15659 L -.43132 .2003 L -.45469 .22527 L -.45469 .29396 L -.43132 .31893 L -.38517 .36264 L -.36264 .38517 L -.31893 .43132 L -.29396 .45469 L -.22527 .45469 L -.2003 .43132 L -.15659 .38517 L -.13406 .36264 L -.08791 .31893 L -.05712 .29396 L -.05712 .22527 L -.08791 .2003 L -.13406 .15659 L -.15659 .13406 L -.2003 .08791 L -F -0 g -.22527 .05712 m -.29396 .05712 L -.31893 .08791 L -.36264 .13406 L -.38517 .15659 L -.43132 .2003 L -.45469 .22527 L -.45469 .29396 L -.43132 .31893 L -.38517 .36264 L -.36264 .38517 L -.31893 .43132 L -.29396 .45469 L -.22527 .45469 L -.2003 .43132 L -.15659 .38517 L -.13406 .36264 L -.08791 .31893 L -.05712 .29396 L -.05712 .22527 L -.08791 .2003 L -.13406 .15659 L -.15659 .13406 L -.2003 .08791 L -.22527 .05712 L -s -.7 g -.22527 .58861 m -.29396 .58861 L -.36261 .63736 L -.36264 .63739 L -.41139 .70604 L -.41139 .77473 L -.36264 .84338 L -.36261 .84341 L -.29396 .89216 L -.22527 .89216 L -.15662 .84341 L -.15659 .84338 L -.10784 .77473 L -.10784 .70604 L -.15659 .63739 L -.15662 .63736 L -F -0 g -.22527 .58861 m -.29396 .58861 L -.36261 .63736 L -.36264 .63739 L -.41139 .70604 L -.41139 .77473 L -.36264 .84338 L -.36261 .84341 L -.29396 .89216 L -.22527 .89216 L -.15662 .84341 L -.15659 .84338 L -.10784 .77473 L -.10784 .70604 L -.15659 .63739 L -.15662 .63736 L -.22527 .58861 L -s -.7 g -.22527 .10784 m -.29396 .10784 L -.36261 .15659 L -.36264 .15662 L -.41139 .22527 L -.41139 .29396 L -.36264 .36261 L -.36261 .36264 L -.29396 .41139 L -.22527 .41139 L -.15662 .36264 L -.15659 .36261 L -.10784 .29396 L -.10784 .22527 L -.15659 .15662 L -.15662 .15659 L -F -0 g -.22527 .10784 m -.29396 .10784 L -.36261 .15659 L -.36264 .15662 L -.41139 .22527 L -.41139 .29396 L -.36264 .36261 L -.36261 .36264 L -.29396 .41139 L -.22527 .41139 L -.15662 .36264 L -.15659 .36261 L -.10784 .29396 L -.10784 .22527 L -.15659 .15662 L -.15662 .15659 L -.22527 .10784 L -s -.8 g -.22527 .61796 m -.29396 .61796 L -.3311 .63736 L -.36264 .6689 L -.38204 .70604 L -.38204 .77473 L -.36264 .81187 L -.3311 .84341 L -.29396 .86281 L -.22527 .86281 L -.18813 .84341 L -.15659 .81187 L -.13719 .77473 L -.13719 .70604 L -.15659 .6689 L -.18813 .63736 L -F -0 g -.22527 .61796 m -.29396 .61796 L -.3311 .63736 L -.36264 .6689 L -.38204 .70604 L -.38204 .77473 L -.36264 .81187 L -.3311 .84341 L -.29396 .86281 L -.22527 .86281 L -.18813 .84341 L -.15659 .81187 L -.13719 .77473 L -.13719 .70604 L -.15659 .6689 L -.18813 .63736 L -.22527 .61796 L -s -.8 g -.22527 .13719 m -.29396 .13719 L -.3311 .15659 L -.36264 .18813 L -.38204 .22527 L -.38204 .29396 L -.36264 .3311 L -.3311 .36264 L -.29396 .38204 L -.22527 .38204 L -.18813 .36264 L -.15659 .3311 L -.13719 .29396 L -.13719 .22527 L -.15659 .18813 L -.18813 .15659 L -F -0 g -.22527 .13719 m -.29396 .13719 L -.3311 .15659 L -.36264 .18813 L -.38204 .22527 L -.38204 .29396 L -.36264 .3311 L -.3311 .36264 L -.29396 .38204 L -.22527 .38204 L -.18813 .36264 L -.15659 .3311 L -.13719 .29396 L -.13719 .22527 L -.15659 .18813 L -.18813 .15659 L -.22527 .13719 L -s -.9 g -.22527 .64125 m -.29396 .64125 L -.35875 .70604 L -.35875 .77473 L -.29396 .83952 L -.22527 .83952 L -.16048 .77473 L -.16048 .70604 L -F -0 g -.22527 .64125 m -.29396 .64125 L -.35875 .70604 L -.35875 .77473 L -.29396 .83952 L -.22527 .83952 L -.16048 .77473 L -.16048 .70604 L -.22527 .64125 L -s -.9 g -.22527 .16048 m -.29396 .16048 L -.35875 .22527 L -.35875 .29396 L -.29396 .35875 L -.22527 .35875 L -.16048 .29396 L -.16048 .22527 L -F -0 g -.22527 .16048 m -.29396 .16048 L -.35875 .22527 L -.35875 .29396 L -.29396 .35875 L -.22527 .35875 L -.16048 .29396 L -.16048 .22527 L -.22527 .16048 L -s -1 g -.22527 .67353 m -.29396 .67353 L -.32647 .70604 L -.32647 .77473 L -.29396 .80724 L -.22527 .80724 L -.19276 .77473 L -.19276 .70604 L -F -0 g -.22527 .67353 m -.29396 .67353 L -.32647 .70604 L -.32647 .77473 L -.29396 .80724 L -.22527 .80724 L -.19276 .77473 L -.19276 .70604 L -.22527 .67353 L -s -1 g -.22527 .19276 m -.29396 .19276 L -.32647 .22527 L -.32647 .29396 L -.29396 .32647 L -.22527 .32647 L -.19276 .29396 L -.19276 .22527 L -F -0 g -.22527 .19276 m -.29396 .19276 L -.32647 .22527 L -.32647 .29396 L -.29396 .32647 L -.22527 .32647 L -.19276 .29396 L -.19276 .22527 L -.22527 .19276 L -s -.4 g -.68255 .01923 m -.64729 .08791 L -.63736 .10274 L -.58351 .15659 L -.56868 .16652 L -.5 .20178 L -.43132 .16652 L -.41649 .15659 L -.36264 .10274 L -.35271 .08791 L -.31745 .01923 L -F -0 g -.68255 .01923 m -.64729 .08791 L -.63736 .10274 L -.58351 .15659 L -.56868 .16652 L -.5 .20178 L -.43132 .16652 L -.41649 .15659 L -.36264 .10274 L -.35271 .08791 L -.31745 .01923 L -s -.4 g -.43132 .35271 m -.5 .31745 L -.56868 .35271 L -.58351 .36264 L -.63736 .41649 L -.64729 .43132 L -.68255 .5 L -.64729 .56868 L -.63736 .58351 L -.58351 .63736 L -.56868 .64729 L -.5 .68255 L -.43132 .64729 L -.41649 .63736 L -.36264 .58351 L -.35271 .56868 L -.31745 .5 L -.35271 .43132 L -.36264 .41649 L -.41649 .36264 L -F -0 g -.43132 .35271 m -.5 .31745 L -.56868 .35271 L -.58351 .36264 L -.63736 .41649 L -.64729 .43132 L -.68255 .5 L -.64729 .56868 L -.63736 .58351 L -.58351 .63736 L -.56868 .64729 L -.5 .68255 L -.43132 .64729 L -.41649 .63736 L -.36264 .58351 L -.35271 .56868 L -.31745 .5 L -.35271 .43132 L -.36264 .41649 L -.41649 .36264 L -.43132 .35271 L -s -.4 g -.68255 .98077 m -.64729 .91209 L -.63736 .89726 L -.58351 .84341 L -.56868 .83348 L -.5 .79822 L -.43132 .83348 L -.41649 .84341 L -.36264 .89726 L -.35271 .91209 L -.31745 .98077 L -F -0 g -.68255 .98077 m -.64729 .91209 L -.63736 .89726 L -.58351 .84341 L -.56868 .83348 L -.5 .79822 L -.43132 .83348 L -.41649 .84341 L -.36264 .89726 L -.35271 .91209 L -.31745 .98077 L -s -.3 g -.64844 .01923 m -.63736 .04817 L -.62256 .08791 L -.56868 .14179 L -.53811 .15659 L -.5 .16767 L -.46189 .15659 L -.43132 .14179 L -.37744 .08791 L -.36264 .04817 L -.35156 .01923 L -F -0 g -.64844 .01923 m -.63736 .04817 L -.62256 .08791 L -.56868 .14179 L -.53811 .15659 L -.5 .16767 L -.46189 .15659 L -.43132 .14179 L -.37744 .08791 L -.36264 .04817 L -.35156 .01923 L -s -.3 g -.5 .35156 m -.53811 .36264 L -.56868 .37744 L -.62256 .43132 L -.63736 .46189 L -.64844 .5 L -.63736 .53811 L -.62256 .56868 L -.56868 .62256 L -.53811 .63736 L -.5 .64844 L -.46189 .63736 L -.43132 .62256 L -.37744 .56868 L -.36264 .53811 L -.35156 .5 L -.36264 .46189 L -.37744 .43132 L -.43132 .37744 L -.46189 .36264 L -F -0 g -.5 .35156 m -.53811 .36264 L -.56868 .37744 L -.62256 .43132 L -.63736 .46189 L -.64844 .5 L -.63736 .53811 L -.62256 .56868 L -.56868 .62256 L -.53811 .63736 L -.5 .64844 L -.46189 .63736 L -.43132 .62256 L -.37744 .56868 L -.36264 .53811 L -.35156 .5 L -.36264 .46189 L -.37744 .43132 L -.43132 .37744 L -.46189 .36264 L -.5 .35156 L -s -.3 g -.64844 .98077 m -.63736 .95183 L -.62256 .91209 L -.56868 .85821 L -.53811 .84341 L -.5 .83233 L -.46189 .84341 L -.43132 .85821 L -.37744 .91209 L -.36264 .95183 L -.35156 .98077 L -F -0 g -.64844 .98077 m -.63736 .95183 L -.62256 .91209 L -.56868 .85821 L -.53811 .84341 L -.5 .83233 L -.46189 .84341 L -.43132 .85821 L -.37744 .91209 L -.36264 .95183 L -.35156 .98077 L -s -.2 g -.6234 .01923 m -.59574 .08791 L -.56868 .11498 L -.5 .14263 L -.43132 .11498 L -.40426 .08791 L -.3766 .01923 L -F -0 g -.6234 .01923 m -.59574 .08791 L -.56868 .11498 L -.5 .14263 L -.43132 .11498 L -.40426 .08791 L -.3766 .01923 L -s -.2 g -.43132 .40426 m -.5 .3766 L -.56868 .40426 L -.59574 .43132 L -.6234 .5 L -.59574 .56868 L -.56868 .59574 L -.5 .6234 L -.43132 .59574 L -.40426 .56868 L -.3766 .5 L -.40426 .43132 L -F -0 g -.43132 .40426 m -.5 .3766 L -.56868 .40426 L -.59574 .43132 L -.6234 .5 L -.59574 .56868 L -.56868 .59574 L -.5 .6234 L -.43132 .59574 L -.40426 .56868 L -.3766 .5 L -.40426 .43132 L -.43132 .40426 L -s -.2 g -.6234 .98077 m -.59574 .91209 L -.56868 .88502 L -.5 .85737 L -.43132 .88502 L -.40426 .91209 L -.3766 .98077 L -F -0 g -.6234 .98077 m -.59574 .91209 L -.56868 .88502 L -.5 .85737 L -.43132 .88502 L -.40426 .91209 L -.3766 .98077 L -s -.1 g -.59699 .01923 m -.56868 .06971 L -.55491 .08791 L -.5 .11622 L -.44509 .08791 L -.43132 .06971 L -.40301 .01923 L -F -0 g -.59699 .01923 m -.56868 .06971 L -.55491 .08791 L -.5 .11622 L -.44509 .08791 L -.43132 .06971 L -.40301 .01923 L -s -.1 g -.5 .40301 m -.55491 .43132 L -.56868 .44509 L -.59699 .5 L -.56868 .55491 L -.55491 .56868 L -.5 .59699 L -.44509 .56868 L -.43132 .55491 L -.40301 .5 L -.43132 .44509 L -.44509 .43132 L -F -0 g -.5 .40301 m -.55491 .43132 L -.56868 .44509 L -.59699 .5 L -.56868 .55491 L -.55491 .56868 L -.5 .59699 L -.44509 .56868 L -.43132 .55491 L -.40301 .5 L -.43132 .44509 L -.44509 .43132 L -.5 .40301 L -s -.1 g -.59699 .98077 m -.56868 .93029 L -.55491 .91209 L -.5 .88378 L -.44509 .91209 L -.43132 .93029 L -.40301 .98077 L -F -0 g -.59699 .98077 m -.56868 .93029 L -.55491 .91209 L -.5 .88378 L -.44509 .91209 L -.43132 .93029 L -.40301 .98077 L -s -.55656 .01923 m -.5 .07191 L -.44344 .01923 L -F -.55656 .01923 m -.5 .07191 L -.44344 .01923 L -s -.5 .44344 m -.55656 .5 L -.5 .55656 L -.44344 .5 L -F -.5 .44344 m -.55656 .5 L -.5 .55656 L -.44344 .5 L -.5 .44344 L -s -.55656 .98077 m -.5 .92809 L -.44344 .98077 L -F -.55656 .98077 m -.5 .92809 L -.44344 .98077 L -s -.6 g -.70604 .54531 m -.77473 .54531 L -.7997 .56868 L -.84341 .61483 L -.86594 .63736 L -.91209 .68107 L -.94288 .70604 L -.94288 .77473 L -.91209 .7997 L -.86594 .84341 L -.84341 .86594 L -.7997 .91209 L -.77473 .94288 L -.70604 .94288 L -.68107 .91209 L -.63736 .86594 L -.61483 .84341 L -.56868 .7997 L -.54531 .77473 L -.54531 .70604 L -.56868 .68107 L -.61483 .63736 L -.63736 .61483 L -.68107 .56868 L -F -0 g -.70604 .54531 m -.77473 .54531 L -.7997 .56868 L -.84341 .61483 L -.86594 .63736 L -.91209 .68107 L -.94288 .70604 L -.94288 .77473 L -.91209 .7997 L -.86594 .84341 L -.84341 .86594 L -.7997 .91209 L -.77473 .94288 L -.70604 .94288 L -.68107 .91209 L -.63736 .86594 L -.61483 .84341 L -.56868 .7997 L -.54531 .77473 L -.54531 .70604 L -.56868 .68107 L -.61483 .63736 L -.63736 .61483 L -.68107 .56868 L -.70604 .54531 L -s -.6 g -.70604 .05712 m -.77473 .05712 L -.7997 .08791 L -.84341 .13406 L -.86594 .15659 L -.91209 .2003 L -.94288 .22527 L -.94288 .29396 L -.91209 .31893 L -.86594 .36264 L -.84341 .38517 L -.7997 .43132 L -.77473 .45469 L -.70604 .45469 L -.68107 .43132 L -.63736 .38517 L -.61483 .36264 L -.56868 .31893 L -.54531 .29396 L -.54531 .22527 L -.56868 .2003 L -.61483 .15659 L -.63736 .13406 L -.68107 .08791 L -F -0 g -.70604 .05712 m -.77473 .05712 L -.7997 .08791 L -.84341 .13406 L -.86594 .15659 L -.91209 .2003 L -.94288 .22527 L -.94288 .29396 L -.91209 .31893 L -.86594 .36264 L -.84341 .38517 L -.7997 .43132 L -.77473 .45469 L -.70604 .45469 L -.68107 .43132 L -.63736 .38517 L -.61483 .36264 L -.56868 .31893 L -.54531 .29396 L -.54531 .22527 L -.56868 .2003 L -.61483 .15659 L -.63736 .13406 L -.68107 .08791 L -.70604 .05712 L -s -.7 g -.70604 .58861 m -.77473 .58861 L -.84338 .63736 L -.84341 .63739 L -.89216 .70604 L -.89216 .77473 L -.84341 .84338 L -.84338 .84341 L -.77473 .89216 L -.70604 .89216 L -.63739 .84341 L -.63736 .84338 L -.58861 .77473 L -.58861 .70604 L -.63736 .63739 L -.63739 .63736 L -F -0 g -.70604 .58861 m -.77473 .58861 L -.84338 .63736 L -.84341 .63739 L -.89216 .70604 L -.89216 .77473 L -.84341 .84338 L -.84338 .84341 L -.77473 .89216 L -.70604 .89216 L -.63739 .84341 L -.63736 .84338 L -.58861 .77473 L -.58861 .70604 L -.63736 .63739 L -.63739 .63736 L -.70604 .58861 L -s -.7 g -.70604 .10784 m -.77473 .10784 L -.84338 .15659 L -.84341 .15662 L -.89216 .22527 L -.89216 .29396 L -.84341 .36261 L -.84338 .36264 L -.77473 .41139 L -.70604 .41139 L -.63739 .36264 L -.63736 .36261 L -.58861 .29396 L -.58861 .22527 L -.63736 .15662 L -.63739 .15659 L -F -0 g -.70604 .10784 m -.77473 .10784 L -.84338 .15659 L -.84341 .15662 L -.89216 .22527 L -.89216 .29396 L -.84341 .36261 L -.84338 .36264 L -.77473 .41139 L -.70604 .41139 L -.63739 .36264 L -.63736 .36261 L -.58861 .29396 L -.58861 .22527 L -.63736 .15662 L -.63739 .15659 L -.70604 .10784 L -s -.8 g -.70604 .61796 m -.77473 .61796 L -.81187 .63736 L -.84341 .6689 L -.86281 .70604 L -.86281 .77473 L -.84341 .81187 L -.81187 .84341 L -.77473 .86281 L -.70604 .86281 L -.6689 .84341 L -.63736 .81187 L -.61796 .77473 L -.61796 .70604 L -.63736 .6689 L -.6689 .63736 L -F -0 g -.70604 .61796 m -.77473 .61796 L -.81187 .63736 L -.84341 .6689 L -.86281 .70604 L -.86281 .77473 L -.84341 .81187 L -.81187 .84341 L -.77473 .86281 L -.70604 .86281 L -.6689 .84341 L -.63736 .81187 L -.61796 .77473 L -.61796 .70604 L -.63736 .6689 L -.6689 .63736 L -.70604 .61796 L -s -.8 g -.70604 .13719 m -.77473 .13719 L -.81187 .15659 L -.84341 .18813 L -.86281 .22527 L -.86281 .29396 L -.84341 .3311 L -.81187 .36264 L -.77473 .38204 L -.70604 .38204 L -.6689 .36264 L -.63736 .3311 L -.61796 .29396 L -.61796 .22527 L -.63736 .18813 L -.6689 .15659 L -F -0 g -.70604 .13719 m -.77473 .13719 L -.81187 .15659 L -.84341 .18813 L -.86281 .22527 L -.86281 .29396 L -.84341 .3311 L -.81187 .36264 L -.77473 .38204 L -.70604 .38204 L -.6689 .36264 L -.63736 .3311 L -.61796 .29396 L -.61796 .22527 L -.63736 .18813 L -.6689 .15659 L -.70604 .13719 L -s -.9 g -.70604 .64125 m -.77473 .64125 L -.83952 .70604 L -.83952 .77473 L -.77473 .83952 L -.70604 .83952 L -.64125 .77473 L -.64125 .70604 L -F -0 g -.70604 .64125 m -.77473 .64125 L -.83952 .70604 L -.83952 .77473 L -.77473 .83952 L -.70604 .83952 L -.64125 .77473 L -.64125 .70604 L -.70604 .64125 L -s -.9 g -.70604 .16048 m -.77473 .16048 L -.83952 .22527 L -.83952 .29396 L -.77473 .35875 L -.70604 .35875 L -.64125 .29396 L -.64125 .22527 L -F -0 g -.70604 .16048 m -.77473 .16048 L -.83952 .22527 L -.83952 .29396 L -.77473 .35875 L -.70604 .35875 L -.64125 .29396 L -.64125 .22527 L -.70604 .16048 L -s -1 g -.70604 .67353 m -.77473 .67353 L -.80724 .70604 L -.80724 .77473 L -.77473 .80724 L -.70604 .80724 L -.67353 .77473 L -.67353 .70604 L -F -0 g -.70604 .67353 m -.77473 .67353 L -.80724 .70604 L -.80724 .77473 L -.77473 .80724 L -.70604 .80724 L -.67353 .77473 L -.67353 .70604 L -.70604 .67353 L -s -1 g -.70604 .19276 m -.77473 .19276 L -.80724 .22527 L -.80724 .29396 L -.77473 .32647 L -.70604 .32647 L -.67353 .29396 L -.67353 .22527 L -F -0 g -.70604 .19276 m -.77473 .19276 L -.80724 .22527 L -.80724 .29396 L -.77473 .32647 L -.70604 .32647 L -.67353 .29396 L -.67353 .22527 L -.70604 .19276 L -s -.4 g -.98077 .20178 m -.91209 .16652 L -.89726 .15659 L -.84341 .10274 L -.83348 .08791 L -.79822 .01923 L -.98077 .01923 L -F -0 g -.98077 .20178 m -.91209 .16652 L -.89726 .15659 L -.84341 .10274 L -.83348 .08791 L -.79822 .01923 L -s -.4 g -.98077 .68255 m -.91209 .64729 L -.89726 .63736 L -.84341 .58351 L -.83348 .56868 L -.79822 .5 L -.83348 .43132 L -.84341 .41649 L -.89726 .36264 L -.91209 .35271 L -.98077 .31745 L -F -0 g -.98077 .68255 m -.91209 .64729 L -.89726 .63736 L -.84341 .58351 L -.83348 .56868 L -.79822 .5 L -.83348 .43132 L -.84341 .41649 L -.89726 .36264 L -.91209 .35271 L -.98077 .31745 L -s -.4 g -.98077 .79822 m -.91209 .83348 L -.89726 .84341 L -.84341 .89726 L -.83348 .91209 L -.79822 .98077 L -.98077 .98077 L -F -0 g -.98077 .79822 m -.91209 .83348 L -.89726 .84341 L -.84341 .89726 L -.83348 .91209 L -.79822 .98077 L -s -.3 g -.98077 .16767 m -.95183 .15659 L -.91209 .14179 L -.85821 .08791 L -.84341 .04817 L -.83233 .01923 L -.98077 .01923 L -F -0 g -.98077 .16767 m -.95183 .15659 L -.91209 .14179 L -.85821 .08791 L -.84341 .04817 L -.83233 .01923 L -s -.3 g -.98077 .64844 m -.95183 .63736 L -.91209 .62256 L -.85821 .56868 L -.84341 .53811 L -.83233 .5 L -.84341 .46189 L -.85821 .43132 L -.91209 .37744 L -.95183 .36264 L -.98077 .35156 L -F -0 g -.98077 .64844 m -.95183 .63736 L -.91209 .62256 L -.85821 .56868 L -.84341 .53811 L -.83233 .5 L -.84341 .46189 L -.85821 .43132 L -.91209 .37744 L -.95183 .36264 L -.98077 .35156 L -s -.3 g -.98077 .83233 m -.95183 .84341 L -.91209 .85821 L -.85821 .91209 L -.84341 .95183 L -.83233 .98077 L -.98077 .98077 L -F -0 g -.98077 .83233 m -.95183 .84341 L -.91209 .85821 L -.85821 .91209 L -.84341 .95183 L -.83233 .98077 L -s -.2 g -.98077 .14263 m -.91209 .11498 L -.88502 .08791 L -.85737 .01923 L -.98077 .01923 L -F -0 g -.98077 .14263 m -.91209 .11498 L -.88502 .08791 L -.85737 .01923 L -s -.2 g -.98077 .6234 m -.91209 .59574 L -.88502 .56868 L -.85737 .5 L -.88502 .43132 L -.91209 .40426 L -.98077 .3766 L -F -0 g -.98077 .6234 m -.91209 .59574 L -.88502 .56868 L -.85737 .5 L -.88502 .43132 L -.91209 .40426 L -.98077 .3766 L -s -.2 g -.98077 .85737 m -.91209 .88502 L -.88502 .91209 L -.85737 .98077 L -.98077 .98077 L -F -0 g -.98077 .85737 m -.91209 .88502 L -.88502 .91209 L -.85737 .98077 L -s -.1 g -.98077 .11622 m -.93029 .08791 L -.91209 .06971 L -.88378 .01923 L -.98077 .01923 L -F -0 g -.98077 .11622 m -.93029 .08791 L -.91209 .06971 L -.88378 .01923 L -s -.1 g -.98077 .59699 m -.93029 .56868 L -.91209 .55491 L -.88378 .5 L -.91209 .44509 L -.93029 .43132 L -.98077 .40301 L -F -0 g -.98077 .59699 m -.93029 .56868 L -.91209 .55491 L -.88378 .5 L -.91209 .44509 L -.93029 .43132 L -.98077 .40301 L -s -.1 g -.98077 .88378 m -.93029 .91209 L -.91209 .93029 L -.88378 .98077 L -.98077 .98077 L -F -0 g -.98077 .88378 m -.93029 .91209 L -.91209 .93029 L -.88378 .98077 L -s -.98077 .07191 m -.92809 .01923 L -.98077 .01923 L -F -.98077 .07191 m -.92809 .01923 L -s -.98077 .55656 m -.92809 .5 L -.98077 .44344 L -F -.98077 .55656 m -.92809 .5 L -.98077 .44344 L -s -.98077 .92809 m -.92809 .98077 L -.98077 .98077 L -F -.98077 .92809 m -.92809 .98077 L -s -% End of Graphics -MathPictureEnd -\ -\>"], "Graphics", - ImageSize->{288, 288}, - ImageMargins->{{43, 0}, {0, 0}}, - ImageRegion->{{0, 1}, {0, 1}}, - ImageCache->GraphicsData["Bitmap", "\<\ -CF5dJ6E]HGAYHf4PAg9QL6QYHgon6Ykno_hn?S`2ook>c/mWIfGmoOol005E[;lC4a000<`00IP00V@00c000 -o`0c000c<`0cIP0cV@0cc00co`1V001V<`1VIP1VV@1Vc01Vo`2I002I<`2IIP2IV@2Ic02Io`3<003< -<`3I03>IIIS>IVC>Ic3>Ioc?<03?<@000`40000f00030@0000L00`4i0003 -0@0000@0000H00040@000CH000@1000120000`40000i00030@0003H000<100001`000`40000j0003 -0@0000<0000H00040@000CH000@1000120000`40000g00<1=P030@T000<10000=`00104000450000 -6@020CP00P4900@1>0000`40000f00030@0000L0104g00811P000?l08@0001D0o`4;0@40000E0003 -0@00008000<100002P000`40000900030@0000X000<100002P000`40000:00030@0000X000<10000 -2@000`40000:00030@0000X000<100002P000`40000900030@0000X000<100002P000`40000:0003 -0@0000T000<100002P000`40000:00030@0000X000<100002P000`40000900030@0000800@410000 -5@000`40000200030@0003d000<10000?@000`40000l00030@0003d000<100000P010@40000E0003 -0@000?l01`010@40000>00811@000`40003o00L00@4100003@001040004400814@000`4000090003 -0@0000@000<100000`000`40000600030@0001`000<100001P000`40000400030@0000@000<10000 -20000`40000K00030@0000L000<1000010000`40000400030@0000H000<1000070000`4000060003 -0@0000<000<100001@000`40000800030@0000l00P4100003@001040004400030@0000803P403581 -DP5B0E81DP5B0@MB00L12E89DPT100P902012JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@P9 -00P1DPUB2E890@MB00X1DP5B0E81DP5B7`402U81DP5B0E81DP46DP080E89DPUB2@482@0P0@VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`482@070E89DPUB0@08DP0:0E81DP5B0E81DPh11@010@40 -000=00040@000@@000<100000P0=0@0;DP5B0E81DP5B0E800P46DP070@UB2E890@082@0R0@VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@P900P1DPUB2E890@IB0P402E81DP5B0E81DP0M0@0: -DP5B0E81DP5B0@IB00P1DPUB2E890@P902812JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1 -20T01`5B2E89DP401e820@09DP5B0E81DP5B00d11@010@40000=00040@000@@000<100000P0<0@0; -DP5B0E81DP5B0E800P47DP070E89DPUB0@082@0R0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL90@P900P12E89DPUB0@MB0P402E81DP5B0E81DP0K0@09DP5B0E81DP5B00811U802049DPUB2E81 -20T08P6W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@482@070@UB2E890@08DP8100UB0E81 -DP5B0E80304500410@0000d000@1000110000`40000200/100iB0E81DP5B0E81DP5B0@IB00P1DPUB -2E890@L902@1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@482@070@UB2E890@07DP0< -0E81DP5B0E81DP5B6@402E81DP5B0E81DP020@MB00P1DPUB2E890@L902@1Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2@482@070@UB2E890@07DP0<0E81DP5B0E81DP5B2`4500410@0000h0 -0P4500030@0000802P403U81DP5B0E81DP5B0E811e801`49DPUB2@4020T09049Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@P900P1DPUB2E890@MB00`1DP5B0E81DP5B0E8G0@00E81DP5B0E81DP5B0E870@D00@410000 -5@000`40000200H1011B0E81DP5B0E81DP5B0E811e802049DPUB2E811`T0:049Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`472@080@UB2E89DP48DP0@0E81DP5B0E81DP5B0E81DP/1 -011B0E81DP5B0E81DP5B0E811e802049DPUB2E811`T0:049Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`472@080@UB2E89DP48DP0>0E81DP5B0E81DP5B0E860@D00@4100005@000`40 -000200D1011B0E81DP5B0E81DP5B0E8125801`5B2E89DP401`T0:P49Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@L900P12E89DPUB0@MB0P403e81DP5B0E81DP5B0E81DP090@0@ -DP5B0E81DP5B0E81DP5B0@MB00P12E89DPUB0@L902X12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`472@070@UB2E890@08DP8100eB0E81DP5B0E81DP5B00D11@010@40000E0003 -0@00008010403e81DP5B0E81DP5B0E81DP020@MB00P1DPUB2E890@L900`1Y`VW2JL9Y`VW2JLC0@0; -Y`VW2JL9Y`VW2@401`T0205B2E89DPT125820@0?DP5B0E81DP5B0E81DP5B00L100mB0E81DP5B0E81 -DP5B0E800P47DP080E89DPUB2@472@0;0JL9Y`VW2JL9Y`T050402jL9Y`VW2JL9Y`T100L900P1DPUB -2E890@QB0P403E81DP5B0E81DP5B0E80104500410@0001D000<100000P030@0?DP5B0E81DP5B0E81 -DP5B008125802049DPUB2E811PT03@6W2JL9Y`VW2JL9Y`404jL0306W2JL9Y`VW2JL90@H900P12E89 -DPUB0@QB0181DP5B0E81DP5B0E81DP5B0E850@0?DP5B0E81DP5B0E81DP5B008125802049DPUB2E81 -1PT0306W2JL9Y`VW2JL90ABW00`1Y`VW2JL9Y`VW2@462@080@UB2E89DP48DP0@0E81DP5B0E81DP5B -0E81DP<11@010@40000E00810`020@0BDP5B0E81DP5B0E81DP5B0E8125801`5B2E89DP401`T03049 -Y`VW2JL9Y`VW0AFW00/1Y`VW2JL9Y`VW0@072@080@UB2E89DP48DP0B0E81DP5B0E81DP5B0E81DP5B -0`404U81DP5B0E81DP5B0E81DP5B0@MB00P12E89DPUB0@L900`12JL9Y`VW2JL9Y`4EY`0;0JL9Y`VW -2JL9Y`401`T01`49DPUB2@402E80405B0E81DP5B0E81DP5B0E820@@00P4100005@000`400002000C -0E81DP5B0E81DP5B0E81DP5B0@08DP080E89DPUB2@462@0<0@VW2JL9Y`VW2JL15jL02`6W2JL9Y`VW -2JL100H900P1DPUB2E890@QB0P409581DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0@QB -00P1DPUB2E890@H900`12JL9Y`VW2JL9Y`4FY`0<0@VW2JL9Y`VW2JL11PT0205B2E89DPT125820@0? -DP5B0E81DP5B0E81DP5B008110010@40000E00030@000080019B0E81DP5B0E81DP5B0E81DP49DP07 -0@UB2E890@072@0<0JL9Y`VW2JL9Y`T16:L02P6W2JL9Y`VW2@472@080E89DPUB2@48DP81029B0E81 -DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E812580205B2E89DPT11`T02`6W2JL9Y`VW2JL101RW -00/12JL9Y`VW2JL90@072@070E89DPUB0@09DP8100mB0E81DP5B0E81DP5B0E801@010@40000E0003 -0@0000800141DP5B0E81DP5B0E81DP5B0@09DP080@UB2E89DP462@0<0JL9Y`VW2JL9Y`T16JL02`49 -Y`VW2JL9Y`T100H900P12E89DPUB0@UB0P408581DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81 -2E802049DPUB2E811PT02`6W2JL9Y`VW2JL101ZW00/12JL9Y`VW2JL90@062@080@UB2E89DP49DP81 -00iB0E81DP5B0E81DP5B0@D00@4100005@000`400002000@DP5B0E81DP5B0E81DP5B0@YB00P1DPUB -2E890@H900/12JL9Y`VW2JL90@0KY`0:0@VW2JL9Y`VW0@H900P1DPUB2E890@UB0201DP5B0E81DP5B -0E81DP5B0E81DP5B0E81DP5B0E81DP812E80205B2E89DPT11PT02`49Y`VW2JL9Y`T101^W00X12JL9 -Y`VW2JL11PT0205B2E89DPT12U820@0=DP5B0E81DP5B0E81DP0500410@0001D000<100000P003`5B -0E81DP5B0E81DP5B0@0:DP080E89DPUB2@462@0;0@VW2JL9Y`VW2@407JL02P49Y`VW2JL9Y`462@08 -0E89DPUB2@49DP0N0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0P49DP080E89DPUB2@462@0; -0@VW2JL9Y`VW2@407:L02`6W2JL9Y`VW2JL100H900P1DPUB2E890@YB0P403581DP5B0E81DP5B0@D0 -0@4100005@000`400002000>DP5B0E81DP5B0E81DP4;DP080@UB2E89DP462@0:0JL9Y`VW2JL90AnW -00T12JL9Y`VW2@401PT02049DPUB2E812U830@0IDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@YB -00P12E89DPUB0@H900X1Y`VW2JL9Y`T17ZL02P6W2JL9Y`VW2@462@080@UB2E89DP4;DP8100]B0E81 -DP5B0E81DP0500410@0001D000<100000P002P5B0E81DP5B0E830@]B00P12E89DPUB0@H900X1Y`VW -2JL9Y`T18JL02@49Y`VW2JL90@062@080@UB2E89DP4;DP8101EB0E81DP5B0E81DP5B0E81DP5B0E80 -0`4;DP080@UB2E89DP462@0:0JL9Y`VW2JL90B2W00X1Y`VW2JL9Y`T11PT02049DPUB2E812e820@0: -DP5B0E81DP5B0@D00@4100005@000`4000020009DP5B0E81DP5B008135802049DPUB2E811`T02@49 -Y`VW2JL90@0SY`090@VW2JL9Y`T100H900P12E89DPUB0@aB0`404E81DP5B0E81DP5B0E81DP5B0081 -35802049DPUB2E811`T02@49Y`VW2JL90@0RY`0:0JL9Y`VW2JL90@H900P12E89DPUB0@aB0`401e81 -DP5B0E801@010@40000E00030@00008000H1DP5B0E830@eB00P12E89DPUB0@L900T12JL9Y`VW2@40 -9JL02049Y`VW2JL11`T02049DPUB2E813E820@0=DP5B0E81DP5B0E81DP030@eB00P12E89DPUB0@L9 -00T12JL9Y`VW2@409:L02@6W2JL9Y`VW0@072@080@UB2E89DP4=DP8100IB0E81DP4500410@0001D0 -00<100000P001E81DP5B00813U802049DPUB2E811`T02@49Y`VW2JL90@0WY`080@VW2JL9Y`472@08 -0@UB2E89DP4>DP<100UB0E81DP5B0E800P4>DP080@UB2E89DP472@090@VW2JL9Y`T102JW00T1Y`VW -2JL9Y`401`T02049DPUB2E813U830@03DP5B00D00@4100005@000`40000200030E8100813e802049 -DPUB2E811`T02@49Y`VW2JL90@0;Ya<12jL02049Y`VW2JL11`T02049DPUB2E813e820@05DP5B0E80 -0`4?DP080@UB2E89DP472@090@VW2JL9Y`T100ZW504:Y`090JL9Y`VW2JL100L900P12E89DPUB0@mB -0P400e81000400410@0001D000<100000P000e810@0@DP080@UB2E89DP472@090@VW2JL9Y`T100ZW -0P404jL8Y`RW2:L8Y`RW2:L8Y`RW2:L00P4:Y`080@VW2JL9Y`472@080@UB2E89DP4@DP<100=B0@40 -45802049DPUB2E811`T02@49Y`VW2JL90@09Y`8101@8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`812JL02@6W -2JL9Y`VW0@072@080@UB2E89DP4@DP811@010@40000E00810`000`5BDP0>DP8100L9DPUB2E8100L9 -00T12JL9Y`VW2@402ZL06@48Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20402JL02@6W2JL9Y`VW0@072@07 -0@UB2E89DP020A1B0P4@DP8100L9DPUB2E8100L900T12JL9Y`VW2@402JL06P6W2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`P12JL02@6W2JL9Y`VW0@072@070@UB2E89DP020A1B00@100000P4100005@000`40 -000200mB0P402589DPUB2E811`T02@49Y`VW2JL90@09Y`8101X8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L80@VW00T1Y`VW2JL9Y`401`T02049DPUB2E890`4MDP8100QB2E89DPUB0@L900T12JL9Y`VW2@40 -2JL0706W2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2049Y`090JL9Y`VW2JL100L900P12E89DPUB2@81 -3U8500410@0001D000<100000P02@@1 -00=B2E800`4>2@0:0JL9Y`VW2JL90@JW00P12:L8Y`RW0@X801H100P0200800P0200800P0200800P1 -2@P02@6W2:L8Y`RW0@06Y`080JL9Y`VW2JL20@l90P400`T0000200810@0001D000<100000P020@l9 -0P402JL9Y`VW2JL90@06Y`090@RW2:L8Y`P100X801L1200800P0200800P0200800P020080@0:2008 -0@RW2:L8Y`46Y`090JL9Y`VW2JL9008140T30@l90P402JL9Y`VW2JL90@06Y`080@RW2:L8Y`4:200H -0@0800P0200800P0200800P0200800P12@P02@6W2:L8Y`RW0@06Y`0:0JL9Y`VW2JL90A090P440041 -0@0001D000<100000P0?2@8100X9Y`VW2JL9Y`T11ZL01`48Y`RW2:L00P4:200I0@P0200800P02008 -00P0200800P020080@0:20080@RW2:L8Y`46Y`0:0JL9Y`VW2JL9Y`817PT20@0:2JL9Y`VW2JL90@JW -00P12:L8Y`RW0@X801X100P0200800P0200800P0200800P020080@T80P401`RW2:L8Y`401ZL02@6W -2JL9Y`VW2@020@l91@010@40000E00030@0000803@T20@0;Y`VW2JL9Y`VW2@401ZL02048Y`RW2:L1 -2`P06`4800P0200800P0200800P0200800P020080@0:20080@RW2:L8Y`46Y`0;0JL9Y`VW2JL9Y`T0 -0P4J2@8100^W2JL9Y`VW2JL90@06Y`080@RW2:L8Y`4:200L0@0800P0200800P0200800P0200800P0 -20080@X800P12:L8Y`RW0@JW00X1Y`VW2JL9Y`VW0P4=2@D00@4100005@000`40000200/90P4030VW -2JL9Y`VW2JL90@NW00L1Y`RW2:L100/801d1200800P0200800P0200800P0200800P020080@0:2007 -0@RW2:L80@07Y`0<0JL9Y`VW2JL9Y`VW0P4F2@8100`9Y`VW2JL9Y`VW2@47Y`070JL8Y`RW0@0:200N -0@0800P0200800P0200800P0200800P0200800P12PP01`48Y`RW20401jL02`6W2JL9Y`VW2JL90081 -2`T500410@0001D000<100000P092@8100fW2JL9Y`VW2JL9Y`T100NW00L1Y`RW2:L100/801l12008 -00P0200800P0200800P0200800P0200800P100X800L12:L8Y`P100NW00d1Y`VW2JL9Y`VW2JL90081 -4PT20@0=Y`VW2JL9Y`VW2JL90@07Y`070JL8Y`RW0@0:200P0@0800P0200800P0200800P0200800P0 -200800P0204:20070@RW2:L80@07Y`0<0JL9Y`VW2JL9Y`VW0P492@D00@4100005@000`40000200L9 -0P403PVW2JL9Y`VW2JL9Y`T11jL01`6W2:L8Y`402`P08@4800P0200800P0200800P0200800P02008 -00P020080@0:20070@RW2:L80@07Y`0>0JL9Y`VW2JL9Y`VW2JL20@h90P403PVW2JL9Y`VW2JL9Y`T1 -1jL01`6W2:L8Y`402PP08P40200800P0200800P0200800P0200800P0200800P0204:20070@RW2:L8 -0@07Y`0=0JL9Y`VW2JL9Y`VW2@020@L91@010@40000E00030@0000801@T20@0?Y`VW2JL9Y`VW2JL9 -Y`T100RW00L12:L8Y`P100T80P408PP0200800P0200800P0200800P0200800P0200800P0204:2007 -0@RW2:L80@07Y`0?0JL9Y`VW2JL9Y`VW2JL900812PT20@0?Y`VW2JL9Y`VW2JL9Y`T100RW00L12:L8 -Y`P100T802@100P0200800P0200800P0200800P0200800P0200800P0204:20070@RW2:L80@07Y`0> -0JL9Y`VW2JL9Y`VW2JL20@D91@010@40000E00030@0000800`T20@0@2JL9Y`VW2JL9Y`VW2JL90@RW -00L12:L8Y`P100T800X100P0200800P04`402@0800P020080@0920070JL8Y`RW0@08Y`0@0JL9Y`VW -2JL9Y`VW2JL9Y`811PT20@0@2JL9Y`VW2JL9Y`VW2JL90@RW00L12:L8Y`P100T800T100P0200800P0 -50402@0800P020080@0920070JL8Y`RW0@08Y`0?0JL9Y`VW2JL9Y`VW2JL900810`T500410@0001D0 -00<100000P0050T10JL9Y`VW2JL9Y`VW2JL9Y`T12:L02048Y`RW2:L120P02`40200800P0200101<0 -00X100P0200800P12@P01`6W2:L8Y`402:L04@6W2JL9Y`VW2JL9Y`VW2JL900810PT20@0AY`VW2JL9 -Y`VW2JL9Y`VW2@402:L02048Y`RW2:L120P02P40200800P0204D000:0@0800P020080@T800L1Y`RW -2:L100RW0101Y`VW2JL9Y`VW2JL9Y`VW0P400`T0000300410@0001D000<100000P004`49Y`VW2JL9 -Y`VW2JL9Y`VW2@402:L02048Y`RW2:L120P02`40200800P0200101D000X100P0200800P120P02048 -Y`RW2:L12:L04P6W2JL9Y`VW2JL9Y`VW2JL9Y`810189Y`VW2JL9Y`VW2JL9Y`VW2@48Y`080@RW2:L8 -Y`48200:0@0800P020080AH000X100P0200800P120P02048Y`RW2:L12:L04@6W2JL9Y`VW2JL9Y`VW -2JL9008110010@40000E00030@0000800109Y`VW2JL9Y`VW2JL9Y`VW0P49Y`080JL8Y`RW2047200; -0@0800P0200800405`002P40200800P0204820070@RW2:L80@09Y`0T0JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`T12JL0206W2:L8Y`P11`P02P40200800P0204H000:0@0800P020080@P8 -00L12:L8Y`P100VW0141Y`VW2JL9Y`VW2JL9Y`VW2@0500410@0001D000<100000P004:L9Y`VW2JL9 -Y`VW2JL9Y`4:Y`080JL8Y`RW204720090@0800P0200800816@020@08200800P0204720080JL8Y`RW -2049Y`0R0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@VW00P1Y`RW2:L80@L800X100P0 -200800P16P002P40200800P0204720080JL8Y`RW2049Y`8100h9Y`VW2JL9Y`VW2JL9Y`D00@410000 -5@020@<000l9Y`VW2JL9Y`VW2JL9Y`402ZL02@6W2:L8Y`RW0@06200:0@0800P020080Ad000T12008 -00P020401`P0206W2:L8Y`P12JL20@0N2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T12JL02@6W -2:L8Y`RW0@06200:0@0800P020080A`000X100P0200800P11`P0206W2:L8Y`P12ZL03P49Y`VW2JL9 -Y`VW2JL910020@40000E00030@00008000bW2JL9Y`VW2JL9Y`T20@ZW00T1Y`RW2:L8Y`401PP02P40 -200800P0204O00090@P0200800P100H800T12:L8Y`RW20402ZL07@49Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`T100VW00T1Y`RW2:L8Y`401PP02P40200800P0204N000:0@0800P020080@H800T12:L8 -Y`RW20402ZL03@49Y`VW2JL9Y`VW2JL01@010@40000E00030@00008000`9Y`VW2JL9Y`VW2@42JL9Y`VW2JL9Y`VW2@4;Y`090JL8Y`RW2:L100H800X100P0 -200800P17@002@4800P020080@0720080JL8Y`RW204:Y`0O0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL90@09Y`090JL8Y`RW2:L100H800X100P0200800P170002P40200800P0204720080JL8Y`RW -204:Y`8100bW2JL9Y`VW2JL9Y`T500410@0001D00P43000>Y`VW2JL9Y`VW2JL9Y`T20@ZW00P1Y`RW -2:L80@L800X100P0200800P16`002@4800P020080@0720080JL8Y`RW204:Y`0P0@VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4:Y`080JL8Y`RW2047200:0@0800P020080AX000X100P0200800P1 -1`P0206W2:L8Y`P12ZL03`49Y`VW2JL9Y`VW2JL9Y`0400810@0001D000<100000P004@VW2JL9Y`VW -2JL9Y`VW2JL100VW00T12:L8Y`RW20401`P02P40200800P0204I00090@P0200800P100P800P12:L8 -Y`RW0@VW02812JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL12JL02@48Y`RW2:L80@072009 -0@0800P0200101X000T1200800P0204020P02048Y`RW2:L12JL04049Y`VW2JL9Y`VW2JL9Y`T50041 -0@0001D000<100000P004ZL9Y`VW2JL9Y`VW2JL9Y`VW0@VW00P12:L8Y`RW0@P800X100P0200800P1 -5`002@4800P020080@0820080@RW2:L8Y`49Y`0T0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL12JL02048Y`RW2:L120P02@40200800P00@0H00090@P0200800P100P800P12:L8Y`RW0@VW -01412JL9Y`VW2JL9Y`VW2JL9Y`0500410@0001D000<100000P004`6W2JL9Y`VW2JL9Y`VW2JL9Y`40 -2JL02048Y`RW2:L120P02P40200800P0204E00090@P0200800P100T800L1Y`RW2:L100VW01812JL9 -Y`VW2JL9Y`VW2JL9Y`T20@0BY`VW2JL9Y`VW2JL9Y`VW2JL12JL02048Y`RW2:L120P02@40200800P0 -0@0F00090@P0200800P100T800L1Y`RW2:L100VW01412JL9Y`VW2JL9Y`VW2JL9Y`020@@00@410000 -5@000`400002000D2@412JL9Y`VW2JL9Y`VW2JL9Y`48Y`080JL8Y`RW2049200:0@0800P020080A<0 -00T1200800P020402@P0206W2:L8Y`P12:L04@49Y`VW2JL9Y`VW2JL9Y`VW00810PT20@0A2JL9Y`VW -2JL9Y`VW2JL9Y`402:L0206W2:L8Y`P12@P02@40200800P00@0D00090@P0200800P100T800P1Y`RW -2:L80@RW01012JL9Y`VW2JL9Y`VW2JL90P400`T0000300410@0001D000<100000P032@81012W2JL9 -Y`VW2JL9Y`VW2JL12:L0206W2:L8Y`P12@P02@40200800P0200C0@09200800P0200100T800L12:L8 -Y`P100RW01012JL9Y`VW2JL9Y`VW2JL90P462@81012W2JL9Y`VW2JL9Y`VW2JL12:L0206W2:L8Y`P1 -2@P02040200800P050402@P0200800P00@0920070@RW2:L80@08Y`0?0@VW2JL9Y`VW2JL9Y`VW0081 -0`T500410@0001D000<100000P052@8100l9Y`VW2JL9Y`VW2JL9Y`402:L01`6W2:L8Y`402PP08`40 -200800P0200800P0200800P0200800P0200800P0200100T800L12:L8Y`P100RW00l12JL9Y`VW2JL9 -Y`VW2JL00P4:2@8100l9Y`VW2JL9Y`VW2JL9Y`402:L01`6W2:L8Y`402@P0904800P0200800P02008 -00P0200800P0200800P0200800P00@T800L12:L8Y`P100RW00h12JL9Y`VW2JL9Y`VW2@811@T50041 -0@0001D000<100000P072@8100jW2JL9Y`VW2JL9Y`VW0@RW00L1Y`RW2:L100X8024100P0200800P0 -200800P0200800P0200800P0200800402@P01`48Y`RW20402:L03P49Y`VW2JL9Y`VW2JL90P4>2@81 -00jW2JL9Y`VW2JL9Y`VW0@RW00L1Y`RW2:L100T80281200800P0200800P0200800P0200800P02008 -00P020012@P01`48Y`RW20402:L03@49Y`VW2JL9Y`VW2JL00P472@D00@4100005@000`40000200T9 -0P403@VW2JL9Y`VW2JL9Y`401jL02048Y`RW2:L12PP07`40200800P0200800P0200800P0200800P0 -200800402@P02048Y`RW2:L11jL03@49Y`VW2JL9Y`VW2JL00P4B2@8100d9Y`VW2JL9Y`VW2JL100NW -00P12:L8Y`RW0@T80201200800P0200800P0200800P0200800P0200800P00@T800P12:L8Y`RW0@NW -00`12JL9Y`VW2JL9Y`T20@T91@010@40000E00030@0000802`T20@0DP030@0000800@4100005@020@<000=B0@403U820@07 -DPUB2E890@072@090JL9Y`VW2JL100ZW01T1Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L100VW00T12JL9 -Y`VW2@401`T01`5B2E89DPT00P4?DP8100=B0@403U820@07DPUB2E890@072@090JL9Y`VW2JL100VW -01X12:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@VW00T12JL9Y`VW2@401`T01`5B2E89DPT00P4>DP81 -10020@40000E00030@00008000<1DP400P4>DP080E89DPUB2@472@090JL9Y`VW2JL100ZW0P404`RW -2:L8Y`RW2:L8Y`RW2:L8Y`P00P4:Y`080JL9Y`VW2@472@080E89DPUB2@4?DP<100=B0E800`4>DP08 -0E89DPUB2@472@090JL9Y`VW2JL100VW0P405:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80P49Y`090@VW2JL9 -Y`T100L900P1DPUB2E890@iB0P400e81000400410@0001D000<100000P001U81DP5B0@iB00P1DPUB -2E890@L900T1Y`VW2JL9Y`402jLC0@^W00P1Y`VW2JL90@L900P1DPUB2E890@iB0P402E81DP5B0E81 -DP020@eB00P1DPUB2E890@L900T1Y`VW2JL9Y`402ZLD0@ZW00T12JL9Y`VW2@401`T0205B2E89DPT1 -3U820@03DP5B00D00@4100005@000`40000200060E81DP5B0P4=DP080E89DPUB2@472@090JL9Y`VW -2JL102NW00P1Y`VW2JL90@L900P1DPUB2E890@eB0`402e81DP5B0E81DP5B00813E80205B2E89DPT1 -1`T02@6W2JL9Y`VW0@0VY`090@VW2JL9Y`T100L900P1DPUB2E890@eB0`401581DP4500410@0001D0 -00<100000P001e81DP5B0E800P4=DP080E89DPUB2@472@090JL9Y`VW2JL102FW00P1Y`VW2JL90@L9 -00P1DPUB2E890@aB0P403e81DP5B0E81DP5B0E81DP030@aB00P1DPUB2E890@L900T1Y`VW2JL9Y`40 -9:L02@49Y`VW2JL90@072@080E89DPUB2@4=DP080E81DP5B0E8500410@0001D000<100000P00205B -0E81DP5B0`4W00T1Y`VW2JL9Y`401PT0205B2E89DPT1 -2e830@0CDP5B0E81DP5B0E81DP5B0E81DP020@]B00P1DPUB2E890@L900T1Y`VW2JL9Y`408ZL02P49 -Y`VW2JL9Y`462@080E89DPUB2@40E81DP5B0E81DP5B0E830@UB00P12E89DPUB0@H9 -00/1Y`VW2JL9Y`VW0@0KY`0:0JL9Y`VW2JL90@H900P12E89DPUB0@UB0P408581DP5B0E81DP5B0E81 -DP5B0E81DP5B0E81DP5B0E812E802049DPUB2E811PT02`6W2JL9Y`VW2JL101ZW00/12JL9Y`VW2JL9 -0@062@080@UB2E89DP49DP8100iB0E81DP5B0E81DP5B0@D00@4100005@000`4000020081011B0E81 -DP5B0E81DP5B0E8125802@5B2E89DPUB0@062@0:0JL9Y`VW2JL9Y`815jL20@0:Y`VW2JL9Y`VW0@H9 -00P1DPUB2E890@QB0P403e81DP5B0E81DP5B0E81DP030@0@DP5B0E81DP5B0E81DP5B0@QB00T1DPUB -2E89DP401PT02`6W2JL9Y`VW2JL101RW00`12JL9Y`VW2JL9Y`462@080E89DPUB2@48DP81011B0E81 -DP5B0E81DP5B0E8110010@40000E00030@0000800`404581DP5B0E81DP5B0E81DP48DP080E89DPUB -2@462@0=0@VW2JL9Y`VW2JL90@0EY`0<0@VW2JL9Y`VW2JL11PT0205B2E89DPT125820@0?DP5B0E81 -DP5B0E81DP5B00D1011B0E81DP5B0E81DP5B0E812580205B2E89DPT11PT03049Y`VW2JL9Y`VW0AJW -00`12JL9Y`VW2JL9Y`462@080E89DPUB2@48DP81011B0E81DP5B0E81DP5B0E811@010@40000E0081 -0`040@0@DP5B0E81DP5B0E81DP5B0@MB00T12E89DPUB2@401PT03@49Y`VW2JL9Y`VW2@404jL03@49 -Y`VW2JL9Y`VW2@401PT02049DPUB2E812580405B0E81DP5B0E81DP5B0E870@0@DP5B0E81DP5B0E81 -DP5B0@MB00T12E89DPUB2@401PT03049Y`VW2JL9Y`VW0ABW00d12JL9Y`VW2JL9Y`T100H900P12E89 -DPUB0@QB0101DP5B0E81DP5B0E81DP5B0P4400810@0001D000<100000P050@0=DP5B0E81DP5B0E81 -DP020@QB00P12E89DPUB0@H900d1Y`VW2JL9Y`VW2JL901<100`9Y`VW2JL9Y`VW2@462@090@UB2E89 -DPT100MB0101DP5B0E81DP5B0E81DP5B2@403E81DP5B0E81DP5B0E800P47DP090E89DPUB2E8100H9 -00`1Y`VW2JL9Y`VW2JLD0@0<2JL9Y`VW2JL9Y`T11PT02049DPUB2E812580405B0E81DP5B0E81DP5B -0E830@D00@4100005@000`40000200H100eB0E81DP5B0E81DP5B00811e802@5B2E89DPUB0@062@0[ -0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@062@080E89DPUB2@48DP81 -00eB0E81DP5B0E81DP5B00/100eB0E81DP5B0E81DP5B00811e802@5B2E89DPUB0@062@0[0JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@062@080E89DPUB2@48DP8100eB0E81 -DP5B0E81DP5B00@11@010@40000E00030@0000801`403U81DP5B0E81DP5B0E812580205B2E89DPT1 -1PT0:P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@H900T1DPUB2E89DP40 -1e820@0=DP5B0E81DP5B0E81DP0=0@0>DP5B0E81DP5B0E81DP47DP090@UB2E89DPT100H902X12JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`462@080E89DPUB2@48DP8100eB0E81 -DP5B0E81DP5B00D11@010@40000E00030@00008020403U81DP5B0E81DP5B0E811e802049DPUB2E81 -1`T0:@49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T100H900T12E89DPUB2@40 -1e803P5B0E81DP5B0E81DP5B3`403U81DP5B0E81DP5B0E811e802049DPUB2E811`T0:@49Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T100H900P12E89DPUB0@QB00h1DP5B0E81DP5B -0E81DPH11@010@40000E00030@0000802@402e81DP5B0E81DP5B00811e802@5B2E89DPUB0@062@0X -0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@H900T12E89DPUB2@401e803P5B -0E81DP5B0E81DP5B4@402e81DP5B0E81DP5B00811e802@5B2E89DPUB0@062@0X0JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@H900T12E89DPUB2@401e803P5B0E81DP5B0E81DP5B -1`4500410@0001D000<100000P080@0=DP5B0E81DP5B0E81DP020@MB00P1DPUB2E890@L902L1Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`401PT02@5B2E89DPUB0@07DP8100]B0E81 -DP5B0E81DP0C0@0;DP5B0E81DP5B0E800P46DP090@UB2E89DPT100L902L1Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`401PT0205B2E89DPT125820@0;DP5B0E81DP5B0E8020450041 -0@0001D000<100000P090@0=DP5B0E81DP5B0E81DP020@IB00P12E89DPUB0@L902H12JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@L900P12E89DPUB0@MB0P402e81DP5B0E81DP5B01D1 -00aB0E81DP5B0E81DP47DP080@UB2E89DP472@0V0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`472@080@UB2E89DP47DP8100]B0E81DP5B0E81DP090@D00@4100005@000`40000200X1 -00iB0E81DP5B0E81DP5B0@MB00P12E89DPUB0@L902D12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`T100L900P1DPUB2E890@MB00`1DP5B0E81DP5B0E8G0@0DP5B0E81DP5B0E81DP46DP08 -0E89DPUB2@472@0T0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T11`T02@5B2E89DPUB -0@06DP0<0E81DP5B0E81DP5B6@402E81DP5B0E81DP020@IB00T12E89DPUB2@401`T0906W2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@L900P1DPUB2E890@MB00`1DP5B0E81DP5B0E8;0@D0 -0@4100005@000`40000200`100]B0E81DP5B0E81DP020@MB00L1DPUB2E8100P902<1Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@072@080@UB2E89DP47DP8100UB0E81DP5B0E806`402E81 -DP5B0E81DP020@IB00P12E89DPUB0@P902<1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -0@072@070@UB2E890@08DP8100UB0E81DP5B0E80304500410@0001D000<100000P0=0@0;DP5B0E81 -DP5B0E800P46DP070@UB2E890@082@0R0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@P9 -00P1DPUB2E890@IB0P402E81DP5B0E81DP0M0@0:DP5B0E81DP5B0@IB00P1DPUB2E890@P902812JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL120T01`5B2E89DP401e820@09DP5B0E81DP5B00d1 -1@010@40000=00@110000`40000200h100aB0E81DP5B0E81DP47DP070@UB2E890@082@0Q0@VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T100L900P1DPUB2E890@MB00X1DP5B0E81DP5B7`402U81 -DP5B0E81DP46DP080E89DPUB2@482@0Q0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T100L9 -00L1DPUB2E8100QB00X1DP5B0E81DP5B3P4500410@0000l000<100000`020@<03`403581DP5B0E81 -DP5B0@IB00L1DPUB2E8100P90201Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@P900P12E89 -DPUB0@IB00X1DP5B0E81DP5B8@401e81DP5B0E800P46DP080@UB2E89DP482@0P0JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2@482@070@UB2E890@07DP0:0E81DP5B0E81DPl110020@40000?0003 -0@0000<000<100000P0>0@00@D00@4100003`000`40000300030@0000803@402e81DP5B0E81 -DP5B00811U801`49DPUB2@4020T08P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`482@08 -0E89DPUB2@46DP8100UB0E81DP5B0E807@402U81DP5B0E81DP46DP080E89DPUB2@482@0R0@VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@P900L1DPUB2E8100MB0P402E81DP5B0E81DP0=0@D0 -0@4100003`000`40000300030@00008030402e81DP5B0E81DP5B00811e801`5B2E89DP4020T08`6W -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL100L900P12E89DPUB0@IB00`1DP5B0E81DP5B -0E8K0@09DP5B0E81DP5B00811U802049DPUB2E8120T08`6W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL100L900L12E89DPT100MB00`1DP5B0E81DP5B0E8<0@D00@4100003@030@D000<10000 -0P0;0@0>DP5B0E81DP5B0E81DP46DP080E89DPUB2@472@0T0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`T11`T02@5B2E89DPUB0@06DP0<0E81DP5B0E81DP5B6@402E81DP5B0E81DP020@IB -00T12E89DPUB2@401`T0906W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@L900P1DPUB -2E890@MB00`1DP5B0E81DP5B0E8;0@D00@4100003`000`40000300030@0000802P403U81DP5B0E81 -DP5B0E811e802049DPUB2E811`T09@49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@40 -1`T0205B2E89DPT11U820@0;DP5B0E81DP5B0E805`403581DP5B0E81DP5B0@IB00T1DPUB2E89DP40 -1`T09@49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@401`T01`5B2E89DP401e820@0; -DP5B0E81DP5B0E802P4500410@0001D000<100000P090@0=DP5B0E81DP5B0E81DP020@IB00P12E89 -DPUB0@L902H12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@L900P12E89DPUB0@MB -0P402e81DP5B0E81DP5B01D100aB0E81DP5B0E81DP47DP080@UB2E89DP472@0V0@VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`472@080@UB2E89DP47DP8100]B0E81DP5B0E81DP090@D0 -0@4100005@000`40000200P100eB0E81DP5B0E81DP5B00811e80205B2E89DPT11`T09`6W2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@062@090E89DPUB2E8100IB00h1DP5B0E81DP5B -0E81DQ<100]B0E81DP5B0E81DP020@IB00T12E89DPUB2@401`T09`6W2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW0@062@080E89DPUB2@47DP0>0E81DP5B0E81DP5B0E880@D00@410000 -5@000`40000200T100iB0E81DP5B0E81DP5B0@IB00T1DPUB2E89DP401PT0:06W2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@462@090@UB2E89DPT100MB00h1DP5B0E81DP5B0E81DQ41 -00]B0E81DP5B0E81DP020@MB00T1DPUB2E89DP401PT0:06W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2@462@090@UB2E89DPT100MB00h1DP5B0E81DP5B0E81DPL11@010@40000E0003 -0@00008020403U81DP5B0E81DP5B0E811e802049DPUB2E811`T0:@49Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T100H900T12E89DPUB2@401U820@0=DP5B0E81DP5B0E81DP0?0@0> -DP5B0E81DP5B0E81DP47DP080@UB2E89DP472@0Y0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2@401PT02049DPUB2E811e820@0=DP5B0E81DP5B0E81DP060@D00@4100005@000`40 -000200L100eB0E81DP5B0E81DP5B00811e80205B2E89DPT11PT0:P49Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@H900T1DPUB2E89DP401e820@0=DP5B0E81DP5B0E81DP0=0@0> -DP5B0E81DP5B0E81DP47DP090@UB2E89DPT100H902X12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`462@080E89DPUB2@48DP8100eB0E81DP5B0E81DP5B00D11@010@40000E0003 -0@0000801P403E81DP5B0E81DP5B0E800P47DP090E89DPUB2E8100H902/1Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL100H900P1DPUB2E890@MB0101DP5B0E81DP5B0E81DP5B -2`403E81DP5B0E81DP5B0E800P47DP090E89DPUB2E8100H902/1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL100H900P1DPUB2E890@MB0101DP5B0E81DP5B0E81DP5B10450041 -0@0001D000<100000P050@0@DP5B0E81DP5B0E81DP5B0@MB00P12E89DPUB0@H900d1Y`VW2JL9Y`VW -2JL901<100`9Y`VW2JL9Y`VW2@462@090@UB2E89DPT100MB0101DP5B0E81DP5B0E81DP5B2@403E81 -DP5B0E81DP5B0E800P47DP090E89DPUB2E8100H900`1Y`VW2JL9Y`VW2JLD0@0<2JL9Y`VW2JL9Y`T1 -1PT02049DPUB2E812580405B0E81DP5B0E81DP5B0E830@D00@4100005@020@<010404581DP5B0E81 -DP5B0E81DP47DP090@UB2E89DPT100H900d12JL9Y`VW2JL9Y`T101>W00d12JL9Y`VW2JL9Y`T100H9 -00P12E89DPUB0@MB0P403e81DP5B0E81DP5B0E81DP070@0@DP5B0E81DP5B0E81DP5B0@MB00T12E89 -DPUB2@401PT03049Y`VW2JL9Y`VW0ABW00d12JL9Y`VW2JL9Y`T100H900P12E89DPUB0@MB0P403e81 -DP5B0E81DP5B0E81DP020@@00P4100005@000`40000200<100mB0E81DP5B0E81DP5B0E800P47DP08 -0E89DPUB2@462@0=0@VW2JL9Y`VW2JL90@0EY`0<0@VW2JL9Y`VW2JL11PT0205B2E89DPT125820@0? -DP5B0E81DP5B0E81DP5B00D1011B0E81DP5B0E81DP5B0E812580205B2E89DPT11PT03049Y`VW2JL9 -Y`VW0AJW00`12JL9Y`VW2JL9Y`462@080E89DPUB2@48DP81011B0E81DP5B0E81DP5B0E811@010@40 -000E00030@0000800P403e81DP5B0E81DP5B0E81DP020@MB00T1DPUB2E89DP401PT02P6W2JL9Y`VW -2JL20ANW0P402ZL9Y`VW2JL9Y`462@080E89DPUB2@47DP0B0E81DP5B0E81DP5B0E81DP5B0`403e81 -DP5B0E81DP5B0E81DP020@MB00T1DPUB2E89DP401PT02`6W2JL9Y`VW2JL101RW00`12JL9Y`VW2JL9 -Y`462@080E89DPUB2@47DP0C0E81DP5B0E81DP5B0E81DP5B0@0400410@0001D000<100000P00405B -0E81DP5B0E81DP5B0E820@QB00P12E89DPUB0@H900/1Y`VW2JL9Y`VW0@0KY`0:0JL9Y`VW2JL90@H9 -00P12E89DPUB0@QB0281DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0P48DP080@UB2E89 -DP462@0;0JL9Y`VW2JL9Y`406ZL02`49Y`VW2JL9Y`T100H900P12E89DPUB0@QB0`403U81DP5B0E81 -DP5B0E811@010@40000E00030@00008000eB0E81DP5B0E81DP5B00<12E802@49DPUB2E890@062@0: -0@VW2JL9Y`VW0AfW00X1Y`VW2JL9Y`T11PT02049DPUB2E8125830@0NDP5B0E81DP5B0E81DP5B0E81 -DP5B0E81DP5B0E812E802@49DPUB2E890@062@0:0@VW2JL9Y`VW0AbW00/12JL9Y`VW2JL90@062@08 -0@UB2E89DP49DP8100eB0E81DP5B0E81DP5B00D00@4100005@000`400002000<0E81DP5B0E81DP5B -0P4;DP080E89DPUB2@462@0:0@VW2JL9Y`VW0AnW00T1Y`VW2JL9Y`401PT0205B2E89DPT12U820@0L -DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0@YB00P1DPUB2E890@H900X12JL9Y`VW2JL17ZL02P49 -Y`VW2JL9Y`462@080E89DPUB2@4;DP0=0E81DP5B0E81DP5B0@0500410@0001D000<100000P002e81 -DP5B0E81DP5B00812e80205B2E89DPT11PT02P49Y`VW2JL9Y`4QY`090JL9Y`VW2JL100H900P1DPUB -2E890@YB0P405e81DP5B0E81DP5B0E81DP5B0E81DP5B00<12U80205B2E89DPT11PT02P49Y`VW2JL9 -Y`4PY`0:0@VW2JL9Y`VW0@H900P1DPUB2E890@]B0`402E81DP5B0E81DP0500410@0001D000<10000 -0P00205B0E81DP5B0`4W00T1Y`VW2JL9Y`401PT0205B -2E89DPT12e830@0CDP5B0E81DP5B0E81DP5B0E81DP020@]B00P1DPUB2E890@L900T1Y`VW2JL9Y`40 -8ZL02P49Y`VW2JL9Y`462@080E89DPUB2@4DP07 -0@UB2E890@072@090JL9Y`VW2JL102JW00T12JL9Y`VW2@401`T0205B2E89DPT13E830@0;DP5B0E81 -DP5B0E800P4>DP070@UB2E890@072@090JL9Y`VW2JL102JW00T12JL9Y`VW2@401`T0205B2E89DPT1 -3E830@04DP5B0@D00@4100005@000`4000020006DP5B0E813e801`49DPUB2@401`T02@6W2JL9Y`VW -0@0XY`090@VW2JL9Y`T100L900L1DPUB2E8100mB0P402E81DP5B0E81DP020@iB00L12E89DPT100L9 -00T1Y`VW2JL9Y`40::L02@49Y`VW2JL90@072@070E89DPUB0@0?DP8100=B0E801@010@40000E0003 -0@00008000<1DP400P4?DP070@UB2E890@072@090JL9Y`VW2JL100bW4`4;Y`090@VW2JL9Y`T100L9 -00L1DPUB2E81011B0`400e81DP030@mB00L12E89DPT100L900T1Y`VW2JL9Y`402jLD0@^W00T12JL9 -Y`VW2@401`T01`5B2E89DP403e820@03DP4000@00@4100005@000`4000020003DP41011B00L12E89 -DPT100L900X1Y`VW2JL9Y`T12ZL20@0CY`RW2:L8Y`RW2:L8Y`RW2:L8Y`020@ZW00T12JL9Y`VW2@40 -1`T01`5B2E89DP404E820@03DP41011B00L12E89DPT100L900X1Y`VW2JL9Y`T12JL20@0D2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L20@VW00X1Y`VW2JL9Y`T11`T01`5B2E89DP4045820@D00@4100005@020@<0 -00<1DU803U820@072E89DPUB0@062@0:0JL9Y`VW2JL90@ZW01T12:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`P100ZW00T12JL9Y`VW2@401PT01`49DPUB2E800P4ADP030E9B00iB0P401`UB2E89DP401PT02P6W -2JL9Y`VW2@49Y`0J0JL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2049Y`0:0JL9Y`VW2JL90@H900L12E89 -DPUB00814580104000020@40000E00030@0000803e820@08DPUB2E89DP462@0:0JL9Y`VW2JL90@VW -0P406PRW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P12ZL02@49Y`VW2JL90@062@080@UB2E89DPT30AeB -0P402589DPUB2E811PT02P6W2JL9Y`VW2@49Y`0L0JL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80@VW -00X1Y`VW2JL9Y`T11PT02049DPUB2E890P4>DPD00@4100005@000`40000200aB0`402@UB2E89DPUB -0@062@0:0JL9Y`VW2JL90@VW01d1Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20020@RW00X1Y`VW -2JL9Y`T11PT02P49DPUB2E89DPT20AQB0`402@UB2E89DPUB0@062@0:0JL9Y`VW2JL90@RW0P407:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P20@RW00X1Y`VW2JL9Y`T11PT02@49DPUB2E89DP030@]B -1@010@40000E00030@0000802E830@0;2E89DPUB2E89DP401PT02P6W2JL9Y`VW2@48Y`81022W2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@RW00X1Y`VW2JL9Y`T11PT02`49DPUB2E89DPUB00<1 -4U830@0;2E89DPUB2E89DP401PT02P6W2JL9Y`VW2@48Y`0R0@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW0@RW00X1Y`VW2JL9Y`T11PT02`49DPUB2E89DPUB00812E8500410@0001D000<10000 -0P07DP8100d9DPUB2E89DPUB2E8100L900T12JL9Y`VW2@402:L09048Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW0@RW00T1Y`VW2JL9Y`401`T03@49DPUB2E89DPUB2E800`4=DP8100d9DPUB -2E89DPUB2E8100L900T12JL9Y`VW2@401jL20@0S2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L8Y`402:L02@6W2JL9Y`VW0@072@0<0@UB2E89DPUB2E890`46DPD00@4100005@000`40000200AB -0`403U89DPUB2E89DPUB2E811`T02@49Y`VW2JL90@08Y`0:0@RW2:L8Y`RW21<100P8Y`RW2:L8Y`81 -1jL02@6W2JL9Y`VW0@072@0?0@UB2E89DPUB2E89DPUB008125830@0>DPUB2E89DPUB2E89DP472@09 -0@VW2JL9Y`T100NW00X1Y`RW2:L8Y`RW504020RW2:L8Y`RW0P47Y`090JL9Y`VW2JL100L900h12E89 -DPUB2E89DPUB2@<10e8500410@0001D000<100000P02DP81011B2E89DPUB2E89DPUB2E811`T02@49 -Y`VW2JL90@07Y`8100P8Y`RW2:L8Y`814`P20@09Y`RW2:L8Y`P100NW00T1Y`VW2JL9Y`401`T04049 -DPUB2E89DPUB2E89DPT30@=B0P404589DPUB2E89DPUB2E89DP472@090@VW2JL9Y`T100NW00T1Y`RW -2:L8Y`P00P4D208100VW2:L8Y`RW20401jL02@6W2JL9Y`VW0@072@0@0@UB2E89DPUB2E89DPUB2@81 -00=B00000`010@40000E00030@0000800P403`UB2E89DPUB2E89DPUB2@020@L900T12JL9Y`VW2@40 -1jL02@6W2:L8Y`RW20020AL80P401`RW2:L8Y`P00P46Y`090JL9Y`VW2JL100L901812E89DPUB2E89 -DPUB2E89DPT30@0?2E89DPUB2E89DPUB2E8900811`T02@49Y`VW2JL90@06Y`8100NW2:L8Y`RW0081 -60P02@6W2:L8Y`RW20020@JW00T1Y`VW2JL9Y`401`T20@0?DPUB2E89DPUB2E89DPUB008110010@40 -000E00030@00008000mB2E89DPUB2E89DPUB2E800P482@090@VW2JL9Y`T100JW0P402JL8Y`RW2:L8 -0@0K200:0@RW2:L8Y`RW0@JW00T1Y`VW2JL9Y`401`T20@0ODPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DP020@P900T12JL9Y`VW2@401ZL02P48Y`RW2:L8Y`4K208100T8Y`RW2:L8Y`401ZL02@6W -2JL9Y`VW0@082@<100eB2E89DPUB2E89DPUB00D00@4100005@000`400002000<2E89DPUB2E89DPUB -0`492@090@VW2JL9Y`T100JW00T12:L8Y`RW2:L00P4M208100RW2:L8Y`RW0@JW00T1Y`VW2JL9Y`40 -20T20@0K2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E8900812@T02@49Y`VW2JL90@06Y`080@RW2:L8 -Y`P20Ah800X12:L8Y`RW2:L11ZL02@6W2JL9Y`VW0@0:2@8100/9DPUB2E89DPUB2@0500410@0001D0 -00<100000P002U89DPUB2E89DPT20@/900T12JL9Y`VW2@401JL20@072:L8Y`RW20020B480P401PRW -2:L8Y`<11:L02@6W2JL9Y`VW0@092@8101MB2E89DPUB2E89DPUB2E89DPUB2E89DP020@X900T12JL9 -Y`VW2@401:L30@062:L8Y`RW0P4Q208100NW2:L8Y`RW00<11:L02@6W2JL9Y`VW0@0;2@<100P9DPUB -2E89DPD00@4100005@000`40000200072E89DPUB2@030@/90P4020VW2JL9Y`T11JL02P6W2:L8Y`RW -204U20090@RW2:L8Y`P100FW00T1Y`VW2JL9Y`402PT30@0BDPUB2E89DPUB2E89DPUB2E890P4:2@81 -00P9Y`VW2JL90@FW00T1Y`RW2:L8Y`409@P02P6W2:L8Y`RW2045Y`090JL9Y`VW2JL100d90`401@UB -2E8900D00@4100005@020@<000AB2E890`4<2@8100VW2JL9Y`VW2@401JL02P6W2:L8Y`RW204:21<1 -2PP02@48Y`RW2:L80@05Y`080JL9Y`VW2JL20@/910402PUB2E89DPUB2E840@X90P402JL9Y`VW2JL9 -0@05Y`090JL8Y`RW2:L100X85049200:0JL8Y`RW2:L80@FW00P1Y`VW2JL9Y`813PT20@03DPUB00@0 -0P4100005@000`40000200042E810@h900/12JL9Y`VW2JL90@06Y`090@RW2:L8Y`P100X801D12008 -00P0200800P0200800P020402PP02048Y`RW2:L11ZL02@6W2JL9Y`VW2@020@d910400e89DP030@d9 -00/12JL9Y`VW2JL90@06Y`080@RW2:L8Y`4:200F0@0800P0200800P0200800P020080@T800T1Y`RW -2:L8Y`401ZL02@6W2JL9Y`VW2@020@h90P400`T0000300410@0001D000<100000P020@h90P402PVW -2JL9Y`VW2@46Y`090@RW2:L8Y`P100X801L1200800P0200800P0200800P020080@0:20080@RW2:L8 -Y`46Y`0:0JL9Y`VW2JL9Y`813`T30@h90P402PVW2JL9Y`VW2@46Y`080@RW2:L8Y`4:200H0@0800P0 -200800P0200800P0200800P12@P02@6W2:L8Y`RW0@06Y`0:0JL9Y`VW2JL9Y`813PT20@@00@410000 -5@000`40000200h90P402jL9Y`VW2JL9Y`T100JW00L12:L8Y`RW00812PP06@4800P0200800P02008 -00P0200800P020402PP02048Y`RW2:L11ZL02`6W2JL9Y`VW2JL9008170T20@0;Y`VW2JL9Y`VW2@40 -1ZL02048Y`RW2:L12PP06P40200800P0200800P0200800P0200800P12@P20@072:L8Y`RW0@06Y`0; -0JL9Y`VW2JL9Y`T00P4=2@D00@4100005@000`40000200`90P402PVW2JL9Y`VW2JL20@JW00P12:L8 -Y`RW0@/801/1200800P0200800P0200800P0200800P020402PP02048Y`RW2:L11ZL0306W2JL9Y`VW -2JL9Y`8160T20@0:2JL9Y`VW2JL9Y`811ZL02048Y`RW2:L12PP07040200800P0200800P0200800P0 -200800P0204:20080@RW2:L8Y`46Y`0<0JL9Y`VW2JL9Y`VW0P4;2@D00@4100005@000`40000200X9 -0P403:L9Y`VW2JL9Y`VW0@RW00L1Y`RW2:L100/801d1200800P0200800P0200800P0200800P02008 -0@0:20070@RW2:L80@07Y`8100/9Y`VW2JL9Y`VW2@020A@90P403:L9Y`VW2JL9Y`VW0@RW00L1Y`RW -2:L100X801h100P0200800P0200800P0200800P0200800P0204:20070@RW2:L80@07Y`8100/9Y`VW -2JL9Y`VW2@020@T91@010@40000E00030@0000802@T03P49Y`VW2JL9Y`VW2JL12:L01`6W2:L8Y`40 -2`P07`4800P0200800P0200800P0200800P0200800P020402PP01`48Y`RW20402:L03@49Y`VW2JL9 -Y`VW2JL00P4A2@0>0@VW2JL9Y`VW2JL9Y`48Y`070JL8Y`RW0@0:200P0@0800P0200800P0200800P0 -200800P0200800P0204:20070@RW2:L80@08Y`0>0@VW2JL9Y`VW2JL9Y`482@D00@4100005@000`40 -000200L90P403@VW2JL9Y`VW2JL9Y`402:L01`6W2:L8Y`402`P08@4800P0200800P0200800P02008 -00P0200800P020080@0:20070@RW2:L80@08Y`0>0@VW2JL9Y`VW2JL9Y`T20@d90P403@VW2JL9Y`VW -2JL9Y`402:L01`6W2:L8Y`402PP08P40200800P0200800P0200800P0200800P0200800P0204:2007 -0@RW2:L80@08Y`0=0@VW2JL9Y`VW2JL9Y`020@H91@010@40000E00030@0000801@T20@0>Y`VW2JL9 -Y`VW2JL9Y`49Y`070@RW2:L80@09208100L800P0200801<100P800P020080@X800L12:L8Y`P100RW -00l12JL9Y`VW2JL9Y`VW2JL00P492@8100jW2JL9Y`VW2JL9Y`VW0@VW00L12:L8Y`P100T800P100P0 -200801@100P800P020080@X800L12:L8Y`P100RW00h12JL9Y`VW2JL9Y`VW2@8110T500410@0001D0 -00<100000P032@8100l9Y`VW2JL9Y`VW2JL9Y`402JL01`48Y`RW20402@P02P40200800P0204C0009 -0@P0200800P100T800L1Y`RW2:L100VW01012JL9Y`VW2JL9Y`VW2JL90P452@8100l9Y`VW2JL9Y`VW -2JL9Y`402JL01`48Y`RW20402@P02@40200800P00@0D00090@P0200800P100T800L1Y`RW2:L100VW -00l12JL9Y`VW2JL9Y`VW2JL00P422@D00@4100005@000`400002000C2@41Y`VW2JL9Y`VW2JL9Y`VW -0@09Y`080@RW2:L8Y`48200:0@0800P020080AD000T1200800P020402@P01`6W2:L8Y`402JL04@49 -Y`VW2JL9Y`VW2JL9Y`VW008101<90@6W2JL9Y`VW2JL9Y`VW2JL100VW00P12:L8Y`RW0@P800T100P0 -200800405P002@4800P020080@0920070JL8Y`RW0@09Y`0@0@VW2JL9Y`VW2JL9Y`VW2@811@010@40 -000E00030@00008001812JL9Y`VW2JL9Y`VW2JL9Y`49Y`080@RW2:L8Y`48200:0@0800P020080AL0 -00T1200800P0204020P02048Y`RW2:L12JL09049Y`VW2JL9Y`VW2JL9Y`VW2@49Y`VW2JL9Y`VW2JL9 -Y`VW0@VW00P12:L8Y`RW0@P800T100P02008004060002@4800P020080@0820080@RW2:L8Y`49Y`0B -0@VW2JL9Y`VW2JL9Y`VW2JL110010@40000E00030@0000800149Y`VW2JL9Y`VW2JL9Y`VW0@0:Y`08 -0JL8Y`RW2047200:0@0800P020080AT000T1200800P0204020P01`48Y`RW20402ZL08P49Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4:Y`080JL8Y`RW204720090@0800P0200101X000T12008 -00P0204020P01`48Y`RW20402ZL04049Y`VW2JL9Y`VW2JL9Y`T500410@0001D00P43000>Y`VW2JL9 -Y`VW2JL9Y`T20@ZW00P1Y`RW2:L80@L800X100P0200800P16`002@4800P020080@0720080JL8Y`RW -204:Y`0P0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4:Y`080JL8Y`RW2047200:0@0800P0 -20080AX000X100P0200800P11`P0206W2:L8Y`P12ZL03`49Y`VW2JL9Y`VW2JL9Y`0400810@0001D0 -00<100000P003PVW2JL9Y`VW2JL9Y`T12jL02@6W2:L8Y`RW0@06200:0@0800P020080Ad000T12008 -00P020401`P0206W2:L8Y`P12ZL07`49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@402JL02@6W -2:L8Y`RW0@06200:0@0800P020080A`000X100P0200800P11`P0206W2:L8Y`P12ZL20@0Y`VW2JL9Y`VW2JL9 -Y`49Y`070@RW2:L80@09208100L800P0200801<100P800P020080@X800L12:L8Y`P100RW00l12JL9 -Y`VW2JL9Y`VW2JL00P492@8100jW2JL9Y`VW2JL9Y`VW0@VW00L12:L8Y`P100T800P100P0200801@1 -00P800P020080@X800L12:L8Y`P100RW00h12JL9Y`VW2JL9Y`VW2@8110T500410@0001D000<10000 -0P072@8100d9Y`VW2JL9Y`VW2JL100RW00L1Y`RW2:L100/80241200800P0200800P0200800P02008 -00P0200800P020402PP01`48Y`RW20402:L03P49Y`VW2JL9Y`VW2JL90P4=2@8100d9Y`VW2JL9Y`VW -2JL100RW00L1Y`RW2:L100X8028100P0200800P0200800P0200800P0200800P0200800P12PP01`48 -Y`RW20402:L03@49Y`VW2JL9Y`VW2JL00P462@D00@4100005@000`40000200T900h12JL9Y`VW2JL9 -Y`VW0@RW00L1Y`RW2:L100/801l1200800P0200800P0200800P0200800P0200800P100X800L12:L8 -Y`P100RW00d12JL9Y`VW2JL9Y`VW00814@T03P49Y`VW2JL9Y`VW2JL12:L01`6W2:L8Y`402PP08040 -200800P0200800P0200800P0200800P0200800P12PP01`48Y`RW20402:L03P49Y`VW2JL9Y`VW2JL1 -20T500410@0001D000<100000P0:2@8100bW2JL9Y`VW2JL9Y`48Y`070JL8Y`RW0@0;200M0@P02008 -00P0200800P0200800P0200800P020402PP01`48Y`RW20401jL20@0;2JL9Y`VW2JL9Y`T00P4D2@81 -00bW2JL9Y`VW2JL9Y`48Y`070JL8Y`RW0@0:200N0@0800P0200800P0200800P0200800P0200800P1 -2PP01`48Y`RW20401jL20@0;2JL9Y`VW2JL9Y`T00P492@D00@4100005@000`40000200`90P402PVW -2JL9Y`VW2JL20@JW00P12:L8Y`RW0@/801/1200800P0200800P0200800P0200800P020402PP02048 -Y`RW2:L11ZL0306W2JL9Y`VW2JL9Y`8160T20@0:2JL9Y`VW2JL9Y`811ZL02048Y`RW2:L12PP07040 -200800P0200800P0200800P0200800P0204:20080@RW2:L8Y`46Y`0<0JL9Y`VW2JL9Y`VW0P4;2@D0 -0@4100005@000`40000200h90P402jL9Y`VW2JL9Y`T100JW00L12:L8Y`RW00812PP06@4800P02008 -00P0200800P0200800P020402PP02048Y`RW2:L11ZL02`6W2JL9Y`VW2JL9008170T20@0;Y`VW2JL9 -Y`VW2@401ZL02048Y`RW2:L12PP06P40200800P0200800P0200800P0200800P12@P20@072:L8Y`RW -0@06Y`0;0JL9Y`VW2JL9Y`T00P4=2@D00@4100005@000`40000200813PT20@0:2JL9Y`VW2JL90@JW -00T12:L8Y`RW20402PP05`4800P0200800P0200800P0200800P100X800P12:L8Y`RW0@JW00X1Y`VW -2JL9Y`VW0P4?2@<13PT20@0:2JL9Y`VW2JL90@JW00P12:L8Y`RW0@X801P100P0200800P0200800P0 -200800P0204920090JL8Y`RW2:L100JW00X1Y`VW2JL9Y`VW0P4>2@8110010@40000E00030@000080 -00@9DP413PT02`49Y`VW2JL9Y`T100JW00T12:L8Y`RW20402PP05@4800P0200800P0200800P02008 -0@0:20080@RW2:L8Y`46Y`090JL9Y`VW2JL900813@T40@03DPUB00<13@T02`49Y`VW2JL9Y`T100JW -00P12:L8Y`RW0@X801H100P0200800P0200800P0200800P12@P02@6W2:L8Y`RW0@06Y`090JL9Y`VW -2JL900813PT20@032@0000<00@4100005@020@<000AB2E890`4<2@8100VW2JL9Y`VW2@401JL02P6W -2:L8Y`RW204:21<12PP02@48Y`RW2:L80@05Y`080JL9Y`VW2JL20@/910402PUB2E89DPUB2E840@X9 -0P402JL9Y`VW2JL90@05Y`090JL8Y`RW2:L100X85049200:0JL8Y`RW2:L80@FW00P1Y`VW2JL9Y`81 -3PT20@03DPUB00@00P4100005@000`40000200072E89DPUB2@030@/90P4020VW2JL9Y`T11JL20@08 -2:L8Y`RW204U20090@RW2:L8Y`P100FW00T1Y`VW2JL9Y`402PT30@0BDPUB2E89DPUB2E89DPUB2E89 -0P4:2@8100P9Y`VW2JL90@FW00T1Y`RW2:L8Y`409@P02P6W2:L8Y`RW2045Y`090JL9Y`VW2JL100d9 -0`401@UB2E8900D00@4100005@000`400002000:DPUB2E89DPUB2@812`T02@49Y`VW2JL90@05Y`81 -00L8Y`RW2:L800818@P20@062:L8Y`RW0P45Y`090JL9Y`VW2JL100T90P405e89DPUB2E89DPUB2E89 -DPUB2E89DPUB00812PT02@49Y`VW2JL90@05Y`8100H8Y`RW2:L20B480P401jL8Y`RW2:L00P45Y`09 -0JL9Y`VW2JL100/90`4020UB2E89DPUB1@010@40000E00030@00008000`9DPUB2E89DPUB2E830@T9 -00T12JL9Y`VW2@401ZL02@48Y`RW2:L8Y`020Ad80P402:L8Y`RW2:L11ZL02@6W2JL9Y`VW0@082@81 -01/9DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT00P492@090@VW2JL9Y`T100JW00P12:L8Y`RW2081 -7PP02P48Y`RW2:L8Y`46Y`090JL9Y`VW2JL100X90P402`UB2E89DPUB2E8900D00@4100005@000`40 -0002000?DPUB2E89DPUB2E89DPUB008120T02@49Y`VW2JL90@06Y`8100VW2:L8Y`RW20406`P02P48 -Y`RW2:L8Y`46Y`090JL9Y`VW2JL100L90P407e89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E80 -0P482@090@VW2JL9Y`T100JW00X12:L8Y`RW2:L16`P20@092:L8Y`RW2:L100JW00T1Y`VW2JL9Y`40 -20T30@0=DPUB2E89DPUB2E89DP0500410@0001D000<100000P020@0?2E89DPUB2E89DPUB2E890081 -1`T02@49Y`VW2JL90@07Y`090JL8Y`RW2:L800815`P20@072:L8Y`RW20020@JW00T1Y`VW2JL9Y`40 -1`T04P49DPUB2E89DPUB2E89DPUB2@<100l9DPUB2E89DPUB2E89DPT00P472@090@VW2JL9Y`T100JW -0P401jL8Y`RW2:L00P4H20090JL8Y`RW2:L800811ZL02@6W2JL9Y`VW0@072@8100mB2E89DPUB2E89 -DPUB2E800P4400410@0001D000<100000P02DP81011B2E89DPUB2E89DPUB2E811`T02@49Y`VW2JL9 -0@07Y`8100P8Y`RW2:L8Y`814`P20@09Y`RW2:L8Y`P100NW00T1Y`VW2JL9Y`401`T04049DPUB2E89 -DPUB2E89DPT30@=B0P404589DPUB2E89DPUB2E89DP472@090@VW2JL9Y`T100NW00T1Y`RW2:L8Y`P0 -0P4D208100VW2:L8Y`RW20401jL02@6W2JL9Y`VW0@072@0@0@UB2E89DPUB2E89DPUB2@8100=B0000 -0`010@40000E00030@00008015830@0>DPUB2E89DPUB2E89DP472@090@VW2JL9Y`T100RW00X12:L8 -Y`RW2:L84`4020RW2:L8Y`RW0P47Y`090JL9Y`VW2JL100L900l12E89DPUB2E89DPUB2E800P48DP<1 -00iB2E89DPUB2E89DPUB0@L900T12JL9Y`VW2@401jL02P6W2:L8Y`RW2:LD0@082:L8Y`RW2:L20@NW -00T1Y`VW2JL9Y`401`T03P49DPUB2E89DPUB2E890`43DPD00@4100005@000`40000200MB0P403@UB -2E89DPUB2E89DP401`T02@49Y`VW2JL90@08Y`0T0@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L12:L02@6W2JL9Y`VW0@072@0=0@UB2E89DPUB2E89DP030@eB0P403@UB2E89DPUB2E89DP40 -1`T02@49Y`VW2JL90@07Y`8102<8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@08Y`09 -0JL9Y`VW2JL100L900`12E89DPUB2E89DPT30@IB1@010@40000E00030@0000802E830@0;2E89DPUB -2E89DP401PT02P6W2JL9Y`VW2@48Y`81022W2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@RW -00X1Y`VW2JL9Y`T11PT02`49DPUB2E89DPUB00<14U830@0;2E89DPUB2E89DP401PT02P6W2JL9Y`VW -2@48Y`0R0@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@RW00X1Y`VW2JL9Y`T11PT02`49 -DPUB2E89DPUB00812E8500410@0001D000<100000P0DP81 -00L9DPUB2E8100H900X1Y`VW2JL9Y`T12JL06P6W2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P12JL02P6W -2JL9Y`VW2@462@070@UB2E89DP020A1B00@100000P4100005@000`4000020003DP41011B00L12E89 -DPT100L900X1Y`VW2JL9Y`T12ZL20@0CY`RW2:L8Y`RW2:L8Y`RW2:L8Y`020@ZW00T12JL9Y`VW2@40 -1`T01`5B2E89DP404E820@03DP41011B00L12E89DPT100L900X1Y`VW2JL9Y`T12JL20@0D2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L20@VW00X1Y`VW2JL9Y`T11`T01`5B2E89DP4045820@D00@4100005@000`40 -000200030E8100813e801`49DPUB2@401`T02@6W2JL9Y`VW0@0DP070@UB2E890@072@090JL9Y`VW2JL102RW00T12JL9Y`VW2@401`T01`5B2E89DP403e820@03 -DP5B00D00@4100005@000`40000200060E81DP5B0P4>DP070@UB2E890@072@090JL9Y`VW2JL102JW -00T12JL9Y`VW2@401`T0205B2E89DPT13E830@0;DP5B0E81DP5B0E800P4>DP070@UB2E890@072@09 -0JL9Y`VW2JL102JW00T12JL9Y`VW2@401`T0205B2E89DPT13E830@04DP5B0@D00@4100005@000`40 -00020007DP5B0E81DP020@eB00P1DPUB2E890@L900T1Y`VW2JL9Y`409JL0206W2JL9Y`T11`T0205B -2E89DPT135820@0?DP5B0E81DP5B0E81DP5B00<13580205B2E89DPT11`T02@6W2JL9Y`VW0@0TY`09 -0@VW2JL9Y`T100L900P1DPUB2E890@eB00P1DP5B0E81DPD00@4100005@000`40000200080E81DP5B -0E830@aB00P1DPUB2E890@L900T1Y`VW2JL9Y`408jL02@6W2JL9Y`VW0@062@080E89DPUB2@4;DP<1 -01=B0E81DP5B0E81DP5B0E81DP5B00812e80205B2E89DPT11`T02@6W2JL9Y`VW0@0RY`0:0@VW2JL9 -Y`VW0@H900P1DPUB2E890@aB0P402581DP5B0E811@010@40000E00030@00008000]B0E81DP5B0E81 -DP020@]B00P1DPUB2E890@H900X12JL9Y`VW2JL18JL02@6W2JL9Y`VW0@062@080E89DPUB2@4:DP81 -01MB0E81DP5B0E81DP5B0E81DP5B0E81DP030@YB00P1DPUB2E890@H900X12JL9Y`VW2JL18:L02P49 -Y`VW2JL9Y`462@080E89DPUB2@4;DP<100UB0E81DP5B0E801@010@40000E00030@00008000`1DP5B -0E81DP5B0E820@]B00P1DPUB2E890@H900X12JL9Y`VW2JL17jL02@6W2JL9Y`VW0@062@080E89DPUB -2@4:DP8101aB0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E812U80205B2E89DPT11PT02P49Y`VW2JL9 -Y`4NY`0:0@VW2JL9Y`VW0@H900P1DPUB2E890@]B00d1DP5B0E81DP5B0E8100D00@4100005@000`40 -0002000=DP5B0E81DP5B0E81DP020@YB00P12E89DPUB0@L900X12JL9Y`VW2JL17JL02P6W2JL9Y`VW -2@462@080@UB2E89DP49DP8101iB0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP49DP080@UB2E89 -DP472@0:0@VW2JL9Y`VW0AbW00/12JL9Y`VW2JL90@062@080@UB2E89DP4:DP0>0E81DP5B0E81DP5B -0E8500410@0001D000<100000P003P5B0E81DP5B0E81DP5B0`49DP080@UB2E89DP462@0;0JL9Y`VW -2JL9Y`406jL02P6W2JL9Y`VW2@462@080@UB2E89DP49DP81021B0E81DP5B0E81DP5B0E81DP5B0E81 -DP5B0E81DP5B0@UB00P12E89DPUB0@H900/1Y`VW2JL9Y`VW0@0KY`0:0JL9Y`VW2JL90@H900P12E89 -DPUB0@UB0P403U81DP5B0E81DP5B0E811@010@40000E00030@000080019B0E81DP5B0E81DP5B0E81 -DP48DP080E89DPUB2@472@0;0JL9Y`VW2JL9Y`406JL02`6W2JL9Y`VW2JL100H900P1DPUB2E890@QB -0P408U81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP48DP080E89DPUB2@472@0:0JL9Y`VW -2JL90AZW00/1Y`VW2JL9Y`VW0@062@080E89DPUB2@48DP8100mB0E81DP5B0E81DP5B0E801@010@40 -000E00030@00008001<1DP5B0E81DP5B0E81DP5B0E8100QB00P1DPUB2E890@H900`12JL9Y`VW2JL9 -Y`4HY`0:0@VW2JL9Y`VW0@H900P1DPUB2E890@QB0P409581DP5B0E81DP5B0E81DP5B0E81DP5B0E81 -DP5B0E81DP5B0@QB00P1DPUB2E890@H900/12JL9Y`VW2JL90@0HY`0;0JL9Y`VW2JL9Y`401PT0205B -2E89DPT125820@0?DP5B0E81DP5B0E81DP5B008110010@40000E00810`020@0BDP5B0E81DP5B0E81 -DP5B0E811e802049DPUB2E811`T02`49Y`VW2JL9Y`T101NW00/12JL9Y`VW2JL90@062@080@UB2E89 -DP48DP0B0E81DP5B0E81DP5B0E81DP5B0`404U81DP5B0E81DP5B0E81DP5B0@MB00P12E89DPUB0@L9 -00/12JL9Y`VW2JL90@0FY`0<0JL9Y`VW2JL9Y`T11PT02049DPUB2E812580405B0E81DP5B0E81DP5B -0E820@@00P4100005@000`40000200<100mB0E81DP5B0E81DP5B0E800P48DP070@UB2E890@072@0< -0JL9Y`VW2JL9Y`T15JL02`49Y`VW2JL9Y`T100L900P1DPUB2E890@MB0181DP5B0E81DP5B0E81DP5B -0E850@0?DP5B0E81DP5B0E81DP5B00811e80205B2E89DPT11`T0306W2JL9Y`VW2JL90AFW00/12JL9 -Y`VW2JL90@072@070E89DPUB0@08DP0@0E81DP5B0E81DP5B0E81DP<11@010@40000E00030@000080 -10403e81DP5B0E81DP5B0E81DP020@MB00P1DPUB2E890@L900`1Y`VW2JL9Y`VW2@4CY`0<0@VW2JL9 -Y`VW2JL11PT0205B2E89DPT125820@0?DP5B0E81DP5B0E81DP5B00L100mB0E81DP5B0E81DP5B0E80 -0P47DP080E89DPUB2@472@0;0JL9Y`VW2JL9Y`405:L03049Y`VW2JL9Y`VW0@H900P1DPUB2E890@QB -0P403E81DP5B0E81DP5B0E80104500410@0001D000<100000P050@0@DP5B0E81DP5B0E81DP5B0@QB -00L1DPUB2E8100L900`12JL9Y`VW2JL9Y`TC0@0;2JL9Y`VW2JL9Y`401`T02049DPUB2E811e820@0? -DP5B0E81DP5B0E81DP5B00T1011B0E81DP5B0E81DP5B0E811e802049DPUB2E811`T02`49Y`VW2JL9 -Y`VW01@100/9Y`VW2JL9Y`VW0@072@070@UB2E890@08DP8100eB0E81DP5B0E81DP5B00D11@010@40 -000E00030@0000801P404581DP5B0E81DP5B0E81DP47DP080@UB2E89DP472@0Y0@VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@401PT02@49DPUB2E890@07DP0@0E81DP5B0E81DP5B -0E81DP/1011B0E81DP5B0E81DP5B0E811e802049DPUB2E811`T0:@49Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T100H900P12E89DPUB0@QB00h1DP5B0E81DP5B0E81DPH11@010@40 -000E00030@0000801`403E81DP5B0E81DP5B0E800P47DP080E89DPUB2@472@0X0JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@L900P1DPUB2E890@MB0101DP5B0E81DP5B0E81DP5B -3@403E81DP5B0E81DP5B0E800P47DP080E89DPUB2@472@0X0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL90@L900P1DPUB2E890@MB00h1DP5B0E81DP5B0E81DPL11@010@40000E0003 -0@00008020403E81DP5B0E81DP5B0E800P47DP070E89DPUB0@082@0W0JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL100L900P12E89DPUB0@MB0P402e81DP5B0E81DP5B01<100]B0E81 -DP5B0E81DP020@IB00P12E89DPUB0@P902L1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`401`T01`49DPUB2@4025820@0;DP5B0E81DP5B0E80204500410@0001D000<100000P090@0= -DP5B0E81DP5B0E81DP020@IB00P12E89DPUB0@L902H12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW0@L900P12E89DPUB0@MB0P402e81DP5B0E81DP5B01D100aB0E81DP5B0E81DP47DP08 -0@UB2E89DP472@0V0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`472@080@UB2E89 -DP47DP8100]B0E81DP5B0E81DP090@D00@4100005@000`40000200X100iB0E81DP5B0E81DP5B0@MB -00L12E89DPT100P902D12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T100L900P1DPUB -2E890@MB00`1DP5B0E81DP5B0E8G0@00@D00@4100003@000`40000500810`0?0@0"], - ImageRangeCache->{{{0, 287}, {287, 0}} -> {-0.207, -0.172242, 0.00783272, - 0.00783272}}], - -Cell[BoxData[ - TagBox[\(\[SkeletonIndicator] ContourGraphics \[SkeletonIndicator]\), - False, - Editable->False]], "Output"] -}, Open ]], - -Cell[CellGroupData[{ - -Cell[BoxData[ - \(ContourPlot[Y, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"], - -Cell[GraphicsData["PostScript", "\<\ -%! -%%Creator: Mathematica -%%AspectRatio: 1 -MathPictureStart -/Mabs { -Mgmatrix idtransform -Mtmatrix dtransform -} bind def -/Mabsadd { Mabs -3 -1 roll add -3 1 roll add -exch } bind def -%% ContourGraphics -%%IncludeResource: font Courier -%%IncludeFont: Courier -/Courier findfont 10 scalefont setfont -% Scaling calculations -0.0192308 0.480769 0.0192308 0.480769 [ -[.01923 -0.0125 -3 -9 ] -[.01923 -0.0125 3 0 ] -[.25962 -0.0125 -9 -9 ] -[.25962 -0.0125 9 0 ] -[.5 -0.0125 -3 -9 ] -[.5 -0.0125 3 0 ] -[.74038 -0.0125 -9 -9 ] -[.74038 -0.0125 9 0 ] -[.98077 -0.0125 -3 -9 ] -[.98077 -0.0125 3 0 ] -[ 0 0 -0.125 0 ] -[-0.0125 .01923 -6 -4.5 ] -[-0.0125 .01923 0 4.5 ] -[-0.0125 .25962 -18 -4.5 ] -[-0.0125 .25962 0 4.5 ] -[-0.0125 .5 -6 -4.5 ] -[-0.0125 .5 0 4.5 ] -[-0.0125 .74038 -18 -4.5 ] -[-0.0125 .74038 0 4.5 ] -[-0.0125 .98077 -6 -4.5 ] -[-0.0125 .98077 0 4.5 ] -[ 0 0 -0.125 0 ] -[ 0 1 .125 0 ] -[ 1 0 .125 0 ] -[ 0 0 0 0 ] -[ 1 1 0 0 ] -] MathScale -% Start of Graphics -1 setlinecap -1 setlinejoin -newpath -0 g -.25 Mabswid -.01923 0 m -.01923 .00625 L -s -[(0)] .01923 -0.0125 0 1 Mshowa -.25962 0 m -.25962 .00625 L -s -[(0.5)] .25962 -0.0125 0 1 Mshowa -.5 0 m -.5 .00625 L -s -[(1)] .5 -0.0125 0 1 Mshowa -.74038 0 m -.74038 .00625 L -s -[(1.5)] .74038 -0.0125 0 1 Mshowa -.98077 0 m -.98077 .00625 L -s -[(2)] .98077 -0.0125 0 1 Mshowa -.125 Mabswid -.06731 0 m -.06731 .00375 L -s -.11538 0 m -.11538 .00375 L -s -.16346 0 m -.16346 .00375 L -s -.21154 0 m -.21154 .00375 L -s -.30769 0 m -.30769 .00375 L -s -.35577 0 m -.35577 .00375 L -s -.40385 0 m -.40385 .00375 L -s -.45192 0 m -.45192 .00375 L -s -.54808 0 m -.54808 .00375 L -s -.59615 0 m -.59615 .00375 L -s -.64423 0 m -.64423 .00375 L -s -.69231 0 m -.69231 .00375 L -s -.78846 0 m -.78846 .00375 L -s -.83654 0 m -.83654 .00375 L -s -.88462 0 m -.88462 .00375 L -s -.93269 0 m -.93269 .00375 L -s -.25 Mabswid -0 0 m -1 0 L -s -0 .01923 m -.00625 .01923 L -s -[(0)] -0.0125 .01923 1 0 Mshowa -0 .25962 m -.00625 .25962 L -s -[(0.5)] -0.0125 .25962 1 0 Mshowa -0 .5 m -.00625 .5 L -s -[(1)] -0.0125 .5 1 0 Mshowa -0 .74038 m -.00625 .74038 L -s -[(1.5)] -0.0125 .74038 1 0 Mshowa -0 .98077 m -.00625 .98077 L -s -[(2)] -0.0125 .98077 1 0 Mshowa -.125 Mabswid -0 .06731 m -.00375 .06731 L -s -0 .11538 m -.00375 .11538 L -s -0 .16346 m -.00375 .16346 L -s -0 .21154 m -.00375 .21154 L -s -0 .30769 m -.00375 .30769 L -s -0 .35577 m -.00375 .35577 L -s -0 .40385 m -.00375 .40385 L -s -0 .45192 m -.00375 .45192 L -s -0 .54808 m -.00375 .54808 L -s -0 .59615 m -.00375 .59615 L -s -0 .64423 m -.00375 .64423 L -s -0 .69231 m -.00375 .69231 L -s -0 .78846 m -.00375 .78846 L -s -0 .83654 m -.00375 .83654 L -s -0 .88462 m -.00375 .88462 L -s -0 .93269 m -.00375 .93269 L -s -.25 Mabswid -0 0 m -0 1 L -s -.01923 .99375 m -.01923 1 L -s -.25962 .99375 m -.25962 1 L -s -.5 .99375 m -.5 1 L -s -.74038 .99375 m -.74038 1 L -s -.98077 .99375 m -.98077 1 L -s -.125 Mabswid -.06731 .99625 m -.06731 1 L -s -.11538 .99625 m -.11538 1 L -s -.16346 .99625 m -.16346 1 L -s -.21154 .99625 m -.21154 1 L -s -.30769 .99625 m -.30769 1 L -s -.35577 .99625 m -.35577 1 L -s -.40385 .99625 m -.40385 1 L -s -.45192 .99625 m -.45192 1 L -s -.54808 .99625 m -.54808 1 L -s -.59615 .99625 m -.59615 1 L -s -.64423 .99625 m -.64423 1 L -s -.69231 .99625 m -.69231 1 L -s -.78846 .99625 m -.78846 1 L -s -.83654 .99625 m -.83654 1 L -s -.88462 .99625 m -.88462 1 L -s -.93269 .99625 m -.93269 1 L -s -.25 Mabswid -0 1 m -1 1 L -s -.99375 .01923 m -1 .01923 L -s -.99375 .25962 m -1 .25962 L -s -.99375 .5 m -1 .5 L -s -.99375 .74038 m -1 .74038 L -s -.99375 .98077 m -1 .98077 L -s -.125 Mabswid -.99625 .06731 m -1 .06731 L -s -.99625 .11538 m -1 .11538 L -s -.99625 .16346 m -1 .16346 L -s -.99625 .21154 m -1 .21154 L -s -.99625 .30769 m -1 .30769 L -s -.99625 .35577 m -1 .35577 L -s -.99625 .40385 m -1 .40385 L -s -.99625 .45192 m -1 .45192 L -s -.99625 .54808 m -1 .54808 L -s -.99625 .59615 m -1 .59615 L -s -.99625 .64423 m -1 .64423 L -s -.99625 .69231 m -1 .69231 L -s -.99625 .78846 m -1 .78846 L -s -.99625 .83654 m -1 .83654 L -s -.99625 .88462 m -1 .88462 L -s -.99625 .93269 m -1 .93269 L -s -.25 Mabswid -1 0 m -1 1 L -s -0 0 m -1 0 L -1 1 L -0 1 L -closepath -clip -newpath -.5 g -.01923 .98077 m -.98077 .98077 L -.98077 .01923 L -.01923 .01923 L -F -0 g -.5 Mabswid -.6 g -.01923 .24501 m -.08791 .2434 L -.15659 .23612 L -.19287 .22527 L -.22527 .19287 L -.23612 .15659 L -.2434 .08791 L -.24501 .01923 L -.01923 .01923 L -F -0 g -.01923 .24501 m -.08791 .2434 L -.15659 .23612 L -.19287 .22527 L -.22527 .19287 L -.23612 .15659 L -.2434 .08791 L -.24501 .01923 L -s -.4 g -.01923 .72578 m -.08791 .72416 L -.15659 .71689 L -.19287 .70604 L -.22527 .67364 L -.23612 .63736 L -.2434 .56868 L -.24501 .5 L -.2434 .43132 L -.23612 .36264 L -.22527 .32636 L -.19287 .29396 L -.15659 .28311 L -.08791 .27584 L -.01923 .27422 L -F -0 g -.01923 .72578 m -.08791 .72416 L -.15659 .71689 L -.19287 .70604 L -.22527 .67364 L -.23612 .63736 L -.2434 .56868 L -.24501 .5 L -.2434 .43132 L -.23612 .36264 L -.22527 .32636 L -.19287 .29396 L -.15659 .28311 L -.08791 .27584 L -.01923 .27422 L -s -.6 g -.01923 .75499 m -.08791 .7566 L -.15659 .76388 L -.19287 .77473 L -.22527 .80713 L -.23612 .84341 L -.2434 .91209 L -.24501 .98077 L -.01923 .98077 L -F -0 g -.01923 .75499 m -.08791 .7566 L -.15659 .76388 L -.19287 .77473 L -.22527 .80713 L -.23612 .84341 L -.2434 .91209 L -.24501 .98077 L -s -.7 g -.01923 .21567 m -.08791 .21083 L -.15659 .18768 L -.18768 .15659 L -.21083 .08791 L -.21567 .01923 L -.01923 .01923 L -F -0 g -.01923 .21567 m -.08791 .21083 L -.15659 .18768 L -.18768 .15659 L -.21083 .08791 L -.21567 .01923 L -s -.3 g -.01923 .69644 m -.08791 .69159 L -.15659 .66845 L -.18768 .63736 L -.21083 .56868 L -.21567 .5 L -.21083 .43132 L -.18768 .36264 L -.15659 .33155 L -.08791 .30841 L -.01923 .30356 L -F -0 g -.01923 .69644 m -.08791 .69159 L -.15659 .66845 L -.18768 .63736 L -.21083 .56868 L -.21567 .5 L -.21083 .43132 L -.18768 .36264 L -.15659 .33155 L -.08791 .30841 L -.01923 .30356 L -s -.7 g -.01923 .78433 m -.08791 .78917 L -.15659 .81232 L -.18768 .84341 L -.21083 .91209 L -.21567 .98077 L -.01923 .98077 L -F -0 g -.01923 .78433 m -.08791 .78917 L -.15659 .81232 L -.18768 .84341 L -.21083 .91209 L -.21567 .98077 L -s -.8 g -.01923 .18453 m -.08791 .17501 L -.13801 .15659 L -.15659 .13801 L -.17501 .08791 L -.18453 .01923 L -.01923 .01923 L -F -0 g -.01923 .18453 m -.08791 .17501 L -.13801 .15659 L -.15659 .13801 L -.17501 .08791 L -.18453 .01923 L -s -.2 g -.01923 .6653 m -.08791 .65578 L -.13801 .63736 L -.15659 .61878 L -.17501 .56868 L -.18453 .5 L -.17501 .43132 L -.15659 .38122 L -.13801 .36264 L -.08791 .34422 L -.01923 .3347 L -F -0 g -.01923 .6653 m -.08791 .65578 L -.13801 .63736 L -.15659 .61878 L -.17501 .56868 L -.18453 .5 L -.17501 .43132 L -.15659 .38122 L -.13801 .36264 L -.08791 .34422 L -.01923 .3347 L -s -.8 g -.01923 .81547 m -.08791 .82499 L -.13801 .84341 L -.15659 .86199 L -.17501 .91209 L -.18453 .98077 L -.01923 .98077 L -F -0 g -.01923 .81547 m -.08791 .82499 L -.13801 .84341 L -.15659 .86199 L -.17501 .91209 L -.18453 .98077 L -s -.9 g -.01923 .15309 m -.08791 .14294 L -.14294 .08791 L -.15309 .01923 L -.01923 .01923 L -F -0 g -.01923 .15309 m -.08791 .14294 L -.14294 .08791 L -.15309 .01923 L -s -.1 g -.01923 .63386 m -.08791 .62371 L -.14294 .56868 L -.15309 .5 L -.14294 .43132 L -.08791 .37629 L -.01923 .36614 L -F -0 g -.01923 .63386 m -.08791 .62371 L -.14294 .56868 L -.15309 .5 L -.14294 .43132 L -.08791 .37629 L -.01923 .36614 L -s -.9 g -.01923 .84691 m -.08791 .85706 L -.14294 .91209 L -.15309 .98077 L -.01923 .98077 L -F -0 g -.01923 .84691 m -.08791 .85706 L -.14294 .91209 L -.15309 .98077 L -s -1 g -.01923 .10805 m -.05547 .08791 L -.08791 .05547 L -.10805 .01923 L -.01923 .01923 L -F -0 g -.01923 .10805 m -.05547 .08791 L -.08791 .05547 L -.10805 .01923 L -s -.01923 .58882 m -.05547 .56868 L -.08791 .54644 L -.10805 .5 L -.08791 .45356 L -.05547 .43132 L -.01923 .41118 L -F -.01923 .58882 m -.05547 .56868 L -.08791 .54644 L -.10805 .5 L -.08791 .45356 L -.05547 .43132 L -.01923 .41118 L -s -1 g -.01923 .89195 m -.05547 .91209 L -.08791 .94453 L -.10805 .98077 L -.01923 .98077 L -F -0 g -.01923 .89195 m -.05547 .91209 L -.08791 .94453 L -.10805 .98077 L -s -.4 g -.72578 .01923 m -.72416 .08791 L -.71689 .15659 L -.70604 .19287 L -.67364 .22527 L -.63736 .23612 L -.56868 .2434 L -.5 .24501 L -.43132 .2434 L -.36264 .23612 L -.32636 .22527 L -.29396 .19287 L -.28311 .15659 L -.27584 .08791 L -.27422 .01923 L -F -0 g -.72578 .01923 m -.72416 .08791 L -.71689 .15659 L -.70604 .19287 L -.67364 .22527 L -.63736 .23612 L -.56868 .2434 L -.5 .24501 L -.43132 .2434 L -.36264 .23612 L -.32636 .22527 L -.29396 .19287 L -.28311 .15659 L -.27584 .08791 L -.27422 .01923 L -s -.6 g -.36264 .28311 m -.43132 .27584 L -.5 .27422 L -.56868 .27584 L -.63736 .28311 L -.67364 .29396 L -.70604 .32636 L -.71689 .36264 L -.72416 .43132 L -.72578 .5 L -.72416 .56868 L -.71689 .63736 L -.70604 .67364 L -.67364 .70604 L -.63736 .71689 L -.56868 .72416 L -.5 .72578 L -.43132 .72416 L -.36264 .71689 L -.32636 .70604 L -.29396 .67364 L -.28311 .63736 L -.27584 .56868 L -.27422 .5 L -.27584 .43132 L -.28311 .36264 L -.29396 .32636 L -.32636 .29396 L -F -0 g -.36264 .28311 m -.43132 .27584 L -.5 .27422 L -.56868 .27584 L -.63736 .28311 L -.67364 .29396 L -.70604 .32636 L -.71689 .36264 L -.72416 .43132 L -.72578 .5 L -.72416 .56868 L -.71689 .63736 L -.70604 .67364 L -.67364 .70604 L -.63736 .71689 L -.56868 .72416 L -.5 .72578 L -.43132 .72416 L -.36264 .71689 L -.32636 .70604 L -.29396 .67364 L -.28311 .63736 L -.27584 .56868 L -.27422 .5 L -.27584 .43132 L -.28311 .36264 L -.29396 .32636 L -.32636 .29396 L -.36264 .28311 L -s -.4 g -.72578 .98077 m -.72416 .91209 L -.71689 .84341 L -.70604 .80713 L -.67364 .77473 L -.63736 .76388 L -.56868 .7566 L -.5 .75499 L -.43132 .7566 L -.36264 .76388 L -.32636 .77473 L -.29396 .80713 L -.28311 .84341 L -.27584 .91209 L -.27422 .98077 L -F -0 g -.72578 .98077 m -.72416 .91209 L -.71689 .84341 L -.70604 .80713 L -.67364 .77473 L -.63736 .76388 L -.56868 .7566 L -.5 .75499 L -.43132 .7566 L -.36264 .76388 L -.32636 .77473 L -.29396 .80713 L -.28311 .84341 L -.27584 .91209 L -.27422 .98077 L -s -.3 g -.69644 .01923 m -.69159 .08791 L -.66845 .15659 L -.63736 .18768 L -.56868 .21083 L -.5 .21567 L -.43132 .21083 L -.36264 .18768 L -.33155 .15659 L -.30841 .08791 L -.30356 .01923 L -F -0 g -.69644 .01923 m -.69159 .08791 L -.66845 .15659 L -.63736 .18768 L -.56868 .21083 L -.5 .21567 L -.43132 .21083 L -.36264 .18768 L -.33155 .15659 L -.30841 .08791 L -.30356 .01923 L -s -.7 g -.36264 .33155 m -.43132 .30841 L -.5 .30356 L -.56868 .30841 L -.63736 .33155 L -.66845 .36264 L -.69159 .43132 L -.69644 .5 L -.69159 .56868 L -.66845 .63736 L -.63736 .66845 L -.56868 .69159 L -.5 .69644 L -.43132 .69159 L -.36264 .66845 L -.33155 .63736 L -.30841 .56868 L -.30356 .5 L -.30841 .43132 L -.33155 .36264 L -F -0 g -.36264 .33155 m -.43132 .30841 L -.5 .30356 L -.56868 .30841 L -.63736 .33155 L -.66845 .36264 L -.69159 .43132 L -.69644 .5 L -.69159 .56868 L -.66845 .63736 L -.63736 .66845 L -.56868 .69159 L -.5 .69644 L -.43132 .69159 L -.36264 .66845 L -.33155 .63736 L -.30841 .56868 L -.30356 .5 L -.30841 .43132 L -.33155 .36264 L -.36264 .33155 L -s -.3 g -.69644 .98077 m -.69159 .91209 L -.66845 .84341 L -.63736 .81232 L -.56868 .78917 L -.5 .78433 L -.43132 .78917 L -.36264 .81232 L -.33155 .84341 L -.30841 .91209 L -.30356 .98077 L -F -0 g -.69644 .98077 m -.69159 .91209 L -.66845 .84341 L -.63736 .81232 L -.56868 .78917 L -.5 .78433 L -.43132 .78917 L -.36264 .81232 L -.33155 .84341 L -.30841 .91209 L -.30356 .98077 L -s -.2 g -.6653 .01923 m -.65578 .08791 L -.63736 .13801 L -.61878 .15659 L -.56868 .17501 L -.5 .18453 L -.43132 .17501 L -.38122 .15659 L -.36264 .13801 L -.34422 .08791 L -.3347 .01923 L -F -0 g -.6653 .01923 m -.65578 .08791 L -.63736 .13801 L -.61878 .15659 L -.56868 .17501 L -.5 .18453 L -.43132 .17501 L -.38122 .15659 L -.36264 .13801 L -.34422 .08791 L -.3347 .01923 L -s -.8 g -.43132 .34422 m -.5 .3347 L -.56868 .34422 L -.61878 .36264 L -.63736 .38122 L -.65578 .43132 L -.6653 .5 L -.65578 .56868 L -.63736 .61878 L -.61878 .63736 L -.56868 .65578 L -.5 .6653 L -.43132 .65578 L -.38122 .63736 L -.36264 .61878 L -.34422 .56868 L -.3347 .5 L -.34422 .43132 L -.36264 .38122 L -.38122 .36264 L -F -0 g -.43132 .34422 m -.5 .3347 L -.56868 .34422 L -.61878 .36264 L -.63736 .38122 L -.65578 .43132 L -.6653 .5 L -.65578 .56868 L -.63736 .61878 L -.61878 .63736 L -.56868 .65578 L -.5 .6653 L -.43132 .65578 L -.38122 .63736 L -.36264 .61878 L -.34422 .56868 L -.3347 .5 L -.34422 .43132 L -.36264 .38122 L -.38122 .36264 L -.43132 .34422 L -s -.2 g -.6653 .98077 m -.65578 .91209 L -.63736 .86199 L -.61878 .84341 L -.56868 .82499 L -.5 .81547 L -.43132 .82499 L -.38122 .84341 L -.36264 .86199 L -.34422 .91209 L -.3347 .98077 L -F -0 g -.6653 .98077 m -.65578 .91209 L -.63736 .86199 L -.61878 .84341 L -.56868 .82499 L -.5 .81547 L -.43132 .82499 L -.38122 .84341 L -.36264 .86199 L -.34422 .91209 L -.3347 .98077 L -s -.1 g -.63386 .01923 m -.62371 .08791 L -.56868 .14294 L -.5 .15309 L -.43132 .14294 L -.37629 .08791 L -.36614 .01923 L -F -0 g -.63386 .01923 m -.62371 .08791 L -.56868 .14294 L -.5 .15309 L -.43132 .14294 L -.37629 .08791 L -.36614 .01923 L -s -.9 g -.43132 .37629 m -.5 .36614 L -.56868 .37629 L -.62371 .43132 L -.63386 .5 L -.62371 .56868 L -.56868 .62371 L -.5 .63386 L -.43132 .62371 L -.37629 .56868 L -.36614 .5 L -.37629 .43132 L -F -0 g -.43132 .37629 m -.5 .36614 L -.56868 .37629 L -.62371 .43132 L -.63386 .5 L -.62371 .56868 L -.56868 .62371 L -.5 .63386 L -.43132 .62371 L -.37629 .56868 L -.36614 .5 L -.37629 .43132 L -.43132 .37629 L -s -.1 g -.63386 .98077 m -.62371 .91209 L -.56868 .85706 L -.5 .84691 L -.43132 .85706 L -.37629 .91209 L -.36614 .98077 L -F -0 g -.63386 .98077 m -.62371 .91209 L -.56868 .85706 L -.5 .84691 L -.43132 .85706 L -.37629 .91209 L -.36614 .98077 L -s -.58882 .01923 m -.56868 .05547 L -.54644 .08791 L -.5 .10805 L -.45356 .08791 L -.43132 .05547 L -.41118 .01923 L -F -.58882 .01923 m -.56868 .05547 L -.54644 .08791 L -.5 .10805 L -.45356 .08791 L -.43132 .05547 L -.41118 .01923 L -s -1 g -.5 .41118 m -.54644 .43132 L -.56868 .45356 L -.58882 .5 L -.56868 .54644 L -.54644 .56868 L -.5 .58882 L -.45356 .56868 L -.43132 .54644 L -.41118 .5 L -.43132 .45356 L -.45356 .43132 L -F -0 g -.5 .41118 m -.54644 .43132 L -.56868 .45356 L -.58882 .5 L -.56868 .54644 L -.54644 .56868 L -.5 .58882 L -.45356 .56868 L -.43132 .54644 L -.41118 .5 L -.43132 .45356 L -.45356 .43132 L -.5 .41118 L -s -.58882 .98077 m -.56868 .94453 L -.54644 .91209 L -.5 .89195 L -.45356 .91209 L -.43132 .94453 L -.41118 .98077 L -F -.58882 .98077 m -.56868 .94453 L -.54644 .91209 L -.5 .89195 L -.45356 .91209 L -.43132 .94453 L -.41118 .98077 L -s -.6 g -.98077 .24501 m -.91209 .2434 L -.84341 .23612 L -.80713 .22527 L -.77473 .19287 L -.76388 .15659 L -.7566 .08791 L -.75499 .01923 L -.98077 .01923 L -F -0 g -.98077 .24501 m -.91209 .2434 L -.84341 .23612 L -.80713 .22527 L -.77473 .19287 L -.76388 .15659 L -.7566 .08791 L -.75499 .01923 L -s -.4 g -.98077 .72578 m -.91209 .72416 L -.84341 .71689 L -.80713 .70604 L -.77473 .67364 L -.76388 .63736 L -.7566 .56868 L -.75499 .5 L -.7566 .43132 L -.76388 .36264 L -.77473 .32636 L -.80713 .29396 L -.84341 .28311 L -.91209 .27584 L -.98077 .27422 L -F -0 g -.98077 .72578 m -.91209 .72416 L -.84341 .71689 L -.80713 .70604 L -.77473 .67364 L -.76388 .63736 L -.7566 .56868 L -.75499 .5 L -.7566 .43132 L -.76388 .36264 L -.77473 .32636 L -.80713 .29396 L -.84341 .28311 L -.91209 .27584 L -.98077 .27422 L -s -.6 g -.98077 .75499 m -.91209 .7566 L -.84341 .76388 L -.80713 .77473 L -.77473 .80713 L -.76388 .84341 L -.7566 .91209 L -.75499 .98077 L -.98077 .98077 L -F -0 g -.98077 .75499 m -.91209 .7566 L -.84341 .76388 L -.80713 .77473 L -.77473 .80713 L -.76388 .84341 L -.7566 .91209 L -.75499 .98077 L -s -.7 g -.98077 .21567 m -.91209 .21083 L -.84341 .18768 L -.81232 .15659 L -.78917 .08791 L -.78433 .01923 L -.98077 .01923 L -F -0 g -.98077 .21567 m -.91209 .21083 L -.84341 .18768 L -.81232 .15659 L -.78917 .08791 L -.78433 .01923 L -s -.3 g -.98077 .69644 m -.91209 .69159 L -.84341 .66845 L -.81232 .63736 L -.78917 .56868 L -.78433 .5 L -.78917 .43132 L -.81232 .36264 L -.84341 .33155 L -.91209 .30841 L -.98077 .30356 L -F -0 g -.98077 .69644 m -.91209 .69159 L -.84341 .66845 L -.81232 .63736 L -.78917 .56868 L -.78433 .5 L -.78917 .43132 L -.81232 .36264 L -.84341 .33155 L -.91209 .30841 L -.98077 .30356 L -s -.7 g -.98077 .78433 m -.91209 .78917 L -.84341 .81232 L -.81232 .84341 L -.78917 .91209 L -.78433 .98077 L -.98077 .98077 L -F -0 g -.98077 .78433 m -.91209 .78917 L -.84341 .81232 L -.81232 .84341 L -.78917 .91209 L -.78433 .98077 L -s -.8 g -.98077 .18453 m -.91209 .17501 L -.86199 .15659 L -.84341 .13801 L -.82499 .08791 L -.81547 .01923 L -.98077 .01923 L -F -0 g -.98077 .18453 m -.91209 .17501 L -.86199 .15659 L -.84341 .13801 L -.82499 .08791 L -.81547 .01923 L -s -.2 g -.98077 .6653 m -.91209 .65578 L -.86199 .63736 L -.84341 .61878 L -.82499 .56868 L -.81547 .5 L -.82499 .43132 L -.84341 .38122 L -.86199 .36264 L -.91209 .34422 L -.98077 .3347 L -F -0 g -.98077 .6653 m -.91209 .65578 L -.86199 .63736 L -.84341 .61878 L -.82499 .56868 L -.81547 .5 L -.82499 .43132 L -.84341 .38122 L -.86199 .36264 L -.91209 .34422 L -.98077 .3347 L -s -.8 g -.98077 .81547 m -.91209 .82499 L -.86199 .84341 L -.84341 .86199 L -.82499 .91209 L -.81547 .98077 L -.98077 .98077 L -F -0 g -.98077 .81547 m -.91209 .82499 L -.86199 .84341 L -.84341 .86199 L -.82499 .91209 L -.81547 .98077 L -s -.9 g -.98077 .15309 m -.91209 .14294 L -.85706 .08791 L -.84691 .01923 L -.98077 .01923 L -F -0 g -.98077 .15309 m -.91209 .14294 L -.85706 .08791 L -.84691 .01923 L -s -.1 g -.98077 .63386 m -.91209 .62371 L -.85706 .56868 L -.84691 .5 L -.85706 .43132 L -.91209 .37629 L -.98077 .36614 L -F -0 g -.98077 .63386 m -.91209 .62371 L -.85706 .56868 L -.84691 .5 L -.85706 .43132 L -.91209 .37629 L -.98077 .36614 L -s -.9 g -.98077 .84691 m -.91209 .85706 L -.85706 .91209 L -.84691 .98077 L -.98077 .98077 L -F -0 g -.98077 .84691 m -.91209 .85706 L -.85706 .91209 L -.84691 .98077 L -s -1 g -.98077 .10805 m -.94453 .08791 L -.91209 .05547 L -.89195 .01923 L -.98077 .01923 L -F -0 g -.98077 .10805 m -.94453 .08791 L -.91209 .05547 L -.89195 .01923 L -s -.98077 .58882 m -.94453 .56868 L -.91209 .54644 L -.89195 .5 L -.91209 .45356 L -.94453 .43132 L -.98077 .41118 L -F -.98077 .58882 m -.94453 .56868 L -.91209 .54644 L -.89195 .5 L -.91209 .45356 L -.94453 .43132 L -.98077 .41118 L -s -1 g -.98077 .89195 m -.94453 .91209 L -.91209 .94453 L -.89195 .98077 L -.98077 .98077 L -F -0 g -.98077 .89195 m -.94453 .91209 L -.91209 .94453 L -.89195 .98077 L -s -% End of Graphics -MathPictureEnd -\ -\>"], "Graphics", - ImageSize->{288, 288}, - ImageMargins->{{43, 0}, {0, 0}}, - ImageRegion->{{0, 1}, {0, 1}}, - ImageCache->GraphicsData["Bitmap", "\<\ -CF5dJ6E]HGAYHf4PAg9QL6QYHgon6Ykno_hn?S`2ook>c/mWIfGmoOol005E[;lC4a000<`00IP00V@00c000 -o`0c000c<`0cIP0cV@0cc00co`1V001V<`1VIP1VV@1Vc01Vo`2I002I<`2IIP2IV@2Ic02Io`3<003< -<`3I03>IIIS>IVC>Ic3>Ioc?<03?<@000`40000f00030@0000L00`4i0003 -0@0000@0000H00040@000CH000@1000120000`40000i00030@0003H000<100001`000`40000j0003 -0@0000<0000H00040@000CH000@1000120000`40000g00<1=P030@T000<10000=`00104000450000 -6@020CP00P4900@1>0000`40000f00030@0000L0104g00811P000?l08@0001D0o`4;0@40000E0003 -0@00008000<100002P000`40000900030@0000X000<100002P000`40000:00030@0000X000<10000 -2@000`40000:00030@0000X000<100002P000`40000900030@0000X000<100002P000`40000:0003 -0@0000T000<100002P000`40000:00030@0000X000<100002P000`40000900030@0000800@410000 -5@000`40000200030@0003d000<10000?@000`40000l00030@0003d000<100000P010@40000E0003 -0@000?l01`010@40000>00811@000`40003o00L00@4100003@001040004400816`000`4000080003 -0@0000H000<100001@000`40000500030@0000D000<1000010000`40000600030@0000D000<10000 -2@000`40000/00030@0000T000<100001@000`40000600030@0000D000<1000010000`4000050003 -0@0000D000<100001P000`40000900030@0001P00P4100003@001040004400030@0001T000d100P0 -200800P0200100P800T1Y`RW2:L8Y`401jL02@49Y`VW2JL90@062@0:0@UB2E89DPUB0@MB0P402e81 -DP5B0E81DP5B02l100aB0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@L900P12JL9Y`VW0@NW00T12:L8 -Y`RW204020P03P4800P0200800P020016P010@40000=00040@000@@000<100006@003@4800P02008 -00P0204020P02@48Y`RW2:L80@07Y`090JL9Y`VW2JL100H900X1DPUB2E89DPT11e80305B0E81DP5B -0E81DRl100]B0E81DP5B0E81DP020@MB00X1DPUB2E89DPT11`T0206W2JL9Y`T11jL02@6W2:L8Y`RW -0@08200>0@0800P0200800P0204J00410@0000d000@1000110000`40000H000>0@P0200800P02008 -004820090JL8Y`RW2:L100NW00T12JL9Y`VW2@401PT02P49DPUB2E89DP47DP8100]B0E81DP5B0E81 -DP0_0@0DP5B0E81DP5B0E81DP47DP0: -0@UB2E89DPUB0@P900P1Y`VW2JL90@NW00X1Y`RW2:L8Y`P120P0404800P0200800P02008004G0041 -0@0001D000<100005@004040200800P0200800P02048200:0@RW2:L8Y`RW0@NW00T12JL9Y`VW2@40 -1`T02P5B2E89DPUB2@47DP0@0E81DP5B0E81DP5B0E81DRL100eB0E81DP5B0E81DP5B00811e802P5B -2E89DPUB2@482@080@VW2JL9Y`47Y`0:0@RW2:L8Y`RW0@P8014100P0200800P0200800P00@0F0041 -0@0001D000<1000050004@40200800P0200800P0200100L800X12:L8Y`RW2:L11jL02P49Y`VW2JL9 -Y`472@0:0@UB2E89DPUB0@QB00h1DP5B0E81DP5B0E81DRL100eB0E81DP5B0E81DP5B008125802P49 -DPUB2E89DP472@0:0@VW2JL9Y`VW0@NW00X12:L8Y`RW2:L11`P04@4800P0200800P0200800P101H0 -0@4100005@000`40000C000B0@0800P0200800P0200800P11`P02P6W2:L8Y`RW2047Y`0:0JL9Y`VW -2JL90@L900X1DPUB2E89DPT125820@0=DP5B0E81DP5B0E81DP0U0@0@DP5B0E81DP5B0E81DP5B0@QB -00X1DPUB2E89DPT11`T02P6W2JL9Y`VW2@47Y`0:0JL8Y`RW2:L80@L8018100P0200800P0200800P0 -204E00410@0001D000<100004P004`40200800P0200800P0200800401`P02P48Y`RW2:L8Y`47Y`0: -0@VW2JL9Y`VW0@L900X12E89DPUB2E812580405B0E81DP5B0E81DP5B0E8U0@0=DP5B0E81DP5B0E81 -DP020@QB00X12E89DPUB2E811`T02P49Y`VW2JL9Y`47Y`0:0@RW2:L8Y`RW0@L801<1200800P02008 -00P0200800P101@00@4100005@020A8001@100P0200800P0200800P020080@L800X1Y`RW2:L8Y`P1 -1jL02P6W2JL9Y`VW2@472@0:0E89DPUB2E890@QB0P403e81DP5B0E81DP5B0E81DP0S0@0@DP5B0E81 -DP5B0E81DP5B0@QB00X1DPUB2E89DPT11`T02P6W2JL9Y`VW2@47Y`0:0JL8Y`RW2:L80@L801@100P0 -200800P0200800P020080A800P4100005@000`40000@000E0@0800P0200800P0200800P0200100L8 -00X12:L8Y`RW2:L11jL02P49Y`VW2JL9Y`472@0:0@UB2E89DPUB0@QB0181DP5B0E81DP5B0E81DP5B -0E8Q0@0?DP5B0E81DP5B0E81DP5B008125802P49DPUB2E89DP472@0:0@VW2JL9Y`VW0@NW00X12:L8 -Y`RW2:L11`P05@4800P0200800P0200800P020080@0B00410@0001D000<100004000504800P02008 -00P0200800P0200120P02P6W2:L8Y`RW2047Y`0:0JL9Y`VW2JL90@P900X12E89DPUB2E811e820@0? -DP5B0E81DP5B0E81DP5B0241019B0E81DP5B0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@P900X1Y`VW -2JL9Y`T11jL02P6W2:L8Y`RW2048200E0@P0200800P0200800P0200800P101400@4100005@000`40 -000?000E0@P0200800P0200800P0200800P100L800/1Y`RW2:L8Y`RW0@07Y`0:0@VW2JL9Y`VW0@P9 -00X1DPUB2E89DPT125820@0?DP5B0E81DP5B0E81DP5B01l1019B0E81DP5B0E81DP5B0E81DP48DP0: -0E89DPUB2E890@P900X12JL9Y`VW2JL11jL02`48Y`RW2:L8Y`P100L801H100P0200800P0200800P0 -200800P140010@40000E00030@0000h001H1200800P0200800P0200800P020011`P02`48Y`RW2:L8 -Y`P100NW00X1Y`VW2JL9Y`T120T02P49DPUB2E89DP48DP0B0E81DP5B0E81DP5B0E81DP5B7@404E81 -DP5B0E81DP5B0E81DP5B008125802P49DPUB2E89DP482@0:0JL9Y`VW2JL90@NW00/1Y`RW2:L8Y`RW -0@07200G0@P0200800P0200800P0200800P020403`010@40000E00030@0000d001L1200800P02008 -00P0200800P020080@07200;0JL8Y`RW2:L8Y`401jL02P49Y`VW2JL9Y`482@0:0E89DPUB2E890@QB -0P404E81DP5B0E81DP5B0E81DP5B01d1019B0E81DP5B0E81DP5B0E81DP48DP0:0E89DPUB2E890@P9 -00X12JL9Y`VW2JL11jL02`48Y`RW2:L8Y`P100L801P100P0200800P0200800P0200800P0204>0041 -0@0001D000<100002`020@0G200800P0200800P0200800P0200800401`P02`48Y`RW2:L8Y`P100NW -00X1Y`VW2JL9Y`T120T02P49DPUB2E89DP48DP0D0E81DP5B0E81DP5B0E81DP5B0E8K0@0ADP5B0E81 -DP5B0E81DP5B0E800P48DP0:0@UB2E89DPUB0@P900X1Y`VW2JL9Y`T11jL02`6W2:L8Y`RW2:L100L8 -01T1200800P0200800P0200800P0200800P100d00@4100005@000`400009008101P0200800P02008 -00P0200800P020080048200;0JL8Y`RW2:L8Y`401jL02P49Y`VW2JL9Y`482@0:0E89DPUB2E890@UB -01@1DP5B0E81DP5B0E81DP5B0E81DQL101=B0E81DP5B0E81DP5B0E81DP5B00812E802P5B2E89DPUB -2@482@0:0@VW2JL9Y`VW0@NW00/12:L8Y`RW2:L80@08200H0@P0200800P0200800P0200800P02008 -0P4;00410@0001D000<100001`020@0I200800P0200800P0200800P0200800P00@08200;0JL8Y`RW -2:L8Y`402:L02P6W2JL9Y`VW2@492@0:0E89DPUB2E890@UB01H1DP5B0E81DP5B0E81DP5B0E81DP5B -4`404e81DP5B0E81DP5B0E81DP5B0E800P49DP0:0E89DPUB2E890@T900X1Y`VW2JL9Y`T12:L02`48 -Y`RW2:L8Y`P100P801T1200800P0200800P0200800P0200800P000812@010@40000E00030@0000D0 -0P406P0800P0200800P0200800P0200800P020012@P02`48Y`RW2:L8Y`P100RW00X12JL9Y`VW2JL1 -2@T02P49DPUB2E89DP4:DP0H0E81DP5B0E81DP5B0E81DP5B0E81DP5B3@405E81DP5B0E81DP5B0E81 -DP5B0E81DP020@YB00X12E89DPUB2E812@T02P49Y`VW2JL9Y`48Y`0;0JL8Y`RW2:L8Y`402@P06P48 -00P0200800P0200800P0200800P020080P4700410@0001D000<100000`020@0K200800P0200800P0 -200800P0200800P0200100T800`12:L8Y`RW2:L8Y`48Y`0:0JL9Y`VW2JL90@T900/1DPUB2E89DPUB -0@0:DP0J0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E870@0GDP5B0E81DP5B0E81DP5B0E81DP5B0E80 -0P4:DP0;0@UB2E89DPUB2@402@T02P6W2JL9Y`VW2@49Y`0;0JL8Y`RW2:L8Y`402@P06`4800P02008 -00P0200800P0200800P0200800020@D00@4100005@000`400002000M0@0800P0200800P0200800P0 -200800P0200800402PP02`6W2:L8Y`RW2:L100VW00/12JL9Y`VW2JL90@092@0:0E89DPUB2E890@]B -01X1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DPD101MB0E81DP5B0E81DP5B0E81DP5B0E81DP020@]B -00X1DPUB2E89DPT12@T0306W2JL9Y`VW2JL90@RW00/12:L8Y`RW2:L80@0:200M0@P0200800P02008 -00P0200800P0200800P0204010010@40000E00030@0000<001/800P0200800P0200800P0200800P0 -200800402`P02`48Y`RW2:L8Y`P100VW00/1Y`VW2JL9Y`VW0@092@0:0@UB2E89DPUB0@aB03@1DP5B -0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0P4200;0@RW2:L8Y`RW20402ZL02`49Y`VW2JL9Y`T100X900X12E89DPUB2E81 -3U80;P5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E820@iB00X12E89 -DPUB2E812PT0306W2JL9Y`VW2JL90@ZW00X12:L8Y`RW2:L13PP05`40200800P0200800P0200800P0 -200800D00@4100005@000`400003000F200800P0200800P0200800P020080@h800`12:L8Y`RW2:L8 -Y`49Y`0<0@VW2JL9Y`VW2JL12PT02`5B2E89DPUB2E8100iB02`1DP5B0E81DP5B0E81DP5B0E81DP5B -0E81DP5B0E81DP5B0E81DP5B0E81DP813U802`49DPUB2E89DPT100X900`12JL9Y`VW2JL9Y`4:Y`0; -0JL8Y`RW2:L8Y`403PP05@40200800P0200800P0200800P0200600410@0001D000<100000P005PP0 -200800P0200800P0200800P0204?200;0JL8Y`RW2:L8Y`402ZL0306W2JL9Y`VW2JL90@/900X1DPUB -2E89DPT13e80:P5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP813e802P5B -2E89DPUB2@4;2@0<0JL9Y`VW2JL9Y`T12ZL02`48Y`RW2:L8Y`P100l801D100P0200800P0200800P0 -200800P01@010@40000E00030@0000<001@800P0200800P0200800P020080@l800`1Y`RW2:L8Y`RW -204:Y`0<0@VW2JL9Y`VW2JL12`T02`49DPUB2E89DPT100mB02P1DP5B0E81DP5B0E81DP5B0E81DP5B -0E81DP5B0E81DP5B0E81DP5B0P4?DP0;0E89DPUB2E89DP402`T03049Y`VW2JL9Y`VW0@^W00/12:L8 -Y`RW2:L80@0?200C0@0800P0200800P0200800P0200600410@0001D000<100000P0050P0200800P0 -200800P0200800P140P03048Y`RW2:L8Y`RW0@ZW00`1Y`VW2JL9Y`VW2@4;2@0;0E89DPUB2E89DP40 -45809P5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0P4@DP0;0@UB2E89DPUB2@40 -2`T0306W2JL9Y`VW2JL90@^W00/1Y`RW2:L8Y`RW0@0@200C0@0800P0200800P0200800P020050041 -0@0001D000<100000`003PP0200800P0200800P0104@200<0@RW2:L8Y`RW2:L12jL03@49Y`VW2JL9 -Y`VW2@402`T02`5B2E89DPUB2E81011B1@407E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00@1 -45802`49DPUB2E89DPT100/900h1Y`VW2JL9Y`VW2JL90@ZW00`12:L8Y`RW2:L8Y`4@20<100h02008 -00P0200800P020H00@4100005@000`4000020009200800P0200800H14`P03@48Y`RW2:L8Y`RW2040 -2jL03@6W2JL9Y`VW2JL9Y`402`T03049DPUB2E89DPUB0A=B1P404E81DP5B0E81DP5B0E81DP5B00L1 -4e803049DPUB2E89DPUB0@/900h12JL9Y`VW2JL9Y`VW0@^W00`12:L8Y`RW2:L8Y`4B20H100T800P0 -200800P01@010@40000E00030@0000<000<800401@4H200>0@RW2:L8Y`RW2:L8Y`4;Y`0=0@VW2JL9 -Y`VW2JL90@0;2@0=0E89DPUB2E89DPUB0@0HDPL100EB0E81DP060AQB00d12E89DPUB2E89DPT100/9 -00h1Y`VW2JL9Y`VW2JL90@^W00d1Y`RW2:L8Y`RW2:L101L81P400`08000500410@0001D000<10000 -0P030Ad800h12:L8Y`RW2:L8Y`RW0@bW00d1Y`VW2JL9Y`VW2JL100`900d1DPUB2E89DPUB2E8101eB -1P4MDP0=0@UB2E89DPUB2E890@0<2@0>0@VW2JL9Y`VW2JL9Y`42:L8Y`RW2:L8Y`RW2040@UB2E89DPUB2E89DPT20CQB0P403U89DPUB2E89DPUB2E813@T03P49 -Y`VW2JL9Y`VW2JL13JL03P48Y`RW2:L8Y`RW2:L80P4K20D00@4100005@020@<06@P30@0@2:L8Y`RW -2:L8Y`RW2:L80@fW00l1Y`VW2JL9Y`VW2JL9Y`403@T03`49DPUB2E89DPUB2E89DP030C9B0`403`UB -2E89DPUB2E89DPUB0@0=2@0@0@VW2JL9Y`VW2JL9Y`VW0@fW00l12:L8Y`RW2:L8Y`RW2:L00`4H20@0 -0P4100005@000`40000201H80`404PRW2:L8Y`RW2:L8Y`RW2:L80@jW00l12JL9Y`VW2JL9Y`VW2@40 -3PT04@49DPUB2E89DPUB2E89DPUB00<1;5830@0A2E89DPUB2E89DPUB2E89DP403PT0406W2JL9Y`VW -2JL9Y`VW2@4>Y`0A0@RW2:L8Y`RW2:L8Y`RW2:L00`4E20D00@4100005@000`40000201@80P404PRW -2:L8Y`RW2:L8Y`RW2:L8Y`813jL03`6W2JL9Y`VW2JL9Y`VW0@0?2@0C0@UB2E89DPUB2E89DPUB2E89 -DP020BQB0P404`UB2E89DPUB2E89DPUB2E89DP403`T04049Y`VW2JL9Y`VW2JL9Y`4?Y`0C0@RW2:L8 -Y`RW2:L8Y`RW2:L8Y`020A<81@010@40000E00030@0000803PP60@0DY`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`4AY`0@0@VW2JL9Y`VW2JL9Y`VW0@l901@12E89DPUB2E89DPUB2E89DPUB2@H175860@0DDPUB2E89 -DPUB2E89DPUB2E89DP4@2@0A0JL9Y`VW2JL9Y`VW2JL9Y`403jL05048Y`RW2:L8Y`RW2:L8Y`RW2:L8 -1P4=20D00@4100005@000`40000200D82@406@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`404JL04@49 -Y`VW2JL9Y`VW2JL9Y`T1010901T12E89DPUB2E89DPUB2E89DPUB2E89DPUB00X12E890@0I2E89DPUB -2E89DPUB2E89DPUB2E89DPUB0@0@2@0B0JL9Y`VW2JL9Y`VW2JL9Y`T14:L06@48Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L02@4420D00@4100005@000`40000200D10248Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`404ZL04@6W2JL9Y`VW2JL9Y`VW2JL1014902812E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E892@408@UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB0@0A2@0B0@VW2JL9 -Y`VW2JL9Y`VW2JL14JL08@48Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`050@@00@410000 -5@000`400002000S2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P00P4CY`0A0@VW2JL9 -Y`VW2JL9Y`VW2@404PT20@16DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2@814PT04P6W2JL9Y`VW2JL9Y`VW2JL90A:W0P408ZL8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P500410@0001D000<100000P008:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80`4DY`0C0@VW2JL9Y`VW2JL9Y`VW2JL90@0C2@<1041B2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -0`4C2@0D0JL9Y`VW2JL9Y`VW2JL9Y`VW2@4CY`<101nW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW00D00@4100005@000`400002000M2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P00`4GY`0C -0JL9Y`VW2JL9Y`VW2JL9Y`VW0@0F2@<103YB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E890`4F2@0D0@VW2JL9Y`VW2JL9Y`VW2JL9Y`4FY`<101bW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L81@010@40000E00030@00008001ZW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW20<16JL05@6W2JL9Y`VW2JL9Y`VW2JL9Y`VW0@0H2@<103AB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E890`4H2@0F0@VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW0ARW0`406JL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L01@010@40000E00030@00008001L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW20030A^W01L1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@0J2@<102iB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E890`4J2@0H0@VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL16ZL30@0FY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20D00@4100005@000`400002000D -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P30AfW01T1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL101`90`40:589 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT30A`901X12JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW0AbW0`404jL8Y`RW2:L8Y`RW2:L8Y`RW2:L01@010@40000E00030@00008000h8Y`RW -2:L8Y`RW2:L8Y`H17ZL20@0JY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4N2@H101`9DPUB2E89DPUB -2E89DPUB2E89DPUB2E89DPUB1P4N2@0L0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0AjW1P403@RW -2:L8Y`RW2:L8Y`P01@010@40000E00810`001JL8Y`RW00T18jL07P49Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW0B<92P402E89DPUB2E89DP090B<901h12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`4SY`T100@8Y`RW10020@40000E00030@0000801@4[Y`0P0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`4/2@T1:`T08049Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1:jL50@@00@410000 -5@000`40000202nW02812JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1GPT08P49Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4^Y`D00@4100005@000`40000202fW0P408PVW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL20EX90P408PVW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL20BbW1@010@40000E00030@000080:JL40@0VY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`T30E<910409ZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -0`4YY`D00@4100005@000`40000202JW0`40;@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2@040D`90`40;@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2@040BFW1@010@40000E00030@0000808:L60@0d2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`H1@0T60@0d2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`H17jL500410@0001D000<100000P0GY`T1042W2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -2@4^2@T1042W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL92@4FY`D00@4100005@000`40000201L105:W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -;P40DZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`TG0@@00@4100005@000`400002003oY`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW00D00@4100005@000`400002003o2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900D00@4100000P020@@000<10000 -0P030@D000<100000P00ojL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`0500410@000005004000402`000`4000020081 -0`00o`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2@0400810@000005004000402`000`40000200030@0000800?nW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL01@010@4000001@01000100P00`4500030@0000800?l9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T0 -1@010@4000001@01000100P000<100001@000`400002003oY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00D00@410000 -00D00@000@0800030@0000D000<100000P090@1^Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`TB0@1]Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`0:0@@00@4100000P020@T0104400030@0000802@T>0@1B2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`h14ZL>0@1B2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`d12@T500410@0001D000<10000 -0P0G2@T10409Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2@4^Y`T10409Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@4F2@D00@4100005@000`40000202091`40Y`D102P9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW1@4V2@D00@4100005@000`40000202`9 -0`408PVW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL30ERW0`408PVW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL30B/91@010@40000E00030@000080;`T08P49Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`5NY`0R0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0Bh9 -1@010@40000E00030@000080<0T08049Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1H:L08049 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1;`T500410@0001D000<100000P090BP901h12JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4XYa81::L07P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW0BL92P4400410@0001D00P4300092E89DPUB2E8900/17PT07049Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`4NY`/101:W2:L8Y`RW2:L8Y`RW2:L8Y`P;0AjW01`12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL17PT:0@092E89DPUB2E8900@00P4100005@000`400002000DDPUB2E89DPUB2E89DPUB2E89 -DPT30A`901/12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@406jL30@0XY`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20<16jL0706W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@4K2@<1 -01=B2E89DPUB2E89DPUB2E89DPUB00D00@4100005@000`400002000G2E89DPUB2E89DPUB2E89DPUB -2E89DPT00`4J2@0I0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@0IY`<102jW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80`4IY`0J0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2@4I2@<101IB2E89DPUB2E89DPUB2E89DPUB2E891@010@40000E00030@00008001YB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2@<160T05`49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T101NW0`40=:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P30ANW01P1Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2@4G2@<101UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB00D00@4100005@000`40 -0002000M2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT00`4F2@0E0@VW2JL9Y`VW2JL9Y`VW2JL9 -Y`T101FW0`40>ZL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`P30AFW01H1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T15@T30@0LDPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2@D00@4100005@000`400002000PDPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPT30A@901<12JL9Y`VW2JL9Y`VW2JL9Y`T101>W0`40@:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P30A>W01@1Y`VW2JL9Y`VW2JL9Y`VW -2JL90A<90`407e89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E801@010@40000E00030@000080 -02<9DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2@020A8901<1Y`VW2JL9Y`VW2JL9Y`VW -2JL1016W0P40AZL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P20A6W01@12JL9Y`VW2JL9Y`VW2JL9Y`VW0A490P408U89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT500410@0001D000<100000P030@0S2E89DPUB2E89DPUB -2E89DPUB2E89DPUB2E89DPUB2E89DP404PT04@6W2JL9Y`VW2JL9Y`VW2JL1016W02<12:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`060@0S2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L8Y`404JL04P49Y`VW2JL9Y`VW2JL9Y`VW0A4902812E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89104400410@0001D000<100000P03DPH101iB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DP4A2@0A0@VW2JL9Y`VW2JL9Y`VW2@404:L07P48Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20H1 -1PP60@0NY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L14:L04P6W2JL9Y`VW2JL9Y`VW2JL90A09 -01d12E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP060@=B1@010@40000E00030@0000802E860@0I -2E89DPUB2E89DPUB2E89DPUB2E89DPUB0@0@2@0A0JL9Y`VW2JL9Y`VW2JL9Y`403jL06@48Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L01P4B20H101T8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L100nW01812JL9 -Y`VW2JL9Y`VW2JL9Y`4?2@0H0@UB2E89DPUB2E89DPUB2E89DPUB2E891P49DPD00@4100005@000`40 -000200mB1@405@UB2E89DPUB2E89DPUB2E89DPUB0@0@2@0@0JL9Y`VW2JL9Y`VW2JL90@jW01D12:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L01@4N20D101D8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`403jL04@49Y`VW2JL9 -Y`VW2JL9Y`T100h901D12E89DPUB2E89DPUB2E89DPUB2E80104?DPD00@4100005@000`40000201AB -0P405589DPUB2E89DPUB2E89DPUB2E813`T03`49Y`VW2JL9Y`VW2JL90@0?Y`0C0JL8Y`RW2:L8Y`RW -2:L8Y`RW20020BP80P404jL8Y`RW2:L8Y`RW2:L8Y`RW20403jL0406W2JL9Y`VW2JL9Y`VW2@4?2@0C -0E89DPUB2E89DPUB2E89DPUB2@020A=B1@010@40000E00030@0000805U830@0BDPUB2E89DPUB2E89 -DPUB2E813PT03`6W2JL9Y`VW2JL9Y`VW0@0>Y`0A0JL8Y`RW2:L8Y`RW2:L8Y`P00`4/20<1016W2:L8 -Y`RW2:L8Y`RW2:L80@0>Y`0@0@VW2JL9Y`VW2JL9Y`VW0@h90141DPUB2E89DPUB2E89DPUB2@030AEB -1@010@40000E00810`0IDP<1011B2E89DPUB2E89DPUB2E813@T03`49Y`VW2JL9Y`VW2JL90@0=Y`0? -0JL8Y`RW2:L8Y`RW2:L800<10P20@0>2:L8Y`RW2:L8Y`RW -204=Y`0>0JL9Y`VW2JL9Y`VW2@4=2@0>0E89DPUB2E89DPUB2E820A]B1@010@40000E00030@000080 -7U820@0>DPUB2E89DPUB2E89DP4<2@0=0JL9Y`VW2JL9Y`VW0@0200^0@0800P0200800P0200800P0200800P0200800P0200800P0200800P020080@h8 -00X12:L8Y`RW2:L12jL03049Y`VW2JL9Y`VW0@X900/1DPUB2E89DPUB0@0>DP0F0E81DP5B0E81DP5B -0E81DP5B0E81DPD00@4100005@000`400002000F0E81DP5B0E81DP5B0E81DP5B0E81DP813E80305B -2E89DPUB2E890@T900`1Y`VW2JL9Y`VW2@4:Y`0;0@RW2:L8Y`RW20403@P0<040200800P0200800P0 -200800P0200800P0200800P0200800P0200800P020080@d800/1Y`RW2:L8Y`RW0@0:Y`0<0JL9Y`VW -2JL9Y`T12PT02`49DPUB2E89DPT100eB01L1DP5B0E81DP5B0E81DP5B0E81DP5B0@0500410@0001D0 -00<100000P005e81DP5B0E81DP5B0E81DP5B0E81DP5B00813E802`5B2E89DPUB2E8100X900/1Y`VW -2JL9Y`VW0@0:Y`0:0JL8Y`RW2:L80@d8038100P0200800P0200800P0200800P0200800P0200800P0 -200800P0200800P020080@d800X1Y`RW2:L8Y`P12ZL03049Y`VW2JL9Y`VW0@X900X1DPUB2E89DPT1 -3E80605B0E81DP5B0E81DP5B0E81DP5B0E81DPD00@4100005@000`400002000H0E81DP5B0E81DP5B -0E81DP5B0E81DP5B0P40@D00@4100005@000`4000020141 -00mB0E81DP5B0E81DP5B0E800P48DP0:0@UB2E89DPUB0@L900X12JL9Y`VW2JL12:L02P6W2:L8Y`RW -2047200B0@0800P0200800P0200800P180004P40200800P0200800P020080@L800X1Y`RW2:L8Y`P1 -2:L02P49Y`VW2JL9Y`472@0:0@UB2E89DPUB0@QB0181DP5B0E81DP5B0E81DP5B0E8?0@D00@410000 -5@020@<04P403e81DP5B0E81DP5B0E81DP020@MB00X1DPUB2E89DPT11`T02P6W2JL9Y`VW2@47Y`0: -0JL8Y`RW2:L80@P80141200800P0200800P020080@0R000A0@0800P0200800P02008004020P02P6W -2:L8Y`RW2047Y`0:0JL9Y`VW2JL90@L900X1DPUB2E89DPT11e80405B0E81DP5B0E81DP5B0E8B0@@0 -0P4100005@000`40000201<1011B0E81DP5B0E81DP5B0E811e802P49DPUB2E89DP472@0:0@VW2JL9 -Y`VW0@NW00X12:L8Y`RW2:L120P04040200800P0200800P0204T000@0@0800P0200800P020080@P8 -00X12:L8Y`RW2:L11jL02P49Y`VW2JL9Y`472@0:0@UB2E89DPUB0@MB0P403E81DP5B0E81DP5B0E80 -4`4500410@0001D000<100000P0D0@0=DP5B0E81DP5B0E81DP020@MB00X1DPUB2E89DPT11`T02P6W -2JL9Y`VW2@47Y`0:0JL8Y`RW2:L80@P80101200800P0200800P020019000404800P0200800P02008 -0048200:0JL8Y`RW2:L80@NW00X1Y`VW2JL9Y`T11`T02P5B2E89DPUB2@47DP0@0E81DP5B0E81DP5B -0E81DQ811@010@40000E00030@0000805@403U81DP5B0E81DP5B0E811e802P49DPUB2E89DP472@0: -0@VW2JL9Y`VW0@NW00X12:L8Y`RW2:L120P03`40200800P0200800P00@0V000?0@P0200800P02008 -00P100P800X12:L8Y`RW2:L11jL02P49Y`VW2JL9Y`472@0:0@UB2E89DPUB0@MB0P403E81DP5B0E81 -DP5B0E804`4500410@0001D000<100000P0F0@0;DP5B0E81DP5B0E800P48DP0:0@UB2E89DPUB0@L9 -00T12JL9Y`VW2@401jL02P6W2:L8Y`RW2048200?0@P0200800P0200800P102H0010100P0200800P0 -200800P11`P02P6W2:L8Y`RW2048Y`090@VW2JL9Y`T100L900X1DPUB2E89DPT11e803P5B0E81DP5B -0E81DP5B504500410@0001D000<100000P0E0@0>DP5B0E81DP5B0E81DP48DP0:0E89DPUB2E890@L9 -00T1Y`VW2JL9Y`401jL02P48Y`RW2:L8Y`47200?0@P0200800P0200800P102P000l100P0200800P0 -200800401`P02P48Y`RW2:L8Y`48Y`080JL9Y`VW2@472@0:0E89DPUB2E890@QB0P402e81DP5B0E81 -DP5B01D11@010@40000E00030@0000805P402e81DP5B0E81DP5B008125802P49DPUB2E89DP472@09 -0@VW2JL9Y`T100NW00X1Y`RW2:L8Y`P11`P03`40200800P0200800P00@0X000?0@P0200800P02008 -00P100L800X1Y`RW2:L8Y`P12:L02049Y`VW2JL11`T02P49DPUB2E89DP48DP0>0E81DP5B0E81DP5B -0E8D0@D00@4100005@000`40000201L100aB0E81DP5B0E81DP48DP0:0E89DPUB2E890@L900T1Y`VW -2JL9Y`401jL02P48Y`RW2:L8Y`47200?0@P0200800P0200800P102T000h1200800P0200800P00@L8 -00X12:L8Y`RW2:L12:L0206W2JL9Y`T11`T02P5B2E89DPUB2@48DP8100]B0E81DP5B0E81DP0E0@D0 -0@4100005@000`40000201P100UB0E81DP5B0E800P48DP0:0@UB2E89DPUB0@L900T12JL9Y`VW2@40 -1jL02P6W2:L8Y`RW2047200>0@0800P0200800P0204Z000>0@0800P0200800P02047200:0JL8Y`RW -2:L80@RW00P12JL9Y`VW0@L900X12E89DPUB2E812580305B0E81DP5B0E81DQH11@010@40000E0003 -0@0000805`402e81DP5B0E81DP5B00811e802P5B2E89DPUB2@472@090JL9Y`VW2JL100JW00X1Y`RW -2:L8Y`P120P03P4800P0200800P02001:P003P4800P0200800P0200120P02P6W2:L8Y`RW2047Y`08 -0JL9Y`VW2@472@0:0E89DPUB2E890@MB00h1DP5B0E81DP5B0E81DQD11@010@40000E00030@000080 -60403581DP5B0E81DP5B0@QB00T1DPUB2E89DP401`T02@49Y`VW2JL90@06Y`0:0@RW2:L8Y`RW0@P8 -00d100P0200800P0200102`000h1200800P0200800P00@L800X12:L8Y`RW2:L11jL02049Y`VW2JL1 -1`T02P49DPUB2E89DP47DP8100]B0E81DP5B0E81DP0F0@D00@4100005@000`40000201T100UB0E81 -DP5B0E800P48DP090@UB2E89DPT100L900T1Y`VW2JL9Y`401ZL02P6W2:L8Y`RW2047200>0@0800P0 -200800P0204/000>0@0800P0200800P02047200:0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900T1DPUB -2E89DP402580305B0E81DP5B0E81DQL11@010@40000=00@110000`40000201X100YB0E81DP5B0E81 -25802@5B2E89DPUB0@072@090@VW2JL9Y`T100JW00X12:L8Y`RW2:L11`P03@4800P0200800P02040 -;P003@40200800P0200800401`P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@090@UB2E89DPT100QB -0P402E81DP5B0E81DP0H0@D00@4100003`000`40000300810`0I0@09DP5B0E81DP5B008125802@49 -DPUB2E890@072@090JL9Y`VW2JL100JW00X1Y`RW2:L8Y`P11`P03@40200800P020080040;P003@48 -00P0200800P020401`P02P6W2:L8Y`RW2047Y`080JL9Y`VW2@472@090E89DPUB2E8100QB00`1DP5B -0E81DP5B0E8G0@@00P4100003`000`40000300030@0000806P402U81DP5B0E81DP48DP090E89DPUB -2E8100L900T12JL9Y`VW2@401ZL02P48Y`RW2:L8Y`47200=0@P0200800P020080@0^000=0@0800P0 -200800P00@07200:0@RW2:L8Y`RW0@NW00P12JL9Y`VW0@L900T12E89DPUB2@4025820@09DP5B0E81 -DP5B01P11@010@40000?00030@0000<000<100000P0I0@09DP5B0E81DP5B008125802@49DPUB2E89 -0@072@090JL9Y`VW2JL100JW00X1Y`RW2:L8Y`P11`P03P40200800P0200800P1;0003P40200800P0 -200800P11`P02P6W2:L8Y`RW2047Y`080JL9Y`VW2@472@090E89DPUB2E8100QB00`1DP5B0E81DP5B -0E8G0@D00@4100003`000`40000300030@00008060403581DP5B0E81DP5B0@QB00T1DPUB2E89DP40 -1`T02@49Y`VW2JL90@06Y`0:0@RW2:L8Y`RW0@P800d100P0200800P0200102`000h1200800P02008 -00P00@L800X12:L8Y`RW2:L11jL02049Y`VW2JL11`T02P49DPUB2E89DP47DP8100]B0E81DP5B0E81 -DP0F0@D00@4100003@030@D000<100000P0G0@0;DP5B0E81DP5B0E800P47DP0:0E89DPUB2E890@L9 -00T1Y`VW2JL9Y`401ZL02P6W2:L8Y`RW2048200>0@P0200800P02008004Z000>0@P0200800P02008 -0048200:0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900X1DPUB2E89DPT11e803P5B0E81DP5B0E81DP5B -5@4500410@0000l000<100000`000`40000201P100UB0E81DP5B0E800P48DP0:0@UB2E89DPUB0@L9 -00T12JL9Y`VW2@401jL02P6W2:L8Y`RW2047200>0@0800P0200800P0204Z000>0@0800P0200800P0 -2047200:0JL8Y`RW2:L80@RW00P12JL9Y`VW0@L900X12E89DPUB2E812580305B0E81DP5B0E81DQH1 -1@010@40000E00030@0000805`403581DP5B0E81DP5B0@QB00X1DPUB2E89DPT11`T02@6W2JL9Y`VW -0@07Y`0:0@RW2:L8Y`RW0@L800l1200800P0200800P02040:@003P4800P0200800P020011`P02P48 -Y`RW2:L8Y`48Y`080JL9Y`VW2@472@0:0E89DPUB2E890@QB0P402e81DP5B0E81DP5B01D11@010@40 -000E00030@0000805P402e81DP5B0E81DP5B008125802P49DPUB2E89DP472@090@VW2JL9Y`T100NW -00X1Y`RW2:L8Y`P11`P03`40200800P0200800P00@0X000?0@P0200800P0200800P100L800X1Y`RW -2:L8Y`P12:L02049Y`VW2JL11`T02P49DPUB2E89DP48DP0>0E81DP5B0E81DP5B0E8D0@D00@410000 -5@000`40000201D100iB0E81DP5B0E81DP5B0@QB00X1DPUB2E89DPT11`T02@6W2JL9Y`VW0@07Y`0: -0@RW2:L8Y`RW0@L800l1200800P0200800P02040:0003`40200800P0200800P00@07200:0@RW2:L8 -Y`RW0@RW00P1Y`VW2JL90@L900X1DPUB2E89DPT125820@0;DP5B0E81DP5B0E805@4500410@0001D0 -00<100000P0F0@0;DP5B0E81DP5B0E800P48DP0:0@UB2E89DPUB0@L900T12JL9Y`VW2@401jL02P6W -2:L8Y`RW2048200?0@P0200800P0200800P102H0010100P0200800P0200800P11`P02P6W2:L8Y`RW -2048Y`090@VW2JL9Y`T100L900X1DPUB2E89DPT11e803P5B0E81DP5B0E81DP5B504500410@0001D0 -00<100000P0E0@0>DP5B0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@L900X12JL9Y`VW2JL11jL02P48 -Y`RW2:L8Y`48200?0@0800P0200800P0200102H000l1200800P0200800P0204020P02P48Y`RW2:L8 -Y`47Y`0:0@VW2JL9Y`VW0@L900X12E89DPUB2E811e820@0=DP5B0E81DP5B0E81DP0C0@D00@410000 -5@000`40000201@100eB0E81DP5B0E81DP5B00811e802P5B2E89DPUB2@472@0:0JL9Y`VW2JL90@NW -00X1Y`RW2:L8Y`P120P0404800P0200800P02008004T000@0@P0200800P0200800P00@P800X1Y`RW -2:L8Y`P11jL02P6W2JL9Y`VW2@472@0:0E89DPUB2E890@MB0101DP5B0E81DP5B0E81DP5B4P450041 -0@0001D000<100000P0C0@0@DP5B0E81DP5B0E81DP5B0@MB00X12E89DPUB2E811`T02P49Y`VW2JL9 -Y`47Y`0:0@RW2:L8Y`RW0@P8010100P0200800P0200800P190004040200800P0200800P02048200: -0@RW2:L8Y`RW0@NW00X12JL9Y`VW2JL11`T02P49DPUB2E89DP47DP8100eB0E81DP5B0E81DP5B01<1 -1@010@40000E00810`0B0@0?DP5B0E81DP5B0E81DP5B00811e802P5B2E89DPUB2@472@0:0JL9Y`VW -2JL90@NW00X1Y`RW2:L8Y`P120P04@4800P0200800P0200800P10280014100P0200800P0200800P0 -0@08200:0JL8Y`RW2:L80@NW00X1Y`VW2JL9Y`T11`T02P5B2E89DPUB2@47DP0@0E81DP5B0E81DP5B -0E81DQ8110020@40000E00030@0000804@403e81DP5B0E81DP5B0E81DP020@QB00X12E89DPUB2E81 -1`T02P49Y`VW2JL9Y`48Y`0:0JL8Y`RW2:L80@L8018100P0200800P0200800P0204P000B0@0800P0 -200800P0200800P11`P02P6W2:L8Y`RW2048Y`0:0@VW2JL9Y`VW0@L900X12E89DPUB2E8125804P5B -0E81DP5B0E81DP5B0E81DPl11@010@40000E00030@00008040404U81DP5B0E81DP5B0E81DP5B0@QB -00X1DPUB2E89DPT11`T02P6W2JL9Y`VW2@48Y`0:0@RW2:L8Y`RW0@P8018100P0200800P0200800P0 -204N000C0@0800P0200800P0200800P00@07200:0@RW2:L8Y`RW0@RW00X1Y`VW2JL9Y`T11`T02`5B -2E89DPUB2E8100MB0P404E81DP5B0E81DP5B0E81DP5B00h11@010@40000E00030@0000803`404E81 -DP5B0E81DP5B0E81DP5B00811e802`5B2E89DPUB2E8100L900X12JL9Y`VW2JL12:L02P6W2:L8Y`RW -2048200C0@P0200800P0200800P020080@0L000C0@0800P0200800P0200800P00@08200:0JL8Y`RW -2:L80@RW00X12JL9Y`VW2JL11`T02`49DPUB2E89DPT100MB01@1DP5B0E81DP5B0E81DP5B0E81DPd1 -1@010@40000E00030@00008030405U81DP5B0E81DP5B0E81DP5B0E81DP47DP0;0@UB2E89DPUB2@40 -1`T02P6W2JL9Y`VW2@48Y`0:0@RW2:L8Y`RW0@P801@100P0200800P0200800P020080AX001@100P0 -200800P0200800P020080@P800X12:L8Y`RW2:L12:L02P6W2JL9Y`VW2@472@0;0E89DPUB2E89DP40 -1e820@0CDP5B0E81DP5B0E81DP5B0E81DP0<0@D00@4100005@000`40000200/101EB0E81DP5B0E81 -DP5B0E81DP5B0E800P47DP0;0E89DPUB2E89DP401`T02P49Y`VW2JL9Y`48Y`0:0JL8Y`RW2:L80@P8 -01@1200800P0200800P0200800P020815P020@0D00P0200800P0200800P020080048200:0JL8Y`RW -2:L80@RW00X12JL9Y`VW2JL11`T02`49DPUB2E89DPT100MB01P1DP5B0E81DP5B0E81DP5B0E81DP5B -0E890@D00@4100005@000`40000200X101EB0E81DP5B0E81DP5B0E81DP5B0E800P48DP0;0@UB2E89 -DPUB2@401`T02P6W2JL9Y`VW2@48Y`0:0@RW2:L8Y`RW0@T801D1200800P0200800P0200800P02000 -0P4B008101D800P0200800P0200800P0200800402@P02P48Y`RW2:L8Y`48Y`0:0JL9Y`VW2JL90@L9 -00/1DPUB2E89DPUB0@08DP0H0E81DP5B0E81DP5B0E81DP5B0E81DP5B204500410@0001D000<10000 -0P090@0EDP5B0E81DP5B0E81DP5B0E81DP5B008125802`49DPUB2E89DPT100P900X12JL9Y`VW2JL1 -2JL02P48Y`RW2:L8Y`49200F0@P0200800P0200800P0200800P020813P020@0F00P0200800P02008 -00P0200800P00@T800X12:L8Y`RW2:L12JL02P49Y`VW2JL9Y`482@0;0E89DPUB2E89DP402580605B -0E81DP5B0E81DP5B0E81DP5B0E81DPL11@010@40000E00030@0000801P405e81DP5B0E81DP5B0E81 -DP5B0E81DP5B00812E802`5B2E89DPUB2E8100P900X1Y`VW2JL9Y`T12JL02P6W2:L8Y`RW204:200G -0@P0200800P0200800P0200800P020000P4:008101L800P0200800P0200800P0200800P00@0:200: -0JL8Y`RW2:L80@VW00X1Y`VW2JL9Y`T120T02`49DPUB2E89DPT100UB01P1DP5B0E81DP5B0E81DP5B -0E81DP5B0E860@D00@4100005@000`40000200D101MB0E81DP5B0E81DP5B0E81DP5B0E81DP020@YB -00/12E89DPUB2E890@082@0:0@VW2JL9Y`VW0@VW00X12:L8Y`RW2:L12`P0604800P0200800P02008 -00P0200800P020811P020@0H00P0200800P0200800P0200800P020012`P02P48Y`RW2:L8Y`49Y`0: -0@VW2JL9Y`VW0@P900/1DPUB2E89DPUB0@0:DP0J0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E830@D0 -0@4100005@000`40000200@101MB0E81DP5B0E81DP5B0E81DP5B0E81DP020@YB00/12E89DPUB2E89 -0@092@0;0JL9Y`VW2JL9Y`402JL02P48Y`RW2:L8Y`4;200I0@P0200800P0200800P0200800P02008 -00020@800P406@P0200800P0200800P0200800P0200800402`P02P48Y`RW2:L8Y`49Y`0<0@VW2JL9 -Y`VW2JL120T02`5B2E89DPUB2E8100YB01X1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP811@010@40 -000E00030@00008001X1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP812e802`5B2E89DPUB2E8100T9 -00/12JL9Y`VW2JL90@09Y`0:0JL8Y`RW2:L80@`801X1200800P0200800P0200800P0200800P02081 -01X0200800P0200800P0200800P0200800P00@`800X1Y`RW2:L8Y`P12JL0306W2JL9Y`VW2JL90@P9 -00/12E89DPUB2E890@0;DP0J0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E820@@00@4100005@000`40 -0002000IDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@aB00/12E89DPUB2E890@092@0;0JL9Y`VW -2JL9Y`402JL02`48Y`RW2:L8Y`P100`803@1200800P0200800P0200800P0200800P0200800P02008 -00P0200800P0200800P020013@P02P48Y`RW2:L8Y`49Y`0<0@VW2JL9Y`VW2JL12@T02`49DPUB2E89 -DPT100]B01X1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DPD00@4100005@020@<001P1DP5B0E81DP5B -0E81DP5B0E81DP5B0E820@aB00/12E89DPUB2E890@0:2@0;0@VW2JL9Y`VW2@402ZL02P48Y`RW2:L8 -Y`4<200d0@0800P0200800P0200800P0200800P0200800P0200800P0200800P0200800P020080@`8 -00X12:L8Y`RW2:L12ZL0306W2JL9Y`VW2JL90@T900/1DPUB2E89DPUB0@0200; -0@RW2:L8Y`RW20402ZL03049Y`VW2JL9Y`VW0@X900/1DPUB2E89DPUB0@0>DP0F0E81DP5B0E81DP5B -0E81DP5B0E81DPD00@4100005@000`400002000D0E81DP5B0E81DP5B0E81DP5B0E820@mB00/1DPUB -2E89DPUB0@0:2@0<0JL9Y`VW2JL9Y`T12jL02P6W2:L8Y`RW204?200/0@0800P0200800P0200800P0 -200800P0200800P0200800P0200800P0204?200:0JL8Y`RW2:L80@^W00`1Y`VW2JL9Y`VW2@4:2@0; -0@UB2E89DPUB2@403e805@5B0E81DP5B0E81DP5B0E81DP5B0@0500410@0001D000<100000P004e81 -DP5B0E81DP5B0E81DP5B0E800P4?DP0<0E89DPUB2E89DPT12PT03049Y`VW2JL9Y`VW0@^W00/12:L8 -Y`RW2:L80@0?200Z0@0800P0200800P0200800P0200800P0200800P0200800P0200800P13`P02`6W -2:L8Y`RW2:L100^W00`12JL9Y`VW2JL9Y`4;2@0;0@UB2E89DPUB2@403e80505B0E81DP5B0E81DP5B -0E81DP5B1@010@40000E00030@0000800181DP5B0E81DP5B0E81DP5B0E820A1B00`12E89DPUB2E89 -DP4:2@0<0JL9Y`VW2JL9Y`T12jL02`6W2:L8Y`RW2:L1010802P100P0200800P0200800P0200800P0 -200800P0200800P0200800P140P02`48Y`RW2:L8Y`P100^W00`1Y`VW2JL9Y`VW2@4;2@0;0E89DPUB -2E89DP4045804`5B0E81DP5B0E81DP5B0E81DP401@010@40000E00030@00008000mB0E81DP5B0E81 -DP5B0E80104@DP0<0@UB2E89DPUB2E812`T03@49Y`VW2JL9Y`VW2@402jL02`6W2:L8Y`RW2:L10108 -10407PP0200800P0200800P0200800P0200800P0200800@140P02`48Y`RW2:L8Y`P100^W00h1Y`VW -2JL9Y`VW2JL90@/900/1DPUB2E89DPUB0@0@DP<100mB0E81DP5B0E81DP5B0E801@010@40000E0003 -0@00008000P1DP5B0E81DPL14e803@49DPUB2E89DPUB2@402`T03@6W2JL9Y`VW2JL9Y`402jL03048 -Y`RW2:L8Y`RW0A<81P404P0800P0200800P0200800P020H14`P03048Y`RW2:L8Y`RW0@^W00h12JL9 -Y`VW2JL9Y`VW0@/900`12E89DPUB2E89DP4BDPL100QB0E81DP5B0@D00@4100005@000`4000020003 -DP5B00H165803P49DPUB2E89DPUB2E812`T03@49Y`VW2JL9Y`VW2@402jL03@6W2:L8Y`RW2:L8Y`40 -60P60@06200800P01P4H200=0@RW2:L8Y`RW2:L80@0;Y`0>0JL9Y`VW2JL9Y`VW2@4;2@0=0E89DPUB -2E89DPUB0@0GDPH100=B0E801@010@40000E00030@0000800`4MDP0>0@UB2E89DPUB2E89DP4<2@0= -0JL9Y`VW2JL9Y`VW0@00@RW2:L8Y`RW2:L8 -Y`P20CP80P403ZL8Y`RW2:L8Y`RW2:L13JL03P49Y`VW2JL9Y`VW2JL13@T03P49DPUB2E89DPUB2E89 -0P4KDP@00P4100005@000`40000201UB0`4040UB2E89DPUB2E89DPUB2@4=2@0?0JL9Y`VW2JL9Y`VW -2JL100fW00l12:L8Y`RW2:L8Y`RW2:L00`4b20<100l8Y`RW2:L8Y`RW2:L8Y`403JL04049Y`VW2JL9 -Y`VW2JL9Y`4=2@0?0@UB2E89DPUB2E89DPUB00<1658500410@0001D000<100000P0FDP<10189DPUB -2E89DPUB2E89DPUB2@4>2@0?0@VW2JL9Y`VW2JL9Y`T100jW01412:L8Y`RW2:L8Y`RW2:L8Y`030B`8 -0`404@RW2:L8Y`RW2:L8Y`RW2:L100jW0101Y`VW2JL9Y`VW2JL9Y`T13PT04@49DPUB2E89DPUB2E89 -DPUB00<15E8500410@0001D000<100000P0DDP810189DPUB2E89DPUB2E89DPUB2E820@l900l1Y`VW -2JL9Y`VW2JL9Y`403jL04`48Y`RW2:L8Y`RW2:L8Y`RW2:L00P4X208101<8Y`RW2:L8Y`RW2:L8Y`RW -2:L100nW01012JL9Y`VW2JL9Y`VW2JL13`T04`49DPUB2E89DPUB2E89DPUB2E800P4CDPD00@410000 -5@000`40000200iB1P405589DPUB2E89DPUB2E89DPUB2E8140T04@6W2JL9Y`VW2JL9Y`VW2JL100nW -01@12:L8Y`RW2:L8Y`RW2:L8Y`RW20H170P60@0DY`RW2:L8Y`RW2:L8Y`RW2:L8Y`4?Y`0B0@VW2JL9 -Y`VW2JL9Y`VW2JL13`T05049DPUB2E89DPUB2E89DPUB2E891P4=DPD00@4100005@000`40000200EB -2@406@UB2E89DPUB2E89DPUB2E89DPUB2E89DP404@T04@49Y`VW2JL9Y`VW2JL9Y`T1012W01T12:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW00X12@P90@0I2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@0@Y`0B -0JL9Y`VW2JL9Y`VW2JL9Y`T140T06@49DPUB2E89DPUB2E89DPUB2E89DPUB2E802@44DPD00@410000 -5@000`40000200D10249DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP404PT04@6W2JL9Y`VW -2JL9Y`VW2JL1016W02812:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L82@408@RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@0AY`0B0@VW2JL9Y`VW2JL9Y`VW2JL14@T08@49DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP050@@00@4100005@000`400002000S2E89DPUB2E89DPUB -2E89DPUB2E89DPUB2E89DPUB2E89DPT00P4B2@0C0JL9Y`VW2JL9Y`VW2JL9Y`VW0@0AY`8104JW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L80P4AY`0D0@VW2JL9Y`VW2JL9Y`VW2JL9Y`4A2@81029B2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E891@010@40000E00030@000080021B2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2@<150T04`49Y`VW2JL9Y`VW2JL9Y`VW2@404jL30@10Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20<14jL0506W2JL9Y`VW2JL9Y`VW -2JL9Y`T14`T30@0ODPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP0500410@0001D000<10000 -0P007@UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E8900<15PT05@49Y`VW2JL9Y`VW2JL9Y`VW2JL9 -0@0EY`<103ZW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L80`4EY`0F0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90AD90`407589DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPT500410@0001D000<100000P006U89DPUB2E89DPUB2E89DPUB2E89DPUB2E890`4H2@0G -0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@405jL30@0dY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20<15jL0606W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90AL90`406E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E801@010@40000E00030@00008001L9DPUB2E89DPUB2E89DPUB -2E89DPUB2@030AX901T12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T101VW0`40;ZL8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P30AVW01X1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL90AT90`405U89DPUB2E89DPUB2E89DPUB2E89DPT500410@0001D000<100000P005589DPUB2E89 -DPUB2E89DPUB2E890`4L2@0K0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T101^W0`40::L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P30A^W01`1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`T16`T30@0CDPUB2E89DPUB2E89DPUB2E89DP0500410@0001D00P4300092E89DPUB2E8900/1 -7PT07049Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4NY`/101:W2:L8Y`RW2:L8Y`RW2:L8Y`P;0AjW -01`12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL17PT:0@092E89DPUB2E8900@00P4100005@000`40 -000200T1:0T07P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0BRW4P4XY`0N0@VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL19`T:0@@00@4100005@000`400002030902012JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW0F2W02012JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0Bl91@010@40 -000E00030@000080;`T08P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`5NY`0R0@VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0Bh91@010@40000E00030@000080;@T20@0R2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`81FZL20@0R2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`81;0T500410@0001D000<100000P0Y2@@102JW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2@<1DjL40@0VY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`T30BT91@010@40000E00030@0000809PT30@0]2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL900@1C:L30@0]2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL900@19@T500410@0001D000<100000P0P2@H103@9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW1P50Y`H103@9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW1P4O2@D00@4100005@000`40000201L92@40@:L9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`T90BjW2@40@:L9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`T90AH91@010@40000E00030@0000805`40DZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`T^0@1BY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2AL110010@40000E00030@0000800?nW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL01@010@40000E00030@0000800?l9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T01@010@4000000`010@020@<0 -00<100000P030@D000<100000P00ojL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`0500410@0000<000<100002P000`40 -000200810`00o`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@0400810@0000<000<100002P000`40000200030@000080 -0?nW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL01@010@40000300030@0000L00`4500030@0000800?l9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`T01@010@40000300030@0000L000<100001@000`400002003oY`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00D0 -0@41000000@00@412@000`40000500030@0000805`40DZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T^0@1B -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2AL110010@40000300030@0000L0104400030@0000805jL90@10 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2@T1;PT90@10Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2@T15ZL500410@0001D000<100000P0PY`H103@9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW1P502@H103@9Y`VW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW1P4OY`D00@4100005@000`40000202JW -0`40;@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@040D`90`40;@VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@040BFW1@010@40000E0003 -0@000080:JL40@0VY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T30E<910409ZL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90`4YY`D00@4100005@000`40000202fW -0P408PVW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL20EX90P408PVW2JL9Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL20BbW1@010@40000E00030@000080;jL08P49Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`5N2@0R0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0BjW -1@010@40000E00030@000080<:L08049Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1H0T08049 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1;jL500410@0001D000<100000P090BRW01h12JL9 -Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4X2A81:0T07P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW0BNW2P4400410@0001D00P4300092:L8Y`RW2:L800/17ZL07049Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL9Y`4N2@/1019B2E89DPUB2E89DPUB2E89DPT;0Ah901`12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 -Y`VW2JL17ZL:0@092:L8Y`RW2:L800@00P4100005@000`400002000DY`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`P30AbW01/12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@406`T30@0XDPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2@<16`T0706W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@4KY`<1 -01>W2:L8Y`RW2:L8Y`RW2:L8Y`RW00D00@4100005@000`400002000G2:L8Y`RW2:L8Y`RW2:L8Y`RW -2:L8Y`P00`4JY`0I0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@0I2@<102iB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E890`4I2@0J0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW -2@4IY`<101JW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L81@010@40000E00030@00008001ZW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW20<16:L05`49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T101L90`40=589DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT30AL901P1Y`VW2JL9Y`VW -2JL9Y`VW2JL9Y`VW2@4GY`<101VW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW00D00@4100005@000`40 -0002000M2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P00`4FY`0E0@VW2JL9Y`VW2JL9Y`VW2JL9 -Y`T101D90`40>U89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPT30AD901H1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T15JL30@0LY`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW20D00@4100005@000`400002000PY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 -Y`P30ABW01<12JL9Y`VW2JL9Y`VW2JL9Y`T101<90`40@589DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT30A<901@1Y`VW2JL9Y`VW2JL9Y`VW -2JL90A>W0`407jL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L01@010@40000E00030@000080 -02<8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20020A:W01<1Y`VW2JL9Y`VW2JL9Y`VW -2JL101490P40AU89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPT20A4901@12JL9Y`VW2JL9Y`VW2JL9Y`VW0A6W0P408ZL8Y`RW2:L8 -Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P500410@0001D000<100000P050@0Q2:L8Y`RW2:L8Y`RW -2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L101:W0141Y`VW2JL9Y`VW2JL9Y`VW0@0A2@0R0@UB2E89DPUB2E89 -DPUB2E89DPUB2E89DPUB2E89DPUB2@T10249DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP40 -4@T04P49Y`VW2JL9Y`VW2JL9Y`VW0A6W02412:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L0 -1@4400410@0001D000<100000P0520T101T8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L1016W01412JL9 -Y`VW2JL9Y`VW2JL90@0@2@0I0@UB2E89DPUB2E89DPUB2E89DPUB2E89DP0:0@UB2@406@UB2E89DPUB -2E89DPUB2E89DPUB2E89DP4040T04P6W2JL9Y`VW2JL9Y`VW2JL90A2W01T12:L8Y`RW2:L8Y`RW2:L8 -Y`RW2:L8Y`RW00T110P500410@0001D000<100000P0>20H101BW2:L8Y`RW2:L8Y`RW2:L8Y`RW0A2W -0141Y`VW2JL9Y`VW2JL9Y`VW0@0?2@0D0@UB2E89DPUB2E89DPUB2E89DPT60AaB1P405589DPUB2E89 -DPUB2E89DPUB2E813`T04P49Y`VW2JL9Y`VW2JL9Y`VW0@nW01@12:L8Y`RW2:L8Y`RW2:L8Y`RW20H1 -3@P500410@0001D000<100000P0D20810188Y`RW2:L8Y`RW2:L8Y`RW2:L20@nW00l1Y`VW2JL9Y`VW -2JL9Y`403`T04`49DPUB2E89DPUB2E89DPUB2E800P4XDP8101<9DPUB2E89DPUB2E89DPUB2E8100l9 -01012JL9Y`VW2JL9Y`VW2JL13jL04`48Y`RW2:L8Y`RW2:L8Y`RW2:L00P4C20D00@4100005@000`40 -000201H80`404PRW2:L8Y`RW2:L8Y`RW2:L80@jW00l12JL9Y`VW2JL9Y`VW2@403PT04@49DPUB2E89 -DPUB2E89DPUB00<1;5830@0A2E89DPUB2E89DPUB2E89DP403PT0406W2JL9Y`VW2JL9Y`VW2@4>Y`0A -0@RW2:L8Y`RW2:L8Y`RW2:L00`4E20D00@4100005@000`40000201T80`4040RW2:L8Y`RW2:L8Y`RW -204=Y`0?0JL9Y`VW2JL9Y`VW2JL100d900l12E89DPUB2E89DPUB2E800`4bDP<100l9DPUB2E89DPUB -2E89DP403@T04049Y`VW2JL9Y`VW2JL9Y`4=Y`0?0@RW2:L8Y`RW2:L8Y`RW00<160P500410@0001D0 -0P4301`80P403jL8Y`RW2:L8Y`RW2:L80@0=Y`0=0JL9Y`VW2JL9Y`VW0@0=2@0>0@UB2E89DPUB2E89 -DPT20CQB0P403U89DPUB2E89DPUB2E813@T03P49Y`VW2JL9Y`VW2JL13JL03P48Y`RW2:L8Y`RW2:L8 -0P4K20@00P4100005@000`40000201h80P403PRW2:L8Y`RW2:L8Y`P13:L03@49Y`VW2JL9Y`VW2@40 -30T03@49DPUB2E89DPUB2E800P4lDP8100d9DPUB2E89DPUB2E8100`900h1Y`VW2JL9Y`VW2JL90@bW -00d12:L8Y`RW2:L8Y`RW00817@P500410@0001D000<100000P030Ad800h12:L8Y`RW2:L8Y`RW0@bW -00d1Y`VW2JL9Y`VW2JL100`900d1DPUB2E89DPUB2E8101eB1P4MDP0=0@UB2E89DPUB2E890@0<2@0> -0@VW2JL9Y`VW2JL9Y`40@RW2:L8Y`RW2:L8Y`4;Y`0=0@VW2JL9Y`VW2JL90@0;2@0=0E89DPUB2E89DPUB0@0HDPL1 -00EB0E81DP060AQB00d12E89DPUB2E89DPT100/900h1Y`VW2JL9Y`VW2JL90@^W00d1Y`RW2:L8Y`RW -2:L101L81P400`08000500410@0001D000<100000P002@P0200800P020060A<800d12:L8Y`RW2:L8 -Y`P100^W00d1Y`VW2JL9Y`VW2JL100/900`12E89DPUB2E89DP4CDPH1015B0E81DP5B0E81DP5B0E81 -DP070A=B00`12E89DPUB2E89DP4;2@0>0@VW2JL9Y`VW2JL9Y`4;Y`0<0@RW2:L8Y`RW2:L14PP60@09 -200800P0200800D00@4100005@000`400003000>200800P0200800P020040A0800`12:L8Y`RW2:L8 -Y`4;Y`0=0@VW2JL9Y`VW2JL90@0;2@0;0E89DPUB2E89DP4045850@0MDP5B0E81DP5B0E81DP5B0E81 -DP5B0E81DP5B0E80104@DP0;0@UB2E89DPUB2@402`T03P6W2JL9Y`VW2JL9Y`T12jL02`6W2:L8Y`RW -2:L101080`403P0800P0200800P020081P010@40000E00030@00008001@800P0200800P0200800P0 -20080A0800`12:L8Y`RW2:L8Y`4:Y`0<0JL9Y`VW2JL9Y`T12`T02`5B2E89DPUB2E81011B02H1DP5B -0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP8145802`49DPUB2E89DPT100/900`1Y`VW -2JL9Y`VW2@4;Y`0;0JL8Y`RW2:L8Y`4040P04`40200800P0200800P0200800P01@010@40000E0003 -0@0000<001@800P0200800P0200800P020080@l800`1Y`RW2:L8Y`RW204:Y`0<0@VW2JL9Y`VW2JL1 -2`T02`49DPUB2E89DPT100mB02P1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B -0P4?DP0;0E89DPUB2E89DP402`T03049Y`VW2JL9Y`VW0@^W00/12:L8Y`RW2:L80@0?200C0@0800P0 -200800P0200800P0200600410@0001D000<100000P005PP0200800P0200800P0200800P0204?200; -0JL8Y`RW2:L8Y`402ZL0306W2JL9Y`VW2JL90@/900X1DPUB2E89DPT13e80:P5B0E81DP5B0E81DP5B -0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP813e802P5B2E89DPUB2@4;2@0<0JL9Y`VW2JL9Y`T1 -2ZL02`48Y`RW2:L8Y`P100l801D100P0200800P0200800P0200800P01@010@40000E00030@0000<0 -01H800P0200800P0200800P0200800P13PP03048Y`RW2:L8Y`RW0@VW00`12JL9Y`VW2JL9Y`4:2@0; -0E89DPUB2E89DP403U80;05B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B -0P4>DP0;0@UB2E89DPUB2@402PT03049Y`VW2JL9Y`VW0@ZW00/1Y`RW2:L8Y`RW0@0>200E0@0800P0 -200800P0200800P0200800H00@4100005@000`400002000H200800P0200800P0200800P0200800P1 -3@P0306W2:L8Y`RW2:L80@VW00`1Y`VW2JL9Y`VW2@4:2@0;0@UB2E89DPUB2@403E80;P5B0E81DP5B -0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E820@eB00/1DPUB2E89DPUB0@0:2@0< -0JL9Y`VW2JL9Y`T12ZL02`48Y`RW2:L8Y`P100d801L100P0200800P0200800P0200800P020050041 -0@0001D000<100000`0060P0200800P0200800P0200800P020080@d800/1Y`RW2:L8Y`RW0@0:Y`0; -0JL9Y`VW2JL9Y`402PT02P5B2E89DPUB2@4=DP0`0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B -0E81DP5B0E81DP5B0E81DP5B0P4=DP0:0E89DPUB2E890@X900`12JL9Y`VW2JL9Y`49Y`0;0@RW2:L8 -Y`RW20403@P05`40200800P0200800P0200800P0200800H00@4100005@020@<001X800P0200800P0 -200800P0200800P020080@`800/12:L8Y`RW2:L80@0:Y`0;0@VW2JL9Y`VW2@402PT02P49DPUB2E89 -DP4DP5B0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@P900P1Y`VW2JL90@NW00X1Y`RW -2:L8Y`P120P0404800P0200800P02008004G00410@0001D000<100005P003`4800P0200800P02008 -0@08200:0@RW2:L8Y`RW0@NW00T12JL9Y`VW2@401`T02P5B2E89DPUB2@47DP0>0E81DP5B0E81DP5B -0E8[0@0;DP5B0E81DP5B0E800P47DP0:0E89DPUB2E890@P900P12JL9Y`VW0@NW00X12:L8Y`RW2:L1 -20P04040200800P0200800P0204G00410@0001D000<100005P003`40200800P0200800P00@08200: -0JL8Y`RW2:L80@NW00T1Y`VW2JL9Y`401`T02P49DPUB2E89DP47DP8100]B0E81DP5B0E81DP0[0@0> -DP5B0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@P900P1Y`VW2JL90@NW00X1Y`RW2:L8Y`P120P03`48 -00P0200800P020080@0H00410@0001D000<100005`003P40200800P0200800P120P02P48Y`RW2:L8 -Y`47Y`090@VW2JL9Y`T100L900X1DPUB2E89DPT11e803P5B0E81DP5B0E81DP5B:`402e81DP5B0E81 -DP5B00811e802P5B2E89DPUB2@482@080@VW2JL9Y`47Y`0:0@RW2:L8Y`RW0@P800l100P0200800P0 -2008004060010@40000E00030@0001P000h100P0200800P020080@L800X1Y`RW2:L8Y`P11jL02@6W -2JL9Y`VW0@062@0:0E89DPUB2E890@QB0P402e81DP5B0E81DP5B02d100aB0E81DP5B0E81DP48DP0: -0E89DPUB2E890@L900P1Y`VW2JL90@NW00X1Y`RW2:L8Y`P11`P03`40200800P0200800P00@0I0041 -0@0001D000<1000060003P4800P0200800P0200120P02@6W2:L8Y`RW0@07Y`090@VW2JL9Y`T100H9 -00X12E89DPUB2E812580305B0E81DP5B0E81DRl100aB0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@L9 -00P12JL9Y`VW0@NW00X12:L8Y`RW2:L11`P03`4800P0200800P020080@0I00410@0001D000<10000 -6@003@4800P0200800P0204020P02@48Y`RW2:L80@07Y`090JL9Y`VW2JL100H900X1DPUB2E89DPT1 -1e80305B0E81DP5B0E81DRl100]B0E81DP5B0E81DP020@MB00X1DPUB2E89DPT11`T0206W2JL9Y`T1 -1jL02@6W2:L8Y`RW0@08200>0@0800P0200800P0204J00410@0000d0104400030@0001T000d100P0 -200800P0200100P800T1Y`RW2:L8Y`401jL02@49Y`VW2JL90@062@0:0@UB2E89DPUB0@MB0P402e81 -DP5B0E81DP5B02l100aB0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@L900P12JL9Y`VW0@NW00T12:L8 -Y`RW204020P03P4800P0200800P020016P010@40000=00030@0000D00P4K000<0@0800P0200800P1 -20P02@48Y`RW2:L80@07Y`090JL9Y`VW2JL100H900X1DPUB2E89DPT11e80305B0E81DP5B0E81DS41 -00UB0E81DP5B0E800P47DP0:0E89DPUB2E890@L900P1Y`VW2JL90@NW00T1Y`RW2:L8Y`4020P03@40 -200800P0200800406P020@40000>00030@0000@000<10000o`0700410@0000l000<100000`000`40 -003o00L00@41000040000`40000200030@00008000<10000?@000`40000m00030@0003`000<10000 -?@000`40000200410@0000d000@1000110000`40000200030@0000X000<100002@000`40000:0003 -0@0000X000<100002P000`40000:00030@0000T000<100002P000`40000:00030@0000X000<10000 -2@000`40000:00030@0000X000<100002P000`40000900030@0000X000<100002P000`40000:0003 -0@0000X000<100002@000`40000200410@0000h00P450?l12`410000o`0Q0000o`0Q0000o`0Q0000 -o`0Q0000\ -\>"], - ImageRangeCache->{{{0, 287}, {287, 0}} -> {-0.207, -0.172242, 0.00783272, - 0.00783272}}], - -Cell[BoxData[ - TagBox[\(\[SkeletonIndicator] ContourGraphics \[SkeletonIndicator]\), - False, - Editable->False]], "Output"] -}, Open ]] -}, Open ]] -}, Open ]] -}, -FrontEndVersion->"X 3.0", -ScreenRectangle->{{0, 1280}, {0, 1024}}, -WindowSize->{520, 600}, -WindowMargins->{{296, Automatic}, {Automatic, 88}}, -PrintingPageRange->{Automatic, Automatic}, -PrintingOptions->{"PaperSize"->{612, 792}, -"PaperOrientation"->"Portrait", -"Magnification"->1} -] - - -(*********************************************************************** -Cached data follows. If you edit this Notebook file directly, not using -Mathematica, you must remove the line containing CacheID at the top of -the file. The cache data will then be recreated when you save this file -from within Mathematica. -***********************************************************************) - -(*CellTagsOutline -CellTagsIndex->{} -*) - -(*CellTagsIndex -CellTagsIndex->{} -*) - -(*NotebookFileOutline -Notebook[{ - -Cell[CellGroupData[{ -Cell[1731, 51, 142, 4, 90, "Title"], - -Cell[CellGroupData[{ -Cell[1898, 59, 62, 0, 47, "Section"], - -Cell[CellGroupData[{ -Cell[1985, 63, 97, 2, 27, "Input"], -Cell[2085, 67, 102, 2, 37, "Output"] -}, Open ]], - -Cell[CellGroupData[{ -Cell[2224, 74, 89, 1, 27, "Input"], -Cell[2316, 77, 97, 2, 37, "Output"] -}, Open ]], - -Cell[CellGroupData[{ -Cell[2450, 84, 131, 3, 27, "Input"], -Cell[2584, 89, 125, 2, 47, "Output"] -}, Open ]], - -Cell[CellGroupData[{ -Cell[2746, 96, 89, 1, 27, "Input"], -Cell[2838, 99, 93, 1, 37, "Output"] -}, Open ]] -}, Open ]], - -Cell[CellGroupData[{ -Cell[2980, 106, 44, 0, 47, "Section"], - -Cell[CellGroupData[{ -Cell[3049, 110, 63, 1, 27, "Input"], -Cell[3115, 113, 38, 1, 27, "Output"] -}, Open ]], - -Cell[CellGroupData[{ -Cell[3190, 119, 173, 4, 43, "Input"], -Cell[3366, 125, 38, 1, 27, "Output"] -}, Open ]], - -Cell[CellGroupData[{ -Cell[3441, 131, 173, 4, 43, "Input"], -Cell[3617, 137, 38, 1, 27, "Output"] -}, Open ]], - -Cell[CellGroupData[{ -Cell[3692, 143, 145, 3, 43, "Input"], -Cell[3840, 148, 38, 1, 27, "Output"] -}, Open ]], - -Cell[CellGroupData[{ -Cell[3915, 154, 42, 1, 27, "Input"], -Cell[3960, 157, 35, 1, 27, "Output"] -}, Open ]], - -Cell[CellGroupData[{ -Cell[4032, 163, 71, 1, 27, "Input"], -Cell[4106, 166, 84568, 2080, 296, 16552, 1236, "GraphicsData", -"PostScript", "Graphics"], -Cell[88677, 2248, 137, 3, 27, "Output"] -}, Open ]], - -Cell[CellGroupData[{ -Cell[88851, 2256, 71, 1, 27, "Input"], -Cell[88925, 2259, 84885, 2084, 296, 16553, 1236, "GraphicsData", -"PostScript", "Graphics"], -Cell[173813, 4345, 137, 3, 27, "Output"] -}, Open ]], - -Cell[CellGroupData[{ -Cell[173987, 4353, 71, 1, 27, "Input"], -Cell[174061, 4356, 98250, 2756, 296, 24357, 1839, "GraphicsData", -"PostScript", "Graphics"], -Cell[272314, 7114, 137, 3, 27, "Output"] -}, Open ]], - -Cell[CellGroupData[{ -Cell[272488, 7122, 71, 1, 27, "Input"], -Cell[272562, 7125, 85515, 2207, 296, 17717, 1365, "GraphicsData", -"PostScript", "Graphics"], -Cell[358080, 9334, 137, 3, 27, "Output"] -}, Open ]] -}, Open ]] -}, Open ]] -} -] -*) - - - - -(*********************************************************************** -End of Mathematica Notebook file. -***********************************************************************) - +(*********************************************************************** + + Mathematica-Compatible Notebook + +This notebook can be used on any computer system with Mathematica 3.0, +MathReader 3.0, or any compatible application. The data for the notebook +starts with the line of stars above. + +To get the notebook into a Mathematica-compatible application, do one of +the following: + +* Save the data starting with the line of stars above into a file + with a name ending in .nb, then open the file inside the application; + +* Copy the data starting with the line of stars above to the + clipboard, then use the Paste menu command inside the application. + +Data for notebooks contains only printable 7-bit ASCII and can be +sent directly in email or through ftp in text mode. Newlines can be +CR, LF or CRLF (Unix, Macintosh or MS-DOS style). + +NOTE: If you modify the data for this notebook not in a Mathematica- +compatible application, you must delete the line below containing the +word CacheID, otherwise Mathematica-compatible applications may try to +use invalid cache data. + +For more information on notebooks and Mathematica-compatible +applications, contact Wolfram Research: + web: http://www.wolfram.com + email: info@wolfram.com + phone: +1-217-398-0700 (U.S.) + +Notebook reader applications are available free of charge from +Wolfram Research. +***********************************************************************) + +(*CacheID: 232*) + + +(*NotebookFileLineBreakTest +NotebookFileLineBreakTest*) +(*NotebookOptionsPosition[ 358257, 9342]*) +(*NotebookOutlinePosition[ 359033, 9369]*) +(* CellTagsIndexPosition[ 358989, 9365]*) +(*WindowFrame->Normal*) + + + +Notebook[{ + +Cell[CellGroupData[{ +Cell["\<\ +Evaluation of a 2-d Exact Solution for the Viscous, Incompressible \ +Navier-Stokes Equations\ +\>", "Title", + TextAlignment->Center], + +Cell[CellGroupData[{ + +Cell["Define Velocity, Pressure and Scalar Fields", "Section"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + \(u\ = \ \(-Cos[Pi\ x]\)\ Sin[Pi\ y]\ Exp[\(-2\)\ Pi^2\ nu\ t]\)], + "Input"], + +Cell[BoxData[ + \(\(-E\^\(\(-2\)\ nu\ \[Pi]\^2\ t\)\)\ Cos[\[Pi]\ x]\ Sin[\[Pi]\ y]\)], + "Output"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + \(v\ = \ Sin[Pi\ x]\ Cos[Pi\ y]\ Exp[\(-2\)\ Pi^2\ nu\ t]\)], "Input"], + +Cell[BoxData[ + \(E\^\(\(-2\)\ nu\ \[Pi]\^2\ t\)\ Cos[\[Pi]\ y]\ Sin[\[Pi]\ x]\)], + "Output"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + \(p\ = \ + \(-\ \((Cos[2\ Pi\ x]\ + \ Cos[2\ Pi\ y])\)\)/4\ + Exp[\(-4\)\ Pi^2\ nu\ t]\)], "Input"], + +Cell[BoxData[ + \(1\/4\ E\^\(\(-4\)\ nu\ \[Pi]\^2\ t\)\ + \((\(-Cos[2\ \[Pi]\ x]\) - Cos[2\ \[Pi]\ y])\)\)], "Output"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + \(Y\ = \ Cos[Pi\ x]\ Cos[Pi\ y] Exp[\(-\ 2\)\ Pi^2\ d\ t]\)], "Input"], + +Cell[BoxData[ + \(E\^\(\(-2\)\ d\ \[Pi]\^2\ t\)\ Cos[\[Pi]\ x]\ Cos[\[Pi]\ y]\)], "Output"] +}, Open ]] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Check Governing Equations", "Section"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + \(D[u, x]\ + \ D[v, y]\ == \ 0\)], "Input"], + +Cell[BoxData[ + \(True\)], "Output"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + \(Simplify[ + D[u, t]\ + \ u\ D[u, x]\ + \ v\ D[u, y]\ == \ + \(-\ D[p, x]\)\ + \ nu\ D[u, \ {x, 2}] + \ nu\ D[u, \ {y, 2}]]\)], + "Input"], + +Cell[BoxData[ + \(True\)], "Output"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + \(Simplify[ + D[v, t]\ + \ u\ D[v, x]\ + \ v\ D[v, y]\ == \ + \(-\ D[p, y]\)\ + \ nu\ D[v, \ {x, 2}] + \ nu\ D[v, \ {y, 2}]]\)], + "Input"], + +Cell[BoxData[ + \(True\)], "Output"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + \(Simplify[ + D[Y, t]\ + \ u\ D[Y, x]\ + \ v\ D[Y, y]\ == \ + d\ D[Y, {x, 2}]\ + \ d\ D[Y, {y, 2}]]\)], "Input"], + +Cell[BoxData[ + \(True\)], "Output"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + \(t\ = \ 0\)], "Input"], + +Cell[BoxData[ + \(0\)], "Output"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + \(ContourPlot[u, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"], + +Cell[GraphicsData["PostScript", "\<\ +%! +%%Creator: Mathematica +%%AspectRatio: 1 +MathPictureStart +/Mabs { +Mgmatrix idtransform +Mtmatrix dtransform +} bind def +/Mabsadd { Mabs +3 -1 roll add +3 1 roll add +exch } bind def +%% ContourGraphics +%%IncludeResource: font Courier +%%IncludeFont: Courier +/Courier findfont 10 scalefont setfont +% Scaling calculations +0.0192308 0.480769 0.0192308 0.480769 [ +[.01923 -0.0125 -3 -9 ] +[.01923 -0.0125 3 0 ] +[.25962 -0.0125 -9 -9 ] +[.25962 -0.0125 9 0 ] +[.5 -0.0125 -3 -9 ] +[.5 -0.0125 3 0 ] +[.74038 -0.0125 -9 -9 ] +[.74038 -0.0125 9 0 ] +[.98077 -0.0125 -3 -9 ] +[.98077 -0.0125 3 0 ] +[ 0 0 -0.125 0 ] +[-0.0125 .01923 -6 -4.5 ] +[-0.0125 .01923 0 4.5 ] +[-0.0125 .25962 -18 -4.5 ] +[-0.0125 .25962 0 4.5 ] +[-0.0125 .5 -6 -4.5 ] +[-0.0125 .5 0 4.5 ] +[-0.0125 .74038 -18 -4.5 ] +[-0.0125 .74038 0 4.5 ] +[-0.0125 .98077 -6 -4.5 ] +[-0.0125 .98077 0 4.5 ] +[ 0 0 -0.125 0 ] +[ 0 1 .125 0 ] +[ 1 0 .125 0 ] +[ 0 0 0 0 ] +[ 1 1 0 0 ] +] MathScale +% Start of Graphics +1 setlinecap +1 setlinejoin +newpath +0 g +.25 Mabswid +.01923 0 m +.01923 .00625 L +s +[(0)] .01923 -0.0125 0 1 Mshowa +.25962 0 m +.25962 .00625 L +s +[(0.5)] .25962 -0.0125 0 1 Mshowa +.5 0 m +.5 .00625 L +s +[(1)] .5 -0.0125 0 1 Mshowa +.74038 0 m +.74038 .00625 L +s +[(1.5)] .74038 -0.0125 0 1 Mshowa +.98077 0 m +.98077 .00625 L +s +[(2)] .98077 -0.0125 0 1 Mshowa +.125 Mabswid +.06731 0 m +.06731 .00375 L +s +.11538 0 m +.11538 .00375 L +s +.16346 0 m +.16346 .00375 L +s +.21154 0 m +.21154 .00375 L +s +.30769 0 m +.30769 .00375 L +s +.35577 0 m +.35577 .00375 L +s +.40385 0 m +.40385 .00375 L +s +.45192 0 m +.45192 .00375 L +s +.54808 0 m +.54808 .00375 L +s +.59615 0 m +.59615 .00375 L +s +.64423 0 m +.64423 .00375 L +s +.69231 0 m +.69231 .00375 L +s +.78846 0 m +.78846 .00375 L +s +.83654 0 m +.83654 .00375 L +s +.88462 0 m +.88462 .00375 L +s +.93269 0 m +.93269 .00375 L +s +.25 Mabswid +0 0 m +1 0 L +s +0 .01923 m +.00625 .01923 L +s +[(0)] -0.0125 .01923 1 0 Mshowa +0 .25962 m +.00625 .25962 L +s +[(0.5)] -0.0125 .25962 1 0 Mshowa +0 .5 m +.00625 .5 L +s +[(1)] -0.0125 .5 1 0 Mshowa +0 .74038 m +.00625 .74038 L +s +[(1.5)] -0.0125 .74038 1 0 Mshowa +0 .98077 m +.00625 .98077 L +s +[(2)] -0.0125 .98077 1 0 Mshowa +.125 Mabswid +0 .06731 m +.00375 .06731 L +s +0 .11538 m +.00375 .11538 L +s +0 .16346 m +.00375 .16346 L +s +0 .21154 m +.00375 .21154 L +s +0 .30769 m +.00375 .30769 L +s +0 .35577 m +.00375 .35577 L +s +0 .40385 m +.00375 .40385 L +s +0 .45192 m +.00375 .45192 L +s +0 .54808 m +.00375 .54808 L +s +0 .59615 m +.00375 .59615 L +s +0 .64423 m +.00375 .64423 L +s +0 .69231 m +.00375 .69231 L +s +0 .78846 m +.00375 .78846 L +s +0 .83654 m +.00375 .83654 L +s +0 .88462 m +.00375 .88462 L +s +0 .93269 m +.00375 .93269 L +s +.25 Mabswid +0 0 m +0 1 L +s +.01923 .99375 m +.01923 1 L +s +.25962 .99375 m +.25962 1 L +s +.5 .99375 m +.5 1 L +s +.74038 .99375 m +.74038 1 L +s +.98077 .99375 m +.98077 1 L +s +.125 Mabswid +.06731 .99625 m +.06731 1 L +s +.11538 .99625 m +.11538 1 L +s +.16346 .99625 m +.16346 1 L +s +.21154 .99625 m +.21154 1 L +s +.30769 .99625 m +.30769 1 L +s +.35577 .99625 m +.35577 1 L +s +.40385 .99625 m +.40385 1 L +s +.45192 .99625 m +.45192 1 L +s +.54808 .99625 m +.54808 1 L +s +.59615 .99625 m +.59615 1 L +s +.64423 .99625 m +.64423 1 L +s +.69231 .99625 m +.69231 1 L +s +.78846 .99625 m +.78846 1 L +s +.83654 .99625 m +.83654 1 L +s +.88462 .99625 m +.88462 1 L +s +.93269 .99625 m +.93269 1 L +s +.25 Mabswid +0 1 m +1 1 L +s +.99375 .01923 m +1 .01923 L +s +.99375 .25962 m +1 .25962 L +s +.99375 .5 m +1 .5 L +s +.99375 .74038 m +1 .74038 L +s +.99375 .98077 m +1 .98077 L +s +.125 Mabswid +.99625 .06731 m +1 .06731 L +s +.99625 .11538 m +1 .11538 L +s +.99625 .16346 m +1 .16346 L +s +.99625 .21154 m +1 .21154 L +s +.99625 .30769 m +1 .30769 L +s +.99625 .35577 m +1 .35577 L +s +.99625 .40385 m +1 .40385 L +s +.99625 .45192 m +1 .45192 L +s +.99625 .54808 m +1 .54808 L +s +.99625 .59615 m +1 .59615 L +s +.99625 .64423 m +1 .64423 L +s +.99625 .69231 m +1 .69231 L +s +.99625 .78846 m +1 .78846 L +s +.99625 .83654 m +1 .83654 L +s +.99625 .88462 m +1 .88462 L +s +.99625 .93269 m +1 .93269 L +s +.25 Mabswid +1 0 m +1 1 L +s +0 0 m +1 0 L +1 1 L +0 1 L +closepath +clip +newpath +.5 g +.01923 .98077 m +.98077 .98077 L +.98077 .01923 L +.01923 .01923 L +F +0 g +.5 Mabswid +.4 g +.01923 .48596 m +.08791 .4844 L +.15659 .47739 L +.22527 .43403 L +.22654 .43132 L +.24138 .36264 L +.24501 .29396 L +.24501 .22527 L +.24138 .15659 L +.22654 .08791 L +.22527 .0857 L +.15659 .04742 L +.08791 .03964 L +.01923 .03781 L +F +0 g +.01923 .48596 m +.08791 .4844 L +.15659 .47739 L +.22527 .43403 L +.22654 .43132 L +.24138 .36264 L +.24501 .29396 L +.24501 .22527 L +.24138 .15659 L +.22654 .08791 L +.22527 .0857 L +.15659 .04742 L +.08791 .03964 L +.01923 .03781 L +s +.6 g +.01923 .96219 m +.08791 .96036 L +.15659 .95258 L +.22527 .9143 L +.22654 .91209 L +.24138 .84341 L +.24501 .77473 L +.24501 .70604 L +.24138 .63736 L +.22654 .56868 L +.22527 .56597 L +.15659 .52261 L +.08791 .5156 L +.01923 .51404 L +F +0 g +.01923 .96219 m +.08791 .96036 L +.15659 .95258 L +.22527 .9143 L +.22654 .91209 L +.24138 .84341 L +.24501 .77473 L +.24501 .70604 L +.24138 .63736 L +.22654 .56868 L +.22527 .56597 L +.15659 .52261 L +.08791 .5156 L +.01923 .51404 L +s +.7 g +.01923 .93333 m +.08791 .92913 L +.15521 .91209 L +.15659 .91009 L +.20465 .84341 L +.21567 .77473 L +.21567 .70604 L +.20465 .63736 L +.15659 .57067 L +.15521 .56868 L +.08791 .54788 L +.01923 .54293 L +F +0 g +.01923 .93333 m +.08791 .92913 L +.15521 .91209 L +.15659 .91009 L +.20465 .84341 L +.21567 .77473 L +.21567 .70604 L +.20465 .63736 L +.15659 .57067 L +.15521 .56868 L +.08791 .54788 L +.01923 .54293 L +s +.3 g +.01923 .45707 m +.08791 .45212 L +.15521 .43132 L +.15659 .42933 L +.20465 .36264 L +.21567 .29396 L +.21567 .22527 L +.20465 .15659 L +.15659 .08991 L +.15521 .08791 L +.08791 .07087 L +.01923 .06667 L +F +0 g +.01923 .45707 m +.08791 .45212 L +.15521 .43132 L +.15659 .42933 L +.20465 .36264 L +.21567 .29396 L +.21567 .22527 L +.20465 .15659 L +.15659 .08991 L +.15521 .08791 L +.08791 .07087 L +.01923 .06667 L +s +.8 g +.01923 .90753 m +.08791 .8997 L +.15659 .85304 L +.16237 .84341 L +.18453 .77473 L +.18453 .70604 L +.16237 .63736 L +.15659 .62773 L +.08791 .58107 L +.01923 .57324 L +F +0 g +.01923 .90753 m +.08791 .8997 L +.15659 .85304 L +.16237 .84341 L +.18453 .77473 L +.18453 .70604 L +.16237 .63736 L +.15659 .62773 L +.08791 .58107 L +.01923 .57324 L +s +.2 g +.01923 .42676 m +.08791 .41893 L +.15659 .37227 L +.16237 .36264 L +.18453 .29396 L +.18453 .22527 L +.16237 .15659 L +.15659 .14696 L +.08791 .1003 L +.01923 .09247 L +F +0 g +.01923 .42676 m +.08791 .41893 L +.15659 .37227 L +.16237 .36264 L +.18453 .29396 L +.18453 .22527 L +.16237 .15659 L +.15659 .14696 L +.08791 .1003 L +.01923 .09247 L +s +.9 g +.01923 .87516 m +.08791 .85892 L +.11825 .84341 L +.15309 .77473 L +.15309 .70604 L +.11825 .63736 L +.08791 .62185 L +.01923 .60561 L +F +0 g +.01923 .87516 m +.08791 .85892 L +.11825 .84341 L +.15309 .77473 L +.15309 .70604 L +.11825 .63736 L +.08791 .62185 L +.01923 .60561 L +s +.1 g +.01923 .39439 m +.08791 .37815 L +.11825 .36264 L +.15309 .29396 L +.15309 .22527 L +.11825 .15659 L +.08791 .14108 L +.01923 .12484 L +F +0 g +.01923 .39439 m +.08791 .37815 L +.11825 .36264 L +.15309 .29396 L +.15309 .22527 L +.11825 .15659 L +.08791 .14108 L +.01923 .12484 L +s +1 g +.01923 .82869 m +.08791 .79783 L +.10805 .77473 L +.10805 .70604 L +.08791 .68294 L +.01923 .65208 L +F +0 g +.01923 .82869 m +.08791 .79783 L +.10805 .77473 L +.10805 .70604 L +.08791 .68294 L +.01923 .65208 L +s +.01923 .34792 m +.08791 .31706 L +.10805 .29396 L +.10805 .22527 L +.08791 .20217 L +.01923 .17131 L +F +.01923 .34792 m +.08791 .31706 L +.10805 .29396 L +.10805 .22527 L +.08791 .20217 L +.01923 .17131 L +s +.6 g +.29396 .0857 m +.36264 .04742 L +.43132 .03964 L +.5 .03781 L +.56868 .03964 L +.63736 .04742 L +.70604 .0857 L +.70731 .08791 L +.72215 .15659 L +.72578 .22527 L +.72578 .29396 L +.72215 .36264 L +.70731 .43132 L +.70604 .43403 L +.63736 .47739 L +.56868 .4844 L +.5 .48596 L +.43132 .4844 L +.36264 .47739 L +.29396 .43403 L +.29269 .43132 L +.27785 .36264 L +.27422 .29396 L +.27422 .22527 L +.27785 .15659 L +.29269 .08791 L +F +0 g +.29396 .0857 m +.36264 .04742 L +.43132 .03964 L +.5 .03781 L +.56868 .03964 L +.63736 .04742 L +.70604 .0857 L +.70731 .08791 L +.72215 .15659 L +.72578 .22527 L +.72578 .29396 L +.72215 .36264 L +.70731 .43132 L +.70604 .43403 L +.63736 .47739 L +.56868 .4844 L +.5 .48596 L +.43132 .4844 L +.36264 .47739 L +.29396 .43403 L +.29269 .43132 L +.27785 .36264 L +.27422 .29396 L +.27422 .22527 L +.27785 .15659 L +.29269 .08791 L +.29396 .0857 L +s +.4 g +.29396 .56597 m +.36264 .52261 L +.43132 .5156 L +.5 .51404 L +.56868 .5156 L +.63736 .52261 L +.70604 .56597 L +.70731 .56868 L +.72215 .63736 L +.72578 .70604 L +.72578 .77473 L +.72215 .84341 L +.70731 .91209 L +.70604 .9143 L +.63736 .95258 L +.56868 .96036 L +.5 .96219 L +.43132 .96036 L +.36264 .95258 L +.29396 .9143 L +.29269 .91209 L +.27785 .84341 L +.27422 .77473 L +.27422 .70604 L +.27785 .63736 L +.29269 .56868 L +F +0 g +.29396 .56597 m +.36264 .52261 L +.43132 .5156 L +.5 .51404 L +.56868 .5156 L +.63736 .52261 L +.70604 .56597 L +.70731 .56868 L +.72215 .63736 L +.72578 .70604 L +.72578 .77473 L +.72215 .84341 L +.70731 .91209 L +.70604 .9143 L +.63736 .95258 L +.56868 .96036 L +.5 .96219 L +.43132 .96036 L +.36264 .95258 L +.29396 .9143 L +.29269 .91209 L +.27785 .84341 L +.27422 .77473 L +.27422 .70604 L +.27785 .63736 L +.29269 .56868 L +.29396 .56597 L +s +.3 g +.43132 .54788 m +.5 .54293 L +.56868 .54788 L +.63598 .56868 L +.63736 .57067 L +.68542 .63736 L +.69644 .70604 L +.69644 .77473 L +.68542 .84341 L +.63736 .91009 L +.63598 .91209 L +.56868 .92913 L +.5 .93333 L +.43132 .92913 L +.36402 .91209 L +.36264 .91009 L +.31458 .84341 L +.30356 .77473 L +.30356 .70604 L +.31458 .63736 L +.36264 .57067 L +.36402 .56868 L +F +0 g +.43132 .54788 m +.5 .54293 L +.56868 .54788 L +.63598 .56868 L +.63736 .57067 L +.68542 .63736 L +.69644 .70604 L +.69644 .77473 L +.68542 .84341 L +.63736 .91009 L +.63598 .91209 L +.56868 .92913 L +.5 .93333 L +.43132 .92913 L +.36402 .91209 L +.36264 .91009 L +.31458 .84341 L +.30356 .77473 L +.30356 .70604 L +.31458 .63736 L +.36264 .57067 L +.36402 .56868 L +.43132 .54788 L +s +.7 g +.43132 .07087 m +.5 .06667 L +.56868 .07087 L +.63598 .08791 L +.63736 .08991 L +.68542 .15659 L +.69644 .22527 L +.69644 .29396 L +.68542 .36264 L +.63736 .42933 L +.63598 .43132 L +.56868 .45212 L +.5 .45707 L +.43132 .45212 L +.36402 .43132 L +.36264 .42933 L +.31458 .36264 L +.30356 .29396 L +.30356 .22527 L +.31458 .15659 L +.36264 .08991 L +.36402 .08791 L +F +0 g +.43132 .07087 m +.5 .06667 L +.56868 .07087 L +.63598 .08791 L +.63736 .08991 L +.68542 .15659 L +.69644 .22527 L +.69644 .29396 L +.68542 .36264 L +.63736 .42933 L +.63598 .43132 L +.56868 .45212 L +.5 .45707 L +.43132 .45212 L +.36402 .43132 L +.36264 .42933 L +.31458 .36264 L +.30356 .29396 L +.30356 .22527 L +.31458 .15659 L +.36264 .08991 L +.36402 .08791 L +.43132 .07087 L +s +.2 g +.36264 .62773 m +.43132 .58107 L +.5 .57324 L +.56868 .58107 L +.63736 .62773 L +.64314 .63736 L +.6653 .70604 L +.6653 .77473 L +.64314 .84341 L +.63736 .85304 L +.56868 .8997 L +.5 .90753 L +.43132 .8997 L +.36264 .85304 L +.35686 .84341 L +.3347 .77473 L +.3347 .70604 L +.35686 .63736 L +F +0 g +.36264 .62773 m +.43132 .58107 L +.5 .57324 L +.56868 .58107 L +.63736 .62773 L +.64314 .63736 L +.6653 .70604 L +.6653 .77473 L +.64314 .84341 L +.63736 .85304 L +.56868 .8997 L +.5 .90753 L +.43132 .8997 L +.36264 .85304 L +.35686 .84341 L +.3347 .77473 L +.3347 .70604 L +.35686 .63736 L +.36264 .62773 L +s +.8 g +.36264 .14696 m +.43132 .1003 L +.5 .09247 L +.56868 .1003 L +.63736 .14696 L +.64314 .15659 L +.6653 .22527 L +.6653 .29396 L +.64314 .36264 L +.63736 .37227 L +.56868 .41893 L +.5 .42676 L +.43132 .41893 L +.36264 .37227 L +.35686 .36264 L +.3347 .29396 L +.3347 .22527 L +.35686 .15659 L +F +0 g +.36264 .14696 m +.43132 .1003 L +.5 .09247 L +.56868 .1003 L +.63736 .14696 L +.64314 .15659 L +.6653 .22527 L +.6653 .29396 L +.64314 .36264 L +.63736 .37227 L +.56868 .41893 L +.5 .42676 L +.43132 .41893 L +.36264 .37227 L +.35686 .36264 L +.3347 .29396 L +.3347 .22527 L +.35686 .15659 L +.36264 .14696 L +s +.1 g +.43132 .62185 m +.5 .60561 L +.56868 .62185 L +.59902 .63736 L +.63386 .70604 L +.63386 .77473 L +.59902 .84341 L +.56868 .85892 L +.5 .87516 L +.43132 .85892 L +.40098 .84341 L +.36614 .77473 L +.36614 .70604 L +.40098 .63736 L +F +0 g +.43132 .62185 m +.5 .60561 L +.56868 .62185 L +.59902 .63736 L +.63386 .70604 L +.63386 .77473 L +.59902 .84341 L +.56868 .85892 L +.5 .87516 L +.43132 .85892 L +.40098 .84341 L +.36614 .77473 L +.36614 .70604 L +.40098 .63736 L +.43132 .62185 L +s +.9 g +.43132 .14108 m +.5 .12484 L +.56868 .14108 L +.59902 .15659 L +.63386 .22527 L +.63386 .29396 L +.59902 .36264 L +.56868 .37815 L +.5 .39439 L +.43132 .37815 L +.40098 .36264 L +.36614 .29396 L +.36614 .22527 L +.40098 .15659 L +F +0 g +.43132 .14108 m +.5 .12484 L +.56868 .14108 L +.59902 .15659 L +.63386 .22527 L +.63386 .29396 L +.59902 .36264 L +.56868 .37815 L +.5 .39439 L +.43132 .37815 L +.40098 .36264 L +.36614 .29396 L +.36614 .22527 L +.40098 .15659 L +.43132 .14108 L +s +.43132 .68294 m +.5 .65208 L +.56868 .68294 L +.58882 .70604 L +.58882 .77473 L +.56868 .79783 L +.5 .82869 L +.43132 .79783 L +.41118 .77473 L +.41118 .70604 L +F +.43132 .68294 m +.5 .65208 L +.56868 .68294 L +.58882 .70604 L +.58882 .77473 L +.56868 .79783 L +.5 .82869 L +.43132 .79783 L +.41118 .77473 L +.41118 .70604 L +.43132 .68294 L +s +1 g +.43132 .20217 m +.5 .17131 L +.56868 .20217 L +.58882 .22527 L +.58882 .29396 L +.56868 .31706 L +.5 .34792 L +.43132 .31706 L +.41118 .29396 L +.41118 .22527 L +F +0 g +.43132 .20217 m +.5 .17131 L +.56868 .20217 L +.58882 .22527 L +.58882 .29396 L +.56868 .31706 L +.5 .34792 L +.43132 .31706 L +.41118 .29396 L +.41118 .22527 L +.43132 .20217 L +s +.4 g +.98077 .48596 m +.91209 .4844 L +.84341 .47739 L +.77473 .43403 L +.77346 .43132 L +.75862 .36264 L +.75499 .29396 L +.75499 .22527 L +.75862 .15659 L +.77346 .08791 L +.77473 .0857 L +.84341 .04742 L +.91209 .03964 L +.98077 .03781 L +F +0 g +.98077 .48596 m +.91209 .4844 L +.84341 .47739 L +.77473 .43403 L +.77346 .43132 L +.75862 .36264 L +.75499 .29396 L +.75499 .22527 L +.75862 .15659 L +.77346 .08791 L +.77473 .0857 L +.84341 .04742 L +.91209 .03964 L +.98077 .03781 L +s +.6 g +.98077 .96219 m +.91209 .96036 L +.84341 .95258 L +.77473 .9143 L +.77346 .91209 L +.75862 .84341 L +.75499 .77473 L +.75499 .70604 L +.75862 .63736 L +.77346 .56868 L +.77473 .56597 L +.84341 .52261 L +.91209 .5156 L +.98077 .51404 L +F +0 g +.98077 .96219 m +.91209 .96036 L +.84341 .95258 L +.77473 .9143 L +.77346 .91209 L +.75862 .84341 L +.75499 .77473 L +.75499 .70604 L +.75862 .63736 L +.77346 .56868 L +.77473 .56597 L +.84341 .52261 L +.91209 .5156 L +.98077 .51404 L +s +.7 g +.98077 .93333 m +.91209 .92913 L +.84479 .91209 L +.84341 .91009 L +.79535 .84341 L +.78433 .77473 L +.78433 .70604 L +.79535 .63736 L +.84341 .57067 L +.84479 .56868 L +.91209 .54788 L +.98077 .54293 L +F +0 g +.98077 .93333 m +.91209 .92913 L +.84479 .91209 L +.84341 .91009 L +.79535 .84341 L +.78433 .77473 L +.78433 .70604 L +.79535 .63736 L +.84341 .57067 L +.84479 .56868 L +.91209 .54788 L +.98077 .54293 L +s +.3 g +.98077 .45707 m +.91209 .45212 L +.84479 .43132 L +.84341 .42933 L +.79535 .36264 L +.78433 .29396 L +.78433 .22527 L +.79535 .15659 L +.84341 .08991 L +.84479 .08791 L +.91209 .07087 L +.98077 .06667 L +F +0 g +.98077 .45707 m +.91209 .45212 L +.84479 .43132 L +.84341 .42933 L +.79535 .36264 L +.78433 .29396 L +.78433 .22527 L +.79535 .15659 L +.84341 .08991 L +.84479 .08791 L +.91209 .07087 L +.98077 .06667 L +s +.2 g +.98077 .42676 m +.91209 .41893 L +.84341 .37227 L +.83763 .36264 L +.81547 .29396 L +.81547 .22527 L +.83763 .15659 L +.84341 .14696 L +.91209 .1003 L +.98077 .09247 L +F +0 g +.98077 .42676 m +.91209 .41893 L +.84341 .37227 L +.83763 .36264 L +.81547 .29396 L +.81547 .22527 L +.83763 .15659 L +.84341 .14696 L +.91209 .1003 L +.98077 .09247 L +s +.8 g +.98077 .90753 m +.91209 .8997 L +.84341 .85304 L +.83763 .84341 L +.81547 .77473 L +.81547 .70604 L +.83763 .63736 L +.84341 .62773 L +.91209 .58107 L +.98077 .57324 L +F +0 g +.98077 .90753 m +.91209 .8997 L +.84341 .85304 L +.83763 .84341 L +.81547 .77473 L +.81547 .70604 L +.83763 .63736 L +.84341 .62773 L +.91209 .58107 L +.98077 .57324 L +s +.1 g +.98077 .39439 m +.91209 .37815 L +.88175 .36264 L +.84691 .29396 L +.84691 .22527 L +.88175 .15659 L +.91209 .14108 L +.98077 .12484 L +F +0 g +.98077 .39439 m +.91209 .37815 L +.88175 .36264 L +.84691 .29396 L +.84691 .22527 L +.88175 .15659 L +.91209 .14108 L +.98077 .12484 L +s +.9 g +.98077 .87516 m +.91209 .85892 L +.88175 .84341 L +.84691 .77473 L +.84691 .70604 L +.88175 .63736 L +.91209 .62185 L +.98077 .60561 L +F +0 g +.98077 .87516 m +.91209 .85892 L +.88175 .84341 L +.84691 .77473 L +.84691 .70604 L +.88175 .63736 L +.91209 .62185 L +.98077 .60561 L +s +1 g +.98077 .82869 m +.91209 .79783 L +.89195 .77473 L +.89195 .70604 L +.91209 .68294 L +.98077 .65208 L +F +0 g +.98077 .82869 m +.91209 .79783 L +.89195 .77473 L +.89195 .70604 L +.91209 .68294 L +.98077 .65208 L +s +.98077 .34792 m +.91209 .31706 L +.89195 .29396 L +.89195 .22527 L +.91209 .20217 L +.98077 .17131 L +F +.98077 .34792 m +.91209 .31706 L +.89195 .29396 L +.89195 .22527 L +.91209 .20217 L +.98077 .17131 L +s +% End of Graphics +MathPictureEnd +\ +\>"], "Graphics", + ImageSize->{288, 288}, + ImageMargins->{{43, 0}, {0, 0}}, + ImageRegion->{{0, 1}, {0, 1}}, + ImageCache->GraphicsData["Bitmap", "\<\ +CF5dJ6E]HGAYHf4PAg9QL6QYHgon6Ykno_hn?S`2ook>c/mWIfGmoOol005E[;lC4a000<`00IP00V@00c000 +o`0c000c<`0cIP0cV@0cc00co`1V001V<`1VIP1VV@1Vc01Vo`2I002I<`2IIP2IV@2Ic02Io`3<003< +<`3I03>IIIS>IVC>Ic3>Ioc?<03?<@000`40000f00030@0000L00`4i0003 +0@0000@0000H00040@000CH000@1000120000`40000i00030@0003H000<100001`000`40000j0003 +0@0000<0000H00040@000CH000@1000120000`40000g00<1=P030@T000<10000=`00104000450000 +6@020CP00P4900@1>0000`40000f00030@0000L0104g00811P000?l08@0001D0o`4;0@40000E0003 +0@00008000<100002P000`40000900030@0000X000<100002P000`40000:00030@0000X000<10000 +2@000`40000:00030@0000X000<100002P000`40000900030@0000X000<100002P000`40000:0003 +0@0000T000<100002P000`40000:00030@0000X000<100002P000`40000900030@0000800@410000 +5@000`40000200030@0003d000<10000?@000`40000l00030@0003d000<100000P010@40000E0003 +0@000?l01`010@40000>00811@000`40003o00L00@4100003@00104000440081o`0700810@0000d0 +00@1000110000`400002003oY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00D00@4100003@001040004400030@000080 +0?l9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`T01@010@40000=00040@000@@000<100000P00ojL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`0500410@0000d000@1000110000`400002003o2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900D00@4100003P020@D0 +00<100000P090@1^2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JLB0@1]2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@0:0@@0 +0@4100005@000`40000200T93P40DZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T>0A:W3P40DZL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`T=0@T91@010@40000E00030@0000805`T90@10Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@T1;ZL90@10Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@T1 +5PT500410@0001D000<100000P0P2@D103JW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T50D2W1@40=ZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@D17`T500410@0001D000<100000P0U2@810389Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`81BZL20@0b2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL20B@91@010@40000E00030@000080 +9`T20@0^Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@81CZL20@0^ +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@819PT500410@0001D0 +00<100000P0Y2@8102X9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL20E:W +0P40:PVW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`81:0T500410@0001D0 +00<100000P0[2@8102JW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@81EZL20@0V +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T20BX91@010@40000E00810`090B@9 +0P4090VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90BBW4P4TY`0V0JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@4S2@X10`020@40000E00030@00008000UB2E89DPUB2E80 +2`4K2@8101nW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00816ZL;0@0B2:L8Y`RW2:L8Y`RW +2:L8Y`RW2`4JY`810209Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`816PT:0@09DPUB2E89 +DPUB00D00@4100005@000`400002000D2E89DPUB2E89DPUB2E89DPUB2E840AT90P406`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2@020ARW1040:0RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L40ARW0P407:L9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T20AP910404`UB2E89DPUB +2E89DPUB2E89DPT01@010@40000E00030@00008001QB2E89DPUB2E89DPUB2E89DPUB2E89DPT30AP9 +0P405jL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00815ZL40@0`Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80`4GY`8101P9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL20AH9 +10405e89DPUB2E89DPUB2E89DPUB2E89DPUB00D00@4100005@000`400002000K2E89DPUB2E89DPUB +2E89DPUB2E89DPUB2E8900@15PT20@0C2JL9Y`VW2JL9Y`VW2JL9Y`VW2@020AFW0`40=`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P0104EY`8101BW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2@815@T30@0K2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E8900D00@410000 +5@000`400002000ODPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP040A@901<12JL9Y`VW2JL9 +Y`VW2JL9Y`T101>W1040?PRW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW104CY`0D0JL9Y`VW2JL9Y`VW2JL9Y`VW2@4C2@@101h9DPUB2E89DPUB +2E89DPUB2E89DPUB2E89DPUB2E8500410@0001D000<100000P008`UB2E89DPUB2E89DPUB2E89DPUB +2E89DPUB2E89DPUB2E8900814PT04`6W2JL9Y`VW2JL9Y`VW2JL9Y`404JL20@16Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2081 +4ZL04P6W2JL9Y`VW2JL9Y`VW2JL90A890P408U89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPT500410@0001D000<100000P050@0Q2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E810149 +01<12JL9Y`VW2JL9Y`VW2JL9Y`T1012W02812:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +2@408@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@0AY`0B0@VW2JL9Y`VW2JL9Y`VW2JL1 +4@T08@49DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP050@@00@4100005@000`40000200EB +2@4060UB2E89DPUB2E89DPUB2E89DPUB2E890A4901<1Y`VW2JL9Y`VW2JL9Y`VW2JL1012W01P1Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L:0@T82@4060RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80A6W0181Y`VW +2JL9Y`VW2JL9Y`VW2@4A2@0H0E89DPUB2E89DPUB2E89DPUB2E89DPUB2@44DPD00@4100005@000`40 +000200iB1@4050UB2E89DPUB2E89DPUB2E89DPT14@T04@6W2JL9Y`VW2JL9Y`VW2JL1012W01@1Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`D170P50@0D2:L8Y`RW2:L8Y`RW2:L8Y`RW204AY`0@0JL9Y`VW2JL9Y`VW +2JL90A4901@1DPUB2E89DPUB2E89DPUB2E89DPD13E8500410@0001D000<100000P0CDP8101=B2E89 +DPUB2E89DPUB2E89DPT1010901412JL9Y`VW2JL9Y`VW2JL90@0?Y`0C0JL8Y`RW2:L8Y`RW2:L8Y`RW +20020BH80P404jL8Y`RW2:L8Y`RW2:L8Y`RW20404:L04049Y`VW2JL9Y`VW2JL9Y`4@2@0C0E89DPUB +2E89DPUB2E89DPUB2@020A9B1@010@40000E00030@0000805E80505B2E89DPUB2E89DPUB2E89DPT1 +3`T04@6W2JL9Y`VW2JL9Y`VW2JL100jW01@1Y`RW2:L8Y`RW2:L8Y`RW2:L80BX801@1Y`RW2:L8Y`RW +2:L8Y`RW2:L80@nW0101Y`VW2JL9Y`VW2JL9Y`T13`T0505B2E89DPUB2E89DPUB2E89DPT155850041 +0@0001D000<100000P0FDP810149DPUB2E89DPUB2E89DPUB0@0?2@0A0@VW2JL9Y`VW2JL9Y`VW2@40 +3ZL04@48Y`RW2:L8Y`RW2:L8Y`RW0081;0P20@0A2:L8Y`RW2:L8Y`RW2:L8Y`403jL04049Y`VW2JL9 +Y`VW2JL9Y`4?2@0A0@UB2E89DPUB2E89DPUB2E800P4EDPD00@4100005@020@<065804P49DPUB2E89 +DPUB2E89DPUB0@l900l12JL9Y`VW2JL9Y`VW2@403ZL04P48Y`RW2:L8Y`RW2:L8Y`RW0C0801812:L8 +Y`RW2:L8Y`RW2:L8Y`4?Y`0>0@VW2JL9Y`VW2JL9Y`4?2@0B0@UB2E89DPUB2E89DPUB2E815e840081 +0@0001D000<100000P0IDP81011B2E89DPUB2E89DPUB2E813PT03`6W2JL9Y`VW2JL9Y`VW0@0=Y`0@ +0@RW2:L8Y`RW2:L8Y`RW20810JL8Y`RW2:L8Y`RW +2:L20AX81@4I208100h8Y`RW2:L8Y`RW2:L80@fW00h1Y`VW2JL9Y`VW2JL90@d900h1DPUB2E89DPUB +2E89DP816E830@@00@4100005@000`40000200030E8100@15e803`49DPUB2E89DPUB2E890@0<2@0? +0@VW2JL9Y`VW2JL9Y`T100^W00l1Y`RW2:L8Y`RW2:L8Y`405`P50@05200800P0104G200?0@RW2:L8 +Y`RW2:L8Y`P100bW00h12JL9Y`VW2JL9Y`VW0@`900l1DPUB2E89DPUB2E89DP405e840@03DP4000@0 +0@4100005@000`4000020007DP5B0E81DP050A=B0P403E89DPUB2E89DPUB2@4030T03@49Y`VW2JL9 +Y`VW2@402jL03@6W2:L8Y`RW2:L8Y`P00P4D20@100h800P0200800P0200800D14`P20@0=Y`RW2:L8 +Y`RW2:L80@0DP@100mB0E81DP5B0E81DP5B0E801@010@40000E00030@0000800181DP5B0E81DP5B +0E81DP5B0E830@mB00`12E89DPUB2E89DP4:2@0=0JL9Y`VW2JL9Y`VW0@09Y`0<0@RW2:L8Y`RW2:L1 +3PP20@0W200800P0200800P0200800P0200800P0200800P0200800P0200800813`P03048Y`RW2:L8 +Y`RW0@ZW00`1Y`VW2JL9Y`VW2@4:2@0<0@UB2E89DPUB2E813U830@0BDP5B0E81DP5B0E81DP5B0E81 +1@010@40000E00030@00008001EB0E81DP5B0E81DP5B0E81DP5B0E800P4>DP0<0@UB2E89DPUB2E81 +2PT02`6W2JL9Y`VW2JL100VW00d12:L8Y`RW2:L8Y`P100`80P40:`0800P0200800P0200800P02008 +00P0200800P0200800P0200800P020000P4>200<0@RW2:L8Y`RW2:L12ZL02P6W2JL9Y`VW2@4:2@0< +0@UB2E89DPUB2E813E820@0EDP5B0E81DP5B0E81DP5B0E81DP5B00D00@4100005@000`400002000F +0E81DP5B0E81DP5B0E81DP5B0E81DP<13580305B2E89DPUB2E890@X900/12JL9Y`VW2JL90@09Y`0< +0JL8Y`RW2:L8Y`P12`P20@0_200800P0200800P0200800P0200800P0200800P0200800P0200800P0 +200800P00P4<200<0JL8Y`RW2:L8Y`P12ZL02P49Y`VW2JL9Y`4:2@0<0E89DPUB2E89DPT12e830@0F +DP5B0E81DP5B0E81DP5B0E81DP5B0@D00@4100005@000`400002000IDP5B0E81DP5B0E81DP5B0E81 +DP5B0E81DP020@]B00`1DPUB2E89DPUB2@492@0;0JL9Y`VW2JL9Y`402:L03@6W2:L8Y`RW2:L8Y`40 +2PP0=040200800P0200800P0200800P0200800P0200800P0200800P0200800P0200800P020020@/8 +00`1Y`RW2:L8Y`RW2049Y`0:0JL9Y`VW2JL90@T900`1DPUB2E89DPUB2@4;DP0J0E81DP5B0E81DP5B +0E81DP5B0E81DP5B0E8500410@0001D000<100000P006P5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B +0P4:DP0<0@UB2E89DPUB2E812@T02`49Y`VW2JL9Y`T100RW00d12:L8Y`RW2:L8Y`P100X803L12008 +00P0200800P0200800P0200800P0200800P0200800P0200800P0200800P0200800P100X800`12:L8 +Y`RW2:L8Y`49Y`0:0@VW2JL9Y`VW0@T900`12E89DPUB2E89DP4;DP8101QB0E81DP5B0E81DP5B0E81 +DP5B0E81DP4500410@0001D00P43000LDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0@]B00/12E89 +DPUB2E890@092@0;0JL9Y`VW2JL9Y`402:L0306W2:L8Y`RW2:L80@X803P1200800P0200800P02008 +00P0200800P0200800P0200800P0200800P0200800P0200800P00@/800/12:L8Y`RW2:L80@09Y`0: +0JL9Y`VW2JL90@T900/1DPUB2E89DPUB0@0;DP8101UB0E81DP5B0E81DP5B0E81DP5B0E81DP5B00@0 +0P4100005@000`400002000M0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP402U80305B2E89DPUB +2E890@P900/12JL9Y`VW2JL90@08Y`0<0@RW2:L8Y`RW2:L12PP0>@40200800P0200800P0200800P0 +200800P0200800P0200800P0200800P0200800P0200800P00@0:200<0JL8Y`RW2:L8Y`P12:L02P49 +Y`VW2JL9Y`492@0;0@UB2E89DPUB2@402e806`5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0@050041 +0@0001D000<100000P020@0IDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@YB00`12E89DPUB2E89 +DP482@0;0JL9Y`VW2JL9Y`401jL03@48Y`RW2:L8Y`RW20402@P07040200800P0200800P0200800P0 +200800P020030@0K00P0200800P0200800P0200800P0200800P100X800`12:L8Y`RW2:L8Y`48Y`0: +0JL9Y`VW2JL90@P900`12E89DPUB2E89DP4:DP0J0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E830@@0 +0@4100005@000`40000200D101MB0E81DP5B0E81DP5B0E81DP5B0E81DP020@YB00/12E89DPUB2E89 +0@082@0;0@VW2JL9Y`VW2@401jL0306W2:L8Y`RW2:L80@X801X1200800P0200800P0200800P02008 +00P020810`020@0J200800P0200800P0200800P0200800P02049200<0JL8Y`RW2:L8Y`P12:L02P49 +Y`VW2JL9Y`482@0;0E89DPUB2E89DP402e820@0GDP5B0E81DP5B0E81DP5B0E81DP5B0E800`450041 +0@0001D000<100000P060@0HDP5B0E81DP5B0E81DP5B0E81DP5B0E812U802`5B2E89DPUB2E8100P9 +00/1Y`VW2JL9Y`VW0@07Y`0<0@RW2:L8Y`RW2:L12@P06@4800P0200800P0200800P0200800P02000 +0P47008101P0200800P0200800P0200800P02008004:200;0JL8Y`RW2:L8Y`402:L02P6W2JL9Y`VW +2@482@0;0@UB2E89DPUB2@402U820@0EDP5B0E81DP5B0E81DP5B0E81DP5B00H11@010@40000E0003 +0@0000802@405U81DP5B0E81DP5B0E81DP5B0E81DP49DP0;0@UB2E89DPUB2@4020T02`49Y`VW2JL9 +Y`T100NW00`1Y`RW2:L8Y`RW2049200F0@0800P0200800P0200800P0200800<12`020@0G200800P0 +200800P0200800P0200800402@P02`48Y`RW2:L8Y`P100RW00X12JL9Y`VW2JL120T02`5B2E89DPUB +2E8100YB01H1DP5B0E81DP5B0E81DP5B0E81DP5B1`4500410@0001D000<100000P0<0@0ADP5B0E81 +DP5B0E81DP5B0E800P4:DP0:0@UB2E89DPUB0@P900/1Y`VW2JL9Y`VW0@07Y`0;0@RW2:L8Y`RW2040 +2@P05@40200800P0200800P0200800P020020A000`4050P0200800P0200800P0200800P12@P02`6W +2:L8Y`RW2:L100RW00X1Y`VW2JL9Y`T120T02P49DPUB2E89DP4:DP0D0E81DP5B0E81DP5B0E81DP5B +0E8:0@D00@4100005@000`40000200d1015B0E81DP5B0E81DP5B0E81DP020@UB00/1DPUB2E89DPUB +0@082@0:0JL9Y`VW2JL90@NW00/1Y`RW2:L8Y`RW0@09200B0@P0200800P0200800P020080`4E0081 +01<0200800P0200800P0200800P100T800/1Y`RW2:L8Y`RW0@08Y`090JL9Y`VW2JL100P900X1DPUB +2E89DPT12U820@0?DP5B0E81DP5B0E81DP5B00d11@010@40000E00030@00008040404581DP5B0E81 +DP5B0E81DP49DP0;0@UB2E89DPUB2@4020T02@49Y`VW2JL90@07Y`0<0JL8Y`RW2:L8Y`P120P04@48 +00P0200800P0200800P000816P020@0A200800P0200800P0200800402@P02`48Y`RW2:L8Y`P100RW +00P12JL9Y`VW0@P900/1DPUB2E89DPUB0@09DP8100mB0E81DP5B0E81DP5B0E803P4500410@0001D0 +00<100000P0A0@0@DP5B0E81DP5B0E81DP5B0@UB00X12E89DPUB2E8120T02@6W2JL9Y`VW0@07Y`0; +0@RW2:L8Y`RW20402@P03`40200800P0200800P020020Ah00P40400800P0200800P020080048200; +0JL8Y`RW2:L8Y`402:L0206W2JL9Y`T120T02P49DPUB2E89DP4:DP0>0E81DP5B0E81DP5B0E8A0@D0 +0@4100005@000`40000201@100]B0E81DP5B0E81DP020@UB00X1DPUB2E89DPT120T02@49Y`VW2JL9 +0@07Y`0;0JL8Y`RW2:L8Y`4020P03P40200800P0200800P00P4R008100h800P0200800P020080@P8 +00/12:L8Y`RW2:L80@08Y`080@VW2JL9Y`482@0:0E89DPUB2E890@UB00h1DP5B0E81DP5B0E81DQ81 +1@010@40000E00030@0000805@402e81DP5B0E81DP5B008125802P49DPUB2E89DP482@090JL9Y`VW +2JL100NW00/12:L8Y`RW2:L80@08200>0@P0200800P02008004V000?0@P0200800P0200800P100P8 +00X12:L8Y`RW2:L12:L0206W2JL9Y`T120T02P49DPUB2E89DP49DP8100]B0E81DP5B0E81DP0C0@D0 +0@4100005@000`40000201H100aB0E81DP5B0E81DP49DP090@UB2E89DPT100P900T12JL9Y`VW2@40 +1jL02P6W2:L8Y`RW2048200>0@P0200800P02008004X000>0@P0200800P020080048200:0JL8Y`RW +2:L80@RW00P12JL9Y`VW0@P900T1DPUB2E89DP402E820@0;DP5B0E81DP5B0E80504500410@0001D0 +0P4301L100aB0E81DP5B0E81DP48DP0:0E89DPUB2E890@L900T1Y`VW2JL9Y`401jL02P48Y`RW2:L8 +Y`48200>0@0800P0200800P0204Y000>0@P0200800P020080047200;0@RW2:L8Y`RW20401jL0206W +2JL9Y`T120T02@49DPUB2E890@09DP0<0E81DP5B0E81DP5B5@4400810@0001D000<100000P0H0@09 +DP5B0E81DP5B008125802P49DPUB2E89DP472@090@VW2JL9Y`T100JW00/12:L8Y`RW2:L80@07200> +0@0800P0200800P0204Z000>0@0800P0200800P02047200;0JL8Y`RW2:L8Y`401jL02049Y`VW2JL1 +1`T02P49DPUB2E89DP48DP0<0E81DP5B0E81DP5B5P4500410@0001D000<100000P0I0@09DP5B0E81 +DP5B008125802@49DPUB2E890@072@090JL9Y`VW2JL100JW00X1Y`RW2:L8Y`P120P03@4800P02008 +00P02040;0003P40200800P0200800P11`P02P6W2:L8Y`RW2047Y`080JL9Y`VW2@472@090E89DPUB +2E8100UB0P402E81DP5B0E81DP0G0@D00@4100005@000`40000201X100YB0E81DP5B0E8125802@5B +2E89DPUB0@072@090@VW2JL9Y`T100JW00X12:L8Y`RW2:L11`P03@4800P0200800P02040;P003@40 +200800P0200800401`P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@090@UB2E89DPT100QB0P402E81 +DP5B0E81DP0H0@D00@4100005@000`40000201T100UB0E81DP5B0E800P48DP090@UB2E89DPT100L9 +00T1Y`VW2JL9Y`401ZL02P6W2:L8Y`RW2047200=0@0800P0200800P00@0^000=0@P0200800P02008 +0@07200:0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900T1DPUB2E89DP402580305B0E81DP5B0E81DQL1 +1@010@40000E00030@0000806P402U81DP5B0E81DP48DP090E89DPUB2E8100L900T12JL9Y`VW2@40 +1ZL02P48Y`RW2:L8Y`47200=0@P0200800P020080@0^000=0@0800P0200800P00@07200:0@RW2:L8 +Y`RW0@NW00P12JL9Y`VW0@L900T12E89DPUB2@4025820@09DP5B0E81DP5B01P11@010@40000E0003 +0@0000806@402E81DP5B0E81DP020@QB00T12E89DPUB2@401`T02@6W2JL9Y`VW0@06Y`0:0JL8Y`RW +2:L80@L800d100P0200800P0200102h000d1200800P0200800P100L800X1Y`RW2:L8Y`P11jL0206W +2JL9Y`T11`T02@5B2E89DPUB0@08DP0<0E81DP5B0E81DP5B5`4500410@0001D000<100000P0J0@0: +DP5B0E81DP5B0@QB00T1DPUB2E89DP401`T02@49Y`VW2JL90@06Y`0:0@RW2:L8Y`RW0@L800d12008 +00P0200800P102h000d100P0200800P0200100L800X12:L8Y`RW2:L11jL02049Y`VW2JL11`T02@49 +DPUB2E890@08DP8100UB0E81DP5B0E80604500410@0001D000<100000P0I0@09DP5B0E81DP5B0081 +25802@49DPUB2E890@072@090JL9Y`VW2JL100JW00X1Y`RW2:L8Y`P11`P03@40200800P020080040 +;P003@4800P0200800P020401`P02P6W2:L8Y`RW2047Y`080JL9Y`VW2@472@090E89DPUB2E8100QB +00`1DP5B0E81DP5B0E8G0@D00@4100005@000`40000201X100YB0E81DP5B0E8125802@5B2E89DPUB +0@072@090@VW2JL9Y`T100JW00X12:L8Y`RW2:L11`P03@4800P0200800P02040;P003@40200800P0 +200800401`P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@090@UB2E89DPT100QB0P402E81DP5B0E81 +DP0H0@D00@4100005@000`40000201T100UB0E81DP5B0E800P48DP090@UB2E89DPT100L900T1Y`VW +2JL9Y`401ZL02P6W2:L8Y`RW2047200=0@0800P0200800P00@0^000=0@P0200800P020080@07200: +0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900T1DPUB2E89DP402580305B0E81DP5B0E81DQL11@010@40 +0002008110000`40000200<11@000`40000201X100YB0E81DP5B0E8125802@5B2E89DPUB0@072@09 +0@VW2JL9Y`T100JW00X12:L8Y`RW2:L11`P03@4800P0200800P02040;P003@40200800P020080040 +1`P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@090@UB2E89DPT100QB0P402E81DP5B0E81DP0H0@D0 +0@41000000D00@000@0;00030@0000800P4301T100UB0E81DP5B0E800P48DP090@UB2E89DPT100L9 +00T1Y`VW2JL9Y`401ZL02P6W2:L8Y`RW2047200=0@0800P0200800P00@0^000=0@P0200800P02008 +0@07200:0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900T1DPUB2E89DP402580305B0E81DP5B0E81DQL1 +10020@4000001@01000100/000<100000P000`40000201X100YB0E81DP5B0E8125802@5B2E89DPUB +0@072@090@VW2JL9Y`T100JW00X12:L8Y`RW2:L11`P03@4800P0200800P02040;P003@40200800P0 +200800401`P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@090@UB2E89DPT100QB0P402E81DP5B0E81 +DP0H0@D00@41000000D00@000@0800<11@000`40000201T100UB0E81DP5B0E800P48DP090@UB2E89 +DPT100L900T1Y`VW2JL9Y`401ZL02P6W2:L8Y`RW2047200=0@0800P0200800P00@0^000=0@P02008 +00P020080@07200:0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900T1DPUB2E89DP402580305B0E81DP5B +0E81DQL11@010@4000001@01000100P000<100001@000`40000201X100YB0E81DP5B0E8125802@5B +2E89DPUB0@072@090@VW2JL9Y`T100JW00X12:L8Y`RW2:L11`P03@4800P0200800P02040;P003@40 +200800P0200800401`P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@090@UB2E89DPT100QB0P402E81 +DP5B0E81DP0H0@D00@41000000D00@000@0800030@0000D000<100000P0I0@09DP5B0E81DP5B0081 +25802@49DPUB2E890@072@090JL9Y`VW2JL100JW00X1Y`RW2:L8Y`P11`P03@40200800P020080040 +;P003@4800P0200800P020401`P02P6W2:L8Y`RW2047Y`080JL9Y`VW2@472@090E89DPUB2E8100QB +00`1DP5B0E81DP5B0E8G0@D00@4100000P020@T0104400030@0000806P402U81DP5B0E81DP48DP09 +0E89DPUB2E8100L900T12JL9Y`VW2@401ZL02P48Y`RW2:L8Y`47200=0@P0200800P020080@0^000= +0@0800P0200800P00@07200:0@RW2:L8Y`RW0@NW00P12JL9Y`VW0@L900T12E89DPUB2@4025820@09 +DP5B0E81DP5B01P11@010@40000E00030@0000806@402E81DP5B0E81DP020@QB00T12E89DPUB2@40 +1`T02@6W2JL9Y`VW0@06Y`0:0JL8Y`RW2:L80@L800d100P0200800P0200102h000d1200800P02008 +00P100L800X1Y`RW2:L8Y`P11jL0206W2JL9Y`T11`T02@5B2E89DPUB0@08DP0<0E81DP5B0E81DP5B +5`4500410@0001D000<100000P0J0@0:DP5B0E81DP5B0@QB00T1DPUB2E89DP401`T02@49Y`VW2JL9 +0@06Y`0:0@RW2:L8Y`RW0@L800d1200800P0200800P102h000d100P0200800P0200100L800X12:L8 +Y`RW2:L11jL02049Y`VW2JL11`T02@49DPUB2E890@08DP8100UB0E81DP5B0E80604500410@0001D0 +00<100000P0I0@09DP5B0E81DP5B008125802@49DPUB2E890@072@090JL9Y`VW2JL100JW00X1Y`RW +2:L8Y`P11`P03@40200800P020080040;P003@4800P0200800P020401`P02P6W2:L8Y`RW2047Y`08 +0JL9Y`VW2@472@090E89DPUB2E8100QB00`1DP5B0E81DP5B0E8G0@D00@4100005@000`40000201X1 +00YB0E81DP5B0E8125802@5B2E89DPUB0@072@090@VW2JL9Y`T100JW00X12:L8Y`RW2:L11`P03@48 +00P0200800P02040;P003@40200800P0200800401`P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@09 +0@UB2E89DPT100QB0P402E81DP5B0E81DP0H0@D00@4100005@000`40000201T100UB0E81DP5B0E80 +0P48DP090@UB2E89DPT100L900T1Y`VW2JL9Y`401ZL02P6W2:L8Y`RW2047200>0@0800P0200800P0 +204/000>0@0800P0200800P02047200:0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900T1DPUB2E89DP40 +2580305B0E81DP5B0E81DQL11@010@40000E00030@00008060402E81DP5B0E81DP020@QB00X12E89 +DPUB2E811`T02@49Y`VW2JL90@06Y`0;0@RW2:L8Y`RW20401`P03@40200800P020080040;0003@48 +00P0200800P020401`P02`6W2:L8Y`RW2:L100NW00P12JL9Y`VW0@L900X12E89DPUB2E812580305B +0E81DP5B0E81DQH11@010@40000E00030@0000805`403581DP5B0E81DP5B0@QB00X1DPUB2E89DPT1 +1`T02@6W2JL9Y`VW0@06Y`0;0JL8Y`RW2:L8Y`401`P03P4800P0200800P02001:P003P4800P02008 +00P020011`P02`48Y`RW2:L8Y`P100NW00P1Y`VW2JL90@L900X1DPUB2E89DPT125820@0;DP5B0E81 +DP5B0E805@4500410@0001D00P4301H100aB0E81DP5B0E81DP49DP090@UB2E89DPT100P900T12JL9 +Y`VW2@401jL02P6W2:L8Y`RW2048200>0@P0200800P02008004X000>0@P0200800P020080048200: +0JL8Y`RW2:L80@RW00P12JL9Y`VW0@P900T1DPUB2E89DP402E820@0;DP5B0E81DP5B0E8050440081 +0@0001D000<100000P0E0@0;DP5B0E81DP5B0E800P48DP0:0@UB2E89DPUB0@P900T1Y`VW2JL9Y`40 +1jL02`48Y`RW2:L8Y`P100L800l100P0200800P0200800409P003`4800P0200800P020080@08200: +0@RW2:L8Y`RW0@RW00P1Y`VW2JL90@P900X12E89DPUB2E8125803P5B0E81DP5B0E81DP5B4`450041 +0@0001D000<100000P0D0@0;DP5B0E81DP5B0E800P49DP0:0E89DPUB2E890@P900T12JL9Y`VW2@40 +1jL02`6W2:L8Y`RW2:L100P800h100P0200800P020080BH000h100P0200800P020080@P800/12:L8 +Y`RW2:L80@08Y`080@VW2JL9Y`482@0:0E89DPUB2E890@UB00`1DP5B0E81DP5B0E8D0@D00@410000 +5@000`40000201<100iB0E81DP5B0E81DP5B0@UB00X12E89DPUB2E8120T02@6W2JL9Y`VW0@07Y`0; +0@RW2:L8Y`RW204020P03P4800P0200800P020080P4R008100h0200800P0200800P00@P800/1Y`RW +2:L8Y`RW0@08Y`080JL9Y`VW2@482@0:0@UB2E89DPUB0@UB0P402e81DP5B0E81DP5B01<11@010@40 +000E00030@0000804P403U81DP5B0E81DP5B0E812E802`49DPUB2E89DPT100P900T12JL9Y`VW2@40 +1jL0306W2:L8Y`RW2:L80@P800l1200800P0200800P020000P4N008100l800P0200800P020080040 +2@P02`48Y`RW2:L8Y`P100RW00P12JL9Y`VW0@P900/1DPUB2E89DPUB0@09DP8100eB0E81DP5B0E81 +DP5B01011@010@40000E00030@0000803`403e81DP5B0E81DP5B0E81DP020@UB00/1DPUB2E89DPUB +0@082@090JL9Y`VW2JL100NW00`12:L8Y`RW2:L8Y`48200A0@0800P0200800P0200800P00P4J0081 +0140200800P0200800P020080@09200;0JL8Y`RW2:L8Y`402:L0206W2JL9Y`T120T02`49DPUB2E89 +DPT100UB0101DP5B0E81DP5B0E81DP5B3`4500410@0001D000<100000P0>0@0?DP5B0E81DP5B0E81 +DP5B00812U802P49DPUB2E89DP482@0;0JL9Y`VW2JL9Y`401jL02`48Y`RW2:L8Y`P100T8018100P0 +200800P0200800P020030AD00P404PP0200800P0200800P020080@T800/1Y`RW2:L8Y`RW0@08Y`0: +0JL9Y`VW2JL90@P900X12E89DPUB2E812U804P5B0E81DP5B0E81DP5B0E81DP`11@010@40000E0003 +0@0000802`405581DP5B0E81DP5B0E81DP5B0E812U802P5B2E89DPUB2@482@0;0@VW2JL9Y`VW2@40 +1jL02`6W2:L8Y`RW2:L100T801D1200800P0200800P0200800P020000P4@00<101@0200800P02008 +00P0200800P00@T800/12:L8Y`RW2:L80@08Y`0:0@VW2JL9Y`VW0@P900X1DPUB2E89DPT12U820@0A +DP5B0E81DP5B0E81DP5B0E802`4500410@0001D000<100000P080@0FDP5B0E81DP5B0E81DP5B0E81 +DP5B0@YB00/1DPUB2E89DPUB0@082@0;0JL9Y`VW2JL9Y`401jL03048Y`RW2:L8Y`RW0@T801H12008 +00P0200800P0200800P020080`4;008101H0200800P0200800P0200800P020012PP02`6W2:L8Y`RW +2:L100RW00X1Y`VW2JL9Y`T120T02`49DPUB2E89DPT100YB0P404e81DP5B0E81DP5B0E81DP5B0E80 +204500410@0001D000<100000P070@0EDP5B0E81DP5B0E81DP5B0E81DP5B00812U802`49DPUB2E89 +DPT100P900/12JL9Y`VW2JL90@07Y`0<0JL8Y`RW2:L8Y`P12@P06@40200800P0200800P0200800P0 +200800P00P47008101P800P0200800P0200800P0200800P0204:200;0@RW2:L8Y`RW20402:L02P49 +Y`VW2JL9Y`482@0;0E89DPUB2E89DP402U80605B0E81DP5B0E81DP5B0E81DP5B0E81DPD11@010@40 +000E00030@00008010405e81DP5B0E81DP5B0E81DP5B0E81DP5B00812e802`5B2E89DPUB2E8100P9 +00/1Y`VW2JL9Y`VW0@07Y`0<0@RW2:L8Y`RW2:L12PP06P40200800P0200800P0200800P0200800P0 +0P43008101T0200800P0200800P0200800P0200800P100X800`12:L8Y`RW2:L8Y`48Y`0:0JL9Y`VW +2JL90@P900/12E89DPUB2E890@0;DP0H0E81DP5B0E81DP5B0E81DP5B0E81DP5B104500410@0001D0 +00<100000P030@0JDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP4:DP0<0E89DPUB2E89DPT120T02`49 +Y`VW2JL9Y`T100NW00d1Y`RW2:L8Y`RW2:L100T801`1200800P0200800P0200800P0200800P02008 +0`406`P0200800P0200800P0200800P0200800P00@0:200<0JL8Y`RW2:L8Y`P12:L02P49Y`VW2JL9 +Y`482@0<0E89DPUB2E89DPT12U820@0IDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@@00@410000 +5@000`400002000LDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0@]B00/12E89DPUB2E890@092@0; +0JL9Y`VW2JL9Y`402:L0306W2:L8Y`RW2:L80@X803P1200800P0200800P0200800P0200800P02008 +00P0200800P0200800P0200800P0200800P00@/800/12:L8Y`RW2:L80@09Y`0:0JL9Y`VW2JL90@T9 +00/1DPUB2E89DPUB0@0;DP8101UB0E81DP5B0E81DP5B0E81DP5B0E81DP5B00D00@4100005@020@<0 +01X1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP812e802`5B2E89DPUB2E8100T900/12JL9Y`VW2JL9 +0@08Y`0<0@RW2:L8Y`RW2:L12PP0>040200800P0200800P0200800P0200800P0200800P0200800P0 +200800P0200800P0200800P12`P02`6W2:L8Y`RW2:L100VW00X12JL9Y`VW2JL12@T02`49DPUB2E89 +DPT100]B01/1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP4010020@40000E00030@00008001UB0E81 +DP5B0E81DP5B0E81DP5B0E81DP5B00812e80305B2E89DPUB2E890@T900/1Y`VW2JL9Y`VW0@08Y`0= +0JL8Y`RW2:L8Y`RW0@0:200f0@0800P0200800P0200800P0200800P0200800P0200800P0200800P0 +200800P0200800P12`P0306W2:L8Y`RW2:L80@VW00X1Y`VW2JL9Y`T12@T0305B2E89DPUB2E890@]B +01X1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DPD00@4100005@000`400002000H0E81DP5B0E81DP5B +0E81DP5B0E81DP5B0`4;DP0<0@UB2E89DPUB2E812@T02`49Y`VW2JL9Y`T100RW00d12:L8Y`RW2:L8 +Y`P100X803@1200800P0200800P0200800P0200800P0200800P0200800P0200800P0200800P02008 +0P4;200<0@RW2:L8Y`RW2:L12JL02P49Y`VW2JL9Y`492@0<0@UB2E89DPUB2E812e820@0HDP5B0E81 +DP5B0E81DP5B0E81DP5B0E811@010@40000E00030@00008001MB0E81DP5B0E81DP5B0E81DP5B0E81 +DP020@aB00`12E89DPUB2E89DP4:2@0;0JL9Y`VW2JL9Y`402JL03@48Y`RW2:L8Y`RW20402PP20@0_ +00P0200800P0200800P0200800P0200800P0200800P0200800P0200800P020000P4<200<0@RW2:L8 +Y`RW2:L12ZL02P6W2JL9Y`VW2@4:2@0<0@UB2E89DPUB2E812e820@0GDP5B0E81DP5B0E81DP5B0E81 +DP5B0E801@010@40000E00030@00008001@1DP5B0E81DP5B0E81DP5B0E81DP<13E803049DPUB2E89 +DPUB0@/900/12JL9Y`VW2JL90@0:Y`0<0@RW2:L8Y`RW2:L130P20@0[200800P0200800P0200800P0 +200800P0200800P0200800P0200800P020020@d800`12:L8Y`RW2:L8Y`4;Y`0:0@VW2JL9Y`VW0@/9 +00`12E89DPUB2E89DP40E89DPUB2E89DPUB2@4=DPD100iB0E81DP5B0E81DP5B0@D00@4100005@000`40 +0002000;DP5B0E81DP5B0E801@4@DP0>0E89DPUB2E89DPUB2@4<2@0=0@VW2JL9Y`VW2JL90@0;Y`0> +0JL8Y`RW2:L8Y`RW204@20D101L800P0200800P0200800P0200800P020040A0800h1Y`RW2:L8Y`RW +2:L80@bW00`12JL9Y`VW2JL9Y`4<2@0>0E89DPUB2E89DPUB2@4@DP@100]B0E81DP5B0E81DP050041 +0@0001D000<100000P001P5B0E81DPH14U820@0=DPUB2E89DPUB2E890@0=2@0=0JL9Y`VW2JL9Y`VW +0@02@0?0JL9Y`VW +2JL9Y`VW2JL100fW00l12:L8Y`RW2:L8Y`RW2:L00P4d200A0JL8Y`RW2:L8Y`RW2:L8Y`403ZL03P6W +2JL9Y`VW2JL9Y`T13PT03`49DPUB2E89DPUB2E89DP020AUB1@010@40000E00030@0000806E804@5B +2E89DPUB2E89DPUB2E8100l900l12JL9Y`VW2JL9Y`VW2@403ZL04@48Y`RW2:L8Y`RW2:L8Y`P10388 +0141Y`RW2:L8Y`RW2:L8Y`RW0@0?Y`0>0@VW2JL9Y`VW2JL9Y`4?2@0A0@UB2E89DPUB2E89DPUB2@40 +658500410@0001D00P4301MB0P404E89DPUB2E89DPUB2E89DPT100l900l1Y`VW2JL9Y`VW2JL9Y`40 +3ZL04@6W2:L8Y`RW2:L8Y`RW2:L80081;PP20@0AY`RW2:L8Y`RW2:L8Y`RW20403jL03P6W2JL9Y`VW +2JL9Y`T13`T04@5B2E89DPUB2E89DPUB2E8900815U8400810@0001D000<100000P0FDP0C0@UB2E89 +DPUB2E89DPUB2E890@0?2@0A0JL9Y`VW2JL9Y`VW2JL9Y`403ZL04`6W2:L8Y`RW2:L8Y`RW2:L8Y`40 +;0P04`48Y`RW2:L8Y`RW2:L8Y`RW20403jL0406W2JL9Y`VW2JL9Y`VW2@4?2@0C0E89DPUB2E89DPUB +2E89DPUB0@0EDPD00@4100005@000`40000201EB01<12E89DPUB2E89DPUB2E89DPT1010901412JL9 +Y`VW2JL9Y`VW2JL90@0?Y`0C0JL8Y`RW2:L8Y`RW2:L8Y`RW0@0Z200C0@RW2:L8Y`RW2:L8Y`RW2:L8 +0@0@Y`0@0@VW2JL9Y`VW2JL9Y`VW0A0901<1DPUB2E89DPUB2E89DPUB2E8101AB1@010@40000E0003 +0@0000804e820@0B2E89DPUB2E89DPUB2E89DPT14@T04@6W2JL9Y`VW2JL9Y`VW2JL1012W0181Y`RW +2:L8Y`RW2:L8Y`RW2:L20BH80P404PRW2:L8Y`RW2:L8Y`RW2:L80A6W0101Y`VW2JL9Y`VW2JL9Y`T1 +4@T04P5B2E89DPUB2E89DPUB2E89DP814U8500410@0001D000<100000P0>DPD101AB2E89DPUB2E89 +DPUB2E89DPUB0A4901412JL9Y`VW2JL9Y`VW2JL90@0@Y`0D0@RW2:L8Y`RW2:L8Y`RW2:L8Y`P50A`8 +1@405:L8Y`RW2:L8Y`RW2:L8Y`RW2:L14JL04049Y`VW2JL9Y`VW2JL9Y`4A2@0D0@UB2E89DPUB2E89 +DPUB2E89DPT50@eB1@010@40000E00030@0000801E890@0HDPUB2E89DPUB2E89DPUB2E89DPUB2E81 +4@T04`49Y`VW2JL9Y`VW2JL9Y`VW2@404:L06048Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20X12@P90@0H +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L14JL04P49Y`VW2JL9Y`VW2JL9Y`VW0A4901P12E89DPUB2E89 +DPUB2E89DPUB2E89DPT90@AB1@010@40000E00030@0000801@408589DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E814PT04`6W2JL9Y`VW2JL9Y`VW2JL9Y`404JL08@48Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`090@0PY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`4BY`0B0JL9Y`VW +2JL9Y`VW2JL9Y`T14PT08049DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E891@4400410@0001D0 +00<100000P008e89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB00814PT04`49Y`VW2JL9 +Y`VW2JL9Y`VW2@404JL20@162:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`814ZL04P49Y`VW2JL9Y`VW2JL9Y`VW0A890P408PUB +2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E8500410@0001D000<100000P007`UB2E89DPUB +2E89DPUB2E89DPUB2E89DPUB2E89DPT0104D2@0C0JL9Y`VW2JL9Y`VW2JL9Y`VW0@0CY`@103jW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20@1 +4jL05049Y`VW2JL9Y`VW2JL9Y`VW2JL14`T40@0NDPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +1@010@40000E00030@00008001]B2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E80104F2@8101>W2JL9 +Y`VW2JL9Y`VW2JL9Y`VW00815JL30@0gY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`040AFW0P4050VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0P4E2@<101]B2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E801@010@40000E00030@00008001P9DPUB2E89DPUB2E89DPUB +2E89DPUB2E830AP90P405`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900815ZL40@0`2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0`4GY`8101RW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`T20AH910405`UB2E89DPUB2E89DPUB2E89DPUB2E8900D00@4100005@000`400002000D +DPUB2E89DPUB2E89DPUB2E89DPT40AT90P407:L9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4IY`@1 +02RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8104IY`0N0@VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL16@T40@0CDPUB2E89DPUB2E89DPUB2E89DP0500410@0001D00P43000> +2E89DPUB2E89DPUB2E860A`901l12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00816jL60@0L +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`H16jL20@0N2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW0P4K2@H100d9DPUB2E89DPUB2E8900@00P4100005@000`4000020005DPUB2E802@4P2@81 +0289Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T18:L:0@09Y`RW2:L8Y`RW00T17jL20@0S +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@4080T90@042E89DPD00@4100005@000`40 +000200D19`T20@0TY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90P4XY`T19jL09P49 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90P4W2@D110010@40000E00030@000080 +:`T0:@49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0081E:L20@0X2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`81:@T500410@0001D000<100000P0Y2@81 +02`9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90E:W02h1Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T1:0T500410@0001D000<100000P0W2@81 +02jW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90P5>Y`8102jW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90P4V2@D00@4100005@000`40 +000202D90P40W2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`020A:W01<12JL9Y`VW2JL9 +Y`VW2JL9Y`T101490P40APUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB +2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E820A490P4040VW2JL9Y`VW2JL9Y`VW2JL20A6W0P408PRW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L500410@0001D000<100000P009@RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`404ZL04`6W2JL9Y`VW2JL9Y`VW2JL9Y`404@T0BP49 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E814PT04P6W2JL9Y`VW2JL9Y`VW2JL90A:W02@12:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`P500410@0001D000<100000P050@0Q2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L1016W01<12JL9Y`VW2JL9Y`VW2JL9Y`T1010902812E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E892@408@UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB0@0A2@0B0@VW2JL9 +Y`VW2JL9Y`VW2JL14JL08@48Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`050@@00@410000 +5@000`40000200D82@4060RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80A:W01412JL9Y`VW2JL9Y`VW2JL9 +0@0A2@0H0E89DPUB2E89DPUB2E89DPUB2E89DPUB2P49DPT101P9DPUB2E89DPUB2E89DPUB2E89DPUB +2@4B2@0@0@VW2JL9Y`VW2JL9Y`VW0A:W01P1Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L90@@81@010@40 +000E00030@0000803PP50@0D2:L8Y`RW2:L8Y`RW2:L8Y`RW204AY`0A0JL9Y`VW2JL9Y`VW2JL9Y`40 +40T0505B2E89DPUB2E89DPUB2E89DPUB1@4LDPD101@9DPUB2E89DPUB2E89DPUB2E890A490101Y`VW +2JL9Y`VW2JL9Y`T14JL0506W2:L8Y`RW2:L8Y`RW2:L8Y`RW1@4=20D00@4100005@000`40000201<8 +0P404jL8Y`RW2:L8Y`RW2:L8Y`RW20404:L04@49Y`VW2JL9Y`VW2JL9Y`T100l901<1DPUB2E89DPUB +2E89DPUB2E8900819U820@0CDPUB2E89DPUB2E89DPUB2E890@0@2@0@0@VW2JL9Y`VW2JL9Y`VW0A2W +01<1Y`RW2:L8Y`RW2:L8Y`RW2:L800814PP500410@0001D000<100000P0E200D0JL8Y`RW2:L8Y`RW +2:L8Y`RW204?Y`0A0JL9Y`VW2JL9Y`VW2JL9Y`403PT0505B2E89DPUB2E89DPUB2E89DPT1:U80505B +2E89DPUB2E89DPUB2E89DPT13`T0406W2JL9Y`VW2JL9Y`VW2@4?Y`0D0JL8Y`RW2:L8Y`RW2:L8Y`RW +204D20D00@4100005@000`40000201H80P404@RW2:L8Y`RW2:L8Y`RW2:L100nW01412JL9Y`VW2JL9 +Y`VW2JL90@0>2@0A0@UB2E89DPUB2E89DPUB2E800P4/DP810149DPUB2E89DPUB2E89DPUB0@0?2@0@ +0@VW2JL9Y`VW2JL9Y`VW0@nW01412:L8Y`RW2:L8Y`RW2:L8Y`020AD81@010@40000E00810`0H200B +0@RW2:L8Y`RW2:L8Y`RW2:L13jL03`49Y`VW2JL9Y`VW2JL90@0>2@0B0@UB2E89DPUB2E89DPUB2E81 +<5804P49DPUB2E89DPUB2E89DPUB0@l900h12JL9Y`VW2JL9Y`VW0@nW01812:L8Y`RW2:L8Y`RW2:L8 +Y`4G20@00P4100005@000`40000201T80P404:L8Y`RW2:L8Y`RW2:L8Y`4>Y`0?0JL9Y`VW2JL9Y`VW +2JL100d901012E89DPUB2E89DPUB2E890P4bDP81011B2E89DPUB2E89DPUB2E813PT03P6W2JL9Y`VW +2JL9Y`T13ZL04048Y`RW2:L8Y`RW2:L8Y`P20AP81@010@40000E00030@0000800P4I200A0JL8Y`RW +2:L8Y`RW2:L8Y`403JL03`49Y`VW2JL9Y`VW2JL90@0=2@0@0E89DPUB2E89DPUB2E890AYB0`4IDP0A +0E89DPUB2E89DPUB2E89DP403@T03P49Y`VW2JL9Y`VW2JL13ZL0406W2:L8Y`RW2:L8Y`RW204I2081 +10010@40000E00030@0000<000<80@400P4F208100h8Y`RW2:L8Y`RW2:L80@fW00l1Y`VW2JL9Y`VW +2JL9Y`4030T03P5B2E89DPUB2E89DPUB0P4GDPD100=B0@400`4FDP8100h9DPUB2E89DPUB2E890@d9 +00h1Y`VW2JL9Y`VW2JL90@fW00h1Y`RW2:L8Y`RW2:L8Y`815PP40@H00@4100005@000`4000020006 +200800P00`4E200?0@RW2:L8Y`RW2:L8Y`P100fW00d1Y`VW2JL9Y`VW2JL100`900l1DPUB2E89DPUB +2E89DP405E840@0;DP5B0E81DP5B0E800`4EDP0?0@UB2E89DPUB2E89DPT100d900`1Y`VW2JL9Y`VW +2@4=Y`0?0JL8Y`RW2:L8Y`RW2:L101@810401@P0200800D00@4100005@000`4000030008200800P0 +20040A880P403JL8Y`RW2:L8Y`RW20403:L03@49Y`VW2JL9Y`VW2@402`T03@5B2E89DPUB2E89DPT0 +0P4BDPD1015B0E81DP5B0E81DP5B0E81DP040A9B0P403E89DPUB2E89DPUB2@4030T03049Y`VW2JL9 +Y`VW0@bW00d1Y`RW2:L8Y`RW2:L800814PP30@0800P0200800P600410@0001D000<100000P003@P0 +200800P0200800P0104@200=0JL8Y`RW2:L8Y`RW0@0208101<800P0200800P0200800P0200800D00@410000 +5@000`400003000D200800P0200800P0200800P020020@h800`12:L8Y`RW2:L8Y`4:Y`0;0JL9Y`VW +2JL9Y`402@T03@49DPUB2E89DPUB2@4035820@0[DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81 +DP5B0E81DP5B0E81DP020@iB00`12E89DPUB2E89DP4:2@0:0JL9Y`VW2JL90@ZW00`12:L8Y`RW2:L8 +Y`4=208101@0200800P0200800P0200800P020H00@4100005@000`400002000G200800P0200800P0 +200800P0200800P00P4<200<0JL8Y`RW2:L8Y`P12ZL02`49Y`VW2JL9Y`T100T900`1DPUB2E89DPUB +2@4;DP<102eB0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E800`40@P02008 +00P02008004G00410@0001D00P4G000>0@P0200800P02008004920090@RW2:L8Y`P100RW00T12JL9 +Y`VW2@401`T02P5B2E89DPUB2@48DP8100]B0E81DP5B0E81DP0[0@00@P0200800P020080048200:0JL8Y`RW2:L80@NW00T1Y`VW2JL9Y`401`T02P49 +DPUB2E89DP48DP0<0E81DP5B0E81DP5B;@403581DP5B0E81DP5B0@MB00/12E89DPUB2E890@072@08 +0JL9Y`VW2@48Y`090@RW2:L8Y`P100T800h100P0200800P020080AP00@4100005@000`40000H000= +0@P0200800P020080@08200:0@RW2:L8Y`RW0@NW00T12JL9Y`VW2@401PT02`49DPUB2E89DPT100MB +00`1DP5B0E81DP5B0E8]0@0;DP5B0E81DP5B0E800P47DP0;0E89DPUB2E89DP401`T02049Y`VW2JL1 +1jL02P48Y`RW2:L8Y`48200>0@0800P0200800P0204I00410@0001D000<100006@003@4800P02008 +00P0204020P02@48Y`RW2:L80@07Y`090JL9Y`VW2JL100H900X1DPUB2E89DPT125820@09DP5B0E81 +DP5B02l100]B0E81DP5B0E81DP020@MB00X1DPUB2E89DPT11`T0206W2JL9Y`T11jL02@6W2:L8Y`RW +0@09200=0@P0200800P020080@0J00410@0001D000<100006P00304800P0200800P00@P800T1Y`RW +2:L8Y`401jL02@49Y`VW2JL90@062@0:0@UB2E89DPUB0@MB0P402E81DP5B0E81DP0a0@00@0800P0200800P0204I00410@0001D000<100005`003P48 +00P0200800P0200120P02P6W2:L8Y`RW2047Y`090JL9Y`VW2JL100L900X12E89DPUB2E812580305B +0E81DP5B0E81DRd100aB0E81DP5B0E81DP47DP0;0@UB2E89DPUB2@401`T0206W2JL9Y`T12:L02@48 +Y`RW2:L80@09200>0@0800P0200800P0204H00410@0001D00P4G000>0@P0200800P0200800492009 +0@RW2:L8Y`P100RW00T12JL9Y`VW2@401`T02P5B2E89DPUB2@48DP8100]B0E81DP5B0E81DP0[0@0< +DP5B0E81DP5B0E8125802P5B2E89DPUB2@482@080@VW2JL9Y`48Y`090JL8Y`RW2:L100T800h12008 +00P0200800P00AL00P4100005@000`40000E000?0@P0200800P0200800P100P800X12:L8Y`RW2:L1 +2:L02@6W2JL9Y`VW0@072@0;0@UB2E89DPUB2@4025820@0;DP5B0E81DP5B0E80:@402e81DP5B0E81 +DP5B008125802P49DPUB2E89DP482@080JL9Y`VW2@48Y`0:0@RW2:L8Y`RW0@T800h1200800P02008 +00P00AL00@4100005@000`40000C008100h800P0200800P020080@T800X1Y`RW2:L8Y`P12:L02@49 +Y`VW2JL90@072@0;0E89DPUB2E89DP4025803P5B0E81DP5B0E81DP5B9`402e81DP5B0E81DP5B0081 +25802`49DPUB2E89DPT100P900P12JL9Y`VW0@RW00X1Y`RW2:L8Y`P12@P03P40200800P0200800P0 +0P4E00410@0001D000<100004@020@0@00P0200800P0200800P00@T800X12:L8Y`RW2:L12:L02@6W +2JL9Y`VW0@072@0;0@UB2E89DPUB2@402E803P5B0E81DP5B0E81DP5B8`404581DP5B0E81DP5B0E81 +DP48DP0;0E89DPUB2E89DP4020T0206W2JL9Y`T12:L02P48Y`RW2:L8Y`4:200?0@0800P0200800P0 +200800814`010@40000E00030@0000l00P404@P0200800P0200800P0200100T800/12:L8Y`RW2:L8 +0@08Y`090@VW2JL9Y`T100L900`1DPUB2E89DPUB2@48DP8100mB0E81DP5B0E81DP5B0E807`404581 +DP5B0E81DP5B0E81DP49DP0;0@UB2E89DPUB2@4020T02049Y`VW2JL12:L02`6W2:L8Y`RW2:L100T8 +0141200800P0200800P0200800020A400@4100005@000`40000=008101<0200800P0200800P02008 +00P100T800/1Y`RW2:L8Y`RW0@08Y`0:0JL9Y`VW2JL90@L900/1DPUB2E89DPUB0@09DP8100mB0E81 +DP5B0E81DP5B0E806`404E81DP5B0E81DP5B0E81DP5B00812E802`5B2E89DPUB2E8100P900T1Y`VW +2JL9Y`402:L02P6W2:L8Y`RW204:200B0@P0200800P0200800P020080P4?00410@0001D000<10000 +2P030@0D200800P0200800P0200800P0204:200:0@RW2:L8Y`RW0@RW00/1Y`VW2JL9Y`VW0@072@0; +0@UB2E89DPUB2@402E80505B0E81DP5B0E81DP5B0E81DP5B5`404E81DP5B0E81DP5B0E81DP5B0081 +2E802`5B2E89DPUB2E8100P900X1Y`VW2JL9Y`T12:L02P48Y`RW2:L8Y`4:200D0@0800P0200800P0 +200800P020030@`00@4100005@000`400008008101L800P0200800P0200800P0200800P00@09200; +0@RW2:L8Y`RW20402:L02`49Y`VW2JL9Y`T100L900`1DPUB2E89DPUB2@49DP0F0E81DP5B0E81DP5B +0E81DP5B0E81DQ4101IB0E81DP5B0E81DP5B0E81DP5B0E812E802`49DPUB2E89DPT100P900X12JL9 +Y`VW2JL12:L02`6W2:L8Y`RW2:L100X801H100P0200800P0200800P0200800P00P4:00410@0001D0 +00<100001P020@0H00P0200800P0200800P0200800P020012PP02`6W2:L8Y`RW2:L100RW00/1Y`VW +2JL9Y`VW0@072@0<0@UB2E89DPUB2E812E820@0GDP5B0E81DP5B0E81DP5B0E81DP5B0E802`406581 +DP5B0E81DP5B0E81DP5B0E81DP5B0@YB00/1DPUB2E89DPUB0@082@0:0JL9Y`VW2JL90@RW00/12:L8 +Y`RW2:L80@0:200H0@P0200800P0200800P0200800P020080P4800410@0001D000<1000010020@0J +200800P0200800P0200800P0200800P0204:200;0@RW2:L8Y`RW20402:L02`49Y`VW2JL9Y`T100L9 +00`1DPUB2E89DPUB2@4:DP8101MB0E81DP5B0E81DP5B0E81DP5B0E81DP090@0GDP5B0E81DP5B0E81 +DP5B0E81DP5B0E800P49DP0<0E89DPUB2E89DPT120T02P49Y`VW2JL9Y`48Y`0;0JL8Y`RW2:L8Y`40 +2`P06@4800P0200800P0200800P0200800P020000P4600410@0001D000<100000P020@0K00P02008 +00P0200800P0200800P0200800P100X800`12:L8Y`RW2:L8Y`48Y`0;0JL9Y`VW2JL9Y`401`T03@49 +DPUB2E89DPUB2@402E80705B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E830@0IDP5B0E81DP5B0E81 +DP5B0E81DP5B0E81DP020@YB00`12E89DPUB2E89DP482@0:0JL9Y`VW2JL90@RW00`12:L8Y`RW2:L8 +Y`4:200K0@0800P0200800P0200800P0200800P02008008110010@40000E00030@00008001d800P0 +200800P0200800P0200800P0200800P00@0:200<0JL8Y`RW2:L8Y`P12:L02`49Y`VW2JL9Y`T100P9 +00`12E89DPUB2E89DP4:DP0i0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B +0E81DP5B0E81DP5B0E8100YB00`1DPUB2E89DPUB2@482@0:0@VW2JL9Y`VW0@VW00/12:L8Y`RW2:L8 +0@0;200K0@0800P0200800P0200800P0200800P0200800D00@4100005@000`400003000K200800P0 +200800P0200800P0200800P0200100/800/12:L8Y`RW2:L80@09Y`0;0JL9Y`VW2JL9Y`4020T0305B +2E89DPUB2E890@YB0P40=U81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81 +DP5B0E81DP5B0@]B00/12E89DPUB2E890@092@0:0JL9Y`VW2JL90@VW00/1Y`RW2:L8Y`RW0@0;200J +0@P0200800P0200800P0200800P0200800P600410@0001D00P43000L200800P0200800P0200800P0 +200800P020080@X800`12:L8Y`RW2:L8Y`49Y`0;0@VW2JL9Y`VW2@4020T03@49DPUB2E89DPUB2@40 +2U820@0cDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0081 +2U803049DPUB2E89DPUB0@T900X12JL9Y`VW2JL12JL03048Y`RW2:L8Y`RW0@/801X1200800P02008 +00P0200800P0200800P020@00P4100005@000`400003000H200800P0200800P0200800P0200800P0 +0P4;200<0JL8Y`RW2:L8Y`P12JL02`6W2JL9Y`VW2JL100P900d1DPUB2E89DPUB2E8100YB03@1DP5B +0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0P4;DP0<0E89DPUB +2E89DPT12@T02P6W2JL9Y`VW2@49Y`0<0JL8Y`RW2:L8Y`P12`P06@40200800P0200800P0200800P0 +200800P01P010@40000E00030@00008001L800P0200800P0200800P0200800P020020@`800`1Y`RW +2:L8Y`RW204:Y`0;0@VW2JL9Y`VW2@402@T0305B2E89DPUB2E890@]B0`40;E81DP5B0E81DP5B0E81 +DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP030@aB00`1DPUB2E89DPUB2@4:2@0:0@VW2JL9 +Y`VW0@ZW00`1Y`RW2:L8Y`RW204;208101L800P0200800P0200800P0200800P0200500410@0001D0 +00<100000`0050P0200800P0200800P0200800P00P4>200<0@RW2:L8Y`RW2:L12ZL02`6W2JL9Y`VW +2JL100T900d12E89DPUB2E89DPT100aB0P40:e81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81 +DP5B0E81DP5B0E800P4>DP0<0@UB2E89DPUB2E812PT02P6W2JL9Y`VW2@4:Y`0<0@RW2:L8Y`RW2:L1 +3@P20@0D00P0200800P0200800P0200800P600410@0001D000<100000P004`P0200800P0200800P0 +200800P00P4?200<0@RW2:L8Y`RW2:L12ZL03@6W2JL9Y`VW2JL9Y`402@T03049DPUB2E89DPUB0@iB +0`409E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E800`4?DP0<0@UB2E89DPUB2E81 +2PT0306W2JL9Y`VW2JL90@ZW00`12:L8Y`RW2:L8Y`4>208101<800P0200800P0200800P0200800D0 +0@4100005@000`400003000@200800P0200800P0200800813`P20@0;2:L8Y`RW2:L8Y`402jL03@49 +Y`VW2JL9Y`VW2@402PT02`49DPUB2E89DPUB00813U840@0QDP5B0E81DP5B0E81DP5B0E81DP5B0E81 +DP5B0E81DP5B00813e820@0;2E89DPUB2E89DP402`T03049Y`VW2JL9Y`VW0@^W00/12:L8Y`RW2:L8 +Y`020@h80`403`P0200800P0200800P0200600410@0001D000<100000P003@P0200800P0200800P0 +104@200=0JL8Y`RW2:L8Y`RW0@00E89DPUB2E89DPUB +2E820AMB1@400e810@030AIB0P403PUB2E89DPUB2E89DPT13@T03P6W2JL9Y`VW2JL9Y`T13JL03P6W +2:L8Y`RW2:L8Y`RW0P4F20@11P010@40000E00030@0000800P4I200A0JL8Y`RW2:L8Y`RW2:L8Y`40 +3JL03`49Y`VW2JL9Y`VW2JL90@0=2@0@0E89DPUB2E89DPUB2E890AYB0`4IDP0A0E89DPUB2E89DPUB +2E89DP403@T03P49Y`VW2JL9Y`VW2JL13ZL0406W2:L8Y`RW2:L8Y`RW204I208110010@40000E0003 +0@0000806@P20@0@Y`RW2:L8Y`RW2:L8Y`RW0@jW00l1Y`VW2JL9Y`VW2JL9Y`403@T04049DPUB2E89 +DPUB2E89DPT20C9B0P404589DPUB2E89DPUB2E89DP4>2@0>0JL9Y`VW2JL9Y`VW2@4>Y`0@0@RW2:L8 +Y`RW2:L8Y`RW208160P500410@0001D00P4301P801812:L8Y`RW2:L8Y`RW2:L8Y`4?Y`0?0@VW2JL9 +Y`VW2JL9Y`T100h901812E89DPUB2E89DPUB2E89DP4`DP0B0@UB2E89DPUB2E89DPUB2E813`T03P49 +Y`VW2JL9Y`VW2JL13jL04P48Y`RW2:L8Y`RW2:L8Y`RW0AL810020@40000E00030@0000805PP20@0A +2:L8Y`RW2:L8Y`RW2:L8Y`403jL04@49Y`VW2JL9Y`VW2JL9Y`T100h901412E89DPUB2E89DPUB2E89 +DP020BaB0P404@UB2E89DPUB2E89DPUB2E8100l901012JL9Y`VW2JL9Y`VW2JL13jL04@48Y`RW2:L8 +Y`RW2:L8Y`RW00815@P500410@0001D000<100000P0E200D0JL8Y`RW2:L8Y`RW2:L8Y`RW204?Y`0A +0JL9Y`VW2JL9Y`VW2JL9Y`403PT0505B2E89DPUB2E89DPUB2E89DPT1:U80505B2E89DPUB2E89DPUB +2E89DPT13`T0406W2JL9Y`VW2JL9Y`VW2@4?Y`0D0JL8Y`RW2:L8Y`RW2:L8Y`RW204D20D00@410000 +5@000`40000201<80P404jL8Y`RW2:L8Y`RW2:L8Y`RW20404:L04@49Y`VW2JL9Y`VW2JL9Y`T100l9 +01<1DPUB2E89DPUB2E89DPUB2E8900819U820@0CDPUB2E89DPUB2E89DPUB2E890@0@2@0@0@VW2JL9 +Y`VW2JL9Y`VW0A2W01<1Y`RW2:L8Y`RW2:L8Y`RW2:L800814PP500410@0001D000<100000P0>20D1 +01@8Y`RW2:L8Y`RW2:L8Y`RW2:L80A6W0141Y`VW2JL9Y`VW2JL9Y`VW0@0@2@0D0E89DPUB2E89DPUB +2E89DPUB2E850AaB1@4050UB2E89DPUB2E89DPUB2E89DPT14@T0406W2JL9Y`VW2JL9Y`VW2@4AY`0D +0JL8Y`RW2:L8Y`RW2:L8Y`RW2:L50@d81@010@40000E00030@0000801@P90@0H2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`P14ZL04@49Y`VW2JL9Y`VW2JL9Y`T1014901P1DPUB2E89DPUB2E89DPUB2E89DPUB +2E8:0@UB2@4060UB2E89DPUB2E89DPUB2E89DPUB2E890A8901012JL9Y`VW2JL9Y`VW2JL14ZL0606W +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`T110P500410@0001D000<100000P050@0Q2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L1016W01<12JL9Y`VW2JL9Y`VW2JL9Y`T1010902812E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E892@408@UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB +0@0A2@0B0@VW2JL9Y`VW2JL9Y`VW2JL14JL08@48Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`050@@00@4100005@000`400002000U2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +0@0BY`0C0JL9Y`VW2JL9Y`VW2JL9Y`VW0@0A2@1:0@UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP4B2@0B0JL9Y`VW2JL9Y`VW +2JL9Y`T14ZL09048Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20D00@4100005@000`40 +0002000RY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20<14ZL04`49Y`VW2JL9Y`VW2JL9 +Y`VW2@404@T30@14DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPT30A490P4040VW2JL9Y`VW2JL9Y`VW2JL20A6W0`408JL8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`0500410@0001D000<100000P007PRW2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`@14jL20@0C2JL9Y`VW2JL9Y`VW2JL9Y`VW2@020A891040?0UB2E89DPUB +2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP@14PT20@0D +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T20A:W10407@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L800D0 +0@4100005@000`400002000IY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`050AFW0P405jL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW008150T50@0b2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB +2E89DPUB2E89DPUB2E850A@90P4060VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`815:L50@0H2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW1@010@40000E00030@00008001D8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P0 +104HY`8101/9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T00P4G2@@102YB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT40AL90P407:L9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`T20ANW10405:L8Y`RW2:L8Y`RW2:L8Y`RW2:L81@010@40000E00030@00008000VW2:L8Y`RW2:L0 +304JY`8101nW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00816@T<0@0B2E89DPUB2E89DPUB +2E89DPUB304I2@810209Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`816JL;0@09Y`RW2:L8 +Y`RW00D00@4100005@020@<02@4TY`8102@9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2@4T2A8190T09P6W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T18jL:0@<00P410000 +5@000`40000202^W0P409ZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90P5F2@81 +02JW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@81:ZL500410@0001D000<10000 +0P0YY`8102X9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL20E890P40:PVW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`81::L500410@0001D000<10000 +0P0WY`8102jW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90P5>2@81 +02jW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90P4VY`D00@410000 +5@000`40000202FW0P400A893P40DZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T=0@VW1@010@40000E00030@0000802@40KPVW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW4P40K@VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T02P4400410@0001D000<10000 +0P00o`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2@0500410@0001D000<100000P00ojL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`050041 +0@0001D000<100000P00o`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@0500410@0000d0104400030@0000800?nW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL01@010@40000=00030@0000D00P43003o2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900@00P410000 +3P000`40000400030@000?l01`010@40000?00030@0000<000<10000o`0700410@00010000<10000 +0P000`40000200030@0003d000<10000?@000`40000l00030@0003d000<100000P010@40000=0004 +0@000@@000<100000P000`40000:00030@0000T000<100002P000`40000:00030@0000X000<10000 +2P000`40000900030@0000X000<100002P000`40000:00030@0000T000<100002P000`40000:0003 +0@0000X000<100002@000`40000:00030@0000X000<100002P000`40000:00030@0000T000<10000 +0P010@40000>00811@3o0@/10@000?l08@000?l08@000?l08@000?l08@000001\ +\>"], + ImageRangeCache->{{{0, 287}, {287, 0}} -> {-0.207, -0.172242, 0.00783272, + 0.00783272}}], + +Cell[BoxData[ + TagBox[\(\[SkeletonIndicator] ContourGraphics \[SkeletonIndicator]\), + False, + Editable->False]], "Output"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + \(ContourPlot[v, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"], + +Cell[GraphicsData["PostScript", "\<\ +%! +%%Creator: Mathematica +%%AspectRatio: 1 +MathPictureStart +/Mabs { +Mgmatrix idtransform +Mtmatrix dtransform +} bind def +/Mabsadd { Mabs +3 -1 roll add +3 1 roll add +exch } bind def +%% ContourGraphics +%%IncludeResource: font Courier +%%IncludeFont: Courier +/Courier findfont 10 scalefont setfont +% Scaling calculations +0.0192308 0.480769 0.0192308 0.480769 [ +[.01923 -0.0125 -3 -9 ] +[.01923 -0.0125 3 0 ] +[.25962 -0.0125 -9 -9 ] +[.25962 -0.0125 9 0 ] +[.5 -0.0125 -3 -9 ] +[.5 -0.0125 3 0 ] +[.74038 -0.0125 -9 -9 ] +[.74038 -0.0125 9 0 ] +[.98077 -0.0125 -3 -9 ] +[.98077 -0.0125 3 0 ] +[ 0 0 -0.125 0 ] +[-0.0125 .01923 -6 -4.5 ] +[-0.0125 .01923 0 4.5 ] +[-0.0125 .25962 -18 -4.5 ] +[-0.0125 .25962 0 4.5 ] +[-0.0125 .5 -6 -4.5 ] +[-0.0125 .5 0 4.5 ] +[-0.0125 .74038 -18 -4.5 ] +[-0.0125 .74038 0 4.5 ] +[-0.0125 .98077 -6 -4.5 ] +[-0.0125 .98077 0 4.5 ] +[ 0 0 -0.125 0 ] +[ 0 1 .125 0 ] +[ 1 0 .125 0 ] +[ 0 0 0 0 ] +[ 1 1 0 0 ] +] MathScale +% Start of Graphics +1 setlinecap +1 setlinejoin +newpath +0 g +.25 Mabswid +.01923 0 m +.01923 .00625 L +s +[(0)] .01923 -0.0125 0 1 Mshowa +.25962 0 m +.25962 .00625 L +s +[(0.5)] .25962 -0.0125 0 1 Mshowa +.5 0 m +.5 .00625 L +s +[(1)] .5 -0.0125 0 1 Mshowa +.74038 0 m +.74038 .00625 L +s +[(1.5)] .74038 -0.0125 0 1 Mshowa +.98077 0 m +.98077 .00625 L +s +[(2)] .98077 -0.0125 0 1 Mshowa +.125 Mabswid +.06731 0 m +.06731 .00375 L +s +.11538 0 m +.11538 .00375 L +s +.16346 0 m +.16346 .00375 L +s +.21154 0 m +.21154 .00375 L +s +.30769 0 m +.30769 .00375 L +s +.35577 0 m +.35577 .00375 L +s +.40385 0 m +.40385 .00375 L +s +.45192 0 m +.45192 .00375 L +s +.54808 0 m +.54808 .00375 L +s +.59615 0 m +.59615 .00375 L +s +.64423 0 m +.64423 .00375 L +s +.69231 0 m +.69231 .00375 L +s +.78846 0 m +.78846 .00375 L +s +.83654 0 m +.83654 .00375 L +s +.88462 0 m +.88462 .00375 L +s +.93269 0 m +.93269 .00375 L +s +.25 Mabswid +0 0 m +1 0 L +s +0 .01923 m +.00625 .01923 L +s +[(0)] -0.0125 .01923 1 0 Mshowa +0 .25962 m +.00625 .25962 L +s +[(0.5)] -0.0125 .25962 1 0 Mshowa +0 .5 m +.00625 .5 L +s +[(1)] -0.0125 .5 1 0 Mshowa +0 .74038 m +.00625 .74038 L +s +[(1.5)] -0.0125 .74038 1 0 Mshowa +0 .98077 m +.00625 .98077 L +s +[(2)] -0.0125 .98077 1 0 Mshowa +.125 Mabswid +0 .06731 m +.00375 .06731 L +s +0 .11538 m +.00375 .11538 L +s +0 .16346 m +.00375 .16346 L +s +0 .21154 m +.00375 .21154 L +s +0 .30769 m +.00375 .30769 L +s +0 .35577 m +.00375 .35577 L +s +0 .40385 m +.00375 .40385 L +s +0 .45192 m +.00375 .45192 L +s +0 .54808 m +.00375 .54808 L +s +0 .59615 m +.00375 .59615 L +s +0 .64423 m +.00375 .64423 L +s +0 .69231 m +.00375 .69231 L +s +0 .78846 m +.00375 .78846 L +s +0 .83654 m +.00375 .83654 L +s +0 .88462 m +.00375 .88462 L +s +0 .93269 m +.00375 .93269 L +s +.25 Mabswid +0 0 m +0 1 L +s +.01923 .99375 m +.01923 1 L +s +.25962 .99375 m +.25962 1 L +s +.5 .99375 m +.5 1 L +s +.74038 .99375 m +.74038 1 L +s +.98077 .99375 m +.98077 1 L +s +.125 Mabswid +.06731 .99625 m +.06731 1 L +s +.11538 .99625 m +.11538 1 L +s +.16346 .99625 m +.16346 1 L +s +.21154 .99625 m +.21154 1 L +s +.30769 .99625 m +.30769 1 L +s +.35577 .99625 m +.35577 1 L +s +.40385 .99625 m +.40385 1 L +s +.45192 .99625 m +.45192 1 L +s +.54808 .99625 m +.54808 1 L +s +.59615 .99625 m +.59615 1 L +s +.64423 .99625 m +.64423 1 L +s +.69231 .99625 m +.69231 1 L +s +.78846 .99625 m +.78846 1 L +s +.83654 .99625 m +.83654 1 L +s +.88462 .99625 m +.88462 1 L +s +.93269 .99625 m +.93269 1 L +s +.25 Mabswid +0 1 m +1 1 L +s +.99375 .01923 m +1 .01923 L +s +.99375 .25962 m +1 .25962 L +s +.99375 .5 m +1 .5 L +s +.99375 .74038 m +1 .74038 L +s +.99375 .98077 m +1 .98077 L +s +.125 Mabswid +.99625 .06731 m +1 .06731 L +s +.99625 .11538 m +1 .11538 L +s +.99625 .16346 m +1 .16346 L +s +.99625 .21154 m +1 .21154 L +s +.99625 .30769 m +1 .30769 L +s +.99625 .35577 m +1 .35577 L +s +.99625 .40385 m +1 .40385 L +s +.99625 .45192 m +1 .45192 L +s +.99625 .54808 m +1 .54808 L +s +.99625 .59615 m +1 .59615 L +s +.99625 .64423 m +1 .64423 L +s +.99625 .69231 m +1 .69231 L +s +.99625 .78846 m +1 .78846 L +s +.99625 .83654 m +1 .83654 L +s +.99625 .88462 m +1 .88462 L +s +.99625 .93269 m +1 .93269 L +s +.25 Mabswid +1 0 m +1 1 L +s +0 0 m +1 0 L +1 1 L +0 1 L +closepath +clip +newpath +.5 g +.01923 .98077 m +.98077 .98077 L +.98077 .01923 L +.01923 .01923 L +F +0 g +.5 Mabswid +.6 g +.48596 .01923 m +.4844 .08791 L +.47739 .15659 L +.43403 .22527 L +.43132 .22654 L +.36264 .24138 L +.29396 .24501 L +.22527 .24501 L +.15659 .24138 L +.08791 .22654 L +.0857 .22527 L +.04742 .15659 L +.03964 .08791 L +.03781 .01923 L +F +0 g +.48596 .01923 m +.4844 .08791 L +.47739 .15659 L +.43403 .22527 L +.43132 .22654 L +.36264 .24138 L +.29396 .24501 L +.22527 .24501 L +.15659 .24138 L +.08791 .22654 L +.0857 .22527 L +.04742 .15659 L +.03964 .08791 L +.03781 .01923 L +s +.4 g +.08791 .29269 m +.15659 .27785 L +.22527 .27422 L +.29396 .27422 L +.36264 .27785 L +.43132 .29269 L +.43403 .29396 L +.47739 .36264 L +.4844 .43132 L +.48596 .5 L +.4844 .56868 L +.47739 .63736 L +.43403 .70604 L +.43132 .70731 L +.36264 .72215 L +.29396 .72578 L +.22527 .72578 L +.15659 .72215 L +.08791 .70731 L +.0857 .70604 L +.04742 .63736 L +.03964 .56868 L +.03781 .5 L +.03964 .43132 L +.04742 .36264 L +.0857 .29396 L +F +0 g +.08791 .29269 m +.15659 .27785 L +.22527 .27422 L +.29396 .27422 L +.36264 .27785 L +.43132 .29269 L +.43403 .29396 L +.47739 .36264 L +.4844 .43132 L +.48596 .5 L +.4844 .56868 L +.47739 .63736 L +.43403 .70604 L +.43132 .70731 L +.36264 .72215 L +.29396 .72578 L +.22527 .72578 L +.15659 .72215 L +.08791 .70731 L +.0857 .70604 L +.04742 .63736 L +.03964 .56868 L +.03781 .5 L +.03964 .43132 L +.04742 .36264 L +.0857 .29396 L +.08791 .29269 L +s +.6 g +.48596 .98077 m +.4844 .91209 L +.47739 .84341 L +.43403 .77473 L +.43132 .77346 L +.36264 .75862 L +.29396 .75499 L +.22527 .75499 L +.15659 .75862 L +.08791 .77346 L +.0857 .77473 L +.04742 .84341 L +.03964 .91209 L +.03781 .98077 L +F +0 g +.48596 .98077 m +.4844 .91209 L +.47739 .84341 L +.43403 .77473 L +.43132 .77346 L +.36264 .75862 L +.29396 .75499 L +.22527 .75499 L +.15659 .75862 L +.08791 .77346 L +.0857 .77473 L +.04742 .84341 L +.03964 .91209 L +.03781 .98077 L +s +.7 g +.45707 .01923 m +.45212 .08791 L +.43132 .15521 L +.42933 .15659 L +.36264 .20465 L +.29396 .21567 L +.22527 .21567 L +.15659 .20465 L +.08991 .15659 L +.08791 .15521 L +.07087 .08791 L +.06667 .01923 L +F +0 g +.45707 .01923 m +.45212 .08791 L +.43132 .15521 L +.42933 .15659 L +.36264 .20465 L +.29396 .21567 L +.22527 .21567 L +.15659 .20465 L +.08991 .15659 L +.08791 .15521 L +.07087 .08791 L +.06667 .01923 L +s +.3 g +.15659 .31458 m +.22527 .30356 L +.29396 .30356 L +.36264 .31458 L +.42933 .36264 L +.43132 .36402 L +.45212 .43132 L +.45707 .5 L +.45212 .56868 L +.43132 .63598 L +.42933 .63736 L +.36264 .68542 L +.29396 .69644 L +.22527 .69644 L +.15659 .68542 L +.08991 .63736 L +.08791 .63598 L +.07087 .56868 L +.06667 .5 L +.07087 .43132 L +.08791 .36402 L +.08991 .36264 L +F +0 g +.15659 .31458 m +.22527 .30356 L +.29396 .30356 L +.36264 .31458 L +.42933 .36264 L +.43132 .36402 L +.45212 .43132 L +.45707 .5 L +.45212 .56868 L +.43132 .63598 L +.42933 .63736 L +.36264 .68542 L +.29396 .69644 L +.22527 .69644 L +.15659 .68542 L +.08991 .63736 L +.08791 .63598 L +.07087 .56868 L +.06667 .5 L +.07087 .43132 L +.08791 .36402 L +.08991 .36264 L +.15659 .31458 L +s +.7 g +.45707 .98077 m +.45212 .91209 L +.43132 .84479 L +.42933 .84341 L +.36264 .79535 L +.29396 .78433 L +.22527 .78433 L +.15659 .79535 L +.08991 .84341 L +.08791 .84479 L +.07087 .91209 L +.06667 .98077 L +F +0 g +.45707 .98077 m +.45212 .91209 L +.43132 .84479 L +.42933 .84341 L +.36264 .79535 L +.29396 .78433 L +.22527 .78433 L +.15659 .79535 L +.08991 .84341 L +.08791 .84479 L +.07087 .91209 L +.06667 .98077 L +s +.8 g +.42676 .01923 m +.41893 .08791 L +.37227 .15659 L +.36264 .16237 L +.29396 .18453 L +.22527 .18453 L +.15659 .16237 L +.14696 .15659 L +.1003 .08791 L +.09247 .01923 L +F +0 g +.42676 .01923 m +.41893 .08791 L +.37227 .15659 L +.36264 .16237 L +.29396 .18453 L +.22527 .18453 L +.15659 .16237 L +.14696 .15659 L +.1003 .08791 L +.09247 .01923 L +s +.2 g +.15659 .35686 m +.22527 .3347 L +.29396 .3347 L +.36264 .35686 L +.37227 .36264 L +.41893 .43132 L +.42676 .5 L +.41893 .56868 L +.37227 .63736 L +.36264 .64314 L +.29396 .6653 L +.22527 .6653 L +.15659 .64314 L +.14696 .63736 L +.1003 .56868 L +.09247 .5 L +.1003 .43132 L +.14696 .36264 L +F +0 g +.15659 .35686 m +.22527 .3347 L +.29396 .3347 L +.36264 .35686 L +.37227 .36264 L +.41893 .43132 L +.42676 .5 L +.41893 .56868 L +.37227 .63736 L +.36264 .64314 L +.29396 .6653 L +.22527 .6653 L +.15659 .64314 L +.14696 .63736 L +.1003 .56868 L +.09247 .5 L +.1003 .43132 L +.14696 .36264 L +.15659 .35686 L +s +.8 g +.42676 .98077 m +.41893 .91209 L +.37227 .84341 L +.36264 .83763 L +.29396 .81547 L +.22527 .81547 L +.15659 .83763 L +.14696 .84341 L +.1003 .91209 L +.09247 .98077 L +F +0 g +.42676 .98077 m +.41893 .91209 L +.37227 .84341 L +.36264 .83763 L +.29396 .81547 L +.22527 .81547 L +.15659 .83763 L +.14696 .84341 L +.1003 .91209 L +.09247 .98077 L +s +.9 g +.39439 .01923 m +.37815 .08791 L +.36264 .11825 L +.29396 .15309 L +.22527 .15309 L +.15659 .11825 L +.14108 .08791 L +.12484 .01923 L +F +0 g +.39439 .01923 m +.37815 .08791 L +.36264 .11825 L +.29396 .15309 L +.22527 .15309 L +.15659 .11825 L +.14108 .08791 L +.12484 .01923 L +s +.1 g +.15659 .40098 m +.22527 .36614 L +.29396 .36614 L +.36264 .40098 L +.37815 .43132 L +.39439 .5 L +.37815 .56868 L +.36264 .59902 L +.29396 .63386 L +.22527 .63386 L +.15659 .59902 L +.14108 .56868 L +.12484 .5 L +.14108 .43132 L +F +0 g +.15659 .40098 m +.22527 .36614 L +.29396 .36614 L +.36264 .40098 L +.37815 .43132 L +.39439 .5 L +.37815 .56868 L +.36264 .59902 L +.29396 .63386 L +.22527 .63386 L +.15659 .59902 L +.14108 .56868 L +.12484 .5 L +.14108 .43132 L +.15659 .40098 L +s +.9 g +.39439 .98077 m +.37815 .91209 L +.36264 .88175 L +.29396 .84691 L +.22527 .84691 L +.15659 .88175 L +.14108 .91209 L +.12484 .98077 L +F +0 g +.39439 .98077 m +.37815 .91209 L +.36264 .88175 L +.29396 .84691 L +.22527 .84691 L +.15659 .88175 L +.14108 .91209 L +.12484 .98077 L +s +1 g +.34792 .01923 m +.31706 .08791 L +.29396 .10805 L +.22527 .10805 L +.20217 .08791 L +.17131 .01923 L +F +0 g +.34792 .01923 m +.31706 .08791 L +.29396 .10805 L +.22527 .10805 L +.20217 .08791 L +.17131 .01923 L +s +.22527 .41118 m +.29396 .41118 L +.31706 .43132 L +.34792 .5 L +.31706 .56868 L +.29396 .58882 L +.22527 .58882 L +.20217 .56868 L +.17131 .5 L +.20217 .43132 L +F +.22527 .41118 m +.29396 .41118 L +.31706 .43132 L +.34792 .5 L +.31706 .56868 L +.29396 .58882 L +.22527 .58882 L +.20217 .56868 L +.17131 .5 L +.20217 .43132 L +.22527 .41118 L +s +1 g +.34792 .98077 m +.31706 .91209 L +.29396 .89195 L +.22527 .89195 L +.20217 .91209 L +.17131 .98077 L +F +0 g +.34792 .98077 m +.31706 .91209 L +.29396 .89195 L +.22527 .89195 L +.20217 .91209 L +.17131 .98077 L +s +.4 g +.96219 .01923 m +.96036 .08791 L +.95258 .15659 L +.9143 .22527 L +.91209 .22654 L +.84341 .24138 L +.77473 .24501 L +.70604 .24501 L +.63736 .24138 L +.56868 .22654 L +.56597 .22527 L +.52261 .15659 L +.5156 .08791 L +.51404 .01923 L +F +0 g +.96219 .01923 m +.96036 .08791 L +.95258 .15659 L +.9143 .22527 L +.91209 .22654 L +.84341 .24138 L +.77473 .24501 L +.70604 .24501 L +.63736 .24138 L +.56868 .22654 L +.56597 .22527 L +.52261 .15659 L +.5156 .08791 L +.51404 .01923 L +s +.6 g +.56868 .29269 m +.63736 .27785 L +.70604 .27422 L +.77473 .27422 L +.84341 .27785 L +.91209 .29269 L +.9143 .29396 L +.95258 .36264 L +.96036 .43132 L +.96219 .5 L +.96036 .56868 L +.95258 .63736 L +.9143 .70604 L +.91209 .70731 L +.84341 .72215 L +.77473 .72578 L +.70604 .72578 L +.63736 .72215 L +.56868 .70731 L +.56597 .70604 L +.52261 .63736 L +.5156 .56868 L +.51404 .5 L +.5156 .43132 L +.52261 .36264 L +.56597 .29396 L +F +0 g +.56868 .29269 m +.63736 .27785 L +.70604 .27422 L +.77473 .27422 L +.84341 .27785 L +.91209 .29269 L +.9143 .29396 L +.95258 .36264 L +.96036 .43132 L +.96219 .5 L +.96036 .56868 L +.95258 .63736 L +.9143 .70604 L +.91209 .70731 L +.84341 .72215 L +.77473 .72578 L +.70604 .72578 L +.63736 .72215 L +.56868 .70731 L +.56597 .70604 L +.52261 .63736 L +.5156 .56868 L +.51404 .5 L +.5156 .43132 L +.52261 .36264 L +.56597 .29396 L +.56868 .29269 L +s +.4 g +.96219 .98077 m +.96036 .91209 L +.95258 .84341 L +.9143 .77473 L +.91209 .77346 L +.84341 .75862 L +.77473 .75499 L +.70604 .75499 L +.63736 .75862 L +.56868 .77346 L +.56597 .77473 L +.52261 .84341 L +.5156 .91209 L +.51404 .98077 L +F +0 g +.96219 .98077 m +.96036 .91209 L +.95258 .84341 L +.9143 .77473 L +.91209 .77346 L +.84341 .75862 L +.77473 .75499 L +.70604 .75499 L +.63736 .75862 L +.56868 .77346 L +.56597 .77473 L +.52261 .84341 L +.5156 .91209 L +.51404 .98077 L +s +.3 g +.93333 .01923 m +.92913 .08791 L +.91209 .15521 L +.91009 .15659 L +.84341 .20465 L +.77473 .21567 L +.70604 .21567 L +.63736 .20465 L +.57067 .15659 L +.56868 .15521 L +.54788 .08791 L +.54293 .01923 L +F +0 g +.93333 .01923 m +.92913 .08791 L +.91209 .15521 L +.91009 .15659 L +.84341 .20465 L +.77473 .21567 L +.70604 .21567 L +.63736 .20465 L +.57067 .15659 L +.56868 .15521 L +.54788 .08791 L +.54293 .01923 L +s +.7 g +.63736 .31458 m +.70604 .30356 L +.77473 .30356 L +.84341 .31458 L +.91009 .36264 L +.91209 .36402 L +.92913 .43132 L +.93333 .5 L +.92913 .56868 L +.91209 .63598 L +.91009 .63736 L +.84341 .68542 L +.77473 .69644 L +.70604 .69644 L +.63736 .68542 L +.57067 .63736 L +.56868 .63598 L +.54788 .56868 L +.54293 .5 L +.54788 .43132 L +.56868 .36402 L +.57067 .36264 L +F +0 g +.63736 .31458 m +.70604 .30356 L +.77473 .30356 L +.84341 .31458 L +.91009 .36264 L +.91209 .36402 L +.92913 .43132 L +.93333 .5 L +.92913 .56868 L +.91209 .63598 L +.91009 .63736 L +.84341 .68542 L +.77473 .69644 L +.70604 .69644 L +.63736 .68542 L +.57067 .63736 L +.56868 .63598 L +.54788 .56868 L +.54293 .5 L +.54788 .43132 L +.56868 .36402 L +.57067 .36264 L +.63736 .31458 L +s +.3 g +.93333 .98077 m +.92913 .91209 L +.91209 .84479 L +.91009 .84341 L +.84341 .79535 L +.77473 .78433 L +.70604 .78433 L +.63736 .79535 L +.57067 .84341 L +.56868 .84479 L +.54788 .91209 L +.54293 .98077 L +F +0 g +.93333 .98077 m +.92913 .91209 L +.91209 .84479 L +.91009 .84341 L +.84341 .79535 L +.77473 .78433 L +.70604 .78433 L +.63736 .79535 L +.57067 .84341 L +.56868 .84479 L +.54788 .91209 L +.54293 .98077 L +s +.2 g +.90753 .01923 m +.8997 .08791 L +.85304 .15659 L +.84341 .16237 L +.77473 .18453 L +.70604 .18453 L +.63736 .16237 L +.62773 .15659 L +.58107 .08791 L +.57324 .01923 L +F +0 g +.90753 .01923 m +.8997 .08791 L +.85304 .15659 L +.84341 .16237 L +.77473 .18453 L +.70604 .18453 L +.63736 .16237 L +.62773 .15659 L +.58107 .08791 L +.57324 .01923 L +s +.8 g +.63736 .35686 m +.70604 .3347 L +.77473 .3347 L +.84341 .35686 L +.85304 .36264 L +.8997 .43132 L +.90753 .5 L +.8997 .56868 L +.85304 .63736 L +.84341 .64314 L +.77473 .6653 L +.70604 .6653 L +.63736 .64314 L +.62773 .63736 L +.58107 .56868 L +.57324 .5 L +.58107 .43132 L +.62773 .36264 L +F +0 g +.63736 .35686 m +.70604 .3347 L +.77473 .3347 L +.84341 .35686 L +.85304 .36264 L +.8997 .43132 L +.90753 .5 L +.8997 .56868 L +.85304 .63736 L +.84341 .64314 L +.77473 .6653 L +.70604 .6653 L +.63736 .64314 L +.62773 .63736 L +.58107 .56868 L +.57324 .5 L +.58107 .43132 L +.62773 .36264 L +.63736 .35686 L +s +.2 g +.90753 .98077 m +.8997 .91209 L +.85304 .84341 L +.84341 .83763 L +.77473 .81547 L +.70604 .81547 L +.63736 .83763 L +.62773 .84341 L +.58107 .91209 L +.57324 .98077 L +F +0 g +.90753 .98077 m +.8997 .91209 L +.85304 .84341 L +.84341 .83763 L +.77473 .81547 L +.70604 .81547 L +.63736 .83763 L +.62773 .84341 L +.58107 .91209 L +.57324 .98077 L +s +.1 g +.87516 .01923 m +.85892 .08791 L +.84341 .11825 L +.77473 .15309 L +.70604 .15309 L +.63736 .11825 L +.62185 .08791 L +.60561 .01923 L +F +0 g +.87516 .01923 m +.85892 .08791 L +.84341 .11825 L +.77473 .15309 L +.70604 .15309 L +.63736 .11825 L +.62185 .08791 L +.60561 .01923 L +s +.9 g +.63736 .40098 m +.70604 .36614 L +.77473 .36614 L +.84341 .40098 L +.85892 .43132 L +.87516 .5 L +.85892 .56868 L +.84341 .59902 L +.77473 .63386 L +.70604 .63386 L +.63736 .59902 L +.62185 .56868 L +.60561 .5 L +.62185 .43132 L +F +0 g +.63736 .40098 m +.70604 .36614 L +.77473 .36614 L +.84341 .40098 L +.85892 .43132 L +.87516 .5 L +.85892 .56868 L +.84341 .59902 L +.77473 .63386 L +.70604 .63386 L +.63736 .59902 L +.62185 .56868 L +.60561 .5 L +.62185 .43132 L +.63736 .40098 L +s +.1 g +.87516 .98077 m +.85892 .91209 L +.84341 .88175 L +.77473 .84691 L +.70604 .84691 L +.63736 .88175 L +.62185 .91209 L +.60561 .98077 L +F +0 g +.87516 .98077 m +.85892 .91209 L +.84341 .88175 L +.77473 .84691 L +.70604 .84691 L +.63736 .88175 L +.62185 .91209 L +.60561 .98077 L +s +.82869 .01923 m +.79783 .08791 L +.77473 .10805 L +.70604 .10805 L +.68294 .08791 L +.65208 .01923 L +F +.82869 .01923 m +.79783 .08791 L +.77473 .10805 L +.70604 .10805 L +.68294 .08791 L +.65208 .01923 L +s +1 g +.70604 .41118 m +.77473 .41118 L +.79783 .43132 L +.82869 .5 L +.79783 .56868 L +.77473 .58882 L +.70604 .58882 L +.68294 .56868 L +.65208 .5 L +.68294 .43132 L +F +0 g +.70604 .41118 m +.77473 .41118 L +.79783 .43132 L +.82869 .5 L +.79783 .56868 L +.77473 .58882 L +.70604 .58882 L +.68294 .56868 L +.65208 .5 L +.68294 .43132 L +.70604 .41118 L +s +.82869 .98077 m +.79783 .91209 L +.77473 .89195 L +.70604 .89195 L +.68294 .91209 L +.65208 .98077 L +F +.82869 .98077 m +.79783 .91209 L +.77473 .89195 L +.70604 .89195 L +.68294 .91209 L +.65208 .98077 L +s +% End of Graphics +MathPictureEnd +\ +\>"], "Graphics", + ImageSize->{288, 288}, + ImageMargins->{{43, 0}, {0, 0}}, + ImageRegion->{{0, 1}, {0, 1}}, + ImageCache->GraphicsData["Bitmap", "\<\ +CF5dJ6E]HGAYHf4PAg9QL6QYHgon6Ykno_hn?S`2ook>c/mWIfGmoOol005E[;lC4a000<`00IP00V@00c000 +o`0c000c<`0cIP0cV@0cc00co`1V001V<`1VIP1VV@1Vc01Vo`2I002I<`2IIP2IV@2Ic02Io`3<003< +<`3I03>IIIS>IVC>Ic3>Ioc?<03?<@000`40000f00030@0000L00`4i0003 +0@0000@0000H00040@000CH000@1000120000`40000i00030@0003H000<100001`000`40000j0003 +0@0000<0000H00040@000CH000@1000120000`40000g00<1=P030@T000<10000=`00104000450000 +6@020CP00P4900@1>0000`40000f00030@0000L0104g00811P000?l08@0001D0o`4;0@40000E0003 +0@00008000<100002P000`40000900030@0000X000<100002P000`40000:00030@0000X000<10000 +2@000`40000:00030@0000X000<100002P000`40000900030@0000X000<100002P000`40000:0003 +0@0000T000<100002P000`40000:00030@0000X000<100002P000`40000900030@0000800@410000 +5@000`40000200030@0003d000<10000?@000`40000l00030@0003d000<100000P010@40000E0003 +0@000?l01`010@40000>00811@000`40003o00L00@4100003@0010400044008120000`4000050003 +0@0000<000<100001P000`40000900030@0002`000<100002P000`40000500030@0000D000<10000 +1@000`40000400030@0000D000<100001@000`40000600030@0000T000<10000;0000`4000090003 +0@0000H000<1000010000`40000400030@0000H00P4100003@001040004400030@00008000JW2JL9 +Y`47Y`070@RW2:L80@08200=0@P0200800P020080@0^000>0@0800P0200800P0204720090JL8Y`RW +2:L100NW00P12JL9Y`VW0@L900T12E89DPUB2@4025820@09DP5B0E81DP5B034100aB0E81DP5B0E81 +DP48DP080E89DPUB2@462@050@VW2JL01@010@40000=00040@000@@000<100000P001PVW2JL90@NW +00L1Y`RW2:L100P800h100P0200800P020080B`000h100P0200800P020080@P800T12:L8Y`RW2040 +1jL0206W2JL9Y`T11`T02@5B2E89DPUB0@08DP0<0E81DP5B0E81DP5B;`402e81DP5B0E81DP5B0081 +25802049DPUB2E811PT01@6W2JL900D00@4100003@001040004400030@00008000JW2JL9Y`47Y`07 +0@RW2:L80@09200=0@0800P0200800P00@0/000>0@P0200800P02008004820090JL8Y`RW2:L100NW +00P12JL9Y`VW0@L900T12E89DPUB2@402E80305B0E81DP5B0E81DRl100UB0E81DP5B0E800P49DP08 +0E89DPUB2@462@050@VW2JL01@010@40000=00040@000@@000<100000P001PVW2JL90@NW00L1Y`RW +2:L100T800h1200800P0200800P00BX000l1200800P0200800P0204020P02@48Y`RW2:L80@07Y`08 +0JL9Y`VW2@472@090E89DPUB2E8100UB0P402e81DP5B0E81DP5B02d100aB0E81DP5B0E81DP49DP08 +0@UB2E89DP462@050JL9Y`T01@010@40000>00811@000`4000020006Y`VW2JL11jL02048Y`RW2:L1 +20P03P40200800P0200800P1:P003`40200800P0200800P00@07200:0@RW2:L8Y`RW0@NW00P12JL9 +Y`VW0@L900X12E89DPUB2E812580305B0E81DP5B0E81DRd100]B0E81DP5B0E81DP020@QB00T12E89 +DPUB2@401PT01@49Y`VW00D00@4100005@000`40000200062JL9Y`T11jL0206W2:L8Y`P120P03`48 +00P0200800P020080@0X000?0@0800P0200800P0200100P800X1Y`RW2:L8Y`P11jL0206W2JL9Y`T1 +1`T02P5B2E89DPUB2@48DP8100]B0E81DP5B0E81DP0[0@0>DP5B0E81DP5B0E81DP48DP090E89DPUB +2E8100H900D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@NW00P12:L8Y`RW0@P800l100P0 +200800P020080040:0003`4800P0200800P020080@08200:0@RW2:L8Y`RW0@NW00P12JL9Y`VW0@L9 +00X12E89DPUB2E8125803P5B0E81DP5B0E81DP5B:`402e81DP5B0E81DP5B008125802@49DPUB2E89 +0@062@050@VW2JL01@010@40000E00030@00008000H9Y`VW2@47Y`080JL8Y`RW2049200?0@0800P0 +200800P0200102L000l100P0200800P02008004020P02P6W2:L8Y`RW2047Y`080JL9Y`VW2@472@0: +0E89DPUB2E890@UB00`1DP5B0E81DP5B0E8[0@0;DP5B0E81DP5B0E800P49DP090E89DPUB2E8100H9 +00D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@NW00P12:L8Y`RW0@T800l1200800P02008 +00P020409P004040200800P0200800P02048200:0@RW2:L8Y`RW0@NW00P12JL9Y`VW0@L900X12E89 +DPUB2E812E820@0;DP5B0E81DP5B0E80:@403U81DP5B0E81DP5B0E812E802@49DPUB2E890@062@05 +0@VW2JL01@010@40000E00030@00008000H9Y`VW2@48Y`070@RW2:L80@09200@0@0800P0200800P0 +20080BD000l1200800P0200800P020402@P02@6W2:L8Y`RW0@07Y`0:0@VW2JL9Y`VW0@L900T12E89 +DPUB2@402E803P5B0E81DP5B0E81DP5B:@402e81DP5B0E81DP5B00812E80205B2E89DPT11`T01@6W +2JL900D00@4100005@000`4000020006Y`VW2JL12:L01`6W2:L8Y`402@P0404800P0200800P02008 +004T000@0@P0200800P0200800P00@T800T12:L8Y`RW20401jL02P6W2JL9Y`VW2@472@090E89DPUB +2E8100UB0P403E81DP5B0E81DP5B0E809`403U81DP5B0E81DP5B0E812E802049DPUB2E811`T01@49 +Y`VW00D00@4100005@000`40000200062JL9Y`T12:L01`48Y`RW20402PP0404800P0200800P02008 +004S000@0@0800P0200800P020080@T800T1Y`RW2:L8Y`401jL02P49Y`VW2JL9Y`472@090@UB2E89 +DPT100YB0P402e81DP5B0E81DP5B02L100iB0E81DP5B0E81DP5B0@YB00P1DPUB2E890@L900D1Y`VW +2@0500410@0001D00P430006Y`VW2JL12:L01`6W2:L8Y`402PP04040200800P0200800P0204S000@ +0@P0200800P0200800P00@T800T12:L8Y`RW20401jL02P6W2JL9Y`VW2@472@090E89DPUB2E8100YB +00h1DP5B0E81DP5B0E81DRL100]B0E81DP5B0E81DP020@YB00P12E89DPUB0@L900D12JL9Y`040081 +0@0001D000<100000P001PVW2JL90@RW00L12:L8Y`P100X80141200800P0200800P020080@0Q000@ +0@P0200800P0200800P00@X800T1Y`RW2:L8Y`401jL02P49Y`VW2JL9Y`472@090@UB2E89DPT100YB +0P403E81DP5B0E81DP5B0E809@403U81DP5B0E81DP5B0E812U80205B2E89DPT11`T01@6W2JL900D0 +0@4100005@000`4000020006Y`VW2JL12:L0206W2:L8Y`P12@P04@40200800P0200800P020010240 +010100P0200800P0200800P12@P02P6W2:L8Y`RW2047Y`0:0JL9Y`VW2JL90@L900X1DPUB2E89DPT1 +2E803P5B0E81DP5B0E81DP5B9@403E81DP5B0E81DP5B0E800P49DP090E89DPUB2E8100L900D12JL9 +Y`0500410@0001D000<100000P001PVW2JL90@RW00P12:L8Y`RW0@T80181200800P0200800P02008 +004O000A0@0800P0200800P0200800402@P02P48Y`RW2:L8Y`47Y`0:0@VW2JL9Y`VW0@L900X12E89 +DPUB2E812E820@0=DP5B0E81DP5B0E81DP0S0@0@DP5B0E81DP5B0E81DP5B0@UB00T12E89DPUB2@40 +1`T01@6W2JL900D00@4100005@000`4000020006Y`VW2JL12:L0206W2:L8Y`P12PP04@4800P02008 +00P0200800P101l00141200800P0200800P020080@09200:0JL8Y`RW2:L80@NW00X1Y`VW2JL9Y`T1 +1`T02P5B2E89DPUB2@4:DP8100eB0E81DP5B0E81DP5B02<100iB0E81DP5B0E81DP5B0@YB00T1DPUB +2E89DP401`T01@49Y`VW00D00@4100005@000`40000200062JL9Y`T12:L02048Y`RW2:L12PP04P40 +200800P0200800P020080Ad00141200800P0200800P020080@0:200:0@RW2:L8Y`RW0@NW00X12JL9 +Y`VW2JL11`T02P49DPUB2E89DP4:DP0@0E81DP5B0E81DP5B0E81DR4100eB0E81DP5B0E81DP5B0081 +2U802@49DPUB2E890@072@050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`48Y`080JL8Y`RW +204:200B0@P0200800P0200800P020017@004@40200800P0200800P0200100X800X1Y`RW2:L8Y`P1 +1jL02P6W2JL9Y`VW2@472@0:0E89DPUB2E890@YB0P403E81DP5B0E81DP5B0E808@404581DP5B0E81 +DP5B0E81DP4:DP090E89DPUB2E8100L900D12JL9Y`0500410@0001D000<100000P001PVW2JL90@RW +00T12:L8Y`RW20402PP04P4800P0200800P0200800P00A/0018100P0200800P0200800P02049200; +0JL8Y`RW2:L8Y`401jL02P49Y`VW2JL9Y`472@0;0@UB2E89DPUB2@402U820@0=DP5B0E81DP5B0E81 +DP0O0@0?DP5B0E81DP5B0E81DP5B00812E802P5B2E89DPUB2@472@050JL9Y`T01@010@40000E0003 +0@00008000JW2JL9Y`48Y`090JL8Y`RW2:L100X801<100P0200800P0200800P0200101P00P404@08 +00P0200800P0200800P100X800X12:L8Y`RW2:L12:L02P6W2JL9Y`VW2@482@0:0@UB2E89DPUB0@YB +0101DP5B0E81DP5B0E81DP5B7@403e81DP5B0E81DP5B0E81DP020@YB00T12E89DPUB2@4020T01@49 +Y`VW00D00@4100005@000`40000200062JL9Y`T12JL02@6W2:L8Y`RW0@0:200B0@0800P0200800P0 +200800P00P4E000D0@P0200800P0200800P020080049200;0@RW2:L8Y`RW20402:L02P49Y`VW2JL9 +Y`482@0;0E89DPUB2E89DP402U80405B0E81DP5B0E81DP5B0E8K0@0BDP5B0E81DP5B0E81DP5B0E81 +2E802P49DPUB2E89DP482@050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`49Y`0:0@RW2:L8 +Y`RW0@T801D1200800P0200800P0200800P020404`00504800P0200800P0200800P020012@P03048 +Y`RW2:L8Y`RW0@RW00X1Y`VW2JL9Y`T120T03049DPUB2E89DPUB0@UB0P404E81DP5B0E81DP5B0E81 +DP5B01L1019B0E81DP5B0E81DP5B0E81DP49DP0;0@UB2E89DPUB2@4020T01@49Y`VW00D00@410000 +5@000`40000200072JL9Y`VW0@08Y`0;0JL8Y`RW2:L8Y`402@P0504800P0200800P0200800P02008 +4`4050P0200800P0200800P0200800P12@P02`6W2:L8Y`RW2:L100VW00/12JL9Y`VW2JL90@082@0< +0@UB2E89DPUB2E812E820@0ADP5B0E81DP5B0E81DP5B0E805@404E81DP5B0E81DP5B0E81DP5B0081 +25803049DPUB2E89DPUB0@L900H12JL9Y`T500410@0001D000<100000P001jL9Y`VW2@402:L02`48 +Y`RW2:L8Y`P100T803X100P0200800P0200800P0200800P0200800P0200800P0200800P0200800P0 +200800P0200800P12@P0306W2:L8Y`RW2:L80@VW00/1Y`VW2JL9Y`VW0@082@0<0E89DPUB2E89DPT1 +2E80>05B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B +0P49DP0;0E89DPUB2E89DP4020T01P6W2JL9Y`D00@4100005@020@<000L9Y`VW2JL100VW00/12:L8 +Y`RW2:L80@09200i0@0800P0200800P0200800P0200800P0200800P0200800P0200800P0200800P0 +200800P0200100P800d1Y`RW2:L8Y`RW2:L100VW00/12JL9Y`VW2JL90@082@0=0@UB2E89DPUB2E89 +0@09DP0i0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B +0E8100QB00`1DPUB2E89DPUB2@482@060@VW2JL910020@40000E00030@00008000NW2JL9Y`T100VW +00`1Y`RW2:L8Y`RW2048208103@0200800P0200800P0200800P0200800P0200800P0200800P02008 +00P0200800P020080P49200<0@RW2:L8Y`RW2:L12ZL02`6W2JL9Y`VW2JL100T900d12E89DPUB2E89 +DPT100QB0P400@UB2E89DPUB2E89 +DP4:DP<102]B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00<12e803@49 +DPUB2E89DPUB2@402@T01P6W2JL9Y`D00@4100005@000`40000200072JL9Y`VW0@09Y`0>0@RW2:L8 +Y`RW2:L8Y`4<208102P800P0200800P0200800P0200800P0200800P0200800P0200800P00P4=200= +0JL8Y`RW2:L8Y`RW0@0:Y`0<0JL9Y`VW2JL9Y`T12PT03P49DPUB2E89DPUB2E812e820@0YDP5B0E81 +DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E800P40@UB2E89DPUB2E89DP492@06 +0@VW2JL91@010@40000E00030@00008000NW2JL9Y`T100ZW00h12:L8Y`RW2:L8Y`RW0@d80P409008 +00P0200800P0200800P0200800P0200800P0200800P020813PP03P6W2:L8Y`RW2:L8Y`P12ZL03049 +Y`VW2JL9Y`VW0@X900l1DPUB2E89DPUB2E89DP4035830@0SDP5B0E81DP5B0E81DP5B0E81DP5B0E81 +DP5B0E81DP5B0E800`4=DP0?0@UB2E89DPUB2E89DPT100T900H1Y`VW2JL500410@0001D000<10000 +0P001`VW2JL9Y`402ZL03P6W2:L8Y`RW2:L8Y`P13`P20@0P200800P0200800P0200800P0200800P0 +200800P020020@l800l1Y`RW2:L8Y`RW2:L8Y`402ZL0306W2JL9Y`VW2JL90@X900l12E89DPUB2E89 +DPUB2@403U820@0QDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00813e803P5B2E89DPUB +2E89DPT12PT01P49Y`VW2@D00@4100005@000`4000020008Y`VW2JL9Y`49Y`0?0@RW2:L8Y`RW2:L8 +Y`P101080P40700800P0200800P0200800P0200800P0200800P20A4800h12:L8Y`RW2:L8Y`RW0@^W +00d12JL9Y`VW2JL9Y`T100X900l12E89DPUB2E89DPUB2@403e830@0KDP5B0E81DP5B0E81DP5B0E81 +DP5B0E81DP5B00<145803`5B2E89DPUB2E89DPUB0@092@070@VW2JL9Y`0500410@0001D000<10000 +0P0020VW2JL9Y`T12JL0406W2:L8Y`RW2:L8Y`RW204A208101P800P0200800P0200800P0200800P0 +20020A8800l12:L8Y`RW2:L8Y`RW20402jL03@6W2JL9Y`VW2JL9Y`402PT0405B2E89DPUB2E89DPUB +2@4@DP8101UB0E81DP5B0E81DP5B0E81DP5B0E81DP5B00814E80405B2E89DPUB2E89DPUB2@492@07 +0JL9Y`VW2@0500410@0001D000<100000P002:L9Y`VW2JL12ZL0406W2:L8Y`RW2:L8Y`RW204B2081 +01@0200800P0200800P0200800P020814`P04048Y`RW2:L8Y`RW2:L8Y`4;Y`0=0@VW2JL9Y`VW2JL9 +0@0:2@0A0@UB2E89DPUB2E89DPUB2@404E830@0CDP5B0E81DP5B0E81DP5B0E81DP030A9B0141DPUB +2E89DPUB2E89DPUB0@092@070@VW2JL9Y`0500410@0001D000<100000P0020VW2JL9Y`T12ZL04048 +Y`RW2:L8Y`RW2:L8Y`4D21@15@P03`6W2:L8Y`RW2:L8Y`RW0@0PP20@0?Y`RW2:L8Y`RW2:L8 +Y`P100bW00d12JL9Y`VW2JL9Y`T100/90141DPUB2E89DPUB2E89DPUB0@0iDP8100h9DPUB2E89DPUB +2E89DP812PT01`49Y`VW2JL01@010@40000E00030@00008000T9Y`VW2JL9Y`402jL03`48Y`RW2:L8 +Y`RW2:L8Y`030C@80`403PRW2:L8Y`RW2:L8Y`RW0P4Y`0?0JL9Y`VW2JL9Y`VW2JL100d901412E89DPUB2E89DPUB2E89DP030BiB0`403`UB2E89DPUB +2E89DPUB2@020@`900P1Y`VW2JL9Y`@00P4100005@000`400002000:2JL9Y`VW2JL90@fW0181Y`RW +2:L8Y`RW2:L8Y`RW2:L30BP80`404`RW2:L8Y`RW2:L8Y`RW2:L8Y`403ZL04@6W2JL9Y`VW2JL9Y`VW +2JL100d901<12E89DPUB2E89DPUB2E89DPUB00<1:5830@0B2E89DPUB2E89DPUB2E89DPT13@T02@6W +2JL9Y`VW2@0500410@0001D000<100000P002ZL9Y`VW2JL9Y`4>Y`0D0JL8Y`RW2:L8Y`RW2:L8Y`RW +2:L40B480`404`RW2:L8Y`RW2:L8Y`RW2:L8Y`P00P4>Y`0B0JL9Y`VW2JL9Y`VW2JL9Y`T13PT20@0C +DPUB2E89DPUB2E89DPUB2E89DP030B9B0`4050UB2E89DPUB2E89DPUB2E89DPT13PT02@49Y`VW2JL9 +Y`0500410@0001D000<100000P002`VW2JL9Y`VW2JL100jW0P405@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +20030A/80`405PRW2:L8Y`RW2:L8Y`RW2:L8Y`RW204@Y`0C0@VW2JL9Y`VW2JL9Y`VW2JL90@0?2@0F +0E89DPUB2E89DPUB2E89DPUB2E89DP<175830@0D2E89DPUB2E89DPUB2E89DPUB2E820@h900X12JL9 +Y`VW2JL91@010@40000E00030@00008000bW2JL9Y`VW2JL9Y`4?Y`0H0@RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L80`4E20<101H8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0P4@Y`0E0@VW2JL9Y`VW2JL9Y`VW2JL9 +Y`T100l901P1DPUB2E89DPUB2E89DPUB2E89DPUB2E830AIB0`405`UB2E89DPUB2E89DPUB2E89DPUB +2E81010900X1Y`VW2JL9Y`VW1@010@40000E00030@00008000`9Y`VW2JL9Y`VW2@4@Y`0J0@RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`PE0@0I2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@0AY`0F0@VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW0A090P4060UB2E89DPUB2E89DPUB2E89DPUB2E89DQH101T9DPUB2E89DPUB +2E89DPUB2E89DPUB2E81010900/1Y`VW2JL9Y`VW2@0500410@0001D000<100000P003JL9Y`VW2JL9 +Y`VW2@404:L20@14Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`4BY`0G0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`404@T0A049DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +0P4A2@0;0@VW2JL9Y`VW2JL01@010@40000E00030@00008000h9Y`VW2JL9Y`VW2JL90A6W0441Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +20020A:W01T1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL101490P40@E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT1018900`12JL9Y`VW2JL9 +Y`T500410@0001D000<100000P003ZL9Y`VW2JL9Y`VW2JL14ZL0@06W2:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW204CY`0J0JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2@4C2@100E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB +2E89DPUB2E89DPUB2E89DPUB2E890A8900d12JL9Y`VW2JL9Y`VW00D00@4100005@000`400002000? +2JL9Y`VW2JL9Y`VW2JL101:W0P40?0RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80ABW01/12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@404`T0?05B +2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP81 +4`T03@6W2JL9Y`VW2JL9Y`T01@010@40000E00030@00008000nW2JL9Y`VW2JL9Y`VW2@405:L0>@48 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`020ABW +01`12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL150T20@0i2E89DPUB2E89DPUB2E89DPUB2E89DPUB +2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E8101@900h1Y`VW2JL9Y`VW2JL9Y`D00@410000 +5@000`400002000@2JL9Y`VW2JL9Y`VW2JL90ABW1040<:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20@15JL07P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0AD9 +0`40<@UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT0104E2@0> +0@VW2JL9Y`VW2JL9Y`T500410@0001D000<100000P004JL9Y`VW2JL9Y`VW2JL9Y`T101NW1P4090RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`H16JL07`6W2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`405`T60@0UDPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP060AP9 +00l12JL9Y`VW2JL9Y`VW2JL01@010@40000E00810`004@VW2JL9Y`VW2JL9Y`VW2JL101fW1P406:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20H17ZL0806W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T1 +7@T60@0I2E89DPUB2E89DPUB2E89DPUB2E89DPUB2@060Ah900l1Y`VW2JL9Y`VW2JL9Y`T010020@40 +000E00030@00008001:W2JL9Y`VW2JL9Y`VW2JL9Y`4RYaP18jL08P6W2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2@4R2AT18`T0406W2JL9Y`VW2JL9Y`VW2JL500410@0001D000<100000P004PVW +2JL9Y`VW2JL9Y`VW2JL90EfW02812JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1GPT04049 +Y`VW2JL9Y`VW2JL9Y`T500410@0001D000<100000P004jL9Y`VW2JL9Y`VW2JL9Y`VW2@40FjL09049 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0E`901412JL9Y`VW2JL9Y`VW2JL9Y`050041 +0@0001D000<100000P004PVW2JL9Y`VW2JL9Y`VW2JL9Y`<1EJL40@0T2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW0`5E2@@10149Y`VW2JL9Y`VW2JL9Y`VW2@0500410@0001D000<10000 +0P005JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`060DVW1P40:jL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL01P592@H101FW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL01@010@40000E0003 +0@00008001/9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T01P4mY`H103L9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900H1?@T60@0K2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL900D00@4100005@000`400002000QY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW00d19:L<0@13Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`0<0BD930408JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`0500410@0001D000<100000P00;PVW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JLT0@1K2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@0U0@0]2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900D00@4100005@000`400002003o +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW00D00@4100005@000`400002003o2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900D00@410000 +0P020@@000<100000P030@D000<100000P00ojL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`0500410@00000500400040 +2`000`40000200810`00o`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@0400810@000005004000402`000`4000020003 +0@0000800?nW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL01@010@4000001@01000100P00`4500030@0000800?l9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`T01@010@4000001@01000100P000<100001@000`400002003oY`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW00D00@41000000D00@000@0800030@0000D000<100000P00;PVW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JLT0@1K2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2@0U0@0]2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900D00@410000 +0P020@T0104400030@00008002:W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9304T2@`1 +04BW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2@/19JL<0@0QY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00D00@410000 +5@000`400002000N2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW104l2@@103`9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL40CbW10407@VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900D00@4100005@000`400002000IY`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`050D@91@40W +6@4TY`0?0JL9Y`VW2JL9Y`VW2JL900D00@4100005@020@<0016W2JL9Y`VW2JL9Y`VW2JL90@0M2@H1 +01P9DPUB2E89DPUB2E89DPUB2E89DPUB2E860Al901l1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL101fW1P406JL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L01P4NY`0?0@VW2JL9Y`VW2JL9Y`VW00@0 +0P4100005@000`400002000@2JL9Y`VW2JL9Y`VW2JL90AP91P409589DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2@H16@T07P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0ARW1P409@RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P01P4IY`0>0@VW2JL9Y`VW2JL9Y`T50041 +0@0001D000<100000P004:L9Y`VW2JL9Y`VW2JL9Y`4D2@@10309DPUB2E89DPUB2E89DPUB2E89DPUB +2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E840AH901d12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +0@0EY`<1036W2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW00@1 +5JL03P6W2JL9Y`VW2JL9Y`VW1@010@40000E00030@00008000l9Y`VW2JL9Y`VW2JL9Y`4050T0>@5B +2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2@020A@9 +01`1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T15:L20@0iY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P101FW00d1Y`VW2JL9Y`VW2JL900D00@410000 +5@000`400002000>Y`VW2JL9Y`VW2JL9Y`4C2@8103aB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP4D2@0J0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2@4DY`0l0@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L80P4CY`0=0@VW2JL9Y`VW2JL9Y`0500410@0001D000<100000P003PVW2JL9Y`VW2JL9Y`T1 +4PT0@049DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DP4D2@0I0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@0CY`100@RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0A>W00`12JL9Y`VW2JL9 +Y`T500410@0001D000<100000P003JL9Y`VW2JL9Y`VW2@404PT0@@49DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB00814PT06049Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW0A:W0P40@@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L101:W00`1Y`VW2JL9Y`VW2JL500410@0001D000<10000 +0P003@VW2JL9Y`VW2JL9Y`4040T20@0G2E89DPUB2E89DPUB2E89DPUB2E89DPT05@4060UB2E89DPUB +2E89DPUB2E89DPUB2E890A8901L12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@0AY`0H0JL8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW5P405PRW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L20A6W00/1Y`VW2JL9Y`VW2@050041 +0@0001D000<100000P003:L9Y`VW2JL9Y`VW0A0901L1DPUB2E89DPUB2E89DPUB2E89DPUB2@030AEB +0`405PUB2E89DPUB2E89DPUB2E89DPUB2@4B2@0E0@VW2JL9Y`VW2JL9Y`VW2JL9Y`T1012W0P405JL8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`030AH80`405PRW2:L8Y`RW2:L8Y`RW2:L8Y`RW204@Y`0;0@VW2JL9 +Y`VW2JL01@010@40000E00030@00008000/9Y`VW2JL9Y`VW0@0@2@0E0E89DPUB2E89DPUB2E89DPUB +2E8900<16e830@0C2E89DPUB2E89DPUB2E89DPUB2@020A0901@1Y`VW2JL9Y`VW2JL9Y`VW2JL90A2W +01D12:L8Y`RW2:L8Y`RW2:L8Y`RW2:L00`4L20<101@8Y`RW2:L8Y`RW2:L8Y`RW2:L80A2W00X12JL9 +Y`VW2JL91@010@40000E00030@00008000^W2JL9Y`VW2JL90@0>2@81015B2E89DPUB2E89DPUB2E89 +DP040B5B0`404`UB2E89DPUB2E89DPUB2E89DP4040T04`6W2JL9Y`VW2JL9Y`VW2JL9Y`403jL04`48 +Y`RW2:L8Y`RW2:L8Y`RW2:L00`4R20<10148Y`RW2:L8Y`RW2:L8Y`RW20020@jW00X1Y`VW2JL9Y`VW +1@010@40000E00030@00008000X9Y`VW2JL9Y`T13PT04@49DPUB2E89DPUB2E89DPUB00<1:5830@0@ +2E89DPUB2E89DPUB2E89DP813PT04P49Y`VW2JL9Y`VW2JL9Y`VW0@jW0P4040RW2:L8Y`RW2:L8Y`RW +2:L30BP80`404@RW2:L8Y`RW2:L8Y`RW2:L100jW00T1Y`VW2JL9Y`T01@010@40000E00030@000080 +00ZW2JL9Y`VW2JL13@T03`49DPUB2E89DPUB2E89DP030BiB0`4040UB2E89DPUB2E89DPUB2@4>2@0A +0@VW2JL9Y`VW2JL9Y`VW2@403JL0406W2:L8Y`RW2:L8Y`RW2:L30Bh80`403`RW2:L8Y`RW2:L8Y`RW +0@0=Y`090@VW2JL9Y`VW00D00@4100005@020@<000T9Y`VW2JL9Y`4030T20@0=2E89DPUB2E89DPUB +2@020CAB0P403e89DPUB2E89DPUB2E890@0>2@0?0@VW2JL9Y`VW2JL9Y`T100fW00l1Y`RW2:L8Y`RW +2:L8Y`P00P4d208100fW2:L8Y`RW2:L8Y`RW00813:L02049Y`VW2JL910020@40000E00030@000080 +00VW2JL9Y`VW2@402`T0405B2E89DPUB2E89DPUB2@4hDP8100d9DPUB2E89DPUB2E89008130T03`6W +2JL9Y`VW2JL9Y`VW0@0;Y`8100nW2:L8Y`RW2:L8Y`RW2040>0P0406W2:L8Y`RW2:L8Y`RW204;Y`08 +0JL9Y`VW2JL500410@0001D000<100000P0020VW2JL9Y`T12PT20@0?DPUB2E89DPUB2E89DPT103]B +01012E89DPUB2E89DPUB2E8130T03@6W2JL9Y`VW2JL9Y`402jL04@48Y`RW2:L8Y`RW2:L8Y`P103X8 +00l1Y`RW2:L8Y`RW2:L8Y`P00P4:Y`070JL9Y`VW2@0500410@0001D000<100000P002:L9Y`VW2JL1 +2PT0405B2E89DPUB2E89DPUB2@4DDQ@15E803`49DPUB2E89DPUB2E890@0<2@0=0@VW2JL9Y`VW2JL9 +0@0;Y`0@0JL8Y`RW2:L8Y`RW2:L80A<85@4D200@0JL8Y`RW2:L8Y`RW2:L80@ZW00L12JL9Y`VW00D0 +0@4100005@000`40000200082JL9Y`VW2@4:2@0@0@UB2E89DPUB2E89DPUB0A9B0`404e81DP5B0E81 +DP5B0E81DP5B0E800P4CDP0@0E89DPUB2E89DPUB2E890@/900d1Y`VW2JL9Y`VW2JL100ZW0141Y`RW +2:L8Y`RW2:L8Y`RW0@0A208101D0200800P0200800P0200800P020000P4B200A0@RW2:L8Y`RW2:L8 +Y`RW20402JL01`6W2JL9Y`T01@010@40000E00030@00008000RW2JL9Y`VW0@T901012E89DPUB2E89 +DPUB2E814E820@0GDP5B0E81DP5B0E81DP5B0E81DP5B0E800`4BDP0?0E89DPUB2E89DPUB2E8100/9 +00d12JL9Y`VW2JL9Y`T100ZW01012:L8Y`RW2:L8Y`RW2:L140P20@0I200800P0200800P0200800P0 +200800P020020A4801012:L8Y`RW2:L8Y`RW2:L12JL01`49Y`VW2JL01@010@40000E00030@000080 +00P9Y`VW2JL90@T900l1DPUB2E89DPUB2E89DP4045830@0KDP5B0E81DP5B0E81DP5B0E81DP5B0E81 +DP5B00814E803P5B2E89DPUB2E89DPT12`T03@6W2JL9Y`VW2JL9Y`402ZL03`6W2:L8Y`RW2:L8Y`RW +0@0?208101d0200800P0200800P0200800P0200800P0200800020A0800l12:L8Y`RW2:L8Y`RW2040 +2JL01`6W2JL9Y`T01@010@40000E00030@00008000NW2JL9Y`T100X900h12E89DPUB2E89DPUB0@mB +0P407e81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E800`4?DP0?0@UB2E89DPUB2E89DPT100X9 +00`12JL9Y`VW2JL9Y`4:Y`0?0JL8Y`RW2:L8Y`RW2:L100h80P408@P0200800P0200800P0200800P0 +200800P0200800P020020@l800h12:L8Y`RW2:L8Y`RW0@ZW00H1Y`VW2JL500410@0001D000<10000 +0P001`VW2JL9Y`402PT03P5B2E89DPUB2E89DPT13E830@0SDP5B0E81DP5B0E81DP5B0E81DP5B0E81 +DP5B0E81DP5B0E800P4>DP0>0@UB2E89DPUB2E89DP4:2@0<0JL9Y`VW2JL9Y`T12ZL03`48Y`RW2:L8 +Y`RW2:L80@0<208102D0200800P0200800P0200800P0200800P0200800P0200800P000813@P03`6W +2:L8Y`RW2:L8Y`RW0@09Y`060@VW2JL91@010@40000E00030@00008000NW2JL9Y`T100T900h1DPUB +2E89DPUB2E890@aB0P409e81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP030@eB +00d12E89DPUB2E89DPT100X900`12JL9Y`VW2JL9Y`4:Y`0>0JL8Y`RW2:L8Y`RW204;208102T800P0 +200800P0200800P0200800P0200800P0200800P0200800P020020@`800h1Y`RW2:L8Y`RW2:L80@VW +00H1Y`VW2JL500410@0001D000<100000P001`VW2JL9Y`402@T03@49DPUB2E89DPUB2@402e830@0[ +DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@]B00h1DPUB2E89DPUB +2E890@T900`1Y`VW2JL9Y`VW2@49Y`0>0JL8Y`RW2:L8Y`RW204:208102d0200800P0200800P02008 +00P0200800P0200800P0200800P0200800P020000P4;200=0JL8Y`RW2:L8Y`RW0@09Y`060@VW2JL9 +1@010@40000E00030@00008000NW2JL9Y`T100T900d1DPUB2E89DPUB2E8100UB0P40;e81DP5B0E81 +DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00<12U803@5B2E89DPUB2E89DP40 +2PT02`6W2JL9Y`VW2JL100VW00h12:L8Y`RW2:L8Y`RW0@P80P40<@P0200800P0200800P0200800P0 +200800P0200800P0200800P0200800P0200800P00P4:200=0JL8Y`RW2:L8Y`RW0@08Y`060JL9Y`VW +1@010@40000E00030@00008000L9Y`VW2JL100T900`12E89DPUB2E89DP48DP<103=B0E81DP5B0E81 +DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E800P49DP0<0E89DPUB2E89DPT1 +2PT02`49Y`VW2JL9Y`T100VW00d1Y`RW2:L8Y`RW2:L100P803H100P0200800P0200800P0200800P0 +200800P0200800P0200800P0200800P0200800P020020@P800d12:L8Y`RW2:L8Y`P100RW00H12JL9 +Y`T500410@0001D00P430007Y`VW2JL90@092@0;0E89DPUB2E89DP402E820@0eDP5B0E81DP5B0E81 +DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E800P48DP0=0@UB2E89DPUB2E89 +0@092@0;0JL9Y`VW2JL9Y`402:L03@6W2:L8Y`RW2:L8Y`402@P0>@4800P0200800P0200800P02008 +00P0200800P0200800P0200800P0200800P0200800P020080@08200<0@RW2:L8Y`RW2:L12:L01P6W +2JL9Y`@00P4100005@000`40000200072JL9Y`VW0@082@0;0E89DPUB2E89DP402E820@0hDP5B0E81 +DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP49DP0<0@UB2E89 +DPUB2E812@T02`49Y`VW2JL9Y`T100RW00`12:L8Y`RW2:L8Y`49200j0@P0200800P0200800P02008 +00P0200800P0200800P0200800P0200800P0200800P0200800P00@T800/12:L8Y`RW2:L80@08Y`06 +0@VW2JL91@010@40000E00030@00008000NW2JL9Y`T100P900/12E89DPUB2E890@09DP0D0E81DP5B +0E81DP5B0E81DP5B0E8C0@0DDP5B0E81DP5B0E81DP5B0E81DP49DP0;0@UB2E89DPUB2@402@T02`6W +2JL9Y`VW2JL100RW00`1Y`RW2:L8Y`RW2049200C0@0800P0200800P0200800P0200D0@0D00P02008 +00P0200800P020080048200<0JL8Y`RW2:L8Y`P11jL01P6W2JL9Y`D00@4100005@000`4000020006 +2JL9Y`T12@T02P5B2E89DPUB2@49DP0D0E81DP5B0E81DP5B0E81DP5B0E8E0@0ADP5B0E81DP5B0E81 +DP5B0E800P49DP0<0E89DPUB2E89DPT120T02P49Y`VW2JL9Y`48Y`0<0JL8Y`RW2:L8Y`P12@P05040 +200800P0200800P0200800P150005040200800P0200800P0200800P12@P02`6W2:L8Y`RW2:L100RW +00D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@T900T12E89DPUB2@402U820@0?DP5B0E81 +DP5B0E81DP5B01T1015B0E81DP5B0E81DP5B0E81DP020@UB00/1DPUB2E89DPUB0@082@0:0JL9Y`VW +2JL90@RW00/12:L8Y`RW2:L80@0:200A0@P0200800P0200800P020000P4F000D0@0800P0200800P0 +200800P02049200:0JL8Y`RW2:L80@RW00D12JL9Y`0500410@0001D000<100000P001PVW2JL90@P9 +00T12E89DPUB2@402U820@0?DP5B0E81DP5B0E81DP5B01d1011B0E81DP5B0E81DP5B0E812U802P5B +2E89DPUB2@482@0:0@VW2JL9Y`VW0@RW00X1Y`RW2:L8Y`P12PP04P4800P0200800P0200800P00AT0 +0P404@P0200800P0200800P0200100X800T1Y`RW2:L8Y`402:L01@6W2JL900D00@4100005@000`40 +00020006Y`VW2JL120T02@5B2E89DPUB0@0:DP0@0E81DP5B0E81DP5B0E81DQl1011B0E81DP5B0E81 +DP5B0E812E802`49DPUB2E89DPT100L900X1Y`VW2JL9Y`T11jL02`6W2:L8Y`RW2:L100X8014100P0 +200800P0200800P00@0L000B0@P0200800P0200800P020012@P02P48Y`RW2:L8Y`47Y`050@VW2JL0 +1@010@40000E00030@00008000H9Y`VW2@482@080@UB2E89DP4:DP0@0E81DP5B0E81DP5B0E81DR41 +00eB0E81DP5B0E81DP5B00812U802P49DPUB2E89DP472@0:0@VW2JL9Y`VW0@NW00X12:L8Y`RW2:L1 +2PP04@40200800P0200800P0200101h00141200800P0200800P020080@0:20090@RW2:L8Y`P100NW +00D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@P900P1DPUB2E890@YB0P403e81DP5B0E81 +DP5B0E81DP0O0@0@DP5B0E81DP5B0E81DP5B0@YB00X1DPUB2E89DPT11`T02P6W2JL9Y`VW2@47Y`0: +0JL8Y`RW2:L80@X80141200800P0200800P020080@0N000A0@0800P0200800P0200800402PP02@6W +2:L8Y`RW0@07Y`050@VW2JL01@010@40000E00030@00008000H9Y`VW2@482@080@UB2E89DP4:DP0@ +0E81DP5B0E81DP5B0E81DR41011B0E81DP5B0E81DP5B0E812E802P49DPUB2E89DP472@0:0@VW2JL9 +Y`VW0@NW00X12:L8Y`RW2:L12PP04040200800P0200800P0204P000@0@0800P0200800P020080@X8 +00T12:L8Y`RW20401jL01@6W2JL900D00@4100005@000`4000020006Y`VW2JL120T0205B2E89DPT1 +2E80405B0E81DP5B0E81DP5B0E8S0@0=DP5B0E81DP5B0E81DP020@UB00X1DPUB2E89DPT11`T02P6W +2JL9Y`VW2@47Y`0:0JL8Y`RW2:L80@T8014100P0200800P0200800P00@0P000A0@P0200800P02008 +00P020402@P02@6W2:L8Y`RW0@07Y`050@VW2JL01@010@40000E00030@00008000H9Y`VW2@482@08 +0@UB2E89DP49DP8100eB0E81DP5B0E81DP5B02D100iB0E81DP5B0E81DP5B0@UB00X12E89DPUB2E81 +1`T02P49Y`VW2JL9Y`47Y`0:0@RW2:L8Y`RW0@T80101200800P0200800P020018P00404800P02008 +00P02008004920090@RW2:L8Y`P100NW00D1Y`VW2@0500410@0001D00P430006Y`VW2JL120T01`5B +2E89DP402U80405B0E81DP5B0E81DP5B0E8S0@0=DP5B0E81DP5B0E81DP020@YB00T12E89DPUB2@40 +1`T02P6W2JL9Y`VW2@47Y`090JL8Y`RW2:L100X8010100P0200800P0200800P18P004040200800P0 +200800P0204:20080@RW2:L8Y`47Y`050@VW2JL010020@40000E00030@00008000H9Y`VW2@482@07 +0@UB2E890@0:DP8100eB0E81DP5B0E81DP5B02D100eB0E81DP5B0E81DP5B00812E802@5B2E89DPUB +0@072@0:0@VW2JL9Y`VW0@NW00T12:L8Y`RW20402PP03`4800P0200800P020080@0T000?0@0800P0 +200800P0200100X800P1Y`RW2:L80@NW00D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@P9 +00L1DPUB2E8100UB0P403E81DP5B0E81DP5B0E809`403U81DP5B0E81DP5B0E812E802@49DPUB2E89 +0@072@0:0JL9Y`VW2JL90@NW00T1Y`RW2:L8Y`402@P0404800P0200800P02008004T000@0@P02008 +00P0200800P00@T800P12:L8Y`RW0@NW00D12JL9Y`0500410@0001D000<100000P001PVW2JL90@P9 +00L12E89DPT100UB00h1DP5B0E81DP5B0E81DRT100]B0E81DP5B0E81DP020@UB00T1DPUB2E89DP40 +1`T02P49Y`VW2JL9Y`47Y`090@RW2:L8Y`P100T800l100P0200800P0200800409P003`4800P02008 +00P020080@0920080JL8Y`RW2047Y`050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`482@07 +0E89DPUB0@09DP8100eB0E81DP5B0E81DP5B02L100eB0E81DP5B0E81DP5B008125802P49DPUB2E89 +DP472@090@VW2JL9Y`T100NW00T1Y`RW2:L8Y`402@P03`4800P0200800P020080@0V000?0@0800P0 +200800P0200100T800T12:L8Y`RW20401ZL01@49Y`VW00D00@4100005@000`40000200062JL9Y`T1 +1`T0205B2E89DPT12E803P5B0E81DP5B0E81DP5B:@403U81DP5B0E81DP5B0E8125802P5B2E89DPUB +2@472@080JL9Y`VW2@47Y`0:0JL8Y`RW2:L80@T800l100P0200800P0200800409P003`4800P02008 +00P020080@0920090JL8Y`RW2:L100JW00D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@L9 +00P12E89DPUB0@UB0P402e81DP5B0E81DP5B02/100]B0E81DP5B0E81DP020@QB00X12E89DPUB2E81 +1`T02049Y`VW2JL11jL02P48Y`RW2:L8Y`49200>0@P0200800P02008004X000>0@P0200800P02008 +004920090@RW2:L8Y`P100JW00D12JL9Y`0500410@0001D000<100000P001PVW2JL90@L900P1DPUB +2E890@QB0P402e81DP5B0E81DP5B02/100iB0E81DP5B0E81DP5B0@QB00X1DPUB2E89DPT11`T0206W +2JL9Y`T11jL02P6W2:L8Y`RW2048200?0@P0200800P0200800P102P000l100P0200800P020080040 +20P02@6W2:L8Y`RW0@06Y`050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`472@080@UB2E89 +DP48DP0>0E81DP5B0E81DP5B0E8[0@0>DP5B0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@L900P12JL9 +Y`VW0@NW00X12:L8Y`RW2:L120P03P40200800P0200800P1:P003P40200800P0200800P120P02@48 +Y`RW2:L80@06Y`050@VW2JL01@010@40000E00030@00008000H9Y`VW2@472@070E89DPUB0@09DP81 +00]B0E81DP5B0E81DP0]0@0;DP5B0E81DP5B0E800P48DP090@UB2E89DPT100L900P1Y`VW2JL90@NW +00T1Y`RW2:L8Y`402@P03P4800P0200800P02001:P003P4800P0200800P020012@P02048Y`RW2:L1 +1ZL01@6W2JL900D00@4100005@000`4000020006Y`VW2JL11`T01`49DPUB2@402E80305B0E81DP5B +0E81DRl100aB0E81DP5B0E81DP48DP090E89DPUB2E8100L900P12JL9Y`VW0@NW00T12:L8Y`RW2040 +2@P03@40200800P020080040;0003@4800P0200800P020402@P0206W2:L8Y`P11ZL01@49Y`VW00D0 +0@4100005@000`40000200062JL9Y`T11`T01`5B2E89DP402580305B0E81DP5B0E81DRl100]B0E81 +DP5B0E81DP020@QB00T12E89DPUB2@401`T0206W2JL9Y`T11jL02@6W2:L8Y`RW0@08200>0@0800P0 +200800P0204/000>0@0800P0200800P0204820080@RW2:L8Y`46Y`050JL9Y`T01@010@40000=00@1 +10000`4000020006Y`VW2JL11`T01`49DPUB2@4025820@0;DP5B0E81DP5B0E80;`402e81DP5B0E81 +DP5B00811e802@5B2E89DPUB0@072@080@VW2JL9Y`47Y`090@RW2:L8Y`P100P800d1200800P02008 +00P102h000d100P0200800P0200100P800P1Y`RW2:L80@JW00D12JL9Y`0500410@0000l000<10000 +0`020@<000H9Y`VW2@472@070E89DPUB0@08DP0<0E81DP5B0E81DP5B<@403581DP5B0E81DP5B0@MB +00T12E89DPUB2@401`T0206W2JL9Y`T11jL02@6W2:L8Y`RW0@08200=0@0800P0200800P00@0^000= +0@P0200800P020080@0820080@RW2:L8Y`46Y`050JL9Y`T010020@40000?00030@0000<000<10000 +0P001ZL9Y`VW0@L900L12E89DPT100QB0P402e81DP5B0E81DP5B02l100]B0E81DP5B0E81DP020@MB +00T1DPUB2E89DP401`T02049Y`VW2JL11jL02@48Y`RW2:L80@08200=0@P0200800P020080@0^000= +0@0800P0200800P00@0820080JL8Y`RW2046Y`050@VW2JL01@010@40000?00030@0000<000<10000 +0P001PVW2JL90@L900L1DPUB2E8100QB00`1DP5B0E81DP5B0E8_0@0;DP5B0E81DP5B0E800P48DP09 +0@UB2E89DPT100L900P1Y`VW2JL90@NW00T1Y`RW2:L8Y`4020P03P40200800P0200800P1;0003P40 +200800P0200800P120P02048Y`RW2:L11ZL01@6W2JL900D00@4100003`000`40000300030@000080 +00JW2JL9Y`472@070@UB2E890@09DP0<0E81DP5B0E81DP5B;`403581DP5B0E81DP5B0@QB00T1DPUB +2E89DP401`T02049Y`VW2JL11jL02@48Y`RW2:L80@09200=0@0800P0200800P00@0/000=0@P02008 +00P020080@0920080JL8Y`RW2046Y`050@VW2JL01@010@40000=00<11@000`40000200062JL9Y`T1 +1`T01`5B2E89DP402E820@0;DP5B0E81DP5B0E80;@402e81DP5B0E81DP5B008125802@49DPUB2E89 +0@072@080JL9Y`VW2@47Y`090JL8Y`RW2:L100T800h1200800P0200800P00BX000h1200800P02008 +00P00@T800P12:L8Y`RW0@JW00D1Y`VW2@0500410@0000l000<100000`000`4000020006Y`VW2JL1 +1`T02049DPUB2E8125803P5B0E81DP5B0E81DP5B:`403U81DP5B0E81DP5B0E811e802P49DPUB2E89 +DP472@080@VW2JL9Y`47Y`0:0@RW2:L8Y`RW0@P800h100P0200800P020080BX000h100P0200800P0 +20080@P800T12:L8Y`RW20401ZL01@49Y`VW00D00@4100005@000`40000200062JL9Y`T11`T0205B +2E89DPT125820@0;DP5B0E81DP5B0E80:`403U81DP5B0E81DP5B0E8125802P5B2E89DPUB2@472@08 +0JL9Y`VW2@47Y`0:0JL8Y`RW2:L80@P800l1200800P0200800P02040:0003`40200800P0200800P0 +0@0820090JL8Y`RW2:L100JW00D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@L900P12E89 +DPUB0@UB0P402e81DP5B0E81DP5B02/100]B0E81DP5B0E81DP020@QB00X12E89DPUB2E811`T02049 +Y`VW2JL11jL02P48Y`RW2:L8Y`49200>0@P0200800P02008004X000>0@P0200800P0200800492009 +0@RW2:L8Y`P100JW00D12JL9Y`0500410@0001D000<100000P001PVW2JL90@L900P1DPUB2E890@UB +00h1DP5B0E81DP5B0E81DRT100iB0E81DP5B0E81DP5B0@QB00X1DPUB2E89DPT11`T0206W2JL9Y`T1 +1jL02P6W2:L8Y`RW2049200?0@0800P0200800P0200102H000l1200800P0200800P020402@P02@6W +2:L8Y`RW0@06Y`050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`482@070E89DPUB0@09DP81 +00eB0E81DP5B0E81DP5B02L100eB0E81DP5B0E81DP5B008125802P49DPUB2E89DP472@090@VW2JL9 +Y`T100NW00T1Y`RW2:L8Y`402@P03`4800P0200800P020080@0V000?0@0800P0200800P0200100T8 +00T12:L8Y`RW20401ZL01@49Y`VW00D00@4100005@000`40000200062JL9Y`T120T01`49DPUB2@40 +2E803P5B0E81DP5B0E81DP5B:@402e81DP5B0E81DP5B00812E802@5B2E89DPUB0@072@0:0@VW2JL9 +Y`VW0@NW00T12:L8Y`RW20402@P03`40200800P0200800P00@0V000?0@P0200800P0200800P100T8 +00P1Y`RW2:L80@NW00D1Y`VW2@0500410@0001D000<100000P001ZL9Y`VW0@P900L1DPUB2E8100UB +0P403E81DP5B0E81DP5B0E809`403U81DP5B0E81DP5B0E812E802@49DPUB2E890@072@0:0JL9Y`VW +2JL90@NW00T1Y`RW2:L8Y`402@P0404800P0200800P02008004T000@0@P0200800P0200800P00@T8 +00P12:L8Y`RW0@NW00D12JL9Y`0500410@0001D000<100000P001PVW2JL90@P900L12E89DPT100YB +0P403E81DP5B0E81DP5B0E809@403E81DP5B0E81DP5B0E800P49DP090E89DPUB2E8100L900X12JL9 +Y`VW2JL11jL02@48Y`RW2:L80@0:200?0@P0200800P0200800P102@000l100P0200800P020080040 +2PP0206W2:L8Y`P11jL01@6W2JL900D00@4100005@020@<000JW2JL9Y`482@070E89DPUB0@0:DP0@ +0E81DP5B0E81DP5B0E81DR<100eB0E81DP5B0E81DP5B00812U802@49DPUB2E890@072@0:0JL9Y`VW +2JL90@NW00T1Y`RW2:L8Y`402PP04040200800P0200800P0204R000@0@0800P0200800P020080@X8 +00P12:L8Y`RW0@NW00D12JL9Y`0400810@0001D000<100000P001PVW2JL90@P900P12E89DPUB0@UB +0P403E81DP5B0E81DP5B0E809@403U81DP5B0E81DP5B0E812E802P49DPUB2E89DP472@0:0@VW2JL9 +Y`VW0@NW00X12:L8Y`RW2:L12@P0404800P0200800P02008004R000@0@P0200800P0200800P00@T8 +00T12:L8Y`RW20401jL01@6W2JL900D00@4100005@000`4000020006Y`VW2JL120T0205B2E89DPT1 +2E80405B0E81DP5B0E81DP5B0E8S0@0=DP5B0E81DP5B0E81DP020@UB00X1DPUB2E89DPT11`T02P6W +2JL9Y`VW2@47Y`0:0JL8Y`RW2:L80@T8014100P0200800P0200800P00@0P000A0@P0200800P02008 +00P020402@P02@6W2:L8Y`RW0@07Y`050@VW2JL01@010@40000E00030@00008000H9Y`VW2@482@08 +0@UB2E89DP4:DP0@0E81DP5B0E81DP5B0E81DR41011B0E81DP5B0E81DP5B0E812E802P49DPUB2E89 +DP472@0:0@VW2JL9Y`VW0@NW00X12:L8Y`RW2:L12PP04040200800P0200800P0204P000@0@0800P0 +200800P020080@X800T12:L8Y`RW20401jL01@6W2JL900D00@4100005@000`4000020006Y`VW2JL1 +20T0205B2E89DPT12U820@0?DP5B0E81DP5B0E81DP5B01l1011B0E81DP5B0E81DP5B0E812U802P5B +2E89DPUB2@472@0:0JL9Y`VW2JL90@NW00X1Y`RW2:L8Y`P12PP04@4800P0200800P0200800P101h0 +014100P0200800P0200800P00@0:20090JL8Y`RW2:L100NW00D12JL9Y`0500410@0001D000<10000 +0P001PVW2JL90@P900P12E89DPUB0@YB0101DP5B0E81DP5B0E81DP5B8@403E81DP5B0E81DP5B0E80 +0P4:DP0:0@UB2E89DPUB0@L900X12JL9Y`VW2JL11jL02P48Y`RW2:L8Y`4:200A0@0800P0200800P0 +200800407P004@4800P0200800P0200800P100X800T12:L8Y`RW20401jL01@6W2JL900D00@410000 +5@000`4000020006Y`VW2JL120T02@5B2E89DPUB0@0:DP0@0E81DP5B0E81DP5B0E81DQl1011B0E81 +DP5B0E81DP5B0E812E802`49DPUB2E89DPT100L900X1Y`VW2JL9Y`T11jL02`6W2:L8Y`RW2:L100X8 +014100P0200800P0200800P00@0L000B0@P0200800P0200800P020012@P02P48Y`RW2:L8Y`47Y`05 +0@VW2JL01@010@40000E00030@00008000H9Y`VW2@482@090@UB2E89DPT100YB0P403e81DP5B0E81 +DP5B0E81DP0M0@0@DP5B0E81DP5B0E81DP5B0@YB00X1DPUB2E89DPT120T02P49Y`VW2JL9Y`48Y`0: +0JL8Y`RW2:L80@X80181200800P0200800P02008004J000B0@P0200800P0200800P020012PP02@6W +2:L8Y`RW0@08Y`050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`492@090@UB2E89DPT100YB +0P403e81DP5B0E81DP5B0E81DP0K0@0?DP5B0E81DP5B0E81DP5B00812E802`5B2E89DPUB2E8100P9 +00X1Y`VW2JL9Y`T12:L02`48Y`RW2:L8Y`P100X80181200800P0200800P02008004H000C0@P02008 +00P0200800P020080@09200:0JL8Y`RW2:L80@RW00D12JL9Y`0500410@0001D000<100000P001PVW +2JL90@T900X1DPUB2E89DPT12E804P5B0E81DP5B0E81DP5B0E81DQT100mB0E81DP5B0E81DP5B0E80 +0P49DP0<0E89DPUB2E89DPT120T02P49Y`VW2JL9Y`48Y`0<0JL8Y`RW2:L8Y`P12@P04`40200800P0 +200800P0200800405P004`4800P0200800P0200800P020402@P02`6W2:L8Y`RW2:L100RW00D1Y`VW +2@0500410@0001D000<100000P001jL9Y`VW2@4020T02P49DPUB2E89DP4:DP0B0E81DP5B0E81DP5B +0E81DP5B5`404U81DP5B0E81DP5B0E81DP5B0@UB00/12E89DPUB2E890@092@0;0JL9Y`VW2JL9Y`40 +2:L02`6W2:L8Y`RW2:L100X801<100P0200800P0200800P0200101@001@1200800P0200800P02008 +00P00@T800/12:L8Y`RW2:L80@07Y`060JL9Y`VW1@010@40000E00030@00008000L9Y`VW2JL100P9 +00/1DPUB2E89DPUB0@09DP81015B0E81DP5B0E81DP5B0E81DP0E0@0BDP5B0E81DP5B0E81DP5B0E81 +2E803049DPUB2E89DPUB0@T900/12JL9Y`VW2JL90@08Y`0<0@RW2:L8Y`RW2:L12@P04`4800P02008 +00P0200800P0200050404`P0200800P0200800P0200800402@P02`48Y`RW2:L8Y`P100RW00H12JL9 +Y`T500410@0001D000<100000P001jL9Y`VW2@402@T02`5B2E89DPUB2E8100UB0P40=E81DP5B0E81 +DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00812E80305B2E89DPUB +2E890@T900/1Y`VW2JL9Y`VW0@08Y`0=0JL8Y`RW2:L8Y`RW0@09200i0@P0200800P0200800P02008 +00P0200800P0200800P0200800P0200800P0200800P0200800P100P800`12:L8Y`RW2:L8Y`48Y`06 +0JL9Y`VW1@010@40000E00810`001`VW2JL9Y`402@T02`49DPUB2E89DPT100UB03H1DP5B0E81DP5B +0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E820@UB00`1DPUB2E89DPUB +2@4:2@0;0@VW2JL9Y`VW2@402JL0306W2:L8Y`RW2:L80@T803P100P0200800P0200800P0200800P0 +200800P0200800P0200800P0200800P0200800P020080@T800`1Y`RW2:L8Y`RW2048Y`060@VW2JL9 +10020@40000E00030@00008000NW2JL9Y`T100T900`1DPUB2E89DPUB2@49DP<1035B0E81DP5B0E81 +DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00812E803@5B2E89DPUB2E89DP40 +2PT02`6W2JL9Y`VW2JL100VW00d12:L8Y`RW2:L8Y`P100T80P400JL8Y`RW2:L8Y`RW204:208102h0200800P0200800P0200800P02008 +00P0200800P0200800P0200800P020080P4:200=0JL8Y`RW2:L8Y`RW0@09Y`060@VW2JL91@010@40 +000E00030@00008000NW2JL9Y`T100T900h1DPUB2E89DPUB2E890@]B0`40:E81DP5B0E81DP5B0E81 +DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B008135803@49DPUB2E89DPUB2@402PT03049Y`VW2JL9 +Y`VW0@ZW00h1Y`RW2:L8Y`RW2:L80@/80P40:PP0200800P0200800P0200800P0200800P0200800P0 +200800P0200800812`P03P6W2:L8Y`RW2:L8Y`P12JL01P6W2JL9Y`D00@4100005@000`4000020007 +2JL9Y`VW0@0:2@0=0E89DPUB2E89DPUB0@0=DP8102EB0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81 +DP5B0E81DP5B00<13E803P49DPUB2E89DPUB2E812PT0306W2JL9Y`VW2JL90@ZW00h12:L8Y`RW2:L8 +Y`RW0@d80P409P0800P0200800P0200800P0200800P0200800P0200800P020080P4=200>0@RW2:L8 +Y`RW2:L8Y`49Y`060@VW2JL91@010@40000E00030@00008000NW2JL9Y`T100X900h12E89DPUB2E89 +DPUB0@iB0`408E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@mB00h1DPUB2E89DPUB +2E890@X900`12JL9Y`VW2JL9Y`4:Y`0?0JL8Y`RW2:L8Y`RW2:L100h802H100P0200800P0200800P0 +200800P0200800P0200800P020080@h800h12:L8Y`RW2:L8Y`RW0@ZW00H1Y`VW2JL500410@0001D0 +00<100000P001`VW2JL9Y`402PT03`5B2E89DPUB2E89DPUB0@0?DP8101mB0E81DP5B0E81DP5B0E81 +DP5B0E81DP5B0E81DP5B00813e803P5B2E89DPUB2E89DPT12`T0306W2JL9Y`VW2JL90@^W00l1Y`RW +2:L8Y`RW2:L8Y`403PP20@0P200800P0200800P0200800P0200800P0200800P020020@h800l12:L8 +Y`RW2:L8Y`RW20402ZL01P49Y`VW2@D00@4100005@000`4000020008Y`VW2JL9Y`492@0?0@UB2E89 +DPUB2E89DPT1015B0`406E81DP5B0E81DP5B0E81DP5B0E81DP5B0E800`4ADP0>0@UB2E89DPUB2E89 +DP4;2@0=0@VW2JL9Y`VW2JL90@0:Y`0?0@RW2:L8Y`RW2:L8Y`P101080P40700800P0200800P02008 +00P0200800P0200800P20A0800l1Y`RW2:L8Y`RW2:L8Y`402JL01`49Y`VW2JL01@010@40000E0003 +0@00008000P9Y`VW2JL90@X900l12E89DPUB2E89DPUB2@404U820@0GDP5B0E81DP5B0E81DP5B0E81 +DP5B0E800P4BDP0?0@UB2E89DPUB2E89DPT100/900d1Y`VW2JL9Y`VW2JL100ZW0101Y`RW2:L8Y`RW +2:L8Y`P14@P20@0H200800P0200800P0200800P0200800P00P4A200@0JL8Y`RW2:L8Y`RW2:L80@VW +00L1Y`VW2JL900D00@4100005@000`4000020008Y`VW2JL9Y`4:2@0@0E89DPUB2E89DPUB2E890A=B +0`404E81DP5B0E81DP5B0E81DP5B00<14e803`49DPUB2E89DPUB2E890@0<2@0=0@VW2JL9Y`VW2JL9 +0@0;Y`0@0JL8Y`RW2:L8Y`RW2:L80A880P40500800P0200800P0200800P020080P4B200@0JL8Y`RW +2:L8Y`RW2:L80@ZW00L12JL9Y`VW00D00@4100005@000`40000200082JL9Y`VW2@4:2@0@0@UB2E89 +DPUB2E89DPUB0AEB4`4EDP0?0E89DPUB2E89DPUB2E8100`900d1Y`VW2JL9Y`VW2JL100^W01012:L8 +Y`RW2:L8Y`RW2:L150PD0A@801012:L8Y`RW2:L8Y`RW2:L12ZL01`6W2JL9Y`T01@010@40000E0003 +0@00008000RW2JL9Y`VW0@/901012E89DPUB2E89DPUB2E81>U820@0?DPUB2E89DPUB2E89DPT100`9 +00d12JL9Y`VW2JL9Y`T100^W0141Y`RW2:L8Y`RW2:L8Y`RW0@0i208100l8Y`RW2:L8Y`RW2:L8Y`40 +2jL01`49Y`VW2JL01@010@40000E00810`002@VW2JL9Y`VW0@0;2@8100eB2E89DPUB2E89DPUB00<1 +=5830@0>2E89DPUB2E89DPUB2E820@`900l12JL9Y`VW2JL9Y`VW2@402jL20@0>2:L8Y`RW2:L8Y`RW +2:L30C@80P403ZL8Y`RW2:L8Y`RW2:L80P4;Y`080@VW2JL9Y`T400810@0001D000<100000P002JL9 +Y`VW2JL90@0=2@0@0E89DPUB2E89DPUB2E89DP<1;U830@0A2E89DPUB2E89DPUB2E89DP403PT03`6W +2JL9Y`VW2JL9Y`VW0@0=Y`0A0@RW2:L8Y`RW2:L8Y`RW2:L00`4^20<10108Y`RW2:L8Y`RW2:L8Y`P1 +3JL0206W2JL9Y`VW1@010@40000E00030@00008000X9Y`VW2JL9Y`T13@T04P5B2E89DPUB2E89DPUB +2E89DP<1:5830@0A2E89DPUB2E89DPUB2E89DPT00P4>2@0A0JL9Y`VW2JL9Y`VW2JL9Y`403JL20@0A +Y`RW2:L8Y`RW2:L8Y`RW2:L00`4X20<10188Y`RW2:L8Y`RW2:L8Y`RW204=Y`090JL9Y`VW2JL900D0 +0@4100005@000`400002000:Y`VW2JL9Y`VW0@h90P404PUB2E89DPUB2E89DPUB2E89DP@18E830@0D +2E89DPUB2E89DPUB2E89DPUB2@4?2@0B0JL9Y`VW2JL9Y`VW2JL9Y`T13jL0506W2:L8Y`RW2:L8Y`RW +2:L8Y`RW0`4R20<10188Y`RW2:L8Y`RW2:L8Y`RW2:L20@jW00T12JL9Y`VW2JL01@010@40000E0003 +0@00008000/9Y`VW2JL9Y`VW0@0?2@0F0@UB2E89DPUB2E89DPUB2E89DPUB2@<16e830@0D2E89DPUB +2E89DPUB2E89DPUB2E820A0901<12JL9Y`VW2JL9Y`VW2JL9Y`T100nW0P4050RW2:L8Y`RW2:L8Y`RW +2:L8Y`RW0`4L20<101D8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`403jL02P49Y`VW2JL9Y`T500410@0001D0 +00<100000P003:L9Y`VW2JL9Y`VW0@l90P405U89DPUB2E89DPUB2E89DPUB2E89DPT30AEB0`405`UB +2E89DPUB2E89DPUB2E89DPUB2E81014901D12JL9Y`VW2JL9Y`VW2JL9Y`VW2@404:L05`48Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW00<15PP30@0E2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L800814:L02P6W2JL9Y`VW +2JL500410@0001D000<100000P0030VW2JL9Y`VW2JL90A4901T1DPUB2E89DPUB2E89DPUB2E89DPUB +2E8901D101L9DPUB2E89DPUB2E89DPUB2E89DPUB2@020A4901H12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1 +4JL20@0GY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L05P4060RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80A6W +00/1Y`VW2JL9Y`VW2@0500410@0001D000<100000P003JL9Y`VW2JL9Y`VW2@404@T20@122E89DPUB +2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT1 +4`T05`6W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL101:W0481Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L20A:W00/12JL9Y`VW2JL9Y`050041 +0@0001D000<100000P003PVW2JL9Y`VW2JL9Y`T14PT0?`49DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP020A<901T1Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL101:W0P40?`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW0@0CY`0<0@VW2JL9Y`VW2JL91@010@40000E00030@00008000jW2JL9 +Y`VW2JL9Y`VW0A<903h12E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB0A@901X1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90ABW03h12:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0A>W00d12JL9 +Y`VW2JL9Y`VW00D00@4100005@000`400002000?2JL9Y`VW2JL9Y`VW2JL101<90P40>589DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E890P4E2@0K0@VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T101BW0P40>:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80P4DY`0=0JL9Y`VW2JL9Y`VW2@0500410@0001D000<10000 +0P003jL9Y`VW2JL9Y`VW2JL90@0E2@@10309DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB +2E89DPUB2E89DPUB2E840AH901`12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL15ZL30@0aY`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`040AFW00h1Y`VW2JL9Y`VW +2JL9Y`D00@4100005@000`400002000@2JL9Y`VW2JL9Y`VW2JL90AP91P409589DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2@H16@T07P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0ARW +1P409@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P01P4IY`0>0@VW2JL9Y`VW2JL9 +Y`T500410@0001D00P43000AY`VW2JL9Y`VW2JL9Y`VW2@407@T60@0H2E89DPUB2E89DPUB2E89DPUB +2E89DPUB1P4O2@0O0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@0MY`H101VW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW00H17ZL03`49Y`VW2JL9Y`VW2JL9Y`0400810@0001D000<100000P004@VW +2JL9Y`VW2JL9Y`VW2JL102<9604T2@0P0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@4SYaT1 +9:L03`6W2JL9Y`VW2JL9Y`VW2@0500410@0001D000<100000P004ZL9Y`VW2JL9Y`VW2JL9Y`VW0Ed9 +0281Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T1GZL0406W2JL9Y`VW2JL9Y`VW2JL50041 +0@0001D000<100000P004PVW2JL9Y`VW2JL9Y`VW2JL90Ed902812JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL1GZL04049Y`VW2JL9Y`VW2JL9Y`T500410@0001D000<100000P004ZL9Y`VW2JL9 +Y`VW2JL9Y`VW2@<1EPT40@0R2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`@1EZL40@0@ +2JL9Y`VW2JL9Y`VW2JL9Y`D00@4100005@000`400002000E2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900@1 +CPT40@0ZY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9105>Y`@101BW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2@D00@4100005@000`400002000IY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`050D@91@40Y`@102ZW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`T40Dh910405:L9Y`VW2JL9Y`VW2JL9Y`VW2JL91@010@40000E00030@000080 +01:W2JL9Y`VW2JL9Y`VW2JL9Y`T30EJW10408PVW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL40EH9104040VW2JL9Y`VW2JL9Y`VW2JL500410@0001D000<100000P004PVW2JL9Y`VW2JL9Y`VW +2JL90EfW02812JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1GPT04049Y`VW2JL9Y`VW2JL9 +Y`T500410@0001D000<100000P004ZL9Y`VW2JL9Y`VW2JL9Y`VW0EfW0281Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`T1GPT0406W2JL9Y`VW2JL9Y`VW2JL500410@0001D000<100000P004@VW +2JL9Y`VW2JL9Y`VW2JL102>W604TY`0P0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@4S2AT1 +90T03`6W2JL9Y`VW2JL9Y`VW2@0500410@0001D00P43000AY`VW2JL9Y`VW2JL9Y`VW2@407JL60@0H +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW1P4OY`0O0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +0@0M2@H101UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB00H17PT03`49Y`VW2JL9Y`VW2JL9Y`040081 +0@0001D000<100000P0040VW2JL9Y`VW2JL9Y`VW2@4HY`H102BW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`P60AVW01h12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4H2@H102D9DPUB +2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E8900H16@T03P49Y`VW2JL9Y`VW2JL91@010@40 +000E00030@00008000nW2JL9Y`VW2JL9Y`VW2@405JL40@0`2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW104FY`0L0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0AH9 +0`40 +0JL9Y`VW2JL9Y`VW2JL500410@0001D000<100000P003`VW2JL9Y`VW2JL9Y`VW0@0CY`8103RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20815JL06`49 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@0D2@8103QB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2@8150T03@6W2JL9Y`VW2JL9Y`T01@010@40000E0003 +0@00008000jW2JL9Y`VW2JL9Y`VW0A>W03h12:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0ABW01X1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90A@9 +03h12E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB0A<900d12JL9Y`VW2JL9Y`VW00D00@4100005@000`400002000>2JL9Y`VW2JL9Y`VW2@4BY`0o +0@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW00814jL06@6W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`404PT20@0o2E89DPUB2E89DPUB2E89DPUB +2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E8101<900`12JL9Y`VW2JL9 +Y`T500410@0001D000<100000P003JL9Y`VW2JL9Y`VW2@404JL20@122:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P14jL05`6W2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL101890481DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB +2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E820A8900/12JL9Y`VW2JL9Y`0500410@0001D000<10000 +0P0030VW2JL9Y`VW2JL90A6W01T1Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L801D101L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW20020A6W01H12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL14@T20@0GDPUB2E89DPUB2E89 +DPUB2E89DPUB2E805P4060UB2E89DPUB2E89DPUB2E89DPUB2E890A4900/1Y`VW2JL9Y`VW2@050041 +0@0001D000<100000P003:L9Y`VW2JL9Y`VW0@nW0P405ZL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P30AD8 +0`405`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L1016W01D12JL9Y`VW2JL9Y`VW2JL9Y`VW2@4040T05`49 +DPUB2E89DPUB2E89DPUB2E89DPUB00<15U830@0E2E89DPUB2E89DPUB2E89DPUB2E89008140T02P6W +2JL9Y`VW2JL500410@0001D000<100000P002`VW2JL9Y`VW2JL100nW01H12:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L80`4K20<101@8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`814:L04`49Y`VW2JL9Y`VW2JL9Y`VW2@40 +3`T20@0D2E89DPUB2E89DPUB2E89DPUB2E830AaB0`405@UB2E89DPUB2E89DPUB2E89DPUB0@0?2@0: +0@VW2JL9Y`VW2@D00@4100005@000`400002000:Y`VW2JL9Y`VW0@jW0P404PRW2:L8Y`RW2:L8Y`RW +2:L8Y`@18@P30@0D2:L8Y`RW2:L8Y`RW2:L8Y`RW204?Y`0B0JL9Y`VW2JL9Y`VW2JL9Y`T13`T0505B +2E89DPUB2E89DPUB2E89DPUB0`4RDP<10189DPUB2E89DPUB2E89DPUB2E820@h900T12JL9Y`VW2JL0 +1@010@40000E00030@00008000X9Y`VW2JL9Y`T13JL04P6W2:L8Y`RW2:L8Y`RW2:L8Y`<1:0P30@0A +2:L8Y`RW2:L8Y`RW2:L8Y`P00P4>Y`0A0JL9Y`VW2JL9Y`VW2JL9Y`403@T20@0ADPUB2E89DPUB2E89 +DPUB2E800`4XDP<10189DPUB2E89DPUB2E89DPUB2@4=2@090JL9Y`VW2JL900D00@4100005@000`40 +00020009Y`VW2JL9Y`T100fW0101Y`RW2:L8Y`RW2:L8Y`RW0`4^20<10148Y`RW2:L8Y`RW2:L8Y`RW +0@0>Y`0?0JL9Y`VW2JL9Y`VW2JL100d901412E89DPUB2E89DPUB2E89DP030BiB0`4040UB2E89DPUB +2E89DPUB2@4=2@080JL9Y`VW2JL500410@0001D00P4300092JL9Y`VW2JL100^W0P403JL8Y`RW2:L8 +Y`RW2:L00`4d20<100h8Y`RW2:L8Y`RW2:L8Y`813:L03`49Y`VW2JL9Y`VW2JL90@0;2@8100h9DPUB +2E89DPUB2E89DP<1=5820@0>DPUB2E89DPUB2E89DPT20@/900P12JL9Y`VW2@@00P4100005@000`40 +00020008Y`VW2JL9Y`4;Y`0@0@RW2:L8Y`RW2:L8Y`RW0CX80P403jL8Y`RW2:L8Y`RW2:L80@0E820@0?2E89DPUB2E89DPUB2E8100/9 +00L12JL9Y`VW00D00@4100005@000`40000200082JL9Y`VW2@4:Y`0@0@RW2:L8Y`RW2:L8Y`RW0AD8 +4`4E200?0JL8Y`RW2:L8Y`RW2:L100bW00d1Y`VW2JL9Y`VW2JL100/901012E89DPUB2E89DPUB2E81 +558D0AAB01012E89DPUB2E89DPUB2E812PT01`6W2JL9Y`T01@010@40000E00030@00008000RW2JL9 +Y`VW0@ZW0101Y`RW2:L8Y`RW2:L8Y`P14`P20@0C200800P0200800P0200800P020020A<800l12:L8 +Y`RW2:L8Y`RW20403:L03@49Y`VW2JL9Y`VW2@402`T0405B2E89DPUB2E89DPUB2@4BDP8101=B0E81 +DP5B0E81DP5B0E81DP5B00<14U80405B2E89DPUB2E89DPUB2@4:2@070@VW2JL9Y`0500410@0001D0 +00<100000P0020VW2JL9Y`T12ZL03`48Y`RW2:L8Y`RW2:L80@0B208101L0200800P0200800P02008 +00P0200800020A8800l12:L8Y`RW2:L8Y`RW20402jL03@6W2JL9Y`VW2JL9Y`402PT0405B2E89DPUB +2E89DPUB2@4ADP<101MB0E81DP5B0E81DP5B0E81DP5B0E81DP020A5B0101DPUB2E89DPUB2E89DPT1 +2@T01`6W2JL9Y`T01@010@40000E00030@00008000RW2JL9Y`VW0@VW00l12:L8Y`RW2:L8Y`RW2040 +4@P20@0K200800P0200800P0200800P0200800P0200800814@P03P48Y`RW2:L8Y`RW2:L12jL03@49 +Y`VW2JL9Y`VW2@402PT03`49DPUB2E89DPUB2E890@0@DP8101]B0E81DP5B0E81DP5B0E81DP5B0E81 +DP5B0E800`4@DP0?0E89DPUB2E89DPUB2E8100T900L12JL9Y`VW00D00@4100005@000`4000020007 +2JL9Y`VW0@0:Y`0?0JL8Y`RW2:L8Y`RW2:L100l80P407`0800P0200800P0200800P0200800P02008 +00P020000P4?200>0JL8Y`RW2:L8Y`RW204;Y`0<0JL9Y`VW2JL9Y`T12`T03`5B2E89DPUB2E89DPUB +0@0>DP<101mB0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00813U803`49DPUB2E89DPUB2E89 +0@0:2@060@VW2JL91@010@40000E00030@00008000NW2JL9Y`T100ZW00h12:L8Y`RW2:L8Y`RW0@h8 +0P4090P0200800P0200800P0200800P0200800P0200800P020080@l800h1Y`RW2:L8Y`RW2:L80@ZW +00`12JL9Y`VW2JL9Y`4:2@0?0E89DPUB2E89DPUB2E8100iB02@1DP5B0E81DP5B0E81DP5B0E81DP5B +0E81DP5B0E81DP5B0E820@iB00h12E89DPUB2E89DPUB0@X900H1Y`VW2JL500410@0001D000<10000 +0P001`VW2JL9Y`402ZL03@6W2:L8Y`RW2:L8Y`403@P20@0V00P0200800P0200800P0200800P02008 +00P0200800P0200800P20@d800h12:L8Y`RW2:L8Y`RW0@ZW00`1Y`VW2JL9Y`VW2@4:2@0>0@UB2E89 +DPUB2E89DP4=DP8102EB0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00<13E803P49 +DPUB2E89DPUB2E812@T01P49Y`VW2@D00@4100005@000`4000020007Y`VW2JL90@09Y`0>0JL8Y`RW +2:L8Y`RW204;208102X800P0200800P0200800P0200800P0200800P0200800P0200800P020020@`8 +00d12:L8Y`RW2:L8Y`P100ZW00`12JL9Y`VW2JL9Y`4:2@0>0E89DPUB2E89DPUB2@4;DP<102UB0E81 +DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@]B00h1DPUB2E89DPUB2E890@T9 +00H1Y`VW2JL500410@0001D000<100000P001`VW2JL9Y`402JL03@48Y`RW2:L8Y`RW20402PP20@0^ +00P0200800P0200800P0200800P0200800P0200800P0200800P0200800P020812`P03@48Y`RW2:L8 +Y`RW20402JL0306W2JL9Y`VW2JL90@T900h1DPUB2E89DPUB2E890@YB0P40;E81DP5B0E81DP5B0E81 +DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP030@YB00d1DPUB2E89DPUB2E8100T900H12JL9 +Y`T500410@0001D000<100000P001jL9Y`VW2@402JL0306W2:L8Y`RW2:L80@T80P40040200800P0200800P0 +200800P0200800P0200800P0200800P0200800P0200800P0200800P12@P0306W2:L8Y`RW2:L80@ZW +00/12JL9Y`VW2JL90@092@0<0E89DPUB2E89DPT12E80=P5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B +0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP812E80305B2E89DPUB2E890@P900H12JL9Y`T40081 +0@0001D000<100000P001jL9Y`VW2@402JL02`6W2:L8Y`RW2:L100T803T1200800P0200800P02008 +00P0200800P0200800P0200800P0200800P0200800P0200800P020402@P0306W2:L8Y`RW2:L80@VW +00/1Y`VW2JL9Y`VW0@082@0=0E89DPUB2E89DPUB0@09DP8103EB0E81DP5B0E81DP5B0E81DP5B0E81 +DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@QB00`12E89DPUB2E89DP482@060JL9Y`VW +1@010@40000E00030@00008000L9Y`VW2JL100RW00/1Y`RW2:L8Y`RW0@09200D0@P0200800P02008 +00P0200800PC0@0C200800P0200800P0200800P00@09200<0@RW2:L8Y`RW2:L12JL02`49Y`VW2JL9 +Y`T100P900`12E89DPUB2E89DP49DP81015B0E81DP5B0E81DP5B0E81DP0E0@0BDP5B0E81DP5B0E81 +DP5B0E812E802`49DPUB2E89DPT100P900H12JL9Y`T500410@0001D000<100000P001jL9Y`VW2@40 +2:L02P48Y`RW2:L8Y`4:200D0@0800P0200800P0200800P0204C000D0@P0200800P0200800P02008 +0049200;0@RW2:L8Y`RW20402JL02`6W2JL9Y`VW2JL100P900/1DPUB2E89DPUB0@0:DP0B0E81DP5B +0E81DP5B0E81DP5B5`404U81DP5B0E81DP5B0E81DP5B0@UB00/12E89DPUB2E890@072@060JL9Y`VW +1@010@40000E00030@00008000H9Y`VW2@49Y`0:0JL8Y`RW2:L80@T801@100P0200800P0200800P0 +20080AD001<1200800P0200800P0200800P100T800`1Y`RW2:L8Y`RW2048Y`0:0@VW2JL9Y`VW0@P9 +00`1DPUB2E89DPUB2@49DP0B0E81DP5B0E81DP5B0E81DP5B6@403e81DP5B0E81DP5B0E81DP020@UB +00/1DPUB2E89DPUB0@082@050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`49Y`090@RW2:L8 +Y`P100X801<1200800P0200800P0200800P101L001<1200800P0200800P0200800P100T800/1Y`RW +2:L8Y`RW0@08Y`0:0JL9Y`VW2JL90@P900/12E89DPUB2E890@0:DP8100mB0E81DP5B0E81DP5B0E80 +6`403e81DP5B0E81DP5B0E81DP020@UB00X1DPUB2E89DPT120T01@49Y`VW00D00@4100005@000`40 +000200062JL9Y`T12:L02@48Y`RW2:L80@0:200C0@P0200800P0200800P020080@0I000B0@P02008 +00P0200800P020012PP02P6W2:L8Y`RW2048Y`0:0@VW2JL9Y`VW0@P900X1DPUB2E89DPT12U820@0? +DP5B0E81DP5B0E81DP5B01d1011B0E81DP5B0E81DP5B0E812U802@5B2E89DPUB0@082@050JL9Y`T0 +1@010@40000E00030@00008000JW2JL9Y`48Y`090JL8Y`RW2:L100X8018100P0200800P0200800P0 +204K000B0@P0200800P0200800P020012@P02`48Y`RW2:L8Y`P100NW00X1Y`VW2JL9Y`T11`T02`5B +2E89DPUB2E8100YB0101DP5B0E81DP5B0E81DP5B7`404581DP5B0E81DP5B0E81DP49DP0:0@UB2E89 +DPUB0@L900D12JL9Y`0500410@0001D000<100000P001PVW2JL90@RW00P12:L8Y`RW0@X8018100P0 +200800P0200800P0204M000A0@P0200800P0200800P020402PP02P48Y`RW2:L8Y`47Y`0:0@VW2JL9 +Y`VW0@L900X12E89DPUB2E812U80405B0E81DP5B0E81DP5B0E8Q0@0=DP5B0E81DP5B0E81DP020@YB +00T12E89DPUB2@401`T01@6W2JL900D00@4100005@000`4000020006Y`VW2JL12:L0206W2:L8Y`P1 +2PP04P4800P0200800P0200800P00Ad0014100P0200800P0200800P00@0:200:0JL8Y`RW2:L80@NW +00X1Y`VW2JL9Y`T11`T02P5B2E89DPUB2@4:DP8100eB0E81DP5B0E81DP5B0241011B0E81DP5B0E81 +DP5B0E812U802@5B2E89DPUB0@072@050@VW2JL01@010@40000E00030@00008000H9Y`VW2@48Y`08 +0@RW2:L8Y`4:200A0@0800P0200800P0200800407`004@40200800P0200800P0200100T800X12:L8 +Y`RW2:L11jL02P49Y`VW2JL9Y`472@0:0@UB2E89DPUB0@YB00h1DP5B0E81DP5B0E81DR<100eB0E81 +DP5B0E81DP5B00812U802@49DPUB2E890@072@050JL9Y`T01@010@40000E00030@00008000JW2JL9 +Y`48Y`080JL8Y`RW2049200B0@0800P0200800P0200800P17`004@4800P0200800P0200800P100T8 +00X1Y`RW2:L8Y`P11jL02P6W2JL9Y`VW2@472@0:0E89DPUB2E890@UB0101DP5B0E81DP5B0E81DP5B +8`403E81DP5B0E81DP5B0E800P49DP090E89DPUB2E8100L900D12JL9Y`0500410@0001D000<10000 +0P001PVW2JL90@RW00P12:L8Y`RW0@T80141200800P0200800P020080@0Q000@0@P0200800P02008 +00P00@T800X12:L8Y`RW2:L11jL02P49Y`VW2JL9Y`472@0:0@UB2E89DPUB0@UB0P403E81DP5B0E81 +DP5B0E809@403U81DP5B0E81DP5B0E812E802@49DPUB2E890@072@050JL9Y`T01@010@40000E0081 +0`001ZL9Y`VW0@RW00L1Y`RW2:L100X8014100P0200800P0200800P00@0Q000@0@0800P0200800P0 +20080@X800T12:L8Y`RW20401jL02P6W2JL9Y`VW2@472@090E89DPUB2E8100YB00h1DP5B0E81DP5B +0E81DRD100eB0E81DP5B0E81DP5B00812U802049DPUB2E811`T01@49Y`VW00@00P4100005@000`40 +000200062JL9Y`T12:L01`48Y`RW20402PP0404800P0200800P02008004S000@0@0800P0200800P0 +20080@T800T1Y`RW2:L8Y`401jL02P49Y`VW2JL9Y`472@090@UB2E89DPT100YB0P402e81DP5B0E81 +DP5B02L100iB0E81DP5B0E81DP5B0@YB00P1DPUB2E890@L900D1Y`VW2@0500410@0001D000<10000 +0P001ZL9Y`VW0@RW00L1Y`RW2:L100T80141200800P0200800P020080@0S000@0@P0200800P02008 +00P00@T800T12:L8Y`RW20401jL02P6W2JL9Y`VW2@472@090E89DPUB2E8100UB0P403E81DP5B0E81 +DP5B0E809`403U81DP5B0E81DP5B0E812E802049DPUB2E811`T01@49Y`VW00D00@4100005@000`40 +000200062JL9Y`T12:L01`48Y`RW20402@P04040200800P0200800P0204U000?0@P0200800P02008 +00P100T800T1Y`RW2:L8Y`401jL02P49Y`VW2JL9Y`472@090@UB2E89DPT100UB00h1DP5B0E81DP5B +0E81DRT100]B0E81DP5B0E81DP020@UB00P1DPUB2E890@L900D1Y`VW2@0500410@0001D000<10000 +0P001ZL9Y`VW0@RW00L1Y`RW2:L100T80101200800P0200800P020019@004040200800P0200800P0 +2048200:0@RW2:L8Y`RW0@NW00T12JL9Y`VW2@401`T02@5B2E89DPUB0@09DP8100]B0E81DP5B0E81 +DP0Y0@0>DP5B0E81DP5B0E81DP49DP090@UB2E89DPT100H900D12JL9Y`0500410@0001D000<10000 +0P001PVW2JL90@NW00P1Y`RW2:L80@T800l100P0200800P0200800409P00404800P0200800P02008 +0048200:0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900X1DPUB2E89DPT12E803P5B0E81DP5B0E81DP5B +:@402e81DP5B0E81DP5B00812E802@5B2E89DPUB0@062@050JL9Y`T01@010@40000E00030@000080 +00JW2JL9Y`47Y`080@RW2:L8Y`49200?0@P0200800P0200800P102L000l1200800P0200800P02040 +20P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@0:0@UB2E89DPUB0@UB0P402e81DP5B0E81DP5B02/1 +00aB0E81DP5B0E81DP49DP090@UB2E89DPT100H900D12JL9Y`0500410@0001D000<100000P001PVW +2JL90@NW00P1Y`RW2:L80@P800l1200800P0200800P02040:0003`40200800P0200800P00@08200: +0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900X1DPUB2E89DPT125820@0;DP5B0E81DP5B0E80:`403U81 +DP5B0E81DP5B0E8125802@5B2E89DPUB0@062@050JL9Y`T01@010@40000E00030@00008000JW2JL9 +Y`47Y`080@RW2:L8Y`48200?0@0800P0200800P0200102T000l100P0200800P0200800401`P02P48 +Y`RW2:L8Y`47Y`080@VW2JL9Y`472@0:0@UB2E89DPUB0@QB00`1DP5B0E81DP5B0E8]0@0;DP5B0E81 +DP5B0E800P48DP090@UB2E89DPT100H900D12JL9Y`0500410@0001D000<100000P001PVW2JL90@NW +00L1Y`RW2:L100T800h1200800P0200800P00BX000l1200800P0200800P0204020P02@48Y`RW2:L8 +0@07Y`080JL9Y`VW2@472@090E89DPUB2E8100UB0P402e81DP5B0E81DP5B02d100aB0E81DP5B0E81 +DP49DP080@UB2E89DP462@050JL9Y`T01@010@40000E00030@00008000JW2JL9Y`47Y`070@RW2:L8 +0@09200>0@0800P0200800P0204[000>0@P0200800P02008004820090JL8Y`RW2:L100NW00P12JL9 +Y`VW0@L900T12E89DPUB2@402E80305B0E81DP5B0E81DRl100UB0E81DP5B0E800P49DP080E89DPUB +2@462@050@VW2JL01@010@40000E00030@00008000H9Y`VW2@47Y`070JL8Y`RW0@08200>0@0800P0 +200800P0204/000>0@0800P0200800P0204820090@RW2:L8Y`P100NW00P1Y`VW2JL90@L900T1DPUB +2E89DP402580305B0E81DP5B0E81DRl100]B0E81DP5B0E81DP020@QB00P12E89DPUB0@H900D1Y`VW +2@0500410@0000d0104400030@00008000JW2JL9Y`47Y`070@RW2:L80@08200>0@P0200800P02008 +004]000>0@0800P0200800P0204720090JL8Y`RW2:L100NW00P12JL9Y`VW0@L900T12E89DPUB2@40 +25820@09DP5B0E81DP5B034100aB0E81DP5B0E81DP48DP080E89DPUB2@462@050@VW2JL01@010@40 +000=00030@0000D00P4300062JL9Y`T11jL01`6W2:L8Y`4020P03@40200800P020080040;P003P48 +00P0200800P020011`P02@48Y`RW2:L80@07Y`080JL9Y`VW2@472@090E89DPUB2E8100QB00`1DP5B +0E81DP5B0E8a0@09DP5B0E81DP5B008125802049DPUB2E811PT01@6W2JL900@00P4100003P000`40 +000400030@000?l01`010@40000?00030@0000<000<10000o`0700410@00010000<100000P000`40 +000200030@0003d000<10000?@000`40000l00030@0003d000<100000P010@40000=00040@000@@0 +00<100000P000`40000:00030@0000T000<100002P000`40000:00030@0000X000<100002P000`40 +000900030@0000X000<100002P000`40000:00030@0000T000<100002P000`40000:00030@0000X0 +00<100002@000`40000:00030@0000X000<100002P000`40000:00030@0000T000<100000P010@40 +000>00811@3o0@/10@000?l08@000?l08@000?l08@000?l08@000001\ +\>"], + ImageRangeCache->{{{0, 287}, {287, 0}} -> {-0.207, -0.172242, 0.00783272, + 0.00783272}}], + +Cell[BoxData[ + TagBox[\(\[SkeletonIndicator] ContourGraphics \[SkeletonIndicator]\), + False, + Editable->False]], "Output"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + \(ContourPlot[p, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"], + +Cell[GraphicsData["PostScript", "\<\ +%! +%%Creator: Mathematica +%%AspectRatio: 1 +MathPictureStart +/Mabs { +Mgmatrix idtransform +Mtmatrix dtransform +} bind def +/Mabsadd { Mabs +3 -1 roll add +3 1 roll add +exch } bind def +%% ContourGraphics +%%IncludeResource: font Courier +%%IncludeFont: Courier +/Courier findfont 10 scalefont setfont +% Scaling calculations +0.0192308 0.480769 0.0192308 0.480769 [ +[.01923 -0.0125 -3 -9 ] +[.01923 -0.0125 3 0 ] +[.25962 -0.0125 -9 -9 ] +[.25962 -0.0125 9 0 ] +[.5 -0.0125 -3 -9 ] +[.5 -0.0125 3 0 ] +[.74038 -0.0125 -9 -9 ] +[.74038 -0.0125 9 0 ] +[.98077 -0.0125 -3 -9 ] +[.98077 -0.0125 3 0 ] +[ 0 0 -0.125 0 ] +[-0.0125 .01923 -6 -4.5 ] +[-0.0125 .01923 0 4.5 ] +[-0.0125 .25962 -18 -4.5 ] +[-0.0125 .25962 0 4.5 ] +[-0.0125 .5 -6 -4.5 ] +[-0.0125 .5 0 4.5 ] +[-0.0125 .74038 -18 -4.5 ] +[-0.0125 .74038 0 4.5 ] +[-0.0125 .98077 -6 -4.5 ] +[-0.0125 .98077 0 4.5 ] +[ 0 0 -0.125 0 ] +[ 0 1 .125 0 ] +[ 1 0 .125 0 ] +[ 0 0 0 0 ] +[ 1 1 0 0 ] +] MathScale +% Start of Graphics +1 setlinecap +1 setlinejoin +newpath +0 g +.25 Mabswid +.01923 0 m +.01923 .00625 L +s +[(0)] .01923 -0.0125 0 1 Mshowa +.25962 0 m +.25962 .00625 L +s +[(0.5)] .25962 -0.0125 0 1 Mshowa +.5 0 m +.5 .00625 L +s +[(1)] .5 -0.0125 0 1 Mshowa +.74038 0 m +.74038 .00625 L +s +[(1.5)] .74038 -0.0125 0 1 Mshowa +.98077 0 m +.98077 .00625 L +s +[(2)] .98077 -0.0125 0 1 Mshowa +.125 Mabswid +.06731 0 m +.06731 .00375 L +s +.11538 0 m +.11538 .00375 L +s +.16346 0 m +.16346 .00375 L +s +.21154 0 m +.21154 .00375 L +s +.30769 0 m +.30769 .00375 L +s +.35577 0 m +.35577 .00375 L +s +.40385 0 m +.40385 .00375 L +s +.45192 0 m +.45192 .00375 L +s +.54808 0 m +.54808 .00375 L +s +.59615 0 m +.59615 .00375 L +s +.64423 0 m +.64423 .00375 L +s +.69231 0 m +.69231 .00375 L +s +.78846 0 m +.78846 .00375 L +s +.83654 0 m +.83654 .00375 L +s +.88462 0 m +.88462 .00375 L +s +.93269 0 m +.93269 .00375 L +s +.25 Mabswid +0 0 m +1 0 L +s +0 .01923 m +.00625 .01923 L +s +[(0)] -0.0125 .01923 1 0 Mshowa +0 .25962 m +.00625 .25962 L +s +[(0.5)] -0.0125 .25962 1 0 Mshowa +0 .5 m +.00625 .5 L +s +[(1)] -0.0125 .5 1 0 Mshowa +0 .74038 m +.00625 .74038 L +s +[(1.5)] -0.0125 .74038 1 0 Mshowa +0 .98077 m +.00625 .98077 L +s +[(2)] -0.0125 .98077 1 0 Mshowa +.125 Mabswid +0 .06731 m +.00375 .06731 L +s +0 .11538 m +.00375 .11538 L +s +0 .16346 m +.00375 .16346 L +s +0 .21154 m +.00375 .21154 L +s +0 .30769 m +.00375 .30769 L +s +0 .35577 m +.00375 .35577 L +s +0 .40385 m +.00375 .40385 L +s +0 .45192 m +.00375 .45192 L +s +0 .54808 m +.00375 .54808 L +s +0 .59615 m +.00375 .59615 L +s +0 .64423 m +.00375 .64423 L +s +0 .69231 m +.00375 .69231 L +s +0 .78846 m +.00375 .78846 L +s +0 .83654 m +.00375 .83654 L +s +0 .88462 m +.00375 .88462 L +s +0 .93269 m +.00375 .93269 L +s +.25 Mabswid +0 0 m +0 1 L +s +.01923 .99375 m +.01923 1 L +s +.25962 .99375 m +.25962 1 L +s +.5 .99375 m +.5 1 L +s +.74038 .99375 m +.74038 1 L +s +.98077 .99375 m +.98077 1 L +s +.125 Mabswid +.06731 .99625 m +.06731 1 L +s +.11538 .99625 m +.11538 1 L +s +.16346 .99625 m +.16346 1 L +s +.21154 .99625 m +.21154 1 L +s +.30769 .99625 m +.30769 1 L +s +.35577 .99625 m +.35577 1 L +s +.40385 .99625 m +.40385 1 L +s +.45192 .99625 m +.45192 1 L +s +.54808 .99625 m +.54808 1 L +s +.59615 .99625 m +.59615 1 L +s +.64423 .99625 m +.64423 1 L +s +.69231 .99625 m +.69231 1 L +s +.78846 .99625 m +.78846 1 L +s +.83654 .99625 m +.83654 1 L +s +.88462 .99625 m +.88462 1 L +s +.93269 .99625 m +.93269 1 L +s +.25 Mabswid +0 1 m +1 1 L +s +.99375 .01923 m +1 .01923 L +s +.99375 .25962 m +1 .25962 L +s +.99375 .5 m +1 .5 L +s +.99375 .74038 m +1 .74038 L +s +.99375 .98077 m +1 .98077 L +s +.125 Mabswid +.99625 .06731 m +1 .06731 L +s +.99625 .11538 m +1 .11538 L +s +.99625 .16346 m +1 .16346 L +s +.99625 .21154 m +1 .21154 L +s +.99625 .30769 m +1 .30769 L +s +.99625 .35577 m +1 .35577 L +s +.99625 .40385 m +1 .40385 L +s +.99625 .45192 m +1 .45192 L +s +.99625 .54808 m +1 .54808 L +s +.99625 .59615 m +1 .59615 L +s +.99625 .64423 m +1 .64423 L +s +.99625 .69231 m +1 .69231 L +s +.99625 .78846 m +1 .78846 L +s +.99625 .83654 m +1 .83654 L +s +.99625 .88462 m +1 .88462 L +s +.99625 .93269 m +1 .93269 L +s +.25 Mabswid +1 0 m +1 1 L +s +0 0 m +1 0 L +1 1 L +0 1 L +closepath +clip +newpath +.5 g +.01923 .98077 m +.98077 .98077 L +.98077 .01923 L +.01923 .01923 L +F +0 g +.5 Mabswid +.4 g +.01923 .20178 m +.08791 .16652 L +.10274 .15659 L +.15659 .10274 L +.16652 .08791 L +.20178 .01923 L +.01923 .01923 L +F +0 g +.01923 .20178 m +.08791 .16652 L +.10274 .15659 L +.15659 .10274 L +.16652 .08791 L +.20178 .01923 L +s +.4 g +.01923 .68255 m +.08791 .64729 L +.10274 .63736 L +.15659 .58351 L +.16652 .56868 L +.20178 .5 L +.16652 .43132 L +.15659 .41649 L +.10274 .36264 L +.08791 .35271 L +.01923 .31745 L +F +0 g +.01923 .68255 m +.08791 .64729 L +.10274 .63736 L +.15659 .58351 L +.16652 .56868 L +.20178 .5 L +.16652 .43132 L +.15659 .41649 L +.10274 .36264 L +.08791 .35271 L +.01923 .31745 L +s +.4 g +.01923 .79822 m +.08791 .83348 L +.10274 .84341 L +.15659 .89726 L +.16652 .91209 L +.20178 .98077 L +.01923 .98077 L +F +0 g +.01923 .79822 m +.08791 .83348 L +.10274 .84341 L +.15659 .89726 L +.16652 .91209 L +.20178 .98077 L +s +.3 g +.01923 .16767 m +.04817 .15659 L +.08791 .14179 L +.14179 .08791 L +.15659 .04817 L +.16767 .01923 L +.01923 .01923 L +F +0 g +.01923 .16767 m +.04817 .15659 L +.08791 .14179 L +.14179 .08791 L +.15659 .04817 L +.16767 .01923 L +s +.3 g +.01923 .64844 m +.04817 .63736 L +.08791 .62256 L +.14179 .56868 L +.15659 .53811 L +.16767 .5 L +.15659 .46189 L +.14179 .43132 L +.08791 .37744 L +.04817 .36264 L +.01923 .35156 L +F +0 g +.01923 .64844 m +.04817 .63736 L +.08791 .62256 L +.14179 .56868 L +.15659 .53811 L +.16767 .5 L +.15659 .46189 L +.14179 .43132 L +.08791 .37744 L +.04817 .36264 L +.01923 .35156 L +s +.3 g +.01923 .83233 m +.04817 .84341 L +.08791 .85821 L +.14179 .91209 L +.15659 .95183 L +.16767 .98077 L +.01923 .98077 L +F +0 g +.01923 .83233 m +.04817 .84341 L +.08791 .85821 L +.14179 .91209 L +.15659 .95183 L +.16767 .98077 L +s +.2 g +.01923 .14263 m +.08791 .11498 L +.11498 .08791 L +.14263 .01923 L +.01923 .01923 L +F +0 g +.01923 .14263 m +.08791 .11498 L +.11498 .08791 L +.14263 .01923 L +s +.2 g +.01923 .6234 m +.08791 .59574 L +.11498 .56868 L +.14263 .5 L +.11498 .43132 L +.08791 .40426 L +.01923 .3766 L +F +0 g +.01923 .6234 m +.08791 .59574 L +.11498 .56868 L +.14263 .5 L +.11498 .43132 L +.08791 .40426 L +.01923 .3766 L +s +.2 g +.01923 .85737 m +.08791 .88502 L +.11498 .91209 L +.14263 .98077 L +.01923 .98077 L +F +0 g +.01923 .85737 m +.08791 .88502 L +.11498 .91209 L +.14263 .98077 L +s +.1 g +.01923 .11622 m +.06971 .08791 L +.08791 .06971 L +.11622 .01923 L +.01923 .01923 L +F +0 g +.01923 .11622 m +.06971 .08791 L +.08791 .06971 L +.11622 .01923 L +s +.1 g +.01923 .59699 m +.06971 .56868 L +.08791 .55491 L +.11622 .5 L +.08791 .44509 L +.06971 .43132 L +.01923 .40301 L +F +0 g +.01923 .59699 m +.06971 .56868 L +.08791 .55491 L +.11622 .5 L +.08791 .44509 L +.06971 .43132 L +.01923 .40301 L +s +.1 g +.01923 .88378 m +.06971 .91209 L +.08791 .93029 L +.11622 .98077 L +.01923 .98077 L +F +0 g +.01923 .88378 m +.06971 .91209 L +.08791 .93029 L +.11622 .98077 L +s +.01923 .07191 m +.07191 .01923 L +.01923 .01923 L +F +.01923 .07191 m +.07191 .01923 L +s +.01923 .55656 m +.07191 .5 L +.01923 .44344 L +F +.01923 .55656 m +.07191 .5 L +.01923 .44344 L +s +.01923 .92809 m +.07191 .98077 L +.01923 .98077 L +F +.01923 .92809 m +.07191 .98077 L +s +.6 g +.22527 .54531 m +.29396 .54531 L +.31893 .56868 L +.36264 .61483 L +.38517 .63736 L +.43132 .68107 L +.45469 .70604 L +.45469 .77473 L +.43132 .7997 L +.38517 .84341 L +.36264 .86594 L +.31893 .91209 L +.29396 .94288 L +.22527 .94288 L +.2003 .91209 L +.15659 .86594 L +.13406 .84341 L +.08791 .7997 L +.05712 .77473 L +.05712 .70604 L +.08791 .68107 L +.13406 .63736 L +.15659 .61483 L +.2003 .56868 L +F +0 g +.22527 .54531 m +.29396 .54531 L +.31893 .56868 L +.36264 .61483 L +.38517 .63736 L +.43132 .68107 L +.45469 .70604 L +.45469 .77473 L +.43132 .7997 L +.38517 .84341 L +.36264 .86594 L +.31893 .91209 L +.29396 .94288 L +.22527 .94288 L +.2003 .91209 L +.15659 .86594 L +.13406 .84341 L +.08791 .7997 L +.05712 .77473 L +.05712 .70604 L +.08791 .68107 L +.13406 .63736 L +.15659 .61483 L +.2003 .56868 L +.22527 .54531 L +s +.6 g +.22527 .05712 m +.29396 .05712 L +.31893 .08791 L +.36264 .13406 L +.38517 .15659 L +.43132 .2003 L +.45469 .22527 L +.45469 .29396 L +.43132 .31893 L +.38517 .36264 L +.36264 .38517 L +.31893 .43132 L +.29396 .45469 L +.22527 .45469 L +.2003 .43132 L +.15659 .38517 L +.13406 .36264 L +.08791 .31893 L +.05712 .29396 L +.05712 .22527 L +.08791 .2003 L +.13406 .15659 L +.15659 .13406 L +.2003 .08791 L +F +0 g +.22527 .05712 m +.29396 .05712 L +.31893 .08791 L +.36264 .13406 L +.38517 .15659 L +.43132 .2003 L +.45469 .22527 L +.45469 .29396 L +.43132 .31893 L +.38517 .36264 L +.36264 .38517 L +.31893 .43132 L +.29396 .45469 L +.22527 .45469 L +.2003 .43132 L +.15659 .38517 L +.13406 .36264 L +.08791 .31893 L +.05712 .29396 L +.05712 .22527 L +.08791 .2003 L +.13406 .15659 L +.15659 .13406 L +.2003 .08791 L +.22527 .05712 L +s +.7 g +.22527 .58861 m +.29396 .58861 L +.36261 .63736 L +.36264 .63739 L +.41139 .70604 L +.41139 .77473 L +.36264 .84338 L +.36261 .84341 L +.29396 .89216 L +.22527 .89216 L +.15662 .84341 L +.15659 .84338 L +.10784 .77473 L +.10784 .70604 L +.15659 .63739 L +.15662 .63736 L +F +0 g +.22527 .58861 m +.29396 .58861 L +.36261 .63736 L +.36264 .63739 L +.41139 .70604 L +.41139 .77473 L +.36264 .84338 L +.36261 .84341 L +.29396 .89216 L +.22527 .89216 L +.15662 .84341 L +.15659 .84338 L +.10784 .77473 L +.10784 .70604 L +.15659 .63739 L +.15662 .63736 L +.22527 .58861 L +s +.7 g +.22527 .10784 m +.29396 .10784 L +.36261 .15659 L +.36264 .15662 L +.41139 .22527 L +.41139 .29396 L +.36264 .36261 L +.36261 .36264 L +.29396 .41139 L +.22527 .41139 L +.15662 .36264 L +.15659 .36261 L +.10784 .29396 L +.10784 .22527 L +.15659 .15662 L +.15662 .15659 L +F +0 g +.22527 .10784 m +.29396 .10784 L +.36261 .15659 L +.36264 .15662 L +.41139 .22527 L +.41139 .29396 L +.36264 .36261 L +.36261 .36264 L +.29396 .41139 L +.22527 .41139 L +.15662 .36264 L +.15659 .36261 L +.10784 .29396 L +.10784 .22527 L +.15659 .15662 L +.15662 .15659 L +.22527 .10784 L +s +.8 g +.22527 .61796 m +.29396 .61796 L +.3311 .63736 L +.36264 .6689 L +.38204 .70604 L +.38204 .77473 L +.36264 .81187 L +.3311 .84341 L +.29396 .86281 L +.22527 .86281 L +.18813 .84341 L +.15659 .81187 L +.13719 .77473 L +.13719 .70604 L +.15659 .6689 L +.18813 .63736 L +F +0 g +.22527 .61796 m +.29396 .61796 L +.3311 .63736 L +.36264 .6689 L +.38204 .70604 L +.38204 .77473 L +.36264 .81187 L +.3311 .84341 L +.29396 .86281 L +.22527 .86281 L +.18813 .84341 L +.15659 .81187 L +.13719 .77473 L +.13719 .70604 L +.15659 .6689 L +.18813 .63736 L +.22527 .61796 L +s +.8 g +.22527 .13719 m +.29396 .13719 L +.3311 .15659 L +.36264 .18813 L +.38204 .22527 L +.38204 .29396 L +.36264 .3311 L +.3311 .36264 L +.29396 .38204 L +.22527 .38204 L +.18813 .36264 L +.15659 .3311 L +.13719 .29396 L +.13719 .22527 L +.15659 .18813 L +.18813 .15659 L +F +0 g +.22527 .13719 m +.29396 .13719 L +.3311 .15659 L +.36264 .18813 L +.38204 .22527 L +.38204 .29396 L +.36264 .3311 L +.3311 .36264 L +.29396 .38204 L +.22527 .38204 L +.18813 .36264 L +.15659 .3311 L +.13719 .29396 L +.13719 .22527 L +.15659 .18813 L +.18813 .15659 L +.22527 .13719 L +s +.9 g +.22527 .64125 m +.29396 .64125 L +.35875 .70604 L +.35875 .77473 L +.29396 .83952 L +.22527 .83952 L +.16048 .77473 L +.16048 .70604 L +F +0 g +.22527 .64125 m +.29396 .64125 L +.35875 .70604 L +.35875 .77473 L +.29396 .83952 L +.22527 .83952 L +.16048 .77473 L +.16048 .70604 L +.22527 .64125 L +s +.9 g +.22527 .16048 m +.29396 .16048 L +.35875 .22527 L +.35875 .29396 L +.29396 .35875 L +.22527 .35875 L +.16048 .29396 L +.16048 .22527 L +F +0 g +.22527 .16048 m +.29396 .16048 L +.35875 .22527 L +.35875 .29396 L +.29396 .35875 L +.22527 .35875 L +.16048 .29396 L +.16048 .22527 L +.22527 .16048 L +s +1 g +.22527 .67353 m +.29396 .67353 L +.32647 .70604 L +.32647 .77473 L +.29396 .80724 L +.22527 .80724 L +.19276 .77473 L +.19276 .70604 L +F +0 g +.22527 .67353 m +.29396 .67353 L +.32647 .70604 L +.32647 .77473 L +.29396 .80724 L +.22527 .80724 L +.19276 .77473 L +.19276 .70604 L +.22527 .67353 L +s +1 g +.22527 .19276 m +.29396 .19276 L +.32647 .22527 L +.32647 .29396 L +.29396 .32647 L +.22527 .32647 L +.19276 .29396 L +.19276 .22527 L +F +0 g +.22527 .19276 m +.29396 .19276 L +.32647 .22527 L +.32647 .29396 L +.29396 .32647 L +.22527 .32647 L +.19276 .29396 L +.19276 .22527 L +.22527 .19276 L +s +.4 g +.68255 .01923 m +.64729 .08791 L +.63736 .10274 L +.58351 .15659 L +.56868 .16652 L +.5 .20178 L +.43132 .16652 L +.41649 .15659 L +.36264 .10274 L +.35271 .08791 L +.31745 .01923 L +F +0 g +.68255 .01923 m +.64729 .08791 L +.63736 .10274 L +.58351 .15659 L +.56868 .16652 L +.5 .20178 L +.43132 .16652 L +.41649 .15659 L +.36264 .10274 L +.35271 .08791 L +.31745 .01923 L +s +.4 g +.43132 .35271 m +.5 .31745 L +.56868 .35271 L +.58351 .36264 L +.63736 .41649 L +.64729 .43132 L +.68255 .5 L +.64729 .56868 L +.63736 .58351 L +.58351 .63736 L +.56868 .64729 L +.5 .68255 L +.43132 .64729 L +.41649 .63736 L +.36264 .58351 L +.35271 .56868 L +.31745 .5 L +.35271 .43132 L +.36264 .41649 L +.41649 .36264 L +F +0 g +.43132 .35271 m +.5 .31745 L +.56868 .35271 L +.58351 .36264 L +.63736 .41649 L +.64729 .43132 L +.68255 .5 L +.64729 .56868 L +.63736 .58351 L +.58351 .63736 L +.56868 .64729 L +.5 .68255 L +.43132 .64729 L +.41649 .63736 L +.36264 .58351 L +.35271 .56868 L +.31745 .5 L +.35271 .43132 L +.36264 .41649 L +.41649 .36264 L +.43132 .35271 L +s +.4 g +.68255 .98077 m +.64729 .91209 L +.63736 .89726 L +.58351 .84341 L +.56868 .83348 L +.5 .79822 L +.43132 .83348 L +.41649 .84341 L +.36264 .89726 L +.35271 .91209 L +.31745 .98077 L +F +0 g +.68255 .98077 m +.64729 .91209 L +.63736 .89726 L +.58351 .84341 L +.56868 .83348 L +.5 .79822 L +.43132 .83348 L +.41649 .84341 L +.36264 .89726 L +.35271 .91209 L +.31745 .98077 L +s +.3 g +.64844 .01923 m +.63736 .04817 L +.62256 .08791 L +.56868 .14179 L +.53811 .15659 L +.5 .16767 L +.46189 .15659 L +.43132 .14179 L +.37744 .08791 L +.36264 .04817 L +.35156 .01923 L +F +0 g +.64844 .01923 m +.63736 .04817 L +.62256 .08791 L +.56868 .14179 L +.53811 .15659 L +.5 .16767 L +.46189 .15659 L +.43132 .14179 L +.37744 .08791 L +.36264 .04817 L +.35156 .01923 L +s +.3 g +.5 .35156 m +.53811 .36264 L +.56868 .37744 L +.62256 .43132 L +.63736 .46189 L +.64844 .5 L +.63736 .53811 L +.62256 .56868 L +.56868 .62256 L +.53811 .63736 L +.5 .64844 L +.46189 .63736 L +.43132 .62256 L +.37744 .56868 L +.36264 .53811 L +.35156 .5 L +.36264 .46189 L +.37744 .43132 L +.43132 .37744 L +.46189 .36264 L +F +0 g +.5 .35156 m +.53811 .36264 L +.56868 .37744 L +.62256 .43132 L +.63736 .46189 L +.64844 .5 L +.63736 .53811 L +.62256 .56868 L +.56868 .62256 L +.53811 .63736 L +.5 .64844 L +.46189 .63736 L +.43132 .62256 L +.37744 .56868 L +.36264 .53811 L +.35156 .5 L +.36264 .46189 L +.37744 .43132 L +.43132 .37744 L +.46189 .36264 L +.5 .35156 L +s +.3 g +.64844 .98077 m +.63736 .95183 L +.62256 .91209 L +.56868 .85821 L +.53811 .84341 L +.5 .83233 L +.46189 .84341 L +.43132 .85821 L +.37744 .91209 L +.36264 .95183 L +.35156 .98077 L +F +0 g +.64844 .98077 m +.63736 .95183 L +.62256 .91209 L +.56868 .85821 L +.53811 .84341 L +.5 .83233 L +.46189 .84341 L +.43132 .85821 L +.37744 .91209 L +.36264 .95183 L +.35156 .98077 L +s +.2 g +.6234 .01923 m +.59574 .08791 L +.56868 .11498 L +.5 .14263 L +.43132 .11498 L +.40426 .08791 L +.3766 .01923 L +F +0 g +.6234 .01923 m +.59574 .08791 L +.56868 .11498 L +.5 .14263 L +.43132 .11498 L +.40426 .08791 L +.3766 .01923 L +s +.2 g +.43132 .40426 m +.5 .3766 L +.56868 .40426 L +.59574 .43132 L +.6234 .5 L +.59574 .56868 L +.56868 .59574 L +.5 .6234 L +.43132 .59574 L +.40426 .56868 L +.3766 .5 L +.40426 .43132 L +F +0 g +.43132 .40426 m +.5 .3766 L +.56868 .40426 L +.59574 .43132 L +.6234 .5 L +.59574 .56868 L +.56868 .59574 L +.5 .6234 L +.43132 .59574 L +.40426 .56868 L +.3766 .5 L +.40426 .43132 L +.43132 .40426 L +s +.2 g +.6234 .98077 m +.59574 .91209 L +.56868 .88502 L +.5 .85737 L +.43132 .88502 L +.40426 .91209 L +.3766 .98077 L +F +0 g +.6234 .98077 m +.59574 .91209 L +.56868 .88502 L +.5 .85737 L +.43132 .88502 L +.40426 .91209 L +.3766 .98077 L +s +.1 g +.59699 .01923 m +.56868 .06971 L +.55491 .08791 L +.5 .11622 L +.44509 .08791 L +.43132 .06971 L +.40301 .01923 L +F +0 g +.59699 .01923 m +.56868 .06971 L +.55491 .08791 L +.5 .11622 L +.44509 .08791 L +.43132 .06971 L +.40301 .01923 L +s +.1 g +.5 .40301 m +.55491 .43132 L +.56868 .44509 L +.59699 .5 L +.56868 .55491 L +.55491 .56868 L +.5 .59699 L +.44509 .56868 L +.43132 .55491 L +.40301 .5 L +.43132 .44509 L +.44509 .43132 L +F +0 g +.5 .40301 m +.55491 .43132 L +.56868 .44509 L +.59699 .5 L +.56868 .55491 L +.55491 .56868 L +.5 .59699 L +.44509 .56868 L +.43132 .55491 L +.40301 .5 L +.43132 .44509 L +.44509 .43132 L +.5 .40301 L +s +.1 g +.59699 .98077 m +.56868 .93029 L +.55491 .91209 L +.5 .88378 L +.44509 .91209 L +.43132 .93029 L +.40301 .98077 L +F +0 g +.59699 .98077 m +.56868 .93029 L +.55491 .91209 L +.5 .88378 L +.44509 .91209 L +.43132 .93029 L +.40301 .98077 L +s +.55656 .01923 m +.5 .07191 L +.44344 .01923 L +F +.55656 .01923 m +.5 .07191 L +.44344 .01923 L +s +.5 .44344 m +.55656 .5 L +.5 .55656 L +.44344 .5 L +F +.5 .44344 m +.55656 .5 L +.5 .55656 L +.44344 .5 L +.5 .44344 L +s +.55656 .98077 m +.5 .92809 L +.44344 .98077 L +F +.55656 .98077 m +.5 .92809 L +.44344 .98077 L +s +.6 g +.70604 .54531 m +.77473 .54531 L +.7997 .56868 L +.84341 .61483 L +.86594 .63736 L +.91209 .68107 L +.94288 .70604 L +.94288 .77473 L +.91209 .7997 L +.86594 .84341 L +.84341 .86594 L +.7997 .91209 L +.77473 .94288 L +.70604 .94288 L +.68107 .91209 L +.63736 .86594 L +.61483 .84341 L +.56868 .7997 L +.54531 .77473 L +.54531 .70604 L +.56868 .68107 L +.61483 .63736 L +.63736 .61483 L +.68107 .56868 L +F +0 g +.70604 .54531 m +.77473 .54531 L +.7997 .56868 L +.84341 .61483 L +.86594 .63736 L +.91209 .68107 L +.94288 .70604 L +.94288 .77473 L +.91209 .7997 L +.86594 .84341 L +.84341 .86594 L +.7997 .91209 L +.77473 .94288 L +.70604 .94288 L +.68107 .91209 L +.63736 .86594 L +.61483 .84341 L +.56868 .7997 L +.54531 .77473 L +.54531 .70604 L +.56868 .68107 L +.61483 .63736 L +.63736 .61483 L +.68107 .56868 L +.70604 .54531 L +s +.6 g +.70604 .05712 m +.77473 .05712 L +.7997 .08791 L +.84341 .13406 L +.86594 .15659 L +.91209 .2003 L +.94288 .22527 L +.94288 .29396 L +.91209 .31893 L +.86594 .36264 L +.84341 .38517 L +.7997 .43132 L +.77473 .45469 L +.70604 .45469 L +.68107 .43132 L +.63736 .38517 L +.61483 .36264 L +.56868 .31893 L +.54531 .29396 L +.54531 .22527 L +.56868 .2003 L +.61483 .15659 L +.63736 .13406 L +.68107 .08791 L +F +0 g +.70604 .05712 m +.77473 .05712 L +.7997 .08791 L +.84341 .13406 L +.86594 .15659 L +.91209 .2003 L +.94288 .22527 L +.94288 .29396 L +.91209 .31893 L +.86594 .36264 L +.84341 .38517 L +.7997 .43132 L +.77473 .45469 L +.70604 .45469 L +.68107 .43132 L +.63736 .38517 L +.61483 .36264 L +.56868 .31893 L +.54531 .29396 L +.54531 .22527 L +.56868 .2003 L +.61483 .15659 L +.63736 .13406 L +.68107 .08791 L +.70604 .05712 L +s +.7 g +.70604 .58861 m +.77473 .58861 L +.84338 .63736 L +.84341 .63739 L +.89216 .70604 L +.89216 .77473 L +.84341 .84338 L +.84338 .84341 L +.77473 .89216 L +.70604 .89216 L +.63739 .84341 L +.63736 .84338 L +.58861 .77473 L +.58861 .70604 L +.63736 .63739 L +.63739 .63736 L +F +0 g +.70604 .58861 m +.77473 .58861 L +.84338 .63736 L +.84341 .63739 L +.89216 .70604 L +.89216 .77473 L +.84341 .84338 L +.84338 .84341 L +.77473 .89216 L +.70604 .89216 L +.63739 .84341 L +.63736 .84338 L +.58861 .77473 L +.58861 .70604 L +.63736 .63739 L +.63739 .63736 L +.70604 .58861 L +s +.7 g +.70604 .10784 m +.77473 .10784 L +.84338 .15659 L +.84341 .15662 L +.89216 .22527 L +.89216 .29396 L +.84341 .36261 L +.84338 .36264 L +.77473 .41139 L +.70604 .41139 L +.63739 .36264 L +.63736 .36261 L +.58861 .29396 L +.58861 .22527 L +.63736 .15662 L +.63739 .15659 L +F +0 g +.70604 .10784 m +.77473 .10784 L +.84338 .15659 L +.84341 .15662 L +.89216 .22527 L +.89216 .29396 L +.84341 .36261 L +.84338 .36264 L +.77473 .41139 L +.70604 .41139 L +.63739 .36264 L +.63736 .36261 L +.58861 .29396 L +.58861 .22527 L +.63736 .15662 L +.63739 .15659 L +.70604 .10784 L +s +.8 g +.70604 .61796 m +.77473 .61796 L +.81187 .63736 L +.84341 .6689 L +.86281 .70604 L +.86281 .77473 L +.84341 .81187 L +.81187 .84341 L +.77473 .86281 L +.70604 .86281 L +.6689 .84341 L +.63736 .81187 L +.61796 .77473 L +.61796 .70604 L +.63736 .6689 L +.6689 .63736 L +F +0 g +.70604 .61796 m +.77473 .61796 L +.81187 .63736 L +.84341 .6689 L +.86281 .70604 L +.86281 .77473 L +.84341 .81187 L +.81187 .84341 L +.77473 .86281 L +.70604 .86281 L +.6689 .84341 L +.63736 .81187 L +.61796 .77473 L +.61796 .70604 L +.63736 .6689 L +.6689 .63736 L +.70604 .61796 L +s +.8 g +.70604 .13719 m +.77473 .13719 L +.81187 .15659 L +.84341 .18813 L +.86281 .22527 L +.86281 .29396 L +.84341 .3311 L +.81187 .36264 L +.77473 .38204 L +.70604 .38204 L +.6689 .36264 L +.63736 .3311 L +.61796 .29396 L +.61796 .22527 L +.63736 .18813 L +.6689 .15659 L +F +0 g +.70604 .13719 m +.77473 .13719 L +.81187 .15659 L +.84341 .18813 L +.86281 .22527 L +.86281 .29396 L +.84341 .3311 L +.81187 .36264 L +.77473 .38204 L +.70604 .38204 L +.6689 .36264 L +.63736 .3311 L +.61796 .29396 L +.61796 .22527 L +.63736 .18813 L +.6689 .15659 L +.70604 .13719 L +s +.9 g +.70604 .64125 m +.77473 .64125 L +.83952 .70604 L +.83952 .77473 L +.77473 .83952 L +.70604 .83952 L +.64125 .77473 L +.64125 .70604 L +F +0 g +.70604 .64125 m +.77473 .64125 L +.83952 .70604 L +.83952 .77473 L +.77473 .83952 L +.70604 .83952 L +.64125 .77473 L +.64125 .70604 L +.70604 .64125 L +s +.9 g +.70604 .16048 m +.77473 .16048 L +.83952 .22527 L +.83952 .29396 L +.77473 .35875 L +.70604 .35875 L +.64125 .29396 L +.64125 .22527 L +F +0 g +.70604 .16048 m +.77473 .16048 L +.83952 .22527 L +.83952 .29396 L +.77473 .35875 L +.70604 .35875 L +.64125 .29396 L +.64125 .22527 L +.70604 .16048 L +s +1 g +.70604 .67353 m +.77473 .67353 L +.80724 .70604 L +.80724 .77473 L +.77473 .80724 L +.70604 .80724 L +.67353 .77473 L +.67353 .70604 L +F +0 g +.70604 .67353 m +.77473 .67353 L +.80724 .70604 L +.80724 .77473 L +.77473 .80724 L +.70604 .80724 L +.67353 .77473 L +.67353 .70604 L +.70604 .67353 L +s +1 g +.70604 .19276 m +.77473 .19276 L +.80724 .22527 L +.80724 .29396 L +.77473 .32647 L +.70604 .32647 L +.67353 .29396 L +.67353 .22527 L +F +0 g +.70604 .19276 m +.77473 .19276 L +.80724 .22527 L +.80724 .29396 L +.77473 .32647 L +.70604 .32647 L +.67353 .29396 L +.67353 .22527 L +.70604 .19276 L +s +.4 g +.98077 .20178 m +.91209 .16652 L +.89726 .15659 L +.84341 .10274 L +.83348 .08791 L +.79822 .01923 L +.98077 .01923 L +F +0 g +.98077 .20178 m +.91209 .16652 L +.89726 .15659 L +.84341 .10274 L +.83348 .08791 L +.79822 .01923 L +s +.4 g +.98077 .68255 m +.91209 .64729 L +.89726 .63736 L +.84341 .58351 L +.83348 .56868 L +.79822 .5 L +.83348 .43132 L +.84341 .41649 L +.89726 .36264 L +.91209 .35271 L +.98077 .31745 L +F +0 g +.98077 .68255 m +.91209 .64729 L +.89726 .63736 L +.84341 .58351 L +.83348 .56868 L +.79822 .5 L +.83348 .43132 L +.84341 .41649 L +.89726 .36264 L +.91209 .35271 L +.98077 .31745 L +s +.4 g +.98077 .79822 m +.91209 .83348 L +.89726 .84341 L +.84341 .89726 L +.83348 .91209 L +.79822 .98077 L +.98077 .98077 L +F +0 g +.98077 .79822 m +.91209 .83348 L +.89726 .84341 L +.84341 .89726 L +.83348 .91209 L +.79822 .98077 L +s +.3 g +.98077 .16767 m +.95183 .15659 L +.91209 .14179 L +.85821 .08791 L +.84341 .04817 L +.83233 .01923 L +.98077 .01923 L +F +0 g +.98077 .16767 m +.95183 .15659 L +.91209 .14179 L +.85821 .08791 L +.84341 .04817 L +.83233 .01923 L +s +.3 g +.98077 .64844 m +.95183 .63736 L +.91209 .62256 L +.85821 .56868 L +.84341 .53811 L +.83233 .5 L +.84341 .46189 L +.85821 .43132 L +.91209 .37744 L +.95183 .36264 L +.98077 .35156 L +F +0 g +.98077 .64844 m +.95183 .63736 L +.91209 .62256 L +.85821 .56868 L +.84341 .53811 L +.83233 .5 L +.84341 .46189 L +.85821 .43132 L +.91209 .37744 L +.95183 .36264 L +.98077 .35156 L +s +.3 g +.98077 .83233 m +.95183 .84341 L +.91209 .85821 L +.85821 .91209 L +.84341 .95183 L +.83233 .98077 L +.98077 .98077 L +F +0 g +.98077 .83233 m +.95183 .84341 L +.91209 .85821 L +.85821 .91209 L +.84341 .95183 L +.83233 .98077 L +s +.2 g +.98077 .14263 m +.91209 .11498 L +.88502 .08791 L +.85737 .01923 L +.98077 .01923 L +F +0 g +.98077 .14263 m +.91209 .11498 L +.88502 .08791 L +.85737 .01923 L +s +.2 g +.98077 .6234 m +.91209 .59574 L +.88502 .56868 L +.85737 .5 L +.88502 .43132 L +.91209 .40426 L +.98077 .3766 L +F +0 g +.98077 .6234 m +.91209 .59574 L +.88502 .56868 L +.85737 .5 L +.88502 .43132 L +.91209 .40426 L +.98077 .3766 L +s +.2 g +.98077 .85737 m +.91209 .88502 L +.88502 .91209 L +.85737 .98077 L +.98077 .98077 L +F +0 g +.98077 .85737 m +.91209 .88502 L +.88502 .91209 L +.85737 .98077 L +s +.1 g +.98077 .11622 m +.93029 .08791 L +.91209 .06971 L +.88378 .01923 L +.98077 .01923 L +F +0 g +.98077 .11622 m +.93029 .08791 L +.91209 .06971 L +.88378 .01923 L +s +.1 g +.98077 .59699 m +.93029 .56868 L +.91209 .55491 L +.88378 .5 L +.91209 .44509 L +.93029 .43132 L +.98077 .40301 L +F +0 g +.98077 .59699 m +.93029 .56868 L +.91209 .55491 L +.88378 .5 L +.91209 .44509 L +.93029 .43132 L +.98077 .40301 L +s +.1 g +.98077 .88378 m +.93029 .91209 L +.91209 .93029 L +.88378 .98077 L +.98077 .98077 L +F +0 g +.98077 .88378 m +.93029 .91209 L +.91209 .93029 L +.88378 .98077 L +s +.98077 .07191 m +.92809 .01923 L +.98077 .01923 L +F +.98077 .07191 m +.92809 .01923 L +s +.98077 .55656 m +.92809 .5 L +.98077 .44344 L +F +.98077 .55656 m +.92809 .5 L +.98077 .44344 L +s +.98077 .92809 m +.92809 .98077 L +.98077 .98077 L +F +.98077 .92809 m +.92809 .98077 L +s +% End of Graphics +MathPictureEnd +\ +\>"], "Graphics", + ImageSize->{288, 288}, + ImageMargins->{{43, 0}, {0, 0}}, + ImageRegion->{{0, 1}, {0, 1}}, + ImageCache->GraphicsData["Bitmap", "\<\ +CF5dJ6E]HGAYHf4PAg9QL6QYHgon6Ykno_hn?S`2ook>c/mWIfGmoOol005E[;lC4a000<`00IP00V@00c000 +o`0c000c<`0cIP0cV@0cc00co`1V001V<`1VIP1VV@1Vc01Vo`2I002I<`2IIP2IV@2Ic02Io`3<003< +<`3I03>IIIS>IVC>Ic3>Ioc?<03?<@000`40000f00030@0000L00`4i0003 +0@0000@0000H00040@000CH000@1000120000`40000i00030@0003H000<100001`000`40000j0003 +0@0000<0000H00040@000CH000@1000120000`40000g00<1=P030@T000<10000=`00104000450000 +6@020CP00P4900@1>0000`40000f00030@0000L0104g00811P000?l08@0001D0o`4;0@40000E0003 +0@00008000<100002P000`40000900030@0000X000<100002P000`40000:00030@0000X000<10000 +2@000`40000:00030@0000X000<100002P000`40000900030@0000X000<100002P000`40000:0003 +0@0000T000<100002P000`40000:00030@0000X000<100002P000`40000900030@0000800@410000 +5@000`40000200030@0003d000<10000?@000`40000l00030@0003d000<100000P010@40000E0003 +0@000?l01`010@40000>00811@000`40003o00L00@4100003@001040004400814@000`4000090003 +0@0000@000<100000`000`40000600030@0001`000<100001P000`40000400030@0000@000<10000 +20000`40000K00030@0000L000<1000010000`40000400030@0000H000<1000070000`4000060003 +0@0000<000<100001@000`40000800030@0000l00P4100003@001040004400030@0000803P403581 +DP5B0E81DP5B0@MB00L12E89DPT100P902012JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@P9 +00P1DPUB2E890@MB00X1DP5B0E81DP5B7`402U81DP5B0E81DP46DP080E89DPUB2@482@0P0@VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`482@070E89DPUB0@08DP0:0E81DP5B0E81DPh11@010@40 +000=00040@000@@000<100000P0=0@0;DP5B0E81DP5B0E800P46DP070@UB2E890@082@0R0@VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@P900P1DPUB2E890@IB0P402E81DP5B0E81DP0M0@0: +DP5B0E81DP5B0@IB00P1DPUB2E890@P902812JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1 +20T01`5B2E89DP401e820@09DP5B0E81DP5B00d11@010@40000=00040@000@@000<100000P0<0@0; +DP5B0E81DP5B0E800P47DP070E89DPUB0@082@0R0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL90@P900P12E89DPUB0@MB0P402E81DP5B0E81DP0K0@09DP5B0E81DP5B00811U802049DPUB2E81 +20T08P6W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@482@070@UB2E890@08DP8100UB0E81 +DP5B0E80304500410@0000d000@1000110000`40000200/100iB0E81DP5B0E81DP5B0@IB00P1DPUB +2E890@L902@1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@482@070@UB2E890@07DP0< +0E81DP5B0E81DP5B6@402E81DP5B0E81DP020@MB00P1DPUB2E890@L902@1Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2@482@070@UB2E890@07DP0<0E81DP5B0E81DP5B2`4500410@0000h0 +0P4500030@0000802P403U81DP5B0E81DP5B0E811e801`49DPUB2@4020T09049Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@P900P1DPUB2E890@MB00`1DP5B0E81DP5B0E8G0@00E81DP5B0E81DP5B0E870@D00@410000 +5@000`40000200H1011B0E81DP5B0E81DP5B0E811e802049DPUB2E811`T0:049Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`472@080@UB2E89DP48DP0@0E81DP5B0E81DP5B0E81DP/1 +011B0E81DP5B0E81DP5B0E811e802049DPUB2E811`T0:049Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`472@080@UB2E89DP48DP0>0E81DP5B0E81DP5B0E860@D00@4100005@000`40 +000200D1011B0E81DP5B0E81DP5B0E8125801`5B2E89DP401`T0:P49Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@L900P12E89DPUB0@MB0P403e81DP5B0E81DP5B0E81DP090@0@ +DP5B0E81DP5B0E81DP5B0@MB00P12E89DPUB0@L902X12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`472@070@UB2E890@08DP8100eB0E81DP5B0E81DP5B00D11@010@40000E0003 +0@00008010403e81DP5B0E81DP5B0E81DP020@MB00P1DPUB2E890@L900`1Y`VW2JL9Y`VW2JLC0@0; +Y`VW2JL9Y`VW2@401`T0205B2E89DPT125820@0?DP5B0E81DP5B0E81DP5B00L100mB0E81DP5B0E81 +DP5B0E800P47DP080E89DPUB2@472@0;0JL9Y`VW2JL9Y`T050402jL9Y`VW2JL9Y`T100L900P1DPUB +2E890@QB0P403E81DP5B0E81DP5B0E80104500410@0001D000<100000P030@0?DP5B0E81DP5B0E81 +DP5B008125802049DPUB2E811PT03@6W2JL9Y`VW2JL9Y`404jL0306W2JL9Y`VW2JL90@H900P12E89 +DPUB0@QB0181DP5B0E81DP5B0E81DP5B0E850@0?DP5B0E81DP5B0E81DP5B008125802049DPUB2E81 +1PT0306W2JL9Y`VW2JL90ABW00`1Y`VW2JL9Y`VW2@462@080@UB2E89DP48DP0@0E81DP5B0E81DP5B +0E81DP<11@010@40000E00810`020@0BDP5B0E81DP5B0E81DP5B0E8125801`5B2E89DP401`T03049 +Y`VW2JL9Y`VW0AFW00/1Y`VW2JL9Y`VW0@072@080@UB2E89DP48DP0B0E81DP5B0E81DP5B0E81DP5B +0`404U81DP5B0E81DP5B0E81DP5B0@MB00P12E89DPUB0@L900`12JL9Y`VW2JL9Y`4EY`0;0JL9Y`VW +2JL9Y`401`T01`49DPUB2@402E80405B0E81DP5B0E81DP5B0E820@@00P4100005@000`400002000C +0E81DP5B0E81DP5B0E81DP5B0@08DP080E89DPUB2@462@0<0@VW2JL9Y`VW2JL15jL02`6W2JL9Y`VW +2JL100H900P1DPUB2E890@QB0P409581DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0@QB +00P1DPUB2E890@H900`12JL9Y`VW2JL9Y`4FY`0<0@VW2JL9Y`VW2JL11PT0205B2E89DPT125820@0? +DP5B0E81DP5B0E81DP5B008110010@40000E00030@000080019B0E81DP5B0E81DP5B0E81DP49DP07 +0@UB2E890@072@0<0JL9Y`VW2JL9Y`T16:L02P6W2JL9Y`VW2@472@080E89DPUB2@48DP81029B0E81 +DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E812580205B2E89DPT11`T02`6W2JL9Y`VW2JL101RW +00/12JL9Y`VW2JL90@072@070E89DPUB0@09DP8100mB0E81DP5B0E81DP5B0E801@010@40000E0003 +0@0000800141DP5B0E81DP5B0E81DP5B0@09DP080@UB2E89DP462@0<0JL9Y`VW2JL9Y`T16JL02`49 +Y`VW2JL9Y`T100H900P12E89DPUB0@UB0P408581DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81 +2E802049DPUB2E811PT02`6W2JL9Y`VW2JL101ZW00/12JL9Y`VW2JL90@062@080@UB2E89DP49DP81 +00iB0E81DP5B0E81DP5B0@D00@4100005@000`400002000@DP5B0E81DP5B0E81DP5B0@YB00P1DPUB +2E890@H900/12JL9Y`VW2JL90@0KY`0:0@VW2JL9Y`VW0@H900P1DPUB2E890@UB0201DP5B0E81DP5B +0E81DP5B0E81DP5B0E81DP5B0E81DP812E80205B2E89DPT11PT02`49Y`VW2JL9Y`T101^W00X12JL9 +Y`VW2JL11PT0205B2E89DPT12U820@0=DP5B0E81DP5B0E81DP0500410@0001D000<100000P003`5B +0E81DP5B0E81DP5B0@0:DP080E89DPUB2@462@0;0@VW2JL9Y`VW2@407JL02P49Y`VW2JL9Y`462@08 +0E89DPUB2@49DP0N0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0P49DP080E89DPUB2@462@0; +0@VW2JL9Y`VW2@407:L02`6W2JL9Y`VW2JL100H900P1DPUB2E890@YB0P403581DP5B0E81DP5B0@D0 +0@4100005@000`400002000>DP5B0E81DP5B0E81DP4;DP080@UB2E89DP462@0:0JL9Y`VW2JL90AnW +00T12JL9Y`VW2@401PT02049DPUB2E812U830@0IDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@YB +00P12E89DPUB0@H900X1Y`VW2JL9Y`T17ZL02P6W2JL9Y`VW2@462@080@UB2E89DP4;DP8100]B0E81 +DP5B0E81DP0500410@0001D000<100000P002P5B0E81DP5B0E830@]B00P12E89DPUB0@H900X1Y`VW +2JL9Y`T18JL02@49Y`VW2JL90@062@080@UB2E89DP4;DP8101EB0E81DP5B0E81DP5B0E81DP5B0E80 +0`4;DP080@UB2E89DP462@0:0JL9Y`VW2JL90B2W00X1Y`VW2JL9Y`T11PT02049DPUB2E812e820@0: +DP5B0E81DP5B0@D00@4100005@000`4000020009DP5B0E81DP5B008135802049DPUB2E811`T02@49 +Y`VW2JL90@0SY`090@VW2JL9Y`T100H900P12E89DPUB0@aB0`404E81DP5B0E81DP5B0E81DP5B0081 +35802049DPUB2E811`T02@49Y`VW2JL90@0RY`0:0JL9Y`VW2JL90@H900P12E89DPUB0@aB0`401e81 +DP5B0E801@010@40000E00030@00008000H1DP5B0E830@eB00P12E89DPUB0@L900T12JL9Y`VW2@40 +9JL02049Y`VW2JL11`T02049DPUB2E813E820@0=DP5B0E81DP5B0E81DP030@eB00P12E89DPUB0@L9 +00T12JL9Y`VW2@409:L02@6W2JL9Y`VW0@072@080@UB2E89DP4=DP8100IB0E81DP4500410@0001D0 +00<100000P001E81DP5B00813U802049DPUB2E811`T02@49Y`VW2JL90@0WY`080@VW2JL9Y`472@08 +0@UB2E89DP4>DP<100UB0E81DP5B0E800P4>DP080@UB2E89DP472@090@VW2JL9Y`T102JW00T1Y`VW +2JL9Y`401`T02049DPUB2E813U830@03DP5B00D00@4100005@000`40000200030E8100813e802049 +DPUB2E811`T02@49Y`VW2JL90@0;Ya<12jL02049Y`VW2JL11`T02049DPUB2E813e820@05DP5B0E80 +0`4?DP080@UB2E89DP472@090@VW2JL9Y`T100ZW504:Y`090JL9Y`VW2JL100L900P12E89DPUB0@mB +0P400e81000400410@0001D000<100000P000e810@0@DP080@UB2E89DP472@090@VW2JL9Y`T100ZW +0P404jL8Y`RW2:L8Y`RW2:L8Y`RW2:L00P4:Y`080@VW2JL9Y`472@080@UB2E89DP4@DP<100=B0@40 +45802049DPUB2E811`T02@49Y`VW2JL90@09Y`8101@8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`812JL02@6W +2JL9Y`VW0@072@080@UB2E89DP4@DP811@010@40000E00810`000`5BDP0>DP8100L9DPUB2E8100L9 +00T12JL9Y`VW2@402ZL06@48Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20402JL02@6W2JL9Y`VW0@072@07 +0@UB2E89DP020A1B0P4@DP8100L9DPUB2E8100L900T12JL9Y`VW2@402JL06P6W2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`P12JL02@6W2JL9Y`VW0@072@070@UB2E89DP020A1B00@100000P4100005@000`40 +000200mB0P402589DPUB2E811`T02@49Y`VW2JL90@09Y`8101X8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L80@VW00T1Y`VW2JL9Y`401`T02049DPUB2E890`4MDP8100QB2E89DPUB0@L900T12JL9Y`VW2@40 +2JL0706W2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2049Y`090JL9Y`VW2JL100L900P12E89DPUB2@81 +3U8500410@0001D000<100000P02@@1 +00=B2E800`4>2@0:0JL9Y`VW2JL90@JW00P12:L8Y`RW0@X801H100P0200800P0200800P0200800P1 +2@P02@6W2:L8Y`RW0@06Y`080JL9Y`VW2JL20@l90P400`T0000200810@0001D000<100000P020@l9 +0P402JL9Y`VW2JL90@06Y`090@RW2:L8Y`P100X801L1200800P0200800P0200800P020080@0:2008 +0@RW2:L8Y`46Y`090JL9Y`VW2JL9008140T30@l90P402JL9Y`VW2JL90@06Y`080@RW2:L8Y`4:200H +0@0800P0200800P0200800P0200800P12@P02@6W2:L8Y`RW0@06Y`0:0JL9Y`VW2JL90A090P440041 +0@0001D000<100000P0?2@8100X9Y`VW2JL9Y`T11ZL01`48Y`RW2:L00P4:200I0@P0200800P02008 +00P0200800P020080@0:20080@RW2:L8Y`46Y`0:0JL9Y`VW2JL9Y`817PT20@0:2JL9Y`VW2JL90@JW +00P12:L8Y`RW0@X801X100P0200800P0200800P0200800P020080@T80P401`RW2:L8Y`401ZL02@6W +2JL9Y`VW2@020@l91@010@40000E00030@0000803@T20@0;Y`VW2JL9Y`VW2@401ZL02048Y`RW2:L1 +2`P06`4800P0200800P0200800P0200800P020080@0:20080@RW2:L8Y`46Y`0;0JL9Y`VW2JL9Y`T0 +0P4J2@8100^W2JL9Y`VW2JL90@06Y`080@RW2:L8Y`4:200L0@0800P0200800P0200800P0200800P0 +20080@X800P12:L8Y`RW0@JW00X1Y`VW2JL9Y`VW0P4=2@D00@4100005@000`40000200/90P4030VW +2JL9Y`VW2JL90@NW00L1Y`RW2:L100/801d1200800P0200800P0200800P0200800P020080@0:2007 +0@RW2:L80@07Y`0<0JL9Y`VW2JL9Y`VW0P4F2@8100`9Y`VW2JL9Y`VW2@47Y`070JL8Y`RW0@0:200N +0@0800P0200800P0200800P0200800P0200800P12PP01`48Y`RW20401jL02`6W2JL9Y`VW2JL90081 +2`T500410@0001D000<100000P092@8100fW2JL9Y`VW2JL9Y`T100NW00L1Y`RW2:L100/801l12008 +00P0200800P0200800P0200800P0200800P100X800L12:L8Y`P100NW00d1Y`VW2JL9Y`VW2JL90081 +4PT20@0=Y`VW2JL9Y`VW2JL90@07Y`070JL8Y`RW0@0:200P0@0800P0200800P0200800P0200800P0 +200800P0204:20070@RW2:L80@07Y`0<0JL9Y`VW2JL9Y`VW0P492@D00@4100005@000`40000200L9 +0P403PVW2JL9Y`VW2JL9Y`T11jL01`6W2:L8Y`402`P08@4800P0200800P0200800P0200800P02008 +00P020080@0:20070@RW2:L80@07Y`0>0JL9Y`VW2JL9Y`VW2JL20@h90P403PVW2JL9Y`VW2JL9Y`T1 +1jL01`6W2:L8Y`402PP08P40200800P0200800P0200800P0200800P0200800P0204:20070@RW2:L8 +0@07Y`0=0JL9Y`VW2JL9Y`VW2@020@L91@010@40000E00030@0000801@T20@0?Y`VW2JL9Y`VW2JL9 +Y`T100RW00L12:L8Y`P100T80P408PP0200800P0200800P0200800P0200800P0200800P0204:2007 +0@RW2:L80@07Y`0?0JL9Y`VW2JL9Y`VW2JL900812PT20@0?Y`VW2JL9Y`VW2JL9Y`T100RW00L12:L8 +Y`P100T802@100P0200800P0200800P0200800P0200800P0200800P0204:20070@RW2:L80@07Y`0> +0JL9Y`VW2JL9Y`VW2JL20@D91@010@40000E00030@0000800`T20@0@2JL9Y`VW2JL9Y`VW2JL90@RW +00L12:L8Y`P100T800X100P0200800P04`402@0800P020080@0920070JL8Y`RW0@08Y`0@0JL9Y`VW +2JL9Y`VW2JL9Y`811PT20@0@2JL9Y`VW2JL9Y`VW2JL90@RW00L12:L8Y`P100T800T100P0200800P0 +50402@0800P020080@0920070JL8Y`RW0@08Y`0?0JL9Y`VW2JL9Y`VW2JL900810`T500410@0001D0 +00<100000P0050T10JL9Y`VW2JL9Y`VW2JL9Y`T12:L02048Y`RW2:L120P02`40200800P0200101<0 +00X100P0200800P12@P01`6W2:L8Y`402:L04@6W2JL9Y`VW2JL9Y`VW2JL900810PT20@0AY`VW2JL9 +Y`VW2JL9Y`VW2@402:L02048Y`RW2:L120P02P40200800P0204D000:0@0800P020080@T800L1Y`RW +2:L100RW0101Y`VW2JL9Y`VW2JL9Y`VW0P400`T0000300410@0001D000<100000P004`49Y`VW2JL9 +Y`VW2JL9Y`VW2@402:L02048Y`RW2:L120P02`40200800P0200101D000X100P0200800P120P02048 +Y`RW2:L12:L04P6W2JL9Y`VW2JL9Y`VW2JL9Y`810189Y`VW2JL9Y`VW2JL9Y`VW2@48Y`080@RW2:L8 +Y`48200:0@0800P020080AH000X100P0200800P120P02048Y`RW2:L12:L04@6W2JL9Y`VW2JL9Y`VW +2JL9008110010@40000E00030@0000800109Y`VW2JL9Y`VW2JL9Y`VW0P49Y`080JL8Y`RW2047200; +0@0800P0200800405`002P40200800P0204820070@RW2:L80@09Y`0T0JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`T12JL0206W2:L8Y`P11`P02P40200800P0204H000:0@0800P020080@P8 +00L12:L8Y`P100VW0141Y`VW2JL9Y`VW2JL9Y`VW2@0500410@0001D000<100000P004:L9Y`VW2JL9 +Y`VW2JL9Y`4:Y`080JL8Y`RW204720090@0800P0200800816@020@08200800P0204720080JL8Y`RW +2049Y`0R0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@VW00P1Y`RW2:L80@L800X100P0 +200800P16P002P40200800P0204720080JL8Y`RW2049Y`8100h9Y`VW2JL9Y`VW2JL9Y`D00@410000 +5@020@<000l9Y`VW2JL9Y`VW2JL9Y`402ZL02@6W2:L8Y`RW0@06200:0@0800P020080Ad000T12008 +00P020401`P0206W2:L8Y`P12JL20@0N2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T12JL02@6W +2:L8Y`RW0@06200:0@0800P020080A`000X100P0200800P11`P0206W2:L8Y`P12ZL03P49Y`VW2JL9 +Y`VW2JL910020@40000E00030@00008000bW2JL9Y`VW2JL9Y`T20@ZW00T1Y`RW2:L8Y`401PP02P40 +200800P0204O00090@P0200800P100H800T12:L8Y`RW20402ZL07@49Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`T100VW00T1Y`RW2:L8Y`401PP02P40200800P0204N000:0@0800P020080@H800T12:L8 +Y`RW20402ZL03@49Y`VW2JL9Y`VW2JL01@010@40000E00030@00008000`9Y`VW2JL9Y`VW2@42JL9Y`VW2JL9Y`VW2@4;Y`090JL8Y`RW2:L100H800X100P0 +200800P17@002@4800P020080@0720080JL8Y`RW204:Y`0O0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL90@09Y`090JL8Y`RW2:L100H800X100P0200800P170002P40200800P0204720080JL8Y`RW +204:Y`8100bW2JL9Y`VW2JL9Y`T500410@0001D00P43000>Y`VW2JL9Y`VW2JL9Y`T20@ZW00P1Y`RW +2:L80@L800X100P0200800P16`002@4800P020080@0720080JL8Y`RW204:Y`0P0@VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4:Y`080JL8Y`RW2047200:0@0800P020080AX000X100P0200800P1 +1`P0206W2:L8Y`P12ZL03`49Y`VW2JL9Y`VW2JL9Y`0400810@0001D000<100000P004@VW2JL9Y`VW +2JL9Y`VW2JL100VW00T12:L8Y`RW20401`P02P40200800P0204I00090@P0200800P100P800P12:L8 +Y`RW0@VW02812JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL12JL02@48Y`RW2:L80@072009 +0@0800P0200101X000T1200800P0204020P02048Y`RW2:L12JL04049Y`VW2JL9Y`VW2JL9Y`T50041 +0@0001D000<100000P004ZL9Y`VW2JL9Y`VW2JL9Y`VW0@VW00P12:L8Y`RW0@P800X100P0200800P1 +5`002@4800P020080@0820080@RW2:L8Y`49Y`0T0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL12JL02048Y`RW2:L120P02@40200800P00@0H00090@P0200800P100P800P12:L8Y`RW0@VW +01412JL9Y`VW2JL9Y`VW2JL9Y`0500410@0001D000<100000P004`6W2JL9Y`VW2JL9Y`VW2JL9Y`40 +2JL02048Y`RW2:L120P02P40200800P0204E00090@P0200800P100T800L1Y`RW2:L100VW01812JL9 +Y`VW2JL9Y`VW2JL9Y`T20@0BY`VW2JL9Y`VW2JL9Y`VW2JL12JL02048Y`RW2:L120P02@40200800P0 +0@0F00090@P0200800P100T800L1Y`RW2:L100VW01412JL9Y`VW2JL9Y`VW2JL9Y`020@@00@410000 +5@000`400002000D2@412JL9Y`VW2JL9Y`VW2JL9Y`48Y`080JL8Y`RW2049200:0@0800P020080A<0 +00T1200800P020402@P0206W2:L8Y`P12:L04@49Y`VW2JL9Y`VW2JL9Y`VW00810PT20@0A2JL9Y`VW +2JL9Y`VW2JL9Y`402:L0206W2:L8Y`P12@P02@40200800P00@0D00090@P0200800P100T800P1Y`RW +2:L80@RW01012JL9Y`VW2JL9Y`VW2JL90P400`T0000300410@0001D000<100000P032@81012W2JL9 +Y`VW2JL9Y`VW2JL12:L0206W2:L8Y`P12@P02@40200800P0200C0@09200800P0200100T800L12:L8 +Y`P100RW01012JL9Y`VW2JL9Y`VW2JL90P462@81012W2JL9Y`VW2JL9Y`VW2JL12:L0206W2:L8Y`P1 +2@P02040200800P050402@P0200800P00@0920070@RW2:L80@08Y`0?0@VW2JL9Y`VW2JL9Y`VW0081 +0`T500410@0001D000<100000P052@8100l9Y`VW2JL9Y`VW2JL9Y`402:L01`6W2:L8Y`402PP08`40 +200800P0200800P0200800P0200800P0200800P0200100T800L12:L8Y`P100RW00l12JL9Y`VW2JL9 +Y`VW2JL00P4:2@8100l9Y`VW2JL9Y`VW2JL9Y`402:L01`6W2:L8Y`402@P0904800P0200800P02008 +00P0200800P0200800P0200800P00@T800L12:L8Y`P100RW00h12JL9Y`VW2JL9Y`VW2@811@T50041 +0@0001D000<100000P072@8100jW2JL9Y`VW2JL9Y`VW0@RW00L1Y`RW2:L100X8024100P0200800P0 +200800P0200800P0200800P0200800402@P01`48Y`RW20402:L03P49Y`VW2JL9Y`VW2JL90P4>2@81 +00jW2JL9Y`VW2JL9Y`VW0@RW00L1Y`RW2:L100T80281200800P0200800P0200800P0200800P02008 +00P020012@P01`48Y`RW20402:L03@49Y`VW2JL9Y`VW2JL00P472@D00@4100005@000`40000200T9 +0P403@VW2JL9Y`VW2JL9Y`401jL02048Y`RW2:L12PP07`40200800P0200800P0200800P0200800P0 +200800402@P02048Y`RW2:L11jL03@49Y`VW2JL9Y`VW2JL00P4B2@8100d9Y`VW2JL9Y`VW2JL100NW +00P12:L8Y`RW0@T80201200800P0200800P0200800P0200800P0200800P00@T800P12:L8Y`RW0@NW +00`12JL9Y`VW2JL9Y`T20@T91@010@40000E00030@0000802`T20@0DP030@0000800@4100005@020@<000=B0@403U820@07 +DPUB2E890@072@090JL9Y`VW2JL100ZW01T1Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L100VW00T12JL9 +Y`VW2@401`T01`5B2E89DPT00P4?DP8100=B0@403U820@07DPUB2E890@072@090JL9Y`VW2JL100VW +01X12:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@VW00T12JL9Y`VW2@401`T01`5B2E89DPT00P4>DP81 +10020@40000E00030@00008000<1DP400P4>DP080E89DPUB2@472@090JL9Y`VW2JL100ZW0P404`RW +2:L8Y`RW2:L8Y`RW2:L8Y`P00P4:Y`080JL9Y`VW2@472@080E89DPUB2@4?DP<100=B0E800`4>DP08 +0E89DPUB2@472@090JL9Y`VW2JL100VW0P405:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80P49Y`090@VW2JL9 +Y`T100L900P1DPUB2E890@iB0P400e81000400410@0001D000<100000P001U81DP5B0@iB00P1DPUB +2E890@L900T1Y`VW2JL9Y`402jLC0@^W00P1Y`VW2JL90@L900P1DPUB2E890@iB0P402E81DP5B0E81 +DP020@eB00P1DPUB2E890@L900T1Y`VW2JL9Y`402ZLD0@ZW00T12JL9Y`VW2@401`T0205B2E89DPT1 +3U820@03DP5B00D00@4100005@000`40000200060E81DP5B0P4=DP080E89DPUB2@472@090JL9Y`VW +2JL102NW00P1Y`VW2JL90@L900P1DPUB2E890@eB0`402e81DP5B0E81DP5B00813E80205B2E89DPT1 +1`T02@6W2JL9Y`VW0@0VY`090@VW2JL9Y`T100L900P1DPUB2E890@eB0`401581DP4500410@0001D0 +00<100000P001e81DP5B0E800P4=DP080E89DPUB2@472@090JL9Y`VW2JL102FW00P1Y`VW2JL90@L9 +00P1DPUB2E890@aB0P403e81DP5B0E81DP5B0E81DP030@aB00P1DPUB2E890@L900T1Y`VW2JL9Y`40 +9:L02@49Y`VW2JL90@072@080E89DPUB2@4=DP080E81DP5B0E8500410@0001D000<100000P00205B +0E81DP5B0`4W00T1Y`VW2JL9Y`401PT0205B2E89DPT1 +2e830@0CDP5B0E81DP5B0E81DP5B0E81DP020@]B00P1DPUB2E890@L900T1Y`VW2JL9Y`408ZL02P49 +Y`VW2JL9Y`462@080E89DPUB2@40E81DP5B0E81DP5B0E830@UB00P12E89DPUB0@H9 +00/1Y`VW2JL9Y`VW0@0KY`0:0JL9Y`VW2JL90@H900P12E89DPUB0@UB0P408581DP5B0E81DP5B0E81 +DP5B0E81DP5B0E81DP5B0E812E802049DPUB2E811PT02`6W2JL9Y`VW2JL101ZW00/12JL9Y`VW2JL9 +0@062@080@UB2E89DP49DP8100iB0E81DP5B0E81DP5B0@D00@4100005@000`4000020081011B0E81 +DP5B0E81DP5B0E8125802@5B2E89DPUB0@062@0:0JL9Y`VW2JL9Y`815jL20@0:Y`VW2JL9Y`VW0@H9 +00P1DPUB2E890@QB0P403e81DP5B0E81DP5B0E81DP030@0@DP5B0E81DP5B0E81DP5B0@QB00T1DPUB +2E89DP401PT02`6W2JL9Y`VW2JL101RW00`12JL9Y`VW2JL9Y`462@080E89DPUB2@48DP81011B0E81 +DP5B0E81DP5B0E8110010@40000E00030@0000800`404581DP5B0E81DP5B0E81DP48DP080E89DPUB +2@462@0=0@VW2JL9Y`VW2JL90@0EY`0<0@VW2JL9Y`VW2JL11PT0205B2E89DPT125820@0?DP5B0E81 +DP5B0E81DP5B00D1011B0E81DP5B0E81DP5B0E812580205B2E89DPT11PT03049Y`VW2JL9Y`VW0AJW +00`12JL9Y`VW2JL9Y`462@080E89DPUB2@48DP81011B0E81DP5B0E81DP5B0E811@010@40000E0081 +0`040@0@DP5B0E81DP5B0E81DP5B0@MB00T12E89DPUB2@401PT03@49Y`VW2JL9Y`VW2@404jL03@49 +Y`VW2JL9Y`VW2@401PT02049DPUB2E812580405B0E81DP5B0E81DP5B0E870@0@DP5B0E81DP5B0E81 +DP5B0@MB00T12E89DPUB2@401PT03049Y`VW2JL9Y`VW0ABW00d12JL9Y`VW2JL9Y`T100H900P12E89 +DPUB0@QB0101DP5B0E81DP5B0E81DP5B0P4400810@0001D000<100000P050@0=DP5B0E81DP5B0E81 +DP020@QB00P12E89DPUB0@H900d1Y`VW2JL9Y`VW2JL901<100`9Y`VW2JL9Y`VW2@462@090@UB2E89 +DPT100MB0101DP5B0E81DP5B0E81DP5B2@403E81DP5B0E81DP5B0E800P47DP090E89DPUB2E8100H9 +00`1Y`VW2JL9Y`VW2JLD0@0<2JL9Y`VW2JL9Y`T11PT02049DPUB2E812580405B0E81DP5B0E81DP5B +0E830@D00@4100005@000`40000200H100eB0E81DP5B0E81DP5B00811e802@5B2E89DPUB0@062@0[ +0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@062@080E89DPUB2@48DP81 +00eB0E81DP5B0E81DP5B00/100eB0E81DP5B0E81DP5B00811e802@5B2E89DPUB0@062@0[0JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@062@080E89DPUB2@48DP8100eB0E81 +DP5B0E81DP5B00@11@010@40000E00030@0000801`403U81DP5B0E81DP5B0E812580205B2E89DPT1 +1PT0:P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@H900T1DPUB2E89DP40 +1e820@0=DP5B0E81DP5B0E81DP0=0@0>DP5B0E81DP5B0E81DP47DP090@UB2E89DPT100H902X12JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`462@080E89DPUB2@48DP8100eB0E81 +DP5B0E81DP5B00D11@010@40000E00030@00008020403U81DP5B0E81DP5B0E811e802049DPUB2E81 +1`T0:@49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T100H900T12E89DPUB2@40 +1e803P5B0E81DP5B0E81DP5B3`403U81DP5B0E81DP5B0E811e802049DPUB2E811`T0:@49Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T100H900P12E89DPUB0@QB00h1DP5B0E81DP5B +0E81DPH11@010@40000E00030@0000802@402e81DP5B0E81DP5B00811e802@5B2E89DPUB0@062@0X +0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@H900T12E89DPUB2@401e803P5B +0E81DP5B0E81DP5B4@402e81DP5B0E81DP5B00811e802@5B2E89DPUB0@062@0X0JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@H900T12E89DPUB2@401e803P5B0E81DP5B0E81DP5B +1`4500410@0001D000<100000P080@0=DP5B0E81DP5B0E81DP020@MB00P1DPUB2E890@L902L1Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`401PT02@5B2E89DPUB0@07DP8100]B0E81 +DP5B0E81DP0C0@0;DP5B0E81DP5B0E800P46DP090@UB2E89DPT100L902L1Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`401PT0205B2E89DPT125820@0;DP5B0E81DP5B0E8020450041 +0@0001D000<100000P090@0=DP5B0E81DP5B0E81DP020@IB00P12E89DPUB0@L902H12JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@L900P12E89DPUB0@MB0P402e81DP5B0E81DP5B01D1 +00aB0E81DP5B0E81DP47DP080@UB2E89DP472@0V0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`472@080@UB2E89DP47DP8100]B0E81DP5B0E81DP090@D00@4100005@000`40000200X1 +00iB0E81DP5B0E81DP5B0@MB00P12E89DPUB0@L902D12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`T100L900P1DPUB2E890@MB00`1DP5B0E81DP5B0E8G0@0DP5B0E81DP5B0E81DP46DP08 +0E89DPUB2@472@0T0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T11`T02@5B2E89DPUB +0@06DP0<0E81DP5B0E81DP5B6@402E81DP5B0E81DP020@IB00T12E89DPUB2@401`T0906W2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@L900P1DPUB2E890@MB00`1DP5B0E81DP5B0E8;0@D0 +0@4100005@000`40000200`100]B0E81DP5B0E81DP020@MB00L1DPUB2E8100P902<1Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@072@080@UB2E89DP47DP8100UB0E81DP5B0E806`402E81 +DP5B0E81DP020@IB00P12E89DPUB0@P902<1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +0@072@070@UB2E890@08DP8100UB0E81DP5B0E80304500410@0001D000<100000P0=0@0;DP5B0E81 +DP5B0E800P46DP070@UB2E890@082@0R0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@P9 +00P1DPUB2E890@IB0P402E81DP5B0E81DP0M0@0:DP5B0E81DP5B0@IB00P1DPUB2E890@P902812JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL120T01`5B2E89DP401e820@09DP5B0E81DP5B00d1 +1@010@40000=00@110000`40000200h100aB0E81DP5B0E81DP47DP070@UB2E890@082@0Q0@VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T100L900P1DPUB2E890@MB00X1DP5B0E81DP5B7`402U81 +DP5B0E81DP46DP080E89DPUB2@482@0Q0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T100L9 +00L1DPUB2E8100QB00X1DP5B0E81DP5B3P4500410@0000l000<100000`020@<03`403581DP5B0E81 +DP5B0@IB00L1DPUB2E8100P90201Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@P900P12E89 +DPUB0@IB00X1DP5B0E81DP5B8@401e81DP5B0E800P46DP080@UB2E89DP482@0P0JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2@482@070@UB2E890@07DP0:0E81DP5B0E81DPl110020@40000?0003 +0@0000<000<100000P0>0@00@D00@4100003`000`40000300030@0000803@402e81DP5B0E81 +DP5B00811U801`49DPUB2@4020T08P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`482@08 +0E89DPUB2@46DP8100UB0E81DP5B0E807@402U81DP5B0E81DP46DP080E89DPUB2@482@0R0@VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@P900L1DPUB2E8100MB0P402E81DP5B0E81DP0=0@D0 +0@4100003`000`40000300030@00008030402e81DP5B0E81DP5B00811e801`5B2E89DP4020T08`6W +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL100L900P12E89DPUB0@IB00`1DP5B0E81DP5B +0E8K0@09DP5B0E81DP5B00811U802049DPUB2E8120T08`6W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL100L900L12E89DPT100MB00`1DP5B0E81DP5B0E8<0@D00@4100003@030@D000<10000 +0P0;0@0>DP5B0E81DP5B0E81DP46DP080E89DPUB2@472@0T0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`T11`T02@5B2E89DPUB0@06DP0<0E81DP5B0E81DP5B6@402E81DP5B0E81DP020@IB +00T12E89DPUB2@401`T0906W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@L900P1DPUB +2E890@MB00`1DP5B0E81DP5B0E8;0@D00@4100003`000`40000300030@0000802P403U81DP5B0E81 +DP5B0E811e802049DPUB2E811`T09@49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@40 +1`T0205B2E89DPT11U820@0;DP5B0E81DP5B0E805`403581DP5B0E81DP5B0@IB00T1DPUB2E89DP40 +1`T09@49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@401`T01`5B2E89DP401e820@0; +DP5B0E81DP5B0E802P4500410@0001D000<100000P090@0=DP5B0E81DP5B0E81DP020@IB00P12E89 +DPUB0@L902H12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@L900P12E89DPUB0@MB +0P402e81DP5B0E81DP5B01D100aB0E81DP5B0E81DP47DP080@UB2E89DP472@0V0@VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`472@080@UB2E89DP47DP8100]B0E81DP5B0E81DP090@D0 +0@4100005@000`40000200P100eB0E81DP5B0E81DP5B00811e80205B2E89DPT11`T09`6W2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@062@090E89DPUB2E8100IB00h1DP5B0E81DP5B +0E81DQ<100]B0E81DP5B0E81DP020@IB00T12E89DPUB2@401`T09`6W2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW0@062@080E89DPUB2@47DP0>0E81DP5B0E81DP5B0E880@D00@410000 +5@000`40000200T100iB0E81DP5B0E81DP5B0@IB00T1DPUB2E89DP401PT0:06W2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@462@090@UB2E89DPT100MB00h1DP5B0E81DP5B0E81DQ41 +00]B0E81DP5B0E81DP020@MB00T1DPUB2E89DP401PT0:06W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2@462@090@UB2E89DPT100MB00h1DP5B0E81DP5B0E81DPL11@010@40000E0003 +0@00008020403U81DP5B0E81DP5B0E811e802049DPUB2E811`T0:@49Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T100H900T12E89DPUB2@401U820@0=DP5B0E81DP5B0E81DP0?0@0> +DP5B0E81DP5B0E81DP47DP080@UB2E89DP472@0Y0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2@401PT02049DPUB2E811e820@0=DP5B0E81DP5B0E81DP060@D00@4100005@000`40 +000200L100eB0E81DP5B0E81DP5B00811e80205B2E89DPT11PT0:P49Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@H900T1DPUB2E89DP401e820@0=DP5B0E81DP5B0E81DP0=0@0> +DP5B0E81DP5B0E81DP47DP090@UB2E89DPT100H902X12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`462@080E89DPUB2@48DP8100eB0E81DP5B0E81DP5B00D11@010@40000E0003 +0@0000801P403E81DP5B0E81DP5B0E800P47DP090E89DPUB2E8100H902/1Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL100H900P1DPUB2E890@MB0101DP5B0E81DP5B0E81DP5B +2`403E81DP5B0E81DP5B0E800P47DP090E89DPUB2E8100H902/1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL100H900P1DPUB2E890@MB0101DP5B0E81DP5B0E81DP5B10450041 +0@0001D000<100000P050@0@DP5B0E81DP5B0E81DP5B0@MB00P12E89DPUB0@H900d1Y`VW2JL9Y`VW +2JL901<100`9Y`VW2JL9Y`VW2@462@090@UB2E89DPT100MB0101DP5B0E81DP5B0E81DP5B2@403E81 +DP5B0E81DP5B0E800P47DP090E89DPUB2E8100H900`1Y`VW2JL9Y`VW2JLD0@0<2JL9Y`VW2JL9Y`T1 +1PT02049DPUB2E812580405B0E81DP5B0E81DP5B0E830@D00@4100005@020@<010404581DP5B0E81 +DP5B0E81DP47DP090@UB2E89DPT100H900d12JL9Y`VW2JL9Y`T101>W00d12JL9Y`VW2JL9Y`T100H9 +00P12E89DPUB0@MB0P403e81DP5B0E81DP5B0E81DP070@0@DP5B0E81DP5B0E81DP5B0@MB00T12E89 +DPUB2@401PT03049Y`VW2JL9Y`VW0ABW00d12JL9Y`VW2JL9Y`T100H900P12E89DPUB0@MB0P403e81 +DP5B0E81DP5B0E81DP020@@00P4100005@000`40000200<100mB0E81DP5B0E81DP5B0E800P47DP08 +0E89DPUB2@462@0=0@VW2JL9Y`VW2JL90@0EY`0<0@VW2JL9Y`VW2JL11PT0205B2E89DPT125820@0? +DP5B0E81DP5B0E81DP5B00D1011B0E81DP5B0E81DP5B0E812580205B2E89DPT11PT03049Y`VW2JL9 +Y`VW0AJW00`12JL9Y`VW2JL9Y`462@080E89DPUB2@48DP81011B0E81DP5B0E81DP5B0E811@010@40 +000E00030@0000800P403e81DP5B0E81DP5B0E81DP020@MB00T1DPUB2E89DP401PT02P6W2JL9Y`VW +2JL20ANW0P402ZL9Y`VW2JL9Y`462@080E89DPUB2@47DP0B0E81DP5B0E81DP5B0E81DP5B0`403e81 +DP5B0E81DP5B0E81DP020@MB00T1DPUB2E89DP401PT02`6W2JL9Y`VW2JL101RW00`12JL9Y`VW2JL9 +Y`462@080E89DPUB2@47DP0C0E81DP5B0E81DP5B0E81DP5B0@0400410@0001D000<100000P00405B +0E81DP5B0E81DP5B0E820@QB00P12E89DPUB0@H900/1Y`VW2JL9Y`VW0@0KY`0:0JL9Y`VW2JL90@H9 +00P12E89DPUB0@QB0281DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0P48DP080@UB2E89 +DP462@0;0JL9Y`VW2JL9Y`406ZL02`49Y`VW2JL9Y`T100H900P12E89DPUB0@QB0`403U81DP5B0E81 +DP5B0E811@010@40000E00030@00008000eB0E81DP5B0E81DP5B00<12E802@49DPUB2E890@062@0: +0@VW2JL9Y`VW0AfW00X1Y`VW2JL9Y`T11PT02049DPUB2E8125830@0NDP5B0E81DP5B0E81DP5B0E81 +DP5B0E81DP5B0E812E802@49DPUB2E890@062@0:0@VW2JL9Y`VW0AbW00/12JL9Y`VW2JL90@062@08 +0@UB2E89DP49DP8100eB0E81DP5B0E81DP5B00D00@4100005@000`400002000<0E81DP5B0E81DP5B +0P4;DP080E89DPUB2@462@0:0@VW2JL9Y`VW0AnW00T1Y`VW2JL9Y`401PT0205B2E89DPT12U820@0L +DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0@YB00P1DPUB2E890@H900X12JL9Y`VW2JL17ZL02P49 +Y`VW2JL9Y`462@080E89DPUB2@4;DP0=0E81DP5B0E81DP5B0@0500410@0001D000<100000P002e81 +DP5B0E81DP5B00812e80205B2E89DPT11PT02P49Y`VW2JL9Y`4QY`090JL9Y`VW2JL100H900P1DPUB +2E890@YB0P405e81DP5B0E81DP5B0E81DP5B0E81DP5B00<12U80205B2E89DPT11PT02P49Y`VW2JL9 +Y`4PY`0:0@VW2JL9Y`VW0@H900P1DPUB2E890@]B0`402E81DP5B0E81DP0500410@0001D000<10000 +0P00205B0E81DP5B0`4W00T1Y`VW2JL9Y`401PT0205B +2E89DPT12e830@0CDP5B0E81DP5B0E81DP5B0E81DP020@]B00P1DPUB2E890@L900T1Y`VW2JL9Y`40 +8ZL02P49Y`VW2JL9Y`462@080E89DPUB2@4DP07 +0@UB2E890@072@090JL9Y`VW2JL102JW00T12JL9Y`VW2@401`T0205B2E89DPT13E830@0;DP5B0E81 +DP5B0E800P4>DP070@UB2E890@072@090JL9Y`VW2JL102JW00T12JL9Y`VW2@401`T0205B2E89DPT1 +3E830@04DP5B0@D00@4100005@000`4000020006DP5B0E813e801`49DPUB2@401`T02@6W2JL9Y`VW +0@0XY`090@VW2JL9Y`T100L900L1DPUB2E8100mB0P402E81DP5B0E81DP020@iB00L12E89DPT100L9 +00T1Y`VW2JL9Y`40::L02@49Y`VW2JL90@072@070E89DPUB0@0?DP8100=B0E801@010@40000E0003 +0@00008000<1DP400P4?DP070@UB2E890@072@090JL9Y`VW2JL100bW4`4;Y`090@VW2JL9Y`T100L9 +00L1DPUB2E81011B0`400e81DP030@mB00L12E89DPT100L900T1Y`VW2JL9Y`402jLD0@^W00T12JL9 +Y`VW2@401`T01`5B2E89DP403e820@03DP4000@00@4100005@000`4000020003DP41011B00L12E89 +DPT100L900X1Y`VW2JL9Y`T12ZL20@0CY`RW2:L8Y`RW2:L8Y`RW2:L8Y`020@ZW00T12JL9Y`VW2@40 +1`T01`5B2E89DP404E820@03DP41011B00L12E89DPT100L900X1Y`VW2JL9Y`T12JL20@0D2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L20@VW00X1Y`VW2JL9Y`T11`T01`5B2E89DP4045820@D00@4100005@020@<0 +00<1DU803U820@072E89DPUB0@062@0:0JL9Y`VW2JL90@ZW01T12:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`P100ZW00T12JL9Y`VW2@401PT01`49DPUB2E800P4ADP030E9B00iB0P401`UB2E89DP401PT02P6W +2JL9Y`VW2@49Y`0J0JL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2049Y`0:0JL9Y`VW2JL90@H900L12E89 +DPUB00814580104000020@40000E00030@0000803e820@08DPUB2E89DP462@0:0JL9Y`VW2JL90@VW +0P406PRW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P12ZL02@49Y`VW2JL90@062@080@UB2E89DPT30AeB +0P402589DPUB2E811PT02P6W2JL9Y`VW2@49Y`0L0JL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80@VW +00X1Y`VW2JL9Y`T11PT02049DPUB2E890P4>DPD00@4100005@000`40000200aB0`402@UB2E89DPUB +0@062@0:0JL9Y`VW2JL90@VW01d1Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20020@RW00X1Y`VW +2JL9Y`T11PT02P49DPUB2E89DPT20AQB0`402@UB2E89DPUB0@062@0:0JL9Y`VW2JL90@RW0P407:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P20@RW00X1Y`VW2JL9Y`T11PT02@49DPUB2E89DP030@]B +1@010@40000E00030@0000802E830@0;2E89DPUB2E89DP401PT02P6W2JL9Y`VW2@48Y`81022W2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@RW00X1Y`VW2JL9Y`T11PT02`49DPUB2E89DPUB00<1 +4U830@0;2E89DPUB2E89DP401PT02P6W2JL9Y`VW2@48Y`0R0@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW0@RW00X1Y`VW2JL9Y`T11PT02`49DPUB2E89DPUB00812E8500410@0001D000<10000 +0P07DP8100d9DPUB2E89DPUB2E8100L900T12JL9Y`VW2@402:L09048Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW0@RW00T1Y`VW2JL9Y`401`T03@49DPUB2E89DPUB2E800`4=DP8100d9DPUB +2E89DPUB2E8100L900T12JL9Y`VW2@401jL20@0S2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L8Y`402:L02@6W2JL9Y`VW0@072@0<0@UB2E89DPUB2E890`46DPD00@4100005@000`40000200AB +0`403U89DPUB2E89DPUB2E811`T02@49Y`VW2JL90@08Y`0:0@RW2:L8Y`RW21<100P8Y`RW2:L8Y`81 +1jL02@6W2JL9Y`VW0@072@0?0@UB2E89DPUB2E89DPUB008125830@0>DPUB2E89DPUB2E89DP472@09 +0@VW2JL9Y`T100NW00X1Y`RW2:L8Y`RW504020RW2:L8Y`RW0P47Y`090JL9Y`VW2JL100L900h12E89 +DPUB2E89DPUB2@<10e8500410@0001D000<100000P02DP81011B2E89DPUB2E89DPUB2E811`T02@49 +Y`VW2JL90@07Y`8100P8Y`RW2:L8Y`814`P20@09Y`RW2:L8Y`P100NW00T1Y`VW2JL9Y`401`T04049 +DPUB2E89DPUB2E89DPT30@=B0P404589DPUB2E89DPUB2E89DP472@090@VW2JL9Y`T100NW00T1Y`RW +2:L8Y`P00P4D208100VW2:L8Y`RW20401jL02@6W2JL9Y`VW0@072@0@0@UB2E89DPUB2E89DPUB2@81 +00=B00000`010@40000E00030@0000800P403`UB2E89DPUB2E89DPUB2@020@L900T12JL9Y`VW2@40 +1jL02@6W2:L8Y`RW20020AL80P401`RW2:L8Y`P00P46Y`090JL9Y`VW2JL100L901812E89DPUB2E89 +DPUB2E89DPT30@0?2E89DPUB2E89DPUB2E8900811`T02@49Y`VW2JL90@06Y`8100NW2:L8Y`RW0081 +60P02@6W2:L8Y`RW20020@JW00T1Y`VW2JL9Y`401`T20@0?DPUB2E89DPUB2E89DPUB008110010@40 +000E00030@00008000mB2E89DPUB2E89DPUB2E800P482@090@VW2JL9Y`T100JW0P402JL8Y`RW2:L8 +0@0K200:0@RW2:L8Y`RW0@JW00T1Y`VW2JL9Y`401`T20@0ODPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DP020@P900T12JL9Y`VW2@401ZL02P48Y`RW2:L8Y`4K208100T8Y`RW2:L8Y`401ZL02@6W +2JL9Y`VW0@082@<100eB2E89DPUB2E89DPUB00D00@4100005@000`400002000<2E89DPUB2E89DPUB +0`492@090@VW2JL9Y`T100JW00T12:L8Y`RW2:L00P4M208100RW2:L8Y`RW0@JW00T1Y`VW2JL9Y`40 +20T20@0K2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E8900812@T02@49Y`VW2JL90@06Y`080@RW2:L8 +Y`P20Ah800X12:L8Y`RW2:L11ZL02@6W2JL9Y`VW0@0:2@8100/9DPUB2E89DPUB2@0500410@0001D0 +00<100000P002U89DPUB2E89DPT20@/900T12JL9Y`VW2@401JL20@072:L8Y`RW20020B480P401PRW +2:L8Y`<11:L02@6W2JL9Y`VW0@092@8101MB2E89DPUB2E89DPUB2E89DPUB2E89DP020@X900T12JL9 +Y`VW2@401:L30@062:L8Y`RW0P4Q208100NW2:L8Y`RW00<11:L02@6W2JL9Y`VW0@0;2@<100P9DPUB +2E89DPD00@4100005@000`40000200072E89DPUB2@030@/90P4020VW2JL9Y`T11JL02P6W2:L8Y`RW +204U20090@RW2:L8Y`P100FW00T1Y`VW2JL9Y`402PT30@0BDPUB2E89DPUB2E89DPUB2E890P4:2@81 +00P9Y`VW2JL90@FW00T1Y`RW2:L8Y`409@P02P6W2:L8Y`RW2045Y`090JL9Y`VW2JL100d90`401@UB +2E8900D00@4100005@020@<000AB2E890`4<2@8100VW2JL9Y`VW2@401JL02P6W2:L8Y`RW204:21<1 +2PP02@48Y`RW2:L80@05Y`080JL9Y`VW2JL20@/910402PUB2E89DPUB2E840@X90P402JL9Y`VW2JL9 +0@05Y`090JL8Y`RW2:L100X85049200:0JL8Y`RW2:L80@FW00P1Y`VW2JL9Y`813PT20@03DPUB00@0 +0P4100005@000`40000200042E810@h900/12JL9Y`VW2JL90@06Y`090@RW2:L8Y`P100X801D12008 +00P0200800P0200800P020402PP02048Y`RW2:L11ZL02@6W2JL9Y`VW2@020@d910400e89DP030@d9 +00/12JL9Y`VW2JL90@06Y`080@RW2:L8Y`4:200F0@0800P0200800P0200800P020080@T800T1Y`RW +2:L8Y`401ZL02@6W2JL9Y`VW2@020@h90P400`T0000300410@0001D000<100000P020@h90P402PVW +2JL9Y`VW2@46Y`090@RW2:L8Y`P100X801L1200800P0200800P0200800P020080@0:20080@RW2:L8 +Y`46Y`0:0JL9Y`VW2JL9Y`813`T30@h90P402PVW2JL9Y`VW2@46Y`080@RW2:L8Y`4:200H0@0800P0 +200800P0200800P0200800P12@P02@6W2:L8Y`RW0@06Y`0:0JL9Y`VW2JL9Y`813PT20@@00@410000 +5@000`40000200h90P402jL9Y`VW2JL9Y`T100JW00L12:L8Y`RW00812PP06@4800P0200800P02008 +00P0200800P020402PP02048Y`RW2:L11ZL02`6W2JL9Y`VW2JL9008170T20@0;Y`VW2JL9Y`VW2@40 +1ZL02048Y`RW2:L12PP06P40200800P0200800P0200800P0200800P12@P20@072:L8Y`RW0@06Y`0; +0JL9Y`VW2JL9Y`T00P4=2@D00@4100005@000`40000200`90P402PVW2JL9Y`VW2JL20@JW00P12:L8 +Y`RW0@/801/1200800P0200800P0200800P0200800P020402PP02048Y`RW2:L11ZL0306W2JL9Y`VW +2JL9Y`8160T20@0:2JL9Y`VW2JL9Y`811ZL02048Y`RW2:L12PP07040200800P0200800P0200800P0 +200800P0204:20080@RW2:L8Y`46Y`0<0JL9Y`VW2JL9Y`VW0P4;2@D00@4100005@000`40000200X9 +0P403:L9Y`VW2JL9Y`VW0@RW00L1Y`RW2:L100/801d1200800P0200800P0200800P0200800P02008 +0@0:20070@RW2:L80@07Y`8100/9Y`VW2JL9Y`VW2@020A@90P403:L9Y`VW2JL9Y`VW0@RW00L1Y`RW +2:L100X801h100P0200800P0200800P0200800P0200800P0204:20070@RW2:L80@07Y`8100/9Y`VW +2JL9Y`VW2@020@T91@010@40000E00030@0000802@T03P49Y`VW2JL9Y`VW2JL12:L01`6W2:L8Y`40 +2`P07`4800P0200800P0200800P0200800P0200800P020402PP01`48Y`RW20402:L03@49Y`VW2JL9 +Y`VW2JL00P4A2@0>0@VW2JL9Y`VW2JL9Y`48Y`070JL8Y`RW0@0:200P0@0800P0200800P0200800P0 +200800P0200800P0204:20070@RW2:L80@08Y`0>0@VW2JL9Y`VW2JL9Y`482@D00@4100005@000`40 +000200L90P403@VW2JL9Y`VW2JL9Y`402:L01`6W2:L8Y`402`P08@4800P0200800P0200800P02008 +00P0200800P020080@0:20070@RW2:L80@08Y`0>0@VW2JL9Y`VW2JL9Y`T20@d90P403@VW2JL9Y`VW +2JL9Y`402:L01`6W2:L8Y`402PP08P40200800P0200800P0200800P0200800P0200800P0204:2007 +0@RW2:L80@08Y`0=0@VW2JL9Y`VW2JL9Y`020@H91@010@40000E00030@0000801@T20@0>Y`VW2JL9 +Y`VW2JL9Y`49Y`070@RW2:L80@09208100L800P0200801<100P800P020080@X800L12:L8Y`P100RW +00l12JL9Y`VW2JL9Y`VW2JL00P492@8100jW2JL9Y`VW2JL9Y`VW0@VW00L12:L8Y`P100T800P100P0 +200801@100P800P020080@X800L12:L8Y`P100RW00h12JL9Y`VW2JL9Y`VW2@8110T500410@0001D0 +00<100000P032@8100l9Y`VW2JL9Y`VW2JL9Y`402JL01`48Y`RW20402@P02P40200800P0204C0009 +0@P0200800P100T800L1Y`RW2:L100VW01012JL9Y`VW2JL9Y`VW2JL90P452@8100l9Y`VW2JL9Y`VW +2JL9Y`402JL01`48Y`RW20402@P02@40200800P00@0D00090@P0200800P100T800L1Y`RW2:L100VW +00l12JL9Y`VW2JL9Y`VW2JL00P422@D00@4100005@000`400002000C2@41Y`VW2JL9Y`VW2JL9Y`VW +0@09Y`080@RW2:L8Y`48200:0@0800P020080AD000T1200800P020402@P01`6W2:L8Y`402JL04@49 +Y`VW2JL9Y`VW2JL9Y`VW008101<90@6W2JL9Y`VW2JL9Y`VW2JL100VW00P12:L8Y`RW0@P800T100P0 +200800405P002@4800P020080@0920070JL8Y`RW0@09Y`0@0@VW2JL9Y`VW2JL9Y`VW2@811@010@40 +000E00030@00008001812JL9Y`VW2JL9Y`VW2JL9Y`49Y`080@RW2:L8Y`48200:0@0800P020080AL0 +00T1200800P0204020P02048Y`RW2:L12JL09049Y`VW2JL9Y`VW2JL9Y`VW2@49Y`VW2JL9Y`VW2JL9 +Y`VW0@VW00P12:L8Y`RW0@P800T100P02008004060002@4800P020080@0820080@RW2:L8Y`49Y`0B +0@VW2JL9Y`VW2JL9Y`VW2JL110010@40000E00030@0000800149Y`VW2JL9Y`VW2JL9Y`VW0@0:Y`08 +0JL8Y`RW2047200:0@0800P020080AT000T1200800P0204020P01`48Y`RW20402ZL08P49Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4:Y`080JL8Y`RW204720090@0800P0200101X000T12008 +00P0204020P01`48Y`RW20402ZL04049Y`VW2JL9Y`VW2JL9Y`T500410@0001D00P43000>Y`VW2JL9 +Y`VW2JL9Y`T20@ZW00P1Y`RW2:L80@L800X100P0200800P16`002@4800P020080@0720080JL8Y`RW +204:Y`0P0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4:Y`080JL8Y`RW2047200:0@0800P0 +20080AX000X100P0200800P11`P0206W2:L8Y`P12ZL03`49Y`VW2JL9Y`VW2JL9Y`0400810@0001D0 +00<100000P003PVW2JL9Y`VW2JL9Y`T12jL02@6W2:L8Y`RW0@06200:0@0800P020080Ad000T12008 +00P020401`P0206W2:L8Y`P12ZL07`49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@402JL02@6W +2:L8Y`RW0@06200:0@0800P020080A`000X100P0200800P11`P0206W2:L8Y`P12ZL20@0Y`VW2JL9Y`VW2JL9 +Y`49Y`070@RW2:L80@09208100L800P0200801<100P800P020080@X800L12:L8Y`P100RW00l12JL9 +Y`VW2JL9Y`VW2JL00P492@8100jW2JL9Y`VW2JL9Y`VW0@VW00L12:L8Y`P100T800P100P0200801@1 +00P800P020080@X800L12:L8Y`P100RW00h12JL9Y`VW2JL9Y`VW2@8110T500410@0001D000<10000 +0P072@8100d9Y`VW2JL9Y`VW2JL100RW00L1Y`RW2:L100/80241200800P0200800P0200800P02008 +00P0200800P020402PP01`48Y`RW20402:L03P49Y`VW2JL9Y`VW2JL90P4=2@8100d9Y`VW2JL9Y`VW +2JL100RW00L1Y`RW2:L100X8028100P0200800P0200800P0200800P0200800P0200800P12PP01`48 +Y`RW20402:L03@49Y`VW2JL9Y`VW2JL00P462@D00@4100005@000`40000200T900h12JL9Y`VW2JL9 +Y`VW0@RW00L1Y`RW2:L100/801l1200800P0200800P0200800P0200800P0200800P100X800L12:L8 +Y`P100RW00d12JL9Y`VW2JL9Y`VW00814@T03P49Y`VW2JL9Y`VW2JL12:L01`6W2:L8Y`402PP08040 +200800P0200800P0200800P0200800P0200800P12PP01`48Y`RW20402:L03P49Y`VW2JL9Y`VW2JL1 +20T500410@0001D000<100000P0:2@8100bW2JL9Y`VW2JL9Y`48Y`070JL8Y`RW0@0;200M0@P02008 +00P0200800P0200800P0200800P020402PP01`48Y`RW20401jL20@0;2JL9Y`VW2JL9Y`T00P4D2@81 +00bW2JL9Y`VW2JL9Y`48Y`070JL8Y`RW0@0:200N0@0800P0200800P0200800P0200800P0200800P1 +2PP01`48Y`RW20401jL20@0;2JL9Y`VW2JL9Y`T00P492@D00@4100005@000`40000200`90P402PVW +2JL9Y`VW2JL20@JW00P12:L8Y`RW0@/801/1200800P0200800P0200800P0200800P020402PP02048 +Y`RW2:L11ZL0306W2JL9Y`VW2JL9Y`8160T20@0:2JL9Y`VW2JL9Y`811ZL02048Y`RW2:L12PP07040 +200800P0200800P0200800P0200800P0204:20080@RW2:L8Y`46Y`0<0JL9Y`VW2JL9Y`VW0P4;2@D0 +0@4100005@000`40000200h90P402jL9Y`VW2JL9Y`T100JW00L12:L8Y`RW00812PP06@4800P02008 +00P0200800P0200800P020402PP02048Y`RW2:L11ZL02`6W2JL9Y`VW2JL9008170T20@0;Y`VW2JL9 +Y`VW2@401ZL02048Y`RW2:L12PP06P40200800P0200800P0200800P0200800P12@P20@072:L8Y`RW +0@06Y`0;0JL9Y`VW2JL9Y`T00P4=2@D00@4100005@000`40000200813PT20@0:2JL9Y`VW2JL90@JW +00T12:L8Y`RW20402PP05`4800P0200800P0200800P0200800P100X800P12:L8Y`RW0@JW00X1Y`VW +2JL9Y`VW0P4?2@<13PT20@0:2JL9Y`VW2JL90@JW00P12:L8Y`RW0@X801P100P0200800P0200800P0 +200800P0204920090JL8Y`RW2:L100JW00X1Y`VW2JL9Y`VW0P4>2@8110010@40000E00030@000080 +00@9DP413PT02`49Y`VW2JL9Y`T100JW00T12:L8Y`RW20402PP05@4800P0200800P0200800P02008 +0@0:20080@RW2:L8Y`46Y`090JL9Y`VW2JL900813@T40@03DPUB00<13@T02`49Y`VW2JL9Y`T100JW +00P12:L8Y`RW0@X801H100P0200800P0200800P0200800P12@P02@6W2:L8Y`RW0@06Y`090JL9Y`VW +2JL900813PT20@032@0000<00@4100005@020@<000AB2E890`4<2@8100VW2JL9Y`VW2@401JL02P6W +2:L8Y`RW204:21<12PP02@48Y`RW2:L80@05Y`080JL9Y`VW2JL20@/910402PUB2E89DPUB2E840@X9 +0P402JL9Y`VW2JL90@05Y`090JL8Y`RW2:L100X85049200:0JL8Y`RW2:L80@FW00P1Y`VW2JL9Y`81 +3PT20@03DPUB00@00P4100005@000`40000200072E89DPUB2@030@/90P4020VW2JL9Y`T11JL20@08 +2:L8Y`RW204U20090@RW2:L8Y`P100FW00T1Y`VW2JL9Y`402PT30@0BDPUB2E89DPUB2E89DPUB2E89 +0P4:2@8100P9Y`VW2JL90@FW00T1Y`RW2:L8Y`409@P02P6W2:L8Y`RW2045Y`090JL9Y`VW2JL100d9 +0`401@UB2E8900D00@4100005@000`400002000:DPUB2E89DPUB2@812`T02@49Y`VW2JL90@05Y`81 +00L8Y`RW2:L800818@P20@062:L8Y`RW0P45Y`090JL9Y`VW2JL100T90P405e89DPUB2E89DPUB2E89 +DPUB2E89DPUB00812PT02@49Y`VW2JL90@05Y`8100H8Y`RW2:L20B480P401jL8Y`RW2:L00P45Y`09 +0JL9Y`VW2JL100/90`4020UB2E89DPUB1@010@40000E00030@00008000`9DPUB2E89DPUB2E830@T9 +00T12JL9Y`VW2@401ZL02@48Y`RW2:L8Y`020Ad80P402:L8Y`RW2:L11ZL02@6W2JL9Y`VW0@082@81 +01/9DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT00P492@090@VW2JL9Y`T100JW00P12:L8Y`RW2081 +7PP02P48Y`RW2:L8Y`46Y`090JL9Y`VW2JL100X90P402`UB2E89DPUB2E8900D00@4100005@000`40 +0002000?DPUB2E89DPUB2E89DPUB008120T02@49Y`VW2JL90@06Y`8100VW2:L8Y`RW20406`P02P48 +Y`RW2:L8Y`46Y`090JL9Y`VW2JL100L90P407e89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E80 +0P482@090@VW2JL9Y`T100JW00X12:L8Y`RW2:L16`P20@092:L8Y`RW2:L100JW00T1Y`VW2JL9Y`40 +20T30@0=DPUB2E89DPUB2E89DP0500410@0001D000<100000P020@0?2E89DPUB2E89DPUB2E890081 +1`T02@49Y`VW2JL90@07Y`090JL8Y`RW2:L800815`P20@072:L8Y`RW20020@JW00T1Y`VW2JL9Y`40 +1`T04P49DPUB2E89DPUB2E89DPUB2@<100l9DPUB2E89DPUB2E89DPT00P472@090@VW2JL9Y`T100JW +0P401jL8Y`RW2:L00P4H20090JL8Y`RW2:L800811ZL02@6W2JL9Y`VW0@072@8100mB2E89DPUB2E89 +DPUB2E800P4400410@0001D000<100000P02DP81011B2E89DPUB2E89DPUB2E811`T02@49Y`VW2JL9 +0@07Y`8100P8Y`RW2:L8Y`814`P20@09Y`RW2:L8Y`P100NW00T1Y`VW2JL9Y`401`T04049DPUB2E89 +DPUB2E89DPT30@=B0P404589DPUB2E89DPUB2E89DP472@090@VW2JL9Y`T100NW00T1Y`RW2:L8Y`P0 +0P4D208100VW2:L8Y`RW20401jL02@6W2JL9Y`VW0@072@0@0@UB2E89DPUB2E89DPUB2@8100=B0000 +0`010@40000E00030@00008015830@0>DPUB2E89DPUB2E89DP472@090@VW2JL9Y`T100RW00X12:L8 +Y`RW2:L84`4020RW2:L8Y`RW0P47Y`090JL9Y`VW2JL100L900l12E89DPUB2E89DPUB2E800P48DP<1 +00iB2E89DPUB2E89DPUB0@L900T12JL9Y`VW2@401jL02P6W2:L8Y`RW2:LD0@082:L8Y`RW2:L20@NW +00T1Y`VW2JL9Y`401`T03P49DPUB2E89DPUB2E890`43DPD00@4100005@000`40000200MB0P403@UB +2E89DPUB2E89DP401`T02@49Y`VW2JL90@08Y`0T0@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L12:L02@6W2JL9Y`VW0@072@0=0@UB2E89DPUB2E89DP030@eB0P403@UB2E89DPUB2E89DP40 +1`T02@49Y`VW2JL90@07Y`8102<8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@08Y`09 +0JL9Y`VW2JL100L900`12E89DPUB2E89DPT30@IB1@010@40000E00030@0000802E830@0;2E89DPUB +2E89DP401PT02P6W2JL9Y`VW2@48Y`81022W2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@RW +00X1Y`VW2JL9Y`T11PT02`49DPUB2E89DPUB00<14U830@0;2E89DPUB2E89DP401PT02P6W2JL9Y`VW +2@48Y`0R0@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@RW00X1Y`VW2JL9Y`T11PT02`49 +DPUB2E89DPUB00812E8500410@0001D000<100000P0DP81 +00L9DPUB2E8100H900X1Y`VW2JL9Y`T12JL06P6W2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P12JL02P6W +2JL9Y`VW2@462@070@UB2E89DP020A1B00@100000P4100005@000`4000020003DP41011B00L12E89 +DPT100L900X1Y`VW2JL9Y`T12ZL20@0CY`RW2:L8Y`RW2:L8Y`RW2:L8Y`020@ZW00T12JL9Y`VW2@40 +1`T01`5B2E89DP404E820@03DP41011B00L12E89DPT100L900X1Y`VW2JL9Y`T12JL20@0D2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L20@VW00X1Y`VW2JL9Y`T11`T01`5B2E89DP4045820@D00@4100005@000`40 +000200030E8100813e801`49DPUB2@401`T02@6W2JL9Y`VW0@0DP070@UB2E890@072@090JL9Y`VW2JL102RW00T12JL9Y`VW2@401`T01`5B2E89DP403e820@03 +DP5B00D00@4100005@000`40000200060E81DP5B0P4>DP070@UB2E890@072@090JL9Y`VW2JL102JW +00T12JL9Y`VW2@401`T0205B2E89DPT13E830@0;DP5B0E81DP5B0E800P4>DP070@UB2E890@072@09 +0JL9Y`VW2JL102JW00T12JL9Y`VW2@401`T0205B2E89DPT13E830@04DP5B0@D00@4100005@000`40 +00020007DP5B0E81DP020@eB00P1DPUB2E890@L900T1Y`VW2JL9Y`409JL0206W2JL9Y`T11`T0205B +2E89DPT135820@0?DP5B0E81DP5B0E81DP5B00<13580205B2E89DPT11`T02@6W2JL9Y`VW0@0TY`09 +0@VW2JL9Y`T100L900P1DPUB2E890@eB00P1DP5B0E81DPD00@4100005@000`40000200080E81DP5B +0E830@aB00P1DPUB2E890@L900T1Y`VW2JL9Y`408jL02@6W2JL9Y`VW0@062@080E89DPUB2@4;DP<1 +01=B0E81DP5B0E81DP5B0E81DP5B00812e80205B2E89DPT11`T02@6W2JL9Y`VW0@0RY`0:0@VW2JL9 +Y`VW0@H900P1DPUB2E890@aB0P402581DP5B0E811@010@40000E00030@00008000]B0E81DP5B0E81 +DP020@]B00P1DPUB2E890@H900X12JL9Y`VW2JL18JL02@6W2JL9Y`VW0@062@080E89DPUB2@4:DP81 +01MB0E81DP5B0E81DP5B0E81DP5B0E81DP030@YB00P1DPUB2E890@H900X12JL9Y`VW2JL18:L02P49 +Y`VW2JL9Y`462@080E89DPUB2@4;DP<100UB0E81DP5B0E801@010@40000E00030@00008000`1DP5B +0E81DP5B0E820@]B00P1DPUB2E890@H900X12JL9Y`VW2JL17jL02@6W2JL9Y`VW0@062@080E89DPUB +2@4:DP8101aB0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E812U80205B2E89DPT11PT02P49Y`VW2JL9 +Y`4NY`0:0@VW2JL9Y`VW0@H900P1DPUB2E890@]B00d1DP5B0E81DP5B0E8100D00@4100005@000`40 +0002000=DP5B0E81DP5B0E81DP020@YB00P12E89DPUB0@L900X12JL9Y`VW2JL17JL02P6W2JL9Y`VW +2@462@080@UB2E89DP49DP8101iB0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP49DP080@UB2E89 +DP472@0:0@VW2JL9Y`VW0AbW00/12JL9Y`VW2JL90@062@080@UB2E89DP4:DP0>0E81DP5B0E81DP5B +0E8500410@0001D000<100000P003P5B0E81DP5B0E81DP5B0`49DP080@UB2E89DP462@0;0JL9Y`VW +2JL9Y`406jL02P6W2JL9Y`VW2@462@080@UB2E89DP49DP81021B0E81DP5B0E81DP5B0E81DP5B0E81 +DP5B0E81DP5B0@UB00P12E89DPUB0@H900/1Y`VW2JL9Y`VW0@0KY`0:0JL9Y`VW2JL90@H900P12E89 +DPUB0@UB0P403U81DP5B0E81DP5B0E811@010@40000E00030@000080019B0E81DP5B0E81DP5B0E81 +DP48DP080E89DPUB2@472@0;0JL9Y`VW2JL9Y`406JL02`6W2JL9Y`VW2JL100H900P1DPUB2E890@QB +0P408U81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP48DP080E89DPUB2@472@0:0JL9Y`VW +2JL90AZW00/1Y`VW2JL9Y`VW0@062@080E89DPUB2@48DP8100mB0E81DP5B0E81DP5B0E801@010@40 +000E00030@00008001<1DP5B0E81DP5B0E81DP5B0E8100QB00P1DPUB2E890@H900`12JL9Y`VW2JL9 +Y`4HY`0:0@VW2JL9Y`VW0@H900P1DPUB2E890@QB0P409581DP5B0E81DP5B0E81DP5B0E81DP5B0E81 +DP5B0E81DP5B0@QB00P1DPUB2E890@H900/12JL9Y`VW2JL90@0HY`0;0JL9Y`VW2JL9Y`401PT0205B +2E89DPT125820@0?DP5B0E81DP5B0E81DP5B008110010@40000E00810`020@0BDP5B0E81DP5B0E81 +DP5B0E811e802049DPUB2E811`T02`49Y`VW2JL9Y`T101NW00/12JL9Y`VW2JL90@062@080@UB2E89 +DP48DP0B0E81DP5B0E81DP5B0E81DP5B0`404U81DP5B0E81DP5B0E81DP5B0@MB00P12E89DPUB0@L9 +00/12JL9Y`VW2JL90@0FY`0<0JL9Y`VW2JL9Y`T11PT02049DPUB2E812580405B0E81DP5B0E81DP5B +0E820@@00P4100005@000`40000200<100mB0E81DP5B0E81DP5B0E800P48DP070@UB2E890@072@0< +0JL9Y`VW2JL9Y`T15JL02`49Y`VW2JL9Y`T100L900P1DPUB2E890@MB0181DP5B0E81DP5B0E81DP5B +0E850@0?DP5B0E81DP5B0E81DP5B00811e80205B2E89DPT11`T0306W2JL9Y`VW2JL90AFW00/12JL9 +Y`VW2JL90@072@070E89DPUB0@08DP0@0E81DP5B0E81DP5B0E81DP<11@010@40000E00030@000080 +10403e81DP5B0E81DP5B0E81DP020@MB00P1DPUB2E890@L900`1Y`VW2JL9Y`VW2@4CY`0<0@VW2JL9 +Y`VW2JL11PT0205B2E89DPT125820@0?DP5B0E81DP5B0E81DP5B00L100mB0E81DP5B0E81DP5B0E80 +0P47DP080E89DPUB2@472@0;0JL9Y`VW2JL9Y`405:L03049Y`VW2JL9Y`VW0@H900P1DPUB2E890@QB +0P403E81DP5B0E81DP5B0E80104500410@0001D000<100000P050@0@DP5B0E81DP5B0E81DP5B0@QB +00L1DPUB2E8100L900`12JL9Y`VW2JL9Y`TC0@0;2JL9Y`VW2JL9Y`401`T02049DPUB2E811e820@0? +DP5B0E81DP5B0E81DP5B00T1011B0E81DP5B0E81DP5B0E811e802049DPUB2E811`T02`49Y`VW2JL9 +Y`VW01@100/9Y`VW2JL9Y`VW0@072@070@UB2E890@08DP8100eB0E81DP5B0E81DP5B00D11@010@40 +000E00030@0000801P404581DP5B0E81DP5B0E81DP47DP080@UB2E89DP472@0Y0@VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@401PT02@49DPUB2E890@07DP0@0E81DP5B0E81DP5B +0E81DP/1011B0E81DP5B0E81DP5B0E811e802049DPUB2E811`T0:@49Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T100H900P12E89DPUB0@QB00h1DP5B0E81DP5B0E81DPH11@010@40 +000E00030@0000801`403E81DP5B0E81DP5B0E800P47DP080E89DPUB2@472@0X0JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@L900P1DPUB2E890@MB0101DP5B0E81DP5B0E81DP5B +3@403E81DP5B0E81DP5B0E800P47DP080E89DPUB2@472@0X0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL90@L900P1DPUB2E890@MB00h1DP5B0E81DP5B0E81DPL11@010@40000E0003 +0@00008020403E81DP5B0E81DP5B0E800P47DP070E89DPUB0@082@0W0JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL100L900P12E89DPUB0@MB0P402e81DP5B0E81DP5B01<100]B0E81 +DP5B0E81DP020@IB00P12E89DPUB0@P902L1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`401`T01`49DPUB2@4025820@0;DP5B0E81DP5B0E80204500410@0001D000<100000P090@0= +DP5B0E81DP5B0E81DP020@IB00P12E89DPUB0@L902H12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW0@L900P12E89DPUB0@MB0P402e81DP5B0E81DP5B01D100aB0E81DP5B0E81DP47DP08 +0@UB2E89DP472@0V0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`472@080@UB2E89 +DP47DP8100]B0E81DP5B0E81DP090@D00@4100005@000`40000200X100iB0E81DP5B0E81DP5B0@MB +00L12E89DPT100P902D12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T100L900P1DPUB +2E890@MB00`1DP5B0E81DP5B0E8G0@00@D00@4100003@000`40000500810`0?0@0"], + ImageRangeCache->{{{0, 287}, {287, 0}} -> {-0.207, -0.172242, 0.00783272, + 0.00783272}}], + +Cell[BoxData[ + TagBox[\(\[SkeletonIndicator] ContourGraphics \[SkeletonIndicator]\), + False, + Editable->False]], "Output"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + \(ContourPlot[Y, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"], + +Cell[GraphicsData["PostScript", "\<\ +%! +%%Creator: Mathematica +%%AspectRatio: 1 +MathPictureStart +/Mabs { +Mgmatrix idtransform +Mtmatrix dtransform +} bind def +/Mabsadd { Mabs +3 -1 roll add +3 1 roll add +exch } bind def +%% ContourGraphics +%%IncludeResource: font Courier +%%IncludeFont: Courier +/Courier findfont 10 scalefont setfont +% Scaling calculations +0.0192308 0.480769 0.0192308 0.480769 [ +[.01923 -0.0125 -3 -9 ] +[.01923 -0.0125 3 0 ] +[.25962 -0.0125 -9 -9 ] +[.25962 -0.0125 9 0 ] +[.5 -0.0125 -3 -9 ] +[.5 -0.0125 3 0 ] +[.74038 -0.0125 -9 -9 ] +[.74038 -0.0125 9 0 ] +[.98077 -0.0125 -3 -9 ] +[.98077 -0.0125 3 0 ] +[ 0 0 -0.125 0 ] +[-0.0125 .01923 -6 -4.5 ] +[-0.0125 .01923 0 4.5 ] +[-0.0125 .25962 -18 -4.5 ] +[-0.0125 .25962 0 4.5 ] +[-0.0125 .5 -6 -4.5 ] +[-0.0125 .5 0 4.5 ] +[-0.0125 .74038 -18 -4.5 ] +[-0.0125 .74038 0 4.5 ] +[-0.0125 .98077 -6 -4.5 ] +[-0.0125 .98077 0 4.5 ] +[ 0 0 -0.125 0 ] +[ 0 1 .125 0 ] +[ 1 0 .125 0 ] +[ 0 0 0 0 ] +[ 1 1 0 0 ] +] MathScale +% Start of Graphics +1 setlinecap +1 setlinejoin +newpath +0 g +.25 Mabswid +.01923 0 m +.01923 .00625 L +s +[(0)] .01923 -0.0125 0 1 Mshowa +.25962 0 m +.25962 .00625 L +s +[(0.5)] .25962 -0.0125 0 1 Mshowa +.5 0 m +.5 .00625 L +s +[(1)] .5 -0.0125 0 1 Mshowa +.74038 0 m +.74038 .00625 L +s +[(1.5)] .74038 -0.0125 0 1 Mshowa +.98077 0 m +.98077 .00625 L +s +[(2)] .98077 -0.0125 0 1 Mshowa +.125 Mabswid +.06731 0 m +.06731 .00375 L +s +.11538 0 m +.11538 .00375 L +s +.16346 0 m +.16346 .00375 L +s +.21154 0 m +.21154 .00375 L +s +.30769 0 m +.30769 .00375 L +s +.35577 0 m +.35577 .00375 L +s +.40385 0 m +.40385 .00375 L +s +.45192 0 m +.45192 .00375 L +s +.54808 0 m +.54808 .00375 L +s +.59615 0 m +.59615 .00375 L +s +.64423 0 m +.64423 .00375 L +s +.69231 0 m +.69231 .00375 L +s +.78846 0 m +.78846 .00375 L +s +.83654 0 m +.83654 .00375 L +s +.88462 0 m +.88462 .00375 L +s +.93269 0 m +.93269 .00375 L +s +.25 Mabswid +0 0 m +1 0 L +s +0 .01923 m +.00625 .01923 L +s +[(0)] -0.0125 .01923 1 0 Mshowa +0 .25962 m +.00625 .25962 L +s +[(0.5)] -0.0125 .25962 1 0 Mshowa +0 .5 m +.00625 .5 L +s +[(1)] -0.0125 .5 1 0 Mshowa +0 .74038 m +.00625 .74038 L +s +[(1.5)] -0.0125 .74038 1 0 Mshowa +0 .98077 m +.00625 .98077 L +s +[(2)] -0.0125 .98077 1 0 Mshowa +.125 Mabswid +0 .06731 m +.00375 .06731 L +s +0 .11538 m +.00375 .11538 L +s +0 .16346 m +.00375 .16346 L +s +0 .21154 m +.00375 .21154 L +s +0 .30769 m +.00375 .30769 L +s +0 .35577 m +.00375 .35577 L +s +0 .40385 m +.00375 .40385 L +s +0 .45192 m +.00375 .45192 L +s +0 .54808 m +.00375 .54808 L +s +0 .59615 m +.00375 .59615 L +s +0 .64423 m +.00375 .64423 L +s +0 .69231 m +.00375 .69231 L +s +0 .78846 m +.00375 .78846 L +s +0 .83654 m +.00375 .83654 L +s +0 .88462 m +.00375 .88462 L +s +0 .93269 m +.00375 .93269 L +s +.25 Mabswid +0 0 m +0 1 L +s +.01923 .99375 m +.01923 1 L +s +.25962 .99375 m +.25962 1 L +s +.5 .99375 m +.5 1 L +s +.74038 .99375 m +.74038 1 L +s +.98077 .99375 m +.98077 1 L +s +.125 Mabswid +.06731 .99625 m +.06731 1 L +s +.11538 .99625 m +.11538 1 L +s +.16346 .99625 m +.16346 1 L +s +.21154 .99625 m +.21154 1 L +s +.30769 .99625 m +.30769 1 L +s +.35577 .99625 m +.35577 1 L +s +.40385 .99625 m +.40385 1 L +s +.45192 .99625 m +.45192 1 L +s +.54808 .99625 m +.54808 1 L +s +.59615 .99625 m +.59615 1 L +s +.64423 .99625 m +.64423 1 L +s +.69231 .99625 m +.69231 1 L +s +.78846 .99625 m +.78846 1 L +s +.83654 .99625 m +.83654 1 L +s +.88462 .99625 m +.88462 1 L +s +.93269 .99625 m +.93269 1 L +s +.25 Mabswid +0 1 m +1 1 L +s +.99375 .01923 m +1 .01923 L +s +.99375 .25962 m +1 .25962 L +s +.99375 .5 m +1 .5 L +s +.99375 .74038 m +1 .74038 L +s +.99375 .98077 m +1 .98077 L +s +.125 Mabswid +.99625 .06731 m +1 .06731 L +s +.99625 .11538 m +1 .11538 L +s +.99625 .16346 m +1 .16346 L +s +.99625 .21154 m +1 .21154 L +s +.99625 .30769 m +1 .30769 L +s +.99625 .35577 m +1 .35577 L +s +.99625 .40385 m +1 .40385 L +s +.99625 .45192 m +1 .45192 L +s +.99625 .54808 m +1 .54808 L +s +.99625 .59615 m +1 .59615 L +s +.99625 .64423 m +1 .64423 L +s +.99625 .69231 m +1 .69231 L +s +.99625 .78846 m +1 .78846 L +s +.99625 .83654 m +1 .83654 L +s +.99625 .88462 m +1 .88462 L +s +.99625 .93269 m +1 .93269 L +s +.25 Mabswid +1 0 m +1 1 L +s +0 0 m +1 0 L +1 1 L +0 1 L +closepath +clip +newpath +.5 g +.01923 .98077 m +.98077 .98077 L +.98077 .01923 L +.01923 .01923 L +F +0 g +.5 Mabswid +.6 g +.01923 .24501 m +.08791 .2434 L +.15659 .23612 L +.19287 .22527 L +.22527 .19287 L +.23612 .15659 L +.2434 .08791 L +.24501 .01923 L +.01923 .01923 L +F +0 g +.01923 .24501 m +.08791 .2434 L +.15659 .23612 L +.19287 .22527 L +.22527 .19287 L +.23612 .15659 L +.2434 .08791 L +.24501 .01923 L +s +.4 g +.01923 .72578 m +.08791 .72416 L +.15659 .71689 L +.19287 .70604 L +.22527 .67364 L +.23612 .63736 L +.2434 .56868 L +.24501 .5 L +.2434 .43132 L +.23612 .36264 L +.22527 .32636 L +.19287 .29396 L +.15659 .28311 L +.08791 .27584 L +.01923 .27422 L +F +0 g +.01923 .72578 m +.08791 .72416 L +.15659 .71689 L +.19287 .70604 L +.22527 .67364 L +.23612 .63736 L +.2434 .56868 L +.24501 .5 L +.2434 .43132 L +.23612 .36264 L +.22527 .32636 L +.19287 .29396 L +.15659 .28311 L +.08791 .27584 L +.01923 .27422 L +s +.6 g +.01923 .75499 m +.08791 .7566 L +.15659 .76388 L +.19287 .77473 L +.22527 .80713 L +.23612 .84341 L +.2434 .91209 L +.24501 .98077 L +.01923 .98077 L +F +0 g +.01923 .75499 m +.08791 .7566 L +.15659 .76388 L +.19287 .77473 L +.22527 .80713 L +.23612 .84341 L +.2434 .91209 L +.24501 .98077 L +s +.7 g +.01923 .21567 m +.08791 .21083 L +.15659 .18768 L +.18768 .15659 L +.21083 .08791 L +.21567 .01923 L +.01923 .01923 L +F +0 g +.01923 .21567 m +.08791 .21083 L +.15659 .18768 L +.18768 .15659 L +.21083 .08791 L +.21567 .01923 L +s +.3 g +.01923 .69644 m +.08791 .69159 L +.15659 .66845 L +.18768 .63736 L +.21083 .56868 L +.21567 .5 L +.21083 .43132 L +.18768 .36264 L +.15659 .33155 L +.08791 .30841 L +.01923 .30356 L +F +0 g +.01923 .69644 m +.08791 .69159 L +.15659 .66845 L +.18768 .63736 L +.21083 .56868 L +.21567 .5 L +.21083 .43132 L +.18768 .36264 L +.15659 .33155 L +.08791 .30841 L +.01923 .30356 L +s +.7 g +.01923 .78433 m +.08791 .78917 L +.15659 .81232 L +.18768 .84341 L +.21083 .91209 L +.21567 .98077 L +.01923 .98077 L +F +0 g +.01923 .78433 m +.08791 .78917 L +.15659 .81232 L +.18768 .84341 L +.21083 .91209 L +.21567 .98077 L +s +.8 g +.01923 .18453 m +.08791 .17501 L +.13801 .15659 L +.15659 .13801 L +.17501 .08791 L +.18453 .01923 L +.01923 .01923 L +F +0 g +.01923 .18453 m +.08791 .17501 L +.13801 .15659 L +.15659 .13801 L +.17501 .08791 L +.18453 .01923 L +s +.2 g +.01923 .6653 m +.08791 .65578 L +.13801 .63736 L +.15659 .61878 L +.17501 .56868 L +.18453 .5 L +.17501 .43132 L +.15659 .38122 L +.13801 .36264 L +.08791 .34422 L +.01923 .3347 L +F +0 g +.01923 .6653 m +.08791 .65578 L +.13801 .63736 L +.15659 .61878 L +.17501 .56868 L +.18453 .5 L +.17501 .43132 L +.15659 .38122 L +.13801 .36264 L +.08791 .34422 L +.01923 .3347 L +s +.8 g +.01923 .81547 m +.08791 .82499 L +.13801 .84341 L +.15659 .86199 L +.17501 .91209 L +.18453 .98077 L +.01923 .98077 L +F +0 g +.01923 .81547 m +.08791 .82499 L +.13801 .84341 L +.15659 .86199 L +.17501 .91209 L +.18453 .98077 L +s +.9 g +.01923 .15309 m +.08791 .14294 L +.14294 .08791 L +.15309 .01923 L +.01923 .01923 L +F +0 g +.01923 .15309 m +.08791 .14294 L +.14294 .08791 L +.15309 .01923 L +s +.1 g +.01923 .63386 m +.08791 .62371 L +.14294 .56868 L +.15309 .5 L +.14294 .43132 L +.08791 .37629 L +.01923 .36614 L +F +0 g +.01923 .63386 m +.08791 .62371 L +.14294 .56868 L +.15309 .5 L +.14294 .43132 L +.08791 .37629 L +.01923 .36614 L +s +.9 g +.01923 .84691 m +.08791 .85706 L +.14294 .91209 L +.15309 .98077 L +.01923 .98077 L +F +0 g +.01923 .84691 m +.08791 .85706 L +.14294 .91209 L +.15309 .98077 L +s +1 g +.01923 .10805 m +.05547 .08791 L +.08791 .05547 L +.10805 .01923 L +.01923 .01923 L +F +0 g +.01923 .10805 m +.05547 .08791 L +.08791 .05547 L +.10805 .01923 L +s +.01923 .58882 m +.05547 .56868 L +.08791 .54644 L +.10805 .5 L +.08791 .45356 L +.05547 .43132 L +.01923 .41118 L +F +.01923 .58882 m +.05547 .56868 L +.08791 .54644 L +.10805 .5 L +.08791 .45356 L +.05547 .43132 L +.01923 .41118 L +s +1 g +.01923 .89195 m +.05547 .91209 L +.08791 .94453 L +.10805 .98077 L +.01923 .98077 L +F +0 g +.01923 .89195 m +.05547 .91209 L +.08791 .94453 L +.10805 .98077 L +s +.4 g +.72578 .01923 m +.72416 .08791 L +.71689 .15659 L +.70604 .19287 L +.67364 .22527 L +.63736 .23612 L +.56868 .2434 L +.5 .24501 L +.43132 .2434 L +.36264 .23612 L +.32636 .22527 L +.29396 .19287 L +.28311 .15659 L +.27584 .08791 L +.27422 .01923 L +F +0 g +.72578 .01923 m +.72416 .08791 L +.71689 .15659 L +.70604 .19287 L +.67364 .22527 L +.63736 .23612 L +.56868 .2434 L +.5 .24501 L +.43132 .2434 L +.36264 .23612 L +.32636 .22527 L +.29396 .19287 L +.28311 .15659 L +.27584 .08791 L +.27422 .01923 L +s +.6 g +.36264 .28311 m +.43132 .27584 L +.5 .27422 L +.56868 .27584 L +.63736 .28311 L +.67364 .29396 L +.70604 .32636 L +.71689 .36264 L +.72416 .43132 L +.72578 .5 L +.72416 .56868 L +.71689 .63736 L +.70604 .67364 L +.67364 .70604 L +.63736 .71689 L +.56868 .72416 L +.5 .72578 L +.43132 .72416 L +.36264 .71689 L +.32636 .70604 L +.29396 .67364 L +.28311 .63736 L +.27584 .56868 L +.27422 .5 L +.27584 .43132 L +.28311 .36264 L +.29396 .32636 L +.32636 .29396 L +F +0 g +.36264 .28311 m +.43132 .27584 L +.5 .27422 L +.56868 .27584 L +.63736 .28311 L +.67364 .29396 L +.70604 .32636 L +.71689 .36264 L +.72416 .43132 L +.72578 .5 L +.72416 .56868 L +.71689 .63736 L +.70604 .67364 L +.67364 .70604 L +.63736 .71689 L +.56868 .72416 L +.5 .72578 L +.43132 .72416 L +.36264 .71689 L +.32636 .70604 L +.29396 .67364 L +.28311 .63736 L +.27584 .56868 L +.27422 .5 L +.27584 .43132 L +.28311 .36264 L +.29396 .32636 L +.32636 .29396 L +.36264 .28311 L +s +.4 g +.72578 .98077 m +.72416 .91209 L +.71689 .84341 L +.70604 .80713 L +.67364 .77473 L +.63736 .76388 L +.56868 .7566 L +.5 .75499 L +.43132 .7566 L +.36264 .76388 L +.32636 .77473 L +.29396 .80713 L +.28311 .84341 L +.27584 .91209 L +.27422 .98077 L +F +0 g +.72578 .98077 m +.72416 .91209 L +.71689 .84341 L +.70604 .80713 L +.67364 .77473 L +.63736 .76388 L +.56868 .7566 L +.5 .75499 L +.43132 .7566 L +.36264 .76388 L +.32636 .77473 L +.29396 .80713 L +.28311 .84341 L +.27584 .91209 L +.27422 .98077 L +s +.3 g +.69644 .01923 m +.69159 .08791 L +.66845 .15659 L +.63736 .18768 L +.56868 .21083 L +.5 .21567 L +.43132 .21083 L +.36264 .18768 L +.33155 .15659 L +.30841 .08791 L +.30356 .01923 L +F +0 g +.69644 .01923 m +.69159 .08791 L +.66845 .15659 L +.63736 .18768 L +.56868 .21083 L +.5 .21567 L +.43132 .21083 L +.36264 .18768 L +.33155 .15659 L +.30841 .08791 L +.30356 .01923 L +s +.7 g +.36264 .33155 m +.43132 .30841 L +.5 .30356 L +.56868 .30841 L +.63736 .33155 L +.66845 .36264 L +.69159 .43132 L +.69644 .5 L +.69159 .56868 L +.66845 .63736 L +.63736 .66845 L +.56868 .69159 L +.5 .69644 L +.43132 .69159 L +.36264 .66845 L +.33155 .63736 L +.30841 .56868 L +.30356 .5 L +.30841 .43132 L +.33155 .36264 L +F +0 g +.36264 .33155 m +.43132 .30841 L +.5 .30356 L +.56868 .30841 L +.63736 .33155 L +.66845 .36264 L +.69159 .43132 L +.69644 .5 L +.69159 .56868 L +.66845 .63736 L +.63736 .66845 L +.56868 .69159 L +.5 .69644 L +.43132 .69159 L +.36264 .66845 L +.33155 .63736 L +.30841 .56868 L +.30356 .5 L +.30841 .43132 L +.33155 .36264 L +.36264 .33155 L +s +.3 g +.69644 .98077 m +.69159 .91209 L +.66845 .84341 L +.63736 .81232 L +.56868 .78917 L +.5 .78433 L +.43132 .78917 L +.36264 .81232 L +.33155 .84341 L +.30841 .91209 L +.30356 .98077 L +F +0 g +.69644 .98077 m +.69159 .91209 L +.66845 .84341 L +.63736 .81232 L +.56868 .78917 L +.5 .78433 L +.43132 .78917 L +.36264 .81232 L +.33155 .84341 L +.30841 .91209 L +.30356 .98077 L +s +.2 g +.6653 .01923 m +.65578 .08791 L +.63736 .13801 L +.61878 .15659 L +.56868 .17501 L +.5 .18453 L +.43132 .17501 L +.38122 .15659 L +.36264 .13801 L +.34422 .08791 L +.3347 .01923 L +F +0 g +.6653 .01923 m +.65578 .08791 L +.63736 .13801 L +.61878 .15659 L +.56868 .17501 L +.5 .18453 L +.43132 .17501 L +.38122 .15659 L +.36264 .13801 L +.34422 .08791 L +.3347 .01923 L +s +.8 g +.43132 .34422 m +.5 .3347 L +.56868 .34422 L +.61878 .36264 L +.63736 .38122 L +.65578 .43132 L +.6653 .5 L +.65578 .56868 L +.63736 .61878 L +.61878 .63736 L +.56868 .65578 L +.5 .6653 L +.43132 .65578 L +.38122 .63736 L +.36264 .61878 L +.34422 .56868 L +.3347 .5 L +.34422 .43132 L +.36264 .38122 L +.38122 .36264 L +F +0 g +.43132 .34422 m +.5 .3347 L +.56868 .34422 L +.61878 .36264 L +.63736 .38122 L +.65578 .43132 L +.6653 .5 L +.65578 .56868 L +.63736 .61878 L +.61878 .63736 L +.56868 .65578 L +.5 .6653 L +.43132 .65578 L +.38122 .63736 L +.36264 .61878 L +.34422 .56868 L +.3347 .5 L +.34422 .43132 L +.36264 .38122 L +.38122 .36264 L +.43132 .34422 L +s +.2 g +.6653 .98077 m +.65578 .91209 L +.63736 .86199 L +.61878 .84341 L +.56868 .82499 L +.5 .81547 L +.43132 .82499 L +.38122 .84341 L +.36264 .86199 L +.34422 .91209 L +.3347 .98077 L +F +0 g +.6653 .98077 m +.65578 .91209 L +.63736 .86199 L +.61878 .84341 L +.56868 .82499 L +.5 .81547 L +.43132 .82499 L +.38122 .84341 L +.36264 .86199 L +.34422 .91209 L +.3347 .98077 L +s +.1 g +.63386 .01923 m +.62371 .08791 L +.56868 .14294 L +.5 .15309 L +.43132 .14294 L +.37629 .08791 L +.36614 .01923 L +F +0 g +.63386 .01923 m +.62371 .08791 L +.56868 .14294 L +.5 .15309 L +.43132 .14294 L +.37629 .08791 L +.36614 .01923 L +s +.9 g +.43132 .37629 m +.5 .36614 L +.56868 .37629 L +.62371 .43132 L +.63386 .5 L +.62371 .56868 L +.56868 .62371 L +.5 .63386 L +.43132 .62371 L +.37629 .56868 L +.36614 .5 L +.37629 .43132 L +F +0 g +.43132 .37629 m +.5 .36614 L +.56868 .37629 L +.62371 .43132 L +.63386 .5 L +.62371 .56868 L +.56868 .62371 L +.5 .63386 L +.43132 .62371 L +.37629 .56868 L +.36614 .5 L +.37629 .43132 L +.43132 .37629 L +s +.1 g +.63386 .98077 m +.62371 .91209 L +.56868 .85706 L +.5 .84691 L +.43132 .85706 L +.37629 .91209 L +.36614 .98077 L +F +0 g +.63386 .98077 m +.62371 .91209 L +.56868 .85706 L +.5 .84691 L +.43132 .85706 L +.37629 .91209 L +.36614 .98077 L +s +.58882 .01923 m +.56868 .05547 L +.54644 .08791 L +.5 .10805 L +.45356 .08791 L +.43132 .05547 L +.41118 .01923 L +F +.58882 .01923 m +.56868 .05547 L +.54644 .08791 L +.5 .10805 L +.45356 .08791 L +.43132 .05547 L +.41118 .01923 L +s +1 g +.5 .41118 m +.54644 .43132 L +.56868 .45356 L +.58882 .5 L +.56868 .54644 L +.54644 .56868 L +.5 .58882 L +.45356 .56868 L +.43132 .54644 L +.41118 .5 L +.43132 .45356 L +.45356 .43132 L +F +0 g +.5 .41118 m +.54644 .43132 L +.56868 .45356 L +.58882 .5 L +.56868 .54644 L +.54644 .56868 L +.5 .58882 L +.45356 .56868 L +.43132 .54644 L +.41118 .5 L +.43132 .45356 L +.45356 .43132 L +.5 .41118 L +s +.58882 .98077 m +.56868 .94453 L +.54644 .91209 L +.5 .89195 L +.45356 .91209 L +.43132 .94453 L +.41118 .98077 L +F +.58882 .98077 m +.56868 .94453 L +.54644 .91209 L +.5 .89195 L +.45356 .91209 L +.43132 .94453 L +.41118 .98077 L +s +.6 g +.98077 .24501 m +.91209 .2434 L +.84341 .23612 L +.80713 .22527 L +.77473 .19287 L +.76388 .15659 L +.7566 .08791 L +.75499 .01923 L +.98077 .01923 L +F +0 g +.98077 .24501 m +.91209 .2434 L +.84341 .23612 L +.80713 .22527 L +.77473 .19287 L +.76388 .15659 L +.7566 .08791 L +.75499 .01923 L +s +.4 g +.98077 .72578 m +.91209 .72416 L +.84341 .71689 L +.80713 .70604 L +.77473 .67364 L +.76388 .63736 L +.7566 .56868 L +.75499 .5 L +.7566 .43132 L +.76388 .36264 L +.77473 .32636 L +.80713 .29396 L +.84341 .28311 L +.91209 .27584 L +.98077 .27422 L +F +0 g +.98077 .72578 m +.91209 .72416 L +.84341 .71689 L +.80713 .70604 L +.77473 .67364 L +.76388 .63736 L +.7566 .56868 L +.75499 .5 L +.7566 .43132 L +.76388 .36264 L +.77473 .32636 L +.80713 .29396 L +.84341 .28311 L +.91209 .27584 L +.98077 .27422 L +s +.6 g +.98077 .75499 m +.91209 .7566 L +.84341 .76388 L +.80713 .77473 L +.77473 .80713 L +.76388 .84341 L +.7566 .91209 L +.75499 .98077 L +.98077 .98077 L +F +0 g +.98077 .75499 m +.91209 .7566 L +.84341 .76388 L +.80713 .77473 L +.77473 .80713 L +.76388 .84341 L +.7566 .91209 L +.75499 .98077 L +s +.7 g +.98077 .21567 m +.91209 .21083 L +.84341 .18768 L +.81232 .15659 L +.78917 .08791 L +.78433 .01923 L +.98077 .01923 L +F +0 g +.98077 .21567 m +.91209 .21083 L +.84341 .18768 L +.81232 .15659 L +.78917 .08791 L +.78433 .01923 L +s +.3 g +.98077 .69644 m +.91209 .69159 L +.84341 .66845 L +.81232 .63736 L +.78917 .56868 L +.78433 .5 L +.78917 .43132 L +.81232 .36264 L +.84341 .33155 L +.91209 .30841 L +.98077 .30356 L +F +0 g +.98077 .69644 m +.91209 .69159 L +.84341 .66845 L +.81232 .63736 L +.78917 .56868 L +.78433 .5 L +.78917 .43132 L +.81232 .36264 L +.84341 .33155 L +.91209 .30841 L +.98077 .30356 L +s +.7 g +.98077 .78433 m +.91209 .78917 L +.84341 .81232 L +.81232 .84341 L +.78917 .91209 L +.78433 .98077 L +.98077 .98077 L +F +0 g +.98077 .78433 m +.91209 .78917 L +.84341 .81232 L +.81232 .84341 L +.78917 .91209 L +.78433 .98077 L +s +.8 g +.98077 .18453 m +.91209 .17501 L +.86199 .15659 L +.84341 .13801 L +.82499 .08791 L +.81547 .01923 L +.98077 .01923 L +F +0 g +.98077 .18453 m +.91209 .17501 L +.86199 .15659 L +.84341 .13801 L +.82499 .08791 L +.81547 .01923 L +s +.2 g +.98077 .6653 m +.91209 .65578 L +.86199 .63736 L +.84341 .61878 L +.82499 .56868 L +.81547 .5 L +.82499 .43132 L +.84341 .38122 L +.86199 .36264 L +.91209 .34422 L +.98077 .3347 L +F +0 g +.98077 .6653 m +.91209 .65578 L +.86199 .63736 L +.84341 .61878 L +.82499 .56868 L +.81547 .5 L +.82499 .43132 L +.84341 .38122 L +.86199 .36264 L +.91209 .34422 L +.98077 .3347 L +s +.8 g +.98077 .81547 m +.91209 .82499 L +.86199 .84341 L +.84341 .86199 L +.82499 .91209 L +.81547 .98077 L +.98077 .98077 L +F +0 g +.98077 .81547 m +.91209 .82499 L +.86199 .84341 L +.84341 .86199 L +.82499 .91209 L +.81547 .98077 L +s +.9 g +.98077 .15309 m +.91209 .14294 L +.85706 .08791 L +.84691 .01923 L +.98077 .01923 L +F +0 g +.98077 .15309 m +.91209 .14294 L +.85706 .08791 L +.84691 .01923 L +s +.1 g +.98077 .63386 m +.91209 .62371 L +.85706 .56868 L +.84691 .5 L +.85706 .43132 L +.91209 .37629 L +.98077 .36614 L +F +0 g +.98077 .63386 m +.91209 .62371 L +.85706 .56868 L +.84691 .5 L +.85706 .43132 L +.91209 .37629 L +.98077 .36614 L +s +.9 g +.98077 .84691 m +.91209 .85706 L +.85706 .91209 L +.84691 .98077 L +.98077 .98077 L +F +0 g +.98077 .84691 m +.91209 .85706 L +.85706 .91209 L +.84691 .98077 L +s +1 g +.98077 .10805 m +.94453 .08791 L +.91209 .05547 L +.89195 .01923 L +.98077 .01923 L +F +0 g +.98077 .10805 m +.94453 .08791 L +.91209 .05547 L +.89195 .01923 L +s +.98077 .58882 m +.94453 .56868 L +.91209 .54644 L +.89195 .5 L +.91209 .45356 L +.94453 .43132 L +.98077 .41118 L +F +.98077 .58882 m +.94453 .56868 L +.91209 .54644 L +.89195 .5 L +.91209 .45356 L +.94453 .43132 L +.98077 .41118 L +s +1 g +.98077 .89195 m +.94453 .91209 L +.91209 .94453 L +.89195 .98077 L +.98077 .98077 L +F +0 g +.98077 .89195 m +.94453 .91209 L +.91209 .94453 L +.89195 .98077 L +s +% End of Graphics +MathPictureEnd +\ +\>"], "Graphics", + ImageSize->{288, 288}, + ImageMargins->{{43, 0}, {0, 0}}, + ImageRegion->{{0, 1}, {0, 1}}, + ImageCache->GraphicsData["Bitmap", "\<\ +CF5dJ6E]HGAYHf4PAg9QL6QYHgon6Ykno_hn?S`2ook>c/mWIfGmoOol005E[;lC4a000<`00IP00V@00c000 +o`0c000c<`0cIP0cV@0cc00co`1V001V<`1VIP1VV@1Vc01Vo`2I002I<`2IIP2IV@2Ic02Io`3<003< +<`3I03>IIIS>IVC>Ic3>Ioc?<03?<@000`40000f00030@0000L00`4i0003 +0@0000@0000H00040@000CH000@1000120000`40000i00030@0003H000<100001`000`40000j0003 +0@0000<0000H00040@000CH000@1000120000`40000g00<1=P030@T000<10000=`00104000450000 +6@020CP00P4900@1>0000`40000f00030@0000L0104g00811P000?l08@0001D0o`4;0@40000E0003 +0@00008000<100002P000`40000900030@0000X000<100002P000`40000:00030@0000X000<10000 +2@000`40000:00030@0000X000<100002P000`40000900030@0000X000<100002P000`40000:0003 +0@0000T000<100002P000`40000:00030@0000X000<100002P000`40000900030@0000800@410000 +5@000`40000200030@0003d000<10000?@000`40000l00030@0003d000<100000P010@40000E0003 +0@000?l01`010@40000>00811@000`40003o00L00@4100003@001040004400816`000`4000080003 +0@0000H000<100001@000`40000500030@0000D000<1000010000`40000600030@0000D000<10000 +2@000`40000/00030@0000T000<100001@000`40000600030@0000D000<1000010000`4000050003 +0@0000D000<100001P000`40000900030@0001P00P4100003@001040004400030@0001T000d100P0 +200800P0200100P800T1Y`RW2:L8Y`401jL02@49Y`VW2JL90@062@0:0@UB2E89DPUB0@MB0P402e81 +DP5B0E81DP5B02l100aB0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@L900P12JL9Y`VW0@NW00T12:L8 +Y`RW204020P03P4800P0200800P020016P010@40000=00040@000@@000<100006@003@4800P02008 +00P0204020P02@48Y`RW2:L80@07Y`090JL9Y`VW2JL100H900X1DPUB2E89DPT11e80305B0E81DP5B +0E81DRl100]B0E81DP5B0E81DP020@MB00X1DPUB2E89DPT11`T0206W2JL9Y`T11jL02@6W2:L8Y`RW +0@08200>0@0800P0200800P0204J00410@0000d000@1000110000`40000H000>0@P0200800P02008 +004820090JL8Y`RW2:L100NW00T12JL9Y`VW2@401PT02P49DPUB2E89DP47DP8100]B0E81DP5B0E81 +DP0_0@0DP5B0E81DP5B0E81DP47DP0: +0@UB2E89DPUB0@P900P1Y`VW2JL90@NW00X1Y`RW2:L8Y`P120P0404800P0200800P02008004G0041 +0@0001D000<100005@004040200800P0200800P02048200:0@RW2:L8Y`RW0@NW00T12JL9Y`VW2@40 +1`T02P5B2E89DPUB2@47DP0@0E81DP5B0E81DP5B0E81DRL100eB0E81DP5B0E81DP5B00811e802P5B +2E89DPUB2@482@080@VW2JL9Y`47Y`0:0@RW2:L8Y`RW0@P8014100P0200800P0200800P00@0F0041 +0@0001D000<1000050004@40200800P0200800P0200100L800X12:L8Y`RW2:L11jL02P49Y`VW2JL9 +Y`472@0:0@UB2E89DPUB0@QB00h1DP5B0E81DP5B0E81DRL100eB0E81DP5B0E81DP5B008125802P49 +DPUB2E89DP472@0:0@VW2JL9Y`VW0@NW00X12:L8Y`RW2:L11`P04@4800P0200800P0200800P101H0 +0@4100005@000`40000C000B0@0800P0200800P0200800P11`P02P6W2:L8Y`RW2047Y`0:0JL9Y`VW +2JL90@L900X1DPUB2E89DPT125820@0=DP5B0E81DP5B0E81DP0U0@0@DP5B0E81DP5B0E81DP5B0@QB +00X1DPUB2E89DPT11`T02P6W2JL9Y`VW2@47Y`0:0JL8Y`RW2:L80@L8018100P0200800P0200800P0 +204E00410@0001D000<100004P004`40200800P0200800P0200800401`P02P48Y`RW2:L8Y`47Y`0: +0@VW2JL9Y`VW0@L900X12E89DPUB2E812580405B0E81DP5B0E81DP5B0E8U0@0=DP5B0E81DP5B0E81 +DP020@QB00X12E89DPUB2E811`T02P49Y`VW2JL9Y`47Y`0:0@RW2:L8Y`RW0@L801<1200800P02008 +00P0200800P101@00@4100005@020A8001@100P0200800P0200800P020080@L800X1Y`RW2:L8Y`P1 +1jL02P6W2JL9Y`VW2@472@0:0E89DPUB2E890@QB0P403e81DP5B0E81DP5B0E81DP0S0@0@DP5B0E81 +DP5B0E81DP5B0@QB00X1DPUB2E89DPT11`T02P6W2JL9Y`VW2@47Y`0:0JL8Y`RW2:L80@L801@100P0 +200800P0200800P020080A800P4100005@000`40000@000E0@0800P0200800P0200800P0200100L8 +00X12:L8Y`RW2:L11jL02P49Y`VW2JL9Y`472@0:0@UB2E89DPUB0@QB0181DP5B0E81DP5B0E81DP5B +0E8Q0@0?DP5B0E81DP5B0E81DP5B008125802P49DPUB2E89DP472@0:0@VW2JL9Y`VW0@NW00X12:L8 +Y`RW2:L11`P05@4800P0200800P0200800P020080@0B00410@0001D000<100004000504800P02008 +00P0200800P0200120P02P6W2:L8Y`RW2047Y`0:0JL9Y`VW2JL90@P900X12E89DPUB2E811e820@0? +DP5B0E81DP5B0E81DP5B0241019B0E81DP5B0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@P900X1Y`VW +2JL9Y`T11jL02P6W2:L8Y`RW2048200E0@P0200800P0200800P0200800P101400@4100005@000`40 +000?000E0@P0200800P0200800P0200800P100L800/1Y`RW2:L8Y`RW0@07Y`0:0@VW2JL9Y`VW0@P9 +00X1DPUB2E89DPT125820@0?DP5B0E81DP5B0E81DP5B01l1019B0E81DP5B0E81DP5B0E81DP48DP0: +0E89DPUB2E890@P900X12JL9Y`VW2JL11jL02`48Y`RW2:L8Y`P100L801H100P0200800P0200800P0 +200800P140010@40000E00030@0000h001H1200800P0200800P0200800P020011`P02`48Y`RW2:L8 +Y`P100NW00X1Y`VW2JL9Y`T120T02P49DPUB2E89DP48DP0B0E81DP5B0E81DP5B0E81DP5B7@404E81 +DP5B0E81DP5B0E81DP5B008125802P49DPUB2E89DP482@0:0JL9Y`VW2JL90@NW00/1Y`RW2:L8Y`RW +0@07200G0@P0200800P0200800P0200800P020403`010@40000E00030@0000d001L1200800P02008 +00P0200800P020080@07200;0JL8Y`RW2:L8Y`401jL02P49Y`VW2JL9Y`482@0:0E89DPUB2E890@QB +0P404E81DP5B0E81DP5B0E81DP5B01d1019B0E81DP5B0E81DP5B0E81DP48DP0:0E89DPUB2E890@P9 +00X12JL9Y`VW2JL11jL02`48Y`RW2:L8Y`P100L801P100P0200800P0200800P0200800P0204>0041 +0@0001D000<100002`020@0G200800P0200800P0200800P0200800401`P02`48Y`RW2:L8Y`P100NW +00X1Y`VW2JL9Y`T120T02P49DPUB2E89DP48DP0D0E81DP5B0E81DP5B0E81DP5B0E8K0@0ADP5B0E81 +DP5B0E81DP5B0E800P48DP0:0@UB2E89DPUB0@P900X1Y`VW2JL9Y`T11jL02`6W2:L8Y`RW2:L100L8 +01T1200800P0200800P0200800P0200800P100d00@4100005@000`400009008101P0200800P02008 +00P0200800P020080048200;0JL8Y`RW2:L8Y`401jL02P49Y`VW2JL9Y`482@0:0E89DPUB2E890@UB +01@1DP5B0E81DP5B0E81DP5B0E81DQL101=B0E81DP5B0E81DP5B0E81DP5B00812E802P5B2E89DPUB +2@482@0:0@VW2JL9Y`VW0@NW00/12:L8Y`RW2:L80@08200H0@P0200800P0200800P0200800P02008 +0P4;00410@0001D000<100001`020@0I200800P0200800P0200800P0200800P00@08200;0JL8Y`RW +2:L8Y`402:L02P6W2JL9Y`VW2@492@0:0E89DPUB2E890@UB01H1DP5B0E81DP5B0E81DP5B0E81DP5B +4`404e81DP5B0E81DP5B0E81DP5B0E800P49DP0:0E89DPUB2E890@T900X1Y`VW2JL9Y`T12:L02`48 +Y`RW2:L8Y`P100P801T1200800P0200800P0200800P0200800P000812@010@40000E00030@0000D0 +0P406P0800P0200800P0200800P0200800P020012@P02`48Y`RW2:L8Y`P100RW00X12JL9Y`VW2JL1 +2@T02P49DPUB2E89DP4:DP0H0E81DP5B0E81DP5B0E81DP5B0E81DP5B3@405E81DP5B0E81DP5B0E81 +DP5B0E81DP020@YB00X12E89DPUB2E812@T02P49Y`VW2JL9Y`48Y`0;0JL8Y`RW2:L8Y`402@P06P48 +00P0200800P0200800P0200800P020080P4700410@0001D000<100000`020@0K200800P0200800P0 +200800P0200800P0200100T800`12:L8Y`RW2:L8Y`48Y`0:0JL9Y`VW2JL90@T900/1DPUB2E89DPUB +0@0:DP0J0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E870@0GDP5B0E81DP5B0E81DP5B0E81DP5B0E80 +0P4:DP0;0@UB2E89DPUB2@402@T02P6W2JL9Y`VW2@49Y`0;0JL8Y`RW2:L8Y`402@P06`4800P02008 +00P0200800P0200800P0200800020@D00@4100005@000`400002000M0@0800P0200800P0200800P0 +200800P0200800402PP02`6W2:L8Y`RW2:L100VW00/12JL9Y`VW2JL90@092@0:0E89DPUB2E890@]B +01X1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DPD101MB0E81DP5B0E81DP5B0E81DP5B0E81DP020@]B +00X1DPUB2E89DPT12@T0306W2JL9Y`VW2JL90@RW00/12:L8Y`RW2:L80@0:200M0@P0200800P02008 +00P0200800P0200800P0204010010@40000E00030@0000<001/800P0200800P0200800P0200800P0 +200800402`P02`48Y`RW2:L8Y`P100VW00/1Y`VW2JL9Y`VW0@092@0:0@UB2E89DPUB0@aB03@1DP5B +0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0P4200;0@RW2:L8Y`RW20402ZL02`49Y`VW2JL9Y`T100X900X12E89DPUB2E81 +3U80;P5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E820@iB00X12E89 +DPUB2E812PT0306W2JL9Y`VW2JL90@ZW00X12:L8Y`RW2:L13PP05`40200800P0200800P0200800P0 +200800D00@4100005@000`400003000F200800P0200800P0200800P020080@h800`12:L8Y`RW2:L8 +Y`49Y`0<0@VW2JL9Y`VW2JL12PT02`5B2E89DPUB2E8100iB02`1DP5B0E81DP5B0E81DP5B0E81DP5B +0E81DP5B0E81DP5B0E81DP5B0E81DP813U802`49DPUB2E89DPT100X900`12JL9Y`VW2JL9Y`4:Y`0; +0JL8Y`RW2:L8Y`403PP05@40200800P0200800P0200800P0200600410@0001D000<100000P005PP0 +200800P0200800P0200800P0204?200;0JL8Y`RW2:L8Y`402ZL0306W2JL9Y`VW2JL90@/900X1DPUB +2E89DPT13e80:P5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP813e802P5B +2E89DPUB2@4;2@0<0JL9Y`VW2JL9Y`T12ZL02`48Y`RW2:L8Y`P100l801D100P0200800P0200800P0 +200800P01@010@40000E00030@0000<001@800P0200800P0200800P020080@l800`1Y`RW2:L8Y`RW +204:Y`0<0@VW2JL9Y`VW2JL12`T02`49DPUB2E89DPT100mB02P1DP5B0E81DP5B0E81DP5B0E81DP5B +0E81DP5B0E81DP5B0E81DP5B0P4?DP0;0E89DPUB2E89DP402`T03049Y`VW2JL9Y`VW0@^W00/12:L8 +Y`RW2:L80@0?200C0@0800P0200800P0200800P0200600410@0001D000<100000P0050P0200800P0 +200800P0200800P140P03048Y`RW2:L8Y`RW0@ZW00`1Y`VW2JL9Y`VW2@4;2@0;0E89DPUB2E89DP40 +45809P5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0P4@DP0;0@UB2E89DPUB2@40 +2`T0306W2JL9Y`VW2JL90@^W00/1Y`RW2:L8Y`RW0@0@200C0@0800P0200800P0200800P020050041 +0@0001D000<100000`003PP0200800P0200800P0104@200<0@RW2:L8Y`RW2:L12jL03@49Y`VW2JL9 +Y`VW2@402`T02`5B2E89DPUB2E81011B1@407E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B00@1 +45802`49DPUB2E89DPT100/900h1Y`VW2JL9Y`VW2JL90@ZW00`12:L8Y`RW2:L8Y`4@20<100h02008 +00P0200800P020H00@4100005@000`4000020009200800P0200800H14`P03@48Y`RW2:L8Y`RW2040 +2jL03@6W2JL9Y`VW2JL9Y`402`T03049DPUB2E89DPUB0A=B1P404E81DP5B0E81DP5B0E81DP5B00L1 +4e803049DPUB2E89DPUB0@/900h12JL9Y`VW2JL9Y`VW0@^W00`12:L8Y`RW2:L8Y`4B20H100T800P0 +200800P01@010@40000E00030@0000<000<800401@4H200>0@RW2:L8Y`RW2:L8Y`4;Y`0=0@VW2JL9 +Y`VW2JL90@0;2@0=0E89DPUB2E89DPUB0@0HDPL100EB0E81DP060AQB00d12E89DPUB2E89DPT100/9 +00h1Y`VW2JL9Y`VW2JL90@^W00d1Y`RW2:L8Y`RW2:L101L81P400`08000500410@0001D000<10000 +0P030Ad800h12:L8Y`RW2:L8Y`RW0@bW00d1Y`VW2JL9Y`VW2JL100`900d1DPUB2E89DPUB2E8101eB +1P4MDP0=0@UB2E89DPUB2E890@0<2@0>0@VW2JL9Y`VW2JL9Y`42:L8Y`RW2:L8Y`RW2040@UB2E89DPUB2E89DPT20CQB0P403U89DPUB2E89DPUB2E813@T03P49 +Y`VW2JL9Y`VW2JL13JL03P48Y`RW2:L8Y`RW2:L80P4K20D00@4100005@020@<06@P30@0@2:L8Y`RW +2:L8Y`RW2:L80@fW00l1Y`VW2JL9Y`VW2JL9Y`403@T03`49DPUB2E89DPUB2E89DP030C9B0`403`UB +2E89DPUB2E89DPUB0@0=2@0@0@VW2JL9Y`VW2JL9Y`VW0@fW00l12:L8Y`RW2:L8Y`RW2:L00`4H20@0 +0P4100005@000`40000201H80`404PRW2:L8Y`RW2:L8Y`RW2:L80@jW00l12JL9Y`VW2JL9Y`VW2@40 +3PT04@49DPUB2E89DPUB2E89DPUB00<1;5830@0A2E89DPUB2E89DPUB2E89DP403PT0406W2JL9Y`VW +2JL9Y`VW2@4>Y`0A0@RW2:L8Y`RW2:L8Y`RW2:L00`4E20D00@4100005@000`40000201@80P404PRW +2:L8Y`RW2:L8Y`RW2:L8Y`813jL03`6W2JL9Y`VW2JL9Y`VW0@0?2@0C0@UB2E89DPUB2E89DPUB2E89 +DP020BQB0P404`UB2E89DPUB2E89DPUB2E89DP403`T04049Y`VW2JL9Y`VW2JL9Y`4?Y`0C0@RW2:L8 +Y`RW2:L8Y`RW2:L8Y`020A<81@010@40000E00030@0000803PP60@0DY`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`4AY`0@0@VW2JL9Y`VW2JL9Y`VW0@l901@12E89DPUB2E89DPUB2E89DPUB2@H175860@0DDPUB2E89 +DPUB2E89DPUB2E89DP4@2@0A0JL9Y`VW2JL9Y`VW2JL9Y`403jL05048Y`RW2:L8Y`RW2:L8Y`RW2:L8 +1P4=20D00@4100005@000`40000200D82@406@RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`404JL04@49 +Y`VW2JL9Y`VW2JL9Y`T1010901T12E89DPUB2E89DPUB2E89DPUB2E89DPUB00X12E890@0I2E89DPUB +2E89DPUB2E89DPUB2E89DPUB0@0@2@0B0JL9Y`VW2JL9Y`VW2JL9Y`T14:L06@48Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L02@4420D00@4100005@000`40000200D10248Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`404ZL04@6W2JL9Y`VW2JL9Y`VW2JL1014902812E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E892@408@UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB0@0A2@0B0@VW2JL9 +Y`VW2JL9Y`VW2JL14JL08@48Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`050@@00@410000 +5@000`400002000S2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P00P4CY`0A0@VW2JL9 +Y`VW2JL9Y`VW2@404PT20@16DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2@814PT04P6W2JL9Y`VW2JL9Y`VW2JL90A:W0P408ZL8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P500410@0001D000<100000P008:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80`4DY`0C0@VW2JL9Y`VW2JL9Y`VW2JL90@0C2@<1041B2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +0`4C2@0D0JL9Y`VW2JL9Y`VW2JL9Y`VW2@4CY`<101nW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW00D00@4100005@000`400002000M2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P00`4GY`0C +0JL9Y`VW2JL9Y`VW2JL9Y`VW0@0F2@<103YB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E890`4F2@0D0@VW2JL9Y`VW2JL9Y`VW2JL9Y`4FY`<101bW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L81@010@40000E00030@00008001ZW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW20<16JL05@6W2JL9Y`VW2JL9Y`VW2JL9Y`VW0@0H2@<103AB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E890`4H2@0F0@VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW0ARW0`406JL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L01@010@40000E00030@00008001L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW20030A^W01L1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0@0J2@<102iB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E890`4J2@0H0@VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL16ZL30@0FY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20D00@4100005@000`400002000D +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P30AfW01T1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL101`90`40:589 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT30A`901X12JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW0AbW0`404jL8Y`RW2:L8Y`RW2:L8Y`RW2:L01@010@40000E00030@00008000h8Y`RW +2:L8Y`RW2:L8Y`H17ZL20@0JY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4N2@H101`9DPUB2E89DPUB +2E89DPUB2E89DPUB2E89DPUB1P4N2@0L0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0AjW1P403@RW +2:L8Y`RW2:L8Y`P01@010@40000E00810`001JL8Y`RW00T18jL07P49Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW0B<92P402E89DPUB2E89DP090B<901h12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`4SY`T100@8Y`RW10020@40000E00030@0000801@4[Y`0P0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`4/2@T1:`T08049Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1:jL50@@00@410000 +5@000`40000202nW02812JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1GPT08P49Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4^Y`D00@4100005@000`40000202fW0P408PVW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL20EX90P408PVW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL20BbW1@010@40000E00030@000080:JL40@0VY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`T30E<910409ZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +0`4YY`D00@4100005@000`40000202JW0`40;@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2@040D`90`40;@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2@040BFW1@010@40000E00030@0000808:L60@0d2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`H1@0T60@0d2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`H17jL500410@0001D000<100000P0GY`T1042W2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +2@4^2@T1042W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL92@4FY`D00@4100005@000`40000201L105:W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +;P40DZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`TG0@@00@4100005@000`400002003oY`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW00D00@4100005@000`400002003o2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL900D00@4100000P020@@000<10000 +0P030@D000<100000P00ojL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`0500410@000005004000402`000`4000020081 +0`00o`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2@0400810@000005004000402`000`40000200030@0000800?nW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL01@010@4000001@01000100P00`4500030@0000800?l9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T0 +1@010@4000001@01000100P000<100001@000`400002003oY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00D00@410000 +00D00@000@0800030@0000D000<100000P090@1^Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`TB0@1]Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`0:0@@00@4100000P020@T0104400030@0000802@T>0@1B2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`h14ZL>0@1B2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`d12@T500410@0001D000<10000 +0P0G2@T10409Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2@4^Y`T10409Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@4F2@D00@4100005@000`40000202091`40Y`D102P9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW1@4V2@D00@4100005@000`40000202`9 +0`408PVW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL30ERW0`408PVW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL30B/91@010@40000E00030@000080;`T08P49Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`5NY`0R0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0Bh9 +1@010@40000E00030@000080<0T08049Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1H:L08049 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1;`T500410@0001D000<100000P090BP901h12JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4XYa81::L07P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW0BL92P4400410@0001D00P4300092E89DPUB2E8900/17PT07049Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`4NY`/101:W2:L8Y`RW2:L8Y`RW2:L8Y`P;0AjW01`12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL17PT:0@092E89DPUB2E8900@00P4100005@000`400002000DDPUB2E89DPUB2E89DPUB2E89 +DPT30A`901/12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@406jL30@0XY`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20<16jL0706W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@4K2@<1 +01=B2E89DPUB2E89DPUB2E89DPUB00D00@4100005@000`400002000G2E89DPUB2E89DPUB2E89DPUB +2E89DPT00`4J2@0I0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@0IY`<102jW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L80`4IY`0J0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2@4I2@<101IB2E89DPUB2E89DPUB2E89DPUB2E891@010@40000E00030@00008001YB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2@<160T05`49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T101NW0`40=:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P30ANW01P1Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2@4G2@<101UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB00D00@4100005@000`40 +0002000M2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT00`4F2@0E0@VW2JL9Y`VW2JL9Y`VW2JL9 +Y`T101FW0`40>ZL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`P30AFW01H1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T15@T30@0LDPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2@D00@4100005@000`400002000PDPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPT30A@901<12JL9Y`VW2JL9Y`VW2JL9Y`T101>W0`40@:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P30A>W01@1Y`VW2JL9Y`VW2JL9Y`VW +2JL90A<90`407e89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E801@010@40000E00030@000080 +02<9DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2@020A8901<1Y`VW2JL9Y`VW2JL9Y`VW +2JL1016W0P40AZL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P20A6W01@12JL9Y`VW2JL9Y`VW2JL9Y`VW0A490P408U89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT500410@0001D000<100000P030@0S2E89DPUB2E89DPUB +2E89DPUB2E89DPUB2E89DPUB2E89DP404PT04@6W2JL9Y`VW2JL9Y`VW2JL1016W02<12:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`060@0S2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L8Y`404JL04P49Y`VW2JL9Y`VW2JL9Y`VW0A4902812E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89104400410@0001D000<100000P03DPH101iB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DP4A2@0A0@VW2JL9Y`VW2JL9Y`VW2@404:L07P48Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20H1 +1PP60@0NY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L14:L04P6W2JL9Y`VW2JL9Y`VW2JL90A09 +01d12E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP060@=B1@010@40000E00030@0000802E860@0I +2E89DPUB2E89DPUB2E89DPUB2E89DPUB0@0@2@0A0JL9Y`VW2JL9Y`VW2JL9Y`403jL06@48Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L01P4B20H101T8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L100nW01812JL9 +Y`VW2JL9Y`VW2JL9Y`4?2@0H0@UB2E89DPUB2E89DPUB2E89DPUB2E891P49DPD00@4100005@000`40 +000200mB1@405@UB2E89DPUB2E89DPUB2E89DPUB0@0@2@0@0JL9Y`VW2JL9Y`VW2JL90@jW01D12:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L01@4N20D101D8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`403jL04@49Y`VW2JL9 +Y`VW2JL9Y`T100h901D12E89DPUB2E89DPUB2E89DPUB2E80104?DPD00@4100005@000`40000201AB +0P405589DPUB2E89DPUB2E89DPUB2E813`T03`49Y`VW2JL9Y`VW2JL90@0?Y`0C0JL8Y`RW2:L8Y`RW +2:L8Y`RW20020BP80P404jL8Y`RW2:L8Y`RW2:L8Y`RW20403jL0406W2JL9Y`VW2JL9Y`VW2@4?2@0C +0E89DPUB2E89DPUB2E89DPUB2@020A=B1@010@40000E00030@0000805U830@0BDPUB2E89DPUB2E89 +DPUB2E813PT03`6W2JL9Y`VW2JL9Y`VW0@0>Y`0A0JL8Y`RW2:L8Y`RW2:L8Y`P00`4/20<1016W2:L8 +Y`RW2:L8Y`RW2:L80@0>Y`0@0@VW2JL9Y`VW2JL9Y`VW0@h90141DPUB2E89DPUB2E89DPUB2@030AEB +1@010@40000E00810`0IDP<1011B2E89DPUB2E89DPUB2E813@T03`49Y`VW2JL9Y`VW2JL90@0=Y`0? +0JL8Y`RW2:L8Y`RW2:L800<10P20@0>2:L8Y`RW2:L8Y`RW +204=Y`0>0JL9Y`VW2JL9Y`VW2@4=2@0>0E89DPUB2E89DPUB2E820A]B1@010@40000E00030@000080 +7U820@0>DPUB2E89DPUB2E89DP4<2@0=0JL9Y`VW2JL9Y`VW0@0200^0@0800P0200800P0200800P0200800P0200800P0200800P0200800P020080@h8 +00X12:L8Y`RW2:L12jL03049Y`VW2JL9Y`VW0@X900/1DPUB2E89DPUB0@0>DP0F0E81DP5B0E81DP5B +0E81DP5B0E81DPD00@4100005@000`400002000F0E81DP5B0E81DP5B0E81DP5B0E81DP813E80305B +2E89DPUB2E890@T900`1Y`VW2JL9Y`VW2@4:Y`0;0@RW2:L8Y`RW20403@P0<040200800P0200800P0 +200800P0200800P0200800P0200800P0200800P020080@d800/1Y`RW2:L8Y`RW0@0:Y`0<0JL9Y`VW +2JL9Y`T12PT02`49DPUB2E89DPT100eB01L1DP5B0E81DP5B0E81DP5B0E81DP5B0@0500410@0001D0 +00<100000P005e81DP5B0E81DP5B0E81DP5B0E81DP5B00813E802`5B2E89DPUB2E8100X900/1Y`VW +2JL9Y`VW0@0:Y`0:0JL8Y`RW2:L80@d8038100P0200800P0200800P0200800P0200800P0200800P0 +200800P0200800P020080@d800X1Y`RW2:L8Y`P12ZL03049Y`VW2JL9Y`VW0@X900X1DPUB2E89DPT1 +3E80605B0E81DP5B0E81DP5B0E81DP5B0E81DPD00@4100005@000`400002000H0E81DP5B0E81DP5B +0E81DP5B0E81DP5B0P40@D00@4100005@000`4000020141 +00mB0E81DP5B0E81DP5B0E800P48DP0:0@UB2E89DPUB0@L900X12JL9Y`VW2JL12:L02P6W2:L8Y`RW +2047200B0@0800P0200800P0200800P180004P40200800P0200800P020080@L800X1Y`RW2:L8Y`P1 +2:L02P49Y`VW2JL9Y`472@0:0@UB2E89DPUB0@QB0181DP5B0E81DP5B0E81DP5B0E8?0@D00@410000 +5@020@<04P403e81DP5B0E81DP5B0E81DP020@MB00X1DPUB2E89DPT11`T02P6W2JL9Y`VW2@47Y`0: +0JL8Y`RW2:L80@P80141200800P0200800P020080@0R000A0@0800P0200800P02008004020P02P6W +2:L8Y`RW2047Y`0:0JL9Y`VW2JL90@L900X1DPUB2E89DPT11e80405B0E81DP5B0E81DP5B0E8B0@@0 +0P4100005@000`40000201<1011B0E81DP5B0E81DP5B0E811e802P49DPUB2E89DP472@0:0@VW2JL9 +Y`VW0@NW00X12:L8Y`RW2:L120P04040200800P0200800P0204T000@0@0800P0200800P020080@P8 +00X12:L8Y`RW2:L11jL02P49Y`VW2JL9Y`472@0:0@UB2E89DPUB0@MB0P403E81DP5B0E81DP5B0E80 +4`4500410@0001D000<100000P0D0@0=DP5B0E81DP5B0E81DP020@MB00X1DPUB2E89DPT11`T02P6W +2JL9Y`VW2@47Y`0:0JL8Y`RW2:L80@P80101200800P0200800P020019000404800P0200800P02008 +0048200:0JL8Y`RW2:L80@NW00X1Y`VW2JL9Y`T11`T02P5B2E89DPUB2@47DP0@0E81DP5B0E81DP5B +0E81DQ811@010@40000E00030@0000805@403U81DP5B0E81DP5B0E811e802P49DPUB2E89DP472@0: +0@VW2JL9Y`VW0@NW00X12:L8Y`RW2:L120P03`40200800P0200800P00@0V000?0@P0200800P02008 +00P100P800X12:L8Y`RW2:L11jL02P49Y`VW2JL9Y`472@0:0@UB2E89DPUB0@MB0P403E81DP5B0E81 +DP5B0E804`4500410@0001D000<100000P0F0@0;DP5B0E81DP5B0E800P48DP0:0@UB2E89DPUB0@L9 +00T12JL9Y`VW2@401jL02P6W2:L8Y`RW2048200?0@P0200800P0200800P102H0010100P0200800P0 +200800P11`P02P6W2:L8Y`RW2048Y`090@VW2JL9Y`T100L900X1DPUB2E89DPT11e803P5B0E81DP5B +0E81DP5B504500410@0001D000<100000P0E0@0>DP5B0E81DP5B0E81DP48DP0:0E89DPUB2E890@L9 +00T1Y`VW2JL9Y`401jL02P48Y`RW2:L8Y`47200?0@P0200800P0200800P102P000l100P0200800P0 +200800401`P02P48Y`RW2:L8Y`48Y`080JL9Y`VW2@472@0:0E89DPUB2E890@QB0P402e81DP5B0E81 +DP5B01D11@010@40000E00030@0000805P402e81DP5B0E81DP5B008125802P49DPUB2E89DP472@09 +0@VW2JL9Y`T100NW00X1Y`RW2:L8Y`P11`P03`40200800P0200800P00@0X000?0@P0200800P02008 +00P100L800X1Y`RW2:L8Y`P12:L02049Y`VW2JL11`T02P49DPUB2E89DP48DP0>0E81DP5B0E81DP5B +0E8D0@D00@4100005@000`40000201L100aB0E81DP5B0E81DP48DP0:0E89DPUB2E890@L900T1Y`VW +2JL9Y`401jL02P48Y`RW2:L8Y`47200?0@P0200800P0200800P102T000h1200800P0200800P00@L8 +00X12:L8Y`RW2:L12:L0206W2JL9Y`T11`T02P5B2E89DPUB2@48DP8100]B0E81DP5B0E81DP0E0@D0 +0@4100005@000`40000201P100UB0E81DP5B0E800P48DP0:0@UB2E89DPUB0@L900T12JL9Y`VW2@40 +1jL02P6W2:L8Y`RW2047200>0@0800P0200800P0204Z000>0@0800P0200800P02047200:0JL8Y`RW +2:L80@RW00P12JL9Y`VW0@L900X12E89DPUB2E812580305B0E81DP5B0E81DQH11@010@40000E0003 +0@0000805`402e81DP5B0E81DP5B00811e802P5B2E89DPUB2@472@090JL9Y`VW2JL100JW00X1Y`RW +2:L8Y`P120P03P4800P0200800P02001:P003P4800P0200800P0200120P02P6W2:L8Y`RW2047Y`08 +0JL9Y`VW2@472@0:0E89DPUB2E890@MB00h1DP5B0E81DP5B0E81DQD11@010@40000E00030@000080 +60403581DP5B0E81DP5B0@QB00T1DPUB2E89DP401`T02@49Y`VW2JL90@06Y`0:0@RW2:L8Y`RW0@P8 +00d100P0200800P0200102`000h1200800P0200800P00@L800X12:L8Y`RW2:L11jL02049Y`VW2JL1 +1`T02P49DPUB2E89DP47DP8100]B0E81DP5B0E81DP0F0@D00@4100005@000`40000201T100UB0E81 +DP5B0E800P48DP090@UB2E89DPT100L900T1Y`VW2JL9Y`401ZL02P6W2:L8Y`RW2047200>0@0800P0 +200800P0204/000>0@0800P0200800P02047200:0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900T1DPUB +2E89DP402580305B0E81DP5B0E81DQL11@010@40000=00@110000`40000201X100YB0E81DP5B0E81 +25802@5B2E89DPUB0@072@090@VW2JL9Y`T100JW00X12:L8Y`RW2:L11`P03@4800P0200800P02040 +;P003@40200800P0200800401`P02P48Y`RW2:L8Y`47Y`080@VW2JL9Y`472@090@UB2E89DPT100QB +0P402E81DP5B0E81DP0H0@D00@4100003`000`40000300810`0I0@09DP5B0E81DP5B008125802@49 +DPUB2E890@072@090JL9Y`VW2JL100JW00X1Y`RW2:L8Y`P11`P03@40200800P020080040;P003@48 +00P0200800P020401`P02P6W2:L8Y`RW2047Y`080JL9Y`VW2@472@090E89DPUB2E8100QB00`1DP5B +0E81DP5B0E8G0@@00P4100003`000`40000300030@0000806P402U81DP5B0E81DP48DP090E89DPUB +2E8100L900T12JL9Y`VW2@401ZL02P48Y`RW2:L8Y`47200=0@P0200800P020080@0^000=0@0800P0 +200800P00@07200:0@RW2:L8Y`RW0@NW00P12JL9Y`VW0@L900T12E89DPUB2@4025820@09DP5B0E81 +DP5B01P11@010@40000?00030@0000<000<100000P0I0@09DP5B0E81DP5B008125802@49DPUB2E89 +0@072@090JL9Y`VW2JL100JW00X1Y`RW2:L8Y`P11`P03P40200800P0200800P1;0003P40200800P0 +200800P11`P02P6W2:L8Y`RW2047Y`080JL9Y`VW2@472@090E89DPUB2E8100QB00`1DP5B0E81DP5B +0E8G0@D00@4100003`000`40000300030@00008060403581DP5B0E81DP5B0@QB00T1DPUB2E89DP40 +1`T02@49Y`VW2JL90@06Y`0:0@RW2:L8Y`RW0@P800d100P0200800P0200102`000h1200800P02008 +00P00@L800X12:L8Y`RW2:L11jL02049Y`VW2JL11`T02P49DPUB2E89DP47DP8100]B0E81DP5B0E81 +DP0F0@D00@4100003@030@D000<100000P0G0@0;DP5B0E81DP5B0E800P47DP0:0E89DPUB2E890@L9 +00T1Y`VW2JL9Y`401ZL02P6W2:L8Y`RW2048200>0@P0200800P02008004Z000>0@P0200800P02008 +0048200:0JL8Y`RW2:L80@NW00P1Y`VW2JL90@L900X1DPUB2E89DPT11e803P5B0E81DP5B0E81DP5B +5@4500410@0000l000<100000`000`40000201P100UB0E81DP5B0E800P48DP0:0@UB2E89DPUB0@L9 +00T12JL9Y`VW2@401jL02P6W2:L8Y`RW2047200>0@0800P0200800P0204Z000>0@0800P0200800P0 +2047200:0JL8Y`RW2:L80@RW00P12JL9Y`VW0@L900X12E89DPUB2E812580305B0E81DP5B0E81DQH1 +1@010@40000E00030@0000805`403581DP5B0E81DP5B0@QB00X1DPUB2E89DPT11`T02@6W2JL9Y`VW +0@07Y`0:0@RW2:L8Y`RW0@L800l1200800P0200800P02040:@003P4800P0200800P020011`P02P48 +Y`RW2:L8Y`48Y`080JL9Y`VW2@472@0:0E89DPUB2E890@QB0P402e81DP5B0E81DP5B01D11@010@40 +000E00030@0000805P402e81DP5B0E81DP5B008125802P49DPUB2E89DP472@090@VW2JL9Y`T100NW +00X1Y`RW2:L8Y`P11`P03`40200800P0200800P00@0X000?0@P0200800P0200800P100L800X1Y`RW +2:L8Y`P12:L02049Y`VW2JL11`T02P49DPUB2E89DP48DP0>0E81DP5B0E81DP5B0E8D0@D00@410000 +5@000`40000201D100iB0E81DP5B0E81DP5B0@QB00X1DPUB2E89DPT11`T02@6W2JL9Y`VW0@07Y`0: +0@RW2:L8Y`RW0@L800l1200800P0200800P02040:0003`40200800P0200800P00@07200:0@RW2:L8 +Y`RW0@RW00P1Y`VW2JL90@L900X1DPUB2E89DPT125820@0;DP5B0E81DP5B0E805@4500410@0001D0 +00<100000P0F0@0;DP5B0E81DP5B0E800P48DP0:0@UB2E89DPUB0@L900T12JL9Y`VW2@401jL02P6W +2:L8Y`RW2048200?0@P0200800P0200800P102H0010100P0200800P0200800P11`P02P6W2:L8Y`RW +2048Y`090@VW2JL9Y`T100L900X1DPUB2E89DPT11e803P5B0E81DP5B0E81DP5B504500410@0001D0 +00<100000P0E0@0>DP5B0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@L900X12JL9Y`VW2JL11jL02P48 +Y`RW2:L8Y`48200?0@0800P0200800P0200102H000l1200800P0200800P0204020P02P48Y`RW2:L8 +Y`47Y`0:0@VW2JL9Y`VW0@L900X12E89DPUB2E811e820@0=DP5B0E81DP5B0E81DP0C0@D00@410000 +5@000`40000201@100eB0E81DP5B0E81DP5B00811e802P5B2E89DPUB2@472@0:0JL9Y`VW2JL90@NW +00X1Y`RW2:L8Y`P120P0404800P0200800P02008004T000@0@P0200800P0200800P00@P800X1Y`RW +2:L8Y`P11jL02P6W2JL9Y`VW2@472@0:0E89DPUB2E890@MB0101DP5B0E81DP5B0E81DP5B4P450041 +0@0001D000<100000P0C0@0@DP5B0E81DP5B0E81DP5B0@MB00X12E89DPUB2E811`T02P49Y`VW2JL9 +Y`47Y`0:0@RW2:L8Y`RW0@P8010100P0200800P0200800P190004040200800P0200800P02048200: +0@RW2:L8Y`RW0@NW00X12JL9Y`VW2JL11`T02P49DPUB2E89DP47DP8100eB0E81DP5B0E81DP5B01<1 +1@010@40000E00810`0B0@0?DP5B0E81DP5B0E81DP5B00811e802P5B2E89DPUB2@472@0:0JL9Y`VW +2JL90@NW00X1Y`RW2:L8Y`P120P04@4800P0200800P0200800P10280014100P0200800P0200800P0 +0@08200:0JL8Y`RW2:L80@NW00X1Y`VW2JL9Y`T11`T02P5B2E89DPUB2@47DP0@0E81DP5B0E81DP5B +0E81DQ8110020@40000E00030@0000804@403e81DP5B0E81DP5B0E81DP020@QB00X12E89DPUB2E81 +1`T02P49Y`VW2JL9Y`48Y`0:0JL8Y`RW2:L80@L8018100P0200800P0200800P0204P000B0@0800P0 +200800P0200800P11`P02P6W2:L8Y`RW2048Y`0:0@VW2JL9Y`VW0@L900X12E89DPUB2E8125804P5B +0E81DP5B0E81DP5B0E81DPl11@010@40000E00030@00008040404U81DP5B0E81DP5B0E81DP5B0@QB +00X1DPUB2E89DPT11`T02P6W2JL9Y`VW2@48Y`0:0@RW2:L8Y`RW0@P8018100P0200800P0200800P0 +204N000C0@0800P0200800P0200800P00@07200:0@RW2:L8Y`RW0@RW00X1Y`VW2JL9Y`T11`T02`5B +2E89DPUB2E8100MB0P404E81DP5B0E81DP5B0E81DP5B00h11@010@40000E00030@0000803`404E81 +DP5B0E81DP5B0E81DP5B00811e802`5B2E89DPUB2E8100L900X12JL9Y`VW2JL12:L02P6W2:L8Y`RW +2048200C0@P0200800P0200800P020080@0L000C0@0800P0200800P0200800P00@08200:0JL8Y`RW +2:L80@RW00X12JL9Y`VW2JL11`T02`49DPUB2E89DPT100MB01@1DP5B0E81DP5B0E81DP5B0E81DPd1 +1@010@40000E00030@00008030405U81DP5B0E81DP5B0E81DP5B0E81DP47DP0;0@UB2E89DPUB2@40 +1`T02P6W2JL9Y`VW2@48Y`0:0@RW2:L8Y`RW0@P801@100P0200800P0200800P020080AX001@100P0 +200800P0200800P020080@P800X12:L8Y`RW2:L12:L02P6W2JL9Y`VW2@472@0;0E89DPUB2E89DP40 +1e820@0CDP5B0E81DP5B0E81DP5B0E81DP0<0@D00@4100005@000`40000200/101EB0E81DP5B0E81 +DP5B0E81DP5B0E800P47DP0;0E89DPUB2E89DP401`T02P49Y`VW2JL9Y`48Y`0:0JL8Y`RW2:L80@P8 +01@1200800P0200800P0200800P020815P020@0D00P0200800P0200800P020080048200:0JL8Y`RW +2:L80@RW00X12JL9Y`VW2JL11`T02`49DPUB2E89DPT100MB01P1DP5B0E81DP5B0E81DP5B0E81DP5B +0E890@D00@4100005@000`40000200X101EB0E81DP5B0E81DP5B0E81DP5B0E800P48DP0;0@UB2E89 +DPUB2@401`T02P6W2JL9Y`VW2@48Y`0:0@RW2:L8Y`RW0@T801D1200800P0200800P0200800P02000 +0P4B008101D800P0200800P0200800P0200800402@P02P48Y`RW2:L8Y`48Y`0:0JL9Y`VW2JL90@L9 +00/1DPUB2E89DPUB0@08DP0H0E81DP5B0E81DP5B0E81DP5B0E81DP5B204500410@0001D000<10000 +0P090@0EDP5B0E81DP5B0E81DP5B0E81DP5B008125802`49DPUB2E89DPT100P900X12JL9Y`VW2JL1 +2JL02P48Y`RW2:L8Y`49200F0@P0200800P0200800P0200800P020813P020@0F00P0200800P02008 +00P0200800P00@T800X12:L8Y`RW2:L12JL02P49Y`VW2JL9Y`482@0;0E89DPUB2E89DP402580605B +0E81DP5B0E81DP5B0E81DP5B0E81DPL11@010@40000E00030@0000801P405e81DP5B0E81DP5B0E81 +DP5B0E81DP5B00812E802`5B2E89DPUB2E8100P900X1Y`VW2JL9Y`T12JL02P6W2:L8Y`RW204:200G +0@P0200800P0200800P0200800P020000P4:008101L800P0200800P0200800P0200800P00@0:200: +0JL8Y`RW2:L80@VW00X1Y`VW2JL9Y`T120T02`49DPUB2E89DPT100UB01P1DP5B0E81DP5B0E81DP5B +0E81DP5B0E860@D00@4100005@000`40000200D101MB0E81DP5B0E81DP5B0E81DP5B0E81DP020@YB +00/12E89DPUB2E890@082@0:0@VW2JL9Y`VW0@VW00X12:L8Y`RW2:L12`P0604800P0200800P02008 +00P0200800P020811P020@0H00P0200800P0200800P0200800P020012`P02P48Y`RW2:L8Y`49Y`0: +0@VW2JL9Y`VW0@P900/1DPUB2E89DPUB0@0:DP0J0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E830@D0 +0@4100005@000`40000200@101MB0E81DP5B0E81DP5B0E81DP5B0E81DP020@YB00/12E89DPUB2E89 +0@092@0;0JL9Y`VW2JL9Y`402JL02P48Y`RW2:L8Y`4;200I0@P0200800P0200800P0200800P02008 +00020@800P406@P0200800P0200800P0200800P0200800402`P02P48Y`RW2:L8Y`49Y`0<0@VW2JL9 +Y`VW2JL120T02`5B2E89DPUB2E8100YB01X1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP811@010@40 +000E00030@00008001X1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP812e802`5B2E89DPUB2E8100T9 +00/12JL9Y`VW2JL90@09Y`0:0JL8Y`RW2:L80@`801X1200800P0200800P0200800P0200800P02081 +01X0200800P0200800P0200800P0200800P00@`800X1Y`RW2:L8Y`P12JL0306W2JL9Y`VW2JL90@P9 +00/12E89DPUB2E890@0;DP0J0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E820@@00@4100005@000`40 +0002000IDP5B0E81DP5B0E81DP5B0E81DP5B0E81DP020@aB00/12E89DPUB2E890@092@0;0JL9Y`VW +2JL9Y`402JL02`48Y`RW2:L8Y`P100`803@1200800P0200800P0200800P0200800P0200800P02008 +00P0200800P0200800P020013@P02P48Y`RW2:L8Y`49Y`0<0@VW2JL9Y`VW2JL12@T02`49DPUB2E89 +DPT100]B01X1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DPD00@4100005@020@<001P1DP5B0E81DP5B +0E81DP5B0E81DP5B0E820@aB00/12E89DPUB2E890@0:2@0;0@VW2JL9Y`VW2@402ZL02P48Y`RW2:L8 +Y`4<200d0@0800P0200800P0200800P0200800P0200800P0200800P0200800P0200800P020080@`8 +00X12:L8Y`RW2:L12ZL0306W2JL9Y`VW2JL90@T900/1DPUB2E89DPUB0@0200; +0@RW2:L8Y`RW20402ZL03049Y`VW2JL9Y`VW0@X900/1DPUB2E89DPUB0@0>DP0F0E81DP5B0E81DP5B +0E81DP5B0E81DPD00@4100005@000`400002000D0E81DP5B0E81DP5B0E81DP5B0E820@mB00/1DPUB +2E89DPUB0@0:2@0<0JL9Y`VW2JL9Y`T12jL02P6W2:L8Y`RW204?200/0@0800P0200800P0200800P0 +200800P0200800P0200800P0200800P0204?200:0JL8Y`RW2:L80@^W00`1Y`VW2JL9Y`VW2@4:2@0; +0@UB2E89DPUB2@403e805@5B0E81DP5B0E81DP5B0E81DP5B0@0500410@0001D000<100000P004e81 +DP5B0E81DP5B0E81DP5B0E800P4?DP0<0E89DPUB2E89DPT12PT03049Y`VW2JL9Y`VW0@^W00/12:L8 +Y`RW2:L80@0?200Z0@0800P0200800P0200800P0200800P0200800P0200800P0200800P13`P02`6W +2:L8Y`RW2:L100^W00`12JL9Y`VW2JL9Y`4;2@0;0@UB2E89DPUB2@403e80505B0E81DP5B0E81DP5B +0E81DP5B1@010@40000E00030@0000800181DP5B0E81DP5B0E81DP5B0E820A1B00`12E89DPUB2E89 +DP4:2@0<0JL9Y`VW2JL9Y`T12jL02`6W2:L8Y`RW2:L1010802P100P0200800P0200800P0200800P0 +200800P0200800P0200800P140P02`48Y`RW2:L8Y`P100^W00`1Y`VW2JL9Y`VW2@4;2@0;0E89DPUB +2E89DP4045804`5B0E81DP5B0E81DP5B0E81DP401@010@40000E00030@00008000mB0E81DP5B0E81 +DP5B0E80104@DP0<0@UB2E89DPUB2E812`T03@49Y`VW2JL9Y`VW2@402jL02`6W2:L8Y`RW2:L10108 +10407PP0200800P0200800P0200800P0200800P0200800@140P02`48Y`RW2:L8Y`P100^W00h1Y`VW +2JL9Y`VW2JL90@/900/1DPUB2E89DPUB0@0@DP<100mB0E81DP5B0E81DP5B0E801@010@40000E0003 +0@00008000P1DP5B0E81DPL14e803@49DPUB2E89DPUB2@402`T03@6W2JL9Y`VW2JL9Y`402jL03048 +Y`RW2:L8Y`RW0A<81P404P0800P0200800P0200800P020H14`P03048Y`RW2:L8Y`RW0@^W00h12JL9 +Y`VW2JL9Y`VW0@/900`12E89DPUB2E89DP4BDPL100QB0E81DP5B0@D00@4100005@000`4000020003 +DP5B00H165803P49DPUB2E89DPUB2E812`T03@49Y`VW2JL9Y`VW2@402jL03@6W2:L8Y`RW2:L8Y`40 +60P60@06200800P01P4H200=0@RW2:L8Y`RW2:L80@0;Y`0>0JL9Y`VW2JL9Y`VW2@4;2@0=0E89DPUB +2E89DPUB0@0GDPH100=B0E801@010@40000E00030@0000800`4MDP0>0@UB2E89DPUB2E89DP4<2@0= +0JL9Y`VW2JL9Y`VW0@00@RW2:L8Y`RW2:L8 +Y`P20CP80P403ZL8Y`RW2:L8Y`RW2:L13JL03P49Y`VW2JL9Y`VW2JL13@T03P49DPUB2E89DPUB2E89 +0P4KDP@00P4100005@000`40000201UB0`4040UB2E89DPUB2E89DPUB2@4=2@0?0JL9Y`VW2JL9Y`VW +2JL100fW00l12:L8Y`RW2:L8Y`RW2:L00`4b20<100l8Y`RW2:L8Y`RW2:L8Y`403JL04049Y`VW2JL9 +Y`VW2JL9Y`4=2@0?0@UB2E89DPUB2E89DPUB00<1658500410@0001D000<100000P0FDP<10189DPUB +2E89DPUB2E89DPUB2@4>2@0?0@VW2JL9Y`VW2JL9Y`T100jW01412:L8Y`RW2:L8Y`RW2:L8Y`030B`8 +0`404@RW2:L8Y`RW2:L8Y`RW2:L100jW0101Y`VW2JL9Y`VW2JL9Y`T13PT04@49DPUB2E89DPUB2E89 +DPUB00<15E8500410@0001D000<100000P0DDP810189DPUB2E89DPUB2E89DPUB2E820@l900l1Y`VW +2JL9Y`VW2JL9Y`403jL04`48Y`RW2:L8Y`RW2:L8Y`RW2:L00P4X208101<8Y`RW2:L8Y`RW2:L8Y`RW +2:L100nW01012JL9Y`VW2JL9Y`VW2JL13`T04`49DPUB2E89DPUB2E89DPUB2E800P4CDPD00@410000 +5@000`40000200iB1P405589DPUB2E89DPUB2E89DPUB2E8140T04@6W2JL9Y`VW2JL9Y`VW2JL100nW +01@12:L8Y`RW2:L8Y`RW2:L8Y`RW20H170P60@0DY`RW2:L8Y`RW2:L8Y`RW2:L8Y`4?Y`0B0@VW2JL9 +Y`VW2JL9Y`VW2JL13`T05049DPUB2E89DPUB2E89DPUB2E891P4=DPD00@4100005@000`40000200EB +2@406@UB2E89DPUB2E89DPUB2E89DPUB2E89DP404@T04@49Y`VW2JL9Y`VW2JL9Y`T1012W01T12:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW00X12@P90@0I2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@0@Y`0B +0JL9Y`VW2JL9Y`VW2JL9Y`T140T06@49DPUB2E89DPUB2E89DPUB2E89DPUB2E802@44DPD00@410000 +5@000`40000200D10249DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP404PT04@6W2JL9Y`VW +2JL9Y`VW2JL1016W02812:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L82@408@RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW0@0AY`0B0@VW2JL9Y`VW2JL9Y`VW2JL14@T08@49DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP050@@00@4100005@000`400002000S2E89DPUB2E89DPUB +2E89DPUB2E89DPUB2E89DPUB2E89DPT00P4B2@0C0JL9Y`VW2JL9Y`VW2JL9Y`VW0@0AY`8104JW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L80P4AY`0D0@VW2JL9Y`VW2JL9Y`VW2JL9Y`4A2@81029B2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E891@010@40000E00030@000080021B2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2@<150T04`49Y`VW2JL9Y`VW2JL9Y`VW2@404jL30@10Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20<14jL0506W2JL9Y`VW2JL9Y`VW +2JL9Y`T14`T30@0ODPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP0500410@0001D000<10000 +0P007@UB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E8900<15PT05@49Y`VW2JL9Y`VW2JL9Y`VW2JL9 +0@0EY`<103ZW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L80`4EY`0F0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90AD90`407589DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPT500410@0001D000<100000P006U89DPUB2E89DPUB2E89DPUB2E89DPUB2E890`4H2@0G +0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@405jL30@0dY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20<15jL0606W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90AL90`406E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E801@010@40000E00030@00008001L9DPUB2E89DPUB2E89DPUB +2E89DPUB2@030AX901T12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T101VW0`40;ZL8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P30AVW01X1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL90AT90`405U89DPUB2E89DPUB2E89DPUB2E89DPT500410@0001D000<100000P005589DPUB2E89 +DPUB2E89DPUB2E890`4L2@0K0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T101^W0`40::L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P30A^W01`1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`T16`T30@0CDPUB2E89DPUB2E89DPUB2E89DP0500410@0001D00P4300092E89DPUB2E8900/1 +7PT07049Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4NY`/101:W2:L8Y`RW2:L8Y`RW2:L8Y`P;0AjW +01`12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL17PT:0@092E89DPUB2E8900@00P4100005@000`40 +000200T1:0T07P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0BRW4P4XY`0N0@VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL19`T:0@@00@4100005@000`400002030902012JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW0F2W02012JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0Bl91@010@40 +000E00030@000080;`T08P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`5NY`0R0@VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0Bh91@010@40000E00030@000080;@T20@0R2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`81FZL20@0R2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`81;0T500410@0001D000<100000P0Y2@@102JW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2@<1DjL40@0VY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`T30BT91@010@40000E00030@0000809PT30@0]2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL900@1C:L30@0]2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL900@19@T500410@0001D000<100000P0P2@H103@9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW1P50Y`H103@9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW1P4O2@D00@4100005@000`40000201L92@40@:L9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`T90BjW2@40@:L9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`T90AH91@010@40000E00030@0000805`40DZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`T^0@1BY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2AL110010@40000E00030@0000800?nW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL01@010@40000E00030@0000800?l9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T01@010@4000000`010@020@<0 +00<100000P030@D000<100000P00ojL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`0500410@0000<000<100002P000`40 +000200810`00o`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@0400810@0000<000<100002P000`40000200030@000080 +0?nW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL01@010@40000300030@0000L00`4500030@0000800?l9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`T01@010@40000300030@0000L000<100001@000`400002003oY`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW00D0 +0@41000000@00@412@000`40000500030@0000805`40DZL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T^0@1B +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2AL110010@40000300030@0000L0104400030@0000805jL90@10 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2@T1;PT90@10Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2@T15ZL500410@0001D000<100000P0PY`H103@9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW1P502@H103@9Y`VW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW1P4OY`D00@4100005@000`40000202JW +0`40;@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@040D`90`40;@VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@040BFW1@010@40000E0003 +0@000080:JL40@0VY`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T30E<910409ZL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90`4YY`D00@4100005@000`40000202fW +0P408PVW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL20EX90P408PVW2JL9Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL20BbW1@010@40000E00030@000080;jL08P49Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`5N2@0R0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW0BjW +1@010@40000E00030@000080<:L08049Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1H0T08049 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL1;jL500410@0001D000<100000P090BRW01h12JL9 +Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`4X2A81:0T07P49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW0BNW2P4400410@0001D00P4300092:L8Y`RW2:L800/17ZL07049Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL9Y`4N2@/1019B2E89DPUB2E89DPUB2E89DPT;0Ah901`12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9 +Y`VW2JL17ZL:0@092:L8Y`RW2:L800@00P4100005@000`400002000DY`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`P30AbW01/12JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@406`T30@0XDPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2@<16`T0706W2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2@4KY`<1 +01>W2:L8Y`RW2:L8Y`RW2:L8Y`RW00D00@4100005@000`400002000G2:L8Y`RW2:L8Y`RW2:L8Y`RW +2:L8Y`P00`4JY`0I0@VW2JL9Y`VW2JL9Y`VW2JL9Y`VW2JL90@0I2@<102iB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E890`4I2@0J0JL9Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`VW +2@4IY`<101JW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L81@010@40000E00030@00008001ZW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW20<16:L05`49Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T101L90`40=589DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT30AL901P1Y`VW2JL9Y`VW +2JL9Y`VW2JL9Y`VW2@4GY`<101VW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW00D00@4100005@000`40 +0002000M2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P00`4FY`0E0@VW2JL9Y`VW2JL9Y`VW2JL9 +Y`T101D90`40>U89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPT30AD901H1Y`VW2JL9Y`VW2JL9Y`VW2JL9Y`T15JL30@0LY`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW20D00@4100005@000`400002000PY`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8 +Y`P30ABW01<12JL9Y`VW2JL9Y`VW2JL9Y`T101<90`40@589DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPT30A<901@1Y`VW2JL9Y`VW2JL9Y`VW +2JL90A>W0`407jL8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L01@010@40000E00030@000080 +02<8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW20020A:W01<1Y`VW2JL9Y`VW2JL9Y`VW +2JL101490P40AU89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPT20A4901@12JL9Y`VW2JL9Y`VW2JL9Y`VW0A6W0P408ZL8Y`RW2:L8 +Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`P500410@0001D000<100000P050@0Q2:L8Y`RW2:L8Y`RW +2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L101:W0141Y`VW2JL9Y`VW2JL9Y`VW0@0A2@0R0@UB2E89DPUB2E89 +DPUB2E89DPUB2E89DPUB2E89DPUB2@T10249DPUB2E89DPUB2E89DPUB2E89DPUB2E89DPUB2E89DP40 +4@T04P49Y`VW2JL9Y`VW2JL9Y`VW0A6W02412:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L0 +1@4400410@0001D000<100000P0520T101T8Y`RW2:L8Y`RW2:L8Y`RW2:L8Y`RW2:L1016W01412JL9 +Y`VW2JL9Y`VW2JL90@0@2@0I0@UB2E89DPUB2E89DPUB2E89DPUB2E89DP0:0@UB2@406@UB2E89DPUB +2E89DPUB2E89DPUB2E89DP4040T04P6W2JL9Y`VW2JL9Y`VW2JL90A2W01T12:L8Y`RW2:L8Y`RW2:L8 +Y`RW2:L8Y`RW00T110P500410@0001D000<100000P0>20H101BW2:L8Y`RW2:L8Y`RW2:L8Y`RW0A2W +0141Y`VW2JL9Y`VW2JL9Y`VW0@0?2@0D0@UB2E89DPUB2E89DPUB2E89DPT60AaB1P405589DPUB2E89 +DPUB2E89DPUB2E813`T04P49Y`VW2JL9Y`VW2JL9Y`VW0@nW01@12:L8Y`RW2:L8Y`RW2:L8Y`RW20H1 +3@P500410@0001D000<100000P0D20810188Y`RW2:L8Y`RW2:L8Y`RW2:L20@nW00l1Y`VW2JL9Y`VW +2JL9Y`403`T04`49DPUB2E89DPUB2E89DPUB2E800P4XDP8101<9DPUB2E89DPUB2E89DPUB2E8100l9 +01012JL9Y`VW2JL9Y`VW2JL13jL04`48Y`RW2:L8Y`RW2:L8Y`RW2:L00P4C20D00@4100005@000`40 +000201H80`404PRW2:L8Y`RW2:L8Y`RW2:L80@jW00l12JL9Y`VW2JL9Y`VW2@403PT04@49DPUB2E89 +DPUB2E89DPUB00<1;5830@0A2E89DPUB2E89DPUB2E89DP403PT0406W2JL9Y`VW2JL9Y`VW2@4>Y`0A +0@RW2:L8Y`RW2:L8Y`RW2:L00`4E20D00@4100005@000`40000201T80`4040RW2:L8Y`RW2:L8Y`RW +204=Y`0?0JL9Y`VW2JL9Y`VW2JL100d900l12E89DPUB2E89DPUB2E800`4bDP<100l9DPUB2E89DPUB +2E89DP403@T04049Y`VW2JL9Y`VW2JL9Y`4=Y`0?0@RW2:L8Y`RW2:L8Y`RW00<160P500410@0001D0 +0P4301`80P403jL8Y`RW2:L8Y`RW2:L80@0=Y`0=0JL9Y`VW2JL9Y`VW0@0=2@0>0@UB2E89DPUB2E89 +DPT20CQB0P403U89DPUB2E89DPUB2E813@T03P49Y`VW2JL9Y`VW2JL13JL03P48Y`RW2:L8Y`RW2:L8 +0P4K20@00P4100005@000`40000201h80P403PRW2:L8Y`RW2:L8Y`P13:L03@49Y`VW2JL9Y`VW2@40 +30T03@49DPUB2E89DPUB2E800P4lDP8100d9DPUB2E89DPUB2E8100`900h1Y`VW2JL9Y`VW2JL90@bW +00d12:L8Y`RW2:L8Y`RW00817@P500410@0001D000<100000P030Ad800h12:L8Y`RW2:L8Y`RW0@bW +00d1Y`VW2JL9Y`VW2JL100`900d1DPUB2E89DPUB2E8101eB1P4MDP0=0@UB2E89DPUB2E890@0<2@0> +0@VW2JL9Y`VW2JL9Y`40@RW2:L8Y`RW2:L8Y`4;Y`0=0@VW2JL9Y`VW2JL90@0;2@0=0E89DPUB2E89DPUB0@0HDPL1 +00EB0E81DP060AQB00d12E89DPUB2E89DPT100/900h1Y`VW2JL9Y`VW2JL90@^W00d1Y`RW2:L8Y`RW +2:L101L81P400`08000500410@0001D000<100000P002@P0200800P020060A<800d12:L8Y`RW2:L8 +Y`P100^W00d1Y`VW2JL9Y`VW2JL100/900`12E89DPUB2E89DP4CDPH1015B0E81DP5B0E81DP5B0E81 +DP070A=B00`12E89DPUB2E89DP4;2@0>0@VW2JL9Y`VW2JL9Y`4;Y`0<0@RW2:L8Y`RW2:L14PP60@09 +200800P0200800D00@4100005@000`400003000>200800P0200800P020040A0800`12:L8Y`RW2:L8 +Y`4;Y`0=0@VW2JL9Y`VW2JL90@0;2@0;0E89DPUB2E89DP4045850@0MDP5B0E81DP5B0E81DP5B0E81 +DP5B0E81DP5B0E80104@DP0;0@UB2E89DPUB2@402`T03P6W2JL9Y`VW2JL9Y`T12jL02`6W2:L8Y`RW +2:L101080`403P0800P0200800P020081P010@40000E00030@00008001@800P0200800P0200800P0 +20080A0800`12:L8Y`RW2:L8Y`4:Y`0<0JL9Y`VW2JL9Y`T12`T02`5B2E89DPUB2E81011B02H1DP5B +0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP8145802`49DPUB2E89DPT100/900`1Y`VW +2JL9Y`VW2@4;Y`0;0JL8Y`RW2:L8Y`4040P04`40200800P0200800P0200800P01@010@40000E0003 +0@0000<001@800P0200800P0200800P020080@l800`1Y`RW2:L8Y`RW204:Y`0<0@VW2JL9Y`VW2JL1 +2`T02`49DPUB2E89DPT100mB02P1DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B +0P4?DP0;0E89DPUB2E89DP402`T03049Y`VW2JL9Y`VW0@^W00/12:L8Y`RW2:L80@0?200C0@0800P0 +200800P0200800P0200600410@0001D000<100000P005PP0200800P0200800P0200800P0204?200; +0JL8Y`RW2:L8Y`402ZL0306W2JL9Y`VW2JL90@/900X1DPUB2E89DPT13e80:P5B0E81DP5B0E81DP5B +0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP813e802P5B2E89DPUB2@4;2@0<0JL9Y`VW2JL9Y`T1 +2ZL02`48Y`RW2:L8Y`P100l801D100P0200800P0200800P0200800P01@010@40000E00030@0000<0 +01H800P0200800P0200800P0200800P13PP03048Y`RW2:L8Y`RW0@VW00`12JL9Y`VW2JL9Y`4:2@0; +0E89DPUB2E89DP403U80;05B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B +0P4>DP0;0@UB2E89DPUB2@402PT03049Y`VW2JL9Y`VW0@ZW00/1Y`RW2:L8Y`RW0@0>200E0@0800P0 +200800P0200800P0200800H00@4100005@000`400002000H200800P0200800P0200800P0200800P1 +3@P0306W2:L8Y`RW2:L80@VW00`1Y`VW2JL9Y`VW2@4:2@0;0@UB2E89DPUB2@403E80;P5B0E81DP5B +0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E820@eB00/1DPUB2E89DPUB0@0:2@0< +0JL9Y`VW2JL9Y`T12ZL02`48Y`RW2:L8Y`P100d801L100P0200800P0200800P0200800P020050041 +0@0001D000<100000`0060P0200800P0200800P0200800P020080@d800/1Y`RW2:L8Y`RW0@0:Y`0; +0JL9Y`VW2JL9Y`402PT02P5B2E89DPUB2@4=DP0`0E81DP5B0E81DP5B0E81DP5B0E81DP5B0E81DP5B +0E81DP5B0E81DP5B0E81DP5B0P4=DP0:0E89DPUB2E890@X900`12JL9Y`VW2JL9Y`49Y`0;0@RW2:L8 +Y`RW20403@P05`40200800P0200800P0200800P0200800H00@4100005@020@<001X800P0200800P0 +200800P0200800P020080@`800/12:L8Y`RW2:L80@0:Y`0;0@VW2JL9Y`VW2@402PT02P49DPUB2E89 +DP4DP5B0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@P900P1Y`VW2JL90@NW00X1Y`RW +2:L8Y`P120P0404800P0200800P02008004G00410@0001D000<100005P003`4800P0200800P02008 +0@08200:0@RW2:L8Y`RW0@NW00T12JL9Y`VW2@401`T02P5B2E89DPUB2@47DP0>0E81DP5B0E81DP5B +0E8[0@0;DP5B0E81DP5B0E800P47DP0:0E89DPUB2E890@P900P12JL9Y`VW0@NW00X12:L8Y`RW2:L1 +20P04040200800P0200800P0204G00410@0001D000<100005P003`40200800P0200800P00@08200: +0JL8Y`RW2:L80@NW00T1Y`VW2JL9Y`401`T02P49DPUB2E89DP47DP8100]B0E81DP5B0E81DP0[0@0> +DP5B0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@P900P1Y`VW2JL90@NW00X1Y`RW2:L8Y`P120P03`48 +00P0200800P020080@0H00410@0001D000<100005`003P40200800P0200800P120P02P48Y`RW2:L8 +Y`47Y`090@VW2JL9Y`T100L900X1DPUB2E89DPT11e803P5B0E81DP5B0E81DP5B:`402e81DP5B0E81 +DP5B00811e802P5B2E89DPUB2@482@080@VW2JL9Y`47Y`0:0@RW2:L8Y`RW0@P800l100P0200800P0 +2008004060010@40000E00030@0001P000h100P0200800P020080@L800X1Y`RW2:L8Y`P11jL02@6W +2JL9Y`VW0@062@0:0E89DPUB2E890@QB0P402e81DP5B0E81DP5B02d100aB0E81DP5B0E81DP48DP0: +0E89DPUB2E890@L900P1Y`VW2JL90@NW00X1Y`RW2:L8Y`P11`P03`40200800P0200800P00@0I0041 +0@0001D000<1000060003P4800P0200800P0200120P02@6W2:L8Y`RW0@07Y`090@VW2JL9Y`T100H9 +00X12E89DPUB2E812580305B0E81DP5B0E81DRl100aB0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@L9 +00P12JL9Y`VW0@NW00X12:L8Y`RW2:L11`P03`4800P0200800P020080@0I00410@0001D000<10000 +6@003@4800P0200800P0204020P02@48Y`RW2:L80@07Y`090JL9Y`VW2JL100H900X1DPUB2E89DPT1 +1e80305B0E81DP5B0E81DRl100]B0E81DP5B0E81DP020@MB00X1DPUB2E89DPT11`T0206W2JL9Y`T1 +1jL02@6W2:L8Y`RW0@08200>0@0800P0200800P0204J00410@0000d0104400030@0001T000d100P0 +200800P0200100P800T1Y`RW2:L8Y`401jL02@49Y`VW2JL90@062@0:0@UB2E89DPUB0@MB0P402e81 +DP5B0E81DP5B02l100aB0E81DP5B0E81DP47DP0:0@UB2E89DPUB0@L900P12JL9Y`VW0@NW00T12:L8 +Y`RW204020P03P4800P0200800P020016P010@40000=00030@0000D00P4K000<0@0800P0200800P1 +20P02@48Y`RW2:L80@07Y`090JL9Y`VW2JL100H900X1DPUB2E89DPT11e80305B0E81DP5B0E81DS41 +00UB0E81DP5B0E800P47DP0:0E89DPUB2E890@L900P1Y`VW2JL90@NW00T1Y`RW2:L8Y`4020P03@40 +200800P0200800406P020@40000>00030@0000@000<10000o`0700410@0000l000<100000`000`40 +003o00L00@41000040000`40000200030@00008000<10000?@000`40000m00030@0003`000<10000 +?@000`40000200410@0000d000@1000110000`40000200030@0000X000<100002@000`40000:0003 +0@0000X000<100002P000`40000:00030@0000T000<100002P000`40000:00030@0000X000<10000 +2@000`40000:00030@0000X000<100002P000`40000900030@0000X000<100002P000`40000:0003 +0@0000X000<100002@000`40000200410@0000h00P450?l12`410000o`0Q0000o`0Q0000o`0Q0000 +o`0Q0000\ +\>"], + ImageRangeCache->{{{0, 287}, {287, 0}} -> {-0.207, -0.172242, 0.00783272, + 0.00783272}}], + +Cell[BoxData[ + TagBox[\(\[SkeletonIndicator] ContourGraphics \[SkeletonIndicator]\), + False, + Editable->False]], "Output"] +}, Open ]] +}, Open ]] +}, Open ]] +}, +FrontEndVersion->"X 3.0", +ScreenRectangle->{{0, 1280}, {0, 1024}}, +WindowSize->{520, 600}, +WindowMargins->{{296, Automatic}, {Automatic, 88}}, +PrintingPageRange->{Automatic, Automatic}, +PrintingOptions->{"PaperSize"->{612, 792}, +"PaperOrientation"->"Portrait", +"Magnification"->1} +] + + +(*********************************************************************** +Cached data follows. If you edit this Notebook file directly, not using +Mathematica, you must remove the line containing CacheID at the top of +the file. The cache data will then be recreated when you save this file +from within Mathematica. +***********************************************************************) + +(*CellTagsOutline +CellTagsIndex->{} +*) + +(*CellTagsIndex +CellTagsIndex->{} +*) + +(*NotebookFileOutline +Notebook[{ + +Cell[CellGroupData[{ +Cell[1731, 51, 142, 4, 90, "Title"], + +Cell[CellGroupData[{ +Cell[1898, 59, 62, 0, 47, "Section"], + +Cell[CellGroupData[{ +Cell[1985, 63, 97, 2, 27, "Input"], +Cell[2085, 67, 102, 2, 37, "Output"] +}, Open ]], + +Cell[CellGroupData[{ +Cell[2224, 74, 89, 1, 27, "Input"], +Cell[2316, 77, 97, 2, 37, "Output"] +}, Open ]], + +Cell[CellGroupData[{ +Cell[2450, 84, 131, 3, 27, "Input"], +Cell[2584, 89, 125, 2, 47, "Output"] +}, Open ]], + +Cell[CellGroupData[{ +Cell[2746, 96, 89, 1, 27, "Input"], +Cell[2838, 99, 93, 1, 37, "Output"] +}, Open ]] +}, Open ]], + +Cell[CellGroupData[{ +Cell[2980, 106, 44, 0, 47, "Section"], + +Cell[CellGroupData[{ +Cell[3049, 110, 63, 1, 27, "Input"], +Cell[3115, 113, 38, 1, 27, "Output"] +}, Open ]], + +Cell[CellGroupData[{ +Cell[3190, 119, 173, 4, 43, "Input"], +Cell[3366, 125, 38, 1, 27, "Output"] +}, Open ]], + +Cell[CellGroupData[{ +Cell[3441, 131, 173, 4, 43, "Input"], +Cell[3617, 137, 38, 1, 27, "Output"] +}, Open ]], + +Cell[CellGroupData[{ +Cell[3692, 143, 145, 3, 43, "Input"], +Cell[3840, 148, 38, 1, 27, "Output"] +}, Open ]], + +Cell[CellGroupData[{ +Cell[3915, 154, 42, 1, 27, "Input"], +Cell[3960, 157, 35, 1, 27, "Output"] +}, Open ]], + +Cell[CellGroupData[{ +Cell[4032, 163, 71, 1, 27, "Input"], +Cell[4106, 166, 84568, 2080, 296, 16552, 1236, "GraphicsData", +"PostScript", "Graphics"], +Cell[88677, 2248, 137, 3, 27, "Output"] +}, Open ]], + +Cell[CellGroupData[{ +Cell[88851, 2256, 71, 1, 27, "Input"], +Cell[88925, 2259, 84885, 2084, 296, 16553, 1236, "GraphicsData", +"PostScript", "Graphics"], +Cell[173813, 4345, 137, 3, 27, "Output"] +}, Open ]], + +Cell[CellGroupData[{ +Cell[173987, 4353, 71, 1, 27, "Input"], +Cell[174061, 4356, 98250, 2756, 296, 24357, 1839, "GraphicsData", +"PostScript", "Graphics"], +Cell[272314, 7114, 137, 3, 27, "Output"] +}, Open ]], + +Cell[CellGroupData[{ +Cell[272488, 7122, 71, 1, 27, "Input"], +Cell[272562, 7125, 85515, 2207, 296, 17717, 1365, "GraphicsData", +"PostScript", "Graphics"], +Cell[358080, 9334, 137, 3, 27, "Output"] +}, Open ]] +}, Open ]] +}, Open ]] +} +] +*) + + + + +(*********************************************************************** +End of Mathematica Notebook file. +***********************************************************************) + diff --git a/Tutorials_profiling/TaylorGreen/benchmarks/ExSoln_3dIncNS.nb b/Tutorials_profiling/TaylorGreen/benchmarks/ExSoln_3dIncNS.nb index d525c538..0d972666 100644 --- a/Tutorials_profiling/TaylorGreen/benchmarks/ExSoln_3dIncNS.nb +++ b/Tutorials_profiling/TaylorGreen/benchmarks/ExSoln_3dIncNS.nb @@ -1,264 +1,264 @@ -(*********************************************************************** - - Mathematica-Compatible Notebook - -This notebook can be used on any computer system with Mathematica 3.0, -MathReader 3.0, or any compatible application. The data for the notebook -starts with the line of stars above. - -To get the notebook into a Mathematica-compatible application, do one of -the following: - -* Save the data starting with the line of stars above into a file - with a name ending in .nb, then open the file inside the application; - -* Copy the data starting with the line of stars above to the - clipboard, then use the Paste menu command inside the application. - -Data for notebooks contains only printable 7-bit ASCII and can be -sent directly in email or through ftp in text mode. Newlines can be -CR, LF or CRLF (Unix, Macintosh or MS-DOS style). - -NOTE: If you modify the data for this notebook not in a Mathematica- -compatible application, you must delete the line below containing the -word CacheID, otherwise Mathematica-compatible applications may try to -use invalid cache data. - -For more information on notebooks and Mathematica-compatible -applications, contact Wolfram Research: - web: http://www.wolfram.com - email: info@wolfram.com - phone: +1-217-398-0700 (U.S.) - -Notebook reader applications are available free of charge from -Wolfram Research. -***********************************************************************) - -(*CacheID: 232*) - - -(*NotebookFileLineBreakTest -NotebookFileLineBreakTest*) -(*NotebookOptionsPosition[ 4973, 183]*) -(*NotebookOutlinePosition[ 5749, 210]*) -(* CellTagsIndexPosition[ 5705, 206]*) -(*WindowFrame->Normal*) - - - -Notebook[{ - -Cell[CellGroupData[{ -Cell["\<\ -Evaluation of a 3-d Exact Solution for the Viscous, Incompressible \ -Navier-Stokes Equations\ -\>", "Title", - TextAlignment->Center], - -Cell[CellGroupData[{ - -Cell["Define Velocity, Pressure and Scalar Fields", "Section"], - -Cell[BoxData[ - \(u\ = \ - \(-a\)\ \(( - Exp[a\ x]\ Sin[a\ y\ + \ d\ z]\ + \ - Exp[a\ z]\ Cos[a\ x\ + \ d\ y])\)\ Exp[\(-d^2\)\ nu\ t]\)], - "Input"], - -Cell[BoxData[ - \(v\ = \ - \(-a\)\ \((\ - Exp[a\ y] Sin[a\ z\ + \ d\ x]\ + \ - Exp[a\ x]\ Cos[a\ y\ + \ d\ z])\)\ Exp[\(-d^2\)\ nu\ t]\)], - "Input"], - -Cell[BoxData[ - \(w\ = \ - \(-a\)\ \((\ - Exp[a\ z]\ Sin[a\ x\ + \ d\ y]\ + \ - Exp[a\ y]\ Cos[a\ z\ + \ d\ x])\)\ Exp[\(-d^2\)\ nu\ t]\)], - "Input"], - -Cell[BoxData[ - \(p\ = \ - \(-a^2\)/2\ - \((Exp[2\ a\ x]\ + \ Exp[2\ a\ y]\ + \ Exp[2\ a\ z]\ + \ - 2\ Sin[a\ x\ + \ d\ y]\ Cos[a\ z\ + \ d\ x]\ - Exp[a\ \((y\ + \ z)\)]\ + \ - 2\ Sin[a\ y\ + \ d\ z]\ Cos[a\ x\ + \ d\ y]\ - Exp[a\ \((z\ + \ x)\)]\ + \ - 2\ Sin[a\ z\ + \ d\ x]\ Cos[a\ y\ + \ d\ z]\ - Exp[a\ \((x\ + \ y)\)])\)\ Exp[\(-2\)\ d^2\ nu\ t]\)], "Input"], - -Cell[BoxData[ - \(Y\ = \ \.18\)], "Input"] -}, Open ]], - -Cell[CellGroupData[{ - -Cell["Check Governing Equations", "Section"], - -Cell[BoxData[ - \(Simplify[D[u, x]\ + \ D[v, y]\ + \ D[w, z]\ == \ 0]\)], "Input"], - -Cell[BoxData[ - \(Simplify[ - D[u, t]\ + \ u\ D[u, x]\ + \ v\ D[u, y]\ + \ w\ D[u, z]\ == \ - \(-\ D[p, x]\)\ + \ nu\ D[u, {x, 2}] + \ nu\ D[u, {y, 2}]\ + \ - nu\ D[u, {z, 2}]]\)], "Input"], - -Cell[BoxData[ - \(Simplify[ - D[v, t]\ + \ u\ D[v, x]\ + \ v\ D[v, y]\ + \ w\ D[v, z]\ == \ - \(-\ D[p, y]\)\ + \ nu\ D[v, {x, 2}] + \ nu\ D[v, {y, 2}]\ + \ - nu\ D[v, {z, 2}]]\)], "Input"], - -Cell[BoxData[ - \(Simplify[ - D[w, t]\ + \ u\ D[w, x]\ + \ v\ D[w, y]\ + \ w\ D[w, z]\ == \ - \(-\ D[p, z]\)\ + \ nu\ D[w, {x, 2}] + \ nu\ D[w, {y, 2}]\ + \ - nu\ D[w, {z, 2}]]\)], "Input"], - -Cell[BoxData[ - \(Simplify[ - D[Y, t]\ + \ u\ D[Y, x]\ + \ v\ D[Y, y]\ + \ w\ D[Y, z]\ == \ - d\ D[Y, {x, 2}]\ + \ d\ D[Y, {y, 2}]\ + \ d\ D[Y, {z, 2}]]\)], - "Input"] -}, Open ]], - -Cell[CellGroupData[{ - -Cell["Evaluate the Fields for a=Pi, d=Pi", "Section"], - -Cell[BoxData[ - \(a\ = \ Pi\)], "Input"], - -Cell[BoxData[ - \(d\ = \ Pi\)], "Input"], - -Cell[BoxData[ - \(u\)], "Input"], - -Cell[BoxData[ - \(v\)], "Input"], - -Cell[BoxData[ - \(w\)], "Input"], - -Cell[BoxData[ - \(p\)], "Input"], - -Cell[BoxData[ - \(t\ = \ 0\)], "Input"], - -Cell[BoxData[ - \(z\ = \ 0\)], "Input"], - -Cell[BoxData[ - \(Remove[a]\)], "Input"], - -Cell[BoxData[ - \(Remove[d]\)], "Input"], - -Cell[BoxData[ - \(Remove[z]\)], "Input"], - -Cell[BoxData[ - \(Remove[t]\)], "Input"], - -Cell[BoxData[ - \(ContourPlot[u, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"], - -Cell[BoxData[ - \(ContourPlot[v, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"], - -Cell[BoxData[ - \(ContourPlot[p, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"], - -Cell[BoxData[ - \(ContourPlot[Y, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"] -}, Open ]] -}, Open ]] -}, -FrontEndVersion->"X 3.0", -ScreenRectangle->{{0, 1280}, {0, 1024}}, -WindowSize->{520, 600}, -WindowMargins->{{296, Automatic}, {Automatic, 88}}, -PrintingPageRange->{Automatic, Automatic}, -PrintingOptions->{"PaperSize"->{612, 792}, -"PaperOrientation"->"Portrait", -"Magnification"->1} -] - - -(*********************************************************************** -Cached data follows. If you edit this Notebook file directly, not using -Mathematica, you must remove the line containing CacheID at the top of -the file. The cache data will then be recreated when you save this file -from within Mathematica. -***********************************************************************) - -(*CellTagsOutline -CellTagsIndex->{} -*) - -(*CellTagsIndex -CellTagsIndex->{} -*) - -(*NotebookFileOutline -Notebook[{ - -Cell[CellGroupData[{ -Cell[1731, 51, 142, 4, 90, "Title"], - -Cell[CellGroupData[{ -Cell[1898, 59, 62, 0, 47, "Section"], -Cell[1963, 61, 180, 5, 43, "Input"], -Cell[2146, 68, 181, 5, 43, "Input"], -Cell[2330, 75, 182, 5, 43, "Input"], -Cell[2515, 82, 465, 9, 91, "Input"], -Cell[2983, 93, 45, 1, 27, "Input"] -}, Open ]], - -Cell[CellGroupData[{ -Cell[3065, 99, 44, 0, 47, "Section"], -Cell[3112, 101, 87, 1, 27, "Input"], -Cell[3202, 104, 217, 4, 43, "Input"], -Cell[3422, 110, 217, 4, 43, "Input"], -Cell[3642, 116, 217, 4, 43, "Input"], -Cell[3862, 122, 187, 4, 43, "Input"] -}, Open ]], - -Cell[CellGroupData[{ -Cell[4086, 131, 53, 0, 47, "Section"], -Cell[4142, 133, 43, 1, 27, "Input"], -Cell[4188, 136, 43, 1, 27, "Input"], -Cell[4234, 139, 34, 1, 27, "Input"], -Cell[4271, 142, 34, 1, 27, "Input"], -Cell[4308, 145, 34, 1, 27, "Input"], -Cell[4345, 148, 34, 1, 27, "Input"], -Cell[4382, 151, 42, 1, 27, "Input"], -Cell[4427, 154, 42, 1, 27, "Input"], -Cell[4472, 157, 42, 1, 27, "Input"], -Cell[4517, 160, 42, 1, 27, "Input"], -Cell[4562, 163, 42, 1, 27, "Input"], -Cell[4607, 166, 42, 1, 27, "Input"], -Cell[4652, 169, 71, 1, 27, "Input"], -Cell[4726, 172, 71, 1, 27, "Input"], -Cell[4800, 175, 71, 1, 27, "Input"], -Cell[4874, 178, 71, 1, 27, "Input"] -}, Open ]] -}, Open ]] -} -] -*) - - - - -(*********************************************************************** -End of Mathematica Notebook file. -***********************************************************************) - +(*********************************************************************** + + Mathematica-Compatible Notebook + +This notebook can be used on any computer system with Mathematica 3.0, +MathReader 3.0, or any compatible application. The data for the notebook +starts with the line of stars above. + +To get the notebook into a Mathematica-compatible application, do one of +the following: + +* Save the data starting with the line of stars above into a file + with a name ending in .nb, then open the file inside the application; + +* Copy the data starting with the line of stars above to the + clipboard, then use the Paste menu command inside the application. + +Data for notebooks contains only printable 7-bit ASCII and can be +sent directly in email or through ftp in text mode. Newlines can be +CR, LF or CRLF (Unix, Macintosh or MS-DOS style). + +NOTE: If you modify the data for this notebook not in a Mathematica- +compatible application, you must delete the line below containing the +word CacheID, otherwise Mathematica-compatible applications may try to +use invalid cache data. + +For more information on notebooks and Mathematica-compatible +applications, contact Wolfram Research: + web: http://www.wolfram.com + email: info@wolfram.com + phone: +1-217-398-0700 (U.S.) + +Notebook reader applications are available free of charge from +Wolfram Research. +***********************************************************************) + +(*CacheID: 232*) + + +(*NotebookFileLineBreakTest +NotebookFileLineBreakTest*) +(*NotebookOptionsPosition[ 4973, 183]*) +(*NotebookOutlinePosition[ 5749, 210]*) +(* CellTagsIndexPosition[ 5705, 206]*) +(*WindowFrame->Normal*) + + + +Notebook[{ + +Cell[CellGroupData[{ +Cell["\<\ +Evaluation of a 3-d Exact Solution for the Viscous, Incompressible \ +Navier-Stokes Equations\ +\>", "Title", + TextAlignment->Center], + +Cell[CellGroupData[{ + +Cell["Define Velocity, Pressure and Scalar Fields", "Section"], + +Cell[BoxData[ + \(u\ = \ + \(-a\)\ \(( + Exp[a\ x]\ Sin[a\ y\ + \ d\ z]\ + \ + Exp[a\ z]\ Cos[a\ x\ + \ d\ y])\)\ Exp[\(-d^2\)\ nu\ t]\)], + "Input"], + +Cell[BoxData[ + \(v\ = \ + \(-a\)\ \((\ + Exp[a\ y] Sin[a\ z\ + \ d\ x]\ + \ + Exp[a\ x]\ Cos[a\ y\ + \ d\ z])\)\ Exp[\(-d^2\)\ nu\ t]\)], + "Input"], + +Cell[BoxData[ + \(w\ = \ + \(-a\)\ \((\ + Exp[a\ z]\ Sin[a\ x\ + \ d\ y]\ + \ + Exp[a\ y]\ Cos[a\ z\ + \ d\ x])\)\ Exp[\(-d^2\)\ nu\ t]\)], + "Input"], + +Cell[BoxData[ + \(p\ = \ + \(-a^2\)/2\ + \((Exp[2\ a\ x]\ + \ Exp[2\ a\ y]\ + \ Exp[2\ a\ z]\ + \ + 2\ Sin[a\ x\ + \ d\ y]\ Cos[a\ z\ + \ d\ x]\ + Exp[a\ \((y\ + \ z)\)]\ + \ + 2\ Sin[a\ y\ + \ d\ z]\ Cos[a\ x\ + \ d\ y]\ + Exp[a\ \((z\ + \ x)\)]\ + \ + 2\ Sin[a\ z\ + \ d\ x]\ Cos[a\ y\ + \ d\ z]\ + Exp[a\ \((x\ + \ y)\)])\)\ Exp[\(-2\)\ d^2\ nu\ t]\)], "Input"], + +Cell[BoxData[ + \(Y\ = \ \.18\)], "Input"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Check Governing Equations", "Section"], + +Cell[BoxData[ + \(Simplify[D[u, x]\ + \ D[v, y]\ + \ D[w, z]\ == \ 0]\)], "Input"], + +Cell[BoxData[ + \(Simplify[ + D[u, t]\ + \ u\ D[u, x]\ + \ v\ D[u, y]\ + \ w\ D[u, z]\ == \ + \(-\ D[p, x]\)\ + \ nu\ D[u, {x, 2}] + \ nu\ D[u, {y, 2}]\ + \ + nu\ D[u, {z, 2}]]\)], "Input"], + +Cell[BoxData[ + \(Simplify[ + D[v, t]\ + \ u\ D[v, x]\ + \ v\ D[v, y]\ + \ w\ D[v, z]\ == \ + \(-\ D[p, y]\)\ + \ nu\ D[v, {x, 2}] + \ nu\ D[v, {y, 2}]\ + \ + nu\ D[v, {z, 2}]]\)], "Input"], + +Cell[BoxData[ + \(Simplify[ + D[w, t]\ + \ u\ D[w, x]\ + \ v\ D[w, y]\ + \ w\ D[w, z]\ == \ + \(-\ D[p, z]\)\ + \ nu\ D[w, {x, 2}] + \ nu\ D[w, {y, 2}]\ + \ + nu\ D[w, {z, 2}]]\)], "Input"], + +Cell[BoxData[ + \(Simplify[ + D[Y, t]\ + \ u\ D[Y, x]\ + \ v\ D[Y, y]\ + \ w\ D[Y, z]\ == \ + d\ D[Y, {x, 2}]\ + \ d\ D[Y, {y, 2}]\ + \ d\ D[Y, {z, 2}]]\)], + "Input"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Evaluate the Fields for a=Pi, d=Pi", "Section"], + +Cell[BoxData[ + \(a\ = \ Pi\)], "Input"], + +Cell[BoxData[ + \(d\ = \ Pi\)], "Input"], + +Cell[BoxData[ + \(u\)], "Input"], + +Cell[BoxData[ + \(v\)], "Input"], + +Cell[BoxData[ + \(w\)], "Input"], + +Cell[BoxData[ + \(p\)], "Input"], + +Cell[BoxData[ + \(t\ = \ 0\)], "Input"], + +Cell[BoxData[ + \(z\ = \ 0\)], "Input"], + +Cell[BoxData[ + \(Remove[a]\)], "Input"], + +Cell[BoxData[ + \(Remove[d]\)], "Input"], + +Cell[BoxData[ + \(Remove[z]\)], "Input"], + +Cell[BoxData[ + \(Remove[t]\)], "Input"], + +Cell[BoxData[ + \(ContourPlot[u, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"], + +Cell[BoxData[ + \(ContourPlot[v, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"], + +Cell[BoxData[ + \(ContourPlot[p, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"], + +Cell[BoxData[ + \(ContourPlot[Y, {x, 0, 2}, \ {y, 0, 2}]\)], "Input"] +}, Open ]] +}, Open ]] +}, +FrontEndVersion->"X 3.0", +ScreenRectangle->{{0, 1280}, {0, 1024}}, +WindowSize->{520, 600}, +WindowMargins->{{296, Automatic}, {Automatic, 88}}, +PrintingPageRange->{Automatic, Automatic}, +PrintingOptions->{"PaperSize"->{612, 792}, +"PaperOrientation"->"Portrait", +"Magnification"->1} +] + + +(*********************************************************************** +Cached data follows. If you edit this Notebook file directly, not using +Mathematica, you must remove the line containing CacheID at the top of +the file. The cache data will then be recreated when you save this file +from within Mathematica. +***********************************************************************) + +(*CellTagsOutline +CellTagsIndex->{} +*) + +(*CellTagsIndex +CellTagsIndex->{} +*) + +(*NotebookFileOutline +Notebook[{ + +Cell[CellGroupData[{ +Cell[1731, 51, 142, 4, 90, "Title"], + +Cell[CellGroupData[{ +Cell[1898, 59, 62, 0, 47, "Section"], +Cell[1963, 61, 180, 5, 43, "Input"], +Cell[2146, 68, 181, 5, 43, "Input"], +Cell[2330, 75, 182, 5, 43, "Input"], +Cell[2515, 82, 465, 9, 91, "Input"], +Cell[2983, 93, 45, 1, 27, "Input"] +}, Open ]], + +Cell[CellGroupData[{ +Cell[3065, 99, 44, 0, 47, "Section"], +Cell[3112, 101, 87, 1, 27, "Input"], +Cell[3202, 104, 217, 4, 43, "Input"], +Cell[3422, 110, 217, 4, 43, "Input"], +Cell[3642, 116, 217, 4, 43, "Input"], +Cell[3862, 122, 187, 4, 43, "Input"] +}, Open ]], + +Cell[CellGroupData[{ +Cell[4086, 131, 53, 0, 47, "Section"], +Cell[4142, 133, 43, 1, 27, "Input"], +Cell[4188, 136, 43, 1, 27, "Input"], +Cell[4234, 139, 34, 1, 27, "Input"], +Cell[4271, 142, 34, 1, 27, "Input"], +Cell[4308, 145, 34, 1, 27, "Input"], +Cell[4345, 148, 34, 1, 27, "Input"], +Cell[4382, 151, 42, 1, 27, "Input"], +Cell[4427, 154, 42, 1, 27, "Input"], +Cell[4472, 157, 42, 1, 27, "Input"], +Cell[4517, 160, 42, 1, 27, "Input"], +Cell[4562, 163, 42, 1, 27, "Input"], +Cell[4607, 166, 42, 1, 27, "Input"], +Cell[4652, 169, 71, 1, 27, "Input"], +Cell[4726, 172, 71, 1, 27, "Input"], +Cell[4800, 175, 71, 1, 27, "Input"], +Cell[4874, 178, 71, 1, 27, "Input"] +}, Open ]] +}, Open ]] +} +] +*) + + + + +(*********************************************************************** +End of Mathematica Notebook file. +***********************************************************************) + diff --git a/Tutorials_profiling/TaylorGreen/benchmarks/GNUmakefile b/Tutorials_profiling/TaylorGreen/benchmarks/GNUmakefile index 5b61a10b..cebb0953 100644 --- a/Tutorials_profiling/TaylorGreen/benchmarks/GNUmakefile +++ b/Tutorials_profiling/TaylorGreen/benchmarks/GNUmakefile @@ -1,42 +1,42 @@ - -AMREX_HOME ?= ../../../../amrex - -TOP = $(AMREX_HOME) - -# -# Variables for the user to set ... -# -PRECISION = DOUBLE -DEBUG = TRUE -DIM = 3 -COMP = g++ -USE_MPI = FALSE - -DEFINES += -DBL_PARALLEL_IO -EBASE = ViscBench - -include $(AMREX_HOME)/Tools/GNUMake/Make.defs -include ./Make.package -include $(AMREX_HOME)/Src/Base/Make.package -include $(AMREX_HOME)/Src/Extern/amrdata/Make.package - -vpathdir += .. - -INCLUDE_LOCATIONS += $(AMREX_HOME)/Src/Base -vpathdir += $(AMREX_HOME)/Src/Base - -INCLUDE_LOCATIONS += $(AMREX_HOME)/Src/Extern/amrdata -vpathdir += $(AMREX_HOME)/Src/Extern/amrdata - - -vpath %.c : . $(vpathdir) -vpath %.h : . $(vpathdir) -vpath %.cpp : . $(vpathdir) -vpath %.H : . $(vpathdir) -vpath %.F : . $(vpathdir) -vpath %.f : . $(vpathdir) -vpath %.f90 : . $(vpathdir) - -all: $(executable) - -include $(AMREX_HOME)/Tools/GNUMake/Make.rules + +AMREX_HOME ?= ../../../../amrex + +TOP = $(AMREX_HOME) + +# +# Variables for the user to set ... +# +PRECISION = DOUBLE +DEBUG = TRUE +DIM = 3 +COMP = g++ +USE_MPI = FALSE + +DEFINES += -DBL_PARALLEL_IO +EBASE = ViscBench + +include $(AMREX_HOME)/Tools/GNUMake/Make.defs +include ./Make.package +include $(AMREX_HOME)/Src/Base/Make.package +include $(AMREX_HOME)/Src/Extern/amrdata/Make.package + +vpathdir += .. + +INCLUDE_LOCATIONS += $(AMREX_HOME)/Src/Base +vpathdir += $(AMREX_HOME)/Src/Base + +INCLUDE_LOCATIONS += $(AMREX_HOME)/Src/Extern/amrdata +vpathdir += $(AMREX_HOME)/Src/Extern/amrdata + + +vpath %.c : . $(vpathdir) +vpath %.h : . $(vpathdir) +vpath %.cpp : . $(vpathdir) +vpath %.H : . $(vpathdir) +vpath %.F : . $(vpathdir) +vpath %.f : . $(vpathdir) +vpath %.f90 : . $(vpathdir) + +all: $(executable) + +include $(AMREX_HOME)/Tools/GNUMake/Make.rules diff --git a/Tutorials_profiling/TaylorGreen/benchmarks/Make.package b/Tutorials_profiling/TaylorGreen/benchmarks/Make.package index cc264b5b..b3207eff 100644 --- a/Tutorials_profiling/TaylorGreen/benchmarks/Make.package +++ b/Tutorials_profiling/TaylorGreen/benchmarks/Make.package @@ -1,5 +1,5 @@ - -CEXE_sources += ViscBench.cpp - -FEXE_sources += EXACT_$(DIM)D.F -FEXE_headers += + +CEXE_sources += ViscBench.cpp + +FEXE_sources += EXACT_$(DIM)D.F +FEXE_headers += diff --git a/Tutorials_profiling/TaylorGreen/benchmarks/ViscBench.cpp b/Tutorials_profiling/TaylorGreen/benchmarks/ViscBench.cpp index b2861af3..742e0f9d 100644 --- a/Tutorials_profiling/TaylorGreen/benchmarks/ViscBench.cpp +++ b/Tutorials_profiling/TaylorGreen/benchmarks/ViscBench.cpp @@ -1,272 +1,275 @@ - -#include -#include -#include -#include -#include - -using std::ios; - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define GARBAGE 666.e+40 - -using namespace amrex; - -// ----------------------------------------------------------- -// This case is an unsteady viscous benchmark for which the -// exact solution in 2D is -// u(x,y,t) = Sin(2 Pi x) Cos(2 Pi y) Exp(-2 (2Pi)^2 Nu t) -// v(x,y,t) = - Cos(2 Pi x) Sin(2 Pi y) Exp(-2 (2Pi)^2 Nu t) -// p(x,y,t) = - {Cos(4 Pi x) + Cos(4 Pi y)} Exp(-4 (2Pi)^2 Nu t) / 4 -// This tool reads a plotfile and compares it against this exact solution. -// This benchmark was originally derived by G.I. Taylor (Phil. Mag., -// Vol. 46, No. 274, pp. 671-674, 1923) and Ethier and Steinman -// (Intl. J. Num. Meth. Fluids, Vol. 19, pp. 369-375, 1994) give -// the pressure field. -// -// For 3D, the 2D solution is used in conjunction with a uniform 3rd dimension. -// When generating 3D data, check IAMR/Source/prob/prob_init.cpp to ensure -// that the problem setup matches the solution here with t=0. -// -// Analytic, fully 3D solutions (not implemented here) are discussed in, -// for example, -// Antuono, M. (2020). Tri-periodic fully three-dimensional analytic solutions for the Navier–Stokes equations. Journal of Fluid Mechanics, 890, A23. doi:10.1017/jfm.2020.126 -// -static -void -PrintUsage (const char* progName) -{ - std::cout << '\n'; - std::cout << "This program reads a plot file and compares the results\n" - << "against the 2-d viscous benchmark of G.I. Taylor (for 2d build)\n" - << "or a 3-d analog, which takes the 2-d solution and then is\n" - << "is uniform in the third-dimension. The uniform\n" - << "direction can be in any of the three coordinate directions\n"; - std::cout << "Usage:" << '\n'; - std::cout << progName << '\n'; - std::cout << " infile = inputFileName" << '\n'; - std::cout << " mu = viscosity" << '\n'; - std::cout << " unifdir = uniformDirection (optional, default is z-dir)" << '\n'; - std::cout << " errfile = ErrorFileOutputFileName (optional)" << '\n'; - std::cout << " exfile = ExactSolnOutputFileName (optional)" << '\n'; - std::cout << " norm = integer norm (optional, default is 2 for L2 norm, 1 for L1 norm, 0 for L_{inf} norm)" << '\n'; - std::cout << " [-help]" << '\n'; - std::cout << " [-verbose]" << '\n'; - std::cout << '\n'; - exit(1); -} - -bool -amrDatasHaveSameDerives(const AmrData& amrd1, - const AmrData& amrd2); -int -main (int argc, - char* argv[]) -{ - amrex::Initialize(argc,argv); - - if (argc == 1) - PrintUsage(argv[0]); - - ParmParse pp; - - if (pp.contains("help")) - PrintUsage(argv[0]); - - FArrayBox::setFormat(FABio::FAB_IEEE_32); - // - // Scan the arguments. - // - std::string iFile, errFile, exFile; - - bool verbose = false; - if (pp.contains("verbose")) - { - verbose = true; - AmrData::SetVerbose(true); - } - pp.query("infile", iFile); - if (iFile.empty()) - amrex::Abort("You must specify `infile'"); - - pp.query("exfile", exFile); - pp.query("errfile", errFile); - - // Direction with uniform velocity. Default to z-direction - int unifDir = 2; - pp.query("unifdir", unifDir); - if (unifDir < 0 || unifDir > 2) - amrex::Abort("You must specify a valid direction of uniform velocity, `unifdir = ...'"); - - Real mu = -1.0; - pp.query("mu", mu); - if (mu < 0.0) - amrex::Abort("You must specify `mu'"); - - int norm = 2; - pp.query("norm", norm); - - DataServices::SetBatchMode(); - Amrvis::FileType fileType(Amrvis::NEWPLT); - - DataServices dataServicesC(iFile, fileType); - - if (!dataServicesC.AmrDataOk()) - DataServices::Dispatch(DataServices::ExitRequest, NULL); - - // - // Generate AmrData Objects - // - AmrData& amrDataI = dataServicesC.AmrDataRef(); - - const int nComp = AMREX_SPACEDIM+1; //amrDataI.NComp(); - const Real time = amrDataI.Time(); - const int finestLevel = amrDataI.FinestLevel(); - const Vector& derives = amrDataI.PlotVarNames(); - - - // - // Compute the error - // - Vector error(finestLevel+1); - Vector dataE(finestLevel+1); - - std::cout << "Level Delta L"<< norm << " norm of Error in Each Component" << std::endl - << "-----------------------------------------------" << std::endl; - - for (int iLevel = 0; iLevel <= finestLevel; ++iLevel) - { - const BoxArray& baI = amrDataI.boxArray(iLevel); - Vector delI = amrDataI.DxLevel()[iLevel]; - DistributionMapping dmap(baI); - - error[iLevel] = new MultiFab(baI, dmap, nComp, 0); - error[iLevel]->setVal(GARBAGE); - - dataE[iLevel] = new MultiFab(baI, dmap, nComp, 0); - dataE[iLevel]->setVal(GARBAGE); - - MultiFab dataI(baI, dmap, nComp, 0); - - for (int iGrid=0; iGrid xlo = amrDataI.GridLocLo()[iLevel][iGrid]; - Vector xhi = amrDataI.GridLocHi()[iLevel][iGrid]; - -#if (AMREX_SPACEDIM == 3) - FORT_VISCBENCH(&time, &mu, &unifDir, - lo, hi, &nComp, - ((*dataE[iLevel])[iGrid]).dataPtr(), - ARLIM(lo), ARLIM(hi), - delI.dataPtr(), - xlo.dataPtr(), xhi.dataPtr()); -#else - FORT_VISCBENCH(&time, &mu, - lo, hi, &nComp, - ((*dataE[iLevel])[iGrid]).dataPtr(), - ARLIM(lo), ARLIM(hi), - delI.dataPtr(), - xlo.dataPtr(), xhi.dataPtr()); -#endif - } - - (*error[iLevel]).ParallelCopy(dataI); - (*error[iLevel]).minus((*dataE[iLevel]), 0, nComp, 0); - - - // - // Output Statistics - // - Real cellvol = 1.0; - for (int i=0; i varNames{ AMREX_D_DECL("x_velocity", "y_velocity", "z_velocity"), "density"}; - // - if (!errFile.empty()) - WritePlotFile(error, amrDataI, errFile, verbose, varNames); - - if (!exFile.empty()) - WritePlotFile(dataE, amrDataI, exFile, verbose, varNames); - - - for (int iLevel = 0; iLevel <= finestLevel; ++iLevel) { - delete error[iLevel]; - delete dataE[iLevel]; - } - - amrex::Finalize(); -} - - -bool -amrDatasHaveSameDerives(const AmrData& amrd1, - const AmrData& amrd2) -{ - const Vector& derives1 = amrd1.PlotVarNames(); - const Vector& derives2 = amrd2.PlotVarNames(); - int length = derives1.size(); - if (length != derives2.size()) - return false; - for (int i=0; i +#include +#include +#include +#include + +using std::ios; + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define GARBAGE 666.e+40 + +using namespace amrex; + +// ----------------------------------------------------------- +// This case is an unsteady viscous benchmark for which the +// exact solution in 2D is +// u(x,y,t) = Sin(2 Pi x) Cos(2 Pi y) Exp(-2 (2Pi)^2 Nu t) +// v(x,y,t) = - Cos(2 Pi x) Sin(2 Pi y) Exp(-2 (2Pi)^2 Nu t) +// p(x,y,t) = - {Cos(4 Pi x) + Cos(4 Pi y)} Exp(-4 (2Pi)^2 Nu t) / 4 +// This tool reads a plotfile and compares it against this exact solution. +// This benchmark was originally derived by G.I. Taylor (Phil. Mag., +// Vol. 46, No. 274, pp. 671-674, 1923) and Ethier and Steinman +// (Intl. J. Num. Meth. Fluids, Vol. 19, pp. 369-375, 1994) give +// the pressure field. +// +// For 3D, the 2D solution is used in conjunction with a uniform 3rd dimension. +// When generating 3D data, check IAMR/Source/prob/prob_init.cpp to ensure +// that the problem setup matches the solution here with t=0. +// +// Analytic, fully 3D solutions (not implemented here) are discussed in, +// for example, +// Antuono, M. (2020). Tri-periodic fully three-dimensional analytic solutions for the Navier–Stokes equations. Journal of Fluid Mechanics, 890, A23. doi:10.1017/jfm.2020.126 +// +static +void +PrintUsage (const char* progName) +{ + std::cout << '\n'; + std::cout << "This program reads a plot file and compares the results\n" + << "against the 2-d viscous benchmark of G.I. Taylor (for 2d build)\n" + << "or a 3-d analog, which takes the 2-d solution and then is\n" + << "is uniform in the third-dimension. The uniform\n" + << "direction can be in any of the three coordinate directions\n"; + std::cout << "Usage:" << '\n'; + std::cout << progName << '\n'; + std::cout << " infile = inputFileName" << '\n'; + std::cout << " mu = viscosity" << '\n'; + std::cout << " unifdir = uniformDirection (optional, default is z-dir)" << '\n'; + std::cout << " errfile = ErrorFileOutputFileName (optional)" << '\n'; + std::cout << " exfile = ExactSolnOutputFileName (optional)" << '\n'; + std::cout << " norm = integer norm (optional, default is 2 for L2 norm, 1 for L1 norm, 0 for L_{inf} norm)" << '\n'; + std::cout << " [-help]" << '\n'; + std::cout << " [-verbose]" << '\n'; + std::cout << '\n'; + exit(1); +} + +bool +amrDatasHaveSameDerives(const AmrData& amrd1, + const AmrData& amrd2); +int +main (int argc, + char* argv[]) +{ + amrex::Initialize(argc,argv); + + if (argc == 1) + PrintUsage(argv[0]); + + ParmParse pp; + + if (pp.contains("help")) + PrintUsage(argv[0]); + + FArrayBox::setFormat(FABio::FAB_IEEE_32); + // + // Scan the arguments. + // + std::string iFile, errFile, exFile; + + bool verbose = false; + if (pp.contains("verbose")) + { + verbose = true; + AmrData::SetVerbose(true); + } + pp.query("infile", iFile); + if (iFile.empty()) + amrex::Abort("You must specify `infile'"); + + pp.query("exfile", exFile); + pp.query("errfile", errFile); + + // Direction with uniform velocity. Default to z-direction + int unifDir = 2; + pp.query("unifdir", unifDir); + if (unifDir < 0 || unifDir > 2) + amrex::Abort("You must specify a valid direction of uniform velocity, `unifdir = ...'"); + + Real mu = -1.0; + pp.query("mu", mu); + if (mu < 0.0) + amrex::Abort("You must specify `mu'"); + + int norm = 2; + pp.query("norm", norm); + + DataServices::SetBatchMode(); + Amrvis::FileType fileType(Amrvis::NEWPLT); + + DataServices dataServicesC(iFile, fileType); + + if (!dataServicesC.AmrDataOk()) + DataServices::Dispatch(DataServices::ExitRequest, NULL); + + // + // Generate AmrData Objects + // + AmrData& amrDataI = dataServicesC.AmrDataRef(); + + const int nComp = AMREX_SPACEDIM+1; //amrDataI.NComp(); + const Real time = amrDataI.Time(); + const int finestLevel = amrDataI.FinestLevel(); + const Vector& derives = amrDataI.PlotVarNames(); + + + // + // Compute the error + // + Vector error(finestLevel+1); + Vector dataE(finestLevel+1); + + std::cout << "Level Delta L"<< norm << " norm of Error in Each Component" << std::endl + << "-----------------------------------------------" << std::endl; + + for (int iLevel = 0; iLevel <= finestLevel; ++iLevel) + { + const BoxArray& baI = amrDataI.boxArray(iLevel); + Vector delI = amrDataI.DxLevel()[iLevel]; + DistributionMapping dmap(baI); + + error[iLevel] = new MultiFab(baI, dmap, nComp, 0); + error[iLevel]->setVal(GARBAGE); + + dataE[iLevel] = new MultiFab(baI, dmap, nComp, 0); + dataE[iLevel]->setVal(GARBAGE); + + MultiFab dataI(baI, dmap, nComp, 0); + + for (int iGrid=0; iGrid xlo = amrDataI.GridLocLo()[iLevel][iGrid]; + Vector xhi = amrDataI.GridLocHi()[iLevel][iGrid]; + +#if (AMREX_SPACEDIM == 3) + FORT_VISCBENCH(&time, &mu, &unifDir, + lo, hi, &nComp, + ((*dataE[iLevel])[iGrid]).dataPtr(), + ARLIM(lo), ARLIM(hi), + delI.dataPtr(), + xlo.dataPtr(), xhi.dataPtr()); +#else + FORT_VISCBENCH(&time, &mu, + lo, hi, &nComp, + ((*dataE[iLevel])[iGrid]).dataPtr(), + ARLIM(lo), ARLIM(hi), + delI.dataPtr(), + xlo.dataPtr(), xhi.dataPtr()); +#endif + } + + (*error[iLevel]).ParallelCopy(dataI); + (*error[iLevel]).minus((*dataE[iLevel]), 0, nComp, 0); + + + // + // Output Statistics + // + Real cellvol = 1.0; + for (int i=0; i varNames{ AMREX_D_DECL("x_velocity", "y_velocity", "z_velocity"), "density"}; + // + if (!errFile.empty()) + WritePlotFile(error, amrDataI, errFile, verbose, varNames); + + if (!exFile.empty()) + WritePlotFile(dataE, amrDataI, exFile, verbose, varNames); + + + for (int iLevel = 0; iLevel <= finestLevel; ++iLevel) { + delete error[iLevel]; + delete dataE[iLevel]; + } + + amrex::Finalize(); +} + + +bool +amrDatasHaveSameDerives(const AmrData& amrd1, + const AmrData& amrd2) +{ + const Vector& derives1 = amrd1.PlotVarNames(); + const Vector& derives2 = amrd2.PlotVarNames(); + int length = derives1.size(); + if (length != derives2.size()) + return false; + for (int i=0; i & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#AMREX_HOME defines the directory in which we will find the BoxLib directory +AMREX_HOME ?= ../../../amrex +AMREX_HYDRO_HOME ?= ../../../AMReX-Hydro + +#TOP defines the directory in which we will find Source, Exec, etc. +TOP = ../.. + +# +# Variables for the user to set ... +# + +PRECISION = DOUBLE + +DIM = 2 +COMP = gnu + +DEBUG = FALSE +USE_MPI = FALSE +USE_OMP = FALSE +PROFILE = FALSE + +USE_CUDA = FALSE + +USE_SENSEI_INSITU = FALSE + +EBASE = amr + +Blocs := . + +include $(TOP)/Exec/Make.IAMR diff --git a/Tutorials_profiling/TracerAdvection/inputs.2d.traceradvect b/Tutorials_profiling/TracerAdvection/inputs.2d.traceradvect index cb504bfd..c89090f2 100644 --- a/Tutorials_profiling/TracerAdvection/inputs.2d.traceradvect +++ b/Tutorials_profiling/TracerAdvection/inputs.2d.traceradvect @@ -1,120 +1,126 @@ - -#******************************************************************************* -# INPUTS.2D.TRACERADVECT -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 50 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 10000 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 64 64 -amr.max_grid_size = 64 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 50 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 50 - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 0.9 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 1.0 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.0 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Forcing term defaults to rho * abs(gravity) "down" -ns.gravity = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z. -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1. 1. - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 4 -prob.velocity_ic = 1.0 2.0 -prob.density_ic = 1.0 -prob.blob_center = 0.5 0.5 - -#******************************************************************************* - +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* +# INPUTS.2D.TRACERADVECT +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 50 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 10000 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 64 64 +amr.max_grid_size = 64 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 50 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 50 + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 0.9 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 1.0 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.0 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Forcing term defaults to rho * abs(gravity) "down" +ns.gravity = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z. +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1. 1. + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 4 +prob.velocity_ic = 1.0 2.0 +prob.density_ic = 1.0 +prob.blob_center = 0.5 0.5 + +#******************************************************************************* + diff --git a/Tutorials_profiling/TracerAdvection/inputs.3d.traceradvect b/Tutorials_profiling/TracerAdvection/inputs.3d.traceradvect index 9df99f91..25c7d66a 100644 --- a/Tutorials_profiling/TracerAdvection/inputs.3d.traceradvect +++ b/Tutorials_profiling/TracerAdvection/inputs.3d.traceradvect @@ -1,117 +1,123 @@ - -#******************************************************************************* - -#NOTE: You may set *either* max_step or stop_time, or you may set them both. - -# Maximum number of coarse grid timesteps to be taken, if stop_time is -# not reached first. -max_step = 10 - -# Time at which calculation stops, if max_step is not reached first. -stop_time = 100 - -#******************************************************************************* - -# Number of cells in each coordinate direction at the coarsest level -amr.n_cell = 32 32 32 - -#******************************************************************************* - -# Maximum level (defaults to 0 for single level calculation) -amr.max_level = 0 # maximum number of levels of refinement - -#******************************************************************************* - -# Interval (in number of level l timesteps) between regridding -amr.regrid_int = 2 2 2 2 2 2 2 - -#******************************************************************************* - -# Refinement ratio as a function of level -amr.ref_ratio = 2 2 2 2 - -#******************************************************************************* - -# Sets the "NavierStokes" code to be verbose -ns.v = 1 -ns.sum_interval = 1 - -#******************************************************************************* - -# Sets the "amr" code to be verbose -amr.v = 1 - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between checkpoint(restart) files -amr.check_int = 50 -amr.check_file = chk - -#******************************************************************************* - -# Interval (in number of coarse timesteps) between plot files -amr.plot_int = 50 -amr.plot_file = plt - -#******************************************************************************* - -# CFL number to be used in calculating the time step : dt = dx / max(velocity) -ns.cfl = 1.0 # CFL number used to set dt - -#******************************************************************************* - -# Factor by which the first time is shrunk relative to CFL constraint -ns.init_shrink = 1.0 # factor which multiplies the very first time step - -#******************************************************************************* - -# Viscosity coefficient -ns.vel_visc_coef = 0.0 - -#******************************************************************************* - -# Diffusion coefficient for first scalar -ns.scal_diff_coefs = 0.0 - -#******************************************************************************* - -# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). -geometry.coord_sys = 0 - -#******************************************************************************* - -# Physical dimensions of the low end of the domain. -geometry.prob_lo = 0. 0. 0. - -# Physical dimensions of the high end of the domain. -geometry.prob_hi = 1.0 1.0 1.0 - -#******************************************************************************* - -#Set to 1 if periodic in that direction -geometry.is_periodic = 1 1 1 - -#******************************************************************************* - -# Boundary conditions on the low end of the domain. -ns.lo_bc = 0 0 0 - -# Boundary conditions on the high end of the domain. -ns.hi_bc = 0 0 0 - -# 0 = Interior/Periodic 3 = Symmetry -# 1 = Inflow 4 = SlipWall -# 2 = Outflow 5 = NoSlipWall - -#******************************************************************************* - -# Problem parameters -prob.probtype = 4 -prob.velocity_ic = 1.0 2.0 3.0 -prob.density_ic = 1.0 -prob.blob_center = 0.5 0.5 0.5 - -#******************************************************************************* - -# Add vorticity to the variables in the plot files. -amr.derive_plot_vars = mag_vort +# SPDX-FileCopyrightText: 1998 - 2023 Berkeley Lab +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: LicenseRef-OpenSource +# Modified from IAMR, originally developed at Lawrence Berkeley National Lab. +# Original source: https://github.com/AMReX-Fluids/IAMR + +#******************************************************************************* + +#NOTE: You may set *either* max_step or stop_time, or you may set them both. + +# Maximum number of coarse grid timesteps to be taken, if stop_time is +# not reached first. +max_step = 10 + +# Time at which calculation stops, if max_step is not reached first. +stop_time = 100 + +#******************************************************************************* + +# Number of cells in each coordinate direction at the coarsest level +amr.n_cell = 32 32 32 + +#******************************************************************************* + +# Maximum level (defaults to 0 for single level calculation) +amr.max_level = 0 # maximum number of levels of refinement + +#******************************************************************************* + +# Interval (in number of level l timesteps) between regridding +amr.regrid_int = 2 2 2 2 2 2 2 + +#******************************************************************************* + +# Refinement ratio as a function of level +amr.ref_ratio = 2 2 2 2 + +#******************************************************************************* + +# Sets the "NavierStokes" code to be verbose +ns.v = 1 +ns.sum_interval = 1 + +#******************************************************************************* + +# Sets the "amr" code to be verbose +amr.v = 1 + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between checkpoint(restart) files +amr.check_int = 50 +amr.check_file = chk + +#******************************************************************************* + +# Interval (in number of coarse timesteps) between plot files +amr.plot_int = 50 +amr.plot_file = plt + +#******************************************************************************* + +# CFL number to be used in calculating the time step : dt = dx / max(velocity) +ns.cfl = 1.0 # CFL number used to set dt + +#******************************************************************************* + +# Factor by which the first time is shrunk relative to CFL constraint +ns.init_shrink = 1.0 # factor which multiplies the very first time step + +#******************************************************************************* + +# Viscosity coefficient +ns.vel_visc_coef = 0.0 + +#******************************************************************************* + +# Diffusion coefficient for first scalar +ns.scal_diff_coefs = 0.0 + +#******************************************************************************* + +# Set to 0 if x-y coordinate system, set to 1 if r-z (in 2-d). +geometry.coord_sys = 0 + +#******************************************************************************* + +# Physical dimensions of the low end of the domain. +geometry.prob_lo = 0. 0. 0. + +# Physical dimensions of the high end of the domain. +geometry.prob_hi = 1.0 1.0 1.0 + +#******************************************************************************* + +#Set to 1 if periodic in that direction +geometry.is_periodic = 1 1 1 + +#******************************************************************************* + +# Boundary conditions on the low end of the domain. +ns.lo_bc = 0 0 0 + +# Boundary conditions on the high end of the domain. +ns.hi_bc = 0 0 0 + +# 0 = Interior/Periodic 3 = Symmetry +# 1 = Inflow 4 = SlipWall +# 2 = Outflow 5 = NoSlipWall + +#******************************************************************************* + +# Problem parameters +prob.probtype = 4 +prob.velocity_ic = 1.0 2.0 3.0 +prob.density_ic = 1.0 +prob.blob_center = 0.5 0.5 0.5 + +#******************************************************************************* + +# Add vorticity to the variables in the plot files. +amr.derive_plot_vars = mag_vort diff --git a/Tutorials_profiling/jobiamr2dcpu b/Tutorials_profiling/jobiamr2dcpu index 76eafb09..24299995 100755 --- a/Tutorials_profiling/jobiamr2dcpu +++ b/Tutorials_profiling/jobiamr2dcpu @@ -1,5 +1,9 @@ #!/bin/bash +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: BSD-3-Clause + # break the cases into different key-value pairs declare -A Cases Cases[Bubble]=inputs.2d.bubble diff --git a/Tutorials_profiling/jobiamr2dgpu b/Tutorials_profiling/jobiamr2dgpu index ba061e70..d88d7bb7 100755 --- a/Tutorials_profiling/jobiamr2dgpu +++ b/Tutorials_profiling/jobiamr2dgpu @@ -1,5 +1,9 @@ #!/bin/bash +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: BSD-3-Clause + # break the cases into different key-value pairs declare -A Cases Cases[Bubble]=inputs.2d.bubble diff --git a/Tutorials_profiling/jobiamr3dcpu b/Tutorials_profiling/jobiamr3dcpu index 94e53029..5296fb74 100755 --- a/Tutorials_profiling/jobiamr3dcpu +++ b/Tutorials_profiling/jobiamr3dcpu @@ -1,97 +1,101 @@ -#!/bin/bash - -# break the cases into different key-value pairs -declare -A Cases -Cases[ConvectedVortex]=inputs.3d.convectedvortex -Cases[FlowPastCylinder]=inputs.3d.flow_past_cylinder-x -Cases[LidDrivenCavity]=inputs.3d.lid_driven_cavity -Cases[TaylorGreen]=inputs.3d.taylorgreen - -for i in "${!Cases[@]}" -do - echo "key : $i" - echo "value: ${Cases[$i]}" - work_folder=${PWD} - new_case_dir=${PWD}/$i - cd $new_case_dir - rm -rf plt* chk* *.visit Backtrace* bl_prof* log* - echo "delete old data" - - # Build a new dir for storing the results - results_topdir=$new_case_dir/case_results_cpu3d - # echo "delete the old dir $results_topdir" - # rm -rf $results_topdir - echo "build a new dir $results_topdir" - mkdir -p $results_topdir - - cd $new_case_dir - - cp GNUmakefile GNUmakefile.temp - sed -i "s/2 # DIM/3 # DIM/g" GNUmakefile - sed -i "s/FALSE # MPI/TRUE # MPI/g" GNUmakefile - sed -i "s/FALSE # OMP/TRUE # OMP/g" GNUmakefile - sed -i "s/TRUE # CUDA/FALSE # CUDA/g" GNUmakefile - - # build the simulation for CPU - make -j16 - - # restore the input file - cp ${Cases[$i]}.temp ${Cases[$i]} - - for skip_level_projector in 0 #1 - do - for cycling in None Auto - do - for max_level in 2 # 1 2 - do - for max_grid_size in 16 # 8 16 - do - for regrid_int in 4 # 4 8 - do - - cd $new_case_dir - cp ${Cases[$i]} ${Cases[$i]}.temp - -################################################################################ - # replace the variables - sed -i "s/0 # skip_level_projector/${skip_level_projector} # skip_level_projector/g" ${Cases[$i]} - sed -i "s/Auto # subcycling_mode/${cycling} # subcycling_mode/g" ${Cases[$i]} - sed -i "s/8 # max_grid_size/${max_grid_size} # max_grid_size/g" ${Cases[$i]} - sed -i "s/0 # max_level/${max_level} # max_level/g" ${Cases[$i]} - sed -i "s/4 # regrid_int/${regrid_int} # regrid_int/g" ${Cases[$i]} - - # run the simulation - OMP_NUM_THREADS=2 mpiexec -n 16 ./amr3d.gnu.PROF.MPI.OMP.ex ${Cases[$i]} > log.txt - results_saveddir=$new_case_dir/case_results_cpu3d/cpu3d_skip${skip_level_projector}_${cycling}_mgs${max_grid_size}_$maxlev${max_level}_regrid${regrid_int} - echo "delete the old saved dir $results_saveddir" - rm -rf $results_saveddir - - results_bottomdir=$new_case_dir/cpu3d_skip${skip_level_projector}_${cycling}_mgs${max_grid_size}_$maxlev${max_level}_regrid${regrid_int} - echo "delete the old dir $results_bottomdir" - rm -rf $results_bottomdir - echo "build a new dir $results_bottomdir" - mkdir -p $results_bottomdir - echo "move the results into $results_bottomdir" - mv plt* chk* bl_prof* log* $results_bottomdir - cp ${Cases[$i]} $results_bottomdir - mv $results_bottomdir $results_topdir -################################################################################ - - # restore the input file - cp ${Cases[$i]}.temp ${Cases[$i]} - - # exit - echo "exit the dir $new_case_dir" - cd ${work_folder} - done - done - done - done - done - - cd $new_case_dir - - # restore the GNUMakefile - cp GNUmakefile.temp GNUmakefile - -done +#!/bin/bash + +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: BSD-3-Clause + +# break the cases into different key-value pairs +declare -A Cases +Cases[ConvectedVortex]=inputs.3d.convectedvortex +Cases[FlowPastCylinder]=inputs.3d.flow_past_cylinder-x +Cases[LidDrivenCavity]=inputs.3d.lid_driven_cavity +Cases[TaylorGreen]=inputs.3d.taylorgreen + +for i in "${!Cases[@]}" +do + echo "key : $i" + echo "value: ${Cases[$i]}" + work_folder=${PWD} + new_case_dir=${PWD}/$i + cd $new_case_dir + rm -rf plt* chk* *.visit Backtrace* bl_prof* log* + echo "delete old data" + + # Build a new dir for storing the results + results_topdir=$new_case_dir/case_results_cpu3d + # echo "delete the old dir $results_topdir" + # rm -rf $results_topdir + echo "build a new dir $results_topdir" + mkdir -p $results_topdir + + cd $new_case_dir + + cp GNUmakefile GNUmakefile.temp + sed -i "s/2 # DIM/3 # DIM/g" GNUmakefile + sed -i "s/FALSE # MPI/TRUE # MPI/g" GNUmakefile + sed -i "s/FALSE # OMP/TRUE # OMP/g" GNUmakefile + sed -i "s/TRUE # CUDA/FALSE # CUDA/g" GNUmakefile + + # build the simulation for CPU + make -j16 + + # restore the input file + cp ${Cases[$i]}.temp ${Cases[$i]} + + for skip_level_projector in 0 #1 + do + for cycling in None Auto + do + for max_level in 2 # 1 2 + do + for max_grid_size in 16 # 8 16 + do + for regrid_int in 4 # 4 8 + do + + cd $new_case_dir + cp ${Cases[$i]} ${Cases[$i]}.temp + +################################################################################ + # replace the variables + sed -i "s/0 # skip_level_projector/${skip_level_projector} # skip_level_projector/g" ${Cases[$i]} + sed -i "s/Auto # subcycling_mode/${cycling} # subcycling_mode/g" ${Cases[$i]} + sed -i "s/8 # max_grid_size/${max_grid_size} # max_grid_size/g" ${Cases[$i]} + sed -i "s/0 # max_level/${max_level} # max_level/g" ${Cases[$i]} + sed -i "s/4 # regrid_int/${regrid_int} # regrid_int/g" ${Cases[$i]} + + # run the simulation + OMP_NUM_THREADS=2 mpiexec -n 16 ./amr3d.gnu.PROF.MPI.OMP.ex ${Cases[$i]} > log.txt + results_saveddir=$new_case_dir/case_results_cpu3d/cpu3d_skip${skip_level_projector}_${cycling}_mgs${max_grid_size}_$maxlev${max_level}_regrid${regrid_int} + echo "delete the old saved dir $results_saveddir" + rm -rf $results_saveddir + + results_bottomdir=$new_case_dir/cpu3d_skip${skip_level_projector}_${cycling}_mgs${max_grid_size}_$maxlev${max_level}_regrid${regrid_int} + echo "delete the old dir $results_bottomdir" + rm -rf $results_bottomdir + echo "build a new dir $results_bottomdir" + mkdir -p $results_bottomdir + echo "move the results into $results_bottomdir" + mv plt* chk* bl_prof* log* $results_bottomdir + cp ${Cases[$i]} $results_bottomdir + mv $results_bottomdir $results_topdir +################################################################################ + + # restore the input file + cp ${Cases[$i]}.temp ${Cases[$i]} + + # exit + echo "exit the dir $new_case_dir" + cd ${work_folder} + done + done + done + done + done + + cd $new_case_dir + + # restore the GNUMakefile + cp GNUmakefile.temp GNUmakefile + +done diff --git a/Tutorials_profiling/jobiamr3dgpu b/Tutorials_profiling/jobiamr3dgpu index b06b071c..3f991f71 100755 --- a/Tutorials_profiling/jobiamr3dgpu +++ b/Tutorials_profiling/jobiamr3dgpu @@ -1,99 +1,103 @@ -#!/bin/bash - -# break the cases into different key-value pairs -declare -A Cases -Cases[ConvectedVortex]=inputs.3d.convectedvortex -Cases[FlowPastCylinder]=inputs.3d.flow_past_cylinder-x -Cases[LidDrivenCavity]=inputs.3d.lid_driven_cavity -Cases[TaylorGreen]=inputs.3d.taylorgreen - -for i in "${!Cases[@]}" -do - echo "key : $i" - echo "value: ${Cases[$i]}" - work_folder=${PWD} - new_case_dir=${PWD}/$i - cd $new_case_dir - rm -rf plt* chk* *.visit Backtrace* bl_prof* log* - echo "delete old data" - - # Build a new dir for storing the results - results_topdir=$new_case_dir/case_results_gpu3d - # echo "delete the old dir $results_topdir" - # rm -rf $results_topdir - echo "build a new dir $results_topdir" - mkdir -p $results_topdir - - cd $new_case_dir - - cp GNUmakefile GNUmakefile.temp - sed -i "s/2 # DIM/3 # DIM/g" GNUmakefile - sed -i "s/TRUE # MPI/FALSE # MPI/g" GNUmakefile - sed -i "s/TRUE # OMP/FALSE # OMP/g" GNUmakefile - sed -i "s/FALSE # CUDA/TRUE # CUDA/g" GNUmakefile - - # build the simulation for GPU - # make -j16 AMREX_CUDA_ARCH=86 - make -j16 - - # restore the input file - cp ${Cases[$i]}.temp ${Cases[$i]} - - for skip_level_projector in 0 #1 - do - for cycling in None # Auto - do - for max_level in 2 # 1 2 - do - for max_grid_size in 16 # 8 16 - do - for regrid_int in 4 # 4 8 - do - - cd $new_case_dir - cp ${Cases[$i]} ${Cases[$i]}.temp - -################################################################################ - # replace the variables - sed -i "s/0 # skip_level_projector/${skip_level_projector} # skip_level_projector/g" ${Cases[$i]} - sed -i "s/Auto # subcycling_mode/${cycling} # subcycling_mode/g" ${Cases[$i]} - sed -i "s/8 # max_grid_size/${max_grid_size} # max_grid_size/g" ${Cases[$i]} - sed -i "s/0 # max_level/${max_level} # max_level/g" ${Cases[$i]} - sed -i "s/4 # regrid_int/${regrid_int} # regrid_int/g" ${Cases[$i]} - - # run the simulation - ./amr3d.gnu.PROF.CUDA.ex ${Cases[$i]} > log.txt - - results_saveddir=$new_case_dir/case_results_gpu3d/gpu3d_skip${skip_level_projector}_${cycling}_mgs${max_grid_size}_$maxlev${max_level}_regrid${regrid_int} - echo "delete the old saved dir $results_saveddir" - rm -rf $results_saveddir - - results_bottomdir=$new_case_dir/gpu3d_skip${skip_level_projector}_${cycling}_mgs${max_grid_size}_$maxlev${max_level}_regrid${regrid_int} - echo "delete the old dir $results_bottomdir" - rm -rf $results_bottomdir - echo "build a new dir $results_bottomdir" - mkdir -p $results_bottomdir - echo "move the results into $results_bottomdir" - mv plt* chk* bl_prof* log* $results_bottomdir - cp ${Cases[$i]} $results_bottomdir - mv $results_bottomdir $results_topdir -################################################################################ - - # restore the input file - cp ${Cases[$i]}.temp ${Cases[$i]} - - # exit - echo "exit the dir $new_case_dir" - cd ${work_folder} - done - done - done - done - done - - cd $new_case_dir - - # restore the GNUMakefile - cp GNUmakefile.temp GNUmakefile - -done +#!/bin/bash + +# SPDX-FileCopyrightText: 2023 - 2025 Yadong Zeng & Dewen Liu<1803368907@qq.com> +# +# SPDX-License-Identifier: BSD-3-Clause + +# break the cases into different key-value pairs +declare -A Cases +Cases[ConvectedVortex]=inputs.3d.convectedvortex +Cases[FlowPastCylinder]=inputs.3d.flow_past_cylinder-x +Cases[LidDrivenCavity]=inputs.3d.lid_driven_cavity +Cases[TaylorGreen]=inputs.3d.taylorgreen + +for i in "${!Cases[@]}" +do + echo "key : $i" + echo "value: ${Cases[$i]}" + work_folder=${PWD} + new_case_dir=${PWD}/$i + cd $new_case_dir + rm -rf plt* chk* *.visit Backtrace* bl_prof* log* + echo "delete old data" + + # Build a new dir for storing the results + results_topdir=$new_case_dir/case_results_gpu3d + # echo "delete the old dir $results_topdir" + # rm -rf $results_topdir + echo "build a new dir $results_topdir" + mkdir -p $results_topdir + + cd $new_case_dir + + cp GNUmakefile GNUmakefile.temp + sed -i "s/2 # DIM/3 # DIM/g" GNUmakefile + sed -i "s/TRUE # MPI/FALSE # MPI/g" GNUmakefile + sed -i "s/TRUE # OMP/FALSE # OMP/g" GNUmakefile + sed -i "s/FALSE # CUDA/TRUE # CUDA/g" GNUmakefile + + # build the simulation for GPU + # make -j16 AMREX_CUDA_ARCH=86 + make -j16 + + # restore the input file + cp ${Cases[$i]}.temp ${Cases[$i]} + + for skip_level_projector in 0 #1 + do + for cycling in None # Auto + do + for max_level in 2 # 1 2 + do + for max_grid_size in 16 # 8 16 + do + for regrid_int in 4 # 4 8 + do + + cd $new_case_dir + cp ${Cases[$i]} ${Cases[$i]}.temp + +################################################################################ + # replace the variables + sed -i "s/0 # skip_level_projector/${skip_level_projector} # skip_level_projector/g" ${Cases[$i]} + sed -i "s/Auto # subcycling_mode/${cycling} # subcycling_mode/g" ${Cases[$i]} + sed -i "s/8 # max_grid_size/${max_grid_size} # max_grid_size/g" ${Cases[$i]} + sed -i "s/0 # max_level/${max_level} # max_level/g" ${Cases[$i]} + sed -i "s/4 # regrid_int/${regrid_int} # regrid_int/g" ${Cases[$i]} + + # run the simulation + ./amr3d.gnu.PROF.CUDA.ex ${Cases[$i]} > log.txt + + results_saveddir=$new_case_dir/case_results_gpu3d/gpu3d_skip${skip_level_projector}_${cycling}_mgs${max_grid_size}_$maxlev${max_level}_regrid${regrid_int} + echo "delete the old saved dir $results_saveddir" + rm -rf $results_saveddir + + results_bottomdir=$new_case_dir/gpu3d_skip${skip_level_projector}_${cycling}_mgs${max_grid_size}_$maxlev${max_level}_regrid${regrid_int} + echo "delete the old dir $results_bottomdir" + rm -rf $results_bottomdir + echo "build a new dir $results_bottomdir" + mkdir -p $results_bottomdir + echo "move the results into $results_bottomdir" + mv plt* chk* bl_prof* log* $results_bottomdir + cp ${Cases[$i]} $results_bottomdir + mv $results_bottomdir $results_topdir +################################################################################ + + # restore the input file + cp ${Cases[$i]}.temp ${Cases[$i]} + + # exit + echo "exit the dir $new_case_dir" + cd ${work_folder} + done + done + done + done + done + + cd $new_case_dir + + # restore the GNUMakefile + cp GNUmakefile.temp GNUmakefile + +done