Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interface for ELM->ATS coupling - WIP #216

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
20dae3c
added basic ELM-ATS interface
jbeisman Sep 14, 2022
eada89b
replace Coordinator's constructor with default constructor and move i…
jbeisman Sep 15, 2022
312aa7b
ELM->ATS driver
jbeisman Sep 15, 2022
bba9dee
added CMakeLists.txt and updated a few things; interface is compiling…
jbeisman Sep 16, 2022
2704dd9
add C++ and Fortran tests - both currently passing column tests
jbeisman Sep 16, 2022
704c25c
organized api directory structure and build system
jbeisman Sep 17, 2022
5e59a11
update to be inline with recent Amanzi and ATS changes
jbeisman Sep 20, 2022
a68f7b7
Merge branch 'master' into jb/elm_api
jbeisman Sep 20, 2022
b68126c
a few changes to the ELM API. Work in progress with ELM
ecoon Sep 27, 2022
fdffc7b
removes indexer for now -- will revisit
ecoon Sep 28, 2022
c94ba70
Merge branch 'jb/elm_api' of https://github.com/amanzi/ats into jb/el…
ecoon Nov 2, 2022
b5b3325
merge from master
ecoon Nov 16, 2022
9ffa11e
updates ELM API, updates implementation of the API
ecoon Nov 18, 2022
f186146
updates to ELM api
ecoon Nov 22, 2022
fe63ea8
debugging ELM-ATS api
ecoon Nov 22, 2022
f2a69e5
Merge branch 'master' of github.com:amanzi/ats into jb/elm_api
jbeisman Mar 14, 2023
a48e52e
Fix from merge - replace registration includes with ats_registrations…
jbeisman Mar 15, 2023
bb24059
Fixed naming confusion and changed some function signatures in API
jbeisman Mar 16, 2023
5f87eff
Got cc driver test working
jbeisman Mar 16, 2023
f105cbc
Got Fortran driver test working
jbeisman Mar 16, 2023
7f5683f
ELM->ATS coupling progress
jbeisman Apr 25, 2023
90c62dc
updates to ELM->ATS driver
jbeisman May 16, 2023
e575f10
Working changes to ELM-ATS driver - fluxes and state variables are pa…
jbeisman Jun 27, 2023
f6252d3
Merge remote-tracking branch 'origin/master' into jb/elm_api
jbeisman Jun 27, 2023
347a002
changes to driver - hydrostatic initialization option, convenience dz…
jbeisman Jul 20, 2023
a1be5ad
stash working changes before merge
jbeisman Jul 21, 2023
33ea9ea
Merge remote-tracking branch 'origin' into jb/elm_api
jbeisman Jul 21, 2023
7351d45
updates to driver and ELM interface
jbeisman Aug 3, 2023
475acee
update tests to work with 2D hillslope example
jbeisman Aug 3, 2023
208a280
Added a few more options for passing ATS transpiration fluxes to ELM.
jbeisman Aug 9, 2023
ed2d16f
Added some comments to ELM-ATS driver
jbeisman Oct 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/documentation/source/ats_demos
Submodule ats_demos updated 50 files
+4 −4 01_richards_steadystate/richards_steadystate.ipynb
+23 −45 01_richards_steadystate/richards_steadystate.xml
+22 −13 02_richards/infiltration.xml
+22 −13 02_richards/infiltration_then_seepage.xml
+13 −13 02_richards/richards.ipynb
+18 −10 02_richards/seepage_drawdown.xml
+21 −13 02_richards/seepage_exfiltration.xml
+22 −13 02_richards/seepage_infiltration.xml
+31 −19 03_surface_water/critical_depth.xml
+31 −19 03_surface_water/max_head.xml
+8 −8 03_surface_water/surface_water.ipynb
+31 −19 03_surface_water/surface_water.xml
+31 −19 03_surface_water/zero_gradient.xml
+6 −6 04_integrated_hydro/IHMIP_units.ipynb
+56 −32 04_integrated_hydro/column.xml
+51 −29 04_integrated_hydro/infiltration_limited1.xml
+51 −29 04_integrated_hydro/infiltration_limited2.xml
+51 −29 04_integrated_hydro/infiltration_limited3.xml
+39 −37 04_integrated_hydro/integrated_hydro.ipynb
+51 −29 04_integrated_hydro/saturation_limited1.xml
+51 −29 04_integrated_hydro/saturation_limited2.xml
+51 −29 04_integrated_hydro/saturation_limited3.xml
+117 −109 04_integrated_hydro/superslab.xml
+56 −31 04_integrated_hydro/transect.xml
+ 05_ecohydrology/data/daymet.h5
+ 05_ecohydrology/data/prescribed_pet.h5
+80 −49 05_ecohydrology/dynamic_vegetation.xml
+1 −0 05_ecohydrology/ecohydrology.cfg
+103 −93 05_ecohydrology/ecohydrology.ipynb
+154 −131 05_ecohydrology/full_energy.xml
+116 −65 05_ecohydrology/prescribed_surface_evaporation.xml
+129 −69 05_ecohydrology/prescribed_transpiration.xml
+115 −81 05_ecohydrology/priestley_taylor.xml
+133 −174 05_ecohydrology/priestley_taylor_canopy_evapotranspiration.xml
+162 −116 05_ecohydrology/simple_energy.xml
+53 −33 05_ecohydrology/spinup.xml
+17 −9 05_ecohydrology/spinup_vegetation.xml
+0 −490 05_ecohydrology/water_balance_pt_canopy.ipynb
+10 −23 06_arctic_hydrology/arctic_hydrology.ipynb
+ 06_arctic_hydrology/data/spinup-10yr.h5
+115 −20 06_arctic_hydrology/freezeup.xml
+151 −98 06_arctic_hydrology/permafrost_column.xml
+138 −80 06_arctic_hydrology/permafrost_transect.xml
+81 −23 06_arctic_hydrology/surface_water_icedam.xml
+105 −26 08_integrated_hydro_transport/hillslope.xml
+196 −86 13_integrated_hydro_reactive_transport/1d-infiltration-column.xml
+1 −1 13_integrated_hydro_reactive_transport/data/1d-calcite-crunch.in
+164 −109 13_integrated_hydro_reactive_transport/hillslope_calcite_crunch_sigmoid.xml
+93 −28 13_integrated_hydro_reactive_transport/integrated_hydro_reactive_transport-superslab.xml
+86 −34 13_integrated_hydro_reactive_transport/integrated_hydro_reactive_transport.ipynb
11 changes: 10 additions & 1 deletion src/executables/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ include_directories(${ATS_SOURCE_DIR}/src/pks)
include_directories(${ATS_SOURCE_DIR}/src/pks/mpc)
include_directories(${ATS_SOURCE_DIR}/src/pks/energy)
include_directories(${ATS_SOURCE_DIR}/src/pks/flow)
include_directories(${ATS_SOURCE_DIR}/src/pks/deformation)
include_directories(${ATS_SOURCE_DIR}/src/pks/deform)
include_directories(${ATS_SOURCE_DIR}/src/pks/transport)
include_directories(${ATS_SOURCE_DIR}/src/operators/upwinding)
include_directories(${ATS_SOURCE_DIR}/src/operators/advection)
Expand Down Expand Up @@ -182,3 +182,12 @@ add_amanzi_executable(ats
LINK_LIBS ats_executable ${fates_link_libs} ${tpl_link_libs} ${ats_link_libs} ${amanzi_link_libs}
OUTPUT_NAME ats
OUTPUT_DIRECTORY ${ATS_BINARY_DIR})


# set this here for now
# add option to bootstrap before completion
set (BUILD_ELM_ATS_API true)
if (BUILD_ELM_ATS_API)
message("building elm_ats api")
add_subdirectory(elm_ats_api)
endif()
47 changes: 47 additions & 0 deletions src/executables/elm_ats_api/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# -*- mode: cmake -*-
#
# ELM_ATS_API
# library
#
# builds both dynamic and static libs for now
# need to add build logic to make configurable

# verify the compatibility of the C/Fortran and C++/Fortran compilers
# Amanzi probably does this somewhere upstream, should check
include(FortranCInterface)
FortranCInterface_VERIFY(CXX)

include_directories(${ATS_SOURCE_DIR}/src/executables)

set(elm_ats_src_files
${ATS_SOURCE_DIR}/src/executables/coordinator.cc
${ATS_SOURCE_DIR}/src/executables/ats_mesh_factory.cc
elm_ats_driver.cc
elm_ats_api.cc
)

set(elm_ats_inc_files
${ATS_SOURCE_DIR}/src/executables/coordinator.hh
${ATS_SOURCE_DIR}/src/executables/ats_mesh_factory.hh
elm_ats_driver.hh
elm_ats_api.h
)

## build shared lib
add_amanzi_library(elm_ats
SOURCE ${elm_ats_src_files}
HEADERS ${elm_ats_inc_files}
LINK_LIBS ${fates_link_libs} ${tpl_link_libs} ${ats_link_libs} ${amanzi_link_libs})
if (APPLE AND BUILD_SHARED_LIBS)
set_target_properties(elm_ats PROPERTIES LINK_FLAGS "-Wl,-undefined,dynamic_lookup")
endif()

# ## build static lib
# add_amanzi_library(elm_ats_static
# STATIC
# SOURCE ${elm_ats_src_files}
# HEADERS ${elm_ats_inc_files}
# LINK_LIBS ${fates_link_libs} ${tpl_link_libs} ${ats_link_libs} ${amanzi_link_libs})

# re-enable later
add_subdirectory(test)
108 changes: 108 additions & 0 deletions src/executables/elm_ats_api/Indexer.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
ATS is released under the three-clause BSD License.
The terms of use and "as is" disclaimer for this license are
provided in the top-level COPYRIGHT file.

Authors: Ethan Coon
*/
//! Tools for indexing arbitrary arrays in a variety of ways.

#pragma once


namespace ATS {
namespace Utils {

enum class Indexer_kind {
SCALAR = 0,
ELM,
ATS
};

enum class Domain_kind {
SURF,
SUBSURF
};


template<Indexer_kind ikind, Domain_kind dkind, typename T> struct Indexer;

//
// Indexer for scalars.
//
template<Domain_kind dkind, typename T>
struct Indexer<Indexer_kind::SCALAR, dkind, T> {
template<typename D = T>
typename std::enable_if<dkind == Domain_kind::SUBSURF, D&>::type
get(T const * const& val, const int col, const int cic) const { return *val_; }

template<typename D = T>
typename std::enable_if<dkind == Domain_kind::SURF, D&>::type
get(T const * const& val, const int i) const { return *val_; }

private:
T* val_;
};


//
// Indexer for ELM
//
template<Domain_kind dkind, typename T>
struct Indexer<Indexer_kind::ELM, dkind, T> {

Indexer(int ncells_per_col=-1)
: ncells_per_col_(ncells_per_col) {}

// for use by subsurface
template<typename D = T>
typename std::enable_if<dkind == Domain_kind::SUBSURF, D&>::type
get(T * const& val, const int col, const int cic) const {
return val[col * ncells_per_col_ + cic];
}

// for use by surface
template<typename D = T>
typename std::enable_if<dkind == Domain_kind::SURF, D&>::type
get(T * const& val, const int i) const {
return val[i];
}

private:
int ncells_per_col_;
};


//
// Indexer for ATS
//
template<Domain_kind dkind, typename T>
struct Indexer<Indexer_kind::ATS, dkind, T> {

Indexer(const Amanzi::AmanziMesh::Mesh& mesh)
: mesh_(mesh) {}

// for use by subsurface
template<typename D = T>
typename std::enable_if<dkind == Domain_kind::SUBSURF, T&>::type
get(T * const& val, const int col, const int cic) const {
return val[mesh_.cells_of_column(col)[cic]];
}

// for use by surface
template<typename D = T>
typename std::enable_if<dkind == Domain_kind::SURF, D&>::type
get(T * const& val, const int i) const {
return val[i];
}

private:
const Amanzi::AmanziMesh::Mesh& mesh_;
};





} // namespace Utils
} // namespace ATS
146 changes: 146 additions & 0 deletions src/executables/elm_ats_api/elm_ats_api.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
ATS is released under the three-clause BSD License.
The terms of use and "as is" disclaimer for this license are
provided in the top-level COPYRIGHT file.

Authors: Joe Beisman
Fenming Yuan
Ethan Coon
*/
//! Wrapper for driving ATS from ELM.

#include "elm_ats_driver.hh"
#include "elm_ats_api.h"

#ifdef __cplusplus
extern "C"{
#endif

// allocate, call constructor and cast ptr to opaque ELM_ATSDriver_ptr
ELM_ATSDriver_ptr ats_create(MPI_Fint *f_comm, const char *input_filename)
{
return reinterpret_cast<ELM_ATSDriver_ptr>(ATS::createELM_ATSDriver(f_comm, input_filename));
}

// reinterpret as elm_ats_driver and delete (calls destructor)
void ats_delete(ELM_ATSDriver_ptr ats)
{
auto ats_ptr = reinterpret_cast<ATS::ELM_ATSDriver*>(ats);
ats_ptr->finalize();
delete ats_ptr;
}

// call driver advance()
void ats_advance(ELM_ATSDriver_ptr ats,
double const * const dt,
bool const * const checkpoint,
bool const * const visualize)
{
reinterpret_cast<ATS::ELM_ATSDriver*>(ats)->advance(*dt, *checkpoint, *visualize);
}

// call driver advance_test()
void ats_advance_test(ELM_ATSDriver_ptr ats)
{
reinterpret_cast<ATS::ELM_ATSDriver*>(ats)->advance_test();
}

void ats_get_mesh_info(ELM_ATSDriver_ptr ats,
int * const ncols_local,
int * const ncols_global,
double * const lat,
double * const lon,
double * const elev,
double * const surf_area,
int * const pft,
int * const nlevgrnd,
double * const depth)
{
reinterpret_cast<ATS::ELM_ATSDriver*>(ats)->get_mesh_info(*ncols_local, *ncols_global,
lat, lon, elev, surf_area, pft, *nlevgrnd, depth);
}


// call driver setup()
void ats_setup(ELM_ATSDriver_ptr ats)
{
reinterpret_cast<ATS::ELM_ATSDriver*>(ats)->setup();
}

// call driver initialize()
void ats_initialize(ELM_ATSDriver_ptr ats,
double const * const start_time,
double const * const soil_water_content,
double const * const soil_pressure)
{
reinterpret_cast<ATS::ELM_ATSDriver*>(ats)->initialize(*start_time, soil_water_content, soil_pressure);
}


void ats_set_soil_hydrologic_parameters(ELM_ATSDriver_ptr ats,
double const * const base_porosity,
double const * const hydraulic_conductivity,
double const * const clapp_horn_b,
double const * const clapp_horn_smpsat,
double const * const clapp_horn_sr)
{
reinterpret_cast<ATS::ELM_ATSDriver*>(ats)
->set_soil_hydrologic_parameters(base_porosity, hydraulic_conductivity,
clapp_horn_b, clapp_horn_smpsat, clapp_horn_sr);
}


void ats_set_soil_hydrologic_properties(ELM_ATSDriver_ptr ats,
double const * const effective_porosity)
{
reinterpret_cast<ATS::ELM_ATSDriver*>(ats)
->set_soil_hydrologic_properties(effective_porosity);
}


// set veg properties, non-constant in time
void ats_set_veg_properties(ELM_ATSDriver_ptr ats,
double const * const rooting_fraction)
{
reinterpret_cast<ATS::ELM_ATSDriver*>(ats)
->set_veg_properties(rooting_fraction);
}


// call driver set_sources()
void ats_set_sources(ELM_ATSDriver_ptr ats,
double const * const surface_source,
double const * const potential_evaporation,
double const * const potential_transpiration)
{
reinterpret_cast<ATS::ELM_ATSDriver*>(ats)
->set_potential_sources(surface_source, potential_evaporation, potential_transpiration);
}


void ats_get_waterstate(ELM_ATSDriver_ptr ats,
double * const ponded_depth,
double * const water_table_depth,
double * const mass_water_content)
{
reinterpret_cast<ATS::ELM_ATSDriver*>(ats)
->get_waterstate(ponded_depth, water_table_depth, mass_water_content);
}


void ats_get_water_fluxes(ELM_ATSDriver_ptr ats,
double * const infiltration,
double * const evaporation,
double * const transpiration,
double * const root_flux,
double * net_subsurface_fluxes,
double * net_runon)
{
reinterpret_cast<ATS::ELM_ATSDriver*>(ats)
->get_water_fluxes(infiltration, evaporation, transpiration,
root_flux, net_subsurface_fluxes, net_runon);
}

#ifdef __cplusplus
}
#endif
Loading