27 void fem_product::init() {
29 GMM_ASSERT1(pfems[0]->target_dim() == 1,
"To be done");
30 GMM_ASSERT1(pfems[1]->target_dim() == 1,
31 "The second finite element should be scalar");
33 cvr = pfems[0]->ref_convex(cv);
34 dim_ = cvr->structure()->dim();
35 is_equiv = real_element_defined =
true;
36 is_polycomp = is_pol = is_lag = is_standard_fem =
false;
40 nm <<
"FEM_PRODUCT(" << pfems[0]->debug_name() <<
","
41 << pfems[1]->debug_name() <<
"," << cv <<
")";
42 debug_name_ = nm.str();
45 for (dal::bv_visitor i(enriched_dof1); !i.finished(); ++i) {
46 for (
size_type j = 0; j < pfems[1]->nb_dof(cv); ++j)
47 add_node(
xfem_dof(pfems[0]->dof_types()[i], xfem_index+j),
48 pfems[0]->node_of_dof(cv,i));
52 void fem_product::base_value(
const base_node &,
54 { GMM_ASSERT1(
false,
"No base values, real only element."); }
55 void fem_product::grad_base_value(
const base_node &,
57 { GMM_ASSERT1(
false,
"No base values, real only element."); }
58 void fem_product::hess_base_value(
const base_node &,
60 { GMM_ASSERT1(
false,
"No base values, real only element."); }
62 void fem_product::real_base_value(
const fem_interpolation_context &c,
63 base_tensor &t,
bool)
const {
64 bgeot::multi_index mi(2);
65 mi[1] = target_dim(); mi[0] =
short_type(nb_dof(0));
67 base_tensor::iterator it = t.begin(), itf;
69 fem_interpolation_context c0 = c;
70 std::vector<base_tensor> val_e(2);
73 c0.set_pfp(
fem_precomp(pfems[k], c0.pfp()->get_ppoint_tab(),
75 }
else { c0.set_pf(pfems[k]); }
76 c0.base_value(val_e[k]);
79 assert(target_dim() == 1);
80 for (dal::bv_visitor i(enriched_dof1); !i.finished(); ++i) {
81 itf = val_e[1].begin();
82 scalar_type e = val_e[0][i];
83 for (
size_type j = 0; j < pfems[1]->nb_dof(cv); ++j)
86 assert(it == t.end());
89 void fem_product::real_grad_base_value(
const fem_interpolation_context &c,
90 base_tensor &t,
bool)
const {
91 bgeot::multi_index mi(3);
92 mi[2] =
short_type(c.N()); mi[1] = target_dim();
95 base_tensor::iterator it = t.begin();
97 fem_interpolation_context c0 = c;
98 std::vector<base_tensor> grad_e(2), val_e(2);
101 c0.set_pfp(
fem_precomp(pfems[k], c0.pfp()->get_ppoint_tab(),
103 }
else { c0.set_pf(pfems[k]); }
104 c0.grad_base_value(grad_e[k]);
105 c0.base_value(val_e[k]);
108 assert(target_dim() == 1);
109 for (dim_type k = 0; k < c.N() ; ++k) {
110 for (dal::bv_visitor i(enriched_dof1); !i.finished(); ++i) {
111 size_type posg0 = k * pfems[0]->nb_dof(cv);
112 size_type posg1 = k * pfems[1]->nb_dof(cv);
113 for (
size_type j = 0; j < pfems[1]->nb_dof(cv); ++j)
114 *it++ = grad_e[0][i + posg0] * val_e[1][j]
115 + grad_e[1][j + posg1] * val_e[0][i];
118 assert(it == t.end());
121 void fem_product::real_hess_base_value(
const fem_interpolation_context &c,
122 base_tensor &t,
bool)
const {
123 t.adjust_sizes(nb_dof(0), target_dim(), gmm::sqr(c.N()));
124 base_tensor::iterator it = t.begin();
126 fem_interpolation_context c0 = c;
127 std::vector<base_tensor> hess_e(2), grad_e(2), val_e(2);
130 c0.set_pfp(
fem_precomp(pfems[k], c0.pfp()->get_ppoint_tab(),
132 }
else { c0.set_pf(pfems[k]); }
133 c0.hess_base_value(hess_e[k]);
134 c0.grad_base_value(grad_e[k]);
135 c0.base_value(val_e[k]);
138 assert(target_dim() == 1);
139 for (dim_type k0 = 0; k0 < c.N(); ++k0) {
140 for (dim_type k1 = 0; k1 < c.N() ; ++k1) {
141 for (dal::bv_visitor i(enriched_dof1); !i.finished(); ++i) {
142 size_type posh0 = (k0*c.N()+k1) * pfems[0]->nb_dof(cv);
143 size_type posh1 = (k0*c.N()+k1) * pfems[1]->nb_dof(cv);
144 size_type posg00 = k0 * pfems[0]->nb_dof(cv);
145 size_type posg01 = k1 * pfems[0]->nb_dof(cv);
146 size_type posg10 = k0 * pfems[1]->nb_dof(cv);
147 size_type posg11 = k1 * pfems[1]->nb_dof(cv);
148 for (
size_type j = 0; j < pfems[1]->nb_dof(cv); ++j) {
149 *it++ = hess_e[0][i + posh0] * val_e[1][j] +
150 hess_e[1][j + posh1] * val_e[0][i] +
151 grad_e[0][i + posg00] * grad_e[1][j + posg11] +
152 grad_e[0][i + posg01] * grad_e[1][j + posg10];
157 assert(it == t.end());
160 void mesh_fem_product::clear_build_methods() {
161 for (
size_type i = 0; i < build_methods.size(); ++i)
163 build_methods.clear();
165 void mesh_fem_product::clear(
void) {
167 clear_build_methods();
171 DAL_SIMPLE_KEY(special_mflproduct_key,
pfem);
173 void mesh_fem_product::adapt(
void) {
177 GMM_ASSERT1(!mf1.is_reduced() && !mf2.is_reduced(),
178 "Sorry, mesh_fem_product not defined for reduced mesh_fems");
180 for (dal::bv_visitor cv(linked_mesh().convex_index()); !cv.finished();
182 dal::bit_vector local_enriched_dof;
183 for (
size_type i = 0; i < mf1.nb_basic_dof_of_element(cv); ++i)
184 if (enriched_dof.is_in(mf1.ind_basic_dof_of_element(cv)[i]))
185 local_enriched_dof.add(i);
186 if (local_enriched_dof.card() > 0) {
187 pfem pf = std::make_shared<fem_product>
188 (mf1.fem_of_element(cv), mf2.fem_of_element(cv), cv,
189 xfem_index, local_enriched_dof);
190 dal::pstatic_stored_object_key
191 pk = std::make_shared<special_mflproduct_key>(pf);
193 build_methods.push_back(pf);
194 set_finite_element(cv, pf);
197 is_adapted =
true; touch();