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