From b8988b1246d83e828559bfbc40ac8e8c51ec893a Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Wed, 6 Sep 2023 19:47:58 +0200 Subject: [PATCH 1/3] Add capability to concatenate two fieldsets --- src/atlas/field/FieldSet.cc | 12 ++++++++++++ src/atlas/field/FieldSet.h | 3 +++ src/atlas_f/field/atlas_FieldSet_module.fypp | 13 +++++++++++-- src/tests/field/fctest_field.F90 | 13 +++++++++++-- src/tests/field/test_fieldset.cc | 17 +++++++++++++++++ 5 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/atlas/field/FieldSet.cc b/src/atlas/field/FieldSet.cc index e8ba510ce..d9ee713f9 100644 --- a/src/atlas/field/FieldSet.cc +++ b/src/atlas/field/FieldSet.cc @@ -102,6 +102,12 @@ Field FieldSetImpl::add(const Field& field) { return field; } +void FieldSetImpl::add(const FieldSet& fieldset) { + for( auto& field : fieldset) { + add(field); + } +} + bool FieldSetImpl::has(const std::string& name) const { return index_.count(name); } @@ -204,6 +210,12 @@ void atlas__FieldSet__add_field(FieldSetImpl* This, FieldImpl* field) { This->add(field); } +void atlas__FieldSet__add_fieldset(FieldSetImpl* This, FieldSetImpl* fieldset) { + ATLAS_ASSERT(This != nullptr, "Reason: Use of uninitialised atlas_FieldSet"); + ATLAS_ASSERT(fieldset != nullptr, "Reason: Use of uninitialised atlas_FieldSet"); + This->add(fieldset); +} + int atlas__FieldSet__has_field(const FieldSetImpl* This, char* name) { ATLAS_ASSERT(This != nullptr, "Reason: Use of uninitialised atlas_FieldSet"); return This->has(std::string(name)); diff --git a/src/atlas/field/FieldSet.h b/src/atlas/field/FieldSet.h index fbcd065d5..7e110b121 100644 --- a/src/atlas/field/FieldSet.h +++ b/src/atlas/field/FieldSet.h @@ -117,6 +117,7 @@ class FieldSetImpl : public util::Object { const std::vector& field_names() const; Field add(const Field&); + void add(const FieldSet&); bool has(const std::string& name) const; @@ -153,6 +154,7 @@ extern "C" { FieldSetImpl* atlas__FieldSet__new(char* name); void atlas__FieldSet__delete(FieldSetImpl* This); void atlas__FieldSet__add_field(FieldSetImpl* This, FieldImpl* field); +void atlas__FieldSet__add_fieldset(FieldSetImpl* This, FieldSetImpl* fieldset); int atlas__FieldSet__has_field(const FieldSetImpl* This, char* name); const char* atlas__FieldSet__name(FieldSetImpl* This); idx_t atlas__FieldSet__size(const FieldSetImpl* This); @@ -239,6 +241,7 @@ class FieldSet : DOXYGEN_HIDE(public util::ObjectHandle) { const std::vector& field_names() const { return get()->field_names(); } Field add(const Field& field) { return get()->add(field); } + void add(const FieldSet& fieldset) { return get()->add(fieldset); } bool has(const std::string& name) const { return get()->has(name); } diff --git a/src/atlas_f/field/atlas_FieldSet_module.fypp b/src/atlas_f/field/atlas_FieldSet_module.fypp index e337c958c..36a2a38da 100644 --- a/src/atlas_f/field/atlas_FieldSet_module.fypp +++ b/src/atlas_f/field/atlas_FieldSet_module.fypp @@ -51,7 +51,9 @@ contains procedure, private :: field_by_name procedure, private :: field_by_idx_int procedure, private :: field_by_idx_long - procedure, public :: add + procedure, public :: add_field + procedure, public :: add_fieldset + generic :: add => add_field, add_fieldset generic :: field => field_by_name, field_by_idx_int, field_by_idx_long procedure, public :: set_dirty @@ -213,7 +215,7 @@ function FieldSet__name(this) result(fieldset_name) fieldset_name = c_ptr_to_string(fieldset_name_c_str) end function FieldSet__name -subroutine add(this,field) +subroutine add_field(this,field) use atlas_fieldset_c_binding use atlas_Field_module, only: atlas_Field class(atlas_FieldSet), intent(in) :: this @@ -221,6 +223,13 @@ subroutine add(this,field) call atlas__FieldSet__add_field(this%CPTR_PGIBUG_A, field%CPTR_PGIBUG_A) end subroutine +subroutine add_fieldset(this,fset) + use atlas_fieldset_c_binding + class(atlas_FieldSet), intent(inout) :: this + class(atlas_FieldSet), intent(in) :: fset + call atlas__FieldSet__add_fieldset(this%CPTR_PGIBUG_A, fset%CPTR_PGIBUG_A) +end subroutine + function has(this,name) result(flag) use, intrinsic :: iso_c_binding, only: c_int use fckit_c_interop_module, only: c_str diff --git a/src/tests/field/fctest_field.F90 b/src/tests/field/fctest_field.F90 index 8ea98e09d..d934b4886 100644 --- a/src/tests/field/fctest_field.F90 +++ b/src/tests/field/fctest_field.F90 @@ -139,8 +139,8 @@ module fcta_Field_fixture TEST( test_fieldset ) implicit none - type(atlas_FieldSet) :: fieldset - type(atlas_Field) :: field + type(atlas_FieldSet) :: fieldset, fieldset_2 + type(atlas_Field) :: field, field_2 write(*,*) "test_fieldset starting" @@ -163,6 +163,15 @@ module fcta_Field_fixture FCTEST_CHECK_EQUAL( field%name(), "field_1" ) field = fieldset%field(3) FCTEST_CHECK_EQUAL( field%name(), "field_2" ) + + fieldset_2 = atlas_FieldSet() + call fieldset_2%add(fieldset) + field_2 = fieldset_2%field("field_0") + call field_2%rename("field_00") + FCTEST_CHECK(fieldset%has("field_00")) + field = fieldset%field("field_00") + FCTEST_CHECK_EQUAL(field%name(), "field_00") + call fieldset%final() write(0,*) "test_fieldset end" diff --git a/src/tests/field/test_fieldset.cc b/src/tests/field/test_fieldset.cc index e8762e657..474fd5b5b 100644 --- a/src/tests/field/test_fieldset.cc +++ b/src/tests/field/test_fieldset.cc @@ -56,7 +56,24 @@ CASE("test_rename") { EXPECT(!fieldset.has("field_1")); EXPECT_EQ(fieldset.field(1).name(),std::string("")); EXPECT(fieldset.has("[1]")); +} +CASE("test_fieldset_concatenation") { + FieldSet fieldset_1; + FieldSet fieldset_2; + auto field_1 = fieldset_1.add(Field("0", make_datatype(), array::make_shape(10,4))); + auto field_1_v = array::make_view(field_1); + field_1_v(1,1) = 2.; + + fieldset_2.add(fieldset_1); + auto field_2 = fieldset_2.field("0"); + field_2.rename(""); + auto field_2_v = array::make_view(field_2); + field_2_v(1,1) = 1.; + + EXPECT(!fieldset_2.has("")); + EXPECT_EQ(fieldset_2.field(0).name(), ""); + EXPECT_EQ(field_1_v(1,1), 1.); } CASE("test_duplicate_name_throws") { From 380eecde3c605750e888466eb4b5864f8932ee13 Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Wed, 23 Aug 2023 09:17:46 +0000 Subject: [PATCH 2/3] Add access to nproma for BlockStructuredColumns in Fortran --- .../detail/BlockStructuredColumnsInterface.cc | 3 +++ .../detail/BlockStructuredColumnsInterface.h | 1 + .../atlas_functionspace_BlockStructuredColumns_module.F90 | 8 ++++++++ 3 files changed, 12 insertions(+) diff --git a/src/atlas/functionspace/detail/BlockStructuredColumnsInterface.cc b/src/atlas/functionspace/detail/BlockStructuredColumnsInterface.cc index 988bc1c86..492a6105b 100644 --- a/src/atlas/functionspace/detail/BlockStructuredColumnsInterface.cc +++ b/src/atlas/functionspace/detail/BlockStructuredColumnsInterface.cc @@ -175,6 +175,9 @@ idx_t atlas__fs__BStructuredColumns__block_begin(const detail::BlockStructuredCo idx_t atlas__fs__BStructuredColumns__block_size(const detail::BlockStructuredColumns* This, idx_t jblk) { return This->block_size(jblk); } +idx_t atlas__fs__BStructuredColumns__nproma(const detail::BlockStructuredColumns* This) { + return This->nproma(); +} idx_t atlas__fs__BStructuredColumns__nblks(const detail::BlockStructuredColumns* This) { return This->nblks(); } diff --git a/src/atlas/functionspace/detail/BlockStructuredColumnsInterface.h b/src/atlas/functionspace/detail/BlockStructuredColumnsInterface.h index 7428afdf1..5a660132c 100644 --- a/src/atlas/functionspace/detail/BlockStructuredColumnsInterface.h +++ b/src/atlas/functionspace/detail/BlockStructuredColumnsInterface.h @@ -102,6 +102,7 @@ idx_t atlas__fs__BStructuredColumns__i_end_halo(const detail::BlockStructuredCol idx_t atlas__fs__BStructuredColumns__levels(const detail::BlockStructuredColumns* This); idx_t atlas__fs__BStructuredColumns__block_begin(const detail::BlockStructuredColumns* This, idx_t jblk); idx_t atlas__fs__BStructuredColumns__block_size(const detail::BlockStructuredColumns* This, idx_t jblk); +idx_t atlas__fs__BStructuredColumns__nproma(const detail::BlockStructuredColumns* This); idx_t atlas__fs__BStructuredColumns__nblks(const detail::BlockStructuredColumns* This); field::FieldImpl* atlas__fs__BStructuredColumns__xy(const detail::BlockStructuredColumns* This); diff --git a/src/atlas_f/functionspace/atlas_functionspace_BlockStructuredColumns_module.F90 b/src/atlas_f/functionspace/atlas_functionspace_BlockStructuredColumns_module.F90 index f25f76321..de3770e28 100644 --- a/src/atlas_f/functionspace/atlas_functionspace_BlockStructuredColumns_module.F90 +++ b/src/atlas_f/functionspace/atlas_functionspace_BlockStructuredColumns_module.F90 @@ -89,6 +89,7 @@ module atlas_functionspace_BlockStructuredColumns_module procedure :: levels procedure :: block_begin procedure :: block_size + procedure :: nproma procedure :: nblks procedure :: xy @@ -554,6 +555,13 @@ function block_size(this,j) result(i) i = atlas__fs__BStructuredColumns__block_size(this%CPTR_PGIBUG_A,j-1) end function +function nproma(this) result(i) + use atlas_functionspace_BlockStructuredColumns_c_binding + integer(ATLAS_KIND_IDX) :: i + class(atlas_functionspace_BlockStructuredColumns), intent(in) :: this + i = atlas__fs__BStructuredColumns__nproma(this%CPTR_PGIBUG_A) +end function + function nblks(this) result(i) use atlas_functionspace_BlockStructuredColumns_c_binding integer(ATLAS_KIND_IDX) :: i From e5823e08ab2db107d7a2cd9f71e26e855fd8cbc9 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 5 Sep 2023 18:41:49 +0200 Subject: [PATCH 3/3] Add FieldObserver::onFieldDestruction --- src/atlas/field/detail/FieldImpl.cc | 3 +++ src/atlas/field/detail/FieldImpl.h | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/atlas/field/detail/FieldImpl.cc b/src/atlas/field/detail/FieldImpl.cc index 78d929f23..3d655926d 100644 --- a/src/atlas/field/detail/FieldImpl.cc +++ b/src/atlas/field/detail/FieldImpl.cc @@ -94,6 +94,9 @@ FieldImpl::FieldImpl(const std::string& name, array::Array* array) } FieldImpl::~FieldImpl() { + for (FieldObserver* observer : field_observers_) { + observer->onFieldDestruction(*this); + } array_->detach(); if (array_->owners() == 0) { for (auto& f : callback_on_destruction_) { diff --git a/src/atlas/field/detail/FieldImpl.h b/src/atlas/field/detail/FieldImpl.h index cdd9c308f..24af72d2c 100644 --- a/src/atlas/field/detail/FieldImpl.h +++ b/src/atlas/field/detail/FieldImpl.h @@ -257,7 +257,8 @@ class FieldObserver { } } - virtual void onFieldRename(FieldImpl&) = 0; + virtual void onFieldRename(FieldImpl&) {} + virtual void onFieldDestruction(FieldImpl&) {} }; //----------------------------------------------------------------------------------------------------------------------