1 //                                               -*- C++ -*-
2 /**
3  *  @brief Abstract top-level class for all temporal functions
4  *
5  *  Copyright 2005-2021 Airbus-EDF-IMACS-ONERA-Phimeca
6  *
7  *  This library is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU Lesser General Public License as published by
9  *  the Free Software Foundation, either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public License
18  *  along with this library.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 #include "openturns/VertexValueFunction.hxx"
22 #include "openturns/PersistentObjectFactory.hxx"
23 #include "openturns/EvaluationImplementation.hxx"
24 #include "openturns/NoEvaluation.hxx"
25 
26 BEGIN_NAMESPACE_OPENTURNS
27 
28 CLASSNAMEINIT(VertexValueFunction)
29 
30 static const Factory<VertexValueFunction> Factory_VertexValueFunction;
31 
32 /* Default constructor */
VertexValueFunction()33 VertexValueFunction::VertexValueFunction()
34   : FieldFunctionImplementation()
35   , function_()
36 {
37   // Nothing to do
38 }
39 
40 /* Parameter constructor */
VertexValueFunction(const Function & function,const Mesh & mesh)41 VertexValueFunction::VertexValueFunction(const Function & function,
42     const Mesh & mesh)
43   : FieldFunctionImplementation(mesh, std::max(static_cast<SignedInteger>(function.getInputDimension()) - static_cast<SignedInteger>(mesh.getDimension()), static_cast<SignedInteger>(0)), mesh, function.getOutputDimension())
44   , function_(function)
45 {
46   // Check that the given function has an input dimension large enough to be compatible with the mesh dimension
47   if (function_.getInputDimension() < mesh.getDimension()) throw InvalidArgumentException(HERE) << "Error: the given function should have an input dimension at least equal to the mesh dimension=" << mesh.getDimension() << ". Here input dimension=" << function_.getInputDimension();
48   // Set the descriptions
49   Description inputDescription(function_.getInputDescription());
50   inputDescription.erase(inputDescription.begin(), inputDescription.begin() + mesh.getDimension());
51   setInputDescription(inputDescription);
52   setOutputDescription(function_.getOutputDescription());
53 }
54 
55 /* Parameter constructor */
VertexValueFunction(const Evaluation & evaluation,const Mesh & mesh)56 VertexValueFunction::VertexValueFunction(const Evaluation & evaluation,
57     const Mesh & mesh)
58   : FieldFunctionImplementation(mesh, std::max(static_cast<SignedInteger>(evaluation.getInputDimension()) - static_cast<SignedInteger>(mesh.getDimension()), static_cast<SignedInteger>(0)), mesh, evaluation.getOutputDimension())
59   , function_(evaluation)
60 {
61   // Check that the given function has an input dimension large enough to be compatible with the mesh dimension
62   if (function_.getInputDimension() < mesh.getDimension()) throw InvalidArgumentException(HERE) << "Error: the given function should have an input dimension at least equal to the mesh dimension=" << mesh.getDimension() << ". Here input dimension=" << function_.getInputDimension();
63   // Set the descriptions
64   Description inputDescription(function_.getInputDescription());
65   inputDescription.erase(inputDescription.begin(), inputDescription.begin() + mesh.getDimension());
66   setInputDescription(inputDescription);
67   setOutputDescription(function_.getOutputDescription());
68 }
69 
70 /* Parameter constructor */
VertexValueFunction(const EvaluationImplementation & evaluation,const Mesh & mesh)71 VertexValueFunction::VertexValueFunction(const EvaluationImplementation & evaluation,
72     const Mesh & mesh)
73   : FieldFunctionImplementation(mesh, std::max(static_cast<SignedInteger>(evaluation.getInputDimension()) - static_cast<SignedInteger>(mesh.getDimension()), static_cast<SignedInteger>(0)), mesh, evaluation.getOutputDimension())
74   , function_(evaluation)
75 {
76   // Check that the given function has an input dimension large enough to be compatible with the mesh dimension
77   if (function_.getInputDimension() < mesh.getDimension()) throw InvalidArgumentException(HERE) << "Error: the given function should have an input dimension at least equal to the mesh dimension=" << mesh.getDimension() << ". Here input dimension=" << function_.getInputDimension();
78   // Set the descriptions
79   Description inputDescription(function_.getInputDescription());
80   inputDescription.erase(inputDescription.begin(), inputDescription.begin() + mesh.getDimension());
81   setInputDescription(inputDescription);
82   setOutputDescription(function_.getOutputDescription());
83 }
84 
85 /* Virtual constructor */
clone() const86 VertexValueFunction * VertexValueFunction::clone() const
87 {
88   return new VertexValueFunction(*this);
89 }
90 
91 /* Comparison operator */
operator ==(const VertexValueFunction &) const92 Bool VertexValueFunction::operator ==(const VertexValueFunction & ) const
93 {
94   return true;
95 }
96 
97 /* String converter */
__repr__() const98 String VertexValueFunction::__repr__() const
99 {
100   OSS oss(true);
101   oss << "class=" << VertexValueFunction::GetClassName()
102       << " evaluation=" << function_.__repr__();
103   return oss;
104 }
105 
106 /* String converter */
__str__(const String & offset) const107 String VertexValueFunction::__str__(const String & offset) const
108 {
109   return OSS(false) << function_.__str__(offset);
110 }
111 
112 /* Operator () */
operator ()(const Sample & inFld) const113 Sample VertexValueFunction::operator() (const Sample & inFld) const
114 {
115   if (inFld.getDimension() != getInputDimension()) throw InvalidArgumentException(HERE) << "Error: expected a field with dimension=" << getInputDimension() << ", got dimension=" << inFld.getDimension();
116   callsNumber_.increment();
117   Sample verticesValues(getInputMesh().getVertices());
118   verticesValues.stack(inFld);
119   return function_(verticesValues);
120 }
121 
122 /* Get the i-th marginal function */
getMarginal(const UnsignedInteger i) const123 VertexValueFunction::Implementation VertexValueFunction::getMarginal(const UnsignedInteger i) const
124 {
125   if (!(i < getOutputDimension())) throw InvalidArgumentException(HERE) << "Error: the index of a marginal function must be in the range [0, outputDimension-1], here index=" << i << " and outputDimension=" << getOutputDimension();
126   return new VertexValueFunction(function_.getMarginal(i), getInputMesh());
127 }
128 
129 /* Get the function corresponding to indices components */
getMarginal(const Indices & indices) const130 VertexValueFunction::Implementation VertexValueFunction::getMarginal(const Indices & indices) const
131 {
132   if (!indices.check(getOutputDimension())) throw InvalidArgumentException(HERE) << "Error: the indices of a marginal function must be in the range [0, outputDimension-1] and must be different";
133   return new VertexValueFunction(function_.getMarginal(indices), getInputMesh());
134 }
135 
136 /* Evaluation accessor */
getFunction() const137 Function VertexValueFunction::getFunction() const
138 {
139   return function_;
140 }
141 
isActingPointwise() const142 Bool VertexValueFunction::isActingPointwise() const
143 {
144   return true;
145 }
146 
147 /* Method save() stores the object through the StorageManager */
save(Advocate & adv) const148 void VertexValueFunction::save(Advocate & adv) const
149 {
150   FieldFunctionImplementation::save(adv);
151   adv.saveAttribute( "function_", function_ );
152 }
153 
154 /* Method load() reloads the object from the StorageManager */
load(Advocate & adv)155 void VertexValueFunction::load(Advocate & adv)
156 {
157   FieldFunctionImplementation::load(adv);
158   adv.loadAttribute( "function_", function_ );
159 }
160 
161 
162 
163 
164 END_NAMESPACE_OPENTURNS
165