1596x
001773
2022-10-18

Инструмент веб-сервис для подпорной воды в C#

API для RFEM 6, RSTAB 9 и RSECTION основан на концепции веб-сервисов. Чтобы получить хорошее представление о предмете, в следующей статье будет объяснён еще один пример в C#.

В примере показан расчет водной нагрузки, приложенной к балке, которая увеличивается из-за прогиба балки '. Для большей гибкости пользователь должен иметь возможность выбирать балки. Кроме того, не следует изменять дополнительные нагрузки, действующие на кровлю, которые применяются к одному и тому же загружению независимо от водной нагрузки. Известны/применяются следующие граничные условия:

  • Уровень воды над недеформированной системой
  • Ширина зоны подачи стержня для нагрузки по площади
  • Номер загружения, к которому должна быть приложена нагрузка
  • Нагрузка на площадь воды на 1 м вод. Ст. (10000 Н/м³)
  • Идентификатор, используемый для идентификации нагрузок на площадь

Поэтому в программе создаются следующие переменные:


            

двойной h_water = 0,1;//высота воды над недеформированной системой в [м]
двойной w_ref = 2;//контрольная ширина для нагрузки на поверхность в [м]
int load_case_no = 1;//номер загружения, к которому приложена нагрузка
string water_accu_comment = «скопление воды»;//идентификационная строка
двойной std_magnitude = 10000;//нагрузка на поверхность на высоту воды в [Н/м ^ 3]


Что касается реализации, то программа должна включать в себя следующие элементы:

  1. Фильтрация выбранных элементов
  2. Удаление водных нагрузок из предыдущих запусков
  3. Создание новых нагрузок
  4. Начать расчет
  5. Определение прогиба
  6. Вернемся к шагу 3 и создадим новые нагрузки от деформаций
  7. Повторение итераций до достижения предельного значения

Помимо этих функций, требуются соединение с программой и моделью, различные блоки 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, а также для считывания результатов. С его помощью можно реализовать множество различных проектов. Программа, показанная в этой статье, включает в себя только первый шаг из множества различных элементов:

  1. Получить выбранные элементы
  2. Создать нагрузки
  3. Получение и фильтрация результатов
  4. Фильтровать элементы по комментариям
  5. Удалить элементы

Благодаря такому разнообразию. программа также может служить образцом для других проектов.


Автор

Г-н Гюнтель осуществляет техническую поддержку пользователей Dlubal Software.

Скачивания