Chi-Tech
multifield.cc
Go to the documentation of this file.
1#include "multifield.h"
2
3#include "ChiObjectFactory.h"
4
7
9{
10
12
13// ##################################################################
14/**Returns the input parameters.*/
16{
18
19 params.SetDocGroup("DocFieldOperation");
20
21 params.AddRequiredParameter<size_t>(
22 "result_field_handle",
23 "Handle to the field function that should "
24 "receive the result of the operation.");
25
26 params.AddOptionalParameterArray("dependent_field_handles",
27 std::vector<int>{},
28 "List of dependent field handles");
29
30 params.AddOptionalParameterArray("dependent_component_references",
31 std::vector<unsigned int>{},
32 "The components of interest for each "
33 "handle supplied");
34 params.AddOptionalParameterArray("result_component_references",
35 std::vector<unsigned int>{},
36 "The components to write into the result "
37 "field function");
38
39 params.AddRequiredParameter<size_t>("function_handle",
40 "Handle to a FunctionDimAToDimB derived"
41 " object");
42
43 return params;
44}
45
46// ##################################################################
47/**Constructor.*/
49 const chi::InputParameters& params)
50 : FieldOperation(params),
51 result_field_handle_(params.GetParamValue<size_t>("result_field_handle")),
52 dependent_field_handles_(
53 params.GetParamVectorValue<size_t>("dependent_field_handles")),
54 function_handle_(params.GetParamValue<size_t>("function_handle"))
55{
56 //============================================= Make component references
57 const auto& user_supplied_params = params.ParametersAtAssignment();
58 if (user_supplied_params.Has("dependent_component_references"))
59 {
61 user_supplied_params.GetParamVectorValue<unsigned int>(
62 "dependent_component_references");
63
66 "Not each dependent field handle has an associated "
67 "reference component");
68 }
69 else
71
72 if (user_supplied_params.Has("result_component_references"))
73 {
75 user_supplied_params.GetParamVectorValue<unsigned int>(
76 "result_component_references");
77 }
78 else
80
81 //============================================= Process handles
82 auto ff_base_ptr = Chi::GetStackItemPtr(
84
85 primary_ff_ = std::dynamic_pointer_cast<FieldFunctionGridBased>(ff_base_ptr);
86
88 "Primary field function must be based on "
89 "FieldFunctionGridBased");
90
91 for (const size_t dep_handle : dependent_field_handles_)
92 {
93 auto dep_ff_base_ptr =
94 Chi::GetStackItemPtr(Chi::field_function_stack, dep_handle, __FUNCTION__);
95
96 auto dep_ff_ptr =
97 std::dynamic_pointer_cast<FieldFunctionGridBased>(dep_ff_base_ptr);
98
99 ChiLogicalErrorIf(not dep_ff_ptr,
100 "Dependent field function must be based on "
101 "FieldFunctionGridBased");
102
103 dependent_ffs_.push_back(dep_ff_ptr);
104 }
105
106 auto function_base_obj =
108
110 std::dynamic_pointer_cast<chi_math::FunctionDimAToDimB>(function_base_obj);
111
112 ChiLogicalErrorIf(not function_ptr_, "Casting failure of function");
113
114 const size_t num_dependencies = dependent_ffs_.size() + 4;
115 ChiInvalidArgumentIf(function_ptr_->InputDimension() != num_dependencies,
116 std::string("The function will be called with "
117 "x,y,z,material_id and then each of the "
118 "dependent field function values. ") +
119 "This means the function needs to be callable"
120 " with 4+" +
121 std::to_string(dependent_ffs_.size()) +
122 " values, "
123 "however, it only supports " +
124 std::to_string(function_ptr_->InputDimension()) +
125 " values.");
126
128 function_ptr_->OutputDimension() != result_component_references_.size(),
129 std::string("The function will return ") +
130 std::to_string(function_ptr_->OutputDimension()) +
131 " values however this operation only requires " +
132 std::to_string(result_component_references_.size()) + " value(s).");
133}
134
135// ##################################################################
136/**Constructor.*/
138{
139 typedef unsigned int uint;
140 typedef const int64_t cint64_t;
141 const auto& sdm = primary_ff_->GetSpatialDiscretization();
142 const auto& uk_man = primary_ff_->GetUnknownManager();
143 const auto& grid = sdm.Grid();
144
145 const size_t num_deps = dependent_ffs_.size();
146
147 for (const auto& cell : grid.local_cells)
148 {
149 const auto& cell_mapping = sdm.GetCellMapping(cell);
150 const size_t num_nodes = cell_mapping.NumNodes();
151
152 const auto nodes_xyz = cell_mapping.GetNodeLocations();
153
154 for (size_t i = 0; i < num_nodes; ++i)
155 {
156 std::vector<double> input_params;
157 const auto& node_i_xyz = nodes_xyz[i];
158 for (size_t d = 0; d < 3; ++d)
159 input_params.push_back(node_i_xyz[d]);
160 input_params.push_back(static_cast<double>(cell.material_id_));
161
162 for (size_t k = 0; k < num_deps; ++k)
163 {
164 const auto& dep_ff = dependent_ffs_[k];
165 const double value =
166 dep_ff->Evaluate(cell, node_i_xyz, dependent_field_ref_component_[k]);
167 input_params.push_back(value);
168 }
169
170 std::vector<double> output_params = function_ptr_->Evaluate(input_params);
171
173 output_params.size() != result_component_references_.size(),
174 "Calling function number of output values not matching");
175
176 size_t k = 0;
178 {
179 cint64_t dof_map = sdm.MapDOFLocal(cell, i, uk_man, 0, c);
180
181 primary_ff_->FieldVector()[dof_map] = output_params[k++];
182 }
183
184 } // for node i
185 } // for cell
186}
187
188} // namespace chi_physics::field_operations
#define ChiLogicalErrorIf(condition, message)
#define ChiInvalidArgumentIf(condition, message)
static std::vector< chi_physics::FieldFunctionPtr > field_function_stack
Definition: chi_runtime.h:92
static std::vector< ChiObjectPtr > object_stack
Definition: chi_runtime.h:96
static std::shared_ptr< T > & GetStackItemPtr(std::vector< std::shared_ptr< T > > &stack, const size_t handle, const std::string &calling_function_name="Unknown")
Definition: chi_runtime.h:258
void SetDocGroup(const std::string &doc_group)
void AddRequiredParameter(const std::string &name, const std::string &doc_string)
const ParameterBlock & ParametersAtAssignment() const
void AddOptionalParameterArray(const std::string &name, const std::vector< T > &array, const std::string &doc_string)
static chi::InputParameters GetInputParameters()
const std::vector< size_t > dependent_field_handles_
Definition: multifield.h:17
std::vector< unsigned int > result_component_references_
Definition: multifield.h:21
std::vector< std::shared_ptr< const FieldFunction > > dependent_ffs_
Definition: multifield.h:24
std::shared_ptr< const chi_math::FunctionDimAToDimB > function_ptr_
Definition: multifield.h:26
static chi::InputParameters GetInputParameters()
Definition: multifield.cc:15
std::shared_ptr< FieldFunctionGridBased > primary_ff_
Definition: multifield.h:23
std::vector< unsigned int > dependent_field_ref_component_
Definition: multifield.h:20
MultiFieldOperation(const chi::InputParameters &params)
Definition: multifield.cc:48
RegisterChiObject(chi_physics::field_operations, FieldCopyOperation)
#define uint