В примере показан расчет водной нагрузки, приложенной к балке, которая увеличивается из-за прогиба балки '. Для большей гибкости пользователь должен иметь возможность выбирать балки. Кроме того, не следует изменять дополнительные нагрузки, действующие на кровлю, которые применяются к одному и тому же загружению независимо от водной нагрузки. Известны/применяются следующие граничные условия:
- Уровень воды над недеформированной системой
- Ширина зоны подачи стержня для нагрузки по площади
- Номер загружения, к которому должна быть приложена нагрузка
- Нагрузка на площадь воды на 1 м вод. Ст. (10000 Н/м³)
- Идентификатор, используемый для идентификации нагрузок на площадь
Поэтому в программе создаются следующие переменные:
двойной h_water = 0,1;//высота воды над недеформированной системой в [м]
двойной w_ref = 2;//контрольная ширина для нагрузки на поверхность в [м]
int load_case_no = 1;//номер загружения, к которому приложена нагрузка
string water_accu_comment = «скопление воды»;//идентификационная строка
двойной std_magnitude = 10000;//нагрузка на поверхность на высоту воды в [Н/м ^ 3]
Что касается реализации, то программа должна включать в себя следующие элементы:
- Фильтрация выбранных элементов
- Удаление водных нагрузок из предыдущих запусков
- Создание новых нагрузок
- Начать расчет
- Определение прогиба
- Вернемся к шагу 3 и создадим новые нагрузки от деформаций
- Повторение итераций до достижения предельного значения
Помимо этих функций, требуются соединение с программой и моделью, различные блоки try-catch и другие стандартные элементы, которые здесь не описываются более подробно. Затем эти элементы содержатся в исходном коде, который можно скачать под статьей.
1. Фильтрация выбранных элементов
Сначала мы получаем информацию обо всех выбранных объектах с помощью функции get_all_selected_objects. Полученный массив содержит элементы типа object_location, которые содержат, например, тип, номер и номер вышестоящего «родительского» объекта. В следующем цикле номера всех объектов типа E_OBJECT_TYPE_MEMBER (т.е. все номера элементов) извлекаются и сохраняются в массиве mem_noes_sel.
//получаем выбранные объекты
object_location [] obj_locs = model.get_all_selected_objects ();
//извлекаем элементы
int [] mem_noes_sel = новый int [0];
foreach (object_location obj_loc в obj_locs)
{
if (obj_loc.type == object_types.E_OBJECT_TYPE_MEMBER)
{
Array.Resize (ref mem_noes_sel, mem_noes_sel.Length + 1);
mem_noes_sel [mem_noes_sel.Length-1] = obj_loc.no;
}
}
2. Удаление водных нагрузок из предыдущих запусков
С помощью номеров стержней теперь можно отфильтровать связанные нагрузки на стержни из всех нагрузок на стержни. Используется петля, надетая на номера нагрузок на стержни. В этом цикле мы получаем данные о нагрузке на стержень, проверяем его номера стержней на соответствие выбранным номерам стержней, и, если есть совпадение, соответствующая нагрузка на стержень удаляется:
//удаляем все нагрузки water_accu
//получить все номера членов
int [] mem_load_noes = модель.get_all_object_numbers (object_types.E_OBJECT_TYPE_MEMBER_LOAD, load_case_no);
//цикл по всем нагрузкам на стержни в загружении
foreach (int mem_load_no в mem_load_noes)
{
//получаем нагрузку на стержень
member_load mem_load = модель.get_member_load (mem_load_no, load_case_no);
если (mem_load.comment == water_accu_comment)
{
//цикл нагрузки на стержень по стержням
для (int i = 0; i
{
//цикл нагрузки на стержень по стержням
для (int j = 0; j
{
if (mem_load.members [i] == mem_noes_sel [j])
{
//удаляем нагрузку на стержень
model.delete_object (object_types.E_OBJECT_TYPE_MEMBER_LOAD, mem_load_no, load_case_no);
}
}
}
}
}
Чтобы никакие другие нагрузки на стержень не перезаписывались, на следующем этапе считывается последний использованный номер нагрузки на стержень:
//получаем номер последней загрузки
int no_offset = модель.get_nth_object_number (object_types.E_OBJECT_TYPE_MEMBER_LOAD, 0, load_case_no) + 1;
Теперь следующим шагом является создание новых нагрузок на стержни, которые уже являются частью итерационного цикла do-while. Этот цикл построен следующим образом:
do
{
//сбросить дельта-деформацию
delta_def = 0;
//применяем нагрузку
model.begin_modification («Нагрузки»);
//создаем нагрузки на стержень для каждого стержня
...
model.finish_modification ();
...
//рассчитать загружение
...
//получаем деформации на концах стержня
...
//проверяем критерий
} while (delta_def> 0,0001);
Для остановки итерационного цикла было выбрано изменение деформации, определяемое при фильтрации результатов. Если все деформации отклоняются от деформации в предыдущем прогоне менее чем на 0,0001 м (т.е. 0,1 мм), петля останавливается.
3. Создание новых нагрузок
В качестве типа нагрузки выбрана трапециевидная нагрузка, действующая в общем направлении z, которая может иметь разные значения в начале и в конце стержня. Учтите, что для передаваемых параметров соответствующей переменной «Specified» должно быть задано значение «true». Это необходимо для того, чтобы не передать все параметры класса и сохранить таким образом небольшой объем передаваемых данных. Значение нагрузки ' s рассчитывается из начальной высоты «h_water» (была задана) и дополнительной узловой деформации в этом месте. Высота, заданная в [м], умножается на «std_magnitude» в [Н/м3 ] и ширину зоны подачи, заданную в [м], в результате получается нагрузка на линию, заданную в [Н/м]:
//создаем нагрузки на стержень для каждого стержня
for (int i = 0; i
Функция set_member_load используется для передачи нагрузки. Для назначения нагрузок в качестве комментария используется строка water_accu_comment. В следующих итерациях нагрузки больше не удаляются; вместо этого, путем указания номера загрузки, они перезаписываются при повторной передаче. Поэтому комментарий требуется только для фильтрации и удаления нагрузок при перезапуске приложения. Кроме того, для задания нагрузки была выбрана относительная ссылка, которая, однако, находится в диапазоне 0-100%.
Следующим шагом является начало расчета. Сначала создается поле с объектами типа calculate_specific_loading. Это поле содержит все загружения/сочетания для расчета. В данном случае создается только один элемент типа загружения с заданным номером загружения load_case_no:
//рассчитать загружение
Calculate_specific_loading [] csl = новая calculate_specific_loading [1];
csl [0] = новая программа calculate_specific_loading ();
csl [0] .no = load_case_no;
csl [0] .type = case_object_types.E_OBJECT_TYPE_LOAD_CASE;
model.calculate_specific (csl, true);
Теперь, когда доступны результаты, необходимо отфильтровать общие деформации в начале и в конце каждого стержня. Функция get_results_for_members_global_deformations используется для получения всех глобальных деформаций стержней для заданного случая нагружения и выбранных стержней. Структура результатов такая же, как в соответствующей таблице в RFEM 6. Один из вариантов - считывание длины стержня и сравнение результата по оси x. Другой вариант использует данное описание и тот факт, что крайности следуют за всеми x-точками. Был выбран второй вариант, и когда «Крайности» появляется в описании впервые, для поиска последнего x-элемента используется предыдущий индекс. Поскольку первое местоположение стержня также влияет на первую запись, дальнейшая фильтрация здесь не требуется:
//получаем деформации на концах стержня
for (int i = 0; i delta_def)
delta_def = Math.Abs (mem_end_defs [i, 0] - mem_defs_glbl [0] .row.displacement_z);
mem_end_defs [i, 0] = mem_defs_glbl [0] .row.displacement_z;
//получаем деформацию в конечной точке
для (int j = 0; j delta_def)
delta_def = Math.Abs (mem_end_defs [i, 1] - mem_defs_glbl [j - 1] .row.displacement_z);
mem_end_defs [i, 1] = mem_defs_glbl [j - 1] .row.displacement_z;
перерыв;
}
}
}
Помимо определения деформаций, также рассчитывается переменная «delta_def», которая используется в качестве критерия остановки. Сначала рассчитывается разница между значением деформации предыдущей итерации (ноль в начале) и текущим значением. Абсолютное значение берется из разницы, а затем находится максимум. Как уже было показано в описании итерационного цикла, мы останавливаемся на значении меньше 0,0001 м (т.е. 0,1 мм).
В видео, прилагаемом к этой статье, вы можете увидеть, с одной стороны, фильтр нагрузки, а с другой - этап итерации. В конце отображается найденная нагрузка.
Интерфейс веб-сервиса предлагает множество возможностей для изменения элементов в RFEM 6/RSTAB 9, а также для считывания результатов. С его помощью можно реализовать множество различных проектов. Программа, показанная в этой статье, включает в себя только первый шаг из множества различных элементов:
- Получить выбранные элементы
- Создать нагрузки
- Получение и фильтрация результатов
- Фильтровать элементы по комментариям
- Удалить элементы
Благодаря такому разнообразию. программа также может служить образцом для других проектов.