在 Fortran 中将指针分配给可分配的派生类型组件
我是 Fortran 新手,正在开发一个代码,我经常在其中对两个相似的派生类型(在本例中表示科学计算代码中的粒子模型)进行操作。这两种类型是相同的,只是一种仅具有平移位置和速度分量,而另一种还包括角位置和速度。
type(particle_A)
real :: position(3)
real :: velocity(3)
end type
type(particle_B)
real :: position(6)
real :: velocity(6)
end type
我有另一种派生类型,它将两种粒子的数组(以及实际应用程序中的其他一些数据)分组:
type(particleGroup)
type(particle_A), allocatable :: particleA_array(:)
integer :: NparticlesA
type(particle_B), allocatable :: particleB_array(:)
integer :: NparticlesB
character(len=30) :: particle_kind
end type
如果有更多粒子进入此特定过程的模拟,则在运行时期间分配和重新分配两个数组。根据粒子类型(在初始化期间)的设置,我想循环这两个数组之一并调用一些子例程(例如,用于更新位置和速度)。像这样(在循环第一个数组的情况下)
do iParticle = 1, nParticlesA
call updateVelocity( particleGroup%particleA_array(iParticle) )
end do
循环第二个数组
do iParticle = 1, nParticlesB
call updateVelocity( particleGroup%particleB_array(iParticle) )
end do
和使用使用接口块实现的通用过程 updateVelocity
。 Fortran 中有没有一种方法可以存储初始化期间要循环的数组(作为指针?),这样我就不必在每次循环迭代时检查 article_kind
?或者有更好的方法来处理这个问题吗?
I am new to Fortran and am developing a code in which I frequently do operations on two similar derived types (in this case representing models of particles in a scientific computing code). The two types are identical except one has only translational position and velocity components whereas the other also includes angular positions and velocities.
type(particle_A)
real :: position(3)
real :: velocity(3)
end type
type(particle_B)
real :: position(6)
real :: velocity(6)
end type
I have another derived type which groups arrays of both kinds of particles (together with some other data in the actual application):
type(particleGroup)
type(particle_A), allocatable :: particleA_array(:)
integer :: NparticlesA
type(particle_B), allocatable :: particleB_array(:)
integer :: NparticlesB
character(len=30) :: particle_kind
end type
Where both arrays are allocated and re-allocated during runtime if more particles enter the simulation on this particular process. Depending on what particle_kind
is set to (during initialization) I want to loop over one of these two arrays and call some subroutine (e.g. for updating the position and velocity). Something like this (in case of looping over the first array)
do iParticle = 1, nParticlesA
call updateVelocity( particleGroup%particleA_array(iParticle) )
end do
and this for looping over the second array
do iParticle = 1, nParticlesB
call updateVelocity( particleGroup%particleB_array(iParticle) )
end do
with the generic procedure updateVelocity
implemented using an interface block.
Is there a way in Fortran to store which array to loop over during initialization (as a pointer?), so that I do not have to check particle_kind
at every loop iteration? Or is there some better way of handling this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您只对在运行时使用 ParticleA 或
ParticleB
感兴趣,那么您可以使用多态数组。您首先必须定义一个父类,
ParticleA
和ParticleB
都可以从该父类继承,类似于然后您可以将
ParticleA
写为和 类似对于
ParticleB
。这将允许您将
ParticleGroup
编写为具有单个多态数组,该数组在运行时可以是ParticleA
类型或ParticleB
类型,例如You然后可以使用这些类,例如
在简单的示例中,将
article_group%no_articles
单独保留到size(article_group%articles)
是多余的,但我想如果您开始这样做,您可能需要它更先进内存存储策略(例如C++ std::向量式存储)。If you are only interested in using either
ParticleA
orParticleB
at runtime then you can achieve what you want using a polymorphic array.You would first have to define a parent class, from which both
ParticleA
andParticleB
can inherit, something likeThen you could write
ParticleA
asand analogously for
ParticleB
.This would allow you to write
ParticleGroup
as having a single polymorphic array, which could be either of typeParticleA
orParticleB
at runtime, something likeYou could then use these classes like
In simple examples, keeping
particle_group%no_particles
separately tosize(particle_group%particles)
is redundant, but I guess you might need it if you start doing more advanced memory-storage strategies (e.g. C++ std::vector-style storage).