1 #ifndef __H2D_NEUTRONICS_WEAK_FORMS_H
2 #define __H2D_NEUTRONICS_WEAK_FORMS_H
4 #include "weakforms_h1.h"
6 #include "../function/filter.h"
12 namespace WeakFormsNeutronics
14 namespace Monoenergetic
39 template<
typename Scalar>
44 std::vector<double> D_map,
45 std::vector<double> Sigma_a_map,
46 std::vector<double> Q_map);
53 namespace MaterialProperties
58 typedef std::vector<double> rank1;
59 typedef std::vector<std::vector<double > > rank2;
60 typedef std::vector<std::vector<std::vector<double > > > rank3;
62 typedef std::map<std::string, rank0> MaterialPropertyMap0;
63 typedef std::map<std::string, rank1> MaterialPropertyMap1;
64 typedef std::map<std::string, rank2> MaterialPropertyMap2;
65 typedef std::map<std::string, rank3> MaterialPropertyMap3;
67 typedef std::vector<bool > bool1;
68 typedef std::vector<std::vector<bool > > bool2;
73 static const char* E_INF_VALUE =
74 "Attempt to set an infinite material property.";
75 static const char* W_NEG_VALUE =
76 "Entered material data lead to some negative properties.";
77 static const char* W_MG_EXTENSION =
78 "Attempted to create a multigroup material-property map in a container for singlegroup maps.";
79 static const char* W_SA_LT_SF =
80 "Possible unphysical situation detected: Sigma_a < Sigma_f.";
81 static const char* E_MR_EXTENSION =
82 "Cannot create a multiregion material-property map: no regions specified.";
83 static const char* E_INSUFFICIENT_DATA =
84 "Not all required material properties have been set.";
85 static const char* W_NO_FISSION =
86 "Not all required fission properties have been set or could be determined automatically."
87 "Assuming a non-fissioning system.";
88 static const char* W_NO_SCATTERING =
89 "Not all required scattering properties have been set or could be determined automatically."
90 "Assuming a purely absorbing system.";
91 static const char* E_INVALID_COMBINATION =
92 "Invalid combination of entered material properties.";
93 static const char* E_NONMATCHING_PROPERTIES =
94 "All properties must be defined for a single given number of materials.";
95 static const char* E_INVALID_SIZE =
96 "Material property defined for an unexpected number of groups.";
97 static const char* E_INVALID_GROUP_INDEX =
98 "Attempted to access an out-of-range group.";
99 static const char* E_INVALID_MARKER =
100 "Material data undefined for the given element marker.";
101 static const char* E_SG_SIGMA_R =
102 "Group-reduction cross-section (Sigma_r) is not defined for one-group (i.e. monoenergetic) problems."
103 "Set Sigma_a instead.";
106 namespace ValidationFunctors
108 using namespace Definitions;
109 using namespace Messages;
112 void operator() (MaterialPropertyMap1::value_type x) {
113 MaterialPropertyMap1::mapped_type::iterator it;
114 for (it = x.second.begin(); it != x.second.end(); ++it)
115 if (fabs(*it) > 1e-14)
116 throw Hermes::Exceptions::Exception(E_INVALID_COMBINATION);
121 ensure_size(
unsigned int nrows,
unsigned int ncols = 0)
122 : nrows(nrows), ncols(ncols) {};
124 void operator() (MaterialPropertyMap1::value_type x) {
125 if (x.second.size() != nrows)
126 throw Hermes::Exceptions::Exception(E_INVALID_SIZE);
129 void operator() (MaterialPropertyMap2::value_type x) {
130 if (x.second.size() != nrows)
131 throw Hermes::Exceptions::Exception(E_INVALID_SIZE);
133 MaterialPropertyMap2::mapped_type::iterator it;
134 for (it = x.second.begin(); it != x.second.end(); ++it)
135 if (it->size() != ncols)
136 throw Hermes::Exceptions::Exception(E_INVALID_SIZE);
140 unsigned int nrows, ncols;
146 using namespace Definitions;
147 using namespace Messages;
156 template <
typename NDArrayType>
157 static rank0 divide(rank0 x, rank0 y) {
158 if (x == 0 && y == 0)
162 throw Hermes::Exceptions::Exception(E_INF_VALUE);
169 template <
typename NDArrayType>
170 static rank0 multiply(rank0 x, rank0 y) {
174 template <
typename NDArrayType>
175 static rank0 add(rank0 x, rank0 y) {
179 template <
typename NDArrayType>
180 static rank0 subtract(rank0 x, rank0 y) {
187 #define for_each_element_in_dimension \
188 typedef typename NDArrayType::value_type dim_type; \
189 typename NDArrayType::const_iterator dim_iterator_x = x.begin(); \
190 typename NDArrayType::const_iterator dim_iterator_y = y.begin(); \
191 for (; dim_iterator_x != x.end(); ++dim_iterator_x, ++dim_iterator_y)
193 template <
typename NDArrayType>
194 static NDArrayType divide(
const NDArrayType& x,
const NDArrayType& y)
196 NDArrayType res; res.reserve(x.size());
198 for_each_element_in_dimension
199 res.push_back(divide<dim_type>(*dim_iterator_x, *dim_iterator_y));
204 template <
typename NDArrayType>
205 static NDArrayType multiply(
const NDArrayType& x,
const NDArrayType& y)
207 NDArrayType res; res.reserve(x.size());
209 for_each_element_in_dimension
210 res.push_back(multiply<dim_type>(*dim_iterator_x, *dim_iterator_y));
215 template <
typename NDArrayType>
216 static NDArrayType add(
const NDArrayType& x,
const NDArrayType& y)
218 NDArrayType res; res.reserve(x.size());
220 for_each_element_in_dimension
221 res.push_back(add<dim_type>(*dim_iterator_x, *dim_iterator_y));
226 template <
typename NDArrayType>
227 static NDArrayType subtract(
const NDArrayType& x,
const NDArrayType& y)
229 NDArrayType res; res.reserve(x.size());
231 for_each_element_in_dimension
232 res.push_back(subtract<dim_type>(*dim_iterator_x, *dim_iterator_y));
237 #undef for_each_element_in_dimension
239 #define for_each_element_in_map \
240 typename std::map<std::string, T>::iterator iterator_ret = ret.begin(); \
241 typename std::map<std::string, T>::const_iterator iterator_x = x.begin(); \
242 typename std::map<std::string, T>::const_iterator iterator_y = y.begin(); \
243 for (; iterator_x != x.end(); ++iterator_x, ++iterator_y, ++iterator_ret)
245 template <
typename T>
246 static std::map<std::string, T> divide(
const std::map<std::string, T>& x,
247 const std::map<std::string, T>& y)
249 std::map<std::string, T> ret = x;
251 for_each_element_in_map
252 iterator_ret->second = divide<T>(iterator_x->second, iterator_y->second);
257 template <
typename T>
258 static std::map<std::string, T> multiply(
const std::map<std::string, T>& x,
259 const std::map<std::string, T>& y)
261 std::map<std::string, T> ret = x;
263 for_each_element_in_map
264 iterator_ret->second = multiply<T>(iterator_x->second, iterator_y->second);
269 template <
typename T>
270 static std::map<std::string, T> add(
const std::map<std::string, T>& x,
271 const std::map<std::string, T>& y)
273 std::map<std::string, T> ret = x;
275 for_each_element_in_map
276 iterator_ret->second = add<T>(iterator_x->second, iterator_y->second);
281 template <
typename T>
282 static std::map<std::string, T> subtract(
const std::map<std::string, T>& x,
283 const std::map<std::string, T>& y)
285 std::map<std::string, T> ret = x;
287 for_each_element_in_map
288 iterator_ret->second = subtract<T>(iterator_x->second, iterator_y->second);
293 #undef for_each_element_in_map
300 MaterialPropertyMap1 Sigma_f;
301 MaterialPropertyMap1 nu;
302 MaterialPropertyMap1 chi;
304 MaterialPropertyMap1 Sigma_a;
305 MaterialPropertyMap1 nuSigma_f;
307 std::set<std::string> materials_list;
310 bool1 fission_multigroup_structure;
312 void extend_to_multigroup(
const MaterialPropertyMap0& mrsg_map, MaterialPropertyMap1 *mrmg_map);
314 void extend_to_multiregion(
const rank1& srmg_array, MaterialPropertyMap1 *mrmg_map);
316 void extend_to_multiregion_multigroup(
const rank0& srsg_value, MaterialPropertyMap1 *mrmg_map);
318 void fill_with(
double c, MaterialPropertyMap1 *mrmg_map);
321 : materials_list(mat_list), G(G) { };
323 virtual void validate();
327 void set_nu(
const MaterialPropertyMap1& nu) {
331 void set_nu(
const MaterialPropertyMap0& nu) {
332 extend_to_multigroup(nu, &this->nu);
335 void set_nu(
const rank1& nu) {
336 extend_to_multiregion(nu, &this->nu);
339 void set_nu(
const rank0& nu) {
340 extend_to_multiregion_multigroup(nu, &this->nu);
343 void set_chi(
const MaterialPropertyMap1& chi) {
347 void set_chi(
const rank1& chi) {
348 extend_to_multiregion(chi, &this->chi);
351 void set_fission_multigroup_structure(
const bool1& chi_nnz) {
352 this->fission_multigroup_structure = chi_nnz;
355 void set_Sigma_a(
const MaterialPropertyMap1& Sa) {
359 void set_Sigma_f(
const MaterialPropertyMap1& Sf) {
363 void set_nuSigma_f(
const MaterialPropertyMap1 nSf) {
364 this->nuSigma_f = nSf;
367 const MaterialPropertyMap1& get_Sigma_f()
const {
368 return this->Sigma_f;
370 const MaterialPropertyMap1& get_nu()
const {
373 const MaterialPropertyMap1& get_chi()
const {
376 const bool1& get_fission_multigroup_structure()
const {
377 return this->fission_multigroup_structure;
380 const rank1& get_Sigma_f(
std::string material)
const;
384 unsigned int get_G()
const {
return G; }
392 using namespace Definitions;
393 using namespace Messages;
399 MaterialPropertyMap1 D;
400 MaterialPropertyMap1 Sigma_r;
401 MaterialPropertyMap2 Sigma_s;
402 MaterialPropertyMap1 src;
404 MaterialPropertyMap1 Sigma_t;
406 bool2 scattering_multigroup_structure;
413 MaterialPropertyMap1 extract_map2_diagonals(
const MaterialPropertyMap2& map2);
415 MaterialPropertyMap1 sum_map2_columns(
const MaterialPropertyMap2& map2);
417 MaterialPropertyMap2 create_map2_by_diagonals(
const MaterialPropertyMap1& diags);
419 void fill_with(
double c, MaterialPropertyMap2 *mrmg_map);
428 virtual void validate();
430 void set_src(
const MaterialPropertyMap1& src) {
434 void set_src(
const MaterialPropertyMap0& src) {
435 extend_to_multigroup(src, &this->src);
438 void set_src(
const rank1& src) {
439 extend_to_multiregion(src, &this->src);
442 void set_src(
const double& src) {
443 extend_to_multiregion_multigroup(src, &this->src);
446 void set_D(
const MaterialPropertyMap1& D) {
450 void set_Sigma_r(
const MaterialPropertyMap1& Sr) {
454 void set_Sigma_t(
const MaterialPropertyMap1& St) {
458 void set_Sigma_s(
const MaterialPropertyMap2& Ss) {
462 void set_scattering_multigroup_structure(
const bool2& Ss_nnz) {
463 this->scattering_multigroup_structure = Ss_nnz;
466 const MaterialPropertyMap2& get_Sigma_s()
const {
467 return this->Sigma_s;
469 const MaterialPropertyMap1& get_Sigma_r()
const {
470 return this->Sigma_r;
472 const MaterialPropertyMap1& get_D()
const {
475 const MaterialPropertyMap1& get_src()
const {
478 const bool2& get_scattering_multigroup_structure()
const {
479 return this->scattering_multigroup_structure;
482 const rank2& get_Sigma_s(
std::string material)
const;
483 const rank1& get_Sigma_r(
std::string material)
const;
487 friend HERMES_API std::ostream & operator<< (std::ostream& os,
const MaterialPropertyMaps& matprop);
491 template <
typename NDArrayType>
495 std::map<std::string, NDArrayType> m_map;
506 operator std::map<std::string, NDArrayType>() {
511 template <
typename NDArrayType>
515 std::vector<NDArrayType> m_data;
518 m_data.push_back(val);
522 m_data.push_back(val);
526 operator std::vector<NDArrayType>() {
531 namespace Definitions
540 namespace ElementaryForms
544 using namespace MaterialProperties::Diffusion;
554 : matprop(matprop), geom_type(geom_type)
559 : matprop(matprop), geom_type(geom_type), mesh(mesh)
568 template<
typename Scalar>
574 g(g), geom_type(geom_type)
579 g(g), geom_type(geom_type)
581 this->set_area(area);
584 template<
typename Real,
typename ScalarTestFns>
590 return matrix_form<double, Scalar>(n, wt, u_ext, u, v, e, ext);
595 return matrix_form<Hermes::Ord, Hermes::Ord>(n, wt, u_ext, u, v, e, ext);
608 template<
typename Scalar>
614 g(g), geom_type(geom_type)
619 g(g), geom_type(geom_type)
621 this->set_area(area);
624 template<
typename Real,
typename ScalarTestFns>
628 virtual Scalar value(
int n,
double *wt,
Func<Scalar> *u_ext[],
630 return vector_form<double, Scalar>(n, wt, u_ext, v, e, ext);
635 return vector_form<Hermes::Ord, Hermes::Ord>(n, wt, u_ext, v, e, ext);
651 template<
typename Scalar>
668 this->set_area(area);
684 this->set_area(area);
687 template<
typename Real,
typename ScalarTestFns>
693 return matrix_form<double, Scalar>(n, wt, u_ext, u, v, e, ext);
698 return matrix_form<Hermes::Ord, Hermes::Ord>(n, wt, u_ext, u, v, e, ext);
711 template<
typename Scalar>
729 this->set_area(area);
745 this->set_area(area);
748 template<
typename Real,
typename ScalarTestFns>
754 return vector_form<double, Scalar>(n, wt, u_ext, v, e, ext);
759 return vector_form<Hermes::Ord, Hermes::Ord>(n, wt, u_ext, v, e, ext);
775 template<
typename Scalar>
780 Jacobian(
unsigned int gto,
unsigned int gfrom,
784 gto(gto), gfrom(gfrom)
791 gto(gto), gfrom(gfrom)
793 this->set_area(area);
796 Jacobian(
unsigned int gto,
unsigned int gfrom,
800 gto(gto), gfrom(gfrom)
807 gto(gto), gfrom(gfrom)
809 this->set_area(area);
812 template<
typename Real,
typename ScalarTestFns>
818 return -1.0 * matrix_form<double, Scalar>(n, wt, u_ext, u, v, e, ext);
823 return matrix_form<Hermes::Ord, Hermes::Ord>(n, wt, u_ext, u, v, e, ext);
833 unsigned int gto, gfrom;
836 template<
typename Scalar>
851 if (g >= iterates.size())
852 throw Hermes::Exceptions::Exception(E_INVALID_GROUP_INDEX);
864 this->set_area(area);
866 if (g >= iterates.size())
867 throw Hermes::Exceptions::Exception(E_INVALID_GROUP_INDEX);
880 if (g >= iterates.size())
881 throw Hermes::Exceptions::Exception(E_INVALID_GROUP_INDEX);
893 this->set_area(area);
895 if (g >= iterates.size())
896 throw Hermes::Exceptions::Exception(E_INVALID_GROUP_INDEX);
899 template<
typename Real,
typename ScalarTestFns>
905 return -1.0 * vector_form<double, Scalar>(n, wt, u_ext, v, e, ext);
910 return vector_form<Hermes::Ord, Hermes::Ord>(n, wt, u_ext, v, e, ext);
918 void update_keff(
double new_keff) { keff = new_keff; }
926 template<
typename Scalar>
930 Residual(
unsigned int gto,
unsigned int gfrom,
934 gto(gto), gfrom(gfrom)
941 gto(gto), gfrom(gfrom)
943 this->set_area(area);
946 Residual(
unsigned int gto,
unsigned int gfrom,
950 gto(gto), gfrom(gfrom)
957 gto(gto), gfrom(gfrom)
959 this->set_area(area);
962 template<
typename Real,
typename ScalarTestFns>
968 return -1.0 * vector_form<double, Scalar>(n, wt, u_ext, v, e, ext);
973 return vector_form<Hermes::Ord, Hermes::Ord>(n, wt, u_ext, v, e, ext);
983 unsigned int gto, gfrom;
989 template<
typename Scalar>
994 Jacobian(
unsigned int gto,
unsigned int gfrom,
998 gto(gto), gfrom(gfrom)
1005 gto(gto), gfrom(gfrom)
1008 Jacobian(
unsigned int gto,
unsigned int gfrom,
1012 gto(gto), gfrom(gfrom)
1019 gto(gto), gfrom(gfrom)
1022 template<
typename Real,
typename ScalarTestFns>
1028 return -1.0 * matrix_form<double, Scalar>(n, wt, u_ext, u, v, e, ext);
1033 return matrix_form<Hermes::Ord, Hermes::Ord>(n, wt, u_ext, u, v, e, ext);
1043 unsigned int gto, gfrom;
1046 template<
typename Scalar>
1050 Residual(
unsigned int gto,
unsigned int gfrom,
1052 GeomType geom_type = HERMES_PLANAR)
1055 gto(gto), gfrom(gfrom)
1060 GeomType geom_type = HERMES_PLANAR)
1063 gto(gto), gfrom(gfrom)
1066 Residual(
unsigned int gto,
unsigned int gfrom,
1068 GeomType geom_type = HERMES_PLANAR)
1071 gto(gto), gfrom(gfrom)
1076 GeomType geom_type = HERMES_PLANAR)
1079 gto(gto), gfrom(gfrom)
1082 template<
typename Real,
typename ScalarTestFns>
1088 return -1.0 * vector_form<double, Scalar>(n, wt, u_ext, v, e, ext);
1093 return vector_form<Hermes::Ord, Hermes::Ord>(n, wt, u_ext, v, e, ext);
1103 unsigned int gto, gfrom;
1109 template<
typename Scalar>
1142 template<
typename Real,
typename ScalarTestFns>
1148 return -1.0 * vector_form<double, Scalar>(n, wt, u_ext, v, e, ext);
1153 return vector_form<Hermes::Ord, Hermes::Ord>(n, wt, u_ext, v, e, ext);
1169 namespace CompleteWeakForms
1173 using namespace MaterialProperties;
1174 using namespace ElementaryForms::Diffusion;
1176 template<
typename Scalar>
1184 GeomType geom_type = HERMES_PLANAR);
1187 Hermes2DFunction<Scalar>*f_src,
1189 GeomType geom_type = HERMES_PLANAR);
1192 Hermes2DFunction<Scalar>*f_src,
1193 std::vector<std::string> src_areas,
1194 GeomType geom_type = HERMES_PLANAR);
1197 const std::vector<Hermes2DFunction<Scalar>*>& f_src,
1199 GeomType geom_type = HERMES_PLANAR);
1202 const std::vector<Hermes2DFunction<Scalar>*>& f_src,
1203 std::vector<std::string> src_areas,
1204 GeomType geom_type = HERMES_PLANAR);
1207 template<
typename Scalar>
1211 std::vector<FissionYield::OuterIterationForm<Scalar>*> keff_iteration_forms;
1216 double initial_keff_guess,
1217 GeomType geom_type = HERMES_PLANAR);
1219 void update_keff(
double new_keff);
1227 namespace SupportClasses
1229 using MaterialProperties::Common::MaterialPropertyMaps;
1230 using namespace MaterialProperties::Definitions;
1237 :
SimpleFilter<double>(solutions, std::vector<int>()), matprop(matprop), source_area(source_area)
1239 nu = matprop->get_nu().at(source_area);
1240 Sigma_f = matprop->get_Sigma_f().at(source_area);
1245 const MaterialPropertyMaps* matprop;
1248 void filter_fn(
int n,
const std::vector<const double*>& values,
double* result);
Geometry - volumetric - for order calculation.
Calculated function values (from the class Function) on an element for assembling.
::xsd::cxx::tree::string< char, simple_type > string
C++ type corresponding to the string XML Schema built-in type.
Geometry - surface - for order calculation.
GeomType
Geometrical type of weak forms.