36 using namespace Utilities;
46 min_depth(NaN::
DSNAN),
51 this->
name =
"random uniform distribution deflected";
63 "Random uniform distribution grains model. The size of the grains can be independently set " 64 "to a single value or to a random distribution.");
68 "The depth in meters from which the grains of this feature are present.");
70 "The depth in meters to which the grains of this feature are present.");
73 "A list with the integer labels of the composition which are present there.");
76 "Whether the value should replace any value previously defined at this location (replace) or " 77 "add the value to the previously define value (add, not implemented). Replacing implies that all values not " 78 "explicitly defined are set to zero.");
82 "A list of the size of all of the grains in each composition. If set to <0, the size will be randomized between 0 and 1.");
86 "A list of whether the sizes of the grains should be normalized or not. If normalized, the total of the grains of a composition will be equal to 1.");
90 "A list of the deflections of all of the grains in each composition between 0 and 1.");
93 "A list with the rotation matrices of the grains which are present there for each compositions.");
96 "A list with the z-x-z Euler angles of the grains which are present there for each compositions.");
108 const bool set_euler_angles = prm.
check_entry(
"basis Euler angles z-x-z");
109 const bool set_rotation_matrices = prm.
check_entry(
"basis rotation matrices");
111 WBAssertThrow(!(set_euler_angles ==
true && set_rotation_matrices ==
true),
112 "Only Euler angles or Rotation matrices may be set, but both are set for " << prm.
get_full_json_path());
115 WBAssertThrow(!(set_euler_angles ==
false && set_rotation_matrices ==
false),
116 "Euler angles or Rotation matrices have to be set, but neither are set for " << prm.
get_full_json_path());
118 if (set_euler_angles)
120 std::vector<std::array<double,3> > basis_euler_angles_vector = prm.
get_vector<std::array<double,3> >(
"basis Euler angles z-x-z");
122 for (
size_t i = 0; i<basis_euler_angles_vector.size(); ++i)
133 operation = prm.
get<std::string>(
"orientation operation");
140 "There are not the same amount of compositions (" << compositions.size()
141 <<
") and grain_sizes (" << grain_sizes.size() <<
").");
142 WBAssertThrow(compositions.size() == normalize_grain_sizes.size(),
143 "There are not the same amount of compositions (" << compositions.size()
144 <<
") and normalize_grain_sizes (" << normalize_grain_sizes.size() <<
").");
146 "There are not the same amount of compositions (" << compositions.size()
147 <<
") and deflections (" << deflections.size() <<
").");
149 "There are not the same amount of compositions (" << compositions.size()
157 const unsigned int composition_number,
163 if (depth <= max_depth && depth >=
min_depth)
169 std::uniform_real_distribution<> dist(0.0,1.0);
194 const double z = 2.0 * three * deflections[i];
202 const double r = std::sqrt( z );
203 const double Vx =
std::sin( phi ) * r;
204 const double Vy =
std::cos( phi ) * r;
205 const double Vz = std::sqrt( 2.F - z );
211 const double st =
std::sin( theta );
212 const double ct =
std::cos( theta );
213 const double Sx = Vx * ct - Vy * st;
214 const double Sy = Vx * st + Vy * ct;
219 std::array<std::array<double,3>,3> rotation_matrices;
220 rotation_matrices[0][0] = (Vx * Sx - ct);
221 rotation_matrices[0][1] = (Vx * Sy - st);
222 rotation_matrices[0][2] = Vx * Vz;
224 rotation_matrices[1][0] = (Vy * Sx + st);
225 rotation_matrices[1][1] = (Vy * Sy - ct);
226 rotation_matrices[1][2] = Vy * Vz;
228 rotation_matrices[2][0] = Vz * Sx;
229 rotation_matrices[2][1] = Vz * Sy;
230 rotation_matrices[2][2] = 1.0 - z;
234 std::array<std::array<double, 3>, 3> rot_T= rotation_matrices;
235 rot_T[0][1] = rotation_matrices[1][0];
236 rot_T[1][0] = rotation_matrices[0][1];
237 rot_T[1][2] = rotation_matrices[2][1];
238 rot_T[2][1] = rotation_matrices[1][2];
239 rot_T[0][2] = rotation_matrices[2][0];
240 rot_T[2][0] = rotation_matrices[0][2];
245 it_rotation_matrices = result1;
248 double total_size = 0;
249 for (
auto &&it_sizes : grains_local.
sizes)
252 total_size += it_sizes;
257 const double one_over_total_size = 1/total_size;
263 for (
auto &&size : grains_local.
sizes)
265 size = size*one_over_total_size;
bool check_entry(const std::string &name) const
std::array< std::array< double, 3 >, 3 > multiply_3x3_matrices(const std::array< std::array< double, 3 >, 3 > mat1, const std::array< std::array< double, 3 >, 3 > mat2)
std::mt19937 & get_random_number_engine()
std::vector< double > sizes
#define WB_REGISTER_FEATURE_PLUME_GRAINS_MODEL(classname, name)
std::string get_full_json_path(size_t max_size=std::numeric_limits< size_t >::max()) const
WorldBuilder::World * world
double cos(const double angle)
#define WBAssertThrow(condition, message)
std::array< std::array< double, 3 >, 3 > euler_angles_to_rotation_matrix(double phi1_d, double theta_d, double phi2_d)
double sin(const double raw_angle)
std::vector< std::array< std::array< double, 3 >, 3 > > rotation_matrices
void declare_entry(const std::string &name, const Types::Interface &type, const std::string &documentation)
std::vector< T > get_vector(const std::string &name)
T get(const std::string &name)