Я работаю с параллельным кодом конечного элемента, который был написан
другой человек, и есть некоторые фрагменты кода, которые я не могу понять.
В частности есть создание карты для степеней свободы
принадлежность к каждому узлу вычислительной сетки. Сетка сделана из
четырехугольные элементы, и каждый узел имеет nb_dofs степени свободы.
Элементы сетки подразделяются на патчи и каждый патч
принадлежат другому процессору. Смежные патчи элементов разделяют
одинаковые узлы и одинаковая степень свободы.
Карта создается в следующих шагах.
(1) Функтор « edl » создается через вызов конструктора:
element_dof_list<mesh_type> edl(mesh);
где сетка — это расчетная сетка.
Тело конструктора:
element_dof_list(const mesh_type& m):mesh_m(m){},
где m, как я уже говорил, — это сетка, используемая для вычислений.
(2) Правило, согласно которому должна быть создана карта
определяется через вызов:
element_mapping<mesh_type, element_dof_list<mesh_type> > e_dof_map(mesh, edl);
где mesh — это вычислительная сетка, а edl — функтор, созданный в (1).
Тело конструктора правил:
element_mapping(const mesh_type& m, const rule_type& r):mesh_m(m),rule_m(r) {}
где, согласно вызову, написанному выше, член mesh_m является
вычислительная сетка, а член rule_m является функтором edl.
(3) Наконец (но это самая сложная часть), есть призыв к
построитель карты:
dof_map_m = make_map<shared_epetra_map>(e_dof_map);
где shared_epetra_map — это общая карта Epetra пакета Trilinos, поскольку
степень свободы принадлежащих соседним участкам элементов, принадлежащих
на разные процессоры делятся. e_dof_map определено в (2).
Тело вызова в (3):
template<typename map_type, typename data_type>
inline map_type* make_map(const data_type& g) {
return build_map<map_type, data_type>::do_map( g );
}
где data_type — это element_mapping, а входной аргумент g — e_dof_map.
Эта функция вызывает функцию
build_map<map_type, data_type>::do_map( g )
в соответствии с data_type, переданного во вход.
В моем случае входной аргумент element_mapping вызывает вызов
template<typename map_type, typename data_type>
struct build_map {
static map_type* do_map(const data_type& g){
return build_map<map_type, typename data_type::result_type>::do_map(g());
}
};
где operator g()
называется.
Оператор g () — это просто вложенная итерация по всем элементам и всем узлам, принадлежащим конкретному элементу, которые извлекают std :: vector степени свободы для всей сетки (называемой gid_m). Этот вектор, как я уже сказал, имеет общие степени свободы для смежных элементов, которые принадлежат разным процессорам.
Таким образом, do_map (g ()) заполняется std :: vector gid_m.
(4) Теперь приходит то, что я не могу понять.
После звонка
struct build_map {
static map_type* do_map(const data_type& g){
return build_map<map_type, typename data_type::result_type>::do_map(g());
}
};
и возвращение g () в виде std :: vector общих степеней свободы называется функцией:
template<typename map_type>
struct build_map<map_type, std::valarray<int> > {
static map_type* do_map(const std::valarray<int>& gid) {
return new map_type(-1,gid.size(),&(gid[0]));
}
};
это, наконец, создает карту.
Что я не понимаю, так это:
(а) как разработка кода делает do_map(g())
позвонить
do_map(const std::valarray<int>& gid)
(б) как инструкция map_type(-1,gid.size(),&(gid[0]))
может создать
карта. Я искал в своем коде, но я не нашел ни одного
инструкция, которая может создать карту из вышеуказанной информации
(-1,gid.size(),&(gid[0]))
это стандарт или функция
трилино?
Я надеюсь, что я достаточно ясно, но все это вызывает последующие структуры
сводит меня с ума Есть ли кто-нибудь, кто хочет мне помочь?
Я не могу спросить человека, который написал код, так как он забыл всю эту цепочку вызовов (прошло некоторое время с тех пор, как он написал код, и теперь он работает в другом месте над другими вещами).
Вы правы в отношении конструктора совместно используемой карты epetra, я проверил пакет epetra из трилино, и есть конструктор, принимающий в качестве аргументов
(-1,gid.size(),&(gid[0])).
Но то, что я не могу понять, это то, как от звонка
struct build_map {
static map_type* do_map(const data_type& g){
return build_map<map_type, typename data_type::result_type>::do_map(g());
}
};
где оператор g () возвращает std :: vector, он автоматически вызывается функцией:
template<typename map_type>
struct build_map<map_type, std::valarray<int> > {
static map_type* do_map(const std::valarray<int>& gid) {
return new map_type(-1,gid.size(),&(gid[0]));
}
};
Задача ещё не решена.