Skip to content

Commit 87c889b

Browse files
committed
Initial v2 draft of litho1.0 implementation.
1 parent 006bead commit 87c889b

File tree

7 files changed

+192
-9
lines changed

7 files changed

+192
-9
lines changed

include/world_builder/types/one_of.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ namespace WorldBuilder
4343
OneOf(const Interface &type_1,
4444
const Interface &type_2);
4545

46+
/**
47+
* Constructor for the declaration
48+
*/
49+
OneOf(const Interface &type_1,
50+
const Interface &type_2,
51+
const Interface &type_3);
52+
4653
/**
4754
* Constructor for cloning an array.
4855
*/

include/world_builder/world.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,11 @@ namespace WorldBuilder
257257
*/
258258
std::vector<Point<2> > cross_section;
259259

260+
/**
261+
* The path to the Litho1.0 data directory
262+
*/
263+
std::string litho_1_0_path;
264+
260265
/**
261266
* Todo
262267
*/

source/world_builder/features/continental_plate_models/composition/uniform.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,14 @@ namespace WorldBuilder
6262
"Uniform compositional model. Sets constant compositional field.");
6363

6464
// Declare entries of this plugin
65-
prm.declare_entry("min depth", Types::OneOf(Types::Double(0),Types::Array(Types::ValueAtPoints(0., 2.))),
65+
prm.declare_entry("min depth", Types::OneOf(Types::Double(0),
66+
Types::Array(Types::ValueAtPoints(0., 2.)),
67+
Types::String("")),
6668
"The depth in meters from which the composition of this feature is present.");
6769

68-
prm.declare_entry("max depth", Types::OneOf(Types::Double(std::numeric_limits<double>::max()),Types::Array(Types::ValueAtPoints(std::numeric_limits<double>::max(), 2.))),
70+
prm.declare_entry("max depth", Types::OneOf(Types::Double(std::numeric_limits<double>::max()),
71+
Types::Array(Types::ValueAtPoints(std::numeric_limits<double>::max(), 2.)),
72+
Types::String("")),
6973
"The depth in meters to which the composition of this feature is present.");
7074

7175
prm.declare_entry("compositions", Types::Array(Types::UnsignedInt(),0),

source/world_builder/features/continental_plate_models/temperature/linear.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,12 @@ namespace WorldBuilder
6464
"Linear temperature model. Can be set to use an adiabatic temperature at the boundaries.");
6565

6666
// Declare entries of this plugin
67-
prm.declare_entry("min depth", Types::OneOf(Types::Double(0),Types::Array(Types::ValueAtPoints(0., 2.))),
67+
prm.declare_entry("min depth", Types::OneOf(Types::Double(0),
68+
Types::Array(Types::ValueAtPoints(0., 2.)),
69+
Types::String("")),
6870
"The depth in meters from which the composition of this feature is present.");
6971

70-
prm.declare_entry("max depth", Types::OneOf(Types::Double(std::numeric_limits<double>::max()),Types::Array(Types::ValueAtPoints(std::numeric_limits<double>::max(), 2.))),
72+
prm.declare_entry("max depth", Types::OneOf(Types::Double(std::numeric_limits<double>::max()),Types::Array(Types::ValueAtPoints(std::numeric_limits<double>::max(), 2.)),Types::String("")),
7173
"The depth in meters to which the composition of this feature is present.");
7274

7375
prm.declare_entry("top temperature", Types::Double(293.15),

source/world_builder/parameters.cc

Lines changed: 157 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919

2020

21+
#include "world_builder/assert.h"
2122
#include "world_builder/features/continental_plate_models/composition/interface.h"
2223
#include "world_builder/features/continental_plate_models/velocity/interface.h"
2324
#include "world_builder/features/continental_plate_models/grains/interface.h"
@@ -517,6 +518,7 @@ namespace WorldBuilder
517518
// 2. One double provided: use the default value everywhere. Return first with one value and second with size 0.
518519
// 3. One value in a double array and no points provided: use that value everywhere. Return first with one value and second with size 0.
519520
// 4. Other: fill the vectors with the default value and addition points and then add new point.
521+
// 5. A string provided: for example litho1 sediment 3, and a path provided?
520522
// If a value without points is encountered, the additional points are used.
521523
std::pair<std::vector<double>,std::vector<double>> result;
522524

@@ -525,9 +527,11 @@ namespace WorldBuilder
525527
// start with adding the additional points with the default value
526528
// to do this we need the default value
527529
double default_value = 0;
528-
bool is_array = true;
530+
enum InputTypes {DOUBLE_TYPE,ARRAY_TYPE,STRING_TYPE,MAX_INPUT_TYPES};
531+
InputTypes input_type = InputTypes::MAX_INPUT_TYPES;
529532
if (Pointer((strict_base + "/" + name).c_str()).Get(parameters) != nullptr && Pointer((strict_base + "/" + name).c_str()).Get(parameters)->IsArray())
530533
{
534+
input_type = InputTypes::ARRAY_TYPE;
531535
const std::string value_def_path = get_full_json_schema_path() + "/" + name + "/oneOf/1/items/items/anyOf/0/default value";
532536
Value *value_def = Pointer(value_def_path.c_str()).Get(declarations);
533537
WBAssertThrow(value_def != nullptr,
@@ -538,9 +542,15 @@ namespace WorldBuilder
538542
// So no try/catch needed.
539543
default_value = value_def->GetDouble();
540544
}
545+
else if (Pointer((strict_base + "/" + name).c_str()).Get(parameters) != nullptr && Pointer((strict_base + "/" + name).c_str()).Get(parameters)->IsString())
546+
{
547+
input_type = InputTypes::STRING_TYPE;
548+
// I don't know if a default value makes sense here
549+
550+
}
541551
else
542552
{
543-
is_array = false;
553+
input_type = InputTypes::DOUBLE_TYPE;
544554
Value *value_def = Pointer((get_full_json_schema_path() + "/" + name + "/oneOf/0/default value").c_str()).Get(declarations);
545555
WBAssertThrow(value_def != nullptr,
546556
"internal error: could not retrieve the default value at: "
@@ -556,8 +566,8 @@ namespace WorldBuilder
556566
// check if there is a user defined value
557567
if (Pointer((strict_base + "/" + name).c_str()).Get(parameters) != nullptr)
558568
{
559-
// there is a user defined value, so either case 2, 3 or 4.
560-
if (is_array)
569+
// there is a user defined value, so either case 2, 3 4, or 5.
570+
if (input_type == InputTypes::ARRAY_TYPE)
561571
{
562572
Value *array = Pointer((strict_base + "/" + name).c_str()).Get(parameters);
563573

@@ -690,6 +700,147 @@ namespace WorldBuilder
690700
}
691701
}
692702
}
703+
else if (input_type == InputTypes::STRING_TYPE)
704+
{
705+
// case 5: a string. Get the string and decode it
706+
std::string value = "";
707+
708+
try
709+
{
710+
value = Pointer((strict_base + "/" + name).c_str()).Get(parameters)->GetString();
711+
}
712+
catch (...)
713+
{
714+
WBAssertThrow(false, "Could not convert values of " << strict_base << "/" << name << " into a String. "
715+
<< "The provided value was \"" << Pointer((strict_base + "/" + name).c_str()).Get(parameters)->GetString() << "\".");
716+
}
717+
if (value.substr(0,8) == "Litho1.0")
718+
{
719+
enum LayerType
720+
{
721+
// ASTHENOSPHERE,
722+
LITHOSPHERE,
723+
CRUST3,
724+
CRUST2,
725+
CRUST1,
726+
SEDIMENT3,
727+
SEDIMENT2,
728+
SEDIMENT1,
729+
ICE,
730+
WATER,
731+
MAX_LAYERTYPE
732+
};
733+
size_t colon_location = value.find(':');
734+
WBAssertThrow(colon_location!= std::string::npos,"when chosing Litho1.0 you need to specify a subunit with the colon (:)." );
735+
std::string rest_of_string = value.substr(colon_location); // TODO: improve and make more robust, look at gwb-dat example
736+
while ((!rest_of_string.empty()) && (rest_of_string[0] == ' '))
737+
rest_of_string.erase(rest_of_string.begin());
738+
while ((!rest_of_string.empty()) && (rest_of_string[0] == ':'))
739+
rest_of_string.erase(rest_of_string.begin());
740+
while ((!rest_of_string.empty()) && (rest_of_string[0] == ' '))
741+
rest_of_string.erase(rest_of_string.begin());
742+
while ((!rest_of_string.empty()) && (rest_of_string[rest_of_string.size() - 1] == ' '))
743+
rest_of_string.erase(rest_of_string.end() - 1);
744+
LayerType layer_type = LayerType::MAX_LAYERTYPE;
745+
if (rest_of_string == "lithosphere")
746+
{
747+
layer_type = LayerType::LITHOSPHERE;
748+
}
749+
else if (rest_of_string == "crust 3")
750+
{
751+
layer_type = LayerType::CRUST3;
752+
}
753+
else if (rest_of_string == "crust 2")
754+
{
755+
layer_type = LayerType::CRUST2;
756+
}
757+
else if (rest_of_string == "crust 1")
758+
{
759+
layer_type = LayerType::CRUST1;
760+
}
761+
else if (rest_of_string == "sediment 3")
762+
{
763+
layer_type = LayerType::SEDIMENT3;
764+
}
765+
else if (rest_of_string == "sediment 2")
766+
{
767+
layer_type = LayerType::SEDIMENT2;
768+
}
769+
else if (rest_of_string == "sediment 1")
770+
{
771+
layer_type = LayerType::SEDIMENT1;
772+
}
773+
else if (rest_of_string == "ice")
774+
{
775+
layer_type = LayerType::ICE;
776+
}
777+
else if (rest_of_string == "water")
778+
{
779+
layer_type = LayerType::WATER;
780+
}
781+
WBAssertThrow(layer_type != LayerType::MAX_LAYERTYPE, "Could not find litho1.0 layer type " << rest_of_string);
782+
std::string litho_1_0_path = "";
783+
Value *value_pointer = Pointer("/Litho1.0 path").Get(parameters);
784+
WBAssertThrow(value_pointer != nullptr, "You are using the Litho1.0 dataset, but you have not specified the path to the dataset. Please add below \"version\": \"Litho1.0 path\". ");
785+
try
786+
{
787+
litho_1_0_path = value_pointer->GetString();
788+
}
789+
catch (...)
790+
{
791+
WBAssertThrow(false, "Could not convert values of /Litho1.0 path into a String. ");
792+
}
793+
//std::cout << "flag 160" << std::endl;
794+
//WBAssertThrow(false,"Got it! path = " << litho_1_0_path);
795+
constexpr int n1 = 40962;
796+
constexpr int n_layers = 9;
797+
float location_data[40962 * 2];
798+
float depth_data[40962 * 9];
799+
char tessfile[200];
800+
sprintf(tessfile, "%s/litho_depth_data.bin", litho_1_0_path.c_str());
801+
FILE *fptrb = nullptr;
802+
if ((fptrb = fopen(tessfile, "rb")) == nullptr)
803+
{
804+
WBAssertThrow(false, "ERROR: Could not open file " << tessfile);
805+
}
806+
fread(&depth_data, sizeof(float), n1 * n_layers, fptrb);
807+
fclose(fptrb);
808+
809+
sprintf(tessfile, "%s/Icosahedron_Level7_LatLon_mod.txt",
810+
litho_1_0_path.c_str());
811+
FILE *fp = nullptr;
812+
if ((fp = fopen(tessfile, "r")) == nullptr)
813+
{
814+
WBAssertThrow(false, "ERROR: Could not open file " << tessfile);
815+
}
816+
817+
// fread(&depth_data, sizeof(float), n1 * n_layers, fp);
818+
//std::cout << std::endl << litho_1_0_path << std::endl;
819+
int counter_location_data = 0;
820+
float latitude, glatitude, longitude = 0;
821+
while (fscanf(fp, "%f %f %f", &latitude, &glatitude, &longitude) != EOF)
822+
{
823+
const size_t global_index = (counter_location_data/2)*n_layers+layer_type;
824+
result.first.emplace_back(depth_data[global_index]);
825+
result.second.emplace_back(longitude * Consts::PI / 180.);
826+
result.second.emplace_back(latitude * Consts::PI / 180.);
827+
std::cout << counter_location_data << "long:lat:depth = " << longitude << ":"
828+
<< latitude << ", " << ", "
829+
<< ":" << depth_data[global_index] << " (node:global index:local index = " << counter_location_data/2 << ":" << global_index << ":" << layer_type << ")"<< std::endl;
830+
831+
counter_location_data += 2;
832+
}
833+
834+
fclose(fp);
835+
// float depth_data[40962 * 9];
836+
}
837+
else
838+
{
839+
std::cout << "could not find \"" << value << "\"" << std::endl;
840+
assert(false);
841+
}
842+
assert(result.first.size() > 0);
843+
}
693844
else
694845
{
695846
// case 2: there one value, not an array
@@ -711,7 +862,8 @@ namespace WorldBuilder
711862
// there is no user defined value. Case one: return the default value and no points
712863
result.first.emplace_back(default_value);
713864
}
714-
865+
assert(result.first.size() > 0);
866+
WBAssertThrow(result.first.size() > 0, "Internal error: no entries returned when fetching value at points.");
715867
return result;
716868
}
717869

source/world_builder/types/one_of.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,17 @@ namespace WorldBuilder
3333

3434
}
3535

36+
OneOf::OneOf(const Interface &type_1,
37+
const Interface &type_2,
38+
const Interface &type_3)
39+
{
40+
this->type_name = Types::type::OneOf;
41+
inner_types_ptr.emplace_back(type_1.clone());
42+
inner_types_ptr.emplace_back(type_2.clone());
43+
inner_types_ptr.emplace_back(type_3.clone());
44+
45+
}
46+
3647
OneOf::OneOf(OneOf const &other)
3748
{
3849
this->type_name = Types::type::OneOf;

source/world_builder/world.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ namespace WorldBuilder
113113
prm.declare_entry("$schema", Types::String(""),"The optional filename or https address to a JSON schema file");
114114

115115
prm.declare_entry("cross section", Types::Array(Types::Point<2>(),2,2),"This is an array of two points along where the cross section is taken");
116+
prm.declare_entry("Litho1.0 path", Types::String(""), "Path to the litho1.0 files");
116117

117118
prm.declare_entry("potential mantle temperature", Types::Double(1600),
118119
"The potential temperature of the mantle at the surface in Kelvin.");
@@ -197,6 +198,7 @@ namespace WorldBuilder
197198
prm.get_unique_pointers<Features::Interface>("features",prm.features);
198199

199200
const bool set_cross_section = prm.check_entry("cross section");
201+
litho_1_0_path = prm.get<std::string>("Litho1.0 path");
200202

201203
const CoordinateSystem coordinate_system = prm.coordinate_system->natural_coordinate_system();
202204

0 commit comments

Comments
 (0)