第 3 章:ACT 模块用户指南

本文详细描述了MODFLOW-SURFACT/MODHMS的代码结构,包括其模块化设计、运行流程和传输模拟的三种类型。重点介绍了如何准备输入文件,包括流输入文件的修改和新传输文件的创建。文章还涵盖了空间和时间离散化的设置以及输入指令的详细说明。
摘要由CSDN通过智能技术生成

3.1 概述

本章介绍了 MODFLOW-SURFACT/MODHMS 代码结构和操作,并提供了准备 ACT 模块和相关包的输入文件的说明。 对于每台计算机运行,MODFLOW-SURFACT/MODHMS 提供流量和相关传输问题的双重分析。 如前所述,MODFLOW-SURFACT/MODHMS 的输入准备非常简单,并遵循 MODFLOW 格式结构。 运输模拟利用所有 MODFLOW 数据集,并且消除了该数据的重复。
本章介绍了输入准备指南,假设用户具有用于地下水流分析的现有数据文件,并准备好继续编辑这些文件以及为污染物迁移分析创建其他输入文件。 如果这个假设不正确,用户将需要参考 MODFLOW 用户手册和 MODFLOW-SURFACT/MODHMS 文件第一卷来创建流量输入文件。

3.2 代码结构及运行

MODFLOW-SURFACT/MODHMS 保留了原始 MODFLOW 代码的模块化结构。 类似的代码结构设计旨在促进流和传输模块的使用一致,并最大限度地减少用户的学习曲线。
MODFLOW-SURFACT/MODHMS 提供对流量和相关传输问题的完整分析。 图 3.1 显示了描述代码功能操作的一般流程图。 计算机内存首先被分配给流和传输模块的阵列。 接下来是读取和处理流和传输数据的例程。 然后读取每个应力周期的流量和传输的边界数据,并进入时间步进循环。 然后求解地下水流方程,然后求解每个时间步长的溶质输运方程。 如果流量处于稳态,则仅在第一个时间步长求解流量方程。 如图 3.1 所示,每个流时间步长输入一次传输模块。 图 3.2 所示为瞬态传输分析的一般程序。 传输例程组装并求解模拟中考虑的每个物种的传输方程。 对于非线性情况,执行迭代直到每个物种获得收敛。
使用 MODFLOW-SURFACT/MODHMS 可以进行三种类型的传输模拟,如下所述。

1.    瞬态流场中的瞬态输运模拟。
2.    稳态流场中的瞬态输运模拟。
3.    稳态流场中的稳态输运模拟。
第一种情况是瞬态流场中瞬态传输的最常见情况,其中针对每个应力周期的每个流动时间步长求解传输方程。 第二种情况是通过在MODFLOW中设置稳态标志(即ISS ≠ 0)来进行稳态流动模拟的情况。 随后,在该稳态速度场中,针对每个应力周期,针对所有时间步执行相关的输运模拟。 如果流场在应力周期之间发生变化,则通过设置 MODFLOW 的稳态标志(即 ISS≠0)并使用非常大的 (1010) 时间步长来进行场(场景 3)。

图 3.1 流程图描述了集成 MODFLOW-SURFACT/MODHMS 代码的功能操作。

图 3.2 描述瞬态传输分析计算程序的流程图。

如果在处理场景 2 和 3 时,稳态流不收敛,则需要在很长一段时间内使用瞬态模拟方法来解决问题,直到存储项减少到可忽略不计的值并达到稳态条件 。 然后,最终的一组水头值可以用作代码的起始条件,以在使用完全瞬态方法的后续组合流动/传输模拟运行中完成分析。 由于流场接近或处于稳态,因此流动解应该快速收敛。
MODFLOW-SURFACT/MODHMS 中的传输解决方案选项可以通过基本传输 (BTN1) 包中设置的两个标志来指定(第 3.4.2 节中描述)。 标志 IACLVL 控制空间精度,标志 THETRD 控制时间离散化精度。 标志 IACLVL 提供以下空间近似选项:

如果在处理场景 2 和 3 时,稳态流不收敛,则需要在很长一段时间内使用瞬态模拟方法来解决问题,直到存储项减少到可忽略不计的值并达到稳态条件 。 然后,最终的一组水头值可以用作代码的起始条件,以在使用完全瞬态方法的后续组合流动/传输模拟运行中完成分析。 由于流场接近或处于稳态,因此流动解应该快速收敛。
MODFLOW-SURFACT/MODHMS 中的传输解决方案选项可以通过基本传输 (BTN1) 包中设置的两个标志来指定(第 3.4.2 节中描述)。 标志 IACLVL 控制空间精度,标志 THETRD 控制时间离散化精度。 标志 IACLVL 提供以下空间近似选项:

1.    全上游加权(IACLVL=0);
2.    由代码自动确定上游因子的混合(上游-中心差组合)加权(IACLVL=1);

3.    用户定义的空间权重(IACLVL=–1); 或者
4.    采用 van Leer 通量限制器的 TVD 方案 (IACLVL–2)。
前三个方案是线性方案,而最后一个方案是非线性的,用于非显式时间步进。 建议新手运输建模者为早期校准模拟设置 IACLVL = 0 或 1,对于需要更高精度的最终模拟,可以将其切换为 IACLVL = –2。

THETRD 标志提供以下时间离散化选项:

1.    自动选择隐式(THETRD=0);
2.    完全隐式时间加权(THETRD=1);
3.    曲柄尼科尔森时间加权(THETRD=0.5); 和
4.    明确的时间加权 (THETRD=0.0001)。
建议新手运输建模者始终使用 THETRD=0。 对于非 TVD 方案,这将提供具有二阶时间精度的 Crank-Nicolson 时间加权。 对于 TVD 方案,选择的隐式尽可能接近 Crank-Nicolson,而不违反 TVD 属性。 有经验的建模者可以选择 THETRD 的任何值,从完全隐式到完全显式。 当使用显式方案时,稳定性条件由 MODFLOW-SURFACT/MODHMS 自动检查。 通过设置 IACLVL=–2 并将最大传输迭代次数 (MXITERC) 设置为 2,可以针对线性传输问题实施通量校正传输 (FCT) 方案。用户应确保模拟中的库朗数不会比 1 大很多 当使用 FCT 方案时,为了保持解的精度。 请注意,库朗数定义为 VΔt/Δx,其中 V 是污染物或溶质速度,Δt 是时间步长,Δx 是网格节点间距。
对于非线性传输模拟(由于非线性延迟或使用非线性 TVD 方案),传输迭代的最大数量 (MXITERC) 应大于 1。 如果在指定的迭代次数(建议次数在 5 到 25 之间)内未实现收敛,则时间步长减半,并针对该物种重复传输解决方案。 重复此过程,直到实现收敛或达到最大时间步减少数 (NNOTCV),从而中止模拟。 在进入下一个目标时间步之前,获得所有子时间步的收敛解。 可以通过设置 MXITERC=1 来实现对此项的时间滞后,但不建议这样做。 FCT类型的更新可以通过将MXITERC设置为2来执行。

对于包含残差、溶解 NAPL 相(即,如果 IEQPART=2)的输运模拟,索引 MXOUTIT 确定非线性输运迭代的最大数量(建议值在 5 到 25 之间),索引 NITFLASH 确定牛顿迭代的最大数量 在闪存计算期间执行(建议值在 10 到 30 之间)。 如果 MXOUTIT 设置为 1,则重新分配 NAPL 阶段的饱和更新会出现时间滞后,但不建议这样做。 如果 MXOUTIT=2,则在进入下一个时间步之前执行校正迭代,如 FCT 方案中那样。 对于 MXOUTIT $3,传输解决方案将继续进行直至收敛。 如果在规定的 MXOUTIT 迭代内未实现收敛,则时间步长减半,并且针对较小的时间值,与闪存计算一起重复所有物种的传输解决方案。 在进入下一个目标时间步骤之前,获得所有子时间步骤的收敛解。
请注意,自动时间步进不受非线性传输模拟收敛行为的影响。 当用于稳态流动条件时,自动时间步长的
行为类似于 MODFLOW 的常规时间步长增量方案,具有不能超过的时间步长最大限制。 最大时间步长是所有涉及传输的模拟的重要考虑因素,因为大库朗数可能会因时间离散误差而产生显着的数值色散。 用户对空间和时间离散化的良好判断是不容易替代的。

3.3 输入准备的基本程序

如前所述,MODFLOW-SURFACT/MODHMS 旨在在单台计算机运行中对地下水流和污染物迁移进行双重分析。 因此,在此阶段假设用户已经创建或获得了用于地下水流模拟的输入文件。 有了这个假设,涉及运输模拟选项所需的输入准备的基本程序就很简单了。
本质上,用户需要修改相关的流输入文件并创建最多三个新的输入文件,其中包含传输建模所需的附加信息。 表 3.1 显示了相关流程包和三个传输包的识别和输入功能,下一节将介绍输入准备的详细说明。

3.4 输入指令

3.4.1 概述


本节提供了准备代码所需的附加输入数据的一般和具体说明,以便在同一计算机运行中同时进行输运模拟和地下水流模拟。
用户通过 BAS 包的控制变量(ITRAN)指定传输模拟的要求,如第 3.4.2 节所述。 BAS 包已被修改,以合并 ITRAN 和传输分析所需的附加输入文件单元。 BTN1、HCN1 和 PCN1 包使用这些输入文件单元读取与传输参数和第一类边界条件相关的数据,如第 3.4.3 节到第 3.4.5 节中所述。 第 3.4.6 节到第 3.4.11 节提供了 WEL、DRN、RIV、GHB、RSF4 和 FWL4 包的输入指令,所有这些包都经过修改以纳入用于传输模拟的附加接收器/源数据。 请注意,接收器/源包仅在需要时才被调用(即,当相关接收器/源存在于流域中时)。
为了求解输运矩阵方程,MODFLOW-SURFACT/MODHMS 采用了具有矩阵预处理和正交加速的迭代方法,称为 Orthomin 技术,包含在 PCG4 包中。 第 3.4.12 节提供了 PCG4 求解器的输入指令。 最后,第 3.4.13 节和第 3.4.14 节详细介绍了 OC 和 ATO4 包的输入指令。 整个流动和传输模拟打印输出由从这两个中选择的包控制。 请注意,特别提倡使用 ATO4 包的自适应时间步进来进行无侧限流模拟。

  • 18
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,以下是使用DQN算法打印历代奖励值的代码示例: ```python import gym import numpy as np import tensorflow as tf from collections import deque class DQNAgent: def __init__(self, state_size, action_size): self.state_size = state_size self.action_size = action_size self.memory = deque(maxlen=2000) self.gamma = 0.95 self.epsilon = 1.0 self.epsilon_min = 0.01 self.epsilon_decay = 0.995 self.learning_rate = 0.001 self.model = self._build_model() def _build_model(self): model = tf.keras.models.Sequential() model.add(tf.keras.layers.Dense(24, input_dim=self.state_size, activation='relu')) model.add(tf.keras.layers.Dense(24, activation='relu')) model.add(tf.keras.layers.Dense(self.action_size, activation='linear')) model.compile(loss='mse', optimizer=tf.keras.optimizers.Adam(lr=self.learning_rate)) return model def remember(self, state, action, reward, next_state, done): self.memory.append((state, action, reward, next_state, done)) def act(self, state): if np.random.rand() <= self.epsilon: return np.random.choice(self.action_size) act_values = self.model.predict(state) return np.argmax(act_values[0]) def replay(self, batch_size): minibatch = np.array(random.sample(self.memory, batch_size)) states = np.concatenate(minibatch[:,0], axis=0) actions = np.concatenate(minibatch[:,1], axis=0) rewards = minibatch[:,2] next_states = np.concatenate(minibatch[:,3], axis=0) dones = minibatch[:,4] targets = self.model.predict(states) next_state_targets = self.model.predict(next_states) for i in range(batch_size): if dones[i]: targets[i][actions[i]] = rewards[i] else: targets[i][actions[i]] = rewards[i] + self.gamma * np.amax(next_state_targets[i]) self.model.fit(states, targets, epochs=1, verbose=0) if self.epsilon > self.epsilon_min: self.epsilon *= self.epsilon_decay def load(self, name): self.model.load_weights(name) def save(self, name): self.model.save_weights(name) if __name__ == "__main__": env = gym.make('CartPole-v1') state_size = env.observation_space.shape[0] action_size = env.action_space.n agent = DQNAgent(state_size, action_size) done = False batch_size = 32 num_episodes = 1000 rewards = [] for e in range(num_episodes): state = env.reset() state = np.reshape(state, [1, state_size]) total_reward = 0 for time in range(500): action = agent.act(state) next_state, reward, done, _ = env.step(action) reward = reward if not done else -10 next_state = np.reshape(next_state, [1, state_size]) agent.remember(state, action, reward, next_state, done) state = next_state total_reward += reward if done: print("episode: {}/{}, score: {}".format(e+1, num_episodes, time)) rewards.append(total_reward) break if len(agent.memory) > batch_size: agent.replay(batch_size) if (e+1) % 10 == 0: agent.save("cartpole-dqn.h5") env.close() print("Average reward for last 100 episodes: ", np.mean(rewards[-100:])) ``` 在上面的代码中,我们定义了一个`DQNAgent`类来实现DQN算法。`remember`方法用于存储经验回放,`act`方法用于选择动作,`replay`方法用于训练模型。在主程序中,我们使用`for`循环来运行多个episode,并在每个episode结束时打印分数。最后,我们通过计算最后100个episode的平均奖励来评估算法的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

___Y1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值