preCICE v3.1.1
Loading...
Searching...
No Matches
ScaleByAreaAction.cpp
Go to the documentation of this file.
2#include <Eigen/Core>
3#include <memory>
4#include "action/Action.hpp"
6#include "mapping/Mapping.hpp"
7#include "mesh/Data.hpp"
8#include "mesh/Edge.hpp"
9#include "mesh/Mesh.hpp"
10#include "mesh/Vertex.hpp"
11#include "utils/assertion.hpp"
12
13namespace precice::action {
14
16 Timing timing,
17 int targetDataID,
18 const mesh::PtrMesh &mesh,
19 Scaling scaling)
20 : Action(timing, mesh, mapping::Mapping::MeshRequirement::FULL),
21 _targetData(mesh->data(targetDataID)),
22 _scaling(scaling)
23{
24}
25
27{
29 const int meshDimensions = getMesh()->getDimensions();
30
31 for (auto &targetStample : _targetData->stamples()) {
32
33 auto &targetValues = _targetData->values();
34 targetValues = targetStample.sample.values;
35 const int valueDimensions = _targetData->getDimensions();
36 Eigen::VectorXd areas = Eigen::VectorXd::Zero(getMesh()->nVertices());
37 PRECICE_ASSERT(targetValues.size() / valueDimensions == areas.size());
38
39 if (meshDimensions == 2) {
40 PRECICE_CHECK(getMesh()->edges().size() != 0,
41 "The multiply/divide-by-area actions require meshes with connectivity information. In 2D, please ensure that the mesh {} contains edges.", getMesh()->getName());
42 for (mesh::Edge &edge : getMesh()->edges()) {
43 areas[edge.vertex(0).getID()] += edge.getEnclosingRadius();
44 areas[edge.vertex(1).getID()] += edge.getEnclosingRadius();
45 }
46 } else {
47 PRECICE_CHECK(getMesh()->triangles().size() != 0,
48 "The multiply/divide-by-area actions require meshes with connectivity information. In 3D, please ensure that the mesh {} contains triangles.", getMesh()->getName());
49 for (mesh::Triangle &face : getMesh()->triangles()) {
50 areas[face.vertex(0).getID()] += face.getArea() / 3.0;
51 areas[face.vertex(1).getID()] += face.getArea() / 3.0;
52 areas[face.vertex(2).getID()] += face.getArea() / 3.0;
53 }
54 }
56 for (int i = 0; i < areas.size(); i++) {
57 for (int dim = 0; dim < valueDimensions; dim++) {
58 int valueIndex = i * valueDimensions + dim;
59 targetValues[valueIndex] /= areas[i];
60 }
61 }
62 } else if (_scaling == SCALING_MULTIPLY_BY_AREA) {
63 for (int i = 0; i < areas.size(); i++) {
64 for (int dim = 0; dim < valueDimensions; dim++) {
65 int valueIndex = i * valueDimensions + dim;
66 targetValues[valueIndex] *= areas[i];
67 }
68 }
69 }
70 _targetData->setSampleAtTime(targetStample.timestamp, _targetData->sample());
71 }
72}
73
74} // namespace precice::action
#define PRECICE_TRACE(...)
Definition LogMacros.hpp:95
#define PRECICE_CHECK(check,...)
Definition LogMacros.hpp:35
#define PRECICE_ASSERT(...)
Definition assertion.hpp:87
Abstract base class for configurable actions on data and/or meshes.
Definition Action.hpp:14
Timing
Defines the time and place of application of the action.
Definition Action.hpp:17
const mesh::PtrMesh & getMesh() const
Returns the mesh carrying the data used in the action.
Definition Action.hpp:57
@ SCALING_MULTIPLY_BY_AREA
Multiplies the data by the area of neighboring edges/triangles.
@ SCALING_DIVIDE_BY_AREA
Divides the data by the area of neighboring edges/triangles.
ScaleByAreaAction(Timing timing, int targetDataID, const mesh::PtrMesh &mesh, Scaling scaling)
Constructor.
void performAction() final override
Scales data on mesh nodes according to selected scaling type.
Linear edge of a mesh, defined by two Vertex objects.
Definition Edge.hpp:16
Triangle of a mesh, defined by three vertices.
Definition Triangle.hpp:27
contains actions to modify exchanged data.
Definition Action.hpp:6