Skip to content

Commit

Permalink
Add Fortran API for functionspace::CellColumns (#164)
Browse files Browse the repository at this point in the history
Add FortranAPI for CellColumns including unit test
  • Loading branch information
sbrdar authored Nov 20, 2023
1 parent 4c27375 commit 99207ce
Show file tree
Hide file tree
Showing 7 changed files with 800 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/atlas/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,8 @@ functionspace/detail/BlockStructuredColumns.h
functionspace/detail/BlockStructuredColumns.cc
functionspace/detail/BlockStructuredColumnsInterface.h
functionspace/detail/BlockStructuredColumnsInterface.cc
functionspace/detail/CellColumnsInterface.h
functionspace/detail/CellColumnsInterface.cc
functionspace/detail/FunctionSpaceImpl.h
functionspace/detail/FunctionSpaceImpl.cc
functionspace/detail/FunctionSpaceInterface.h
Expand Down
155 changes: 155 additions & 0 deletions src/atlas/functionspace/detail/CellColumnsInterface.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
* (C) Copyright 2013 ECMWF.
*
* This software is licensed under the terms of the Apache Licence Version 2.0
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
* In applying this licence, ECMWF does not waive the privileges and immunities
* granted to it by virtue of its status as an intergovernmental organisation
* nor does it submit to any jurisdiction.
*/

#include <cstring>

#include "CellColumnsInterface.h"
#include "atlas/field/FieldSet.h"
#include "atlas/field/detail/FieldImpl.h"
#include "atlas/runtime/Exception.h"

namespace atlas {
namespace functionspace {
namespace detail {

using atlas::FieldSet;
using atlas::field::FieldImpl;
using atlas::field::FieldSetImpl;

// ----------------------------------------------------------------------

extern "C" {
const CellColumns* atlas__CellsFunctionSpace__new(Mesh::Implementation* mesh, const eckit::Configuration* config) {
ATLAS_ASSERT(mesh);
Mesh m(mesh);
return new CellColumns(m, *config);
}

void atlas__CellsFunctionSpace__delete(CellColumns* This) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
delete (This);
}

int atlas__CellsFunctionSpace__nb_cells(const CellColumns* This) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
return This->nb_cells();
}

const Mesh::Implementation* atlas__CellsFunctionSpace__mesh(const CellColumns* This) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
return This->mesh().get();
}

const mesh::HybridElements* atlas__CellsFunctionSpace__cells(const CellColumns* This) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
return &This->cells();
}

void atlas__CellsFunctionSpace__halo_exchange_fieldset(const CellColumns* This, field::FieldSetImpl* fieldset) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
ATLAS_ASSERT(fieldset != nullptr, "Cannot access uninitialised atlas_FieldSet");
FieldSet f(fieldset);
This->haloExchange(f);
}

void atlas__CellsFunctionSpace__halo_exchange_field(const CellColumns* This, field::FieldImpl* field) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
ATLAS_ASSERT(field != nullptr, "Cannot access uninitialised atlas_Field");
Field f(field);
This->haloExchange(f);
}

const parallel::HaloExchange* atlas__CellsFunctionSpace__get_halo_exchange(const CellColumns* This) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
return &This->halo_exchange();
}

void atlas__CellsFunctionSpace__gather_fieldset(const CellColumns* This, const field::FieldSetImpl* local,
field::FieldSetImpl* global) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
ATLAS_ASSERT(local != nullptr, "Cannot access uninitialised local atlas_FieldSet");
ATLAS_ASSERT(global != nullptr, "Cannot access uninitialised global atlas_FieldSet");
const FieldSet l(local);
FieldSet g(global);
This->gather(l, g);
}

void atlas__CellsFunctionSpace__gather_field(const CellColumns* This, const field::FieldImpl* local,
field::FieldImpl* global) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
ATLAS_ASSERT(local != nullptr, "Cannot access uninitialised local atlas_Field");
ATLAS_ASSERT(global != nullptr, "Cannot access uninitialised global atlas_Field");
const Field l(local);
Field g(global);
This->gather(l, g);
}

const parallel::GatherScatter* atlas__CellsFunctionSpace__get_gather(const CellColumns* This) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
return &This->gather();
}

const parallel::GatherScatter* atlas__CellsFunctionSpace__get_scatter(const CellColumns* This) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
return &This->scatter();
}

void atlas__CellsFunctionSpace__scatter_fieldset(const CellColumns* This, const field::FieldSetImpl* global,
field::FieldSetImpl* local) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
ATLAS_ASSERT(local != nullptr, "Cannot access uninitialised local atlas_FieldSet");
ATLAS_ASSERT(global != nullptr, "Cannot access uninitialised global atlas_FieldSet");
const FieldSet g(global);
FieldSet l(local);
This->scatter(g, l);
}

void atlas__CellsFunctionSpace__scatter_field(const CellColumns* This, const field::FieldImpl* global,
field::FieldImpl* local) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
ATLAS_ASSERT(local != nullptr, "Cannot access uninitialised local atlas_Field");
ATLAS_ASSERT(global != nullptr, "Cannot access uninitialised global atlas_Field");
const Field g(global);
Field l(local);
This->scatter(g, l);
}

const parallel::Checksum* atlas__CellsFunctionSpace__get_checksum(const CellColumns* This) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
return &This->checksum();
}

void atlas__CellsFunctionSpace__checksum_fieldset(const CellColumns* This, const field::FieldSetImpl* fieldset,
char*& checksum, int& size, int& allocated) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
ATLAS_ASSERT(fieldset != nullptr, "Cannot access uninitialised atlas_FieldSet");
std::string checksum_str(This->checksum(fieldset));
size = static_cast<int>(checksum_str.size());
checksum = new char[size + 1];
allocated = true;
std::strncpy(checksum, checksum_str.c_str(), size + 1);
}

void atlas__CellsFunctionSpace__checksum_field(const CellColumns* This, const field::FieldImpl* field, char*& checksum,
int& size, int& allocated) {
ATLAS_ASSERT(This != nullptr, "Cannot access uninitialised atlas_functionspace_CellColumns");
ATLAS_ASSERT(field != nullptr, "Cannot access uninitialised atlas_Field");
std::string checksum_str(This->checksum(field));
size = static_cast<int>(checksum_str.size());
checksum = new char[size + 1];
allocated = true;
std::strncpy(checksum, checksum_str.c_str(), size + 1);
}

} // extern C

} // namespace detail
} // namespace functionspace
} // namespace atlas
59 changes: 59 additions & 0 deletions src/atlas/functionspace/detail/CellColumnsInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* (C) Copyright 2013 ECMWF.
*
* This software is licensed under the terms of the Apache Licence Version 2.0
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
* In applying this licence, ECMWF does not waive the privileges and immunities
* granted to it by virtue of its status as an intergovernmental organisation
* nor does it submit to any jurisdiction.
*/

#pragma once

#include "atlas/functionspace/CellColumns.h"
#include "atlas/mesh/Mesh.h"

namespace atlas {
namespace field {
class FieldSetImpl;
class FieldImpl;
} // namespace field
} // namespace atlas

namespace atlas {
namespace functionspace {
namespace detail {

extern "C" {
const CellColumns* atlas__CellsFunctionSpace__new(Mesh::Implementation* mesh, const eckit::Configuration* config);
void atlas__CellsFunctionSpace__delete(CellColumns* This);
int atlas__CellsFunctionSpace__nb_cells(const CellColumns* This);
const Mesh::Implementation* atlas__CellsFunctionSpace__mesh(const CellColumns* This);
const mesh::HybridElements* atlas__CellsFunctionSpace__cells(const CellColumns* This);

void atlas__CellsFunctionSpace__halo_exchange_fieldset(const CellColumns* This, field::FieldSetImpl* fieldset);
void atlas__CellsFunctionSpace__halo_exchange_field(const CellColumns* This, field::FieldImpl* field);
const parallel::HaloExchange* atlas__CellsFunctionSpace__get_halo_exchange(const CellColumns* This);

void atlas__CellsFunctionSpace__gather_fieldset(const CellColumns* This, const field::FieldSetImpl* local,
field::FieldSetImpl* global);
void atlas__CellsFunctionSpace__gather_field(const CellColumns* This, const field::FieldImpl* local,
field::FieldImpl* global);
const parallel::GatherScatter* atlas__CellsFunctionSpace__get_gather(const CellColumns* This);

void atlas__CellsFunctionSpace__scatter_fieldset(const CellColumns* This, const field::FieldSetImpl* global,
field::FieldSetImpl* local);
void atlas__CellsFunctionSpace__scatter_field(const CellColumns* This, const field::FieldImpl* global,
field::FieldImpl* local);
const parallel::GatherScatter* atlas__CellsFunctionSpace__get_scatter(const CellColumns* This);

void atlas__CellsFunctionSpace__checksum_fieldset(const CellColumns* This, const field::FieldSetImpl* fieldset,
char*& checksum, int& size, int& allocated);
void atlas__CellsFunctionSpace__checksum_field(const CellColumns* This, const field::FieldImpl* field, char*& checksum,
int& size, int& allocated);
const parallel::Checksum* atlas__CellsFunctionSpace__get_checksum(const CellColumns* This);
}

} // namespace detail
} // namespace functionspace
} // namespace atlas
4 changes: 4 additions & 0 deletions src/atlas_f/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/functionspace/detail/Structu
generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/functionspace/detail/BlockStructuredColumnsInterface.h
MODULE atlas_functionspace_BlockStructuredColumns_c_binding
OUTPUT functionspace_BlockStructuredColumns_c_binding.f90 )
generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/functionspace/detail/CellColumnsInterface.h
MODULE atlas_functionspace_CellColumns_c_binding
OUTPUT functionspace_CellColumns_c_binding.f90)
generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/functionspace/detail/NodeColumnsInterface.h
MODULE atlas_functionspace_NodeColumns_c_binding
OUTPUT functionspace_NodeColumns_c_binding.f90)
Expand Down Expand Up @@ -213,6 +216,7 @@ ecbuild_add_library( TARGET atlas_f
domain/atlas_Domain_module.F90
functionspace/atlas_FunctionSpace_module.F90
functionspace/atlas_functionspace_EdgeColumns_module.F90
functionspace/atlas_functionspace_CellColumns_module.F90
functionspace/atlas_functionspace_NodeColumns_module.fypp
functionspace/atlas_functionspace_StructuredColumns_module.F90
functionspace/atlas_functionspace_BlockStructuredColumns_module.F90
Expand Down
2 changes: 2 additions & 0 deletions src/atlas_f/atlas_module.F90
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ module atlas_module
& atlas_Vertical
use atlas_functionspace_EdgeColumns_module, only: &
& atlas_functionspace_EdgeColumns
use atlas_functionspace_CellColumns_module, only: &
& atlas_functionspace_CellColumns
use atlas_functionspace_NodeColumns_module, only: &
& atlas_functionspace_NodeColumns
use atlas_functionspace_PointCloud_module, only: &
Expand Down
Loading

0 comments on commit 99207ce

Please sign in to comment.