Code Monkey home page Code Monkey logo

apcemm's Introduction

DOI

README for the APCEMM Source code repository

APCEMM stands for Aircraft Plume Chemistry Emission and Microphysics Model. The model aims to assess the chemical and microphysical perturbations introduced by a conventional aircraft, equipped with gas turbine engines. Global chemistry transport models commonly assume that emissions are released in grid-boxes that can be several orders of magnitude greater than an airplane's typical dimensions. APCEMM accounts for the fine-scale representation of an aircraft plume. To account for plume-scale processes, APCEMM has the option of computing effective emissions that correspond to what should be released in a grid-box model to match the plume model's output.

Currently, we are focusing on the development of the contrail modeling components of APCEMM. The chemistry modules are for the time being incompatible with the current version of the code and hence should be disabled until development resumes.

APCEMM Development

The development of APCEMM in C++ started in September 2018.

This repository contains multiple branches. Each branch pertains to a specific function.

  • The main branch always contains the most up-to-date and stable version. New code should never be added to that branch directly. Instead, a new branch, forked from master, should be created.
  • The dev* branch contains in-development code for future versions.

For VSCode users, a Docker Dev Container is defined in .devcontainer. See the tutorial to develop inside a containerized environment.

Dependencies

These are all managed using the vcpkg tool (see below) so do not need to be installed explicitly.

  • netcdf-c (requires HDF5 and zlib)
  • netcdf-cxx4
  • Catch2
  • FFTW3
  • OpenMP
  • Boost libraries
  • yaml-cpp
  • Eigen3

See the Dockerfile in the .devcontainer directory for specifics.

APCEMM: Installation instructions

APCEMM can be built using CMake and requires GCC >= 11.2. Previously, the dependency structure and compile instructions were specified using manually generated Makefiles. CMake generates these Makefiles automatically, and should lead to a more pleasant software build experience. Dependencies on external libraries are managed using the vcpkg tool, which is installed as a Git submodule. (This means that you just need to run the git submodule update command below to set it up.)

CMake will generate a single executable APCEMM that can receive an input file input.yaml. To compile this executable, you can call CMake as follows:

git submodule update --init --recursive
mkdir build
cd build
cmake ../Code.v05-00
cmake --build .

The git submodule update command installs the vcpkg dependency management tool, and the first time that you run CMake, all of the C++ dependencies will be installed. This will take some time, but subsequent runs of CMake will use cached binary builds of the dependencies, so will be much quicker.

The above commands will generate the APCEMM executable in the build directory (an "out-of-source" build). It is also possible to perform a build directly in the Code.v05-00 directory, but this is not preferred. You can perform an "out-of-source" build anywhere that it's convenient, simply by calling CMake from within a different directory. For example,

cd APCEMM/rundirs/SampleRunDir/
cmake ../../Code.v05-00
cmake --build .

will generate the executable in the rundirs/SampleRunDir/ directory.

Getting Started

To start a run from the aforementioned rundirs/SampleRunDir, simply call:

./../../Code.v05-00 input.yaml

Three examples and their accompanying jupyter notebooks for postprocessing tutorials are provided in the examples folder. The first example is one where the contrail doesn't persists, and only focuses on analyzing the output of the early plume model (EPM) module of APCEMM. The second example is a persistent contrail simulation where the ice supersaturated layer depth is specified. The third example features using a meteorological input file.

The input file options are explained via comments in the file rundirs/SampleRunDir/input.yaml

Advanced simulation parameters hidden in the input files (e.g. Aerosol bin size ratios, minimum/max bin aerosol sizes, etc) can be modified in Code.v05-00/src/include/Parameters.hpp.

Debugging

APCEMM can be compiled in debug mode to ensure reproducible results during testing. This fixes the seed of the random number generator and enforces single threaded computation. It can be enabled by passing the -DDEBUG=ON flag to CMake:

cmake ../Code.v05-00 -DDEBUG=ON

To debug APCEMM using gdb and the VSCode debugger the binary can be compiled with debug instructions by adding the -DCMAKE_BUILD_TYPE="Debug" flag. This comes at a significant cost in performance.

cmake ../Code.v05-00 -DCMAKE_BUILD_TYPE="Debug"

Here's an example configuration of the VSCode debugger in APCEMM/.vscode/launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch APCEMM debug",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/rundirs/debug/APCEMM",
            "cwd": "${workspaceFolder}/rundirs/debug/test_rundir/",
            "args": ["${workspaceFolder}/examples/Example1_EPM/input.yaml"],
            "environment": [
                {
                    "name": "LD_LIBRARY_PATH",
                    "value": "${workspaceFolder}/build/lib"
                },
            ],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        },
    ]
}

This configuration runs the APCEMM binary located in "${workspaceFolder}/rundirs/debug/ using the input file located in ${workspaceFolder}/examples/Example1_EPM/input.yaml and the working directory ${workspaceFolder}/rundirs/debug/test_rundir/. Paths can be changed to suit the case to debug.

apcemm's People

Contributors

aagarwal93 avatar dcdrake avatar ddrake-mitre avatar fritzt avatar ian-ross avatar lrobion avatar michaelxu3 avatar sdeastham avatar speth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

apcemm's Issues

No unit tests

APCEMM currently has no unit tests. Adding these will allow us to verify the implementation of the various physical mechanisms and numerical methods contained within the model. As we further develop the model, we can use automated testing to guarantee that changes do not break the code.

Uninitialized aerArray causes failure of EPM

double varSoot = Soot_amb + EI.getSoot() / ( 4.0 / double(3.0) * physConst::PI * physConst::RHO_SOOT * 1.00E+03 * EI.getSootRad() * EI.getSootRad() * EI.getSootRad() ) * AC.FuelFlow() / double(AC.EngNumber()) / AC.VFlight() / Ab0 * 1.00E-06 ; /* [ #/cm^3 ] */

In tests on the Imperial HPC system, the EPM never finds water saturation. After some debugging I believe this line is the issue. The variable varSoot is important, but it relies on Soot_amb, which is set at

double Soot_amb = aerArray[ind_SOOT][0]/n_air_amb; ///n_air_amb; /* [#/cm^3] */

That in turn relies on aerArray[ind_SOOT][0] - however, as far as I can tell, this is not set after first being declared. In LAGRIDPlumeModel the line in question is

double aerArray[N_AER][2]; /* aerArray stores all the number concentrations of aerosols */

although the same issue appears to affect PlumeModel. It looks like this error crept in when the line ambientData.getData( aerArray, nTime ); was deleted in the LAGRID update. Setting aerArray to be filled with zeros appears to at least let the code run but it would be good to get input from @michaelxu3 on a more robust solution that brings in the missing data (i.e. initial conditions from ambient data).

Error with Eigen Dependency during APCEMM compilation

Current Behavior:

Attempting to build APCEMM within a Docker image results in the following terminal error:

Consolidate compiler generated dependencies of target FVM_ANDS
[ 10%] Building CXX object src/FVM_ANDS/CMakeFiles/FVM_ANDS.dir/AdvDiffSystem.cpp.o
In file included from /home/APCEMM/Code.v05-00/src/FVM_ANDS/AdvDiffSystem.cpp:1:
/home/APCEMM/Code.v05-00/include/FVM_ANDS/AdvDiffSystem.hpp: In member function 'void FVM_ANDS::AdvDiffSystem::updatePhi(const VectorXd&)':
/home/APCEMM/Code.v05-00/include/FVM_ANDS/AdvDiffSystem.hpp:46:29: error: 'seq' is not a member of 'Eigen'; did you mean 'pstl::execution::v1::seq'?
46 | phi
(Eigen::seq(0, nx
* ny_ - 1)) = phi_new(Eigen::seq(0, nx_ * ny_ - 1));
| ^~~
In file included from /usr/local/include/c++/9.3.0/pstl/glue_algorithm_defs.h:15,
from /usr/local/include/c++/9.3.0/algorithm:71,
from /usr/include/eigen3/Eigen/Core:288,
from /usr/include/eigen3/Eigen/SparseCore:11,
from /usr/include/eigen3/Eigen/Sparse:26,
from /home/APCEMM/Code.v05-00/include/FVM_ANDS/AdvDiffSystem.hpp:4,
from /home/APCEMM/Code.v05-00/src/FVM_ANDS/AdvDiffSystem.cpp:1:
/usr/local/include/c++/9.3.0/pstl/execution_defs.h:112:28: note: 'pstl::execution::v1::seq' declared here
112 | constexpr sequenced_policy seq{};
| ^~~
In file included from /home/APCEMM/Code.v05-00/src/FVM_ANDS/AdvDiffSystem.cpp:1:
/home/APCEMM/Code.v05-00/include/FVM_ANDS/AdvDiffSystem.hpp:46:69: error: 'seq' is not a member of 'Eigen'; did you mean 'pstl::execution::v1::seq'?
46 | phi
(Eigen::seq(0, nx
* ny
- 1)) = phi_new(Eigen::seq(0, nx
* ny_ - 1));
| ^~~
In file included from /usr/local/include/c++/9.3.0/pstl/glue_algorithm_defs.h:15,
from /usr/local/include/c++/9.3.0/algorithm:71,
from /usr/include/eigen3/Eigen/Core:288,
from /usr/include/eigen3/Eigen/SparseCore:11,
from /usr/include/eigen3/Eigen/Sparse:26,
from /home/APCEMM/Code.v05-00/include/FVM_ANDS/AdvDiffSystem.hpp:4,
from /home/APCEMM/Code.v05-00/src/FVM_ANDS/AdvDiffSystem.cpp:1:
/usr/local/include/c++/9.3.0/pstl/execution_defs.h:112:28: note: '__pstl::execution::v1::seq' declared here
112 | constexpr sequenced_policy seq{};
| ^~~
make[2]: *** [src/FVM_ANDS/CMakeFiles/FVM_ANDS.dir/build.make:76: src/FVM_ANDS/CMakeFiles/FVM_ANDS.dir/AdvDiffSystem.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:1296: src/FVM_ANDS/CMakeFiles/FVM_ANDS.dir/all] Error 2
make: *** [Makefile:101: all] Error 2

Expected Behavior:

No error messages should appear when building APCEMM from the VS Docker terminal.

Steps To Reproduce:

  1. Git checkout to commit ending in 1b07fbb
  2. Open the APCEMM folder in VS Code
  3. Run Docker
  4. Install the "Dev Containers" VS Code extension (if not already installed)
  5. Open the APCEMM folder in a VS Docker image by following the Dev Containers tutorial here
  6. On the VS Docker image terminal: cd APCEMM/Code.v05-00
  7. On the VS Docke image terminal: cmake .
  8. On the VS Docke image terminal: cmake --build .

Environment Details

VS Code version: 1.83.1
Dev Containers version: 0.315.1
Docker version: 4.24.0
OS: Windows 10 Pro
OS Version: 22H2
OS Build: 19045.3570

Anything else:

I have tried the following steps to fix this so far without success:

  • Installing Eigen from the VS Docker terminal before running the CMAKE commands by using: sudo apt install libeigen3-dev

This is a follow-on issue to APCEMM issue #5.

@sdeastham @michaelxu3 @ddrake-mitre

The Saturation Depth Does Not Appear to Be Respected

I have noticed that the saturation depth (meant to be 1000m) does not appear to be respected in the current version of APCEMM. See the figures below:

fig-alt
fig-RHi
The RHi and altitude are both taken with index selection at x_i = 0 and y_i = 0 so they are not representative of the contrail centre.

The input.yaml file I used is available here

@michaelxu3
@sdeastham

SEGFAULT loading met data with time-varying RHw

I am trying to load a met data file that has a RH values for 24 time steps and 28 altitude steps. This causes APCEMM to throw a segfault. I dug into the issue a little bit and found that the segfault occurs at line 440 of Meteorology.cpp.

Here is the code in question starting at line 433:

//Assumes constant RHw for the entire domain

/* Define temperature input dimension */
NcVar relhumid_ncVar = dataFile.getVar("relative_humidity");
relhumid_ncVar.getVar(relhumid_init);

/* Identify temperature at above pressure */
RHw_user = relhumid_init[i_Zp];

The issue is that relhumid_init is an array that is of length altitudeDim. When relhumid_ncVar.getVar gets called, it writes 24*28 floats to relhumid_init because of the size of the RH values stored in the data being loaded. This clobbers a bunch of variables including i_Zp which causes the segfault on line 440.

Is there any way to run APCEMM in a way that accounts for changing RH values or does the met data need to be contained to only having data from a single time? If the later is true you may wish to check the dimensions of the met data and raise an error here rather than allowing the code to segfault.

Vertical velocities from netCDF input

I've been running some APCEMM simulations with met data read from a netCDF file and have noticed what seems like strange behavior: I get different results from a simulation that doesn't read vertical velocities and from a simulation that reads a vertical velocity field that's zero everywhere.

This zip archive includes a sample netCDF file and two YAML files that reproduce this issue:

input.zip

When I run without reading vertical velocities (w_off.yaml), I get this IWC field after 1 hour:

image

When I run a simulation that reads vertical velocities equal to zero everywhere (w_on.yaml), I get a different result:

image

(I'm open to the possibility that this is an issue with the way I've set up my APCEMM input files--if that's the case please let me know!)

Recurring horizontal stripe pattern appears in H2O field

In the current version of APCEMM, a strange striping seems to occur. If all transport and ice growth processes are turned off, and the contrail size is expanded to 5 times normal, you can see this evolving over several time steps. This is generally somewhat difficult to observe, but does bias simulations and may increase in visibility with decreasing time step length. Results below are from a simulation with a one minute transport time step and fixed meteorology (100 meter discretization, which appears to be related to the odd striping pattern frequency):

image

Additional debugging suggests this is occurring during the call to remapVariable. Further diagnosis is underway.

Voids appearing in the H2O field

Near-zero values appear in the H2O field at the end of some time steps. This appears to be due to a bug in the remapping algorithm.

image

Docker image not able to be run

Current Behavior:

Attempting to run a docker image of APCEMM results in the following error:

Error: (HTTP code 400) unexpected - failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "/usr/sbin/sshd": stat /usr/sbin/sshd: no such file or directory: unknown

Expected Behavior:

Docker image should run without any error messages

Steps To Reproduce:

  1. Git checkout to commit ending in 1b07fbb
  2. On the command line (CMD) cd to APCEMM's root repository
  3. Run the following command in the terminal: docker build . -t apcemm -f .devcontainer/Dockerfile.apcemm
  4. Open docker desktop
  5. Navigate to the "Images" tab
  6. Find the "apcemm" image
  7. Under "Actions", click on the play symbol that displays "Run" when you hover over it

Environment Details

  • Docker version: 4.24.0
  • OS: Windows 10 Pro
  • OS Version: 22H2
  • OS Build: 19045.3570

Anything else:

It is my first time running an instance of Docker, so I might have missed something obvious.

@ddrake-mitre @sdeastham

Default time step is too long for high RHi cases

The default transport and ice growth time steps are currently 10 minutes, which is too long for high RHi cases. See below - when ice crystals are able to grow large, they settle through many grid cells in a single step. As a result, water in the intervening cells is not taken up, resulting in "pulse-like" behaviour:

image

Reducing the time step to one minute improves (but does not fully fix) this issue:

image

Not only is this an imperfect fix, it increases run times significantly (~4x in the given test case, going from 30 seconds to 2 minutes). It would be better to find other fixes (e.g. include simplified ice growth in transport sub-cycling).

Inconsistent Results When "OpenMP Num Threads" is Greater Than 1

There seems to be an issue with threads reading and writing parts of the memory at the same time.

Here are APCEMM outputs with two consecutive runs when using 8 threads:
Run1
Run2

I was not able to recreate the random jumps with OpenMP Num Threads set to 1, but I was with more threads.

Eigen3 dependencies

It wasn't clear to me why we specify NO_MODULE in the search for Eigen3. I found that Eigen3 could most easily located by first removing NO_MODULE from the CMakeLists.txt file, including the FindEigen3.cmake file (which is provided by the Eigen3 authors) in the cmake directory, and then including the Eigen3 directory in the CMAKE_PREFIX_PATH. Is there a reason this shouldn't become the standard approach? Open to all possibilities (curious to get your thougths @michaelxu3 !)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.