Skip to content

Commit e6eb1fc

Browse files
authored
Merge pull request #765 from MFraters/add_properties_wrapper_functions
Add properties wrapper functions to c wrapper
2 parents 062d91d + 8844806 commit e6eb1fc

File tree

9 files changed

+492
-36
lines changed

9 files changed

+492
-36
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
1313
### Added
1414
- Added a velocities system where each feature can define a velocity field and the gwb can return the resulting velocity field. \[Menno Fraters; 2024-10-20; [#761](https://github.com/GeodynamicWorldBuilder/WorldBuilder/pull/761)\]
1515
- There is now a CMake variable to automatically update the reference files for failed tests (gdb-dat and gwb-grid tests) \[Menno Fraters; 2024-10-20; [#761](https://github.com/GeodynamicWorldBuilder/WorldBuilder/pull/761)\]
16+
- There is now a properties_output_size function, which returns the size of the output vector/array returned by the properties functions for a given properties input vector \[Menno Fraters; 2024-10-27; [#765](https://github.com/GeodynamicWorldBuilder/WorldBuilder/pull/765)\]
17+
- Added 2d and 3d versions of the properties function to the C wrapper \[Menno Fraters; 2024-10-27; [#765](https://github.com/GeodynamicWorldBuilder/WorldBuilder/pull/765)\]
1618

1719
## Changed
1820

include/world_builder/world.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,15 @@ namespace WorldBuilder
7878
*/
7979
void parse_entries(Parameters &prm);
8080

81+
/**
82+
* Return the size of the output vector returned by the properties function for a given properties vector.
83+
*
84+
* @param properties The properties parameter from the properties function. See the documentation of that
85+
* function for more info.
86+
* @return unsigned int Return the size of the output vector returned by the properties function for a given properties vector.
87+
*/
88+
unsigned int properties_output_size(const std::vector<std::array<unsigned int,3>> &properties) const;
89+
8190
/**
8291
* Returns different values at a single point in one go stored in a vector of doubles.
8392
*

include/world_builder/wrapper_c.h

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,111 @@ extern "C" {
3333
*/
3434
void create_world(void **ptr_ptr_world, const char *world_builder_file, const bool *has_output_dir, const char *output_dir, const unsigned long random_number_seed);
3535

36+
37+
38+
/**
39+
* Return the size of the output vector returned by the properties function for a given properties vector.
40+
*
41+
* @param properties The properties parameter from the properties function. See the documentation of that
42+
* function for more info.
43+
* @param n_properties number of properties
44+
* @return unsigned int Return the size of the output vector returned by the properties function for a given properties vector.
45+
*/
46+
unsigned int properties_output_size(void *ptr_ptr_world,
47+
const unsigned int properties[][3],
48+
const unsigned int n_properties);
49+
50+
/**
51+
* @brief This function returns 2D properties.
52+
*
53+
* The properties input decides what each entry means, and the output is generated in the
54+
* same order as the properties input. The properties input consists of
55+
* a 3D array, where the first entry identifies the property and the last two entries
56+
* provide extra information about that property.
57+
*
58+
* Temperature is identified by 1 and no extra information is needed. So temperature
59+
* input usually looks like {1,0,0}. A temperature query prodoces one entry in the output
60+
* vector.
61+
*
62+
* Composition is identified by 2. This produces one
63+
* value in the output. The second entry identifies the composition number and the third
64+
* number is not used. So a composition query asking about composition 1 looks like this:
65+
* {2,1,0}. A composition query prodoces one entry in the output vector.
66+
*
67+
* Grains are identified by 3. The second entry is the grain composition number and the third
68+
* entry is the number of grains. A query about the grains, where it asks about composition 1
69+
* (for example enstatite) and 500 grains, looks like this: {3,1,500}.
70+
* A composition query prodoces n_grains*10 entries in the output vector. The first n_grains
71+
* entries are the sizes of all the grains, and the other 9 entries are sets of rotation
72+
* matrices. The rotation matrix entries are ordered [0][0],[0][1],[0][2],[1][0],[1][1],etc.
73+
*
74+
* The tag is identified by 4 and no extra information is needed. So the tag
75+
* input usually looks like {4,0,0}. A tag query prodoces one entry in the output
76+
* vector, representing the index of the tag of the last/dominant feature.
77+
*
78+
* @param ptr_ptr_world a pointer to the world
79+
* @param x The x position of the point
80+
* @param z The z position of the point
81+
* @param depth The depth of the point
82+
* @param properties an array of properties, which each property is an array of three integers.
83+
* @param n_properties number of properties.
84+
* @param values are the return values as a pointer to an array of doubles
85+
*/
86+
void properties_2d(void *ptr_ptr_world,
87+
const double x,
88+
const double z,
89+
const double depth,
90+
const unsigned int properties[][3],
91+
const unsigned int n_properties,
92+
double values[]);
93+
94+
95+
/**
96+
* @brief This function returns 3D properties.
97+
*
98+
* The properties input decides what each entry means, and the output is generated in the
99+
* same order as the properties input. The properties input consists of
100+
* a 3D array, where the first entry identifies the property and the last two entries
101+
* provide extra information about that property.
102+
*
103+
* Temperature is identified by 1 and no extra information is needed. So temperature
104+
* input usually looks like {1,0,0}. A temperature query prodoces one entry in the output
105+
* vector.
106+
*
107+
* Composition is identified by 2. This produces one
108+
* value in the output. The second entry identifies the composition number and the third
109+
* number is not used. So a composition query asking about composition 1 looks like this:
110+
* {2,1,0}. A composition query prodoces one entry in the output vector.
111+
*
112+
* Grains are identified by 3. The second entry is the grain composition number and the third
113+
* entry is the number of grains. A query about the grains, where it asks about composition 1
114+
* (for example enstatite) and 500 grains, looks like this: {3,1,500}.
115+
* A composition query prodoces n_grains*10 entries in the output vector. The first n_grains
116+
* entries are the sizes of all the grains, and the other 9 entries are sets of rotation
117+
* matrices. The rotation matrix entries are ordered [0][0],[0][1],[0][2],[1][0],[1][1],etc.
118+
*
119+
* The tag is identified by 4 and no extra information is needed. So the tag
120+
* input usually looks like {4,0,0}. A tag query prodoces one entry in the output
121+
* vector, representing the index of the tag of the last/dominant feature.
122+
*
123+
* @param ptr_ptr_world a pointer to the world
124+
* @param x The x position of the point
125+
* @param x The y position of the point
126+
* @param z The z position of the point
127+
* @param depth The depth of the point
128+
* @param properties an array of properties, which each property is an array of three integers.
129+
* @param n_properties number of properties.
130+
* @param values are the return values as a pointer to an array of doubles
131+
*/
132+
void properties_3d(void *ptr_ptr_world,
133+
const double x,
134+
const double y,
135+
const double z,
136+
const double depth,
137+
const unsigned int properties[][3],
138+
const unsigned int n_properties,
139+
double values[]);
140+
36141
/**
37142
* This function return the temperature at a specific location given x, z, depth and
38143
* gravity.

source/world_builder/world.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,47 @@ namespace WorldBuilder
270270

271271

272272

273+
unsigned int
274+
World::properties_output_size(const std::vector<std::array<unsigned int,3>> &properties) const
275+
{
276+
unsigned int n_output_entries = 0;
277+
for (auto property : properties)
278+
{
279+
switch (property[0])
280+
{
281+
case 1: // Temperature
282+
n_output_entries += 1;
283+
break;
284+
case 2: // composition
285+
n_output_entries += 1;
286+
break;
287+
case 3: // grains (10 entries per grain)
288+
{
289+
n_output_entries += property[2]*10;
290+
break;
291+
}
292+
case 4: // tag
293+
{
294+
n_output_entries += 1;
295+
break;
296+
}
297+
case 5: // velocity (3 entries)
298+
{
299+
n_output_entries += 3;
300+
break;
301+
}
302+
default:
303+
WBAssertThrow(false,
304+
"Internal error: Unimplemented property provided. " <<
305+
"Only temperature (1), composition (2), grains (3), tag (4) or velocity (5) are allowed. "
306+
"Provided property number was: " << property[0]);
307+
}
308+
}
309+
return n_output_entries;
310+
}
311+
312+
313+
273314
std::vector<double>
274315
World::properties(const std::array<double, 2> &point,
275316
const double depth,

source/world_builder/wrapper_c.cc

Lines changed: 105 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,19 @@
1919

2020
#include "world_builder/wrapper_c.h"
2121

22+
#include "world_builder/assert.h"
2223
#include "world_builder/world.h"
24+
#include <vector>
2325

2426
extern "C" {
2527
/**
2628
* This function creates an object of the world builder and returns a pointer
2729
* to it. This pointer can then be used to call the temperature and composition
2830
* functions. When done call the release world function to destroy the object.
2931
*/
30-
void create_world(void **ptr_ptr_world, const char *world_builder_file, const bool *has_output_dir_, const char *output_dir_, const unsigned long random_number_seed)
32+
void create_world(void **ptr_ptr_world, const char *world_builder_file,
33+
const bool *has_output_dir_, const char *output_dir_,
34+
const unsigned long random_number_seed)
3135
{
3236
bool has_output_dir = false;
3337

@@ -42,67 +46,135 @@ extern "C" {
4246
output_dir = *output_dir_;
4347
}
4448

45-
WorldBuilder::World *a = new WorldBuilder::World(std::string(world_builder_file), has_output_dir, output_dir,random_number_seed);
49+
WorldBuilder::World *a =
50+
new WorldBuilder::World(std::string(world_builder_file), has_output_dir,
51+
output_dir, random_number_seed);
4652

4753
*ptr_ptr_world = reinterpret_cast<void *>(a);
4854
}
4955

50-
51-
/**
52-
* This function return the temperature at a specific location given x, z, depth and
53-
* gravity.
54-
*/
55-
void temperature_2d(void *ptr_ptr_world, double x, double z, double depth, double *temperature)
56+
unsigned int properties_output_size(void *ptr_ptr_world,const unsigned int properties_[][3],
57+
const unsigned int n_properties)
5658
{
57-
WorldBuilder::World *a = reinterpret_cast<WorldBuilder::World *>(ptr_ptr_world);
58-
const std::array<double,2> position = {{x,z}};
59-
*temperature = a->temperature(position,depth);
59+
WorldBuilder::World *a =
60+
reinterpret_cast<WorldBuilder::World *>(ptr_ptr_world);
61+
std::vector<std::array<unsigned int, 3>> properties(n_properties);
62+
for (size_t i = 0; i < n_properties; ++i)
63+
{
64+
properties[i][0] = properties_[i][0];
65+
properties[i][1] = properties_[i][1];
66+
properties[i][2] = properties_[i][2];
67+
}
68+
return a->properties_output_size(properties);
6069
}
6170

71+
void properties_2d(void *ptr_ptr_world, const double x, const double z,
72+
const double depth, const unsigned int properties_[][3],
73+
const unsigned int n_properties, double values[])
74+
{
75+
WorldBuilder::World *a =
76+
reinterpret_cast<WorldBuilder::World *>(ptr_ptr_world);
77+
const std::array<double, 2> position = {{x, z}};
78+
std::vector<std::array<unsigned int, 3>> properties(n_properties);
79+
for (size_t i = 0; i < n_properties; ++i)
80+
{
81+
properties[i][0] = properties_[i][0];
82+
properties[i][1] = properties_[i][1];
83+
properties[i][2] = properties_[i][2];
84+
}
85+
std::vector<double> returned_values = a->properties(position, depth, properties);
86+
for (unsigned i = 0; i < returned_values.size(); ++i)
87+
{
88+
values[i] = returned_values[i];
89+
}
90+
}
6291

63-
/**
64-
* This function return the temperature at a specific location given x, y, z, depth and
65-
* gravity.
66-
*/
67-
void temperature_3d(void *ptr_ptr_world, double x, double y, double z, double depth, double *temperature)
92+
void properties_3d(void *ptr_ptr_world,
93+
const double x,
94+
const double y,
95+
const double z,
96+
const double depth,
97+
const unsigned int properties_[][3],
98+
const unsigned int n_properties,
99+
double values[])
68100
{
69101
WorldBuilder::World *a = reinterpret_cast<WorldBuilder::World *>(ptr_ptr_world);
70102
const std::array<double,3> position = {{x,y,z}};
71-
*temperature = a->temperature(position,depth);
103+
std::vector<std::array<unsigned int,3>> properties(n_properties);
104+
for (size_t i = 0; i < n_properties; ++i)
105+
{
106+
properties[i][0] = properties_[i][0];
107+
properties[i][1] = properties_[i][1];
108+
properties[i][2] = properties_[i][2];
109+
}
110+
std::vector<double> returned_values = a->properties(position, depth, properties);
111+
for (unsigned i = 0; i < returned_values.size(); ++i)
112+
{
113+
values[i] = returned_values[i];
114+
}
72115
}
73116

74-
75117
/**
76-
* This function return the composition at a specific location given x, z, depth and
77-
* composition number.
118+
* This function return the temperature at a specific location given x, z, depth
119+
* and gravity.
78120
*/
79-
void composition_2d(void *ptr_ptr_world, double x, double z, double depth, unsigned int composition_number, double *composition)
121+
void temperature_2d(void *ptr_ptr_world, double x, double z, double depth,
122+
double *temperature)
80123
{
81-
WorldBuilder::World *a = reinterpret_cast<WorldBuilder::World *>(ptr_ptr_world);
82-
const std::array<double,2> position = {{x,z}};
83-
*composition = a->composition(position,depth,composition_number);
124+
WorldBuilder::World *a =
125+
reinterpret_cast<WorldBuilder::World *>(ptr_ptr_world);
126+
const std::array<double, 2> position = {{x, z}};
127+
*temperature = a->temperature(position, depth);
84128
}
85129

130+
/**
131+
* This function return the temperature at a specific location given x, y, z,
132+
* depth and gravity.
133+
*/
134+
void temperature_3d(void *ptr_ptr_world, double x, double y, double z,
135+
double depth, double *temperature)
136+
{
137+
WorldBuilder::World *a =
138+
reinterpret_cast<WorldBuilder::World *>(ptr_ptr_world);
139+
const std::array<double, 3> position = {{x, y, z}};
140+
*temperature = a->temperature(position, depth);
141+
}
86142

87143
/**
88-
* This function return the composition at a specific location given x, y, z, depth and
89-
* composition number.
144+
* This function return the composition at a specific location given x, z, depth
145+
* and composition number.
90146
*/
91-
void composition_3d(void *ptr_ptr_world, double x, double y, double z, double depth, unsigned int composition_number, double *composition)
147+
void composition_2d(void *ptr_ptr_world, double x, double z, double depth,
148+
unsigned int composition_number, double *composition)
92149
{
93-
WorldBuilder::World *a = reinterpret_cast<WorldBuilder::World *>(ptr_ptr_world);
94-
const std::array<double,3> position = {{x,y,z}};
95-
*composition = a->composition(position,depth,composition_number);
150+
WorldBuilder::World *a =
151+
reinterpret_cast<WorldBuilder::World *>(ptr_ptr_world);
152+
const std::array<double, 2> position = {{x, z}};
153+
*composition = a->composition(position, depth, composition_number);
96154
}
97155

156+
/**
157+
* This function return the composition at a specific location given x, y, z,
158+
* depth and composition number.
159+
*/
160+
void composition_3d(void *ptr_ptr_world, double x, double y, double z,
161+
double depth, unsigned int composition_number,
162+
double *composition)
163+
{
164+
WorldBuilder::World *a =
165+
reinterpret_cast<WorldBuilder::World *>(ptr_ptr_world);
166+
const std::array<double, 3> position = {{x, y, z}};
167+
*composition = a->composition(position, depth, composition_number);
168+
}
98169

99170
/**
100-
* The destructor for the world builder class. Call this function when done with the
101-
* world builder.
171+
* The destructor for the world builder class. Call this function when done with
172+
* the world builder.
102173
*/
103174
void release_world(void *ptr_ptr_world)
104175
{
105-
WorldBuilder::World *a = reinterpret_cast<WorldBuilder::World *>(ptr_ptr_world);
176+
WorldBuilder::World *a =
177+
reinterpret_cast<WorldBuilder::World *>(ptr_ptr_world);
106178
delete a;
107179
}
108180
}

0 commit comments

Comments
 (0)