分享分配数组 [英] Share allocatable Arrays

查看:151
本文介绍了分享分配数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我需要一些子程序之间分享一些分配数组。我通常只会它们作为参数传递或者在模块写的一切,但恐怕这是不可能在我的处境。

我只写了一些自己的子程序,并使用通过有限元求解器提​​供和描述子程序。所以我不能改变这个子程序的参数或在模块将它们包装。

据我所知,也不可能建立公共块在编译时未知大小的数组。

有没有别的东西通过我的阵列?

更新:结果
此刻我的编程环境是这样的:

我有一个子程序中,由有限元法的程序,其每一个增量后称为提供,这要求数我的子程序其中I计算的一些值的每个节点或这些的子集。

要显示在后仿真这些值,我必须将它们传递给另一个子程序。该子程序由有限元解算器用于在增量的端部的每个节点调用。所以我转移code这个子程序会产生很大的开销。

我的想法是,计算的值一次,将值存储在数组中,这数组传递到它们将被写入到计算的数据库中的第二子程序。

更新结果
有些伪code:结果
从程序行为假设:

 程序FEM解决者
     *魔法*
     调用ENDINC(AR1,AR2)
     * *的东西
     DO节点ID = 1,Sum_Of_Nodes
        做VALUEID = 1,Sum_Of_User_Computed_Values​​!($ p中$ pprocessing定义)
           调用nodeval(节点ID,VALUEID,价值,AR3,...,ARN)
        做到底
     做到底
     * *巫术
 最终方案的有限元求解器

书面和工作:

 子程序ENDINC(AR1,AR2)
  *某些节点值的计算*
  *自己的子程序,从而计算多个值的呼叫*
  *写作与结果值的数组一些/每个节点(S)*
   nodersltArr(节点ID,RSLT)= *一些价值*
结束子程序ENDINC

根据需要writng计算值到节点解决方案数据库:

 子程序nodeval(节点ID,VALUEID,价值,AR3,...,ARN)
  *呼吁每个节点ID和VALUEID *
   值= noderslArr(节点ID,VALUEID)
结束子程序nodeval


解决方案

您可以传递一个分配数组到未申报使用分配数组,只要数组在调用之前分配的过程。 (当然,你不能使用数组作为在它是在未使用财产申报程序可分配数组)。也许这将解决您的问题。在分配你写,不是把它作为参数传递给有限元求解器的code数组。

举例code:(我通常把函数到一个模块,但你说你不能这样做,所以我写呈现不使用模块的情况为例)

 函数MySum(RegArray)真正:: MySum
真实的,尺寸(:),意图(中):: RegArrayMySum = SUM(RegArray)最终功能MySum
节目TestArray   隐无   接口AFunc      功能MySum(的someArray)         真正:: MySum
         真实的,尺寸(:),意图(中)::的someArray      最终功能MySum   结束接口AFunc   真实的,尺寸(:),可分配:: AllocArray
   整数::ñ
   真正的答案::   写(*,(输入数组大小:)',预先=否)
   读(*,*)N   分配(AllocArray(1:N))
   AllocArray = 1.0   答案= MySum(AllocArray)
   写(*,*)答案程序结束TestArray

----------编辑:第二个概念---------

共享两个子程序之间的分配数组,而不调用程序作为阵列的感知。

 模块MySubs   真实的,分配的,尺寸(::) ::阵列包含
子程序的一个(X,Y,...,N,M)的   整数,意图(中):: N,M   如果(.NOT。分配(阵列))分配(阵列(N,M))
结束一个子程序
两个子程序(....)
结束两个子程序
前端模块MySubs

更新:注意:这种方法可用于通过两个例程之间的信息,而不对这个问题的主要具有程序访问模块...,而不修改原始主prpgram。的示例的部分是如何分配的阵列:实施例确实,通过具有将首先使用阵列是否被分配的阵列测试子程序 - 如果不是,它分配阵列

I have some allocatable arrays which I need to share between some subroutines. I usually would just pass them as arguments or maybe write everything in a Module, but I'm afraid this isn't possible in my situation.

I only write some own subroutines and use subroutines provided and described by an FEM-Solver. So i cannot alter the arguments of this subroutines or wrap them in a Module.

As far as i know it also isn't possible to Build common blocks with array of unknown size at compile time.

Is there something else to pass my arrays?

Update:
At the moment my program environment looks like this:

I have a subroutine, provided by the FEM-program, which is called after each increment, this calls several of my subroutines where I compute some values for each node or for a subset of those.

To display these values in the post-Simulation, i have to pass them to another subroutine. This subroutine is called by the FEM-solver for each node at the end of the increment. So shifting my code to this Subroutine would produce a lot of overhead.

My idea is to compute the values once, store the Values in an array and pass this array to the second subroutine where they will be written to the database of the computation.

Update
Some Pseudo-code:
Assumed from program behaviour:

 Program FEM-solver
     *magic* 
     call ENDINC(ar1,ar2)
     *something* 
     do NodeID=1,Sum_Of_Nodes
        do valueID=1,Sum_Of_User_Computed_Values !(defined in preprocessing)
           call nodeval(NodeID,valueID,Value,ar3,...,arN)
        end do
     end do
     *voodoo* 
 end program FEM-solver    

Written and working:

Subroutine ENDINC(ar1,ar2)
  *Computation of some node values*
  *Calling of own Subroutines, which compute more values*
  *Writing an array with results values for some/each node(s)*
   nodersltArr(NodeID,rslt)=*some Value*
end Subroutine ENDINC

Needed, writng the computed Values to the Node solution database:

Subroutine nodeval(NodeID,valueID,Value,ar3,...,arN)  
  *called for each NodeID and valueID*
   value=noderslArr(NodeID,valueID)
end subroutine nodeval

解决方案

You can pass an allocatable array to procedure that isn't declared to use allocatable arrays, as long as the array is allocated before the call. (Of course, you can't use the array as an allocatable array in the procedure in which it is declared without that property.) Perhaps that will solve your problem. Allocate the array in the code that you write, than pass it as an argument to the FEM solver.

Example code: (I'd normally put the function into a module but you say that you can't do that, so I write an example showing the case of not using a module.)

function MySum ( RegArray )

real :: MySum
real, dimension (:), intent (in) :: RegArray

MySum = sum (RegArray)

end function MySum


program TestArray

   implicit none

   interface AFunc

      function MySum ( SomeArray )

         real :: MySum
         real, dimension (:), intent (in) :: SomeArray

      end function MySum

   end interface AFunc

   real, dimension (:), allocatable :: AllocArray
   integer :: N
   real :: answer

   write (*, '("Input array size: ")', advance="no")
   read (*, *) N

   allocate ( AllocArray (1:N) )
   AllocArray = 1.0

   answer = MySum ( AllocArray )
   write (*, *) answer

end program TestArray

---------- EDIT: Second Concept ---------

Sharing an allocatable array between two subroutines, without the calling routine being "aware" of the array.

module MySubs

   real, allocatable, dimension (:,:) :: array

contains


subroutine One ( x, y, ... N, M )

   integer, intent (in) :: N, M

   if ( .NOT. allocated (array) ) allocate ( array (N, M) )


end subroutine One


subroutine Two ( .... )


end subroutine Two


end module MySubs

UPDATE: note: This approach can be used to pass information between the two routines without the main program having access the module ... for the question, without modifying the original main prpgram. Part of the example is how to allocate the arrays: the example does that by having the subroutine that would first use the array test whether the array is allocated -- if not, it allocates the array.

这篇关于分享分配数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆