Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MatL] Multi-phase/-component library. #2303

Merged
merged 4 commits into from
Jan 17, 2019
Merged

Conversation

endJunction
Copy link
Member

@endJunction endJunction commented Dec 21, 2018

This is part of #1955 which is used in multi component transport (#2304). Mainly infrastructure, since only constant properties were used so far in the ComponentTransportProcess.

@TomFischer
Copy link
Member

The copyright has to be updated.

/// determine the size of the VariableArray. If the variable of your choice is
/// missing, simply add it somewhere at the list, but above the last entry
/// 'numberOfVariables'
enum Variables : std::size_t
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not 'enum class'?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implicit conversion to int (I changed the underlying type) is quite handy.

#pragma once

#include <boost/algorithm/string/predicate.hpp>
#include <boost/variant.hpp>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we already use std::variant?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately not until gcc-7.1. And also the macOS's clang in version 10 does not support it fully yet. But (fasten your belts!!!) the latest visual studio would work!

Also tried new syntax for "structured binding declarations" instead of std::tie

auto [a, b, c] = function_returning_a_tuple_of_tree();

working only since gcc-7

/// in alphabetical order (of course, except for the last entry
/// 'number_of_property_enums'). Please note that any of these entries must also
/// appear in below convert functions.
enum PropertyType : std::size_t
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not enum class?

MaterialLib/MPL/Enums.h Outdated Show resolved Hide resolved
class MaterialSpatialDistributionMap
{
private:
std::map<int, std::unique_ptr<Medium>> const& _media;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I understand the domain of the map is [0, #number of media]. Maybe a vector can be used here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to myself; compare with error/warning message code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TomFischer the media ids follow numbering from MaterialIDs and can be rather arbitrary, especially negative. We might have a look on it later, if it looks like a bottleneck.

MaterialLib/MPL/Medium.h Outdated Show resolved Hide resolved
@@ -26,6 +26,7 @@
#include "BaseLib/FileTools.h"

#include "GeoLib/GEOObjects.h"
#include "MaterialLib/MPL/mpMedium.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for this PR: In future I would like to replace MPL with MaterialPropertyLib. Also, it is better to replace mpMedium.h` with some meaningful name.

Applications/ApplicationsLib/ProjectData.cpp Outdated Show resolved Hide resolved
if (_media.rbegin()->first != static_cast<int>(_media.size()) - 1)
OGS_FATAL(
"The ids in the porous media definitions in the project file have "
"to be sequential, starting with the id zero.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the id zero --> the id of zero.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dropped the whole if-condition. The requirement of media to be numbered from 0 to n sequentially, does not match with the freedom of the MaterialIDs, which can be any int, especially negative.

{
// If a name is given, it must conform with one of the derived component
// names in the following list:
if (boost::iequals(component_name, "water"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not if (component_name == "water")?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Norbert's argument is that it is difficult to explain people, why "Water" is not good enough for the specification of water. Same goes with "CO2" etc.

*/
#pragma once

#include "BaseLib/ConfigTree.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can use forward declaration.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whole creation of media, phases, components, and properties is now moved into corresponding CreateX.h/cpp files.

@@ -0,0 +1,25 @@
/**
* \file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove it or leave a blank line after it.

*/
#pragma once

#include "Constant.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file only contains one include.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as for components, the full implementation has many, and the properties include is specified once in the process.
Other properties (and also components) which are not tested in the follow-up PR, are excluded.

#include <boost/variant.hpp>
#include <string>

#include "BaseLib/ConfigTree.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forward declaration.

@@ -0,0 +1,21 @@
/**
* \file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leave a blank line after it.

Tests/MaterialLib/TestMPLParseMaterial.cpp Outdated Show resolved Hide resolved
};

using PropertyDataType =
boost::variant<double, Pair, Vector, SymmTensor, Tensor, std::string>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think std::variant can be used.

Copy link
Member

@wenqing wenqing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Only one idea about MaterialPropertyLib::PropertyType and its converters.

std::stringstream issValue(sValue);

std::vector<double> values;
double dummy(0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dummy cann't be const since it is used to read from the stringstream issValues. So maybe 'dummy' isn't so dummy ;-)

Copy link
Member Author

@endJunction endJunction Jan 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't see the reading of std::vector<double> from the config. ConfigTree supports getConfigParameter<std::vector<T>>(...). The whole section is replaced by single statement.

/// I suggest that the syntax of the properties in the input-files (i.e. the
/// strings) have to be identical to the syntax of the entries in the
/// enumerator.
inline PropertyType convertStringToProperty(std::string const& inString)
Copy link
Member

@wenqing wenqing Jan 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to the elements of PropertyType, we have to to change strings in convertStringToProperty and property_enum_to_string as well.

It might be good to
1) create a enum to std::string convertor in BaseLib (see https://stackoverflow.com/questions/28828957/enum-to-string-in-modern-c11-c14-c17-and-future-c20).
2) use the enum to std::string convertor to initialize std::array<std::string, PropertyType::number_of_properties> property_enum_to_string
3) create a std::map<std::string, PropertyType> by using of std::string convertor to replace ~convertStringToProperty ~

With that, we only need to change the elements of PropertyType if such change is needed.

The current implementation is also OK because there might be less change in PropertyType.

Copy link
Member

@wenqing wenqing Jan 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1) is not good. One still has to use the enum name to get its string type. It seems that each name of enum element must appears at least two times in the source code. Therefore, please go forward with the present implementation.

std::unique_ptr<PropertyArray>&& properties);
virtual ~Component() = default;

/// A get-function for retrieving a cartain property.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cartain -> certain

return property(p).template value<T>();
}

template <typename T>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is my understanding correct: the variable_array is used to pass information for property value calculation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

ERR("Phase type should be one of:");
for (auto const type : allowed_phase_types)
{
ERR(type.c_str());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this valid? I thought it must be ERR("%s", type.c_str()).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just a char array, with substitution or without.

return p.value().which();
}

inline void overwriteExistingProperties(PropertyArray& properties,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since in line 111 new_properties entries are moved, the new_properties aren't valid anymore, isn't it? Maybe the name of the function is a bit misleading, but I haven't a good suggestion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Need a name.


/// Simple symmetric tensor data type for holding
/// xx, yy, zz, xy, xz, yz tensor components.
using SymmTensor = std::array<double, 9>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation says there are 6 entries, the array has size 9. Is this correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! fixing.

}

/// This method creates an XML-snippet of a sigle property.
std::string makeProperty(std::size_t ind, std::size_t index,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not ... makeProperty(std::size_t const ind, std::size_t const index, std::string const& property)?

{
std::stringstream sProperty;

if (property == "")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe property.empty() would be more readable.

// What follows is a C-style string-to-double-conversion...
// seems so easy compared to c++-standard; Feel free to
// change it to latest standard..
if (double value = atof(property.c_str()))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::atof please.

return sComponents.str();
}

/// This method creates an XML-snippet of a sigle material
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sigle -> single


/// This method creates an XML-snippet of the material
/// phases.
std::string makePhases(std::vector<Phase> phases)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::vector<Phase> const& phases?

/// This method creates the entire XML-tree structure from the string-
/// based medium specification object. I know, indentation is not
/// necessary for this, but my OCD kicked in...
std::string makeMedium(Medium m)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium const& m

std::vector<std::string>* exp)
{
obs->push_back(observed_name);
if (expectation == "")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO expectation.empty() would be more readable.

Copy link
Member

@TomFischer TomFischer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. ⏩

private:
std::vector<std::unique_ptr<Component>> const _components;

/// Here, all for all properties listed in the Properties enumerator are
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all for

@endJunction
Copy link
Member Author

@TomFischer I polished the TestMPLParseMaterial.cpp with all the const, &, typos, etc. being fixed now.

@endJunction
Copy link
Member Author

Two open points remain: enum <-> string, and name for overwriteProperties.

endJunction and others added 4 commits January 17, 2019 09:26
A lot of changes are renames for consistency with OGS.

Splitting files, and rename them (dropping mp, p, c prefixes).

Extraction of the create* functions lead to single step initialization
of the Medium, Phase, Component, and Property objects.

Formatting and clang-tidy.
Improve const-correctness.

Remove unneeded Undefined property: The nullptr is probably sufficient
in the PropertyArray, which is an array of pointers, for the property to
be undefined.

Unify value/dValue/d2Value access.

[App] Remove requirement for media ids sequence.

Reorder public, protected, private sections.

Add missing ogs_file_param documentation lines in the code.
@endJunction
Copy link
Member Author

When there are no further comments, and the builds pass, this can be merged.
The enum <-> string conversion needs additional discussions first.

@wenqing
Copy link
Member

wenqing commented Jan 17, 2019

@TomFischer TomFischer merged commit 8972d34 into ufz:master Jan 17, 2019
@endJunction endJunction deleted the gpml branch January 18, 2019 13:02
@endJunction endJunction mentioned this pull request Apr 15, 2019
@ogsbot
Copy link
Member

ogsbot commented Jun 19, 2020

OpenGeoSys development has been moved to GitLab.

See this pull request on GitLab.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants