OpenModelica能源模型导入CSV气象数据及Matlab脚本转译咨询
将Matlab气象数据读取脚本转换为OpenModelica代码的解决方案
当然可以把你的Matlab脚本转换成OpenModelica代码来读取这份气象CSV数据!我经常帮人做这类工具转换,下面就给你一步步拆解实现,完全适配你需要提取多列数据给不同模型类调用的需求。
核心实现思路
OpenModelica里处理CSV数据有两种常用方式:一种是手动解析每一列(和你Matlab脚本的逻辑完全对应),另一种是用专门的时序数据块CombiTimeTable——后者更适合你的气象时序数据,因为能直接把数据映射成模型可用的输入信号。我会把两种方式都给你,你可以根据自己的模型需求选。
方式一:手动解析列数据(和Matlab逻辑完全匹配)
这个写法完全对应你Matlab里提取各列的操作,适合需要单独处理每一列数据的场景:
model WeatherDataManualReader import Modelica.Utilities.Files; import Modelica.Utilities.Strings; // 定义变量存储各列数据,数组大小会自动匹配CSV行数 Real Jahr_Temp[:]; // 年份列(对应Matlab的Temperatur(:,2)) Real Monat_Temp[:]; // 月份列(Temperatur(:,3)) Real Tag_Temp[:]; // 日期列(Temperatur(:,4)) Real Stunde_Temp[:]; // 小时列(Temperatur(:,5)) Real T[:]; // 温度列(Temperatur(:,7)) Real RF[:]; // 空气湿度列(Temperatur(:,8)) protected // 读取整个CSV文件内容 String fileContent = Files.readFile("Wetterdaten/TemperaturSPO3.csv"); // 按换行分割成每行 String[:] lines = Strings.split(fileContent, "\n"); // 计算有效数据行数(假设第一行是表头,减去表头行) Integer numRows = size(lines, 1) - 1; algorithm // 初始化各数组的大小 Jahr_Temp := fill(0, numRows); Monat_Temp := fill(0, numRows); Tag_Temp := fill(0, numRows); Stunde_Temp := fill(0, numRows); T := fill(0, numRows); RF := fill(0, numRows); // 逐行解析CSV(从第二行开始跳过表头) for i in 2:numRows loop // 按逗号分割每行成列 String[:] columns = Strings.split(lines[i], ","); // 注意:OpenModelica数组索引从1开始,和Matlab一致,直接对应你要的列 Jahr_Temp[i-1] := String.toReal(columns[2]); Monat_Temp[i-1] := String.toReal(columns[3]); Tag_Temp[i-1] := String.toReal(columns[4]); Stunde_Temp[i-1] := String.toReal(columns[5]); T[i-1] := String.toReal(columns[7]); RF[i-1] := String.toReal(columns[8]); end for; end WeatherDataManualReader;
方式二:用时序数据块(更适合模型调用)
如果你的模型是时序驱动的,用CombiTimeTable会更高效——它能直接把CSV里的时间和参数绑定成模型可直接调用的信号,不用手动处理数组:
model WeatherDataTimeTable import Modelica.Blocks.Sources.CombiTimeTable; import Modelica.Units.SI; // 创建时序数据块,读取CSV文件 CombiTimeTable weatherTable( fileName = "Wetterdaten/TemperaturSPO3.csv", tableOnFile = true, firstRow = 2, // 跳过CSV的表头行 // 指定要读取的列索引(对应你Matlab里的列:年、月、日、时、温度、湿度) columns = {2,3,4,5,7,8}, // 如果你想把时间戳转换成模型可用的秒数,可以自定义时间计算逻辑 // 比如把1999-12-01 00:00作为起始时刻,计算每个时间点的秒数 // 也可以预先在CSV里添加一列计算好的时间秒数,直接设columns[1]为时间列更方便 ); // 定义输出变量,供其他模型类直接调用 SI.Temperature temperature = weatherTable.y[5]; // 温度列 Real airMoisture = weatherTable.y[6]; // 空气湿度列 Integer year = integer(weatherTable.y[1]); Integer month = integer(weatherTable.y[2]); Integer day = integer(weatherTable.y[3]); Integer hour = integer(weatherTable.y[4]); end WeatherDataTimeTable;
实用提示
- 路径注意:OpenModelica的工作目录是你的模型文件所在文件夹,所以如果
Wetterdaten是模型文件夹下的子文件夹,用"Wetterdaten/TemperaturSPO3.csv"就没问题,记得用正斜杠(/)而不是反斜杠(\)。 - 表头处理:如果你的CSV第一行是表头,一定要设置
firstRow = 2,不然会把表头字符串当成数值解析,报错。 - 模型调用:其他模型类需要用到这些数据时,直接把上面的模型作为子模型集成进去,或者引用对应的输出变量就行。
- 时间优化:如果你的模型需要精确的时间驱动,建议预先在CSV里计算好从起始时刻(比如1999-12-01 00:00)开始的秒数列,这样
CombiTimeTable可以直接用这一列作为时间输入,运行效率更高。
内容的提问来源于stack exchange,提问作者Anni
相关产品推荐
相关产品推荐

