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

Impl. of BalanceProcess #1429

Merged
merged 12 commits into from
Sep 30, 2016
Merged

Conversation

TomFischer
Copy link
Member

@TomFischer TomFischer commented Sep 23, 2016

This PR implements the basic infrastructure for balancing fluxes. In the moment the balance can only be calculated for a quad mesh that is a boundary of a hexahedra mesh. This will be extended in further PR. At the moment the balance is only implemented into the GroundwaterFlow but is ready to use in any other process, too. This will also changed in further PRs.

Update

  • After the review I'll rename BalanceProcess to CalculateSurfaceFlux as suggested by @wenqing and @norihiro-w.
  • ChangeLog entry

@ogsbot
Copy link
Member

ogsbot commented Sep 23, 2016

Jenkins: OGS-6/Linux-PRs-dynamic failed: https://svn.ufz.de:8443/job/OGS-6/job/Linux-PRs-dynamic/1178/

@TomFischer
Copy link
Member Author

Jenkins, test this please.

2 similar comments
@TomFischer
Copy link
Member Author

Jenkins, test this please.

@TomFischer
Copy link
Member Author

Jenkins, test this please.

Copy link
Collaborator

@chleh chleh left a comment

Choose a reason for hiding this comment

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

In general it looks good. Only minor things from my side. Thanks for implementing this.

@@ -179,9 +186,11 @@ class Process
unsigned const _integration_order = 2;
GlobalSparsityPattern _sparsity_pattern;

protected:
Copy link
Collaborator

@chleh chleh Sep 26, 2016

Choose a reason for hiding this comment

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

Maybe rather move the member up to the existing protected section. ✅

@@ -53,6 +54,12 @@ class LocalAssemblerInterface
NumLib::LocalToGlobalIndexMap const& dof_table,
GlobalVector const& x);

virtual std::vector<double> getFlux(
MathLib::Point3d const& p, std::vector<double> const& local_x) const
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why Point3d? I'd find SpatialPosition more natural. Maybe time has to be passed, too (for time-dependent parameters).

Copy link
Member Author

Choose a reason for hiding this comment

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

  • Point3d is a point given in natural coordinates. I will change the parameter name to better reflect this.
  • I would implement time depenedency in a separate PR later on when it is needed.

Copy link
Collaborator

Choose a reason for hiding this comment

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

OK.

//! \ogs_file_attr{process__balance__mesh}
balance_config->getConfigParameter<std::string>("mesh");
balance_pv_name =
//! \ogs_file_attr{process__balance__balance_pv_name}
Copy link
Collaborator

@chleh chleh Sep 26, 2016

Choose a reason for hiding this comment

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

... balance_property_name ✅

#include "MeshLib/Elements/FaceRule.h"
#include "MeshLib/Elements/Elements.h"

inline MathLib::Point3d getBulkElementPoint(MeshLib::Quad const& quad,
Copy link
Collaborator

@chleh chleh Sep 26, 2016

Choose a reason for hiding this comment

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

Please add some docu. ✅
Maybe the defintions should be moved to a cpp file? ✅

typename ShapeMatricesType::ShapeMatrices shape_matrices(
ShapeFunction::DIM, GlobalDim, ShapeFunction::NPOINTS);

fe.computeShapeFunctions(p.getCoords(), shape_matrices, GlobalDim);
Copy link
Collaborator

Choose a reason for hiding this comment

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

OK, here you need the Point3D. I guess it has to be in natural coordinates. Maybe that should be documented (and reflected in the argument name).

_integration_method.getNumberOfPoints();

std::vector<typename ShapeMatricesType::ShapeMatrices> shape_matrices;
shape_matrices.reserve(n_integration_points);
Copy link
Collaborator

@chleh chleh Sep 26, 2016

Choose a reason for hiding this comment

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

No need to store all shape matrices if you only need detJ. ✅

std::size_t const n_integration_points =
_integration_method.getNumberOfPoints();
// balance[id_of_element] =
// int_{\Gamma_e} \alpha \cdot grad variable \cdot normal \d \Gamma
Copy link
Collaborator

@chleh chleh Sep 26, 2016

Choose a reason for hiding this comment

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

\cdot grad variable\cdot flux

// int_{\Gamma_e} \alpha \cdot grad variable \cdot normal \d \Gamma
for (std::size_t ip(0); ip < n_integration_points; ip++)
{
pos.setIntegrationPoint(ip);
Copy link
Collaborator

@chleh chleh Sep 26, 2016

Choose a reason for hiding this comment

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

pos is currently not used.

Copy link
Member Author

Choose a reason for hiding this comment

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

Removed.

component_id < balance.getNumberOfComponents();
++component_id)
{
// TODO find solution for 2d case
Copy link
Collaborator

Choose a reason for hiding this comment

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

Eigen::Map<...>(bulk_flux.data(), bulk_flux.size()).dot(Eigen::Map<...>(surface_element_normal.data(), surface_element_normal.size()) or similar.

Copy link
Member Author

Choose a reason for hiding this comment

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

getSurfaceNormal returns a MathLib::Vector3 object, i.e., the normal of the surface is always a 3d vector. Maybe we have o handle the 2d bulk / 1d boundary case special, i.e., rotate the 3d normal to the 2d plane. Anyway, I will change this and use the Eigen::Map solution.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I meant the Eigen::Map stuff as a solution for any dimension.
Even though getSurfaceNormal() returns a 3D vector, in 2D the z-component should always be zero, So you don't need to write a fixed 3 in your implementation.
Shouldn't the following work in any dimension (note the bulk_flux.size() in both places)?

                   Eigen::Map<Eigen::RowVectorXd const>(bulk_flux.data(),
                                                  bulk_flux.size())
                       .dot(Eigen::Map<Eigen::RowVectorXd const>(
                           surface_element_normal.getCoords(), bulk_flux.size())));

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 element normal is calculated in the physical space, not in natural coordinates. If the element is not in the x-y-plane then I am not convinced that the z-component of the element normal vanishs.

Copy link
Collaborator

@chleh chleh Sep 27, 2016

Choose a reason for hiding this comment

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

If the element is not in the x-y-plane then I am not convinced that the z-component of the element normal vanishs.

But then you are not in 2D (at least for my understanding). OK, there is the case of having 2D elements in 3D space... Let's leave it for later.

pos.setElementID(element_id);

auto surface_element_normal =
MeshLib::FaceRule::getSurfaceNormal(&_surface_element);
Copy link
Collaborator

@chleh chleh Sep 26, 2016

Choose a reason for hiding this comment

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

Note: A different approach is needed for higher order elements. Maybe add a TODO note?

Copy link
Member

Choose a reason for hiding this comment

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

The higher order elements are geometrically linear. Could you explain a little more, what should be different.

Copy link
Collaborator

@chleh chleh Sep 26, 2016

Choose a reason for hiding this comment

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

The higher order elements are geometrically linear.

AFAIK that is not true in general. The higher-order nodes are not necessarily on the faces, but can deviate from them. I think, @nagelt can explain that better than I.
Maybe cf. Isoparametric finite elements: Coordinates have the same shape functions as fields.

Copy link
Member Author

Choose a reason for hiding this comment

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

In the current implementation only geometricaly linear element are allowed.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't want to blame the current implementation, but maybe add a comment somewhere that for higher-order elements further work is needed. (E.g., add a todo note at this line.)

@@ -191,4 +191,24 @@ std::ostream& operator<<(std::ostream& os, LocalToGlobalIndexMap const& map)
}
#endif // NDEBUG

NumLib::LocalToGlobalIndexMap::RowColumnIndices getRowColumnIndices(
Copy link
Collaborator

Choose a reason for hiding this comment

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

There already is a very similar method (getIndices()) in NumLib/DOF/DOFTableUtil.cpp
Your getVectorValues() is already provided by EigenVector::get() etc.
As far as I can see.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for pointing this out, the changes concerning dof table are moved to a separat PR #1442.

@TomFischer
Copy link
Member Author

I am reworking the implementation.

@TomFischer TomFischer force-pushed the BalanceProcessPartII_a branch 2 times, most recently from b5bb3b7 to 9123797 Compare September 27, 2016 06:34
@TomFischer
Copy link
Member Author

I hope I fixed/commented all of @chleh remarks. The review can go on ...

@chleh
Copy link
Collaborator

chleh commented Sep 27, 2016

Two new comments (see above)

  • getSurfaceNormal
  • Eigen::Map<...>

afterwards 👍

#ifndef PROCESS_LIB_BALANCEPROCESS_H_
#define PROCESS_LIB_BALANCEPROCESS_H_

#include "NumLib/Extrapolation/LocalLinearLeastSquaresExtrapolator.h"
Copy link
Collaborator

@norihiro-w norihiro-w Sep 27, 2016

Choose a reason for hiding this comment

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

it's not used here ✅

boost::optional<MeshLib::PropertyVector<std::size_t> const&>
bulk_element_ids(boundary_mesh.getProperties()
.template getPropertyVector<std::size_t>(
"OriginalSubsurfaceElementIDs"));
Copy link
Collaborator

Choose a reason for hiding this comment

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

i think Subsurface is too specific. why not OriginalElementID?

Copy link
Member Author

Choose a reason for hiding this comment

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

If I change the name here, I have to change also the name in the tool ExtractSurface. If you really want change the name I would do this in a separate PR.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it's better to make the name general, but it's not urgent issue. One can change it later when they need it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Opened #1449.

case 3:
return MathLib::Point3d{std::array<double, 3>{{0.0, 1.0 - wp[0], 0.0}}};
default:
OGS_FATAL("Invalid face id '%u' for the quad.");
Copy link
Collaborator

@norihiro-w norihiro-w Sep 27, 2016

Choose a reason for hiding this comment

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

argument is missing ✅


#include "MeshLib/Elements/FaceRule.h"
#include "MeshLib/Elements/Elements.h"

Copy link
Collaborator

@norihiro-w norihiro-w Sep 27, 2016

Choose a reason for hiding this comment

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

i would add namespace ProcessLib ✅

GlobalDim);
std::vector<double> gradient;
gradient.resize(3);
Eigen::Map<Eigen::RowVectorXd>(gradient.data(), gradient.size()) =
Copy link
Collaborator

Choose a reason for hiding this comment

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

why is Conductivity not included?

Copy link
Member Author

Choose a reason for hiding this comment

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

Until know for the simple tests conductivity was always 1. I'll add conductivity to the formula.

{
std::vector<double> init_values(
_balance_mesh->getNumberOfElements(), 0.0);
MeshLib::addPropertyToMesh(*_balance_mesh, _balance_pv_name,
Copy link
Collaborator

Choose a reason for hiding this comment

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

does it add a new property every time step?

Copy link
Member Author

Choose a reason for hiding this comment

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

Here I assume that postTimeStepConcreteProcess() is called only once. If it is called for every time step a new name for PropertyVector has to be generated.

Copy link
Collaborator

Choose a reason for hiding this comment

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

is it because GroundwaterFlowProcess solves only one time step? I though postTimeStepConcreteProcess() is called for every time step...

Copy link
Collaborator

Choose a reason for hiding this comment

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

Obviously it has to be configurable at which timesteps the surface fluxes will be computed.
I suggest to implement it in a follow-up PR, and to leave the current implementation as it is.

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, here I assumed that GroundwaterFlowProcess solves only one time step.

@@ -175,13 +182,13 @@ class Process

VectorMatrixAssembler _global_assembler;

/// Variables used by this process.
std::vector<std::reference_wrapper<ProcessVariable>> _process_variables;
Copy link
Collaborator

Choose a reason for hiding this comment

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

isn't it possible to use getProcessVariables()?

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, it is possible. I revert my change and use getProcessVariables().

auto const k = _process_data.hydraulic_conductivity(t, pos)[0];

Eigen::Map<Eigen::RowVectorXd>(flux.data(), flux.size()) =
k * shape_matrices.dNdx *
Copy link
Collaborator

@norihiro-w norihiro-w Sep 28, 2016

Choose a reason for hiding this comment

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

we need a negative sign here, q = - K * grad(head) ✅

@norihiro-w
Copy link
Collaborator

👍 from my side

@TomFischer
Copy link
Member Author

Thanks for the review. Will start rebase and renaming ...

@TomFischer TomFischer force-pushed the BalanceProcessPartII_a branch 2 times, most recently from 89cc34e to d3f9068 Compare September 30, 2016 07:00
@TomFischer TomFischer merged commit 2a19360 into ufz:master Sep 30, 2016
@TomFischer TomFischer deleted the BalanceProcessPartII_a branch September 30, 2016 12:16
@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
Development

Successfully merging this pull request may close these issues.

5 participants